--- /dev/null
+Index: linux-2.6.0-test5/arch/alpha/boot/misc.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/alpha/boot/misc.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/alpha/boot/misc.c 2003-09-27 11:38:18.536710376 +0800
+@@ -106,8 +106,8 @@
+ {
+ void *p;
+
+- if (size <0) error("Malloc error\n");
+- if (free_mem_ptr <= 0) error("Memory error\n");
++ if (size <0) error("Malloc error");
++ if (free_mem_ptr <= 0) error("Memory error");
+
+ free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
+
+@@ -140,7 +140,7 @@
+ int fill_inbuf(void)
+ {
+ if (insize != 0)
+- error("ran out of input data\n");
++ error("ran out of input data");
+
+ inbuf = input_data;
+ insize = input_data_size;
+Index: linux-2.6.0-test5/arch/alpha/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/alpha/Kconfig 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/alpha/Kconfig 2003-09-27 11:38:18.543709312 +0800
+@@ -484,6 +484,9 @@
+
+ Otherwise, say N.
+
++config EISA_ALWAYS
++ def_bool EISA
++
+ config SMP
+ bool "Symmetric multi-processing support"
+ depends on ALPHA_SABLE || ALPHA_LYNX || ALPHA_RAWHIDE || ALPHA_DP264 || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_GENERIC || ALPHA_SHARK || ALPHA_MARVEL
+Index: linux-2.6.0-test5/arch/alpha/kernel/core_irongate.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/alpha/kernel/core_irongate.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/alpha/kernel/core_irongate.c 2003-09-27 11:38:18.546708856 +0800
+@@ -391,7 +391,7 @@
+ cur_gatt = phys_to_virt(GET_GATT(baddr) & ~1);
+ pte = cur_gatt[GET_GATT_OFF(baddr)] & ~1;
+
+- if (__alpha_remap_area_pages(VMALLOC_VMADDR(vaddr),
++ if (__alpha_remap_area_pages(vaddr,
+ pte, PAGE_SIZE, 0)) {
+ printk("AGP ioremap: FAILED to map...\n");
+ vfree(area->addr);
+Index: linux-2.6.0-test5/arch/alpha/kernel/core_marvel.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/alpha/kernel/core_marvel.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/alpha/kernel/core_marvel.c 2003-09-27 11:38:18.553707792 +0800
+@@ -696,7 +696,7 @@
+ }
+ pfn >>= 1; /* make it a true pfn */
+
+- if (__alpha_remap_area_pages(VMALLOC_VMADDR(vaddr),
++ if (__alpha_remap_area_pages(vaddr,
+ pfn << PAGE_SHIFT,
+ PAGE_SIZE, 0)) {
+ printk("FAILED to map...\n");
+Index: linux-2.6.0-test5/arch/alpha/kernel/core_titan.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/alpha/kernel/core_titan.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/alpha/kernel/core_titan.c 2003-09-27 11:38:18.562706424 +0800
+@@ -534,7 +534,7 @@
+ }
+ pfn >>= 1; /* make it a true pfn */
+
+- if (__alpha_remap_area_pages(VMALLOC_VMADDR(vaddr),
++ if (__alpha_remap_area_pages(vaddr,
+ pfn << PAGE_SHIFT,
+ PAGE_SIZE, 0)) {
+ printk("FAILED to map...\n");
+Index: linux-2.6.0-test5/arch/arm26/boot/compressed/misc.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm26/boot/compressed/misc.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm26/boot/compressed/misc.c 2003-09-27 11:38:18.564706120 +0800
+@@ -191,8 +191,8 @@
+ {
+ void *p;
+
+- if (size <0) error("Malloc error\n");
+- if (free_mem_ptr <= 0) error("Memory error\n");
++ if (size <0) error("Malloc error");
++ if (free_mem_ptr <= 0) error("Memory error");
+
+ free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
+
+@@ -236,7 +236,7 @@
+ int fill_inbuf(void)
+ {
+ if (insize != 0)
+- error("ran out of input data\n");
++ error("ran out of input data");
+
+ inbuf = input_data;
+ insize = &input_data_end[0] - &input_data[0];
+Index: linux-2.6.0-test5/arch/arm26/kernel/setup.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm26/kernel/setup.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm26/kernel/setup.c 2003-09-27 11:38:18.569705360 +0800
+@@ -286,7 +286,7 @@
+ if (tag->hdr.size > 2) {
+ if ((tag->u.core.flags & 1) == 0)
+ root_mountflags &= ~MS_RDONLY;
+- ROOT_DEV = tag->u.core.rootdev;
++ ROOT_DEV = old_decode_dev(tag->u.core.rootdev);
+ }
+ return 0;
+ }
+Index: linux-2.6.0-test5/arch/arm/boot/bootp/init.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/boot/bootp/init.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/boot/bootp/init.S 2003-09-27 11:38:18.570705208 +0800
+@@ -1,86 +1,69 @@
+ /*
+ * linux/arch/arm/boot/bootp/init.S
+ *
+- * Copyright (C) 2000-2002 Russell King
++ * Copyright (C) 2000-2003 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+- * Header file for splitting kernel + initrd. Note that we pass
++ * "Header" file for splitting kernel + initrd. Note that we pass
+ * r0 through to r3 straight through.
++ *
++ * This demonstrates how to append code to the start of the kernel
++ * zImage, and boot the kernel without copying it around. This
++ * example would be simpler; if we didn't have an object of unknown
++ * size immediately following the kernel, we could build this into
++ * a binary blob, and concatenate the zImage using the cat command.
+ */
+ .section .start,#alloc,#execinstr
+ .type _start, #function
+ .globl _start
+-_start: adr r10, initdata
+- ldr r11, initdata
+- sub r11, r10, r11 @ work out exec offset
+- b splitify
+- .size _entry,. - _entry
+-
+- .type initdata, #object
+-initdata: .word initdata @ compiled address of this
+- .size initdata,. - initdata
+-
+-splitify: adr r13, data
+- ldmia r13!, {r4-r6} @ move the initrd
+- add r4, r4, r11 @ correction
+- bl move
++
++_start: adr r12, kernel_start @ offset of kernel zImage
++ ldr r4, [r12, #0x2c] @ length of zImage
++ adr r13, data
++ add r4, r4, r12 @ end of zImage, start of initrd
++ ldmia r13!, {r5-r6} @ r5 = dest, r6 = length
++ bl move @ move the initrd
+
+ /*
+- * Setup the initrd parameters to pass to the kernel. This can either be
+- * passed in via a param_struct or a tag list. We spot the param_struct
+- * method by looking at the first word; this should either indicate a page
+- * size of 4K, 16K or 32K.
++ * Setup the initrd parameters to pass to the kernel. This can only be
++ * passed in via the tagged list.
+ */
+- ldmia r13, {r4-r8} @ get size and addr of initrd
+- @ r5 = ATAG_INITRD
+- @ r6 = initrd start
+- @ r7 = initrd end
+- @ r8 = param_struct address
+- ldr r9, [r8, #0] @ no param struct?
+- teq r9, #0x1000 @ 4K?
+- teqne r9, #0x4000 @ 16K?
+- teqne r9, #0x8000 @ 32K?
+- beq param_struct
+-
+- ldr r9, [r8, #4] @ get first tag
+- teq r9, r4
+- bne taglist @ ok, we have a tag list
++ ldmia r13, {r5-r9} @ get size and addr of initrd
++ @ r5 = ATAG_CORE
++ @ r6 = ATAG_INITRD2
++ @ r7 = initrd start
++ @ r8 = initrd end
++ @ r9 = param_struct address
+
++ ldr r10, [r9, #4] @ get first tag
++ teq r10, r5 @ is it ATAG_CORE?
+ /*
+- * We didn't find a valid tag list - create one.
++ * If we didn't find a valid tag list, create a dummy ATAG_CORE entry.
+ */
+- str r4, [r8, #4]
+- mov r4, #8
+- str r4, [r8, #0]
+- mov r4, #0
+- str r4, [r8, #8]
++ movne r10, #0 @ terminator
++ movne r4, #2 @ Size of this entry (2 words)
++ stmneia r8, {r4, r5, r10} @ Size, ATAG_CORE, terminator
+
+ /*
+ * find the end of the tag list, and then add an INITRD tag on the end.
+ * If there is already an INITRD tag, then we ignore it; the last INITRD
+ * tag takes precidence.
+ */
+-taglist: ldr r9, [r8, #0] @ tag length
+- teq r9, #0 @ last tag?
+- addne r8, r8, r9
++taglist: ldr r10, [r9, #0] @ tag length
++ teq r10, #0 @ last tag (zero length)?
++ addne r9, r9, r10, lsl #2
+ bne taglist
+
+- mov r4, #16 @ length of initrd tag
+- mov r9, #0 @ end of tag list terminator
+- stmia r8, {r4, r5, r6, r7, r9}
+- adr r12, kernel_start
++ mov r5, #4 @ Size of initrd tag (4 words)
++ stmia r9, {r5, r6, r7, r8, r10}
+ mov pc, r12 @ call kernel
+
+ /*
+- * We found a param struct. Modify the param struct for the initrd
++ * Move the block of memory length r6 from address r4 to address r5
+ */
+-param_struct: add r8, r8, #16*4
+- stmia r8, {r6,r7} @ save in param_struct
+- mov pc, r12 @ call kernel
+-
+ move: ldmia r4!, {r7 - r10} @ move 32-bytes at a time
+ stmia r5!, {r7 - r10}
+ ldmia r4!, {r7 - r10}
+@@ -89,15 +72,18 @@
+ bcs move
+ mov pc, lr
+
+-data: .word initrd_start
+- .word initrd_addr
+- .word initrd_len
++ .size _start, . - _start
++
++ .type data,#object
++data: .word initrd_addr @ destination initrd address
++ .word initrd_len @ initrd size
+
+ .word 0x54410001 @ r4 = ATAG_CORE
+- .word 0x54420005 @ r5 = ATAG_INITRD
++ .word 0x54420005 @ r5 = ATAG_INITRD2
+ .word initrd_addr @ r6
+ .word initrd_len @ r7
+ .word params @ r8
++ .size data, . - _data
+
+ .type initrd_start,#object
+
+Index: linux-2.6.0-test5/arch/arm/boot/compressed/head-sa1100.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/boot/compressed/head-sa1100.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/boot/compressed/head-sa1100.S 2003-09-27 11:38:18.572704904 +0800
+@@ -34,6 +34,10 @@
+ @ REVISIT_PFS168: Temporary until firmware updated to use assigned machine number
+ mov r7, #MACH_TYPE_PFS168
+ #endif
++#ifdef CONFIG_SA1100_SIMPAD
++ @ UNTIL we've something like an open bootldr
++ mov r7, #MACH_TYPE_SIMPAD @should be 87
++#endif
+
+ #ifdef CONFIG_SA1100_VICTOR
+ teq r7, #MACH_TYPE_VICTOR
+Index: linux-2.6.0-test5/arch/arm/boot/compressed/misc.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/boot/compressed/misc.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/boot/compressed/misc.c 2003-09-27 11:38:18.574704600 +0800
+@@ -191,8 +191,8 @@
+ {
+ void *p;
+
+- if (size <0) error("Malloc error\n");
+- if (free_mem_ptr <= 0) error("Memory error\n");
++ if (size <0) error("Malloc error");
++ if (free_mem_ptr <= 0) error("Memory error");
+
+ free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
+
+@@ -236,7 +236,7 @@
+ int fill_inbuf(void)
+ {
+ if (insize != 0)
+- error("ran out of input data\n");
++ error("ran out of input data");
+
+ inbuf = input_data;
+ insize = &input_data_end[0] - &input_data[0];
+Index: linux-2.6.0-test5/arch/arm/common/sa1111.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/common/sa1111.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/common/sa1111.c 2003-09-27 11:38:18.583703232 +0800
+@@ -14,6 +14,7 @@
+ * All initialization functions provided here are intended to be called
+ * from machine specific code with proper arguments when required.
+ */
++#include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+@@ -54,87 +55,74 @@
+ */
+ static struct sa1111 *g_sa1111;
+
+-static struct sa1111_dev usb_dev = {
+- .skpcr_mask = SKPCR_UCLKEN,
+- .devid = SA1111_DEVID_USB,
+- .irq = {
+- IRQ_USBPWR,
+- IRQ_HCIM,
+- IRQ_HCIBUFFACC,
+- IRQ_HCIRMTWKP,
+- IRQ_NHCIMFCIR,
+- IRQ_USB_PORT_RESUME
+- },
++struct sa1111_dev_info {
++ unsigned long offset;
++ unsigned long skpcr_mask;
++ unsigned int devid;
++ unsigned int irq[6];
+ };
+
+-static struct sa1111_dev sac_dev = {
+- .skpcr_mask = SKPCR_I2SCLKEN | SKPCR_L3CLKEN,
+- .devid = SA1111_DEVID_SAC,
+- .irq = {
+- AUDXMTDMADONEA,
+- AUDXMTDMADONEB,
+- AUDRCVDMADONEA,
+- AUDRCVDMADONEB
++static struct sa1111_dev_info sa1111_devices[] = {
++ {
++ .offset = SA1111_USB,
++ .skpcr_mask = SKPCR_UCLKEN,
++ .devid = SA1111_DEVID_USB,
++ .irq = {
++ IRQ_USBPWR,
++ IRQ_HCIM,
++ IRQ_HCIBUFFACC,
++ IRQ_HCIRMTWKP,
++ IRQ_NHCIMFCIR,
++ IRQ_USB_PORT_RESUME
++ },
+ },
+-};
+-
+-static struct sa1111_dev ssp_dev = {
+- .skpcr_mask = SKPCR_SCLKEN,
+- .devid = SA1111_DEVID_SSP,
+-};
+-
+-static struct sa1111_dev kbd_dev = {
+- .skpcr_mask = SKPCR_PTCLKEN,
+- .devid = SA1111_DEVID_PS2,
+- .irq = {
+- IRQ_TPRXINT,
+- IRQ_TPTXINT
++ {
++ .offset = 0x0600,
++ .skpcr_mask = SKPCR_I2SCLKEN | SKPCR_L3CLKEN,
++ .devid = SA1111_DEVID_SAC,
++ .irq = {
++ AUDXMTDMADONEA,
++ AUDXMTDMADONEB,
++ AUDRCVDMADONEA,
++ AUDRCVDMADONEB
++ },
+ },
+-};
+-
+-static struct sa1111_dev mse_dev = {
+- .skpcr_mask = SKPCR_PMCLKEN,
+- .devid = SA1111_DEVID_PS2,
+- .irq = {
+- IRQ_MSRXINT,
+- IRQ_MSTXINT
++ {
++ .offset = 0x0800,
++ .skpcr_mask = SKPCR_SCLKEN,
++ .devid = SA1111_DEVID_SSP,
+ },
+-};
+-
+-static struct sa1111_dev int_dev = {
+- .skpcr_mask = 0,
+- .devid = SA1111_DEVID_INT,
+-};
+-
+-static struct sa1111_dev pcmcia_dev = {
+- .skpcr_mask = 0,
+- .devid = SA1111_DEVID_PCMCIA,
+- .irq = {
+- IRQ_S0_READY_NINT,
+- IRQ_S0_CD_VALID,
+- IRQ_S0_BVD1_STSCHG,
+- IRQ_S1_READY_NINT,
+- IRQ_S1_CD_VALID,
+- IRQ_S1_BVD1_STSCHG,
++ {
++ .offset = SA1111_KBD,
++ .skpcr_mask = SKPCR_PTCLKEN,
++ .devid = SA1111_DEVID_PS2,
++ .irq = {
++ IRQ_TPRXINT,
++ IRQ_TPTXINT
++ },
++ },
++ {
++ .offset = SA1111_MSE,
++ .skpcr_mask = SKPCR_PMCLKEN,
++ .devid = SA1111_DEVID_PS2,
++ .irq = {
++ IRQ_MSRXINT,
++ IRQ_MSTXINT
++ },
++ },
++ {
++ .offset = 0x1800,
++ .skpcr_mask = 0,
++ .devid = SA1111_DEVID_PCMCIA,
++ .irq = {
++ IRQ_S0_READY_NINT,
++ IRQ_S0_CD_VALID,
++ IRQ_S0_BVD1_STSCHG,
++ IRQ_S1_READY_NINT,
++ IRQ_S1_CD_VALID,
++ IRQ_S1_BVD1_STSCHG,
++ },
+ },
+-};
+-
+-static struct sa1111_dev *devs[] = {
+- &usb_dev,
+- &sac_dev,
+- &ssp_dev,
+- &kbd_dev,
+- &mse_dev,
+- &pcmcia_dev,
+-};
+-
+-static unsigned int dev_offset[] = {
+- SA1111_USB,
+- 0x0600,
+- 0x0800,
+- SA1111_KBD,
+- SA1111_MSE,
+- 0x1800,
+ };
+
+ /*
+@@ -372,44 +360,45 @@
+ .wake = sa1111_wake_highirq,
+ };
+
+-static void __init sa1111_init_irq(struct sa1111_dev *sadev)
++static void sa1111_setup_irq(struct sa1111 *sachip)
+ {
++ void *irqbase = sachip->base + SA1111_INTC;
+ unsigned int irq;
+
+ /*
+ * We're guaranteed that this region hasn't been taken.
+ */
+- request_mem_region(sadev->res.start, 512, "irqs");
++ request_mem_region(sachip->phys + SA1111_INTC, 512, "irq");
+
+ /* disable all IRQs */
+- sa1111_writel(0, sadev->mapbase + SA1111_INTEN0);
+- sa1111_writel(0, sadev->mapbase + SA1111_INTEN1);
+- sa1111_writel(0, sadev->mapbase + SA1111_WAKEEN0);
+- sa1111_writel(0, sadev->mapbase + SA1111_WAKEEN1);
++ sa1111_writel(0, irqbase + SA1111_INTEN0);
++ sa1111_writel(0, irqbase + SA1111_INTEN1);
++ sa1111_writel(0, irqbase + SA1111_WAKEEN0);
++ sa1111_writel(0, irqbase + SA1111_WAKEEN1);
+
+ /*
+ * detect on rising edge. Note: Feb 2001 Errata for SA1111
+ * specifies that S0ReadyInt and S1ReadyInt should be '1'.
+ */
+- sa1111_writel(0, sadev->mapbase + SA1111_INTPOL0);
++ sa1111_writel(0, irqbase + SA1111_INTPOL0);
+ sa1111_writel(SA1111_IRQMASK_HI(IRQ_S0_READY_NINT) |
+ SA1111_IRQMASK_HI(IRQ_S1_READY_NINT),
+- sadev->mapbase + SA1111_INTPOL1);
++ irqbase + SA1111_INTPOL1);
+
+ /* clear all IRQs */
+- sa1111_writel(~0, sadev->mapbase + SA1111_INTSTATCLR0);
+- sa1111_writel(~0, sadev->mapbase + SA1111_INTSTATCLR1);
++ sa1111_writel(~0, irqbase + SA1111_INTSTATCLR0);
++ sa1111_writel(~0, irqbase + SA1111_INTSTATCLR1);
+
+ for (irq = IRQ_GPAIN0; irq <= SSPROR; irq++) {
+ set_irq_chip(irq, &sa1111_low_chip);
+- set_irq_chipdata(irq, sadev->mapbase);
++ set_irq_chipdata(irq, irqbase);
+ set_irq_handler(irq, do_edge_IRQ);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ }
+
+ for (irq = AUDXMTDMADONEA; irq <= IRQ_S1_BVD1_STSCHG; irq++) {
+ set_irq_chip(irq, &sa1111_high_chip);
+- set_irq_chipdata(irq, sadev->mapbase);
++ set_irq_chipdata(irq, irqbase);
+ set_irq_handler(irq, do_edge_IRQ);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ }
+@@ -417,9 +406,9 @@
+ /*
+ * Register SA1111 interrupt
+ */
+- set_irq_type(sadev->irq[0], IRQT_RISING);
+- set_irq_data(sadev->irq[0], sadev->mapbase);
+- set_irq_chained_handler(sadev->irq[0], sa1111_irq_handler);
++ set_irq_type(sachip->irq, IRQT_RISING);
++ set_irq_data(sachip->irq, irqbase);
++ set_irq_chained_handler(sachip->irq, sa1111_irq_handler);
+ }
+
+ /*
+@@ -529,37 +518,64 @@
+
+ #endif
+
+-static void
++static void sa1111_dev_release(struct device *_dev)
++{
++ struct sa1111_dev *dev = SA1111_DEV(_dev);
++
++ release_resource(&dev->res);
++ kfree(dev);
++}
++
++static int
+ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent,
+- struct sa1111_dev *sadev, unsigned int offset)
++ struct sa1111_dev_info *info)
+ {
+- snprintf(sadev->dev.bus_id, sizeof(sadev->dev.bus_id),
+- "%4.4x", offset);
++ struct sa1111_dev *dev;
++ int ret;
++
++ dev = kmalloc(sizeof(struct sa1111_dev), GFP_KERNEL);
++ if (!dev) {
++ ret = -ENOMEM;
++ goto out;
++ }
++ memset(dev, 0, sizeof(struct sa1111_dev));
++
++ snprintf(dev->dev.bus_id, sizeof(dev->dev.bus_id),
++ "%4.4lx", info->offset);
+
+ /*
+ * If the parent device has a DMA mask associated with it,
+ * propagate it down to the children.
+ */
+ if (sachip->dev->dma_mask) {
+- sadev->dma_mask = *sachip->dev->dma_mask;
+- sadev->dev.dma_mask = &sadev->dma_mask;
++ dev->dma_mask = *sachip->dev->dma_mask;
++ dev->dev.dma_mask = &dev->dma_mask;
+ }
+
+- sadev->dev.parent = sachip->dev;
+- sadev->dev.bus = &sa1111_bus_type;
+- sadev->res.start = sachip->phys + offset;
+- sadev->res.end = sadev->res.start + 511;
+- sadev->res.name = sadev->dev.bus_id;
+- sadev->res.flags = IORESOURCE_MEM;
+- sadev->mapbase = sachip->base + offset;
++ dev->devid = info->devid;
++ dev->dev.parent = sachip->dev;
++ dev->dev.bus = &sa1111_bus_type;
++ dev->dev.release = sa1111_dev_release;
++ dev->res.start = sachip->phys + info->offset;
++ dev->res.end = dev->res.start + 511;
++ dev->res.name = dev->dev.bus_id;
++ dev->res.flags = IORESOURCE_MEM;
++ dev->mapbase = sachip->base + info->offset;
+
+- if (request_resource(parent, &sadev->res)) {
++ ret = request_resource(parent, &dev->res);
++ if (ret) {
+ printk("SA1111: failed to allocate resource for %s\n",
+- sadev->res.name);
+- return;
++ dev->res.name);
++ goto out;
+ }
+
+- device_register(&sadev->dev);
++ ret = device_register(&dev->dev);
++ if (ret) {
++ release_resource(&dev->res);
++ out:
++ kfree(dev);
++ }
++ return ret;
+ }
+
+ /**
+@@ -655,11 +671,8 @@
+ * The interrupt controller must be initialised before any
+ * other device to ensure that the interrupts are available.
+ */
+- if (irq != NO_IRQ) {
+- int_dev.irq[0] = irq;
+- sa1111_init_one_child(sachip, mem, &int_dev, SA1111_INTC);
+- sa1111_init_irq(&int_dev);
+- }
++ if (sachip->irq != NO_IRQ)
++ sa1111_setup_irq(sachip);
+
+ g_sa1111 = sachip;
+
+@@ -670,9 +683,9 @@
+ else
+ has_devs &= ~(1 << 1);
+
+- for (i = 0; i < ARRAY_SIZE(devs); i++)
++ for (i = 0; i < ARRAY_SIZE(sa1111_devices); i++)
+ if (has_devs & (1 << i))
+- sa1111_init_one_child(sachip, mem, devs[i], dev_offset[i]);
++ sa1111_init_one_child(sachip, mem, &sa1111_devices[i]);
+
+ return 0;
+
+@@ -685,11 +698,26 @@
+
+ static void __sa1111_remove(struct sa1111 *sachip)
+ {
+- int i;
++ struct list_head *l, *n;
++ void *irqbase = sachip->base + SA1111_INTC;
++
++ list_for_each_safe(l, n, &sachip->dev->children) {
++ struct device *d = list_to_dev(l);
+
+- for (i = 0; i < ARRAY_SIZE(devs); i++) {
+- put_device(&devs[i]->dev);
+- release_resource(&devs[i]->res);
++ device_unregister(d);
++ }
++
++ /* disable all IRQs */
++ sa1111_writel(0, irqbase + SA1111_INTEN0);
++ sa1111_writel(0, irqbase + SA1111_INTEN1);
++ sa1111_writel(0, irqbase + SA1111_WAKEEN0);
++ sa1111_writel(0, irqbase + SA1111_WAKEEN1);
++
++ if (sachip->irq != NO_IRQ) {
++ set_irq_chained_handler(sachip->irq, NULL);
++ set_irq_data(sachip->irq, NULL);
++
++ release_mem_region(sachip->phys + SA1111_INTC, 512);
+ }
+
+ iounmap(sachip->base);
+@@ -958,17 +986,6 @@
+ };
+
+ /*
+- * Register the SA1111 driver with LDM.
+- */
+-static int sa1111_driver_init(void)
+-{
+- driver_register(&sa1111_device_driver);
+- return 0;
+-}
+-
+-arch_initcall(sa1111_driver_init);
+-
+-/*
+ * Get the parent device driver (us) structure
+ * from a child function device
+ */
+@@ -1180,13 +1197,6 @@
+ .resume = sa1111_bus_resume,
+ };
+
+-static int sa1111_rab_bus_init(void)
+-{
+- return bus_register(&sa1111_bus_type);
+-}
+-
+-postcore_initcall(sa1111_rab_bus_init);
+-
+ int sa1111_driver_register(struct sa1111_driver *driver)
+ {
+ driver->drv.probe = sa1111_bus_probe;
+@@ -1200,6 +1210,26 @@
+ driver_unregister(&driver->drv);
+ }
+
++static int __init sa1111_init(void)
++{
++ int ret = bus_register(&sa1111_bus_type);
++ if (ret == 0)
++ driver_register(&sa1111_device_driver);
++ return ret;
++}
++
++static void __exit sa1111_exit(void)
++{
++ driver_unregister(&sa1111_device_driver);
++ bus_unregister(&sa1111_bus_type);
++}
++
++module_init(sa1111_init);
++module_exit(sa1111_exit);
++
++MODULE_DESCRIPTION("Intel Corporation SA1111 core driver");
++MODULE_LICENSE("GPL");
++
+ EXPORT_SYMBOL(sa1111_check_dma_bug);
+ EXPORT_SYMBOL(sa1111_select_audio_mode);
+ EXPORT_SYMBOL(sa1111_set_audio_rate);
+Index: linux-2.6.0-test5/arch/arm/common/sa1111-pcipool.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/common/sa1111-pcipool.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/common/sa1111-pcipool.c 2003-09-27 11:38:18.591702016 +0800
+@@ -51,7 +51,7 @@
+
+ static inline const char *slot_name(const struct pci_pool *pool)
+ {
+- const struct pci_dev *pdev = pool->dev;
++ struct pci_dev *pdev = (struct pci_dev *)pool->dev;
+
+ if (pdev == 0)
+ return "[0]";
+Index: linux-2.6.0-test5/arch/arm/configs/a5k_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/a5k_defconfig 2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/a5k_defconfig 2003-09-27 11:38:18.592701864 +0800
+@@ -0,0 +1,526 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_SBUS is not set
++CONFIG_UID16=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_OBSOLETE=y
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++CONFIG_ARCH_ARCA5K=y
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++CONFIG_ARCH_A5K=y
++
++#
++# Footbridge Implementations
++#
++
++#
++# SA11x0 Implementations
++#
++CONFIG_ARCH_ACORN=y
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++# CONFIG_CPU_32 is not set
++CONFIG_CPU_26=y
++# CONFIG_PAGESIZE_16 is not set
++
++#
++# Processor Type
++#
++# CONFIG_DISCONTIGMEM is not set
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++# CONFIG_HOTPLUG is not set
++# CONFIG_PCMCIA is not set
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_NWFPE=y
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++# CONFIG_BINFMT_ELF is not set
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++
++#
++# Parallel port support
++#
++CONFIG_PARPORT=m
++CONFIG_PARPORT_PC=m
++# CONFIG_PARPORT_PC_FIFO is not set
++CONFIG_PARPORT_PC_SUPERIO=y
++# CONFIG_PARPORT_ARC is not set
++# CONFIG_PARPORT_AMIGA is not set
++# CONFIG_PARPORT_MFC3 is not set
++# CONFIG_PARPORT_ATARI is not set
++# CONFIG_PARPORT_SUNBPP is not set
++# CONFIG_PARPORT_OTHER is not set
++# CONFIG_PARPORT_1284 is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++# CONFIG_MTD is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++
++#
++# Block devices
++#
++CONFIG_BLK_DEV_FD=y
++# 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_BLK_DEV_DAC960 is not set
++CONFIG_BLK_DEV_LOOP=m
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Acorn-specific block devices
++#
++# CONFIG_BLK_DEV_FD1772 is not set
++CONFIG_BLK_DEV_MFM=m
++CONFIG_BLK_DEV_MFM_AUTODETECT=y
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++# CONFIG_NETLINK 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 is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE 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
++# CONFIG_ATM is not set
++
++#
++#
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK 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_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 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_NET_SB1000 is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++CONFIG_ARM_ETHER1=y
++CONFIG_ARM_ETHER3=y
++# CONFIG_ARM_ETHERH 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_AT1700 is not set
++# CONFIG_DEPCA 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_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN 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
++
++#
++# 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_IDEDISK=y
++# CONFIG_IDEDISK_MULTI_MODE is not set
++# CONFIG_BLK_DEV_IDECS 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
++
++#
++# 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_IDE_ICSIDE=y
++# CONFIG_BLK_DEV_IDEDMA_ICS is not set
++# CONFIG_IDEDMA_ICS_AUTO is not set
++# CONFIG_BLK_DEV_IDEDMA is not set
++# CONFIG_BLK_DEV_IDE_RAPIDE is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O 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
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_SERIAL=y
++CONFIG_SERIAL_CONSOLE=y
++# CONFIG_ATOMWIDE_SERIAL is not set
++# CONFIG_DUALSP_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_UNIX98_PTYS is not set
++# CONFIG_PRINTER is not set
++# CONFIG_PPDEV is not set
++
++#
++# I2C support
++#
++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_I2C_ALGOPCF is not set
++CONFIG_I2C_CHARDEV=y
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++CONFIG_MOUSE=y
++# CONFIG_PSMOUSE is not set
++# CONFIG_82C710_MOUSE is not set
++# CONFIG_PC110_PAD is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++
++#
++# Input core support is needed for joysticks
++#
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG 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
++# CONFIG_DRM is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++CONFIG_AUTOFS4_FS=y
++CONFIG_ADFS_FS=y
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++CONFIG_FAT_FS=m
++CONFIG_MSDOS_FS=m
++# 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_CRAMFS is not set
++# CONFIG_RAMFS is not set
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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 is not set
++# 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_SYSV_FS_WRITE 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
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=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_MOUNT_SUBDIR is not set
++# CONFIG_NCPFS_NDS_DOMAINS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++CONFIG_ACORN_PARTITION=y
++CONFIG_ACORN_PARTITION_ADFS=y
++CONFIG_ACORN_PARTITION_ICS=y
++CONFIG_ACORN_PARTITION_POWERTEC=y
++CONFIG_ACORN_PARTITION_RISCIX=y
++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_874 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_ISO8859_1 is not set
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_UTF8 is not set
++
++#
++# Console drivers
++#
++CONFIG_FB=y
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FB_ACORN=y
++# CONFIG_FB_CYBER2000 is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FBCON_ADVANCED is not set
++CONFIG_FBCON_MFB=y
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
++CONFIG_FBCON_FONTS=y
++# CONFIG_FONT_8x8 is not set
++# CONFIG_FONT_8x16 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_SUN12x22 is not set
++# CONFIG_FONT_6x11 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++CONFIG_FONT_ACORN_8x8=y
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++CONFIG_MAGIC_SYSRQ=y
++CONFIG_NO_PGT_CACHE=y
++CONFIG_DEBUG_LL=y
+Index: linux-2.6.0-test5/arch/arm/configs/adi_evb_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/adi_evb_defconfig 2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/adi_evb_defconfig 2003-09-27 11:38:18.593701712 +0800
+@@ -0,0 +1,681 @@
++#
++# Automatically generated by make menuconfig: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++# CONFIG_GENERIC_BUST_SPINLOCK is not set
++# CONFIG_GENERIC_ISA_DMA is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++CONFIG_ARCH_ADIFCC=y
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_IOP310 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++# CONFIG_SA1100_USB is not set
++# CONFIG_SA1100_USB_NETLINK is not set
++# CONFIG_SA1100_USB_CHAR is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++CONFIG_ARCH_ADI_EVB=y
++CONFIG_XSCALE_PMU_TIMER=y
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++# CONFIG_CPU_32v3 is not set
++# CONFIG_CPU_32v4 is not set
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM926T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++# CONFIG_CPU_SA1100 is not set
++CONFIG_CPU_32v4=y
++CONFIG_CPU_XSCALE=y
++CONFIG_ARM_THUMB=y
++# CONFIG_XSCALE_TOOLS is not set
++CONFIG_XSCALE_WRITE_ALLOC=y
++CONFIG_XSCALE_PMU=y
++CONFIG_ARM_THUMB=y
++# CONFIG_DISCONTIGMEM is not set
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++# CONFIG_HOTPLUG is not set
++# CONFIG_PCMCIA is not set
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/mtdblock1 mem=32M initrd=0xc0800000,3M"
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_BOOTLDR_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++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 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_NORA is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_CDB89712 is not set
++# CONFIG_MTD_SA1100 is not set
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++CONFIG_MTD_ADI_EVB=y
++# CONFIG_MTD_PCI 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
++# 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
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++# CONFIG_PNPBIOS 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_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=8192
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# 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 is not set
++CONFIG_NETLINK=y
++CONFIG_RTNETLINK=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 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_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
++# CONFIG_ATM is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK 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 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_ARM_AM79C961A is not set
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNBMAC is not set
++# CONFIG_SUNQE is not set
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNGEM is not set
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_LANCE is not set
++# CONFIG_NET_VENDOR_SMC is not set
++# CONFIG_NET_VENDOR_RACAL 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_MYRI_SBUS is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN 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
++
++#
++# ATA/IDE/MFM/RLL support
++#
++# CONFIG_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O 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
++
++#
++# 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
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++CONFIG_SERIAL=y
++CONFIG_SERIAL_CONSOLE=y
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_ANAKIN is not set
++# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_UART00 is not set
++# CONFIG_SERIAL_UART00_CONSOLE is not set
++# CONFIG_SERIAL_SA1100 is not set
++# CONFIG_SERIAL_SA1100_CONSOLE is not set
++# CONFIG_SERIAL_8250 is not set
++# CONFIG_SERIAL_8250_CONSOLE is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_MULTIPORT is not set
++# CONFIG_SERIAL_8250_HUB6 is not set
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++# CONFIG_L3_ALGOBIT is not set
++# CONFIG_L3_BIT_SA1100_GPIO is not set
++# CONFIG_L3_SA1111 is not set
++# CONFIG_BIT_SA1100_GPIO is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++CONFIG_MOUSE=y
++CONFIG_PSMOUSE=y
++# CONFIG_82C710_MOUSE is not set
++# CONFIG_PC110_PAD is not set
++
++#
++# Joysticks
++#
++# CONFIG_INPUT_GAMEPORT is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG 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
++# CONFIG_DRM is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA 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_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_BFS_FS is not set
++# CONFIG_CMS_FS is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_JBD is not set
++# 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=y
++CONFIG_JFFS2_FS_DEBUG=0
++# CONFIG_CRAMFS is not set
++# CONFIG_TMPFS is not set
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_ZISOFS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_FREEVXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
++# CONFIG_NFS_FS is not set
++# CONFIG_NFS_V3 is not set
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++# CONFIG_SUNRPC is not set
++# CONFIG_LOCKD is not set
++# 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_ZLIB_FS_INFLATE is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++# CONFIG_MSDOS_PARTITION is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_SMB_NLS is not set
++# CONFIG_NLS is not set
++
++#
++# Multimedia Capabilities Port drivers
++#
++# CONFIG_MCP is not set
++# CONFIG_MCP_SA1100 is not set
++# CONFIG_MCP_UCB1200 is not set
++# CONFIG_MCP_UCB1200_AUDIO is not set
++# CONFIG_MCP_UCB1200_TS is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++# CONFIG_USB_OHCI is not set
++# CONFIG_USB_OHCI_SA1111 is not set
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++# 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_JUMPSHOT is not set
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# 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
++# CONFIG_USB_PEGASUS 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
++# CONFIG_USB_USS720 is not set
++
++#
++# USB Serial Converter support
++#
++# CONFIG_USB_SERIAL is not set
++# CONFIG_USB_SERIAL_GENERIC is not set
++# CONFIG_USB_SERIAL_BELKIN is not set
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
++# CONFIG_USB_SERIAL_EMPEG is not set
++# CONFIG_USB_SERIAL_FTDI_SIO is not set
++# CONFIG_USB_SERIAL_VISOR is not set
++# CONFIG_USB_SERIAL_IR is not set
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
++# CONFIG_USB_SERIAL_MCT_U232 is not set
++# CONFIG_USB_SERIAL_PL2303 is not set
++# CONFIG_USB_SERIAL_CYBERJACK is not set
++# CONFIG_USB_SERIAL_XIRCOM is not set
++# CONFIG_USB_SERIAL_OMNINET is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_ID75 is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++CONFIG_DEBUG_SLAB=y
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_NO_PGT_CACHE is not set
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/adsbitsy_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/adsbitsy_defconfig 2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/adsbitsy_defconfig 2003-09-27 11:38:18.595701408 +0800
+@@ -0,0 +1,664 @@
++#
++# Automatically generated by make menuconfig: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_BITSY is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++CONFIG_SA1100_ADSBITSY=y
++CONFIG_SA1111=y
++# CONFIG_SA1100_USB is not set
++# CONFIG_SA1100_USB_NETLINK is not set
++# CONFIG_SA1100_USB_CHAR is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++CONFIG_DISCONTIGMEM=y
++# CONFIG_CPU_BIG_ENDIAN is not set
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++# CONFIG_CPU_FREQ is not set
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=y
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=y
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_APM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="ip=off mem=32M root=/dev/ram ramdisk=8192 initrd=0xc0800000,4M"
++# CONFIG_PFS168_CMDLINE is not set
++# CONFIG_LEDS is not set
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++# CONFIG_MTD 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_BLK_DEV_DAC960 is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=8192
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# 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_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++# CONFIG_NETLINK 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 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_INET_ECN is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK 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 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
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNBMAC is not set
++# CONFIG_SUNQE is not set
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNGEM is not set
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_LANCE is not set
++# CONFIG_NET_VENDOR_SMC is not set
++# CONFIG_NET_VENDOR_RACAL 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_ACENIC_OMIT_TIGON_I is not set
++# CONFIG_MYRI_SBUS is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_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
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=y
++# CONFIG_PCMCIA_NMCLAN is not set
++# CONFIG_PCMCIA_SMC91C92 is not set
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++CONFIG_IDE=y
++
++#
++# IDE, ATA and ATAPI Block devices
++#
++CONFIG_BLK_DEV_IDE=y
++# CONFIG_BLK_DEV_HD_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++CONFIG_BLK_DEV_IDEDISK=y
++# CONFIG_IDEDISK_MULTI_MODE is not set
++CONFIG_BLK_DEV_IDECS=y
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
++# CONFIG_BLK_DEV_ISAPNP is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O 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
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_KEYBDEV is not set
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=38400
++# CONFIG_SERIAL_8250 is not set
++# CONFIG_SERIAL_8250_CONSOLE is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++CONFIG_UCB1200=y
++CONFIG_TOUCHSCREEN_UCB1200=y
++CONFIG_AUDIO_UCB1200=y
++CONFIG_ADC_UCB1200=y
++# CONFIG_TOUCHSCREEN_BITSY is not set
++# CONFIG_PROFILER is not set
++# CONFIG_PFS168_SPI is not set
++# CONFIG_PFS168_DTMF is not set
++# CONFIG_PFS168_MISC is not set
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_SA1100_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
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA 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_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_BFS_FS is not set
++CONFIG_FAT_FS=y
++# CONFIG_MSDOS_FS is not set
++# 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 is not set
++CONFIG_CRAMFS=y
++# CONFIG_TMPFS is not set
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=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
++
++#
++# 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_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
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_CLPS711X is not set
++# CONFIG_FB_CYBER2000 is not set
++CONFIG_FB_SA1100=y
++# CONFIG_FB_ANAKIN is not set
++# CONFIG_FB_E1355 is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FBCON_ADVANCED is not set
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++CONFIG_FBCON_FONTWIDTH8_ONLY=y
++CONFIG_FBCON_FONTS=y
++# CONFIG_FONT_8x8 is not set
++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
++#
++# CONFIG_SOUND is not set
++
++#
++# USB support
++#
++CONFIG_USB=y
++# CONFIG_USB_DEBUG is not set
++CONFIG_USB_DEVICEFS=y
++# CONFIG_USB_BANDWIDTH is not set
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++CONFIG_USB_OHCI=y
++CONFIG_USB_OHCI_NOPCI=y
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++# CONFIG_USB_STORAGE is not set
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# CONFIG_USB_HID is not set
++# CONFIG_USB_KBD is not set
++CONFIG_USB_MOUSE=y
++# CONFIG_USB_WACOM is not set
++# 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_IBMCAM is not set
++# CONFIG_USB_OV511 is not set
++# CONFIG_USB_PWC is not set
++# CONFIG_USB_SE401 is not set
++# CONFIG_USB_DSBR is not set
++# CONFIG_USB_DABUSB is not set
++# CONFIG_USB_PLUSB is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_NET1080 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_USB_USS720 is not set
++
++#
++# USB Serial Converter support
++#
++# CONFIG_USB_SERIAL is not set
++# CONFIG_USB_RIO500 is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++# CONFIG_DEBUG_USER is not set
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_NO_PGT_CACHE is not set
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/anakin_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/anakin_defconfig 2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/anakin_defconfig 2003-09-27 11:38:18.596701256 +0800
+@@ -0,0 +1,632 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++# CONFIG_GENERIC_BUST_SPINLOCK is not set
++# CONFIG_GENERIC_ISA_DMA is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++
++#
++# General setup
++#
++CONFIG_NET=y
++# CONFIG_SYSVIPC is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_SYSCTL is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ADIFCC is not set
++CONFIG_ARCH_ANAKIN=y
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_IOP310 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_H3100 is not set
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_H3800 is not set
++# CONFIG_SA1100_H3XXX is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_BADGE4 is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_PT_SYSTEM3 is not set
++# CONFIG_SA1100_SHANNON is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++# CONFIG_SA1100_STORK is not set
++# CONFIG_SA1100_USB is not set
++# CONFIG_SA1100_USB_NETLINK is not set
++# CONFIG_SA1100_USB_CHAR is not set
++# CONFIG_H3600_SLEEVE is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_AUTCPU12 is not set
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_FORTUNET is not set
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_32v5 is not set
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM922T is not set
++# CONFIG_CPU_ARM926T is not set
++# CONFIG_CPU_ARM1020 is not set
++CONFIG_CPU_SA110=y
++# CONFIG_CPU_SA1100 is not set
++# CONFIG_CPU_XSCALE is not set
++# CONFIG_XSCALE_PMU is not set
++
++#
++# Processor Features
++#
++
++#
++# General setup
++#
++# CONFIG_DISCONTIGMEM is not set
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++# CONFIG_FIQ is not set
++# CONFIG_ZBOOT_ROM is not set
++CONFIG_ZBOOT_ROM_TEXT=0
++CONFIG_ZBOOT_ROM_BSS=0
++# CONFIG_HOTPLUG is not set
++# CONFIG_PCMCIA is not set
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_PREEMPT is not set
++# CONFIG_APM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="root=/dev/ram initrd=0xc0800000,4M"
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++# CONFIG_MTD is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++# CONFIG_PNPBIOS 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_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_UMEM is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=8192
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# 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 is not set
++# 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 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
++# 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 device support
++#
++# CONFIG_NETDEVICES is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++CONFIG_IRDA=y
++
++#
++# IrDA protocols
++#
++# CONFIG_IRLAN is not set
++# CONFIG_IRCOMM is not set
++# CONFIG_IRDA_ULTRA is not set
++
++#
++# IrDA options
++#
++# CONFIG_IRDA_CACHE_LAST_LSAP is not set
++# CONFIG_IRDA_FAST_RR is not set
++# CONFIG_IRDA_DEBUG is not set
++
++#
++# Infrared-port device drivers
++#
++
++#
++# SIR device drivers
++#
++CONFIG_IRTTY_SIR=y
++# 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_FIR is not set
++# CONFIG_SMC_IRCC_FIR is not set
++# CONFIG_ALI_FIR is not set
++# CONFIG_VLSI_FIR is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++# CONFIG_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O 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
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN_BOOL is not set
++
++#
++# Input device 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_GAMEPORT is not set
++CONFIG_SOUND_GAMEPORT=y
++# CONFIG_GAMEPORT_NS558 is not set
++# CONFIG_GAMEPORT_L4 is not set
++# CONFIG_INPUT_EMU10K1 is not set
++# CONFIG_GAMEPORT_PCIGAME is not set
++# CONFIG_GAMEPORT_FM801 is not set
++# CONFIG_GAMEPORT_CS461x is not set
++# CONFIG_SERIO is not set
++# CONFIG_SERIO_SERPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++# CONFIG_SERIAL_8250_CONSOLE is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_MULTIPORT is not set
++# CONFIG_SERIAL_8250_RSA is not set
++
++#
++# Non-8250 serial port support
++#
++
++#
++# ARM Serial drivers
++#
++# CONFIG_ATOMWIDE_SERIAL is not set
++# CONFIG_DUALSP_SERIAL is not set
++CONFIG_SERIAL_ANAKIN=y
++CONFIG_SERIAL_ANAKIN_CONSOLE=y
++CONFIG_ANAKIN_DEFAULT_BAUDRATE=115200
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_UART00 is not set
++# CONFIG_SERIAL_UART00_CONSOLE is not set
++# CONFIG_SERIAL_SA1100 is not set
++# CONFIG_SERIAL_SA1100_CONSOLE is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_TOUCHSCREEN_ANAKIN=y
++# CONFIG_UNIX98_PTYS is not set
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++# CONFIG_L3_ALGOBIT is not set
++# CONFIG_L3_BIT_SA1100_GPIO is not set
++
++#
++# Other L3 adapters
++#
++# CONFIG_L3_SA1111 is not set
++# CONFIG_BIT_SA1100_GPIO is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG 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
++# CONFIG_DRM is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_QFMT_V1 is not set
++# CONFIG_QFMT_V2 is not set
++# CONFIG_QIFACE_COMPAT 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_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 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 is not set
++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_DEBUG 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 is not set
++# 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
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
++# CONFIG_NFS_FS is not set
++# CONFIG_NFS_V3 is not set
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++# CONFIG_NFSD_TCP is not set
++# CONFIG_SUNRPC is not set
++# CONFIG_LOCKD is not set
++# CONFIG_EXPORTFS is not set
++# 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_SMB_NLS is not set
++# CONFIG_NLS is not set
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++CONFIG_FB_ANAKIN=y
++# CONFIG_FB_CLPS711X is not set
++# CONFIG_FB_SA1100 is not set
++# CONFIG_FB_CYBER2000 is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FBCON_ADVANCED is not set
++CONFIG_FBCON_CFB16=y
++# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
++# CONFIG_FBCON_FONTS is not set
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++
++#
++# Multimedia Capabilities Port drivers
++#
++# CONFIG_MCP is not set
++# CONFIG_MCP_SA1100 is not set
++# CONFIG_MCP_UCB1200 is not set
++# CONFIG_MCP_UCB1200_AUDIO is not set
++# CONFIG_MCP_UCB1200_TS is not set
++
++#
++# Console Switches
++#
++# CONFIG_SWITCHES is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_DEBUG_SLAB is not set
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_WAITQ is not set
++# CONFIG_DEBUG_BUGVERBOSE is not set
++# CONFIG_DEBUG_ERRORS is not set
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
++
++#
++# Library routines
++#
++# CONFIG_CRC32 is not set
++# CONFIG_ZLIB_INFLATE is not set
++# CONFIG_ZLIB_DEFLATE is not set
+Index: linux-2.6.0-test5/arch/arm/configs/assabet_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/assabet_defconfig 2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/assabet_defconfig 2003-09-27 11:38:18.598700952 +0800
+@@ -0,0 +1,966 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++# CONFIG_GENERIC_BUST_SPINLOCK is not set
++# CONFIG_GENERIC_ISA_DMA is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++CONFIG_SA1100_ASSABET=y
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++CONFIG_SA1100_USB=m
++CONFIG_SA1100_USB_NETLINK=m
++# CONFIG_SA1100_USB_CHAR is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++# CONFIG_ARM_THUMB is not set
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++CONFIG_ISA=y
++# CONFIG_ISA_DMA is not set
++CONFIG_CPU_FREQ=y
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=y
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=y
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++CONFIG_PM=y
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="mem=32M console=ttySA0,38400n8 initrd=0xc0800000,3M root=/dev/ram"
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=y
++CONFIG_MTD_REDBOOT_PARTS=y
++# CONFIG_MTD_BOOTLDR_PARTS is not set
++# CONFIG_MTD_AFS_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=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++CONFIG_MTD_CFI_GEOMETRY=y
++# CONFIG_MTD_CFI_B1 is not set
++# CONFIG_MTD_CFI_B2 is not set
++CONFIG_MTD_CFI_B4=y
++# CONFIG_MTD_CFI_I1 is not set
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD 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_NORA is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_CDB89712 is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++# CONFIG_MTD_PCI 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
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++# CONFIG_PNPBIOS 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_BLK_DEV_DAC960 is not set
++CONFIG_BLK_DEV_LOOP=m
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# 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 is not set
++# CONFIG_NETLINK 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 is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE 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
++# CONFIG_ATM is not set
++
++#
++#
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK 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 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
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# CONFIG_ARM_AM79C961A is not set
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNBMAC is not set
++# CONFIG_SUNQE is not set
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNGEM is not set
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_LANCE is not set
++# CONFIG_NET_VENDOR_SMC is not set
++# CONFIG_NET_VENDOR_RACAL is not set
++# CONFIG_AT1700 is not set
++# CONFIG_DEPCA 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_MYRI_SBUS is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN 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
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=y
++# CONFIG_PCMCIA_NMCLAN is not set
++# CONFIG_PCMCIA_SMC91C92 is not set
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++CONFIG_IRDA=m
++
++#
++# IrDA protocols
++#
++CONFIG_IRLAN=m
++# CONFIG_IRNET is not set
++# CONFIG_IRCOMM is not set
++# CONFIG_IRDA_ULTRA is not set
++# CONFIG_IRDA_OPTIONS 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_FIR is not set
++# CONFIG_SMC_IRCC_FIR is not set
++# CONFIG_ALI_FIR is not set
++# CONFIG_VLSI_FIR is not set
++CONFIG_SA1100_FIR=m
++
++#
++# 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_IDEDISK=y
++# CONFIG_IDEDISK_MULTI_MODE is not set
++CONFIG_BLK_DEV_IDECS=y
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++
++#
++# 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_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++# CONFIG_BLK_DEV_ATARAID is not set
++# CONFIG_BLK_DEV_ATARAID_PDC is not set
++# CONFIG_BLK_DEV_ATARAID_HPT is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O 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
++
++#
++# 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
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_ANAKIN is not set
++# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_UART00 is not set
++# CONFIG_SERIAL_UART00_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=38400
++CONFIG_SERIAL_8250=m
++# CONFIG_SERIAL_8250_CONSOLE is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_MULTIPORT is not set
++# CONFIG_SERIAL_8250_HUB6 is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# L3 serial bus support
++#
++CONFIG_L3=y
++CONFIG_L3_ALGOBIT=y
++CONFIG_L3_BIT_SA1100_GPIO=y
++
++#
++# Other L3 adapters
++#
++# CONFIG_L3_SA1111 is not set
++CONFIG_BIT_SA1100_GPIO=y
++
++#
++# 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
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++CONFIG_SA1100_RTC=y
++# 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
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++CONFIG_PCMCIA_SERIAL_CS=m
++# CONFIG_MWAVE is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA 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_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_BFS_FS is not set
++# CONFIG_CMS_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 is not set
++# 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 is not set
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_ZISOFS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_FREEVXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=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_ZLIB_FS_INFLATE is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_SMB_NLS is not set
++CONFIG_NLS=y
++
++#
++# Native Language Support
++#
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=y
++# 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_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
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_ANAKIN is not set
++# CONFIG_FB_CLPS711X is not set
++CONFIG_FB_SA1100=y
++# CONFIG_FB_CYBER2000 is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FBCON_ADVANCED is not set
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++CONFIG_FBCON_FONTWIDTH8_ONLY=y
++CONFIG_FBCON_FONTS=y
++CONFIG_FONT_8x8=y
++# CONFIG_FONT_8x16 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++
++#
++# Sound
++#
++CONFIG_SOUND=y
++# 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_ICH is not set
++# CONFIG_SOUND_RME96XX is not set
++# CONFIG_SOUND_SONICVIBES 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_SA1100=y
++CONFIG_SOUND_UDA1341=y
++CONFIG_SOUND_ASSABET_UDA1341=y
++# CONFIG_SOUND_H3600_UDA1341 is not set
++# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
++# CONFIG_SOUND_SA1111_UDA1341 is not set
++# CONFIG_SOUND_SA1100SSP is not set
++# CONFIG_SOUND_OSS is not set
++# CONFIG_SOUND_WAVEARTIST is not set
++# CONFIG_SOUND_TVMIXER is not set
++
++#
++# Multimedia Capabilities Port drivers
++#
++CONFIG_MCP=y
++CONFIG_MCP_SA1100=y
++CONFIG_MCP_UCB1200=y
++CONFIG_MCP_UCB1200_AUDIO=m
++CONFIG_MCP_UCB1200_TS=y
++
++#
++# Console Switches
++#
++CONFIG_SWITCHES=y
++CONFIG_SWITCHES_SA1100=y
++CONFIG_SWITCHES_UCB1X00=y
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# USB Controllers
++#
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++# CONFIG_USB_OHCI is not set
++# CONFIG_USB_OHCI_SA1111 is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++# 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_JUMPSHOT is not set
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# USB Human Interface Devices (HID)
++#
++
++#
++# Input core support is needed for USB HID
++#
++
++#
++# 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_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
++# CONFIG_USB_SERIAL_GENERIC is not set
++# CONFIG_USB_SERIAL_BELKIN is not set
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
++# CONFIG_USB_SERIAL_EMPEG is not set
++# CONFIG_USB_SERIAL_FTDI_SIO is not set
++# CONFIG_USB_SERIAL_VISOR is not set
++# CONFIG_USB_SERIAL_IR is not set
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
++# CONFIG_USB_SERIAL_MCT_U232 is not set
++# CONFIG_USB_SERIAL_PL2303 is not set
++# CONFIG_USB_SERIAL_CYBERJACK is not set
++# CONFIG_USB_SERIAL_XIRCOM is not set
++# CONFIG_USB_SERIAL_OMNINET is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_ID75 is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_DEBUG_SLAB is not set
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_NO_PGT_CACHE is not set
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/badge4_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/badge4_defconfig 2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/badge4_defconfig 2003-09-27 11:38:18.601700496 +0800
+@@ -0,0 +1,1162 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++# CONFIG_GENERIC_BUST_SPINLOCK is not set
++# CONFIG_GENERIC_ISA_DMA is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++
++#
++# General setup
++#
++CONFIG_NET=y
++# CONFIG_SYSVIPC is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++CONFIG_MODVERSIONS=y
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_ADIFCC is not set
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_IOP310 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_H3100 is not set
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_H3800 is not set
++# CONFIG_SA1100_H3XXX is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++CONFIG_SA1100_BADGE4=y
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_PT_SYSTEM3 is not set
++# CONFIG_SA1100_SHANNON is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++# CONFIG_SA1100_STORK is not set
++CONFIG_SA1111=y
++CONFIG_FORCE_MAX_ZONEORDER=9
++# CONFIG_SA1100_USB is not set
++# CONFIG_SA1100_USB_NETLINK is not set
++# CONFIG_SA1100_USB_CHAR is not set
++# CONFIG_H3600_SLEEVE is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_AUTCPU12 is not set
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_FORTUNET is not set
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM922T is not set
++# CONFIG_CPU_ARM926T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++# CONFIG_XSCALE_PMU is not set
++# CONFIG_ARM_THUMB is not set
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++CONFIG_ISA=y
++# CONFIG_ISA_DMA is not set
++# CONFIG_FIQ is not set
++CONFIG_CPU_FREQ=y
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=y
++CONFIG_PCMCIA_PROBE=y
++# CONFIG_I82092 is not set
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=y
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++CONFIG_FPE_FASTFPE=m
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=m
++CONFIG_BINFMT_ELF=y
++CONFIG_BINFMT_MISC=m
++# CONFIG_PM is not set
++# CONFIG_PREEMPT is not set
++# CONFIG_APM is not set
++CONFIG_ARTHUR=m
++CONFIG_CMDLINE="init=/linuxrc root=/dev/mtdblock3"
++# CONFIG_LEDS is not set
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++CONFIG_PARPORT=m
++# CONFIG_PARPORT_PC is not set
++# CONFIG_PARPORT_ARC is not set
++# CONFIG_PARPORT_AMIGA is not set
++# CONFIG_PARPORT_MFC3 is not set
++# CONFIG_PARPORT_ATARI is not set
++# CONFIG_PARPORT_GSC is not set
++# CONFIG_PARPORT_SUNBPP is not set
++# CONFIG_PARPORT_OTHER is not set
++# CONFIG_PARPORT_1284 is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++CONFIG_MTD_DEBUG=y
++CONFIG_MTD_DEBUG_VERBOSE=0
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_BOOTLDR_PARTS is not set
++# CONFIG_MTD_AFS_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=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++CONFIG_MTD_CFI_GEOMETRY=y
++# CONFIG_MTD_CFI_B1 is not set
++CONFIG_MTD_CFI_B2=y
++# CONFIG_MTD_CFI_B4 is not set
++CONFIG_MTD_CFI_I1=y
++# CONFIG_MTD_CFI_I2 is not set
++# CONFIG_MTD_CFI_I4 is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++CONFIG_MTD_RAM=y
++# 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_NORA is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_CDB89712 is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_2PARTS_IPAQ is not set
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++# CONFIG_MTD_EPXA10DB is not set
++# CONFIG_MTD_PCI 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
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++# CONFIG_PNPBIOS 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_BLK_DEV_DAC960 is not set
++CONFIG_BLK_DEV_LOOP=y
++CONFIG_BLK_DEV_NBD=m
++# CONFIG_BLK_DEV_RAM is not set
++# CONFIG_BLK_DEV_INITRD 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 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 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
++# CONFIG_ATM is not set
++# CONFIG_VLAN_8021Q is not set
++
++#
++#
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK 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 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 is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K 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_SK98LIN 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=y
++# CONFIG_STRIP 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
++
++#
++# Wireless ISA/PCI cards support
++#
++# CONFIG_WAVELAN is not set
++# CONFIG_AIRO is not set
++CONFIG_HERMES=y
++
++#
++# Wireless Pcmcia/Cardbus cards support
++#
++CONFIG_PCMCIA_NETWAVE=m
++CONFIG_PCMCIA_WAVELAN=m
++CONFIG_PCMCIA_HERMES=y
++CONFIG_AIRO_CS=m
++CONFIG_NET_WIRELESS=y
++
++#
++# 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=y
++CONFIG_PCMCIA_3C589=y
++CONFIG_PCMCIA_3C574=m
++CONFIG_PCMCIA_FMVJ18X=m
++CONFIG_PCMCIA_PCNET=y
++CONFIG_PCMCIA_NMCLAN=m
++CONFIG_PCMCIA_SMC91C92=m
++CONFIG_PCMCIA_XIRC2PS=m
++CONFIG_PCMCIA_AXNET=m
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++CONFIG_NET_PCMCIA_RADIO=y
++CONFIG_PCMCIA_RAYCS=m
++# CONFIG_AIRONET4500_CS is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++CONFIG_IRDA=y
++
++#
++# IrDA protocols
++#
++CONFIG_IRLAN=y
++# CONFIG_IRNET is not set
++CONFIG_IRCOMM=y
++CONFIG_IRDA_ULTRA=y
++
++#
++# IrDA options
++#
++# CONFIG_IRDA_CACHE_LAST_LSAP is not set
++# CONFIG_IRDA_FAST_RR is not set
++# 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_FIR is not set
++# CONFIG_SMC_IRCC_FIR is not set
++# CONFIG_ALI_FIR is not set
++# CONFIG_VLSI_FIR is not set
++CONFIG_SA1100_FIR=y
++
++#
++# ATA/IDE/MFM/RLL support
++#
++CONFIG_IDE=m
++
++#
++# IDE, ATA and ATAPI Block devices
++#
++CONFIG_BLK_DEV_IDE=m
++
++#
++# 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_IDEDISK=m
++# CONFIG_IDEDISK_MULTI_MODE is not set
++# CONFIG_IDEDISK_STROKE is not set
++# CONFIG_BLK_DEV_IDECS is not set
++CONFIG_BLK_DEV_IDECD=m
++# CONFIG_BLK_DEV_IDETAPE is not set
++CONFIG_BLK_DEV_IDEFLOPPY=m
++CONFIG_BLK_DEV_IDESCSI=m
++
++#
++# 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_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++# CONFIG_BLK_DEV_ATARAID is not set
++# CONFIG_BLK_DEV_ATARAID_PDC is not set
++# CONFIG_BLK_DEV_ATARAID_HPT 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=m
++# CONFIG_CHR_DEV_OSST is not set
++CONFIG_BLK_DEV_SR=m
++# 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_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++
++#
++# SCSI low-level drivers
++#
++# 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_AIC7XXX 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_BUSLOGIC 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_PPA is not set
++# CONFIG_SCSI_IMM is not set
++# CONFIG_SCSI_NCR53C406A is not set
++# CONFIG_SCSI_NCR53C7xx 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_SIM710 is not set
++# CONFIG_SCSI_SYM53C416 is not set
++# CONFIG_SCSI_T128 is not set
++# CONFIG_SCSI_U14_34F is not set
++# CONFIG_SCSI_DEBUG is not set
++
++#
++# PCMCIA SCSI adapter support
++#
++# CONFIG_SCSI_PCMCIA is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O 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
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input device 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_GAMEPORT is not set
++CONFIG_SOUND_GAMEPORT=y
++# CONFIG_GAMEPORT_NS558 is not set
++# CONFIG_GAMEPORT_L4 is not set
++# CONFIG_INPUT_EMU10K1 is not set
++# CONFIG_GAMEPORT_PCIGAME is not set
++# CONFIG_GAMEPORT_FM801 is not set
++# CONFIG_GAMEPORT_CS461x is not set
++# CONFIG_SERIO is not set
++# CONFIG_SERIO_SERPORT is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_ANAKIN is not set
++# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_UART00 is not set
++# CONFIG_SERIAL_UART00_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=115200
++# CONFIG_SERIAL_8250 is not set
++# CONFIG_SERIAL_8250_CONSOLE is not set
++# CONFIG_ATOMWIDE_SERIAL is not set
++# CONFIG_DUALSP_SERIAL is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_MULTIPORT is not set
++# CONFIG_SERIAL_8250_RSA is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++# CONFIG_PRINTER is not set
++# CONFIG_PPDEV is not set
++
++#
++# I2C support
++#
++CONFIG_I2C=m
++CONFIG_I2C_ALGOBIT=m
++# CONFIG_I2C_PHILIPSPAR is not set
++CONFIG_I2C_ELV=m
++CONFIG_I2C_VELLEMAN=m
++# CONFIG_I2C_BIT_SA1100_GPIO is not set
++CONFIG_I2C_ALGOPCF=m
++CONFIG_I2C_ELEKTOR=m
++CONFIG_I2C_CHARDEV=m
++CONFIG_I2C_PROC=m
++
++#
++# L3 serial bus support
++#
++CONFIG_L3=y
++# CONFIG_L3_ALGOBIT is not set
++# CONFIG_L3_BIT_SA1100_GPIO is not set
++
++#
++# Other L3 adapters
++#
++CONFIG_L3_SA1111=y
++# CONFIG_BIT_SA1100_GPIO is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++CONFIG_WATCHDOG=y
++# CONFIG_WATCHDOG_NOWAYOUT is not set
++CONFIG_SOFT_WATCHDOG=m
++# CONFIG_WDT is not set
++# CONFIG_WDTPCI is not set
++# CONFIG_PCWATCHDOG is not set
++# CONFIG_ACQUIRE_WDT is not set
++# CONFIG_ADVANTECH_WDT is not set
++# CONFIG_21285_WATCHDOG is not set
++# CONFIG_977_WATCHDOG is not set
++CONFIG_SA1100_WATCHDOG=m
++# CONFIG_EUROTECH_WDT is not set
++# CONFIG_IB700_WDT is not set
++# CONFIG_I810_TCO is not set
++# CONFIG_MIXCOMWD is not set
++# CONFIG_60XX_WDT is not set
++# CONFIG_W83877F_WDT is not set
++# CONFIG_MACHZ_WDT is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++CONFIG_RTC=m
++CONFIG_SA1100_RTC=m
++# 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
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++
++#
++# Multimedia devices
++#
++CONFIG_VIDEO_DEV=y
++
++#
++# Video For Linux
++#
++CONFIG_VIDEO_PROC_FS=y
++# CONFIG_I2C_PARPORT is not set
++
++#
++# Video Adapters
++#
++# CONFIG_VIDEO_BT848 is not set
++# CONFIG_VIDEO_PMS is not set
++# CONFIG_VIDEO_BWQCAM is not set
++# CONFIG_VIDEO_CQCAM is not set
++# CONFIG_VIDEO_CPIA is not set
++# CONFIG_VIDEO_SAA5249 is not set
++# CONFIG_TUNER_3036 is not set
++# CONFIG_VIDEO_STRADIS is not set
++# CONFIG_VIDEO_ZORAN is not set
++# CONFIG_VIDEO_ZORAN_BUZ is not set
++# CONFIG_VIDEO_ZORAN_DC10 is not set
++# CONFIG_VIDEO_ZORAN_LML33 is not set
++# CONFIG_VIDEO_ZR36120 is not set
++# CONFIG_VIDEO_MEYE is not set
++# CONFIG_VIDEO_CYBERPRO is not set
++
++#
++# Radio Adapters
++#
++# CONFIG_RADIO_CADET is not set
++# CONFIG_RADIO_RTRACK is not set
++# CONFIG_RADIO_RTRACK2 is not set
++# CONFIG_RADIO_AZTECH is not set
++# CONFIG_RADIO_GEMTEK is not set
++# CONFIG_RADIO_GEMTEK_PCI is not set
++# CONFIG_RADIO_MAXIRADIO is not set
++# CONFIG_RADIO_MAESTRO is not set
++# CONFIG_RADIO_MIROPCM20 is not set
++# CONFIG_RADIO_MIROPCM20_RDS is not set
++# CONFIG_RADIO_SF16FMI is not set
++# CONFIG_RADIO_TERRATEC is not set
++# CONFIG_RADIO_TRUST is not set
++# CONFIG_RADIO_TYPHOON is not set
++# CONFIG_RADIO_ZOLTRIX is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA 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_BFS_FS is not set
++CONFIG_EXT3_FS=m
++CONFIG_JBD=m
++# CONFIG_JBD_DEBUG is not set
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++# CONFIG_UMSDOS_FS is not set
++CONFIG_VFAT_FS=m
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++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_MINIX_FS=m
++# CONFIG_VXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG is not set
++# CONFIG_NTFS_RW is not set
++# CONFIG_HPFS_FS is not set
++CONFIG_PROC_FS=y
++CONFIG_DEVFS_FS=y
++CONFIG_DEVFS_MOUNT=y
++# CONFIG_DEVFS_DEBUG is not set
++# CONFIG_DEVPTS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_QNX4FS_RW is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_EXT2_FS=m
++# 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
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
++CONFIG_NFS_FS=m
++CONFIG_NFS_V3=y
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=m
++CONFIG_LOCKD=m
++CONFIG_LOCKD_V4=y
++CONFIG_SMB_FS=m
++# CONFIG_SMB_NLS_DEFAULT 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=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++CONFIG_SMB_NLS=y
++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_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
++
++#
++# Sound
++#
++CONFIG_SOUND=y
++
++#
++# Open Sound System
++#
++CONFIG_SOUND_PRIME=y
++# 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_ICH is not set
++# CONFIG_SOUND_RME96XX is not set
++# CONFIG_SOUND_SONICVIBES 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_SA1100=y
++CONFIG_SOUND_UDA1341=y
++# CONFIG_SOUND_ASSABET_UDA1341 is not set
++# CONFIG_SOUND_H3600_UDA1341 is not set
++# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
++CONFIG_SOUND_SA1111_UDA1341=y
++# CONFIG_SOUND_STORK_UDA1341 is not set
++# CONFIG_SOUND_SA1100SSP is not set
++# CONFIG_SOUND_STORK_AC97 is not set
++# CONFIG_SOUND_OSS is not set
++# CONFIG_SOUND_WAVEARTIST is not set
++# CONFIG_SOUND_TVMIXER is not set
++
++#
++# Advanced Linux Sound Architecture
++#
++# CONFIG_SND is not set
++
++#
++# Multimedia Capabilities Port drivers
++#
++CONFIG_MCP=y
++CONFIG_MCP_SA1100=y
++# CONFIG_MCP_UCB1200 is not set
++# CONFIG_MCP_UCB1200_AUDIO is not set
++# CONFIG_MCP_UCB1200_TS is not set
++
++#
++# USB support
++#
++CONFIG_USB=y
++CONFIG_USB_DEBUG=y
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++# CONFIG_USB_BANDWIDTH is not set
++# CONFIG_USB_LONG_TIMEOUT is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_EHCI_HCD is not set
++# CONFIG_USB_OHCI_HCD is not set
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++# CONFIG_USB_OHCI is not set
++CONFIG_USB_OHCI_SA1111=y
++
++#
++# USB Device Class drivers
++#
++CONFIG_USB_AUDIO=y
++CONFIG_USB_BLUETOOTH=m
++CONFIG_USB_STORAGE=y
++CONFIG_USB_STORAGE_DEBUG=y
++# 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_JUMPSHOT is not set
++CONFIG_USB_ACM=m
++CONFIG_USB_PRINTER=m
++
++#
++# USB Human Interface Devices (HID)
++#
++
++#
++# Input core support is needed for USB HID
++#
++
++#
++# USB Imaging devices
++#
++CONFIG_USB_DC2XX=m
++CONFIG_USB_MDC800=m
++CONFIG_USB_SCANNER=m
++CONFIG_USB_MICROTEK=m
++CONFIG_USB_HPUSBSCSI=m
++
++#
++# USB Multimedia devices
++#
++CONFIG_USB_IBMCAM=m
++CONFIG_USB_OV511=m
++CONFIG_USB_PWC=m
++CONFIG_USB_SE401=m
++# CONFIG_USB_STV680 is not set
++CONFIG_USB_VICAM=m
++CONFIG_USB_DSBR=m
++CONFIG_USB_DABUSB=m
++CONFIG_USB_KONICAWC=m
++
++#
++# USB Network adaptors
++#
++CONFIG_USB_PEGASUS=m
++CONFIG_USB_KAWETH=m
++CONFIG_USB_CATC=m
++CONFIG_USB_CDCETHER=m
++CONFIG_USB_USBNET=m
++
++#
++# USB port drivers
++#
++CONFIG_USB_USS720=m
++
++#
++# USB Serial Converter support
++#
++CONFIG_USB_SERIAL=m
++CONFIG_USB_SERIAL_GENERIC=y
++CONFIG_USB_SERIAL_BELKIN=m
++CONFIG_USB_SERIAL_WHITEHEAT=m
++CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
++CONFIG_USB_SERIAL_EMPEG=m
++CONFIG_USB_SERIAL_FTDI_SIO=m
++CONFIG_USB_SERIAL_VISOR=m
++# CONFIG_USB_SERIAL_IPAQ is not set
++CONFIG_USB_SERIAL_IR=m
++CONFIG_USB_SERIAL_EDGEPORT=m
++CONFIG_USB_SERIAL_KEYSPAN_PDA=m
++CONFIG_USB_SERIAL_KEYSPAN=m
++# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
++CONFIG_USB_SERIAL_MCT_U232=m
++# CONFIG_USB_SERIAL_KLSI is not set
++CONFIG_USB_SERIAL_PL2303=m
++CONFIG_USB_SERIAL_CYBERJACK=m
++CONFIG_USB_SERIAL_XIRCOM=m
++CONFIG_USB_SERIAL_OMNINET=m
++
++#
++# USB Miscellaneous drivers
++#
++CONFIG_USB_RIO500=m
++# CONFIG_USB_AUERSWALD is not set
++
++#
++# Bluetooth support
++#
++CONFIG_BT=m
++CONFIG_BT_L2CAP=m
++
++#
++# Bluetooth device drivers
++#
++CONFIG_BT_HCIUSB=m
++CONFIG_BT_HCIUART=m
++CONFIG_BT_HCIVHCI=m
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_INFO=y
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SLAB is not set
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_WAITQ is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
++
++#
++# Library routines
++#
++# CONFIG_CRC32 is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
+Index: linux-2.6.0-test5/arch/arm/configs/brutus_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/brutus_defconfig 2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/brutus_defconfig 2003-09-27 11:38:18.601700496 +0800
+@@ -0,0 +1,296 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_SBUS is not set
++CONFIG_UID16=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++CONFIG_SA1100_BRUTUS=y
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_BITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_THINCLIENT is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++CONFIG_ANGELBOOT=y
++# CONFIG_SA1100_FREQUENCY_SCALE is not set
++# CONFIG_SA1100_VOLTAGE_SCALE is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++CONFIG_CPU_32v4=y
++CONFIG_CPU_SA1100=y
++CONFIG_DISCONTIGMEM=y
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++CONFIG_PC_KEYMAP=y
++
++#
++# General setup
++#
++# CONFIG_HOTPLUG is not set
++# CONFIG_PCMCIA is not set
++# CONFIG_NET is not set
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_NWFPE=y
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="mem=4M@0xc0000000 mem=4M@0xc8000000 mem=4M@0xd0000000 mem=4M@0xd8000000 keepinitrd root=/dev/ram ramdisk=8192 initrd=0xd8000000,3M"
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++# CONFIG_MTD 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_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_LVM 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_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++CONFIG_BLK_DEV_INITRD=y
++# CONFIG_BLK_DEV_FLASH is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++# CONFIG_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++# CONFIG_TOUCHSCREEN_UCB1200 is not set
++# CONFIG_TOUCHSCREEN_BITSY is not set
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++
++#
++# Video For Linux
++#
++# CONFIG_VIDEO_DEV 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
++# CONFIG_DRM is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS 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_BFS_FS 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_CRAMFS is not set
++# CONFIG_RAMFS is not set
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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_SYSV_FS_WRITE 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_NCPFS_NLS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_NLS is not set
++
++#
++# Console drivers
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_FB=y
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_CYBER2000 is not set
++CONFIG_FB_SA1100=y
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FBCON_ADVANCED is not set
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++CONFIG_FBCON_FONTWIDTH8_ONLY=y
++CONFIG_FBCON_FONTS=y
++CONFIG_FONT_8x8=y
++# CONFIG_FONT_8x16 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_INFO=y
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_DEBUG_LL is not set
+Index: linux-2.6.0-test5/arch/arm/configs/cerfcube_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/cerfcube_defconfig 2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/cerfcube_defconfig 2003-09-27 11:38:18.603700192 +0800
+@@ -0,0 +1,873 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++CONFIG_SA1100_CERF=y
++# CONFIG_SA1100_CERF_FLASH_8MB is not set
++CONFIG_SA1100_CERF_FLASH_16MB=y
++# CONFIG_SA1100_CERF_FLASH_32MB is not set
++# CONFIG_SA1100_CERF_CPLD is not set
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++CONFIG_SA1100_USB=y
++CONFIG_SA1100_USB_NETLINK=y
++CONFIG_SA1100_USB_CHAR=y
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++# CONFIG_ARM_THUMB is not set
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++CONFIG_CPU_FREQ=y
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=y
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=y
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++CONFIG_BSD_PROCESS_ACCT=y
++CONFIG_SYSCTL=y
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_APM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="console=ttySA0 root=/dev/mtdblock3 rw mem=32M"
++# CONFIG_PFS168_CMDLINE is not set
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_BOOTLDR_PARTS is not set
++# CONFIG_MTD_AFS_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 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
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_SUN_UFLASH is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_PNC2000 is not set
++# CONFIG_MTD_RPXLITE is not set
++# CONFIG_MTD_TQM8XXL is not set
++# CONFIG_MTD_SC520CDP is not set
++# CONFIG_MTD_NETSC520 is not set
++# CONFIG_MTD_SBC_GXX is not set
++# CONFIG_MTD_ELAN_104NC is not set
++# CONFIG_MTD_DBOX2 is not set
++# CONFIG_MTD_CSTM_MIPS_IXX is not set
++# CONFIG_MTD_CFI_FLAGADM is not set
++# CONFIG_MTD_SOLUTIONENGINE is not set
++# CONFIG_MTD_MIXMEM is not set
++# CONFIG_MTD_OCTAGON is not set
++# CONFIG_MTD_VMAX is not set
++# CONFIG_MTD_OCELOT is not set
++# CONFIG_MTD_L440GX is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_CDB89712 is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_LART 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
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++# CONFIG_PNPBIOS 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_BLK_DEV_DAC960 is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# 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_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_NETLINK=y
++CONFIG_RTNETLINK=y
++# CONFIG_NETLINK_DEV is not set
++# CONFIG_NETFILTER is not set
++CONFIG_FILTER=y
++CONFIG_UNIX=y
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++# CONFIG_IP_PNP is not set
++# CONFIG_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
++# CONFIG_ATM is not set
++
++#
++#
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK 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 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_SUNBMAC is not set
++# CONFIG_SUNQE is not set
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNGEM is not set
++CONFIG_NET_VENDOR_3COM=y
++# CONFIG_EL1 is not set
++# CONFIG_EL2 is not set
++# CONFIG_ELPLUS is not set
++# CONFIG_EL16 is not set
++# CONFIG_ELMC is not set
++# CONFIG_ELMC_II is not set
++CONFIG_CERF_CS8900A=y
++# CONFIG_LANCE is not set
++# CONFIG_NET_VENDOR_SMC is not set
++# CONFIG_NET_VENDOR_RACAL 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_MYRI_SBUS is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN 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
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=m
++# CONFIG_PCMCIA_NMCLAN is not set
++# CONFIG_PCMCIA_SMC91C92 is not set
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA 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_IDEDISK=y
++# CONFIG_IDEDISK_MULTI_MODE is not set
++CONFIG_BLK_DEV_IDECS=m
++# 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
++
++#
++# 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_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++# CONFIG_BLK_DEV_ATARAID is not set
++# CONFIG_BLK_DEV_ATARAID_PDC is not set
++# CONFIG_BLK_DEV_ATARAID_HPT is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O 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
++
++#
++# 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
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_ANAKIN is not set
++# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=9600
++# CONFIG_SERIAL_8250 is not set
++# CONFIG_SERIAL_8250_CONSOLE is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_MULTIPORT is not set
++# CONFIG_SERIAL_8250_HUB6 is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++# CONFIG_UCB1200 is not set
++# CONFIG_TOUCHSCREEN_UCB1200 is not set
++# CONFIG_AUDIO_UCB1200 is not set
++# CONFIG_ADC_UCB1200 is not set
++# CONFIG_TOUCHSCREEN_H3600 is not set
++# CONFIG_PROFILER is not set
++# CONFIG_PFS168_SPI is not set
++# CONFIG_PFS168_DTMF is not set
++# CONFIG_PFS168_MISC is not set
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++# CONFIG_L3_ALGOBIT is not set
++# CONFIG_L3_BIT_SA1100_GPIO is not set
++# CONFIG_BIT_SA1100_UCB1200 is not set
++
++#
++# Other L3 adapters
++#
++# CONFIG_L3_SA1111 is not set
++
++#
++# L3 driver support
++#
++# CONFIG_L3_DRV_UDA1341 is not set
++# CONFIG_BIT_SA1100_GPIO 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
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++CONFIG_SA1100_RTC=y
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++# CONFIG_SONYPI is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++CONFIG_AUTOFS_FS=y
++CONFIG_AUTOFS4_FS=y
++# 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_BFS_FS is not set
++# CONFIG_CMS_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=y
++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 is not set
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_FREEVXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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=y
++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
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 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
++
++#
++# 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_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
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++
++#
++# Frame-buffer support
++#
++# CONFIG_FB is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# USB Controllers
++#
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++# CONFIG_USB_OHCI is not set
++# CONFIG_USB_OHCI_SA1111 is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++# 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_JUMPSHOT 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_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# USB Human Interface Devices (HID)
++#
++
++#
++# Input core support is needed for USB HID
++#
++
++#
++# 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
++#
++# CONFIG_USB_DABUSB is not set
++
++#
++# USB Network adaptors
++#
++# CONFIG_USB_PLUSB is not set
++# CONFIG_USB_PEGASUS 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
++# CONFIG_USB_SERIAL_GENERIC is not set
++# CONFIG_USB_SERIAL_BELKIN is not set
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
++# CONFIG_USB_SERIAL_EMPEG is not set
++# CONFIG_USB_SERIAL_FTDI_SIO is not set
++# CONFIG_USB_SERIAL_VISOR is not set
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
++# CONFIG_USB_SERIAL_MCT_U232 is not set
++# CONFIG_USB_SERIAL_PL2303 is not set
++# CONFIG_USB_SERIAL_CYBERJACK is not set
++# CONFIG_USB_SERIAL_OMNINET is not set
++
++#
++# Miscellaneous USB drivers
++#
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_ID75 is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_NO_PGT_CACHE is not set
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/cerfpda_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/cerfpda_defconfig 2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/cerfpda_defconfig 2003-09-27 11:38:18.605699888 +0800
+@@ -0,0 +1,967 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++CONFIG_SA1100_CERF=y
++# CONFIG_SA1100_CERF_FLASH_8MB is not set
++# CONFIG_SA1100_CERF_FLASH_16MB is not set
++CONFIG_SA1100_CERF_FLASH_32MB=y
++CONFIG_SA1100_CERF_CPLD=y
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++CONFIG_SA1100_USB=y
++CONFIG_SA1100_USB_NETLINK=y
++CONFIG_SA1100_USB_CHAR=y
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++# CONFIG_ARM_THUMB is not set
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++CONFIG_CPU_FREQ=y
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=y
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=y
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++CONFIG_BSD_PROCESS_ACCT=y
++CONFIG_SYSCTL=y
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_APM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="console=ttySA0 cpufreq_max=221200 root=/dev/mtdblock3 rw mem=64M"
++# CONFIG_PFS168_CMDLINE is not set
++# CONFIG_LEDS is not set
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_BOOTLDR_PARTS is not set
++# CONFIG_MTD_AFS_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=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++CONFIG_MTD_CFI_GEOMETRY=y
++# CONFIG_MTD_CFI_B1 is not set
++# CONFIG_MTD_CFI_B2 is not set
++CONFIG_MTD_CFI_B4=y
++# CONFIG_MTD_CFI_I1 is not set
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD 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
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_SUN_UFLASH is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_PNC2000 is not set
++# CONFIG_MTD_RPXLITE is not set
++# CONFIG_MTD_TQM8XXL is not set
++# CONFIG_MTD_SC520CDP is not set
++# CONFIG_MTD_NETSC520 is not set
++# CONFIG_MTD_SBC_GXX is not set
++# CONFIG_MTD_ELAN_104NC is not set
++# CONFIG_MTD_DBOX2 is not set
++# CONFIG_MTD_CSTM_MIPS_IXX is not set
++# CONFIG_MTD_CFI_FLAGADM is not set
++# CONFIG_MTD_SOLUTIONENGINE is not set
++# CONFIG_MTD_MIXMEM is not set
++# CONFIG_MTD_OCTAGON is not set
++# CONFIG_MTD_VMAX is not set
++# CONFIG_MTD_OCELOT is not set
++# CONFIG_MTD_L440GX is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_CDB89712 is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_LART 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
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++# CONFIG_PNPBIOS 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_BLK_DEV_DAC960 is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# 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_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++CONFIG_NETLINK=y
++CONFIG_RTNETLINK=y
++# CONFIG_NETLINK_DEV is not set
++# CONFIG_NETFILTER 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 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
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++
++#
++#
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK 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 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_SUNBMAC is not set
++# CONFIG_SUNQE is not set
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNGEM is not set
++CONFIG_NET_VENDOR_3COM=y
++# CONFIG_EL1 is not set
++# CONFIG_EL2 is not set
++# CONFIG_ELPLUS is not set
++# CONFIG_EL16 is not set
++# CONFIG_ELMC is not set
++# CONFIG_ELMC_II is not set
++CONFIG_CERF_CS8900A=y
++# CONFIG_LANCE is not set
++# CONFIG_NET_VENDOR_SMC is not set
++# CONFIG_NET_VENDOR_RACAL 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_MYRI_SBUS is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN 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=y
++CONFIG_STRIP=m
++CONFIG_WAVELAN=m
++CONFIG_ARLAN=m
++CONFIG_AIRONET4500=m
++CONFIG_AIRONET4500_NONCS=m
++# CONFIG_AIRONET4500_PNP is not set
++# CONFIG_AIRONET4500_PCI is not set
++# CONFIG_AIRONET4500_ISA is not set
++# CONFIG_AIRONET4500_I365 is not set
++CONFIG_AIRONET4500_PROC=m
++
++#
++# Wireless Pcmcia cards support
++#
++CONFIG_PCMCIA_HERMES=m
++CONFIG_AIRO_CS=m
++CONFIG_NET_WIRELESS=y
++
++#
++# 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=y
++CONFIG_PCMCIA_3C589=m
++CONFIG_PCMCIA_3C574=m
++CONFIG_PCMCIA_FMVJ18X=m
++CONFIG_PCMCIA_PCNET=m
++CONFIG_PCMCIA_NMCLAN=m
++CONFIG_PCMCIA_SMC91C92=m
++CONFIG_PCMCIA_XIRC2PS=m
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++CONFIG_NET_PCMCIA_RADIO=y
++CONFIG_PCMCIA_RAYCS=m
++CONFIG_PCMCIA_NETWAVE=m
++CONFIG_PCMCIA_WAVELAN=m
++CONFIG_AIRONET4500_CS=m
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA 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_IDEDISK=y
++# CONFIG_IDEDISK_MULTI_MODE is not set
++CONFIG_BLK_DEV_IDECS=m
++# 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
++
++#
++# 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_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++# CONFIG_BLK_DEV_ATARAID is not set
++# CONFIG_BLK_DEV_ATARAID_PDC is not set
++# CONFIG_BLK_DEV_ATARAID_HPT is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O 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
++
++#
++# 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
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_ANAKIN is not set
++# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=38400
++CONFIG_SERIAL_8250=y
++# CONFIG_SERIAL_8250_CONSOLE is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_MULTIPORT is not set
++# CONFIG_SERIAL_8250_HUB6 is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++CONFIG_UCB1200=y
++CONFIG_TOUCHSCREEN_UCB1200=y
++CONFIG_CERF_TS_MANUAL=y
++CONFIG_CERF_TS_MAXX="924"
++CONFIG_CERF_TS_MAXY="920"
++CONFIG_CERF_TS_MINX="57"
++CONFIG_CERF_TS_MINY="52"
++CONFIG_CERF_TS_RESX="240"
++CONFIG_CERF_TS_RESY="320"
++# CONFIG_AUDIO_UCB1200 is not set
++# CONFIG_ADC_UCB1200 is not set
++# CONFIG_TOUCHSCREEN_H3600 is not set
++# CONFIG_PROFILER is not set
++# CONFIG_PFS168_SPI is not set
++# CONFIG_PFS168_DTMF is not set
++# CONFIG_PFS168_MISC is not set
++CONFIG_SA1100_CERF_KEYPAD=y
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++# CONFIG_L3_ALGOBIT is not set
++# CONFIG_L3_BIT_SA1100_GPIO is not set
++# CONFIG_BIT_SA1100_UCB1200 is not set
++
++#
++# Other L3 adapters
++#
++# CONFIG_L3_SA1111 is not set
++
++#
++# L3 driver support
++#
++# CONFIG_L3_DRV_UDA1341 is not set
++# CONFIG_BIT_SA1100_GPIO 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
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++CONFIG_SA1100_RTC=y
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++# CONFIG_SONYPI is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA 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_BFS_FS is not set
++# CONFIG_CMS_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=y
++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 is not set
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_FREEVXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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=y
++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
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 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
++
++#
++# 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_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
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_ANAKIN is not set
++# CONFIG_FB_CLPS711X is not set
++# CONFIG_FB_CYBER2000 is not set
++CONFIG_FB_SA1100=y
++CONFIG_CERF_LCD_38_A=y
++# CONFIG_CERF_LCD_57_A is not set
++# CONFIG_CERF_LCD_72_A is not set
++CONFIG_SA1100_CERF_LCD_BACKLIGHT=y
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FBCON_ADVANCED is not set
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++# 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_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_ICH is not set
++# CONFIG_SOUND_RME96XX is not set
++# CONFIG_SOUND_SONICVIBES 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_ASSABET_UDA1341 is not set
++# CONFIG_SOUND_H3600_UDA1341 is not set
++# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
++# CONFIG_SOUND_SA1111_UDA1341 is not set
++CONFIG_SOUND_CERF_UDA1341=y
++# CONFIG_SOUND_SA1100SSP is not set
++# CONFIG_SOUND_OSS is not set
++# CONFIG_SOUND_WAVEARTIST is not set
++# CONFIG_SOUND_TVMIXER is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# USB Controllers
++#
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++# CONFIG_USB_OHCI is not set
++# CONFIG_USB_OHCI_SA1111 is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++# 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_JUMPSHOT 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_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# USB Human Interface Devices (HID)
++#
++
++#
++# Input core support is needed for USB HID
++#
++
++#
++# 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
++#
++# CONFIG_USB_DABUSB is not set
++
++#
++# USB Network adaptors
++#
++# CONFIG_USB_PLUSB is not set
++# CONFIG_USB_PEGASUS 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
++# CONFIG_USB_SERIAL_GENERIC is not set
++# CONFIG_USB_SERIAL_BELKIN is not set
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
++# CONFIG_USB_SERIAL_EMPEG is not set
++# CONFIG_USB_SERIAL_FTDI_SIO is not set
++# CONFIG_USB_SERIAL_VISOR is not set
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
++# CONFIG_USB_SERIAL_MCT_U232 is not set
++# CONFIG_USB_SERIAL_PL2303 is not set
++# CONFIG_USB_SERIAL_CYBERJACK is not set
++# CONFIG_USB_SERIAL_OMNINET is not set
++
++#
++# Miscellaneous USB drivers
++#
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_ID75 is not set
++
++#
++# Bluetooth support
++#
++CONFIG_BT=y
++CONFIG_BT_L2CAP=y
++
++#
++# Bluetooth device drivers
++#
++# CONFIG_BT_HCIUSB is not set
++CONFIG_BT_HCIUART=y
++# CONFIG_BT_HCIVHCI is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_NO_PGT_CACHE is not set
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/cerfpod_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/cerfpod_defconfig 2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/cerfpod_defconfig 2003-09-27 11:38:18.607699584 +0800
+@@ -0,0 +1,894 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++CONFIG_SA1100_CERF=y
++# CONFIG_SA1100_CERF_FLASH_8MB is not set
++CONFIG_SA1100_CERF_FLASH_16MB=y
++# CONFIG_SA1100_CERF_FLASH_32MB is not set
++# CONFIG_SA1100_CERF_CPLD is not set
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++CONFIG_SA1100_USB=y
++CONFIG_SA1100_USB_NETLINK=y
++CONFIG_SA1100_USB_CHAR=y
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++# CONFIG_ARM_THUMB is not set
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++CONFIG_CPU_FREQ=y
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=y
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=y
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++CONFIG_BSD_PROCESS_ACCT=y
++CONFIG_SYSCTL=y
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_APM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="console=ttySA0 root=/dev/mtdblock3 rw mem=32M"
++# CONFIG_PFS168_CMDLINE is not set
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_BOOTLDR_PARTS is not set
++# CONFIG_MTD_AFS_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 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
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_SUN_UFLASH is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_PNC2000 is not set
++# CONFIG_MTD_RPXLITE is not set
++# CONFIG_MTD_TQM8XXL is not set
++# CONFIG_MTD_SC520CDP is not set
++# CONFIG_MTD_NETSC520 is not set
++# CONFIG_MTD_SBC_GXX is not set
++# CONFIG_MTD_ELAN_104NC is not set
++# CONFIG_MTD_DBOX2 is not set
++# CONFIG_MTD_CSTM_MIPS_IXX is not set
++# CONFIG_MTD_CFI_FLAGADM is not set
++# CONFIG_MTD_SOLUTIONENGINE is not set
++# CONFIG_MTD_MIXMEM is not set
++# CONFIG_MTD_OCTAGON is not set
++# CONFIG_MTD_VMAX is not set
++# CONFIG_MTD_OCELOT is not set
++# CONFIG_MTD_L440GX is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_CDB89712 is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_LART 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
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++# CONFIG_PNPBIOS 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_BLK_DEV_DAC960 is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# 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_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++CONFIG_NETLINK=y
++CONFIG_RTNETLINK=y
++# CONFIG_NETLINK_DEV is not set
++# CONFIG_NETFILTER 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 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
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++
++#
++#
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK 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 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_SUNBMAC is not set
++# CONFIG_SUNQE is not set
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNGEM is not set
++CONFIG_NET_VENDOR_3COM=y
++# CONFIG_EL1 is not set
++# CONFIG_EL2 is not set
++# CONFIG_ELPLUS is not set
++# CONFIG_EL16 is not set
++# CONFIG_ELMC is not set
++# CONFIG_ELMC_II is not set
++CONFIG_CERF_CS8900A=y
++# CONFIG_LANCE is not set
++# CONFIG_NET_VENDOR_SMC is not set
++# CONFIG_NET_VENDOR_RACAL 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_MYRI_SBUS is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN 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
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=y
++# CONFIG_PCMCIA_NMCLAN is not set
++# CONFIG_PCMCIA_SMC91C92 is not set
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA 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_IDEDISK=y
++# CONFIG_IDEDISK_MULTI_MODE is not set
++CONFIG_BLK_DEV_IDECS=m
++# 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
++
++#
++# 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_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++# CONFIG_BLK_DEV_ATARAID is not set
++# CONFIG_BLK_DEV_ATARAID_PDC is not set
++# CONFIG_BLK_DEV_ATARAID_HPT is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O 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
++
++#
++# 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
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_ANAKIN is not set
++# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=38400
++# CONFIG_SERIAL_8250 is not set
++# CONFIG_SERIAL_8250_CONSOLE is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_MULTIPORT is not set
++# CONFIG_SERIAL_8250_HUB6 is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++CONFIG_UCB1200=y
++CONFIG_TOUCHSCREEN_UCB1200=y
++# CONFIG_CERF_TS_MANUAL is not set
++CONFIG_AUDIO_UCB1200=y
++# CONFIG_ADC_UCB1200 is not set
++# CONFIG_TOUCHSCREEN_H3600 is not set
++# CONFIG_PROFILER is not set
++# CONFIG_PFS168_SPI is not set
++# CONFIG_PFS168_DTMF is not set
++# CONFIG_PFS168_MISC is not set
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++# CONFIG_L3_ALGOBIT is not set
++# CONFIG_L3_BIT_SA1100_GPIO is not set
++# CONFIG_BIT_SA1100_UCB1200 is not set
++
++#
++# Other L3 adapters
++#
++# CONFIG_L3_SA1111 is not set
++
++#
++# L3 driver support
++#
++# CONFIG_L3_DRV_UDA1341 is not set
++# CONFIG_BIT_SA1100_GPIO 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
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++CONFIG_SA1100_RTC=y
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++# CONFIG_SONYPI is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA 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_BFS_FS is not set
++# CONFIG_CMS_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=y
++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 is not set
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_FREEVXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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=y
++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
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 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
++
++#
++# 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_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
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_ANAKIN is not set
++# CONFIG_FB_CLPS711X is not set
++# CONFIG_FB_CYBER2000 is not set
++CONFIG_FB_SA1100=y
++# CONFIG_CERF_LCD_38_A is not set
++CONFIG_CERF_LCD_57_A=y
++# CONFIG_CERF_LCD_72_A is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FBCON_ADVANCED is not set
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
++# CONFIG_FBCON_FONTS is not set
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# USB Controllers
++#
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++# CONFIG_USB_OHCI is not set
++# CONFIG_USB_OHCI_SA1111 is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++# 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_JUMPSHOT 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_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# USB Human Interface Devices (HID)
++#
++
++#
++# Input core support is needed for USB HID
++#
++
++#
++# 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
++#
++# CONFIG_USB_DABUSB is not set
++
++#
++# USB Network adaptors
++#
++# CONFIG_USB_PLUSB is not set
++# CONFIG_USB_PEGASUS 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
++# CONFIG_USB_SERIAL_GENERIC is not set
++# CONFIG_USB_SERIAL_BELKIN is not set
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
++# CONFIG_USB_SERIAL_EMPEG is not set
++# CONFIG_USB_SERIAL_FTDI_SIO is not set
++# CONFIG_USB_SERIAL_VISOR is not set
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
++# CONFIG_USB_SERIAL_MCT_U232 is not set
++# CONFIG_USB_SERIAL_PL2303 is not set
++# CONFIG_USB_SERIAL_CYBERJACK is not set
++# CONFIG_USB_SERIAL_OMNINET is not set
++
++#
++# Miscellaneous USB drivers
++#
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_ID75 is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_NO_PGT_CACHE is not set
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/clps7500_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/clps7500_defconfig 2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/clps7500_defconfig 2003-09-27 11:38:18.608699432 +0800
+@@ -0,0 +1,520 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_OBSOLETE=y
++
++#
++# Loadable module support
++#
++# CONFIG_MODULES is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ARCA5K is not set
++CONFIG_ARCH_CLPS7500=y
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_FTVPCI is not set
++# CONFIG_ARCH_TBOX is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_CLPS711X is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Footbridge Implementations
++#
++
++#
++# SA11x0 Implementations
++#
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++CONFIG_CPU_32v3=y
++# CONFIG_CPU_32v4 is not set
++# CONFIG_CPU_ARM610 is not set
++CONFIG_CPU_ARM710=y
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++# CONFIG_CPU_SA1100 is not set
++# CONFIG_DISCONTIGMEM is not set
++
++#
++# General setup
++#
++CONFIG_ANGELBOOT=y
++# CONFIG_PCI is not set
++CONFIG_ISA=y
++# CONFIG_ISA_DMA is not set
++# CONFIG_HOTPLUG is not set
++# CONFIG_PCMCIA is not set
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_SYSCTL is not set
++CONFIG_NWFPE=y
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="mem=16M root=nfs"
++# CONFIG_ALIGNMENT_TRAP is not set
++
++#
++# Parallel port support
++#
++CONFIG_PARPORT=y
++CONFIG_PARPORT_PC=y
++CONFIG_PARPORT_PC_FIFO=y
++# CONFIG_PARPORT_PC_SUPERIO is not set
++# CONFIG_PARPORT_AMIGA is not set
++# CONFIG_PARPORT_MFC3 is not set
++# CONFIG_PARPORT_ATARI is not set
++# CONFIG_PARPORT_SUNBPP is not set
++# CONFIG_PARPORT_OTHER is not set
++CONFIG_PARPORT_1284=y
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG 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
++
++#
++# RAM/ROM Device Drivers
++#
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PMC551_BUGFIX is not set
++# CONFIG_MTD_PMC551_DEBUG is not set
++# CONFIG_MTD_MTDRAM is not set
++
++#
++# Linearly Mapped Flash Device Drivers
++#
++# CONFIG_MTD_CFI is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_JEDEC is not set
++
++#
++# Drivers for chip mappings
++#
++
++#
++# User modules and translation layers for MTD devices
++#
++# CONFIG_MTD_CHAR is not set
++# CONFIG_MTD_BLOCK is not set
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP 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_DEV_LOOP is not set
++CONFIG_BLK_DEV_NBD=y
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++# CONFIG_BLK_DEV_INITRD is not set
++# CONFIG_BLK_DEV_FLD7500 is not set
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++# CONFIG_NETLINK 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_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE 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
++# CONFIG_ATM is not set
++
++#
++#
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++CONFIG_DUMMY=y
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_NET_SB1000 is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# 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_AT1700 is not set
++# CONFIG_DEPCA is not set
++# CONFIG_HP100 is not set
++# CONFIG_NET_ISA is not set
++CONFIG_NET_PCI=y
++# CONFIG_AC3200 is not set
++# CONFIG_APRICOT is not set
++CONFIG_CS89x0=y
++# CONFIG_ZNET is not set
++# CONFIG_NET_POCKET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC_OMIT_TIGON_I is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PLIP is not set
++CONFIG_PPP=y
++# CONFIG_PPP_MULTILINK is not set
++# CONFIG_PPP_ASYNC is not set
++# CONFIG_PPP_SYNC_TTY is not set
++# CONFIG_PPP_DEFLATE is not set
++# CONFIG_PPP_BSDCOMP is not set
++# CONFIG_PPPOE is not set
++CONFIG_SLIP=y
++CONFIG_SLIP_COMPRESSED=y
++# CONFIG_SLIP_SMART is not set
++# CONFIG_SLIP_MODE_SLIP6 is not set
++
++#
++# Wireless LAN (non-hamradio)
++#
++# CONFIG_NET_RADIO is not set
++
++#
++# Token Ring devices
++#
++# CONFIG_TR is not set
++# CONFIG_NET_FC is not set
++# CONFIG_RCPCI is not set
++# CONFIG_SHAPER is not set
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++# CONFIG_ASH is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++# CONFIG_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++# CONFIG_INPUT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_SERIAL=y
++# CONFIG_SERIAL_CONSOLE is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++CONFIG_PRINTER=y
++# CONFIG_LP_CONSOLE is not set
++# CONFIG_PPDEV is not set
++
++#
++# I2C support
++#
++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_I2C_ALGOPCF is not set
++# CONFIG_I2C_CHARDEV is not set
++
++#
++# Mice
++#
++CONFIG_BUSMOUSE=y
++# CONFIG_ATIXL_BUSMOUSE is not set
++# CONFIG_LOGIBUSMOUSE is not set
++# CONFIG_MS_BUSMOUSE is not set
++CONFIG_MOUSE=y
++# CONFIG_PSMOUSE is not set
++# CONFIG_82C710_MOUSE is not set
++# CONFIG_PC110_PAD is not set
++
++#
++# Joysticks
++#
++
++#
++# Game port support
++#
++
++#
++# Gameport joysticks
++#
++
++#
++# Serial port support
++#
++
++#
++# Serial port joysticks
++#
++
++#
++# Parallel port joysticks
++#
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++CONFIG_CLPS7500_FLASH=y
++# 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
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_FAT_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_RAMFS is not set
++# CONFIG_ISO9660_FS is not set
++CONFIG_MINIX_FS=y
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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_DEVPTS_FS=y
++# CONFIG_QNX4FS_FS 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_UFS_FS is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=y
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++# CONFIG_MSDOS_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_SMB_NLS is not set
++# CONFIG_NLS is not set
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYB=y
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_FB=y
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FB_ACORN=y
++# CONFIG_CHRONTEL_7003 is not set
++# CONFIG_FB_VIRTUAL is not set
++CONFIG_FBCON_ADVANCED=y
++CONFIG_FBCON_MFB=y
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++CONFIG_FBCON_CFB24=y
++# CONFIG_FBCON_CFB32 is not set
++# CONFIG_FBCON_AFB is not set
++# CONFIG_FBCON_ILBM is not set
++# CONFIG_FBCON_IPLAN2P2 is not set
++# CONFIG_FBCON_IPLAN2P4 is not set
++# CONFIG_FBCON_IPLAN2P8 is not set
++# CONFIG_FBCON_MAC is not set
++# CONFIG_FBCON_VGA_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 is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_FRAME_POINTER is not set
++# CONFIG_DEBUG_ERRORS is not set
++# CONFIG_DEBUG_USER is not set
++# CONFIG_DEBUG_INFO is not set
++CONFIG_MAGIC_SYSRQ=y
++CONFIG_DEBUG_LL=y
+Index: linux-2.6.0-test5/arch/arm/configs/ebsa110_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/ebsa110_defconfig 2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/ebsa110_defconfig 2003-09-27 11:38:18.609699280 +0800
+@@ -0,0 +1,605 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CO285 is not set
++CONFIG_ARCH_EBSA110=y
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_ANAKIN is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_BITSY is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++CONFIG_CPU_SA110=y
++# CONFIG_CPU_SA1100 is not set
++# CONFIG_DISCONTIGMEM is not set
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++CONFIG_ISA=y
++# CONFIG_ISA_DMA is not set
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=m
++CONFIG_I82365=y
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++# CONFIG_PCMCIA_SA1100 is not set
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++CONFIG_BSD_PROCESS_ACCT=y
++CONFIG_SYSCTL=y
++CONFIG_FPE_NWFPE=y
++CONFIG_FPE_FASTFPE=y
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="root=/dev/nfs rw mem=16M console=ttyS1,38400n8"
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++
++#
++# Parallel port support
++#
++CONFIG_PARPORT=y
++CONFIG_PARPORT_PC=y
++CONFIG_PARPORT_PC_FIFO=y
++# CONFIG_PARPORT_PC_SUPERIO is not set
++# CONFIG_PARPORT_PC_PCMCIA is not set
++# CONFIG_PARPORT_ARC is not set
++# CONFIG_PARPORT_AMIGA is not set
++# CONFIG_PARPORT_MFC3 is not set
++# CONFIG_PARPORT_ATARI is not set
++# CONFIG_PARPORT_SUNBPP is not set
++# CONFIG_PARPORT_OTHER is not set
++CONFIG_PARPORT_1284=y
++
++#
++# 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_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++# CONFIG_BLK_DEV_INITRD 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_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++CONFIG_NETLINK=y
++CONFIG_RTNETLINK=y
++# CONFIG_NETLINK_DEV is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++CONFIG_IP_ADVANCED_ROUTER=y
++CONFIG_RTNETLINK=y
++CONFIG_NETLINK=y
++CONFIG_IP_MULTIPLE_TABLES=y
++CONFIG_IP_ROUTE_FWMARK=y
++CONFIG_IP_ROUTE_NAT=y
++# CONFIG_IP_ROUTE_MULTIPATH is not set
++# CONFIG_IP_ROUTE_TOS is not set
++CONFIG_IP_ROUTE_VERBOSE=y
++# CONFIG_IP_ROUTE_LARGE_TABLES 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=y
++CONFIG_SYN_COOKIES=y
++
++#
++# IP: Netfilter Configuration
++#
++CONFIG_IP_NF_CONNTRACK=y
++CONFIG_IP_NF_FTP=y
++CONFIG_IP_NF_IRC=y
++# CONFIG_IP_NF_QUEUE is not set
++CONFIG_IP_NF_IPTABLES=y
++CONFIG_IP_NF_MATCH_LIMIT=y
++# CONFIG_IP_NF_MATCH_MAC is not set
++CONFIG_IP_NF_MATCH_MARK=y
++CONFIG_IP_NF_MATCH_MULTIPORT=y
++CONFIG_IP_NF_MATCH_TOS=y
++# CONFIG_IP_NF_MATCH_TCPMSS is not set
++CONFIG_IP_NF_MATCH_STATE=y
++CONFIG_IP_NF_MATCH_UNCLEAN=y
++# CONFIG_IP_NF_MATCH_OWNER is not set
++CONFIG_IP_NF_FILTER=y
++CONFIG_IP_NF_TARGET_REJECT=y
++# CONFIG_IP_NF_TARGET_MIRROR is not set
++CONFIG_IP_NF_NAT=y
++CONFIG_IP_NF_NAT_NEEDED=y
++CONFIG_IP_NF_TARGET_MASQUERADE=y
++CONFIG_IP_NF_TARGET_REDIRECT=y
++CONFIG_IP_NF_NAT_IRC=y
++CONFIG_IP_NF_NAT_FTP=y
++CONFIG_IP_NF_MANGLE=y
++CONFIG_IP_NF_TARGET_TOS=y
++CONFIG_IP_NF_TARGET_MARK=y
++CONFIG_IP_NF_TARGET_LOG=y
++# CONFIG_IP_NF_TARGET_TCPMSS is not set
++CONFIG_IPV6=y
++
++#
++# IPv6: Netfilter Configuration
++#
++CONFIG_IP6_NF_IPTABLES=y
++CONFIG_IP6_NF_MATCH_LIMIT=y
++CONFIG_IP6_NF_MATCH_MARK=y
++CONFIG_IP6_NF_FILTER=y
++CONFIG_IP6_NF_MANGLE=y
++CONFIG_IP6_NF_TARGET_MARK=y
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++
++#
++#
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK 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 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
++# CONFIG_NET_SB1000 is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++CONFIG_ARM_AM79C961A=y
++# 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_AT1700 is not set
++# CONFIG_DEPCA 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_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PLIP is not set
++CONFIG_PPP=m
++# CONFIG_PPP_MULTILINK is not set
++# CONFIG_PPP_FILTER is not set
++CONFIG_PPP_ASYNC=m
++# CONFIG_PPP_SYNC_TTY is not set
++CONFIG_PPP_DEFLATE=m
++CONFIG_PPP_BSDCOMP=m
++# CONFIG_PPPOE 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
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=m
++# CONFIG_PCMCIA_NMCLAN is not set
++# CONFIG_PCMCIA_SMC91C92 is not set
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++# CONFIG_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O 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
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++# CONFIG_INPUT is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++CONFIG_SERIAL=y
++CONFIG_SERIAL_CONSOLE=y
++CONFIG_SERIAL_EXTENDED=y
++# CONFIG_SERIAL_MANY_PORTS is not set
++# CONFIG_SERIAL_SHARE_IRQ is not set
++# CONFIG_SERIAL_DETECT_IRQ is not set
++# CONFIG_SERIAL_MULTIPORT is not set
++# CONFIG_HUB6 is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_SA1100 is not set
++# CONFIG_SERIAL_SA1100_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++CONFIG_PRINTER=m
++# CONFIG_LP_CONSOLE is not set
++# CONFIG_PPDEV is not set
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++
++#
++# Input core support is needed for joysticks
++#
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++CONFIG_WATCHDOG=y
++# CONFIG_WATCHDOG_NOWAYOUT is not set
++CONFIG_SOFT_WATCHDOG=y
++# CONFIG_WDT is not set
++# CONFIG_WDTPCI is not set
++# CONFIG_PCWATCHDOG is not set
++# CONFIG_ACQUIRE_WDT is not set
++# CONFIG_ADVANTECH_WDT is not set
++# CONFIG_60XX_WDT is not set
++# CONFIG_MIXCOMWD is not set
++# CONFIG_I810_TCO is not set
++# CONFIG_MACHZ_WDT is not set
++# CONFIG_INTEL_RNG 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
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++# CONFIG_PCMCIA_SERIAL_CS is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++CONFIG_AUTOFS4_FS=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_REISERFS_CHECK 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_BFS_FS 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 is not set
++# CONFIG_RAMFS is not set
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++CONFIG_MINIX_FS=y
++# CONFIG_VXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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 is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_SYSV_FS_WRITE 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
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=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
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++# CONFIG_MSDOS_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_SMB_NLS is not set
++# CONFIG_NLS is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++# CONFIG_DEBUG_USER is not set
++# CONFIG_DEBUG_INFO is not set
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_NO_PGT_CACHE is not set
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/edb7211_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/edb7211_defconfig 2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/edb7211_defconfig 2003-09-27 11:38:18.610699128 +0800
+@@ -0,0 +1,401 @@
++#
++# Automatically generated by make menuconfig: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++# CONFIG_MODULES is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++CONFIG_ARCH_CLPS711X=y
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Footbridge Implementations
++#
++
++#
++# SA11x0 Implementations
++#
++
++#
++# CLPS711X/EP721X Implementations
++#
++CONFIG_ARCH_EDB7211=y
++CONFIG_EP7211_BOOT_MODE=y
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_ACORN is not set
++CONFIG_ARCH_EP7211=y
++# CONFIG_ARCH_EP7212 is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++CONFIG_CPU_ARM720T=y
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++# CONFIG_CPU_SA1100 is not set
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++# CONFIG_ANGELBOOT is not set
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++# CONFIG_HOTPLUG is not set
++# CONFIG_PCMCIA is not set
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_NWFPE=y
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++# CONFIG_MTD 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_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++# CONFIG_NETLINK 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 is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE 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
++# CONFIG_ATM is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK 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 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_NET_SB1000 is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++# CONFIG_NET_ETHERNET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI 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
++
++#
++# ATA/IDE/MFM/RLL support
++#
++# CONFIG_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O 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
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++# CONFIG_INPUT is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++CONFIG_SERIAL_CLPS711X=y
++CONFIG_SERIAL_CLPS711X_CONSOLE=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++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_JOYSTICK is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG 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
++# CONFIG_DRM is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS 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_BFS_FS 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_CRAMFS is not set
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++CONFIG_MINIX_FS=y
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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_SYSV_FS_WRITE 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
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_NFS_FS is not set
++# CONFIG_NFS_V3 is not set
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++# CONFIG_SUNRPC is not set
++# CONFIG_LOCKD is not set
++# 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
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++# CONFIG_MSDOS_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_SMB_NLS is not set
++# CONFIG_NLS is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++CONFIG_MAGIC_SYSRQ=y
++CONFIG_DEBUG_LL=y
+Index: linux-2.6.0-test5/arch/arm/configs/empeg_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/empeg_defconfig 2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/empeg_defconfig 2003-09-27 11:38:18.611698976 +0800
+@@ -0,0 +1,265 @@
++#
++#
++# Example empeg-car kernel configuration file.
++#
++CONFIG_ARM=y
++
++#
++# System and processor type
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_FOOTBRIDGE is not set
++CONFIG_ARCH_SA1100=y
++CONFIG_CPU_SA1100=y
++# CONFIG_SA1100_BRUTUS is not set
++CONFIG_SA1100_EMPEG=y
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_EMPEG_HENRY is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_ISA_DMA is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++# CONFIG_CPU_ARM2 is not set
++# CONFIG_CPU_ARM3 is not set
++# CONFIG_CPU_ARM6 is not set
++# CONFIG_CPU_ARM7 is not set
++CONFIG_CPU_SA110=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_ALIGNMENT_TRAP is not set
++# CONFIG_TEXT_SECTIONS is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++CONFIG_MODVERSIONS=y
++# CONFIG_KMOD is not set
++
++#
++# General setup
++#
++CONFIG_NET=y
++# CONFIG_SYSVIPC is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_SYSCTL is not set
++CONFIG_NWFPE=y
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_ARTHUR is not set
++# CONFIG_PARPORT is not set
++CONFIG_CMDLINE="mem=4M@0xc0000000 mem=4M@0xc8000000 root=/dev/hda1 initrd=0xd00b0000,320K"
++
++#
++# Plug and Play support
++#
++# CONFIG_PNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++CONFIG_BLK_DEV_IDE=y
++# CONFIG_BLK_DEV_HD_IDE is not set
++CONFIG_BLK_DEV_IDEDISK=y
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_MD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_INITRD=y
++# CONFIG_BLK_DEV_XD is not set
++CONFIG_PARIDE_PARPORT=y
++# CONFIG_PARIDE is not set
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_UNIX98_PTYS is not set
++# CONFIG_MOUSE is not set
++# CONFIG_QIC02_TAPE is not set
++# CONFIG_WATCHDOG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++CONFIG_EMPEG_IR=y
++CONFIG_EMPEG_USB=y
++
++#
++# Video For Linux
++#
++CONFIG_VIDEO_DEV=y
++# CONFIG_RADIO_RTRACK is not set
++# CONFIG_RADIO_RTRACK2 is not set
++# CONFIG_RADIO_AZTECH is not set
++# CONFIG_RADIO_CADET is not set
++# CONFIG_RADIO_MIROPCM20 is not set
++# CONFIG_RADIO_GEMTEK is not set
++CONFIG_RADIO_EMPEG=y
++# CONFIG_VIDEO_BT848 is not set
++# CONFIG_VIDEO_PMS is not set
++# CONFIG_VIDEO_SAA5249 is not set
++# CONFIG_RADIO_SF16FMI is not set
++# CONFIG_RADIO_TYPHOON is not set
++# CONFIG_RADIO_ZOLTRIX is not set
++
++#
++# Joystick support
++#
++# CONFIG_JOYSTICK is not set
++# CONFIG_DTLK is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++# CONFIG_NETLINK is not set
++# CONFIG_FIREWALL is not set
++# CONFIG_FILTER is not set
++# CONFIG_UNIX is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++# CONFIG_IP_PNP is not set
++# CONFIG_IP_ROUTER is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_ALIAS is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_RARP is not set
++# CONFIG_SKB_LARGE is not set
++# CONFIG_IPV6 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_LLC is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_NET_FASTROUTE is not set
++# CONFIG_NET_HW_FLOWCONTROL is not set
++# CONFIG_CPU_IS_SLOW is not set
++
++#
++# QoS and/or fair queueing
++#
++# CONFIG_NET_SCHED is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA subsystem support
++#
++# CONFIG_IRDA is not set
++
++#
++# Network device support
++#
++CONFIG_NETDEVICES=y
++# CONFIG_ARCNET is not set
++# CONFIG_DUMMY is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_NET_ETHERNET is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_DLCI is not set
++CONFIG_PPP=y
++# CONFIG_SLIP is not set
++# CONFIG_NET_RADIO is not set
++# CONFIG_TR is not set
++# CONFIG_SHAPER is not set
++# CONFIG_HOSTESS_SV11 is not set
++# CONFIG_COSA is not set
++# CONFIG_RCPCI is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# Filesystems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS 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_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_HPFS_FS is not set
++CONFIG_PROC_FS=y
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_NFS_FS is not set
++# CONFIG_NFSD is not set
++# CONFIG_SUNRPC is not set
++# CONFIG_LOCKD is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_NLS is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_USER_BACKTRACE=y
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_DEBUG_LL is not set
+Index: linux-2.6.0-test5/arch/arm/configs/epxa10db_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/epxa10db_defconfig 2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/epxa10db_defconfig 2003-09-27 11:38:18.612698824 +0800
+@@ -0,0 +1,566 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++CONFIG_MMU=y
++CONFIG_SWAP=y
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++
++#
++# General setup
++#
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_LOG_BUF_SHIFT=14
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODULE_UNLOAD is not set
++CONFIG_OBSOLETE_MODPARM=y
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ADIFCC is not set
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_EBSA110 is not set
++CONFIG_ARCH_CAMELOT=y
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_IOP310 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++
++#
++# CLPS711X/EP721X Implementations
++#
++
++#
++# Epxa10db
++#
++
++#
++# PLD hotswap support
++#
++CONFIG_PLD=y
++# CONFIG_PLD_HOTSWAP is not set
++
++#
++# Footbridge Implementations
++#
++
++#
++# IOP310 Implementation Options
++#
++
++#
++# IOP310 Chipset Features
++#
++
++#
++# Intel PXA250/210 Implementations
++#
++
++#
++# SA11x0 Implementations
++#
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_ARM922T=y
++CONFIG_CPU_32v4=y
++
++#
++# Processor Features
++#
++# CONFIG_ARM_THUMB is not set
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
++
++#
++# General setup
++#
++# CONFIG_ZBOOT_ROM is not set
++CONFIG_ZBOOT_ROM_TEXT=0
++CONFIG_ZBOOT_ROM_BSS=0
++# CONFIG_HOTPLUG is not set
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_PREEMPT is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="mem=32M console=ttyUA0,38400 root=/dev/mtdblock0 rw"
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++CONFIG_MTD_DEBUG=y
++CONFIG_MTD_DEBUG_VERBOSE=0
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_CONCAT is not set
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_CMDLINE_PARTS is not set
++# CONFIG_MTD_AFS_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 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
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++CONFIG_MTD_EPXA10DB=y
++# CONFIG_MTD_EDB7312 is not set
++# CONFIG_MTD_UCLINUX is not set
++
++#
++# Self-contained MTD device drivers
++#
++# 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
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++
++#
++# Plug and Play support
++#
++# CONFIG_PNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=8192
++# CONFIG_BLK_DEV_INITRD is not set
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++
++#
++# Networking support
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++# CONFIG_NETLINK_DEV is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++# CONFIG_NET_KEY is not set
++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=y
++# 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_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_XFRM_USER is not set
++# CONFIG_IPV6 is not set
++
++#
++# SCTP Configuration (EXPERIMENTAL)
++#
++CONFIG_IPV6_SCTP__=y
++# CONFIG_IP_SCTP is not set
++# CONFIG_ATM is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_LLC is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB 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
++CONFIG_NETDEVICES=y
++# 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_ETHER00=m
++
++#
++# Ethernet (1000 Mbit)
++#
++CONFIG_PPP=y
++CONFIG_PPP_MULTILINK=y
++CONFIG_PPP_ASYNC=y
++CONFIG_PPP_SYNC_TTY=y
++# CONFIG_PPP_DEFLATE is not set
++# CONFIG_PPP_BSDCOMP is not set
++# CONFIG_PPPOE is not set
++# CONFIG_SLIP is not set
++
++#
++# Wireless LAN (non-hamradio)
++#
++# CONFIG_NET_RADIO is not set
++
++#
++# Token Ring devices (depends on LLC=y)
++#
++# CONFIG_SHAPER is not set
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# ATA/ATAPI/MFM/RLL support
++#
++# CONFIG_IDE is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN_BOOL is not set
++
++#
++# Input device support
++#
++# CONFIG_INPUT is not set
++
++#
++# Userland interfaces
++#
++
++#
++# Input I/O drivers
++#
++# CONFIG_GAMEPORT is not set
++CONFIG_SOUND_GAMEPORT=y
++# CONFIG_SERIO is not set
++
++#
++# Input Device Drivers
++#
++
++#
++# Character devices
++#
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_DZ is not set
++CONFIG_SERIAL_UART00=y
++CONFIG_SERIAL_UART00_CONSOLE=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# I2C Hardware Sensors Mainboard support
++#
++
++#
++# I2C Hardware Sensors Chip support
++#
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# IPMI
++#
++# CONFIG_IPMI_HANDLER is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_GEN_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
++# CONFIG_DRM is not set
++# CONFIG_RAW_DRIVER is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_JBD is not set
++# CONFIG_FAT_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++# CONFIG_JFFS2_FS_NAND is not set
++# CONFIG_CRAMFS is not set
++CONFIG_TMPFS=y
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_HPFS_FS is not set
++CONFIG_PROC_FS=y
++# CONFIG_DEVFS_FS is not set
++CONFIG_DEVPTS_FS=y
++# CONFIG_QNX4FS_FS is not set
++CONFIG_ROMFS_FS=y
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_XFS_FS 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 is not set
++# CONFIG_NFS_V4 is not set
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_GSS is not set
++CONFIG_LOCKD=y
++# CONFIG_EXPORTFS is not set
++# CONFIG_CIFS is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++
++#
++# Graphics support
++#
++# CONFIG_FB is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++# CONFIG_MDA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++
++#
++# Misc devices
++#
++
++#
++# Multimedia Capabilities Port drivers
++#
++# CONFIG_MCP is not set
++
++#
++# Console Switches
++#
++# CONFIG_SWITCHES is not set
++
++#
++# USB support
++#
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++# CONFIG_DEBUG_USER is not set
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_DEBUG_KERNEL is not set
++
++#
++# Security options
++#
++# CONFIG_SECURITY is not set
++
++#
++# Cryptographic options
++#
++# CONFIG_CRYPTO is not set
++
++#
++# Library routines
++#
++# CONFIG_CRC32 is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
+Index: linux-2.6.0-test5/arch/arm/configs/flexanet_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/flexanet_defconfig 2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/flexanet_defconfig 2003-09-27 11:38:18.614698520 +0800
+@@ -0,0 +1,900 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++# CONFIG_GENERIC_BUST_SPINLOCK is not set
++# CONFIG_GENERIC_ISA_DMA is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++CONFIG_SA1100_FLEXANET=y
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_SHANNON is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++CONFIG_SA1100_USB=y
++CONFIG_SA1100_USB_NETLINK=y
++# CONFIG_SA1100_USB_CHAR is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_AUTCPU12 is not set
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM922T is not set
++# CONFIG_CPU_ARM926T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++# CONFIG_ARM_THUMB is not set
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++CONFIG_ISA=y
++# CONFIG_ISA_DMA is not set
++CONFIG_CPU_FREQ=y
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=y
++# CONFIG_I82092 is not set
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=y
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++CONFIG_FPE_FASTFPE=y
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++CONFIG_PM=y
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="mem=64M root=/dev/ram initrd=0xc0800000,3M"
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=y
++CONFIG_MTD_REDBOOT_PARTS=y
++# CONFIG_MTD_BOOTLDR_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++# CONFIG_MTD_CHAR is not set
++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=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_GEOMETRY is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD 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_NORA is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_CDB89712 is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++# CONFIG_MTD_PCI 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
++
++#
++# 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_BLK_DEV_DAC960 is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=8192
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# 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 is not set
++# CONFIG_NETLINK 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_INET_ECN is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++# CONFIG_VLAN_8021Q is not set
++
++#
++#
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK 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 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
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# CONFIG_ARM_AM79C961A is not set
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNBMAC is not set
++# CONFIG_SUNQE is not set
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNGEM is not set
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_LANCE is not set
++CONFIG_NET_VENDOR_SMC=y
++# CONFIG_WD80x3 is not set
++# CONFIG_ULTRAMCA is not set
++# CONFIG_ULTRA is not set
++# CONFIG_ULTRA32 is not set
++CONFIG_SMC9194=y
++# CONFIG_NET_VENDOR_RACAL is not set
++# CONFIG_AT1700 is not set
++# CONFIG_DEPCA 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_MYRI_SBUS is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN 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=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=m
++
++#
++# Wireless Pcmcia cards support
++#
++CONFIG_PCMCIA_HERMES=m
++# CONFIG_AIRO_CS is not set
++CONFIG_NET_WIRELESS=y
++
++#
++# 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=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=y
++# CONFIG_PCMCIA_NMCLAN is not set
++# CONFIG_PCMCIA_SMC91C92 is not set
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_PCMCIA_AXNET is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA 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_IDEDISK=y
++# CONFIG_IDEDISK_MULTI_MODE is not set
++CONFIG_BLK_DEV_IDECS=y
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++
++#
++# 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_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++# CONFIG_BLK_DEV_ATARAID is not set
++# CONFIG_BLK_DEV_ATARAID_PDC is not set
++# CONFIG_BLK_DEV_ATARAID_HPT is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O 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
++
++#
++# 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
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_ANAKIN is not set
++# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_UART00 is not set
++# CONFIG_SERIAL_UART00_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=57600
++# CONFIG_SERIAL_8250 is not set
++# CONFIG_SERIAL_8250_CONSOLE is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_MULTIPORT is not set
++# CONFIG_SERIAL_8250_HUB6 is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++# CONFIG_L3_ALGOBIT is not set
++# CONFIG_L3_BIT_SA1100_GPIO is not set
++
++#
++# Other L3 adapters
++#
++# CONFIG_L3_SA1111 is not set
++# CONFIG_BIT_SA1100_GPIO 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
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++CONFIG_SA1100_RTC=y
++# 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
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA 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_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 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=y
++CONFIG_JFFS2_FS_DEBUG=0
++# CONFIG_CRAMFS is not set
++# CONFIG_TMPFS is not set
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_ZISOFS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=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_ZLIB_FS_INFLATE is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_SMB_NLS is not set
++# CONFIG_NLS is not set
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_ANAKIN is not set
++# CONFIG_FB_CLPS711X is not set
++CONFIG_FB_SA1100=y
++# CONFIG_FB_CYBER2000 is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FBCON_ADVANCED is not set
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++# 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_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_ICH is not set
++# CONFIG_SOUND_RME96XX is not set
++# CONFIG_SOUND_SONICVIBES 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_SA1100 is not set
++# CONFIG_SOUND_UDA1341 is not set
++# CONFIG_SOUND_ASSABET_UDA1341 is not set
++# CONFIG_SOUND_H3600_UDA1341 is not set
++# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
++# CONFIG_SOUND_SA1111_UDA1341 is not set
++# CONFIG_SOUND_SA1100SSP is not set
++# CONFIG_SOUND_OSS is not set
++# CONFIG_SOUND_WAVEARTIST is not set
++# CONFIG_SOUND_TVMIXER is not set
++
++#
++# Multimedia Capabilities Port drivers
++#
++# CONFIG_MCP is not set
++# CONFIG_MCP_SA1100 is not set
++# CONFIG_MCP_UCB1200 is not set
++# CONFIG_MCP_UCB1200_AUDIO is not set
++# CONFIG_MCP_UCB1200_TS is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# USB Controllers
++#
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++# CONFIG_USB_OHCI is not set
++# CONFIG_USB_OHCI_SA1111 is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++# 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_JUMPSHOT is not set
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# USB Human Interface Devices (HID)
++#
++
++#
++# Input core support is needed for USB HID
++#
++
++#
++# 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_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
++# CONFIG_USB_SERIAL_GENERIC is not set
++# CONFIG_USB_SERIAL_BELKIN is not set
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
++# CONFIG_USB_SERIAL_EMPEG is not set
++# CONFIG_USB_SERIAL_FTDI_SIO is not set
++# CONFIG_USB_SERIAL_VISOR is not set
++# CONFIG_USB_SERIAL_IR is not set
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
++# CONFIG_USB_SERIAL_MCT_U232 is not set
++# CONFIG_USB_SERIAL_PL2303 is not set
++# CONFIG_USB_SERIAL_CYBERJACK is not set
++# CONFIG_USB_SERIAL_XIRCOM is not set
++# CONFIG_USB_SERIAL_OMNINET is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_RIO500 is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_NO_PGT_CACHE is not set
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_DEBUG_SLAB is not set
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_BUGVERBOSE is not set
++# CONFIG_DEBUG_ERRORS is not set
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/footbridge_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/footbridge_defconfig 2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/footbridge_defconfig 2003-09-27 11:38:18.615698368 +0800
+@@ -0,0 +1,880 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++CONFIG_ARCH_FOOTBRIDGE=y
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_CLPS711X is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++CONFIG_ARCH_EBSA285_HOST=y
++CONFIG_ARCH_NETWINDER=y
++
++#
++# SA11x0 Implementations
++#
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_ACORN is not set
++CONFIG_FOOTBRIDGE=y
++CONFIG_FOOTBRIDGE_HOST=y
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_ARCH_EBSA285=y
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++CONFIG_CPU_32v4=y
++CONFIG_CPU_SA110=y
++# CONFIG_DISCONTIGMEM is not set
++
++#
++# General setup
++#
++# CONFIG_ANGELBOOT is not set
++CONFIG_PCI=y
++CONFIG_ISA=y
++CONFIG_ISA_DMA=y
++CONFIG_PCI_NAMES=y
++# CONFIG_HOTPLUG is not set
++# CONFIG_PCMCIA is not set
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++CONFIG_BSD_PROCESS_ACCT=y
++CONFIG_SYSCTL=y
++CONFIG_NWFPE=y
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++# CONFIG_LEDS_CPU is not set
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++CONFIG_PARPORT=y
++CONFIG_PARPORT_PC=y
++CONFIG_PARPORT_PC_FIFO=y
++# CONFIG_PARPORT_PC_SUPERIO is not set
++# CONFIG_PARPORT_ARC is not set
++# CONFIG_PARPORT_AMIGA is not set
++# CONFIG_PARPORT_MFC3 is not set
++# CONFIG_PARPORT_ATARI is not set
++# CONFIG_PARPORT_SUNBPP is not set
++# CONFIG_PARPORT_OTHER is not set
++CONFIG_PARPORT_1284=y
++
++#
++# Memory Technology Devices (MTD)
++#
++# CONFIG_MTD is not set
++
++#
++# Plug and Play configuration
++#
++CONFIG_PNP=y
++CONFIG_ISAPNP=y
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# CONFIG_BLK_DEV_XD is not set
++CONFIG_PARIDE=m
++CONFIG_PARIDE_PARPORT=y
++
++#
++# Parallel IDE high-level drivers
++#
++CONFIG_PARIDE_PD=m
++CONFIG_PARIDE_PCD=m
++CONFIG_PARIDE_PF=m
++CONFIG_PARIDE_PT=m
++CONFIG_PARIDE_PG=m
++
++#
++# Parallel IDE protocol modules
++#
++CONFIG_PARIDE_ATEN=m
++CONFIG_PARIDE_BPCK=m
++CONFIG_PARIDE_COMM=m
++CONFIG_PARIDE_DSTR=m
++CONFIG_PARIDE_FIT2=m
++CONFIG_PARIDE_FIT3=m
++CONFIG_PARIDE_EPAT=m
++CONFIG_PARIDE_EPIA=m
++CONFIG_PARIDE_FRIQ=m
++CONFIG_PARIDE_FRPW=m
++CONFIG_PARIDE_KBIC=m
++CONFIG_PARIDE_KTTI=m
++CONFIG_PARIDE_ON20=m
++CONFIG_PARIDE_ON26=m
++# CONFIG_BLK_CPQ_DA is not set
++# CONFIG_BLK_CPQ_CISS_DA is not set
++# CONFIG_BLK_DEV_DAC960 is not set
++CONFIG_BLK_DEV_LOOP=m
++CONFIG_BLK_DEV_NBD=m
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++# CONFIG_NETLINK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_PNP=y
++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_INET_ECN is not set
++CONFIG_SYN_COOKIES=y
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++CONFIG_ATM=y
++# CONFIG_ATM_CLIP is not set
++# CONFIG_ATM_LANE is not set
++
++#
++#
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK 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 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_NET_SB1000 is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++CONFIG_NET_VENDOR_3COM=y
++# CONFIG_EL1 is not set
++# CONFIG_EL2 is not set
++# CONFIG_ELPLUS is not set
++# CONFIG_EL16 is not set
++# CONFIG_EL3 is not set
++# CONFIG_3C515 is not set
++# CONFIG_ELMC is not set
++# CONFIG_ELMC_II is not set
++CONFIG_VORTEX=y
++# CONFIG_LANCE is not set
++# CONFIG_NET_VENDOR_SMC is not set
++# CONFIG_NET_VENDOR_RACAL is not set
++# CONFIG_AT1700 is not set
++# CONFIG_DEPCA is not set
++# CONFIG_HP100 is not set
++# CONFIG_NET_ISA is not set
++CONFIG_NET_PCI=y
++# CONFIG_PCNET32 is not set
++# CONFIG_ADAPTEC_STARFIRE is not set
++# CONFIG_AC3200 is not set
++# CONFIG_APRICOT is not set
++# CONFIG_CS89x0 is not set
++CONFIG_TULIP=m
++# CONFIG_DE4X5 is not set
++# CONFIG_DGRS is not set
++# CONFIG_DM9102 is not set
++# CONFIG_EEPRO100 is not set
++# CONFIG_EEPRO100_PM is not set
++# CONFIG_LNE390 is not set
++# CONFIG_NATSEMI is not set
++CONFIG_NE2K_PCI=y
++# CONFIG_NE3210 is not set
++# CONFIG_ES3210 is not set
++# CONFIG_8139TOO is not set
++# CONFIG_RTL8129 is not set
++# CONFIG_SIS900 is not set
++# CONFIG_EPIC100 is not set
++# CONFIG_SUNDANCE is not set
++# CONFIG_TLAN is not set
++# CONFIG_VIA_RHINE is not set
++# CONFIG_WINBOND_840 is not set
++# CONFIG_HAPPYMEAL is not set
++# CONFIG_NET_POCKET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PLIP is not set
++CONFIG_PPP=m
++# CONFIG_PPP_MULTILINK is not set
++CONFIG_PPP_ASYNC=m
++# CONFIG_PPP_SYNC_TTY is not set
++CONFIG_PPP_DEFLATE=m
++CONFIG_PPP_BSDCOMP=m
++CONFIG_PPPOE=m
++CONFIG_SLIP=m
++CONFIG_SLIP_COMPRESSED=y
++CONFIG_SLIP_SMART=y
++CONFIG_SLIP_MODE_SLIP6=y
++
++#
++# 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=m
++
++#
++# IrDA protocols
++#
++CONFIG_IRLAN=m
++CONFIG_IRNET=m
++CONFIG_IRCOMM=m
++CONFIG_IRDA_ULTRA=y
++CONFIG_IRDA_OPTIONS=y
++
++#
++# IrDA options
++#
++CONFIG_IRDA_CACHE_LAST_LSAP=y
++CONFIG_IRDA_FAST_RR=y
++CONFIG_IRDA_DEBUG=y
++
++#
++# Infrared-port device drivers
++#
++
++#
++# SIR device drivers
++#
++# CONFIG_IRTTY_SIR is not set
++# CONFIG_IRPORT_SIR is not set
++
++#
++# FIR device drivers
++#
++# CONFIG_NSC_FIR is not set
++CONFIG_WINBOND_FIR=m
++# CONFIG_TOSHIBA_FIR is not set
++# CONFIG_SMC_IRCC_FIR is not set
++
++#
++# Dongle support
++#
++# CONFIG_DONGLE 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_IDEDISK=y
++CONFIG_IDEDISK_MULTI_MODE=y
++# CONFIG_BLK_DEV_IDECS 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
++
++#
++# 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_RZ1000 is not set
++CONFIG_IDEPCI_SHARE_IRQ=y
++CONFIG_BLK_DEV_IDEDMA_PCI=y
++CONFIG_BLK_DEV_OFFBOARD=y
++CONFIG_IDEDMA_PCI_AUTO=y
++CONFIG_BLK_DEV_IDEDMA=y
++# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
++# CONFIG_BLK_DEV_AEC62XX is not set
++# CONFIG_AEC62XX_TUNING is not set
++# CONFIG_BLK_DEV_ALI15X3 is not set
++# CONFIG_WDC_ALI15X3 is not set
++# CONFIG_BLK_DEV_AMD7409 is not set
++# CONFIG_AMD7409_OVERRIDE is not set
++# CONFIG_BLK_DEV_CMD64X is not set
++CONFIG_BLK_DEV_CY82C693=y
++# 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_NS87415 is not set
++# CONFIG_BLK_DEV_OPTI621 is not set
++# CONFIG_PDC202XX_BURST is not set
++# CONFIG_BLK_DEV_OSB4 is not set
++# CONFIG_BLK_DEV_SIS5513 is not set
++# CONFIG_BLK_DEV_TRM290 is not set
++# CONFIG_BLK_DEV_VIA82CXXX is not set
++CONFIG_BLK_DEV_SL82C105=y
++# CONFIG_IDE_CHIPSETS is not set
++CONFIG_IDEDMA_AUTO=y
++# CONFIG_IDEDMA_IVB is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# IEEE 1394 (FireWire) support
++#
++# 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
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++# CONFIG_INPUT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_SERIAL=y
++CONFIG_SERIAL_CONSOLE=y
++# CONFIG_SERIAL_EXTENDED is not set
++CONFIG_SERIAL_NONSTANDARD=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_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_21285=y
++CONFIG_SERIAL_21285_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++CONFIG_PRINTER=m
++# CONFIG_LP_CONSOLE is not set
++# CONFIG_PPDEV is not set
++
++#
++# I2C support
++#
++CONFIG_I2C=m
++# CONFIG_I2C_ALGOBIT is not set
++# CONFIG_I2C_ALGOPCF is not set
++# CONFIG_I2C_CHARDEV is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++CONFIG_MOUSE=y
++CONFIG_PSMOUSE=y
++# CONFIG_82C710_MOUSE is not set
++# CONFIG_PC110_PAD is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++
++#
++# Input core support is needed for joysticks
++#
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++CONFIG_WATCHDOG=y
++# CONFIG_WATCHDOG_NOWAYOUT is not set
++CONFIG_SOFT_WATCHDOG=y
++# CONFIG_WDT is not set
++# CONFIG_WDTPCI is not set
++# CONFIG_PCWATCHDOG is not set
++# CONFIG_ACQUIRE_WDT is not set
++# CONFIG_60XX_WDT is not set
++# CONFIG_MIXCOMWD is not set
++# CONFIG_I810_TCO is not set
++CONFIG_21285_WATCHDOG=m
++CONFIG_977_WATCHDOG=m
++CONFIG_DS1620=y
++CONFIG_NWBUTTON=y
++CONFIG_NWBUTTON_REBOOT=y
++CONFIG_NWFLASH=m
++# CONFIG_INTEL_RNG is not set
++CONFIG_NVRAM=m
++CONFIG_RTC=y
++# 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
++# CONFIG_DRM is not set
++
++#
++# Multimedia devices
++#
++CONFIG_VIDEO_DEV=m
++
++#
++# Video For Linux
++#
++CONFIG_VIDEO_PROC_FS=y
++# CONFIG_I2C_PARPORT is not set
++
++#
++# Video Adapters
++#
++# CONFIG_VIDEO_PMS is not set
++# CONFIG_VIDEO_BWQCAM is not set
++# CONFIG_VIDEO_CQCAM is not set
++# CONFIG_VIDEO_CPIA is not set
++# CONFIG_VIDEO_SAA5249 is not set
++# CONFIG_TUNER_3036 is not set
++# CONFIG_VIDEO_STRADIS is not set
++# CONFIG_VIDEO_ZORAN is not set
++# CONFIG_VIDEO_BUZ is not set
++# CONFIG_VIDEO_ZR36120 is not set
++CONFIG_VIDEO_CYBERPRO=m
++
++#
++# Radio Adapters
++#
++# CONFIG_RADIO_CADET is not set
++# CONFIG_RADIO_RTRACK is not set
++# CONFIG_RADIO_RTRACK2 is not set
++# CONFIG_RADIO_AZTECH is not set
++# CONFIG_RADIO_GEMTEK is not set
++# CONFIG_RADIO_MAESTRO is not set
++# CONFIG_RADIO_MIROPCM20 is not set
++# CONFIG_RADIO_SF16FMI is not set
++# CONFIG_RADIO_TERRATEC is not set
++# CONFIG_RADIO_TRUST is not set
++# CONFIG_RADIO_TYPHOON is not set
++# CONFIG_RADIO_ZOLTRIX is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++CONFIG_AUTOFS4_FS=y
++CONFIG_ADFS_FS=m
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++CONFIG_FAT_FS=m
++CONFIG_MSDOS_FS=m
++# CONFIG_UMSDOS_FS is not set
++CONFIG_VFAT_FS=m
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_RAMFS is not set
++CONFIG_ISO9660_FS=m
++CONFIG_JOLIET=y
++# CONFIG_MINIX_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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_SYSV_FS_WRITE 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
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++CONFIG_ROOT_NFS=y
++CONFIG_NFSD=m
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=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_MOUNT_SUBDIR is not set
++# CONFIG_NCPFS_NDS_DOMAINS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++CONFIG_ACORN_PARTITION=y
++# CONFIG_ACORN_PARTITION_ICS is not set
++CONFIG_ACORN_PARTITION_ADFS=y
++# CONFIG_ACORN_PARTITION_POWERTEC is not set
++# CONFIG_ACORN_PARTITION_RISCIX is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++CONFIG_NLS=y
++
++#
++# Native Language Support
++#
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=m
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++CONFIG_NLS_CODEPAGE_850=m
++CONFIG_NLS_CODEPAGE_852=m
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++CONFIG_NLS_ISO8859_1=m
++CONFIG_NLS_ISO8859_2=m
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++CONFIG_NLS_ISO8859_15=m
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_UTF8 is not set
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYB=y
++CONFIG_PC_KEYMAP=y
++CONFIG_VGA_CONSOLE=y
++CONFIG_FB=y
++
++#
++# 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_ACORN is not set
++# CONFIG_FB_CLPS711X is not set
++CONFIG_FB_CYBER2000=y
++# CONFIG_FB_SA1100 is not set
++# CONFIG_FB_MATROX is not set
++# CONFIG_FB_ATY is not set
++# CONFIG_FB_ATY128 is not set
++# CONFIG_FB_3DFX is not set
++# CONFIG_FB_SIS is not set
++# CONFIG_FB_VIRTUAL is not set
++CONFIG_FBCON_ADVANCED=y
++# CONFIG_FBCON_MFB is not set
++# CONFIG_FBCON_CFB2 is not set
++# CONFIG_FBCON_CFB4 is not set
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++CONFIG_FBCON_CFB24=y
++# CONFIG_FBCON_CFB32 is not set
++# CONFIG_FBCON_AFB is not set
++# CONFIG_FBCON_ILBM is not set
++# CONFIG_FBCON_IPLAN2P2 is not set
++# CONFIG_FBCON_IPLAN2P4 is not set
++# CONFIG_FBCON_IPLAN2P8 is not set
++# CONFIG_FBCON_MAC is not set
++# CONFIG_FBCON_VGA_PLANES is not set
++CONFIG_FBCON_VGA=y
++# CONFIG_FBCON_HGA is not set
++# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
++CONFIG_FBCON_FONTS=y
++# CONFIG_FONT_8x8 is not set
++# CONFIG_FONT_8x16 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_SUN12x22 is not set
++# CONFIG_FONT_6x11 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++CONFIG_FONT_ACORN_8x8=y
++
++#
++# Sound
++#
++CONFIG_SOUND=m
++# CONFIG_SOUND_CMPCI is not set
++# CONFIG_SOUND_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_SONICVIBES 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_SOUND_OSS=m
++# CONFIG_SOUND_TRACEINIT is not set
++# CONFIG_SOUND_DMAP is not set
++# CONFIG_SOUND_AD1816 is not set
++# CONFIG_SOUND_SGALAXY is not set
++CONFIG_SOUND_ADLIB=m
++# CONFIG_SOUND_ACI_MIXER is not set
++# CONFIG_SOUND_CS4232 is not set
++# CONFIG_SOUND_SSCAPE is not set
++# CONFIG_SOUND_GUS is not set
++# CONFIG_SOUND_ICH is not set
++# CONFIG_SOUND_VMIDI is not set
++# CONFIG_SOUND_TRIX is not set
++# CONFIG_SOUND_MSS is not set
++# CONFIG_SOUND_MPU401 is not set
++# CONFIG_SOUND_NM256 is not set
++# CONFIG_SOUND_MAD16 is not set
++# CONFIG_SOUND_PAS is not set
++# CONFIG_PAS_JOYSTICK is not set
++# CONFIG_SOUND_PSS is not set
++CONFIG_SOUND_SB=m
++# CONFIG_SOUND_AWE32_SYNTH is not set
++# CONFIG_SOUND_WAVEFRONT is not set
++# CONFIG_SOUND_MAUI is not set
++# CONFIG_SOUND_YM3812 is not set
++# CONFIG_SOUND_OPL3SA1 is not set
++# CONFIG_SOUND_OPL3SA2 is not set
++# CONFIG_SOUND_YMPCI is not set
++# CONFIG_SOUND_UART6850 is not set
++# CONFIG_SOUND_AEDSP16 is not set
++CONFIG_SOUND_WAVEARTIST=m
++# CONFIG_SOUND_TVMIXER is not set
++
++#
++# USB support
++#
++CONFIG_USB=m
++CONFIG_USB_DEBUG=y
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++# CONFIG_USB_BANDWIDTH is not set
++
++#
++# USB Controllers
++#
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++CONFIG_USB_OHCI=m
++
++#
++# USB Devices
++#
++CONFIG_USB_PRINTER=m
++# CONFIG_USB_SCANNER is not set
++# CONFIG_USB_MICROTEK is not set
++CONFIG_USB_AUDIO=m
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_SERIAL is not set
++# CONFIG_USB_IBMCAM is not set
++# CONFIG_USB_OV511 is not set
++# CONFIG_USB_DC2XX is not set
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_STORAGE is not set
++# CONFIG_USB_USS720 is not set
++# CONFIG_USB_DABUSB is not set
++# CONFIG_USB_PLUSB is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_DSBR is not set
++# CONFIG_USB_BLUETOOTH is not set
++# CONFIG_USB_NET1080 is not set
++
++#
++# USB Human Interface Devices (HID)
++#
++
++#
++# Input core support is needed for USB HID
++#
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++CONFIG_MAGIC_SYSRQ=y
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_DC21285_PORT is not set
+Index: linux-2.6.0-test5/arch/arm/configs/fortunet_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/fortunet_defconfig 2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/fortunet_defconfig 2003-09-27 11:38:18.617698064 +0800
+@@ -0,0 +1,593 @@
++#
++# Automatically generated by make menuconfig: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++# CONFIG_GENERIC_BUST_SPINLOCK is not set
++# CONFIG_GENERIC_ISA_DMA is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++# CONFIG_MODULES is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++CONFIG_ARCH_CLPS711X=y
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_H3100 is not set
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_H3800 is not set
++# CONFIG_SA1100_H3XXX is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_SHANNON is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++# CONFIG_SA1100_USB is not set
++# CONFIG_SA1100_USB_NETLINK is not set
++# CONFIG_SA1100_USB_CHAR is not set
++# CONFIG_H3600_SLEEVE is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_AUTCPU12 is not set
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++CONFIG_ARCH_FORTUNET=y
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++CONFIG_CPU_ARM720T=y
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM922T is not set
++# CONFIG_CPU_ARM926T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++# CONFIG_CPU_SA1100 is not set
++# CONFIG_ARM_THUMB is not set
++# CONFIG_DISCONTIGMEM is not set
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++# CONFIG_HOTPLUG is not set
++# CONFIG_PCMCIA is not set
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++# CONFIG_FPE_NWFPE is not set
++CONFIG_FPE_FASTFPE=y
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_PARTITIONS is not set
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_BOOTLDR_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++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 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_NORA is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_CDB89712 is not set
++# CONFIG_MTD_SA1100 is not set
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++CONFIG_MTD_FORTUNET=y
++# CONFIG_MTD_PCI 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
++# 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
++
++#
++# 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_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# 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 is not set
++# CONFIG_NETLINK_DEV is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++# CONFIG_INET is not set
++# CONFIG_ATM is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK 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_AUNUDP is not set
++# CONFIG_ECONET_NATIVE 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 device support
++#
++# CONFIG_NETDEVICES is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++# CONFIG_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# Synchronous Serial Interface
++#
++# CONFIG_SSI is not set
++# CONFIG_SSI_CLPS711X is not set
++# CONFIG_SSI_JUNO is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O 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
++
++#
++# 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
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_ANAKIN is not set
++# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++CONFIG_SERIAL_CLPS711X=y
++CONFIG_SERIAL_CLPS711X_CONSOLE=y
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_UART00 is not set
++# CONFIG_SERIAL_UART00_CONSOLE is not set
++# CONFIG_SERIAL_SA1100 is not set
++# CONFIG_SERIAL_SA1100_CONSOLE is not set
++# CONFIG_SERIAL_8250 is not set
++# CONFIG_SERIAL_8250_CONSOLE is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_MULTIPORT is not set
++# CONFIG_SERIAL_8250_HUB6 is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++# CONFIG_L3_ALGOBIT is not set
++# CONFIG_L3_BIT_SA1100_GPIO is not set
++# CONFIG_L3_SA1111 is not set
++# CONFIG_BIT_SA1100_GPIO is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++
++#
++# Joysticks
++#
++# CONFIG_INPUT_GAMEPORT is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG 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
++# CONFIG_DRM is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA 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_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 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=y
++CONFIG_JFFS_FS_VERBOSE=0
++# CONFIG_JFFS_PROC_FS is not set
++# CONFIG_JFFS2_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_TMPFS is not set
++# CONFIG_RAMFS is not set
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_ZISOFS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
++# CONFIG_NFS_FS is not set
++# CONFIG_NFS_V3 is not set
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++# CONFIG_SUNRPC is not set
++# CONFIG_LOCKD is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_ZISOFS_FS is not set
++# CONFIG_ZLIB_FS_INFLATE 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 Capabilities Port drivers
++#
++# CONFIG_MCP is not set
++# CONFIG_MCP_SA1100 is not set
++# CONFIG_MCP_UCB1200 is not set
++# CONFIG_MCP_UCB1200_AUDIO is not set
++# CONFIG_MCP_UCB1200_TS is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++# CONFIG_USB_OHCI is not set
++# CONFIG_USB_OHCI_SA1111 is not set
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++# 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_JUMPSHOT is not set
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# 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
++# CONFIG_USB_PEGASUS 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
++# CONFIG_USB_USS720 is not set
++
++#
++# USB Serial Converter support
++#
++# CONFIG_USB_SERIAL is not set
++# CONFIG_USB_SERIAL_GENERIC is not set
++# CONFIG_USB_SERIAL_BELKIN is not set
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
++# CONFIG_USB_SERIAL_EMPEG is not set
++# CONFIG_USB_SERIAL_FTDI_SIO is not set
++# CONFIG_USB_SERIAL_VISOR is not set
++# CONFIG_USB_SERIAL_IR is not set
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
++# CONFIG_USB_SERIAL_MCT_U232 is not set
++# CONFIG_USB_SERIAL_PL2303 is not set
++# CONFIG_USB_SERIAL_CYBERJACK is not set
++# CONFIG_USB_SERIAL_XIRCOM is not set
++# CONFIG_USB_SERIAL_OMNINET is not set
++# CONFIG_USB_RIO500 is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_NO_PGT_CACHE is not set
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_DEBUG_SLAB is not set
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_WAITQ is not set
++# CONFIG_DEBUG_BUGVERBOSE is not set
++# CONFIG_DEBUG_ERRORS is not set
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
++# CONFIG_DEBUG_LL_SER3 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/freebird_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/freebird_defconfig 2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/freebird_defconfig 2003-09-27 11:38:18.618697912 +0800
+@@ -0,0 +1,615 @@
++#
++# Automatically generated by make menuconfig: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_CLPS711X is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_BITSY is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++CONFIG_SA1100_FREEBIRD=y
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++# CONFIG_SA1100_PFS168 is not set
++CONFIG_SA1100_FREEBIRD_OLD=y
++# CONFIG_SA1100_FREEBIRD_NEW is not set
++CONFIG_SA1100_FL=y
++CONFIG_SA1100_USB=m
++CONFIG_SA1100_USB_NETLINK=m
++CONFIG_SA1100_USB_CHAR=m
++# CONFIG_SA1100_FREQUENCY_SCALE is not set
++# CONFIG_SA1100_VOLTAGE_SCALE is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++# CONFIG_ANGELBOOT is not set
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=y
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=y
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++# CONFIG_FPE_NWFPE is not set
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=m
++CONFIG_BINFMT_ELF=y
++CONFIG_BINFMT_MISC=m
++CONFIG_PM=y
++CONFIG_APM=y
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="mem=32M root=/dev/ram initrd=0xc0800000,3M"
++# CONFIG_PFS168_CMDLINE is not set
++# CONFIG_LEDS is not set
++CONFIG_ALIGNMENT_TRAP=y
++# CONFIG_UCB1200 is not set
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_DOC1000 is not set
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOCPROBE is not set
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_MTDRAM is not set
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_CFI_ADV_OPTIONS is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_PNC2000 is not set
++# CONFIG_MTD_RPXLITE is not set
++# CONFIG_MTD_SC520CDP is not set
++# CONFIG_MTD_SBC_MEDIAGX is not set
++# CONFIG_MTD_ELAN_104NC is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++# CONFIG_MTD_CSTM_CFI_JEDEC is not set
++# CONFIG_MTD_JEDEC is not set
++# CONFIG_MTD_MIXMEM is not set
++# CONFIG_MTD_OCTAGON is not set
++# CONFIG_MTD_VMAX is not set
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_NAND_SPIA is not set
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL 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_BLK_DEV_DAC960 is not set
++CONFIG_BLK_DEV_LOOP=m
++CONFIG_BLK_DEV_NBD=m
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=8192
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# 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_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++# CONFIG_NETLINK 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 is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE 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
++# CONFIG_ATM is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK 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 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_NET_SB1000 is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++# CONFIG_NET_ETHERNET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++CONFIG_PPP=m
++# CONFIG_PPP_MULTILINK is not set
++CONFIG_PPP_ASYNC=m
++# CONFIG_PPP_SYNC_TTY is not set
++CONFIG_PPP_DEFLATE=m
++CONFIG_PPP_BSDCOMP=m
++# CONFIG_PPPOE 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
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=m
++# CONFIG_PCMCIA_NMCLAN is not set
++# CONFIG_PCMCIA_SMC91C92 is not set
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++CONFIG_IRDA=m
++# CONFIG_IRLAN is not set
++# CONFIG_IRNET is not set
++# CONFIG_IRCOMM is not set
++# CONFIG_IRDA_ULTRA is not set
++# CONFIG_IRDA_OPTIONS is not set
++
++#
++# Infrared-port device drivers
++#
++CONFIG_IRTTY_SIR=m
++# CONFIG_IRPORT_SIR is not set
++# CONFIG_NSC_FIR is not set
++# CONFIG_WINBOND_FIR is not set
++# CONFIG_TOSHIBA_FIR is not set
++# CONFIG_SMC_IRCC_FIR is not set
++CONFIG_SA1100_FIR=m
++# CONFIG_DONGLE is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++CONFIG_IDE=y
++
++#
++# IDE, ATA and ATAPI Block devices
++#
++CONFIG_BLK_DEV_IDE=y
++# CONFIG_BLK_DEV_HD_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++CONFIG_BLK_DEV_IDEDISK=m
++# CONFIG_IDEDISK_MULTI_MODE is not set
++CONFIG_BLK_DEV_IDECS=m
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
++# CONFIG_BLK_DEV_ISAPNP is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O 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
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++# CONFIG_INPUT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=9600
++# CONFIG_TOUCHSCREEN_UCB1200 is not set
++# CONFIG_TOUCHSCREEN_BITSY is not set
++CONFIG_FB_TS_BT=y
++# CONFIG_PROFILER is not set
++# CONFIG_PFS168_SPI is not set
++# CONFIG_PFS168_DTMF is not set
++# CONFIG_PFS168_MISC is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++CONFIG_SA1100_RTC=y
++# 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
++# CONFIG_DRM is not set
++# CONFIG_PCMCIA_SERIAL is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA 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_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_BFS_FS 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_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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_SYSV_FS_WRITE 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
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_NFS_FS is not set
++# CONFIG_NFS_V3 is not set
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++# CONFIG_SUNRPC is not set
++# CONFIG_LOCKD is not set
++# 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
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_SMB_NLS is not set
++# CONFIG_NLS is not set
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_FB=y
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_CLPS711X is not set
++# CONFIG_FB_CYBER2000 is not set
++CONFIG_FB_SA1100=y
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FBCON_ADVANCED is not set
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
++CONFIG_FBCON_FONTS=y
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_SUN12x22 is not set
++# CONFIG_FONT_6x11 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++
++#
++# Sound
++#
++CONFIG_SOUND=y
++CONFIG_SOUND_UDA1341=y
++# CONFIG_SOUND_UDA1341_GSM is not set
++# CONFIG_SOUND_SA1100_SSP is not set
++# CONFIG_SOUND_CMPCI is not set
++# CONFIG_SOUND_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_ICH is not set
++# CONFIG_SOUND_SONICVIBES 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_SOUND_OSS is not set
++# CONFIG_SOUND_TVMIXER is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_NO_PGT_CACHE is not set
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/freebird_new_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/freebird_new_defconfig 2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/freebird_new_defconfig 2003-09-27 11:38:18.619697760 +0800
+@@ -0,0 +1,635 @@
++#
++# Automatically generated by make menuconfig: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_CLPS711X is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_BITSY is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++CONFIG_SA1100_FREEBIRD=y
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_FREEBIRD_OLD is not set
++CONFIG_SA1100_FREEBIRD_NEW=y
++CONFIG_SA1100_FL=m
++CONFIG_SA1100_USB=m
++CONFIG_SA1100_USB_NETLINK=m
++CONFIG_SA1100_USB_CHAR=m
++CONFIG_SA1100_FREQUENCY_SCALE=y
++# CONFIG_SA1100_VOLTAGE_SCALE is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++# CONFIG_ANGELBOOT is not set
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=m
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=m
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++# CONFIG_FPE_NWFPE is not set
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++CONFIG_PM=y
++CONFIG_APM=y
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="noinitrd console=ttySA0 init=/linuxrc root=/dev/mtdblock4 mem=32m"
++# CONFIG_PFS168_CMDLINE is not set
++# CONFIG_LEDS is not set
++CONFIG_ALIGNMENT_TRAP=y
++# CONFIG_UCB1200 is not set
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_DOC1000 is not set
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOCPROBE is not set
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_MTDRAM is not set
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_CFI_ADV_OPTIONS is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_PNC2000 is not set
++# CONFIG_MTD_RPXLITE is not set
++# CONFIG_MTD_SC520CDP is not set
++# CONFIG_MTD_SBC_MEDIAGX is not set
++# CONFIG_MTD_ELAN_104NC is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++# CONFIG_MTD_CSTM_CFI_JEDEC is not set
++# CONFIG_MTD_JEDEC is not set
++# CONFIG_MTD_MIXMEM is not set
++# CONFIG_MTD_OCTAGON is not set
++# CONFIG_MTD_VMAX is not set
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_NAND_SPIA is not set
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL 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_BLK_DEV_DAC960 is not set
++CONFIG_BLK_DEV_LOOP=m
++CONFIG_BLK_DEV_NBD=m
++# CONFIG_BLK_DEV_RAM is not set
++# CONFIG_BLK_DEV_INITRD 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_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++CONFIG_NETLINK=y
++CONFIG_RTNETLINK=y
++# CONFIG_NETLINK_DEV is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG 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 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
++
++#
++# 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_COMPAT_IPCHAINS is not set
++# CONFIG_IP_NF_COMPAT_IPFWADM is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK 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 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
++# CONFIG_NET_SB1000 is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++# CONFIG_NET_ETHERNET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++CONFIG_PPP=m
++# CONFIG_PPP_MULTILINK is not set
++CONFIG_PPP_ASYNC=m
++# CONFIG_PPP_SYNC_TTY is not set
++CONFIG_PPP_DEFLATE=m
++CONFIG_PPP_BSDCOMP=m
++# CONFIG_PPPOE 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
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=m
++# CONFIG_PCMCIA_NMCLAN is not set
++# CONFIG_PCMCIA_SMC91C92 is not set
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++CONFIG_IRDA=m
++# CONFIG_IRLAN is not set
++# CONFIG_IRNET is not set
++# CONFIG_IRCOMM is not set
++# CONFIG_IRDA_ULTRA is not set
++# CONFIG_IRDA_OPTIONS is not set
++
++#
++# Infrared-port device drivers
++#
++# CONFIG_IRTTY_SIR is not set
++# CONFIG_IRPORT_SIR is not set
++# CONFIG_NSC_FIR is not set
++# CONFIG_WINBOND_FIR is not set
++# CONFIG_TOSHIBA_FIR is not set
++# CONFIG_SMC_IRCC_FIR is not set
++CONFIG_SA1100_FIR=m
++# CONFIG_DONGLE is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++CONFIG_IDE=m
++
++#
++# IDE, ATA and ATAPI Block devices
++#
++CONFIG_BLK_DEV_IDE=m
++# CONFIG_BLK_DEV_HD_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++CONFIG_BLK_DEV_IDEDISK=m
++# CONFIG_IDEDISK_MULTI_MODE is not set
++CONFIG_BLK_DEV_IDECS=m
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
++# CONFIG_BLK_DEV_ISAPNP is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O 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
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++# CONFIG_INPUT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++CONFIG_SERIAL=m
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=9600
++# CONFIG_TOUCHSCREEN_UCB1200 is not set
++# CONFIG_TOUCHSCREEN_BITSY is not set
++CONFIG_FB_TS_BT=y
++# CONFIG_PROFILER is not set
++# CONFIG_PFS168_SPI is not set
++# CONFIG_PFS168_DTMF is not set
++# CONFIG_PFS168_MISC is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++CONFIG_SA1100_RTC=y
++# 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
++# CONFIG_DRM is not set
++CONFIG_PCMCIA_SERIAL=m
++
++#
++# PCMCIA character device support
++#
++CONFIG_PCMCIA_SERIAL_CS=m
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++CONFIG_AUTOFS_FS=m
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_REISERFS_CHECK 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_BFS_FS 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=m
++CONFIG_JFFS_FS_VERBOSE=0
++# CONFIG_JFFS2_FS is not set
++CONFIG_CRAMFS=y
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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=m
++# CONFIG_SYSV_FS is not set
++# CONFIG_SYSV_FS_WRITE 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
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++CONFIG_NFS_FS=m
++# CONFIG_NFS_V3 is not set
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=m
++CONFIG_LOCKD=m
++# 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
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_SMB_NLS is not set
++# CONFIG_NLS is not set
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_FB=y
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_CLPS711X is not set
++# CONFIG_FB_CYBER2000 is not set
++CONFIG_FB_SA1100=y
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FBCON_ADVANCED is not set
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
++CONFIG_FBCON_FONTS=y
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_SUN12x22 is not set
++# CONFIG_FONT_6x11 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++
++#
++# Sound
++#
++CONFIG_SOUND=y
++CONFIG_SOUND_UDA1341=y
++# CONFIG_SOUND_UDA1341_GSM is not set
++# CONFIG_SOUND_SA1100_SSP is not set
++# CONFIG_SOUND_CMPCI is not set
++# CONFIG_SOUND_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_ICH is not set
++# CONFIG_SOUND_SONICVIBES 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_SOUND_OSS is not set
++# CONFIG_SOUND_TVMIXER is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++# CONFIG_DEBUG_USER is not set
++# CONFIG_DEBUG_INFO is not set
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_NO_PGT_CACHE is not set
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/graphicsclient_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/graphicsclient_defconfig 2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/graphicsclient_defconfig 2003-09-27 11:38:18.621697456 +0800
+@@ -0,0 +1,732 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_BITSY is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++CONFIG_SA1100_GRAPHICSCLIENT=y
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_USB is not set
++# CONFIG_SA1100_USB_NETLINK is not set
++# CONFIG_SA1100_USB_CHAR is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++CONFIG_DISCONTIGMEM=y
++# CONFIG_CPU_BIG_ENDIAN is not set
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++# CONFIG_CPU_FREQ is not set
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=y
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=y
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_APM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="ip=off mem=16M@0xc0000000 mem=16M@0xc8000000 root=/dev/ram initrd=0xc0800000,4M"
++# CONFIG_PFS168_CMDLINE is not set
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_BOOTLDR_PARTS is not set
++# CONFIG_MTD_AFS_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_CFI_ADV_OPTIONS is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_JEDEC is not set
++
++#
++# Mapping drivers for chip access
++#
++CONFIG_MTD_PHYSMAP=y
++CONFIG_MTD_PHYSMAP_START=800000
++CONFIG_MTD_PHYSMAP_LEN=1000000
++CONFIG_MTD_PHYSMAP_BUSWIDTH=4
++# CONFIG_MTD_SUN_UFLASH is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_PNC2000 is not set
++# CONFIG_MTD_RPXLITE is not set
++# CONFIG_MTD_TQM8XXL is not set
++# CONFIG_MTD_SC520CDP is not set
++# CONFIG_MTD_NETSC520 is not set
++# CONFIG_MTD_SBC_GXX is not set
++# CONFIG_MTD_ELAN_104NC is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_SA1100_REDBOOT_PARTITIONS is not set
++# CONFIG_MTD_SA1100_BOOTLDR_PARTITIONS is not set
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++# CONFIG_MTD_DBOX2 is not set
++# CONFIG_MTD_CSTM_MIPS_IXX is not set
++# CONFIG_MTD_CFI_FLAGADM is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_SOLUTIONENGINE is not set
++# CONFIG_MTD_MIXMEM is not set
++# CONFIG_MTD_OCTAGON is not set
++# CONFIG_MTD_VMAX is not set
++# CONFIG_MTD_OCELOT is not set
++# CONFIG_MTD_L440GX is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_LART 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
++
++#
++# 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_BLK_DEV_DAC960 is not set
++CONFIG_BLK_DEV_LOOP=m
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=8192
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# 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_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++# CONFIG_NETLINK 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 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_INET_ECN is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++
++#
++#
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK 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 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
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNBMAC is not set
++# CONFIG_SUNQE is not set
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNGEM is not set
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_LANCE is not set
++CONFIG_NET_VENDOR_SMC=y
++# CONFIG_WD80x3 is not set
++# CONFIG_ULTRAMCA is not set
++# CONFIG_ULTRA is not set
++# CONFIG_ULTRA32 is not set
++CONFIG_SMC9194=y
++# CONFIG_NET_VENDOR_RACAL 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_ACENIC_OMIT_TIGON_I is not set
++# CONFIG_MYRI_SBUS is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_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
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=y
++# CONFIG_PCMCIA_NMCLAN is not set
++# CONFIG_PCMCIA_SMC91C92 is not set
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA 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_IDEDISK=y
++# CONFIG_IDEDISK_MULTI_MODE is not set
++CONFIG_BLK_DEV_IDECS=y
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++
++#
++# 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_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O 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
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++# CONFIG_INPUT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=38400
++# CONFIG_SERIAL_8250 is not set
++# CONFIG_SERIAL_8250_CONSOLE is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++CONFIG_UCB1200=y
++CONFIG_TOUCHSCREEN_UCB1200=y
++CONFIG_AUDIO_UCB1200=y
++CONFIG_ADC_UCB1200=y
++# CONFIG_TOUCHSCREEN_BITSY is not set
++# CONFIG_PROFILER is not set
++# CONFIG_PFS168_SPI is not set
++# CONFIG_PFS168_DTMF is not set
++# CONFIG_PFS168_MISC is not set
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++
++#
++# Input core support is needed for joysticks
++#
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_SA1100_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
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA 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_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_BFS_FS is not set
++CONFIG_FAT_FS=y
++# CONFIG_MSDOS_FS is not set
++# CONFIG_UMSDOS_FS is not set
++CONFIG_VFAT_FS=y
++# CONFIG_EFS_FS is not set
++CONFIG_JFFS_FS=y
++CONFIG_JFFS_FS_VERBOSE=0
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_CRAMFS=y
++# CONFIG_TMPFS is not set
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=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
++
++#
++# 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_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
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_CLPS711X is not set
++# CONFIG_FB_CYBER2000 is not set
++CONFIG_FB_SA1100=y
++# CONFIG_FB_ANAKIN is not set
++# CONFIG_FB_E1355 is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FBCON_ADVANCED is not set
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++CONFIG_FBCON_FONTWIDTH8_ONLY=y
++CONFIG_FBCON_FONTS=y
++# CONFIG_FONT_8x8 is not set
++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
++#
++# CONFIG_SOUND is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_NO_PGT_CACHE is not set
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/graphicsmaster_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/graphicsmaster_defconfig 2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/graphicsmaster_defconfig 2003-09-27 11:38:18.622697304 +0800
+@@ -0,0 +1,745 @@
++#
++# Automatically generated by make menuconfig: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_BITSY is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++CONFIG_SA1100_GRAPHICSMASTER=y
++# CONFIG_SA1100_ADSBITSY is not set
++CONFIG_SA1111=y
++# CONFIG_SA1100_USB is not set
++# CONFIG_SA1100_USB_NETLINK is not set
++# CONFIG_SA1100_USB_CHAR is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++CONFIG_DISCONTIGMEM=y
++# CONFIG_CPU_BIG_ENDIAN is not set
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++# CONFIG_CPU_FREQ is not set
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=y
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=y
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_APM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="ip=off mem=16M@0xc0000000 mem=16M@0xc8000000 root=/dev/ram initrd=0xc0800000,4M"
++# CONFIG_PFS168_CMDLINE is not set
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_BOOTLDR_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++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_CFI_ADV_OPTIONS is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_JEDEC is not set
++
++#
++# Mapping drivers for chip access
++#
++CONFIG_MTD_PHYSMAP=y
++CONFIG_MTD_PHYSMAP_START=800000
++CONFIG_MTD_PHYSMAP_LEN=1000000
++CONFIG_MTD_PHYSMAP_BUSWIDTH=4
++# CONFIG_MTD_SUN_UFLASH is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_PNC2000 is not set
++# CONFIG_MTD_RPXLITE is not set
++# CONFIG_MTD_TQM8XXL is not set
++# CONFIG_MTD_SC520CDP is not set
++# CONFIG_MTD_NETSC520 is not set
++# CONFIG_MTD_SBC_GXX is not set
++# CONFIG_MTD_ELAN_104NC is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_SA1100_REDBOOT_PARTITIONS is not set
++# CONFIG_MTD_SA1100_BOOTLDR_PARTITIONS is not set
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++# CONFIG_MTD_DBOX2 is not set
++# CONFIG_MTD_CSTM_MIPS_IXX is not set
++# CONFIG_MTD_CFI_FLAGADM is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_SOLUTIONENGINE is not set
++# CONFIG_MTD_MIXMEM is not set
++# CONFIG_MTD_OCTAGON is not set
++# CONFIG_MTD_VMAX is not set
++# CONFIG_MTD_OCELOT is not set
++# CONFIG_MTD_L440GX is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_LART is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLKMTD is not set
++# 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
++
++#
++# 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_BLK_DEV_DAC960 is not set
++CONFIG_BLK_DEV_LOOP=m
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=8192
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# 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_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++# CONFIG_NETLINK 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 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_INET_ECN is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK 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 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
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNBMAC is not set
++# CONFIG_SUNQE is not set
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNGEM is not set
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_LANCE is not set
++CONFIG_NET_VENDOR_SMC=y
++# CONFIG_WD80x3 is not set
++# CONFIG_ULTRAMCA is not set
++# CONFIG_ULTRA is not set
++# CONFIG_ULTRA32 is not set
++CONFIG_SMC9194=y
++# CONFIG_NET_VENDOR_RACAL 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_ACENIC_OMIT_TIGON_I is not set
++# CONFIG_MYRI_SBUS is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_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
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=y
++# CONFIG_PCMCIA_NMCLAN is not set
++# CONFIG_PCMCIA_SMC91C92 is not set
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++CONFIG_IDE=y
++
++#
++# IDE, ATA and ATAPI Block devices
++#
++CONFIG_BLK_DEV_IDE=y
++# CONFIG_BLK_DEV_HD_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++CONFIG_BLK_DEV_IDEDISK=y
++# CONFIG_IDEDISK_MULTI_MODE is not set
++CONFIG_BLK_DEV_IDECS=y
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
++# CONFIG_BLK_DEV_ISAPNP is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O 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
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_KEYBDEV is not set
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=38400
++# CONFIG_SERIAL_8250 is not set
++# CONFIG_SERIAL_8250_CONSOLE is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++CONFIG_UCB1200=y
++CONFIG_TOUCHSCREEN_UCB1200=y
++CONFIG_AUDIO_UCB1200=y
++CONFIG_ADC_UCB1200=y
++# CONFIG_TOUCHSCREEN_BITSY is not set
++# CONFIG_PROFILER is not set
++# CONFIG_PFS168_SPI is not set
++# CONFIG_PFS168_DTMF is not set
++# CONFIG_PFS168_MISC is not set
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_SA1100_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
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA 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_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_BFS_FS is not set
++CONFIG_FAT_FS=y
++# CONFIG_MSDOS_FS is not set
++# CONFIG_UMSDOS_FS is not set
++CONFIG_VFAT_FS=y
++# CONFIG_EFS_FS is not set
++CONFIG_JFFS_FS=y
++CONFIG_JFFS_FS_VERBOSE=0
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_CRAMFS=y
++# CONFIG_TMPFS is not set
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=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
++
++#
++# 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_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
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_CLPS711X is not set
++# CONFIG_FB_CYBER2000 is not set
++CONFIG_FB_SA1100=y
++# CONFIG_FB_ANAKIN is not set
++# CONFIG_FB_E1355 is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FBCON_ADVANCED is not set
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++CONFIG_FBCON_FONTWIDTH8_ONLY=y
++CONFIG_FBCON_FONTS=y
++# CONFIG_FONT_8x8 is not set
++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
++#
++# CONFIG_SOUND is not set
++
++#
++# USB support
++#
++CONFIG_USB=y
++# CONFIG_USB_DEBUG is not set
++CONFIG_USB_DEVICEFS=y
++# CONFIG_USB_BANDWIDTH is not set
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++CONFIG_USB_OHCI=y
++CONFIG_USB_OHCI_NOPCI=y
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++# CONFIG_USB_STORAGE is not set
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# CONFIG_USB_HID is not set
++# CONFIG_USB_KBD is not set
++CONFIG_USB_MOUSE=y
++# CONFIG_USB_WACOM is not set
++# 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_IBMCAM is not set
++# CONFIG_USB_OV511 is not set
++# CONFIG_USB_PWC is not set
++# CONFIG_USB_SE401 is not set
++# CONFIG_USB_DSBR is not set
++# CONFIG_USB_DABUSB is not set
++# CONFIG_USB_PLUSB is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_NET1080 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_USB_USS720 is not set
++
++#
++# USB Serial Converter support
++#
++# CONFIG_USB_SERIAL is not set
++# CONFIG_USB_RIO500 is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_NO_PGT_CACHE is not set
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/h3600_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/h3600_defconfig 2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/h3600_defconfig 2003-09-27 11:38:18.624697000 +0800
+@@ -0,0 +1,951 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++# CONFIG_GENERIC_BUST_SPINLOCK is not set
++# CONFIG_GENERIC_ISA_DMA is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++CONFIG_SA1100_H3600=y
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++CONFIG_SA1100_USB=m
++CONFIG_SA1100_USB_NETLINK=m
++# CONFIG_SA1100_USB_CHAR is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++# CONFIG_ARM_THUMB is not set
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++CONFIG_ISA=y
++# CONFIG_ISA_DMA is not set
++CONFIG_CPU_FREQ=y
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=y
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=y
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++CONFIG_PM=y
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE=""
++# CONFIG_LEDS is not set
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=y
++CONFIG_MTD_REDBOOT_PARTS=y
++CONFIG_MTD_BOOTLDR_PARTS=y
++# CONFIG_MTD_AFS_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=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++CONFIG_MTD_CFI_GEOMETRY=y
++# CONFIG_MTD_CFI_B1 is not set
++# CONFIG_MTD_CFI_B2 is not set
++CONFIG_MTD_CFI_B4=y
++# CONFIG_MTD_CFI_I1 is not set
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD 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_NORA is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_CDB89712 is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++# CONFIG_MTD_PCI 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
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++# CONFIG_PNPBIOS 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_BLK_DEV_DAC960 is not set
++CONFIG_BLK_DEV_LOOP=m
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=8192
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# 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 is not set
++# CONFIG_NETLINK 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 is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE 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
++# CONFIG_ATM is not set
++
++#
++#
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK 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 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
++
++#
++# Ethernet (10 or 100Mbit)
++#
++# CONFIG_NET_ETHERNET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K 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_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PLIP is not set
++CONFIG_PPP=m
++# CONFIG_PPP_MULTILINK is not set
++# CONFIG_PPP_FILTER is not set
++CONFIG_PPP_ASYNC=m
++# CONFIG_PPP_SYNC_TTY is not set
++CONFIG_PPP_DEFLATE=m
++CONFIG_PPP_BSDCOMP=m
++# CONFIG_PPPOE 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
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=y
++# CONFIG_PCMCIA_NMCLAN is not set
++# CONFIG_PCMCIA_SMC91C92 is not set
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++CONFIG_IRDA=m
++
++#
++# IrDA protocols
++#
++CONFIG_IRLAN=m
++CONFIG_IRNET=m
++CONFIG_IRCOMM=m
++# CONFIG_IRDA_ULTRA is not set
++# CONFIG_IRDA_OPTIONS 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_FIR is not set
++# CONFIG_SMC_IRCC_FIR is not set
++# CONFIG_ALI_FIR is not set
++# CONFIG_VLSI_FIR is not set
++CONFIG_SA1100_FIR=m
++
++#
++# ATA/IDE/MFM/RLL support
++#
++CONFIG_IDE=m
++
++#
++# IDE, ATA and ATAPI Block devices
++#
++CONFIG_BLK_DEV_IDE=m
++
++#
++# 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_IDEDISK=m
++# CONFIG_IDEDISK_MULTI_MODE is not set
++# CONFIG_BLK_DEV_IDECS is not set
++CONFIG_BLK_DEV_IDECD=m
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI 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_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++# CONFIG_BLK_DEV_ATARAID is not set
++# CONFIG_BLK_DEV_ATARAID_PDC is not set
++# CONFIG_BLK_DEV_ATARAID_HPT is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O 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
++
++#
++# 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
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++CONFIG_SERIAL=m
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_ANAKIN is not set
++# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_UART00 is not set
++# CONFIG_SERIAL_UART00_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=38400
++CONFIG_SERIAL_8250=m
++# CONFIG_SERIAL_8250_CONSOLE is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_MULTIPORT is not set
++# CONFIG_SERIAL_8250_HUB6 is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# L3 serial bus support
++#
++CONFIG_L3=y
++CONFIG_L3_ALGOBIT=y
++CONFIG_L3_BIT_SA1100_GPIO=y
++
++#
++# Other L3 adapters
++#
++# CONFIG_L3_SA1111 is not set
++CONFIG_BIT_SA1100_GPIO=y
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++CONFIG_MOUSE=m
++# CONFIG_PSMOUSE is not set
++# CONFIG_82C710_MOUSE is not set
++# CONFIG_PC110_PAD 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
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++CONFIG_SA1100_RTC=m
++# 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
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++# CONFIG_PCMCIA_SERIAL_CS is not set
++# CONFIG_MWAVE is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA 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_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_BFS_FS is not set
++# CONFIG_CMS_FS is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_JBD is not set
++# CONFIG_JBD_DEBUG is not set
++CONFIG_FAT_FS=m
++CONFIG_MSDOS_FS=m
++# CONFIG_UMSDOS_FS is not set
++CONFIG_VFAT_FS=m
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_CRAMFS=m
++# CONFIG_TMPFS is not set
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_ZISOFS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_FREEVXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++# CONFIG_ROOT_NFS is not set
++CONFIG_NFSD=m
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=y
++CONFIG_SMB_FS=m
++# CONFIG_SMB_NLS_DEFAULT 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_ZLIB_FS_INFLATE=m
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++CONFIG_SMB_NLS=y
++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_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
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_ANAKIN is not set
++# CONFIG_FB_CLPS711X is not set
++CONFIG_FB_SA1100=y
++# CONFIG_FB_CYBER2000 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 is not set
++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 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++
++#
++# Sound
++#
++CONFIG_SOUND=y
++# 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_ICH is not set
++# CONFIG_SOUND_RME96XX is not set
++# CONFIG_SOUND_SONICVIBES 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_SA1100=y
++CONFIG_SOUND_UDA1341=y
++# CONFIG_SOUND_ASSABET_UDA1341 is not set
++CONFIG_SOUND_H3600_UDA1341=y
++# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
++# CONFIG_SOUND_SA1111_UDA1341 is not set
++# CONFIG_SOUND_SA1100SSP is not set
++# CONFIG_SOUND_OSS is not set
++# CONFIG_SOUND_WAVEARTIST is not set
++# CONFIG_SOUND_TVMIXER is not set
++
++#
++# Multimedia Capabilities Port drivers
++#
++# CONFIG_MCP is not set
++# CONFIG_MCP_SA1100 is not set
++# CONFIG_MCP_UCB1200 is not set
++# CONFIG_MCP_UCB1200_AUDIO is not set
++# CONFIG_MCP_UCB1200_TS is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# USB Controllers
++#
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++# CONFIG_USB_OHCI is not set
++# CONFIG_USB_OHCI_SA1111 is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++# 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_JUMPSHOT is not set
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# USB Human Interface Devices (HID)
++#
++
++#
++# Input core support is needed for USB HID
++#
++
++#
++# 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_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
++# CONFIG_USB_SERIAL_GENERIC is not set
++# CONFIG_USB_SERIAL_BELKIN is not set
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
++# CONFIG_USB_SERIAL_EMPEG is not set
++# CONFIG_USB_SERIAL_FTDI_SIO is not set
++# CONFIG_USB_SERIAL_VISOR is not set
++# CONFIG_USB_SERIAL_IR is not set
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
++# CONFIG_USB_SERIAL_MCT_U232 is not set
++# CONFIG_USB_SERIAL_PL2303 is not set
++# CONFIG_USB_SERIAL_CYBERJACK is not set
++# CONFIG_USB_SERIAL_XIRCOM is not set
++# CONFIG_USB_SERIAL_OMNINET is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_ID75 is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++# CONFIG_DEBUG_USER is not set
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_DEBUG_SLAB is not set
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_NO_PGT_CACHE is not set
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/hackkit_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/hackkit_defconfig 2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/hackkit_defconfig 2003-09-27 11:38:18.625696848 +0800
+@@ -0,0 +1,654 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++CONFIG_MMU=y
++CONFIG_SWAP=y
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++
++#
++# General setup
++#
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODULE_UNLOAD is not set
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_ADIFCC is not set
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_IOP310 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++
++#
++# CLPS711X/EP721X Implementations
++#
++
++#
++# Epxa10db
++#
++
++#
++# Footbridge Implementations
++#
++
++#
++# IOP310 Implementation Options
++#
++
++#
++# IOP310 Chipset Features
++#
++
++#
++# Intel PXA250/210 Implementations
++#
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_H3100 is not set
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_H3800 is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_BADGE4 is not set
++# CONFIG_SA1100_JORNADA720 is not set
++CONFIG_SA1100_HACKKIT=y
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_PT_SYSTEM3 is not set
++# CONFIG_SA1100_SHANNON is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++# CONFIG_SA1100_STORK is not set
++# CONFIG_SA1100_USB is not set
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_SA1100=y
++CONFIG_CPU_32v4=y
++
++#
++# Processor Features
++#
++
++#
++# General setup
++#
++CONFIG_DISCONTIGMEM=y
++CONFIG_ISA=y
++# CONFIG_ZBOOT_ROM is not set
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_CPU_FREQ=y
++CONFIG_CPU_FREQ_24_API=y
++CONFIG_CPU_FREQ_26_API=y
++# CONFIG_HOTPLUG is not set
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_PREEMPT is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="console=ttySA0,115200 root=/dev/ram0 initrd=0xc0400000,8M init=/rootshell"
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++CONFIG_MTD_DEBUG=y
++CONFIG_MTD_DEBUG_VERBOSE=3
++# CONFIG_MTD_PARTITIONS is not set
++# CONFIG_MTD_CONCAT 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 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
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_EDB7312 is not set
++
++#
++# Self-contained MTD device drivers
++#
++# 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
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# CONFIG_BLK_DEV_XD is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=8192
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++# CONFIG_NETLINK_DEV is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++# CONFIG_IP_PNP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_ARPD is not set
++CONFIG_INET_ECN=y
++CONFIG_SYN_COOKIES=y
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_XFRM_USER is not set
++# CONFIG_IPV6 is not set
++
++#
++# SCTP Configuration (EXPERIMENTAL)
++#
++CONFIG_IPV6_SCTP__=y
++# CONFIG_IP_SCTP is not set
++# CONFIG_ATM is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_LLC is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB 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
++
++#
++# Network device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++CONFIG_DUMMY=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)
++#
++# CONFIG_NET_ETHERNET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++
++#
++# Wireless LAN (non-hamradio)
++#
++CONFIG_NET_RADIO=y
++# CONFIG_STRIP is not set
++# CONFIG_ARLAN is not set
++# CONFIG_AIRONET4500 is not set
++
++#
++# Wireless ISA/PCI cards support
++#
++# CONFIG_WAVELAN is not set
++# CONFIG_AIRO is not set
++# CONFIG_HERMES is not set
++CONFIG_NET_WIRELESS=y
++
++#
++# Token Ring devices (depends on LLC=y)
++#
++# CONFIG_NET_FC is not set
++# CONFIG_SHAPER is not set
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# ATA/ATAPI/MFM/RLL support
++#
++# CONFIG_IDE is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN_BOOL is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_TSDEV is not set
++# CONFIG_INPUT_TSLIBDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input I/O drivers
++#
++# CONFIG_GAMEPORT is not set
++CONFIG_SOUND_GAMEPORT=y
++CONFIG_SERIO=y
++# CONFIG_SERIO_I8042 is not set
++CONFIG_SERIO_SERPORT=y
++# CONFIG_SERIO_CT82C710 is not set
++
++#
++# Input Device Drivers
++#
++# CONFIG_INPUT_KEYBOARD is not set
++# CONFIG_INPUT_MOUSE is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_GEN_RTC is not set
++CONFIG_SA1100_RTC=y
++# 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
++# CONFIG_DRM is not set
++# CONFIG_RAW_DRIVER is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_JBD is not set
++CONFIG_FAT_FS=y
++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_CRAMFS=y
++CONFIG_TMPFS=y
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_HPFS_FS is not set
++CONFIG_PROC_FS=y
++# CONFIG_DEVFS_FS is not set
++CONFIG_DEVPTS_FS=y
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_XFS_FS is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
++# CONFIG_NFS_FS is not set
++# CONFIG_NFSD is not set
++# CONFIG_EXPORTFS is not set
++# CONFIG_CIFS is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED 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
++
++#
++# Console drivers
++#
++# CONFIG_VGA_CONSOLE is not set
++
++#
++# Frame-buffer support
++#
++# CONFIG_FB is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# Misc devices
++#
++
++#
++# Multimedia Capabilities Port drivers
++#
++# CONFIG_MCP is not set
++
++#
++# Console Switches
++#
++# CONFIG_SWITCHES is not set
++
++#
++# USB support
++#
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++CONFIG_DEBUG_KERNEL=y
++CONFIG_DEBUG_SLAB=y
++CONFIG_MAGIC_SYSRQ=y
++CONFIG_DEBUG_SPINLOCK=y
++CONFIG_DEBUG_WAITQ=y
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_KALLSYMS=y
++CONFIG_DEBUG_LL=y
++
++#
++# Security options
++#
++CONFIG_SECURITY_CAPABILITIES=y
++
++#
++# Cryptographic options
++#
++# CONFIG_CRYPTO is not set
++
++#
++# Library routines
++#
++# CONFIG_CRC32 is not set
++CONFIG_ZLIB_INFLATE=y
+Index: linux-2.6.0-test5/arch/arm/configs/huw_webpanel_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/huw_webpanel_defconfig 2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/huw_webpanel_defconfig 2003-09-27 11:38:18.626696696 +0800
+@@ -0,0 +1,435 @@
++#
++# Automatically generated by make menuconfig: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_CLPS711X is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Footbridge Implementations
++#
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++CONFIG_SA1100_HUW_WEBPANEL=y
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_BITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_YOPY is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_USB is not set
++# CONFIG_SA1100_FREQUENCY_SCALE is not set
++# CONFIG_SA1100_VOLTAGE_SCALE is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++CONFIG_CPU_32v4=y
++CONFIG_CPU_SA1100=y
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++# CONFIG_ANGELBOOT is not set
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++# CONFIG_HOTPLUG is not set
++# CONFIG_PCMCIA is not set
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_NWFPE=y
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="keepinitrd mem=32480K root=/dev/ram initrd=0xc0800000,8M"
++# CONFIG_LEDS is not set
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_DOC1000 is not set
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOCPROBE is not set
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_MTDRAM is not set
++CONFIG_MTD_CFI=y
++CONFIG_MTD_CFI_GEOMETRY=y
++# CONFIG_MTD_CFI_B1 is not set
++# CONFIG_MTD_CFI_B2 is not set
++CONFIG_MTD_CFI_B4=y
++# CONFIG_MTD_CFI_I1 is not set
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_PNC2000 is not set
++# CONFIG_MTD_RPXLITE is not set
++# CONFIG_MTD_SBC_MEDIAGX is not set
++# CONFIG_MTD_ELAN_104NC is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_JEDEC is not set
++# CONFIG_MTD_MIXMEM is not set
++# CONFIG_MTD_OCTAGON is not set
++# CONFIG_MTD_VMAX is not set
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_NAND_SPIA is not set
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL 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_BLK_DEV_DAC960 is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=8192
++CONFIG_BLK_DEV_INITRD=y
++# CONFIG_BLK_DEV_FLASH is not set
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++# CONFIG_NETLINK 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 is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE 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
++# CONFIG_ATM is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK 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 device support
++#
++# CONFIG_NETDEVICES is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++# CONFIG_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O 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
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++# CONFIG_INPUT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=115200
++CONFIG_TOUCHSCREEN_UCB1200=y
++# CONFIG_TOUCHSCREEN_BITSY is not set
++# CONFIG_PROFILER is not set
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_SA1100_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
++# CONFIG_DRM is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS 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_BFS_FS 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_CRAMFS=y
++# CONFIG_RAMFS is not set
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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=y
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_SYSV_FS_WRITE 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
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_NFS_FS is not set
++# CONFIG_NFS_V3 is not set
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++# CONFIG_SUNRPC is not set
++# CONFIG_LOCKD is not set
++# 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_MOUNT_SUBDIR is not set
++# CONFIG_NCPFS_NDS_DOMAINS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_NLS is not set
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_FB=y
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_CLPS711X is not set
++# CONFIG_FB_CYBER2000 is not set
++CONFIG_FB_SA1100=y
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FBCON_ADVANCED is not set
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++CONFIG_FBCON_FONTWIDTH8_ONLY=y
++CONFIG_FBCON_FONTS=y
++CONFIG_FONT_8x8=y
++# CONFIG_FONT_8x16 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_DEBUG_LL is not set
+Index: linux-2.6.0-test5/arch/arm/configs/integrator_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/integrator_defconfig 2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/integrator_defconfig 2003-09-27 11:38:18.628696392 +0800
+@@ -0,0 +1,663 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++CONFIG_ARCH_INTEGRATOR=y
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_ANAKIN is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_BITSY is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++CONFIG_CPU_ARM720T=y
++CONFIG_CPU_ARM920T=y
++CONFIG_CPU_ARM920_CPU_IDLE=y
++CONFIG_CPU_ARM920_I_CACHE_ON=y
++CONFIG_CPU_ARM920_D_CACHE_ON=y
++# CONFIG_CPU_ARM920_WRITETHROUGH is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++# CONFIG_CPU_SA1100 is not set
++# CONFIG_DISCONTIGMEM is not set
++
++#
++# General setup
++#
++CONFIG_PCI_INTEGRATOR=y
++CONFIG_PCI=y
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++CONFIG_CPU_CLOCK=y
++CONFIG_PCI_NAMES=y
++# CONFIG_HOTPLUG is not set
++# CONFIG_PCMCIA is not set
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++# CONFIG_FPE_NWFPE is not set
++CONFIG_FPE_FASTFPE=y
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++CONFIG_PM=y
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="root=1f03 mem=32M"
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_BOOTLDR_PARTS is not set
++CONFIG_MTD_AFS_PARTS=y
++
++#
++# 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_CFI_VIRTUAL_ER is not set
++CONFIG_MTD_CFI_ADV_OPTIONS=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LART_BIT_SWAP is not set
++# CONFIG_MTD_CFI_GEOMETRY is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_JEDEC is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_SUN_UFLASH is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_PNC2000 is not set
++# CONFIG_MTD_RPXLITE is not set
++# CONFIG_MTD_SC520CDP is not set
++# CONFIG_MTD_NETSC520 is not set
++# CONFIG_MTD_SBC_GXX is not set
++# CONFIG_MTD_ELAN_104NC is not set
++# CONFIG_MTD_SA1100 is not set
++# CONFIG_MTD_SA1100_REDBOOT_PARTITIONS is not set
++# CONFIG_MTD_SA1100_BOOTLDR_PARTITIONS is not set
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++# CONFIG_MTD_DBOX2 is not set
++# CONFIG_MTD_CSTM_MIPS_IXX is not set
++# CONFIG_MTD_CFI_FLAGADM is not set
++# CONFIG_MTD_MIXMEM is not set
++# CONFIG_MTD_OCTAGON is not set
++# CONFIG_MTD_VMAX is not set
++CONFIG_MTD_ARMFLASH=y
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_MTDRAM 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
++# CONFIG_MTD_NAND_SPIA 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_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++# CONFIG_BLK_DEV_INITRD 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_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++CONFIG_NETLINK=y
++# CONFIG_RTNETLINK is not set
++# 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=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_INET_ECN=y
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++
++#
++#
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK 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 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
++# CONFIG_NET_SB1000 is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# 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_AT1700 is not set
++# CONFIG_DEPCA is not set
++# CONFIG_HP100 is not set
++# CONFIG_NET_ISA is not set
++CONFIG_NET_PCI=y
++# CONFIG_PCNET32 is not set
++# CONFIG_ADAPTEC_STARFIRE is not set
++# CONFIG_APRICOT is not set
++# CONFIG_CS89x0 is not set
++# CONFIG_TULIP is not set
++# CONFIG_DE4X5 is not set
++# CONFIG_DGRS is not set
++# CONFIG_DM9102 is not set
++CONFIG_EEPRO100=y
++CONFIG_EEPRO100_PM=y
++# CONFIG_LNE390 is not set
++# CONFIG_FEALNX is not set
++# CONFIG_NATSEMI is not set
++# CONFIG_NE2K_PCI is not set
++# CONFIG_NE3210 is not set
++# CONFIG_ES3210 is not set
++# CONFIG_8139TOO is not set
++# CONFIG_8139TOO_PIO is not set
++# CONFIG_8139TOO_TUNE_TWISTER is not set
++# CONFIG_8139TOO_8129 is not set
++# CONFIG_SIS900 is not set
++# CONFIG_EPIC100 is not set
++# CONFIG_SUNDANCE is not set
++# CONFIG_TLAN is not set
++# CONFIG_VIA_RHINE is not set
++# CONFIG_WINBOND_840 is not set
++# CONFIG_HAPPYMEAL is not set
++# CONFIG_NET_POCKET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI 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
++
++#
++# ATA/IDE/MFM/RLL support
++#
++# CONFIG_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# IEEE 1394 (FireWire) support
++#
++# 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
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++# CONFIG_INPUT 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 is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_SA1100 is not set
++# CONFIG_SERIAL_SA1100_CONSOLE is not set
++CONFIG_SERIAL_AMBA=y
++CONFIG_SERIAL_AMBA_CONSOLE=y
++CONFIG_SERIAL_INTEGRATOR=y
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++CONFIG_MOUSE=y
++CONFIG_PSMOUSE=y
++# CONFIG_82C710_MOUSE is not set
++# CONFIG_PC110_PAD is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++
++#
++# Input core support is needed for joysticks
++#
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG 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
++# CONFIG_DRM is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA 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_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_BFS_FS 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=y
++CONFIG_JFFS2_FS_DEBUG=0
++# CONFIG_CRAMFS is not set
++# CONFIG_TMPFS is not set
++# CONFIG_RAMFS is not set
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++CONFIG_MINIX_FS=y
++# CONFIG_VXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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=y
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_SYSV_FS_WRITE 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
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++CONFIG_ROOT_NFS=y
++CONFIG_NFSD=y
++CONFIG_NFSD_V3=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
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++# CONFIG_MSDOS_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_SMB_NLS is not set
++# CONFIG_NLS is not set
++
++#
++# Console drivers
++#
++CONFIG_KMI_KEYB=y
++CONFIG_KMI_MOUSE=y
++CONFIG_PC_KEYMAP=y
++CONFIG_VGA_CONSOLE=y
++CONFIG_FB=y
++
++#
++# 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_ACORN is not set
++# CONFIG_FB_CLPS711X is not set
++# CONFIG_FB_CYBER2000 is not set
++# CONFIG_FB_SA1100 is not set
++# CONFIG_FB_ANAKIN is not set
++# CONFIG_FB_E1355 is not set
++# CONFIG_FB_MATROX is not set
++# CONFIG_FB_ATY is not set
++# CONFIG_FB_ATY128 is not set
++# CONFIG_FB_3DFX is not set
++# CONFIG_FB_SIS is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FBCON_ADVANCED is not set
++# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
++CONFIG_FBCON_FONTS=y
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_SUN12x22 is not set
++# CONFIG_FONT_6x11 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_NO_PGT_CACHE is not set
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/iq80310_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/iq80310_defconfig 2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/iq80310_defconfig 2003-09-27 11:38:18.629696240 +0800
+@@ -0,0 +1,770 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++CONFIG_MMU=y
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++
++#
++# General setup
++#
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_EMBEDDED is not set
++CONFIG_KALLSYMS=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODULE_UNLOAD is not set
++CONFIG_OBSOLETE_MODPARM=y
++# CONFIG_MODVERSIONS is not set
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_ADIFCC is not set
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++CONFIG_ARCH_IOP3XX=y
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_SHARK is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++
++#
++# Epxa10db
++#
++
++#
++# Footbridge Implementations
++#
++
++#
++# IOP3xx Implementation Options
++#
++CONFIG_ARCH_IQ80310=y
++# CONFIG_ARCH_IQ80321 is not set
++CONFIG_ARCH_IOP310=y
++# CONFIG_ARCH_IOP321 is not set
++
++#
++# IOP3xx Chipset Features
++#
++# CONFIG_IOP3XX_AAU is not set
++# CONFIG_IOP3XX_DMA is not set
++# CONFIG_IOP3XX_MU is not set
++# CONFIG_IOP3XX_PMON is not set
++
++#
++# ADIFCC Implementation Options
++#
++
++#
++# ADI Board Types
++#
++
++#
++# Intel PXA250/210 Implementations
++#
++
++#
++# SA11x0 Implementations
++#
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_XSCALE=y
++CONFIG_XS80200=y
++CONFIG_CPU_32v5=y
++
++#
++# Processor Features
++#
++CONFIG_ARM_THUMB=y
++CONFIG_XSCALE_PMU=y
++
++#
++# General setup
++#
++CONFIG_PCI=y
++# CONFIG_ZBOOT_ROM is not set
++CONFIG_ZBOOT_ROM_TEXT=0x00060000
++CONFIG_ZBOOT_ROM_BSS=0xa1008000
++# CONFIG_PCI_LEGACY_PROC is not set
++CONFIG_PCI_NAMES=y
++# CONFIG_HOTPLUG is not set
++
++#
++# MMC/SD Card support
++#
++# CONFIG_MMC is not set
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_NWFPE_XP is not set
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_PREEMPT is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="console=ttyS0,115200 ip=bootp mem=32M root=/dev/nfs initrd=0xc0800000,4M"
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT 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=y
++# CONFIG_MTD_CMDLINE_PARTS is not set
++# CONFIG_MTD_AFS_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
++# CONFIG_INFTL 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 is not set
++# 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
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++CONFIG_MTD_IQ80310=y
++# CONFIG_MTD_EDB7312 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_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++
++#
++# Plug and Play support
++#
++# CONFIG_PNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# CONFIG_BLK_CPQ_DA is not set
++# CONFIG_BLK_CPQ_CISS_DA is not set
++# CONFIG_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_UMEM is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=8192
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++
++#
++# Networking support
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++# CONFIG_NETLINK_DEV is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++CONFIG_UNIX=y
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# 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_ARPD is not set
++# CONFIG_INET_ECN is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP 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_XFRM_USER is not set
++
++#
++# SCTP Configuration (EXPERIMENTAL)
++#
++CONFIG_IPV6_SCTP__=y
++# CONFIG_IP_SCTP is not set
++# CONFIG_ATM is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_LLC is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB 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
++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_MII=y
++# CONFIG_SMC91X is not set
++# CONFIG_HAPPYMEAL is not set
++# CONFIG_SUNGEM is not set
++# CONFIG_NET_VENDOR_3COM is not set
++
++#
++# Tulip family network device support
++#
++# CONFIG_NET_TULIP is not set
++# CONFIG_HP100 is not set
++CONFIG_NET_PCI=y
++# CONFIG_PCNET32 is not set
++# CONFIG_AMD8111_ETH is not set
++# CONFIG_ADAPTEC_STARFIRE is not set
++# CONFIG_B44 is not set
++# CONFIG_DGRS is not set
++CONFIG_EEPRO100=y
++# CONFIG_EEPRO100_PIO is not set
++# CONFIG_E100 is not set
++# CONFIG_FEALNX is not set
++# CONFIG_NATSEMI is not set
++# CONFIG_NE2K_PCI is not set
++# CONFIG_8139CP is not set
++# CONFIG_8139TOO is not set
++# CONFIG_SIS900 is not set
++# CONFIG_EPIC100 is not set
++# CONFIG_SUNDANCE is not set
++# CONFIG_TLAN is not set
++# CONFIG_VIA_RHINE is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K is not set
++# CONFIG_E1000 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
++
++#
++# Ethernet (10000 Mbit)
++#
++# CONFIG_IXGB is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI 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 (depends on LLC=y)
++#
++# CONFIG_RCPCI is not set
++# CONFIG_SHAPER is not set
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# ATA/ATAPI/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 is not set
++CONFIG_BLK_DEV_IDEDISK=y
++# CONFIG_IDEDISK_MULTI_MODE is not set
++# CONFIG_IDEDISK_STROKE is not set
++CONFIG_BLK_DEV_IDECD=y
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_IDE_TASK_IOCTL is not set
++# CONFIG_IDE_TASKFILE_IO is not set
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_BLK_DEV_IDEPCI is not set
++
++#
++# SCSI device support
++#
++# CONFIG_SCSI is not set
++
++#
++# IEEE 1394 (FireWire) support (EXPERIMENTAL)
++#
++# CONFIG_IEEE1394 is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN_BOOL is not set
++
++#
++# Input device support
++#
++# CONFIG_INPUT is not set
++
++#
++# Userland interfaces
++#
++
++#
++# Input I/O drivers
++#
++# CONFIG_GAMEPORT is not set
++CONFIG_SOUND_GAMEPORT=y
++# CONFIG_SERIO is not set
++
++#
++# Input Device Drivers
++#
++
++#
++# Character devices
++#
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_DZ is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# I2C Hardware Sensors Mainboard support
++#
++
++#
++# I2C Hardware Sensors Chip support
++#
++# CONFIG_I2C_SENSOR is not set
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# IPMI
++#
++# CONFIG_IPMI_HANDLER is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_GEN_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
++# CONFIG_DRM is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_HANGCHECK_TIMER is not set
++
++#
++# Multimedia devices
++#
++CONFIG_VIDEO_DEV=y
++
++#
++# Video For Linux
++#
++# CONFIG_VIDEO_PROC_FS is not set
++
++#
++# Video Adapters
++#
++# CONFIG_VIDEO_PMS is not set
++# CONFIG_VIDEO_CPIA is not set
++# CONFIG_VIDEO_STRADIS is not set
++# CONFIG_VIDEO_HEXIUM_ORION is not set
++# CONFIG_VIDEO_HEXIUM_GEMINI is not set
++
++#
++# Radio Adapters
++#
++# CONFIG_RADIO_GEMTEK_PCI is not set
++# CONFIG_RADIO_MAXIRADIO is not set
++# CONFIG_RADIO_MAESTRO is not set
++
++#
++# Digital Video Broadcasting Devices
++#
++CONFIG_DVB=y
++CONFIG_DVB_CORE=y
++
++#
++# Supported Frontend Modules
++#
++# CONFIG_DVB_STV0299 is not set
++# CONFIG_DVB_ALPS_BSRV2 is not set
++# CONFIG_DVB_ALPS_TDLB7 is not set
++# CONFIG_DVB_ALPS_TDMB7 is not set
++# CONFIG_DVB_ATMEL_AT76C651 is not set
++# CONFIG_DVB_CX24110 is not set
++# CONFIG_DVB_GRUNDIG_29504_491 is not set
++# CONFIG_DVB_GRUNDIG_29504_401 is not set
++# CONFIG_DVB_MT312 is not set
++# CONFIG_DVB_VES1820 is not set
++# CONFIG_DVB_TDA1004X is not set
++
++#
++# Supported SAA7146 based PCI Adapters
++#
++# CONFIG_DVB_AV7110 is not set
++# CONFIG_DVB_BUDGET is not set
++
++#
++# Supported FlexCopII (B2C2) Adapters
++#
++# CONFIG_DVB_B2C2_SKYSTAR is not set
++# CONFIG_VIDEO_BTCX is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_JBD is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++# CONFIG_FAT_FS is not set
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++# CONFIG_DEVFS_FS is not set
++CONFIG_DEVPTS_FS=y
++# CONFIG_DEVPTS_FS_XATTR is not set
++CONFIG_TMPFS=y
++CONFIG_RAMFS=y
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++# CONFIG_JFFS2_FS_NAND is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++
++#
++# Network File Systems
++#
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++# CONFIG_NFS_V4 is not set
++# CONFIG_NFSD is not set
++CONFIG_ROOT_NFS=y
++CONFIG_LOCKD=y
++# CONFIG_EXPORTFS is not set
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_GSS is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_NEC98_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++
++#
++# Graphics support
++#
++# CONFIG_FB is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# Misc devices
++#
++
++#
++# Multimedia Capabilities Port drivers
++#
++# CONFIG_MCP is not set
++
++#
++# Console Switches
++#
++# CONFIG_SWITCHES is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++# CONFIG_USB_GADGET is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SLAB is not set
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_WAITQ is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_LL=y
++
++#
++# Security options
++#
++# CONFIG_SECURITY is not set
++
++#
++# Cryptographic options
++#
++# CONFIG_CRYPTO is not set
++
++#
++# Library routines
++#
++# CONFIG_CRC32 is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
+Index: linux-2.6.0-test5/arch/arm/configs/iq80321_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/iq80321_defconfig 2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/iq80321_defconfig 2003-09-27 11:38:18.631695936 +0800
+@@ -0,0 +1,776 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++CONFIG_MMU=y
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++
++#
++# General setup
++#
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_EMBEDDED is not set
++CONFIG_KALLSYMS=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODULE_UNLOAD is not set
++CONFIG_OBSOLETE_MODPARM=y
++# CONFIG_MODVERSIONS is not set
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_ADIFCC is not set
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++CONFIG_ARCH_IOP3XX=y
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_SHARK is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++
++#
++# Epxa10db
++#
++
++#
++# Footbridge Implementations
++#
++
++#
++# IOP3xx Implementation Options
++#
++# CONFIG_ARCH_IQ80310 is not set
++CONFIG_ARCH_IQ80321=y
++# CONFIG_ARCH_IOP310 is not set
++CONFIG_ARCH_IOP321=y
++
++#
++# IOP3xx Chipset Features
++#
++# CONFIG_IOP3XX_AAU is not set
++# CONFIG_IOP3XX_DMA is not set
++# CONFIG_IOP3XX_MU is not set
++# CONFIG_IOP3XX_PMON is not set
++
++#
++# ADIFCC Implementation Options
++#
++
++#
++# ADI Board Types
++#
++
++#
++# Intel PXA250/210 Implementations
++#
++
++#
++# SA11x0 Implementations
++#
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_XSCALE=y
++CONFIG_CPU_32v5=y
++
++#
++# Processor Features
++#
++# CONFIG_ARM_THUMB is not set
++CONFIG_XSCALE_PMU=y
++
++#
++# General setup
++#
++CONFIG_PCI=y
++# CONFIG_ZBOOT_ROM is not set
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++# CONFIG_PCI_LEGACY_PROC is not set
++CONFIG_PCI_NAMES=y
++# CONFIG_HOTPLUG is not set
++
++#
++# MMC/SD Card support
++#
++# CONFIG_MMC is not set
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_NWFPE_XP is not set
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_PREEMPT is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200 mem=128M@0xa0000000"
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT 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=y
++# CONFIG_MTD_CMDLINE_PARTS is not set
++# CONFIG_MTD_AFS_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
++# CONFIG_INFTL 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 is not set
++# 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
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_EDB7312 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_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++
++#
++# Plug and Play support
++#
++# CONFIG_PNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# CONFIG_BLK_CPQ_DA is not set
++# CONFIG_BLK_CPQ_CISS_DA is not set
++# CONFIG_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_UMEM is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=8192
++# CONFIG_BLK_DEV_INITRD is not set
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++
++#
++# Networking support
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++# CONFIG_NETLINK_DEV is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++CONFIG_UNIX=y
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# 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_ARPD is not set
++# CONFIG_INET_ECN is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP 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_XFRM_USER is not set
++
++#
++# SCTP Configuration (EXPERIMENTAL)
++#
++CONFIG_IPV6_SCTP__=y
++# CONFIG_IP_SCTP is not set
++# CONFIG_ATM is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_LLC is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB 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
++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_MII is not set
++# CONFIG_SMC91X is not set
++# CONFIG_HAPPYMEAL is not set
++# CONFIG_SUNGEM is not set
++# CONFIG_NET_VENDOR_3COM is not set
++
++#
++# Tulip family network device support
++#
++# CONFIG_NET_TULIP is not set
++# CONFIG_HP100 is not set
++CONFIG_NET_PCI=y
++# CONFIG_PCNET32 is not set
++# CONFIG_AMD8111_ETH is not set
++# CONFIG_ADAPTEC_STARFIRE is not set
++# CONFIG_B44 is not set
++# CONFIG_DGRS is not set
++CONFIG_EEPRO100=y
++# CONFIG_EEPRO100_PIO is not set
++# CONFIG_E100 is not set
++# CONFIG_FEALNX is not set
++# CONFIG_NATSEMI is not set
++# CONFIG_NE2K_PCI is not set
++# CONFIG_8139CP is not set
++# CONFIG_8139TOO is not set
++# CONFIG_SIS900 is not set
++# CONFIG_EPIC100 is not set
++# CONFIG_SUNDANCE is not set
++# CONFIG_TLAN is not set
++# CONFIG_VIA_RHINE is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K is not set
++CONFIG_E1000=y
++CONFIG_E1000_NAPI=y
++# 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
++
++#
++# Ethernet (10000 Mbit)
++#
++# CONFIG_IXGB is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI 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 (depends on LLC=y)
++#
++# CONFIG_RCPCI is not set
++# CONFIG_SHAPER is not set
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# ATA/ATAPI/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 is not set
++CONFIG_BLK_DEV_IDEDISK=y
++# CONFIG_IDEDISK_MULTI_MODE is not set
++# CONFIG_IDEDISK_STROKE is not set
++CONFIG_BLK_DEV_IDECD=y
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_IDE_TASK_IOCTL is not set
++# CONFIG_IDE_TASKFILE_IO is not set
++
++#
++# IDE chipset support/bugfixes
++#
++CONFIG_BLK_DEV_IDEPCI=y
++# CONFIG_BLK_DEV_GENERIC is not set
++# CONFIG_IDEPCI_SHARE_IRQ is not set
++CONFIG_BLK_DEV_IDEDMA_PCI=y
++# CONFIG_BLK_DEV_IDE_TCQ is not set
++# CONFIG_BLK_DEV_OFFBOARD is not set
++# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
++CONFIG_IDEDMA_PCI_AUTO=y
++# CONFIG_IDEDMA_ONLYDISK is not set
++CONFIG_BLK_DEV_IDEDMA=y
++# CONFIG_IDEDMA_PCI_WIP is not set
++CONFIG_BLK_DEV_ADMA=y
++# CONFIG_BLK_DEV_AEC62XX is not set
++# CONFIG_BLK_DEV_ALI15X3 is not set
++# CONFIG_BLK_DEV_AMD74XX is not set
++CONFIG_BLK_DEV_CMD64X=y
++# CONFIG_BLK_DEV_TRIFLEX is not set
++# CONFIG_BLK_DEV_CY82C693 is not set
++# CONFIG_BLK_DEV_CS5520 is not set
++# CONFIG_BLK_DEV_HPT34X is not set
++# CONFIG_BLK_DEV_HPT366 is not set
++# CONFIG_BLK_DEV_SC1200 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 is not set
++# CONFIG_BLK_DEV_PDC202XX_NEW is not set
++# CONFIG_BLK_DEV_SVWKS is not set
++# CONFIG_BLK_DEV_SIIMAGE 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_BLK_DEV_SL82C105 is not set
++CONFIG_IDEDMA_AUTO=y
++# CONFIG_IDEDMA_IVB is not set
++
++#
++# SCSI device support
++#
++# CONFIG_SCSI is not set
++
++#
++# IEEE 1394 (FireWire) support (EXPERIMENTAL)
++#
++# CONFIG_IEEE1394 is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN_BOOL is not set
++
++#
++# Input device support
++#
++# CONFIG_INPUT is not set
++
++#
++# Userland interfaces
++#
++
++#
++# Input I/O drivers
++#
++# CONFIG_GAMEPORT is not set
++CONFIG_SOUND_GAMEPORT=y
++# CONFIG_SERIO is not set
++
++#
++# Input Device Drivers
++#
++
++#
++# Character devices
++#
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_DZ is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# I2C Hardware Sensors Mainboard support
++#
++
++#
++# I2C Hardware Sensors Chip support
++#
++# CONFIG_I2C_SENSOR is not set
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# IPMI
++#
++# CONFIG_IPMI_HANDLER is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_GEN_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
++# CONFIG_DRM is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_HANGCHECK_TIMER is not set
++
++#
++# Multimedia devices
++#
++CONFIG_VIDEO_DEV=y
++
++#
++# Video For Linux
++#
++# CONFIG_VIDEO_PROC_FS is not set
++
++#
++# Video Adapters
++#
++# CONFIG_VIDEO_PMS is not set
++# CONFIG_VIDEO_CPIA is not set
++# CONFIG_VIDEO_STRADIS is not set
++# CONFIG_VIDEO_HEXIUM_ORION is not set
++# CONFIG_VIDEO_HEXIUM_GEMINI is not set
++
++#
++# Radio Adapters
++#
++# CONFIG_RADIO_GEMTEK_PCI is not set
++# CONFIG_RADIO_MAXIRADIO is not set
++# CONFIG_RADIO_MAESTRO is not set
++
++#
++# Digital Video Broadcasting Devices
++#
++# CONFIG_DVB is not set
++# CONFIG_VIDEO_BTCX is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_JBD is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++# CONFIG_FAT_FS is not set
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++# CONFIG_DEVFS_FS is not set
++CONFIG_DEVPTS_FS=y
++# CONFIG_DEVPTS_FS_XATTR is not set
++CONFIG_TMPFS=y
++CONFIG_RAMFS=y
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++# CONFIG_JFFS2_FS_NAND is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++
++#
++# Network File Systems
++#
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++# CONFIG_NFS_V4 is not set
++# CONFIG_NFSD is not set
++CONFIG_ROOT_NFS=y
++CONFIG_LOCKD=y
++# CONFIG_EXPORTFS is not set
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_GSS is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_NEC98_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++
++#
++# Graphics support
++#
++# CONFIG_FB is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# Misc devices
++#
++
++#
++# Multimedia Capabilities Port drivers
++#
++# CONFIG_MCP is not set
++
++#
++# Console Switches
++#
++# CONFIG_SWITCHES is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++# CONFIG_USB_GADGET is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++# CONFIG_DEBUG_USER is not set
++# CONFIG_DEBUG_INFO is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SLAB is not set
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_WAITQ is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_LL=y
++
++#
++# Security options
++#
++# CONFIG_SECURITY is not set
++
++#
++# Cryptographic options
++#
++# CONFIG_CRYPTO is not set
++
++#
++# Library routines
++#
++# CONFIG_CRC32 is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
+Index: linux-2.6.0-test5/arch/arm/configs/jornada720_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/jornada720_defconfig 2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/jornada720_defconfig 2003-09-27 11:38:18.632695784 +0800
+@@ -0,0 +1,897 @@
++#
++# Automatically generated by make menuconfig: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++# CONFIG_GENERIC_BUST_SPINLOCK is not set
++# CONFIG_GENERIC_ISA_DMA is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_H3100 is not set
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_H3800 is not set
++# CONFIG_SA1100_H3XXX is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++CONFIG_SA1100_JORNADA720=y
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_SHANNON is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++CONFIG_SA1111=y
++CONFIG_FORCE_MAX_ZONEORDER=9
++# CONFIG_SA1100_USB is not set
++# CONFIG_SA1100_USB_NETLINK is not set
++# CONFIG_SA1100_USB_CHAR is not set
++# CONFIG_REGISTERS is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_AUTCPU12 is not set
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM922T is not set
++# CONFIG_CPU_ARM926T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++# CONFIG_ARM_THUMB is not set
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++CONFIG_ISA=y
++# CONFIG_ISA_DMA is not set
++# CONFIG_CPU_FREQ is not set
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=y
++# CONFIG_I82092 is not set
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=y
++# CONFIG_MERCURY_BACKPAQ is not set
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_FPE_NWFPE=y
++CONFIG_FPE_FASTFPE=y
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=m
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++CONFIG_PM=y
++# CONFIG_APM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="keepinitrd mem=32M"
++# CONFIG_LEDS is not set
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++CONFIG_MTD_DEBUG=y
++CONFIG_MTD_DEBUG_VERBOSE=1
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++CONFIG_MTD_BOOTLDR_PARTS=y
++# CONFIG_MTD_AFS_PARTS is not set
++CONFIG_MTD_CHAR=m
++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=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++CONFIG_MTD_CFI_GEOMETRY=y
++# CONFIG_MTD_CFI_B1 is not set
++CONFIG_MTD_CFI_B2=y
++CONFIG_MTD_CFI_B4=y
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD 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_NORA is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_CDB89712 is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_H3600_BACKPAQ is not set
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 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
++# 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
++
++#
++# 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_BLK_DEV_DAC960 is not set
++CONFIG_BLK_DEV_LOOP=m
++CONFIG_BLK_DEV_NBD=m
++# CONFIG_BLK_DEV_RAM is not set
++# CONFIG_BLK_DEV_INITRD 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=y
++CONFIG_NETLINK=y
++CONFIG_RTNETLINK=y
++# 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 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_COMPAT_IPCHAINS is not set
++# CONFIG_IP_NF_COMPAT_IPFWADM is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK 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 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 is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K 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_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PLIP is not set
++CONFIG_PPP=m
++# CONFIG_PPP_MULTILINK is not set
++# CONFIG_PPP_FILTER is not set
++CONFIG_PPP_ASYNC=m
++# CONFIG_PPP_SYNC_TTY is not set
++CONFIG_PPP_DEFLATE=m
++CONFIG_PPP_BSDCOMP=m
++# CONFIG_PPPOE is not set
++# CONFIG_SLIP is not set
++
++#
++# Wireless LAN (non-hamradio)
++#
++CONFIG_NET_RADIO=y
++# CONFIG_STRIP is not set
++CONFIG_WAVELAN=m
++CONFIG_ARLAN=m
++CONFIG_AIRONET4500=m
++CONFIG_AIRONET4500_NONCS=m
++# CONFIG_AIRONET4500_PNP is not set
++# CONFIG_AIRONET4500_PCI is not set
++# CONFIG_AIRONET4500_ISA is not set
++# CONFIG_AIRONET4500_I365 is not set
++# CONFIG_AIRONET4500_PROC is not set
++# CONFIG_AIRO is not set
++CONFIG_HERMES=m
++CONFIG_PCMCIA_HERMES=m
++CONFIG_AIRO_CS=m
++CONFIG_NET_WIRELESS=y
++
++#
++# 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=y
++CONFIG_PCMCIA_3C589=m
++CONFIG_PCMCIA_3C574=m
++CONFIG_PCMCIA_FMVJ18X=m
++CONFIG_PCMCIA_PCNET=m
++CONFIG_PCMCIA_NMCLAN=m
++CONFIG_PCMCIA_SMC91C92=m
++CONFIG_PCMCIA_XIRC2PS=m
++# CONFIG_PCMCIA_AXNET is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++CONFIG_NET_PCMCIA_RADIO=y
++# CONFIG_PCMCIA_RAYCS is not set
++# CONFIG_PCMCIA_NETWAVE is not set
++CONFIG_PCMCIA_WAVELAN=m
++CONFIG_AIRONET4500_CS=m
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++CONFIG_IRDA=m
++CONFIG_IRLAN=m
++# CONFIG_IRNET is not set
++CONFIG_IRCOMM=m
++# CONFIG_IRDA_ULTRA is not set
++# CONFIG_IRDA_OPTIONS is not set
++
++#
++# Infrared-port device drivers
++#
++# CONFIG_IRTTY_SIR is not set
++# CONFIG_IRPORT_SIR is not set
++# CONFIG_DONGLE is not set
++# CONFIG_USB_IRDA is not set
++# CONFIG_NSC_FIR is not set
++# CONFIG_WINBOND_FIR is not set
++# CONFIG_TOSHIBA_FIR is not set
++# CONFIG_SMC_IRCC_FIR is not set
++# CONFIG_ALI_FIR is not set
++# CONFIG_VLSI_FIR is not set
++CONFIG_SA1100_FIR=m
++
++#
++# ATA/IDE/MFM/RLL support
++#
++CONFIG_IDE=m
++
++#
++# IDE, ATA and ATAPI Block devices
++#
++CONFIG_BLK_DEV_IDE=m
++# CONFIG_BLK_DEV_HD_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++CONFIG_BLK_DEV_IDEDISK=m
++# CONFIG_IDEDISK_MULTI_MODE is not set
++CONFIG_BLK_DEV_IDECS=m
++CONFIG_BLK_DEV_IDECD=m
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
++# CONFIG_BLK_DEV_ISAPNP is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++# CONFIG_BLK_DEV_ATARAID is not set
++# CONFIG_BLK_DEV_ATARAID_PDC is not set
++# CONFIG_BLK_DEV_ATARAID_HPT is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O 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
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_KEYBDEV is not set
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_SERIAL=m
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_ANAKIN is not set
++# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_UART00 is not set
++# CONFIG_SERIAL_UART00_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=115200
++# CONFIG_SERIAL_8250 is not set
++# CONFIG_SERIAL_8250_CONSOLE is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_MULTIPORT is not set
++# CONFIG_SERIAL_8250_HUB6 is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++# CONFIG_NEWTONKBD is not set
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++# CONFIG_L3_ALGOBIT is not set
++# CONFIG_L3_BIT_SA1100_GPIO is not set
++# CONFIG_L3_SA1111 is not set
++# CONFIG_BIT_SA1100_GPIO is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++CONFIG_MOUSE=m
++# CONFIG_PSMOUSE is not set
++# CONFIG_82C710_MOUSE is not set
++# CONFIG_PC110_PAD 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
++# 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
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++CONFIG_SA1100_RTC=m
++# 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
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++# CONFIG_PCMCIA_SERIAL_CS is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_V4L2_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA 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_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 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=y
++CONFIG_JFFS2_FS_DEBUG=2
++# CONFIG_CRAMFS is not set
++# CONFIG_TMPFS is not set
++CONFIG_RAMFS=y
++CONFIG_ISO9660_FS=m
++# CONFIG_JOLIET is not set
++# CONFIG_ZISOFS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG is not set
++# CONFIG_NTFS_RW is not set
++# CONFIG_HPFS_FS is not set
++CONFIG_PROC_FS=y
++CONFIG_DEVFS_FS=y
++CONFIG_DEVFS_MOUNT=y
++CONFIG_DEVFS_DEBUG=y
++# CONFIG_DRIVERFS_FS 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
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
++CONFIG_NFS_FS=m
++CONFIG_NFS_V3=y
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=m
++CONFIG_LOCKD=m
++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_ZLIB_FS_INFLATE 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
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_ANAKIN is not set
++# CONFIG_FB_CLPS711X is not set
++# CONFIG_FB_SA1100 is not set
++CONFIG_FB_EPSON1356=y
++# CONFIG_FB_CYBER2000 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 is not set
++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 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++
++#
++# Sound
++#
++CONFIG_SOUND=m
++# 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_ICH is not set
++# CONFIG_SOUND_RME96XX is not set
++# CONFIG_SOUND_SONICVIBES 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_SA1100=m
++# CONFIG_SOUND_UDA1341 is not set
++# CONFIG_SOUND_ASSABET_UDA1341 is not set
++# CONFIG_SOUND_H3600_UDA1341 is not set
++# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
++# CONFIG_SOUND_SA1111_UDA1341 is not set
++# CONFIG_SOUND_SA1100SSP is not set
++# CONFIG_SOUND_OSS is not set
++# CONFIG_SOUND_WAVEARTIST is not set
++# CONFIG_SOUND_TVMIXER is not set
++
++#
++# Multimedia Capabilities Port drivers
++#
++# CONFIG_MCP is not set
++# CONFIG_MCP_SA1100 is not set
++# CONFIG_MCP_UCB1200 is not set
++# CONFIG_MCP_UCB1200_AUDIO is not set
++# CONFIG_MCP_UCB1200_TS is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++# CONFIG_USB_OHCI is not set
++# CONFIG_USB_OHCI_SA1111 is not set
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++# 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_JUMPSHOT is not set
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# CONFIG_USB_HID is not set
++# CONFIG_USB_HIDDEV is not set
++# CONFIG_USB_KBD is not set
++# CONFIG_USB_MOUSE is not set
++# CONFIG_USB_WACOM is not set
++# 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
++# CONFIG_USB_PEGASUS 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
++# CONFIG_USB_USS720 is not set
++
++#
++# USB Serial Converter support
++#
++# CONFIG_USB_SERIAL is not set
++# CONFIG_USB_SERIAL_GENERIC is not set
++# CONFIG_USB_SERIAL_BELKIN is not set
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
++# CONFIG_USB_SERIAL_EMPEG is not set
++# CONFIG_USB_SERIAL_FTDI_SIO is not set
++# CONFIG_USB_SERIAL_VISOR is not set
++# CONFIG_USB_SERIAL_IR is not set
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
++# CONFIG_USB_SERIAL_MCT_U232 is not set
++# CONFIG_USB_SERIAL_PL2303 is not set
++# CONFIG_USB_SERIAL_CYBERJACK is not set
++# CONFIG_USB_SERIAL_XIRCOM is not set
++# CONFIG_USB_SERIAL_OMNINET is not set
++# CONFIG_USB_RIO500 is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++# CONFIG_DEBUG_USER is not set
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_NO_PGT_CACHE is not set
++CONFIG_DEBUG_KERNEL=y
++CONFIG_DEBUG_SLAB=y
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_WAITQ is not set
++# CONFIG_DEBUG_BUGVERBOSE is not set
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
++# CONFIG_DEBUG_LL_SER3 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/lart_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/lart_defconfig 2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/lart_defconfig 2003-09-27 11:38:18.634695480 +0800
+@@ -0,0 +1,893 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++CONFIG_SA1100_LART=y
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++CONFIG_SA1100_USB=m
++CONFIG_SA1100_USB_NETLINK=m
++CONFIG_SA1100_USB_CHAR=m
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++CONFIG_DISCONTIGMEM=y
++# CONFIG_CPU_BIG_ENDIAN is not set
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++CONFIG_CPU_FREQ=y
++# CONFIG_HOTPLUG is not set
++# CONFIG_PCMCIA is not set
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++CONFIG_PM=y
++CONFIG_APM=m
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="console=ttySA0,9600 root=/dev/ram"
++# CONFIG_PFS168_CMDLINE is not set
++CONFIG_LEDS=y
++# CONFIG_LEDS_TIMER is not set
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++CONFIG_MTD_DEBUG=y
++CONFIG_MTD_DEBUG_VERBOSE=1
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_BOOTLDR_PARTS is not set
++# CONFIG_MTD_AFS_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 is not set
++# CONFIG_MTD_CFI_INTELEXT is not set
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_JEDEC is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_SUN_UFLASH is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_PNC2000 is not set
++# CONFIG_MTD_RPXLITE is not set
++# CONFIG_MTD_TQM8XXL is not set
++# CONFIG_MTD_SC520CDP is not set
++# CONFIG_MTD_NETSC520 is not set
++# CONFIG_MTD_SBC_GXX is not set
++# CONFIG_MTD_ELAN_104NC is not set
++# CONFIG_MTD_DBOX2 is not set
++# CONFIG_MTD_CSTM_MIPS_IXX is not set
++# CONFIG_MTD_CFI_FLAGADM is not set
++# CONFIG_MTD_SOLUTIONENGINE is not set
++# CONFIG_MTD_MIXMEM is not set
++# CONFIG_MTD_OCTAGON is not set
++# CONFIG_MTD_VMAX is not set
++# CONFIG_MTD_OCELOT is not set
++# CONFIG_MTD_L440GX is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_CDB89712 is not set
++# CONFIG_MTD_SA1100 is not set
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++CONFIG_MTD_LART=y
++# 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
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++# CONFIG_PNPBIOS 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_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# 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_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=m
++# CONFIG_PACKET_MMAP is not set
++# CONFIG_NETLINK 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 is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++CONFIG_INET_ECN=y
++CONFIG_SYN_COOKIES=y
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++
++#
++#
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++CONFIG_DUMMY=m
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNBMAC is not set
++# CONFIG_SUNQE is not set
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNGEM is not set
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_LANCE is not set
++# CONFIG_NET_VENDOR_SMC is not set
++# CONFIG_NET_VENDOR_RACAL 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_MYRI_SBUS is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PLIP is not set
++CONFIG_PPP=m
++# CONFIG_PPP_MULTILINK is not set
++# CONFIG_PPP_FILTER is not set
++CONFIG_PPP_ASYNC=m
++# CONFIG_PPP_SYNC_TTY is not set
++CONFIG_PPP_DEFLATE=m
++CONFIG_PPP_BSDCOMP=m
++# CONFIG_PPPOE is not set
++CONFIG_SLIP=m
++CONFIG_SLIP_COMPRESSED=y
++# CONFIG_SLIP_SMART is not set
++# CONFIG_SLIP_MODE_SLIP6 is not set
++
++#
++# Wireless LAN (non-hamradio)
++#
++# CONFIG_NET_RADIO is not set
++
++#
++# Token Ring devices
++#
++# CONFIG_TR is not set
++# CONFIG_NET_FC is not set
++# CONFIG_RCPCI is not set
++# CONFIG_SHAPER is not set
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++CONFIG_IRDA=m
++
++#
++# IrDA protocols
++#
++CONFIG_IRLAN=m
++CONFIG_IRNET=m
++CONFIG_IRCOMM=m
++# CONFIG_IRDA_ULTRA is not set
++CONFIG_IRDA_OPTIONS=y
++
++#
++# IrDA options
++#
++CONFIG_IRDA_CACHE_LAST_LSAP=y
++# CONFIG_IRDA_FAST_RR is not set
++CONFIG_IRDA_DEBUG=y
++
++#
++# 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_FIR is not set
++# CONFIG_SMC_IRCC_FIR is not set
++# CONFIG_ALI_FIR is not set
++# CONFIG_VLSI_FIR is not set
++CONFIG_SA1100_FIR=m
++
++#
++# ATA/IDE/MFM/RLL support
++#
++CONFIG_IDE=m
++
++#
++# IDE, ATA and ATAPI Block devices
++#
++CONFIG_BLK_DEV_IDE=m
++
++#
++# 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_IDEDISK=m
++# CONFIG_IDEDISK_MULTI_MODE is not set
++# CONFIG_BLK_DEV_IDECS is not set
++CONFIG_BLK_DEV_IDECD=m
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI 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_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++# CONFIG_BLK_DEV_ATARAID is not set
++# CONFIG_BLK_DEV_ATARAID_PDC is not set
++# CONFIG_BLK_DEV_ATARAID_HPT is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O 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
++
++#
++# 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
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_ANAKIN is not set
++# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=9600
++# CONFIG_SERIAL_8250 is not set
++# CONFIG_SERIAL_8250_CONSOLE is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_MULTIPORT is not set
++# CONFIG_SERIAL_8250_HUB6 is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++CONFIG_UCB1200=m
++CONFIG_TOUCHSCREEN_UCB1200=m
++CONFIG_AUDIO_UCB1200=m
++CONFIG_ADC_UCB1200=m
++# CONFIG_TOUCHSCREEN_H3600 is not set
++CONFIG_PROFILER=m
++# CONFIG_PFS168_SPI is not set
++# CONFIG_PFS168_DTMF is not set
++# CONFIG_PFS168_MISC is not set
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++# CONFIG_L3_ALGOBIT is not set
++# CONFIG_L3_BIT_SA1100_GPIO is not set
++
++#
++# Other L3 adapters
++#
++# CONFIG_L3_SA1111 is not set
++
++#
++# L3 driver support
++#
++# CONFIG_L3_DRV_UDA1341 is not set
++# CONFIG_BIT_SA1100_GPIO 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
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++CONFIG_SA1100_RTC=m
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++# CONFIG_SONYPI is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++CONFIG_REISERFS_FS=m
++# 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_BFS_FS is not set
++# CONFIG_CMS_FS is not set
++CONFIG_EXT3_FS=m
++CONFIG_JBD=m
++# 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=m
++CONFIG_JFFS2_FS_DEBUG=1
++CONFIG_CRAMFS=m
++CONFIG_TMPFS=y
++CONFIG_RAMFS=m
++CONFIG_ISO9660_FS=m
++CONFIG_JOLIET=y
++# CONFIG_MINIX_FS is not set
++# CONFIG_FREEVXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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=m
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
++CONFIG_NFS_FS=m
++CONFIG_NFS_V3=y
++# CONFIG_ROOT_NFS is not set
++CONFIG_NFSD=m
++CONFIG_NFSD_V3=y
++CONFIG_SUNRPC=m
++CONFIG_LOCKD=m
++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
++
++#
++# 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=m
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++CONFIG_NLS_CODEPAGE_850=m
++# 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_1251 is not set
++CONFIG_NLS_ISO8859_1=m
++# 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=m
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++CONFIG_NLS_UTF8=m
++
++#
++# Sound
++#
++CONFIG_SOUND=m
++# CONFIG_SOUND_BT878 is not set
++# CONFIG_SOUND_CMPCI is not set
++# CONFIG_SOUND_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_ICH is not set
++# CONFIG_SOUND_RME96XX is not set
++# CONFIG_SOUND_SONICVIBES 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_ASSABET_UDA1341 is not set
++# CONFIG_SOUND_H3600_UDA1341 is not set
++# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
++# CONFIG_SOUND_SA1111_UDA1341 is not set
++CONFIG_SOUND_SA1100SSP=m
++# CONFIG_SOUND_OSS is not set
++# CONFIG_SOUND_WAVEARTIST is not set
++# CONFIG_SOUND_TVMIXER is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# USB Controllers
++#
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++# CONFIG_USB_OHCI is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++# 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_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_DPCM is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# USB Human Interface Devices (HID)
++#
++
++#
++# Input core support is needed for USB HID
++#
++
++#
++# 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
++#
++# CONFIG_USB_DABUSB is not set
++
++#
++# USB Network adaptors
++#
++# CONFIG_USB_PLUSB is not set
++# CONFIG_USB_PEGASUS 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
++# CONFIG_USB_SERIAL_GENERIC is not set
++# CONFIG_USB_SERIAL_BELKIN is not set
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
++# CONFIG_USB_SERIAL_EMPEG is not set
++# CONFIG_USB_SERIAL_FTDI_SIO is not set
++# CONFIG_USB_SERIAL_VISOR is not set
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
++# CONFIG_USB_SERIAL_MCT_U232 is not set
++# CONFIG_USB_SERIAL_PL2303 is not set
++# CONFIG_USB_SERIAL_CYBERJACK is not set
++# CONFIG_USB_SERIAL_OMNINET is not set
++
++#
++# Miscellaneous USB drivers
++#
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_ID75 is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_NO_PGT_CACHE is not set
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/lubbock_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/lubbock_defconfig 2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/lubbock_defconfig 2003-09-27 11:38:18.636695176 +0800
+@@ -0,0 +1,882 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++# CONFIG_GENERIC_BUST_SPINLOCK is not set
++# CONFIG_GENERIC_ISA_DMA is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++
++#
++# General setup
++#
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ADIFCC is not set
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++CONFIG_ARCH_PXA=y
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_IOP310 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_H3100 is not set
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_H3800 is not set
++# CONFIG_SA1100_H3XXX is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_BADGE4 is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_PT_SYSTEM3 is not set
++# CONFIG_SA1100_SHANNON is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++# CONFIG_SA1100_STORK is not set
++# CONFIG_SA1100_USB is not set
++# CONFIG_SA1100_USB_NETLINK is not set
++# CONFIG_SA1100_USB_CHAR is not set
++# CONFIG_H3600_SLEEVE is not set
++
++#
++# Intel PXA250/210 Implementations
++#
++CONFIG_ARCH_LUBBOCK=y
++# CONFIG_ARCH_PXA_IDP is not set
++CONFIG_SA1111=y
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_AUTCPU12 is not set
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_FORTUNET is not set
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++
++#
++# IOP310 Implementation Options
++#
++# CONFIG_ARCH_IQ80310 is not set
++
++#
++# IOP310 Chipset Features
++#
++# CONFIG_IOP310_AAU is not set
++# CONFIG_IOP310_DMA is not set
++# CONFIG_IOP310_MU is not set
++# CONFIG_IOP310_PMON is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++# CONFIG_CPU_32v4 is not set
++CONFIG_CPU_32v5=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM922T is not set
++# CONFIG_CPU_ARM926T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++# CONFIG_CPU_SA1100 is not set
++CONFIG_CPU_XSCALE=y
++CONFIG_XSCALE_CACHE_ERRATA=y
++CONFIG_XSCALE_PMU=y
++
++#
++# Processor Features
++#
++# CONFIG_ARM_THUMB is not set
++
++#
++# General setup
++#
++# CONFIG_DISCONTIGMEM is not set
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++# CONFIG_FIQ is not set
++# CONFIG_ZBOOT_ROM is not set
++CONFIG_ZBOOT_ROM_TEXT=0
++CONFIG_ZBOOT_ROM_BSS=0
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=y
++CONFIG_PCMCIA_PROBE=y
++# CONFIG_I82092 is not set
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++# CONFIG_PCMCIA_SA1100 is not set
++CONFIG_PCMCIA_PXA=y
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_PREEMPT is not set
++# CONFIG_APM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="root=/dev/nfs ip=bootp console=ttyS0,115200 mem=64M"
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT 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=y
++# CONFIG_MTD_BOOTLDR_PARTS is not set
++# CONFIG_MTD_AFS_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=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++CONFIG_MTD_CFI_GEOMETRY=y
++# CONFIG_MTD_CFI_B1 is not set
++# CONFIG_MTD_CFI_B2 is not set
++CONFIG_MTD_CFI_B4=y
++# CONFIG_MTD_CFI_I1 is not set
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD 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_NORA is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_CDB89712 is not set
++# CONFIG_MTD_SA1100 is not set
++# CONFIG_MTD_2PARTS_IPAQ is not set
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++CONFIG_MTD_LUBBOCK=y
++# CONFIG_MTD_EPXA10DB is not set
++# CONFIG_MTD_FORTUNET is not set
++# CONFIG_MTD_PCI 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
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++# CONFIG_PNPBIOS 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_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_UMEM is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_RAM is not set
++# CONFIG_BLK_DEV_INITRD 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 is not set
++# 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 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_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
++# 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 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_ARM_AM79C961A is not set
++# CONFIG_SUNLANCE 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=y
++# CONFIG_WD80x3 is not set
++# CONFIG_ULTRAMCA is not set
++# CONFIG_ULTRA is not set
++# CONFIG_ULTRA32 is not set
++CONFIG_SMC9194=y
++# CONFIG_NET_VENDOR_RACAL 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_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
++
++#
++# Tulip family network device support
++#
++# CONFIG_NET_TULIP is not set
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=y
++# CONFIG_PCMCIA_NMCLAN is not set
++# CONFIG_PCMCIA_SMC91C92 is not set
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_PCMCIA_AXNET is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++# CONFIG_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O 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
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN_BOOL is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_KEYBDEV is not set
++# CONFIG_INPUT_MOUSEDEV is not set
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_GAMEPORT is not set
++CONFIG_SOUND_GAMEPORT=y
++# CONFIG_GAMEPORT_NS558 is not set
++# CONFIG_GAMEPORT_L4 is not set
++# CONFIG_INPUT_EMU10K1 is not set
++# CONFIG_GAMEPORT_PCIGAME is not set
++# CONFIG_GAMEPORT_FM801 is not set
++# CONFIG_GAMEPORT_CS461x is not set
++# CONFIG_SERIO is not set
++# CONFIG_SERIO_SERPORT is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_JOYSTICK_ANALOG is not set
++# CONFIG_JOYSTICK_A3D is not set
++# CONFIG_JOYSTICK_ADI is not set
++# CONFIG_JOYSTICK_COBRA is not set
++# CONFIG_JOYSTICK_GF2K is not set
++# CONFIG_JOYSTICK_GRIP is not set
++# CONFIG_JOYSTICK_INTERACT is not set
++# CONFIG_JOYSTICK_SIDEWINDER is not set
++# CONFIG_JOYSTICK_TMDC is not set
++# CONFIG_JOYSTICK_IFORCE_USB is not set
++# CONFIG_JOYSTICK_IFORCE_232 is not set
++# CONFIG_JOYSTICK_WARRIOR is not set
++# CONFIG_JOYSTICK_MAGELLAN is not set
++# CONFIG_JOYSTICK_SPACEORB is not set
++# CONFIG_JOYSTICK_SPACEBALL is not set
++# CONFIG_JOYSTICK_STINGER is not set
++# CONFIG_JOYSTICK_DB9 is not set
++# CONFIG_JOYSTICK_GAMECON is not set
++# CONFIG_JOYSTICK_TURBOGRAFX is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++# CONFIG_SERIAL_8250_CS is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_MULTIPORT is not set
++# CONFIG_SERIAL_8250_RSA is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_ATOMWIDE_SERIAL is not set
++# CONFIG_DUALSP_SERIAL is not set
++# CONFIG_SERIAL_ANAKIN is not set
++# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X_OLD_NAME is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_UART00 is not set
++# CONFIG_SERIAL_UART00_CONSOLE is not set
++# CONFIG_SERIAL_SA1100 is not set
++# CONFIG_SERIAL_SA1100_CONSOLE is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++# CONFIG_L3_ALGOBIT is not set
++# CONFIG_L3_BIT_SA1100_GPIO is not set
++
++#
++# Other L3 adapters
++#
++# CONFIG_L3_SA1111 is not set
++# CONFIG_BIT_SA1100_GPIO is not set
++
++#
++# Mice
++#
++CONFIG_BUSMOUSE=y
++# CONFIG_ATIXL_BUSMOUSE is not set
++# CONFIG_LOGIBUSMOUSE is not set
++# CONFIG_MS_BUSMOUSE is not set
++CONFIG_MOUSE=y
++CONFIG_PSMOUSE=y
++# CONFIG_82C710_MOUSE is not set
++# CONFIG_PC110_PAD is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG 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
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++# CONFIG_SYNCLINK_CS is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_QFMT_V1 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_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 is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++# CONFIG_JFFS2_FS_NAND is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_TMPFS is not set
++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_DEBUG 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
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 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_EXPORTFS is not set
++# 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_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=y
++# 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
++
++#
++# Sound
++#
++CONFIG_SOUND=y
++
++#
++# Open Sound System
++#
++CONFIG_SOUND_PRIME=y
++# 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_ICH is not set
++# CONFIG_SOUND_RME96XX is not set
++# CONFIG_SOUND_SONICVIBES 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_WAVEARTIST is not set
++# CONFIG_SOUND_PXA_AC97 is not set
++# CONFIG_SOUND_TVMIXER is not set
++
++#
++# Advanced Linux Sound Architecture
++#
++# CONFIG_SND is not set
++
++#
++# Multimedia Capabilities Port drivers
++#
++# CONFIG_MCP is not set
++# CONFIG_MCP_SA1100 is not set
++# CONFIG_MCP_UCB1200 is not set
++# CONFIG_MCP_UCB1200_AUDIO is not set
++# CONFIG_MCP_UCB1200_TS is not set
++# CONFIG_MCP_UCB1400_TS is not set
++
++#
++# Console Switches
++#
++# CONFIG_SWITCHES is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_INFO=y
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SLAB is not set
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_WAITQ is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
++
++#
++# Library routines
++#
++CONFIG_CRC32=y
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
+Index: linux-2.6.0-test5/arch/arm/configs/lusl7200_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/lusl7200_defconfig 2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/lusl7200_defconfig 2003-09-27 11:38:18.637695024 +0800
+@@ -0,0 +1,488 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++# CONFIG_GENERIC_BUST_SPINLOCK is not set
++# CONFIG_GENERIC_ISA_DMA is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++
++#
++# General setup
++#
++# CONFIG_NET is not set
++CONFIG_SYSVIPC=y
++CONFIG_BSD_PROCESS_ACCT=y
++CONFIG_SYSCTL=y
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_ADIFCC is not set
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_IOP310 is not set
++CONFIG_ARCH_L7200=y
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_H3100 is not set
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_H3800 is not set
++# CONFIG_SA1100_H3XXX is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_BADGE4 is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_PT_SYSTEM3 is not set
++# CONFIG_SA1100_SHANNON is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++# CONFIG_SA1100_STORK is not set
++# CONFIG_SA1100_USB is not set
++# CONFIG_SA1100_USB_NETLINK is not set
++# CONFIG_SA1100_USB_CHAR is not set
++# CONFIG_H3600_SLEEVE is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_AUTCPU12 is not set
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_FORTUNET is not set
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_32v5 is not set
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++CONFIG_CPU_ARM720T=y
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM922T is not set
++# CONFIG_CPU_ARM926T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++# CONFIG_CPU_SA1100 is not set
++# CONFIG_CPU_XSCALE is not set
++# CONFIG_XSCALE_PMU is not set
++
++#
++# Processor Features
++#
++# CONFIG_ARM_THUMB is not set
++
++#
++# General setup
++#
++# CONFIG_DISCONTIGMEM is not set
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++CONFIG_FIQ=y
++CONFIG_ZBOOT_ROM=y
++CONFIG_ZBOOT_ROM_TEXT=00010000
++CONFIG_ZBOOT_ROM_BSS=f03e0000
++# CONFIG_HOTPLUG is not set
++# CONFIG_PCMCIA is not set
++
++#
++# At least one math emulation must be selected
++#
++# CONFIG_FPE_NWFPE is not set
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_PREEMPT is not set
++# CONFIG_APM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="console=tty0 console=ttyLU1,115200 root=/dev/ram initrd=0xf1000000,0x005dac7b mem=32M"
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++# CONFIG_MTD is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++# CONFIG_PNPBIOS 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_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_UMEM is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# 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
++
++#
++# ATA/IDE/MFM/RLL support
++#
++# CONFIG_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++
++#
++# Input device 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_GAMEPORT is not set
++CONFIG_SOUND_GAMEPORT=y
++# CONFIG_GAMEPORT_NS558 is not set
++# CONFIG_GAMEPORT_L4 is not set
++# CONFIG_INPUT_EMU10K1 is not set
++# CONFIG_GAMEPORT_PCIGAME is not set
++# CONFIG_GAMEPORT_FM801 is not set
++# CONFIG_GAMEPORT_CS461x is not set
++# CONFIG_SERIO is not set
++# CONFIG_SERIO_SERPORT is not set
++
++#
++# Character devices
++#
++# CONFIG_VT 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
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++# CONFIG_SERIAL_8250_CONSOLE is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_MULTIPORT is not set
++# CONFIG_SERIAL_8250_RSA is not set
++
++#
++# Non-8250 serial port support
++#
++
++#
++# ARM Serial drivers
++#
++# CONFIG_ATOMWIDE_SERIAL is not set
++# CONFIG_DUALSP_SERIAL is not set
++# CONFIG_SERIAL_ANAKIN is not set
++# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_UART00 is not set
++# CONFIG_SERIAL_UART00_CONSOLE is not set
++# CONFIG_SERIAL_SA1100 is not set
++# CONFIG_SERIAL_SA1100_CONSOLE is not set
++# CONFIG_UNIX98_PTYS is not set
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++# CONFIG_L3_ALGOBIT is not set
++# CONFIG_L3_BIT_SA1100_GPIO is not set
++
++#
++# Other L3 adapters
++#
++# CONFIG_L3_SA1111 is not set
++# CONFIG_BIT_SA1100_GPIO is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG 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
++# CONFIG_DRM is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_QFMT_V1 is not set
++# CONFIG_QFMT_V2 is not set
++# CONFIG_QIFACE_COMPAT 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_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 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 is not set
++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_DEBUG 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 is not set
++# 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_NCPFS_NLS is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_ZISOFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++# CONFIG_SMB_NLS is not set
++# CONFIG_NLS is not set
++
++#
++# Multimedia Capabilities Port drivers
++#
++# CONFIG_MCP is not set
++# CONFIG_MCP_SA1100 is not set
++# CONFIG_MCP_UCB1200 is not set
++# CONFIG_MCP_UCB1200_AUDIO is not set
++# CONFIG_MCP_UCB1200_TS is not set
++
++#
++# Console Switches
++#
++# CONFIG_SWITCHES is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_INFO=y
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_DEBUG_SLAB is not set
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_WAITQ is not set
++# CONFIG_DEBUG_BUGVERBOSE is not set
++# CONFIG_DEBUG_ERRORS is not set
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
++
++#
++# Library routines
++#
++# CONFIG_CRC32 is not set
++# CONFIG_ZLIB_INFLATE is not set
++# CONFIG_ZLIB_DEFLATE is not set
+Index: linux-2.6.0-test5/arch/arm/configs/neponset_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/neponset_defconfig 2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/neponset_defconfig 2003-09-27 11:38:18.639694720 +0800
+@@ -0,0 +1,895 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++CONFIG_MMU=y
++CONFIG_SWAP=y
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++
++#
++# General setup
++#
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ADIFCC is not set
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_IOP310 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++
++#
++# CLPS711X/EP721X Implementations
++#
++
++#
++# Epxa10db
++#
++
++#
++# Footbridge Implementations
++#
++
++#
++# IOP310 Implementation Options
++#
++
++#
++# IOP310 Chipset Features
++#
++
++#
++# Intel PXA250/210 Implementations
++#
++
++#
++# SA11x0 Implementations
++#
++CONFIG_SA1100_ASSABET=y
++CONFIG_ASSABET_NEPONSET=y
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_H3100 is not set
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_H3800 is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_BADGE4 is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_PT_SYSTEM3 is not set
++# CONFIG_SA1100_SHANNON is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++# CONFIG_SA1100_STORK is not set
++CONFIG_SA1100_USB=m
++CONFIG_SA1100_USB_NETLINK=m
++CONFIG_SA1100_USB_CHAR=m
++CONFIG_SA1111=y
++CONFIG_FORCE_MAX_ZONEORDER=9
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_SA1100=y
++CONFIG_CPU_32v4=y
++
++#
++# Processor Features
++#
++
++#
++# General setup
++#
++CONFIG_DISCONTIGMEM=y
++CONFIG_ISA=y
++CONFIG_ZBOOT_ROM=y
++CONFIG_ZBOOT_ROM_TEXT=0x80000
++CONFIG_ZBOOT_ROM_BSS=0xc1000000
++CONFIG_CPU_FREQ=y
++CONFIG_CPU_FREQ_24_API=y
++CONFIG_CPU_FREQ_26_API=y
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=y
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++CONFIG_PCMCIA_SA1100=y
++CONFIG_PCMCIA_SA1111=y
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++CONFIG_PM=y
++# CONFIG_PREEMPT is not set
++CONFIG_APM=y
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="console=ttySA0,38400n8 cpufreq=221200 rw root=/dev/mtdblock2 mtdparts=sa1100:512K(boot),1M(kernel),2560K(initrd),4M(root) load_ramdisk=1 prompt_ramdisk=0 mem=32M noinitrd initrd=0xc0800000,3M"
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=y
++CONFIG_MTD_CONCAT=y
++CONFIG_MTD_REDBOOT_PARTS=y
++CONFIG_MTD_CMDLINE_PARTS=y
++# CONFIG_MTD_AFS_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++# CONFIG_MTD_CHAR is not set
++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=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_GEOMETRY is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++CONFIG_MTD_RAM=y
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_OBSOLETE_CHIPS is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_EDB7312 is not set
++CONFIG_MTD_PCMCIA=y
++# CONFIG_MTD_UCLINUX is not set
++
++#
++# Self-contained MTD device drivers
++#
++# 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
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# CONFIG_BLK_DEV_XD is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=8192
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD 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 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
++
++#
++# SCTP Configuration (EXPERIMENTAL)
++#
++CONFIG_IPV6_SCTP__=y
++# CONFIG_IP_SCTP is not set
++# CONFIG_ATM is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_LLC is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB 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 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_NET_VENDOR_3COM is not set
++# CONFIG_LANCE is not set
++CONFIG_NET_VENDOR_SMC=y
++# CONFIG_WD80x3 is not set
++# CONFIG_ULTRA is not set
++CONFIG_SMC9194=y
++# CONFIG_NET_VENDOR_RACAL is not set
++# CONFIG_AT1700 is not set
++# CONFIG_DEPCA 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_FDDI is not set
++# CONFIG_HIPPI 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_SHAPER is not set
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=y
++# CONFIG_PCMCIA_NMCLAN is not set
++# CONFIG_PCMCIA_SMC91C92 is not set
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_PCMCIA_AXNET is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# ATA/ATAPI/MFM/RLL support
++#
++# CONFIG_IDE is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN_BOOL is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++
++#
++# Userland interfaces
++#
++# CONFIG_INPUT_MOUSEDEV is not set
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_TSDEV=y
++CONFIG_INPUT_TSDEV_SCREEN_X=240
++CONFIG_INPUT_TSDEV_SCREEN_Y=320
++CONFIG_INPUT_TSLIBDEV=y
++# CONFIG_INPUT_EVDEV is not set
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input I/O drivers
++#
++# CONFIG_GAMEPORT is not set
++CONFIG_SOUND_GAMEPORT=y
++CONFIG_SERIO=y
++# CONFIG_SERIO_I8042 is not set
++CONFIG_SERIO_SERPORT=m
++# CONFIG_SERIO_CT82C710 is not set
++CONFIG_SERIO_SA1111=y
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_INPUT_MOUSE is not set
++# CONFIG_INPUT_JOYSTICK is not set
++CONFIG_INPUT_TOUCHSCREEN=y
++# CONFIG_TOUCHSCREEN_GUNZE is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++CONFIG_SERIAL_NONSTANDARD=y
++# CONFIG_COMPUTONE is not set
++# CONFIG_ROCKETPORT 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
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++# CONFIG_SERIAL_8250_CONSOLE is not set
++CONFIG_SERIAL_8250_CS=y
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++
++#
++# I2C support
++#
++CONFIG_I2C=y
++CONFIG_I2C_ALGOBIT=y
++# CONFIG_I2C_ELV is not set
++# CONFIG_I2C_VELLEMAN is not set
++# CONFIG_SCx200_ACB is not set
++CONFIG_I2C_BIT_SA1100_GPIO=y
++# CONFIG_I2C_ALGOPCF is not set
++CONFIG_I2C_CHARDEV=y
++CONFIG_I2C_PROC=y
++
++#
++# L3 serial bus support
++#
++CONFIG_L3=y
++CONFIG_L3_ALGOBIT=y
++CONFIG_L3_BIT_SA1100_GPIO=y
++CONFIG_BIT_SA1100_GPIO=y
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++CONFIG_WATCHDOG=y
++# CONFIG_WATCHDOG_NOWAYOUT is not set
++# CONFIG_SOFT_WATCHDOG is not set
++# CONFIG_WDT is not set
++# CONFIG_WDTPCI is not set
++# CONFIG_PCWATCHDOG is not set
++# CONFIG_ACQUIRE_WDT is not set
++# CONFIG_ADVANTECH_WDT is not set
++CONFIG_SA1100_WATCHDOG=m
++# CONFIG_EUROTECH_WDT is not set
++# CONFIG_IB700_WDT is not set
++# CONFIG_I810_TCO is not set
++# CONFIG_MIXCOMWD is not set
++# CONFIG_SCx200_WDT is not set
++# CONFIG_60XX_WDT is not set
++# CONFIG_W83877F_WDT is not set
++# CONFIG_MACHZ_WDT is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_GEN_RTC is not set
++CONFIG_SA1100_RTC=y
++# 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
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++# CONFIG_SYNCLINK_CS is not set
++# CONFIG_RAW_DRIVER is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_JBD is not set
++CONFIG_FAT_FS=m
++CONFIG_MSDOS_FS=m
++CONFIG_VFAT_FS=m
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++# CONFIG_JFFS2_FS_NAND is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_TMPFS is not set
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_HPFS_FS is not set
++CONFIG_PROC_FS=y
++# CONFIG_DEVFS_FS is not set
++CONFIG_DEVPTS_FS=y
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_XFS_FS 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 is not set
++# CONFIG_NFS_V4 is not set
++# CONFIG_NFSD is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=y
++# CONFIG_EXPORTFS is not set
++# CONFIG_CIFS is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++# CONFIG_MSDOS_PARTITION is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++CONFIG_NLS=y
++
++#
++# Native Language Support
++#
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=m
++# 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=m
++# 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
++
++#
++# Console drivers
++#
++# CONFIG_VGA_CONSOLE is not set
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FB_SA1100=y
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FBCON_ADVANCED is not set
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++CONFIG_FBCON_FONTWIDTH8_ONLY=y
++# CONFIG_FONT_SUN8x16 is not set
++CONFIG_FBCON_FONTS=y
++# CONFIG_FONT_8x8 is not set
++# CONFIG_FONT_8x16 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++CONFIG_FONT_ACORN_8x8=y
++# CONFIG_FONT_MINI_4x6 is not set
++
++#
++# Sound
++#
++CONFIG_SOUND=y
++
++#
++# Open Sound System
++#
++CONFIG_SOUND_PRIME=y
++# CONFIG_SOUND_BT878 is not set
++# CONFIG_SOUND_FUSION is not set
++# CONFIG_SOUND_CS4281 is not set
++# CONFIG_SOUND_ESSSOLO1 is not set
++# CONFIG_SOUND_MAESTRO is not set
++# CONFIG_SOUND_SONICVIBES is not set
++# CONFIG_SOUND_TRIDENT is not set
++# CONFIG_SOUND_MSNDCLAS is not set
++# CONFIG_SOUND_MSNDPIN is not set
++CONFIG_SOUND_SA1100=y
++CONFIG_SOUND_UDA1341=y
++CONFIG_SOUND_ASSABET_UDA1341=y
++CONFIG_SOUND_SA1111_UDA1341=y
++# CONFIG_SOUND_SA1100SSP is not set
++# CONFIG_SOUND_OSS is not set
++# CONFIG_SOUND_TVMIXER is not set
++
++#
++# Advanced Linux Sound Architecture
++#
++# CONFIG_SND is not set
++
++#
++# Misc devices
++#
++
++#
++# Multimedia Capabilities Port drivers
++#
++CONFIG_MCP=y
++CONFIG_MCP_SA1100=y
++CONFIG_MCP_UCB1200=y
++CONFIG_MCP_UCB1200_AUDIO=m
++CONFIG_MCP_UCB1200_TS=y
++
++#
++# Console Switches
++#
++# CONFIG_SWITCHES is not set
++
++#
++# USB support
++#
++CONFIG_USB=m
++CONFIG_USB_DEBUG=y
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++# CONFIG_USB_LONG_TIMEOUT is not set
++# CONFIG_USB_BANDWIDTH is not set
++# CONFIG_USB_DYNAMIC_MINORS is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_EHCI_HCD is not set
++CONFIG_USB_OHCI_HCD=m
++# CONFIG_USB_UHCI_HCD_ALT is not set
++# CONFIG_USB_SL811HS is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH_TTY is not set
++# CONFIG_USB_MIDI is not set
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# SCSI support is needed for USB Storage
++#
++
++#
++# USB Human Interface Devices (HID)
++#
++# CONFIG_USB_HID is not set
++
++#
++# USB HID Boot Protocol drivers
++#
++# CONFIG_USB_KBD is not set
++CONFIG_USB_MOUSE=m
++# CONFIG_USB_AIPTEK is not set
++# CONFIG_USB_WACOM is not set
++# CONFIG_USB_POWERMATE is not set
++# CONFIG_USB_XPAD is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_SCANNER is not set
++
++#
++# USB Multimedia devices
++#
++# CONFIG_USB_DABUSB is not set
++
++#
++# Video4Linux support is needed for USB Multimedia device support
++#
++
++#
++# USB Network adaptors
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_CDCETHER is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
++
++#
++# USB port drivers
++#
++
++#
++# USB Serial Converter support
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_TIGL is not set
++# CONFIG_USB_AUERSWALD is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_BRLVGER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_TEST is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++CONFIG_DEBUG_KERNEL=y
++CONFIG_DEBUG_SLAB=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_WAITQ is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_ERRORS=y
++# CONFIG_KALLSYMS is not set
++CONFIG_DEBUG_LL=y
++
++#
++# Security options
++#
++CONFIG_SECURITY_CAPABILITIES=y
++
++#
++# Cryptographic options
++#
++# CONFIG_CRYPTO is not set
++
++#
++# Library routines
++#
++# CONFIG_CRC32 is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
+Index: linux-2.6.0-test5/arch/arm/configs/omnimeter_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/omnimeter_defconfig 2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/omnimeter_defconfig 2003-09-27 11:38:18.640694568 +0800
+@@ -0,0 +1,571 @@
++#
++# Automatically generated by make menuconfig: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_SBUS is not set
++CONFIG_UID16=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_CLPS711X is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Footbridge Implementations
++#
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_SA1100_BRUTUS is not set
++CONFIG_SA1100_OMNIMETER=y
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_BITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_USB is not set
++# CONFIG_SA1100_FREQUENCY_SCALE is not set
++# CONFIG_SA1100_VOLTAGE_SCALE is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++CONFIG_CPU_32v4=y
++CONFIG_CPU_SA1100=y
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++# CONFIG_ANGELBOOT is not set
++# CONFIG_PCI is not set
++CONFIG_ISA=y
++# CONFIG_ISA_DMA is not set
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=y
++CONFIG_I82365=y
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_SA1100_PCMCIA=y
++# CONFIG_H3600_SLEEVE is not set
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_NWFPE=y
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="keepinitrd mem=16M root=/dev/ram ramdisk=8192 initrd=0xd0000000,4M"
++# CONFIG_LEDS is not set
++# CONFIG_ALIGNMENT_TRAP is not set
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++# CONFIG_MTD 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_BLK_DEV_DAC960 is not set
++CONFIG_BLK_DEV_LOOP=m
++CONFIG_BLK_DEV_NBD=m
++# CONFIG_BLK_DEV_RAM is not set
++# CONFIG_BLK_DEV_INITRD is not set
++# CONFIG_BLK_DEV_FLASH is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++CONFIG_NETLINK=y
++CONFIG_RTNETLINK=y
++# CONFIG_NETLINK_DEV is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++# CONFIG_IP_PNP 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_COMPAT_IPCHAINS is not set
++# CONFIG_IP_NF_COMPAT_IPFWADM is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK 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 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
++# CONFIG_NET_SB1000 is not set
++# CONFIG_NET_SA1100_USB_HOST is not set
++# CONFIG_NET_SA1100_USB_CLIENT is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# 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_AT1700 is not set
++# CONFIG_DEPCA 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_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI 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
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++CONFIG_PCMCIA_3C589=y
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=y
++# CONFIG_PCMCIA_NMCLAN is not set
++# CONFIG_PCMCIA_SMC91C92 is not set
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++CONFIG_NET_PCMCIA_RADIO=y
++# CONFIG_PCMCIA_RAYCS is not set
++# CONFIG_PCMCIA_NETWAVE is not set
++CONFIG_PCMCIA_WAVELAN=y
++CONFIG_AIRONET4500_CS=y
++CONFIG_PCMCIA_WVLAN=y
++CONFIG_PCMCIA_NETCARD=y
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++CONFIG_IDE=y
++
++#
++# IDE, ATA and ATAPI Block devices
++#
++CONFIG_BLK_DEV_IDE=y
++# CONFIG_BLK_DEV_HD_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++CONFIG_BLK_DEV_IDEDISK=y
++# CONFIG_IDEDISK_MULTI_MODE is not set
++CONFIG_BLK_DEV_IDECS=y
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
++# CONFIG_BLK_DEV_ISAPNP is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O 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
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++# CONFIG_INPUT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++# CONFIG_TOUCHSCREEN_UCB1200 is not set
++# CONFIG_TOUCHSCREEN_BITSY is not set
++# CONFIG_TOUCHSCREEN_BITSY_KEYBOARD is not set
++# CONFIG_H3600_SLEEVE is not set
++CONFIG_SERIAL=y
++# CONFIG_SERIAL_CONSOLE is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=9600
++# CONFIG_TOUCHSCREEN_UCB1200 is not set
++# CONFIG_TOUCHSCREEN_BITSY is not set
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++CONFIG_MOUSE=m
++# CONFIG_PSMOUSE is not set
++# CONFIG_82C710_MOUSE is not set
++# CONFIG_PC110_PAD is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_SA1100_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
++# CONFIG_DRM is not set
++CONFIG_PCMCIA_SERIAL=y
++
++#
++# PCMCIA character device support
++#
++# CONFIG_PCMCIA_SERIAL_CS is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS 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_BFS_FS is not set
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++# 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_CRAMFS is not set
++# CONFIG_RAMFS is not set
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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 is not set
++# 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_SYSV_FS_WRITE 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
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=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_MOUNT_SUBDIR is not set
++# CONFIG_NCPFS_NDS_DOMAINS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++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_874 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_ISO8859_1 is not set
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_UTF8 is not set
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_FB=y
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_CLPS711X is not set
++# CONFIG_FB_CYBER2000 is not set
++CONFIG_FB_SA1100=y
++# 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=y
++# CONFIG_FBCON_CFB8 is not set
++# CONFIG_FBCON_CFB16 is not set
++# 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 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++# CONFIG_DEBUG_USER is not set
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_MAGIC_SYSRQ is not set
++CONFIG_DEBUG_LL=y
+Index: linux-2.6.0-test5/arch/arm/configs/pangolin_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/pangolin_defconfig 2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/pangolin_defconfig 2003-09-27 11:38:18.642694264 +0800
+@@ -0,0 +1,742 @@
++#
++# Automatically generated by make menuconfig: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_BITSY is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++CONFIG_SA1100_PANGOLIN=y
++CONFIG_SA1100_PANGOLIN_PCMCIA_IDE=y
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++# CONFIG_SA1100_USB is not set
++# CONFIG_SA1100_USB_NETLINK is not set
++# CONFIG_SA1100_USB_CHAR is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++CONFIG_DISCONTIGMEM=y
++# CONFIG_CPU_BIG_ENDIAN is not set
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++# CONFIG_CPU_FREQ is not set
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=y
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=y
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++# CONFIG_FPE_NWFPE is not set
++CONFIG_FPE_FASTFPE=y
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_APM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="keepinitrd mem=128M root=/dev/ram initrd=0xc0800000,3M"
++# CONFIG_PFS168_CMDLINE is not set
++# CONFIG_LEDS is not set
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_BOOTLDR_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++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_CFI_ADV_OPTIONS=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++CONFIG_MTD_CFI_GEOMETRY=y
++# CONFIG_MTD_CFI_B1 is not set
++# CONFIG_MTD_CFI_B2 is not set
++CONFIG_MTD_CFI_B4=y
++# CONFIG_MTD_CFI_I1 is not set
++# CONFIG_MTD_CFI_I2 is not set
++CONFIG_MTD_CFI_I4=y
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_JEDEC is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_SUN_UFLASH is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_PNC2000 is not set
++# CONFIG_MTD_RPXLITE is not set
++# CONFIG_MTD_TQM8XXL is not set
++# CONFIG_MTD_SC520CDP is not set
++# CONFIG_MTD_NETSC520 is not set
++# CONFIG_MTD_SBC_GXX is not set
++# CONFIG_MTD_ELAN_104NC is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_SA1100_REDBOOT_PARTITIONS is not set
++# CONFIG_MTD_SA1100_BOOTLDR_PARTITIONS is not set
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++# CONFIG_MTD_DBOX2 is not set
++# CONFIG_MTD_CSTM_MIPS_IXX is not set
++# CONFIG_MTD_CFI_FLAGADM is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_SOLUTIONENGINE is not set
++# CONFIG_MTD_MIXMEM is not set
++# CONFIG_MTD_OCTAGON is not set
++# CONFIG_MTD_VMAX is not set
++# CONFIG_MTD_OCELOT is not set
++# CONFIG_MTD_L440GX is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_LART is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLKMTD is not set
++# 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
++
++#
++# 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_BLK_DEV_DAC960 is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=16384
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# 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_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++# CONFIG_NETLINK 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 is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE 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
++# CONFIG_ATM is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK 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 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
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNBMAC is not set
++# CONFIG_SUNQE is not set
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNGEM is not set
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_LANCE is not set
++CONFIG_NET_VENDOR_SMC=y
++# CONFIG_WD80x3 is not set
++# CONFIG_ULTRAMCA is not set
++# CONFIG_ULTRA is not set
++# CONFIG_ULTRA32 is not set
++CONFIG_SMC9194=y
++# CONFIG_NET_VENDOR_RACAL 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_ACENIC_OMIT_TIGON_I is not set
++# CONFIG_MYRI_SBUS is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_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
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=y
++# CONFIG_PCMCIA_NMCLAN is not set
++# CONFIG_PCMCIA_SMC91C92 is not set
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++CONFIG_NET_PCMCIA_RADIO=y
++# CONFIG_PCMCIA_RAYCS is not set
++# CONFIG_PCMCIA_NETWAVE is not set
++# CONFIG_PCMCIA_WAVELAN is not set
++# CONFIG_AIRONET4500_CS is not set
++CONFIG_PCMCIA_WVLAN=y
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++CONFIG_IDE=m
++
++#
++# IDE, ATA and ATAPI Block devices
++#
++CONFIG_BLK_DEV_IDE=m
++# CONFIG_BLK_DEV_HD_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++CONFIG_BLK_DEV_IDEDISK=m
++# CONFIG_IDEDISK_MULTI_MODE is not set
++CONFIG_BLK_DEV_IDECS=m
++# CONFIG_BLK_DEV_PANGOLIN 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_BLK_DEV_CMD640 is not set
++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
++# CONFIG_BLK_DEV_ISAPNP is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O 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
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++# CONFIG_INPUT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=115200
++# CONFIG_SERIAL_8250 is not set
++# CONFIG_SERIAL_8250_CONSOLE is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++# CONFIG_UCB1200 is not set
++# CONFIG_TOUCHSCREEN_UCB1200 is not set
++# CONFIG_AUDIO_UCB1200 is not set
++# CONFIG_ADC_UCB1200 is not set
++# CONFIG_TOUCHSCREEN_BITSY is not set
++CONFIG_PROFILER=y
++# CONFIG_PFS168_SPI is not set
++# CONFIG_PFS168_DTMF is not set
++# CONFIG_PFS168_MISC is not set
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++CONFIG_SA1100_RTC=y
++# 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
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA 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_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_BFS_FS 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=y
++CONFIG_JFFS_FS_VERBOSE=0
++# CONFIG_JFFS2_FS is not set
++CONFIG_CRAMFS=y
++# CONFIG_TMPFS is not set
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_NFS_FS is not set
++# CONFIG_NFS_V3 is not set
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++# CONFIG_SUNRPC is not set
++# CONFIG_LOCKD is not set
++# 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
++
++#
++# 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=y
++# 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_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
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_CLPS711X is not set
++# CONFIG_FB_CYBER2000 is not set
++# CONFIG_FB_SA1100 is not set
++CONFIG_FB_MQ200=y
++# CONFIG_FB_ANAKIN is not set
++# CONFIG_FB_E1355 is not set
++# CONFIG_FB_VIRTUAL is not set
++CONFIG_FBCON_ADVANCED=y
++# CONFIG_FBCON_MFB is not set
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++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 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++
++#
++# Sound
++#
++CONFIG_SOUND=y
++# CONFIG_SOUND_ASSABET_UDA1341 is not set
++CONFIG_SOUND_PANGOLIN_UDA1341=y
++# CONFIG_SOUND_BITSY_UDA1341 is not set
++# CONFIG_SOUND_SA1111_UDA1341 is not set
++# CONFIG_SOUND_SA1100SSP is not set
++# CONFIG_SOUND_CMPCI is not set
++# CONFIG_SOUND_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_ICH is not set
++# CONFIG_SOUND_SONICVIBES 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
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_INFO=y
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_NO_PGT_CACHE is not set
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/pfs168_mqtft_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/pfs168_mqtft_defconfig 2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/pfs168_mqtft_defconfig 2003-09-27 11:38:18.643694112 +0800
+@@ -0,0 +1,782 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_CLPS711X is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_BITSY is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++CONFIG_SA1100_PFS168=y
++CONFIG_SA1111=y
++CONFIG_SA1100_USB=m
++CONFIG_SA1100_USB_NETLINK=m
++CONFIG_SA1100_USB_CHAR=m
++CONFIG_SA1100_FREQUENCY_SCALE=m
++# CONFIG_SA1100_VOLTAGE_SCALE is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++
++#
++# Please ensure that you have read the help on the next option
++#
++# CONFIG_ANGELBOOT is not set
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=m
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=m
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="root=/dev/nfs mem=16M"
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++CONFIG_UCB1200=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG 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
++
++#
++# RAM/ROM Device Drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_MTDRAM is not set
++
++#
++# Linearly Mapped Flash Device Drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_CFI_GEOMETRY is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_PNC2000 is not set
++# CONFIG_MTD_RPXLITE is not set
++# CONFIG_MTD_SC520CDP is not set
++# CONFIG_MTD_SBC_MEDIAGX is not set
++# CONFIG_MTD_ELAN_104NC is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_CSTM_CFI_JEDEC is not set
++# CONFIG_MTD_JEDEC is not set
++# CONFIG_MTD_MIXMEM is not set
++# CONFIG_MTD_OCTAGON is not set
++# CONFIG_MTD_VMAX is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_NAND_SPIA 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
++
++#
++# 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_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# 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_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++# CONFIG_NETLINK 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_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE 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
++# CONFIG_ATM is not set
++
++#
++#
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK 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 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_NET_SB1000 is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_LANCE is not set
++CONFIG_NET_VENDOR_SMC=y
++# CONFIG_WD80x3 is not set
++# CONFIG_ULTRA is not set
++# CONFIG_ULTRA32 is not set
++CONFIG_SMC9194=y
++# CONFIG_NET_VENDOR_RACAL is not set
++# CONFIG_AT1700 is not set
++# CONFIG_DEPCA 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_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++CONFIG_PPP=m
++# CONFIG_PPP_MULTILINK is not set
++CONFIG_PPP_ASYNC=m
++CONFIG_PPP_SYNC_TTY=m
++CONFIG_PPP_DEFLATE=m
++# CONFIG_PPP_BSDCOMP is not set
++# CONFIG_PPPOE 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
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=m
++# CONFIG_PCMCIA_NMCLAN is not set
++CONFIG_PCMCIA_SMC91C92=m
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++CONFIG_IRDA=m
++
++#
++# IrDA protocols
++#
++CONFIG_IRLAN=m
++CONFIG_IRNET=m
++CONFIG_IRCOMM=m
++CONFIG_IRDA_ULTRA=y
++# CONFIG_IRDA_OPTIONS is not set
++
++#
++# Infrared-port device drivers
++#
++
++#
++# SIR device drivers
++#
++CONFIG_IRTTY_SIR=m
++CONFIG_IRPORT_SIR=m
++
++#
++# FIR device drivers
++#
++# CONFIG_NSC_FIR is not set
++# CONFIG_WINBOND_FIR is not set
++# CONFIG_TOSHIBA_FIR is not set
++# CONFIG_SMC_IRCC_FIR is not set
++CONFIG_SA1100_FIR=m
++
++#
++# Dongle support
++#
++# CONFIG_DONGLE is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++CONFIG_IDE=m
++
++#
++# IDE, ATA and ATAPI Block devices
++#
++CONFIG_BLK_DEV_IDE=m
++
++#
++# 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_IDEDISK=m
++# CONFIG_IDEDISK_MULTI_MODE is not set
++CONFIG_BLK_DEV_IDECS=m
++# 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
++
++#
++# 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_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O 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
++
++#
++# 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 is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++CONFIG_SERIAL=y
++# CONFIG_SERIAL_CONSOLE is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=115200
++CONFIG_TOUCHSCREEN_UCB1200=y
++# CONFIG_TOUCHSCREEN_BITSY is not set
++# CONFIG_PROFILER is not set
++# CONFIG_PFS168_SPI is not set
++CONFIG_PFS168_DTMF=y
++CONFIG_PFS168_MISC=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++
++#
++# I2C support
++#
++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_I2C_ASSABET is not set
++CONFIG_I2C_PFS168=y
++# CONFIG_I2C_ALGOPCF is not set
++CONFIG_I2C_CHARDEV=y
++CONFIG_I2C_SENSORS=y
++CONFIG_I2C_EEPROM=y
++CONFIG_I2C_EEPROM=y
++CONFIG_I2C_M41T11=y
++CONFIG_I2C_X9221=y
++CONFIG_I2C_PCF8574=y
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++CONFIG_MOUSE=y
++CONFIG_PSMOUSE=y
++# CONFIG_82C710_MOUSE is not set
++# CONFIG_PC110_PAD is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++
++#
++# Input core support is needed for joysticks
++#
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_SA1100_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
++# CONFIG_DRM is not set
++CONFIG_PCMCIA_SERIAL=m
++
++#
++# PCMCIA character device support
++#
++# CONFIG_PCMCIA_SERIAL_CS is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA 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_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_BFS_FS 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=y
++CONFIG_JFFS_FS_VERBOSE=0
++# CONFIG_JFFS2_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_RAMFS is not set
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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_SYSV_FS_WRITE 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
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=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
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_SMB_NLS is not set
++# CONFIG_NLS is not set
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_FB=y
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_CLPS711X is not set
++# CONFIG_FB_CYBER2000 is not set
++# CONFIG_FB_SA1100 is not set
++CONFIG_FB_MQ200=y
++# CONFIG_PFS168_MQVGA is not set
++CONFIG_PFS168_MQTFT=y
++# CONFIG_FB_VIRTUAL is not set
++CONFIG_FBCON_ADVANCED=y
++# CONFIG_FBCON_MFB is not set
++# CONFIG_FBCON_CFB2 is not set
++# CONFIG_FBCON_CFB4 is not set
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++CONFIG_FBCON_CFB24=y
++CONFIG_FBCON_CFB32=y
++# 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 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# USB support
++#
++CONFIG_USB=m
++# CONFIG_USB_DEBUG is not set
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++# CONFIG_USB_BANDWIDTH is not set
++
++#
++# USB Controllers
++#
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++CONFIG_USB_OHCI=m
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++# CONFIG_USB_STORAGE is not set
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# USB Human Interface Devices (HID)
++#
++CONFIG_USB_HID=m
++CONFIG_USB_KBD=m
++CONFIG_USB_MOUSE=m
++# CONFIG_USB_WACOM 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
++
++#
++# USB Multimedia devices
++#
++# CONFIG_USB_IBMCAM is not set
++# CONFIG_USB_OV511 is not set
++# CONFIG_USB_DSBR is not set
++# CONFIG_USB_DABUSB is not set
++
++#
++# USB Network adaptors
++#
++# CONFIG_USB_PLUSB is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_NET1080 is not set
++
++#
++# USB port drivers
++#
++# CONFIG_USB_USS720 is not set
++
++#
++# USB Serial Converter support
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB misc drivers
++#
++# CONFIG_USB_RIO500 is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_INFO=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_NO_PGT_CACHE is not set
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_DC21285_PORT is not set
+Index: linux-2.6.0-test5/arch/arm/configs/pfs168_mqvga_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/pfs168_mqvga_defconfig 2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/pfs168_mqvga_defconfig 2003-09-27 11:38:18.644693960 +0800
+@@ -0,0 +1,782 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_CLPS711X is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_BITSY is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++CONFIG_SA1100_PFS168=y
++CONFIG_SA1111=y
++CONFIG_SA1100_USB=m
++CONFIG_SA1100_USB_NETLINK=m
++CONFIG_SA1100_USB_CHAR=m
++CONFIG_SA1100_FREQUENCY_SCALE=m
++# CONFIG_SA1100_VOLTAGE_SCALE is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++
++#
++# Please ensure that you have read the help on the next option
++#
++# CONFIG_ANGELBOOT is not set
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=m
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=m
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="root=/dev/nfs mem=16M"
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++CONFIG_UCB1200=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG 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
++
++#
++# RAM/ROM Device Drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_MTDRAM is not set
++
++#
++# Linearly Mapped Flash Device Drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_CFI_GEOMETRY is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_PNC2000 is not set
++# CONFIG_MTD_RPXLITE is not set
++# CONFIG_MTD_SC520CDP is not set
++# CONFIG_MTD_SBC_MEDIAGX is not set
++# CONFIG_MTD_ELAN_104NC is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_CSTM_CFI_JEDEC is not set
++# CONFIG_MTD_JEDEC is not set
++# CONFIG_MTD_MIXMEM is not set
++# CONFIG_MTD_OCTAGON is not set
++# CONFIG_MTD_VMAX is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_NAND_SPIA 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
++
++#
++# 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_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# 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_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++# CONFIG_NETLINK 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_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE 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
++# CONFIG_ATM is not set
++
++#
++#
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK 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 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_NET_SB1000 is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_LANCE is not set
++CONFIG_NET_VENDOR_SMC=y
++# CONFIG_WD80x3 is not set
++# CONFIG_ULTRA is not set
++# CONFIG_ULTRA32 is not set
++CONFIG_SMC9194=y
++# CONFIG_NET_VENDOR_RACAL is not set
++# CONFIG_AT1700 is not set
++# CONFIG_DEPCA 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_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++CONFIG_PPP=m
++# CONFIG_PPP_MULTILINK is not set
++CONFIG_PPP_ASYNC=m
++CONFIG_PPP_SYNC_TTY=m
++CONFIG_PPP_DEFLATE=m
++# CONFIG_PPP_BSDCOMP is not set
++# CONFIG_PPPOE 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
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=m
++# CONFIG_PCMCIA_NMCLAN is not set
++CONFIG_PCMCIA_SMC91C92=m
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++CONFIG_IRDA=m
++
++#
++# IrDA protocols
++#
++CONFIG_IRLAN=m
++CONFIG_IRNET=m
++CONFIG_IRCOMM=m
++CONFIG_IRDA_ULTRA=y
++# CONFIG_IRDA_OPTIONS is not set
++
++#
++# Infrared-port device drivers
++#
++
++#
++# SIR device drivers
++#
++CONFIG_IRTTY_SIR=m
++CONFIG_IRPORT_SIR=m
++
++#
++# FIR device drivers
++#
++# CONFIG_NSC_FIR is not set
++# CONFIG_WINBOND_FIR is not set
++# CONFIG_TOSHIBA_FIR is not set
++# CONFIG_SMC_IRCC_FIR is not set
++CONFIG_SA1100_FIR=m
++
++#
++# Dongle support
++#
++# CONFIG_DONGLE is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++CONFIG_IDE=m
++
++#
++# IDE, ATA and ATAPI Block devices
++#
++CONFIG_BLK_DEV_IDE=m
++
++#
++# 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_IDEDISK=m
++# CONFIG_IDEDISK_MULTI_MODE is not set
++CONFIG_BLK_DEV_IDECS=m
++# 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
++
++#
++# 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_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O 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
++
++#
++# 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 is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++CONFIG_SERIAL=y
++# CONFIG_SERIAL_CONSOLE is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=115200
++CONFIG_TOUCHSCREEN_UCB1200=y
++# CONFIG_TOUCHSCREEN_BITSY is not set
++# CONFIG_PROFILER is not set
++# CONFIG_PFS168_SPI is not set
++CONFIG_PFS168_DTMF=y
++CONFIG_PFS168_MISC=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++
++#
++# I2C support
++#
++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_I2C_ASSABET is not set
++CONFIG_I2C_PFS168=y
++# CONFIG_I2C_ALGOPCF is not set
++CONFIG_I2C_CHARDEV=y
++CONFIG_I2C_SENSORS=y
++CONFIG_I2C_EEPROM=y
++CONFIG_I2C_EEPROM=y
++CONFIG_I2C_M41T11=y
++CONFIG_I2C_X9221=y
++CONFIG_I2C_PCF8574=y
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++CONFIG_MOUSE=y
++CONFIG_PSMOUSE=y
++# CONFIG_82C710_MOUSE is not set
++# CONFIG_PC110_PAD is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++
++#
++# Input core support is needed for joysticks
++#
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_SA1100_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
++# CONFIG_DRM is not set
++CONFIG_PCMCIA_SERIAL=m
++
++#
++# PCMCIA character device support
++#
++# CONFIG_PCMCIA_SERIAL_CS is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA 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_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_BFS_FS 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=y
++CONFIG_JFFS_FS_VERBOSE=0
++# CONFIG_JFFS2_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_RAMFS is not set
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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_SYSV_FS_WRITE 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
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=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
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_SMB_NLS is not set
++# CONFIG_NLS is not set
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_FB=y
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_CLPS711X is not set
++# CONFIG_FB_CYBER2000 is not set
++# CONFIG_FB_SA1100 is not set
++CONFIG_FB_MQ200=y
++CONFIG_PFS168_MQVGA=y
++# CONFIG_PFS168_MQTFT is not set
++# CONFIG_FB_VIRTUAL is not set
++CONFIG_FBCON_ADVANCED=y
++# CONFIG_FBCON_MFB is not set
++# CONFIG_FBCON_CFB2 is not set
++# CONFIG_FBCON_CFB4 is not set
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++CONFIG_FBCON_CFB24=y
++CONFIG_FBCON_CFB32=y
++# 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 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# USB support
++#
++CONFIG_USB=m
++# CONFIG_USB_DEBUG is not set
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++# CONFIG_USB_BANDWIDTH is not set
++
++#
++# USB Controllers
++#
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++CONFIG_USB_OHCI=m
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++# CONFIG_USB_STORAGE is not set
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# USB Human Interface Devices (HID)
++#
++CONFIG_USB_HID=m
++CONFIG_USB_KBD=m
++CONFIG_USB_MOUSE=m
++# CONFIG_USB_WACOM 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
++
++#
++# USB Multimedia devices
++#
++# CONFIG_USB_IBMCAM is not set
++# CONFIG_USB_OV511 is not set
++# CONFIG_USB_DSBR is not set
++# CONFIG_USB_DABUSB is not set
++
++#
++# USB Network adaptors
++#
++# CONFIG_USB_PLUSB is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_NET1080 is not set
++
++#
++# USB port drivers
++#
++# CONFIG_USB_USS720 is not set
++
++#
++# USB Serial Converter support
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB misc drivers
++#
++# CONFIG_USB_RIO500 is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_INFO=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_NO_PGT_CACHE is not set
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_DC21285_PORT is not set
+Index: linux-2.6.0-test5/arch/arm/configs/pfs168_sastn_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/pfs168_sastn_defconfig 2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/pfs168_sastn_defconfig 2003-09-27 11:38:18.646693656 +0800
+@@ -0,0 +1,774 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_CLPS711X is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_BITSY is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++CONFIG_SA1100_PFS168=y
++CONFIG_SA1111=y
++CONFIG_SA1100_USB=m
++CONFIG_SA1100_USB_NETLINK=m
++CONFIG_SA1100_USB_CHAR=m
++CONFIG_SA1100_FREQUENCY_SCALE=m
++# CONFIG_SA1100_VOLTAGE_SCALE is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++
++#
++# Please ensure that you have read the help on the next option
++#
++# CONFIG_ANGELBOOT is not set
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=m
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=m
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="root=/dev/nfs mem=16M"
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++CONFIG_UCB1200=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG 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
++
++#
++# RAM/ROM Device Drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_MTDRAM is not set
++
++#
++# Linearly Mapped Flash Device Drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_CFI_ADV_OPTIONS is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_PNC2000 is not set
++# CONFIG_MTD_RPXLITE is not set
++# CONFIG_MTD_SC520CDP is not set
++# CONFIG_MTD_SBC_MEDIAGX is not set
++# CONFIG_MTD_ELAN_104NC is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++# CONFIG_MTD_CSTM_CFI_JEDEC is not set
++# CONFIG_MTD_JEDEC is not set
++# CONFIG_MTD_MIXMEM is not set
++# CONFIG_MTD_OCTAGON is not set
++# CONFIG_MTD_VMAX is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_NAND_SPIA 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
++
++#
++# 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_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# 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_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++# CONFIG_NETLINK 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_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE 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
++# CONFIG_ATM is not set
++
++#
++#
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK 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 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_NET_SB1000 is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_LANCE is not set
++CONFIG_NET_VENDOR_SMC=y
++# CONFIG_WD80x3 is not set
++# CONFIG_ULTRA is not set
++# CONFIG_ULTRA32 is not set
++CONFIG_SMC9194=y
++# CONFIG_NET_VENDOR_RACAL is not set
++# CONFIG_AT1700 is not set
++# CONFIG_DEPCA 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_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++CONFIG_PPP=m
++# CONFIG_PPP_MULTILINK is not set
++CONFIG_PPP_ASYNC=m
++CONFIG_PPP_SYNC_TTY=m
++CONFIG_PPP_DEFLATE=m
++# CONFIG_PPP_BSDCOMP is not set
++# CONFIG_PPPOE 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
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=m
++# CONFIG_PCMCIA_NMCLAN is not set
++CONFIG_PCMCIA_SMC91C92=m
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++CONFIG_IRDA=m
++
++#
++# IrDA protocols
++#
++CONFIG_IRLAN=m
++CONFIG_IRNET=m
++CONFIG_IRCOMM=m
++CONFIG_IRDA_ULTRA=y
++# CONFIG_IRDA_OPTIONS is not set
++
++#
++# Infrared-port device drivers
++#
++
++#
++# SIR device drivers
++#
++CONFIG_IRTTY_SIR=m
++CONFIG_IRPORT_SIR=m
++
++#
++# FIR device drivers
++#
++# CONFIG_NSC_FIR is not set
++# CONFIG_WINBOND_FIR is not set
++# CONFIG_TOSHIBA_FIR is not set
++# CONFIG_SMC_IRCC_FIR is not set
++CONFIG_SA1100_FIR=m
++
++#
++# Dongle support
++#
++# CONFIG_DONGLE is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++CONFIG_IDE=m
++
++#
++# IDE, ATA and ATAPI Block devices
++#
++CONFIG_BLK_DEV_IDE=m
++
++#
++# 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_IDEDISK=m
++# CONFIG_IDEDISK_MULTI_MODE is not set
++CONFIG_BLK_DEV_IDECS=m
++# 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
++
++#
++# 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_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O 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
++
++#
++# 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 is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++CONFIG_SERIAL=y
++# CONFIG_SERIAL_CONSOLE is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=115200
++CONFIG_TOUCHSCREEN_UCB1200=y
++# CONFIG_TOUCHSCREEN_BITSY is not set
++# CONFIG_PROFILER is not set
++# CONFIG_PFS168_SPI is not set
++CONFIG_PFS168_DTMF=y
++CONFIG_PFS168_MISC=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++
++#
++# I2C support
++#
++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_I2C_ASSABET is not set
++# CONFIG_I2C_ALGOPCF is not set
++CONFIG_I2C_CHARDEV=y
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++CONFIG_MOUSE=y
++CONFIG_PSMOUSE=y
++# CONFIG_82C710_MOUSE is not set
++# CONFIG_PC110_PAD is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++
++#
++# Input core support is needed for joysticks
++#
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_SA1100_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
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++# CONFIG_PCMCIA_SERIAL_CS is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA 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_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_BFS_FS 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=y
++CONFIG_JFFS_FS_VERBOSE=0
++# CONFIG_JFFS2_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_RAMFS is not set
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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_SYSV_FS_WRITE 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
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=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
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_SMB_NLS is not set
++# CONFIG_NLS is not set
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_FB=y
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_CLPS711X is not set
++# CONFIG_FB_CYBER2000 is not set
++CONFIG_FB_SA1100=y
++# CONFIG_FB_VIRTUAL is not set
++CONFIG_FBCON_ADVANCED=y
++# CONFIG_FBCON_MFB is not set
++# CONFIG_FBCON_CFB2 is not set
++# CONFIG_FBCON_CFB4 is not set
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++CONFIG_FBCON_CFB24=y
++CONFIG_FBCON_CFB32=y
++# 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 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# USB support
++#
++CONFIG_USB=m
++# CONFIG_USB_DEBUG is not set
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++# CONFIG_USB_BANDWIDTH is not set
++
++#
++# USB Controllers
++#
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++CONFIG_USB_OHCI=m
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++# CONFIG_USB_STORAGE is not set
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# USB Human Interface Devices (HID)
++#
++CONFIG_USB_HID=m
++CONFIG_USB_KBD=m
++CONFIG_USB_MOUSE=m
++# CONFIG_USB_WACOM 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
++
++#
++# USB Multimedia devices
++#
++# CONFIG_USB_IBMCAM is not set
++# CONFIG_USB_OV511 is not set
++# CONFIG_USB_DSBR is not set
++# CONFIG_USB_DABUSB is not set
++
++#
++# USB Network adaptors
++#
++# CONFIG_USB_PLUSB is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_NET1080 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 misc drivers
++#
++# CONFIG_USB_RIO500 is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_INFO=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_NO_PGT_CACHE is not set
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/pfs168_satft_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/pfs168_satft_defconfig 2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/pfs168_satft_defconfig 2003-09-27 11:38:18.647693504 +0800
+@@ -0,0 +1,782 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_CLPS711X is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_BITSY is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++CONFIG_SA1100_PFS168=y
++CONFIG_SA1111=y
++CONFIG_SA1100_USB=m
++CONFIG_SA1100_USB_NETLINK=m
++CONFIG_SA1100_USB_CHAR=m
++CONFIG_SA1100_FREQUENCY_SCALE=m
++# CONFIG_SA1100_VOLTAGE_SCALE is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++
++#
++# Please ensure that you have read the help on the next option
++#
++# CONFIG_ANGELBOOT is not set
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=m
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=m
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="root=/dev/nfs mem=16M"
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++CONFIG_UCB1200=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG 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
++
++#
++# RAM/ROM Device Drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_MTDRAM is not set
++
++#
++# Linearly Mapped Flash Device Drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_CFI_GEOMETRY is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_PNC2000 is not set
++# CONFIG_MTD_RPXLITE is not set
++# CONFIG_MTD_SC520CDP is not set
++# CONFIG_MTD_SBC_MEDIAGX is not set
++# CONFIG_MTD_ELAN_104NC is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_CSTM_CFI_JEDEC is not set
++# CONFIG_MTD_JEDEC is not set
++# CONFIG_MTD_MIXMEM is not set
++# CONFIG_MTD_OCTAGON is not set
++# CONFIG_MTD_VMAX is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_NAND_SPIA 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
++
++#
++# 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_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# 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_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++# CONFIG_NETLINK 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_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE 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
++# CONFIG_ATM is not set
++
++#
++#
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK 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 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_NET_SB1000 is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_LANCE is not set
++CONFIG_NET_VENDOR_SMC=y
++# CONFIG_WD80x3 is not set
++# CONFIG_ULTRA is not set
++# CONFIG_ULTRA32 is not set
++CONFIG_SMC9194=y
++# CONFIG_NET_VENDOR_RACAL is not set
++# CONFIG_AT1700 is not set
++# CONFIG_DEPCA 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_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++CONFIG_PPP=m
++# CONFIG_PPP_MULTILINK is not set
++CONFIG_PPP_ASYNC=m
++CONFIG_PPP_SYNC_TTY=m
++CONFIG_PPP_DEFLATE=m
++# CONFIG_PPP_BSDCOMP is not set
++# CONFIG_PPPOE 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
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=m
++# CONFIG_PCMCIA_NMCLAN is not set
++CONFIG_PCMCIA_SMC91C92=m
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++CONFIG_IRDA=m
++
++#
++# IrDA protocols
++#
++CONFIG_IRLAN=m
++CONFIG_IRNET=m
++CONFIG_IRCOMM=m
++CONFIG_IRDA_ULTRA=y
++# CONFIG_IRDA_OPTIONS is not set
++
++#
++# Infrared-port device drivers
++#
++
++#
++# SIR device drivers
++#
++CONFIG_IRTTY_SIR=m
++CONFIG_IRPORT_SIR=m
++
++#
++# FIR device drivers
++#
++# CONFIG_NSC_FIR is not set
++# CONFIG_WINBOND_FIR is not set
++# CONFIG_TOSHIBA_FIR is not set
++# CONFIG_SMC_IRCC_FIR is not set
++CONFIG_SA1100_FIR=m
++
++#
++# Dongle support
++#
++# CONFIG_DONGLE is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++CONFIG_IDE=m
++
++#
++# IDE, ATA and ATAPI Block devices
++#
++CONFIG_BLK_DEV_IDE=m
++
++#
++# 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_IDEDISK=m
++# CONFIG_IDEDISK_MULTI_MODE is not set
++CONFIG_BLK_DEV_IDECS=m
++# 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
++
++#
++# 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_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O 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
++
++#
++# 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 is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++CONFIG_SERIAL=y
++# CONFIG_SERIAL_CONSOLE is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=115200
++CONFIG_TOUCHSCREEN_UCB1200=y
++# CONFIG_TOUCHSCREEN_BITSY is not set
++# CONFIG_PROFILER is not set
++# CONFIG_PFS168_SPI is not set
++CONFIG_PFS168_DTMF=y
++CONFIG_PFS168_MISC=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++
++#
++# I2C support
++#
++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_I2C_ASSABET is not set
++CONFIG_I2C_PFS168=y
++# CONFIG_I2C_ALGOPCF is not set
++CONFIG_I2C_CHARDEV=y
++CONFIG_I2C_SENSORS=y
++CONFIG_I2C_EEPROM=y
++CONFIG_I2C_EEPROM=y
++CONFIG_I2C_M41T11=y
++CONFIG_I2C_X9221=y
++CONFIG_I2C_PCF8574=y
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++CONFIG_MOUSE=y
++CONFIG_PSMOUSE=y
++# CONFIG_82C710_MOUSE is not set
++# CONFIG_PC110_PAD is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++
++#
++# Input core support is needed for joysticks
++#
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_SA1100_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
++# CONFIG_DRM is not set
++CONFIG_PCMCIA_SERIAL=m
++
++#
++# PCMCIA character device support
++#
++# CONFIG_PCMCIA_SERIAL_CS is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA 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_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_BFS_FS 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=y
++CONFIG_JFFS_FS_VERBOSE=0
++# CONFIG_JFFS2_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_RAMFS is not set
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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_SYSV_FS_WRITE 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
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=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
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_SMB_NLS is not set
++# CONFIG_NLS is not set
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_FB=y
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_CLPS711X is not set
++# CONFIG_FB_CYBER2000 is not set
++CONFIG_FB_SA1100=y
++# CONFIG_PFS168_SASTN is not set
++CONFIG_PFS168_SATFT=y
++# CONFIG_FB_MQ200 is not set
++# CONFIG_FB_VIRTUAL is not set
++CONFIG_FBCON_ADVANCED=y
++# CONFIG_FBCON_MFB is not set
++# CONFIG_FBCON_CFB2 is not set
++# CONFIG_FBCON_CFB4 is not set
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++CONFIG_FBCON_CFB24=y
++CONFIG_FBCON_CFB32=y
++# 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 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# USB support
++#
++CONFIG_USB=m
++# CONFIG_USB_DEBUG is not set
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++# CONFIG_USB_BANDWIDTH is not set
++
++#
++# USB Controllers
++#
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++CONFIG_USB_OHCI=m
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++# CONFIG_USB_STORAGE is not set
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# USB Human Interface Devices (HID)
++#
++CONFIG_USB_HID=m
++CONFIG_USB_KBD=m
++CONFIG_USB_MOUSE=m
++# CONFIG_USB_WACOM 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
++
++#
++# USB Multimedia devices
++#
++# CONFIG_USB_IBMCAM is not set
++# CONFIG_USB_OV511 is not set
++# CONFIG_USB_DSBR is not set
++# CONFIG_USB_DABUSB is not set
++
++#
++# USB Network adaptors
++#
++# CONFIG_USB_PLUSB is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_NET1080 is not set
++
++#
++# USB port drivers
++#
++# CONFIG_USB_USS720 is not set
++
++#
++# USB Serial Converter support
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB misc drivers
++#
++# CONFIG_USB_RIO500 is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_INFO=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_NO_PGT_CACHE is not set
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_DC21285_PORT is not set
+Index: linux-2.6.0-test5/arch/arm/configs/pleb_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/pleb_defconfig 2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/pleb_defconfig 2003-09-27 11:38:18.649693200 +0800
+@@ -0,0 +1,535 @@
++#
++# Automatically generated by make menuconfig: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_ANAKIN is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_BITSY is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++CONFIG_SA1100_PLEB=y
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++# CONFIG_SA1100_USB is not set
++# CONFIG_SA1100_USB_NETLINK is not set
++# CONFIG_SA1100_USB_CHAR is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++CONFIG_DISCONTIGMEM=y
++# CONFIG_CPU_BIG_ENDIAN is not set
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++CONFIG_CPU_FREQ=y
++# CONFIG_HOTPLUG is not set
++# CONFIG_PCMCIA is not set
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_APM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="console=ttySA0,9600 mem=16M@0xc0000000 mem=16M@0xc8000000 root=/dev/ram initrd=0xc0400000,4M"
++# CONFIG_PFS168_CMDLINE is not set
++# CONFIG_LEDS is not set
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++# CONFIG_MTD is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++# CONFIG_MTD_CFI is not set
++# CONFIG_MTD_CFI_INTELEXT is not set
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_JEDEC is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_SUN_UFLASH is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_PNC2000 is not set
++# CONFIG_MTD_RPXLITE is not set
++# CONFIG_MTD_SC520CDP is not set
++# CONFIG_MTD_NETSC520 is not set
++# CONFIG_MTD_SBC_GXX is not set
++# CONFIG_MTD_ELAN_104NC is not set
++# CONFIG_MTD_SA1100 is not set
++# CONFIG_MTD_SA1100_REDBOOT_PARTITIONS is not set
++# CONFIG_MTD_SA1100_BOOTLDR_PARTITIONS is not set
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++# CONFIG_MTD_DBOX2 is not set
++# CONFIG_MTD_CSTM_MIPS_IXX is not set
++# CONFIG_MTD_CFI_FLAGADM is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_MIXMEM is not set
++# CONFIG_MTD_OCTAGON is not set
++# CONFIG_MTD_VMAX is not set
++# CONFIG_MTD_OCELOT 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_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
++
++#
++# 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_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=8192
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# 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_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=m
++# CONFIG_PACKET_MMAP is not set
++# CONFIG_NETLINK 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 is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++CONFIG_INET_ECN=y
++CONFIG_SYN_COOKIES=y
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++CONFIG_DUMMY=m
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++# CONFIG_NET_ETHERNET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_ACENIC_OMIT_TIGON_I is not set
++# CONFIG_MYRI_SBUS is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_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
++
++#
++# ATA/IDE/MFM/RLL support
++#
++# CONFIG_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O 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
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++# CONFIG_INPUT is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++# CONFIG_SERIAL_SA1100_OLD is not set
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=9600
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++# CONFIG_UCB1200 is not set
++# CONFIG_TOUCHSCREEN_UCB1200 is not set
++# CONFIG_AUDIO_UCB1200 is not set
++# CONFIG_ADC_UCB1200 is not set
++# CONFIG_TOUCHSCREEN_BITSY is not set
++CONFIG_PROFILER=y
++# CONFIG_PFS168_SPI is not set
++# CONFIG_PFS168_DTMF is not set
++# CONFIG_PFS168_MISC is not set
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++CONFIG_SA1100_RTC=y
++# 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
++# CONFIG_DRM is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA 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_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_BFS_FS 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 is not set
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_NFS_FS is not set
++# CONFIG_NFS_V3 is not set
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++# CONFIG_SUNRPC is not set
++# CONFIG_LOCKD is not set
++# 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
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_SMB_NLS is not set
++# CONFIG_NLS is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_NO_PGT_CACHE is not set
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/rpc_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/rpc_defconfig 2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/rpc_defconfig 2003-09-27 11:38:18.650693048 +0800
+@@ -0,0 +1,781 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++CONFIG_MMU=y
++CONFIG_SWAP=y
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++
++#
++# General setup
++#
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_ADIFCC is not set
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_IOP310 is not set
++# CONFIG_ARCH_L7200 is not set
++CONFIG_ARCH_RPC=y
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++
++#
++# CLPS711X/EP721X Implementations
++#
++
++#
++# Epxa10db
++#
++
++#
++# Footbridge Implementations
++#
++
++#
++# IOP310 Implementation Options
++#
++
++#
++# IOP310 Chipset Features
++#
++
++#
++# Intel PXA250/210 Implementations
++#
++
++#
++# SA11x0 Implementations
++#
++CONFIG_ARCH_ACORN=y
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_ARM610=y
++CONFIG_CPU_ARM710=y
++CONFIG_CPU_SA110=y
++CONFIG_CPU_32v3=y
++
++#
++# Processor Features
++#
++
++#
++# General setup
++#
++CONFIG_FIQ=y
++# CONFIG_ZBOOT_ROM is not set
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++# CONFIG_HOTPLUG is not set
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_PREEMPT is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE=""
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++CONFIG_PARPORT=y
++CONFIG_PARPORT_PC=y
++CONFIG_PARPORT_PC_CML1=y
++# CONFIG_PARPORT_SERIAL is not set
++CONFIG_PARPORT_PC_FIFO=y
++# CONFIG_PARPORT_PC_SUPERIO is not set
++# CONFIG_PARPORT_ARC is not set
++# CONFIG_PARPORT_OTHER is not set
++# CONFIG_PARPORT_1284 is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++# CONFIG_MTD is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++
++#
++# Block devices
++#
++CONFIG_BLK_DEV_FD=y
++# CONFIG_PARIDE is not set
++CONFIG_BLK_DEV_LOOP=m
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++
++#
++# Acorn-specific block devices
++#
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++CONFIG_NETLINK_DEV=y
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++# CONFIG_IP_PNP 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
++# CONFIG_IPV6 is not set
++
++#
++# SCTP Configuration (EXPERIMENTAL)
++#
++CONFIG_IPV6_SCTP__=y
++# CONFIG_IP_SCTP is not set
++# CONFIG_ATM is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_LLC is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB 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 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_ARM_ETHER1=y
++CONFIG_ARM_ETHER3=y
++CONFIG_ARM_ETHERH=y
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_NET_VENDOR_SMC is not set
++# CONFIG_NET_VENDOR_RACAL is not set
++# CONFIG_NET_POCKET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PLIP is not set
++CONFIG_PPP=m
++# CONFIG_PPP_MULTILINK is not set
++# CONFIG_PPP_ASYNC is not set
++# CONFIG_PPP_SYNC_TTY is not set
++# CONFIG_PPP_DEFLATE is not set
++# CONFIG_PPP_BSDCOMP is not set
++CONFIG_PPPOE=m
++# CONFIG_SLIP is not set
++
++#
++# Wireless LAN (non-hamradio)
++#
++# CONFIG_NET_RADIO is not set
++
++#
++# Token Ring devices
++#
++# CONFIG_NET_FC is not set
++# CONFIG_SHAPER is not set
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# ATA/ATAPI/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 is not set
++CONFIG_BLK_DEV_IDEDISK=y
++CONFIG_IDEDISK_MULTI_MODE=y
++# CONFIG_IDEDISK_STROKE is not set
++CONFIG_BLK_DEV_IDECD=y
++# 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_IDEDMA=y
++CONFIG_BLK_DEV_IDE_ICSIDE=y
++CONFIG_BLK_DEV_IDEDMA_ICS=y
++CONFIG_IDEDMA_ICS_AUTO=y
++CONFIG_BLK_DEV_IDE_RAPIDE=y
++CONFIG_IDEDMA_AUTO=y
++# CONFIG_IDEDMA_IVB is not set
++
++#
++# SCSI support
++#
++CONFIG_SCSI=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++CONFIG_CHR_DEV_ST=m
++# CONFIG_CHR_DEV_OSST is not set
++CONFIG_BLK_DEV_SR=y
++CONFIG_BLK_DEV_SR_VENDOR=y
++CONFIG_SR_EXTRA_DEVS=2
++CONFIG_CHR_DEV_SG=y
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_REPORT_LUNS is not set
++CONFIG_SCSI_CONSTANTS=y
++CONFIG_SCSI_LOGGING=y
++
++#
++# SCSI low-level drivers
++#
++# CONFIG_SCSI_ACARD is not set
++# CONFIG_SCSI_AIC7XXX 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_MEGARAID is not set
++# CONFIG_SCSI_BUSLOGIC 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_GENERIC_NCR5380_MMIO is not set
++CONFIG_SCSI_PPA=m
++CONFIG_SCSI_IMM=m
++# CONFIG_SCSI_IZIP_EPP16 is not set
++# CONFIG_SCSI_IZIP_SLOW_CTR is not set
++# CONFIG_SCSI_PCI2000 is not set
++# CONFIG_SCSI_PCI2220I is not set
++# CONFIG_SCSI_U14_34F is not set
++# CONFIG_SCSI_NSP32 is not set
++# CONFIG_SCSI_DEBUG is not set
++CONFIG_SCSI_ACORNSCSI_3=m
++CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE=y
++CONFIG_SCSI_ACORNSCSI_SYNC=y
++CONFIG_SCSI_ARXESCSI=m
++CONFIG_SCSI_CUMANA_2=m
++CONFIG_SCSI_EESOXSCSI=m
++CONFIG_SCSI_POWERTECSCSI=y
++
++#
++# The following drivers are not fully supported
++#
++CONFIG_SCSI_CUMANA_1=m
++CONFIG_SCSI_OAK1=m
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN_BOOL is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_TSDEV is not set
++# CONFIG_INPUT_TSLIBDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input I/O drivers
++#
++# CONFIG_GAMEPORT is not set
++CONFIG_SOUND_GAMEPORT=y
++CONFIG_SERIO=y
++# CONFIG_SERIO_I8042 is not set
++# CONFIG_SERIO_SERPORT is not set
++# CONFIG_SERIO_CT82C710 is not set
++# CONFIG_SERIO_PARKBD is not set
++CONFIG_SERIO_RPCKBD=y
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++CONFIG_INPUT_MOUSE=y
++# CONFIG_MOUSE_PS2 is not set
++# CONFIG_MOUSE_SERIAL is not set
++CONFIG_MOUSE_RISCPC=y
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_8250_ACORN=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++CONFIG_PRINTER=m
++# CONFIG_LP_CONSOLE is not set
++# CONFIG_PPDEV is not set
++# CONFIG_TIPAR is not set
++
++#
++# I2C support
++#
++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_ACB is not set
++# CONFIG_I2C_ALGOPCF is not set
++CONFIG_I2C_CHARDEV=y
++# CONFIG_I2C_PROC is not set
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_GEN_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
++# CONFIG_DRM is not set
++# CONFIG_RAW_DRIVER is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++CONFIG_AUTOFS4_FS=m
++# CONFIG_REISERFS_FS is not set
++CONFIG_ADFS_FS=y
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++CONFIG_EXT3_FS=y
++CONFIG_EXT3_FS_XATTR=y
++# CONFIG_EXT3_FS_POSIX_ACL is not set
++CONFIG_JBD=y
++# CONFIG_JBD_DEBUG is not set
++# CONFIG_FAT_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_TMPFS is not set
++CONFIG_RAMFS=y
++CONFIG_ISO9660_FS=y
++CONFIG_JOLIET=y
++# CONFIG_ZISOFS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_HPFS_FS is not set
++CONFIG_PROC_FS=y
++# CONFIG_DEVFS_FS is not set
++CONFIG_DEVPTS_FS=y
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_XFS_FS 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 is not set
++# CONFIG_NFS_V4 is not set
++# CONFIG_NFSD is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=y
++# CONFIG_EXPORTFS is not set
++# CONFIG_CIFS is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_AFS_FS is not set
++CONFIG_FS_MBCACHE=y
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++CONFIG_ACORN_PARTITION=y
++# CONFIG_ACORN_PARTITION_CUMANA is not set
++# CONFIG_ACORN_PARTITION_EESOX is not set
++CONFIG_ACORN_PARTITION_ICS=y
++CONFIG_ACORN_PARTITION_ADFS=y
++CONFIG_ACORN_PARTITION_POWERTEC=y
++CONFIG_ACORN_PARTITION_RISCIX=y
++CONFIG_OSF_PARTITION=y
++CONFIG_AMIGA_PARTITION=y
++# CONFIG_ATARI_PARTITION is not set
++CONFIG_MAC_PARTITION=y
++CONFIG_MSDOS_PARTITION=y
++CONFIG_BSD_DISKLABEL=y
++# CONFIG_MINIX_SUBPARTITION is not set
++CONFIG_SOLARIS_X86_PARTITION=y
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++CONFIG_SGI_PARTITION=y
++# CONFIG_ULTRIX_PARTITION is not set
++CONFIG_SUN_PARTITION=y
++# CONFIG_EFI_PARTITION is not set
++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 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=m
++CONFIG_NLS_ISO8859_8=m
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++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 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++CONFIG_NLS_KOI8_R=m
++# CONFIG_NLS_KOI8_U is not set
++# CONFIG_NLS_UTF8 is not set
++
++#
++# Console drivers
++#
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FB_ACORN=y
++# CONFIG_FB_VIRTUAL is not set
++CONFIG_FBCON_ADVANCED=y
++CONFIG_FBCON_MFB=y
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++CONFIG_FBCON_CFB24=y
++CONFIG_FBCON_CFB32=y
++# CONFIG_FBCON_ACCEL 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_VGA_PLANES is not set
++# CONFIG_FBCON_HGA is not set
++# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_SUN12x22 is not set
++CONFIG_FBCON_FONTS=y
++# CONFIG_FONT_8x8 is not set
++# CONFIG_FONT_8x16 is not set
++# CONFIG_FONT_6x11 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++CONFIG_FONT_ACORN_8x8=y
++# CONFIG_FONT_MINI_4x6 is not set
++
++#
++# Sound
++#
++CONFIG_SOUND=m
++
++#
++# Open Sound System
++#
++CONFIG_SOUND_PRIME=m
++# CONFIG_SOUND_BT878 is not set
++# CONFIG_SOUND_FUSION is not set
++# CONFIG_SOUND_CS4281 is not set
++# CONFIG_SOUND_ESSSOLO1 is not set
++# CONFIG_SOUND_MAESTRO is not set
++# CONFIG_SOUND_SONICVIBES is not set
++# CONFIG_SOUND_TRIDENT is not set
++# CONFIG_SOUND_MSNDCLAS is not set
++# CONFIG_SOUND_MSNDPIN is not set
++CONFIG_SOUND_OSS=m
++# CONFIG_SOUND_TRACEINIT is not set
++# CONFIG_SOUND_DMAP is not set
++# CONFIG_SOUND_AD1816 is not set
++# CONFIG_SOUND_SGALAXY is not set
++# CONFIG_SOUND_ADLIB is not set
++# CONFIG_SOUND_ACI_MIXER is not set
++# CONFIG_SOUND_CS4232 is not set
++# CONFIG_SOUND_SSCAPE is not set
++# CONFIG_SOUND_GUS is not set
++# CONFIG_SOUND_VMIDI is not set
++# CONFIG_SOUND_TRIX is not set
++# CONFIG_SOUND_MSS is not set
++# CONFIG_SOUND_MPU401 is not set
++# CONFIG_SOUND_NM256 is not set
++# CONFIG_SOUND_MAD16 is not set
++# CONFIG_SOUND_PAS is not set
++# CONFIG_SOUND_PSS is not set
++# CONFIG_SOUND_SB is not set
++# CONFIG_SOUND_AWE32_SYNTH is not set
++# CONFIG_SOUND_WAVEFRONT is not set
++# CONFIG_SOUND_MAUI is not set
++# CONFIG_SOUND_YM3812 is not set
++# CONFIG_SOUND_OPL3SA1 is not set
++# CONFIG_SOUND_OPL3SA2 is not set
++# CONFIG_SOUND_UART6850 is not set
++# CONFIG_SOUND_AEDSP16 is not set
++CONFIG_SOUND_VIDC=m
++# CONFIG_SOUND_TVMIXER is not set
++
++#
++# Advanced Linux Sound Architecture
++#
++# CONFIG_SND is not set
++
++#
++# Misc devices
++#
++
++#
++# Multimedia Capabilities Port drivers
++#
++# CONFIG_MCP is not set
++
++#
++# Console Switches
++#
++# CONFIG_SWITCHES is not set
++
++#
++# USB support
++#
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SLAB is not set
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_WAITQ is not set
++# CONFIG_DEBUG_BUGVERBOSE is not set
++CONFIG_DEBUG_ERRORS=y
++# CONFIG_KALLSYMS is not set
++CONFIG_DEBUG_LL=y
++
++#
++# Security options
++#
++CONFIG_SECURITY_CAPABILITIES=y
++
++#
++# Cryptographic options
++#
++# CONFIG_CRYPTO is not set
++
++#
++# Library routines
++#
++# CONFIG_CRC32 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/shannon_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/shannon_defconfig 2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/shannon_defconfig 2003-09-27 11:38:18.652692744 +0800
+@@ -0,0 +1,735 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++# CONFIG_GENERIC_BUST_SPINLOCK is not set
++# CONFIG_GENERIC_ISA_DMA is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_OBSOLETE=y
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++
++#
++# Footbridge Implementations
++#
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++CONFIG_SA1100_SHANNON=y
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++# CONFIG_SA1100_USB is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM922T is not set
++# CONFIG_CPU_ARM926T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++# CONFIG_ARM_THUMB is not set
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++CONFIG_ISA=y
++# CONFIG_ISA_DMA is not set
++# CONFIG_CPU_FREQ is not set
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=y
++# CONFIG_I82092 is not set
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++CONFIG_PCMCIA_SA1100=y
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="console=ttySA0,9600 console=tty1 root=/dev/mtdblock2 init=/linuxrc"
++# CONFIG_LEDS is not set
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_BOOTLDR_PARTS is not set
++# CONFIG_MTD_AFS_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_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_OBSOLETE_CHIPS is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_IQ80310 is not set
++
++#
++# Self-contained MTD device drivers
++#
++# 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
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# CONFIG_BLK_DEV_XD is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=8192
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++# CONFIG_NETLINK 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 is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE 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
++# CONFIG_ATM is not set
++
++#
++#
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK 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 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
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# 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_AT1700 is not set
++# CONFIG_DEPCA 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_OMIT_TIGON_I is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI 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_SHAPER is not set
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=y
++# CONFIG_PCMCIA_NMCLAN is not set
++CONFIG_PCMCIA_SMC91C92=y
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++CONFIG_IDE=m
++
++#
++# IDE, ATA and ATAPI Block devices
++#
++CONFIG_BLK_DEV_IDE=m
++
++#
++# 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_IDEDISK is not set
++# CONFIG_BLK_DEV_IDECS is not set
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++# CONFIG_BLK_DEV_ATARAID is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++CONFIG_INPUT=y
++CONFIG_INPUT_KEYBDEV=y
++# CONFIG_INPUT_MOUSEDEV is not set
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=9600
++# CONFIG_SERIAL_8250 is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++
++#
++# Other L3 adapters
++#
++# CONFIG_BIT_SA1100_GPIO is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++
++#
++# Joysticks
++#
++# CONFIG_INPUT_GAMEPORT is not set
++# CONFIG_INPUT_SERIO is not set
++
++#
++# Joysticks
++#
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++CONFIG_WATCHDOG=y
++# CONFIG_WATCHDOG_NOWAYOUT is not set
++# CONFIG_SOFT_WATCHDOG is not set
++# CONFIG_WDT is not set
++# CONFIG_WDTPCI is not set
++# CONFIG_PCWATCHDOG is not set
++# CONFIG_ACQUIRE_WDT is not set
++# CONFIG_ADVANTECH_WDT is not set
++CONFIG_SA1100_WATCHDOG=y
++# CONFIG_EUROTECH_WDT is not set
++# CONFIG_IB700_WDT is not set
++# CONFIG_I810_TCO is not set
++# CONFIG_MIXCOMWD is not set
++# CONFIG_60XX_WDT is not set
++# CONFIG_W83877F_WDT is not set
++# CONFIG_MACHZ_WDT is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++CONFIG_SA1100_RTC=y
++# 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
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_CMS_FS is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_JBD 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 is not set
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++CONFIG_MINIX_FS=y
++# CONFIG_FREEVXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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_DEVPTS_FS=y
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_EXT2_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UFS_FS 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 is not set
++# CONFIG_NFSD is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=y
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_ZISOFS_FS is not set
++# CONFIG_ZLIB_FS_INFLATE is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# 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_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
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FB_SA1100=y
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FBCON_ADVANCED is not set
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++# 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_BT878 is not set
++# CONFIG_SOUND_FUSION is not set
++# CONFIG_SOUND_CS4281 is not set
++# CONFIG_SOUND_ESSSOLO1 is not set
++# CONFIG_SOUND_MAESTRO is not set
++# CONFIG_SOUND_SONICVIBES is not set
++# CONFIG_SOUND_TRIDENT is not set
++# CONFIG_SOUND_MSNDCLAS is not set
++# CONFIG_SOUND_MSNDPIN is not set
++CONFIG_SOUND_SA1100=y
++# CONFIG_SOUND_SA1100SSP is not set
++# CONFIG_SOUND_OSS is not set
++
++#
++# Multimedia Capabilities Port drivers
++#
++CONFIG_MCP=y
++CONFIG_MCP_SA1100=y
++CONFIG_MCP_UCB1200=y
++CONFIG_MCP_UCB1200_AUDIO=y
++CONFIG_MCP_UCB1200_TS=y
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# USB Controllers
++#
++
++#
++# USB Device Class drivers
++#
++
++#
++# USB Human Interface Devices (HID)
++#
++
++#
++# USB Imaging devices
++#
++
++#
++# USB Multimedia devices
++#
++
++#
++# Video4Linux support is needed for USB Multimedia device support
++#
++
++#
++# USB Network adaptors
++#
++
++#
++# USB port drivers
++#
++
++#
++# USB Serial Converter support
++#
++
++#
++# USB Miscellaneous drivers
++#
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_DEBUG_SLAB is not set
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_DEBUG_SPINLOCK is not set
++CONFIG_DEBUG_LL=y
+Index: linux-2.6.0-test5/arch/arm/configs/shark_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/shark_defconfig 2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/shark_defconfig 2003-09-27 11:38:18.653692592 +0800
+@@ -0,0 +1,852 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++CONFIG_MMU=y
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++
++#
++# General setup
++#
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_LOG_BUF_SHIFT=14
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++CONFIG_MODULE_FORCE_UNLOAD=y
++CONFIG_OBSOLETE_MODPARM=y
++# CONFIG_MODVERSIONS is not set
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_ADIFCC is not set
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_IOP310 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++CONFIG_ARCH_SHARK=y
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++
++#
++# CLPS711X/EP721X Implementations
++#
++
++#
++# Epxa10db
++#
++
++#
++# Footbridge Implementations
++#
++
++#
++# IOP310 Implementation Options
++#
++
++#
++# IOP310 Chipset Features
++#
++
++#
++# Intel PXA250/210 Implementations
++#
++
++#
++# SA11x0 Implementations
++#
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_SA110=y
++CONFIG_CPU_32v4=y
++
++#
++# Processor Features
++#
++
++#
++# General setup
++#
++CONFIG_PCI=y
++CONFIG_PCI_HOST_VIA82C505=y
++CONFIG_ISA=y
++CONFIG_ISA_DMA=y
++# CONFIG_ZBOOT_ROM is not set
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_PCI_LEGACY_PROC=y
++# CONFIG_PCI_NAMES is not set
++# CONFIG_HOTPLUG is not set
++
++#
++# At least one math emulation must be selected
++#
++# CONFIG_FPE_NWFPE is not set
++CONFIG_FPE_FASTFPE=y
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_PREEMPT is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE=""
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++# CONFIG_LEDS_CPU is not set
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++CONFIG_PARPORT=y
++CONFIG_PARPORT_PC=y
++CONFIG_PARPORT_PC_CML1=y
++# CONFIG_PARPORT_SERIAL is not set
++# CONFIG_PARPORT_PC_FIFO is not set
++# CONFIG_PARPORT_PC_SUPERIO is not set
++# CONFIG_PARPORT_ARC is not set
++# CONFIG_PARPORT_OTHER is not set
++# CONFIG_PARPORT_1284 is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++# CONFIG_MTD is not set
++
++#
++# Plug and Play support
++#
++# CONFIG_PNP 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_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_UMEM is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++# CONFIG_BLK_DEV_INITRD is not set
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++
++#
++# Networking support
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++# CONFIG_NETLINK_DEV is not set
++# CONFIG_NETFILTER is not set
++CONFIG_UNIX=y
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++# CONFIG_IP_PNP 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_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_IPV6 is not set
++# CONFIG_XFRM_USER is not set
++
++#
++# SCTP Configuration (EXPERIMENTAL)
++#
++CONFIG_IPV6_SCTP__=y
++# CONFIG_IP_SCTP is not set
++# CONFIG_ATM is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_LLC is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB 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
++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_MII is not set
++# CONFIG_HAPPYMEAL 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
++
++#
++# Tulip family network device support
++#
++# CONFIG_NET_TULIP is not set
++# CONFIG_AT1700 is not set
++# CONFIG_DEPCA is not set
++# CONFIG_HP100 is not set
++# CONFIG_NET_ISA is not set
++CONFIG_NET_PCI=y
++# CONFIG_PCNET32 is not set
++# CONFIG_AMD8111_ETH is not set
++# CONFIG_ADAPTEC_STARFIRE is not set
++# CONFIG_AC3200 is not set
++# CONFIG_APRICOT is not set
++# CONFIG_B44 is not set
++CONFIG_CS89x0=y
++# CONFIG_DGRS is not set
++# CONFIG_EEPRO100 is not set
++# CONFIG_E100 is not set
++# CONFIG_FEALNX is not set
++# CONFIG_NATSEMI is not set
++# CONFIG_NE2K_PCI is not set
++# CONFIG_8139CP is not set
++# CONFIG_8139TOO is not set
++# CONFIG_SIS900 is not set
++# CONFIG_EPIC100 is not set
++# CONFIG_SUNDANCE is not set
++# CONFIG_TLAN is not set
++# CONFIG_VIA_RHINE 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_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 (depends on LLC=y)
++#
++# CONFIG_NET_FC is not set
++# CONFIG_RCPCI is not set
++# CONFIG_SHAPER is not set
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# ATA/ATAPI/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 is not set
++CONFIG_BLK_DEV_IDEDISK=y
++# CONFIG_IDEDISK_MULTI_MODE is not set
++# CONFIG_IDEDISK_STROKE is not set
++CONFIG_BLK_DEV_IDECD=y
++CONFIG_BLK_DEV_IDEFLOPPY=y
++# CONFIG_BLK_DEV_IDESCSI is not set
++# CONFIG_IDE_TASK_IOCTL is not set
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_BLK_DEV_IDEPCI is not set
++# CONFIG_IDE_CHIPSETS is not set
++
++#
++# SCSI support
++#
++CONFIG_SCSI=m
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=m
++CONFIG_CHR_DEV_ST=m
++# CONFIG_CHR_DEV_OSST is not set
++CONFIG_BLK_DEV_SR=m
++# CONFIG_BLK_DEV_SR_VENDOR is not set
++CONFIG_CHR_DEV_SG=m
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_REPORT_LUNS 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_AACRAID is not set
++# CONFIG_SCSI_AIC7XXX is not set
++# CONFIG_SCSI_AIC7XXX_OLD is not set
++# CONFIG_SCSI_AIC79XX 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_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_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_GENERIC_NCR5380_MMIO is not set
++# CONFIG_SCSI_INITIO is not set
++# CONFIG_SCSI_INIA100 is not set
++# CONFIG_SCSI_PPA is not set
++# CONFIG_SCSI_IMM 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_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
++
++#
++# IEEE 1394 (FireWire) support (EXPERIMENTAL)
++#
++# CONFIG_IEEE1394 is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN_BOOL is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_TSDEV is not set
++# CONFIG_INPUT_TSLIBDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input I/O drivers
++#
++# CONFIG_GAMEPORT is not set
++CONFIG_SOUND_GAMEPORT=y
++CONFIG_SERIO=y
++CONFIG_SERIO_I8042=y
++# CONFIG_SERIO_SERPORT is not set
++# CONFIG_SERIO_CT82C710 is not set
++# CONFIG_SERIO_PARKBD is not set
++# CONFIG_SERIO_PCIPS2 is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++CONFIG_INPUT_MOUSE=y
++CONFIG_MOUSE_PS2=y
++# CONFIG_MOUSE_SERIAL is not set
++# CONFIG_MOUSE_INPORT is not set
++# CONFIG_MOUSE_LOGIBM is not set
++# CONFIG_MOUSE_PC110PAD is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_DZ is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++CONFIG_PRINTER=m
++# CONFIG_LP_CONSOLE is not set
++# CONFIG_PPDEV is not set
++# CONFIG_TIPAR is not set
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# I2C Hardware Sensors Mainboard support
++#
++
++#
++# I2C Hardware Sensors Chip support
++#
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# IPMI
++#
++# CONFIG_IPMI_HANDLER is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_NVRAM is not set
++CONFIG_RTC=y
++# 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
++# CONFIG_DRM is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_HANGCHECK_TIMER is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++CONFIG_EXT3_FS=y
++CONFIG_EXT3_FS_XATTR=y
++# CONFIG_EXT3_FS_POSIX_ACL is not set
++CONFIG_JBD=y
++# CONFIG_JBD_DEBUG is not set
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++CONFIG_ISO9660_FS=y
++CONFIG_JOLIET=y
++# CONFIG_ZISOFS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_DEVFS_FS=y
++CONFIG_DEVFS_MOUNT=y
++# CONFIG_DEVFS_DEBUG is not set
++# CONFIG_DEVPTS_FS is not set
++# CONFIG_TMPFS is not set
++CONFIG_RAMFS=y
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++
++#
++# Network File Systems
++#
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++# CONFIG_NFS_V4 is not set
++# CONFIG_NFSD is not set
++CONFIG_LOCKD=y
++# CONFIG_EXPORTFS is not set
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_GSS is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_NEC98_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++CONFIG_NLS=y
++
++#
++# Native Language Support
++#
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++CONFIG_NLS_CODEPAGE_850=y
++# 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=y
++# 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
++
++#
++# Graphics support
++#
++CONFIG_FB=y
++# CONFIG_FB_CIRRUS is not set
++# CONFIG_FB_PM2 is not set
++CONFIG_FB_CYBER2000=y
++# CONFIG_FB_IMSTT is not set
++# CONFIG_FB_RIVA is not set
++# CONFIG_FB_MATROX is not set
++# CONFIG_FB_RADEON is not set
++# CONFIG_FB_ATY128 is not set
++# CONFIG_FB_ATY 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_PM3 is not set
++# CONFIG_FB_VIRTUAL is not set
++
++#
++# Logo configuration
++#
++# CONFIG_LOGO is not set
++
++#
++# Sound
++#
++CONFIG_SOUND=m
++
++#
++# Advanced Linux Sound Architecture
++#
++# CONFIG_SND is not set
++
++#
++# Open Sound System
++#
++CONFIG_SOUND_PRIME=m
++# CONFIG_SOUND_BT878 is not set
++# CONFIG_SOUND_CMPCI is not set
++# CONFIG_SOUND_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_ICH is not set
++# CONFIG_SOUND_RME96XX is not set
++# CONFIG_SOUND_SONICVIBES 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_SOUND_OSS=m
++# CONFIG_SOUND_TRACEINIT is not set
++# CONFIG_SOUND_DMAP is not set
++# CONFIG_SOUND_AD1816 is not set
++# CONFIG_SOUND_SGALAXY is not set
++CONFIG_SOUND_ADLIB=m
++# CONFIG_SOUND_ACI_MIXER is not set
++# CONFIG_SOUND_CS4232 is not set
++# CONFIG_SOUND_SSCAPE is not set
++# CONFIG_SOUND_GUS is not set
++# CONFIG_SOUND_VMIDI is not set
++# CONFIG_SOUND_TRIX is not set
++# CONFIG_SOUND_MSS is not set
++# CONFIG_SOUND_MPU401 is not set
++# CONFIG_SOUND_NM256 is not set
++# CONFIG_SOUND_MAD16 is not set
++# CONFIG_SOUND_PAS is not set
++# CONFIG_SOUND_PSS is not set
++CONFIG_SOUND_SB=m
++# CONFIG_SOUND_AWE32_SYNTH is not set
++# CONFIG_SOUND_WAVEFRONT is not set
++# CONFIG_SOUND_MAUI is not set
++# CONFIG_SOUND_YM3812 is not set
++# CONFIG_SOUND_OPL3SA1 is not set
++# CONFIG_SOUND_OPL3SA2 is not set
++# CONFIG_SOUND_YMFPCI is not set
++# CONFIG_SOUND_UART6850 is not set
++# CONFIG_SOUND_AEDSP16 is not set
++
++#
++# Misc devices
++#
++
++#
++# Multimedia Capabilities Port drivers
++#
++# CONFIG_MCP is not set
++
++#
++# Console Switches
++#
++# CONFIG_SWITCHES is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_DEBUG_KERNEL is not set
++
++#
++# Security options
++#
++# CONFIG_SECURITY is not set
++
++#
++# Cryptographic options
++#
++# CONFIG_CRYPTO is not set
++
++#
++# Library routines
++#
++CONFIG_CRC32=y
+Index: linux-2.6.0-test5/arch/arm/configs/sherman_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/sherman_defconfig 2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/sherman_defconfig 2003-09-27 11:38:18.654692440 +0800
+@@ -0,0 +1,215 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++
++#
++# System and processor type
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_FOOTBRIDGE is not set
++CONFIG_ARCH_SA1100=y
++CONFIG_CPU_SA1100=y
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_EMPEG is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_VICTOR is not set
++CONFIG_SA1100_SHERMAN=y
++# CONFIG_VICTOR_BOARD1 is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_ISA_DMA is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++# CONFIG_CPU_ARM2 is not set
++# CONFIG_CPU_ARM3 is not set
++# CONFIG_CPU_ARM6 is not set
++# CONFIG_CPU_ARM7 is not set
++CONFIG_CPU_SA110=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_ALIGNMENT_TRAP=y
++# CONFIG_TEXT_SECTIONS is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# General setup
++#
++CONFIG_ZBOOT_ROM=y
++CONFIG_ZBOOT_ROM_TEXT=0x00050000
++CONFIG_ZBOOT_ROM_BSS=0xc0200000
++# CONFIG_NET is not set
++# CONFIG_SYSVIPC is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_SYSCTL is not set
++CONFIG_NWFPE=y
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_ARTHUR is not set
++# CONFIG_PARPORT is not set
++CONFIG_CMDLINE="mem=64M@0xc0000000 mem=64M@0xc8000000 root=/dev/mtdblock2"
++
++#
++# Plug and Play support
++#
++# CONFIG_PNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# CONFIG_BLK_DEV_IDE is not set
++
++#
++# Please see Documentation/ide.txt for help/info on IDE drives
++#
++# CONFIG_BLK_DEV_HD_IDE is not set
++# CONFIG_BLK_DEV_IDEDISK 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_BLK_DEV_CMD640 is not set
++# CONFIG_IDE_CHIPSETS is not set
++
++#
++# Additional Block Devices
++#
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_MD is not set
++CONFIG_BLK_DEV_RAM=y
++# CONFIG_BLK_DEV_INITRD is not set
++# CONFIG_BLK_DEV_XD is not set
++# CONFIG_PARIDE_PARPORT is not set
++# CONFIG_PARIDE is not set
++# CONFIG_BLK_DEV_HD is not set
++CONFIG_BLK_DEV_FLASH=y
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_UNIX98_PTYS is not set
++# CONFIG_MOUSE is not set
++# CONFIG_QIC02_TAPE is not set
++# CONFIG_WATCHDOG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++
++#
++# Video For Linux
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# Joystick support
++#
++# CONFIG_JOYSTICK is not set
++# CONFIG_DTLK is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# Filesystems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS 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_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG is not set
++# CONFIG_NTFS_RW is not set
++# CONFIG_HPFS_FS is not set
++CONFIG_PROC_FS=y
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++# CONFIG_MSDOS_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ACORN_PARTITION is not set
++CONFIG_NLS=y
++
++#
++# Native Language Support
++#
++# CONFIG_NLS_CODEPAGE_437 is not set
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_1 is not set
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_INFO=y
++# CONFIG_MAGIC_SYSRQ is not set
++CONFIG_DEBUG_LL=y
+Index: linux-2.6.0-test5/arch/arm/configs/stork_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/stork_defconfig 2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/stork_defconfig 2003-09-27 11:38:18.656692136 +0800
+@@ -0,0 +1,966 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++# CONFIG_GENERIC_BUST_SPINLOCK is not set
++# CONFIG_GENERIC_ISA_DMA is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_ADIFCC is not set
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_IOP310 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_H3100 is not set
++CONFIG_SA1100_H3600=y
++# CONFIG_SA1100_H3800 is not set
++CONFIG_SA1100_H3XXX=y
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_BADGE4 is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_PT_SYSTEM3 is not set
++# CONFIG_SA1100_SHANNON is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++CONFIG_SA1100_USB=m
++CONFIG_SA1100_USB_NETLINK=m
++# CONFIG_SA1100_USB_CHAR is not set
++CONFIG_H3600_SLEEVE=m
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_AUTCPU12 is not set
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_FORTUNET is not set
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM922T is not set
++# CONFIG_CPU_ARM926T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++# CONFIG_XSCALE_PMU is not set
++# CONFIG_ARM_THUMB is not set
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++CONFIG_ISA=y
++# CONFIG_ISA_DMA is not set
++# CONFIG_FIQ is not set
++CONFIG_CPU_FREQ=y
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=m
++CONFIG_PCMCIA_PROBE=y
++# CONFIG_I82092 is not set
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=m
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=m
++CONFIG_FPE_FASTFPE=y
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++CONFIG_PM=y
++# CONFIG_APM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="N"
++# CONFIG_LEDS is not set
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=y
++CONFIG_MTD_REDBOOT_PARTS=y
++CONFIG_MTD_BOOTLDR_PARTS=y
++# CONFIG_MTD_AFS_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=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_GEOMETRY is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD 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_NORA is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_CDB89712 is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++# CONFIG_MTD_EPXA10DB is not set
++# CONFIG_MTD_PCI 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
++
++#
++# 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_BLK_DEV_DAC960 is not set
++CONFIG_BLK_DEV_LOOP=m
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_RAM is not set
++# CONFIG_BLK_DEV_INITRD 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=y
++CONFIG_RTNETLINK=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 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
++# CONFIG_ATM is not set
++# CONFIG_VLAN_8021Q is not set
++
++#
++#
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK 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 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 is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K 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_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PLIP is not set
++CONFIG_PPP=m
++# CONFIG_PPP_MULTILINK is not set
++# CONFIG_PPP_FILTER is not set
++CONFIG_PPP_ASYNC=m
++# CONFIG_PPP_SYNC_TTY is not set
++CONFIG_PPP_DEFLATE=m
++CONFIG_PPP_BSDCOMP=m
++# CONFIG_PPPOE is not set
++# CONFIG_SLIP is not set
++
++#
++# Wireless LAN (non-hamradio)
++#
++CONFIG_NET_RADIO=y
++# CONFIG_STRIP is not set
++CONFIG_WAVELAN=m
++# 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=m
++
++#
++# Wireless Pcmcia cards support
++#
++CONFIG_PCMCIA_HERMES=m
++# CONFIG_AIRO_CS is not set
++CONFIG_NET_WIRELESS=y
++
++#
++# 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=y
++CONFIG_PCMCIA_3C589=m
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=m
++# CONFIG_PCMCIA_NMCLAN is not set
++# CONFIG_PCMCIA_SMC91C92 is not set
++CONFIG_PCMCIA_XIRC2PS=m
++# CONFIG_PCMCIA_AXNET is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++CONFIG_IDE=m
++
++#
++# IDE, ATA and ATAPI Block devices
++#
++CONFIG_BLK_DEV_IDE=m
++
++#
++# 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_IDEDISK=m
++# CONFIG_IDEDISK_MULTI_MODE is not set
++CONFIG_BLK_DEV_IDECS=m
++CONFIG_BLK_DEV_IDECD=m
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI 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_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++# CONFIG_BLK_DEV_ATARAID is not set
++# CONFIG_BLK_DEV_ATARAID_PDC is not set
++# CONFIG_BLK_DEV_ATARAID_HPT is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O 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
++
++#
++# 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
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++CONFIG_SERIAL=y
++CONFIG_SERIAL_CONSOLE=y
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_ANAKIN is not set
++# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_UART00 is not set
++# CONFIG_SERIAL_UART00_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=115200
++CONFIG_SERIAL_8250=m
++# CONFIG_SERIAL_8250_CONSOLE is not set
++# CONFIG_ATOMWIDE_SERIAL is not set
++# CONFIG_DUALSP_SERIAL is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_MULTIPORT is not set
++# CONFIG_SERIAL_8250_RSA is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# L3 serial bus support
++#
++CONFIG_L3=y
++CONFIG_L3_ALGOBIT=y
++CONFIG_L3_BIT_SA1100_GPIO=y
++
++#
++# Other L3 adapters
++#
++# CONFIG_L3_SA1111 is not set
++CONFIG_BIT_SA1100_GPIO=y
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++CONFIG_MOUSE=m
++# CONFIG_PSMOUSE is not set
++# CONFIG_82C710_MOUSE is not set
++# CONFIG_PC110_PAD 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
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++CONFIG_SA1100_RTC=m
++# 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
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++# CONFIG_PCMCIA_SERIAL_CS is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA 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_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=m
++CONFIG_MSDOS_FS=m
++# CONFIG_UMSDOS_FS is not set
++CONFIG_VFAT_FS=m
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_CRAMFS=y
++# CONFIG_TMPFS is not set
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_ZISOFS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG is not set
++# CONFIG_NTFS_RW is not set
++# CONFIG_HPFS_FS is not set
++CONFIG_PROC_FS=y
++CONFIG_DEVFS_FS=y
++CONFIG_DEVFS_MOUNT=y
++# 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
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++# CONFIG_ROOT_NFS is not set
++CONFIG_NFSD=m
++CONFIG_NFSD_V3=y
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_SMB_FS=m
++# CONFIG_SMB_NLS_DEFAULT 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_ZLIB_FS_INFLATE=y
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++CONFIG_SMB_NLS=y
++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_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
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_ANAKIN is not set
++# CONFIG_FB_CLPS711X is not set
++CONFIG_FB_SA1100=y
++# CONFIG_FB_CYBER2000 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 is not set
++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
++#
++CONFIG_SOUND=y
++# 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_ICH is not set
++# CONFIG_SOUND_RME96XX is not set
++# CONFIG_SOUND_SONICVIBES 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_SA1100=y
++CONFIG_SOUND_UDA1341=m
++# CONFIG_SOUND_ASSABET_UDA1341 is not set
++CONFIG_SOUND_H3600_UDA1341=m
++# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
++# CONFIG_SOUND_SA1111_UDA1341 is not set
++# CONFIG_SOUND_SA1100SSP is not set
++# CONFIG_SOUND_OSS is not set
++# CONFIG_SOUND_WAVEARTIST is not set
++# CONFIG_SOUND_TVMIXER is not set
++
++#
++# Multimedia Capabilities Port drivers
++#
++# CONFIG_MCP is not set
++# CONFIG_MCP_SA1100 is not set
++# CONFIG_MCP_UCB1200 is not set
++# CONFIG_MCP_UCB1200_AUDIO is not set
++# CONFIG_MCP_UCB1200_TS is not set
++
++#
++# USB support
++#
++# CONFIG_USB 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 is not set
++# CONFIG_USB_OHCI_SA1111 is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH 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_JUMPSHOT is not set
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# USB Human Interface Devices (HID)
++#
++
++#
++# Input core support is needed for USB HID
++#
++
++#
++# 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_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
++# CONFIG_USB_SERIAL_GENERIC is not set
++# CONFIG_USB_SERIAL_BELKIN is not set
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
++# CONFIG_USB_SERIAL_EMPEG is not set
++# CONFIG_USB_SERIAL_FTDI_SIO is not set
++# CONFIG_USB_SERIAL_VISOR is not set
++# CONFIG_USB_SERIAL_IPAQ is not set
++# CONFIG_USB_SERIAL_IR is not set
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
++# CONFIG_USB_SERIAL_MCT_U232 is not set
++# CONFIG_USB_SERIAL_KLSI is not set
++# CONFIG_USB_SERIAL_PL2303 is not set
++# CONFIG_USB_SERIAL_CYBERJACK is not set
++# CONFIG_USB_SERIAL_XIRCOM is not set
++# CONFIG_USB_SERIAL_OMNINET is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_AUERSWALD is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++# CONFIG_DEBUG_USER is not set
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_NO_PGT_CACHE is not set
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_DEBUG_SLAB is not set
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_WAITQ is not set
++# CONFIG_DEBUG_BUGVERBOSE is not set
++# CONFIG_DEBUG_ERRORS is not set
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
++
++#
++# Library routines
++#
++# CONFIG_CRC32 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/system3_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/system3_defconfig 2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/system3_defconfig 2003-09-27 11:38:18.658691832 +0800
+@@ -0,0 +1,967 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++# CONFIG_GENERIC_BUST_SPINLOCK is not set
++# CONFIG_GENERIC_ISA_DMA is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_SHANNON is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++CONFIG_SA1100_PT_SYSTEM3=y
++CONFIG_SA1111=y
++CONFIG_FORCE_MAX_ZONEORDER=9
++CONFIG_SA1100_USB=m
++CONFIG_SA1100_USB_NETLINK=m
++CONFIG_SA1100_USB_CHAR=m
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_AUTCPU12 is not set
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM922T is not set
++# CONFIG_CPU_ARM926T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++# CONFIG_ARM_THUMB is not set
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++CONFIG_ISA=y
++# CONFIG_ISA_DMA is not set
++CONFIG_CPU_FREQ=y
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=m
++# CONFIG_I82092 is not set
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=m
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++CONFIG_PM=y
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="noinitrd root=/dev/mtdblock3"
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=y
++CONFIG_MTD_REDBOOT_PARTS=m
++CONFIG_MTD_BOOTLDR_PARTS=m
++# CONFIG_MTD_AFS_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++# CONFIG_MTD_CHAR is not set
++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 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_NORA is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_CDB89712 is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++# CONFIG_MTD_PCI 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
++
++#
++# 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_BLK_DEV_DAC960 is not set
++CONFIG_BLK_DEV_LOOP=m
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# 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 is not set
++# CONFIG_NETLINK 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 is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE 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
++# CONFIG_ATM is not set
++# CONFIG_VLAN_8021Q is not set
++
++#
++#
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++CONFIG_DUMMY=m
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# CONFIG_ARM_AM79C961A is not set
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNBMAC is not set
++# CONFIG_SUNQE is not set
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNGEM is not set
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_LANCE is not set
++CONFIG_NET_VENDOR_SMC=y
++# CONFIG_WD80x3 is not set
++# CONFIG_ULTRAMCA is not set
++# CONFIG_ULTRA is not set
++# CONFIG_ULTRA32 is not set
++CONFIG_SMC9194=m
++# CONFIG_NET_VENDOR_RACAL is not set
++# CONFIG_AT1700 is not set
++# CONFIG_DEPCA 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_MYRI_SBUS is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN 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
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=m
++# CONFIG_PCMCIA_NMCLAN is not set
++CONFIG_PCMCIA_SMC91C92=m
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_PCMCIA_AXNET is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++CONFIG_IRDA=m
++
++#
++# IrDA protocols
++#
++CONFIG_IRLAN=m
++# CONFIG_IRNET is not set
++CONFIG_IRCOMM=m
++# CONFIG_IRDA_ULTRA is not set
++# CONFIG_IRDA_OPTIONS is not set
++
++#
++# Infrared-port device drivers
++#
++
++#
++# SIR device drivers
++#
++CONFIG_IRTTY_SIR=m
++CONFIG_IRPORT_SIR=m
++
++#
++# 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_FIR is not set
++# CONFIG_SMC_IRCC_FIR is not set
++# CONFIG_ALI_FIR is not set
++# CONFIG_VLSI_FIR is not set
++CONFIG_SA1100_FIR=m
++
++#
++# 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_IDEDISK=y
++# CONFIG_IDEDISK_MULTI_MODE is not set
++CONFIG_BLK_DEV_IDECS=m
++# 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
++
++#
++# 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_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++# CONFIG_BLK_DEV_ATARAID is not set
++# CONFIG_BLK_DEV_ATARAID_PDC is not set
++# CONFIG_BLK_DEV_ATARAID_HPT is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O 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
++
++#
++# 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 is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_ANAKIN is not set
++# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_UART00 is not set
++# CONFIG_SERIAL_UART00_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=38400
++CONFIG_SERIAL_8250=m
++# CONFIG_SERIAL_8250_CONSOLE is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_MULTIPORT is not set
++# CONFIG_SERIAL_8250_HUB6 is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++# CONFIG_L3_ALGOBIT is not set
++# CONFIG_L3_BIT_SA1100_GPIO is not set
++
++#
++# Other L3 adapters
++#
++# CONFIG_L3_SA1111 is not set
++# CONFIG_BIT_SA1100_GPIO 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
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_SA1100_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
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++CONFIG_PCMCIA_SERIAL_CS=m
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA 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_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 is not set
++# 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 is not set
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_ZISOFS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=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_ZLIB_FS_INFLATE is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_SMB_NLS is not set
++CONFIG_NLS=y
++
++#
++# Native Language Support
++#
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=y
++# 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_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
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_ANAKIN is not set
++# CONFIG_FB_CLPS711X is not set
++CONFIG_FB_SA1100=y
++# CONFIG_FB_CYBER2000 is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FBCON_ADVANCED is not set
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++CONFIG_FBCON_FONTWIDTH8_ONLY=y
++CONFIG_FBCON_FONTS=y
++CONFIG_FONT_8x8=y
++# CONFIG_FONT_8x16 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# Multimedia Capabilities Port drivers
++#
++# CONFIG_MCP is not set
++# CONFIG_MCP_SA1100 is not set
++# CONFIG_MCP_UCB1200 is not set
++# CONFIG_MCP_UCB1200_AUDIO is not set
++# CONFIG_MCP_UCB1200_TS is not set
++
++#
++# USB support
++#
++CONFIG_USB=m
++# CONFIG_USB_DEBUG is not set
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++# CONFIG_USB_BANDWIDTH is not set
++# CONFIG_USB_LONG_TIMEOUT is not set
++
++#
++# USB Controllers
++#
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++# CONFIG_USB_OHCI is not set
++CONFIG_USB_OHCI_SA1111=m
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++# 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_JUMPSHOT is not set
++# CONFIG_USB_ACM is not set
++CONFIG_USB_PRINTER=m
++
++#
++# USB Human Interface Devices (HID)
++#
++CONFIG_USB_HID=m
++CONFIG_USB_HIDDEV=y
++CONFIG_USB_KBD=m
++CONFIG_USB_MOUSE=m
++# CONFIG_USB_WACOM 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_KAWETH is not set
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_CDCETHER is not set
++CONFIG_USB_USBNET=m
++
++#
++# USB port drivers
++#
++# CONFIG_USB_USS720 is not set
++
++#
++# USB Serial Converter support
++#
++# CONFIG_USB_SERIAL is not set
++# CONFIG_USB_SERIAL_GENERIC is not set
++# CONFIG_USB_SERIAL_BELKIN is not set
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
++# CONFIG_USB_SERIAL_EMPEG is not set
++# CONFIG_USB_SERIAL_FTDI_SIO is not set
++# CONFIG_USB_SERIAL_VISOR is not set
++# CONFIG_USB_SERIAL_IR is not set
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
++# CONFIG_USB_SERIAL_MCT_U232 is not set
++# CONFIG_USB_SERIAL_PL2303 is not set
++# CONFIG_USB_SERIAL_CYBERJACK is not set
++# CONFIG_USB_SERIAL_XIRCOM is not set
++# CONFIG_USB_SERIAL_OMNINET is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_RIO500 is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_INFO=y
++# CONFIG_NO_PGT_CACHE is not set
++CONFIG_DEBUG_KERNEL=y
++CONFIG_DEBUG_SLAB=y
++CONFIG_MAGIC_SYSRQ=y
++CONFIG_DEBUG_SPINLOCK=y
++CONFIG_DEBUG_WAITQ=y
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/trizeps_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/trizeps_defconfig 2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/trizeps_defconfig 2003-09-27 11:38:18.660691528 +0800
+@@ -0,0 +1,851 @@
++#
++# Automatically generated by make menuconfig: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++# CONFIG_GENERIC_BUST_SPINLOCK is not set
++# CONFIG_GENERIC_ISA_DMA is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++
++#
++# General setup
++#
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_ADIFCC is not set
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_IOP310 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_AUTCPU12 is not set
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CEIVA is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_FORTUNET is not set
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++
++#
++# Epxa10db
++#
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# IOP310 Implementation Options
++#
++# CONFIG_ARCH_IQ80310 is not set
++# CONFIG_IOP310_AAU is not set
++# CONFIG_IOP310_DMA is not set
++# CONFIG_IOP310_MU is not set
++# CONFIG_IOP310_PMON is not set
++
++#
++# Intel PXA250/210 Implementations
++#
++# CONFIG_ARCH_LUBBOCK is not set
++# CONFIG_ARCH_PXA_IDP is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_H3100 is not set
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_H3800 is not set
++# CONFIG_SA1100_H3XXX is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_BADGE4 is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_PT_SYSTEM3 is not set
++# CONFIG_SA1100_SHANNON is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++CONFIG_SA1100_TRIZEPS=y
++CONFIG_TRIZEPS_MFTB2=y
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++# CONFIG_SA1100_STORK is not set
++# CONFIG_SA1100_USB is not set
++# CONFIG_SA1100_USB_NETLINK is not set
++# CONFIG_SA1100_USB_CHAR is not set
++# CONFIG_H3600_SLEEVE is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++# CONFIG_SA1111 is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM922T is not set
++# CONFIG_CPU_ARM926T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++# CONFIG_CPU_XSCALE is not set
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_32v5 is not set
++# CONFIG_ARM_THUMB is not set
++
++#
++# General setup
++#
++CONFIG_DISCONTIGMEM=y
++# CONFIG_PCI is not set
++CONFIG_ISA=y
++# CONFIG_ISA_DMA is not set
++# CONFIG_FIQ is not set
++# CONFIG_ZBOOT_ROM is not set
++CONFIG_ZBOOT_ROM_TEXT=0
++CONFIG_ZBOOT_ROM_BSS=0
++# CONFIG_CPU_FREQ is not set
++# CONFIG_CPU_FREQ_24_API is not set
++# CONFIG_CPU_FREQ_26_API is not set
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=m
++# CONFIG_I82092 is not set
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=m
++# CONFIG_PCMCIA_SA1111 is not set
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_PREEMPT is not set
++# CONFIG_APM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="keepinitrd mem=16M root=/dev/hda2 1"
++# CONFIG_LEDS is not set
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=m
++CONFIG_MTD_CONCAT=m
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_CMDLINE_PARTS is not set
++CONFIG_MTD_AFS_PARTS=m
++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 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_NORA is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_CDB89712 is not set
++CONFIG_MTD_SA1100=m
++# CONFIG_MTD_2PARTS_IPAQ is not set
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++# CONFIG_MTD_EPXA10DB is not set
++# CONFIG_MTD_FORTUNET is not set
++# CONFIG_MTD_AUTCPU12 is not set
++# CONFIG_MTD_EDB7312 is not set
++# CONFIG_MTD_IMPA7 is not set
++# CONFIG_MTD_CEIVA 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
++# 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
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_PNP_NAMES is not set
++# CONFIG_PNP_DEBUG is not set
++# CONFIG_ISAPNP is not set
++# CONFIG_PNPBIOS 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_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_UMEM is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++# CONFIG_BLK_DEV_INITRD 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 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 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
++
++#
++# SCTP Configuration (EXPERIMENTAL)
++#
++CONFIG_IPV6_SCTP__=y
++# CONFIG_IP_SCTP is not set
++# CONFIG_ATM is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_LLC is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# 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_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 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 is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K is not set
++# CONFIG_E1000 is not set
++# CONFIG_E1000_NAPI 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_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 is not set
++# CONFIG_PPP_FILTER is not set
++CONFIG_PPP_ASYNC=m
++# CONFIG_PPP_SYNC_TTY is not set
++CONFIG_PPP_DEFLATE=m
++CONFIG_PPP_BSDCOMP=m
++# CONFIG_PPPOE is not set
++# CONFIG_SLIP is not set
++
++#
++# Wireless LAN (non-hamradio)
++#
++CONFIG_NET_RADIO=y
++# CONFIG_STRIP 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_WAVELAN is not set
++# CONFIG_AIRO is not set
++# CONFIG_HERMES is not set
++# CONFIG_PCMCIA_NETWAVE is not set
++# CONFIG_PCMCIA_WAVELAN is not set
++# CONFIG_PCMCIA_HERMES is not set
++CONFIG_AIRO_CS=m
++CONFIG_NET_WIRELESS=y
++
++#
++# 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=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++# CONFIG_PCMCIA_PCNET is not set
++# CONFIG_PCMCIA_NMCLAN is not set
++# CONFIG_PCMCIA_SMC91C92 is not set
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_PCMCIA_AXNET is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++CONFIG_NET_PCMCIA_RADIO=y
++# CONFIG_PCMCIA_RAYCS is not set
++# CONFIG_AIRONET4500_CS is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# ATA/ATAPI/MFM/RLL support
++#
++CONFIG_IDE=y
++
++#
++# IDE, ATA and ATAPI Block devices
++#
++CONFIG_BLK_DEV_IDE=y
++# CONFIG_BLK_DEV_HD_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++CONFIG_BLK_DEV_IDEDISK=y
++# CONFIG_IDEDISK_MULTI_MODE is not set
++# CONFIG_IDEDISK_STROKE is not set
++CONFIG_BLK_DEV_IDECS=m
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++# CONFIG_IDE_TASK_IOCTL is not set
++# 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_IDE_ICSIDE is not set
++# CONFIG_BLK_DEV_IDEDMA_ICS is not set
++# CONFIG_IDEDMA_ICS_AUTO is not set
++# CONFIG_BLK_DEV_IDEDMA is not set
++# CONFIG_BLK_DEV_IDE_RAPIDE is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++# CONFIG_DMA_NONPCI is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O 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
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN_BOOL is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_MOUSEDEV is not set
++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_TSDEV is not set
++# CONFIG_INPUT_TSLIBDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++# CONFIG_INPUT_EVBUG is not set
++# CONFIG_GAMEPORT is not set
++CONFIG_SOUND_GAMEPORT=y
++# CONFIG_GAMEPORT_NS558 is not set
++# CONFIG_GAMEPORT_L4 is not set
++# CONFIG_GAMEPORT_EMU10K1 is not set
++# CONFIG_GAMEPORT_VORTEX is not set
++# CONFIG_GAMEPORT_FM801 is not set
++# CONFIG_GAMEPORT_CS461x is not set
++# CONFIG_SERIO is not set
++# CONFIG_SERIO_I8042 is not set
++# CONFIG_SERIO_SERPORT is not set
++# CONFIG_SERIO_CT82C710 is not set
++# CONFIG_SERIO_PARKBD is not set
++# CONFIG_SERIO_RPCKBD is not set
++# CONFIG_SERIO_AMBAKMI is not set
++# CONFIG_SERIO_SA1111 is not set
++# CONFIG_INPUT_KEYBOARD is not set
++# CONFIG_KEYBOARD_ATKBD is not set
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_INPUT_MOUSE is not set
++# CONFIG_MOUSE_PS2 is not set
++# CONFIG_MOUSE_SERIAL is not set
++# CONFIG_MOUSE_INPORT is not set
++# CONFIG_MOUSE_LOGIBM is not set
++# CONFIG_MOUSE_PC110PAD is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_JOYSTICK_ANALOG is not set
++# CONFIG_JOYSTICK_A3D is not set
++# CONFIG_JOYSTICK_ADI is not set
++# CONFIG_JOYSTICK_COBRA is not set
++# CONFIG_JOYSTICK_GF2K is not set
++# CONFIG_JOYSTICK_GRIP is not set
++# CONFIG_JOYSTICK_GRIP_MP is not set
++# CONFIG_JOYSTICK_GUILLEMOT is not set
++# CONFIG_JOYSTICK_INTERACT is not set
++# CONFIG_JOYSTICK_SIDEWINDER is not set
++# CONFIG_JOYSTICK_TMDC is not set
++# CONFIG_JOYSTICK_IFORCE is not set
++# CONFIG_JOYSTICK_WARRIOR is not set
++# CONFIG_JOYSTICK_MAGELLAN is not set
++# CONFIG_JOYSTICK_SPACEORB is not set
++# CONFIG_JOYSTICK_SPACEBALL is not set
++# CONFIG_JOYSTICK_STINGER is not set
++# CONFIG_JOYSTICK_TWIDDLER is not set
++# CONFIG_JOYSTICK_DB9 is not set
++# CONFIG_JOYSTICK_GAMECON is not set
++# CONFIG_JOYSTICK_TURBOGRAFX is not set
++# CONFIG_INPUT_JOYDUMP is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_TOUCHSCREEN_GUNZE is not set
++# CONFIG_INPUT_MISC is not set
++# CONFIG_INPUT_PCSPKR is not set
++# CONFIG_INPUT_UINPUT is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++# CONFIG_SERIAL_8250_CONSOLE is not set
++# CONFIG_SERIAL_8250_CS is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_MULTIPORT is not set
++# CONFIG_SERIAL_8250_RSA is not set
++# CONFIG_SERIAL_ACORN is not set
++# CONFIG_SERIAL_ANAKIN is not set
++# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X_OLD_NAME is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_UART00 is not set
++# CONFIG_SERIAL_UART00_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++# CONFIG_UNIX98_PTYS is not set
++
++#
++# I2C support
++#
++CONFIG_I2C=m
++CONFIG_I2C_ALGOBIT=m
++# 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_BIT_SA1100_GPIO is not set
++# CONFIG_I2C_ALGOPCF is not set
++CONFIG_I2C_CHARDEV=m
++CONFIG_I2C_PROC=m
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++# CONFIG_L3_ALGOBIT is not set
++# CONFIG_L3_BIT_SA1100_GPIO is not set
++# CONFIG_BIT_SA1100_GPIO is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_GEN_RTC is not set
++# CONFIG_SA1100_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
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++# CONFIG_SYNCLINK_CS is not set
++# CONFIG_SCx200_GPIO is not set
++# CONFIG_RAW_DRIVER is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_QFMT_V1 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_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 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 is not set
++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_DEBUG 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 is not set
++# 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_RT is not set
++# CONFIG_XFS_QUOTA 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 is not set
++# CONFIG_NFS_V4 is not set
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++# CONFIG_NFSD_V4 is not set
++# CONFIG_NFSD_TCP is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=y
++# CONFIG_EXPORTFS is not set
++# CONFIG_CIFS is not set
++# 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_AFS_FS is not set
++# CONFIG_ZISOFS_FS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# 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
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# Multimedia Capabilities Port drivers
++#
++# CONFIG_MCP is not set
++# CONFIG_MCP_SA1100 is not set
++# CONFIG_MCP_UCB1200 is not set
++# CONFIG_MCP_UCB1200_AUDIO is not set
++# CONFIG_MCP_UCB1200_TS is not set
++
++#
++# Console Switches
++#
++# CONFIG_SWITCHES is not set
++# CONFIG_SWITCHES_SA1100 is not set
++# CONFIG_SWITCHES_UCB1X00 is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_NO_FRAME_POINTER is not set
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SLAB is not set
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_WAITQ is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_ERRORS=y
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
++
++#
++# Security options
++#
++CONFIG_SECURITY_CAPABILITIES=y
++
++#
++# Library routines
++#
++# CONFIG_CRC32 is not set
++CONFIG_ZLIB_INFLATE=m
++CONFIG_ZLIB_DEFLATE=m
+Index: linux-2.6.0-test5/arch/arm/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/Kconfig 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/Kconfig 2003-09-27 11:38:18.668690312 +0800
+@@ -213,198 +213,7 @@
+ depends on SA1111
+ default "9"
+
+-comment "Processor Type"
+-
+-# Figure out whether this system uses 26-bit or 32-bit CPUs.
+-config CPU_32
+- bool
+- default y
+-
+-# Select CPU types depending on the architecture selected. This selects
+-# which CPUs we support in the kernel image, and the compiler instruction
+-# optimiser behaviour.
+-# ARM610
+-config CPU_ARM610
+- bool "Support ARM610 processor"
+- depends on ARCH_RPC
+- help
+- The ARM610 is the successor to the ARM3 processor
+- and was produced by VLSI Technology Inc.
+-
+- Say Y if you want support for the ARM610 processor.
+- Otherwise, say N.
+-
+-# ARM710
+-config CPU_ARM710
+- bool "Support ARM710 processor" if !ARCH_CLPS7500 && ARCH_RPC
+- default y if ARCH_CLPS7500
+- help
+- A 32-bit RISC microprocessor based on the ARM7 processor core
+- designed by Advanced RISC Machines Ltd. The ARM710 is the
+- successor to the ARM610 processor. It was released in
+- July 1994 by VLSI Technology Inc.
+-
+- Say Y if you want support for the ARM710 processor.
+- Otherwise, say N.
+-
+-# ARM720T
+-config CPU_ARM720T
+- bool "Support ARM720T processor" if !ARCH_CLPS711X && !ARCH_L7200 && !ARCH_CDB89712 && ARCH_INTEGRATOR
+- default y if ARCH_CLPS711X || ARCH_L7200 || ARCH_CDB89712
+- help
+- A 32-bit RISC processor with 8kByte Cache, Write Buffer and
+- MMU built around an ARM7TDMI core.
+-
+- Say Y if you want support for the ARM720T processor.
+- Otherwise, say N.
+-
+-# ARM920T
+-config CPU_ARM920T
+- bool "Support ARM920T processor"
+- depends on ARCH_INTEGRATOR
+- help
+- The ARM920T is licensed to be produced by numerous vendors,
+- and is used in the Maverick EP9312. More information at
+- <http://linuxdevices.com/products/PD2382866068.html>.
+-
+- Say Y if you want support for the ARM920T processor.
+- Otherwise, say N.
+-
+-# ARM922T
+-config CPU_ARM922T
+- bool
+- depends on ARCH_CAMELOT
+- default y
+- help
+- The ARM922T is a version of the ARM920T, but with smaller
+- instruction and data caches. It is used in Altera's
+- Excalibur XA device family.
+-
+- Say Y if you want support for the ARM922T processor.
+- Otherwise, say N.
+-
+-# ARM926T
+-config CPU_ARM926T
+- bool "Support ARM926T processor"
+- depends on ARCH_INTEGRATOR
+- help
+- This is a variant of the ARM920. It has slightly different
+- instruction sequences for cache and TLB operations. Curiously,
+- there is no documentation on it at the ARM corporate website.
+-
+- Say Y if you want support for the ARM926T processor.
+- Otherwise, say N.
+-
+-# ARM1020
+-config CPU_ARM1020
+- bool "Support ARM1020 processor"
+- depends on ARCH_INTEGRATOR
+- help
+- The ARM1020 is the cached version of the ARM10 processor,
+- with an addition of a floating-point unit.
+-
+- Say Y if you want support for the ARM1020 processor.
+- Otherwise, say N.
+-
+-# SA110
+-config CPU_SA110
+- bool "Support StrongARM(R) SA-110 processor" if !ARCH_EBSA110 && !FOOTBRIDGE && !ARCH_TBOX && !ARCH_SHARK && !ARCH_NEXUSPCI && !ARCH_ANAKIN && ARCH_RPC
+- default y if ARCH_EBSA110 || FOOTBRIDGE || ARCH_TBOX || ARCH_SHARK || ARCH_NEXUSPCI || ARCH_ANAKIN
+- help
+- The Intel StrongARM(R) SA-110 is a 32-bit microprocessor and
+- is available at five speeds ranging from 100 MHz to 233 MHz.
+- More information is available at
+- <http://developer.intel.com/design/strong/sa110.htm>.
+-
+- Say Y if you want support for the SA-110 processor.
+- Otherwise, say N.
+-
+-# SA1100
+-config CPU_SA1100
+- bool
+- depends on ARCH_SA1100
+- default y
+-
+-# XScale
+-config CPU_XSCALE
+- bool
+- depends on ARCH_IOP3XX || ARCH_ADIFCC || ARCH_PXA
+- default y
+-
+-# Figure out what processor architecture version we should be using.
+-# This defines the compiler instruction set which depends on the machine type.
+-config CPU_32v3
+- bool
+- depends on ARCH_RPC || ARCH_CLPS7500
+- default y
+-
+-config CPU_32v4
+- bool
+- depends on ARCH_EBSA110 || FOOTBRIDGE || ARCH_TBOX || ARCH_SHARK || ARCH_NEXUSPCI || ARCH_CLPS711X || ARCH_INTEGRATOR || ARCH_SA1100 || ARCH_L7200 || ARCH_ANAKIN || ARCH_CAMELOT
+- default y
+-
+-config CPU_32v5
+- bool
+- depends on ARCH_IOP3XX || ARCH_ADIFCC || ARCH_PXA
+- default y
+-
+-comment "Processor Features"
+-
+-config ARM_THUMB
+- bool "Support Thumb instructions (EXPERIMENTAL)"
+- depends on (CPU_ARM720T || CPU_ARM920T || CPU_ARM922T || CPU_ARM926T || CPU_ARM1020 || CPU_XSCALE) && EXPERIMENTAL
+- help
+- Say Y if you want to have kernel support for ARM Thumb instructions,
+- fault handlers, and system calls.
+-
+- The Thumb instruction set is a compressed form of the standard ARM
+- instruction set resulting in smaller binaries at the expense of
+- slightly less efficient code.
+-
+- If you don't know what this all is, saying Y is a safe choice.
+-
+-config CPU_BIG_ENDIAN
+- bool "Build big-endian kernel"
+- depends on ARCH_SUPPORTS_BIG_ENDIAN
+- help
+- Say Y if you plan on running a kernel in big-endian mode.
+- Note that your board must be properly built and your board
+- port must properly enable and big-endian related features
+- of your chipset/board/processor.
+-
+-config CPU_ICACHE_DISABLE
+- bool "Disable I-Cache"
+- depends on CPU_ARM920T || CPU_ARM922T || CPU_ARM926T || CPU_ARM1020
+- help
+- Say Y here to disable the processor instruction cache. Unless
+- you have a reason not to or are unsure, say N.
+-
+-config CPU_DCACHE_DISABLE
+- bool "Disable D-Cache"
+- depends on CPU_ARM920T || CPU_ARM922T || CPU_ARM926T || CPU_ARM1020
+- help
+- Say Y here to disable the processor data cache. Unless
+- you have a reason not to or are unsure, say N.
+-
+-config CPU_DCACHE_WRITETHROUGH
+- bool "Force write through D-cache"
+- depends on (CPU_ARM920T || CPU_ARM922T || CPU_ARM926T || CPU_ARM1020) && !CPU_DISABLE_DCACHE
+- help
+- Say Y here to use the data cache in writethough mode. Unless you
+- specifically require this or are unsure, say N.
+-
+-config CPU_CACHE_ROUND_ROBIN
+- bool "Round robin I and D cache replacement algorithm"
+- depends on (CPU_ARM926T || CPU_ARM1020) && (!CPU_ICACHE_DISABLE || !CPU_DCACHE_DISABLE)
+- help
+- Say Y here to use the predictable round-robin cache replacement
+- policy. Unless you specifically require this or are unsure, say N.
+-
+-config CPU_BPREDICT_DISABLE
+- bool "Disable branch prediction"
+- depends on CPU_ARM1020
+- help
+- Say Y here to disable branch prediction. If unsure, say N.
++source arch/arm/mm/Kconfig
+
+ # bool 'Use XScale PMU as timer source' CONFIG_XSCALE_PMU_TIMER
+ config XSCALE_PMU
+@@ -842,11 +651,6 @@
+
+ source "drivers/char/Kconfig"
+
+-config KBDMOUSE
+- bool
+- depends on ARCH_ACORN && BUSMOUSE=y && !ARCH_RPC
+- default y
+-
+ source "drivers/media/Kconfig"
+
+ source "fs/Kconfig"
+Index: linux-2.6.0-test5/arch/arm/kernel/asm-offsets.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/kernel/asm-offsets.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/kernel/asm-offsets.c 2003-09-27 11:38:18.678688792 +0800
+@@ -10,14 +10,9 @@
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+-
+-#include <linux/config.h>
+ #include <linux/sched.h>
+ #include <linux/mm.h>
+
+-#include <asm/pgtable.h>
+-#include <asm/uaccess.h>
+-
+ /*
+ * Make sure that the compiler and target are compatible.
+ */
+@@ -58,19 +53,6 @@
+ BLANK();
+ DEFINE(VM_EXEC, VM_EXEC);
+ BLANK();
+- DEFINE(HPTE_TYPE_SMALL, PTE_TYPE_SMALL);
+- DEFINE(HPTE_AP_READ, PTE_AP_READ);
+- DEFINE(HPTE_AP_WRITE, PTE_AP_WRITE);
+- BLANK();
+- DEFINE(LPTE_PRESENT, L_PTE_PRESENT);
+- DEFINE(LPTE_YOUNG, L_PTE_YOUNG);
+- DEFINE(LPTE_BUFFERABLE, L_PTE_BUFFERABLE);
+- DEFINE(LPTE_CACHEABLE, L_PTE_CACHEABLE);
+- DEFINE(LPTE_USER, L_PTE_USER);
+- DEFINE(LPTE_WRITE, L_PTE_WRITE);
+- DEFINE(LPTE_EXEC, L_PTE_EXEC);
+- DEFINE(LPTE_DIRTY, L_PTE_DIRTY);
+- BLANK();
+ DEFINE(PAGE_SZ, PAGE_SIZE);
+ BLANK();
+ DEFINE(SYS_ERROR0, 0x9f0000);
+Index: linux-2.6.0-test5/arch/arm/kernel/bios32.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/kernel/bios32.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/kernel/bios32.c 2003-09-27 11:38:18.682688184 +0800
+@@ -35,18 +35,17 @@
+ continue;
+
+ pci_read_config_word(dev, PCI_STATUS, &status);
++ if (status == 0xffff)
++ continue;
+
+- status &= status_mask;
+- if (status == 0)
++ if ((status & status_mask) == 0)
+ continue;
+
+ /* clear the status errors */
+- pci_write_config_word(dev, PCI_STATUS, status);
++ pci_write_config_word(dev, PCI_STATUS, status & status_mask);
+
+ if (warn)
+- printk("(%02x:%02x.%d: %04X) ", dev->bus->number,
+- PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn),
+- status);
++ printk("(%s: %04X) ", pci_name(dev), status);
+ }
+ }
+
+Index: linux-2.6.0-test5/arch/arm/kernel/ecard.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/kernel/ecard.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/kernel/ecard.c 2003-09-27 11:38:18.690686968 +0800
+@@ -329,8 +329,7 @@
+ BUG();
+
+ if (ecard_pid <= 0)
+- ecard_pid = kernel_thread(ecard_task, NULL,
+- CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++ ecard_pid = kernel_thread(ecard_task, NULL, CLONE_KERNEL);
+
+ ecard_req = req;
+ wake_up(&ecard_wait);
+Index: linux-2.6.0-test5/arch/arm/kernel/entry-armv.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/kernel/entry-armv.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/kernel/entry-armv.S 2003-09-27 11:38:18.699685600 +0800
+@@ -729,7 +729,7 @@
+ * This routine must not corrupt r9
+ */
+ #ifdef MULTI_ABORT
+- ldr r4, .LCprocfns @ pass r0, r3 to
++ ldr r4, .LCprocfns @ pass r2, r3 to
+ mov lr, pc @ processor code
+ ldr pc, [r4] @ call processor specific code
+ #else
+@@ -871,7 +871,7 @@
+ alignment_trap r7, r7, __temp_abt
+ zero_fp
+ #ifdef MULTI_ABORT
+- ldr r4, .LCprocfns @ pass r0, r3 to
++ ldr r4, .LCprocfns @ pass r2, r3 to
+ mov lr, pc @ processor code
+ ldr pc, [r4] @ call processor specific code
+ #else
+Index: linux-2.6.0-test5/arch/arm/kernel/fiq.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/kernel/fiq.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/kernel/fiq.c 2003-09-27 11:38:18.710683928 +0800
+@@ -35,7 +35,6 @@
+ * - enables FIQ.
+ * 6. Goto 3
+ */
+-#include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/mm.h>
+Index: linux-2.6.0-test5/arch/arm/kernel/process.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/kernel/process.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/kernel/process.c 2003-09-27 11:38:18.713683472 +0800
+@@ -312,8 +312,8 @@
+ asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
+
+ int
+-copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
+- unsigned long unused, struct task_struct *p, struct pt_regs *regs)
++copy_thread(int nr, unsigned long clone_flags, unsigned long stack_start,
++ unsigned long stk_sz, struct task_struct *p, struct pt_regs *regs)
+ {
+ struct thread_info *thread = p->thread_info;
+ struct pt_regs *childregs;
+@@ -321,7 +321,7 @@
+ childregs = ((struct pt_regs *)((unsigned long)thread + THREAD_SIZE - 8)) - 1;
+ *childregs = *regs;
+ childregs->ARM_r0 = 0;
+- childregs->ARM_sp = esp;
++ childregs->ARM_sp = stack_start;
+
+ memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));
+ thread->cpu_context.sp = (unsigned long)childregs;
+@@ -373,33 +373,35 @@
+ }
+
+ /*
+- * This is the mechanism for creating a new kernel thread.
+- *
+- * NOTE! Only a kernel-only process(ie the swapper or direct descendants
+- * who haven't done an "execve()") should use this: it will work within
+- * a system call from a "real" process, but the process memory space will
+- * not be free'd until both the parent and the child have exited.
++ * Shuffle the argument into the correct register before calling the
++ * thread function. r1 is the thread argument, r2 is the pointer to
++ * the thread function, and r3 points to the exit function.
++ */
++extern void kernel_thread_helper(void);
++asm( ".align\n"
++" .type kernel_thread_helper, #function\n"
++"kernel_thread_helper:\n"
++" mov r0, r1\n"
++" mov lr, r3\n"
++" mov pc, r2\n"
++" .size kernel_thread_helper, . - kernel_thread_helper");
++
++/*
++ * Create a kernel thread.
+ */
+ pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
+ {
+- register unsigned int r0 asm("r0") = flags | CLONE_VM | CLONE_UNTRACED;
+- register unsigned int r1 asm("r1") = 0;
+- register pid_t __ret asm("r0");
+-
+- __asm__ __volatile__(
+- __syscall(clone)" @ kernel_thread sys_clone \n\
+- movs %0, r0 @ if we are the child \n\
+- bne 1f \n\
+- mov fp, #0 @ ensure that fp is zero \n\
+- mov r0, %4 \n\
+- mov lr, pc \n\
+- mov pc, %3 \n\
+- b sys_exit \n\
+-1: "
+- : "=r" (__ret)
+- : "0" (r0), "r" (r1), "r" (fn), "r" (arg)
+- : "lr");
+- return __ret;
++ struct pt_regs regs;
++
++ memset(®s, 0, sizeof(regs));
++
++ regs.ARM_r1 = (unsigned long)arg;
++ regs.ARM_r2 = (unsigned long)fn;
++ regs.ARM_r3 = (unsigned long)do_exit;
++ regs.ARM_pc = (unsigned long)kernel_thread_helper;
++ regs.ARM_cpsr = SVC_MODE;
++
++ return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 0, NULL, NULL);
+ }
+
+ /*
+Index: linux-2.6.0-test5/arch/arm/kernel/ptrace.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/kernel/ptrace.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/kernel/ptrace.c 2003-09-27 11:38:18.719682560 +0800
+@@ -9,7 +9,6 @@
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+-#include <linux/config.h>
+ #include <linux/kernel.h>
+ #include <linux/sched.h>
+ #include <linux/mm.h>
+Index: linux-2.6.0-test5/arch/arm/kernel/semaphore.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/kernel/semaphore.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/kernel/semaphore.c 2003-09-27 11:38:18.724681800 +0800
+@@ -11,7 +11,6 @@
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+-#include <linux/config.h>
+ #include <linux/sched.h>
+ #include <linux/errno.h>
+
+Index: linux-2.6.0-test5/arch/arm/kernel/setup.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/kernel/setup.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/kernel/setup.c 2003-09-27 11:38:18.736679976 +0800
+@@ -498,7 +498,7 @@
+ if (tag->hdr.size > 2) {
+ if ((tag->u.core.flags & 1) == 0)
+ root_mountflags &= ~MS_RDONLY;
+- ROOT_DEV = tag->u.core.rootdev;
++ ROOT_DEV = old_decode_dev(tag->u.core.rootdev);
+ }
+ return 0;
+ }
+@@ -798,7 +798,7 @@
+ seq_printf(m, "Cache type\t: %s\n"
+ "Cache clean\t: %s\n"
+ "Cache lockdown\t: %s\n"
+- "Cache unified\t: %s\n",
++ "Cache format\t: %s\n",
+ cache_types[CACHE_TYPE(cache_info)],
+ cache_clean[CACHE_TYPE(cache_info)],
+ cache_lockdown[CACHE_TYPE(cache_info)],
+Index: linux-2.6.0-test5/arch/arm/lib/io-readsb.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/lib/io-readsb.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/lib/io-readsb.S 2003-09-27 11:38:18.737679824 +0800
+@@ -9,7 +9,6 @@
+ */
+ #include <linux/linkage.h>
+ #include <asm/assembler.h>
+-#include <asm/hardware.h>
+
+ .insb_align: rsb ip, ip, #4
+ cmp ip, r2
+@@ -37,32 +36,36 @@
+
+ .insb_16_lp: ldrb r3, [r0]
+ ldrb r4, [r0]
+- orr r3, r3, r4, lsl #8
+- ldrb r4, [r0]
+- orr r3, r3, r4, lsl #16
+- ldrb r4, [r0]
+- orr r3, r3, r4, lsl #24
+- ldrb r4, [r0]
+- ldrb r5, [r0]
+- orr r4, r4, r5, lsl #8
+- ldrb r5, [r0]
+- orr r4, r4, r5, lsl #16
+- ldrb r5, [r0]
+- orr r4, r4, r5, lsl #24
+ ldrb r5, [r0]
++ mov r3, r3, lsl #byte(0)
+ ldrb r6, [r0]
+- orr r5, r5, r6, lsl #8
+- ldrb r6, [r0]
+- orr r5, r5, r6, lsl #16
++ orr r3, r3, r4, lsl #byte(1)
++ ldrb r4, [r0]
++ orr r3, r3, r5, lsl #byte(2)
++ ldrb r5, [r0]
++ orr r3, r3, r6, lsl #byte(3)
+ ldrb r6, [r0]
+- orr r5, r5, r6, lsl #24
++ mov r4, r4, lsl #byte(0)
++ ldrb ip, [r0]
++ orr r4, r4, r5, lsl #byte(1)
++ ldrb r5, [r0]
++ orr r4, r4, r6, lsl #byte(2)
+ ldrb r6, [r0]
++ orr r4, r4, ip, lsl #byte(3)
+ ldrb ip, [r0]
+- orr r6, r6, ip, lsl #8
++ mov r5, r5, lsl #byte(0)
++ ldrb lr, [r0]
++ orr r5, r5, r6, lsl #byte(1)
++ ldrb r6, [r0]
++ orr r5, r5, ip, lsl #byte(2)
+ ldrb ip, [r0]
+- orr r6, r6, ip, lsl #16
++ orr r5, r5, lr, lsl #byte(3)
++ ldrb lr, [r0]
++ mov r6, r6, lsl #byte(0)
++ orr r6, r6, ip, lsl #byte(1)
+ ldrb ip, [r0]
+- orr r6, r6, ip, lsl #24
++ orr r6, r6, lr, lsl #byte(2)
++ orr r6, r6, ip, lsl #byte(3)
+ stmia r1!, {r3 - r6}
+
+ subs r2, r2, #16
+@@ -76,18 +79,20 @@
+
+ ldrb r3, [r0]
+ ldrb r4, [r0]
+- orr r3, r3, r4, lsl #8
+- ldrb r4, [r0]
+- orr r3, r3, r4, lsl #16
+- ldrb r4, [r0]
+- orr r3, r3, r4, lsl #24
+- ldrb r4, [r0]
+ ldrb r5, [r0]
+- orr r4, r4, r5, lsl #8
+- ldrb r5, [r0]
+- orr r4, r4, r5, lsl #16
++ mov r3, r3, lsl #byte(0)
++ ldrb r6, [r0]
++ orr r3, r3, r4, lsl #byte(1)
++ ldrb r4, [r0]
++ orr r3, r3, r5, lsl #byte(2)
+ ldrb r5, [r0]
+- orr r4, r4, r5, lsl #24
++ orr r3, r3, r6, lsl #byte(3)
++ ldrb r6, [r0]
++ mov r4, r4, lsl #byte(0)
++ ldrb ip, [r0]
++ orr r4, r4, r5, lsl #byte(1)
++ orr r4, r4, r6, lsl #byte(2)
++ orr r4, r4, ip, lsl #byte(3)
+ stmia r1!, {r3, r4}
+
+ .insb_no_8: tst r2, #4
+@@ -95,11 +100,12 @@
+
+ ldrb r3, [r0]
+ ldrb r4, [r0]
+- orr r3, r3, r4, lsl #8
+- ldrb r4, [r0]
+- orr r3, r3, r4, lsl #16
+- ldrb r4, [r0]
+- orr r3, r3, r4, lsl #24
++ ldrb r5, [r0]
++ ldrb r6, [r0]
++ mov r3, r3, lsl #byte(0)
++ orr r3, r3, r4, lsl #byte(1)
++ orr r3, r3, r5, lsl #byte(2)
++ orr r3, r3, r6, lsl #byte(3)
+ str r3, [r1], #4
+
+ .insb_no_4: ands r2, r2, #3
+Index: linux-2.6.0-test5/arch/arm/lib/io-writesb.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/lib/io-writesb.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/lib/io-writesb.S 2003-09-27 11:38:18.739679520 +0800
+@@ -9,7 +9,26 @@
+ */
+ #include <linux/linkage.h>
+ #include <asm/assembler.h>
+-#include <asm/hardware.h>
++
++ .macro outword, rd
++#ifndef __ARMEB__
++ strb \rd, [r0]
++ mov \rd, \rd, lsr #8
++ strb \rd, [r0]
++ mov \rd, \rd, lsr #8
++ strb \rd, [r0]
++ mov \rd, \rd, lsr #8
++ strb \rd, [r0]
++#else
++ mov lr, \rd, lsr #24
++ strb lr, [r0]
++ mov lr, \rd, lsr #16
++ strb lr, [r0]
++ mov lr, \rd, lsr #8
++ strb lr, [r0]
++ strb \rd, [r0]
++#endif
++ .endm
+
+ .outsb_align: rsb ip, ip, #4
+ cmp ip, r2
+@@ -30,86 +49,37 @@
+ ands ip, r1, #3
+ bne .outsb_align
+
+-.outsb_aligned: stmfd sp!, {r4 - r6, lr}
++.outsb_aligned: stmfd sp!, {r4, r5, lr}
+
+ subs r2, r2, #16
+ bmi .outsb_no_16
+
+-.outsb_16_lp: ldmia r1!, {r3 - r6}
+-
+- strb r3, [r0]
+- mov r3, r3, lsr #8
+- strb r3, [r0]
+- mov r3, r3, lsr #8
+- strb r3, [r0]
+- mov r3, r3, lsr #8
+- strb r3, [r0]
+-
+- strb r4, [r0]
+- mov r4, r4, lsr #8
+- strb r4, [r0]
+- mov r4, r4, lsr #8
+- strb r4, [r0]
+- mov r4, r4, lsr #8
+- strb r4, [r0]
+-
+- strb r5, [r0]
+- mov r5, r5, lsr #8
+- strb r5, [r0]
+- mov r5, r5, lsr #8
+- strb r5, [r0]
+- mov r5, r5, lsr #8
+- strb r5, [r0]
+-
+- strb r6, [r0]
+- mov r6, r6, lsr #8
+- strb r6, [r0]
+- mov r6, r6, lsr #8
+- strb r6, [r0]
+- mov r6, r6, lsr #8
+- strb r6, [r0]
+-
++.outsb_16_lp: ldmia r1!, {r3, r4, r5, ip}
++ outword r3
++ outword r4
++ outword r5
++ outword ip
+ subs r2, r2, #16
+ bpl .outsb_16_lp
+
+ tst r2, #15
+- LOADREGS(eqfd, sp!, {r4 - r6, pc})
++ LOADREGS(eqfd, sp!, {r4, r5, pc})
+
+ .outsb_no_16: tst r2, #8
+ beq .outsb_no_8
+
+ ldmia r1!, {r3, r4}
+-
+- strb r3, [r0]
+- mov r3, r3, lsr #8
+- strb r3, [r0]
+- mov r3, r3, lsr #8
+- strb r3, [r0]
+- mov r3, r3, lsr #8
+- strb r3, [r0]
+-
+- strb r4, [r0]
+- mov r4, r4, lsr #8
+- strb r4, [r0]
+- mov r4, r4, lsr #8
+- strb r4, [r0]
+- mov r4, r4, lsr #8
+- strb r4, [r0]
++ outword r3
++ outword r4
+
+ .outsb_no_8: tst r2, #4
+ beq .outsb_no_4
+
+ ldr r3, [r1], #4
+- strb r3, [r0]
+- mov r3, r3, lsr #8
+- strb r3, [r0]
+- mov r3, r3, lsr #8
+- strb r3, [r0]
+- mov r3, r3, lsr #8
+- strb r3, [r0]
++ outword r3
+
+ .outsb_no_4: ands r2, r2, #3
+- LOADREGS(eqfd, sp!, {r4 - r6, pc})
++ LOADREGS(eqfd, sp!, {r4, r5, pc})
+
+ cmp r2, #2
+ ldrb r3, [r1], #1
+@@ -119,4 +89,4 @@
+ ldrgtb r3, [r1]
+ strgtb r3, [r0]
+
+- LOADREGS(fd, sp!, {r4 - r6, pc})
++ LOADREGS(fd, sp!, {r4, r5, pc})
+Index: linux-2.6.0-test5/arch/arm/lib/io-writesl.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/lib/io-writesl.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/lib/io-writesl.S 2003-09-27 11:38:18.740679368 +0800
+@@ -17,10 +17,15 @@
+ ands ip, r1, #3
+ bne 2f
+
+-1: ldr r3, [r1], #4
+- str r3, [r0]
+- subs r2, r2, #1
+- bne 1b
++ tst r2, #1
++ ldrne r3, [r1], #4
++ strne r3, [r0, #0]
++1: subs r2, r2, #2
++ ldrcs r3, [r1], #4
++ ldrcs ip, [r1], #4
++ strcs r3, [r0, #0]
++ strcs ip, [r0, #0]
++ bcs 1b
+ mov pc, lr
+
+ 2: bic r1, r1, #3
+@@ -31,25 +36,25 @@
+
+ 3: mov ip, r3, lsr #16
+ ldr r3, [r1], #4
+- orr ip, ip, r3, lsl #16
+- str ip, [r0]
+ subs r2, r2, #1
++ orr ip, ip, r3, lsl #16
++ str ip, [r0, #0]
+ bne 3b
+ mov pc, lr
+
+ 4: mov ip, r3, lsr #24
+ ldr r3, [r1], #4
+- orr ip, ip, r3, lsl #8
+- str ip, [r0]
+ subs r2, r2, #1
++ orr ip, ip, r3, lsl #8
++ str ip, [r0, #0]
+ bne 4b
+ mov pc, lr
+
+ 5: mov ip, r3, lsr #8
+ ldr r3, [r1], #4
+- orr ip, ip, r3, lsl #24
+- str ip, [r0]
+ subs r2, r2, #1
++ orr ip, ip, r3, lsl #24
++ str ip, [r0, #0]
+ bne 5b
+ mov pc, lr
+
+Index: linux-2.6.0-test5/arch/arm/lib/lib1funcs.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/lib/lib1funcs.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/lib/lib1funcs.S 2003-09-27 11:38:18.744678760 +0800
+@@ -41,7 +41,6 @@
+ #include <linux/linkage.h>
+ #include <asm/assembler.h>
+ #include <asm/hardware.h>
+-#include <linux/config.h>
+
+ #define RET mov
+ #define RETc(x) mov##x
+Index: linux-2.6.0-test5/arch/arm/mach-anakin/arch.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-anakin/arch.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-anakin/arch.c 2003-09-27 11:38:18.745678608 +0800
+@@ -10,8 +10,6 @@
+ * Changelog:
+ * 09-Apr-2001 W/TTC Created
+ */
+-
+-#include <linux/config.h>
+ #include <linux/tty.h>
+ #include <linux/init.h>
+
+Index: linux-2.6.0-test5/arch/arm/mach-clps711x/mm.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-clps711x/mm.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-clps711x/mm.c 2003-09-27 11:38:18.746678456 +0800
+@@ -22,7 +22,6 @@
+ #include <linux/kernel.h>
+ #include <linux/mm.h>
+ #include <linux/init.h>
+-#include <linux/config.h>
+ #include <linux/bootmem.h>
+
+ #include <asm/hardware.h>
+Index: linux-2.6.0-test5/arch/arm/mach-integrator/core.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-integrator/core.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-integrator/core.c 2003-09-27 11:38:18.749678000 +0800
+@@ -17,7 +17,6 @@
+ * 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/types.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+@@ -34,6 +33,8 @@
+ #include <asm/hardware/amba.h>
+ #include <asm/hardware/amba_kmi.h>
+
++#include <asm/arch/lm.h>
++
+ #include <asm/mach/arch.h>
+ #include <asm/mach/irq.h>
+ #include <asm/mach/map.h>
+@@ -46,6 +47,7 @@
+ * just for now).
+ */
+ #define VA_IC_BASE IO_ADDRESS(INTEGRATOR_IC_BASE)
++#define VA_SC_BASE IO_ADDRESS(INTEGRATOR_SC_BASE)
+ #define VA_CMIC_BASE IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_IC_OFFSET
+
+ /*
+@@ -66,7 +68,7 @@
+ * f1a00000 1a000000 Debug LEDs
+ * f1b00000 1b000000 GPIO
+ */
+-
++
+ static struct map_desc integrator_io_desc[] __initdata = {
+ { IO_ADDRESS(INTEGRATOR_HDR_BASE), INTEGRATOR_HDR_BASE, SZ_4K, MT_DEVICE },
+ { IO_ADDRESS(INTEGRATOR_SC_BASE), INTEGRATOR_SC_BASE, SZ_4K, MT_DEVICE },
+@@ -89,7 +91,7 @@
+ iotable_init(integrator_io_desc, ARRAY_SIZE(integrator_io_desc));
+ }
+
+-#define ALLPCI ( (1 << IRQ_PCIINT0) | (1 << IRQ_PCIINT1) | (1 << IRQ_PCIINT2) | (1 << IRQ_PCIINT3) )
++#define ALLPCI ( (1 << IRQ_PCIINT0) | (1 << IRQ_PCIINT1) | (1 << IRQ_PCIINT2) | (1 << IRQ_PCIINT3) )
+
+ static void sc_mask_irq(unsigned int irq)
+ {
+@@ -161,6 +163,7 @@
+
+ static int __init register_devices(void)
+ {
++ unsigned long sc_dec;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
+@@ -169,6 +172,28 @@
+ amba_device_register(d, &iomem_resource);
+ }
+
++ sc_dec = readl(VA_SC_BASE + INTEGRATOR_SC_DEC_OFFSET);
++ for (i = 0; i < 4; i++) {
++ struct lm_device *lmdev;
++
++ if ((sc_dec & (16 << i)) == 0)
++ continue;
++
++ lmdev = kmalloc(sizeof(struct lm_device), GFP_KERNEL);
++ if (!lmdev)
++ continue;
++
++ memset(lmdev, 0, sizeof(struct lm_device));
++
++ lmdev->resource.start = 0xc0000000 + 0x10000000 * i;
++ lmdev->resource.end = lmdev->resource.start + 0x0fffffff;
++ lmdev->resource.flags = IORESOURCE_MEM;
++ lmdev->irq = IRQ_EXPINT0 + i;
++ lmdev->id = i;
++
++ lm_device_register(lmdev);
++ }
++
+ return 0;
+ }
+
+Index: linux-2.6.0-test5/arch/arm/mach-integrator/cpu.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-integrator/cpu.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-integrator/cpu.c 2003-09-27 11:38:18.751677696 +0800
+@@ -11,7 +11,6 @@
+ *
+ * CPU support functions
+ */
+-#include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+Index: linux-2.6.0-test5/arch/arm/mach-integrator/impd1.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-integrator/impd1.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-integrator/impd1.c 2003-09-27 11:38:18.754677240 +0800
+@@ -10,7 +10,7 @@
+ * This file provides the core support for the IM-PD1 module.
+ *
+ * Module / boot parameters.
+- * id=n impd1.id=n - set the logic module position in stack to 'n'
++ * lmid=n impd1.lmid=n - set the logic module position in stack to 'n'
+ */
+ #include <linux/module.h>
+ #include <linux/moduleparam.h>
+@@ -21,17 +21,15 @@
+ #include <asm/io.h>
+ #include <asm/hardware/icst525.h>
+ #include <asm/hardware/amba.h>
++#include <asm/arch/lm.h>
+ #include <asm/arch/impd1.h>
+ #include <asm/sizes.h>
+
+ static int module_id;
+
+-module_param_named(lmid, module_id, int, 0);
++module_param_named(lmid, module_id, int, 0444);
+ MODULE_PARM_DESC(lmid, "logic module stack position");
+
+-#define ROM_OFFSET 0x0fffff00
+-#define ROM_SIZE 256
+-
+ struct impd1_module {
+ void *base;
+ };
+@@ -142,17 +140,15 @@
+ }
+ };
+
+-static int impd1_probe(struct device *dev)
++static int impd1_probe(struct lm_device *dev)
+ {
+- struct platform_device *pdev = to_platform_device(dev);
+- struct resource *res = &pdev->resource[0];
+ struct impd1_module *impd1;
+ int i, ret;
+
+- if (pdev->id != module_id)
++ if (dev->id != module_id)
+ return -EINVAL;
+
+- if (!request_mem_region(res->start, SZ_4K, "LM registers"))
++ if (!request_mem_region(dev->resource.start, SZ_4K, "LM registers"))
+ return -EBUSY;
+
+ impd1 = kmalloc(sizeof(struct impd1_module), GFP_KERNEL);
+@@ -162,22 +158,22 @@
+ }
+ memset(impd1, 0, sizeof(struct impd1_module));
+
+- impd1->base = ioremap(res->start, SZ_4K);
++ impd1->base = ioremap(dev->resource.start, SZ_4K);
+ if (!impd1->base) {
+ ret = -ENOMEM;
+ goto free_impd1;
+ }
+
+- dev_set_drvdata(dev, impd1);
++ lm_set_drvdata(dev, impd1);
+
+- printk("IM-PD1 found at 0x%08lx\n", res->start);
++ printk("IM-PD1 found at 0x%08lx\n", dev->resource.start);
+
+ for (i = 0; i < ARRAY_SIZE(impd1_devs); i++) {
+ struct impd1_device *idev = impd1_devs + i;
+ struct amba_device *d;
+ unsigned long pc_base;
+
+- pc_base = res->start + idev->offset;
++ pc_base = dev->resource.start + idev->offset;
+
+ d = kmalloc(sizeof(struct amba_device), GFP_KERNEL);
+ if (!d)
+@@ -186,16 +182,16 @@
+ memset(d, 0, sizeof(struct amba_device));
+
+ snprintf(d->dev.bus_id, sizeof(d->dev.bus_id),
+- "lm%x:%5.5lx", pdev->id, idev->offset >> 12);
++ "lm%x:%5.5lx", dev->id, idev->offset >> 12);
+
+- d->dev.parent = &pdev->dev;
+- d->res.start = res->start + idev->offset;
++ d->dev.parent = &dev->dev;
++ d->res.start = dev->resource.start + idev->offset;
+ d->res.end = d->res.start + SZ_4K - 1;
+ d->res.flags = IORESOURCE_MEM;
+- d->irq = pdev->resource[1].start;
++ d->irq = dev->irq;
+ d->periphid = idev->id;
+
+- ret = amba_device_register(d, res);
++ ret = amba_device_register(d, &dev->resource);
+ if (ret) {
+ printk("unable to register device %s: %d\n",
+ d->dev.bus_id, ret);
+@@ -211,47 +207,44 @@
+ if (impd1)
+ kfree(impd1);
+ release_lm:
+- release_mem_region(res->start, SZ_4K);
++ release_mem_region(dev->resource.start, SZ_4K);
+ return ret;
+ }
+
+-static int impd1_remove(struct device *dev)
++static void impd1_remove(struct lm_device *dev)
+ {
+- struct platform_device *pdev = to_platform_device(dev);
+- struct resource *res = &pdev->resource[0];
+- struct impd1_module *impd1 = dev_get_drvdata(dev);
++ struct impd1_module *impd1 = lm_get_drvdata(dev);
+ struct list_head *l, *n;
+
+- list_for_each_safe(l, n, &dev->children) {
++ list_for_each_safe(l, n, &dev->dev.children) {
+ struct device *d = list_to_dev(l);
+
+ device_unregister(d);
+ }
+
+- dev_set_drvdata(dev, NULL);
++ lm_set_drvdata(dev, NULL);
+
+ iounmap(impd1->base);
+ kfree(impd1);
+- release_mem_region(res->start, SZ_4K);
+-
+- return 0;
++ release_mem_region(dev->resource.start, SZ_4K);
+ }
+
+-static struct device_driver impd1_driver = {
+- .name = "lm",
+- .bus = &platform_bus_type,
++static struct lm_driver impd1_driver = {
++ .drv = {
++ .name = "impd1",
++ },
+ .probe = impd1_probe,
+ .remove = impd1_remove,
+ };
+
+ static int __init impd1_init(void)
+ {
+- return driver_register(&impd1_driver);
++ return lm_driver_register(&impd1_driver);
+ }
+
+ static void __exit impd1_exit(void)
+ {
+- driver_unregister(&impd1_driver);
++ lm_driver_unregister(&impd1_driver);
+ }
+
+ module_init(impd1_init);
+Index: linux-2.6.0-test5/arch/arm/mach-integrator/lm.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-integrator/lm.c 2003-09-27 11:38:18.429726640 +0800
++++ linux-2.6.0-test5/arch/arm/mach-integrator/lm.c 2003-09-27 11:38:18.754677240 +0800
+@@ -0,0 +1,92 @@
++/*
++ * linux/arch/arm/mach-integrator/lm.c
++ *
++ * Copyright (C) 2003 Deep Blue Solutions Ltd, All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++#include <linux/init.h>
++#include <linux/device.h>
++
++#include <asm/arch/lm.h>
++
++#define to_lm_device(d) container_of(d, struct lm_device, dev)
++#define to_lm_driver(d) container_of(d, struct lm_driver, drv)
++
++static int lm_match(struct device *dev, struct device_driver *drv)
++{
++ return 1;
++}
++
++static struct bus_type lm_bustype = {
++ .name = "logicmodule",
++ .match = lm_match,
++// .suspend = lm_suspend,
++// .resume = lm_resume,
++};
++
++static int __init lm_init(void)
++{
++ return bus_register(&lm_bustype);
++}
++
++postcore_initcall(lm_init);
++
++static int lm_bus_probe(struct device *dev)
++{
++ struct lm_device *lmdev = to_lm_device(dev);
++ struct lm_driver *lmdrv = to_lm_driver(dev->driver);
++
++ return lmdrv->probe(lmdev);
++}
++
++static int lm_bus_remove(struct device *dev)
++{
++ struct lm_device *lmdev = to_lm_device(dev);
++ struct lm_driver *lmdrv = to_lm_driver(dev->driver);
++
++ lmdrv->remove(lmdev);
++ return 0;
++}
++
++int lm_driver_register(struct lm_driver *drv)
++{
++ drv->drv.bus = &lm_bustype;
++ drv->drv.probe = lm_bus_probe;
++ drv->drv.remove = lm_bus_remove;
++
++ return driver_register(&drv->drv);
++}
++
++void lm_driver_unregister(struct lm_driver *drv)
++{
++ driver_unregister(&drv->drv);
++}
++
++static void lm_device_release(struct device *dev)
++{
++ struct lm_device *d = to_lm_device(dev);
++
++ kfree(d);
++}
++
++int lm_device_register(struct lm_device *dev)
++{
++ int ret;
++
++ dev->dev.release = lm_device_release;
++ dev->dev.bus = &lm_bustype;
++
++ snprintf(dev->dev.bus_id, sizeof(dev->dev.bus_id), "lm%d", dev->id);
++ dev->resource.name = dev->dev.bus_id;
++
++ ret = request_resource(&iomem_resource, &dev->resource);
++ if (ret == 0) {
++ ret = device_register(&dev->dev);
++ if (ret)
++ release_resource(&dev->resource);
++ }
++ return ret;
++}
+Index: linux-2.6.0-test5/arch/arm/mach-integrator/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-integrator/Makefile 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-integrator/Makefile 2003-09-27 11:38:18.756676936 +0800
+@@ -4,7 +4,7 @@
+
+ # Object file lists.
+
+-obj-y := core.o time.o
++obj-y := core.o lm.o time.o
+
+ obj-$(CONFIG_LEDS) += leds.o
+ obj-$(CONFIG_PCI) += pci_v3.o pci.o
+Index: linux-2.6.0-test5/arch/arm/mach-iop3xx/mm-321.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-iop3xx/mm-321.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-iop3xx/mm-321.c 2003-09-27 11:38:18.757676784 +0800
+@@ -12,7 +12,7 @@
+ * option) any later version.
+ *
+ */
+-
++#include <linux/config.h>
+ #include <linux/mm.h>
+ #include <linux/init.h>
+
+Index: linux-2.6.0-test5/arch/arm/mach-l7200/core.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-l7200/core.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-l7200/core.c 2003-09-27 11:38:18.758676632 +0800
+@@ -5,7 +5,6 @@
+ *
+ * Extra MM routines for L7200 architecture
+ */
+-#include <linux/config.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+
+Index: linux-2.6.0-test5/arch/arm/mach-pxa/generic.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-pxa/generic.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-pxa/generic.c 2003-09-27 11:38:18.760676328 +0800
+@@ -16,7 +16,6 @@
+ * initialization stuff for PXA machines which can be overridden later if
+ * need be.
+ */
+-#include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+Index: linux-2.6.0-test5/arch/arm/mach-pxa/leds.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-pxa/leds.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-pxa/leds.c 2003-09-27 11:38:18.761676176 +0800
+@@ -7,7 +7,6 @@
+ *
+ * Copyright (c) 2001 Jeff Sutherland, Accelent Systems Inc.
+ */
+-#include <linux/config.h>
+ #include <linux/init.h>
+
+ #include <asm/leds.h>
+Index: linux-2.6.0-test5/arch/arm/mach-pxa/pm.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-pxa/pm.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-pxa/pm.c 2003-09-27 11:38:18.763675872 +0800
+@@ -10,7 +10,7 @@
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License.
+ */
+-
++#include <linux/config.h>
+ #include <linux/errno.h>
+ #include <linux/time.h>
+
+Index: linux-2.6.0-test5/arch/arm/mach-rpc/riscpc.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-rpc/riscpc.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-rpc/riscpc.c 2003-09-27 11:38:18.764675720 +0800
+@@ -17,7 +17,6 @@
+
+ #include <asm/elf.h>
+ #include <asm/io.h>
+-#include <asm/setup.h>
+ #include <asm/mach-types.h>
+ #include <asm/hardware.h>
+ #include <asm/page.h>
+Index: linux-2.6.0-test5/arch/arm/mach-sa1100/h3600.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-sa1100/h3600.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-sa1100/h3600.c 2003-09-27 11:38:18.770674808 +0800
+@@ -19,6 +19,7 @@
+ * and abstracted EGPIO interface.
+ *
+ */
++#include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+Index: linux-2.6.0-test5/arch/arm/mach-sa1100/hackkit.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-sa1100/hackkit.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-sa1100/hackkit.c 2003-09-27 11:38:18.771674656 +0800
+@@ -11,8 +11,6 @@
+ * published by the Free Software Foundation.
+ *
+ */
+-
+-#include <linux/config.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+ #include <linux/sched.h>
+Index: linux-2.6.0-test5/arch/arm/mach-sa1100/pfs168.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-sa1100/pfs168.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-sa1100/pfs168.c 2003-09-27 11:38:18.773674352 +0800
+@@ -1,7 +1,6 @@
+ /*
+ * linux/arch/arm/mach-sa1100/pfs168.c
+ */
+-#include <linux/config.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+ #include <linux/tty.h>
+Index: linux-2.6.0-test5/arch/arm/mach-sa1100/simpad.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-sa1100/simpad.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-sa1100/simpad.c 2003-09-27 11:38:18.775674048 +0800
+@@ -9,24 +9,37 @@
+ #include <linux/tty.h>
+ #include <linux/proc_fs.h>
+ #include <linux/string.h>
++#include <linux/pm.h>
+
++#include <asm/irq.h>
+ #include <asm/hardware.h>
+ #include <asm/setup.h>
+
++#include <asm/mach-types.h>
+ #include <asm/mach/arch.h>
+ #include <asm/mach/map.h>
+ #include <asm/mach/serial_sa1100.h>
++#include <asm/arch/simpad.h>
++#include <asm/arch/registry.h>
++
+ #include <linux/serial_core.h>
++#include <linux/ioport.h>
++#include <asm/io.h>
+
+ #include "generic.h"
+
+ long cs3_shadow;
+
+-long get_cs3_shadow()
++long get_cs3_shadow(void)
+ {
+ return cs3_shadow;
+ }
+
++void set_cs3(long value)
++{
++ *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow = value;
++}
++
+ void set_cs3_bit(int value)
+ {
+ cs3_shadow |= value;
+@@ -39,10 +52,15 @@
+ *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow;
+ }
+
++EXPORT_SYMBOL(set_cs3_bit);
++EXPORT_SYMBOL(clear_cs3_bit);
++
+ static struct map_desc simpad_io_desc[] __initdata = {
+- /* virtual physical length type */
+- { 0xf2800000, 0x4b800000, 0x00800000, MT_DEVICE }, /* MQ200 */
+- { 0xf1000000, 0x18000000, 0x00100000, MT_DEVICE } /* Paules CS3, write only */
++ /* virtual physical length type */
++ /* MQ200 */
++ { 0xf2800000, 0x4b800000, 0x00800000, MT_DEVICE },
++ /* Paules CS3, write only */
++ { 0xf1000000, 0x18000000, 0x00100000, MT_DEVICE },
+ };
+
+
+@@ -50,32 +68,52 @@
+ {
+ if (port->mapbase == (u_int)&Ser1UTCR0) {
+ if (state)
++ {
+ clear_cs3_bit(RS232_ON);
+- else
++ clear_cs3_bit(DECT_POWER_ON);
++ }else
++ {
+ set_cs3_bit(RS232_ON);
++ set_cs3_bit(DECT_POWER_ON);
++ }
+ }
+ }
+
+ static struct sa1100_port_fns simpad_port_fns __initdata = {
+- .pm = simpad_uart_pm,
++ .pm = simpad_uart_pm,
+ };
+
+ static void __init simpad_map_io(void)
+ {
+ sa1100_map_io();
++
+ iotable_init(simpad_io_desc, ARRAY_SIZE(simpad_io_desc));
+
+- PSPR = 0xc0008000;
+- GPDR &= ~GPIO_GPIO0;
+- cs3_shadow = (EN1 | EN0 | LED2_ON | DISPLAY_ON | RS232_ON |
+- ENABLE_5V | RESET_SIMCARD);
+- *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow;
++ set_cs3_bit (EN1 | EN0 | LED2_ON | DISPLAY_ON | RS232_ON |
++ ENABLE_5V | RESET_SIMCARD | DECT_POWER_ON);
++
++
++ sa1100_register_uart_fns(&simpad_port_fns);
++ sa1100_register_uart(0, 3); /* serial interface */
++ sa1100_register_uart(1, 1); /* DECT */
++
++ // Reassign UART 1 pins
++ GAFR |= GPIO_UART_TXD | GPIO_UART_RXD;
++ GPDR |= GPIO_UART_TXD | GPIO_LDD13 | GPIO_LDD15;
++ GPDR &= ~GPIO_UART_RXD;
++ PPAR |= PPAR_UPR;
++
++ /*
++ * Set up registers for sleep mode.
++ */
++
++
++ PWER = PWER_GPIO0| PWER_RTC;
++ PGSR = 0x818;
++ PCFR = 0;
++ PSDR = 0;
+
+- //It is only possible to register 3 UART in serial_sa1100.c
+- sa1100_register_uart(0, 3);
+- sa1100_register_uart(1, 1);
+
+- set_irq_type(IRQ_GPIO_UCB1300_IRQ, IRQT_RISING);
+ }
+
+ #ifdef CONFIG_PROC_FS
+@@ -105,7 +143,7 @@
+ char *p = page;
+ int len, i;
+
+- p += sprintf(p, "Chipselect3 : %x\n", cs3_shadow);
++ p += sprintf(p, "Chipselect3 : %x\n", (uint)cs3_shadow);
+ for (i = 0; i <= 15; i++) {
+ if(cs3_shadow & (1<<i)) {
+ p += sprintf(p, "%s\t: TRUE \n",name[i]);
+@@ -121,23 +159,76 @@
+
+ return len;
+ }
+-
++
++static int proc_cs3_write(struct file * file, const char * buffer,
++ size_t count, loff_t *ppos)
++{
++ unsigned long newRegValue;
++ char *endp;
++
++ newRegValue = simple_strtoul(buffer,&endp,0);
++ set_cs3( newRegValue );
++ return (count+endp-buffer);
++}
++
++#endif
+
+ static int __init cs3_init(void)
+ {
+- struct proc_dir_entry *proc_cs3 = create_proc_entry("cs3", 0, 0);
++
++#ifdef CONFIG_PROC_FS
++ struct proc_dir_entry *proc_cs3 = create_proc_entry("CS3", 0, 0);
+ if (proc_cs3)
++ {
+ proc_cs3->read_proc = proc_cs3_read;
++ proc_cs3->write_proc = (void*)proc_cs3_write;
++ }
++#endif
++
++
++
+ return 0;
+ }
+
+ arch_initcall(cs3_init);
+
+-#endif // CONFIG_PROC_FS
++static void simpad_power_off(void)
++{
++ local_irq_disable(); // was cli
++ set_cs3(0x800); /* only SD_MEDIAQ */
++
++ /* disable internal oscillator, float CS lines */
++ PCFR = (PCFR_OPDE | PCFR_FP | PCFR_FS);
++ /* enable wake-up on GPIO0 (Assabet...) */
++ PWER = GFER = GRER = 1;
++ /*
++ * set scratchpad to zero, just in case it is used as a
++ * restart address by the bootloader.
++ */
++ PSPR = 0;
++ PGSR = 0;
++ /* enter sleep mode */
++ PMCR = PMCR_SF;
++ while(1);
++
++ local_irq_enable(); /* we won't ever call it */
++
++
++}
++
++static int __init simpad_init(void)
++{
++ set_power_off_handler( simpad_power_off );
++ return 0;
++}
++
++arch_initcall(simpad_init);
++
+
+ MACHINE_START(SIMPAD, "Simpad")
+ MAINTAINER("Juergen Messerer")
+ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
++ BOOT_PARAMS(0xc0000100)
+ MAPIO(simpad_map_io)
+ INITIRQ(sa1100_init_irq)
+ MACHINE_END
+Index: linux-2.6.0-test5/arch/arm/mach-sa1100/stork.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-sa1100/stork.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-sa1100/stork.c 2003-09-27 11:38:18.778673592 +0800
+@@ -8,8 +8,6 @@
+ * published by the Free Software Foundation.
+ *
+ */
+-
+-#include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+Index: linux-2.6.0-test5/arch/arm/mach-sa1100/trizeps.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-sa1100/trizeps.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-sa1100/trizeps.c 2003-09-27 11:38:18.780673288 +0800
+@@ -12,7 +12,6 @@
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+-#include <linux/config.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+ #include <linux/sched.h>
+Index: linux-2.6.0-test5/arch/arm/mach-tbox/core.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-tbox/core.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-tbox/core.c 2003-09-27 11:38:18.782672984 +0800
+@@ -16,7 +16,6 @@
+ #include <asm/io.h>
+ #include <asm/pgtable.h>
+ #include <asm/page.h>
+-#include <asm/io.h>
+
+ #include <asm/mach/arch.h>
+ #include <asm/mach/map.h>
+Index: linux-2.6.0-test5/arch/arm/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/Makefile 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/Makefile 2003-09-27 11:38:18.784672680 +0800
+@@ -27,7 +27,6 @@
+ AFLAGS += -mbig-endian
+ 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)
+ comma = ,
+
+ # This selects which instruction set is used.
+@@ -172,22 +171,6 @@
+ i:; $(Q)$(MAKE) $(build)=$(boot) install
+ zi:; $(Q)$(MAKE) $(build)=$(boot) zinstall
+
+-#
+-# Configuration targets. Use these to select a
+-# configuration for your architecture
+-%_config:
+- @( \
+- CFG=$(@:_config=); \
+- if [ -f arch/arm/def-configs/$$CFG ]; then \
+- [ -f .config ] && mv -f .config .config.old; \
+- cp arch/arm/def-configs/$$CFG .config; \
+- echo "*** Default configuration for $$CFG installed"; \
+- echo "*** Next, you may run 'make oldconfig'"; \
+- else \
+- echo "$$CFG does not exist"; \
+- fi; \
+- )
+-
+ arch/$(ARCH)/kernel/asm-offsets.s: include/asm include/linux/version.h \
+ include/asm-arm/.arch \
+ include/config/MARKER
+Index: linux-2.6.0-test5/arch/arm/mm/abort-ev5tj.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/abort-ev5tj.S 2003-09-27 11:38:18.430726488 +0800
++++ linux-2.6.0-test5/arch/arm/mm/abort-ev5tj.S 2003-09-27 11:38:18.785672528 +0800
+@@ -0,0 +1,36 @@
++#include <linux/linkage.h>
++#include <asm/assembler.h>
++/*
++ * Function: v5tj_early_abort
++ *
++ * Params : r2 = address of aborted instruction
++ * : r3 = saved SPSR
++ *
++ * Returns : r0 = address of abort
++ * : r1 = FSR, bit 11 = write
++ * : r2-r8 = corrupted
++ * : r9 = preserved
++ * : sp = pointer to registers
++ *
++ * Purpose : obtain information about current aborted instruction.
++ * Note: we read user space. This means we might cause a data
++ * abort here if the I-TLB and D-TLB aren't seeing the same
++ * picture. Unfortunately, this does happen. We live with it.
++ */
++ .align 5
++ENTRY(v5tj_early_abort)
++ mrc p15, 0, r1, c5, c0, 0 @ get FSR
++ mrc p15, 0, r0, c6, c0, 0 @ get FAR
++ bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR
++ tst r3, #PSR_J_BIT @ Java?
++ orrne r1, r1, #1 << 11 @ always assume write
++ movne pc, lr
++ tst r3, #PSR_T_BIT @ Thumb?
++ ldrneh r3, [r2] @ read aborted thumb instruction
++ ldreq r3, [r2] @ read aborted ARM instruction
++ movne r3, r3, lsl #(21 - 12) @ move thumb bit 11 to ARM bit 20
++ tst r3, #1 << 20 @ L = 0 -> write
++ orreq r1, r1, #1 << 11 @ yes.
++ mov pc, lr
++
++
+Index: linux-2.6.0-test5/arch/arm/mm/abort-ev5t.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/abort-ev5t.S 2003-09-27 11:38:18.430726488 +0800
++++ linux-2.6.0-test5/arch/arm/mm/abort-ev5t.S 2003-09-27 11:38:18.785672528 +0800
+@@ -0,0 +1,31 @@
++#include <linux/linkage.h>
++#include <asm/assembler.h>
++/*
++ * Function: v5t_early_abort
++ *
++ * Params : r2 = address of aborted instruction
++ * : r3 = saved SPSR
++ *
++ * Returns : r0 = address of abort
++ * : r1 = FSR, bit 11 = write
++ * : r2-r8 = corrupted
++ * : r9 = preserved
++ * : sp = pointer to registers
++ *
++ * Purpose : obtain information about current aborted instruction.
++ * Note: we read user space. This means we might cause a data
++ * abort here if the I-TLB and D-TLB aren't seeing the same
++ * picture. Unfortunately, this does happen. We live with it.
++ */
++ .align 5
++ENTRY(v5t_early_abort)
++ mrc p15, 0, r1, c5, c0, 0 @ get FSR
++ mrc p15, 0, r0, c6, c0, 0 @ get FAR
++ tst r3, #PSR_T_BIT
++ ldrneh r3, [r2] @ read aborted thumb instruction
++ ldreq r3, [r2] @ read aborted ARM instruction
++ bic r1, r1, #1 << 11 @ clear bits 11 of FSR
++ movne r3, r3, lsl #(21 - 12) @ move thumb bit 11 to ARM bit 20
++ tst r3, #1 << 20 @ check write
++ orreq r1, r1, #1 << 11
++ mov pc, lr
+Index: linux-2.6.0-test5/arch/arm/mm/cache-v3.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/cache-v3.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/cache-v3.S 2003-09-27 11:38:18.786672376 +0800
+@@ -8,6 +8,7 @@
+ * published by the Free Software Foundation.
+ */
+ #include <linux/linkage.h>
++#include <linux/init.h>
+ #include <asm/hardware.h>
+ #include <asm/page.h>
+ #include "proc-macros.S"
+@@ -107,6 +108,9 @@
+ ENTRY(v3_dma_clean_range)
+ mov pc, lr
+
++ __INITDATA
++
++ .type v3_cache_fns, #object
+ ENTRY(v3_cache_fns)
+ .long v3_flush_kern_cache_all
+ .long v3_flush_user_cache_all
+@@ -116,3 +120,4 @@
+ .long v3_dma_inv_range
+ .long v3_dma_clean_range
+ .long v3_dma_flush_range
++ .size v3_cache_fns, . - v3_cache_fns
+Index: linux-2.6.0-test5/arch/arm/mm/cache-v4.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/cache-v4.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/cache-v4.S 2003-09-27 11:38:18.788672072 +0800
+@@ -8,6 +8,7 @@
+ * published by the Free Software Foundation.
+ */
+ #include <linux/linkage.h>
++#include <linux/init.h>
+ #include <asm/hardware.h>
+ #include <asm/page.h>
+ #include "proc-macros.S"
+@@ -109,6 +110,9 @@
+ ENTRY(v4_dma_clean_range)
+ mov pc, lr
+
++ __INITDATA
++
++ .type v4_cache_fns, #object
+ ENTRY(v4_cache_fns)
+ .long v4_flush_kern_cache_all
+ .long v4_flush_user_cache_all
+@@ -118,3 +122,4 @@
+ .long v4_dma_inv_range
+ .long v4_dma_clean_range
+ .long v4_dma_flush_range
++ .size v4_cache_fns, . - v4_cache_fns
+Index: linux-2.6.0-test5/arch/arm/mm/cache-v4wb.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/cache-v4wb.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/cache-v4wb.S 2003-09-27 11:38:18.790671768 +0800
+@@ -7,7 +7,9 @@
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
++#include <linux/config.h>
+ #include <linux/linkage.h>
++#include <linux/init.h>
+ #include <asm/hardware.h>
+ #include <asm/page.h>
+ #include "proc-macros.S"
+@@ -185,6 +187,9 @@
+ .globl v4wb_dma_flush_range
+ .set v4wb_dma_flush_range, v4wb_coherent_kern_range
+
++ __INITDATA
++
++ .type v4wb_cache_fns, #object
+ ENTRY(v4wb_cache_fns)
+ .long v4wb_flush_kern_cache_all
+ .long v4wb_flush_user_cache_all
+@@ -194,3 +199,4 @@
+ .long v4wb_dma_inv_range
+ .long v4wb_dma_clean_range
+ .long v4wb_dma_flush_range
++ .size v4wb_cache_fns, . - v4wb_cache_fns
+Index: linux-2.6.0-test5/arch/arm/mm/cache-v4wt.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/cache-v4wt.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/cache-v4wt.S 2003-09-27 11:38:18.792671464 +0800
+@@ -12,6 +12,7 @@
+ * We assume that the write buffer is not enabled.
+ */
+ #include <linux/linkage.h>
++#include <linux/init.h>
+ #include <asm/hardware.h>
+ #include <asm/page.h>
+ #include "proc-macros.S"
+@@ -158,6 +159,9 @@
+ .globl v4wt_dma_flush_range
+ .equ v4wt_dma_flush_range, v4wt_dma_inv_range
+
++ __INITDATA
++
++ .type v4wt_cache_fns, #object
+ ENTRY(v4wt_cache_fns)
+ .long v4wt_flush_kern_cache_all
+ .long v4wt_flush_user_cache_all
+@@ -167,4 +171,4 @@
+ .long v4wt_dma_inv_range
+ .long v4wt_dma_clean_range
+ .long v4wt_dma_flush_range
+-
++ .size v4wt_cache_fns, . - v4wt_cache_fns
+Index: linux-2.6.0-test5/arch/arm/mm/consistent.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/consistent.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/consistent.c 2003-09-27 11:38:18.795671008 +0800
+@@ -9,7 +9,6 @@
+ *
+ * DMA uncached mapping support.
+ */
+-#include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/mm.h>
+ #include <linux/slab.h>
+Index: linux-2.6.0-test5/arch/arm/mm/copypage-v3.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/copypage-v3.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/copypage-v3.S 2003-09-27 11:38:18.797670704 +0800
+@@ -58,8 +58,10 @@
+ bne 1b @ 1
+ ldr pc, [sp], #4
+
+- __INIT
++ __INITDATA
+
++ .type v3_user_fns, #object
+ ENTRY(v3_user_fns)
+ .long v3_clear_user_page
+ .long v3_copy_user_page
++ .size v3_user_fns, . - v3_user_fns
+Index: linux-2.6.0-test5/arch/arm/mm/copypage-v4mc.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/copypage-v4mc.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/copypage-v4mc.S 2003-09-27 11:38:18.798670552 +0800
+@@ -71,9 +71,10 @@
+ bne 1b @ 1
+ ldr pc, [sp], #4
+
+- __INIT
++ __INITDATA
+
++ .type v4_mc_user_fns, #object
+ ENTRY(v4_mc_user_fns)
+ .long v4_mc_clear_user_page
+ .long v4_mc_copy_user_page
+-
++ .size v4_mc_user_fns, . - v4_mc_user_fns
+Index: linux-2.6.0-test5/arch/arm/mm/copypage-v4wb.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/copypage-v4wb.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/copypage-v4wb.S 2003-09-27 11:38:18.799670400 +0800
+@@ -70,9 +70,10 @@
+ mcr p15, 0, r1, c7, c10, 4 @ 1 drain WB
+ ldr pc, [sp], #4
+
+- __INIT
++ __INITDATA
+
++ .type v4wb_user_fns, #object
+ ENTRY(v4wb_user_fns)
+ .long v4wb_clear_user_page
+ .long v4wb_copy_user_page
+-
++ .size v4wb_user_fns, . - v4wb_user_fns
+Index: linux-2.6.0-test5/arch/arm/mm/copypage-v4wt.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/copypage-v4wt.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/copypage-v4wt.S 2003-09-27 11:38:18.801670096 +0800
+@@ -64,9 +64,10 @@
+ mcr p15, 0, r2, c7, c7, 0 @ flush ID cache
+ ldr pc, [sp], #4
+
+- __INIT
++ __INITDATA
+
++ .type v4wt_user_fns, #object
+ ENTRY(v4wt_user_fns)
+ .long v4wt_clear_user_page
+ .long v4wt_copy_user_page
+-
++ .size v4wt_user_fns, . - v4wt_user_fns
+Index: linux-2.6.0-test5/arch/arm/mm/copypage-xscale.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/copypage-xscale.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/copypage-xscale.S 2003-09-27 11:38:18.802669944 +0800
+@@ -104,8 +104,10 @@
+ bne 1b
+ mov pc, lr
+
+- __INIT
++ __INITDATA
+
++ .type xscale_mc_user_fns, #object
+ ENTRY(xscale_mc_user_fns)
+ .long xscale_mc_clear_user_page
+ .long xscale_mc_copy_user_page
++ .size xscale_mc_user_fns, . - xscale_mc_user_fns
+Index: linux-2.6.0-test5/arch/arm/mm/discontig.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/discontig.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/discontig.c 2003-09-27 11:38:18.804669640 +0800
+@@ -15,7 +15,7 @@
+ #include <linux/init.h>
+ #include <linux/bootmem.h>
+
+-#if NR_NODES != 4
++#if MAX_NUMNODES != 4
+ #error Fix Me Please
+ #endif
+
+@@ -23,9 +23,9 @@
+ * Our node_data structure for discontiguous memory.
+ */
+
+-static bootmem_data_t node_bootmem_data[NR_NODES];
++static bootmem_data_t node_bootmem_data[MAX_NUMNODES];
+
+-pg_data_t discontig_node_data[NR_NODES] = {
++pg_data_t discontig_node_data[MAX_NUMNODES] = {
+ { .bdata = &node_bootmem_data[0] },
+ { .bdata = &node_bootmem_data[1] },
+ { .bdata = &node_bootmem_data[2] },
+Index: linux-2.6.0-test5/arch/arm/mm/fault-armv.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/fault-armv.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/fault-armv.c 2003-09-27 11:38:18.806669336 +0800
+@@ -14,9 +14,11 @@
+ #include <linux/ptrace.h>
+ #include <linux/mm.h>
+ #include <linux/bitops.h>
++#include <linux/vmalloc.h>
+ #include <linux/init.h>
+
+ #include <asm/cacheflush.h>
++#include <asm/io.h>
+ #include <asm/pgalloc.h>
+ #include <asm/pgtable.h>
+ #include <asm/tlbflush.h>
+@@ -127,6 +129,8 @@
+ do_translation_fault(addr, 0, regs);
+ }
+
++static unsigned long shared_pte_mask = L_PTE_CACHEABLE;
++
+ /*
+ * We take the easy way out of this problem - we make the
+ * PTE uncacheable. However, we leave the write buffer on.
+@@ -157,9 +161,9 @@
+ * If this page isn't present, or is already setup to
+ * fault (ie, is old), we can safely ignore any issues.
+ */
+- if (pte_present(entry) && pte_val(entry) & L_PTE_CACHEABLE) {
++ if (pte_present(entry) && pte_val(entry) & shared_pte_mask) {
+ flush_cache_page(vma, address);
+- pte_val(entry) &= ~L_PTE_CACHEABLE;
++ pte_val(entry) &= ~shared_pte_mask;
+ set_pte(pte, entry);
+ flush_tlb_page(vma, address);
+ ret = 1;
+@@ -297,3 +301,65 @@
+ make_coherent(vma, addr, page, dirty);
+ }
+ }
++
++/*
++ * Check whether the write buffer has physical address aliasing
++ * issues. If it has, we need to avoid them for the case where
++ * we have several shared mappings of the same object in user
++ * space.
++ */
++static int __init check_writebuffer(unsigned long *p1, unsigned long *p2)
++{
++ register unsigned long zero = 0, one = 1, val;
++
++ local_irq_disable();
++ mb();
++ *p1 = one;
++ mb();
++ *p2 = zero;
++ mb();
++ val = *p1;
++ mb();
++ local_irq_enable();
++ return val != zero;
++}
++
++void __init check_writebuffer_bugs(void)
++{
++ struct page *page;
++ const char *reason;
++ unsigned long v = 1;
++
++ printk(KERN_INFO "CPU: Testing write buffer coherency: ");
++
++ page = alloc_page(GFP_KERNEL);
++ if (page) {
++ unsigned long *p1, *p2;
++ pgprot_t prot = __pgprot(L_PTE_PRESENT|L_PTE_YOUNG|
++ L_PTE_DIRTY|L_PTE_WRITE|
++ L_PTE_BUFFERABLE);
++
++ p1 = vmap(&page, 1, VM_IOREMAP, prot);
++ p2 = vmap(&page, 1, VM_IOREMAP, prot);
++
++ if (p1 && p2) {
++ v = check_writebuffer(p1, p2);
++ reason = "enabling work-around";
++ } else {
++ reason = "unable to map memory\n";
++ }
++
++ vunmap(p1);
++ vunmap(p2);
++ put_page(page);
++ } else {
++ reason = "unable to grab page\n";
++ }
++
++ if (v) {
++ printk("failed, %s\n", reason);
++ shared_pte_mask |= L_PTE_BUFFERABLE;
++ } else {
++ printk("ok\n");
++ }
++}
+Index: linux-2.6.0-test5/arch/arm/mm/init.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/init.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/init.c 2003-09-27 11:38:18.811668576 +0800
+@@ -33,12 +33,6 @@
+ #include <asm/mach/arch.h>
+ #include <asm/mach/map.h>
+
+-#ifndef CONFIG_DISCONTIGMEM
+-#define NR_NODES 1
+-#else
+-#define NR_NODES 4
+-#endif
+-
+ #ifdef CONFIG_CPU_32
+ #define TABLE_OFFSET (PTRS_PER_PTE)
+ #else
+@@ -178,7 +172,7 @@
+ {
+ unsigned int i, bootmem_pages = 0, memend_pfn = 0;
+
+- for (i = 0; i < NR_NODES; i++) {
++ for (i = 0; i < MAX_NUMNODES; i++) {
+ np[i].start = -1U;
+ np[i].end = 0;
+ np[i].bootmap_pages = 0;
+@@ -207,7 +201,7 @@
+ * we have, we're in trouble. (maybe we ought to
+ * limit, instead of bugging?)
+ */
+- if (numnodes > NR_NODES)
++ if (numnodes > MAX_NUMNODES)
+ BUG();
+ }
+
+@@ -365,7 +359,7 @@
+ */
+ void __init bootmem_init(struct meminfo *mi)
+ {
+- struct node_info node_info[NR_NODES], *np = node_info;
++ struct node_info node_info[MAX_NUMNODES], *np = node_info;
+ unsigned int bootmap_pages, bootmap_pfn, map_pg;
+ int node, initrd_node;
+
+Index: linux-2.6.0-test5/arch/arm/mm/ioremap.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/ioremap.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/ioremap.c 2003-09-27 11:38:18.813668272 +0800
+@@ -150,7 +150,7 @@
+ if (!area)
+ return NULL;
+ addr = area->addr;
+- if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) {
++ if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
+ vfree(addr);
+ return NULL;
+ }
+Index: linux-2.6.0-test5/arch/arm/mm/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/Kconfig 2003-09-27 11:38:18.430726488 +0800
++++ linux-2.6.0-test5/arch/arm/mm/Kconfig 2003-09-27 11:38:18.814668120 +0800
+@@ -0,0 +1,344 @@
++comment "Processor Type"
++
++config CPU_32
++ bool
++ default y
++
++# Select CPU types depending on the architecture selected. This selects
++# which CPUs we support in the kernel image, and the compiler instruction
++# optimiser behaviour.
++
++# ARM610
++config CPU_ARM610
++ bool "Support ARM610 processor"
++ depends on ARCH_RPC
++ select CPU_32v3
++ select CPU_CACHE_V3
++ select CPU_COPY_V3
++ select CPU_TLB_V3
++ help
++ The ARM610 is the successor to the ARM3 processor
++ and was produced by VLSI Technology Inc.
++
++ Say Y if you want support for the ARM610 processor.
++ Otherwise, say N.
++
++# ARM710
++config CPU_ARM710
++ bool "Support ARM710 processor" if !ARCH_CLPS7500 && ARCH_RPC
++ default y if ARCH_CLPS7500
++ select CPU_32v3
++ select CPU_CACHE_V3
++ select CPU_COPY_V3
++ select CPU_TLB_V3
++ help
++ A 32-bit RISC microprocessor based on the ARM7 processor core
++ designed by Advanced RISC Machines Ltd. The ARM710 is the
++ successor to the ARM610 processor. It was released in
++ July 1994 by VLSI Technology Inc.
++
++ Say Y if you want support for the ARM710 processor.
++ Otherwise, say N.
++
++# ARM720T
++config CPU_ARM720T
++ bool "Support ARM720T processor" if !ARCH_CLPS711X && !ARCH_L7200 && !ARCH_CDB89712 && ARCH_INTEGRATOR
++ default y if ARCH_CLPS711X || ARCH_L7200 || ARCH_CDB89712
++ select CPU_32v4
++ select CPU_ABRT_LV4T
++ select CPU_CACHE_V4
++ select CPU_COPY_V4WT
++ select CPU_TLB_V4WT
++ help
++ A 32-bit RISC processor with 8kByte Cache, Write Buffer and
++ MMU built around an ARM7TDMI core.
++
++ Say Y if you want support for the ARM720T processor.
++ Otherwise, say N.
++
++# ARM920T
++config CPU_ARM920T
++ bool "Support ARM920T processor"
++ depends on ARCH_INTEGRATOR
++ select CPU_32v4
++ select CPU_ABRT_EV4T
++ select CPU_CACHE_V4WT
++ select CPU_COPY_V4WB
++ select CPU_TLB_V4WBI
++ help
++ The ARM920T is licensed to be produced by numerous vendors,
++ and is used in the Maverick EP9312. More information at
++ <http://linuxdevices.com/products/PD2382866068.html>.
++
++ Say Y if you want support for the ARM920T processor.
++ Otherwise, say N.
++
++# ARM922T
++config CPU_ARM922T
++ bool
++ depends on ARCH_CAMELOT
++ default y
++ select CPU_32v4
++ select CPU_ABRT_EV4T
++ select CPU_CACHE_V4WT
++ select CPU_COPY_V4WB
++ select CPU_TLB_V4WBI
++ help
++ The ARM922T is a version of the ARM920T, but with smaller
++ instruction and data caches. It is used in Altera's
++ Excalibur XA device family.
++
++ Say Y if you want support for the ARM922T processor.
++ Otherwise, say N.
++
++# ARM926T
++config CPU_ARM926T
++ bool "Support ARM926T processor"
++ depends on ARCH_INTEGRATOR
++ select CPU_32v5
++ select CPU_ABRT_EV5TJ
++ select CPU_COPY_V4WB
++ select CPU_TLB_V4WBI
++ help
++ This is a variant of the ARM920. It has slightly different
++ instruction sequences for cache and TLB operations. Curiously,
++ there is no documentation on it at the ARM corporate website.
++
++ Say Y if you want support for the ARM926T processor.
++ Otherwise, say N.
++
++# ARM1020 - needs validating
++config CPU_ARM1020
++ bool "Support ARM1020T (rev 0) processor"
++ depends on ARCH_INTEGRATOR
++ select CPU_32v5
++ select CPU_ABRT_EV4T
++ select CPU_CACHE_V4WT
++ select CPU_COPY_V4WB
++ select CPU_TLB_V4WBI
++ help
++ The ARM1020 is the 32K cached version of the ARM10 processor,
++ with an addition of a floating-point unit.
++
++ Say Y if you want support for the ARM1020 processor.
++ Otherwise, say N.
++
++# ARM1020E - needs validating
++config CPU_ARM1020E
++ bool "Support ARM1020E processor"
++ depends on ARCH_INTEGRATOR
++ select CPU_32v5
++ select CPU_ABRT_EV4T
++ select CPU_CACHE_V4WT
++ select CPU_COPY_V4WB
++ select CPU_TLB_V4WBI
++ depends on n
++
++# ARM1022E
++config CPU_ARM1022
++ bool "Support ARM1022E processor"
++ depends on ARCH_INTEGRATOR
++ select CPU_32v5
++ select CPU_ABRT_EV4T
++ select CPU_COPY_V4WB # can probably do better
++ select CPU_TLB_V4WBI
++ help
++ The ARM1022E is an implementation of the ARMv5TE architecture
++ based upon the ARM10 integer core with a 16KiB L1 Harvard cache,
++ embedded trace macrocell, and a floating-point unit.
++
++ Say Y if you want support for the ARM1022E processor.
++ Otherwise, say N.
++
++# ARM1026EJ-S
++config CPU_ARM1026
++ bool "Support ARM1026EJ-S processor"
++ depends on ARCH_INTEGRATOR
++ select CPU_32v5
++ select CPU_ABRT_EV5T # But need Jazelle, but EV5TJ ignores bit 10
++ select CPU_COPY_V4WB # can probably do better
++ select CPU_TLB_V4WBI
++ help
++ The ARM1026EJ-S is an implementation of the ARMv5TEJ architecture
++ based upon the ARM10 integer core.
++
++ Say Y if you want support for the ARM1026EJ-S processor.
++ Otherwise, say N.
++
++# SA110
++config CPU_SA110
++ bool "Support StrongARM(R) SA-110 processor" if !ARCH_EBSA110 && !FOOTBRIDGE && !ARCH_TBOX && !ARCH_SHARK && !ARCH_NEXUSPCI && !ARCH_ANAKIN && ARCH_RPC
++ default y if ARCH_EBSA110 || FOOTBRIDGE || ARCH_TBOX || ARCH_SHARK || ARCH_NEXUSPCI || ARCH_ANAKIN
++ select CPU_32v3 if ARCH_RPC
++ select CPU_32v4 if !ARCH_RPC
++ select CPU_ABRT_EV4
++ select CPU_CACHE_V4WB
++ select CPU_COPY_V4WB
++ select CPU_TLB_V4WB
++ help
++ The Intel StrongARM(R) SA-110 is a 32-bit microprocessor and
++ is available at five speeds ranging from 100 MHz to 233 MHz.
++ More information is available at
++ <http://developer.intel.com/design/strong/sa110.htm>.
++
++ Say Y if you want support for the SA-110 processor.
++ Otherwise, say N.
++
++# SA1100
++config CPU_SA1100
++ bool
++ depends on ARCH_SA1100
++ default y
++ select CPU_32v4
++ select CPU_ABRT_EV4
++ select CPU_CACHE_V4WB
++ select CPU_TLB_V4WB
++ select CPU_MINICACHE
++
++# XScale
++config CPU_XSCALE
++ bool
++ depends on ARCH_IOP3XX || ARCH_ADIFCC || ARCH_PXA
++ default y
++ select CPU_32v5
++ select CPU_ABRT_EV5T
++ select CPU_TLB_V4WBI
++ select CPU_MINICACHE
++
++# This defines the compiler instruction set which depends on the machine type.
++config CPU_32v3
++ bool
++
++config CPU_32v4
++ bool
++
++config CPU_32v5
++ bool
++
++# The abort model
++config CPU_ABRT_EV4
++ bool
++
++config CPU_ABRT_EV4T
++ bool
++
++config CPU_ABRT_LV4T
++ bool
++
++config CPU_ABRT_EV5T
++ bool
++
++config CPU_ABRT_EV5TJ
++ bool
++
++# The cache model
++config CPU_CACHE_V3
++ bool
++
++config CPU_CACHE_V4
++ bool
++
++config CPU_CACHE_V4WT
++ bool
++
++config CPU_CACHE_V4WB
++ bool
++
++# The copy-page model
++config CPU_COPY_V3
++ bool
++
++config CPU_COPY_V4WT
++ bool
++
++config CPU_COPY_V4WB
++ bool
++
++# This selects the TLB model
++config CPU_TLB_V3
++ bool
++ help
++ ARM Architecture Version 3 TLB.
++
++config CPU_TLB_V4WT
++ bool
++ help
++ ARM Architecture Version 4 TLB with writethrough cache.
++
++config CPU_TLB_V4WB
++ bool
++ help
++ ARM Architecture Version 4 TLB with writeback cache.
++
++config CPU_TLB_V4WBI
++ bool
++ help
++ ARM Architecture Version 4 TLB with writeback cache and invalidate
++ instruction cache entry.
++
++config CPU_TLB_V6
++ bool
++
++config CPU_MINICACHE
++ bool
++ help
++ Processor has a minicache.
++
++comment "Processor Features"
++
++config ARM_THUMB
++ bool "Support Thumb user binaries"
++ depends on CPU_ARM720T || CPU_ARM920T || CPU_ARM922T || CPU_ARM926T || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE
++ default y
++ help
++ Say Y if you want to have kernel support for ARM Thumb instructions,
++ fault handlers, and system calls.
++
++ The Thumb instruction set is a compressed form of the standard ARM
++ instruction set resulting in smaller binaries at the expense of
++ slightly less efficient code.
++
++ If you don't know what this all is, saying Y is a safe choice.
++
++config CPU_BIG_ENDIAN
++ bool "Build big-endian kernel"
++ depends on ARCH_SUPPORTS_BIG_ENDIAN
++ help
++ Say Y if you plan on running a kernel in big-endian mode.
++ Note that your board must be properly built and your board
++ port must properly enable and big-endian related features
++ of your chipset/board/processor.
++
++config CPU_ICACHE_DISABLE
++ bool "Disable I-Cache"
++ depends on CPU_ARM920T || CPU_ARM922T || CPU_ARM926T || CPU_ARM1020
++ help
++ Say Y here to disable the processor instruction cache. Unless
++ you have a reason not to or are unsure, say N.
++
++config CPU_DCACHE_DISABLE
++ bool "Disable D-Cache"
++ depends on CPU_ARM920T || CPU_ARM922T || CPU_ARM926T || CPU_ARM1020
++ help
++ Say Y here to disable the processor data cache. Unless
++ you have a reason not to or are unsure, say N.
++
++config CPU_DCACHE_WRITETHROUGH
++ bool "Force write through D-cache"
++ depends on (CPU_ARM920T || CPU_ARM922T || CPU_ARM926T || CPU_ARM1020) && !CPU_DISABLE_DCACHE
++ help
++ Say Y here to use the data cache in writethough mode. Unless you
++ specifically require this or are unsure, say N.
++
++config CPU_CACHE_ROUND_ROBIN
++ bool "Round robin I and D cache replacement algorithm"
++ depends on (CPU_ARM926T || CPU_ARM1020) && (!CPU_ICACHE_DISABLE || !CPU_DCACHE_DISABLE)
++ help
++ Say Y here to use the predictable round-robin cache replacement
++ policy. Unless you specifically require this or are unsure, say N.
++
++config CPU_BPREDICT_DISABLE
++ bool "Disable branch prediction"
++ depends on CPU_ARM1020
++ help
++ Say Y here to disable branch prediction. If unsure, say N.
+Index: linux-2.6.0-test5/arch/arm/mm/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/Makefile 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/Makefile 2003-09-27 11:38:18.816667816 +0800
+@@ -2,29 +2,48 @@
+ # Makefile for the linux arm-specific parts of the memory manager.
+ #
+
+-# Object file lists.
++obj-y := consistent.o extable.o fault-armv.o \
++ fault-common.o init.o ioremap.o mm-armv.o
+
+-obj-y := consistent.o extable.o fault-armv.o fault-common.o \
+- init.o ioremap.o mm-armv.o
+-obj-$(CONFIG_MODULES) += proc-syms.o
+-
+-obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o
+-obj-$(CONFIG_DISCONTIGMEM) += discontig.o
+-
+-# ARMv3
+-p-$(CONFIG_CPU_ARM610) += proc-arm6_7.o tlb-v3.o cache-v3.o copypage-v3.o
+-p-$(CONFIG_CPU_ARM710) += proc-arm6_7.o tlb-v3.o cache-v3.o copypage-v3.o
+-
+-# ARMv4
+-p-$(CONFIG_CPU_ARM720T) += proc-arm720.o tlb-v4.o cache-v4.o copypage-v4wt.o abort-lv4t.o
+-p-$(CONFIG_CPU_ARM920T) += proc-arm920.o tlb-v4wbi.o cache-v4wt.o copypage-v4wb.o abort-ev4t.o
+-p-$(CONFIG_CPU_ARM922T) += proc-arm922.o tlb-v4wbi.o cache-v4wt.o copypage-v4wb.o abort-ev4t.o
+-p-$(CONFIG_CPU_ARM1020) += proc-arm1020.o tlb-v4wbi.o cache-v4wt.o copypage-v4wb.o abort-ev4t.o
+-p-$(CONFIG_CPU_SA110) += proc-sa110.o tlb-v4wb.o cache-v4wb.o copypage-v4wb.o abort-ev4.o
+-p-$(CONFIG_CPU_SA1100) += proc-sa1100.o tlb-v4wb.o cache-v4wb.o copypage-v4mc.o abort-ev4.o minicache.o
+-
+-# ARMv5
+-p-$(CONFIG_CPU_ARM926T) += proc-arm926.o tlb-v4wbi.o copypage-v4wb.o abort-ev5tej.o
+-p-$(CONFIG_CPU_XSCALE) += proc-xscale.o tlb-v4wbi.o copypage-xscale.o abort-xscale.o minicache.o
++obj-$(CONFIG_MODULES) += proc-syms.o
+
+-obj-y += $(sort $(p-y))
++obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o
++obj-$(CONFIG_DISCONTIGMEM) += discontig.o
++
++obj-$(CONFIG_CPU_ABRT_EV4) += abort-ev4.o
++obj-$(CONFIG_CPU_ABRT_EV4T) += abort-ev4t.o
++obj-$(CONFIG_CPU_ABRT_LV4T) += abort-lv4t.o
++obj-$(CONFIG_CPU_ABRT_EV5T) += abort-ev5t.o
++obj-$(CONFIG_CPU_ABRT_EV5TJ) += abort-ev5tj.o
++
++obj-$(CONFIG_CPU_CACHE_V3) += cache-v3.o
++obj-$(CONFIG_CPU_CACHE_V4) += cache-v4.o
++obj-$(CONFIG_CPU_CACHE_V4WT) += cache-v4wt.o
++obj-$(CONFIG_CPU_CACHE_V4WB) += cache-v4wb.o
++
++obj-$(CONFIG_CPU_COPY_V3) += copypage-v3.o
++obj-$(CONFIG_CPU_COPY_V4WT) += copypage-v4wt.o
++obj-$(CONFIG_CPU_COPY_V4WB) += copypage-v4wb.o
++obj-$(CONFIG_CPU_SA1100) += copypage-v4mc.o
++obj-$(CONFIG_CPU_XSCALE) += copypage-xscale.o
++
++obj-$(CONFIG_CPU_MINICACHE) += minicache.o
++
++obj-$(CONFIG_CPU_TLB_V3) += tlb-v3.o
++obj-$(CONFIG_CPU_TLB_V4WT) += tlb-v4.o
++obj-$(CONFIG_CPU_TLB_V4WB) += tlb-v4wb.o
++obj-$(CONFIG_CPU_TLB_V4WBI) += tlb-v4wbi.o
++
++obj-$(CONFIG_CPU_ARM610) += proc-arm6_7.o
++obj-$(CONFIG_CPU_ARM710) += proc-arm6_7.o
++obj-$(CONFIG_CPU_ARM720T) += proc-arm720.o
++obj-$(CONFIG_CPU_ARM920T) += proc-arm920.o
++obj-$(CONFIG_CPU_ARM922T) += proc-arm922.o
++obj-$(CONFIG_CPU_ARM926T) += proc-arm926.o
++obj-$(CONFIG_CPU_ARM1020) += proc-arm1020.o
++obj-$(CONFIG_CPU_ARM1020E) += proc-arm1020e.o
++obj-$(CONFIG_CPU_ARM1022) += proc-arm1022.o
++obj-$(CONFIG_CPU_ARM1026) += proc-arm1026.o
++obj-$(CONFIG_CPU_SA110) += proc-sa110.o
++obj-$(CONFIG_CPU_SA1100) += proc-sa1100.o
++obj-$(CONFIG_CPU_XSCALE) += proc-xscale.o
+Index: linux-2.6.0-test5/arch/arm/mm/mm-armv.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/mm-armv.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/mm-armv.c 2003-09-27 11:38:18.820667208 +0800
+@@ -9,6 +9,7 @@
+ *
+ * Page table sludge for ARM v3 and v4 processor architectures.
+ */
++#include <linux/config.h>
+ #include <linux/mm.h>
+ #include <linux/init.h>
+ #include <linux/bootmem.h>
+@@ -392,12 +393,19 @@
+ long off;
+
+ if (md->virtual != vectors_base() && md->virtual < PAGE_OFFSET) {
+- printk(KERN_WARNING "MM: not creating mapping for "
++ printk(KERN_WARNING "BUG: not creating mapping for "
+ "0x%08lx at 0x%08lx in user region\n",
+ md->physical, md->virtual);
+ return;
+ }
+
++ if (md->type == MT_DEVICE &&
++ md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) {
++ printk(KERN_WARNING "BUG: mapping for 0x%08lx at 0x%08lx "
++ "overlaps vmalloc space\n",
++ md->physical, md->virtual);
++ }
++
+ domain = mem_types[md->type].domain;
+ prot_pte = __pgprot(mem_types[md->type].prot_pte);
+ prot_l1 = mem_types[md->type].prot_l1 | PMD_DOMAIN(domain);
+@@ -409,7 +417,7 @@
+
+ if (mem_types[md->type].prot_l1 == 0 &&
+ (virt & 0xfffff || (virt + off) & 0xfffff || (virt + length) & 0xfffff)) {
+- printk(KERN_WARNING "MM: map for 0x%08lx at 0x%08lx can not "
++ printk(KERN_WARNING "BUG: map for 0x%08lx at 0x%08lx can not "
+ "be mapped using pages, ignoring.\n",
+ md->physical, md->virtual);
+ return;
+Index: linux-2.6.0-test5/arch/arm/mm/proc-arm1020e.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/proc-arm1020e.S 2003-09-27 11:38:18.430726488 +0800
++++ linux-2.6.0-test5/arch/arm/mm/proc-arm1020e.S 2003-09-27 11:38:18.821667056 +0800
+@@ -0,0 +1,504 @@
++/*
++ * linux/arch/arm/mm/proc-arm1020e.S: MMU functions for ARM1020
++ *
++ * Copyright (C) 2000 ARM Limited
++ * Copyright (C) 2000 Deep Blue Solutions Ltd.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ *
++ * These are the low level assembler for performing cache and TLB
++ * functions on the arm1020e.
++ *
++ * CONFIG_CPU_ARM1020_CPU_IDLE -> nohlt
++ */
++#include <linux/linkage.h>
++#include <linux/config.h>
++#include <linux/init.h>
++#include <asm/assembler.h>
++#include <asm/constants.h>
++#include <asm/pgtable.h>
++#include <asm/procinfo.h>
++#include <asm/ptrace.h>
++#include <asm/hardware.h>
++
++/*
++ * This is the maximum size of an area which will be invalidated
++ * using the single invalidate entry instructions. Anything larger
++ * than this, and we go for the whole cache.
++ *
++ * This value should be chosen such that we choose the cheapest
++ * alternative.
++ */
++#define MAX_AREA_SIZE 32768
++
++/*
++ * The size of one data cache line.
++ */
++#define CACHE_DLINESIZE 32
++
++/*
++ * The number of data cache segments.
++ */
++#define CACHE_DSEGMENTS 16
++
++/*
++ * The number of lines in a cache segment.
++ */
++#define CACHE_DENTRIES 64
++
++/*
++ * This is the size at which it becomes more efficient to
++ * clean the whole cache, rather than using the individual
++ * cache line maintainence instructions.
++ */
++#define CACHE_DLIMIT 32768
++
++ .text
++/*
++ * cpu_arm1020e_proc_init()
++ */
++ENTRY(cpu_arm1020e_proc_init)
++ mov pc, lr
++
++/*
++ * cpu_arm1020e_proc_fin()
++ */
++ENTRY(cpu_arm1020e_proc_fin)
++ stmfd sp!, {lr}
++ mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
++ msr cpsr_c, ip
++ bl arm1020e_flush_kern_cache_all
++ mrc p15, 0, r0, c1, c0, 0 @ ctrl register
++ bic r0, r0, #0x1000 @ ...i............
++ bic r0, r0, #0x000e @ ............wca.
++ mcr p15, 0, r0, c1, c0, 0 @ disable caches
++ ldmfd sp!, {pc}
++
++/*
++ * cpu_arm1020e_reset(loc)
++ *
++ * Perform a soft reset of the system. Put the CPU into the
++ * same state as it would be if it had been reset, and branch
++ * to what would be the reset vector.
++ *
++ * loc: location to jump to for soft reset
++ */
++ .align 5
++ENTRY(cpu_arm1020e_reset)
++ mov ip, #0
++ mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
++ mcr p15, 0, ip, c7, c10, 4 @ drain WB
++ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
++ mrc p15, 0, ip, c1, c0, 0 @ ctrl register
++ bic ip, ip, #0x000f @ ............wcam
++ bic ip, ip, #0x1100 @ ...i...s........
++ mcr p15, 0, ip, c1, c0, 0 @ ctrl register
++ mov pc, r0
++
++/*
++ * cpu_arm1020e_do_idle()
++ */
++ .align 5
++ENTRY(cpu_arm1020e_do_idle)
++ mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
++ mov pc, lr
++
++/* ================================= CACHE ================================ */
++
++ .align 5
++/*
++ * flush_user_cache_all()
++ *
++ * Invalidate all cache entries in a particular address
++ * space.
++ */
++ENTRY(arm1020e_flush_user_cache_all)
++ /* FALLTHROUGH */
++/*
++ * flush_kern_cache_all()
++ *
++ * Clean and invalidate the entire cache.
++ */
++ENTRY(arm1020e_flush_kern_cache_all)
++ mov r2, #VM_EXEC
++ mov ip, #0
++__flush_whole_cache:
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ mcr p15, 0, ip, c7, c10, 4 @ drain WB
++ mov r1, #(CACHE_DSEGMENTS - 1) << 5 @ 16 segments
++1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries
++2: mcr p15, 0, r3, c7, c14, 2 @ clean+invalidate D index
++ subs r3, r3, #1 << 26
++ bcs 2b @ entries 63 to 0
++ subs r1, r1, #1 << 5
++ bcs 1b @ segments 15 to 0
++#endif
++ tst r2, #VM_EXEC
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++ mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
++#endif
++ mcrne p15, 0, ip, c7, c10, 4 @ drain WB
++ mov pc, lr
++
++/*
++ * flush_user_cache_range(start, end, flags)
++ *
++ * Invalidate a range of cache entries in the specified
++ * address space.
++ *
++ * - start - start address (inclusive)
++ * - end - end address (exclusive)
++ * - flags - vm_flags for this space
++ */
++ENTRY(arm1020e_flush_user_cache_range)
++ mov ip, #0
++ sub r3, r1, r0 @ calculate total size
++ cmp r3, #CACHE_DLIMIT
++ bhs __flush_whole_cache
++
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
++ add r0, r0, #CACHE_DLINESIZE
++ cmp r0, r1
++ blo 1b
++#endif
++ tst r2, #VM_EXEC
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++ mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
++#endif
++ mcrne p15, 0, ip, c7, c10, 4 @ drain WB
++ mov pc, lr
++
++/*
++ * coherent_kern_range(start, end)
++ *
++ * Ensure coherency between the Icache and the Dcache in the
++ * region described by start. If you have non-snooping
++ * Harvard caches, you need to implement this function.
++ *
++ * - start - virtual start address
++ * - end - virtual end address
++ */
++ENTRY(arm1020e_coherent_kern_range)
++ mov ip, #0
++ bic r0, r0, #CACHE_DLINESIZE - 1
++1:
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
++#endif
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++ mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
++#endif
++ add r0, r0, #CACHE_DLINESIZE
++ cmp r0, r1
++ blo 1b
++ mcr p15, 0, ip, c7, c10, 4 @ drain WB
++ mov pc, lr
++
++/*
++ * flush_kern_dcache_page(void *page)
++ *
++ * Ensure no D cache aliasing occurs, either with itself or
++ * the I cache
++ *
++ * - page - page aligned address
++ */
++ENTRY(arm1020e_flush_kern_dcache_page)
++ mov ip, #0
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ add r1, r0, #PAGE_SZ
++1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
++ add r0, r0, #CACHE_DLINESIZE
++ cmp r0, r1
++ blo 1b
++#endif
++ mcr p15, 0, ip, c7, c10, 4 @ drain WB
++ mov pc, lr
++
++/*
++ * dma_inv_range(start, end)
++ *
++ * Invalidate (discard) the specified virtual address range.
++ * May not write back any entries. If 'start' or 'end'
++ * are not cache line aligned, those lines must be written
++ * back.
++ *
++ * - start - virtual start address
++ * - end - virtual end address
++ *
++ * (same as v4wb)
++ */
++ENTRY(arm1020e_dma_inv_range)
++ mov ip, #0
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ tst r0, #CACHE_DLINESIZE - 1
++ bic r0, r0, #CACHE_DLINESIZE - 1
++ mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
++ tst r1, #CACHE_DLINESIZE - 1
++ mcrne p15, 0, r1, c7, c10, 1 @ clean D entry
++1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
++ add r0, r0, #CACHE_DLINESIZE
++ cmp r0, r1
++ blo 1b
++#endif
++ mcr p15, 0, ip, c7, c10, 4 @ drain WB
++ mov pc, lr
++
++/*
++ * dma_clean_range(start, end)
++ *
++ * Clean the specified virtual address range.
++ *
++ * - start - virtual start address
++ * - end - virtual end address
++ *
++ * (same as v4wb)
++ */
++ENTRY(arm1020e_dma_clean_range)
++ mov ip, #0
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ bic r0, r0, #CACHE_DLINESIZE - 1
++1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
++ add r0, r0, #CACHE_DLINESIZE
++ cmp r0, r1
++ blo 1b
++#endif
++ mcr p15, 0, ip, c7, c10, 4 @ drain WB
++ mov pc, lr
++
++/*
++ * dma_flush_range(start, end)
++ *
++ * Clean and invalidate the specified virtual address range.
++ *
++ * - start - virtual start address
++ * - end - virtual end address
++ */
++ENTRY(arm1020e_dma_flush_range)
++ mov ip, #0
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ bic r0, r0, #CACHE_DLINESIZE - 1
++1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
++ add r0, r0, #CACHE_DLINESIZE
++ cmp r0, r1
++ blo 1b
++#endif
++ mcr p15, 0, ip, c7, c10, 4 @ drain WB
++ mov pc, lr
++
++ENTRY(arm1020e_cache_fns)
++ .long arm1020e_flush_kern_cache_all
++ .long arm1020e_flush_user_cache_all
++ .long arm1020e_flush_user_cache_range
++ .long arm1020e_coherent_kern_range
++ .long arm1020e_flush_kern_dcache_page
++ .long arm1020e_dma_inv_range
++ .long arm1020e_dma_clean_range
++ .long arm1020e_dma_flush_range
++
++ .align 5
++ENTRY(cpu_arm1020e_dcache_clean_area)
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ mov ip, #0
++1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
++ add r0, r0, #CACHE_DLINESIZE
++ subs r1, r1, #CACHE_DLINESIZE
++ bhi 1b
++#endif
++ mov pc, lr
++
++/* =============================== PageTable ============================== */
++
++/*
++ * cpu_arm1020e_switch_mm(pgd)
++ *
++ * Set the translation base pointer to be as described by pgd.
++ *
++ * pgd: new page tables
++ */
++ .align 5
++ENTRY(cpu_arm1020e_switch_mm)
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ mcr p15, 0, r3, c7, c10, 4
++ mov r1, #0xF @ 16 segments
++1: mov r3, #0x3F @ 64 entries
++2: mov ip, r3, LSL #26 @ shift up entry
++ orr ip, ip, r1, LSL #5 @ shift in/up index
++ mcr p15, 0, ip, c7, c14, 2 @ Clean & Inval DCache entry
++ mov ip, #0
++ subs r3, r3, #1
++ cmp r3, #0
++ bge 2b @ entries 3F to 0
++ subs r1, r1, #1
++ cmp r1, #0
++ bge 1b @ segments 15 to 0
++
++#endif
++ mov r1, #0
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++ mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache
++#endif
++ mcr p15, 0, r1, c7, c10, 4 @ drain WB
++ mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
++ mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs
++ mov pc, lr
++
++/*
++ * cpu_arm1020e_set_pte(ptep, pte)
++ *
++ * Set a PTE and flush it out
++ */
++ .align 5
++ENTRY(cpu_arm1020e_set_pte)
++ str r1, [r0], #-2048 @ linux version
++
++ eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
++
++ bic r2, r1, #PTE_SMALL_AP_MASK
++ bic r2, r2, #PTE_TYPE_MASK
++ orr r2, r2, #PTE_TYPE_SMALL
++
++ tst r1, #L_PTE_USER @ User?
++ orrne r2, r2, #PTE_SMALL_AP_URO_SRW
++
++ tst r1, #L_PTE_WRITE | L_PTE_DIRTY @ Write and Dirty?
++ orreq r2, r2, #PTE_SMALL_AP_UNO_SRW
++
++ tst r1, #L_PTE_PRESENT | L_PTE_YOUNG @ Present and Young?
++ movne r2, #0
++
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++ eor r3, r1, #0x0a @ C & small page?
++ tst r3, #0x0b
++ biceq r2, r2, #4
++#endif
++ str r2, [r0] @ hardware version
++ mov r0, r0
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
++#endif
++ mov pc, lr
++
++ __INIT
++
++ .type __arm1020e_setup, #function
++__arm1020e_setup:
++ mov r0, #0
++ mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4
++ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4
++ mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4
++ mcr p15, 0, r4, c2, c0 @ load page table pointer
++ mov r0, #0x1f @ Domains 0, 1 = client
++ mcr p15, 0, r0, c3, c0 @ load domain access register
++ mrc p15, 0, r0, c1, c0 @ get control register v4
++/*
++ * Clear out 'unwanted' bits (then put them in if we need them)
++ */
++ bic r0, r0, #0x1e00 @ i...??r.........
++ bic r0, r0, #0x000e @ ............wca.
++/*
++ * Turn on what we want
++ */
++ orr r0, r0, #0x0031 @ ..........DP...M
++ orr r0, r0, #0x0100 @ .......S........
++
++#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
++ orr r0, r0, #0x4000 @ .R..............
++#endif
++#ifndef CONFIG_CPU_BPREDICT_DISABLE
++ orr r0, r0, #0x0800 @ ....Z...........
++#endif
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ orr r0, r0, #0x0004 @ Enable D cache
++#endif
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++ orr r0, r0, #0x1000 @ I Cache on
++#endif
++ mov pc, lr
++ .size __arm1020e_setup, . - __arm1020e_setup
++
++ __INITDATA
++
++/*
++ * Purpose : Function pointers used to access above functions - all calls
++ * come through these
++ */
++ .type arm1020e_processor_functions, #object
++arm1020e_processor_functions:
++ .word v4t_early_abort
++ .word cpu_arm1020e_proc_init
++ .word cpu_arm1020e_proc_fin
++ .word cpu_arm1020e_reset
++ .word cpu_arm1020e_do_idle
++ .word cpu_arm1020e_dcache_clean_area
++ .word cpu_arm1020e_switch_mm
++ .word cpu_arm1020e_set_pte
++ .size arm1020e_processor_functions, . - arm1020e_processor_functions
++
++ .section ".rodata"
++
++ .type cpu_arch_name, #object
++cpu_arch_name:
++ .asciz "armv5te"
++ .size cpu_arch_name, . - cpu_arch_name
++
++ .type cpu_elf_name, #object
++cpu_elf_name:
++ .asciz "v5"
++ .size cpu_elf_name, . - cpu_elf_name
++
++ .type cpu_arm1020e_name, #object
++cpu_arm1020e_name:
++ .ascii "ARM1020E"
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++ .ascii "i"
++#endif
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ .ascii "d"
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++ .ascii "(wt)"
++#else
++ .ascii "(wb)"
++#endif
++#endif
++#ifndef CONFIG_CPU_BPREDICT_DISABLE
++ .ascii "B"
++#endif
++#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
++ .ascii "RR"
++#endif
++ .ascii "\0"
++ .size cpu_arm1020e_name, . - cpu_arm1020e_name
++
++ .align
++
++ .section ".proc.info", #alloc, #execinstr
++
++ .type __arm1020e_proc_info,#object
++__arm1020e_proc_info:
++ .long 0x4105a200 @ ARM 1020TE (Architecture v5TE)
++ .long 0xff0ffff0
++ .long 0x00000c12 @ mmuflags
++ b __arm1020e_setup
++ .long cpu_arch_name
++ .long cpu_elf_name
++ .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
++ .long cpu_arm1020e_name
++ .long arm1020e_processor_functions
++ .long v4wbi_tlb_fns
++ .long v4wb_user_fns
++ .long arm1020e_cache_fns
++ .size __arm1020e_proc_info, . - __arm1020e_proc_info
+Index: linux-2.6.0-test5/arch/arm/mm/proc-arm1020.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/proc-arm1020.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/proc-arm1020.S 2003-09-27 11:38:18.826666296 +0800
+@@ -1,5 +1,5 @@
+ /*
+- * linux/arch/arm/mm/arm1020.S: MMU functions for ARM1020
++ * linux/arch/arm/mm/proc-arm1020.S: MMU functions for ARM1020
+ *
+ * Copyright (C) 2000 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd.
+@@ -29,6 +29,7 @@
+ #include <linux/init.h>
+ #include <asm/assembler.h>
+ #include <asm/constants.h>
++#include <asm/pgtable.h>
+ #include <asm/procinfo.h>
+ #include <asm/ptrace.h>
+ #include <asm/hardware.h>
+@@ -379,19 +380,19 @@
+ ENTRY(cpu_arm1020_set_pte)
+ str r1, [r0], #-2048 @ linux version
+
+- eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
++ eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
+
+- bic r2, r1, #0xff0
+- bic r2, r2, #3
+- orr r2, r2, #HPTE_TYPE_SMALL
++ bic r2, r1, #PTE_SMALL_AP_MASK
++ bic r2, r2, #PTE_TYPE_MASK
++ orr r2, r2, #PTE_TYPE_SMALL
+
+- tst r1, #LPTE_USER @ User?
+- orrne r2, r2, #HPTE_AP_READ
++ tst r1, #L_PTE_USER @ User?
++ orrne r2, r2, #PTE_SMALL_AP_URO_SRW
+
+- tst r1, #LPTE_WRITE | LPTE_DIRTY @ Write and Dirty?
+- orreq r2, r2, #HPTE_AP_WRITE
++ tst r1, #L_PTE_WRITE | L_PTE_DIRTY @ Write and Dirty?
++ orreq r2, r2, #PTE_SMALL_AP_UNO_SRW
+
+- tst r1, #LPTE_PRESENT | LPTE_YOUNG @ Present and Young?
++ tst r1, #L_PTE_PRESENT | L_PTE_YOUNG @ Present and Young?
+ movne r2, #0
+
+ #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+@@ -408,31 +409,9 @@
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+-
+-ENTRY(cpu_arm1020_name)
+- .ascii "Arm1020"
+-#ifndef CONFIG_CPU_ICACHE_DISABLE
+- .ascii "i"
+-#endif
+-#ifndef CONFIG_CPU_DCACHE_DISABLE
+- .ascii "d"
+-#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+- .ascii "(wt)"
+-#else
+- .ascii "(wb)"
+-#endif
+-#endif
+-#ifndef CONFIG_CPU_BPREDICT_DISABLE
+- .ascii "B"
+-#endif
+-#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
+- .ascii "RR"
+-#endif
+- .ascii "\0"
+- .align
+-
+ __INIT
+
++ .type __arm1020_setup, #function
+ __arm1020_setup:
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4
+@@ -445,10 +424,8 @@
+ /*
+ * Clear out 'unwanted' bits (then put them in if we need them)
+ */
+- bic r0, r0, #0x0e00 @ ....??r.........
+- bic r0, r0, #0x0002 @ ..............a.
+- bic r0, r0, #0x000c @ W,D
+- bic r0, r0, #0x1000 @ I
++ bic r0, r0, #0x1e00 @ i...??r.........
++ bic r0, r0, #0x000e @ ............wca.
+ /*
+ * Turn on what we want
+ */
+@@ -468,8 +445,9 @@
+ orr r0, r0, #0x1000 @ I Cache on
+ #endif
+ mov pc, lr
++ .size __arm1020_setup, . - __arm1020_setup
+
+- .text
++ __INITDATA
+
+ /*
+ * Purpose : Function pointers used to access above functions - all calls
+@@ -485,26 +463,51 @@
+ .word cpu_arm1020_dcache_clean_area
+ .word cpu_arm1020_switch_mm
+ .word cpu_arm1020_set_pte
+-
+ .size arm1020_processor_functions, . - arm1020_processor_functions
+
++ .section ".rodata"
++
+ .type cpu_arch_name, #object
+ cpu_arch_name:
+- .asciz "armv4t"
++ .asciz "armv5t"
+ .size cpu_arch_name, . - cpu_arch_name
+
+ .type cpu_elf_name, #object
+ cpu_elf_name:
+- .asciz "v4"
++ .asciz "v5"
+ .size cpu_elf_name, . - cpu_elf_name
++
++ .type cpu_arm1020_name, #object
++cpu_arm1020_name:
++ .ascii "ARM1020"
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++ .ascii "i"
++#endif
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ .ascii "d"
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++ .ascii "(wt)"
++#else
++ .ascii "(wb)"
++#endif
++#endif
++#ifndef CONFIG_CPU_BPREDICT_DISABLE
++ .ascii "B"
++#endif
++#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
++ .ascii "RR"
++#endif
++ .ascii "\0"
++ .size cpu_arm1020_name, . - cpu_arm1020_name
++
+ .align
+
+ .section ".proc.info", #alloc, #execinstr
+
+ .type __arm1020_proc_info,#object
+ __arm1020_proc_info:
+- .long 0x4100a200
+- .long 0xff00fff0
++ .long 0x4104a200 @ ARM 1020T (Architecture v5T)
++ .long 0xff0ffff0
+ .long 0x00000c02 @ mmuflags
+ b __arm1020_setup
+ .long cpu_arch_name
+Index: linux-2.6.0-test5/arch/arm/mm/proc-arm1022.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/proc-arm1022.S 2003-09-27 11:38:18.431726336 +0800
++++ linux-2.6.0-test5/arch/arm/mm/proc-arm1022.S 2003-09-27 11:38:18.827666144 +0800
+@@ -0,0 +1,484 @@
++/*
++ * linux/arch/arm/mm/proc-arm1022.S: MMU functions for ARM1022E
++ *
++ * Copyright (C) 2000 ARM Limited
++ * Copyright (C) 2000 Deep Blue Solutions Ltd.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ *
++ * These are the low level assembler for performing cache and TLB
++ * functions on the ARM1022E.
++ */
++#include <linux/linkage.h>
++#include <linux/config.h>
++#include <linux/init.h>
++#include <asm/assembler.h>
++#include <asm/constants.h>
++#include <asm/pgtable.h>
++#include <asm/procinfo.h>
++#include <asm/ptrace.h>
++
++/*
++ * This is the maximum size of an area which will be invalidated
++ * using the single invalidate entry instructions. Anything larger
++ * than this, and we go for the whole cache.
++ *
++ * This value should be chosen such that we choose the cheapest
++ * alternative.
++ */
++#define MAX_AREA_SIZE 32768
++
++/*
++ * The size of one data cache line.
++ */
++#define CACHE_DLINESIZE 32
++
++/*
++ * The number of data cache segments.
++ */
++#define CACHE_DSEGMENTS 16
++
++/*
++ * The number of lines in a cache segment.
++ */
++#define CACHE_DENTRIES 64
++
++/*
++ * This is the size at which it becomes more efficient to
++ * clean the whole cache, rather than using the individual
++ * cache line maintainence instructions.
++ */
++#define CACHE_DLIMIT 32768
++
++ .text
++/*
++ * cpu_arm1022_proc_init()
++ */
++ENTRY(cpu_arm1022_proc_init)
++ mov pc, lr
++
++/*
++ * cpu_arm1022_proc_fin()
++ */
++ENTRY(cpu_arm1022_proc_fin)
++ stmfd sp!, {lr}
++ mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
++ msr cpsr_c, ip
++ bl arm1022_flush_kern_cache_all
++ mrc p15, 0, r0, c1, c0, 0 @ ctrl register
++ bic r0, r0, #0x1000 @ ...i............
++ bic r0, r0, #0x000e @ ............wca.
++ mcr p15, 0, r0, c1, c0, 0 @ disable caches
++ ldmfd sp!, {pc}
++
++/*
++ * cpu_arm1022_reset(loc)
++ *
++ * Perform a soft reset of the system. Put the CPU into the
++ * same state as it would be if it had been reset, and branch
++ * to what would be the reset vector.
++ *
++ * loc: location to jump to for soft reset
++ */
++ .align 5
++ENTRY(cpu_arm1022_reset)
++ mov ip, #0
++ mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
++ mcr p15, 0, ip, c7, c10, 4 @ drain WB
++ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
++ mrc p15, 0, ip, c1, c0, 0 @ ctrl register
++ bic ip, ip, #0x000f @ ............wcam
++ bic ip, ip, #0x1100 @ ...i...s........
++ mcr p15, 0, ip, c1, c0, 0 @ ctrl register
++ mov pc, r0
++
++/*
++ * cpu_arm1022_do_idle()
++ */
++ .align 5
++ENTRY(cpu_arm1022_do_idle)
++ mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
++ mov pc, lr
++
++/* ================================= CACHE ================================ */
++
++ .align 5
++/*
++ * flush_user_cache_all()
++ *
++ * Invalidate all cache entries in a particular address
++ * space.
++ */
++ENTRY(arm1022_flush_user_cache_all)
++ /* FALLTHROUGH */
++/*
++ * flush_kern_cache_all()
++ *
++ * Clean and invalidate the entire cache.
++ */
++ENTRY(arm1022_flush_kern_cache_all)
++ mov r2, #VM_EXEC
++ mov ip, #0
++__flush_whole_cache:
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ mov r1, #(CACHE_DSEGMENTS - 1) << 5 @ 16 segments
++1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries
++2: mcr p15, 0, r3, c7, c14, 2 @ clean+invalidate D index
++ subs r3, r3, #1 << 26
++ bcs 2b @ entries 63 to 0
++ subs r1, r1, #1 << 5
++ bcs 1b @ segments 15 to 0
++#endif
++ tst r2, #VM_EXEC
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++ mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
++#endif
++ mcrne p15, 0, ip, c7, c10, 4 @ drain WB
++ mov pc, lr
++
++/*
++ * flush_user_cache_range(start, end, flags)
++ *
++ * Invalidate a range of cache entries in the specified
++ * address space.
++ *
++ * - start - start address (inclusive)
++ * - end - end address (exclusive)
++ * - flags - vm_flags for this space
++ */
++ENTRY(arm1022_flush_user_cache_range)
++ mov ip, #0
++ sub r3, r1, r0 @ calculate total size
++ cmp r3, #CACHE_DLIMIT
++ bhs __flush_whole_cache
++
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
++ add r0, r0, #CACHE_DLINESIZE
++ cmp r0, r1
++ blo 1b
++#endif
++ tst r2, #VM_EXEC
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++ mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
++#endif
++ mcrne p15, 0, ip, c7, c10, 4 @ drain WB
++ mov pc, lr
++
++/*
++ * coherent_kern_range(start, end)
++ *
++ * Ensure coherency between the Icache and the Dcache in the
++ * region described by start. If you have non-snooping
++ * Harvard caches, you need to implement this function.
++ *
++ * - start - virtual start address
++ * - end - virtual end address
++ */
++ENTRY(arm1022_coherent_kern_range)
++ mov ip, #0
++ bic r0, r0, #CACHE_DLINESIZE - 1
++1:
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
++#endif
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++ mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
++#endif
++ add r0, r0, #CACHE_DLINESIZE
++ cmp r0, r1
++ blo 1b
++ mcr p15, 0, ip, c7, c10, 4 @ drain WB
++ mov pc, lr
++
++/*
++ * flush_kern_dcache_page(void *page)
++ *
++ * Ensure no D cache aliasing occurs, either with itself or
++ * the I cache
++ *
++ * - page - page aligned address
++ */
++ENTRY(arm1022_flush_kern_dcache_page)
++ mov ip, #0
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ add r1, r0, #PAGE_SZ
++1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
++ add r0, r0, #CACHE_DLINESIZE
++ cmp r0, r1
++ blo 1b
++#endif
++ mcr p15, 0, ip, c7, c10, 4 @ drain WB
++ mov pc, lr
++
++/*
++ * dma_inv_range(start, end)
++ *
++ * Invalidate (discard) the specified virtual address range.
++ * May not write back any entries. If 'start' or 'end'
++ * are not cache line aligned, those lines must be written
++ * back.
++ *
++ * - start - virtual start address
++ * - end - virtual end address
++ *
++ * (same as v4wb)
++ */
++ENTRY(arm1022_dma_inv_range)
++ mov ip, #0
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ tst r0, #CACHE_DLINESIZE - 1
++ bic r0, r0, #CACHE_DLINESIZE - 1
++ mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
++ tst r1, #CACHE_DLINESIZE - 1
++ mcrne p15, 0, r1, c7, c10, 1 @ clean D entry
++1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
++ add r0, r0, #CACHE_DLINESIZE
++ cmp r0, r1
++ blo 1b
++#endif
++ mcr p15, 0, ip, c7, c10, 4 @ drain WB
++ mov pc, lr
++
++/*
++ * dma_clean_range(start, end)
++ *
++ * Clean the specified virtual address range.
++ *
++ * - start - virtual start address
++ * - end - virtual end address
++ *
++ * (same as v4wb)
++ */
++ENTRY(arm1022_dma_clean_range)
++ mov ip, #0
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ bic r0, r0, #CACHE_DLINESIZE - 1
++1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
++ add r0, r0, #CACHE_DLINESIZE
++ cmp r0, r1
++ blo 1b
++#endif
++ mcr p15, 0, ip, c7, c10, 4 @ drain WB
++ mov pc, lr
++
++/*
++ * dma_flush_range(start, end)
++ *
++ * Clean and invalidate the specified virtual address range.
++ *
++ * - start - virtual start address
++ * - end - virtual end address
++ */
++ENTRY(arm1022_dma_flush_range)
++ mov ip, #0
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ bic r0, r0, #CACHE_DLINESIZE - 1
++1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
++ add r0, r0, #CACHE_DLINESIZE
++ cmp r0, r1
++ blo 1b
++#endif
++ mcr p15, 0, ip, c7, c10, 4 @ drain WB
++ mov pc, lr
++
++ENTRY(arm1022_cache_fns)
++ .long arm1022_flush_kern_cache_all
++ .long arm1022_flush_user_cache_all
++ .long arm1022_flush_user_cache_range
++ .long arm1022_coherent_kern_range
++ .long arm1022_flush_kern_dcache_page
++ .long arm1022_dma_inv_range
++ .long arm1022_dma_clean_range
++ .long arm1022_dma_flush_range
++
++ .align 5
++ENTRY(cpu_arm1022_dcache_clean_area)
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ mov ip, #0
++1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
++ add r0, r0, #CACHE_DLINESIZE
++ subs r1, r1, #CACHE_DLINESIZE
++ bhi 1b
++#endif
++ mov pc, lr
++
++/* =============================== PageTable ============================== */
++
++/*
++ * cpu_arm1022_switch_mm(pgd)
++ *
++ * Set the translation base pointer to be as described by pgd.
++ *
++ * pgd: new page tables
++ */
++ .align 5
++ENTRY(cpu_arm1022_switch_mm)
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ mov r1, #(CACHE_DSEGMENTS - 1) << 5 @ 16 segments
++1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries
++2: mcr p15, 0, r3, c7, c14, 2 @ clean+invalidate D index
++ subs r3, r3, #1 << 26
++ bcs 2b @ entries 63 to 0
++ subs r1, r1, #1 << 5
++ bcs 1b @ segments 15 to 0
++#endif
++ mov r1, #0
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++ mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache
++#endif
++ mcr p15, 0, r1, c7, c10, 4 @ drain WB
++ mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
++ mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs
++ mov pc, lr
++
++/*
++ * cpu_arm1022_set_pte(ptep, pte)
++ *
++ * Set a PTE and flush it out
++ */
++ .align 5
++ENTRY(cpu_arm1022_set_pte)
++ str r1, [r0], #-2048 @ linux version
++
++ eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
++
++ bic r2, r1, #PTE_SMALL_AP_MASK
++ bic r2, r2, #PTE_TYPE_MASK
++ orr r2, r2, #PTE_TYPE_SMALL
++
++ tst r1, #L_PTE_USER @ User?
++ orrne r2, r2, #PTE_SMALL_AP_URO_SRW
++
++ tst r1, #L_PTE_WRITE | L_PTE_DIRTY @ Write and Dirty?
++ orreq r2, r2, #PTE_SMALL_AP_UNO_SRW
++
++ tst r1, #L_PTE_PRESENT | L_PTE_YOUNG @ Present and Young?
++ movne r2, #0
++
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++ eor r3, r1, #0x0a @ C & small page?
++ tst r3, #0x0b
++ biceq r2, r2, #4
++#endif
++ str r2, [r0] @ hardware version
++ mov r0, r0
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
++#endif
++ mov pc, lr
++
++ __INIT
++
++ .type __arm1022_setup, #function
++__arm1022_setup:
++ mov r0, #0
++ mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4
++ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4
++ mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4
++ mcr p15, 0, r4, c2, c0 @ load page table pointer
++ mov r0, #0x1f @ Domains 0, 1 = client
++ mcr p15, 0, r0, c3, c0 @ load domain access register
++ mrc p15, 0, r0, c1, c0 @ get control register v4
++/*
++ * Clear out 'unwanted' bits (then put them in if we need them)
++ */
++ bic r0, r0, #0x1e00 @ ...i??r.........
++ bic r0, r0, #0x000e @ ............wca.
++/*
++ * Turn on what we want
++ */
++ orr r0, r0, #0x0031 @ ..........DP...M
++ orr r0, r0, #0x2100 @ ..V....S........
++
++#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
++ orr r0, r0, #0x4000 @ .R..............
++#endif
++#ifndef CONFIG_CPU_BPREDICT_DISABLE
++ orr r0, r0, #0x0800 @ ....Z...........
++#endif
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ orr r0, r0, #0x0004 @ .............C..
++#endif
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++ orr r0, r0, #0x1000 @ ...I............
++#endif
++ mov pc, lr
++ .size __arm1022_setup, . - __arm1022_setup
++
++ __INITDATA
++
++/*
++ * Purpose : Function pointers used to access above functions - all calls
++ * come through these
++ */
++ .type arm1022_processor_functions, #object
++arm1022_processor_functions:
++ .word v4t_early_abort
++ .word cpu_arm1022_proc_init
++ .word cpu_arm1022_proc_fin
++ .word cpu_arm1022_reset
++ .word cpu_arm1022_do_idle
++ .word cpu_arm1022_dcache_clean_area
++ .word cpu_arm1022_switch_mm
++ .word cpu_arm1022_set_pte
++ .size arm1022_processor_functions, . - arm1022_processor_functions
++
++ .section ".rodata"
++
++ .type cpu_arch_name, #object
++cpu_arch_name:
++ .asciz "armv5te"
++ .size cpu_arch_name, . - cpu_arch_name
++
++ .type cpu_elf_name, #object
++cpu_elf_name:
++ .asciz "v5"
++ .size cpu_elf_name, . - cpu_elf_name
++
++ .type cpu_arm1022_name, #object
++cpu_arm1022_name:
++ .ascii "arm1022"
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++ .ascii "i"
++#endif
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ .ascii "d"
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++ .ascii "(wt)"
++#else
++ .ascii "(wb)"
++#endif
++#endif
++#ifndef CONFIG_CPU_BPREDICT_DISABLE
++ .ascii "B"
++#endif
++#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
++ .ascii "RR"
++#endif
++ .ascii "\0"
++ .size cpu_arm1022_name, . - cpu_arm1022_name
++
++ .align
++
++ .section ".proc.info", #alloc, #execinstr
++
++ .type __arm1022_proc_info,#object
++__arm1022_proc_info:
++ .long 0x4105a220 @ ARM 1022E (v5TE)
++ .long 0xff0ffff0
++ .long 0x00000c12 @ mmuflags
++ b __arm1022_setup
++ .long cpu_arch_name
++ .long cpu_elf_name
++ .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
++ .long cpu_arm1022_name
++ .long arm1022_processor_functions
++ .long v4wbi_tlb_fns
++ .long v4wb_user_fns
++ .long arm1022_cache_fns
++ .size __arm1022_proc_info, . - __arm1022_proc_info
+Index: linux-2.6.0-test5/arch/arm/mm/proc-arm1026.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/proc-arm1026.S 2003-09-27 11:38:18.431726336 +0800
++++ linux-2.6.0-test5/arch/arm/mm/proc-arm1026.S 2003-09-27 11:38:18.829665840 +0800
+@@ -0,0 +1,480 @@
++/*
++ * linux/arch/arm/mm/proc-arm1026.S: MMU functions for ARM1026EJ-S
++ *
++ * Copyright (C) 2000 ARM Limited
++ * Copyright (C) 2000 Deep Blue Solutions Ltd.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ *
++ * These are the low level assembler for performing cache and TLB
++ * functions on the ARM1026EJ-S.
++ */
++#include <linux/linkage.h>
++#include <linux/config.h>
++#include <linux/init.h>
++#include <asm/assembler.h>
++#include <asm/constants.h>
++#include <asm/pgtable.h>
++#include <asm/procinfo.h>
++#include <asm/ptrace.h>
++
++/*
++ * This is the maximum size of an area which will be invalidated
++ * using the single invalidate entry instructions. Anything larger
++ * than this, and we go for the whole cache.
++ *
++ * This value should be chosen such that we choose the cheapest
++ * alternative.
++ */
++#define MAX_AREA_SIZE 32768
++
++/*
++ * The size of one data cache line.
++ */
++#define CACHE_DLINESIZE 32
++
++/*
++ * The number of data cache segments.
++ */
++#define CACHE_DSEGMENTS 16
++
++/*
++ * The number of lines in a cache segment.
++ */
++#define CACHE_DENTRIES 64
++
++/*
++ * This is the size at which it becomes more efficient to
++ * clean the whole cache, rather than using the individual
++ * cache line maintainence instructions.
++ */
++#define CACHE_DLIMIT 32768
++
++ .text
++/*
++ * cpu_arm1026_proc_init()
++ */
++ENTRY(cpu_arm1026_proc_init)
++ mov pc, lr
++
++/*
++ * cpu_arm1026_proc_fin()
++ */
++ENTRY(cpu_arm1026_proc_fin)
++ stmfd sp!, {lr}
++ mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
++ msr cpsr_c, ip
++ bl arm1026_flush_kern_cache_all
++ mrc p15, 0, r0, c1, c0, 0 @ ctrl register
++ bic r0, r0, #0x1000 @ ...i............
++ bic r0, r0, #0x000e @ ............wca.
++ mcr p15, 0, r0, c1, c0, 0 @ disable caches
++ ldmfd sp!, {pc}
++
++/*
++ * cpu_arm1026_reset(loc)
++ *
++ * Perform a soft reset of the system. Put the CPU into the
++ * same state as it would be if it had been reset, and branch
++ * to what would be the reset vector.
++ *
++ * loc: location to jump to for soft reset
++ */
++ .align 5
++ENTRY(cpu_arm1026_reset)
++ mov ip, #0
++ mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
++ mcr p15, 0, ip, c7, c10, 4 @ drain WB
++ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
++ mrc p15, 0, ip, c1, c0, 0 @ ctrl register
++ bic ip, ip, #0x000f @ ............wcam
++ bic ip, ip, #0x1100 @ ...i...s........
++ mcr p15, 0, ip, c1, c0, 0 @ ctrl register
++ mov pc, r0
++
++/*
++ * cpu_arm1026_do_idle()
++ */
++ .align 5
++ENTRY(cpu_arm1026_do_idle)
++ mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
++ mov pc, lr
++
++/* ================================= CACHE ================================ */
++
++ .align 5
++/*
++ * flush_user_cache_all()
++ *
++ * Invalidate all cache entries in a particular address
++ * space.
++ */
++ENTRY(arm1026_flush_user_cache_all)
++ /* FALLTHROUGH */
++/*
++ * flush_kern_cache_all()
++ *
++ * Clean and invalidate the entire cache.
++ */
++ENTRY(arm1026_flush_kern_cache_all)
++ mov r2, #VM_EXEC
++ mov ip, #0
++__flush_whole_cache:
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++1: mrc p15, 0, r15, c7, c14, 3 @ test, clean, invalidate
++ bne 1b
++#endif
++ tst r2, #VM_EXEC
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++ mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
++#endif
++ mcrne p15, 0, ip, c7, c10, 4 @ drain WB
++ mov pc, lr
++
++/*
++ * flush_user_cache_range(start, end, flags)
++ *
++ * Invalidate a range of cache entries in the specified
++ * address space.
++ *
++ * - start - start address (inclusive)
++ * - end - end address (exclusive)
++ * - flags - vm_flags for this space
++ */
++ENTRY(arm1026_flush_user_cache_range)
++ mov ip, #0
++ sub r3, r1, r0 @ calculate total size
++ cmp r3, #CACHE_DLIMIT
++ bhs __flush_whole_cache
++
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
++ add r0, r0, #CACHE_DLINESIZE
++ cmp r0, r1
++ blo 1b
++#endif
++ tst r2, #VM_EXEC
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++ mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
++#endif
++ mcrne p15, 0, ip, c7, c10, 4 @ drain WB
++ mov pc, lr
++
++/*
++ * coherent_kern_range(start, end)
++ *
++ * Ensure coherency between the Icache and the Dcache in the
++ * region described by start. If you have non-snooping
++ * Harvard caches, you need to implement this function.
++ *
++ * - start - virtual start address
++ * - end - virtual end address
++ */
++ENTRY(arm1026_coherent_kern_range)
++ mov ip, #0
++ bic r0, r0, #CACHE_DLINESIZE - 1
++1:
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
++#endif
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++ mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
++#endif
++ add r0, r0, #CACHE_DLINESIZE
++ cmp r0, r1
++ blo 1b
++ mcr p15, 0, ip, c7, c10, 4 @ drain WB
++ mov pc, lr
++
++/*
++ * flush_kern_dcache_page(void *page)
++ *
++ * Ensure no D cache aliasing occurs, either with itself or
++ * the I cache
++ *
++ * - page - page aligned address
++ */
++ENTRY(arm1026_flush_kern_dcache_page)
++ mov ip, #0
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ add r1, r0, #PAGE_SZ
++1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
++ add r0, r0, #CACHE_DLINESIZE
++ cmp r0, r1
++ blo 1b
++#endif
++ mcr p15, 0, ip, c7, c10, 4 @ drain WB
++ mov pc, lr
++
++/*
++ * dma_inv_range(start, end)
++ *
++ * Invalidate (discard) the specified virtual address range.
++ * May not write back any entries. If 'start' or 'end'
++ * are not cache line aligned, those lines must be written
++ * back.
++ *
++ * - start - virtual start address
++ * - end - virtual end address
++ *
++ * (same as v4wb)
++ */
++ENTRY(arm1026_dma_inv_range)
++ mov ip, #0
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ tst r0, #CACHE_DLINESIZE - 1
++ bic r0, r0, #CACHE_DLINESIZE - 1
++ mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
++ tst r1, #CACHE_DLINESIZE - 1
++ mcrne p15, 0, r1, c7, c10, 1 @ clean D entry
++1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
++ add r0, r0, #CACHE_DLINESIZE
++ cmp r0, r1
++ blo 1b
++#endif
++ mcr p15, 0, ip, c7, c10, 4 @ drain WB
++ mov pc, lr
++
++/*
++ * dma_clean_range(start, end)
++ *
++ * Clean the specified virtual address range.
++ *
++ * - start - virtual start address
++ * - end - virtual end address
++ *
++ * (same as v4wb)
++ */
++ENTRY(arm1026_dma_clean_range)
++ mov ip, #0
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ bic r0, r0, #CACHE_DLINESIZE - 1
++1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
++ add r0, r0, #CACHE_DLINESIZE
++ cmp r0, r1
++ blo 1b
++#endif
++ mcr p15, 0, ip, c7, c10, 4 @ drain WB
++ mov pc, lr
++
++/*
++ * dma_flush_range(start, end)
++ *
++ * Clean and invalidate the specified virtual address range.
++ *
++ * - start - virtual start address
++ * - end - virtual end address
++ */
++ENTRY(arm1026_dma_flush_range)
++ mov ip, #0
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ bic r0, r0, #CACHE_DLINESIZE - 1
++1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
++ add r0, r0, #CACHE_DLINESIZE
++ cmp r0, r1
++ blo 1b
++#endif
++ mcr p15, 0, ip, c7, c10, 4 @ drain WB
++ mov pc, lr
++
++ENTRY(arm1026_cache_fns)
++ .long arm1026_flush_kern_cache_all
++ .long arm1026_flush_user_cache_all
++ .long arm1026_flush_user_cache_range
++ .long arm1026_coherent_kern_range
++ .long arm1026_flush_kern_dcache_page
++ .long arm1026_dma_inv_range
++ .long arm1026_dma_clean_range
++ .long arm1026_dma_flush_range
++
++ .align 5
++ENTRY(cpu_arm1026_dcache_clean_area)
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ mov ip, #0
++1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
++ add r0, r0, #CACHE_DLINESIZE
++ subs r1, r1, #CACHE_DLINESIZE
++ bhi 1b
++#endif
++ mov pc, lr
++
++/* =============================== PageTable ============================== */
++
++/*
++ * cpu_arm1026_switch_mm(pgd)
++ *
++ * Set the translation base pointer to be as described by pgd.
++ *
++ * pgd: new page tables
++ */
++ .align 5
++ENTRY(cpu_arm1026_switch_mm)
++ mov r1, #0
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++1: mrc p15, 0, r15, c7, c14, 3 @ test, clean, invalidate
++ bne 1b
++#endif
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++ mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache
++#endif
++ mcr p15, 0, r1, c7, c10, 4 @ drain WB
++ mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
++ mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs
++ mov pc, lr
++
++/*
++ * cpu_arm1026_set_pte(ptep, pte)
++ *
++ * Set a PTE and flush it out
++ */
++ .align 5
++ENTRY(cpu_arm1026_set_pte)
++ str r1, [r0], #-2048 @ linux version
++
++ eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
++
++ bic r2, r1, #PTE_SMALL_AP_MASK
++ bic r2, r2, #PTE_TYPE_MASK
++ orr r2, r2, #PTE_TYPE_SMALL
++
++ tst r1, #L_PTE_USER @ User?
++ orrne r2, r2, #PTE_SMALL_AP_URO_SRW
++
++ tst r1, #L_PTE_WRITE | L_PTE_DIRTY @ Write and Dirty?
++ orreq r2, r2, #PTE_SMALL_AP_UNO_SRW
++
++ tst r1, #L_PTE_PRESENT | L_PTE_YOUNG @ Present and Young?
++ movne r2, #0
++
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++ eor r3, r1, #0x0a @ C & small page?
++ tst r3, #0x0b
++ biceq r2, r2, #4
++#endif
++ str r2, [r0] @ hardware version
++ mov r0, r0
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
++#endif
++ mov pc, lr
++
++
++ __INIT
++
++ .type __arm1026_setup, #function
++__arm1026_setup:
++ mov r0, #0
++ mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4
++ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4
++ mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4
++ mcr p15, 0, r4, c2, c0 @ load page table pointer
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++ mov r0, #4 @ explicitly disable writeback
++ mcr p15, 7, r0, c15, c0, 0
++#endif
++ mov r0, #0x1f @ Domains 0, 1 = client
++ mcr p15, 0, r0, c3, c0 @ load domain access register
++ mrc p15, 0, r0, c1, c0 @ get control register v4
++/*
++ * Clear out 'unwanted' bits (then put them in if we need them)
++ */
++ bic r0, r0, #0x1e00 @ ...i??r.........
++ bic r0, r0, #0x000e @ ............wca.
++/*
++ * Turn on what we want
++ */
++ orr r0, r0, #0x0031 @ ..........DP...M
++ orr r0, r0, #0x2100 @ ..V....S........
++
++#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
++ orr r0, r0, #0x4000 @ .R..............
++#endif
++#ifndef CONFIG_CPU_BPREDICT_DISABLE
++ orr r0, r0, #0x0800 @ ....Z...........
++#endif
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ orr r0, r0, #0x0004 @ .............C..
++#endif
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++ orr r0, r0, #0x1000 @ ...I............
++#endif
++ mov pc, lr
++ .size __arm1026_setup, . - __arm1026_setup
++
++ __INITDATA
++
++/*
++ * Purpose : Function pointers used to access above functions - all calls
++ * come through these
++ */
++ .type arm1026_processor_functions, #object
++arm1026_processor_functions:
++ .word v5t_early_abort
++ .word cpu_arm1026_proc_init
++ .word cpu_arm1026_proc_fin
++ .word cpu_arm1026_reset
++ .word cpu_arm1026_do_idle
++ .word cpu_arm1026_dcache_clean_area
++ .word cpu_arm1026_switch_mm
++ .word cpu_arm1026_set_pte
++ .size arm1026_processor_functions, . - arm1026_processor_functions
++
++ .section .rodata
++
++ .type cpu_arch_name, #object
++cpu_arch_name:
++ .asciz "armv5tej"
++ .size cpu_arch_name, . - cpu_arch_name
++
++ .type cpu_elf_name, #object
++cpu_elf_name:
++ .asciz "v5"
++ .size cpu_elf_name, . - cpu_elf_name
++ .align
++
++ .type cpu_arm1026_name, #object
++cpu_arm1026_name:
++ .ascii "ARM1026EJ-S"
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++ .ascii "i"
++#endif
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ .ascii "d"
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++ .ascii "(wt)"
++#else
++ .ascii "(wb)"
++#endif
++#endif
++#ifndef CONFIG_CPU_BPREDICT_DISABLE
++ .ascii "B"
++#endif
++#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
++ .ascii "RR"
++#endif
++ .ascii "\0"
++ .size cpu_arm1026_name, . - cpu_arm1026_name
++
++ .align
++
++ .section ".proc.info", #alloc, #execinstr
++
++ .type __arm1026_proc_info,#object
++__arm1026_proc_info:
++ .long 0x4106a260 @ ARM 1026EJ-S (v5TEJ)
++ .long 0xff0ffff0
++ .long 0x00000c12 @ mmuflags
++ b __arm1026_setup
++ .long cpu_arch_name
++ .long cpu_elf_name
++ .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | HWCAP_FAST_MULT
++ .long cpu_arm1026_name
++ .long arm1026_processor_functions
++ .long v4wbi_tlb_fns
++ .long v4wb_user_fns
++ .long arm1026_cache_fns
++ .size __arm1026_proc_info, . - __arm1026_proc_info
+Index: linux-2.6.0-test5/arch/arm/mm/proc-arm6_7.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/proc-arm6_7.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/proc-arm6_7.S 2003-09-27 11:38:18.832665384 +0800
+@@ -14,6 +14,7 @@
+ #include <linux/init.h>
+ #include <asm/assembler.h>
+ #include <asm/constants.h>
++#include <asm/pgtable.h>
+ #include <asm/procinfo.h>
+ #include <asm/ptrace.h>
+
+@@ -214,19 +215,19 @@
+ ENTRY(cpu_arm7_set_pte)
+ str r1, [r0], #-2048 @ linux version
+
+- eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
++ eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
+
+- bic r2, r1, #0xff0
+- bic r2, r2, #3
+- orr r2, r2, #HPTE_TYPE_SMALL
++ bic r2, r1, #PTE_SMALL_AP_MASK
++ bic r2, r2, #PTE_TYPE_MASK
++ orr r2, r2, #PTE_TYPE_SMALL
+
+- tst r1, #LPTE_USER | LPTE_EXEC @ User or Exec?
+- orrne r2, r2, #HPTE_AP_READ
++ tst r1, #L_PTE_USER @ User?
++ orrne r2, r2, #PTE_SMALL_AP_URO_SRW
+
+- tst r1, #LPTE_WRITE | LPTE_DIRTY @ Write and Dirty?
+- orreq r2, r2, #HPTE_AP_WRITE
++ tst r1, #L_PTE_WRITE | L_PTE_DIRTY @ Write and Dirty?
++ orreq r2, r2, #PTE_SMALL_AP_UNO_SRW
+
+- tst r1, #LPTE_PRESENT | LPTE_YOUNG @ Present and Young
++ tst r1, #L_PTE_PRESENT | L_PTE_YOUNG @ Present and Young
+ movne r2, #0
+
+ str r2, [r0] @ hardware version
+@@ -246,16 +247,9 @@
+ mcr p15, 0, r1, c1, c0, 0 @ turn off MMU etc
+ mov pc, r0
+
+-cpu_arm6_name: .asciz "ARM6"
+-cpu_arm610_name:
+- .asciz "ARM610"
+-cpu_arm7_name: .asciz "ARM7"
+-cpu_arm710_name:
+- .asciz "ARM710"
+- .align
+-
+ __INIT
+
++ .type __arm6_setup, #function
+ __arm6_setup: mov r0, #0
+ mcr p15, 0, r0, c7, c0 @ flush caches on v3
+ mcr p15, 0, r0, c5, c0 @ flush TLBs on v3
+@@ -265,7 +259,9 @@
+ mov r0, #0x3d @ . ..RS BLDP WCAM
+ orr r0, r0, #0x100 @ . ..01 0011 1101
+ mov pc, lr
++ .size __arm6_setup, . - __arm6_setup
+
++ .type __arm7_setup, #function
+ __arm7_setup: mov r0, #0
+ mcr p15, 0, r0, c7, c0 @ flush caches on v3
+ mcr p15, 0, r0, c5, c0 @ flush TLBs on v3
+@@ -275,6 +271,9 @@
+ mov r0, #0x7d @ . ..RS BLDP WCAM
+ orr r0, r0, #0x100 @ . ..01 0111 1101
+ mov pc, lr
++ .size __arm7_setup, . - __arm7_setup
++
++ __INITDATA
+
+ /*
+ * Purpose : Function pointers used to access above functions - all calls
+@@ -308,6 +307,8 @@
+ .word cpu_arm7_set_pte
+ .size arm7_processor_functions, . - arm7_processor_functions
+
++ .section ".rodata"
++
+ .type cpu_arch_name, #object
+ cpu_arch_name: .asciz "armv3"
+ .size cpu_arch_name, . - cpu_arch_name
+@@ -315,6 +316,25 @@
+ .type cpu_elf_name, #object
+ cpu_elf_name: .asciz "v3"
+ .size cpu_elf_name, . - cpu_elf_name
++
++ .type cpu_arm6_name, #object
++cpu_arm6_name: .asciz "ARM6"
++ .size cpu_arm6_name, . - cpu_arm6_name
++
++ .type cpu_arm610_name, #object
++cpu_arm610_name:
++ .asciz "ARM610"
++ .size cpu_arm610_name, . - cpu_arm610_name
++
++ .type cpu_arm7_name, #object
++cpu_arm7_name: .asciz "ARM7"
++ .size cpu_arm7_name, . - cpu_arm7_name
++
++ .type cpu_arm710_name, #object
++cpu_arm710_name:
++ .asciz "ARM710"
++ .size cpu_arm710_name, . - cpu_arm710_name
++
+ .align
+
+ .section ".proc.info", #alloc, #execinstr
+Index: linux-2.6.0-test5/arch/arm/mm/proc-arm720.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/proc-arm720.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/proc-arm720.S 2003-09-27 11:38:18.835664928 +0800
+@@ -34,6 +34,7 @@
+ #include <linux/init.h>
+ #include <asm/assembler.h>
+ #include <asm/constants.h>
++#include <asm/pgtable.h>
+ #include <asm/procinfo.h>
+ #include <asm/ptrace.h>
+ #include <asm/hardware.h>
+@@ -90,19 +91,19 @@
+ ENTRY(cpu_arm720_set_pte)
+ str r1, [r0], #-2048 @ linux version
+
+- eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
++ eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
+
+- bic r2, r1, #0xff0
+- bic r2, r2, #3
+- orr r2, r2, #HPTE_TYPE_SMALL
++ bic r2, r1, #PTE_SMALL_AP_MASK
++ bic r2, r2, #PTE_TYPE_MASK
++ orr r2, r2, #PTE_TYPE_SMALL
+
+- tst r1, #LPTE_USER @ User?
+- orrne r2, r2, #HPTE_AP_READ
++ tst r1, #L_PTE_USER @ User?
++ orrne r2, r2, #PTE_SMALL_AP_URO_SRW
+
+- tst r1, #LPTE_WRITE | LPTE_DIRTY @ Write and Dirty?
+- orreq r2, r2, #HPTE_AP_WRITE
++ tst r1, #L_PTE_WRITE | L_PTE_DIRTY @ Write and Dirty?
++ orreq r2, r2, #PTE_SMALL_AP_UNO_SRW
+
+- tst r1, #LPTE_PRESENT | LPTE_YOUNG @ Present and Young
++ tst r1, #L_PTE_PRESENT | L_PTE_YOUNG @ Present and Young
+ movne r2, #0
+
+ str r2, [r0] @ hardware version
+@@ -123,13 +124,9 @@
+ mcr p15, 0, ip, c1, c0, 0 @ ctrl register
+ mov pc, r0
+
+-
+-cpu_arm720_name:
+- .asciz "ARM720T"
+- .align
+-
+ __INIT
+
++ .type __arm720_setup, #function
+ __arm720_setup: mov r0, #0
+ mcr p15, 0, r0, c7, c7, 0 @ invalidate caches
+ mcr p15, 0, r0, c8, c7, 0 @ flush TLB (v4)
+@@ -142,6 +139,9 @@
+ orr r0, r0, #0x2100 @ .... .... .111 .... (old)
+ orr r0, r0, #0x003d @ ..1. ..01 ..11 1101 (new)
+ mov pc, lr @ __ret (head-armv.S)
++ .size __arm720_setup, . - __arm720_setup
++
++ __INITDATA
+
+ /*
+ * Purpose : Function pointers used to access above functions - all calls
+@@ -159,6 +159,8 @@
+ .word cpu_arm720_set_pte
+ .size arm720_processor_functions, . - arm720_processor_functions
+
++ .section ".rodata"
++
+ .type cpu_arch_name, #object
+ cpu_arch_name: .asciz "armv4t"
+ .size cpu_arch_name, . - cpu_arch_name
+@@ -166,6 +168,12 @@
+ .type cpu_elf_name, #object
+ cpu_elf_name: .asciz "v4"
+ .size cpu_elf_name, . - cpu_elf_name
++
++ .type cpu_arm720_name, #object
++cpu_arm720_name:
++ .asciz "ARM720T"
++ .size cpu_arm720_name, . - cpu_arm720_name
++
+ .align
+
+ /*
+Index: linux-2.6.0-test5/arch/arm/mm/proc-arm920.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/proc-arm920.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/proc-arm920.S 2003-09-27 11:38:18.838664472 +0800
+@@ -1,5 +1,5 @@
+ /*
+- * linux/arch/arm/mm/arm920.S: MMU functions for ARM920
++ * linux/arch/arm/mm/proc-arm920.S: MMU functions for ARM920
+ *
+ * Copyright (C) 1999,2000 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd.
+@@ -28,6 +28,7 @@
+ #include <linux/config.h>
+ #include <linux/init.h>
+ #include <asm/assembler.h>
++#include <asm/pgtable.h>
+ #include <asm/procinfo.h>
+ #include <asm/hardware.h>
+ #include <asm/page.h>
+@@ -333,19 +334,19 @@
+ ENTRY(cpu_arm920_set_pte)
+ str r1, [r0], #-2048 @ linux version
+
+- eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
++ eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
+
+- bic r2, r1, #0xff0
+- bic r2, r2, #3
+- orr r2, r2, #HPTE_TYPE_SMALL
++ bic r2, r1, #PTE_SMALL_AP_MASK
++ bic r2, r2, #PTE_TYPE_MASK
++ orr r2, r2, #PTE_TYPE_SMALL
+
+- tst r1, #LPTE_USER @ User or Exec?
+- orrne r2, r2, #HPTE_AP_READ
++ tst r1, #L_PTE_USER @ User?
++ orrne r2, r2, #PTE_SMALL_AP_URO_SRW
+
+- tst r1, #LPTE_WRITE | LPTE_DIRTY @ Write and Dirty?
+- orreq r2, r2, #HPTE_AP_WRITE
++ tst r1, #L_PTE_WRITE | L_PTE_DIRTY @ Write and Dirty?
++ orreq r2, r2, #PTE_SMALL_AP_UNO_SRW
+
+- tst r1, #LPTE_PRESENT | LPTE_YOUNG @ Present and Young?
++ tst r1, #L_PTE_PRESENT | L_PTE_YOUNG @ Present and Young?
+ movne r2, #0
+
+ #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+@@ -359,25 +360,9 @@
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+-
+-ENTRY(cpu_arm920_name)
+- .ascii "Arm920T"
+-#ifndef CONFIG_CPU_ICACHE_DISABLE
+- .ascii "i"
+-#endif
+-#ifndef CONFIG_CPU_DCACHE_DISABLE
+- .ascii "d"
+-#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+- .ascii "(wt)"
+-#else
+- .ascii "(wb)"
+-#endif
+-#endif
+- .ascii "\0"
+- .align
+-
+ __INIT
+
++ .type __arm920_setup, #function
+ __arm920_setup:
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4
+@@ -408,8 +393,9 @@
+ orr r0, r0, #0x1000 @ ...1 .... .... ....
+ #endif
+ mov pc, lr
++ .size __arm920_setup, . - __arm920_setup
+
+- .text
++ __INITDATA
+
+ /*
+ * Purpose : Function pointers used to access above functions - all calls
+@@ -427,6 +413,8 @@
+ .word cpu_arm920_set_pte
+ .size arm920_processor_functions, . - arm920_processor_functions
+
++ .section ".rodata"
++
+ .type cpu_arch_name, #object
+ cpu_arch_name:
+ .asciz "armv4t"
+@@ -436,6 +424,24 @@
+ cpu_elf_name:
+ .asciz "v4"
+ .size cpu_elf_name, . - cpu_elf_name
++
++ .type cpu_arm920_name, #object
++cpu_arm920_name:
++ .ascii "ARM920T"
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++ .ascii "i"
++#endif
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ .ascii "d"
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++ .ascii "(wt)"
++#else
++ .ascii "(wb)"
++#endif
++#endif
++ .ascii "\0"
++ .size cpu_arm920_name, . - cpu_arm920_name
++
+ .align
+
+ .section ".proc.info", #alloc, #execinstr
+Index: linux-2.6.0-test5/arch/arm/mm/proc-arm922.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/proc-arm922.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/proc-arm922.S 2003-09-27 11:38:18.842663864 +0800
+@@ -1,5 +1,5 @@
+ /*
+- * linux/arch/arm/mm/arm922.S: MMU functions for ARM922
++ * linux/arch/arm/mm/proc-arm922.S: MMU functions for ARM922
+ *
+ * Copyright (C) 1999,2000 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd.
+@@ -29,6 +29,7 @@
+ #include <linux/config.h>
+ #include <linux/init.h>
+ #include <asm/assembler.h>
++#include <asm/pgtable.h>
+ #include <asm/procinfo.h>
+ #include <asm/hardware.h>
+ #include <asm/page.h>
+@@ -337,19 +338,19 @@
+ ENTRY(cpu_arm922_set_pte)
+ str r1, [r0], #-2048 @ linux version
+
+- eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
++ eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
+
+- bic r2, r1, #0xff0
+- bic r2, r2, #3
+- orr r2, r2, #HPTE_TYPE_SMALL
++ bic r2, r1, #PTE_SMALL_AP_MASK
++ bic r2, r2, #PTE_TYPE_MASK
++ orr r2, r2, #PTE_TYPE_SMALL
+
+- tst r1, #LPTE_USER @ User?
+- orrne r2, r2, #HPTE_AP_READ
++ tst r1, #L_PTE_USER @ User?
++ orrne r2, r2, #PTE_SMALL_AP_URO_SRW
+
+- tst r1, #LPTE_WRITE | LPTE_DIRTY @ Write and Dirty?
+- orreq r2, r2, #HPTE_AP_WRITE
++ tst r1, #L_PTE_WRITE | L_PTE_DIRTY @ Write and Dirty?
++ orreq r2, r2, #PTE_SMALL_AP_UNO_SRW
+
+- tst r1, #LPTE_PRESENT | LPTE_YOUNG @ Present and Young?
++ tst r1, #L_PTE_PRESENT | L_PTE_YOUNG @ Present and Young?
+ movne r2, #0
+
+ #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+@@ -363,25 +364,9 @@
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+-
+-ENTRY(cpu_arm922_name)
+- .ascii "Arm922T"
+-#ifndef CONFIG_CPU_ICACHE_DISABLE
+- .ascii "i"
+-#endif
+-#ifndef CONFIG_CPU_DCACHE_DISABLE
+- .ascii "d"
+-#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+- .ascii "(wt)"
+-#else
+- .ascii "(wb)"
+-#endif
+-#endif
+- .ascii "\0"
+- .align
+-
+ __INIT
+
++ .type __arm922_setup, #function
+ __arm922_setup:
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4
+@@ -412,8 +397,9 @@
+ orr r0, r0, #0x1000 @ ...1 .... .... ....
+ #endif
+ mov pc, lr
++ .size __arm922_setup, . - __arm922_setup
+
+- .text
++ __INITDATA
+
+ /*
+ * Purpose : Function pointers used to access above functions - all calls
+@@ -431,6 +417,8 @@
+ .word cpu_arm922_set_pte
+ .size arm922_processor_functions, . - arm922_processor_functions
+
++ .section ".rodata"
++
+ .type cpu_arch_name, #object
+ cpu_arch_name:
+ .asciz "armv4t"
+@@ -440,6 +428,24 @@
+ cpu_elf_name:
+ .asciz "v4"
+ .size cpu_elf_name, . - cpu_elf_name
++
++ .type cpu_arm922_name, #object
++cpu_arm922_name:
++ .ascii "ARM922T"
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++ .ascii "i"
++#endif
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ .ascii "d"
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++ .ascii "(wt)"
++#else
++ .ascii "(wb)"
++#endif
++#endif
++ .ascii "\0"
++ .size cpu_arm922_name, . - cpu_arm922_name
++
+ .align
+
+ .section ".proc.info", #alloc, #execinstr
+Index: linux-2.6.0-test5/arch/arm/mm/proc-arm926.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/proc-arm926.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/proc-arm926.S 2003-09-27 11:38:18.846663256 +0800
+@@ -28,6 +28,7 @@
+ #include <linux/config.h>
+ #include <linux/init.h>
+ #include <asm/assembler.h>
++#include <asm/pgtable.h>
+ #include <asm/procinfo.h>
+ #include <asm/hardware.h>
+ #include <asm/page.h>
+@@ -337,19 +338,19 @@
+ ENTRY(cpu_arm926_set_pte)
+ str r1, [r0], #-2048 @ linux version
+
+- eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
++ eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
+
+- bic r2, r1, #0xff0
+- bic r2, r2, #3
+- orr r2, r2, #HPTE_TYPE_SMALL
++ bic r2, r1, #PTE_SMALL_AP_MASK
++ bic r2, r2, #PTE_TYPE_MASK
++ orr r2, r2, #PTE_TYPE_SMALL
+
+- tst r1, #LPTE_USER @ User?
+- orrne r2, r2, #HPTE_AP_READ
++ tst r1, #L_PTE_USER @ User?
++ orrne r2, r2, #PTE_SMALL_AP_URO_SRW
+
+- tst r1, #LPTE_WRITE | LPTE_DIRTY @ Write and Dirty?
+- orreq r2, r2, #HPTE_AP_WRITE
++ tst r1, #L_PTE_WRITE | L_PTE_DIRTY @ Write and Dirty?
++ orreq r2, r2, #PTE_SMALL_AP_UNO_SRW
+
+- tst r1, #LPTE_PRESENT | LPTE_YOUNG @ Present and Young?
++ tst r1, #L_PTE_PRESENT | L_PTE_YOUNG @ Present and Young?
+ movne r2, #0
+
+ #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+@@ -365,28 +366,9 @@
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+-
+-ENTRY(cpu_arm926_name)
+- .ascii "ARM926EJ-S"
+-#ifndef CONFIG_CPU_ICACHE_DISABLE
+- .ascii "i"
+-#endif
+-#ifndef CONFIG_CPU_DCACHE_DISABLE
+- .ascii "d"
+-#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+- .ascii "(wt)"
+-#else
+- .ascii "(wb)"
+-#endif
+-#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
+- .ascii "RR"
+-#endif
+-#endif
+- .ascii "\0"
+- .align
+-
+ __INIT
+
++ .type __arm926_setup, #function
+ __arm926_setup:
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4
+@@ -427,8 +409,9 @@
+ orr r0, r0, #0x1000 @ ...1 .... .... ....
+ #endif
+ mov pc, lr
++ .size __arm926_setup, . - __arm926_setup
+
+- .text
++ __INITDATA
+
+ /*
+ * Purpose : Function pointers used to access above functions - all calls
+@@ -436,7 +419,7 @@
+ */
+ .type arm926_processor_functions, #object
+ arm926_processor_functions:
+- .word v5tej_early_abort
++ .word v5tj_early_abort
+ .word cpu_arm926_proc_init
+ .word cpu_arm926_proc_fin
+ .word cpu_arm926_reset
+@@ -446,6 +429,8 @@
+ .word cpu_arm926_set_pte
+ .size arm926_processor_functions, . - arm926_processor_functions
+
++ .section ".rodata"
++
+ .type cpu_arch_name, #object
+ cpu_arch_name:
+ .asciz "armv5tej"
+@@ -455,14 +440,35 @@
+ cpu_elf_name:
+ .asciz "v5"
+ .size cpu_elf_name, . - cpu_elf_name
++
++ .type cpu_arm926_name, #object
++cpu_arm926_name:
++ .ascii "ARM926EJ-S"
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++ .ascii "i"
++#endif
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++ .ascii "d"
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++ .ascii "(wt)"
++#else
++ .ascii "(wb)"
++#endif
++#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
++ .ascii "RR"
++#endif
++#endif
++ .ascii "\0"
++ .size cpu_arm926_name, . - cpu_arm926_name
++
+ .align
+
+ .section ".proc.info", #alloc, #execinstr
+
+ .type __arm926_proc_info,#object
+ __arm926_proc_info:
+- .long 0x41009260
+- .long 0xff00fff0
++ .long 0x41069260 @ ARM926EJ-S (v5TEJ)
++ .long 0xff0ffff0
+ .long 0x00000c1e @ mmuflags
+ b __arm926_setup
+ .long cpu_arch_name
+Index: linux-2.6.0-test5/arch/arm/mm/proc-sa1100.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/proc-sa1100.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/proc-sa1100.S 2003-09-27 11:38:18.848662952 +0800
+@@ -1,5 +1,5 @@
+ /*
+- * linux/arch/arm/mm/proc-sa110.S
++ * linux/arch/arm/mm/proc-sa1100.S
+ *
+ * Copyright (C) 1997-2002 Russell King
+ *
+@@ -187,11 +187,11 @@
+
+ eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
+
+- bic r2, r1, #0xff0
+- bic r2, r2, #3
++ bic r2, r1, #PTE_SMALL_AP_MASK
++ bic r2, r2, #PTE_TYPE_MASK
+ orr r2, r2, #PTE_TYPE_SMALL
+
+- tst r1, #L_PTE_USER @ User or Exec?
++ tst r1, #L_PTE_USER @ User?
+ orrne r2, r2, #PTE_SMALL_AP_URO_SRW
+
+ tst r1, #L_PTE_WRITE | L_PTE_DIRTY @ Write and Dirty?
+@@ -206,15 +206,9 @@
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+-
+-cpu_sa1100_name:
+- .asciz "StrongARM-1100"
+-cpu_sa1110_name:
+- .asciz "StrongARM-1110"
+- .align
+-
+ __INIT
+
++ .type __sa1100_setup, #function
+ __sa1100_setup:
+ mov r10, #0
+ mcr p15, 0, r10, c7, c7 @ invalidate I,D caches on v4
+@@ -229,8 +223,9 @@
+ orr r0, r0, #0x003d
+ orr r0, r0, #0x3100 @ ..11 ...1 ..11 11.1
+ mov pc, lr
++ .size __sa1100_setup, . - __sa1100_setup
+
+- .text
++ __INITDATA
+
+ /*
+ * Purpose : Function pointers used to access above functions - all calls
+@@ -252,6 +247,8 @@
+ .word cpu_sa1100_set_pte
+ .size sa1100_processor_functions, . - sa1100_processor_functions
+
++ .section ".rodata"
++
+ .type cpu_arch_name, #object
+ cpu_arch_name:
+ .asciz "armv4"
+@@ -261,6 +258,17 @@
+ cpu_elf_name:
+ .asciz "v4"
+ .size cpu_elf_name, . - cpu_elf_name
++
++ .type cpu_sa1100_name, #object
++cpu_sa1100_name:
++ .asciz "StrongARM-1100"
++ .size cpu_sa1100_name, . - cpu_sa1100_name
++
++ .type cpu_sa1110_name, #object
++cpu_sa1110_name:
++ .asciz "StrongARM-1110"
++ .size cpu_sa1110_name, . - cpu_sa1110_name
++
+ .align
+
+ .section ".proc.info", #alloc, #execinstr
+Index: linux-2.6.0-test5/arch/arm/mm/proc-sa110.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/proc-sa110.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/proc-sa110.S 2003-09-27 11:38:18.851662496 +0800
+@@ -163,11 +163,11 @@
+
+ eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
+
+- bic r2, r1, #0xff0
+- bic r2, r2, #3
++ bic r2, r1, #PTE_SMALL_AP_MASK
++ bic r2, r2, #PTE_TYPE_MASK
+ orr r2, r2, #PTE_TYPE_SMALL
+
+- tst r1, #L_PTE_USER @ User or Exec?
++ tst r1, #L_PTE_USER @ User?
+ orrne r2, r2, #PTE_SMALL_AP_URO_SRW
+
+ tst r1, #L_PTE_WRITE | L_PTE_DIRTY @ Write and Dirty?
+@@ -182,13 +182,9 @@
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+-
+-cpu_sa110_name:
+- .asciz "StrongARM-110"
+- .align
+-
+ __INIT
+
++ .type __sa110_setup, #function
+ __sa110_setup:
+ mrc p15, 0, r0, c1, c0 @ get control register v4
+ bic r0, r0, #0x2e00 @ ..VI ZFRS BLDP WCAM
+@@ -203,8 +199,9 @@
+ mov r10, #0x1f @ Domains 0, 1 = client
+ mcr p15, 0, r10, c3, c0 @ load domain access register
+ mov pc, lr
++ .size __sa110_setup, . - __sa110_setup
+
+- .text
++ __INITDATA
+
+ /*
+ * Purpose : Function pointers used to access above functions - all calls
+@@ -218,16 +215,13 @@
+ .word cpu_sa110_proc_fin
+ .word cpu_sa110_reset
+ .word cpu_sa110_do_idle
+-
+- /* dcache */
+ .word cpu_sa110_dcache_clean_area
+-
+- /* pgtable */
+ .word cpu_sa110_switch_mm
+ .word cpu_sa110_set_pte
+-
+ .size sa110_processor_functions, . - sa110_processor_functions
+
++ .section ".rodata"
++
+ .type cpu_arch_name, #object
+ cpu_arch_name:
+ .asciz "armv4"
+@@ -237,6 +231,12 @@
+ cpu_elf_name:
+ .asciz "v4"
+ .size cpu_elf_name, . - cpu_elf_name
++
++ .type cpu_sa110_name, #object
++cpu_sa110_name:
++ .asciz "StrongARM-110"
++ .size cpu_sa110_name, . - cpu_sa110_name
++
+ .align
+
+ .section ".proc.info", #alloc, #execinstr
+Index: linux-2.6.0-test5/arch/arm/mm/proc-xscale.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/proc-xscale.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/proc-xscale.S 2003-09-27 11:38:18.856661736 +0800
+@@ -236,6 +236,9 @@
+ *
+ * - start - virtual start address
+ * - end - virtual end address
++ *
++ * Note: single I-cache line invalidation isn't used here since
++ * it also trashes the mini I-cache used by JTAG debuggers.
+ */
+ ENTRY(xscale_coherent_kern_range)
+ bic r0, r0, #CACHELINESIZE - 1
+@@ -568,22 +571,11 @@
+
+ .ltorg
+
+-cpu_80200_name:
+- .asciz "XScale-80200"
+-
+-cpu_80321_name:
+- .asciz "XScale-IOP80321"
+-
+-cpu_pxa250_name:
+- .asciz "XScale-PXA250"
+-
+-cpu_pxa210_name:
+- .asciz "XScale-PXA210"
+-
+ .align
+
+ __INIT
+
++ .type __xscale_setup, #function
+ __xscale_setup:
+ mov r0, #PSR_F_BIT|PSR_I_BIT|SVC_MODE
+ msr cpsr_c, r0
+@@ -602,8 +594,9 @@
+ orr r0, r0, #0x0005 @ .... .... .... .C.M
+ orr r0, r0, #0x3900 @ ..VI Z..S .... ....
+ mov pc, lr
++ .size __xscale_setup, . - __xscale_setup
+
+- .text
++ __INITDATA
+
+ /*
+ * Purpose : Function pointers used to access above functions - all calls
+@@ -612,7 +605,7 @@
+
+ .type xscale_processor_functions, #object
+ ENTRY(xscale_processor_functions)
+- .word xscale_abort
++ .word v5t_early_abort
+ .word cpu_xscale_proc_init
+ .word cpu_xscale_proc_fin
+ .word cpu_xscale_reset
+@@ -622,6 +615,8 @@
+ .word cpu_xscale_set_pte
+ .size xscale_processor_functions, . - xscale_processor_functions
+
++ .section ".rodata"
++
+ .type cpu_arch_name, #object
+ cpu_arch_name:
+ .asciz "armv5te"
+@@ -631,6 +626,27 @@
+ cpu_elf_name:
+ .asciz "v5"
+ .size cpu_elf_name, . - cpu_elf_name
++
++ .type cpu_80200_name, #object
++cpu_80200_name:
++ .asciz "XScale-80200"
++ .size cpu_80200_name, . - cpu_80200_name
++
++ .type cpu_80321_name, #object
++cpu_80321_name:
++ .asciz "XScale-IOP80321"
++ .size cpu_80321_name, . - cpu_80321_name
++
++ .type cpu_pxa250_name, #object
++cpu_pxa250_name:
++ .asciz "XScale-PXA250"
++ .size cpu_pxa250_name, . - cpu_pxa250_name
++
++ .type cpu_pxa210_name, #object
++cpu_pxa210_name:
++ .asciz "XScale-PXA210"
++ .size cpu_pxa210_name, . - cpu_pxa210_name
++
+ .align
+
+ .section ".proc.info", #alloc, #execinstr
+Index: linux-2.6.0-test5/arch/arm/mm/tlb-v3.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/tlb-v3.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/tlb-v3.S 2003-09-27 11:38:18.858661432 +0800
+@@ -42,7 +42,7 @@
+ blo 1b
+ mov pc, lr
+
+- __INIT
++ __INITDATA
+
+ .type v3_tlb_fns, #object
+ ENTRY(v3_tlb_fns)
+Index: linux-2.6.0-test5/arch/arm/mm/tlb-v4.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/tlb-v4.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/tlb-v4.S 2003-09-27 11:38:18.859661280 +0800
+@@ -34,7 +34,6 @@
+ act_mm r3 @ get current->active_mm
+ eors r3, ip, r3 @ == mm ?
+ movne pc, lr @ no, we dont do anything
+- vma_vm_flags ip, r2
+ .v4_flush_kern_tlb_range:
+ bic r0, r0, #0x0ff
+ bic r0, r0, #0xf00
+@@ -56,7 +55,7 @@
+ .globl v4_flush_kern_tlb_range
+ .equ v4_flush_kern_tlb_range, .v4_flush_kern_tlb_range
+
+- __INIT
++ __INITDATA
+
+ .type v4_tlb_fns, #object
+ ENTRY(v4_tlb_fns)
+Index: linux-2.6.0-test5/arch/arm/mm/tlb-v4wbi.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/tlb-v4wbi.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/tlb-v4wbi.S 2003-09-27 11:38:18.860661128 +0800
+@@ -58,7 +58,7 @@
+ blo 1b
+ mov pc, lr
+
+- __INIT
++ __INITDATA
+
+ .type v4wbi_tlb_fns, #object
+ ENTRY(v4wbi_tlb_fns)
+Index: linux-2.6.0-test5/arch/arm/mm/tlb-v4wb.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/tlb-v4wb.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/tlb-v4wb.S 2003-09-27 11:38:18.862660824 +0800
+@@ -67,7 +67,7 @@
+ blo 1b
+ mov pc, lr
+
+- __INIT
++ __INITDATA
+
+ .type v4wb_tlb_fns, #object
+ ENTRY(v4wb_tlb_fns)
+Index: linux-2.6.0-test5/arch/arm/nwfpe/fpa11.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/nwfpe/fpa11.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/nwfpe/fpa11.c 2003-09-27 11:38:18.863660672 +0800
+@@ -26,6 +26,7 @@
+ #include "fpmodule.h"
+ #include "fpmodule.inl"
+
++#include <linux/config.h>
+ #include <linux/compiler.h>
+ #include <linux/string.h>
+ #include <asm/system.h>
+Index: linux-2.6.0-test5/arch/arm/nwfpe/fpa11_cpdo.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/nwfpe/fpa11_cpdo.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/nwfpe/fpa11_cpdo.c 2003-09-27 11:38:18.865660368 +0800
+@@ -20,6 +20,7 @@
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
++#include <linux/config.h>
+ #include "fpa11.h"
+ #include "fpopcode.h"
+
+Index: linux-2.6.0-test5/arch/arm/nwfpe/fpa11_cpdt.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/nwfpe/fpa11_cpdt.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/nwfpe/fpa11_cpdt.c 2003-09-27 11:38:18.867660064 +0800
+@@ -20,6 +20,7 @@
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
++#include <linux/config.h>
+ #include "fpa11.h"
+ #include "softfloat.h"
+ #include "fpopcode.h"
+Index: linux-2.6.0-test5/arch/arm/nwfpe/fpa11_cprt.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/nwfpe/fpa11_cprt.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/nwfpe/fpa11_cprt.c 2003-09-27 11:38:18.870659608 +0800
+@@ -20,6 +20,7 @@
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
++#include <linux/config.h>
+ #include "fpa11.h"
+ #include "fpopcode.h"
+ #include "fpa11.inl"
+Index: linux-2.6.0-test5/arch/arm/nwfpe/fpa11.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/nwfpe/fpa11.h 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/nwfpe/fpa11.h 2003-09-27 11:38:18.872659304 +0800
+@@ -33,6 +33,7 @@
+
+ #define GET_USERREG() (user_registers)
+
++#include <linux/config.h>
+ #include <linux/thread_info.h>
+
+ /* includes */
+Index: linux-2.6.0-test5/arch/arm/nwfpe/fpopcode.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/nwfpe/fpopcode.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/nwfpe/fpopcode.c 2003-09-27 11:38:18.874659000 +0800
+@@ -19,6 +19,7 @@
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
++#include <linux/config.h>
+ #include "fpa11.h"
+ #include "softfloat.h"
+ #include "fpopcode.h"
+Index: linux-2.6.0-test5/arch/arm/nwfpe/fpopcode.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/nwfpe/fpopcode.h 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/nwfpe/fpopcode.h 2003-09-27 11:38:18.878658392 +0800
+@@ -23,6 +23,8 @@
+ #ifndef __FPOPCODE_H__
+ #define __FPOPCODE_H__
+
++#include <linux/config.h>
++
+ /*
+ ARM Floating Point Instruction Classes
+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+Index: linux-2.6.0-test5/arch/arm/nwfpe/softfloat.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/nwfpe/softfloat.h 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/nwfpe/softfloat.h 2003-09-27 11:38:18.883657632 +0800
+@@ -32,6 +32,8 @@
+ #ifndef __SOFTFLOAT_H__
+ #define __SOFTFLOAT_H__
+
++#include <linux/config.h>
++
+ /*
+ -------------------------------------------------------------------------------
+ The macro `FLOATX80' must be defined to enable the extended double-precision
+Index: linux-2.6.0-test5/arch/arm/tools/mach-types
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/tools/mach-types 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/tools/mach-types 2003-09-27 11:38:18.887657024 +0800
+@@ -6,7 +6,7 @@
+ # To add an entry into this database, please see Documentation/arm/README,
+ # or contact rmk@arm.linux.org.uk
+ #
+-# Last update: Sun Aug 3 16:26:10 2003
++# Last update: Thu Sep 18 17:15:55 2003
+ #
+ # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
+ #
+@@ -367,3 +367,21 @@
+ ixp2000 ARCH_IXP2000 IXP2000 356
+ xda SA1100_XDA XDA 357
+ csir_ims ARCH_CSIR_IMS CSIR_IMS 358
++ixp421_dnaeeth ARCH_IXP421_DNAEETH IXP421_DNAEETH 359
++pocketserv9200 ARCH_POCKETSERV9200 POCKETSERV9200 360
++toto ARCH_TOTO TOTO 361
++s3c2440 ARCH_S3C2440 S3C2440 362
++ks8695p ARCH_KS8695P KS8695P 363
++se4000 ARCH_SE4000 SE4000 364
++quadriceps ARCH_QUADRICEPS QUADRICEPS 365
++bronco ARCH_BRONCO BRONCO 366
++esl_wireless_tab ARCH_ESL_WIRELESS_TABLETESL_WIRELESS_TABLET 367
++esl_sofcomp ARCH_ESL_SOFCOMP ESL_SOFCOMP 368
++s5c7375 ARCH_S5C7375 S5C7375 369
++spearhead ARCH_SPEARHEAD SPEARHEAD 370
++pantera ARCH_PANTERA PANTERA 371
++prayoglite ARCH_PRAYOGLITE PRAYOGLITE 372
++gumstik ARCH_GUMSTIK GUMSTIK 373
++rcube ARCH_RCUBE RCUBE 374
++rea_olv ARCH_REA_OLV REA_OLV 375
++pxa_iphone ARCH_PXA_IPHONE PXA_IPHONE 376
+Index: linux-2.6.0-test5/arch/cris/arch-v10/boot/compressed/misc.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/cris/arch-v10/boot/compressed/misc.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/cris/arch-v10/boot/compressed/misc.c 2003-09-27 11:38:18.890656568 +0800
+@@ -115,7 +115,7 @@
+ {
+ void *p;
+
+- if (size <0) error("Malloc error\n");
++ if (size <0) error("Malloc error");
+
+ free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
+
+Index: linux-2.6.0-test5/arch/cris/mm/ioremap.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/cris/mm/ioremap.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/cris/mm/ioremap.c 2003-09-27 11:38:18.892656264 +0800
+@@ -157,7 +157,7 @@
+ if (!area)
+ return NULL;
+ addr = area->addr;
+- if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) {
++ if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
+ vfree(addr);
+ return NULL;
+ }
+Index: linux-2.6.0-test5/arch/h8300/kernel/signal.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/h8300/kernel/signal.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/h8300/kernel/signal.c 2003-09-27 11:38:18.897655504 +0800
+@@ -593,7 +593,7 @@
+ continue;
+
+ case SIGTSTP: case SIGTTIN: case SIGTTOU:
+- if (is_orphaned_pgrp(current->pgrp))
++ if (is_orphaned_pgrp(process_group(current)))
+ continue;
+ /* FALLTHRU */
+
+Index: linux-2.6.0-test5/arch/i386/boot98/compressed/misc.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/boot98/compressed/misc.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/boot98/compressed/misc.c 2003-09-27 11:38:18.901654896 +0800
+@@ -132,8 +132,8 @@
+ {
+ void *p;
+
+- if (size <0) error("Malloc error\n");
+- if (free_mem_ptr <= 0) error("Memory error\n");
++ if (size <0) error("Malloc error");
++ if (free_mem_ptr <= 0) error("Memory error");
+
+ free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
+
+@@ -141,7 +141,7 @@
+ free_mem_ptr += size;
+
+ if (free_mem_ptr >= free_mem_end_ptr)
+- error("\nOut of memory\n");
++ error("Out of memory");
+
+ return p;
+ }
+@@ -232,7 +232,7 @@
+ static int fill_inbuf(void)
+ {
+ if (insize != 0) {
+- error("ran out of input data\n");
++ error("ran out of input data");
+ }
+
+ inbuf = input_data;
+@@ -306,9 +306,9 @@
+ static void setup_normal_output_buffer(void)
+ {
+ #ifdef STANDARD_MEMORY_BIOS_CALL
+- if (EXT_MEM_K < 1024) error("Less than 2MB of memory.\n");
++ if (EXT_MEM_K < 1024) error("Less than 2MB of memory");
+ #else
+- if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < 1024) error("Less than 2MB of memory.\n");
++ if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < 1024) error("Less than 2MB of memory");
+ #endif
+ output_data = (char *)0x100000; /* Points to 1M */
+ free_mem_end_ptr = (long)real_mode;
+@@ -323,9 +323,9 @@
+ {
+ high_buffer_start = (uch *)(((ulg)&end) + HEAP_SIZE);
+ #ifdef STANDARD_MEMORY_BIOS_CALL
+- if (EXT_MEM_K < (3*1024)) error("Less than 4MB of memory.\n");
++ if (EXT_MEM_K < (3*1024)) error("Less than 4MB of memory");
+ #else
+- if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < (3*1024)) error("Less than 4MB of memory.\n");
++ if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < (3*1024)) error("Less than 4MB of memory");
+ #endif
+ mv->low_buffer_start = output_data = (char *)LOW_BUFFER_START;
+ low_buffer_end = ((unsigned int)real_mode > LOW_BUFFER_MAX
+Index: linux-2.6.0-test5/arch/i386/boot/compressed/misc.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/boot/compressed/misc.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/boot/compressed/misc.c 2003-09-27 11:38:18.904654440 +0800
+@@ -132,8 +132,8 @@
+ {
+ void *p;
+
+- if (size <0) error("Malloc error\n");
+- if (free_mem_ptr <= 0) error("Memory error\n");
++ if (size <0) error("Malloc error");
++ if (free_mem_ptr <= 0) error("Memory error");
+
+ free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
+
+@@ -141,7 +141,7 @@
+ free_mem_ptr += size;
+
+ if (free_mem_ptr >= free_mem_end_ptr)
+- error("\nOut of memory\n");
++ error("Out of memory");
+
+ return p;
+ }
+@@ -232,7 +232,7 @@
+ static int fill_inbuf(void)
+ {
+ if (insize != 0) {
+- error("ran out of input data\n");
++ error("ran out of input data");
+ }
+
+ inbuf = input_data;
+@@ -306,9 +306,9 @@
+ static void setup_normal_output_buffer(void)
+ {
+ #ifdef STANDARD_MEMORY_BIOS_CALL
+- if (EXT_MEM_K < 1024) error("Less than 2MB of memory.\n");
++ if (EXT_MEM_K < 1024) error("Less than 2MB of memory");
+ #else
+- if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < 1024) error("Less than 2MB of memory.\n");
++ if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < 1024) error("Less than 2MB of memory");
+ #endif
+ output_data = (char *)0x100000; /* Points to 1M */
+ free_mem_end_ptr = (long)real_mode;
+@@ -323,9 +323,9 @@
+ {
+ high_buffer_start = (uch *)(((ulg)&end) + HEAP_SIZE);
+ #ifdef STANDARD_MEMORY_BIOS_CALL
+- if (EXT_MEM_K < (3*1024)) error("Less than 4MB of memory.\n");
++ if (EXT_MEM_K < (3*1024)) error("Less than 4MB of memory");
+ #else
+- if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < (3*1024)) error("Less than 4MB of memory.\n");
++ if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < (3*1024)) error("Less than 4MB of memory");
+ #endif
+ mv->low_buffer_start = output_data = (char *)LOW_BUFFER_START;
+ low_buffer_end = ((unsigned int)real_mode > LOW_BUFFER_MAX
+Index: linux-2.6.0-test5/arch/i386/boot/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/boot/Makefile 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/boot/Makefile 2003-09-27 11:38:18.906654136 +0800
+@@ -99,4 +99,4 @@
+ if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
+
+ install: $(BOOTIMAGE)
+- sh $(src)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map "$(INSTALL_PATH)"
++ sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $< System.map "$(INSTALL_PATH)"
+Index: linux-2.6.0-test5/arch/i386/boot/setup.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/boot/setup.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/boot/setup.S 2003-09-27 11:38:18.914652920 +0800
+@@ -162,7 +162,7 @@
+ # can be located anywhere in
+ # low memory 0x10000 or higher.
+
+-ramdisk_max: .long MAXMEM-1 # (Header version 0x0203 or later)
++ramdisk_max: .long __MAXMEM-1 # (Header version 0x0203 or later)
+ # The highest safe address for
+ # the contents of an initrd
+
+@@ -506,6 +506,17 @@
+ movw $0xAA, (0x1ff) # device present
+ no_psmouse:
+
++#if defined(CONFIG_X86_SPEEDSTEP_SMI) || defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE)
++ movl $0x0000E980, %eax # IST Support
++ movl $0x47534943, %edx # Request value
++ int $0x15
++
++ movl %eax, (96)
++ movl %ebx, (100)
++ movl %ecx, (104)
++ movl %edx, (108)
++#endif
++
+ #if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
+ # Then check for an APM BIOS...
+ # %ds points to the bootsector
+Index: linux-2.6.0-test5/arch/i386/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/Kconfig 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/Kconfig 2003-09-27 11:38:18.926651096 +0800
+@@ -397,16 +397,53 @@
+ depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6
+ default y
+
+-config HUGETLB_PAGE
+- bool "Huge TLB Page Support"
++config X86_4G
++ bool "4 GB kernel-space and 4 GB user-space virtual memory support"
+ help
+- This enables support for huge pages. User space applications
+- can make use of this support with the sys_alloc_hugepages and
+- sys_free_hugepages system calls. If your applications are
+- huge page aware and your processor (Pentium or later for x86)
+- supports this, then say Y here.
++ This option is only useful for systems that have more than 1 GB
++ of RAM.
+
+- Otherwise, say N.
++ The default kernel VM layout leaves 1 GB of virtual memory for
++ kernel-space mappings, and 3 GB of VM for user-space applications.
++ This option ups both the kernel-space VM and the user-space VM to
++ 4 GB.
++
++ The cost of this option is additional TLB flushes done at
++ system-entry points that transition from user-mode into kernel-mode.
++ I.e. system calls and page faults, and IRQs that interrupt user-mode
++ code. There's also additional overhead to kernel operations that copy
++ memory to/from user-space. The overhead from this is hard to tell and
++ depends on the workload - it can be anything from no visible overhead
++ to 20-30% overhead. A good rule of thumb is to count with a runtime
++ overhead of 20%.
++
++ The upside is the much increased kernel-space VM, which more than
++ quadruples the maximum amount of RAM supported. Kernels compiled with
++ this option boot on 64GB of RAM and still have more than 3.1 GB of
++ 'lowmem' left. Another bonus is that highmem IO bouncing decreases,
++ if used with drivers that still use bounce-buffers.
++
++ There's also a 33% increase in user-space VM size - database
++ applications might see a boost from this.
++
++ But the cost of the TLB flushes and the runtime overhead has to be
++ weighed against the bonuses offered by the larger VM spaces. The
++ dividing line depends on the actual workload - there might be 4 GB
++ systems that benefit from this option. Systems with less than 4 GB
++ of RAM will rarely see a benefit from this option - but it's not
++ out of question, the exact circumstances have to be considered.
++
++config X86_SWITCH_PAGETABLES
++ def_bool X86_4G
++
++config X86_4G_VM_LAYOUT
++ def_bool X86_4G
++
++config X86_UACCESS_INDIRECT
++ def_bool X86_4G
++
++config X86_HIGH_ENTRY
++ def_bool X86_4G
+
+ config HPET_TIMER
+ bool "HPET Timer Support"
+@@ -454,6 +491,7 @@
+ config NR_CPUS
+ int "Maximum number of CPUs (2-255)"
+ depends on SMP
++ default "32" if X86_NUMAQ || X86_SUMMIT || X86_BIGSMP || X86_ES7000
+ default "8"
+ help
+ This allows you to specify the maximum number of CPUs which this
+@@ -814,49 +852,7 @@
+ menu "Power management options (ACPI, APM)"
+ depends on !X86_VOYAGER
+
+-config PM
+- bool "Power Management support"
+- ---help---
+- "Power Management" means that parts of your computer are shut
+- off or put into a power conserving "sleep" mode if they are not
+- being used. There are two competing standards for doing this: APM
+- and ACPI. If you want to use either one, say Y here and then also
+- to the requisite support below.
+-
+- Power Management is most important for battery powered laptop
+- computers; if you have a laptop, check out the Linux Laptop home
+- page on the WWW at
+- <http://www.cs.utexas.edu/users/kharker/linux-laptop/> and the
+- Battery Powered Linux mini-HOWTO, available from
+- <http://www.tldp.org/docs.html#howto>.
+-
+- Note that, even if you say N here, Linux on the x86 architecture
+- will issue the hlt instruction if nothing is to be done, thereby
+- sending the processor to sleep and saving power.
+-
+-config SOFTWARE_SUSPEND
+- bool "Software Suspend (EXPERIMENTAL)"
+- depends on EXPERIMENTAL && PM && SWAP
+- ---help---
+- Enable the possibilty of suspendig machine. It doesn't need APM.
+- You may suspend your machine by 'swsusp' or 'shutdown -z <time>'
+- (patch for sysvinit needed).
+-
+- It creates an image which is saved in your active swaps. By the next
+- booting the, pass 'resume=/dev/swappartition' and kernel will
+- detect the saved image, restore the memory from
+- it and then it continues to run as before you've suspended.
+- If you don't want the previous state to continue use the 'noresume'
+- kernel option. However note that your partitions will be fsck'd and
+- you must re-mkswap your swap partitions. It does not work with swap
+- files.
+-
+- Right now you may boot without resuming and then later resume but
+- in meantime you cannot use those swap partitions/files which were
+- involved in suspending. Also in this case there is a risk that buffers
+- on disk won't match with saved ones.
+-
+- For more information take a look at Documentation/swsusp.txt.
++source kernel/power/Kconfig
+
+ source "drivers/acpi/Kconfig"
+
+@@ -1293,6 +1289,15 @@
+ This results in a large slowdown, but helps to find certain types
+ of memory corruptions.
+
++config SPINLINE
++ bool "Spinlock inlining"
++ depends on DEBUG_KERNEL
++ help
++ This will change spinlocks from out of line to inline, making them
++ account cost to the callers in readprofile, rather than the lock
++ itself (as ".text.lock.filename"). This can be helpful for finding
++ the callers of locks.
++
+ config DEBUG_HIGHMEM
+ bool "Highmem debugging"
+ depends on DEBUG_KERNEL && HIGHMEM
+@@ -1309,20 +1314,208 @@
+ Say Y here only if you plan to use gdb to debug the kernel.
+ If you don't debug the kernel, you can say N.
+
++config LOCKMETER
++ bool "Kernel lock metering"
++ depends on SMP && !PREEMPT
++ help
++ Say Y to enable kernel lock metering, which adds overhead to SMP locks,
++ but allows you to see various statistics using the lockstat command.
++
+ config DEBUG_SPINLOCK_SLEEP
+ bool "Sleep-inside-spinlock checking"
+ help
+ If you say Y here, various routines which may sleep will become very
+ noisy if they are called with a spinlock held.
+
++config KGDB
++ bool "Include kgdb kernel debugger"
++ depends on DEBUG_KERNEL
++ help
++ If you say Y here, the system will be compiled with the debug
++ option (-g) and a debugging stub will be included in the
++ kernel. This stub communicates with gdb on another (host)
++ computer via a serial port. The host computer should have
++ access to the kernel binary file (vmlinux) and a serial port
++ that is connected to the target machine. Gdb can be made to
++ configure the serial port or you can use stty and setserial to
++ do this. See the 'target' command in gdb. This option also
++ configures in the ability to request a breakpoint early in the
++ boot process. To request the breakpoint just include 'kgdb'
++ as a boot option when booting the target machine. The system
++ will then break as soon as it looks at the boot options. This
++ option also installs a breakpoint in panic and sends any
++ kernel faults to the debugger. For more information see the
++ Documentation/i386/kgdb.txt file.
++
++choice
++ depends on KGDB
++ prompt "Debug serial port BAUD"
++ default KGDB_115200BAUD
++ help
++ Gdb and the kernel stub need to agree on the baud rate to be
++ used. Some systems (x86 family at this writing) allow this to
++ be configured.
++
++config KGDB_9600BAUD
++ bool "9600"
++
++config KGDB_19200BAUD
++ bool "19200"
++
++config KGDB_38400BAUD
++ bool "38400"
++
++config KGDB_57600BAUD
++ bool "57600"
++
++config KGDB_115200BAUD
++ bool "115200"
++endchoice
++
++config KGDB_PORT
++ hex "hex I/O port address of the debug serial port"
++ depends on KGDB
++ default 3f8
++ help
++ Some systems (x86 family at this writing) allow the port
++ address to be configured. The number entered is assumed to be
++ hex, don't put 0x in front of it. The standard address are:
++ COM1 3f8 , irq 4 and COM2 2f8 irq 3. Setserial /dev/ttySx
++ will tell you what you have. It is good to test the serial
++ connection with a live system before trying to debug.
++
++config KGDB_IRQ
++ int "IRQ of the debug serial port"
++ depends on KGDB
++ default 4
++ help
++ This is the irq for the debug port. If everything is working
++ correctly and the kernel has interrupts on a control C to the
++ port should cause a break into the kernel debug stub.
++
++config DEBUG_INFO
++ bool
++ depends on KGDB
++ default y
++
++config KGDB_MORE
++ bool "Add any additional compile options"
++ depends on KGDB
++ default n
++ help
++ Saying yes here turns on the ability to enter additional
++ compile options.
++
++
++config KGDB_OPTIONS
++ depends on KGDB_MORE
++ string "Additional compile arguments"
++ default "-O1"
++ help
++ This option allows you enter additional compile options for
++ the whole kernel compile. Each platform will have a default
++ that seems right for it. For example on PPC "-ggdb -O1", and
++ for i386 "-O1". Note that by configuring KGDB "-g" is already
++ turned on. In addition, on i386 platforms
++ "-fomit-frame-pointer" is deleted from the standard compile
++ options.
++
++config NO_KGDB_CPUS
++ int "Number of CPUs"
++ depends on KGDB && SMP
++ default NR_CPUS
++ help
++
++ This option sets the number of cpus for kgdb ONLY. It is used
++ to prune some internal structures so they look "nice" when
++ displayed with gdb. This is to overcome possibly larger
++ numbers that may have been entered above. Enter the real
++ number to get nice clean kgdb_info displays.
++
++config KGDB_TS
++ bool "Enable kgdb time stamp macros?"
++ depends on KGDB
++ default n
++ help
++ Kgdb event macros allow you to instrument your code with calls
++ to the kgdb event recording function. The event log may be
++ examined with gdb at a break point. Turning on this
++ capability also allows you to choose how many events to
++ keep. Kgdb always keeps the lastest events.
++
++choice
++ depends on KGDB_TS
++ prompt "Max number of time stamps to save?"
++ default KGDB_TS_128
++
++config KGDB_TS_64
++ bool "64"
++
++config KGDB_TS_128
++ bool "128"
++
++config KGDB_TS_256
++ bool "256"
++
++config KGDB_TS_512
++ bool "512"
++
++config KGDB_TS_1024
++ bool "1024"
++
++endchoice
++
++config STACK_OVERFLOW_TEST
++ bool "Turn on kernel stack overflow testing?"
++ depends on KGDB
++ default n
++ help
++ This option enables code in the front line interrupt handlers
++ to check for kernel stack overflow on interrupts and system
++ calls. This is part of the kgdb code on x86 systems.
++
++config KGDB_CONSOLE
++ bool "Enable serial console thru kgdb port"
++ depends on KGDB
++ default n
++ help
++ This option enables the command line "console=kgdb" option.
++ When the system is booted with this option in the command line
++ all kernel printk output is sent to gdb (as well as to other
++ consoles). For this to work gdb must be connected. For this
++ reason, this command line option will generate a breakpoint if
++ gdb has not yet connected. After the gdb continue command is
++ given all pent up console output will be printed by gdb on the
++ host machine. Neither this option, nor KGDB require the
++ serial driver to be configured.
++
++config KGDB_SYSRQ
++ bool "Turn on SysRq 'G' command to do a break?"
++ depends on KGDB
++ default y
++ help
++ This option includes an option in the SysRq code that allows
++ you to enter SysRq G which generates a breakpoint to the KGDB
++ stub. This will work if the keyboard is alive and can
++ interrupt the system. Because of constraints on when the
++ serial port interrupt can be enabled, this code may allow you
++ to interrupt the system before the serial port control C is
++ available. Just say yes here.
++
+ config FRAME_POINTER
+ bool "Compile the kernel with frame pointers"
++ default KGDB
+ help
+ If you say Y here the resulting kernel image will be slightly larger
+ and slower, but it will give very useful debugging information.
+ If you don't debug the kernel, you can say N, but we may not be able
+ to solve problems without frame pointers.
+
++config MAGIC_SYSRQ
++ bool
++ depends on KGDB_SYSRQ
++ default y
++
+ config X86_EXTRA_IRQS
+ bool
+ depends on X86_LOCAL_APIC || X86_VOYAGER
+Index: linux-2.6.0-test5/arch/i386/kernel/acpi/boot.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/acpi/boot.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/acpi/boot.c 2003-09-27 11:38:18.930650488 +0800
+@@ -183,8 +183,7 @@
+
+ #endif /*CONFIG_X86_LOCAL_APIC*/
+
+-#ifdef CONFIG_X86_IO_APIC
+-
++#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_ACPI_INTERPRETER)
+
+ static int __init
+ acpi_parse_ioapic (
+@@ -368,7 +367,6 @@
+
+ result = acpi_table_parse(ACPI_APIC, acpi_parse_madt);
+ if (!result) {
+- printk(KERN_WARNING PREFIX "MADT not present\n");
+ return 0;
+ }
+ else if (result < 0) {
+@@ -416,7 +414,7 @@
+
+ #endif /*CONFIG_X86_LOCAL_APIC*/
+
+-#ifdef CONFIG_X86_IO_APIC
++#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_ACPI_INTERPRETER)
+
+ /*
+ * I/O APIC
+@@ -472,7 +470,8 @@
+ acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC;
+
+ acpi_ioapic = 1;
+-#endif /*CONFIG_X86_IO_APIC*/
++
++#endif /* CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER */
+
+ #ifdef CONFIG_X86_LOCAL_APIC
+ if (acpi_lapic && acpi_ioapic) {
+@@ -480,6 +479,7 @@
+ clustered_apic_check();
+ }
+ #endif
++
+ #ifdef CONFIG_HPET_TIMER
+ acpi_table_parse(ACPI_HPET, acpi_parse_hpet);
+ #endif
+Index: linux-2.6.0-test5/arch/i386/kernel/apm.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/apm.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/apm.c 2003-09-27 11:38:18.946648056 +0800
+@@ -2008,7 +2008,7 @@
+ if (apm_proc)
+ apm_proc->owner = THIS_MODULE;
+
+- kernel_thread(apm, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
++ kernel_thread(apm, NULL, CLONE_KERNEL | SIGCHLD);
+
+ if (num_online_cpus() > 1 && !smp ) {
+ printk(KERN_NOTICE
+Index: linux-2.6.0-test5/arch/i386/kernel/asm-offsets.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/asm-offsets.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/asm-offsets.c 2003-09-27 11:38:18.948647752 +0800
+@@ -4,9 +4,11 @@
+ * to extract and format the required data.
+ */
+
++#include <linux/sched.h>
+ #include <linux/signal.h>
+ #include <asm/ucontext.h>
+ #include "sigframe.h"
++#include <asm/fixmap.h>
+
+ #define DEFINE(sym, val) \
+ asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+@@ -28,4 +30,17 @@
+
+ DEFINE(RT_SIGFRAME_sigcontext,
+ offsetof (struct rt_sigframe, uc.uc_mcontext));
++ DEFINE(TI_task, offsetof (struct thread_info, task));
++ DEFINE(TI_exec_domain, offsetof (struct thread_info, exec_domain));
++ DEFINE(TI_flags, offsetof (struct thread_info, flags));
++ DEFINE(TI_preempt_count, offsetof (struct thread_info, preempt_count));
++ DEFINE(TI_addr_limit, offsetof (struct thread_info, addr_limit));
++ DEFINE(TI_real_stack, offsetof (struct thread_info, real_stack));
++ DEFINE(TI_virtual_stack, offsetof (struct thread_info, virtual_stack));
++ DEFINE(TI_user_pgd, offsetof (struct thread_info, user_pgd));
++
++ DEFINE(FIX_ENTRY_TRAMPOLINE_0_addr, __fix_to_virt(FIX_ENTRY_TRAMPOLINE_0));
++ DEFINE(FIX_VSYSCALL_addr, __fix_to_virt(FIX_VSYSCALL));
++ DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
++ DEFINE(task_thread_db7, offsetof (struct task_struct, thread.debugreg[7]));
+ }
+Index: linux-2.6.0-test5/arch/i386/kernel/cpu/common.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/cpu/common.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/cpu/common.c 2003-09-27 11:38:18.952647144 +0800
+@@ -510,16 +510,20 @@
+ BUG();
+ enter_lazy_tlb(&init_mm, current);
+
+- load_esp0(t, thread->esp0);
+- set_tss_desc(cpu,t);
++ t->esp0 = thread->esp0;
++ set_tss_desc(cpu, t);
+ cpu_gdt_table[cpu][GDT_ENTRY_TSS].b &= 0xfffffdff;
+ load_TR_desc();
+- load_LDT(&init_mm.context);
++ if (cpu)
++ load_LDT(&init_mm.context);
+
+ /* Set up doublefault TSS pointer in the GDT */
+ __set_tss_desc(cpu, GDT_ENTRY_DOUBLEFAULT_TSS, &doublefault_tss);
+ cpu_gdt_table[cpu][GDT_ENTRY_DOUBLEFAULT_TSS].b &= 0xfffffdff;
+
++ if (cpu)
++ trap_init_virtual_GDT();
++
+ /* Clear %fs and %gs. */
+ asm volatile ("xorl %eax, %eax; movl %eax, %fs; movl %eax, %gs");
+
+Index: linux-2.6.0-test5/arch/i386/kernel/cpu/cpufreq/acpi.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/cpu/cpufreq/acpi.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/cpu/cpufreq/acpi.c 2003-09-27 11:38:18.957646384 +0800
+@@ -24,6 +24,7 @@
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
++#include <linux/config.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+Index: linux-2.6.0-test5/arch/i386/kernel/cpu/cpufreq/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/cpu/cpufreq/Kconfig 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/cpu/cpufreq/Kconfig 2003-09-27 11:38:18.960645928 +0800
+@@ -99,34 +99,46 @@
+
+ If in doubt, say N.
+
++config X86_SPEEDSTEP_CENTRINO
++ tristate "Intel Enhanced SpeedStep"
++ depends on CPU_FREQ_TABLE
++ help
++ This adds the CPUFreq driver for Enhanced SpeedStep enabled
++ mobile CPUs. This means Intel Pentium M (Centrino) CPUs.
++
++ For details, take a look at linux/Documentation/cpu-freq.
++
++ If in doubt, say N.
++
+ config X86_SPEEDSTEP_ICH
+- tristate "Intel Speedstep"
++ tristate "Intel Speedstep on ICH-M chipsets (ioport interface)"
+ depends on CPU_FREQ_TABLE
+ help
+ This adds the CPUFreq driver for certain mobile Intel Pentium III
+ (Coppermine), all mobile Intel Pentium III-M (Tualatin) and all
+- mobile Intel Pentium 4 P4-Ms, with an Intel ICH2, ICH3,
+- or ICH4 southbridge.
++ mobile Intel Pentium 4 P4-M on systems which have an Intel ICH2,
++ ICH3 or ICH4 southbridge.
+
+ For details, take a look at linux/Documentation/cpu-freq.
+
+ If in doubt, say N.
+
+-config X86_SPEEDSTEP_CENTRINO
+- tristate "Intel Enhanced SpeedStep"
+- depends on CPU_FREQ_TABLE
++config X86_SPEEDSTEP_SMI
++ tristate "Intel SpeedStep on 440BX/ZX/MX chipsets (SMI interface)"
++ depends on CPU_FREQ_TABLE && EXPERIMENTAL
+ help
+- This adds the CPUFreq driver for Enhanced SpeedStep enabled
+- mobile CPUs. This means Intel Pentium M (Centrino) CPUs.
+-
+- For details, take a look at linux/Documentation/cpu-freq.
+-
++ This adds the CPUFreq driver for certain mobile Intel Pentium III
++ (Coppermine), all mobile Intel Pentium III-M (Tualatin)
++ on systems which have an Intel 440BX/ZX/MX southbridge.
++
++ For details, take a look at linux/Documentation/cpu-freq.
++
+ If in doubt, say N.
+
+ config X86_SPEEDSTEP_LIB
+- tristate
+- depends on X86_SPEEDSTEP_ICH
+- default X86_SPEEDSTEP_ICH
++ tristate
++ depends on (X86_SPEEDSTEP_ICH || X86_SPEEDSTEP_SMI)
++ default (X86_SPEEDSTEP_ICH || X86_SPEEDSTEP_SMI)
+
+ config X86_P4_CLOCKMOD
+ tristate "Intel Pentium 4 clock modulation"
+Index: linux-2.6.0-test5/arch/i386/kernel/cpu/cpufreq/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/cpu/cpufreq/Makefile 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/cpu/cpufreq/Makefile 2003-09-27 11:38:18.961645776 +0800
+@@ -9,6 +9,7 @@
+ obj-$(CONFIG_X86_SPEEDSTEP_ICH) += speedstep-ich.o
+ obj-$(CONFIG_X86_SPEEDSTEP_CENTRINO) += speedstep-centrino.o
+ obj-$(CONFIG_X86_SPEEDSTEP_LIB) += speedstep-lib.o
++obj-$(CONFIG_X86_SPEEDSTEP_SMI) += speedstep-smi.o
+
+ ifdef CONFIG_X86_ACPI_CPUFREQ
+ ifdef CONFIG_ACPI_DEBUG
+Index: linux-2.6.0-test5/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c 2003-09-27 11:38:18.964645320 +0800
+@@ -20,6 +20,7 @@
+ *
+ */
+
++#include <linux/config.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+Index: linux-2.6.0-test5/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/cpu/cpufreq/powernow-k7.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/cpu/cpufreq/powernow-k7.c 2003-09-27 11:38:18.967644864 +0800
+@@ -14,6 +14,7 @@
+ * - We disable half multipliers if ACPI is used on A0 stepping CPUs.
+ */
+
++#include <linux/config.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+@@ -191,10 +192,11 @@
+ {
+ union msr_fidvidctl fidvidctl;
+
++ rdmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
+ if (fidvidctl.bits.FID != fid) {
+- rdmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
+ fidvidctl.bits.SGTC = latency;
+ fidvidctl.bits.FID = fid;
++ fidvidctl.bits.VIDC = 0;
+ fidvidctl.bits.FIDC = 1;
+ wrmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
+ }
+@@ -205,9 +207,11 @@
+ {
+ union msr_fidvidctl fidvidctl;
+
++ rdmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
+ if (fidvidctl.bits.VID != vid) {
+- rdmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
++ fidvidctl.bits.SGTC = latency;
+ fidvidctl.bits.VID = vid;
++ fidvidctl.bits.FIDC = 0;
+ fidvidctl.bits.VIDC = 1;
+ wrmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
+ }
+@@ -297,8 +301,14 @@
+ dprintk (" voltage regulator)\n");
+
+ latency = psb->settlingtime;
++ if (latency < 100) {
++ printk (KERN_INFO PFX "BIOS set settling time to %d microseconds."
++ "Should be at least 100. Correcting.\n", latency);
++ latency = 100;
++ }
+ dprintk (KERN_INFO PFX "Settling Time: %d microseconds.\n", psb->settlingtime);
+ dprintk (KERN_INFO PFX "Has %d PST tables. (Only dumping ones relevant to this CPU).\n", psb->numpst);
++ latency *= 100; /* SGTC needs to be in units of 10ns */
+
+ p += sizeof (struct psb_s);
+
+Index: linux-2.6.0-test5/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c 2003-09-27 11:38:18.432726184 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c 2003-09-27 11:38:18.968644712 +0800
+@@ -0,0 +1,362 @@
++/*
++ * Intel SpeedStep SMI driver.
++ *
++ * (C) 2003 Hiroshi Miura <miura@da-cha.org>
++ *
++ * Licensed under the terms of the GNU GPL License version 2.
++ *
++ */
++
++
++/*********************************************************************
++ * SPEEDSTEP - DEFINITIONS *
++ *********************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/init.h>
++#include <linux/cpufreq.h>
++#include <linux/pci.h>
++#include <linux/slab.h>
++#include <asm/ist.h>
++
++#include "speedstep-lib.h"
++
++#define PFX "speedstep-smi: "
++
++/* speedstep system management interface port/command.
++ *
++ * These parameters are got from IST-SMI BIOS call.
++ * If user gives it, these are used.
++ *
++ */
++static int smi_port = 0;
++static int smi_cmd = 0;
++static unsigned int smi_sig = 0;
++
++
++/*
++ * There are only two frequency states for each processor. Values
++ * are in kHz for the time being.
++ */
++static struct cpufreq_frequency_table speedstep_freqs[] = {
++ {SPEEDSTEP_HIGH, 0},
++ {SPEEDSTEP_LOW, 0},
++ {0, CPUFREQ_TABLE_END},
++};
++
++#define GET_SPEEDSTEP_OWNER 0
++#define GET_SPEEDSTEP_STATE 1
++#define SET_SPEEDSTEP_STATE 2
++#define GET_SPEEDSTEP_FREQS 4
++
++/* DEBUG
++ * Define it if you want verbose debug output, e.g. for bug reporting
++ */
++#define SPEEDSTEP_DEBUG
++
++#ifdef SPEEDSTEP_DEBUG
++#define dprintk(msg...) printk(msg)
++#else
++#define dprintk(msg...) do { } while(0)
++#endif
++
++/**
++ * speedstep_smi_ownership
++ */
++static int speedstep_smi_ownership (void)
++{
++ u32 command, result, magic;
++ u32 function = GET_SPEEDSTEP_OWNER;
++ unsigned char magic_data[] = "Copyright (c) 1999 Intel Corporation";
++
++ command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff);
++ magic = virt_to_phys(magic_data);
++
++ __asm__ __volatile__(
++ "out %%al, (%%dx)\n"
++ : "=D" (result)
++ : "a" (command), "b" (function), "c" (0), "d" (smi_port), "D" (0), "S" (magic)
++ );
++
++ return result;
++}
++
++/**
++ * speedstep_smi_get_freqs - get SpeedStep preferred & current freq.
++ *
++ */
++static int speedstep_smi_get_freqs (unsigned int *low, unsigned int *high)
++{
++ u32 command, result, edi, high_mhz, low_mhz;
++ u32 state=0;
++ u32 function = GET_SPEEDSTEP_FREQS;
++
++ command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff);
++
++ __asm__ __volatile__("movl $0, %%edi\n"
++ "out %%al, (%%dx)\n"
++ : "=a" (result), "=b" (high_mhz), "=c" (low_mhz), "=d" (state), "=D" (edi)
++ : "a" (command), "b" (function), "c" (state), "d" (smi_port), "S" (0)
++ );
++ *high = high_mhz * 1000;
++ *low = low_mhz * 1000;
++
++ return result;
++}
++
++/**
++ * speedstep_get_state - set the SpeedStep state
++ * @state: processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH)
++ *
++ */
++static int speedstep_get_state (void)
++{
++ u32 function=GET_SPEEDSTEP_STATE;
++ u32 result, state, edi, command;
++
++ command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff);
++
++ __asm__ __volatile__("movl $0, %%edi\n"
++ "out %%al, (%%dx)\n"
++ : "=a" (result), "=b" (state), "=D" (edi)
++ : "a" (command), "b" (function), "c" (0), "d" (smi_port), "S" (0)
++ );
++
++ return state;
++}
++
++/**
++ * speedstep_set_state - set the SpeedStep state
++ * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH)
++ *
++ */
++static void speedstep_set_state (unsigned int state, unsigned int notify)
++{
++ unsigned int old_state, result, command, new_state;
++ unsigned long flags;
++ struct cpufreq_freqs freqs;
++ unsigned int function=SET_SPEEDSTEP_STATE;
++
++ if (state > 0x1)
++ return;
++
++ old_state = speedstep_get_state();
++ freqs.old = speedstep_freqs[old_state].frequency;
++ freqs.new = speedstep_freqs[state].frequency;
++ freqs.cpu = 0; /* speedstep.c is UP only driver */
++
++ if (old_state == state)
++ return;
++
++ if (notify)
++ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
++
++ /* Disable IRQs */
++ local_irq_save(flags);
++
++ command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff);
++ __asm__ __volatile__(
++ "movl $0, %%edi\n"
++ "out %%al, (%%dx)\n"
++ : "=b" (new_state), "=D" (result)
++ : "a" (command), "b" (function), "c" (state), "d" (smi_port), "S" (0)
++ );
++
++ /* enable IRQs */
++ local_irq_restore(flags);
++
++ if (new_state == state) {
++ dprintk(KERN_INFO "cpufreq: change to %u MHz succeded\n", (freqs.new / 1000));
++ } else {
++ printk(KERN_ERR "cpufreq: change failed\n");
++ }
++
++ if (notify)
++ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
++
++ return;
++}
++
++
++/**
++ * speedstep_target - set a new CPUFreq policy
++ * @policy: new policy
++ * @target_freq: new freq
++ * @relation:
++ *
++ * Sets a new CPUFreq policy/freq.
++ */
++static int speedstep_target (struct cpufreq_policy *policy,
++ unsigned int target_freq, unsigned int relation)
++{
++ unsigned int newstate = 0;
++
++ if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0], target_freq, relation, &newstate))
++ return -EINVAL;
++
++ speedstep_set_state(newstate, 1);
++
++ return 0;
++}
++
++
++/**
++ * speedstep_verify - verifies a new CPUFreq policy
++ * @freq: new policy
++ *
++ * Limit must be within speedstep_low_freq and speedstep_high_freq, with
++ * at least one border included.
++ */
++static int speedstep_verify (struct cpufreq_policy *policy)
++{
++ return cpufreq_frequency_table_verify(policy, &speedstep_freqs[0]);
++}
++
++
++static int speedstep_cpu_init(struct cpufreq_policy *policy)
++{
++ int result;
++ unsigned int speed,state;
++
++ /* capability check */
++ if (policy->cpu != 0)
++ return -ENODEV;
++
++ result = speedstep_smi_ownership();
++
++ if (result)
++ dprintk(KERN_INFO "cpufreq: fails an aquiring ownership of a SMI interface.\n");
++
++ /* detect low and high frequency */
++ result = speedstep_smi_get_freqs(&speedstep_freqs[SPEEDSTEP_LOW].frequency,
++ &speedstep_freqs[SPEEDSTEP_HIGH].frequency);
++ if (result) {
++ /* fall back to speedstep_lib.c dection mechanism: try both states out */
++ unsigned int speedstep_processor = speedstep_detect_processor();
++
++ dprintk(KERN_INFO PFX "could not detect low and high frequencies by SMI call.\n");
++ if (!speedstep_processor)
++ return -ENODEV;
++
++ result = speedstep_get_freqs(speedstep_processor,
++ &speedstep_freqs[SPEEDSTEP_LOW].frequency,
++ &speedstep_freqs[SPEEDSTEP_HIGH].frequency,
++ &speedstep_set_state);
++
++ if (result) {
++ dprintk(KERN_INFO PFX "could not detect two different speeds -- aborting.\n");
++ return result;
++ } else
++ dprintk(KERN_INFO PFX "workaround worked.\n");
++ }
++
++ /* get current speed setting */
++ state = speedstep_get_state();
++ speed = speedstep_freqs[state].frequency;
++
++ dprintk(KERN_INFO "cpufreq: currently at %s speed setting - %i MHz\n",
++ (speed == speedstep_freqs[SPEEDSTEP_LOW].frequency) ? "low" : "high",
++ (speed / 1000));
++
++ /* cpuinfo and default policy values */
++ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
++ policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
++ policy->cur = speed;
++
++ return cpufreq_frequency_table_cpuinfo(policy, &speedstep_freqs[0]);
++}
++
++
++static int speedstep_resume(struct cpufreq_policy *policy)
++{
++ int result = speedstep_smi_ownership();
++
++ if (result)
++ dprintk(KERN_INFO "cpufreq: fails an aquiring ownership of a SMI interface.\n");
++
++ return result;
++}
++
++
++static struct cpufreq_driver speedstep_driver = {
++ .name = "speedstep-smi",
++ .verify = speedstep_verify,
++ .target = speedstep_target,
++ .init = speedstep_cpu_init,
++ .resume = speedstep_resume,
++};
++
++/**
++ * speedstep_init - initializes the SpeedStep CPUFreq driver
++ *
++ * Initializes the SpeedStep support. Returns -ENODEV on unsupported
++ * BIOS, -EINVAL on problems during initiatization, and zero on
++ * success.
++ */
++static int __init speedstep_init(void)
++{
++ struct cpuinfo_x86 *c = cpu_data;
++
++ if (c->x86_vendor != X86_VENDOR_INTEL) {
++ printk (KERN_INFO PFX "No Intel CPU detected.\n");
++ return -ENODEV;
++ }
++
++ dprintk(KERN_DEBUG PFX "signature:0x%.8lx, command:0x%.8lx, event:0x%.8lx, perf_level:0x%.8lx.\n",
++ ist_info.signature, ist_info.command, ist_info.event, ist_info.perf_level);
++
++
++ /* Error if no IST-SMI BIOS or no PARM
++ sig= 'ISGE' aka 'Intel Speedstep Gate E' */
++ if ((ist_info.signature != 0x47534943) && (
++ (smi_port == 0) || (smi_cmd == 0)))
++ return -ENODEV;
++
++ if (smi_sig == 1)
++ smi_sig = 0x47534943;
++ else
++ smi_sig = ist_info.signature;
++
++ /* setup smi_port from MODLULE_PARM or BIOS */
++ if ((smi_port > 0xff) || (smi_port < 0)) {
++ return -EINVAL;
++ } else if (smi_port == 0) {
++ smi_port = ist_info.command & 0xff;
++ }
++
++ if ((smi_cmd > 0xff) || (smi_cmd < 0)) {
++ return -EINVAL;
++ } else if (smi_cmd == 0) {
++ smi_cmd = (ist_info.command >> 16) & 0xff;
++ }
++
++ return cpufreq_register_driver(&speedstep_driver);
++}
++
++
++/**
++ * speedstep_exit - unregisters SpeedStep support
++ *
++ * Unregisters SpeedStep support.
++ */
++static void __exit speedstep_exit(void)
++{
++ cpufreq_unregister_driver(&speedstep_driver);
++}
++
++module_param(smi_port, int, 0444);
++module_param(smi_cmd, int, 0444);
++module_param(smi_sig, uint, 0444);
++
++MODULE_PARM_DESC(smi_port, "Override the BIOS-given IST port with this value -- Intel's default setting is 0xb2");
++MODULE_PARM_DESC(smi_cmd, "Override the BIOS-given IST command with this value -- Intel's default setting is 0x82");
++MODULE_PARM_DESC(smi_sig, "Set to 1 to fake the IST signature when using the SMI interface.");
++
++MODULE_AUTHOR ("Hiroshi Miura");
++MODULE_DESCRIPTION ("Speedstep driver for IST applet SMI interface.");
++MODULE_LICENSE ("GPL");
++
++module_init(speedstep_init);
++module_exit(speedstep_exit);
+Index: linux-2.6.0-test5/arch/i386/kernel/cpu/intel.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/cpu/intel.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/cpu/intel.c 2003-09-27 11:38:18.972644104 +0800
+@@ -8,11 +8,10 @@
+ #include <asm/processor.h>
+ #include <asm/msr.h>
+ #include <asm/uaccess.h>
++#include <asm/desc.h>
+
+ #include "cpu.h"
+
+-extern int trap_init_f00f_bug(void);
+-
+ #ifdef CONFIG_X86_INTEL_USERCOPY
+ /*
+ * Alignment at which movsl is preferred for bulk memory copies.
+@@ -157,14 +156,14 @@
+
+ c->f00f_bug = 1;
+ if ( !f00f_workaround_enabled ) {
+- trap_init_f00f_bug();
++ trap_init_virtual_IDT();
+ printk(KERN_NOTICE "Intel Pentium with F0 0F bug - workaround enabled.\n");
+ f00f_workaround_enabled = 1;
+ }
+ }
+ #endif
+
+-
++ select_idle_routine(c);
+ if (c->cpuid_level > 1) {
+ /* supports eax=2 call */
+ int i, j, n;
+Index: linux-2.6.0-test5/arch/i386/kernel/cpu/mtrr/if.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/cpu/mtrr/if.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/cpu/mtrr/if.c 2003-09-27 11:38:18.975643648 +0800
+@@ -13,7 +13,6 @@
+ /* RED-PEN: this is accessed without any locking */
+ extern unsigned int *usage_table;
+
+-static int mtrr_seq_show(struct seq_file *seq, void *offset);
+
+ #define FILE_FCOUNT(f) (((struct seq_file *)((f)->private_data))->private)
+
+@@ -33,6 +32,8 @@
+ return (x <= 6) ? mtrr_strings[x] : "?";
+ }
+
++#ifdef CONFIG_PROC_FS
++
+ static int
+ mtrr_file_add(unsigned long base, unsigned long size,
+ unsigned int type, char increment, struct file *file, int page)
+@@ -291,6 +292,8 @@
+ return single_release(ino, file);
+ }
+
++static int mtrr_seq_show(struct seq_file *seq, void *offset);
++
+ static int mtrr_open(struct inode *inode, struct file *file)
+ {
+ if (!mtrr_if)
+@@ -310,11 +313,9 @@
+ .release = mtrr_close,
+ };
+
+-# ifdef CONFIG_PROC_FS
+
+ static struct proc_dir_entry *proc_root_mtrr;
+
+-# endif /* CONFIG_PROC_FS */
+
+ static int mtrr_seq_show(struct seq_file *seq, void *offset)
+ {
+@@ -351,15 +352,14 @@
+
+ static int __init mtrr_if_init(void)
+ {
+-#ifdef CONFIG_PROC_FS
+ proc_root_mtrr =
+ create_proc_entry("mtrr", S_IWUSR | S_IRUGO, &proc_root);
+ if (proc_root_mtrr) {
+ proc_root_mtrr->owner = THIS_MODULE;
+ proc_root_mtrr->proc_fops = &mtrr_fops;
+ }
+-#endif
+ return 0;
+ }
+
+ arch_initcall(mtrr_if_init);
++#endif /* CONFIG_PROC_FS */
+Index: linux-2.6.0-test5/arch/i386/kernel/dmi_scan.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/dmi_scan.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/dmi_scan.c 2003-09-27 11:38:18.984642280 +0800
+@@ -939,11 +939,6 @@
+ MATCH(DMI_BOARD_NAME, "CUR-DLS"),
+ NO_MATCH, NO_MATCH }},
+
+- { force_acpi_ht, "ASUS A7V", {
+- MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"),
+- MATCH(DMI_BOARD_NAME, "<A7V>"),
+- MATCH(DMI_BIOS_VERSION, "ASUS A7V ACPI BIOS Revision 1011"), NO_MATCH }},
+-
+ { force_acpi_ht, "ABIT i440BX-W83977", {
+ MATCH(DMI_BOARD_VENDOR, "ABIT <http://www.abit.com>"),
+ MATCH(DMI_BOARD_NAME, "i440BX-W83977 (BP6)"),
+@@ -978,7 +973,10 @@
+ { disable_acpi_pci, "ASUS A7V", {
+ MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"),
+ MATCH(DMI_BOARD_NAME, "<A7V>"),
+- MATCH(DMI_BIOS_VERSION, "ASUS A7V ACPI BIOS Revision 1007"), NO_MATCH }},
++ /* newer BIOS, Revision 1011, does work */
++ MATCH(DMI_BIOS_VERSION, "ASUS A7V ACPI BIOS Revision 1007"),
++ NO_MATCH }},
++
+ #endif
+
+ { NULL, }
+Index: linux-2.6.0-test5/arch/i386/kernel/doublefault.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/doublefault.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/doublefault.c 2003-09-27 11:38:18.985642128 +0800
+@@ -7,12 +7,13 @@
+ #include <asm/uaccess.h>
+ #include <asm/pgtable.h>
+ #include <asm/desc.h>
++#include <asm/fixmap.h>
+
+ #define DOUBLEFAULT_STACKSIZE (1024)
+ static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
+ #define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
+
+-#define ptr_ok(x) ((x) > 0xc0000000 && (x) < 0xc1000000)
++#define ptr_ok(x) (((x) > __PAGE_OFFSET && (x) < (__PAGE_OFFSET + 0x01000000)) || ((x) >= FIXADDR_START))
+
+ static void doublefault_fn(void)
+ {
+@@ -38,8 +39,8 @@
+
+ printk("eax = %08lx, ebx = %08lx, ecx = %08lx, edx = %08lx\n",
+ t->eax, t->ebx, t->ecx, t->edx);
+- printk("esi = %08lx, edi = %08lx\n",
+- t->esi, t->edi);
++ printk("esi = %08lx, edi = %08lx, ebp = %08lx\n",
++ t->esi, t->edi, t->ebp);
+ }
+ }
+
+Index: linux-2.6.0-test5/arch/i386/kernel/entry.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/entry.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/entry.S 2003-09-27 11:38:18.991641216 +0800
+@@ -43,11 +43,25 @@
+ #include <linux/config.h>
+ #include <linux/linkage.h>
+ #include <asm/thread_info.h>
++#include <asm/asm_offsets.h>
+ #include <asm/errno.h>
+ #include <asm/segment.h>
++#include <asm/page.h>
+ #include <asm/smp.h>
+ #include <asm/page.h>
+ #include "irq_vectors.h"
++ /* We do not recover from a stack overflow, but at least
++ * we know it happened and should be able to track it down.
++ */
++#ifdef CONFIG_STACK_OVERFLOW_TEST
++#define STACK_OVERFLOW_TEST \
++ testl $7680,%esp; \
++ jnz 10f; \
++ call stack_overflow; \
++10:
++#else
++#define STACK_OVERFLOW_TEST
++#endif
+
+ EBX = 0x00
+ ECX = 0x04
+@@ -85,7 +99,102 @@
+ #define resume_kernel restore_all
+ #endif
+
+-#define SAVE_ALL \
++#ifdef CONFIG_X86_HIGH_ENTRY
++
++#ifdef CONFIG_X86_SWITCH_PAGETABLES
++
++#if defined(CONFIG_PREEMPT) && defined(CONFIG_SMP)
++/*
++ * If task is preempted in __SWITCH_KERNELSPACE, and moved to another cpu,
++ * __switch_to repoints %esp to the appropriate virtual stack; but %ebp is
++ * left stale, so we must check whether to repeat the real stack calculation.
++ */
++#define repeat_if_esp_changed \
++ xorl %esp, %ebp; \
++ testl $0xffffe000, %ebp; \
++ jnz 0b
++#else
++#define repeat_if_esp_changed
++#endif
++
++/* clobbers ebx, edx and ebp */
++
++#define __SWITCH_KERNELSPACE \
++ cmpl $0xff000000, %esp; \
++ jb 1f; \
++ \
++ /* \
++ * switch pagetables and load the real stack, \
++ * keep the stack offset: \
++ */ \
++ \
++ movl $swapper_pg_dir-__PAGE_OFFSET, %edx; \
++ \
++ /* GET_THREAD_INFO(%ebp) intermixed */ \
++0: \
++ movl %esp, %ebp; \
++ movl %esp, %ebx; \
++ andl $0xffffe000, %ebp; \
++ andl $0x00001fff, %ebx; \
++ orl TI_real_stack(%ebp), %ebx; \
++ repeat_if_esp_changed; \
++ \
++ movl %edx, %cr3; \
++ movl %ebx, %esp; \
++1:
++
++#endif
++
++
++#define __SWITCH_USERSPACE \
++ /* interrupted any of the user return paths? */ \
++ \
++ movl EIP(%esp), %eax; \
++ \
++ cmpl $int80_ret_start_marker, %eax; \
++ jb 33f; /* nope - continue with sysexit check */\
++ cmpl $int80_ret_end_marker, %eax; \
++ jb 22f; /* yes - switch to virtual stack */ \
++33: \
++ cmpl $sysexit_ret_start_marker, %eax; \
++ jb 44f; /* nope - continue with user check */ \
++ cmpl $sysexit_ret_end_marker, %eax; \
++ jb 22f; /* yes - switch to virtual stack */ \
++ /* return to userspace? */ \
++44: \
++ movl EFLAGS(%esp),%ecx; \
++ movb CS(%esp),%cl; \
++ testl $(VM_MASK | 3),%ecx; \
++ jz 2f; \
++22: \
++ /* \
++ * switch to the virtual stack, then switch to \
++ * the userspace pagetables. \
++ */ \
++ \
++ GET_THREAD_INFO(%ebp); \
++ movl TI_virtual_stack(%ebp), %edx; \
++ movl TI_user_pgd(%ebp), %ecx; \
++ \
++ movl %esp, %ebx; \
++ andl $0x1fff, %ebx; \
++ orl %ebx, %edx; \
++int80_ret_start_marker: \
++ movl %edx, %esp; \
++ movl %ecx, %cr3; \
++ \
++ __RESTORE_ALL; \
++int80_ret_end_marker: \
++2:
++
++#else /* !CONFIG_X86_HIGH_ENTRY */
++
++#define __SWITCH_KERNELSPACE
++#define __SWITCH_USERSPACE
++
++#endif
++
++#define __SAVE_ALL \
+ cld; \
+ pushl %es; \
+ pushl %ds; \
+@@ -100,7 +209,7 @@
+ movl %edx, %ds; \
+ movl %edx, %es;
+
+-#define RESTORE_INT_REGS \
++#define __RESTORE_INT_REGS \
+ popl %ebx; \
+ popl %ecx; \
+ popl %edx; \
+@@ -109,29 +218,28 @@
+ popl %ebp; \
+ popl %eax
+
+-#define RESTORE_REGS \
+- RESTORE_INT_REGS; \
+-1: popl %ds; \
+-2: popl %es; \
++#define __RESTORE_REGS \
++ __RESTORE_INT_REGS; \
++111: popl %ds; \
++222: popl %es; \
+ .section .fixup,"ax"; \
+-3: movl $0,(%esp); \
+- jmp 1b; \
+-4: movl $0,(%esp); \
+- jmp 2b; \
++444: movl $0,(%esp); \
++ jmp 111b; \
++555: movl $0,(%esp); \
++ jmp 222b; \
+ .previous; \
+ .section __ex_table,"a";\
+ .align 4; \
+- .long 1b,3b; \
+- .long 2b,4b; \
++ .long 111b,444b;\
++ .long 222b,555b;\
+ .previous
+
+-
+-#define RESTORE_ALL \
+- RESTORE_REGS \
++#define __RESTORE_ALL \
++ __RESTORE_REGS \
+ addl $4, %esp; \
+-1: iret; \
++333: iret; \
+ .section .fixup,"ax"; \
+-2: sti; \
++666: sti; \
+ movl $(__USER_DS), %edx; \
+ movl %edx, %ds; \
+ movl %edx, %es; \
+@@ -140,10 +248,19 @@
+ .previous; \
+ .section __ex_table,"a";\
+ .align 4; \
+- .long 1b,2b; \
++ .long 333b,666b;\
+ .previous
+
++#define SAVE_ALL \
++ __SAVE_ALL; \
++ __SWITCH_KERNELSPACE; \
++ STACK_OVERFLOW_TEST;
++
++#define RESTORE_ALL \
++ __SWITCH_USERSPACE; \
++ __RESTORE_ALL;
+
++.section .entry.text,"ax"
+
+ ENTRY(lcall7)
+ pushfl # We get a different stack layout with call
+@@ -161,7 +278,7 @@
+ movl %edx,EIP(%ebp) # Now we move them to their "normal" places
+ movl %ecx,CS(%ebp) #
+ andl $-8192, %ebp # GET_THREAD_INFO
+- movl TI_EXEC_DOMAIN(%ebp), %edx # Get the execution domain
++ movl TI_exec_domain(%ebp), %edx # Get the execution domain
+ call *4(%edx) # Call the lcall7 handler for the domain
+ addl $4, %esp
+ popl %eax
+@@ -206,7 +323,7 @@
+ cli # make sure we don't miss an interrupt
+ # setting need_resched or sigpending
+ # between sampling and the iret
+- movl TI_FLAGS(%ebp), %ecx
++ movl TI_flags(%ebp), %ecx
+ andl $_TIF_WORK_MASK, %ecx # is there any work to be done on
+ # int/exception return?
+ jne work_pending
+@@ -214,18 +331,18 @@
+
+ #ifdef CONFIG_PREEMPT
+ ENTRY(resume_kernel)
+- cmpl $0,TI_PRE_COUNT(%ebp) # non-zero preempt_count ?
++ cmpl $0,TI_preempt_count(%ebp) # non-zero preempt_count ?
+ jnz restore_all
+ need_resched:
+- movl TI_FLAGS(%ebp), %ecx # need_resched set ?
++ movl TI_flags(%ebp), %ecx # need_resched set ?
+ testb $_TIF_NEED_RESCHED, %cl
+ jz restore_all
+ testl $IF_MASK,EFLAGS(%esp) # interrupts off (exception path) ?
+ jz restore_all
+- movl $PREEMPT_ACTIVE,TI_PRE_COUNT(%ebp)
++ movl $PREEMPT_ACTIVE,TI_preempt_count(%ebp)
+ sti
+ call schedule
+- movl $0,TI_PRE_COUNT(%ebp)
++ movl $0,TI_preempt_count(%ebp)
+ cli
+ jmp need_resched
+ #endif
+@@ -244,37 +361,50 @@
+ pushl $(__USER_CS)
+ pushl $SYSENTER_RETURN
+
+-/*
+- * Load the potential sixth argument from user stack.
+- * Careful about security.
+- */
+- cmpl $__PAGE_OFFSET-3,%ebp
+- jae syscall_fault
+-1: movl (%ebp),%ebp
+-.section __ex_table,"a"
+- .align 4
+- .long 1b,syscall_fault
+-.previous
+-
+ pushl %eax
+ SAVE_ALL
+ GET_THREAD_INFO(%ebp)
+ cmpl $(nr_syscalls), %eax
+ jae syscall_badsys
+
+- testb $_TIF_SYSCALL_TRACE,TI_FLAGS(%ebp)
++ testb $_TIF_SYSCALL_TRACE,TI_flags(%ebp)
+ jnz syscall_trace_entry
+ call *sys_call_table(,%eax,4)
+ movl %eax,EAX(%esp)
+ cli
+- movl TI_FLAGS(%ebp), %ecx
++ movl TI_flags(%ebp), %ecx
+ testw $_TIF_ALLWORK_MASK, %cx
+ jne syscall_exit_work
++
++#ifdef CONFIG_X86_SWITCH_PAGETABLES
++
++ GET_THREAD_INFO(%ebp)
++ movl TI_virtual_stack(%ebp), %edx
++ movl TI_user_pgd(%ebp), %ecx
++ movl %esp, %ebx
++ andl $0x1fff, %ebx
++ orl %ebx, %edx
++sysexit_ret_start_marker:
++ movl %edx, %esp
++ movl %ecx, %cr3
++#endif
++ /*
++ * only ebx is not restored by the userspace sysenter vsyscall
++ * code, it assumes it to be callee-saved.
++ */
++ movl EBX(%esp), %ebx
++
+ /* if something modifies registers it must also disable sysexit */
++
+ movl EIP(%esp), %edx
+ movl OLDESP(%esp), %ecx
++
+ sti
+ sysexit
++#ifdef CONFIG_X86_SWITCH_PAGETABLES
++sysexit_ret_end_marker:
++ nop
++#endif
+
+
+ # system call handler stub
+@@ -285,7 +415,7 @@
+ cmpl $(nr_syscalls), %eax
+ jae syscall_badsys
+ # system call tracing in operation
+- testb $_TIF_SYSCALL_TRACE,TI_FLAGS(%ebp)
++ testb $_TIF_SYSCALL_TRACE,TI_flags(%ebp)
+ jnz syscall_trace_entry
+ syscall_call:
+ call *sys_call_table(,%eax,4)
+@@ -294,10 +424,23 @@
+ cli # make sure we don't miss an interrupt
+ # setting need_resched or sigpending
+ # between sampling and the iret
+- movl TI_FLAGS(%ebp), %ecx
++ movl TI_flags(%ebp), %ecx
+ testw $_TIF_ALLWORK_MASK, %cx # current->work
+ jne syscall_exit_work
+ restore_all:
++#ifdef CONFIG_TRAP_BAD_SYSCALL_EXITS
++ movl EFLAGS(%esp), %eax # mix EFLAGS and CS
++ movb CS(%esp), %al
++ testl $(VM_MASK | 3), %eax
++ jz resume_kernelX # returning to kernel or vm86-space
++
++ cmpl $0,TI_preempt_count(%ebp) # non-zero preempt_count ?
++ jz resume_kernelX
++
++ int $3
++
++resume_kernelX:
++#endif
+ RESTORE_ALL
+
+ # perform work that needs to be done immediately before resumption
+@@ -310,7 +453,7 @@
+ cli # make sure we don't miss an interrupt
+ # setting need_resched or sigpending
+ # between sampling and the iret
+- movl TI_FLAGS(%ebp), %ecx
++ movl TI_flags(%ebp), %ecx
+ andl $_TIF_WORK_MASK, %ecx # is there any work to be done other
+ # than syscall tracing?
+ jz restore_all
+@@ -325,6 +468,22 @@
+ # vm86-space
+ xorl %edx, %edx
+ call do_notify_resume
++
++#if CONFIG_X86_HIGH_ENTRY
++ /*
++ * Reload db7 if necessary:
++ */
++ movl TI_flags(%ebp), %ecx
++ testb $_TIF_DB7, %cl
++ jnz work_db7
++
++ jmp restore_all
++
++work_db7:
++ movl TI_task(%ebp), %edx;
++ movl task_thread_db7(%edx), %edx;
++ movl %edx, %db7;
++#endif
+ jmp restore_all
+
+ ALIGN
+@@ -380,7 +539,7 @@
+ */
+ .data
+ ENTRY(interrupt)
+-.text
++.previous
+
+ vector=0
+ ENTRY(irq_entries_start)
+@@ -390,7 +549,7 @@
+ jmp common_interrupt
+ .data
+ .long 1b
+-.text
++.previous
+ vector=vector+1
+ .endr
+
+@@ -431,12 +590,17 @@
+ movl ES(%esp), %edi # get the function address
+ movl %eax, ORIG_EAX(%esp)
+ movl %ecx, ES(%esp)
+- movl %esp, %edx
+ pushl %esi # push the error code
+- pushl %edx # push the pt_regs pointer
+ movl $(__USER_DS), %edx
+ movl %edx, %ds
+ movl %edx, %es
++
++/* clobbers edx, ebx and ebp */
++ __SWITCH_KERNELSPACE
++
++ leal 4(%esp), %edx # prepare pt_regs
++ pushl %edx # push pt_regs
++
+ call *%edi
+ addl $8, %esp
+ jmp ret_from_exception
+@@ -527,7 +691,7 @@
+ pushl %edx
+ call do_nmi
+ addl $8, %esp
+- RESTORE_ALL
++ jmp restore_all
+
+ nmi_stack_fixup:
+ FIX_STACK(12,nmi_stack_correct, 1)
+@@ -604,6 +768,8 @@
+ pushl $do_spurious_interrupt_bug
+ jmp error_code
+
++.previous
++
+ .data
+ ENTRY(sys_call_table)
+ .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
+@@ -881,3 +1047,57 @@
+ .long sys_fadvise64_64
+
+ nr_syscalls=(.-sys_call_table)/4
++
++
++# Here we do call frames. We cheat a bit as we only really need
++# correct frames at locations we can actually look at from a
++# debugger. Since the break instruction trap actually goes thru
++# some of this code, we don't really need info on those areas, but
++# only after the fact. I.e. if we can not step or break in a
++# location or end up with a return address pointing at the
++# location, we don't need a correct call frame for it.
++
++#if 0
++
++#include <linux/dwarf2-lang.h>
++/*
++ * The register numbers as known by gdb
++ */
++#define _EAX 0
++#define _ECX 1
++#define _EDX 2
++#define _EBX 3
++#define _ESP 4
++#define _EBP 5
++#define _ESI 6
++#define _EDI 7
++#define _PC 8
++#define _EIP 8
++#define _PS 9
++#define _EFLAGS 9
++#define _CS 10
++#define _SS 11
++#define _DS 12
++#define _ES 13
++#define _FS 14
++#define _GS 15
++
++ CFI_preamble(c1,_PC,1,1)
++ CFA_define_reference(_ESP,OLDESP)
++ CFA_define_offset(_EIP,EIP)
++ CFA_define_offset(_EBX,EBX)
++ CFA_define_offset(_ECX,ECX)
++ CFA_define_offset(_EDX,EDX)
++ CFA_define_offset(_ESI,ESI)
++ CFA_define_offset(_EDI,EDI)
++ CFA_define_offset(_EBP,EBP)
++ CFA_define_offset(_EAX,EAX)
++ CFA_define_offset(_EFLAGS,EFLAGS)
++ CFA_define_offset(_CS,CS)
++ CFA_define_offset(_DS,DS)
++ CFA_define_offset(_ES,ES)
++ CFI_postamble(c1)
++
++ FDE_preamble(c1,f1,ret_from_intr,(divide_error - ret_from_intr))
++ FDE_postamble(f1)
++#endif
+Index: linux-2.6.0-test5/arch/i386/kernel/entry_trampoline.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/entry_trampoline.c 2003-09-27 11:38:18.433726032 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/entry_trampoline.c 2003-09-27 11:38:18.992641064 +0800
+@@ -0,0 +1,75 @@
++/*
++ * linux/arch/i386/kernel/entry_trampoline.c
++ *
++ * (C) Copyright 2003 Ingo Molnar
++ *
++ * This file contains the needed support code for 4GB userspace
++ */
++
++#include <linux/init.h>
++#include <linux/smp.h>
++#include <linux/mm.h>
++#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/highmem.h>
++#include <asm/desc.h>
++#include <asm/atomic_kmap.h>
++
++extern char __entry_tramp_start, __entry_tramp_end, __start___entry_text;
++
++void __init init_entry_mappings(void)
++{
++#ifdef CONFIG_X86_HIGH_ENTRY
++ void *tramp;
++
++ /*
++ * We need a high IDT and GDT for the 4G/4G split:
++ */
++ trap_init_virtual_IDT();
++
++ __set_fixmap(FIX_ENTRY_TRAMPOLINE_0, __pa((unsigned long)&__entry_tramp_start), PAGE_KERNEL);
++ __set_fixmap(FIX_ENTRY_TRAMPOLINE_1, __pa((unsigned long)&__entry_tramp_start) + PAGE_SIZE, PAGE_KERNEL);
++ tramp = (void *)fix_to_virt(FIX_ENTRY_TRAMPOLINE_0);
++
++ printk("mapped 4G/4G trampoline to %p.\n", tramp);
++ BUG_ON((void *)&__start___entry_text != tramp);
++ /*
++ * Virtual kernel stack:
++ */
++ BUG_ON(__kmap_atomic_vaddr(KM_VSTACK0) & 8191);
++ BUG_ON(sizeof(struct desc_struct)*NR_CPUS*GDT_ENTRIES > 2*PAGE_SIZE);
++ BUG_ON((unsigned int)&__entry_tramp_end - (unsigned int)&__entry_tramp_start > 2*PAGE_SIZE);
++
++ /*
++ * set up the initial thread's virtual stack related
++ * fields:
++ */
++ current->thread.stack_page0 = virt_to_page((char *)current->thread_info);
++ current->thread.stack_page1 = virt_to_page((char *)current->thread_info + PAGE_SIZE);
++ current->thread_info->virtual_stack = (void *)__kmap_atomic_vaddr(KM_VSTACK0);
++
++ __kunmap_atomic_type(KM_VSTACK0);
++ __kunmap_atomic_type(KM_VSTACK1);
++ __kmap_atomic(current->thread.stack_page0, KM_VSTACK0);
++ __kmap_atomic(current->thread.stack_page1, KM_VSTACK1);
++
++#endif
++ printk("current: %p\n", current);
++ printk("current->thread_info: %p\n", current->thread_info);
++ current->thread_info->real_stack = (void *)current->thread_info;
++ current->thread_info->user_pgd = NULL;
++ current->thread.esp0 = (unsigned long)current->thread_info->real_stack + THREAD_SIZE;
++}
++
++
++
++void __init entry_trampoline_setup(void)
++{
++ /*
++ * old IRQ entries set up by the boot code will still hang
++ * around - they are a sign of hw trouble anyway, now they'll
++ * produce a double fault message.
++ */
++ trap_init_virtual_GDT();
++}
+Index: linux-2.6.0-test5/arch/i386/kernel/head.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/head.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/head.S 2003-09-27 11:38:18.996640456 +0800
+@@ -16,6 +16,7 @@
+ #include <asm/pgtable.h>
+ #include <asm/desc.h>
+ #include <asm/cache.h>
++#include <asm/asm_offsets.h>
+
+ #define OLD_CL_MAGIC_ADDR 0x90020
+ #define OLD_CL_MAGIC 0xA33F
+@@ -330,7 +331,7 @@
+
+ /* This is the default interrupt "handler" :-) */
+ int_msg:
+- .asciz "Unknown interrupt\n"
++ .asciz "Unknown interrupt or fault at EIP %p %p %p\n"
+ ALIGN
+ ignore_int:
+ cld
+@@ -342,9 +343,17 @@
+ movl $(__KERNEL_DS),%eax
+ movl %eax,%ds
+ movl %eax,%es
++ pushl 16(%esp)
++ pushl 24(%esp)
++ pushl 32(%esp)
++ pushl 40(%esp)
+ pushl $int_msg
+ call printk
+ popl %eax
++ popl %eax
++ popl %eax
++ popl %eax
++ popl %eax
+ popl %ds
+ popl %es
+ popl %edx
+@@ -377,23 +386,27 @@
+ .fill NR_CPUS-1,8,0 # space for the other GDT descriptors
+
+ /*
+- * This is initialized to create an identity-mapping at 0-8M (for bootup
+- * purposes) and another mapping of the 0-8M area at virtual address
++ * This is initialized to create an identity-mapping at 0-16M (for bootup
++ * purposes) and another mapping of the 0-16M area at virtual address
+ * PAGE_OFFSET.
+ */
+ .org 0x1000
+ ENTRY(swapper_pg_dir)
+ .long 0x00102007
+ .long 0x00103007
+- .fill BOOT_USER_PGD_PTRS-2,4,0
+- /* default: 766 entries */
++ .long 0x00104007
++ .long 0x00105007
++ .fill BOOT_USER_PGD_PTRS-4,4,0
++ /* default: 764 entries */
+ .long 0x00102007
+ .long 0x00103007
+- /* default: 254 entries */
+- .fill BOOT_KERNEL_PGD_PTRS-2,4,0
++ .long 0x00104007
++ .long 0x00105007
++ /* default: 252 entries */
++ .fill BOOT_KERNEL_PGD_PTRS-4,4,0
+
+ /*
+- * The page tables are initialized to only 8MB here - the final page
++ * The page tables are initialized to only 16MB here - the final page
+ * tables are set up later depending on memory size.
+ */
+ .org 0x2000
+@@ -402,15 +415,21 @@
+ .org 0x3000
+ ENTRY(pg1)
+
++.org 0x4000
++ENTRY(pg2)
++
++.org 0x5000
++ENTRY(pg3)
++
+ /*
+ * empty_zero_page must immediately follow the page tables ! (The
+ * initialization loop counts until empty_zero_page)
+ */
+
+-.org 0x4000
++.org 0x6000
+ ENTRY(empty_zero_page)
+
+-.org 0x5000
++.org 0x7000
+
+ /*
+ * Real beginning of normal "text" segment
+@@ -419,12 +438,12 @@
+ ENTRY(_stext)
+
+ /*
+- * This starts the data section. Note that the above is all
+- * in the text section because it has alignment requirements
+- * that we cannot fulfill any other way.
++ * This starts the data section.
+ */
+ .data
+
++.align PAGE_SIZE_asm
++
+ /*
+ * The Global Descriptor Table contains 28 quadwords, per-CPU.
+ */
+@@ -439,7 +458,9 @@
+ .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */
+ .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */
+ #endif
+- .align L1_CACHE_BYTES
++
++.align PAGE_SIZE_asm
++
+ ENTRY(cpu_gdt_table)
+ .quad 0x0000000000000000 /* NULL descriptor */
+ .quad 0x0000000000000000 /* 0x0b reserved */
+Index: linux-2.6.0-test5/arch/i386/kernel/i386_ksyms.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/i386_ksyms.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/i386_ksyms.c 2003-09-27 11:38:18.998640152 +0800
+@@ -33,6 +33,7 @@
+ #include <asm/tlbflush.h>
+ #include <asm/nmi.h>
+ #include <asm/edd.h>
++#include <asm/ist.h>
+
+ extern void dump_thread(struct pt_regs *, struct user *);
+ extern spinlock_t rtc_lock;
+@@ -62,9 +63,6 @@
+
+ /* platform dependent support */
+ EXPORT_SYMBOL(boot_cpu_data);
+-#ifdef CONFIG_EISA
+-EXPORT_SYMBOL(EISA_bus);
+-#endif
+ EXPORT_SYMBOL(MCA_bus);
+ #ifdef CONFIG_DISCONTIGMEM
+ EXPORT_SYMBOL(node_data);
+@@ -100,7 +98,6 @@
+ EXPORT_SYMBOL_NOVERS(__down_failed_trylock);
+ EXPORT_SYMBOL_NOVERS(__up_wakeup);
+ /* Networking helper routines. */
+-EXPORT_SYMBOL(csum_partial_copy_generic);
+ /* Delay loops */
+ EXPORT_SYMBOL(__ndelay);
+ EXPORT_SYMBOL(__udelay);
+@@ -114,13 +111,17 @@
+ EXPORT_SYMBOL(strpbrk);
+ EXPORT_SYMBOL(strstr);
+
++#if !defined(CONFIG_X86_UACCESS_INDIRECT)
+ EXPORT_SYMBOL(strncpy_from_user);
+-EXPORT_SYMBOL(__strncpy_from_user);
++EXPORT_SYMBOL(__direct_strncpy_from_user);
+ EXPORT_SYMBOL(clear_user);
+ EXPORT_SYMBOL(__clear_user);
+ EXPORT_SYMBOL(__copy_from_user_ll);
+ EXPORT_SYMBOL(__copy_to_user_ll);
+ EXPORT_SYMBOL(strnlen_user);
++#else /* CONFIG_X86_UACCESS_INDIRECT */
++EXPORT_SYMBOL(direct_csum_partial_copy_generic);
++#endif
+
+ EXPORT_SYMBOL(dma_alloc_coherent);
+ EXPORT_SYMBOL(dma_free_coherent);
+@@ -209,3 +210,7 @@
+ EXPORT_SYMBOL(edd);
+ EXPORT_SYMBOL(eddnr);
+ #endif
++
++#if defined(CONFIG_X86_SPEEDSTEP_SMI) || defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE)
++EXPORT_SYMBOL(ist_info);
++#endif
+Index: linux-2.6.0-test5/arch/i386/kernel/i387.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/i387.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/i387.c 2003-09-27 11:38:19.009638480 +0800
+@@ -219,6 +219,7 @@
+ static int convert_fxsr_to_user( struct _fpstate __user *buf,
+ struct i387_fxsave_struct *fxsave )
+ {
++ struct _fpreg tmp[8]; /* 80 bytes scratch area */
+ unsigned long env[7];
+ struct _fpreg __user *to;
+ struct _fpxreg *from;
+@@ -235,23 +236,25 @@
+ if ( __copy_to_user( buf, env, 7 * sizeof(unsigned long) ) )
+ return 1;
+
+- to = &buf->_st[0];
++ to = tmp;
+ from = (struct _fpxreg *) &fxsave->st_space[0];
+ for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
+ unsigned long *t = (unsigned long *)to;
+ unsigned long *f = (unsigned long *)from;
+
+- if (__put_user(*f, t) ||
+- __put_user(*(f + 1), t + 1) ||
+- __put_user(from->exponent, &to->exponent))
+- return 1;
++ *t = *f;
++ *(t + 1) = *(f+1);
++ to->exponent = from->exponent;
+ }
++ if (copy_to_user(buf->_st, tmp, sizeof(struct _fpreg [8])))
++ return 1;
+ return 0;
+ }
+
+ static int convert_fxsr_from_user( struct i387_fxsave_struct *fxsave,
+ struct _fpstate __user *buf )
+ {
++ struct _fpreg tmp[8]; /* 80 bytes scratch area */
+ unsigned long env[7];
+ struct _fpxreg *to;
+ struct _fpreg __user *from;
+@@ -259,6 +262,8 @@
+
+ if ( __copy_from_user( env, buf, 7 * sizeof(long) ) )
+ return 1;
++ if (copy_from_user(tmp, buf->_st, sizeof(struct _fpreg [8])))
++ return 1;
+
+ fxsave->cwd = (unsigned short)(env[0] & 0xffff);
+ fxsave->swd = (unsigned short)(env[1] & 0xffff);
+@@ -270,15 +275,14 @@
+ fxsave->fos = env[6];
+
+ to = (struct _fpxreg *) &fxsave->st_space[0];
+- from = &buf->_st[0];
++ from = tmp;
+ for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
+ unsigned long *t = (unsigned long *)to;
+ unsigned long *f = (unsigned long *)from;
+
+- if (__get_user(*t, f) ||
+- __get_user(*(t + 1), f + 1) ||
+- __get_user(to->exponent, &from->exponent))
+- return 1;
++ *t = *f;
++ *(t + 1) = *(f + 1);
++ to->exponent = from->exponent;
+ }
+ return 0;
+ }
+Index: linux-2.6.0-test5/arch/i386/kernel/init_task.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/init_task.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/init_task.c 2003-09-27 11:38:19.011638176 +0800
+@@ -23,7 +23,7 @@
+ */
+ union thread_union init_thread_union
+ __attribute__((__section__(".data.init_task"))) =
+- { INIT_THREAD_INFO(init_task) };
++ { INIT_THREAD_INFO(init_task, init_thread_union) };
+
+ /*
+ * Initial task structure.
+@@ -39,5 +39,5 @@
+ * section. Since TSS's are completely CPU-local, we want them
+ * on exact cacheline boundaries, to eliminate cacheline ping-pong.
+ */
+-struct tss_struct init_tss[NR_CPUS] __cacheline_aligned = { [0 ... NR_CPUS-1] = INIT_TSS };
++struct tss_struct init_tss[NR_CPUS] __attribute__((__section__(".data.tss"))) = { [0 ... NR_CPUS-1] = INIT_TSS };
+
+Index: linux-2.6.0-test5/arch/i386/kernel/io_apic.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/io_apic.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/io_apic.c 2003-09-27 11:38:19.027635744 +0800
+@@ -1143,6 +1143,7 @@
+ static int __init assign_irq_vector(int irq)
+ {
+ static int current_vector = FIRST_DEVICE_VECTOR, offset = 0;
++ BUG_ON(irq >= NR_IRQS);
+ if (IO_APIC_VECTOR(irq) > 0)
+ return IO_APIC_VECTOR(irq);
+ next:
+@@ -1652,6 +1653,10 @@
+ mp_ioapics[apic].mpc_apicid = reg_00.bits.ID;
+ }
+
++ /* Don't check I/O APIC IDs for some xAPIC systems. They have
++ * no meaning without the serial APIC bus. */
++ if (NO_IOAPIC_CHECK)
++ continue;
+ /*
+ * Sanity check, is the ID really free? Every APIC in a
+ * system must have a unique ID or we get lots of nice
+Index: linux-2.6.0-test5/arch/i386/kernel/irq.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/irq.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/irq.c 2003-09-27 11:38:19.035634528 +0800
+@@ -44,6 +44,7 @@
+ #include <asm/delay.h>
+ #include <asm/desc.h>
+ #include <asm/irq.h>
++#include <asm/kgdb.h>
+
+ /*
+ * Linux has a controller-independent x86 interrupt architecture.
+@@ -499,6 +500,17 @@
+
+ irq_exit();
+
++#ifdef CONFIG_KGDB
++ /*
++ * We need to do this after clearing out of all the interrupt
++ * machinery because kgdb will reenter the NIC driver and the IRQ
++ * system. synchronize_irq() (at least) will deadlock.
++ */
++ if (kgdb_eth_need_breakpoint[smp_processor_id()]) {
++ kgdb_eth_need_breakpoint[smp_processor_id()] = 0;
++ BREAKPOINT;
++ }
++#endif
+ return 1;
+ }
+
+Index: linux-2.6.0-test5/arch/i386/kernel/kgdb_stub.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/kgdb_stub.c 2003-09-27 11:38:18.433726032 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/kgdb_stub.c 2003-09-27 11:38:19.040633768 +0800
+@@ -0,0 +1,2492 @@
++/*
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2, or (at your option) any
++ * later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * General Public License for more details.
++ *
++ */
++
++/*
++ * Copyright (c) 2000 VERITAS Software Corporation.
++ *
++ */
++/****************************************************************************
++ * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
++ *
++ * Module name: remcom.c $
++ * Revision: 1.34 $
++ * Date: 91/03/09 12:29:49 $
++ * Contributor: Lake Stevens Instrument Division$
++ *
++ * Description: low level support for gdb debugger. $
++ *
++ * Considerations: only works on target hardware $
++ *
++ * Written by: Glenn Engel $
++ * Updated by: David Grothe <dave@gcom.com>
++ * Updated by: Robert Walsh <rjwalsh@durables.org>
++ * Updated by: wangdi <wangdi@clusterfs.com>
++ * ModuleState: Experimental $
++ *
++ * NOTES: See Below $
++ *
++ * Modified for 386 by Jim Kingdon, Cygnus Support.
++ * Compatibility with 2.1.xx kernel by David Grothe <dave@gcom.com>
++ *
++ * Changes to allow auto initilization. All that is needed is that it
++ * be linked with the kernel and a break point (int 3) be executed.
++ * The header file <asm/kgdb.h> defines BREAKPOINT to allow one to do
++ * this. It should also be possible, once the interrupt system is up, to
++ * call putDebugChar("+"). Once this is done, the remote debugger should
++ * get our attention by sending a ^C in a packet. George Anzinger
++ * <george@mvista.com>
++ * Integrated into 2.2.5 kernel by Tigran Aivazian <tigran@sco.com>
++ * Added thread support, support for multiple processors,
++ * support for ia-32(x86) hardware debugging.
++ * Amit S. Kale ( akale@veritas.com )
++ *
++ * Modified to support debugging over ethernet by Robert Walsh
++ * <rjwalsh@durables.org> and wangdi <wangdi@clusterfs.com>, based on
++ * code by San Mehat.
++ *
++ *
++ * To enable debugger support, two things need to happen. One, a
++ * call to set_debug_traps() is necessary in order to allow any breakpoints
++ * or error conditions to be properly intercepted and reported to gdb.
++ * Two, a breakpoint needs to be generated to begin communication. This
++ * is most easily accomplished by a call to breakpoint(). Breakpoint()
++ * simulates a breakpoint by executing an int 3.
++ *
++ *************
++ *
++ * The following gdb commands are supported:
++ *
++ * command function Return value
++ *
++ * g return the value of the CPU registers hex data or ENN
++ * G set the value of the CPU registers OK or ENN
++ *
++ * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN
++ * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN
++ *
++ * c Resume at current address SNN ( signal NN)
++ * cAA..AA Continue at address AA..AA SNN
++ *
++ * s Step one instruction SNN
++ * sAA..AA Step one instruction from AA..AA SNN
++ *
++ * k kill
++ *
++ * ? What was the last sigval ? SNN (signal NN)
++ *
++ * All commands and responses are sent with a packet which includes a
++ * checksum. A packet consists of
++ *
++ * $<packet info>#<checksum>.
++ *
++ * where
++ * <packet info> :: <characters representing the command or response>
++ * <checksum> :: < two hex digits computed as modulo 256 sum of <packetinfo>>
++ *
++ * When a packet is received, it is first acknowledged with either '+' or '-'.
++ * '+' indicates a successful transfer. '-' indicates a failed transfer.
++ *
++ * Example:
++ *
++ * Host: Reply:
++ * $m0,10#2a +$00010203040506070809101112131415#42
++ *
++ ****************************************************************************/
++#define KGDB_VERSION "<20030915.1651.33>"
++#include <linux/config.h>
++#include <linux/types.h>
++#include <asm/string.h> /* for strcpy */
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <asm/vm86.h>
++#include <asm/system.h>
++#include <asm/ptrace.h> /* for linux pt_regs struct */
++#include <asm/kgdb_local.h>
++#include <linux/list.h>
++#include <asm/atomic.h>
++#include <asm/processor.h>
++#include <linux/irq.h>
++#include <asm/desc.h>
++#include <linux/inet.h>
++#include <linux/kallsyms.h>
++
++/************************************************************************
++ *
++ * external low-level support routines
++ */
++typedef void (*Function) (void); /* pointer to a function */
++
++/* Thread reference */
++typedef unsigned char threadref[8];
++
++extern int tty_putDebugChar(int); /* write a single character */
++extern int tty_getDebugChar(void); /* read and return a single char */
++extern void tty_flushDebugChar(void); /* flush pending characters */
++extern int eth_putDebugChar(int); /* write a single character */
++extern int eth_getDebugChar(void); /* read and return a single char */
++extern void eth_flushDebugChar(void); /* flush pending characters */
++extern void kgdb_eth_set_trapmode(int);
++extern void kgdb_eth_reply_arp(void); /*send arp request */
++extern volatile int kgdb_eth_is_initializing;
++
++
++/************************************************************************/
++/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
++/* at least NUMREGBYTES*2 are needed for register packets */
++/* Longer buffer is needed to list all threads */
++#define BUFMAX 400
++
++char *kgdb_version = KGDB_VERSION;
++
++/* debug > 0 prints ill-formed commands in valid packets & checksum errors */
++int debug_regs = 0; /* set to non-zero to print registers */
++
++/* filled in by an external module */
++char *gdb_module_offsets;
++
++static const char hexchars[] = "0123456789abcdef";
++
++/* Number of bytes of registers. */
++#define NUMREGBYTES 64
++/*
++ * Note that this register image is in a different order than
++ * the register image that Linux produces at interrupt time.
++ *
++ * Linux's register image is defined by struct pt_regs in ptrace.h.
++ * Just why GDB uses a different order is a historical mystery.
++ */
++enum regnames { _EAX, /* 0 */
++ _ECX, /* 1 */
++ _EDX, /* 2 */
++ _EBX, /* 3 */
++ _ESP, /* 4 */
++ _EBP, /* 5 */
++ _ESI, /* 6 */
++ _EDI, /* 7 */
++ _PC /* 8 also known as eip */ ,
++ _PS /* 9 also known as eflags */ ,
++ _CS, /* 10 */
++ _SS, /* 11 */
++ _DS, /* 12 */
++ _ES, /* 13 */
++ _FS, /* 14 */
++ _GS /* 15 */
++};
++
++/*************************** ASSEMBLY CODE MACROS *************************/
++/*
++ * Put the error code here just in case the user cares.
++ * Likewise, the vector number here (since GDB only gets the signal
++ * number through the usual means, and that's not very specific).
++ * The called_from is the return address so he can tell how we entered kgdb.
++ * This will allow him to seperate out the various possible entries.
++ */
++#define REMOTE_DEBUG 0 /* set != to turn on printing (also available in info) */
++
++#define PID_MAX PID_MAX_DEFAULT
++
++#ifdef CONFIG_SMP
++void smp_send_nmi_allbutself(void);
++#define IF_SMP(x) x
++#undef MAX_NO_CPUS
++#ifndef CONFIG_NO_KGDB_CPUS
++#define CONFIG_NO_KGDB_CPUS 2
++#endif
++#if CONFIG_NO_KGDB_CPUS > NR_CPUS
++#define MAX_NO_CPUS NR_CPUS
++#else
++#define MAX_NO_CPUS CONFIG_NO_KGDB_CPUS
++#endif
++#define hold_init hold_on_sstep: 1,
++#define MAX_CPU_MASK (unsigned long)((1LL << MAX_NO_CPUS) - 1LL)
++#define NUM_CPUS num_online_cpus()
++#else
++#define IF_SMP(x)
++#define hold_init
++#undef MAX_NO_CPUS
++#define MAX_NO_CPUS 1
++#define NUM_CPUS 1
++#endif
++#define NOCPU (struct task_struct *)0xbad1fbad
++/* *INDENT-OFF* */
++struct kgdb_info {
++ int used_malloc;
++ void *called_from;
++ long long entry_tsc;
++ int errcode;
++ int vector;
++ int print_debug_info;
++#ifdef CONFIG_SMP
++ int hold_on_sstep;
++ struct {
++ volatile struct task_struct *task;
++ int pid;
++ int hold;
++ struct pt_regs *regs;
++ } cpus_waiting[MAX_NO_CPUS];
++#endif
++} kgdb_info = {hold_init print_debug_info:REMOTE_DEBUG, vector:-1};
++
++/* *INDENT-ON* */
++
++#define used_m kgdb_info.used_malloc
++/*
++ * This is little area we set aside to contain the stack we
++ * need to build to allow gdb to call functions. We use one
++ * per cpu to avoid locking issues. We will do all this work
++ * with interrupts off so that should take care of the protection
++ * issues.
++ */
++#define LOOKASIDE_SIZE 200 /* should be more than enough */
++#define MALLOC_MAX 200 /* Max malloc size */
++struct {
++ unsigned int esp;
++ int array[LOOKASIDE_SIZE];
++} fn_call_lookaside[MAX_NO_CPUS];
++
++static int trap_cpu;
++static unsigned int OLD_esp;
++
++#define END_OF_LOOKASIDE &fn_call_lookaside[trap_cpu].array[LOOKASIDE_SIZE]
++#define IF_BIT 0x200
++#define TF_BIT 0x100
++
++#define MALLOC_ROUND 8-1
++
++static char malloc_array[MALLOC_MAX];
++IF_SMP(static void to_gdb(const char *mess));
++void *
++malloc(int size)
++{
++
++ if (size <= (MALLOC_MAX - used_m)) {
++ int old_used = used_m;
++ used_m += ((size + MALLOC_ROUND) & (~MALLOC_ROUND));
++ return &malloc_array[old_used];
++ } else {
++ return NULL;
++ }
++}
++
++/*
++ * I/O dispatch functions...
++ * Based upon kgdb_eth, either call the ethernet
++ * handler or the serial one..
++ */
++void
++putDebugChar(int c)
++{
++ if (kgdb_eth == -1) {
++ tty_putDebugChar(c);
++ } else {
++ eth_putDebugChar(c);
++ }
++}
++
++int
++getDebugChar(void)
++{
++ if (kgdb_eth == -1) {
++ return tty_getDebugChar();
++ } else {
++ return eth_getDebugChar();
++ }
++}
++
++void
++flushDebugChar(void)
++{
++ if (kgdb_eth == -1) {
++ tty_flushDebugChar();
++ } else {
++ eth_flushDebugChar();
++ }
++}
++
++/*
++ * Gdb calls functions by pushing agruments, including a return address
++ * on the stack and the adjusting EIP to point to the function. The
++ * whole assumption in GDB is that we are on a different stack than the
++ * one the "user" i.e. code that hit the break point, is on. This, of
++ * course is not true in the kernel. Thus various dodges are needed to
++ * do the call without directly messing with EIP (which we can not change
++ * as it is just a location and not a register. To adjust it would then
++ * require that we move every thing below EIP up or down as needed. This
++ * will not work as we may well have stack relative pointer on the stack
++ * (such as the pointer to regs, for example).
++
++ * So here is what we do:
++ * We detect gdb attempting to store into the stack area and instead, store
++ * into the fn_call_lookaside.array at the same relative location as if it
++ * were the area ESP pointed at. We also trap ESP modifications
++ * and uses these to adjust fn_call_lookaside.esp. On entry
++ * fn_call_lookaside.esp will be set to point at the last entry in
++ * fn_call_lookaside.array. This allows us to check if it has changed, and
++ * if so, on exit, we add the registers we will use to do the move and a
++ * trap/ interrupt return exit sequence. We then adjust the eflags in the
++ * regs array (remember we now have a copy in the fn_call_lookaside.array) to
++ * kill the interrupt bit, AND we change EIP to point at our set up stub.
++ * As part of the register set up we preset the registers to point at the
++ * begining and end of the fn_call_lookaside.array, so all the stub needs to
++ * do is move words from the array to the stack until ESP= the desired value
++ * then do the rti. This will then transfer to the desired function with
++ * all the correct registers. Nifty huh?
++ */
++extern asmlinkage void fn_call_stub(void);
++extern asmlinkage void fn_rtn_stub(void);
++/* *INDENT-OFF* */
++__asm__("fn_rtn_stub:\n\t"
++ "movl %eax,%esp\n\t"
++ "fn_call_stub:\n\t"
++ "1:\n\t"
++ "addl $-4,%ebx\n\t"
++ "movl (%ebx), %eax\n\t"
++ "pushl %eax\n\t"
++ "cmpl %esp,%ecx\n\t"
++ "jne 1b\n\t"
++ "popl %eax\n\t"
++ "popl %ebx\n\t"
++ "popl %ecx\n\t"
++ "iret \n\t");
++/* *INDENT-ON* */
++#define gdb_i386vector kgdb_info.vector
++#define gdb_i386errcode kgdb_info.errcode
++#define waiting_cpus kgdb_info.cpus_waiting
++#define remote_debug kgdb_info.print_debug_info
++#define hold_cpu(cpu) kgdb_info.cpus_waiting[cpu].hold
++/* gdb locks */
++
++#ifdef CONFIG_SMP
++static int in_kgdb_called;
++static spinlock_t waitlocks[MAX_NO_CPUS] =
++ {[0 ... MAX_NO_CPUS - 1] = SPIN_LOCK_UNLOCKED };
++/*
++ * The following array has the thread pointer of each of the "other"
++ * cpus. We make it global so it can be seen by gdb.
++ */
++volatile int in_kgdb_entry_log[MAX_NO_CPUS];
++volatile struct pt_regs *in_kgdb_here_log[MAX_NO_CPUS];
++/*
++static spinlock_t continuelocks[MAX_NO_CPUS];
++*/
++spinlock_t kgdb_spinlock = SPIN_LOCK_UNLOCKED;
++/* waiters on our spinlock plus us */
++static atomic_t spinlock_waiters = ATOMIC_INIT(1);
++static int spinlock_count = 0;
++static int spinlock_cpu = 0;
++/*
++ * Note we use nested spin locks to account for the case where a break
++ * point is encountered when calling a function by user direction from
++ * kgdb. Also there is the memory exception recursion to account for.
++ * Well, yes, but this lets other cpus thru too. Lets add a
++ * cpu id to the lock.
++ */
++#define KGDB_SPIN_LOCK(x) if( spinlock_count == 0 || \
++ spinlock_cpu != smp_processor_id()){\
++ atomic_inc(&spinlock_waiters); \
++ while (! spin_trylock(x)) {\
++ in_kgdb(®s);\
++ }\
++ atomic_dec(&spinlock_waiters); \
++ spinlock_count = 1; \
++ spinlock_cpu = smp_processor_id(); \
++ }else{ \
++ spinlock_count++; \
++ }
++#define KGDB_SPIN_UNLOCK(x) if( --spinlock_count == 0) spin_unlock(x)
++#else
++unsigned kgdb_spinlock = 0;
++#define KGDB_SPIN_LOCK(x) --*x
++#define KGDB_SPIN_UNLOCK(x) ++*x
++#endif
++
++int
++hex(char ch)
++{
++ if ((ch >= 'a') && (ch <= 'f'))
++ return (ch - 'a' + 10);
++ if ((ch >= '0') && (ch <= '9'))
++ return (ch - '0');
++ if ((ch >= 'A') && (ch <= 'F'))
++ return (ch - 'A' + 10);
++ return (-1);
++}
++
++/* scan for the sequence $<data>#<checksum> */
++void
++getpacket(char *buffer)
++{
++ unsigned char checksum;
++ unsigned char xmitcsum;
++ int i;
++ int count;
++ char ch;
++
++ do {
++ /* wait around for the start character, ignore all other characters */
++ while ((ch = (getDebugChar() & 0x7f)) != '$') ;
++ checksum = 0;
++ xmitcsum = -1;
++
++ count = 0;
++
++ /* now, read until a # or end of buffer is found */
++ while (count < BUFMAX) {
++ ch = getDebugChar() & 0x7f;
++ if (ch == '#')
++ break;
++ checksum = checksum + ch;
++ buffer[count] = ch;
++ count = count + 1;
++ }
++ buffer[count] = 0;
++
++ if (ch == '#') {
++ xmitcsum = hex(getDebugChar() & 0x7f) << 4;
++ xmitcsum += hex(getDebugChar() & 0x7f);
++ if ((remote_debug) && (checksum != xmitcsum)) {
++ printk
++ ("bad checksum. My count = 0x%x, sent=0x%x. buf=%s\n",
++ checksum, xmitcsum, buffer);
++ }
++
++ if (checksum != xmitcsum)
++ putDebugChar('-'); /* failed checksum */
++ else {
++ putDebugChar('+'); /* successful transfer */
++ /* if a sequence char is present, reply the sequence ID */
++ if (buffer[2] == ':') {
++ putDebugChar(buffer[0]);
++ putDebugChar(buffer[1]);
++ /* remove sequence chars from buffer */
++ count = strlen(buffer);
++ for (i = 3; i <= count; i++)
++ buffer[i - 3] = buffer[i];
++ }
++ }
++ }
++ } while (checksum != xmitcsum);
++
++ if (remote_debug)
++ printk("R:%s\n", buffer);
++ flushDebugChar();
++}
++
++/* send the packet in buffer. */
++
++void
++putpacket(char *buffer)
++{
++ unsigned char checksum;
++ int count;
++ char ch;
++
++ /* $<packet info>#<checksum>. */
++
++ if (kgdb_eth == -1) {
++ do {
++ if (remote_debug)
++ printk("T:%s\n", buffer);
++ putDebugChar('$');
++ checksum = 0;
++ count = 0;
++
++ while ((ch = buffer[count])) {
++ putDebugChar(ch);
++ checksum += ch;
++ count += 1;
++ }
++
++ putDebugChar('#');
++ putDebugChar(hexchars[checksum >> 4]);
++ putDebugChar(hexchars[checksum % 16]);
++ flushDebugChar();
++
++ } while ((getDebugChar() & 0x7f) != '+');
++ } else {
++ /*
++ * For udp, we can not transfer too much bytes once.
++ * We only transfer MAX_SEND_COUNT size bytes each time
++ */
++
++#define MAX_SEND_COUNT 30
++
++ int send_count = 0, i = 0;
++ char send_buf[MAX_SEND_COUNT];
++
++ do {
++ if (remote_debug)
++ printk("T:%s\n", buffer);
++ putDebugChar('$');
++ checksum = 0;
++ count = 0;
++ send_count = 0;
++ while ((ch = buffer[count])) {
++ if (send_count >= MAX_SEND_COUNT) {
++ for(i = 0; i < MAX_SEND_COUNT; i++) {
++ putDebugChar(send_buf[i]);
++ }
++ flushDebugChar();
++ send_count = 0;
++ } else {
++ send_buf[send_count] = ch;
++ checksum += ch;
++ count ++;
++ send_count++;
++ }
++ }
++ for(i = 0; i < send_count; i++)
++ putDebugChar(send_buf[i]);
++ putDebugChar('#');
++ putDebugChar(hexchars[checksum >> 4]);
++ putDebugChar(hexchars[checksum % 16]);
++ flushDebugChar();
++ } while ((getDebugChar() & 0x7f) != '+');
++ }
++}
++
++static char remcomInBuffer[BUFMAX];
++static char remcomOutBuffer[BUFMAX];
++static short error;
++
++void
++debug_error(char *format, char *parm)
++{
++ if (remote_debug)
++ printk(format, parm);
++}
++
++static void
++print_regs(struct pt_regs *regs)
++{
++ printk("EAX=%08lx ", regs->eax);
++ printk("EBX=%08lx ", regs->ebx);
++ printk("ECX=%08lx ", regs->ecx);
++ printk("EDX=%08lx ", regs->edx);
++ printk("\n");
++ printk("ESI=%08lx ", regs->esi);
++ printk("EDI=%08lx ", regs->edi);
++ printk("EBP=%08lx ", regs->ebp);
++ printk("ESP=%08lx ", (long) ®s->esp);
++ printk("\n");
++ printk(" DS=%08x ", regs->xds);
++ printk(" ES=%08x ", regs->xes);
++ printk(" SS=%08x ", __KERNEL_DS);
++ printk(" FL=%08lx ", regs->eflags);
++ printk("\n");
++ printk(" CS=%08x ", regs->xcs);
++ printk(" IP=%08lx ", regs->eip);
++#if 0
++ printk(" FS=%08x ", regs->fs);
++ printk(" GS=%08x ", regs->gs);
++#endif
++ printk("\n");
++
++} /* print_regs */
++
++#define NEW_esp fn_call_lookaside[trap_cpu].esp
++
++static void
++regs_to_gdb_regs(int *gdb_regs, struct pt_regs *regs)
++{
++ gdb_regs[_EAX] = regs->eax;
++ gdb_regs[_EBX] = regs->ebx;
++ gdb_regs[_ECX] = regs->ecx;
++ gdb_regs[_EDX] = regs->edx;
++ gdb_regs[_ESI] = regs->esi;
++ gdb_regs[_EDI] = regs->edi;
++ gdb_regs[_EBP] = regs->ebp;
++ gdb_regs[_DS] = regs->xds;
++ gdb_regs[_ES] = regs->xes;
++ gdb_regs[_PS] = regs->eflags;
++ gdb_regs[_CS] = regs->xcs;
++ gdb_regs[_PC] = regs->eip;
++ /* Note, as we are a debugging the kernel, we will always
++ * trap in kernel code, this means no priviledge change,
++ * and so the pt_regs structure is not completely valid. In a non
++ * privilege change trap, only EFLAGS, CS and EIP are put on the stack,
++ * SS and ESP are not stacked, this means that the last 2 elements of
++ * pt_regs is not valid (they would normally refer to the user stack)
++ * also, using regs+1 is no good because you end up will a value that is
++ * 2 longs (8) too high. This used to cause stepping over functions
++ * to fail, so my fix is to use the address of regs->esp, which
++ * should point at the end of the stack frame. Note I have ignored
++ * completely exceptions that cause an error code to be stacked, such
++ * as double fault. Stuart Hughes, Zentropix.
++ * original code: gdb_regs[_ESP] = (int) (regs + 1) ;
++
++ * this is now done on entry and moved to OLD_esp (as well as NEW_esp).
++ */
++ gdb_regs[_ESP] = NEW_esp;
++ gdb_regs[_SS] = __KERNEL_DS;
++ gdb_regs[_FS] = 0xFFFF;
++ gdb_regs[_GS] = 0xFFFF;
++} /* regs_to_gdb_regs */
++
++static void
++gdb_regs_to_regs(int *gdb_regs, struct pt_regs *regs)
++{
++ regs->eax = gdb_regs[_EAX];
++ regs->ebx = gdb_regs[_EBX];
++ regs->ecx = gdb_regs[_ECX];
++ regs->edx = gdb_regs[_EDX];
++ regs->esi = gdb_regs[_ESI];
++ regs->edi = gdb_regs[_EDI];
++ regs->ebp = gdb_regs[_EBP];
++ regs->xds = gdb_regs[_DS];
++ regs->xes = gdb_regs[_ES];
++ regs->eflags = gdb_regs[_PS];
++ regs->xcs = gdb_regs[_CS];
++ regs->eip = gdb_regs[_PC];
++ NEW_esp = gdb_regs[_ESP]; /* keep the value */
++#if 0 /* can't change these */
++ regs->esp = gdb_regs[_ESP];
++ regs->xss = gdb_regs[_SS];
++ regs->fs = gdb_regs[_FS];
++ regs->gs = gdb_regs[_GS];
++#endif
++
++} /* gdb_regs_to_regs */
++extern void scheduling_functions_start_here(void);
++extern void scheduling_functions_end_here(void);
++#define first_sched ((unsigned long) scheduling_functions_start_here)
++#define last_sched ((unsigned long) scheduling_functions_end_here)
++
++int thread_list = 0;
++
++void
++get_gdb_regs(struct task_struct *p, struct pt_regs *regs, int *gdb_regs)
++{
++ unsigned long stack_page;
++ int count = 0;
++ IF_SMP(int i);
++ if (!p || p == current) {
++ regs_to_gdb_regs(gdb_regs, regs);
++ return;
++ }
++#ifdef CONFIG_SMP
++ for (i = 0; i < MAX_NO_CPUS; i++) {
++ if (p == kgdb_info.cpus_waiting[i].task) {
++ regs_to_gdb_regs(gdb_regs,
++ kgdb_info.cpus_waiting[i].regs);
++ gdb_regs[_ESP] =
++ (int) &kgdb_info.cpus_waiting[i].regs->esp;
++
++ return;
++ }
++ }
++#endif
++ memset(gdb_regs, 0, NUMREGBYTES);
++ gdb_regs[_ESP] = p->thread.esp;
++ gdb_regs[_PC] = p->thread.eip;
++ gdb_regs[_EBP] = *(int *) gdb_regs[_ESP];
++ gdb_regs[_EDI] = *(int *) (gdb_regs[_ESP] + 4);
++ gdb_regs[_ESI] = *(int *) (gdb_regs[_ESP] + 8);
++
++/*
++ * This code is to give a more informative notion of where a process
++ * is waiting. It is used only when the user asks for a thread info
++ * list. If he then switches to the thread, s/he will find the task
++ * is in schedule, but a back trace should show the same info we come
++ * up with. This code was shamelessly purloined from process.c. It was
++ * then enhanced to provide more registers than simply the program
++ * counter.
++ */
++
++ if (!thread_list) {
++ return;
++ }
++
++ if (p->state == TASK_RUNNING)
++ return;
++ stack_page = (unsigned long) p->thread_info;
++ if (gdb_regs[_ESP] < stack_page || gdb_regs[_ESP] > 8188 + stack_page)
++ return;
++ /* include/asm-i386/system.h:switch_to() pushes ebp last. */
++ do {
++ if (gdb_regs[_EBP] < stack_page ||
++ gdb_regs[_EBP] > 8184 + stack_page)
++ return;
++ gdb_regs[_PC] = *(unsigned long *) (gdb_regs[_EBP] + 4);
++ gdb_regs[_ESP] = gdb_regs[_EBP] + 8;
++ gdb_regs[_EBP] = *(unsigned long *) gdb_regs[_EBP];
++ if (gdb_regs[_PC] < first_sched || gdb_regs[_PC] >= last_sched)
++ return;
++ } while (count++ < 16);
++ return;
++}
++
++/* Indicate to caller of mem2hex or hex2mem that there has been an
++ error. */
++static volatile int mem_err = 0;
++static volatile int mem_err_expected = 0;
++static volatile int mem_err_cnt = 0;
++static int garbage_loc = -1;
++
++int
++get_char(char *addr)
++{
++ return *addr;
++}
++
++void
++set_char(char *addr, int val, int may_fault)
++{
++ /*
++ * This code traps references to the area mapped to the kernel
++ * stack as given by the regs and, instead, stores to the
++ * fn_call_lookaside[cpu].array
++ */
++ if (may_fault &&
++ (unsigned int) addr < OLD_esp &&
++ ((unsigned int) addr > (OLD_esp - (unsigned int) LOOKASIDE_SIZE))) {
++ addr = (char *) END_OF_LOOKASIDE - ((char *) OLD_esp - addr);
++ }
++ *addr = val;
++}
++
++/* convert the memory pointed to by mem into hex, placing result in buf */
++/* return a pointer to the last char put in buf (null) */
++/* If MAY_FAULT is non-zero, then we should set mem_err in response to
++ a fault; if zero treat a fault like any other fault in the stub. */
++char *
++mem2hex(char *mem, char *buf, int count, int may_fault)
++{
++ int i;
++ unsigned char ch;
++
++ if (may_fault) {
++ mem_err_expected = 1;
++ mem_err = 0;
++ }
++ for (i = 0; i < count; i++) {
++ /* printk("%lx = ", mem) ; */
++
++ ch = get_char(mem++);
++
++ /* printk("%02x\n", ch & 0xFF) ; */
++ if (may_fault && mem_err) {
++ if (remote_debug)
++ printk("Mem fault fetching from addr %lx\n",
++ (long) (mem - 1));
++ *buf = 0; /* truncate buffer */
++ return (buf);
++ }
++ *buf++ = hexchars[ch >> 4];
++ *buf++ = hexchars[ch % 16];
++ }
++ *buf = 0;
++ if (may_fault)
++ mem_err_expected = 0;
++ return (buf);
++}
++
++/* convert the hex array pointed to by buf into binary to be placed in mem */
++/* return a pointer to the character AFTER the last byte written */
++/* NOTE: We use the may fault flag to also indicate if the write is to
++ * the registers (0) or "other" memory (!=0)
++ */
++char *
++hex2mem(char *buf, char *mem, int count, int may_fault)
++{
++ int i;
++ unsigned char ch;
++
++ if (may_fault) {
++ mem_err_expected = 1;
++ mem_err = 0;
++ }
++ for (i = 0; i < count; i++) {
++ ch = hex(*buf++) << 4;
++ ch = ch + hex(*buf++);
++ set_char(mem++, ch, may_fault);
++
++ if (may_fault && mem_err) {
++ if (remote_debug)
++ printk("Mem fault storing to addr %lx\n",
++ (long) (mem - 1));
++ return (mem);
++ }
++ }
++ if (may_fault)
++ mem_err_expected = 0;
++ return (mem);
++}
++
++/**********************************************/
++/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
++/* RETURN NUMBER OF CHARS PROCESSED */
++/**********************************************/
++int
++hexToInt(char **ptr, int *intValue)
++{
++ int numChars = 0;
++ int hexValue;
++
++ *intValue = 0;
++
++ while (**ptr) {
++ hexValue = hex(**ptr);
++ if (hexValue >= 0) {
++ *intValue = (*intValue << 4) | hexValue;
++ numChars++;
++ } else
++ break;
++
++ (*ptr)++;
++ }
++
++ return (numChars);
++}
++
++#define stubhex(h) hex(h)
++#ifdef old_thread_list
++
++static int
++stub_unpack_int(char *buff, int fieldlength)
++{
++ int nibble;
++ int retval = 0;
++
++ while (fieldlength) {
++ nibble = stubhex(*buff++);
++ retval |= nibble;
++ fieldlength--;
++ if (fieldlength)
++ retval = retval << 4;
++ }
++ return retval;
++}
++#endif
++static char *
++pack_hex_byte(char *pkt, int byte)
++{
++ *pkt++ = hexchars[(byte >> 4) & 0xf];
++ *pkt++ = hexchars[(byte & 0xf)];
++ return pkt;
++}
++
++#define BUF_THREAD_ID_SIZE 16
++
++static char *
++pack_threadid(char *pkt, threadref * id)
++{
++ char *limit;
++ unsigned char *altid;
++
++ altid = (unsigned char *) id;
++ limit = pkt + BUF_THREAD_ID_SIZE;
++ while (pkt < limit)
++ pkt = pack_hex_byte(pkt, *altid++);
++ return pkt;
++}
++
++#ifdef old_thread_list
++static char *
++unpack_byte(char *buf, int *value)
++{
++ *value = stub_unpack_int(buf, 2);
++ return buf + 2;
++}
++
++static char *
++unpack_threadid(char *inbuf, threadref * id)
++{
++ char *altref;
++ char *limit = inbuf + BUF_THREAD_ID_SIZE;
++ int x, y;
++
++ altref = (char *) id;
++
++ while (inbuf < limit) {
++ x = stubhex(*inbuf++);
++ y = stubhex(*inbuf++);
++ *altref++ = (x << 4) | y;
++ }
++ return inbuf;
++}
++#endif
++void
++int_to_threadref(threadref * id, int value)
++{
++ unsigned char *scan;
++
++ scan = (unsigned char *) id;
++ {
++ int i = 4;
++ while (i--)
++ *scan++ = 0;
++ }
++ *scan++ = (value >> 24) & 0xff;
++ *scan++ = (value >> 16) & 0xff;
++ *scan++ = (value >> 8) & 0xff;
++ *scan++ = (value & 0xff);
++}
++int
++int_to_hex_v(unsigned char * id, int value)
++{
++ unsigned char *start = id;
++ int shift;
++ int ch;
++
++ for (shift = 28; shift >= 0; shift -= 4) {
++ if ((ch = (value >> shift) & 0xf) || (id != start)) {
++ *id = hexchars[ch];
++ id++;
++ }
++ }
++ if (id == start)
++ *id++ = '0';
++ return id - start;
++}
++#ifdef old_thread_list
++
++static int
++threadref_to_int(threadref * ref)
++{
++ int i, value = 0;
++ unsigned char *scan;
++
++ scan = (char *) ref;
++ scan += 4;
++ i = 4;
++ while (i-- > 0)
++ value = (value << 8) | ((*scan++) & 0xff);
++ return value;
++}
++#endif
++static int
++cmp_str(char *s1, char *s2, int count)
++{
++ while (count--) {
++ if (*s1++ != *s2++)
++ return 0;
++ }
++ return 1;
++}
++
++#if 1 /* this is a hold over from 2.4 where O(1) was "sometimes" */
++extern struct task_struct *kgdb_get_idle(int cpu);
++#define idle_task(cpu) kgdb_get_idle(cpu)
++#else
++#define idle_task(cpu) init_tasks[cpu]
++#endif
++
++extern int kgdb_pid_init_done;
++
++struct task_struct *
++getthread(int pid)
++{
++ struct task_struct *thread;
++ if (pid >= PID_MAX && pid <= (PID_MAX + MAX_NO_CPUS)) {
++
++ return idle_task(pid - PID_MAX);
++ } else {
++ /*
++ * find_task_by_pid is relatively safe all the time
++ * Other pid functions require lock downs which imply
++ * that we may be interrupting them (as we get here
++ * in the middle of most any lock down).
++ * Still we don't want to call until the table exists!
++ */
++ if (kgdb_pid_init_done){
++ thread = find_task_by_pid(pid);
++ if (thread) {
++ return thread;
++ }
++ }
++ }
++ return NULL;
++}
++/* *INDENT-OFF* */
++struct hw_breakpoint {
++ unsigned enabled;
++ unsigned type;
++ unsigned len;
++ unsigned addr;
++} breakinfo[4] = { {enabled:0},
++ {enabled:0},
++ {enabled:0},
++ {enabled:0}};
++/* *INDENT-ON* */
++unsigned hw_breakpoint_status;
++void
++correct_hw_break(void)
++{
++ int breakno;
++ int correctit;
++ int breakbit;
++ unsigned dr7;
++
++ asm volatile ("movl %%db7, %0\n":"=r" (dr7)
++ :);
++ /* *INDENT-OFF* */
++ do {
++ unsigned addr0, addr1, addr2, addr3;
++ asm volatile ("movl %%db0, %0\n"
++ "movl %%db1, %1\n"
++ "movl %%db2, %2\n"
++ "movl %%db3, %3\n"
++ :"=r" (addr0), "=r"(addr1),
++ "=r"(addr2), "=r"(addr3)
++ :);
++ } while (0);
++ /* *INDENT-ON* */
++ correctit = 0;
++ for (breakno = 0; breakno < 3; breakno++) {
++ breakbit = 2 << (breakno << 1);
++ if (!(dr7 & breakbit) && breakinfo[breakno].enabled) {
++ correctit = 1;
++ dr7 |= breakbit;
++ dr7 &= ~(0xf0000 << (breakno << 2));
++ dr7 |= (((breakinfo[breakno].len << 2) |
++ breakinfo[breakno].type) << 16) <<
++ (breakno << 2);
++ switch (breakno) {
++ case 0:
++ asm volatile ("movl %0, %%dr0\n"::"r"
++ (breakinfo[breakno].addr));
++ break;
++
++ case 1:
++ asm volatile ("movl %0, %%dr1\n"::"r"
++ (breakinfo[breakno].addr));
++ break;
++
++ case 2:
++ asm volatile ("movl %0, %%dr2\n"::"r"
++ (breakinfo[breakno].addr));
++ break;
++
++ case 3:
++ asm volatile ("movl %0, %%dr3\n"::"r"
++ (breakinfo[breakno].addr));
++ break;
++ }
++ } else if ((dr7 & breakbit) && !breakinfo[breakno].enabled) {
++ correctit = 1;
++ dr7 &= ~breakbit;
++ dr7 &= ~(0xf0000 << (breakno << 2));
++ }
++ }
++ if (correctit) {
++ asm volatile ("movl %0, %%db7\n"::"r" (dr7));
++ }
++}
++
++int
++remove_hw_break(unsigned breakno)
++{
++ if (!breakinfo[breakno].enabled) {
++ return -1;
++ }
++ breakinfo[breakno].enabled = 0;
++ return 0;
++}
++
++int
++set_hw_break(unsigned breakno, unsigned type, unsigned len, unsigned addr)
++{
++ if (breakinfo[breakno].enabled) {
++ return -1;
++ }
++ breakinfo[breakno].enabled = 1;
++ breakinfo[breakno].type = type;
++ breakinfo[breakno].len = len;
++ breakinfo[breakno].addr = addr;
++ return 0;
++}
++
++#ifdef CONFIG_SMP
++static int in_kgdb_console = 0;
++
++int
++in_kgdb(struct pt_regs *regs)
++{
++ unsigned flags;
++ int cpu = smp_processor_id();
++ in_kgdb_called = 1;
++ if (!spin_is_locked(&kgdb_spinlock)) {
++ if (in_kgdb_here_log[cpu] || /* we are holding this cpu */
++ in_kgdb_console) { /* or we are doing slow i/o */
++ return 1;
++ }
++ return 0;
++ }
++
++ /* As I see it the only reason not to let all cpus spin on
++ * the same spin_lock is to allow selected ones to proceed.
++ * This would be a good thing, so we leave it this way.
++ * Maybe someday.... Done !
++
++ * in_kgdb() is called from an NMI so we don't pretend
++ * to have any resources, like printk() for example.
++ */
++
++ kgdb_local_irq_save(flags); /* only local here, to avoid hanging */
++ /*
++ * log arival of this cpu
++ * The NMI keeps on ticking. Protect against recurring more
++ * than once, and ignor the cpu that has the kgdb lock
++ */
++ in_kgdb_entry_log[cpu]++;
++ in_kgdb_here_log[cpu] = regs;
++ if (cpu == spinlock_cpu || waiting_cpus[cpu].task) {
++ goto exit_in_kgdb;
++ }
++ /*
++ * For protection of the initilization of the spin locks by kgdb
++ * it locks the kgdb spinlock before it gets the wait locks set
++ * up. We wait here for the wait lock to be taken. If the
++ * kgdb lock goes away first?? Well, it could be a slow exit
++ * sequence where the wait lock is removed prior to the kgdb lock
++ * so if kgdb gets unlocked, we just exit.
++ */
++ while (spin_is_locked(&kgdb_spinlock) &&
++ !spin_is_locked(waitlocks + cpu)) ;
++ if (!spin_is_locked(&kgdb_spinlock)) {
++ goto exit_in_kgdb;
++ }
++ waiting_cpus[cpu].task = current;
++ waiting_cpus[cpu].pid = (current->pid) ? : (PID_MAX + cpu);
++ waiting_cpus[cpu].regs = regs;
++
++ spin_unlock_wait(waitlocks + cpu);
++ /*
++ * log departure of this cpu
++ */
++ waiting_cpus[cpu].task = 0;
++ waiting_cpus[cpu].pid = 0;
++ waiting_cpus[cpu].regs = 0;
++ correct_hw_break();
++ exit_in_kgdb:
++ in_kgdb_here_log[cpu] = 0;
++ kgdb_local_irq_restore(flags);
++ return 1;
++ /*
++ spin_unlock(continuelocks + smp_processor_id());
++ */
++}
++
++void
++smp__in_kgdb(struct pt_regs regs)
++{
++ ack_APIC_irq();
++ in_kgdb(®s);
++}
++#else
++int
++in_kgdb(struct pt_regs *regs)
++{
++ return (kgdb_spinlock);
++}
++#endif
++
++void
++printexceptioninfo(int exceptionNo, int errorcode, char *buffer)
++{
++ unsigned dr6;
++ int i;
++ switch (exceptionNo) {
++ case 1: /* debug exception */
++ break;
++ case 3: /* breakpoint */
++ sprintf(buffer, "Software breakpoint");
++ return;
++ default:
++ sprintf(buffer, "Details not available");
++ return;
++ }
++ asm volatile ("movl %%db6, %0\n":"=r" (dr6)
++ :);
++ if (dr6 & 0x4000) {
++ sprintf(buffer, "Single step");
++ return;
++ }
++ for (i = 0; i < 4; ++i) {
++ if (dr6 & (1 << i)) {
++ sprintf(buffer, "Hardware breakpoint %d", i);
++ return;
++ }
++ }
++ sprintf(buffer, "Unknown trap");
++ return;
++}
++
++/*
++ * This function does all command procesing for interfacing to gdb.
++ *
++ * NOTE: The INT nn instruction leaves the state of the interrupt
++ * enable flag UNCHANGED. That means that when this routine
++ * is entered via a breakpoint (INT 3) instruction from code
++ * that has interrupts enabled, then interrupts will STILL BE
++ * enabled when this routine is entered. The first thing that
++ * we do here is disable interrupts so as to prevent recursive
++ * entries and bothersome serial interrupts while we are
++ * trying to run the serial port in polled mode.
++ *
++ * For kernel version 2.1.xx the kgdb_cli() actually gets a spin lock so
++ * it is always necessary to do a restore_flags before returning
++ * so as to let go of that lock.
++ */
++int
++kgdb_handle_exception(int exceptionVector,
++ int signo, int err_code, struct pt_regs *linux_regs)
++{
++ struct task_struct *usethread = NULL;
++ struct task_struct *thread_list_start = 0, *thread = NULL;
++ int addr, length;
++ unsigned long address;
++ int breakno, breaktype;
++ char *ptr;
++ int newPC;
++ threadref thref;
++ int threadid;
++ int thread_min = PID_MAX + MAX_NO_CPUS;
++#ifdef old_thread_list
++ int maxthreads;
++#endif
++ int nothreads;
++ unsigned long flags;
++ int gdb_regs[NUMREGBYTES / 4];
++ int dr6;
++ IF_SMP(int entry_state = 0); /* 0, ok, 1, no nmi, 2 sync failed */
++#define NO_NMI 1
++#define NO_SYNC 2
++#define regs (*linux_regs)
++#define NUMREGS NUMREGBYTES/4
++ /*
++ * If the entry is not from the kernel then return to the Linux
++ * trap handler and let it process the interrupt normally.
++ */
++ if ((linux_regs->eflags & VM_MASK) || (3 & linux_regs->xcs)) {
++ printk("ignoring non-kernel exception\n");
++ print_regs(®s);
++ return (0);
++ }
++ /*
++ * If we're using eth mode, set the 'mode' in the netdevice.
++ */
++
++ __asm__("movl %%cr2,%0":"=r" (address));
++
++ if (kgdb_eth != -1) {
++ kgdb_eth_set_trapmode(1);
++ }
++
++ kgdb_local_irq_save(flags);
++
++ /* Get kgdb spinlock */
++
++ KGDB_SPIN_LOCK(&kgdb_spinlock);
++ rdtscll(kgdb_info.entry_tsc);
++ /*
++ * We depend on this spinlock and the NMI watch dog to control the
++ * other cpus. They will arrive at "in_kgdb()" as a result of the
++ * NMI and will wait there for the following spin locks to be
++ * released.
++ */
++#ifdef CONFIG_SMP
++
++#if 0
++ if (cpu_callout_map & ~MAX_CPU_MASK) {
++ printk("kgdb : too many cpus, possibly not mapped"
++ " in contiguous space, change MAX_NO_CPUS"
++ " in kgdb_stub and make new kernel.\n"
++ " cpu_callout_map is %lx\n", cpu_callout_map);
++ goto exit_just_unlock;
++ }
++#endif
++ if (spinlock_count == 1) {
++ int time, end_time, dum;
++ int i;
++ int cpu_logged_in[MAX_NO_CPUS] = {[0 ... MAX_NO_CPUS - 1] = (0)
++ };
++ if (remote_debug) {
++ printk("kgdb : cpu %d entry, syncing others\n",
++ smp_processor_id());
++ }
++ for (i = 0; i < MAX_NO_CPUS; i++) {
++ /*
++ * Use trylock as we may already hold the lock if
++ * we are holding the cpu. Net result is all
++ * locked.
++ */
++ spin_trylock(&waitlocks[i]);
++ }
++ for (i = 0; i < MAX_NO_CPUS; i++)
++ cpu_logged_in[i] = 0;
++ /*
++ * Wait for their arrival. We know the watch dog is active if
++ * in_kgdb() has ever been called, as it is always called on a
++ * watchdog tick.
++ */
++ rdtsc(dum, time);
++ end_time = time + 2; /* Note: we use the High order bits! */
++ i = 1;
++ if (num_online_cpus() > 1) {
++ int me_in_kgdb = in_kgdb_entry_log[smp_processor_id()];
++ smp_send_nmi_allbutself();
++ while (i < num_online_cpus() && time != end_time) {
++ int j;
++ for (j = 0; j < MAX_NO_CPUS; j++) {
++ if (waiting_cpus[j].task &&
++ !cpu_logged_in[j]) {
++ i++;
++ cpu_logged_in[j] = 1;
++ if (remote_debug) {
++ printk
++ ("kgdb : cpu %d arrived at kgdb\n",
++ j);
++ }
++ break;
++ } else if (!waiting_cpus[j].task &&
++ !cpu_online(j)) {
++ waiting_cpus[j].task = NOCPU;
++ cpu_logged_in[j] = 1;
++ waiting_cpus[j].hold = 1;
++ break;
++ }
++ if (!waiting_cpus[j].task &&
++ in_kgdb_here_log[j]) {
++
++ int wait = 100000;
++ while (wait--) ;
++ if (!waiting_cpus[j].task &&
++ in_kgdb_here_log[j]) {
++ printk
++ ("kgdb : cpu %d stall"
++ " in in_kgdb\n",
++ j);
++ i++;
++ cpu_logged_in[j] = 1;
++ waiting_cpus[j].task =
++ (struct task_struct
++ *) 1;
++ }
++ }
++ }
++
++ if (in_kgdb_entry_log[smp_processor_id()] >
++ (me_in_kgdb + 10)) {
++ break;
++ }
++
++ rdtsc(dum, time);
++ }
++ if (i < num_online_cpus()) {
++ printk
++ ("kgdb : time out, proceeding without sync\n");
++#if 0
++ printk("kgdb : Waiting_cpus: 0 = %d, 1 = %d\n",
++ waiting_cpus[0].task != 0,
++ waiting_cpus[1].task != 0);
++ printk("kgdb : Cpu_logged in: 0 = %d, 1 = %d\n",
++ cpu_logged_in[0], cpu_logged_in[1]);
++ printk
++ ("kgdb : in_kgdb_here_log in: 0 = %d, 1 = %d\n",
++ in_kgdb_here_log[0] != 0,
++ in_kgdb_here_log[1] != 0);
++#endif
++ entry_state = NO_SYNC;
++ } else {
++#if 0
++ int ent =
++ in_kgdb_entry_log[smp_processor_id()] -
++ me_in_kgdb;
++ printk("kgdb : sync after %d entries\n", ent);
++#endif
++ }
++ } else {
++ if (remote_debug) {
++ printk
++ ("kgdb : %d cpus, but watchdog not active\n"
++ "proceeding without locking down other cpus\n",
++ num_online_cpus());
++ entry_state = NO_NMI;
++ }
++ }
++ }
++#endif
++
++ if (remote_debug) {
++ printk("handle_exception(exceptionVector=%d, "
++ "signo=%d, err_code=%d, linux_regs=%p)\n",
++ exceptionVector, signo, err_code, linux_regs);
++ printk(" address: %lx\n", address);
++
++ if (debug_regs) {
++ print_regs(®s);
++ show_trace(current, (unsigned long *)®s);
++ }
++ }
++
++ /* Disable hardware debugging while we are in kgdb */
++ /* Get the debug register status register */
++/* *INDENT-OFF* */
++ __asm__("movl %0,%%db7"
++ : /* no output */
++ :"r"(0));
++
++ asm volatile ("movl %%db6, %0\n"
++ :"=r" (hw_breakpoint_status)
++ :);
++
++/* *INDENT-ON* */
++ switch (exceptionVector) {
++ case 0: /* divide error */
++ case 1: /* debug exception */
++ case 2: /* NMI */
++ case 3: /* breakpoint */
++ case 4: /* overflow */
++ case 5: /* bounds check */
++ case 6: /* invalid opcode */
++ case 7: /* device not available */
++ case 8: /* double fault (errcode) */
++ case 10: /* invalid TSS (errcode) */
++ case 12: /* stack fault (errcode) */
++ case 16: /* floating point error */
++ case 17: /* alignment check (errcode) */
++ default: /* any undocumented */
++ break;
++ case 11: /* segment not present (errcode) */
++ case 13: /* general protection (errcode) */
++ case 14: /* page fault (special errcode) */
++ case 19: /* cache flush denied */
++ if (mem_err_expected) {
++ /*
++ * This fault occured because of the
++ * get_char or set_char routines. These
++ * two routines use either eax of edx to
++ * indirectly reference the location in
++ * memory that they are working with.
++ * For a page fault, when we return the
++ * instruction will be retried, so we
++ * have to make sure that these
++ * registers point to valid memory.
++ */
++ mem_err = 1; /* set mem error flag */
++ mem_err_expected = 0;
++ mem_err_cnt++; /* helps in debugging */
++ /* make valid address */
++ regs.eax = (long) &garbage_loc;
++ /* make valid address */
++ regs.edx = (long) &garbage_loc;
++ if (remote_debug)
++ printk("Return after memory error: "
++ "mem_err_cnt=%d\n", mem_err_cnt);
++ if (debug_regs)
++ print_regs(®s);
++ goto exit_kgdb;
++ }
++ break;
++ }
++ if (remote_debug)
++ printk("kgdb : entered kgdb on cpu %d\n", smp_processor_id());
++
++ gdb_i386vector = exceptionVector;
++ gdb_i386errcode = err_code;
++ kgdb_info.called_from = __builtin_return_address(0);
++#ifdef CONFIG_SMP
++ /*
++ * OK, we can now communicate, lets tell gdb about the sync.
++ * but only if we had a problem.
++ */
++ switch (entry_state) {
++ case NO_NMI:
++ to_gdb("NMI not active, other cpus not stopped\n");
++ break;
++ case NO_SYNC:
++ to_gdb("Some cpus not stopped, see 'kgdb_info' for details\n");
++ default:;
++ }
++
++#endif
++/*
++ * Set up the gdb function call area.
++ */
++ trap_cpu = smp_processor_id();
++ OLD_esp = NEW_esp = (int) (&linux_regs->esp);
++
++ IF_SMP(once_again:)
++ /* reply to host that an exception has occurred */
++ remcomOutBuffer[0] = 'S';
++ remcomOutBuffer[1] = hexchars[signo >> 4];
++ remcomOutBuffer[2] = hexchars[signo % 16];
++ remcomOutBuffer[3] = 0;
++
++ if (kgdb_eth_is_initializing) {
++ kgdb_eth_is_initializing = 0;
++ } else {
++ putpacket(remcomOutBuffer);
++ }
++
++ kgdb_eth_reply_arp();
++ while (1 == 1) {
++ error = 0;
++ remcomOutBuffer[0] = 0;
++ getpacket(remcomInBuffer);
++ switch (remcomInBuffer[0]) {
++ case '?':
++ remcomOutBuffer[0] = 'S';
++ remcomOutBuffer[1] = hexchars[signo >> 4];
++ remcomOutBuffer[2] = hexchars[signo % 16];
++ remcomOutBuffer[3] = 0;
++ break;
++ case 'd':
++ remote_debug = !(remote_debug); /* toggle debug flag */
++ printk("Remote debug %s\n",
++ remote_debug ? "on" : "off");
++ break;
++ case 'g': /* return the value of the CPU registers */
++ get_gdb_regs(usethread, ®s, gdb_regs);
++ mem2hex((char *) gdb_regs,
++ remcomOutBuffer, NUMREGBYTES, 0);
++ break;
++ case 'G': /* set the value of the CPU registers - return OK */
++ hex2mem(&remcomInBuffer[1],
++ (char *) gdb_regs, NUMREGBYTES, 0);
++ if (!usethread || usethread == current) {
++ gdb_regs_to_regs(gdb_regs, ®s);
++ strcpy(remcomOutBuffer, "OK");
++ } else {
++ strcpy(remcomOutBuffer, "E00");
++ }
++ break;
++
++ case 'P':{ /* set the value of a single CPU register -
++ return OK */
++ /*
++ * For some reason, gdb wants to talk about psudo
++ * registers (greater than 15). These may have
++ * meaning for ptrace, but for us it is safe to
++ * ignor them. We do this by dumping them into
++ * _GS which we also ignor, but do have memory for.
++ */
++ int regno;
++
++ ptr = &remcomInBuffer[1];
++ regs_to_gdb_regs(gdb_regs, ®s);
++ if ((!usethread || usethread == current) &&
++ hexToInt(&ptr, ®no) &&
++ *ptr++ == '=' && (regno >= 0)) {
++ regno =
++ (regno >= NUMREGS ? _GS : regno);
++ hex2mem(ptr, (char *) &gdb_regs[regno],
++ 4, 0);
++ gdb_regs_to_regs(gdb_regs, ®s);
++ strcpy(remcomOutBuffer, "OK");
++ break;
++ }
++ strcpy(remcomOutBuffer, "E01");
++ break;
++ }
++
++ /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
++ case 'm':
++ /* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */
++ ptr = &remcomInBuffer[1];
++ if (hexToInt(&ptr, &addr) &&
++ (*(ptr++) == ',') && (hexToInt(&ptr, &length))) {
++ ptr = 0;
++ /*
++ * hex doubles the byte count
++ */
++ if (length > (BUFMAX / 2))
++ length = BUFMAX / 2;
++ mem2hex((char *) addr,
++ remcomOutBuffer, length, 1);
++ if (mem_err) {
++ strcpy(remcomOutBuffer, "E03");
++ debug_error("memory fault\n", NULL);
++ }
++ }
++
++ if (ptr) {
++ strcpy(remcomOutBuffer, "E01");
++ debug_error
++ ("malformed read memory command: %s\n",
++ remcomInBuffer);
++ }
++ break;
++
++ /* MAA..AA,LLLL:
++ Write LLLL bytes at address AA.AA return OK */
++ case 'M':
++ /* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */
++ ptr = &remcomInBuffer[1];
++ if (hexToInt(&ptr, &addr) &&
++ (*(ptr++) == ',') &&
++ (hexToInt(&ptr, &length)) && (*(ptr++) == ':')) {
++ hex2mem(ptr, (char *) addr, length, 1);
++
++ if (mem_err) {
++ strcpy(remcomOutBuffer, "E03");
++ debug_error("memory fault\n", NULL);
++ } else {
++ strcpy(remcomOutBuffer, "OK");
++ }
++
++ ptr = 0;
++ }
++ if (ptr) {
++ strcpy(remcomOutBuffer, "E02");
++ debug_error
++ ("malformed write memory command: %s\n",
++ remcomInBuffer);
++ }
++ break;
++ case 'S':
++ remcomInBuffer[0] = 's';
++ case 'C':
++ /* Csig;AA..AA where ;AA..AA is optional
++ * continue with signal
++ * Since signals are meaning less to us, delete that
++ * part and then fall into the 'c' code.
++ */
++ ptr = &remcomInBuffer[1];
++ length = 2;
++ while (*ptr && *ptr != ';') {
++ length++;
++ ptr++;
++ }
++ if (*ptr) {
++ do {
++ ptr++;
++ *(ptr - length++) = *ptr;
++ } while (*ptr);
++ } else {
++ remcomInBuffer[1] = 0;
++ }
++
++ /* cAA..AA Continue at address AA..AA(optional) */
++ /* sAA..AA Step one instruction from AA..AA(optional) */
++ /* D detach, reply OK and then continue */
++ case 'c':
++ case 's':
++ case 'D':
++
++ /* try to read optional parameter,
++ pc unchanged if no parm */
++ ptr = &remcomInBuffer[1];
++ if (hexToInt(&ptr, &addr)) {
++ if (remote_debug)
++ printk("Changing EIP to 0x%x\n", addr);
++
++ regs.eip = addr;
++ }
++
++ newPC = regs.eip;
++
++ if (kgdb_eth != -1) {
++ kgdb_eth_set_trapmode(0);
++ }
++
++ /* clear the trace bit */
++ regs.eflags &= 0xfffffeff;
++
++ /* set the trace bit if we're stepping */
++ if (remcomInBuffer[0] == 's')
++ regs.eflags |= 0x100;
++
++ /* detach is a friendly version of continue. Note that
++ debugging is still enabled (e.g hit control C)
++ */
++ if (remcomInBuffer[0] == 'D') {
++ strcpy(remcomOutBuffer, "OK");
++ putpacket(remcomOutBuffer);
++ }
++
++ if (remote_debug) {
++ printk("Resuming execution\n");
++ print_regs(®s);
++ }
++ asm volatile ("movl %%db6, %0\n":"=r" (dr6)
++ :);
++ if (!(dr6 & 0x4000)) {
++ for (breakno = 0; breakno < 4; ++breakno) {
++ if (dr6 & (1 << breakno) &&
++ (breakinfo[breakno].type == 0)) {
++ /* Set restore flag */
++ regs.eflags |= 0x10000;
++ break;
++ }
++ }
++ }
++ correct_hw_break();
++ asm volatile ("movl %0, %%db6\n"::"r" (0));
++ goto exit_kgdb;
++
++ /* kill the program */
++ case 'k': /* do nothing */
++ break;
++
++ /* query */
++ case 'q':
++ nothreads = 0;
++ switch (remcomInBuffer[1]) {
++ case 'f':
++ threadid = 1;
++ thread_list = 2;
++ thread_list_start = (usethread ? : current);
++ case 's':
++ if (!cmp_str(&remcomInBuffer[2],
++ "ThreadInfo", 10))
++ break;
++
++ remcomOutBuffer[nothreads++] = 'm';
++ for (; threadid < PID_MAX + MAX_NO_CPUS;
++ threadid++) {
++ thread = getthread(threadid);
++ if (thread) {
++ nothreads += int_to_hex_v(
++ &remcomOutBuffer[
++ nothreads],
++ threadid);
++ if (thread_min > threadid)
++ thread_min = threadid;
++ remcomOutBuffer[
++ nothreads] = ',';
++ nothreads++;
++ if (nothreads > BUFMAX - 10)
++ break;
++ }
++ }
++ if (remcomOutBuffer[nothreads - 1] == 'm') {
++ remcomOutBuffer[nothreads - 1] = 'l';
++ } else {
++ nothreads--;
++ }
++ remcomOutBuffer[nothreads] = 0;
++ break;
++
++#ifdef old_thread_list /* Old thread info request */
++ case 'L':
++ /* List threads */
++ thread_list = 2;
++ thread_list_start = (usethread ? : current);
++ unpack_byte(remcomInBuffer + 3, &maxthreads);
++ unpack_threadid(remcomInBuffer + 5, &thref);
++ do {
++ int buf_thread_limit =
++ (BUFMAX - 22) / BUF_THREAD_ID_SIZE;
++ if (maxthreads > buf_thread_limit) {
++ maxthreads = buf_thread_limit;
++ }
++ } while (0);
++ remcomOutBuffer[0] = 'q';
++ remcomOutBuffer[1] = 'M';
++ remcomOutBuffer[4] = '0';
++ pack_threadid(remcomOutBuffer + 5, &thref);
++
++ threadid = threadref_to_int(&thref);
++ for (nothreads = 0;
++ nothreads < maxthreads &&
++ threadid < PID_MAX + MAX_NO_CPUS;
++ threadid++) {
++ thread = getthread(threadid);
++ if (thread) {
++ int_to_threadref(&thref,
++ threadid);
++ pack_threadid(remcomOutBuffer +
++ 21 +
++ nothreads * 16,
++ &thref);
++ nothreads++;
++ if (thread_min > threadid)
++ thread_min = threadid;
++ }
++ }
++
++ if (threadid == PID_MAX + MAX_NO_CPUS) {
++ remcomOutBuffer[4] = '1';
++ }
++ pack_hex_byte(remcomOutBuffer + 2, nothreads);
++ remcomOutBuffer[21 + nothreads * 16] = '\0';
++ break;
++#endif
++ case 'C':
++ /* Current thread id */
++ remcomOutBuffer[0] = 'Q';
++ remcomOutBuffer[1] = 'C';
++ threadid = current->pid;
++ if (!threadid) {
++ /*
++ * idle thread
++ */
++ for (threadid = PID_MAX;
++ threadid < PID_MAX + MAX_NO_CPUS;
++ threadid++) {
++ if (current ==
++ idle_task(threadid -
++ PID_MAX))
++ break;
++ }
++ }
++ int_to_threadref(&thref, threadid);
++ pack_threadid(remcomOutBuffer + 2, &thref);
++ remcomOutBuffer[18] = '\0';
++ break;
++
++ case 'E':
++ /* Print exception info */
++ printexceptioninfo(exceptionVector,
++ err_code, remcomOutBuffer);
++ break;
++ case 'T':{
++ char * nptr;
++ /* Thread extra info */
++ if (!cmp_str(&remcomInBuffer[2],
++ "hreadExtraInfo,", 15)) {
++ break;
++ }
++ ptr = &remcomInBuffer[17];
++ hexToInt(&ptr, &threadid);
++ thread = getthread(threadid);
++ nptr = &thread->comm[0];
++ length = 0;
++ ptr = &remcomOutBuffer[0];
++ do {
++ length++;
++ ptr = pack_hex_byte(ptr, *nptr++);
++ } while (*nptr && length < 16);
++ /*
++ * would like that 16 to be the size of
++ * task_struct.comm but don't know the
++ * syntax..
++ */
++ *ptr = 0;
++ }
++ }
++ break;
++
++ /* task related */
++ case 'H':
++ switch (remcomInBuffer[1]) {
++ case 'g':
++ ptr = &remcomInBuffer[2];
++ hexToInt(&ptr, &threadid);
++ thread = getthread(threadid);
++ if (!thread) {
++ remcomOutBuffer[0] = 'E';
++ remcomOutBuffer[1] = '\0';
++ break;
++ }
++ /*
++ * Just in case I forget what this is all about,
++ * the "thread info" command to gdb causes it
++ * to ask for a thread list. It then switches
++ * to each thread and asks for the registers.
++ * For this (and only this) usage, we want to
++ * fudge the registers of tasks not on the run
++ * list (i.e. waiting) to show the routine that
++ * called schedule. Also, gdb, is a minimalist
++ * in that if the current thread is the last
++ * it will not re-read the info when done.
++ * This means that in this case we must show
++ * the real registers. So here is how we do it:
++ * Each entry we keep track of the min
++ * thread in the list (the last that gdb will)
++ * get info for. We also keep track of the
++ * starting thread.
++ * "thread_list" is cleared when switching back
++ * to the min thread if it is was current, or
++ * if it was not current, thread_list is set
++ * to 1. When the switch to current comes,
++ * if thread_list is 1, clear it, else do
++ * nothing.
++ */
++ usethread = thread;
++ if ((thread_list == 1) &&
++ (thread == thread_list_start)) {
++ thread_list = 0;
++ }
++ if (thread_list && (threadid == thread_min)) {
++ if (thread == thread_list_start) {
++ thread_list = 0;
++ } else {
++ thread_list = 1;
++ }
++ }
++ /* follow through */
++ case 'c':
++ remcomOutBuffer[0] = 'O';
++ remcomOutBuffer[1] = 'K';
++ remcomOutBuffer[2] = '\0';
++ break;
++ }
++ break;
++
++ /* Query thread status */
++ case 'T':
++ ptr = &remcomInBuffer[1];
++ hexToInt(&ptr, &threadid);
++ thread = getthread(threadid);
++ if (thread) {
++ remcomOutBuffer[0] = 'O';
++ remcomOutBuffer[1] = 'K';
++ remcomOutBuffer[2] = '\0';
++ if (thread_min > threadid)
++ thread_min = threadid;
++ } else {
++ remcomOutBuffer[0] = 'E';
++ remcomOutBuffer[1] = '\0';
++ }
++ break;
++
++ case 'Y': /* set up a hardware breakpoint */
++ ptr = &remcomInBuffer[1];
++ hexToInt(&ptr, &breakno);
++ ptr++;
++ hexToInt(&ptr, &breaktype);
++ ptr++;
++ hexToInt(&ptr, &length);
++ ptr++;
++ hexToInt(&ptr, &addr);
++ if (set_hw_break(breakno & 0x3,
++ breaktype & 0x3,
++ length & 0x3, addr) == 0) {
++ strcpy(remcomOutBuffer, "OK");
++ } else {
++ strcpy(remcomOutBuffer, "ERROR");
++ }
++ break;
++
++ /* Remove hardware breakpoint */
++ case 'y':
++ ptr = &remcomInBuffer[1];
++ hexToInt(&ptr, &breakno);
++ if (remove_hw_break(breakno & 0x3) == 0) {
++ strcpy(remcomOutBuffer, "OK");
++ } else {
++ strcpy(remcomOutBuffer, "ERROR");
++ }
++ break;
++
++ case 'r': /* reboot */
++ strcpy(remcomOutBuffer, "OK");
++ putpacket(remcomOutBuffer);
++ /*to_gdb("Rebooting\n"); */
++ /* triplefault no return from here */
++ {
++ static long no_idt[2];
++ __asm__ __volatile__("lidt %0"::"m"(no_idt[0]));
++ BREAKPOINT;
++ }
++
++ } /* switch */
++
++ /* reply to the request */
++ putpacket(remcomOutBuffer);
++ } /* while(1==1) */
++ /*
++ * reached by goto only.
++ */
++ exit_kgdb:
++ /*
++ * Here is where we set up to trap a gdb function call. NEW_esp
++ * will be changed if we are trying to do this. We handle both
++ * adding and subtracting, thus allowing gdb to put grung on
++ * the stack which it removes later.
++ */
++ if (NEW_esp != OLD_esp) {
++ int *ptr = END_OF_LOOKASIDE;
++ if (NEW_esp < OLD_esp)
++ ptr -= (OLD_esp - NEW_esp) / sizeof (int);
++ *--ptr = linux_regs->eflags;
++ *--ptr = linux_regs->xcs;
++ *--ptr = linux_regs->eip;
++ *--ptr = linux_regs->ecx;
++ *--ptr = linux_regs->ebx;
++ *--ptr = linux_regs->eax;
++ linux_regs->ecx = NEW_esp - (sizeof (int) * 6);
++ linux_regs->ebx = (unsigned int) END_OF_LOOKASIDE;
++ if (NEW_esp < OLD_esp) {
++ linux_regs->eip = (unsigned int) fn_call_stub;
++ } else {
++ linux_regs->eip = (unsigned int) fn_rtn_stub;
++ linux_regs->eax = NEW_esp;
++ }
++ linux_regs->eflags &= ~(IF_BIT | TF_BIT);
++ }
++#ifdef CONFIG_SMP
++ /*
++ * Release gdb wait locks
++ * Sanity check time. Must have at least one cpu to run. Also single
++ * step must not be done if the current cpu is on hold.
++ */
++ if (spinlock_count == 1) {
++ int ss_hold = (regs.eflags & 0x100) && kgdb_info.hold_on_sstep;
++ int cpu_avail = 0;
++ int i;
++
++ for (i = 0; i < MAX_NO_CPUS; i++) {
++ if (!cpu_online(i))
++ break;
++ if (!hold_cpu(i)) {
++ cpu_avail = 1;
++ }
++ }
++ /*
++ * Early in the bring up there will be NO cpus on line...
++ */
++ if (!cpu_avail && !cpus_empty(cpu_online_map)) {
++ to_gdb("No cpus unblocked, see 'kgdb_info.hold_cpu'\n");
++ goto once_again;
++ }
++ if (hold_cpu(smp_processor_id()) && (regs.eflags & 0x100)) {
++ to_gdb
++ ("Current cpu must be unblocked to single step\n");
++ goto once_again;
++ }
++ if (!(ss_hold)) {
++ int i;
++ for (i = 0; i < MAX_NO_CPUS; i++) {
++ if (!hold_cpu(i)) {
++ spin_unlock(&waitlocks[i]);
++ }
++ }
++ } else {
++ spin_unlock(&waitlocks[smp_processor_id()]);
++ }
++ /* Release kgdb spinlock */
++ KGDB_SPIN_UNLOCK(&kgdb_spinlock);
++ /*
++ * If this cpu is on hold, this is where we
++ * do it. Note, the NMI will pull us out of here,
++ * but will return as the above lock is not held.
++ * We will stay here till another cpu releases the lock for us.
++ */
++ spin_unlock_wait(waitlocks + smp_processor_id());
++ kgdb_local_irq_restore(flags);
++ return (0);
++ }
++#if 0
++exit_just_unlock:
++#endif
++#endif
++ /* Release kgdb spinlock */
++ KGDB_SPIN_UNLOCK(&kgdb_spinlock);
++ kgdb_local_irq_restore(flags);
++ return (0);
++}
++
++/* this function is used to set up exception handlers for tracing and
++ * breakpoints.
++ * This function is not needed as the above line does all that is needed.
++ * We leave it for backward compatitability...
++ */
++void
++set_debug_traps(void)
++{
++ /*
++ * linux_debug_hook is defined in traps.c. We store a pointer
++ * to our own exception handler into it.
++
++ * But really folks, every hear of labeled common, an old Fortran
++ * concept. Lots of folks can reference it and it is define if
++ * anyone does. Only one can initialize it at link time. We do
++ * this with the hook. See the statement above. No need for any
++ * executable code and it is ready as soon as the kernel is
++ * loaded. Very desirable in kernel debugging.
++
++ linux_debug_hook = handle_exception ;
++ */
++
++ /* In case GDB is started before us, ack any packets (presumably
++ "$?#xx") sitting there.
++ putDebugChar ('+');
++
++ initialized = 1;
++ */
++}
++
++/* This function will generate a breakpoint exception. It is used at the
++ beginning of a program to sync up with a debugger and can be used
++ otherwise as a quick means to stop program execution and "break" into
++ the debugger. */
++/* But really, just use the BREAKPOINT macro. We will handle the int stuff
++ */
++
++#ifdef later
++/*
++ * possibly we should not go thru the traps.c code at all? Someday.
++ */
++void
++do_kgdb_int3(struct pt_regs *regs, long error_code)
++{
++ kgdb_handle_exception(3, 5, error_code, regs);
++ return;
++}
++#endif
++#undef regs
++#ifdef CONFIG_TRAP_BAD_SYSCALL_EXITS
++asmlinkage void
++bad_sys_call_exit(int stuff)
++{
++ struct pt_regs *regs = (struct pt_regs *) &stuff;
++ printk("Sys call %d return with %x preempt_count\n",
++ (int) regs->orig_eax, preempt_count());
++}
++#endif
++#ifdef CONFIG_STACK_OVERFLOW_TEST
++#include <asm/kgdb.h>
++asmlinkage void
++stack_overflow(void)
++{
++#ifdef BREAKPOINT
++ BREAKPOINT;
++#else
++ printk("Kernel stack overflow, looping forever\n");
++#endif
++ while (1) {
++ }
++}
++#endif
++
++#if defined(CONFIG_SMP) || defined(CONFIG_KGDB_CONSOLE)
++char gdbconbuf[BUFMAX];
++
++static void
++kgdb_gdb_message(const char *s, unsigned count)
++{
++ int i;
++ int wcount;
++ char *bufptr;
++ /*
++ * This takes care of NMI while spining out chars to gdb
++ */
++ IF_SMP(in_kgdb_console = 1);
++ gdbconbuf[0] = 'O';
++ bufptr = gdbconbuf + 1;
++ while (count > 0) {
++ if ((count << 1) > (BUFMAX - 2)) {
++ wcount = (BUFMAX - 2) >> 1;
++ } else {
++ wcount = count;
++ }
++ count -= wcount;
++ for (i = 0; i < wcount; i++) {
++ bufptr = pack_hex_byte(bufptr, s[i]);
++ }
++ *bufptr = '\0';
++ s += wcount;
++
++ putpacket(gdbconbuf);
++
++ }
++ IF_SMP(in_kgdb_console = 0);
++}
++#endif
++#ifdef CONFIG_SMP
++static void
++to_gdb(const char *s)
++{
++ int count = 0;
++ while (s[count] && (count++ < BUFMAX)) ;
++ kgdb_gdb_message(s, count);
++}
++#endif
++#ifdef CONFIG_KGDB_CONSOLE
++#include <linux/console.h>
++#include <linux/init.h>
++#include <linux/fs.h>
++#include <asm/uaccess.h>
++#include <asm/semaphore.h>
++
++void
++kgdb_console_write(struct console *co, const char *s, unsigned count)
++{
++
++ if (gdb_i386vector == -1) {
++ /*
++ * We have not yet talked to gdb. What to do...
++ * lets break, on continue we can do the write.
++ * But first tell him whats up. Uh, well no can do,
++ * as this IS the console. Oh well...
++ * We do need to wait or the messages will be lost.
++ * Other option would be to tell the above code to
++ * ignore this breakpoint and do an auto return,
++ * but that might confuse gdb. Also this happens
++ * early enough in boot up that we don't have the traps
++ * set up yet, so...
++ */
++ breakpoint();
++ }
++ kgdb_gdb_message(s, count);
++}
++
++/*
++ * ------------------------------------------------------------
++ * Serial KGDB driver
++ * ------------------------------------------------------------
++ */
++
++static struct console kgdbcons = {
++ name:"kgdb",
++ write:kgdb_console_write,
++#ifdef CONFIG_KGDB_USER_CONSOLE
++ device:kgdb_console_device,
++#endif
++ flags:CON_PRINTBUFFER | CON_ENABLED,
++ index:-1,
++};
++
++/*
++ * The trick here is that this file gets linked before printk.o
++ * That means we get to peer at the console info in the command
++ * line before it does. If we are up, we register, otherwise,
++ * do nothing. By returning 0, we allow printk to look also.
++ */
++static int kgdb_console_enabled;
++
++int __init
++kgdb_console_init(char *str)
++{
++ if ((strncmp(str, "kgdb", 4) == 0) || (strncmp(str, "gdb", 3) == 0)) {
++ register_console(&kgdbcons);
++ kgdb_console_enabled = 1;
++ }
++ return 0; /* let others look at the string */
++}
++
++__setup("console=", kgdb_console_init);
++
++#ifdef CONFIG_KGDB_USER_CONSOLE
++static kdev_t kgdb_console_device(struct console *c);
++/* This stuff sort of works, but it knocks out telnet devices
++ * we are leaving it here in case we (or you) find time to figure it out
++ * better..
++ */
++
++/*
++ * We need a real char device as well for when the console is opened for user
++ * space activities.
++ */
++
++static int
++kgdb_consdev_open(struct inode *inode, struct file *file)
++{
++ return 0;
++}
++
++static ssize_t
++kgdb_consdev_write(struct file *file, const char *buf,
++ size_t count, loff_t * ppos)
++{
++ int size, ret = 0;
++ static char kbuf[128];
++ static DECLARE_MUTEX(sem);
++
++ /* We are not reentrant... */
++ if (down_interruptible(&sem))
++ return -ERESTARTSYS;
++
++ while (count > 0) {
++ /* need to copy the data from user space */
++ size = count;
++ if (size > sizeof (kbuf))
++ size = sizeof (kbuf);
++ if (copy_from_user(kbuf, buf, size)) {
++ ret = -EFAULT;
++ break;;
++ }
++ kgdb_console_write(&kgdbcons, kbuf, size);
++ count -= size;
++ ret += size;
++ buf += size;
++ }
++
++ up(&sem);
++
++ return ret;
++}
++
++struct file_operations kgdb_consdev_fops = {
++ open:kgdb_consdev_open,
++ write:kgdb_consdev_write
++};
++static kdev_t
++kgdb_console_device(struct console *c)
++{
++ return MKDEV(TTYAUX_MAJOR, 1);
++}
++
++/*
++ * This routine gets called from the serial stub in the i386/lib
++ * This is so it is done late in bring up (just before the console open).
++ */
++void
++kgdb_console_finit(void)
++{
++ if (kgdb_console_enabled) {
++ char *cptr = cdevname(MKDEV(TTYAUX_MAJOR, 1));
++ char *cp = cptr;
++ while (*cptr && *cptr != '(')
++ cptr++;
++ *cptr = 0;
++ unregister_chrdev(TTYAUX_MAJOR, cp);
++ register_chrdev(TTYAUX_MAJOR, "kgdb", &kgdb_consdev_fops);
++ }
++}
++#endif
++#endif
++#ifdef CONFIG_KGDB_TS
++#include <asm/msr.h> /* time stamp code */
++#include <asm/hardirq.h> /* in_interrupt */
++#ifdef CONFIG_KGDB_TS_64
++#define DATA_POINTS 64
++#endif
++#ifdef CONFIG_KGDB_TS_128
++#define DATA_POINTS 128
++#endif
++#ifdef CONFIG_KGDB_TS_256
++#define DATA_POINTS 256
++#endif
++#ifdef CONFIG_KGDB_TS_512
++#define DATA_POINTS 512
++#endif
++#ifdef CONFIG_KGDB_TS_1024
++#define DATA_POINTS 1024
++#endif
++#ifndef DATA_POINTS
++#define DATA_POINTS 128 /* must be a power of two */
++#endif
++#define INDEX_MASK (DATA_POINTS - 1)
++#if (INDEX_MASK & DATA_POINTS)
++#error "CONFIG_KGDB_TS_COUNT must be a power of 2"
++#endif
++struct kgdb_and_then_struct {
++#ifdef CONFIG_SMP
++ int on_cpu;
++#endif
++ struct task_struct *task;
++ long long at_time;
++ int from_ln;
++ char *in_src;
++ void *from;
++ int *with_shpf;
++ int data0;
++ int data1;
++};
++struct kgdb_and_then_struct2 {
++#ifdef CONFIG_SMP
++ int on_cpu;
++#endif
++ struct task_struct *task;
++ long long at_time;
++ int from_ln;
++ char *in_src;
++ void *from;
++ int *with_shpf;
++ struct task_struct *t1;
++ struct task_struct *t2;
++};
++struct kgdb_and_then_struct kgdb_data[DATA_POINTS];
++
++struct kgdb_and_then_struct *kgdb_and_then = &kgdb_data[0];
++int kgdb_and_then_count;
++
++void
++kgdb_tstamp(int line, char *source, int data0, int data1)
++{
++ static spinlock_t ts_spin = SPIN_LOCK_UNLOCKED;
++ int flags;
++ kgdb_local_irq_save(flags);
++ spin_lock(&ts_spin);
++ rdtscll(kgdb_and_then->at_time);
++#ifdef CONFIG_SMP
++ kgdb_and_then->on_cpu = smp_processor_id();
++#endif
++ kgdb_and_then->task = current;
++ kgdb_and_then->from_ln = line;
++ kgdb_and_then->in_src = source;
++ kgdb_and_then->from = __builtin_return_address(0);
++ kgdb_and_then->with_shpf = (int *) (((flags & IF_BIT) >> 9) |
++ (preempt_count() << 8));
++ kgdb_and_then->data0 = data0;
++ kgdb_and_then->data1 = data1;
++ kgdb_and_then = &kgdb_data[++kgdb_and_then_count & INDEX_MASK];
++ spin_unlock(&ts_spin);
++ kgdb_local_irq_restore(flags);
++#ifdef CONFIG_PREEMPT
++
++#endif
++ return;
++}
++#endif
++typedef int gdb_debug_hook(int exceptionVector,
++ int signo, int err_code, struct pt_regs *linux_regs);
++gdb_debug_hook *linux_debug_hook = &kgdb_handle_exception; /* histerical reasons... */
++
++static int __init kgdb_opt_kgdbeth(char *str)
++{
++ kgdb_eth = simple_strtoul(str, NULL, 10);
++ return 1;
++}
++
++static int __init kgdb_opt_kgdbeth_remoteip(char *str)
++{
++ kgdb_remoteip = in_aton(str);
++ return 1;
++}
++
++static int __init kgdb_opt_kgdbeth_listenport(char *str)
++{
++ kgdb_listenport = simple_strtoul(str, NULL, 10);
++ kgdb_sendport = kgdb_listenport - 1;
++ return 1;
++}
++
++static int __init parse_hw_addr(char *str, unsigned char *addr)
++{
++ int i;
++ char *p;
++
++ p = str;
++ i = 0;
++ while(1)
++ {
++ unsigned int c;
++
++ sscanf(p, "%x:", &c);
++ addr[i++] = c;
++ while((*p != 0) && (*p != ':')) {
++ p++;
++ }
++ if (*p == 0) {
++ break;
++ }
++ p++;
++ }
++
++ return 1;
++}
++
++static int __init kgdb_opt_kgdbeth_remotemac(char *str)
++{
++ return parse_hw_addr(str, kgdb_remotemac);
++}
++static int __init kgdb_opt_kgdbeth_localmac(char *str)
++{
++ return parse_hw_addr(str, kgdb_localmac);
++}
++
++
++__setup("gdbeth=", kgdb_opt_kgdbeth);
++__setup("gdbeth_remoteip=", kgdb_opt_kgdbeth_remoteip);
++__setup("gdbeth_listenport=", kgdb_opt_kgdbeth_listenport);
++__setup("gdbeth_remotemac=", kgdb_opt_kgdbeth_remotemac);
++__setup("gdbeth_localmac=", kgdb_opt_kgdbeth_localmac);
++
+Index: linux-2.6.0-test5/arch/i386/kernel/ldt.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/ldt.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/ldt.c 2003-09-27 11:38:19.043633312 +0800
+@@ -2,7 +2,7 @@
+ * linux/kernel/ldt.c
+ *
+ * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds
+- * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
++ * Copyright (C) 1999, 2003 Ingo Molnar <mingo@redhat.com>
+ */
+
+ #include <linux/errno.h>
+@@ -18,6 +18,8 @@
+ #include <asm/system.h>
+ #include <asm/ldt.h>
+ #include <asm/desc.h>
++#include <linux/highmem.h>
++#include <asm/atomic_kmap.h>
+
+ #ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
+ static void flush_ldt(void *null)
+@@ -29,34 +31,31 @@
+
+ static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
+ {
+- void *oldldt;
+- void *newldt;
+- int oldsize;
++ int oldsize, newsize, i;
+
+ if (mincount <= pc->size)
+ return 0;
++ /*
++ * LDT got larger - reallocate if necessary.
++ */
+ oldsize = pc->size;
+ mincount = (mincount+511)&(~511);
+- if (mincount*LDT_ENTRY_SIZE > PAGE_SIZE)
+- newldt = vmalloc(mincount*LDT_ENTRY_SIZE);
+- else
+- newldt = kmalloc(mincount*LDT_ENTRY_SIZE, GFP_KERNEL);
+-
+- if (!newldt)
+- return -ENOMEM;
+-
+- if (oldsize)
+- memcpy(newldt, pc->ldt, oldsize*LDT_ENTRY_SIZE);
+- oldldt = pc->ldt;
+- memset(newldt+oldsize*LDT_ENTRY_SIZE, 0, (mincount-oldsize)*LDT_ENTRY_SIZE);
+- pc->ldt = newldt;
+- wmb();
++ newsize = mincount*LDT_ENTRY_SIZE;
++ for (i = 0; i < newsize; i += PAGE_SIZE) {
++ int nr = i/PAGE_SIZE;
++ BUG_ON(i >= 64*1024);
++ if (!pc->ldt_pages[nr]) {
++ pc->ldt_pages[nr] = alloc_page(GFP_HIGHUSER);
++ if (!pc->ldt_pages[nr])
++ return -ENOMEM;
++ clear_highpage(pc->ldt_pages[nr]);
++ }
++ }
+ pc->size = mincount;
+- wmb();
+-
+ if (reload) {
+ #ifdef CONFIG_SMP
+ cpumask_t mask;
++
+ preempt_disable();
+ load_LDT(pc);
+ mask = cpumask_of_cpu(smp_processor_id());
+@@ -67,21 +66,20 @@
+ load_LDT(pc);
+ #endif
+ }
+- if (oldsize) {
+- if (oldsize*LDT_ENTRY_SIZE > PAGE_SIZE)
+- vfree(oldldt);
+- else
+- kfree(oldldt);
+- }
+ return 0;
+ }
+
+ static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
+ {
+- int err = alloc_ldt(new, old->size, 0);
+- if (err < 0)
++ int i, err, size = old->size, nr_pages = (size*LDT_ENTRY_SIZE + PAGE_SIZE-1)/PAGE_SIZE;
++
++ err = alloc_ldt(new, size, 0);
++ if (err < 0) {
++ new->size = 0;
+ return err;
+- memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
++ }
++ for (i = 0; i < nr_pages; i++)
++ copy_user_highpage(new->ldt_pages[i], old->ldt_pages[i], 0);
+ return 0;
+ }
+
+@@ -96,6 +94,7 @@
+
+ init_MUTEX(&mm->context.sem);
+ mm->context.size = 0;
++ memset(mm->context.ldt_pages, 0, sizeof(struct page *) * MAX_LDT_PAGES);
+ old_mm = current->mm;
+ if (old_mm && old_mm->context.size > 0) {
+ down(&old_mm->context.sem);
+@@ -107,23 +106,21 @@
+
+ /*
+ * No need to lock the MM as we are the last user
++ * Do not touch the ldt register, we are already
++ * in the next thread.
+ */
+ void destroy_context(struct mm_struct *mm)
+ {
+- if (mm->context.size) {
+- if (mm == current->active_mm)
+- clear_LDT();
+- if (mm->context.size*LDT_ENTRY_SIZE > PAGE_SIZE)
+- vfree(mm->context.ldt);
+- else
+- kfree(mm->context.ldt);
+- mm->context.size = 0;
+- }
++ int i, nr_pages = (mm->context.size*LDT_ENTRY_SIZE + PAGE_SIZE-1) / PAGE_SIZE;
++
++ for (i = 0; i < nr_pages; i++)
++ __free_page(mm->context.ldt_pages[i]);
++ mm->context.size = 0;
+ }
+
+ static int read_ldt(void __user * ptr, unsigned long bytecount)
+ {
+- int err;
++ int err, i;
+ unsigned long size;
+ struct mm_struct * mm = current->mm;
+
+@@ -138,8 +135,25 @@
+ size = bytecount;
+
+ err = 0;
+- if (copy_to_user(ptr, mm->context.ldt, size))
+- err = -EFAULT;
++ /*
++ * This is necessary just in case we got here straight from a
++ * context-switch where the ptes were set but no tlb flush
++ * was done yet. We rather avoid doing a TLB flush in the
++ * context-switch path and do it here instead.
++ */
++ __flush_tlb_global();
++
++ for (i = 0; i < size; i += PAGE_SIZE) {
++ int nr = i / PAGE_SIZE, bytes;
++ char *kaddr = kmap(mm->context.ldt_pages[nr]);
++
++ bytes = size - i;
++ if (bytes > PAGE_SIZE)
++ bytes = PAGE_SIZE;
++ if (copy_to_user(ptr + i, kaddr, size - i))
++ err = -EFAULT;
++ kunmap(mm->context.ldt_pages[nr]);
++ }
+ up(&mm->context.sem);
+ if (err < 0)
+ return err;
+@@ -158,7 +172,7 @@
+
+ err = 0;
+ address = &default_ldt[0];
+- size = 5*sizeof(struct desc_struct);
++ size = 5*LDT_ENTRY_SIZE;
+ if (size > bytecount)
+ size = bytecount;
+
+@@ -200,7 +214,15 @@
+ goto out_unlock;
+ }
+
+- lp = (__u32 *) ((ldt_info.entry_number << 3) + (char *) mm->context.ldt);
++ /*
++ * No rescheduling allowed from this point to the install.
++ *
++ * We do a TLB flush for the same reason as in the read_ldt() path.
++ */
++ preempt_disable();
++ __flush_tlb_global();
++ lp = (__u32 *) ((ldt_info.entry_number << 3) +
++ (char *) __kmap_atomic_vaddr(KM_LDT_PAGE0));
+
+ /* Allow LDTs to be cleared by the user. */
+ if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
+@@ -221,6 +243,7 @@
+ *lp = entry_1;
+ *(lp+1) = entry_2;
+ error = 0;
++ preempt_enable();
+
+ out_unlock:
+ up(&mm->context.sem);
+@@ -248,3 +271,26 @@
+ }
+ return ret;
+ }
++
++/*
++ * load one particular LDT into the current CPU
++ */
++void load_LDT_nolock(mm_context_t *pc, int cpu)
++{
++ struct page **pages = pc->ldt_pages;
++ int count = pc->size;
++ int nr_pages, i;
++
++ if (likely(!count)) {
++ pages = &default_ldt_page;
++ count = 5;
++ }
++ nr_pages = (count*LDT_ENTRY_SIZE + PAGE_SIZE-1) / PAGE_SIZE;
++
++ for (i = 0; i < nr_pages; i++) {
++ __kunmap_atomic_type(KM_LDT_PAGE0 - i);
++ __kmap_atomic(pages[i], KM_LDT_PAGE0 - i);
++ }
++ set_ldt_desc(cpu, (void *)__kmap_atomic_vaddr(KM_LDT_PAGE0), count);
++ load_LDT_desc();
++}
+Index: linux-2.6.0-test5/arch/i386/kernel/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/Makefile 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/Makefile 2003-09-27 11:38:19.045633008 +0800
+@@ -7,19 +7,18 @@
+ obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \
+ ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o \
+ pci-dma.o i386_ksyms.o i387.o dmi_scan.o bootflag.o \
+- doublefault.o
++ doublefault.o entry_trampoline.o
+
+ obj-y += cpu/
+ obj-y += timers/
+ obj-$(CONFIG_ACPI_BOOT) += acpi/
+ obj-$(CONFIG_X86_BIOS_REBOOT) += reboot.o
+ obj-$(CONFIG_MCA) += mca.o
++obj-$(CONFIG_KGDB) += kgdb_stub.o
+ obj-$(CONFIG_X86_MSR) += msr.o
+ obj-$(CONFIG_X86_CPUID) += cpuid.o
+ obj-$(CONFIG_MICROCODE) += microcode.o
+-obj-$(CONFIG_PM) += suspend.o
+ obj-$(CONFIG_APM) += apm.o
+-obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend_asm.o
+ obj-$(CONFIG_X86_SMP) += smp.o smpboot.o
+ obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o
+ obj-$(CONFIG_X86_MPPARSE) += mpparse.o
+Index: linux-2.6.0-test5/arch/i386/kernel/mpparse.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/mpparse.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/mpparse.c 2003-09-27 11:38:19.053631792 +0800
+@@ -167,6 +167,11 @@
+ boot_cpu_logical_apicid = apicid;
+ }
+
++ if (num_processors >= NR_CPUS) {
++ printk(KERN_WARNING "NR_CPUS limit of %i reached. Cannot "
++ "boot CPU(apicid 0x%d).\n", NR_CPUS, m->mpc_apicid);
++ return;
++ }
+ num_processors++;
+
+ if (MAX_APICS - m->mpc_apicid <= 0) {
+@@ -656,7 +661,7 @@
+ * Read the physical hardware table. Anything here will
+ * override the defaults.
+ */
+- if (!smp_read_mpc((void *)mpf->mpf_physptr)) {
++ if (!smp_read_mpc((void *)phys_to_virt(mpf->mpf_physptr))) {
+ smp_found_config = 0;
+ printk(KERN_ERR "BIOS bug, MP table errors detected!...\n");
+ printk(KERN_ERR "... disabling SMP support. (tell your hw vendor)\n");
+@@ -825,7 +830,7 @@
+ MP_processor_info(&processor);
+ }
+
+-#ifdef CONFIG_X86_IO_APIC
++#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_ACPI_INTERPRETER)
+
+ #define MP_ISA_BUS 0
+ #define MP_MAX_IOAPIC_PIN 127
+@@ -1014,10 +1019,6 @@
+ }
+ }
+
+-#ifdef CONFIG_ACPI
+-
+-/* Ensure the ACPI SCI interrupt level is active low, edge-triggered */
+-
+ extern FADT_DESCRIPTOR acpi_fadt;
+
+ void __init mp_config_ioapic_for_sci(int irq)
+@@ -1026,6 +1027,7 @@
+ int ioapic_pin;
+ struct acpi_table_madt *madt;
+ struct acpi_table_int_src_ovr *entry = NULL;
++ acpi_interrupt_flags flags;
+ void *madt_end;
+ acpi_status status;
+
+@@ -1049,15 +1051,12 @@
+ * See the note at the end of ACPI 2.0b section
+ * 5.2.10.8 for what this is about.
+ */
+- if (entry->bus_irq != entry->global_irq) {
+- acpi_fadt.sci_int = entry->global_irq;
+- irq = entry->global_irq;
+- break;
+- }
+- else
+- return;
++ flags = entry->flags;
++ acpi_fadt.sci_int = entry->global_irq;
++ irq = entry->global_irq;
++ break;
+ }
+-
++
+ entry = (struct acpi_table_int_src_ovr *)
+ ((unsigned long) entry + entry->header.length);
+ }
+@@ -1067,9 +1066,14 @@
+
+ ioapic_pin = irq - mp_ioapic_routing[ioapic].irq_start;
+
+- io_apic_set_pci_routing(ioapic, ioapic_pin, irq, 1, 1); // Active low, level triggered
++ if (flags.polarity == 0)
++ flags.polarity = 0x3; /* Active low */
++ if (flags.trigger == 0)
++ flags.trigger = 0x3; /* Level-triggered */
++
++ io_apic_set_pci_routing(ioapic, ioapic_pin, irq,
++ (flags.trigger >> 1) , (flags.polarity >> 1));
+ }
+-#endif /* CONFIG_ACPI */
+
+ #ifdef CONFIG_ACPI_PCI
+
+@@ -1149,5 +1153,5 @@
+ }
+
+ #endif /*CONFIG_ACPI_PCI*/
+-#endif /* CONFIG_X86_IO_APIC */
++#endif /*CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER*/
+ #endif /*CONFIG_ACPI_BOOT*/
+Index: linux-2.6.0-test5/arch/i386/kernel/nmi.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/nmi.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/nmi.c 2003-09-27 11:38:19.057631184 +0800
+@@ -31,7 +31,16 @@
+ #include <asm/mpspec.h>
+ #include <asm/nmi.h>
+
++#ifdef CONFIG_KGDB
++#include <asm/kgdb.h>
++#ifdef CONFIG_SMP
++unsigned int nmi_watchdog = NMI_IO_APIC;
++#else
++unsigned int nmi_watchdog = NMI_LOCAL_APIC;
++#endif
++#else
+ unsigned int nmi_watchdog = NMI_NONE;
++#endif
+ static unsigned int nmi_hz = HZ;
+ unsigned int nmi_perfctr_msr; /* the MSR to reset in NMI handler */
+ extern void show_registers(struct pt_regs *regs);
+@@ -408,6 +417,9 @@
+ for (i = 0; i < NR_CPUS; i++)
+ alert_counter[i] = 0;
+ }
++#ifdef CONFIG_KGDB
++int tune_watchdog = 5*HZ;
++#endif
+
+ void nmi_watchdog_tick (struct pt_regs * regs)
+ {
+@@ -421,12 +433,24 @@
+
+ sum = irq_stat[cpu].apic_timer_irqs;
+
++#ifdef CONFIG_KGDB
++ if (! in_kgdb(regs) && last_irq_sums[cpu] == sum ) {
++
++#else
+ if (last_irq_sums[cpu] == sum) {
++#endif
+ /*
+ * Ayiee, looks like this CPU is stuck ...
+ * wait a few IRQs (5 seconds) before doing the oops ...
+ */
+ alert_counter[cpu]++;
++#ifdef CONFIG_KGDB
++ if (alert_counter[cpu] == tune_watchdog) {
++ kgdb_handle_exception(2, SIGPWR, 0, regs);
++ last_irq_sums[cpu] = sum;
++ alert_counter[cpu] = 0;
++ }
++#endif
+ if (alert_counter[cpu] == 5*nmi_hz) {
+ spin_lock(&nmi_print_lock);
+ /*
+Index: linux-2.6.0-test5/arch/i386/kernel/numaq.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/numaq.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/numaq.c 2003-09-27 11:38:19.058631032 +0800
+@@ -99,8 +99,14 @@
+ }
+ }
+
+-void __init get_memcfg_numaq(void)
++/*
++ * Unlike Summit, we don't really care to let the NUMA-Q
++ * fall back to flat mode. Don't compile for NUMA-Q
++ * unless you really need it!
++ */
++int __init get_memcfg_numaq(void)
+ {
+ smp_dump_qct();
+ initialize_physnode_map();
++ return 1;
+ }
+Index: linux-2.6.0-test5/arch/i386/kernel/process.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/process.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/process.c 2003-09-27 11:38:19.064630120 +0800
+@@ -47,6 +47,7 @@
+ #include <asm/i387.h>
+ #include <asm/irq.h>
+ #include <asm/desc.h>
++#include <asm/atomic_kmap.h>
+ #ifdef CONFIG_MATH_EMULATION
+ #include <asm/math_emu.h>
+ #endif
+@@ -151,11 +152,57 @@
+ }
+ }
+
++/*
++ * This uses new MONITOR/MWAIT instructions on P4 processors with PNI,
++ * which can obviate IPI to trigger checking of need_resched.
++ * We execute MONITOR against need_resched and enter optimized wait state
++ * through MWAIT. Whenever someone changes need_resched, we would be woken
++ * up from MWAIT (without an IPI).
++ */
++static void mwait_idle(void)
++{
++ local_irq_enable();
++
++ if (!need_resched()) {
++ set_thread_flag(TIF_POLLING_NRFLAG);
++ do {
++ __monitor((void *)¤t_thread_info()->flags, 0, 0);
++ if (need_resched())
++ break;
++ __mwait(0, 0);
++ } while (!need_resched());
++ clear_thread_flag(TIF_POLLING_NRFLAG);
++ }
++}
++
++void __init select_idle_routine(const struct cpuinfo_x86 *c)
++{
++ if (cpu_has(c, X86_FEATURE_MWAIT)) {
++ printk("monitor/mwait feature present.\n");
++ /*
++ * Skip, if setup has overridden idle.
++ * Also, take care of system with asymmetric CPUs.
++ * Use, mwait_idle only if all cpus support it.
++ * If not, we fallback to default_idle()
++ */
++ if (!pm_idle) {
++ printk("using mwait in idle threads.\n");
++ pm_idle = mwait_idle;
++ }
++ return;
++ }
++ pm_idle = default_idle;
++ return;
++}
++
+ static int __init idle_setup (char *str)
+ {
+ if (!strncmp(str, "poll", 4)) {
+ printk("using polling idle threads.\n");
+ pm_idle = poll_idle;
++ } else if (!strncmp(str, "halt", 4)) {
++ printk("using halt in idle threads.\n");
++ pm_idle = default_idle;
+ }
+
+ return 1;
+@@ -252,6 +299,9 @@
+ struct task_struct *tsk = current;
+
+ memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
++#ifdef CONFIG_X86_HIGH_ENTRY
++ clear_thread_flag(TIF_DB7);
++#endif
+ memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
+ /*
+ * Forget coprocessor state..
+@@ -265,9 +315,8 @@
+ if (dead_task->mm) {
+ // temporary debugging check
+ if (dead_task->mm->context.size) {
+- printk("WARNING: dead process %8s still has LDT? <%p/%d>\n",
++ printk("WARNING: dead process %8s still has LDT? <%d>\n",
+ dead_task->comm,
+- dead_task->mm->context.ldt,
+ dead_task->mm->context.size);
+ BUG();
+ }
+@@ -302,7 +351,17 @@
+ p->thread.esp = (unsigned long) childregs;
+ p->thread.esp0 = (unsigned long) (childregs+1);
+
++ /*
++ * get the two stack pages, for the virtual stack.
++ *
++ * IMPORTANT: this code relies on the fact that the task
++ * structure is an 8K aligned piece of physical memory.
++ */
++ p->thread.stack_page0 = virt_to_page((unsigned long)p->thread_info);
++ p->thread.stack_page1 = virt_to_page((unsigned long)p->thread_info + PAGE_SIZE);
++
+ p->thread.eip = (unsigned long) ret_from_fork;
++ p->thread_info->real_stack = p->thread_info;
+
+ savesegment(fs,p->thread.fs);
+ savesegment(gs,p->thread.gs);
+@@ -454,10 +513,40 @@
+
+ __unlazy_fpu(prev_p);
+
++#ifdef CONFIG_X86_HIGH_ENTRY
++ /*
++ * Set the ptes of the virtual stack. (NOTE: a one-page TLB flush is
++ * needed because otherwise NMIs could interrupt the
++ * user-return code with a virtual stack and stale TLBs.)
++ */
++ __kunmap_atomic_type(KM_VSTACK0);
++ __kunmap_atomic_type(KM_VSTACK1);
++ __kmap_atomic(next->stack_page0, KM_VSTACK0);
++ __kmap_atomic(next->stack_page1, KM_VSTACK1);
++
++ /*
++ * NOTE: here we rely on the task being the stack as well
++ */
++ next_p->thread_info->virtual_stack = (void *)__kmap_atomic_vaddr(KM_VSTACK0);
++
++#if defined(CONFIG_PREEMPT) && defined(CONFIG_SMP)
++ /*
++ * If next was preempted on entry from userspace to kernel,
++ * and now it's on a different cpu, we need to adjust %esp.
++ * This assumes that entry.S does not copy %esp while on the
++ * virtual stack (with interrupts enabled): which is so,
++ * except within __SWITCH_KERNELSPACE itself.
++ */
++ if (unlikely(next->esp >= TASK_SIZE)) {
++ next->esp &= THREAD_SIZE - 1;
++ next->esp |= (unsigned long) next_p->thread_info->virtual_stack;
++ }
++#endif
++#endif
+ /*
+- * Reload esp0, LDT and the page table pointer:
++ * Reload esp0:
+ */
+- load_esp0(tss, next->esp0);
++ load_esp0(tss, virtual_esp0(next_p));
+
+ /*
+ * Load the per-thread Thread-Local Storage descriptor.
+Index: linux-2.6.0-test5/arch/i386/kernel/reboot.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/reboot.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/reboot.c 2003-09-27 11:38:19.072628904 +0800
+@@ -153,12 +153,11 @@
+ CMOS_WRITE(0x00, 0x8f);
+ spin_unlock_irqrestore(&rtc_lock, flags);
+
+- /* Remap the kernel at virtual address zero, as well as offset zero
+- from the kernel segment. This assumes the kernel segment starts at
+- virtual address PAGE_OFFSET. */
+-
+- memcpy (swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
+- sizeof (swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
++ /*
++ * Remap the first 16 MB of RAM (which includes the kernel image)
++ * at virtual address zero:
++ */
++ setup_identity_mappings(swapper_pg_dir, 0, 16*1024*1024);
+
+ /*
+ * Use `swapper_pg_dir' as our page directory.
+@@ -251,7 +250,7 @@
+ * other OSs see a clean IRQ state.
+ */
+ smp_send_stop();
+-#elif CONFIG_X86_LOCAL_APIC
++#elif defined(CONFIG_X86_LOCAL_APIC)
+ if (cpu_has_apic) {
+ local_irq_disable();
+ disable_local_APIC();
+Index: linux-2.6.0-test5/arch/i386/kernel/setup.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/setup.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/setup.c 2003-09-27 11:38:19.079627840 +0800
+@@ -44,6 +44,7 @@
+ #include <asm/arch_hooks.h>
+ #include <asm/sections.h>
+ #include <asm/io_apic.h>
++#include <asm/ist.h>
+ #include "setup_arch_pre.h"
+ #include "mach_resources.h"
+
+@@ -63,10 +64,10 @@
+ unsigned long mmu_cr4_features;
+ EXPORT_SYMBOL_GPL(mmu_cr4_features);
+
+-#ifdef CONFIG_ACPI
+- int acpi_disabled __initdata = 0;
++#ifdef CONFIG_ACPI_INTERPRETER
++ int acpi_disabled = 0;
+ #else
+- int acpi_disabled __initdata = 1;
++ int acpi_disabled = 1;
+ #endif
+ EXPORT_SYMBOL(acpi_disabled);
+
+@@ -102,6 +103,7 @@
+ unsigned char table[0];
+ };
+ struct edid_info edid_info;
++struct ist_info ist_info;
+ struct e820map e820;
+
+ unsigned char aux_device_present;
+@@ -955,11 +957,12 @@
+ pre_setup_arch_hook();
+ early_cpu_init();
+
+- ROOT_DEV = ORIG_ROOT_DEV;
++ ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
+ drive_info = DRIVE_INFO;
+ screen_info = SCREEN_INFO;
+ edid_info = EDID_INFO;
+ apm_info.bios = APM_BIOS_INFO;
++ ist_info = IST_INFO;
+ saved_videomode = VIDEO_MODE;
+ printk("Video mode to be used for restore is %lx\n", saved_videomode);
+ if( SYS_DESC_TABLE.length != 0 ) {
+Index: linux-2.6.0-test5/arch/i386/kernel/signal.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/signal.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/signal.c 2003-09-27 11:38:19.084627080 +0800
+@@ -128,25 +128,25 @@
+ */
+
+ static int
+-restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *peax)
++restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *__sc, int *peax)
+ {
+- unsigned int err = 0;
++ struct sigcontext scratch; /* 88 bytes of scratch area */
+
+-#define COPY(x) err |= __get_user(regs->x, &sc->x)
++ if (copy_from_user(&scratch, __sc, sizeof(scratch)))
++ return -EFAULT;
++
++#define COPY(x) regs->x = scratch.x
+
+ #define COPY_SEG(seg) \
+- { unsigned short tmp; \
+- err |= __get_user(tmp, &sc->seg); \
++ { unsigned short tmp = scratch.seg; \
+ regs->x##seg = tmp; }
+
+ #define COPY_SEG_STRICT(seg) \
+- { unsigned short tmp; \
+- err |= __get_user(tmp, &sc->seg); \
++ { unsigned short tmp = scratch.seg; \
+ regs->x##seg = tmp|3; }
+
+ #define GET_SEG(seg) \
+- { unsigned short tmp; \
+- err |= __get_user(tmp, &sc->seg); \
++ { unsigned short tmp = scratch.seg; \
+ loadsegment(seg,tmp); }
+
+ GET_SEG(gs);
+@@ -165,27 +165,23 @@
+ COPY_SEG_STRICT(ss);
+
+ {
+- unsigned int tmpflags;
+- err |= __get_user(tmpflags, &sc->eflags);
++ unsigned int tmpflags = scratch.eflags;
+ regs->eflags = (regs->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
+ regs->orig_eax = -1; /* disable syscall checks */
+ }
+
+ {
+- struct _fpstate __user * buf;
+- err |= __get_user(buf, &sc->fpstate);
++ struct _fpstate * buf = scratch.fpstate;
+ if (buf) {
+ if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
+- goto badframe;
+- err |= restore_i387(buf);
++ return -EFAULT;
++ if (restore_i387(buf))
++ return -EFAULT;
+ }
+ }
+
+- err |= __get_user(*peax, &sc->eax);
+- return err;
+-
+-badframe:
+- return 1;
++ *peax = scratch.eax;
++ return 0;
+ }
+
+ asmlinkage int sys_sigreturn(unsigned long __unused)
+@@ -263,46 +259,47 @@
+ */
+
+ static int
+-setup_sigcontext(struct sigcontext __user *sc, struct _fpstate __user *fpstate,
++setup_sigcontext(struct sigcontext __user *__sc, struct _fpstate __user *fpstate,
+ struct pt_regs *regs, unsigned long mask)
+ {
+- int tmp, err = 0;
++ struct sigcontext sc; /* 88 bytes of scratch area */
++ int tmp;
+
+ tmp = 0;
+ __asm__("movl %%gs,%0" : "=r"(tmp): "0"(tmp));
+- err |= __put_user(tmp, (unsigned int *)&sc->gs);
++ *(unsigned int *)&sc.gs = tmp;
+ __asm__("movl %%fs,%0" : "=r"(tmp): "0"(tmp));
+- err |= __put_user(tmp, (unsigned int *)&sc->fs);
+-
+- err |= __put_user(regs->xes, (unsigned int *)&sc->es);
+- err |= __put_user(regs->xds, (unsigned int *)&sc->ds);
+- err |= __put_user(regs->edi, &sc->edi);
+- err |= __put_user(regs->esi, &sc->esi);
+- err |= __put_user(regs->ebp, &sc->ebp);
+- err |= __put_user(regs->esp, &sc->esp);
+- err |= __put_user(regs->ebx, &sc->ebx);
+- err |= __put_user(regs->edx, &sc->edx);
+- err |= __put_user(regs->ecx, &sc->ecx);
+- err |= __put_user(regs->eax, &sc->eax);
+- err |= __put_user(current->thread.trap_no, &sc->trapno);
+- err |= __put_user(current->thread.error_code, &sc->err);
+- err |= __put_user(regs->eip, &sc->eip);
+- err |= __put_user(regs->xcs, (unsigned int *)&sc->cs);
+- err |= __put_user(regs->eflags, &sc->eflags);
+- err |= __put_user(regs->esp, &sc->esp_at_signal);
+- err |= __put_user(regs->xss, (unsigned int *)&sc->ss);
++ *(unsigned int *)&sc.fs = tmp;
++ *(unsigned int *)&sc.es = regs->xes;
++ *(unsigned int *)&sc.ds = regs->xds;
++ sc.edi = regs->edi;
++ sc.esi = regs->esi;
++ sc.ebp = regs->ebp;
++ sc.esp = regs->esp;
++ sc.ebx = regs->ebx;
++ sc.edx = regs->edx;
++ sc.ecx = regs->ecx;
++ sc.eax = regs->eax;
++ sc.trapno = current->thread.trap_no;
++ sc.err = current->thread.error_code;
++ sc.eip = regs->eip;
++ *(unsigned int *)&sc.cs = regs->xcs;
++ sc.eflags = regs->eflags;
++ sc.esp_at_signal = regs->esp;
++ *(unsigned int *)&sc.ss = regs->xss;
+
+ tmp = save_i387(fpstate);
+ if (tmp < 0)
+- err = 1;
+- else
+- err |= __put_user(tmp ? fpstate : NULL, &sc->fpstate);
++ return 1;
++ sc.fpstate = tmp ? fpstate : NULL;
+
+ /* non-iBCS2 extensions.. */
+- err |= __put_user(mask, &sc->oldmask);
+- err |= __put_user(current->thread.cr2, &sc->cr2);
++ sc.oldmask = mask;
++ sc.cr2 = current->thread.cr2;
+
+- return err;
++ if (copy_to_user(__sc, &sc, sizeof(sc)))
++ return 1;
++ return 0;
+ }
+
+ /*
+@@ -440,7 +437,7 @@
+ /* Create the ucontext. */
+ err |= __put_user(0, &frame->uc.uc_flags);
+ err |= __put_user(0, &frame->uc.uc_link);
+- err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
++ err |= __put_user(current->sas_ss_sp, (unsigned long *)&frame->uc.uc_stack.ss_sp);
+ err |= __put_user(sas_ss_flags(regs->esp),
+ &frame->uc.uc_stack.ss_flags);
+ err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+Index: linux-2.6.0-test5/arch/i386/kernel/smpboot.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/smpboot.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/smpboot.c 2003-09-27 11:38:19.092625864 +0800
+@@ -499,8 +499,8 @@
+ #ifdef CONFIG_NUMA
+
+ /* which logical CPUs are on which nodes */
+-cpumask_t node_2_cpu_mask[MAX_NR_NODES] =
+- { [0 ... MAX_NR_NODES-1] = CPU_MASK_NONE };
++cpumask_t node_2_cpu_mask[MAX_NUMNODES] =
++ { [0 ... MAX_NUMNODES-1] = CPU_MASK_NONE };
+ /* which node each logical CPU is on */
+ int cpu_2_node[NR_CPUS] = { [0 ... NR_CPUS-1] = 0 };
+
+@@ -518,7 +518,7 @@
+ int node;
+
+ printk("Unmapping cpu %d from all nodes\n", cpu);
+- for (node = 0; node < MAX_NR_NODES; node ++)
++ for (node = 0; node < MAX_NUMNODES; node ++)
+ cpu_clear(cpu, node_2_cpu_mask[node]);
+ cpu_2_node[cpu] = -1;
+ }
+@@ -915,13 +915,13 @@
+ cacheflush_time = (cpu_khz>>10) * (cachesize<<10) / bandwidth;
+ }
+
+- cache_decay_ticks = (long)cacheflush_time/cpu_khz * HZ / 1000;
++ cache_decay_ticks = (long)cacheflush_time/cpu_khz + 1;
+
+ printk("per-CPU timeslice cutoff: %ld.%02ld usecs.\n",
+ (long)cacheflush_time/(cpu_khz/1000),
+ ((long)cacheflush_time*100/(cpu_khz/1000)) % 100);
+ printk("task migration cache decay timeout: %ld msecs.\n",
+- (cache_decay_ticks + 1) * 1000 / HZ);
++ cache_decay_ticks);
+ }
+
+ /*
+Index: linux-2.6.0-test5/arch/i386/kernel/smp.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/smp.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/smp.c 2003-09-27 11:38:19.097625104 +0800
+@@ -327,10 +327,12 @@
+
+ if (flush_mm == cpu_tlbstate[cpu].active_mm) {
+ if (cpu_tlbstate[cpu].state == TLBSTATE_OK) {
++#ifndef CONFIG_X86_SWITCH_PAGETABLES
+ if (flush_va == FLUSH_ALL)
+ local_flush_tlb();
+ else
+ __flush_tlb_one(flush_va);
++#endif
+ } else
+ leave_mm(cpu);
+ }
+@@ -396,21 +398,6 @@
+ spin_unlock(&tlbstate_lock);
+ }
+
+-void flush_tlb_current_task(void)
+-{
+- struct mm_struct *mm = current->mm;
+- cpumask_t cpu_mask;
+-
+- preempt_disable();
+- cpu_mask = mm->cpu_vm_mask;
+- cpu_clear(smp_processor_id(), cpu_mask);
+-
+- local_flush_tlb();
+- if (!cpus_empty(cpu_mask))
+- flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
+- preempt_enable();
+-}
+-
+ void flush_tlb_mm (struct mm_struct * mm)
+ {
+ cpumask_t cpu_mask;
+@@ -442,7 +429,10 @@
+
+ if (current->active_mm == mm) {
+ if(current->mm)
+- __flush_tlb_one(va);
++#ifndef CONFIG_X86_SWITCH_PAGETABLES
++ __flush_tlb_one(va)
++#endif
++ ;
+ else
+ leave_mm(smp_processor_id());
+ }
+@@ -466,7 +456,17 @@
+ {
+ on_each_cpu(do_flush_tlb_all, 0, 1, 1);
+ }
+-
++#ifdef CONFIG_KGDB
++/*
++ * By using the NMI code instead of a vector we just sneak thru the
++ * word generator coming out with just what we want. AND it does
++ * not matter if clustered_apic_mode is set or not.
++ */
++void smp_send_nmi_allbutself(void)
++{
++ send_IPI_allbutself(APIC_DM_NMI);
++}
++#endif
+ /*
+ * this function sends a 'reschedule' IPI to another CPU.
+ * it goes straight through and wastes no time serializing
+Index: linux-2.6.0-test5/arch/i386/kernel/srat.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/srat.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/srat.c 2003-09-27 11:38:19.105623888 +0800
+@@ -239,6 +239,11 @@
+ }
+ }
+
++ if (num_memory_chunks == 0) {
++ printk("could not finy any ACPI SRAT memory areas.\n");
++ goto out_fail;
++ }
++
+ /* Calculate total number of nodes in system from PXM bitmap and create
+ * a set of sequential node IDs starting at zero. (ACPI doesn't seem
+ * to specify the range of _PXM values.)
+@@ -295,10 +300,12 @@
+ }
+ }
+ }
++ return 1;
++out_fail:
+ return 0;
+ }
+
+-void __init get_memcfg_from_srat(void)
++int __init get_memcfg_from_srat(void)
+ {
+ struct acpi_table_header *header = NULL;
+ struct acpi_table_rsdp *rsdp = NULL;
+@@ -316,11 +323,11 @@
+ (u32)rsdp_address->pointer.physical;
+ } else {
+ printk("%s: rsdp_address is not a physical pointer\n", __FUNCTION__);
+- return;
++ goto out_err;
+ }
+ if (!rsdp) {
+ printk("%s: Didn't find ACPI root!\n", __FUNCTION__);
+- return;
++ goto out_err;
+ }
+
+ printk(KERN_INFO "%.8s v%d [%.6s]\n", rsdp->signature, rsdp->revision,
+@@ -328,7 +335,7 @@
+
+ if (strncmp(rsdp->signature, RSDP_SIG,strlen(RSDP_SIG))) {
+ printk(KERN_WARNING "%s: RSDP table signature incorrect\n", __FUNCTION__);
+- return;
++ goto out_err;
+ }
+
+ rsdt = (struct acpi_table_rsdt *)
+@@ -338,14 +345,14 @@
+ printk(KERN_WARNING
+ "%s: ACPI: Invalid root system description tables (RSDT)\n",
+ __FUNCTION__);
+- return;
++ goto out_err;
+ }
+
+ header = & rsdt->header;
+
+ if (strncmp(header->signature, RSDT_SIG, strlen(RSDT_SIG))) {
+ printk(KERN_WARNING "ACPI: RSDT signature incorrect\n");
+- return;
++ goto out_err;
+ }
+
+ /*
+@@ -356,15 +363,18 @@
+ */
+ tables = (header->length - sizeof(struct acpi_table_header)) / 4;
+
++ if (!tables)
++ goto out_err;
++
+ memcpy(&saved_rsdt, rsdt, sizeof(saved_rsdt));
+
+ if (saved_rsdt.header.length > sizeof(saved_rsdt)) {
+ printk(KERN_WARNING "ACPI: Too big length in RSDT: %d\n",
+ saved_rsdt.header.length);
+- return;
++ goto out_err;
+ }
+
+-printk("Begin table scan....\n");
++ printk("Begin SRAT table scan....\n");
+
+ for (i = 0; i < tables; i++) {
+ /* Map in header, then map in full table length. */
+@@ -379,10 +389,13 @@
+
+ if (strncmp((char *) &header->signature, "SRAT", 4))
+ continue;
+- acpi20_parse_srat((struct acpi_table_srat *)header);
++
+ /* we've found the srat table. don't need to look at any more tables */
+- break;
++ return acpi20_parse_srat((struct acpi_table_srat *)header);
+ }
++out_err:
++ printk("failed to get NUMA memory information from SRAT table\n");
++ return 0;
+ }
+
+ /* For each node run the memory list to determine whether there are
+Index: linux-2.6.0-test5/arch/i386/kernel/sysenter.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/sysenter.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/sysenter.c 2003-09-27 11:38:19.107623584 +0800
+@@ -18,13 +18,18 @@
+ #include <asm/msr.h>
+ #include <asm/pgtable.h>
+ #include <asm/unistd.h>
++#include <linux/highmem.h>
+
+ extern asmlinkage void sysenter_entry(void);
+
+ void enable_sep_cpu(void *info)
+ {
+ int cpu = get_cpu();
++#ifdef CONFIG_X86_HIGH_ENTRY
++ struct tss_struct *tss = (struct tss_struct *) __fix_to_virt(FIX_TSS_0) + cpu;
++#else
+ struct tss_struct *tss = init_tss + cpu;
++#endif
+
+ tss->ss1 = __KERNEL_CS;
+ tss->esp1 = sizeof(struct tss_struct) + (unsigned long) tss;
+Index: linux-2.6.0-test5/arch/i386/kernel/timers/common.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/timers/common.c 2003-09-27 11:38:18.434725880 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/timers/common.c 2003-09-27 11:38:19.108623432 +0800
+@@ -0,0 +1,139 @@
++/*
++ * Common functions used across the timers go here
++ */
++
++#include <linux/init.h>
++#include <linux/timex.h>
++#include <linux/errno.h>
++
++#include <asm/io.h>
++#include <asm/timer.h>
++#include <asm/hpet.h>
++
++#include "mach_timer.h"
++
++/* ------ Calibrate the TSC -------
++ * Return 2^32 * (1 / (TSC clocks per usec)) for do_fast_gettimeoffset().
++ * Too much 64-bit arithmetic here to do this cleanly in C, and for
++ * accuracy's sake we want to keep the overhead on the CTC speaker (channel 2)
++ * output busy loop as low as possible. We avoid reading the CTC registers
++ * directly because of the awkward 8-bit access mechanism of the 82C54
++ * device.
++ */
++
++#define CALIBRATE_TIME (5 * 1000020/HZ)
++
++unsigned long __init calibrate_tsc(void)
++{
++ mach_prepare_counter();
++
++ {
++ unsigned long startlow, starthigh;
++ unsigned long endlow, endhigh;
++ unsigned long count;
++
++ rdtsc(startlow,starthigh);
++ mach_countup(&count);
++ rdtsc(endlow,endhigh);
++
++
++ /* Error: ECTCNEVERSET */
++ if (count <= 1)
++ goto bad_ctc;
++
++ /* 64-bit subtract - gcc just messes up with long longs */
++ __asm__("subl %2,%0\n\t"
++ "sbbl %3,%1"
++ :"=a" (endlow), "=d" (endhigh)
++ :"g" (startlow), "g" (starthigh),
++ "0" (endlow), "1" (endhigh));
++
++ /* Error: ECPUTOOFAST */
++ if (endhigh)
++ goto bad_ctc;
++
++ /* Error: ECPUTOOSLOW */
++ if (endlow <= CALIBRATE_TIME)
++ goto bad_ctc;
++
++ __asm__("divl %2"
++ :"=a" (endlow), "=d" (endhigh)
++ :"r" (endlow), "0" (0), "1" (CALIBRATE_TIME));
++
++ return endlow;
++ }
++
++ /*
++ * The CTC wasn't reliable: we got a hit on the very first read,
++ * or the CPU was so fast/slow that the quotient wouldn't fit in
++ * 32 bits..
++ */
++bad_ctc:
++ return 0;
++}
++
++#ifdef CONFIG_HPET_TIMER
++/* ------ Calibrate the TSC using HPET -------
++ * Return 2^32 * (1 / (TSC clocks per usec)) for getting the CPU freq.
++ * Second output is parameter 1 (when non NULL)
++ * Set 2^32 * (1 / (tsc per HPET clk)) for delay_hpet().
++ * calibrate_tsc() calibrates the processor TSC by comparing
++ * it to the HPET timer of known frequency.
++ * Too much 64-bit arithmetic here to do this cleanly in C
++ */
++#define CALIBRATE_CNT_HPET (5 * hpet_tick)
++#define CALIBRATE_TIME_HPET (5 * KERNEL_TICK_USEC)
++
++unsigned long __init calibrate_tsc_hpet(unsigned long *tsc_hpet_quotient_ptr)
++{
++ unsigned long tsc_startlow, tsc_starthigh;
++ unsigned long tsc_endlow, tsc_endhigh;
++ unsigned long hpet_start, hpet_end;
++ unsigned long result, remain;
++
++ hpet_start = hpet_readl(HPET_COUNTER);
++ rdtsc(tsc_startlow, tsc_starthigh);
++ do {
++ hpet_end = hpet_readl(HPET_COUNTER);
++ } while ((hpet_end - hpet_start) < CALIBRATE_CNT_HPET);
++ rdtsc(tsc_endlow, tsc_endhigh);
++
++ /* 64-bit subtract - gcc just messes up with long longs */
++ __asm__("subl %2,%0\n\t"
++ "sbbl %3,%1"
++ :"=a" (tsc_endlow), "=d" (tsc_endhigh)
++ :"g" (tsc_startlow), "g" (tsc_starthigh),
++ "0" (tsc_endlow), "1" (tsc_endhigh));
++
++ /* Error: ECPUTOOFAST */
++ if (tsc_endhigh)
++ goto bad_calibration;
++
++ /* Error: ECPUTOOSLOW */
++ if (tsc_endlow <= CALIBRATE_TIME_HPET)
++ goto bad_calibration;
++
++ ASM_DIV64_REG(result, remain, tsc_endlow, 0, CALIBRATE_TIME_HPET);
++ if (remain > (tsc_endlow >> 1))
++ result++; /* rounding the result */
++
++ if (tsc_hpet_quotient_ptr) {
++ unsigned long tsc_hpet_quotient;
++
++ ASM_DIV64_REG(tsc_hpet_quotient, remain, tsc_endlow, 0,
++ CALIBRATE_CNT_HPET);
++ if (remain > (tsc_endlow >> 1))
++ tsc_hpet_quotient++; /* rounding the result */
++ *tsc_hpet_quotient_ptr = tsc_hpet_quotient;
++ }
++
++ return result;
++bad_calibration:
++ /*
++ * the CPU was so fast/slow that the quotient wouldn't fit in
++ * 32 bits..
++ */
++ return 0;
++}
++#endif
++
+Index: linux-2.6.0-test5/arch/i386/kernel/timers/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/timers/Makefile 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/timers/Makefile 2003-09-27 11:38:19.109623280 +0800
+@@ -2,7 +2,7 @@
+ # Makefile for x86 timers
+ #
+
+-obj-y := timer.o timer_none.o timer_tsc.o timer_pit.o
++obj-y := timer.o timer_none.o timer_tsc.o timer_pit.o common.o
+
+ obj-$(CONFIG_X86_CYCLONE_TIMER) += timer_cyclone.o
+ obj-$(CONFIG_HPET_TIMER) += timer_hpet.o
+Index: linux-2.6.0-test5/arch/i386/kernel/timers/timer_cyclone.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/timers/timer_cyclone.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/timers/timer_cyclone.c 2003-09-27 11:38:19.111622976 +0800
+@@ -19,7 +19,6 @@
+ #include <asm/fixmap.h>
+
+ extern spinlock_t i8253_lock;
+-extern unsigned long calibrate_tsc(void);
+
+ /* Number of usecs that the last interrupt was delayed */
+ static int delay_at_last_interrupt;
+Index: linux-2.6.0-test5/arch/i386/kernel/timers/timer_hpet.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/timers/timer_hpet.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/timers/timer_hpet.c 2003-09-27 11:38:19.114622520 +0800
+@@ -131,63 +131,6 @@
+ } while ((hpet_end - hpet_start) < (loops));
+ }
+
+-/* ------ Calibrate the TSC -------
+- * Return 2^32 * (1 / (TSC clocks per usec)) for getting the CPU freq.
+- * Set 2^32 * (1 / (tsc per HPET clk)) for delay_hpet().
+- * calibrate_tsc() calibrates the processor TSC by comparing
+- * it to the HPET timer of known frequency.
+- * Too much 64-bit arithmetic here to do this cleanly in C
+- */
+-#define CALIBRATE_CNT_HPET (5 * hpet_tick)
+-#define CALIBRATE_TIME_HPET (5 * KERNEL_TICK_USEC)
+-
+-static unsigned long __init calibrate_tsc(void)
+-{
+- unsigned long tsc_startlow, tsc_starthigh;
+- unsigned long tsc_endlow, tsc_endhigh;
+- unsigned long hpet_start, hpet_end;
+- unsigned long result, remain;
+-
+- hpet_start = hpet_readl(HPET_COUNTER);
+- rdtsc(tsc_startlow, tsc_starthigh);
+- do {
+- hpet_end = hpet_readl(HPET_COUNTER);
+- } while ((hpet_end - hpet_start) < CALIBRATE_CNT_HPET);
+- rdtsc(tsc_endlow, tsc_endhigh);
+-
+- /* 64-bit subtract - gcc just messes up with long longs */
+- __asm__("subl %2,%0\n\t"
+- "sbbl %3,%1"
+- :"=a" (tsc_endlow), "=d" (tsc_endhigh)
+- :"g" (tsc_startlow), "g" (tsc_starthigh),
+- "0" (tsc_endlow), "1" (tsc_endhigh));
+-
+- /* Error: ECPUTOOFAST */
+- if (tsc_endhigh)
+- goto bad_calibration;
+-
+- /* Error: ECPUTOOSLOW */
+- if (tsc_endlow <= CALIBRATE_TIME_HPET)
+- goto bad_calibration;
+-
+- ASM_DIV64_REG(result, remain, tsc_endlow, 0, CALIBRATE_TIME_HPET);
+- if (remain > (tsc_endlow >> 1))
+- result++; /* rounding the result */
+-
+- ASM_DIV64_REG(tsc_hpet_quotient, remain, tsc_endlow, 0,
+- CALIBRATE_CNT_HPET);
+- if (remain > (tsc_endlow >> 1))
+- tsc_hpet_quotient++; /* rounding the result */
+-
+- return result;
+-bad_calibration:
+- /*
+- * the CPU was so fast/slow that the quotient wouldn't fit in
+- * 32 bits..
+- */
+- return 0;
+-}
+-
+ static int __init init_hpet(char* override)
+ {
+ unsigned long result, remain;
+@@ -201,7 +144,7 @@
+
+ printk("Using HPET for gettimeofday\n");
+ if (cpu_has_tsc) {
+- unsigned long tsc_quotient = calibrate_tsc();
++ unsigned long tsc_quotient = calibrate_tsc_hpet(&tsc_hpet_quotient);
+ if (tsc_quotient) {
+ /* report CPU clock rate in Hz.
+ * The formula is (10^6 * 2^32) / (2^32 * 1 / (clocks/us)) =
+Index: linux-2.6.0-test5/arch/i386/kernel/timers/timer_tsc.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/timers/timer_tsc.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/timers/timer_tsc.c 2003-09-27 11:38:19.121621456 +0800
+@@ -39,7 +39,7 @@
+ static unsigned long last_tsc_low; /* lsb 32 bits of Time Stamp Counter */
+ static unsigned long last_tsc_high; /* msb 32 bits of Time Stamp Counter */
+ static unsigned long long monotonic_base;
+-static rwlock_t monotonic_lock = RW_LOCK_UNLOCKED;
++static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED;
+
+ /* convert from cycles(64bits) => nanoseconds (64bits)
+ * basic equation:
+@@ -111,12 +111,14 @@
+ static unsigned long long monotonic_clock_tsc(void)
+ {
+ unsigned long long last_offset, this_offset, base;
++ unsigned seq;
+
+ /* atomically read monotonic base & last_offset */
+- read_lock_irq(&monotonic_lock);
+- last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low;
+- base = monotonic_base;
+- read_unlock_irq(&monotonic_lock);
++ do {
++ seq = read_seqbegin(&monotonic_lock);
++ last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low;
++ base = monotonic_base;
++ } while (read_seqretry(&monotonic_lock, seq));
+
+ /* Read the Time Stamp Counter */
+ rdtscll(this_offset);
+@@ -125,6 +127,30 @@
+ return base + cycles_2_ns(this_offset - last_offset);
+ }
+
++/*
++ * Scheduler clock - returns current time in nanosec units.
++ */
++unsigned long long sched_clock(void)
++{
++ unsigned long long this_offset;
++
++ /*
++ * In the NUMA case we dont use the TSC as they are not
++ * synchronized across all CPUs.
++ */
++#ifndef CONFIG_NUMA
++ if (unlikely(!cpu_has_tsc))
++#endif
++ return (unsigned long long)jiffies * (1000000000 / HZ);
++
++ /* Read the Time Stamp Counter */
++ rdtscll(this_offset);
++
++ /* return the value in ns */
++ return cycles_2_ns(this_offset);
++}
++
++
+ static void mark_offset_tsc(void)
+ {
+ unsigned long lost,delay;
+@@ -135,7 +161,7 @@
+ unsigned long long this_offset, last_offset;
+ static int lost_count = 0;
+
+- write_lock(&monotonic_lock);
++ write_seqlock(&monotonic_lock);
+ last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low;
+ /*
+ * It is important that these two operations happen almost at
+@@ -204,7 +230,7 @@
+ /* update the monotonic base value */
+ this_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low;
+ monotonic_base += cycles_2_ns(this_offset - last_offset);
+- write_unlock(&monotonic_lock);
++ write_sequnlock(&monotonic_lock);
+
+ /* calculate delay_at_last_interrupt */
+ count = ((LATCH-1) - count) * TICK_SIZE;
+@@ -230,74 +256,13 @@
+ } while ((now-bclock) < loops);
+ }
+
+-/* ------ Calibrate the TSC -------
+- * Return 2^32 * (1 / (TSC clocks per usec)) for do_fast_gettimeoffset().
+- * Too much 64-bit arithmetic here to do this cleanly in C, and for
+- * accuracy's sake we want to keep the overhead on the CTC speaker (channel 2)
+- * output busy loop as low as possible. We avoid reading the CTC registers
+- * directly because of the awkward 8-bit access mechanism of the 82C54
+- * device.
+- */
+-
+-#define CALIBRATE_TIME (5 * 1000020/HZ)
+-
+-static unsigned long __init calibrate_tsc(void)
+-{
+- mach_prepare_counter();
+-
+- {
+- unsigned long startlow, starthigh;
+- unsigned long endlow, endhigh;
+- unsigned long count;
+-
+- rdtsc(startlow,starthigh);
+- mach_countup(&count);
+- rdtsc(endlow,endhigh);
+-
+- last_tsc_low = endlow;
+-
+- /* Error: ECTCNEVERSET */
+- if (count <= 1)
+- goto bad_ctc;
+-
+- /* 64-bit subtract - gcc just messes up with long longs */
+- __asm__("subl %2,%0\n\t"
+- "sbbl %3,%1"
+- :"=a" (endlow), "=d" (endhigh)
+- :"g" (startlow), "g" (starthigh),
+- "0" (endlow), "1" (endhigh));
+-
+- /* Error: ECPUTOOFAST */
+- if (endhigh)
+- goto bad_ctc;
+-
+- /* Error: ECPUTOOSLOW */
+- if (endlow <= CALIBRATE_TIME)
+- goto bad_ctc;
+-
+- __asm__("divl %2"
+- :"=a" (endlow), "=d" (endhigh)
+- :"r" (endlow), "0" (0), "1" (CALIBRATE_TIME));
+-
+- return endlow;
+- }
+-
+- /*
+- * The CTC wasn't reliable: we got a hit on the very first read,
+- * or the CPU was so fast/slow that the quotient wouldn't fit in
+- * 32 bits..
+- */
+-bad_ctc:
+- return 0;
+-}
+-
+ #ifdef CONFIG_HPET_TIMER
+ static void mark_offset_tsc_hpet(void)
+ {
+ unsigned long long this_offset, last_offset;
+ unsigned long offset, temp, hpet_current;
+
+- write_lock(&monotonic_lock);
++ write_seqlock(&monotonic_lock);
+ last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low;
+ /*
+ * It is important that these two operations happen almost at
+@@ -325,7 +290,7 @@
+ /* update the monotonic base value */
+ this_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low;
+ monotonic_base += cycles_2_ns(this_offset - last_offset);
+- write_unlock(&monotonic_lock);
++ write_sequnlock(&monotonic_lock);
+
+ /* calculate delay_at_last_interrupt */
+ /*
+@@ -339,58 +304,6 @@
+ ASM_MUL64_REG(temp, delay_at_last_interrupt,
+ hpet_usec_quotient, delay_at_last_interrupt);
+ }
+-
+-/* ------ Calibrate the TSC based on HPET timer -------
+- * Return 2^32 * (1 / (TSC clocks per usec)) for do_fast_gettimeoffset().
+- * calibrate_tsc() calibrates the processor TSC by comparing
+- * it to the HPET timer of known frequency.
+- * Too much 64-bit arithmetic here to do this cleanly in C
+- */
+-
+-#define CALIBRATE_CNT_HPET (5 * hpet_tick)
+-#define CALIBRATE_TIME_HPET (5 * KERNEL_TICK_USEC)
+-
+-unsigned long __init calibrate_tsc_hpet(void)
+-{
+- unsigned long tsc_startlow, tsc_starthigh;
+- unsigned long tsc_endlow, tsc_endhigh;
+- unsigned long hpet_start, hpet_end;
+- unsigned long result, remain;
+-
+- hpet_start = hpet_readl(HPET_COUNTER);
+- rdtsc(tsc_startlow, tsc_starthigh);
+- do {
+- hpet_end = hpet_readl(HPET_COUNTER);
+- } while ((hpet_end - hpet_start) < CALIBRATE_CNT_HPET);
+- rdtsc(tsc_endlow, tsc_endhigh);
+-
+- /* 64-bit subtract - gcc just messes up with long longs */
+- __asm__("subl %2,%0\n\t"
+- "sbbl %3,%1"
+- :"=a" (tsc_endlow), "=d" (tsc_endhigh)
+- :"g" (tsc_startlow), "g" (tsc_starthigh),
+- "0" (tsc_endlow), "1" (tsc_endhigh));
+-
+- /* Error: ECPUTOOFAST */
+- if (tsc_endhigh)
+- goto bad_calibration;
+-
+- /* Error: ECPUTOOSLOW */
+- if (tsc_endlow <= CALIBRATE_TIME_HPET)
+- goto bad_calibration;
+-
+- ASM_DIV64_REG(result, remain, tsc_endlow, 0, CALIBRATE_TIME_HPET);
+- if (remain > (tsc_endlow >> 1))
+- result++; /* rounding the result */
+-
+- return result;
+-bad_calibration:
+- /*
+- * the CPU was so fast/slow that the quotient wouldn't fit in
+- * 32 bits..
+- */
+- return 0;
+-}
+ #endif
+
+ #ifdef CONFIG_CPU_FREQ
+@@ -425,6 +338,7 @@
+ if (use_tsc) {
+ fast_gettimeoffset_quotient = cpufreq_scale(fast_gettimeoffset_ref, freq->new, ref_freq);
+ cpu_khz = cpufreq_scale(cpu_khz_ref, ref_freq, freq->new);
++ set_cyc2ns_scale(cpu_khz/1000);
+ }
+ #endif
+ }
+@@ -491,7 +405,7 @@
+ if (is_hpet_enabled()){
+ unsigned long result, remain;
+ printk("Using TSC for gettimeofday\n");
+- tsc_quotient = calibrate_tsc_hpet();
++ tsc_quotient = calibrate_tsc_hpet(NULL);
+ timer_tsc.mark_offset = &mark_offset_tsc_hpet;
+ /*
+ * Math to calculate hpet to usec multiplier
+Index: linux-2.6.0-test5/arch/i386/kernel/traps.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/traps.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/traps.c 2003-09-27 11:38:19.128620392 +0800
+@@ -28,6 +28,7 @@
+
+ #ifdef CONFIG_EISA
+ #include <linux/ioport.h>
++#include <linux/eisa.h>
+ #endif
+
+ #ifdef CONFIG_MCA
+@@ -53,12 +54,8 @@
+
+ #include "mach_traps.h"
+
+-asmlinkage int system_call(void);
+-asmlinkage void lcall7(void);
+-asmlinkage void lcall27(void);
+-
+-struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
+- { 0, 0 }, { 0, 0 } };
++struct desc_struct default_ldt[] __attribute__((__section__(".data.default_ldt"))) = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } };
++struct page *default_ldt_page;
+
+ /* Do we ignore FPU interrupts ? */
+ char ignore_fpu_irq = 0;
+@@ -90,6 +87,43 @@
+ asmlinkage void spurious_interrupt_bug(void);
+ asmlinkage void machine_check(void);
+
++#ifdef CONFIG_KGDB
++extern void sysenter_entry(void);
++#include <asm/kgdb.h>
++#include <linux/init.h>
++extern void int3(void);
++extern void debug(void);
++void set_intr_gate(unsigned int n, void *addr);
++static void set_intr_usr_gate(unsigned int n, void *addr);
++/*
++ * Should be able to call this breakpoint() very early in
++ * bring up. Just hard code the call where needed.
++ * The breakpoint() code is here because set_?_gate() functions
++ * are local (static) to trap.c. They need be done only once,
++ * but it does not hurt to do them over.
++ */
++void breakpoint(void)
++{
++ init_entry_mappings();
++ set_intr_usr_gate(3,&int3); /* disable ints on trap */
++ set_intr_gate(1,&debug);
++ set_intr_gate(14,&page_fault);
++
++ BREAKPOINT;
++}
++#define CHK_REMOTE_DEBUG(trapnr,signr,error_code,regs,after) \
++ { \
++ if (!user_mode(regs) ) \
++ { \
++ kgdb_handle_exception(trapnr, signr, error_code, regs); \
++ after; \
++ } else if ((trapnr == 3) && (regs->eflags &0x200)) local_irq_enable(); \
++ }
++#else
++#define CHK_REMOTE_DEBUG(trapnr,signr,error_code,regs,after)
++#endif
++
++
+ static int kstack_depth_to_print = 24;
+
+ void show_trace(struct task_struct *task, unsigned long * stack)
+@@ -172,8 +206,9 @@
+ ss = regs->xss & 0xffff;
+ }
+ print_modules();
+- printk("CPU: %d\nEIP: %04x:[<%08lx>] %s\nEFLAGS: %08lx\n",
+- smp_processor_id(), 0xffff & regs->xcs, regs->eip, print_tainted(), regs->eflags);
++ printk("CPU: %d\nEIP: %04x:[<%08lx>] %s VLI\nEFLAGS: %08lx\n",
++ smp_processor_id(), 0xffff & regs->xcs,
++ regs->eip, print_tainted(), regs->eflags);
+
+ print_symbol("EIP is at %s\n", regs->eip);
+ printk("eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n",
+@@ -189,23 +224,27 @@
+ * time of the fault..
+ */
+ if (in_kernel) {
++ u8 *eip;
+
+ printk("\nStack: ");
+ show_stack(NULL, (unsigned long*)esp);
+
+ printk("Code: ");
+- if(regs->eip < PAGE_OFFSET)
+- goto bad;
+
+- for(i=0;i<20;i++)
+- {
+- unsigned char c;
+- if(__get_user(c, &((unsigned char*)regs->eip)[i])) {
+-bad:
++ eip = (u8 *)regs->eip - 43;
++ for (i = 0; i < 64; i++, eip++) {
++ unsigned char c = 0xff;
++
++ if ((user_mode(regs) && get_user(c, eip)) ||
++ (!user_mode(regs) && __direct_get_user(c, eip))) {
++
+ printk(" Bad EIP value.");
+ break;
+ }
+- printk("%02x ", c);
++ if (eip == (u8 *)regs->eip)
++ printk("<%02x> ", c);
++ else
++ printk("%02x ", c);
+ }
+ }
+ printk("\n");
+@@ -252,12 +291,36 @@
+ void die(const char * str, struct pt_regs * regs, long err)
+ {
+ static int die_counter;
++ int nl = 0;
+
+ console_verbose();
+ spin_lock_irq(&die_lock);
+ bust_spinlocks(1);
+ handle_BUG(regs);
+ printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
++#ifdef CONFIG_PREEMPT
++ printk("PREEMPT ");
++ nl = 1;
++#endif
++#ifdef CONFIG_SMP
++ printk("SMP ");
++ nl = 1;
++#endif
++#ifdef CONFIG_DEBUG_PAGEALLOC
++ printk("DEBUG_PAGEALLOC");
++ nl = 1;
++#endif
++ if (nl)
++ printk("\n");
++#ifdef CONFIG_KGDB
++ /* This is about the only place we want to go to kgdb even if in
++ * user mode. But we must go in via a trap so within kgdb we will
++ * always be in kernel mode.
++ */
++ if (user_mode(regs))
++ BREAKPOINT;
++#endif
++ CHK_REMOTE_DEBUG(0,SIGTRAP,err,regs,)
+ show_registers(regs);
+ bust_spinlocks(0);
+ spin_unlock_irq(&die_lock);
+@@ -327,6 +390,7 @@
+ #define DO_ERROR(trapnr, signr, str, name) \
+ asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
+ { \
++ CHK_REMOTE_DEBUG(trapnr,signr,error_code,regs,)\
+ do_trap(trapnr, signr, str, 0, regs, error_code, NULL); \
+ }
+
+@@ -344,7 +408,9 @@
+ #define DO_VM86_ERROR(trapnr, signr, str, name) \
+ asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
+ { \
++ CHK_REMOTE_DEBUG(trapnr, signr, error_code,regs, return)\
+ do_trap(trapnr, signr, str, 1, regs, error_code, NULL); \
++ return; \
+ }
+
+ #define DO_VM86_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
+@@ -387,8 +453,10 @@
+ return;
+
+ gp_in_kernel:
+- if (!fixup_exception(regs))
++ if (!fixup_exception(regs)){
++ CHK_REMOTE_DEBUG(13,SIGSEGV,error_code,regs,)
+ die("general protection fault", regs, error_code);
++ }
+ }
+
+ static void mem_parity_error(unsigned char reason, struct pt_regs * regs)
+@@ -527,10 +595,18 @@
+ if (regs->eflags & X86_EFLAGS_IF)
+ local_irq_enable();
+
+- /* Mask out spurious debug traps due to lazy DR7 setting */
++ /*
++ * Mask out spurious debug traps due to lazy DR7 setting or
++ * due to 4G/4G kernel mode:
++ */
+ if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
+ if (!tsk->thread.debugreg[7])
+ goto clear_dr7;
++ if (!user_mode(regs)) {
++ // restore upon return-to-userspace:
++ set_thread_flag(TIF_DB7);
++ goto clear_dr7;
++ }
+ }
+
+ if (regs->eflags & VM_MASK)
+@@ -550,8 +626,18 @@
+ * allowing programs to debug themselves without the ptrace()
+ * interface.
+ */
++#ifdef CONFIG_KGDB
++ /*
++ * I think this is the only "real" case of a TF in the kernel
++ * that really belongs to user space. Others are
++ * "Ours all ours!"
++ */
++ if (((regs->xcs & 3) == 0) && ((void *)regs->eip == sysenter_entry))
++ goto clear_TF_reenable;
++#else
+ if ((regs->xcs & 3) == 0)
+ goto clear_TF_reenable;
++#endif
+ if ((tsk->ptrace & (PT_DTRACE|PT_PTRACED)) == PT_DTRACE)
+ goto clear_TF;
+ }
+@@ -563,6 +649,17 @@
+ info.si_errno = 0;
+ info.si_code = TRAP_BRKPT;
+
++#ifdef CONFIG_KGDB
++ /*
++ * If this is a kernel mode trap, we need to reset db7 to allow us
++ * to continue sanely ALSO skip the signal delivery
++ */
++ if ((regs->xcs & 3) == 0)
++ goto clear_dr7;
++
++ /* if not kernel, allow ints but only if they were on */
++ if ( regs->eflags & 0x200) local_irq_enable();
++#endif
+ /* If this is a kernel mode trap, save the user PC on entry to
+ * the kernel, that's what the debugger can make sense of.
+ */
+@@ -577,6 +674,7 @@
+ __asm__("movl %0,%%db7"
+ : /* no output */
+ : "r" (0));
++ CHK_REMOTE_DEBUG(1,SIGTRAP,error_code,regs,)
+ return;
+
+ debug_vm86:
+@@ -772,19 +870,53 @@
+
+ #endif /* CONFIG_MATH_EMULATION */
+
+-#ifdef CONFIG_X86_F00F_BUG
+-void __init trap_init_f00f_bug(void)
++void __init trap_init_virtual_IDT(void)
+ {
+- __set_fixmap(FIX_F00F_IDT, __pa(&idt_table), PAGE_KERNEL_RO);
+-
+ /*
+- * Update the IDT descriptor and reload the IDT so that
+- * it uses the read-only mapped virtual address.
++ * "idt" is magic - it overlaps the idt_descr
++ * variable so that updating idt will automatically
++ * update the idt descriptor..
+ */
+- idt_descr.address = fix_to_virt(FIX_F00F_IDT);
++ __set_fixmap(FIX_IDT, __pa(&idt_table), PAGE_KERNEL_RO);
++ idt_descr.address = __fix_to_virt(FIX_IDT);
++
+ __asm__ __volatile__("lidt %0": "=m" (idt_descr));
+ }
+-#endif
++
++void __init trap_init_virtual_GDT(void)
++{
++ int cpu = smp_processor_id();
++ struct Xgt_desc_struct *gdt_desc = cpu_gdt_descr + cpu;
++ struct Xgt_desc_struct tmp_desc = {0, 0};
++ struct tss_struct * t;
++
++ __asm__ __volatile__("sgdt %0": "=m" (tmp_desc): :"memory");
++
++#ifdef CONFIG_X86_HIGH_ENTRY
++ if (!cpu) {
++ __set_fixmap(FIX_GDT_0, __pa(cpu_gdt_table), PAGE_KERNEL);
++ __set_fixmap(FIX_GDT_1, __pa(cpu_gdt_table) + PAGE_SIZE, PAGE_KERNEL);
++ __set_fixmap(FIX_TSS_0, __pa(init_tss), PAGE_KERNEL);
++ __set_fixmap(FIX_TSS_1, __pa(init_tss) + 1*PAGE_SIZE, PAGE_KERNEL);
++ __set_fixmap(FIX_TSS_2, __pa(init_tss) + 2*PAGE_SIZE, PAGE_KERNEL);
++ __set_fixmap(FIX_TSS_3, __pa(init_tss) + 3*PAGE_SIZE, PAGE_KERNEL);
++ }
++
++ gdt_desc->address = __fix_to_virt(FIX_GDT_0) + sizeof(cpu_gdt_table[0]) * cpu;
++#else
++ gdt_desc->address = (unsigned long)cpu_gdt_table[cpu];
++#endif
++ __asm__ __volatile__("lgdt %0": "=m" (*gdt_desc));
++
++#ifdef CONFIG_X86_HIGH_ENTRY
++ t = (struct tss_struct *) __fix_to_virt(FIX_TSS_0) + cpu;
++#else
++ t = init_tss + cpu;
++#endif
++ set_tss_desc(cpu, t);
++ cpu_gdt_table[cpu][GDT_ENTRY_TSS].b &= 0xfffffdff;
++ load_TR_desc();
++}
+
+ #define _set_gate(gate_addr,type,dpl,addr,seg) \
+ do { \
+@@ -811,20 +943,26 @@
+ _set_gate(idt_table+n,14,0,addr,__KERNEL_CS);
+ }
+
+-static void __init set_trap_gate(unsigned int n, void *addr)
++void __init set_trap_gate(unsigned int n, void *addr)
+ {
+ _set_gate(idt_table+n,15,0,addr,__KERNEL_CS);
+ }
+
+-static void __init set_system_gate(unsigned int n, void *addr)
++void __init set_system_gate(unsigned int n, void *addr)
+ {
+ _set_gate(idt_table+n,15,3,addr,__KERNEL_CS);
+ }
+
+-static void __init set_call_gate(void *a, void *addr)
++void __init set_call_gate(void *a, void *addr)
+ {
+ _set_gate(a,12,3,addr,__KERNEL_CS);
+ }
++#ifdef CONFIG_KGDB
++void set_intr_usr_gate(unsigned int n, void *addr)
++{
++ _set_gate(idt_table+n,14,3,addr,__KERNEL_CS);
++}
++#endif
+
+ static void __init set_task_gate(unsigned int n, unsigned int gdt_entry)
+ {
+@@ -832,10 +970,6 @@
+ }
+
+
+-#ifdef CONFIG_EISA
+-int EISA_bus;
+-#endif
+-
+ void __init trap_init(void)
+ {
+ #ifdef CONFIG_EISA
+@@ -847,11 +981,16 @@
+ #ifdef CONFIG_X86_LOCAL_APIC
+ init_apic_mappings();
+ #endif
++ init_entry_mappings();
+
+ set_trap_gate(0,÷_error);
+ set_intr_gate(1,&debug);
+ set_intr_gate(2,&nmi);
++#ifndef CONFIG_KGDB
+ set_system_gate(3,&int3); /* int3-5 can be called from all */
++#else
++ set_intr_usr_gate(3,&int3); /* int3-5 can be called from all */
++#endif
+ set_system_gate(4,&overflow);
+ set_system_gate(5,&bounds);
+ set_trap_gate(6,&invalid_op);
+Index: linux-2.6.0-test5/arch/i386/kernel/vm86.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/vm86.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/vm86.c 2003-09-27 11:38:19.134619480 +0800
+@@ -117,7 +117,7 @@
+
+ tss = init_tss + get_cpu();
+ current->thread.esp0 = current->thread.saved_esp0;
+- load_esp0(tss, current->thread.esp0);
++ load_esp0(tss, virtual_esp0(current));
+ current->thread.saved_esp0 = 0;
+ put_cpu();
+
+@@ -294,7 +294,8 @@
+ asm volatile("movl %%gs,%0":"=m" (tsk->thread.saved_gs));
+
+ tss = init_tss + get_cpu();
+- tss->esp0 = tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0;
++ tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0;
++ tss->esp0 = virtual_esp0(tsk);
+ disable_sysenter(tss);
+ put_cpu();
+
+Index: linux-2.6.0-test5/arch/i386/kernel/vmlinux.lds.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/vmlinux.lds.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/vmlinux.lds.S 2003-09-27 11:38:19.136619176 +0800
+@@ -3,6 +3,9 @@
+ */
+
+ #include <asm-generic/vmlinux.lds.h>
++#include <linux/config.h>
++#include <asm/page.h>
++#include <asm/asm_offsets.h>
+
+ OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
+ OUTPUT_ARCH(i386)
+@@ -10,7 +13,7 @@
+ jiffies = jiffies_64;
+ SECTIONS
+ {
+- . = 0xC0000000 + 0x100000;
++ . = __PAGE_OFFSET + 0x100000;
+ /* read-only */
+ _text = .; /* Text and read-only data */
+ .text : {
+@@ -19,6 +22,19 @@
+ *(.gnu.warning)
+ } = 0x9090
+
++#ifdef CONFIG_X86_4G
++ . = ALIGN(PAGE_SIZE_asm);
++ __entry_tramp_start = .;
++ . = FIX_ENTRY_TRAMPOLINE_0_addr;
++ __start___entry_text = .;
++ .entry.text : AT (__entry_tramp_start) { *(.entry.text) }
++ __entry_tramp_end = __entry_tramp_start + SIZEOF(.entry.text);
++ . = __entry_tramp_end;
++ . = ALIGN(PAGE_SIZE_asm);
++#else
++ .entry.text : { *(.entry.text) }
++#endif
++
+ _etext = .; /* End of text section */
+
+ . = ALIGN(16); /* Exception table */
+@@ -34,15 +50,12 @@
+ CONSTRUCTORS
+ }
+
+- . = ALIGN(4096);
++ . = ALIGN(PAGE_SIZE_asm);
+ __nosave_begin = .;
+ .data_nosave : { *(.data.nosave) }
+- . = ALIGN(4096);
++ . = ALIGN(PAGE_SIZE_asm);
+ __nosave_end = .;
+
+- . = ALIGN(4096);
+- .data.page_aligned : { *(.data.idt) }
+-
+ . = ALIGN(32);
+ .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+
+@@ -52,7 +65,7 @@
+ .data.init_task : { *(.data.init_task) }
+
+ /* will be freed after init */
+- . = ALIGN(4096); /* Init code and data */
++ . = ALIGN(PAGE_SIZE_asm); /* Init code and data */
+ __init_begin = .;
+ .init.text : {
+ _sinittext = .;
+@@ -91,7 +104,7 @@
+ from .altinstructions and .eh_frame */
+ .exit.text : { *(.exit.text) }
+ .exit.data : { *(.exit.data) }
+- . = ALIGN(4096);
++ . = ALIGN(PAGE_SIZE_asm);
+ __initramfs_start = .;
+ .init.ramfs : { *(.init.ramfs) }
+ __initramfs_end = .;
+@@ -99,10 +112,22 @@
+ __per_cpu_start = .;
+ .data.percpu : { *(.data.percpu) }
+ __per_cpu_end = .;
+- . = ALIGN(4096);
++ . = ALIGN(PAGE_SIZE_asm);
+ __init_end = .;
+ /* freed after init ends here */
+-
++
++ . = ALIGN(PAGE_SIZE_asm);
++ .data.page_aligned_tss : { *(.data.tss) }
++
++ . = ALIGN(PAGE_SIZE_asm);
++ .data.page_aligned_default_ldt : { *(.data.default_ldt) }
++
++ . = ALIGN(PAGE_SIZE_asm);
++ .data.page_aligned_idt : { *(.data.idt) }
++
++ . = ALIGN(PAGE_SIZE_asm);
++ .data.page_aligned_gdt : { *(.data.gdt) }
++
+ __bss_start = .; /* BSS */
+ .bss : { *(.bss) }
+ __bss_stop = .;
+@@ -122,4 +147,6 @@
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
++
++
+ }
+Index: linux-2.6.0-test5/arch/i386/kernel/vsyscall.lds
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/vsyscall.lds 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/vsyscall.lds 2003-09-27 11:38:19.144617960 +0800
+@@ -5,7 +5,7 @@
+ */
+
+ /* This must match <asm/fixmap.h>. */
+-VSYSCALL_BASE = 0xffffe000;
++VSYSCALL_BASE = 0xffffd000;
+
+ SECTIONS
+ {
+Index: linux-2.6.0-test5/arch/i386/kernel/vsyscall-sysenter.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/vsyscall-sysenter.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/vsyscall-sysenter.S 2003-09-27 11:38:19.146617656 +0800
+@@ -7,6 +7,11 @@
+ .type __kernel_vsyscall,@function
+ __kernel_vsyscall:
+ .LSTART_vsyscall:
++ cmpl $192, %eax
++ jne 1f
++ int $0x80
++ ret
++1:
+ push %ecx
+ .Lpush_ecx:
+ push %edx
+Index: linux-2.6.0-test5/arch/i386/lib/checksum.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/lib/checksum.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/lib/checksum.S 2003-09-27 11:38:19.149617200 +0800
+@@ -280,14 +280,14 @@
+ .previous
+
+ .align 4
+-.globl csum_partial_copy_generic
++.globl direct_csum_partial_copy_generic
+
+ #ifndef CONFIG_X86_USE_PPRO_CHECKSUM
+
+ #define ARGBASE 16
+ #define FP 12
+
+-csum_partial_copy_generic:
++direct_csum_partial_copy_generic:
+ subl $4,%esp
+ pushl %edi
+ pushl %esi
+@@ -422,7 +422,7 @@
+
+ #define ARGBASE 12
+
+-csum_partial_copy_generic:
++direct_csum_partial_copy_generic:
+ pushl %ebx
+ pushl %edi
+ pushl %esi
+Index: linux-2.6.0-test5/arch/i386/lib/dec_and_lock.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/lib/dec_and_lock.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/lib/dec_and_lock.c 2003-09-27 11:38:19.151616896 +0800
+@@ -10,6 +10,7 @@
+ #include <linux/spinlock.h>
+ #include <asm/atomic.h>
+
++#ifndef ATOMIC_DEC_AND_LOCK
+ int atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
+ {
+ int counter;
+@@ -38,3 +39,5 @@
+ spin_unlock(lock);
+ return 0;
+ }
++#endif
++
+Index: linux-2.6.0-test5/arch/i386/lib/getuser.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/lib/getuser.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/lib/getuser.S 2003-09-27 11:38:19.152616744 +0800
+@@ -9,6 +9,7 @@
+ * return value.
+ */
+ #include <asm/thread_info.h>
++#include <asm/asm_offsets.h>
+
+
+ /*
+@@ -28,7 +29,7 @@
+ .globl __get_user_1
+ __get_user_1:
+ GET_THREAD_INFO(%edx)
+- cmpl TI_ADDR_LIMIT(%edx),%eax
++ cmpl TI_addr_limit(%edx),%eax
+ jae bad_get_user
+ 1: movzbl (%eax),%edx
+ xorl %eax,%eax
+@@ -40,7 +41,7 @@
+ addl $1,%eax
+ jc bad_get_user
+ GET_THREAD_INFO(%edx)
+- cmpl TI_ADDR_LIMIT(%edx),%eax
++ cmpl TI_addr_limit(%edx),%eax
+ jae bad_get_user
+ 2: movzwl -1(%eax),%edx
+ xorl %eax,%eax
+@@ -52,7 +53,7 @@
+ addl $3,%eax
+ jc bad_get_user
+ GET_THREAD_INFO(%edx)
+- cmpl TI_ADDR_LIMIT(%edx),%eax
++ cmpl TI_addr_limit(%edx),%eax
+ jae bad_get_user
+ 3: movl -3(%eax),%edx
+ xorl %eax,%eax
+Index: linux-2.6.0-test5/arch/i386/lib/kgdb_serial.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/lib/kgdb_serial.c 2003-09-27 11:38:18.434725880 +0800
++++ linux-2.6.0-test5/arch/i386/lib/kgdb_serial.c 2003-09-27 11:38:19.154616440 +0800
+@@ -0,0 +1,499 @@
++/*
++ * Serial interface GDB stub
++ *
++ * Written (hacked together) by David Grothe (dave@gcom.com)
++ * Modified to allow invokation early in boot see also
++ * kgdb.h for instructions by George Anzinger(george@mvista.com)
++ * Modified to handle debugging over ethernet by Robert Walsh
++ * <rjwalsh@durables.org> and wangdi <wangdi@clusterfs.com>, based on
++ * code by San Mehat.
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/errno.h>
++#include <linux/signal.h>
++#include <linux/sched.h>
++#include <linux/timer.h>
++#include <linux/interrupt.h>
++#include <linux/tty.h>
++#include <linux/tty_flip.h>
++#include <linux/serial.h>
++#include <linux/serial_reg.h>
++#include <linux/config.h>
++#include <linux/major.h>
++#include <linux/string.h>
++#include <linux/fcntl.h>
++#include <linux/ptrace.h>
++#include <linux/ioport.h>
++#include <linux/mm.h>
++#include <linux/init.h>
++#include <linux/highmem.h>
++#include <asm/system.h>
++#include <asm/io.h>
++#include <asm/segment.h>
++#include <asm/bitops.h>
++#include <asm/system.h>
++#include <asm/kgdb_local.h>
++#ifdef CONFIG_KGDB_USER_CONSOLE
++extern void kgdb_console_finit(void);
++#endif
++#define PRNT_off
++#define TEST_EXISTANCE
++#ifdef PRNT
++#define dbprintk(s) printk s
++#else
++#define dbprintk(s)
++#endif
++#define TEST_INTERRUPT_off
++#ifdef TEST_INTERRUPT
++#define intprintk(s) printk s
++#else
++#define intprintk(s)
++#endif
++
++#define IRQ_T(info) ((info->flags & ASYNC_SHARE_IRQ) ? SA_SHIRQ : SA_INTERRUPT)
++
++#define GDB_BUF_SIZE 512 /* power of 2, please */
++
++static char gdb_buf[GDB_BUF_SIZE];
++static int gdb_buf_in_inx;
++static atomic_t gdb_buf_in_cnt;
++static int gdb_buf_out_inx;
++
++struct async_struct *gdb_async_info;
++static int gdb_async_irq;
++
++#define outb_px(a,b) outb_p(b,a)
++
++static void program_uart(struct async_struct *info);
++static void write_char(struct async_struct *info, int chr);
++/*
++ * Get a byte from the hardware data buffer and return it
++ */
++static int
++read_data_bfr(struct async_struct *info)
++{
++ char it = inb_p(info->port + UART_LSR);
++
++ if (it & UART_LSR_DR)
++ return (inb_p(info->port + UART_RX));
++ /*
++ * If we have a framing error assume somebody messed with
++ * our uart. Reprogram it and send '-' both ways...
++ */
++ if (it & 0xc) {
++ program_uart(info);
++ write_char(info, '-');
++ return ('-');
++ }
++ return (-1);
++
++} /* read_data_bfr */
++
++/*
++ * Get a char if available, return -1 if nothing available.
++ * Empty the receive buffer first, then look at the interface hardware.
++
++ * Locking here is a bit of a problem. We MUST not lock out communication
++ * if we are trying to talk to gdb about a kgdb entry. ON the other hand
++ * we can loose chars in the console pass thru if we don't lock. It is also
++ * possible that we could hold the lock or be waiting for it when kgdb
++ * NEEDS to talk. Since kgdb locks down the world, it does not need locks.
++ * We do, of course have possible issues with interrupting a uart operation,
++ * but we will just depend on the uart status to help keep that straight.
++
++ */
++static spinlock_t uart_interrupt_lock = SPIN_LOCK_UNLOCKED;
++#ifdef CONFIG_SMP
++extern spinlock_t kgdb_spinlock;
++#endif
++
++static int
++read_char(struct async_struct *info)
++{
++ int chr;
++ unsigned long flags;
++ local_irq_save(flags);
++#ifdef CONFIG_SMP
++ if (!spin_is_locked(&kgdb_spinlock)) {
++ spin_lock(&uart_interrupt_lock);
++ }
++#endif
++ if (atomic_read(&gdb_buf_in_cnt) != 0) { /* intr routine has q'd chars */
++ chr = gdb_buf[gdb_buf_out_inx++];
++ gdb_buf_out_inx &= (GDB_BUF_SIZE - 1);
++ atomic_dec(&gdb_buf_in_cnt);
++ } else {
++ chr = read_data_bfr(info);
++ }
++#ifdef CONFIG_SMP
++ if (!spin_is_locked(&kgdb_spinlock)) {
++ spin_unlock(&uart_interrupt_lock);
++ }
++#endif
++ local_irq_restore(flags);
++ return (chr);
++}
++
++/*
++ * Wait until the interface can accept a char, then write it.
++ */
++static void
++write_char(struct async_struct *info, int chr)
++{
++ while (!(inb_p(info->port + UART_LSR) & UART_LSR_THRE)) ;
++
++ outb_p(chr, info->port + UART_TX);
++
++} /* write_char */
++
++/*
++ * Mostly we don't need a spinlock, but since the console goes
++ * thru here with interrutps on, well, we need to catch those
++ * chars.
++ */
++/*
++ * This is the receiver interrupt routine for the GDB stub.
++ * It will receive a limited number of characters of input
++ * from the gdb host machine and save them up in a buffer.
++ *
++ * When the gdb stub routine tty_getDebugChar() is called it
++ * draws characters out of the buffer until it is empty and
++ * then reads directly from the serial port.
++ *
++ * We do not attempt to write chars from the interrupt routine
++ * since the stubs do all of that via tty_putDebugChar() which
++ * writes one byte after waiting for the interface to become
++ * ready.
++ *
++ * The debug stubs like to run with interrupts disabled since,
++ * after all, they run as a consequence of a breakpoint in
++ * the kernel.
++ *
++ * Perhaps someone who knows more about the tty driver than I
++ * care to learn can make this work for any low level serial
++ * driver.
++ */
++static irqreturn_t
++gdb_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{
++ struct async_struct *info;
++ unsigned long flags;
++
++ info = gdb_async_info;
++ if (!info || !info->tty || irq != gdb_async_irq)
++ return IRQ_NONE;
++
++ local_irq_save(flags);
++ spin_lock(&uart_interrupt_lock);
++ do {
++ int chr = read_data_bfr(info);
++ intprintk(("Debug char on int: %x hex\n", chr));
++ if (chr < 0)
++ continue;
++
++ if (chr == 3) { /* Ctrl-C means remote interrupt */
++ BREAKPOINT;
++ continue;
++ }
++
++ if (atomic_read(&gdb_buf_in_cnt) >= GDB_BUF_SIZE) {
++ /* buffer overflow tosses early char */
++ read_char(info);
++ }
++ gdb_buf[gdb_buf_in_inx++] = chr;
++ gdb_buf_in_inx &= (GDB_BUF_SIZE - 1);
++ } while (inb_p(info->port + UART_IIR) & UART_IIR_RDI);
++ spin_unlock(&uart_interrupt_lock);
++ local_irq_restore(flags);
++ return IRQ_HANDLED;
++} /* gdb_interrupt */
++
++/*
++ * Just a NULL routine for testing.
++ */
++void
++gdb_null(void)
++{
++} /* gdb_null */
++
++/* These structure are filled in with values defined in asm/kgdb_local.h
++ */
++static struct serial_state state = SB_STATE;
++static struct async_struct local_info = SB_INFO;
++static int ok_to_enable_ints = 0;
++static void kgdb_enable_ints_now(void);
++
++extern char *kgdb_version;
++/*
++ * Hook an IRQ for KGDB.
++ *
++ * This routine is called from tty_putDebugChar, below.
++ */
++static int ints_disabled = 1;
++int
++gdb_hook_interrupt(struct async_struct *info, int verb)
++{
++ struct serial_state *state = info->state;
++ unsigned long flags;
++ int port;
++#ifdef TEST_EXISTANCE
++ int scratch, scratch2;
++#endif
++
++ /* The above fails if memory managment is not set up yet.
++ * Rather than fail the set up, just keep track of the fact
++ * and pick up the interrupt thing later.
++ */
++ gdb_async_info = info;
++ port = gdb_async_info->port;
++ gdb_async_irq = state->irq;
++ if (verb) {
++ printk("kgdb %s : port =%x, IRQ=%d, divisor =%d\n",
++ kgdb_version,
++ port,
++ gdb_async_irq, gdb_async_info->state->custom_divisor);
++ }
++ local_irq_save(flags);
++#ifdef TEST_EXISTANCE
++ /* Existance test */
++ /* Should not need all this, but just in case.... */
++
++ scratch = inb_p(port + UART_IER);
++ outb_px(port + UART_IER, 0);
++ outb_px(0xff, 0x080);
++ scratch2 = inb_p(port + UART_IER);
++ outb_px(port + UART_IER, scratch);
++ if (scratch2) {
++ printk
++ ("gdb_hook_interrupt: Could not clear IER, not a UART!\n");
++ local_irq_restore(flags);
++ return 1; /* We failed; there's nothing here */
++ }
++ scratch2 = inb_p(port + UART_LCR);
++ outb_px(port + UART_LCR, 0xBF); /* set up for StarTech test */
++ outb_px(port + UART_EFR, 0); /* EFR is the same as FCR */
++ outb_px(port + UART_LCR, 0);
++ outb_px(port + UART_FCR, UART_FCR_ENABLE_FIFO);
++ scratch = inb_p(port + UART_IIR) >> 6;
++ if (scratch == 1) {
++ printk("gdb_hook_interrupt: Undefined UART type!"
++ " Not a UART! \n");
++ local_irq_restore(flags);
++ return 1;
++ } else {
++ dbprintk(("gdb_hook_interrupt: UART type "
++ "is %d where 0=16450, 2=16550 3=16550A\n", scratch));
++ }
++ scratch = inb_p(port + UART_MCR);
++ outb_px(port + UART_MCR, UART_MCR_LOOP | scratch);
++ outb_px(port + UART_MCR, UART_MCR_LOOP | 0x0A);
++ scratch2 = inb_p(port + UART_MSR) & 0xF0;
++ outb_px(port + UART_MCR, scratch);
++ if (scratch2 != 0x90) {
++ printk("gdb_hook_interrupt: "
++ "Loop back test failed! Not a UART!\n");
++ local_irq_restore(flags);
++ return scratch2 + 1000; /* force 0 to fail */
++ }
++#endif /* test existance */
++ program_uart(info);
++ local_irq_restore(flags);
++
++ return (0);
++
++} /* gdb_hook_interrupt */
++
++static void
++program_uart(struct async_struct *info)
++{
++ int port = info->port;
++
++ (void) inb_p(port + UART_RX);
++ outb_px(port + UART_IER, 0);
++
++ (void) inb_p(port + UART_RX); /* serial driver comments say */
++ (void) inb_p(port + UART_IIR); /* this clears the interrupt regs */
++ (void) inb_p(port + UART_MSR);
++ outb_px(port + UART_LCR, UART_LCR_WLEN8 | UART_LCR_DLAB);
++ outb_px(port + UART_DLL, info->state->custom_divisor & 0xff); /* LS */
++ outb_px(port + UART_DLM, info->state->custom_divisor >> 8); /* MS */
++ outb_px(port + UART_MCR, info->MCR);
++
++ outb_px(port + UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1 | UART_FCR_CLEAR_XMIT | UART_FCR_CLEAR_RCVR); /* set fcr */
++ outb_px(port + UART_LCR, UART_LCR_WLEN8); /* reset DLAB */
++ outb_px(port + UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1); /* set fcr */
++ if (!ints_disabled) {
++ intprintk(("KGDB: Sending %d to port %x offset %d\n",
++ gdb_async_info->IER,
++ (int) gdb_async_info->port, UART_IER));
++ outb_px(gdb_async_info->port + UART_IER, gdb_async_info->IER);
++ }
++ return;
++}
++
++/*
++ * tty_getDebugChar
++ *
++ * This is a GDB stub routine. It waits for a character from the
++ * serial interface and then returns it. If there is no serial
++ * interface connection then it returns a bogus value which will
++ * almost certainly cause the system to hang. In the
++ */
++int kgdb_in_isr = 0;
++int kgdb_in_lsr = 0;
++extern spinlock_t kgdb_spinlock;
++
++/* Caller takes needed protections */
++
++int
++tty_getDebugChar(void)
++{
++ volatile int chr, dum, time, end_time;
++
++ dbprintk(("tty_getDebugChar(port %x): ", gdb_async_info->port));
++
++ if (gdb_async_info == NULL) {
++ gdb_hook_interrupt(&local_info, 0);
++ }
++ /*
++ * This trick says if we wait a very long time and get
++ * no char, return the -1 and let the upper level deal
++ * with it.
++ */
++ rdtsc(dum, time);
++ end_time = time + 2;
++ while (((chr = read_char(gdb_async_info)) == -1) &&
++ (end_time - time) > 0) {
++ rdtsc(dum, time);
++ };
++ /*
++ * This covers our butts if some other code messes with
++ * our uart, hay, it happens :o)
++ */
++ if (chr == -1)
++ program_uart(gdb_async_info);
++
++ dbprintk(("%c\n", chr > ' ' && chr < 0x7F ? chr : ' '));
++ return (chr);
++
++} /* tty_getDebugChar */
++
++static int count = 3;
++static spinlock_t one_at_atime = SPIN_LOCK_UNLOCKED;
++
++static int __init
++kgdb_enable_ints(void)
++{
++ if (kgdb_eth != -1) {
++ return 0;
++ }
++ if (gdb_async_info == NULL) {
++ gdb_hook_interrupt(&local_info, 1);
++ }
++ ok_to_enable_ints = 1;
++ kgdb_enable_ints_now();
++#ifdef CONFIG_KGDB_USER_CONSOLE
++ kgdb_console_finit();
++#endif
++ return 0;
++}
++
++#ifdef CONFIG_SERIAL_8250
++void shutdown_for_kgdb(struct async_struct *gdb_async_info);
++#endif
++
++#ifdef CONFIG_DISCONTIGMEM
++static inline int kgdb_mem_init_done(void)
++{
++ return highmem_start_page != NULL;
++}
++#else
++static inline int kgdb_mem_init_done(void)
++{
++ return max_mapnr != 0;
++}
++#endif
++
++static void
++kgdb_enable_ints_now(void)
++{
++ if (!spin_trylock(&one_at_atime))
++ return;
++ if (!ints_disabled)
++ goto exit;
++ if (kgdb_mem_init_done() &&
++ ints_disabled) { /* don't try till mem init */
++#ifdef CONFIG_SERIAL_8250
++ /*
++ * The ifdef here allows the system to be configured
++ * without the serial driver.
++ * Don't make it a module, however, it will steal the port
++ */
++ shutdown_for_kgdb(gdb_async_info);
++#endif
++ ints_disabled = request_irq(gdb_async_info->state->irq,
++ gdb_interrupt,
++ IRQ_T(gdb_async_info),
++ "KGDB-stub", NULL);
++ intprintk(("KGDB: request_irq returned %d\n", ints_disabled));
++ }
++ if (!ints_disabled) {
++ intprintk(("KGDB: Sending %d to port %x offset %d\n",
++ gdb_async_info->IER,
++ (int) gdb_async_info->port, UART_IER));
++ outb_px(gdb_async_info->port + UART_IER, gdb_async_info->IER);
++ }
++ exit:
++ spin_unlock(&one_at_atime);
++}
++
++/*
++ * tty_putDebugChar
++ *
++ * This is a GDB stub routine. It waits until the interface is ready
++ * to transmit a char and then sends it. If there is no serial
++ * interface connection then it simply returns to its caller, having
++ * pretended to send the char. Caller takes needed protections.
++ */
++void
++tty_putDebugChar(int chr)
++{
++ dbprintk(("tty_putDebugChar(port %x): chr=%02x '%c', ints_on=%d\n",
++ gdb_async_info->port,
++ chr,
++ chr > ' ' && chr < 0x7F ? chr : ' ', ints_disabled ? 0 : 1));
++
++ if (gdb_async_info == NULL) {
++ gdb_hook_interrupt(&local_info, 0);
++ }
++
++ write_char(gdb_async_info, chr); /* this routine will wait */
++ count = (chr == '#') ? 0 : count + 1;
++ if ((count == 2)) { /* try to enable after */
++ if (ints_disabled & ok_to_enable_ints)
++ kgdb_enable_ints_now(); /* try to enable after */
++
++ /* We do this a lot because, well we really want to get these
++ * interrupts. The serial driver will clear these bits when it
++ * initializes the chip. Every thing else it does is ok,
++ * but this.
++ */
++ if (!ints_disabled) {
++ outb_px(gdb_async_info->port + UART_IER,
++ gdb_async_info->IER);
++ }
++ }
++
++} /* tty_putDebugChar */
++
++/*
++ * This does nothing for the serial port, since it doesn't buffer.
++ */
++
++void tty_flushDebugChar(void)
++{
++}
++
++module_init(kgdb_enable_ints);
+Index: linux-2.6.0-test5/arch/i386/lib/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/lib/Makefile 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/lib/Makefile 2003-09-27 11:38:19.164614920 +0800
+@@ -9,4 +9,5 @@
+
+ lib-$(CONFIG_X86_USE_3DNOW) += mmx.o
+ lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o
++lib-$(CONFIG_KGDB) += kgdb_serial.o
+ lib-$(CONFIG_DEBUG_IOVIRT) += iodebug.o
+Index: linux-2.6.0-test5/arch/i386/lib/usercopy.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/lib/usercopy.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/lib/usercopy.c 2003-09-27 11:38:19.170614008 +0800
+@@ -76,7 +76,7 @@
+ * and returns @count.
+ */
+ long
+-__strncpy_from_user(char *dst, const char __user *src, long count)
++__direct_strncpy_from_user(char *dst, const char __user *src, long count)
+ {
+ long res;
+ __do_strncpy_from_user(dst, src, count, res);
+@@ -102,7 +102,7 @@
+ * and returns @count.
+ */
+ long
+-strncpy_from_user(char *dst, const char __user *src, long count)
++direct_strncpy_from_user(char *dst, const char __user *src, long count)
+ {
+ long res = -EFAULT;
+ if (access_ok(VERIFY_READ, src, 1))
+@@ -147,7 +147,7 @@
+ * On success, this will be zero.
+ */
+ unsigned long
+-clear_user(void __user *to, unsigned long n)
++direct_clear_user(void __user *to, unsigned long n)
+ {
+ might_sleep();
+ if (access_ok(VERIFY_WRITE, to, n))
+@@ -167,7 +167,7 @@
+ * On success, this will be zero.
+ */
+ unsigned long
+-__clear_user(void __user *to, unsigned long n)
++__direct_clear_user(void __user *to, unsigned long n)
+ {
+ __do_clear_user(to, n);
+ return n;
+@@ -184,7 +184,7 @@
+ * On exception, returns 0.
+ * If the string is too long, returns a value greater than @n.
+ */
+-long strnlen_user(const char __user *s, long n)
++long direct_strnlen_user(const char __user *s, long n)
+ {
+ unsigned long mask = -__addr_ok(s);
+ unsigned long res, tmp;
+@@ -573,3 +573,4 @@
+ n = __copy_user_zeroing_intel(to, (const void *) from, n);
+ return n;
+ }
++
+Index: linux-2.6.0-test5/arch/i386/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/Makefile 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/Makefile 2003-09-27 11:38:19.182612184 +0800
+@@ -21,11 +21,13 @@
+
+ CFLAGS += -pipe
+
+-check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi)
+-
+ # prevent gcc from keeping the stack 16 byte aligned
+ CFLAGS += $(call check_gcc,-mpreferred-stack-boundary=2,)
+
++# gcc 3.4/3.3-hammer support -funit-at-a-time mode, but the Kernel is not ready
++# for it yet
++CFLAGS += $(call check_gcc,-fno-unit-at-a-time,)
++
+ align := $(subst -functions=0,,$(call check_gcc,-falign-functions=0,-malign-functions=0))
+
+ cflags-$(CONFIG_M386) += -march=i386
+@@ -86,6 +88,9 @@
+ # default subarch .h files
+ mflags-y += -Iinclude/asm-i386/mach-default
+
++mflags-$(CONFIG_KGDB) += -gdwarf-2
++mflags-$(CONFIG_KGDB_MORE) += $(shell echo $(CONFIG_KGDB_OPTIONS) | sed -e 's/"//g')
++
+ head-y := arch/i386/kernel/head.o arch/i386/kernel/init_task.o
+
+ libs-y += arch/i386/lib/
+@@ -96,6 +101,7 @@
+ drivers-$(CONFIG_PCI) += arch/i386/pci/
+ # must be linked after kernel/
+ drivers-$(CONFIG_OPROFILE) += arch/i386/oprofile/
++drivers-$(CONFIG_PM) += arch/i386/power/
+
+ CFLAGS += $(mflags-y)
+ AFLAGS += $(mflags-y)
+Index: linux-2.6.0-test5/arch/i386/math-emu/fpu_system.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/math-emu/fpu_system.h 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/math-emu/fpu_system.h 2003-09-27 11:38:19.184611880 +0800
+@@ -15,6 +15,7 @@
+ #include <linux/sched.h>
+ #include <linux/kernel.h>
+ #include <linux/mm.h>
++#include <asm/atomic_kmap.h>
+
+ /* This sets the pointer FPU_info to point to the argument part
+ of the stack frame of math_emulate() */
+@@ -22,7 +23,7 @@
+
+ /* s is always from a cpu register, and the cpu does bounds checking
+ * during register load --> no further bounds checks needed */
+-#define LDT_DESCRIPTOR(s) (((struct desc_struct *)current->mm->context.ldt)[(s) >> 3])
++#define LDT_DESCRIPTOR(s) (((struct desc_struct *)__kmap_atomic_vaddr(KM_LDT_PAGE0))[(s) >> 3])
+ #define SEG_D_SIZE(x) ((x).b & (3 << 21))
+ #define SEG_G_BIT(x) ((x).b & (1 << 23))
+ #define SEG_GRANULARITY(x) (((x).b & (1 << 23)) ? 4096 : 1)
+Index: linux-2.6.0-test5/arch/i386/mm/discontig.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/mm/discontig.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/mm/discontig.c 2003-09-27 11:38:19.188611272 +0800
+@@ -30,6 +30,7 @@
+ #include <linux/initrd.h>
+ #include <asm/e820.h>
+ #include <asm/setup.h>
++#include <asm/mmzone.h>
+
+ struct pglist_data *node_data[MAX_NUMNODES];
+ bootmem_data_t node0_bdata;
+@@ -84,7 +85,7 @@
+ * a single node with all available processors in it with a flat
+ * memory map.
+ */
+-void __init get_memcfg_numa_flat(void)
++int __init get_memcfg_numa_flat(void)
+ {
+ int pfn;
+
+@@ -107,6 +108,7 @@
+ /* Indicate there is one node available. */
+ node_set_online(0);
+ numnodes = 1;
++ return 1;
+ }
+
+ /*
+@@ -355,17 +357,20 @@
+ unsigned long low = max_low_pfn;
+ unsigned long start = node_start_pfn[nid];
+ unsigned long high = node_end_pfn[nid];
+-
++
+ max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
+
+ if (start > low) {
+ #ifdef CONFIG_HIGHMEM
+- zones_size[ZONE_HIGHMEM] = high - start;
++ BUG_ON(start > high);
++ zones_size[ZONE_HIGHMEM] = high - start;
+ #endif
+ } else {
+ if (low < max_dma)
+ zones_size[ZONE_DMA] = low;
+ else {
++ BUG_ON(max_dma > low);
++ BUG_ON(low > high);
+ zones_size[ZONE_DMA] = max_dma;
+ zones_size[ZONE_NORMAL] = low - max_dma;
+ #ifdef CONFIG_HIGHMEM
+Index: linux-2.6.0-test5/arch/i386/mm/extable.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/mm/extable.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/mm/extable.c 2003-09-27 11:38:19.190610968 +0800
+@@ -6,6 +6,52 @@
+ #include <linux/module.h>
+ #include <linux/spinlock.h>
+ #include <asm/uaccess.h>
++#include <asm/pgtable.h>
++
++extern struct exception_table_entry __start___ex_table[];
++extern struct exception_table_entry __stop___ex_table[];
++
++/*
++ * The exception table needs to be sorted because we use the macros
++ * which put things into the exception table in a variety of sections
++ * as well as the init section and the main kernel text section.
++ */
++static inline void
++sort_ex_table(struct exception_table_entry *start,
++ struct exception_table_entry *finish)
++{
++ struct exception_table_entry el, *p, *q;
++
++ /* insertion sort */
++ for (p = start + 1; p < finish; ++p) {
++ /* start .. p-1 is sorted */
++ if (p[0].insn < p[-1].insn) {
++ /* move element p down to its right place */
++ el = *p;
++ q = p;
++ do {
++ /* el comes before q[-1], move q[-1] up one */
++ q[0] = q[-1];
++ --q;
++ } while (q > start && el.insn < q[-1].insn);
++ *q = el;
++ }
++ }
++}
++
++void fixup_sort_exception_table(void)
++{
++ struct exception_table_entry *p;
++
++ /*
++ * Fix up the trampoline exception addresses:
++ */
++ for (p = __start___ex_table; p < __stop___ex_table; p++) {
++ p->insn = (unsigned long)(void *)p->insn;
++ p->fixup = (unsigned long)(void *)p->fixup;
++ }
++ sort_ex_table(__start___ex_table, __stop___ex_table);
++}
+
+ /* Simple binary search */
+ const struct exception_table_entry *
+@@ -15,13 +61,15 @@
+ {
+ while (first <= last) {
+ const struct exception_table_entry *mid;
+- long diff;
+
+ mid = (last - first) / 2 + first;
+- diff = mid->insn - value;
+- if (diff == 0)
++ /*
++ * careful, the distance between entries can be
++ * larger than 2GB:
++ */
++ if (mid->insn == value)
+ return mid;
+- else if (diff < 0)
++ else if (mid->insn < value)
+ first = mid+1;
+ else
+ last = mid-1;
+Index: linux-2.6.0-test5/arch/i386/mm/fault.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/mm/fault.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/mm/fault.c 2003-09-27 11:38:19.192610664 +0800
+@@ -55,6 +55,85 @@
+ console_loglevel = loglevel_save;
+ }
+
++/* Sometimes AMD K7/K8 reports invalid exceptions on prefetch.
++ Check that here and ignore.
++ Opcode checker based on code by Richard Brunner */
++static int __is_prefetch(struct pt_regs *regs, unsigned long addr)
++{
++ unsigned char *instr = (unsigned char *)(regs->eip);
++ int scan_more;
++ int prefetch = 0;
++ int c;
++
++ /* Avoid recursive faults. This is just an optimization,
++ they must be handled correctly too */
++ if (regs->eip == addr)
++ return 0;
++
++ /* Don't check for LDT code segments because they could have
++ non zero bases. Better would be to add in the base in this case. */
++ if (regs->xcs & (1<<2))
++ return 0;
++
++ scan_more = 1;
++ for (c = 0; c < 15 && scan_more; c++) {
++ unsigned char opcode;
++ unsigned char instr_hi;
++ unsigned char instr_lo;
++
++ if (__get_user(opcode, instr))
++ break;
++
++ instr_hi = opcode & 0xf0;
++ instr_lo = opcode & 0x0f;
++ instr++;
++
++ switch (instr_hi) {
++ case 0x20:
++ case 0x30:
++ /* Values 0x26,0x2E,0x36,0x3E are valid x86
++ prefixes. In long mode, the CPU will signal
++ invalid opcode if some of these prefixes are
++ present so we will never get here anyway */
++ scan_more = ((instr_lo & 7) == 0x6);
++ break;
++
++ case 0x40:
++ /* May be valid in long mode (REX prefixes) */
++ break;
++
++ case 0x60:
++ /* 0x64 thru 0x67 are valid prefixes in all modes. */
++ scan_more = (instr_lo & 0xC) == 0x4;
++ break;
++ case 0xF0:
++ /* 0xF0, 0xF2, and 0xF3 are valid prefixes in all modes. */
++ scan_more = !instr_lo || (instr_lo>>1) == 1;
++ break;
++ case 0x00:
++ /* Prefetch instruction is 0x0F0D or 0x0F18 */
++ scan_more = 0;
++ if (__get_user(opcode, instr))
++ break;
++ prefetch = (instr_lo == 0xF) &&
++ (opcode == 0x0D || opcode == 0x18);
++ break;
++ default:
++ scan_more = 0;
++ break;
++ }
++ }
++ return prefetch;
++}
++
++static inline int is_prefetch(struct pt_regs *regs, unsigned long addr)
++{
++ if (likely(boot_cpu_data.x86_vendor != X86_VENDOR_AMD ||
++ boot_cpu_data.x86 < 6))
++ return 0;
++ return __is_prefetch(regs, addr);
++}
++
+ asmlinkage void do_invalid_op(struct pt_regs *, unsigned long);
+
+ /*
+@@ -110,7 +189,7 @@
+ * atomic region then we must not take the fault..
+ */
+ if (in_atomic() || !mm)
+- goto no_context;
++ goto bad_area_nosemaphore;
+
+ down_read(&mm->mmap_sem);
+
+@@ -198,8 +277,12 @@
+ bad_area:
+ up_read(&mm->mmap_sem);
+
++bad_area_nosemaphore:
+ /* User mode accesses just cause a SIGSEGV */
+ if (error_code & 4) {
++ if (is_prefetch(regs, address))
++ return;
++
+ tsk->thread.cr2 = address;
+ tsk->thread.error_code = error_code;
+ tsk->thread.trap_no = 14;
+@@ -232,10 +315,19 @@
+ if (fixup_exception(regs))
+ return;
+
++ if (is_prefetch(regs, address))
++ return;
++
+ /*
+ * Oops. The kernel tried to access some bad page. We'll have to
+ * terminate things with extreme prejudice.
+ */
++#ifdef CONFIG_KGDB
++ if (!user_mode(regs)){
++ kgdb_handle_exception(14,SIGBUS, error_code, regs);
++ return;
++ }
++#endif
+
+ bust_spinlocks(1);
+
+@@ -286,10 +378,13 @@
+ do_sigbus:
+ up_read(&mm->mmap_sem);
+
+- /*
+- * Send a sigbus, regardless of whether we were in kernel
+- * or user mode.
+- */
++ /* Kernel mode? Handle exceptions or die */
++ if (!(error_code & 4))
++ goto no_context;
++
++ if (is_prefetch(regs, address))
++ return;
++
+ tsk->thread.cr2 = address;
+ tsk->thread.error_code = error_code;
+ tsk->thread.trap_no = 14;
+@@ -298,10 +393,6 @@
+ info.si_code = BUS_ADRERR;
+ info.si_addr = (void *)address;
+ force_sig_info(SIGBUS, &info, tsk);
+-
+- /* Kernel mode? Handle exceptions or die */
+- if (!(error_code & 4))
+- goto no_context;
+ return;
+
+ vmalloc_fault:
+Index: linux-2.6.0-test5/arch/i386/mm/hugetlbpage.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/mm/hugetlbpage.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/mm/hugetlbpage.c 2003-09-27 11:38:19.196610056 +0800
+@@ -355,14 +355,21 @@
+ + (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
+ page = find_get_page(mapping, idx);
+ if (!page) {
++ /* charge the fs quota first */
++ if (hugetlb_get_quota(mapping)) {
++ ret = -ENOMEM;
++ goto out;
++ }
+ page = alloc_hugetlb_page();
+ if (!page) {
++ hugetlb_put_quota(mapping);
+ ret = -ENOMEM;
+ goto out;
+ }
+ ret = add_to_page_cache(page, mapping, idx, GFP_ATOMIC);
+ unlock_page(page);
+ if (ret) {
++ hugetlb_put_quota(mapping);
+ free_huge_page(page);
+ goto out;
+ }
+Index: linux-2.6.0-test5/arch/i386/mm/init.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/mm/init.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/mm/init.c 2003-09-27 11:38:19.210607928 +0800
+@@ -38,125 +38,13 @@
+ #include <asm/tlb.h>
+ #include <asm/tlbflush.h>
+ #include <asm/sections.h>
++#include <asm/desc.h>
+
+ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
+ unsigned long highstart_pfn, highend_pfn;
+
+ static int do_test_wp_bit(void);
+
+-/*
+- * Creates a middle page table and puts a pointer to it in the
+- * given global directory entry. This only returns the gd entry
+- * in non-PAE compilation mode, since the middle layer is folded.
+- */
+-static pmd_t * __init one_md_table_init(pgd_t *pgd)
+-{
+- pmd_t *pmd_table;
+-
+-#ifdef CONFIG_X86_PAE
+- pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+- set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
+- if (pmd_table != pmd_offset(pgd, 0))
+- BUG();
+-#else
+- pmd_table = pmd_offset(pgd, 0);
+-#endif
+-
+- return pmd_table;
+-}
+-
+-/*
+- * Create a page table and place a pointer to it in a middle page
+- * directory entry.
+- */
+-static pte_t * __init one_page_table_init(pmd_t *pmd)
+-{
+- if (pmd_none(*pmd)) {
+- pte_t *page_table = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+- set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
+- if (page_table != pte_offset_kernel(pmd, 0))
+- BUG();
+-
+- return page_table;
+- }
+-
+- return pte_offset_kernel(pmd, 0);
+-}
+-
+-/*
+- * This function initializes a certain range of kernel virtual memory
+- * with new bootmem page tables, everywhere page tables are missing in
+- * the given range.
+- */
+-
+-/*
+- * NOTE: The pagetables are allocated contiguous on the physical space
+- * so we can cache the place of the first one and move around without
+- * checking the pgd every time.
+- */
+-static void __init page_table_range_init (unsigned long start, unsigned long end, pgd_t *pgd_base)
+-{
+- pgd_t *pgd;
+- pmd_t *pmd;
+- int pgd_idx, pmd_idx;
+- unsigned long vaddr;
+-
+- vaddr = start;
+- pgd_idx = pgd_index(vaddr);
+- pmd_idx = pmd_index(vaddr);
+- pgd = pgd_base + pgd_idx;
+-
+- for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
+- if (pgd_none(*pgd))
+- one_md_table_init(pgd);
+-
+- pmd = pmd_offset(pgd, vaddr);
+- for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) {
+- if (pmd_none(*pmd))
+- one_page_table_init(pmd);
+-
+- vaddr += PMD_SIZE;
+- }
+- pmd_idx = 0;
+- }
+-}
+-
+-/*
+- * This maps the physical memory to kernel virtual address space, a total
+- * of max_low_pfn pages, by creating page tables starting from address
+- * PAGE_OFFSET.
+- */
+-static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
+-{
+- unsigned long pfn;
+- pgd_t *pgd;
+- pmd_t *pmd;
+- pte_t *pte;
+- int pgd_idx, pmd_idx, pte_ofs;
+-
+- pgd_idx = pgd_index(PAGE_OFFSET);
+- pgd = pgd_base + pgd_idx;
+- pfn = 0;
+-
+- for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
+- pmd = one_md_table_init(pgd);
+- if (pfn >= max_low_pfn)
+- continue;
+- for (pmd_idx = 0; pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn; pmd++, pmd_idx++) {
+- /* Map with big pages if possible, otherwise create normal page tables. */
+- if (cpu_has_pse) {
+- set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE));
+- pfn += PTRS_PER_PTE;
+- } else {
+- pte = one_page_table_init(pmd);
+-
+- for (pte_ofs = 0; pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn; pte++, pfn++, pte_ofs++)
+- set_pte(pte, pfn_pte(pfn, PAGE_KERNEL));
+- }
+- }
+- }
+-}
+-
+ static inline int page_kills_ppro(unsigned long pagenr)
+ {
+ if (pagenr >= 0x70000 && pagenr <= 0x7003F)
+@@ -186,38 +74,14 @@
+ return 0;
+ }
+
+-#ifdef CONFIG_HIGHMEM
+ pte_t *kmap_pte;
+-pgprot_t kmap_prot;
+
+ #define kmap_get_fixmap_pte(vaddr) \
+ pte_offset_kernel(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
+
+ void __init kmap_init(void)
+ {
+- unsigned long kmap_vstart;
+-
+- /* cache the first kmap pte */
+- kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
+- kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
+-
+- kmap_prot = PAGE_KERNEL;
+-}
+-
+-void __init permanent_kmaps_init(pgd_t *pgd_base)
+-{
+- pgd_t *pgd;
+- pmd_t *pmd;
+- pte_t *pte;
+- unsigned long vaddr;
+-
+- vaddr = PKMAP_BASE;
+- page_table_range_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
+-
+- pgd = swapper_pg_dir + pgd_index(vaddr);
+- pmd = pmd_offset(pgd, vaddr);
+- pte = pte_offset_kernel(pmd, vaddr);
+- pkmap_page_table = pte;
++ kmap_pte = kmap_get_fixmap_pte(__fix_to_virt(FIX_KMAP_BEGIN));
+ }
+
+ void __init one_highpage_init(struct page *page, int pfn, int bad_ppro)
+@@ -232,6 +96,8 @@
+ SetPageReserved(page);
+ }
+
++#ifdef CONFIG_HIGHMEM
++
+ #ifndef CONFIG_DISCONTIGMEM
+ void __init set_highmem_pages_init(int bad_ppro)
+ {
+@@ -243,12 +109,9 @@
+ #else
+ extern void set_highmem_pages_init(int);
+ #endif /* !CONFIG_DISCONTIGMEM */
+-
+ #else
+-#define kmap_init() do { } while (0)
+-#define permanent_kmaps_init(pgd_base) do { } while (0)
+-#define set_highmem_pages_init(bad_ppro) do { } while (0)
+-#endif /* CONFIG_HIGHMEM */
++# define set_highmem_pages_init(bad_ppro) do { } while (0)
++#endif
+
+ unsigned long __PAGE_KERNEL = _PAGE_KERNEL;
+
+@@ -258,30 +121,125 @@
+ extern void __init remap_numa_kva(void);
+ #endif
+
+-static void __init pagetable_init (void)
++static __init void prepare_pagetables(pgd_t *pgd_base, unsigned long address)
++{
++ pgd_t *pgd;
++ pmd_t *pmd;
++ pte_t *pte;
++
++ pgd = pgd_base + pgd_index(address);
++ pmd = pmd_offset(pgd, address);
++ if (!pmd_present(*pmd)) {
++ pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
++ set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)));
++ }
++}
++
++static void __init fixrange_init (unsigned long start, unsigned long end, pgd_t *pgd_base)
+ {
+ unsigned long vaddr;
+- pgd_t *pgd_base = swapper_pg_dir;
+
++ for (vaddr = start; vaddr != end; vaddr += PAGE_SIZE)
++ prepare_pagetables(pgd_base, vaddr);
++}
++
++void setup_identity_mappings(pgd_t *pgd_base, unsigned long start, unsigned long end)
++{
++ unsigned long vaddr;
++ pgd_t *pgd;
++ int i, j, k;
++ pmd_t *pmd;
++ pte_t *pte, *pte_base;
++
++ pgd = pgd_base;
++
++ for (i = 0; i < PTRS_PER_PGD; pgd++, i++) {
++ vaddr = i*PGDIR_SIZE;
++ if (end && (vaddr >= end))
++ break;
++ pmd = pmd_offset(pgd, 0);
++ for (j = 0; j < PTRS_PER_PMD; pmd++, j++) {
++ vaddr = i*PGDIR_SIZE + j*PMD_SIZE;
++ if (end && (vaddr >= end))
++ break;
++ if (vaddr < start)
++ continue;
++ if (cpu_has_pse) {
++ unsigned long __pe;
++
++ set_in_cr4(X86_CR4_PSE);
++ boot_cpu_data.wp_works_ok = 1;
++ __pe = _KERNPG_TABLE + _PAGE_PSE + vaddr - start;
++ /* Make it "global" too if supported */
++ if (cpu_has_pge) {
++ set_in_cr4(X86_CR4_PGE);
++#if !defined(CONFIG_X86_SWITCH_PAGETABLES)
++ __pe += _PAGE_GLOBAL;
++ __PAGE_KERNEL |= _PAGE_GLOBAL;
++#endif
++ }
++ set_pmd(pmd, __pmd(__pe));
++ continue;
++ }
++ if (!pmd_present(*pmd))
++ pte_base = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
++ else
++ pte_base = (pte_t *) page_address(pmd_page(*pmd));
++ pte = pte_base;
++ for (k = 0; k < PTRS_PER_PTE; pte++, k++) {
++ vaddr = i*PGDIR_SIZE + j*PMD_SIZE + k*PAGE_SIZE;
++ if (end && (vaddr >= end))
++ break;
++ if (vaddr < start)
++ continue;
++ *pte = mk_pte_phys(vaddr-start, PAGE_KERNEL);
++ }
++ set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte_base)));
++ }
++ }
++}
++
++static void __init pagetable_init (void)
++{
++ unsigned long vaddr, end;
++ pgd_t *pgd_base;
+ #ifdef CONFIG_X86_PAE
+ int i;
+- /* Init entries of the first-level page table to the zero page */
+- for (i = 0; i < PTRS_PER_PGD; i++)
+- set_pgd(pgd_base + i, __pgd(__pa(empty_zero_page) | _PAGE_PRESENT));
+ #endif
+
+- /* Enable PSE if available */
+- if (cpu_has_pse) {
+- set_in_cr4(X86_CR4_PSE);
+- }
++ /*
++ * This can be zero as well - no problem, in that case we exit
++ * the loops anyway due to the PTRS_PER_* conditions.
++ */
++ end = (unsigned long)__va(max_low_pfn*PAGE_SIZE);
+
+- /* Enable PGE if available */
+- if (cpu_has_pge) {
+- set_in_cr4(X86_CR4_PGE);
+- __PAGE_KERNEL |= _PAGE_GLOBAL;
++ pgd_base = swapper_pg_dir;
++#ifdef CONFIG_X86_PAE
++ /*
++ * It causes too many problems if there's no proper pmd set up
++ * for all 4 entries of the PGD - so we allocate all of them.
++ * PAE systems will not miss this extra 4-8K anyway ...
++ */
++ for (i = 0; i < PTRS_PER_PGD; i++) {
++ pmd_t *pmd = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
++ set_pgd(pgd_base + i, __pgd(__pa(pmd) + 0x1));
+ }
++#endif
++ /*
++ * Set up lowmem-sized identity mappings at PAGE_OFFSET:
++ */
++ setup_identity_mappings(pgd_base, PAGE_OFFSET, end);
+
+- kernel_physical_mapping_init(pgd_base);
++ /*
++ * Add flat-mode identity-mappings - SMP needs it when
++ * starting up on an AP from real-mode. (In the non-PAE
++ * case we already have these mappings through head.S.)
++ * All user-space mappings are explicitly cleared after
++ * SMP startup.
++ */
++#if CONFIG_SMP && CONFIG_X86_PAE
++ setup_identity_mappings(pgd_base, 0, 16*1024*1024);
++#endif
+ remap_numa_kva();
+
+ /*
+@@ -289,38 +247,64 @@
+ * created - mappings will be set by set_fixmap():
+ */
+ vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
+- page_table_range_init(vaddr, 0, pgd_base);
++ fixrange_init(vaddr, 0, pgd_base);
+
+- permanent_kmaps_init(pgd_base);
++#if CONFIG_HIGHMEM
++ {
++ pgd_t *pgd;
++ pmd_t *pmd;
++ pte_t *pte;
+
+-#ifdef CONFIG_X86_PAE
+- /*
+- * Add low memory identity-mappings - SMP needs it when
+- * starting up on an AP from real-mode. In the non-PAE
+- * case we already have these mappings through head.S.
+- * All user-space mappings are explicitly cleared after
+- * SMP startup.
+- */
+- pgd_base[0] = pgd_base[USER_PTRS_PER_PGD];
++ /*
++ * Permanent kmaps:
++ */
++ vaddr = PKMAP_BASE;
++ fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
++
++ pgd = swapper_pg_dir + pgd_index(vaddr);
++ pmd = pmd_offset(pgd, vaddr);
++ pte = pte_offset_kernel(pmd, vaddr);
++ pkmap_page_table = pte;
++ }
+ #endif
+ }
+
+-void zap_low_mappings (void)
++/*
++ * Clear kernel pagetables in a PMD_SIZE-aligned range.
++ */
++static void clear_mappings(pgd_t *pgd_base, unsigned long start, unsigned long end)
+ {
+- int i;
++ unsigned long vaddr;
++ pgd_t *pgd;
++ pmd_t *pmd;
++ int i, j;
++
++ pgd = pgd_base;
++
++ for (i = 0; i < PTRS_PER_PGD; pgd++, i++) {
++ vaddr = i*PGDIR_SIZE;
++ if (end && (vaddr >= end))
++ break;
++ pmd = pmd_offset(pgd, 0);
++ for (j = 0; j < PTRS_PER_PMD; pmd++, j++) {
++ vaddr = i*PGDIR_SIZE + j*PMD_SIZE;
++ if (end && (vaddr >= end))
++ break;
++ if (vaddr < start)
++ continue;
++ pmd_clear(pmd);
++ }
++ }
++ flush_tlb_all();
++}
++
++void __init zap_low_mappings(void)
++{
++ printk("zapping low mappings.\n");
+ /*
+ * Zap initial low-memory mappings.
+- *
+- * Note that "pgd_clear()" doesn't do it for
+- * us, because pgd_clear() is a no-op on i386.
+ */
+- for (i = 0; i < USER_PTRS_PER_PGD; i++)
+-#ifdef CONFIG_X86_PAE
+- set_pgd(swapper_pg_dir+i, __pgd(1 + __pa(empty_zero_page)));
+-#else
+- set_pgd(swapper_pg_dir+i, __pgd(0));
+-#endif
+- flush_tlb_all();
++ clear_mappings(swapper_pg_dir, 0, 16*1024*1024);
+ }
+
+ #ifndef CONFIG_DISCONTIGMEM
+@@ -424,6 +408,7 @@
+ #endif /* !CONFIG_DISCONTIGMEM */
+
+ static struct kcore_list kcore_mem, kcore_vmalloc;
++extern void fixup_sort_exception_table(void);
+
+ void __init mem_init(void)
+ {
+@@ -432,6 +417,8 @@
+ int tmp;
+ int bad_ppro;
+
++ fixup_sort_exception_table();
++
+ #ifndef CONFIG_DISCONTIGMEM
+ if (!mem_map)
+ BUG();
+@@ -507,13 +494,18 @@
+ #ifndef CONFIG_SMP
+ zap_low_mappings();
+ #endif
++ entry_trampoline_setup();
++ default_ldt_page = virt_to_page(default_ldt);
++ load_LDT(&init_mm.context);
+ }
+
+-kmem_cache_t *pgd_cache;
+-kmem_cache_t *pmd_cache;
++kmem_cache_t *pgd_cache, *pmd_cache, *kpmd_cache;
+
+ void __init pgtable_cache_init(void)
+ {
++ void (*ctor)(void *, kmem_cache_t *, unsigned long);
++ void (*dtor)(void *, kmem_cache_t *, unsigned long);
++
+ if (PTRS_PER_PMD > 1) {
+ pmd_cache = kmem_cache_create("pmd",
+ PTRS_PER_PMD*sizeof(pmd_t),
+@@ -523,13 +515,36 @@
+ NULL);
+ if (!pmd_cache)
+ panic("pgtable_cache_init(): cannot create pmd cache");
++
++ if (TASK_SIZE > PAGE_OFFSET) {
++ kpmd_cache = kmem_cache_create("kpmd",
++ PTRS_PER_PMD*sizeof(pmd_t),
++ 0,
++ SLAB_HWCACHE_ALIGN | SLAB_MUST_HWCACHE_ALIGN,
++ kpmd_ctor,
++ NULL);
++ if (!kpmd_cache)
++ panic("pgtable_cache_init(): "
++ "cannot create kpmd cache");
++ }
+ }
++
++ if (PTRS_PER_PMD == 1 || TASK_SIZE <= PAGE_OFFSET)
++ ctor = pgd_ctor;
++ else
++ ctor = NULL;
++
++ if (PTRS_PER_PMD == 1 && TASK_SIZE <= PAGE_OFFSET)
++ dtor = pgd_dtor;
++ else
++ dtor = NULL;
++
+ pgd_cache = kmem_cache_create("pgd",
+ PTRS_PER_PGD*sizeof(pgd_t),
+ 0,
+ SLAB_HWCACHE_ALIGN | SLAB_MUST_HWCACHE_ALIGN,
+- pgd_ctor,
+- PTRS_PER_PMD == 1 ? pgd_dtor : NULL);
++ ctor,
++ dtor);
+ if (!pgd_cache)
+ panic("pgtable_cache_init(): Cannot create pgd cache");
+ }
+Index: linux-2.6.0-test5/arch/i386/mm/ioremap.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/mm/ioremap.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/mm/ioremap.c 2003-09-27 11:38:19.213607472 +0800
+@@ -158,7 +158,7 @@
+ return NULL;
+ area->phys_addr = phys_addr;
+ addr = area->addr;
+- if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) {
++ if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
+ vunmap(addr);
+ return NULL;
+ }
+Index: linux-2.6.0-test5/arch/i386/mm/pgtable.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/mm/pgtable.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/mm/pgtable.c 2003-09-27 11:38:19.218606712 +0800
+@@ -21,6 +21,7 @@
+ #include <asm/e820.h>
+ #include <asm/tlb.h>
+ #include <asm/tlbflush.h>
++#include <asm/atomic_kmap.h>
+
+ void show_mem(void)
+ {
+@@ -157,11 +158,20 @@
+ memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t));
+ }
+
++void kpmd_ctor(void *__pmd, kmem_cache_t *cache, unsigned long flags)
++{
++ pmd_t *kpmd, *pmd;
++ kpmd = pmd_offset(&swapper_pg_dir[PTRS_PER_PGD-1],
++ (PTRS_PER_PMD - NR_SHARED_PMDS)*PMD_SIZE);
++ pmd = (pmd_t *)__pmd + (PTRS_PER_PMD - NR_SHARED_PMDS);
++
++ memset(__pmd, 0, (PTRS_PER_PMD - NR_SHARED_PMDS)*sizeof(pmd_t));
++ memcpy(pmd, kpmd, NR_SHARED_PMDS*sizeof(pmd_t));
++}
++
+ /*
+- * List of all pgd's needed for non-PAE so it can invalidate entries
+- * in both cached and uncached pgd's; not needed for PAE since the
+- * kernel pmd is shared. If PAE were not to share the pmd a similar
+- * tactic would be needed. This is essentially codepath-based locking
++ * List of all pgd's needed so it can invalidate entries in both cached
++ * and uncached pgd's. This is essentially codepath-based locking
+ * against pageattr.c; it is the unique case in which a valid change
+ * of kernel pagetables can't be lazily synchronized by vmalloc faults.
+ * vmalloc faults work because attached pagetables are never freed.
+@@ -170,30 +180,60 @@
+ * could be used. The locking scheme was chosen on the basis of
+ * manfred's recommendations and having no core impact whatsoever.
+ * -- wli
++ *
++ * The entire issue goes away when XKVA is configured.
+ */
+ spinlock_t pgd_lock = SPIN_LOCK_UNLOCKED;
+ LIST_HEAD(pgd_list);
+
+-void pgd_ctor(void *pgd, kmem_cache_t *cache, unsigned long unused)
++/*
++ * This is not that hard to figure out.
++ * (a) PTRS_PER_PMD == 1 means non-PAE.
++ * (b) PTRS_PER_PMD > 1 means PAE.
++ * (c) TASK_SIZE > PAGE_OFFSET means XKVA.
++ * (d) TASK_SIZE <= PAGE_OFFSET means non-XKVA.
++ *
++ * Do *NOT* back out the preconstruction like the patch I'm cleaning
++ * up after this very instant did, or at all, for that matter.
++ * This is never called when PTRS_PER_PMD > 1 && TASK_SIZE > PAGE_OFFSET.
++ * -- wli
++ */
++void pgd_ctor(void *__pgd, kmem_cache_t *cache, unsigned long unused)
+ {
++ pgd_t *pgd = (pgd_t *)__pgd;
+ unsigned long flags;
+
+- if (PTRS_PER_PMD == 1)
+- spin_lock_irqsave(&pgd_lock, flags);
++ if (PTRS_PER_PMD == 1) {
++ if (TASK_SIZE <= PAGE_OFFSET)
++ spin_lock_irqsave(&pgd_lock, flags);
++ else
++ memcpy(&pgd[PTRS_PER_PGD - NR_SHARED_PMDS],
++ &swapper_pg_dir[PTRS_PER_PGD - NR_SHARED_PMDS],
++ NR_SHARED_PMDS * sizeof(pgd_t));
++ }
+
+- memcpy((pgd_t *)pgd + USER_PTRS_PER_PGD,
+- swapper_pg_dir + USER_PTRS_PER_PGD,
+- (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
++ if (TASK_SIZE <= PAGE_OFFSET)
++ memcpy(pgd + USER_PTRS_PER_PGD,
++ swapper_pg_dir + USER_PTRS_PER_PGD,
++ (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
+
+ if (PTRS_PER_PMD > 1)
+ return;
+
+- list_add(&virt_to_page(pgd)->lru, &pgd_list);
+- spin_unlock_irqrestore(&pgd_lock, flags);
+- memset(pgd, 0, USER_PTRS_PER_PGD*sizeof(pgd_t));
++ if (TASK_SIZE > PAGE_OFFSET)
++ memset(pgd, 0, (PTRS_PER_PGD - NR_SHARED_PMDS)*sizeof(pgd_t));
++ else {
++ list_add(&virt_to_page(pgd)->lru, &pgd_list);
++ spin_unlock_irqrestore(&pgd_lock, flags);
++ memset(pgd, 0, USER_PTRS_PER_PGD*sizeof(pgd_t));
++ }
+ }
+
+-/* never called when PTRS_PER_PMD > 1 */
++/*
++ * Never called when PTRS_PER_PMD > 1 || TASK_SIZE > PAGE_OFFSET
++ * for with PAE we would list_del() multiple times, and for non-PAE
++ * with XKVA all the AGP pgd shootdown code is unnecessary.
++ */
+ void pgd_dtor(void *pgd, kmem_cache_t *cache, unsigned long unused)
+ {
+ unsigned long flags; /* can be called from interrupt context */
+@@ -203,6 +243,12 @@
+ spin_unlock_irqrestore(&pgd_lock, flags);
+ }
+
++/*
++ * See the comments above pgd_ctor() wrt. preconstruction.
++ * Do *NOT* memcpy() here. If you do, you back out important
++ * anti- cache pollution code.
++ *
++ */
+ pgd_t *pgd_alloc(struct mm_struct *mm)
+ {
+ int i;
+@@ -211,15 +257,33 @@
+ if (PTRS_PER_PMD == 1 || !pgd)
+ return pgd;
+
++ /*
++ * In the 4G userspace case alias the top 16 MB virtual
++ * memory range into the user mappings as well (these
++ * include the trampoline and CPU data structures).
++ */
+ for (i = 0; i < USER_PTRS_PER_PGD; ++i) {
+- pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL);
++ kmem_cache_t *cache;
++ pmd_t *pmd;
++
++ if (TASK_SIZE > PAGE_OFFSET && i == USER_PTRS_PER_PGD - 1)
++ cache = kpmd_cache;
++ else
++ cache = pmd_cache;
++
++ pmd = kmem_cache_alloc(cache, GFP_KERNEL);
+ if (!pmd)
+ goto out_oom;
+ set_pgd(&pgd[i], __pgd(1 + __pa((u64)((u32)pmd))));
+ }
+- return pgd;
+
++ return pgd;
+ out_oom:
++ /*
++ * we don't have to handle the kpmd_cache here, since it's the
++ * last allocation, and has either nothing to free or when it
++ * succeeds the whole operation succeeds.
++ */
+ for (i--; i >= 0; i--)
+ kmem_cache_free(pmd_cache, (void *)__va(pgd_val(pgd[i])-1));
+ kmem_cache_free(pgd_cache, pgd);
+@@ -230,10 +294,29 @@
+ {
+ int i;
+
+- /* in the PAE case user pgd entries are overwritten before usage */
+- if (PTRS_PER_PMD > 1)
+- for (i = 0; i < USER_PTRS_PER_PGD; ++i)
+- kmem_cache_free(pmd_cache, (void *)__va(pgd_val(pgd[i])-1));
+ /* in the non-PAE case, clear_page_tables() clears user pgd entries */
++ if (PTRS_PER_PMD == 1)
++ goto out_free;
++
++ /* in the PAE case user pgd entries are overwritten before usage */
++ for (i = 0; i < USER_PTRS_PER_PGD; ++i) {
++ kmem_cache_t *cache;
++ pmd_t *pmd = __va(pgd_val(pgd[i]) - 1);
++
++ /*
++ * only userspace pmd's are cleared for us
++ * by mm/memory.c; it's a slab cache invariant
++ * that we must separate the kernel pmd slab
++ * all times, else we'll have bad pmd's.
++ */
++ if (TASK_SIZE > PAGE_OFFSET && i == USER_PTRS_PER_PGD - 1)
++ cache = kpmd_cache;
++ else
++ cache = pmd_cache;
++
++ kmem_cache_free(cache, pmd);
++ }
++out_free:
+ kmem_cache_free(pgd_cache, pgd);
+ }
++
+Index: linux-2.6.0-test5/arch/i386/pci/acpi.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/pci/acpi.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/pci/acpi.c 2003-09-27 11:38:19.219606560 +0800
+@@ -15,10 +15,11 @@
+
+ static int __init pci_acpi_init(void)
+ {
++ extern int acpi_disabled;
+ if (pcibios_scanned)
+ return 0;
+
+- if (!(pci_probe & PCI_NO_ACPI_ROUTING)) {
++ if (!(pci_probe & PCI_NO_ACPI_ROUTING) && !acpi_disabled) {
+ if (!acpi_pci_irq_init()) {
+ printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n");
+ printk(KERN_INFO "PCI: if you experience problems, try using option 'pci=noacpi' or even 'acpi=off'\n");
+Index: linux-2.6.0-test5/arch/i386/power/cpu.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/power/cpu.c 2003-09-27 11:38:18.435725728 +0800
++++ linux-2.6.0-test5/arch/i386/power/cpu.c 2003-09-27 11:38:19.220606408 +0800
+@@ -0,0 +1,141 @@
++/*
++ * Suspend support specific for i386.
++ *
++ * Distribute under GPLv2
++ *
++ * Copyright (c) 2002 Pavel Machek <pavel@suse.cz>
++ * Copyright (c) 2001 Patrick Mochel <mochel@osdl.org>
++ */
++
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/types.h>
++#include <linux/spinlock.h>
++#include <linux/poll.h>
++#include <linux/delay.h>
++#include <linux/sysrq.h>
++#include <linux/proc_fs.h>
++#include <linux/irq.h>
++#include <linux/pm.h>
++#include <linux/device.h>
++#include <linux/suspend.h>
++#include <linux/acpi.h>
++#include <asm/uaccess.h>
++#include <asm/acpi.h>
++#include <asm/tlbflush.h>
++
++static struct saved_context saved_context;
++static void fix_processor_context(void);
++
++unsigned long saved_context_eax, saved_context_ebx;
++unsigned long saved_context_ecx, saved_context_edx;
++unsigned long saved_context_esp, saved_context_ebp;
++unsigned long saved_context_esi, saved_context_edi;
++unsigned long saved_context_eflags;
++
++extern void enable_sep_cpu(void *);
++
++void save_processor_state(void)
++{
++ kernel_fpu_begin();
++
++ /*
++ * descriptor tables
++ */
++ asm volatile ("sgdt %0" : "=m" (saved_context.gdt_limit));
++ asm volatile ("sidt %0" : "=m" (saved_context.idt_limit));
++ asm volatile ("sldt %0" : "=m" (saved_context.ldt));
++ asm volatile ("str %0" : "=m" (saved_context.tr));
++
++ /*
++ * segment registers
++ */
++ asm volatile ("movw %%es, %0" : "=m" (saved_context.es));
++ asm volatile ("movw %%fs, %0" : "=m" (saved_context.fs));
++ asm volatile ("movw %%gs, %0" : "=m" (saved_context.gs));
++ asm volatile ("movw %%ss, %0" : "=m" (saved_context.ss));
++
++ /*
++ * control registers
++ */
++ asm volatile ("movl %%cr0, %0" : "=r" (saved_context.cr0));
++ asm volatile ("movl %%cr2, %0" : "=r" (saved_context.cr2));
++ asm volatile ("movl %%cr3, %0" : "=r" (saved_context.cr3));
++ asm volatile ("movl %%cr4, %0" : "=r" (saved_context.cr4));
++}
++
++static void
++do_fpu_end(void)
++{
++ /* restore FPU regs if necessary */
++ /* Do it out of line so that gcc does not move cr0 load to some stupid place */
++ kernel_fpu_end();
++}
++
++void restore_processor_state(void)
++{
++
++ /*
++ * control registers
++ */
++ asm volatile ("movl %0, %%cr4" :: "r" (saved_context.cr4));
++ asm volatile ("movl %0, %%cr3" :: "r" (saved_context.cr3));
++ asm volatile ("movl %0, %%cr2" :: "r" (saved_context.cr2));
++ asm volatile ("movl %0, %%cr0" :: "r" (saved_context.cr0));
++
++ /*
++ * segment registers
++ */
++ asm volatile ("movw %0, %%es" :: "r" (saved_context.es));
++ asm volatile ("movw %0, %%fs" :: "r" (saved_context.fs));
++ asm volatile ("movw %0, %%gs" :: "r" (saved_context.gs));
++ asm volatile ("movw %0, %%ss" :: "r" (saved_context.ss));
++
++ /*
++ * now restore the descriptor tables to their proper values
++ * ltr is done i fix_processor_context().
++ */
++ asm volatile ("lgdt %0" :: "m" (saved_context.gdt_limit));
++ asm volatile ("lidt %0" :: "m" (saved_context.idt_limit));
++ asm volatile ("lldt %0" :: "m" (saved_context.ldt));
++
++ /*
++ * sysenter MSRs
++ */
++ if (boot_cpu_has(X86_FEATURE_SEP))
++ enable_sep_cpu(NULL);
++
++ fix_processor_context();
++ do_fpu_end();
++}
++
++static void fix_processor_context(void)
++{
++ int cpu = smp_processor_id();
++ struct tss_struct * t = init_tss + cpu;
++
++ set_tss_desc(cpu,t); /* This just modifies memory; should not be necessary. But... This is necessary, because 386 hardware has concept of busy TSS or some similar stupidity. */
++ cpu_gdt_table[cpu][GDT_ENTRY_TSS].b &= 0xfffffdff;
++
++ load_TR_desc(); /* This does ltr */
++ load_LDT(¤t->active_mm->context); /* This does lldt */
++
++ /*
++ * Now maybe reload the debug registers
++ */
++ if (current->thread.debugreg[7]){
++ loaddebug(¤t->thread, 0);
++ loaddebug(¤t->thread, 1);
++ loaddebug(¤t->thread, 2);
++ loaddebug(¤t->thread, 3);
++ /* no 4 and 5 */
++ loaddebug(¤t->thread, 6);
++ loaddebug(¤t->thread, 7);
++ }
++
++}
++
++EXPORT_SYMBOL(save_processor_state);
++EXPORT_SYMBOL(restore_processor_state);
+Index: linux-2.6.0-test5/arch/i386/power/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/power/Makefile 2003-09-27 11:38:18.435725728 +0800
++++ linux-2.6.0-test5/arch/i386/power/Makefile 2003-09-27 11:38:19.220606408 +0800
+@@ -0,0 +1,3 @@
++obj-$(CONFIG_PM) += cpu.o
++obj-$(CONFIG_PM_DISK) += pmdisk.o
++obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o
+Index: linux-2.6.0-test5/arch/i386/power/pmdisk.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/power/pmdisk.S 2003-09-27 11:38:18.435725728 +0800
++++ linux-2.6.0-test5/arch/i386/power/pmdisk.S 2003-09-27 11:38:19.221606256 +0800
+@@ -0,0 +1,94 @@
++.text
++
++/* Originally gcc generated, modified by hand */
++
++#include <linux/linkage.h>
++#include <asm/segment.h>
++#include <asm/page.h>
++
++ .text
++
++ENTRY(pmdisk_arch_suspend)
++ pushl %ebx
++ cmpl $0,8(%esp)
++ jne .L1450
++ call save_processor_state
++
++ movl %esp, saved_context_esp
++ movl %eax, saved_context_eax
++ movl %ebx, saved_context_ebx
++ movl %ecx, saved_context_ecx
++ movl %edx, saved_context_edx
++ movl %ebp, saved_context_ebp
++ movl %esi, saved_context_esi
++ movl %edi, saved_context_edi
++ pushfl ; popl saved_context_eflags
++
++ call pmdisk_suspend
++ jmp .L1449
++ .p2align 4,,7
++.L1450:
++ movl $swapper_pg_dir-__PAGE_OFFSET,%ecx
++ movl %ecx,%cr3
++
++ movl $0,loop
++ cmpl $0,pmdisk_pages
++ je .L1453
++ .p2align 4,,7
++.L1455:
++ movl $0,loop2
++ .p2align 4,,7
++.L1459:
++ movl pm_pagedir_nosave,%ecx
++ movl loop,%eax
++ movl loop2,%edx
++ sall $4,%eax
++ movl 4(%ecx,%eax),%ebx
++ movl (%ecx,%eax),%eax
++ movb (%edx,%eax),%al
++ movb %al,(%edx,%ebx)
++ movl %cr3, %eax;
++ movl %eax, %cr3; # flush TLB
++
++ movl loop2,%eax
++ leal 1(%eax),%edx
++ movl %edx,loop2
++ movl %edx,%eax
++ cmpl $4095,%eax
++ jbe .L1459
++ movl loop,%eax
++ leal 1(%eax),%edx
++ movl %edx,loop
++ movl %edx,%eax
++ cmpl pmdisk_pages,%eax
++ jb .L1455
++ .p2align 4,,7
++.L1453:
++ movl $__USER_DS,%eax
++
++ movw %ax, %ds
++ movw %ax, %es
++ movl saved_context_esp, %esp
++ movl saved_context_ebp, %ebp
++ movl saved_context_eax, %eax
++ movl saved_context_ebx, %ebx
++ movl saved_context_ecx, %ecx
++ movl saved_context_edx, %edx
++ movl saved_context_esi, %esi
++ movl saved_context_edi, %edi
++ pushl saved_context_eflags ; popfl
++ call pmdisk_resume
++.L1449:
++ popl %ebx
++ pushl %eax
++ call restore_processor_state
++ popl %eax
++ ret
++
++ .section .data.nosave
++loop:
++ .quad 0
++loop2:
++ .quad 0
++ .previous
++
+Index: linux-2.6.0-test5/arch/i386/power/swsusp.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/power/swsusp.S 2003-09-27 11:38:18.435725728 +0800
++++ linux-2.6.0-test5/arch/i386/power/swsusp.S 2003-09-27 11:38:19.221606256 +0800
+@@ -0,0 +1,94 @@
++.text
++
++/* Originally gcc generated, modified by hand */
++
++#include <linux/linkage.h>
++#include <asm/segment.h>
++#include <asm/page.h>
++
++ .text
++
++ENTRY(do_magic)
++ pushl %ebx
++ cmpl $0,8(%esp)
++ jne .L1450
++ call do_magic_suspend_1
++ call save_processor_state
++
++ movl %esp, saved_context_esp
++ movl %eax, saved_context_eax
++ movl %ebx, saved_context_ebx
++ movl %ecx, saved_context_ecx
++ movl %edx, saved_context_edx
++ movl %ebp, saved_context_ebp
++ movl %esi, saved_context_esi
++ movl %edi, saved_context_edi
++ pushfl ; popl saved_context_eflags
++
++ call do_magic_suspend_2
++ jmp .L1449
++ .p2align 4,,7
++.L1450:
++ movl $swapper_pg_dir-__PAGE_OFFSET,%ecx
++ movl %ecx,%cr3
++
++ call do_magic_resume_1
++ movl $0,loop
++ cmpl $0,nr_copy_pages
++ je .L1453
++ .p2align 4,,7
++.L1455:
++ movl $0,loop2
++ .p2align 4,,7
++.L1459:
++ movl pagedir_nosave,%ecx
++ movl loop,%eax
++ movl loop2,%edx
++ sall $4,%eax
++ movl 4(%ecx,%eax),%ebx
++ movl (%ecx,%eax),%eax
++ movb (%edx,%eax),%al
++ movb %al,(%edx,%ebx)
++ movl %cr3, %eax;
++ movl %eax, %cr3; # flush TLB
++
++ movl loop2,%eax
++ leal 1(%eax),%edx
++ movl %edx,loop2
++ movl %edx,%eax
++ cmpl $4095,%eax
++ jbe .L1459
++ movl loop,%eax
++ leal 1(%eax),%edx
++ movl %edx,loop
++ movl %edx,%eax
++ cmpl nr_copy_pages,%eax
++ jb .L1455
++ .p2align 4,,7
++.L1453:
++ movl $__USER_DS,%eax
++
++ movw %ax, %ds
++ movw %ax, %es
++ movl saved_context_esp, %esp
++ movl saved_context_ebp, %ebp
++ movl saved_context_eax, %eax
++ movl saved_context_ebx, %ebx
++ movl saved_context_ecx, %ecx
++ movl saved_context_edx, %edx
++ movl saved_context_esi, %esi
++ movl saved_context_edi, %edi
++ call restore_processor_state
++ pushl saved_context_eflags ; popfl
++ call do_magic_resume_2
++.L1449:
++ popl %ebx
++ ret
++
++ .section .data.nosave
++loop:
++ .quad 0
++loop2:
++ .quad 0
++ .previous
++
+\ No newline at end of file
+Index: linux-2.6.0-test5/arch/ia64/hp/common/sba_iommu.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/hp/common/sba_iommu.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/hp/common/sba_iommu.c 2003-09-27 11:38:19.242603064 +0800
+@@ -54,6 +54,11 @@
+ */
+ #define ALLOW_IOV_BYPASS
+
++#ifdef CONFIG_PROC_FS
++ /* turn it off for now; without per-CPU counters, it's too much of a scalability bottleneck: */
++# define SBA_PROC_FS 0
++#endif
++
+ /*
+ ** If a device prefetches beyond the end of a valid pdir entry, it will cause
+ ** a hard failure, ie. MCA. Version 3.0 and later of the zx1 LBA should
+@@ -193,7 +198,7 @@
+ } saved[DELAYED_RESOURCE_CNT];
+ #endif
+
+-#ifdef CONFIG_PROC_FS
++#if SBA_PROC_FS
+ #define SBA_SEARCH_SAMPLE 0x100
+ unsigned long avg_search[SBA_SEARCH_SAMPLE];
+ unsigned long avg_idx; /* current index into avg_search */
+@@ -227,12 +232,7 @@
+ static struct ioc *ioc_list;
+ static int reserve_sba_gart = 1;
+
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ #define sba_sg_address(sg) (page_address((sg)->page) + (sg)->offset)
+-#else
+-#define sba_sg_address(sg) ((sg)->address ? (sg)->address : \
+- page_address((sg)->page) + (sg)->offset)
+-#endif
+
+ #ifdef FULL_VALID_PDIR
+ static u64 prefetch_spill_page;
+@@ -522,7 +522,7 @@
+ sba_alloc_range(struct ioc *ioc, size_t size)
+ {
+ unsigned int pages_needed = size >> IOVP_SHIFT;
+-#ifdef CONFIG_PROC_FS
++#if SBA_PROC_FS
+ unsigned long itc_start = ia64_get_itc();
+ #endif
+ unsigned long pide;
+@@ -556,7 +556,7 @@
+ (uint) ((unsigned long) ioc->res_hint - (unsigned long) ioc->res_map),
+ ioc->res_bitshift );
+
+-#ifdef CONFIG_PROC_FS
++#if SBA_PROC_FS
+ {
+ unsigned long itc_end = ia64_get_itc();
+ unsigned long tmp = itc_end - itc_start;
+@@ -598,7 +598,7 @@
+ __FUNCTION__, (uint) iova, size,
+ bits_not_wanted, m, pide, res_ptr, *res_ptr);
+
+-#ifdef CONFIG_PROC_FS
++#if SBA_PROC_FS
+ ioc->used_pages -= bits_not_wanted;
+ #endif
+
+@@ -790,7 +790,7 @@
+ ** Device is bit capable of DMA'ing to the buffer...
+ ** just return the PCI address of ptr
+ */
+-#ifdef CONFIG_PROC_FS
++#if SBA_PROC_FS
+ spin_lock_irqsave(&ioc->res_lock, flags);
+ ioc->msingle_bypass++;
+ spin_unlock_irqrestore(&ioc->res_lock, flags);
+@@ -816,7 +816,7 @@
+ panic("Sanity check failed");
+ #endif
+
+-#ifdef CONFIG_PROC_FS
++#if SBA_PROC_FS
+ ioc->msingle_calls++;
+ ioc->msingle_pages += size >> IOVP_SHIFT;
+ #endif
+@@ -875,7 +875,7 @@
+ /*
+ ** Address does not fall w/in IOVA, must be bypassing
+ */
+-#ifdef CONFIG_PROC_FS
++#if SBA_PROC_FS
+ spin_lock_irqsave(&ioc->res_lock, flags);
+ ioc->usingle_bypass++;
+ spin_unlock_irqrestore(&ioc->res_lock, flags);
+@@ -900,7 +900,7 @@
+ size = ROUNDUP(size, IOVP_SIZE);
+
+ spin_lock_irqsave(&ioc->res_lock, flags);
+-#ifdef CONFIG_PROC_FS
++#if SBA_PROC_FS
+ ioc->usingle_calls++;
+ ioc->usingle_pages += size >> IOVP_SHIFT;
+ #endif
+@@ -962,20 +962,20 @@
+
+
+ /**
+- * sba_alloc_consistent - allocate/map shared mem for DMA
+- * @hwdev: instance of PCI owned by the driver that's asking.
++ * sba_alloc_coherent - allocate/map shared mem for DMA
++ * @dev: instance of PCI owned by the driver that's asking.
+ * @size: number of bytes mapped in driver buffer.
+ * @dma_handle: IOVA of new buffer.
+ *
+ * See Documentation/DMA-mapping.txt
+ */
+ void *
+-sba_alloc_coherent (struct device *hwdev, size_t size, dma_addr_t *dma_handle, int flags)
++sba_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, int flags)
+ {
+ struct ioc *ioc;
+ void *addr;
+
+- addr = (void *) __get_free_pages(flags, get_order(size));
++ addr = (void *) __get_free_pages(flags, get_order(size));
+ if (!addr)
+ return NULL;
+
+@@ -983,7 +983,7 @@
+ * REVISIT: if sba_map_single starts needing more than dma_mask from the
+ * device, this needs to be updated.
+ */
+- ioc = GET_IOC(hwdev);
++ ioc = GET_IOC(dev);
+ ASSERT(ioc);
+ *dma_handle = sba_map_single(&ioc->sac_only_dev->dev, addr, size, 0);
+
+@@ -993,17 +993,17 @@
+
+
+ /**
+- * sba_free_consistent - free/unmap shared mem for DMA
+- * @hwdev: instance of PCI owned by the driver that's asking.
++ * sba_free_coherent - free/unmap shared mem for DMA
++ * @dev: instance of PCI owned by the driver that's asking.
+ * @size: number of bytes mapped in driver buffer.
+ * @vaddr: virtual address IOVA of "consistent" buffer.
+ * @dma_handler: IO virtual address of "consistent" buffer.
+ *
+ * See Documentation/DMA-mapping.txt
+ */
+-void sba_free_coherent (struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
++void sba_free_coherent (struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle)
+ {
+- sba_unmap_single(hwdev, dma_handle, size, 0);
++ sba_unmap_single(dev, dma_handle, size, 0);
+ free_pages((unsigned long) vaddr, get_order(size));
+ }
+
+@@ -1083,7 +1083,7 @@
+ cnt += dma_offset;
+ dma_offset=0; /* only want offset on first chunk */
+ cnt = ROUNDUP(cnt, IOVP_SIZE);
+-#ifdef CONFIG_PROC_FS
++#if SBA_PROC_FS
+ ioc->msg_pages += cnt >> IOVP_SHIFT;
+ #endif
+ do {
+@@ -1273,7 +1273,7 @@
+ sg->dma_length = sg->length;
+ sg->dma_address = virt_to_phys(sba_sg_address(sg));
+ }
+-#ifdef CONFIG_PROC_FS
++#if SBA_PROC_FS
+ spin_lock_irqsave(&ioc->res_lock, flags);
+ ioc->msg_bypass++;
+ spin_unlock_irqrestore(&ioc->res_lock, flags);
+@@ -1286,7 +1286,7 @@
+ sglist->dma_length = sglist->length;
+ sglist->dma_address = sba_map_single(dev, sba_sg_address(sglist), sglist->length,
+ dir);
+-#ifdef CONFIG_PROC_FS
++#if SBA_PROC_FS
+ /*
+ ** Should probably do some stats counting, but trying to
+ ** be precise quickly starts wasting CPU time.
+@@ -1305,7 +1305,7 @@
+ }
+ #endif
+
+-#ifdef CONFIG_PROC_FS
++#if SBA_PROC_FS
+ ioc->msg_calls++;
+ #endif
+
+@@ -1368,7 +1368,7 @@
+ ioc = GET_IOC(dev);
+ ASSERT(ioc);
+
+-#ifdef CONFIG_PROC_FS
++#if SBA_PROC_FS
+ ioc->usg_calls++;
+ #endif
+
+@@ -1381,7 +1381,7 @@
+ while (nents && sglist->dma_length) {
+
+ sba_unmap_single(dev, sglist->dma_address, sglist->dma_length, dir);
+-#ifdef CONFIG_PROC_FS
++#if SBA_PROC_FS
+ /*
+ ** This leaves inconsistent data in the stats, but we can't
+ ** tell which sg lists were mapped by map_single and which
+@@ -1709,7 +1709,7 @@
+ **
+ **************************************************************************/
+
+-#ifdef CONFIG_PROC_FS
++#if SBA_PROC_FS
+ static void *
+ ioc_start(struct seq_file *s, loff_t *pos)
+ {
+@@ -1763,7 +1763,7 @@
+ if (ioc->avg_search[i] > max) max = ioc->avg_search[i];
+ if (ioc->avg_search[i] < min) min = ioc->avg_search[i];
+ }
+- avg /= SBA_SEARCH_SAMPLE;
++ avg /= SBA_SEARCH_SAMPLE;
+ seq_printf(s, " Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n", min, avg, max);
+
+ seq_printf(s, "pci_map_single(): %12ld calls %12ld pages (avg %d/1000)\n",
+@@ -1864,7 +1864,7 @@
+ }
+ #endif
+
+-void
++static void
+ sba_connect_bus(struct pci_bus *bus)
+ {
+ acpi_handle handle, parent;
+@@ -1872,7 +1872,7 @@
+ struct ioc *ioc;
+
+ if (!PCI_CONTROLLER(bus))
+- panic(PFX "no sysdata on bus %d!\n",bus->number);
++ panic(PFX "no sysdata on bus %d!\n", bus->number);
+
+ if (PCI_CONTROLLER(bus)->iommu)
+ return;
+@@ -1955,7 +1955,7 @@
+ }
+ #endif
+
+-#ifdef CONFIG_PROC_FS
++#if SBA_PROC_FS
+ ioc_proc_init();
+ #endif
+ return 0;
+Index: linux-2.6.0-test5/arch/ia64/hp/sim/boot/boot_head.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/hp/sim/boot/boot_head.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/hp/sim/boot/boot_head.S 2003-09-27 11:38:19.244602760 +0800
+@@ -27,6 +27,14 @@
+ br.call.sptk.many rp=start_bootloader
+ END(_start)
+
++/*
++ * Set a break point on this function so that symbols are available to set breakpoints in
++ * the kernel being debugged.
++ */
++GLOBAL_ENTRY(debug_break)
++ br.ret.sptk.many b0
++END(debug_break)
++
+ GLOBAL_ENTRY(ssc)
+ .regstk 5,0,0,0
+ mov r15=in4
+Index: linux-2.6.0-test5/arch/ia64/hp/sim/boot/bootloader.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/hp/sim/boot/bootloader.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/hp/sim/boot/bootloader.c 2003-09-27 11:38:19.245602608 +0800
+@@ -37,15 +37,7 @@
+
+ extern void jmp_to_kernel (unsigned long bp, unsigned long e_entry);
+ extern struct ia64_boot_param *sys_fw_init (const char *args, int arglen);
+-
+-/*
+- * Set a break point on this function so that symbols are available to set breakpoints in
+- * the kernel being debugged.
+- */
+-static void
+-debug_break (void)
+-{
+-}
++extern void debug_break (void);
+
+ static void
+ cons_write (const char *buf)
+Index: linux-2.6.0-test5/arch/ia64/ia32/elfcore32.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/ia32/elfcore32.h 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/ia32/elfcore32.h 2003-09-27 11:38:19.247602304 +0800
+@@ -8,6 +8,8 @@
+ #ifndef _ELFCORE32_H_
+ #define _ELFCORE32_H_
+
++#include <asm/intrinsics.h>
++
+ #define USE_ELF_CORE_DUMP 1
+
+ /* Override elfcore.h */
+@@ -79,8 +81,7 @@
+ pr_reg[11] = regs->r1; \
+ pr_reg[12] = regs->cr_iip; \
+ pr_reg[13] = regs->r17 & 0xffff; \
+- asm volatile ("mov %0=ar.eflag ;;" \
+- : "=r"(pr_reg[14])); \
++ pr_reg[14] = ia64_getreg(_IA64_REG_AR_EFLAG); \
+ pr_reg[15] = regs->r12; \
+ pr_reg[16] = (regs->r17 >> 16) & 0xffff;
+
+Index: linux-2.6.0-test5/arch/ia64/ia32/ia32priv.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/ia32/ia32priv.h 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/ia32/ia32priv.h 2003-09-27 11:38:19.251601696 +0800
+@@ -168,15 +168,15 @@
+ };
+
+ struct stat64 {
+- unsigned short st_dev;
+- unsigned char __pad0[10];
++ unsigned long long st_dev;
++ unsigned char __pad0[4];
+ unsigned int __st_ino;
+ unsigned int st_mode;
+ unsigned int st_nlink;
+ unsigned int st_uid;
+ unsigned int st_gid;
+- unsigned short st_rdev;
+- unsigned char __pad3[10];
++ unsigned long long st_rdev;
++ unsigned char __pad3[4];
+ unsigned int st_size_lo;
+ unsigned int st_size_hi;
+ unsigned int st_blksize;
+Index: linux-2.6.0-test5/arch/ia64/ia32/sys_ia32.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/ia32/sys_ia32.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/ia32/sys_ia32.c 2003-09-27 11:38:19.289595920 +0800
+@@ -76,6 +76,7 @@
+
+ #define OFFSET4K(a) ((a) & 0xfff)
+ #define PAGE_START(addr) ((addr) & PAGE_MASK)
++#define MINSIGSTKSZ_IA32 2048
+
+ #define high2lowuid(uid) ((uid) > 65535 ? 65534 : (uid))
+ #define high2lowgid(gid) ((gid) > 65535 ? 65534 : (gid))
+@@ -179,19 +180,21 @@
+ {
+ int err;
+
+- if ((u64) stat->size > MAX_NON_LFS)
++ if ((u64) stat->size > MAX_NON_LFS ||
++ !old_valid_dev(stat->dev) ||
++ !old_valid_dev(stat->rdev))
+ return -EOVERFLOW;
+
+ if (clear_user(ubuf, sizeof(*ubuf)))
+ return -EFAULT;
+
+- err = __put_user(stat->dev, &ubuf->st_dev);
++ err = __put_user(old_encode_dev(stat->dev), &ubuf->st_dev);
+ err |= __put_user(stat->ino, &ubuf->st_ino);
+ err |= __put_user(stat->mode, &ubuf->st_mode);
+ err |= __put_user(stat->nlink, &ubuf->st_nlink);
+ err |= __put_user(high2lowuid(stat->uid), &ubuf->st_uid);
+ err |= __put_user(high2lowgid(stat->gid), &ubuf->st_gid);
+- err |= __put_user(stat->rdev, &ubuf->st_rdev);
++ err |= __put_user(old_encode_dev(stat->rdev), &ubuf->st_rdev);
+ err |= __put_user(stat->size, &ubuf->st_size);
+ err |= __put_user(stat->atime.tv_sec, &ubuf->st_atime);
+ err |= __put_user(stat->atime.tv_nsec, &ubuf->st_atime_nsec);
+@@ -2262,10 +2265,18 @@
+ return -EFAULT;
+ uss.ss_sp = (void *) (long) buf32.ss_sp;
+ uss.ss_flags = buf32.ss_flags;
+- uss.ss_size = buf32.ss_size;
++ /* MINSIGSTKSZ is different for ia32 vs ia64. We lie here to pass the
++ check and set it to the user requested value later */
++ if (buf32.ss_size < MINSIGSTKSZ_IA32) {
++ ret = -ENOMEM;
++ goto out;
++ }
++ uss.ss_size = MINSIGSTKSZ;
+ set_fs(KERNEL_DS);
+ ret = do_sigaltstack(uss32 ? &uss : NULL, &uoss, pt->r12);
++ current->sas_ss_size = buf32.ss_size;
+ set_fs(old_fs);
++out:
+ if (ret < 0)
+ return(ret);
+ if (uoss32) {
+@@ -2479,7 +2490,7 @@
+ if (clear_user(ubuf, sizeof(*ubuf)))
+ return -EFAULT;
+
+- err = __put_user(kbuf->dev, &ubuf->st_dev);
++ err = __put_user(huge_encode_dev(kbuf->dev), &ubuf->st_dev);
+ err |= __put_user(kbuf->ino, &ubuf->__st_ino);
+ err |= __put_user(kbuf->ino, &ubuf->st_ino_lo);
+ err |= __put_user(kbuf->ino >> 32, &ubuf->st_ino_hi);
+@@ -2487,7 +2498,7 @@
+ err |= __put_user(kbuf->nlink, &ubuf->st_nlink);
+ err |= __put_user(kbuf->uid, &ubuf->st_uid);
+ err |= __put_user(kbuf->gid, &ubuf->st_gid);
+- err |= __put_user(kbuf->rdev, &ubuf->st_rdev);
++ err |= __put_user(huge_encode_dev(kbuf->rdev), &ubuf->st_rdev);
+ err |= __put_user(kbuf->size, &ubuf->st_size_lo);
+ err |= __put_user((kbuf->size >> 32), &ubuf->st_size_hi);
+ err |= __put_user(kbuf->atime.tv_sec, &ubuf->st_atime);
+Index: linux-2.6.0-test5/arch/ia64/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/Kconfig 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/Kconfig 2003-09-27 11:38:19.295595008 +0800
+@@ -267,7 +267,7 @@
+ unsure, answer Y.
+
+ config PM
+- bool
++ bool "Power Management support"
+ depends on IA64_GENERIC || IA64_DIG || IA64_HP_ZX1
+ default y
+ ---help---
+@@ -304,9 +304,6 @@
+ int
+ default "18"
+
+-config HUGETLB_PAGE
+- bool "IA-64 Huge TLB Page Support"
+-
+ choice
+ prompt "IA-64 Huge TLB Page Size"
+ depends on HUGETLB_PAGE
+@@ -413,6 +410,16 @@
+ To use this option, you have to ensure that the "/proc file system
+ support" (CONFIG_PROC_FS) is enabled, too.
+
++config IA64_SALINFO
++ tristate "/proc/sal support"
++ help
++ The /proc/sal directory exports the SAL (system abstraction layer)
++ feature bits, like whether the platform is subject to ITC drift. It
++ is intended to be used by user programs that care about such things.
++
++ To use this option, you have to ensure that the "/proc file system
++ support" (CONFIG_PROC_FS) is enabled, too.
++
+ config EFI_VARS
+ tristate "/proc/efi/vars support"
+ help
+@@ -424,9 +431,15 @@
+ support" (CONFIG_PROC_FS) is enabled, too.
+
+ config NR_CPUS
+- int "Maximum number of CPUs (2-64)"
++ int "Maximum number of CPUs"
+ depends on SMP
+ default "64"
++ help
++ You should set this to the number of CPUs in your system, but
++ keep in mind that a kernel compiled for, e.g., 2 CPUs will boot but
++ only use 2 CPUs on a >2 CPU system. Setting this to a value larger
++ than 64 will cause the use of a CPU mask array, causing a small
++ performance hit.
+
+ source "fs/Kconfig.binfmt"
+
+@@ -569,6 +582,7 @@
+
+ source "arch/ia64/hp/sim/Kconfig"
+
++source "arch/ia64/oprofile/Kconfig"
+
+ menu "Kernel hacking"
+
+Index: linux-2.6.0-test5/arch/ia64/kernel/acpi.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/kernel/acpi.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/kernel/acpi.c 2003-09-27 11:38:19.310592728 +0800
+@@ -41,6 +41,7 @@
+ #include <linux/irq.h>
+ #include <linux/acpi.h>
+ #include <linux/efi.h>
++#include <linux/mmzone.h>
+ #include <asm/io.h>
+ #include <asm/iosapic.h>
+ #include <asm/machvec.h>
+@@ -56,7 +57,7 @@
+
+ unsigned char acpi_kbd_controller_present = 1;
+
+-int acpi_disabled __initdata; /* XXX this shouldn't be needed---we can't boot without ACPI! */
++int acpi_disabled; /* XXX this shouldn't be needed---we can't boot without ACPI! */
+
+ const char *
+ acpi_get_sysname (void)
+@@ -331,7 +332,7 @@
+
+ #ifdef CONFIG_ACPI_NUMA
+
+-#define SLIT_DEBUG
++#undef SLIT_DEBUG
+
+ #define PXM_FLAG_LEN ((MAX_PXM_DOMAINS + 1)/32)
+
+@@ -341,7 +342,7 @@
+ #define pxm_bit_test(bit) (test_bit(bit,(void *)pxm_flag))
+ /* maps to convert between proximity domain and logical node ID */
+ int __initdata pxm_to_nid_map[MAX_PXM_DOMAINS];
+-int __initdata nid_to_pxm_map[NR_NODES];
++int __initdata nid_to_pxm_map[MAX_NUMNODES];
+ static struct acpi_table_slit __initdata *slit_table;
+
+ /*
+@@ -603,11 +604,13 @@
+ printk(KERN_ERR PREFIX "Can't find FADT\n");
+
+ #ifdef CONFIG_SMP
+- smp_boot_data.cpu_count = available_cpus;
+ if (available_cpus == 0) {
+ printk(KERN_INFO "ACPI: Found 0 CPUS; assuming 1\n");
++ printk(KERN_INFO "CPU 0 (0x%04x)", hard_smp_processor_id());
++ smp_boot_data.cpu_phys_id[available_cpus] = hard_smp_processor_id();
+ available_cpus = 1; /* We've got at least one of these, no? */
+ }
++ smp_boot_data.cpu_count = available_cpus;
+
+ smp_build_cpu_map();
+ # ifdef CONFIG_NUMA
+Index: linux-2.6.0-test5/arch/ia64/kernel/efi.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/kernel/efi.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/kernel/efi.c 2003-09-27 11:38:19.328589992 +0800
+@@ -324,7 +324,7 @@
+ check_md = q;
+
+ if (check_md->attribute & EFI_MEMORY_WB)
+- trim_bottom(md, granule_addr);
++ trim_bottom(check_md, granule_addr);
+
+ if (check_md->phys_addr < granule_addr)
+ continue;
+@@ -446,10 +446,12 @@
+ panic("Woah! PAL code size bigger than a granule!");
+
+ mask = ~((1 << IA64_GRANULE_SHIFT) - 1);
++#if EFI_DEBUG
+ printk(KERN_INFO "CPU %d: mapping PAL code [0x%lx-0x%lx) into [0x%lx-0x%lx)\n",
+ smp_processor_id(), md->phys_addr,
+ md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
+ vaddr & mask, (vaddr & mask) + IA64_GRANULE_SIZE);
++#endif
+
+ /*
+ * Cannot write to CRx with PSR.ic=1
+Index: linux-2.6.0-test5/arch/ia64/kernel/entry.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/kernel/entry.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/kernel/entry.S 2003-09-27 11:38:19.345587408 +0800
+@@ -1448,7 +1448,7 @@
+ data8 sys_sched_setaffinity
+ data8 sys_sched_getaffinity
+ data8 sys_set_tid_address
+- data8 sys_fadvise64
++ data8 sys_fadvise64_64
+ data8 sys_tgkill // 1235
+ data8 sys_exit_group
+ data8 sys_lookup_dcookie
+@@ -1473,7 +1473,7 @@
+ data8 sys_clock_nanosleep
+ data8 sys_fstatfs64
+ data8 sys_statfs64
+- data8 sys_fadvise64_64
++ data8 ia64_ni_syscall
+ data8 ia64_ni_syscall // 1260
+ data8 ia64_ni_syscall
+ data8 ia64_ni_syscall
+Index: linux-2.6.0-test5/arch/ia64/kernel/fsys.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/kernel/fsys.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/kernel/fsys.S 2003-09-27 11:38:19.351586496 +0800
+@@ -655,7 +655,7 @@
+ data8 0 // sched_setaffinity
+ data8 0 // sched_getaffinity
+ data8 fsys_set_tid_address // set_tid_address
+- data8 0 // fadvise64
++ data8 0 // fadvise64_64
+ data8 0 // tgkill // 1235
+ data8 0 // exit_group
+ data8 0 // lookup_dcookie
+@@ -680,7 +680,7 @@
+ data8 0 // clock_nanosleep
+ data8 0 // fstatfs64
+ data8 0 // statfs64
+- data8 0 // fadvise64_64
++ data8 0
+ data8 0 // 1260
+ data8 0
+ data8 0
+Index: linux-2.6.0-test5/arch/ia64/kernel/init_task.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/kernel/init_task.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/kernel/init_task.c 2003-09-27 11:38:19.352586344 +0800
+@@ -28,15 +28,13 @@
+ */
+ #define init_thread_info init_task_mem.s.thread_info
+
+-static union {
++union {
+ struct {
+ struct task_struct task;
+ struct thread_info thread_info;
+ } s;
+ unsigned long stack[KERNEL_STACK_SIZE/sizeof (unsigned long)];
+-} init_task_mem asm ("init_task_mem") __attribute__((section(".data.init_task"))) = {{
++} init_task_mem asm ("init_task") __attribute__((section(".data.init_task"))) = {{
+ .task = INIT_TASK(init_task_mem.s.task),
+ .thread_info = INIT_THREAD_INFO(init_task_mem.s.task)
+ }};
+-
+-extern struct task_struct init_task __attribute__ ((alias("init_task_mem")));
+Index: linux-2.6.0-test5/arch/ia64/kernel/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/kernel/Makefile 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/kernel/Makefile 2003-09-27 11:38:19.353586192 +0800
+@@ -14,6 +14,7 @@
+ obj-$(CONFIG_IA64_HP_ZX1) += acpi-ext.o
+ obj-$(CONFIG_IA64_MCA) += mca.o mca_asm.o
+ obj-$(CONFIG_IA64_PALINFO) += palinfo.o
++obj-$(CONFIG_IA64_SALINFO) += salinfo.o
+ obj-$(CONFIG_IOSAPIC) += iosapic.o
+ obj-$(CONFIG_MODULES) += module.o
+ obj-$(CONFIG_SMP) += smp.o smpboot.o
+Index: linux-2.6.0-test5/arch/ia64/kernel/mca.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/kernel/mca.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/kernel/mca.c 2003-09-27 11:38:19.380582088 +0800
+@@ -1193,7 +1193,7 @@
+ ia64_mca_cmc_poll (unsigned long dummy)
+ {
+ /* Trigger a CMC interrupt cascade */
+- platform_send_ipi(__ffs(cpu_online_map), IA64_CMCP_VECTOR, IA64_IPI_DM_INT, 0);
++ platform_send_ipi(first_cpu(cpu_online_map), IA64_CMCP_VECTOR, IA64_IPI_DM_INT, 0);
+ }
+
+ /*
+@@ -1260,7 +1260,7 @@
+ ia64_mca_cpe_poll (unsigned long dummy)
+ {
+ /* Trigger a CPE interrupt cascade */
+- platform_send_ipi(__ffs(cpu_online_map), IA64_CPEP_VECTOR, IA64_IPI_DM_INT, 0);
++ platform_send_ipi(first_cpu(cpu_online_map), IA64_CPEP_VECTOR, IA64_IPI_DM_INT, 0);
+ }
+
+ /*
+Index: linux-2.6.0-test5/arch/ia64/kernel/perfmon.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/kernel/perfmon.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/kernel/perfmon.c 2003-09-27 11:38:19.436573576 +0800
+@@ -58,23 +58,8 @@
+ #define PFM_CTX_ZOMBIE 4 /* owner of the context is closing it */
+ #define PFM_CTX_TERMINATED 5 /* the task the context was loaded onto is gone */
+
+-#define CTX_LOADED(c) (c)->ctx_state = PFM_CTX_LOADED
+-#define CTX_UNLOADED(c) (c)->ctx_state = PFM_CTX_UNLOADED
+-#define CTX_ZOMBIE(c) (c)->ctx_state = PFM_CTX_ZOMBIE
+-#define CTX_DESTROYED(c) (c)->ctx_state = PFM_CTX_DESTROYED
+-#define CTX_MASKED(c) (c)->ctx_state = PFM_CTX_MASKED
+-#define CTX_TERMINATED(c) (c)->ctx_state = PFM_CTX_TERMINATED
+-
+-#define CTX_IS_UNLOADED(c) ((c)->ctx_state == PFM_CTX_UNLOADED)
+-#define CTX_IS_LOADED(c) ((c)->ctx_state == PFM_CTX_LOADED)
+-#define CTX_IS_ZOMBIE(c) ((c)->ctx_state == PFM_CTX_ZOMBIE)
+-#define CTX_IS_MASKED(c) ((c)->ctx_state == PFM_CTX_MASKED)
+-#define CTX_IS_TERMINATED(c) ((c)->ctx_state == PFM_CTX_TERMINATED)
+-#define CTX_IS_DEAD(c) ((c)->ctx_state == PFM_CTX_TERMINATED || (c)->ctx_state == PFM_CTX_ZOMBIE)
+-
+ #define PFM_INVALID_ACTIVATION (~0UL)
+
+-
+ /*
+ * depth of message queue
+ */
+@@ -155,7 +140,7 @@
+ * in UP:
+ * - we need to protect against PMU overflow interrupts (local_irq_disable)
+ *
+- * spin_lock_irqsave()/spin_lock_irqrestore():
++ * spin_lock_irqsave()/spin_unlock_irqrestore():
+ * in SMP: local_irq_disable + spin_lock
+ * in UP : local_irq_disable
+ *
+@@ -649,6 +634,7 @@
+ DEFINE_PER_CPU(pfm_context_t *, pmu_ctx);
+ DEFINE_PER_CPU(unsigned long, pmu_activation_number);
+
++
+ /* forward declaration */
+ static struct file_operations pfm_file_ops;
+
+@@ -659,7 +645,13 @@
+ static void pfm_lazy_save_regs (struct task_struct *ta);
+ #endif
+
+-#if defined(CONFIG_ITANIUM)
++/*
++ * the HP simulator must be first because
++ * CONFIG_IA64_HP_SIM is independent of CONFIG_MCKINLEY or CONFIG_ITANIUM
++ */
++#if defined(CONFIG_IA64_HP_SIM)
++#include "perfmon_hpsim.h"
++#elif defined(CONFIG_ITANIUM)
+ #include "perfmon_itanium.h"
+ #elif defined(CONFIG_MCKINLEY)
+ #include "perfmon_mckinley.h"
+@@ -953,13 +945,15 @@
+ struct thread_struct *th = &task->thread;
+ unsigned long mask;
+ unsigned long psr, val;
+- int i;
++ int i, is_system;
++
++ is_system = ctx->ctx_fl_system;
+
+ if (task != current) {
+ printk(KERN_ERR "perfmon.%d: invalid task[%d] current[%d]\n", __LINE__, task->pid, current->pid);
+ return;
+ }
+- if (CTX_IS_MASKED(ctx) == 0) {
++ if (ctx->ctx_state != PFM_CTX_MASKED) {
+ printk(KERN_ERR "perfmon.%d: task[%d] current[%d] invalid state=%d\n", __LINE__,
+ task->pid, current->pid, ctx->ctx_state);
+ return;
+@@ -975,7 +969,7 @@
+ *
+ * system-wide session are pinned and self-monitoring
+ */
+- if (ctx->ctx_fl_system && (PFM_CPUINFO_GET() & PFM_CPUINFO_DCR_PP)) {
++ if (is_system && (PFM_CPUINFO_GET() & PFM_CPUINFO_DCR_PP)) {
+ /* disable dcr pp */
+ ia64_setreg(_IA64_REG_CR_DCR, ia64_getreg(_IA64_REG_CR_DCR) & ~IA64_DCR_PP);
+ pfm_clear_psr_pp();
+@@ -1022,7 +1016,7 @@
+ /*
+ * now restore PSR
+ */
+- if (ctx->ctx_fl_system && (PFM_CPUINFO_GET() & PFM_CPUINFO_DCR_PP)) {
++ if (is_system && (PFM_CPUINFO_GET() & PFM_CPUINFO_DCR_PP)) {
+ /* enable dcr pp */
+ ia64_setreg(_IA64_REG_CR_DCR, ia64_getreg(_IA64_REG_CR_DCR) | IA64_DCR_PP);
+ ia64_srlz_i();
+@@ -1825,6 +1819,7 @@
+ void *smpl_buf_vaddr = NULL;
+ void *smpl_buf_addr = NULL;
+ int free_possible = 1;
++ int state, is_system;
+
+ { u64 psr = pfm_get_psr();
+ BUG_ON((psr & IA64_PSR_I) == 0UL);
+@@ -1850,6 +1845,11 @@
+
+ PROTECT_CTX(ctx, flags);
+
++ state = ctx->ctx_state;
++ is_system = ctx->ctx_fl_system;
++
++ task = PFM_CTX_TASK(ctx);
++
+ /*
+ * remove our file from the async queue, if we use it
+ */
+@@ -1859,11 +1859,10 @@
+ DPRINT(("[%d] after async_queue=%p\n", current->pid, ctx->ctx_async_queue));
+ }
+
+- task = PFM_CTX_TASK(ctx);
+
+- DPRINT(("[%d] ctx_state=%d\n", current->pid, ctx->ctx_state));
++ DPRINT(("[%d] ctx_state=%d\n", current->pid, state));
+
+- if (CTX_IS_UNLOADED(ctx) || CTX_IS_TERMINATED(ctx)) {
++ if (state == PFM_CTX_UNLOADED || state == PFM_CTX_TERMINATED) {
+ goto doit;
+ }
+
+@@ -1884,7 +1883,7 @@
+ *
+ * We need to release the resource on the ORIGINAL cpu.
+ */
+- if (ctx->ctx_fl_system && ctx->ctx_cpu != smp_processor_id()) {
++ if (is_system && ctx->ctx_cpu != smp_processor_id()) {
+
+ DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu));
+
+@@ -1900,9 +1899,10 @@
+ task->thread.pfm_context = NULL;
+ ctx->ctx_task = NULL;
+
+- CTX_UNLOADED(ctx);
++ ctx->ctx_state = state = PFM_CTX_UNLOADED;
+
+ pfm_unreserve_session(ctx, 1 , ctx->ctx_cpu);
++
+ } else
+ #endif /* CONFIG_SMP */
+ {
+@@ -1914,19 +1914,20 @@
+ */
+ pfm_context_unload(ctx, NULL, 0, regs);
+
+- CTX_TERMINATED(ctx);
++ ctx->ctx_state = PFM_CTX_TERMINATED;
+
+- DPRINT(("[%d] ctx_state=%d\n", current->pid, ctx->ctx_state));
++ DPRINT(("[%d] ctx_state=%d\n", current->pid, state));
+ }
+ goto doit;
+ }
+
++
+ /*
+ * The task is currently blocked or will block after an overflow.
+ * we must force it to wakeup to get out of the
+ * MASKED state and transition to the unloaded state by itself
+ */
+- if (CTX_IS_MASKED(ctx) && CTX_OVFL_NOBLOCK(ctx) == 0) {
++ if (state == PFM_CTX_MASKED && CTX_OVFL_NOBLOCK(ctx) == 0) {
+
+ /*
+ * set a "partial" zombie state to be checked
+@@ -1949,7 +1950,7 @@
+ */
+ up(&ctx->ctx_restart_sem);
+
+- DPRINT(("waking up ctx_state=%d for [%d]\n", ctx->ctx_state, current->pid));
++ DPRINT(("waking up ctx_state=%d for [%d]\n", state, current->pid));
+
+ /*
+ * put ourself to sleep waiting for the other
+@@ -1971,24 +1972,24 @@
+ */
+ schedule();
+
+- DPRINT(("woken up ctx_state=%d for [%d]\n", ctx->ctx_state, current->pid));
+
+ PROTECT_CTX(ctx, flags);
+
++
+ remove_wait_queue(&ctx->ctx_zombieq, &wait);
+ set_current_state(TASK_RUNNING);
+
+ /*
+ * context is terminated at this point
+ */
+- DPRINT(("after zombie wakeup ctx_state=%d for [%d]\n", ctx->ctx_state, current->pid));
++ DPRINT(("after zombie wakeup ctx_state=%d for [%d]\n", state, current->pid));
+ }
+ else {
+ #ifdef CONFIG_SMP
+ /*
+ * switch context to zombie state
+ */
+- CTX_ZOMBIE(ctx);
++ ctx->ctx_state = PFM_CTX_ZOMBIE;
+
+ DPRINT(("zombie ctx for [%d]\n", task->pid));
+ /*
+@@ -2002,6 +2003,10 @@
+ }
+
+ doit: /* cannot assume task is defined from now on */
++
++ /* reload state, may have changed during opening of critical section */
++ state = ctx->ctx_state;
++
+ /*
+ * the context is still attached to a task (possibly current)
+ * we cannot destroy it right now
+@@ -2032,10 +2037,9 @@
+ ctx->ctx_smpl_hdr = NULL;
+ }
+
+-
+ DPRINT(("[%d] ctx_state=%d free_possible=%d vaddr=%p addr=%p size=%lu\n",
+ current->pid,
+- ctx->ctx_state,
++ state,
+ free_possible,
+ smpl_buf_vaddr,
+ smpl_buf_addr,
+@@ -2047,7 +2051,7 @@
+ * UNLOADED and TERMINATED mean that the session has already been
+ * unreserved.
+ */
+- if (CTX_IS_ZOMBIE(ctx)) {
++ if (state == PFM_CTX_ZOMBIE) {
+ pfm_unreserve_session(ctx, ctx->ctx_fl_system , ctx->ctx_cpu);
+ }
+
+@@ -2360,10 +2364,23 @@
+ static int
+ pfm_bad_permissions(struct task_struct *task)
+ {
+- /* stolen from bad_signal() */
+- return (current->session != task->session)
+- && (current->euid ^ task->suid) && (current->euid ^ task->uid)
+- && (current->uid ^ task->suid) && (current->uid ^ task->uid);
++ /* inspired by ptrace_attach() */
++ DPRINT(("[%d] cur: uid=%d gid=%d task: euid=%d suid=%d uid=%d egid=%d sgid=%d\n",
++ current->pid,
++ current->uid,
++ current->gid,
++ task->euid,
++ task->suid,
++ task->uid,
++ task->egid,
++ task->sgid));
++
++ return ((current->uid != task->euid)
++ || (current->uid != task->suid)
++ || (current->uid != task->uid)
++ || (current->gid != task->egid)
++ || (current->gid != task->sgid)
++ || (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE);
+ }
+
+ static int
+@@ -2655,7 +2672,7 @@
+ /*
+ * context is unloaded
+ */
+- CTX_UNLOADED(ctx);
++ ctx->ctx_state = PFM_CTX_UNLOADED;
+
+ /*
+ * initialization of context's flags
+@@ -2787,7 +2804,7 @@
+
+ if (flag == PFM_PMD_NO_RESET) return;
+
+- if (CTX_IS_MASKED(ctx)) {
++ if (ctx->ctx_state == PFM_CTX_MASKED) {
+ pfm_reset_regs_masked(ctx, ovfl_regs, flag);
+ return;
+ }
+@@ -2836,27 +2853,30 @@
+ unsigned long value;
+ unsigned long smpl_pmds, reset_pmds;
+ unsigned int cnum, reg_flags, flags;
+- int i, can_access_pmu = 0, is_loaded;
+- int is_monitor, is_counting;
++ int i, can_access_pmu = 0, is_loaded, is_system;
++ int is_monitor, is_counting, state;
+ int ret = -EINVAL;
+ #define PFM_CHECK_PMC_PM(x, y, z) ((x)->ctx_fl_system ^ PMC_PM(y, z))
+
+- if (CTX_IS_DEAD(ctx)) return -EINVAL;
++ state = ctx->ctx_state;
++ is_loaded = state == PFM_CTX_LOADED ? 1 : 0;
++ is_system = ctx->ctx_fl_system;
++
++ if (state == PFM_CTX_TERMINATED || state == PFM_CTX_ZOMBIE) return -EINVAL;
+
+- is_loaded = CTX_IS_LOADED(ctx);
+
+ if (is_loaded) {
+ thread = &ctx->ctx_task->thread;
+- can_access_pmu = GET_PMU_OWNER() == ctx->ctx_task ? 1 : 0;
+ /*
+ * In system wide and when the context is loaded, access can only happen
+ * when the caller is running on the CPU being monitored by the session.
+ * It does not have to be the owner (ctx_task) of the context per se.
+ */
+- if (ctx->ctx_fl_system && ctx->ctx_cpu != smp_processor_id()) {
++ if (is_system && ctx->ctx_cpu != smp_processor_id()) {
+ DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu));
+ return -EBUSY;
+ }
++ can_access_pmu = GET_PMU_OWNER() == ctx->ctx_task || is_system ? 1 : 0;
+ }
+
+ for (i = 0; i < count; i++, req++) {
+@@ -2885,7 +2905,7 @@
+ * - system-wide session: PMCx.pm=1 (privileged monitor)
+ * - per-task : PMCx.pm=0 (user monitor)
+ */
+- if ((is_monitor || is_counting) && value != PMC_DFL_VAL(i) && PFM_CHECK_PMC_PM(ctx, cnum, value)) {
++ if ((is_monitor || is_counting) && value != PMC_DFL_VAL(cnum) && PFM_CHECK_PMC_PM(ctx, cnum, value)) {
+ DPRINT(("pmc%u pmc_pm=%ld fl_system=%d\n",
+ cnum,
+ PMC_PM(cnum, value),
+@@ -2893,7 +2913,6 @@
+ goto error;
+ }
+
+-
+ if (is_counting) {
+ pfm_monitor_t *p = (pfm_monitor_t *)&value;
+ /*
+@@ -2975,7 +2994,7 @@
+ * make sure we do not try to reset on
+ * restart because we have established new values
+ */
+- if (CTX_IS_MASKED(ctx)) ctx->ctx_ovfl_regs[0] &= ~1UL << cnum;
++ if (state == PFM_CTX_MASKED) ctx->ctx_ovfl_regs[0] &= ~1UL << cnum;
+ }
+ /*
+ * Needed in case the user does not initialize the equivalent
+@@ -3007,7 +3026,7 @@
+ /*
+ * write thread state
+ */
+- if (ctx->ctx_fl_system == 0) thread->pmcs[cnum] = value;
++ if (is_system == 0) thread->pmcs[cnum] = value;
+
+ /*
+ * write hardware register if we can
+@@ -3067,13 +3086,16 @@
+ pfarg_reg_t *req = (pfarg_reg_t *)arg;
+ unsigned long value, hw_value;
+ unsigned int cnum;
+- int i, can_access_pmu = 0;
+- int is_counting, is_loaded;
++ int i, can_access_pmu = 0, state;
++ int is_counting, is_loaded, is_system;
+ int ret = -EINVAL;
+
+- if (CTX_IS_DEAD(ctx)) return -EINVAL;
+
+- is_loaded = CTX_IS_LOADED(ctx);
++ state = ctx->ctx_state;
++ is_loaded = state == PFM_CTX_LOADED ? 1 : 0;
++ is_system = ctx->ctx_fl_system;
++
++ if (state == PFM_CTX_TERMINATED || state == PFM_CTX_ZOMBIE) return -EINVAL;
+
+ /*
+ * on both UP and SMP, we can only write to the PMC when the task is
+@@ -3081,16 +3103,16 @@
+ */
+ if (is_loaded) {
+ thread = &ctx->ctx_task->thread;
+- can_access_pmu = GET_PMU_OWNER() == ctx->ctx_task ? 1 : 0;
+ /*
+ * In system wide and when the context is loaded, access can only happen
+ * when the caller is running on the CPU being monitored by the session.
+ * It does not have to be the owner (ctx_task) of the context per se.
+ */
+- if (ctx->ctx_fl_system && ctx->ctx_cpu != smp_processor_id()) {
++ if (is_system && ctx->ctx_cpu != smp_processor_id()) {
+ DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu));
+ return -EBUSY;
+ }
++ can_access_pmu = GET_PMU_OWNER() == ctx->ctx_task || is_system ? 1 : 0;
+ }
+
+ for (i = 0; i < count; i++, req++) {
+@@ -3179,7 +3201,7 @@
+ * make sure we do not try to reset on
+ * restart because we have established new values
+ */
+- if (is_counting && CTX_IS_MASKED(ctx)) {
++ if (is_counting && state == PFM_CTX_MASKED) {
+ ctx->ctx_ovfl_regs[0] &= ~1UL << cnum;
+ }
+
+@@ -3187,7 +3209,7 @@
+ /*
+ * write thread state
+ */
+- if (ctx->ctx_fl_system == 0) thread->pmds[cnum] = hw_value;
++ if (is_system == 0) thread->pmds[cnum] = hw_value;
+
+ /*
+ * write hardware register if we can
+@@ -3265,35 +3287,40 @@
+ unsigned long val = 0UL, lval ;
+ pfarg_reg_t *req = (pfarg_reg_t *)arg;
+ unsigned int cnum, reg_flags = 0;
+- int i, is_loaded, can_access_pmu = 0;
++ int i, can_access_pmu = 0, state;
++ int is_loaded, is_system;
+ int ret = -EINVAL;
+
+- if (CTX_IS_ZOMBIE(ctx)) return -EINVAL;
+-
+ /*
+ * access is possible when loaded only for
+ * self-monitoring tasks or in UP mode
+ */
+- is_loaded = CTX_IS_LOADED(ctx);
++
++ state = ctx->ctx_state;
++ is_loaded = state == PFM_CTX_LOADED ? 1 : 0;
++ is_system = ctx->ctx_fl_system;
++
++ if (state == PFM_CTX_ZOMBIE) return -EINVAL;
+
+ if (is_loaded) {
+ thread = &ctx->ctx_task->thread;
+ /*
+- * this can be true when not self-monitoring only in UP
+- */
+- can_access_pmu = GET_PMU_OWNER() == ctx->ctx_task? 1 : 0;
+-
+- if (can_access_pmu) ia64_srlz_d();
+- /*
+ * In system wide and when the context is loaded, access can only happen
+ * when the caller is running on the CPU being monitored by the session.
+ * It does not have to be the owner (ctx_task) of the context per se.
+ */
+- if (ctx->ctx_fl_system && ctx->ctx_cpu != smp_processor_id()) {
++ if (is_system && ctx->ctx_cpu != smp_processor_id()) {
+ DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu));
+ return -EBUSY;
+ }
++ /*
++ * this can be true when not self-monitoring only in UP
++ */
++ can_access_pmu = GET_PMU_OWNER() == ctx->ctx_task || is_system ? 1 : 0;
++
++ if (can_access_pmu) ia64_srlz_d();
+ }
++
+ DPRINT(("enter loaded=%d access_pmu=%d ctx_state=%d\n",
+ is_loaded,
+ can_access_pmu,
+@@ -3334,7 +3361,7 @@
+ * if context is zombie, then task does not exist anymore.
+ * In this case, we use the full value saved in the context (pfm_flush_regs()).
+ */
+- val = CTX_IS_LOADED(ctx) ? thread->pmds[cnum] : 0UL;
++ val = state == PFM_CTX_LOADED ? thread->pmds[cnum] : 0UL;
+ }
+
+ if (PMD_IS_COUNTING(cnum)) {
+@@ -3628,7 +3655,7 @@
+ if (rst_ctrl.bits.mask_monitoring == 0) {
+ DPRINT(("resuming monitoring for [%d]\n", task->pid));
+
+- if (CTX_IS_MASKED(ctx)) pfm_restore_monitoring(task);
++ if (state == PFM_CTX_MASKED) pfm_restore_monitoring(task);
+ } else {
+ DPRINT(("keeping monitoring stopped for [%d]\n", task->pid));
+
+@@ -3643,7 +3670,7 @@
+ /*
+ * back to LOADED state
+ */
+- CTX_LOADED(ctx);
++ ctx->ctx_state = PFM_CTX_LOADED;
+
+ return 0;
+ }
+@@ -3706,30 +3733,34 @@
+ dbreg_t dbreg;
+ unsigned int rnum;
+ int first_time;
+- int ret = 0;
+- int i, can_access_pmu = 0, is_loaded;
++ int ret = 0, state;
++ int i, can_access_pmu = 0;
++ int is_system, is_loaded;
+
+ if (pmu_conf.use_rr_dbregs == 0) return -EINVAL;
+
+- if (CTX_IS_DEAD(ctx)) return -EINVAL;
++ state = ctx->ctx_state;
++ is_loaded = state == PFM_CTX_LOADED ? 1 : 0;
++ is_system = ctx->ctx_fl_system;
++
++ if (state == PFM_CTX_TERMINATED || state == PFM_CTX_ZOMBIE) return -EINVAL;
+
+- is_loaded = CTX_IS_LOADED(ctx);
+ /*
+ * on both UP and SMP, we can only write to the PMC when the task is
+ * the owner of the local PMU.
+ */
+ if (is_loaded) {
+ thread = &ctx->ctx_task->thread;
+- can_access_pmu = GET_PMU_OWNER() == ctx->ctx_task ? 1 : 0;
+ /*
+ * In system wide and when the context is loaded, access can only happen
+ * when the caller is running on the CPU being monitored by the session.
+ * It does not have to be the owner (ctx_task) of the context per se.
+ */
+- if (ctx->ctx_fl_system && ctx->ctx_cpu != smp_processor_id()) {
++ if (is_system && ctx->ctx_cpu != smp_processor_id()) {
+ DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu));
+ return -EBUSY;
+ }
++ can_access_pmu = GET_PMU_OWNER() == ctx->ctx_task || is_system ? 1 : 0;
+ }
+
+ /*
+@@ -3758,7 +3789,7 @@
+ */
+ LOCK_PFS();
+
+- if (first_time && ctx->ctx_fl_system) {
++ if (first_time && is_system) {
+ if (pfm_sessions.pfs_ptrace_use_dbregs)
+ ret = -EBUSY;
+ else
+@@ -3906,16 +3937,19 @@
+ {
+ struct pt_regs *tregs;
+ struct task_struct *task = PFM_CTX_TASK(ctx);
++ int state, is_system;
+
++ state = ctx->ctx_state;
++ is_system = ctx->ctx_fl_system;
+
+- if (CTX_IS_LOADED(ctx) == 0 && CTX_IS_MASKED(ctx) == 0) return -EINVAL;
++ if (state != PFM_CTX_LOADED && state != PFM_CTX_MASKED) return -EINVAL;
+
+ /*
+ * In system wide and when the context is loaded, access can only happen
+ * when the caller is running on the CPU being monitored by the session.
+ * It does not have to be the owner (ctx_task) of the context per se.
+ */
+- if (ctx->ctx_fl_system && ctx->ctx_cpu != smp_processor_id()) {
++ if (is_system && ctx->ctx_cpu != smp_processor_id()) {
+ DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu));
+ return -EBUSY;
+ }
+@@ -3925,7 +3959,7 @@
+ * and the user level state of the caller, which may not
+ * necessarily be the creator of the context.
+ */
+- if (ctx->ctx_fl_system) {
++ if (is_system) {
+ /*
+ * Update local PMU first
+ *
+@@ -3985,15 +4019,19 @@
+ pfm_start(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
+ {
+ struct pt_regs *tregs;
++ int state, is_system;
++
++ state = ctx->ctx_state;
++ is_system = ctx->ctx_fl_system;
+
+- if (CTX_IS_LOADED(ctx) == 0) return -EINVAL;
++ if (state != PFM_CTX_LOADED) return -EINVAL;
+
+ /*
+ * In system wide and when the context is loaded, access can only happen
+ * when the caller is running on the CPU being monitored by the session.
+ * It does not have to be the owner (ctx_task) of the context per se.
+ */
+- if (ctx->ctx_fl_system && ctx->ctx_cpu != smp_processor_id()) {
++ if (is_system && ctx->ctx_cpu != smp_processor_id()) {
+ DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu));
+ return -EBUSY;
+ }
+@@ -4003,7 +4041,7 @@
+ * and the user level state of the caller, which may not
+ * necessarily be the creator of the context.
+ */
+- if (ctx->ctx_fl_system) {
++ if (is_system) {
+
+ /*
+ * set user level psr.pp for the caller
+@@ -4055,7 +4093,6 @@
+ */
+ ia64_psr(tregs)->up = 1;
+ }
+-
+ return 0;
+ }
+
+@@ -4121,11 +4158,14 @@
+ unsigned long *pmcs_source, *pmds_source;
+ int the_cpu;
+ int ret = 0;
++ int state, is_system;
+
++ state = ctx->ctx_state;
++ is_system = ctx->ctx_fl_system;
+ /*
+ * can only load from unloaded or terminated state
+ */
+- if (CTX_IS_UNLOADED(ctx) == 0 && CTX_IS_TERMINATED(ctx) == 0) {
++ if (state != PFM_CTX_UNLOADED && state != PFM_CTX_TERMINATED) {
+ DPRINT(("[%d] cannot load to [%d], invalid ctx_state=%d\n",
+ current->pid,
+ req->load_pid,
+@@ -4151,7 +4191,7 @@
+ /*
+ * system wide is self monitoring only
+ */
+- if (ctx->ctx_fl_system && task != current) {
++ if (is_system && task != current) {
+ DPRINT(("system wide is self monitoring only current=%d load_pid=%d\n",
+ current->pid,
+ req->load_pid));
+@@ -4191,7 +4231,7 @@
+ /*
+ * now reserve the session
+ */
+- ret = pfm_reserve_session(current, ctx->ctx_fl_system, the_cpu);
++ ret = pfm_reserve_session(current, is_system, the_cpu);
+ if (ret) goto error;
+
+ ret = -EBUSY;
+@@ -4216,15 +4256,14 @@
+
+ pfm_reset_msgq(ctx);
+
+- CTX_LOADED(ctx);
++ ctx->ctx_state = PFM_CTX_LOADED;
+
+ /*
+ * link context to task
+ */
+ ctx->ctx_task = task;
+
+- if (ctx->ctx_fl_system) {
+-
++ if (is_system) {
+ /*
+ * we load as stopped
+ */
+@@ -4250,7 +4289,7 @@
+ */
+ if (task == current) {
+
+- if (ctx->ctx_fl_system == 0) {
++ if (is_system == 0) {
+
+ /* allow user level control */
+ ia64_psr(regs)->sp = 0;
+@@ -4318,14 +4357,14 @@
+ /*
+ * release task, there is now a link with the context
+ */
+- if (ctx->ctx_fl_system == 0 && task != current) {
++ if (is_system == 0 && task != current) {
+ pfm_put_task(task);
+
+ if (ret == 0) {
+ ret = pfm_check_task_exist(ctx);
+ if (ret) {
+- CTX_UNLOADED(ctx);
+- ctx->ctx_task = NULL;
++ ctx->ctx_state = PFM_CTX_UNLOADED;
++ ctx->ctx_task = NULL;
+ }
+ }
+ }
+@@ -4347,40 +4386,34 @@
+ {
+ struct task_struct *task = PFM_CTX_TASK(ctx);
+ struct pt_regs *tregs;
++ int state, is_system;
+
+ DPRINT(("ctx_state=%d task [%d]\n", ctx->ctx_state, task ? task->pid : -1));
+
++ state = ctx->ctx_state;
++ is_system = ctx->ctx_fl_system;
++
+ /*
+ * unload only when necessary
+ */
+- if (CTX_IS_TERMINATED(ctx) || CTX_IS_UNLOADED(ctx)) {
++ if (state == PFM_CTX_TERMINATED || state == PFM_CTX_UNLOADED) {
+ DPRINT(("[%d] ctx_state=%d, nothing to do\n", current->pid, ctx->ctx_state));
+ return 0;
+ }
+
+ /*
+- * In system wide and when the context is loaded, access can only happen
+- * when the caller is running on the CPU being monitored by the session.
+- * It does not have to be the owner (ctx_task) of the context per se.
+- */
+- if (ctx->ctx_fl_system && ctx->ctx_cpu != smp_processor_id()) {
+- DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu));
+- return -EBUSY;
+- }
+-
+- /*
+ * clear psr and dcr bits
+ */
+ pfm_stop(ctx, NULL, 0, regs);
+
+- CTX_UNLOADED(ctx);
++ ctx->ctx_state = state = PFM_CTX_UNLOADED;
+
+ /*
+ * in system mode, we need to update the PMU directly
+ * and the user level state of the caller, which may not
+ * necessarily be the creator of the context.
+ */
+- if (ctx->ctx_fl_system) {
++ if (is_system) {
+
+ /*
+ * Update cpuinfo
+@@ -4524,7 +4557,7 @@
+ if (ret) {
+ printk(KERN_ERR "perfmon: pfm_exit_thread [%d] state=%d unload failed %d\n", task->pid, ctx->ctx_state, ret);
+ }
+- CTX_TERMINATED(ctx);
++ ctx->ctx_state = PFM_CTX_TERMINATED;
+ DPRINT(("ctx terminated by [%d]\n", task->pid));
+
+ pfm_end_notify_user(ctx);
+@@ -4606,16 +4639,19 @@
+ pfm_check_task_state(pfm_context_t *ctx, int cmd, unsigned long flags)
+ {
+ struct task_struct *task;
++ int state;
++
++ state = ctx->ctx_state;
+
+ task = PFM_CTX_TASK(ctx);
+ if (task == NULL) {
+- DPRINT(("context %d no task, state=%d\n", ctx->ctx_fd, ctx->ctx_state));
++ DPRINT(("context %d no task, state=%d\n", ctx->ctx_fd, state));
+ return 0;
+ }
+
+ DPRINT(("context %d state=%d [%d] task_state=%ld must_stop=%d\n",
+ ctx->ctx_fd,
+- ctx->ctx_state,
++ state,
+ task->pid,
+ task->state, PFM_CMD_STOPPED(cmd)));
+
+@@ -4631,9 +4667,9 @@
+ /*
+ * context is UNLOADED, MASKED, TERMINATED we are safe to go
+ */
+- if (CTX_IS_LOADED(ctx) == 0) return 0;
++ if (state != PFM_CTX_LOADED == 0) return 0;
+
+- if (CTX_IS_ZOMBIE(ctx)) return -EINVAL;
++ if (state == PFM_CTX_ZOMBIE) return -EINVAL;
+
+ /*
+ * context is loaded, we must make sure the task is stopped
+@@ -4653,6 +4689,7 @@
+ pfm_wait_task_inactive(task);
+
+ PROTECT_CTX(ctx, flags);
++
+ return 0;
+ }
+
+@@ -4830,12 +4867,12 @@
+ }
+ if (rst_ctrl.bits.mask_monitoring == 0) {
+ DPRINT(("resuming monitoring\n"));
+- if (CTX_IS_MASKED(ctx)) pfm_restore_monitoring(current);
++ if (ctx->ctx_state == PFM_CTX_MASKED) pfm_restore_monitoring(current);
+ } else {
+ DPRINT(("stopping monitoring\n"));
+ //pfm_stop_monitoring(current, regs);
+ }
+- CTX_LOADED(ctx);
++ ctx->ctx_state = PFM_CTX_LOADED;
+ }
+ }
+
+@@ -4869,7 +4906,7 @@
+ /*
+ * switch to terminated state
+ */
+- CTX_TERMINATED(ctx);
++ ctx->ctx_state = PFM_CTX_TERMINATED;
+
+ DPRINT(("context <%d> terminated for [%d]\n", ctx->ctx_fd, current->pid));
+
+@@ -4922,7 +4959,7 @@
+ /*
+ * must be done before we check non-blocking mode
+ */
+- if (ctx->ctx_fl_going_zombie || CTX_IS_ZOMBIE(ctx)) goto do_zombie;
++ if (ctx->ctx_fl_going_zombie || ctx->ctx_state == PFM_CTX_ZOMBIE) goto do_zombie;
+
+ ovfl_regs = ctx->ctx_ovfl_regs[0];
+
+@@ -4966,7 +5003,7 @@
+ static int
+ pfm_notify_user(pfm_context_t *ctx, pfm_msg_t *msg)
+ {
+- if (CTX_IS_ZOMBIE(ctx)) {
++ if (ctx->ctx_state == PFM_CTX_ZOMBIE) {
+ DPRINT(("ignoring overflow notification, owner is zombie\n"));
+ return 0;
+ }
+@@ -5049,13 +5086,13 @@
+ pfm_ovfl_arg_t ovfl_arg;
+ unsigned long mask;
+ unsigned long old_val;
+- unsigned long ovfl_notify = 0UL, ovfl_pmds = 0UL;
++ unsigned long ovfl_notify = 0UL, ovfl_pmds = 0UL, smpl_pmds = 0UL;
+ unsigned long tstamp;
+ pfm_ovfl_ctrl_t ovfl_ctrl;
+ unsigned int i, has_smpl;
+ int must_notify = 0;
+
+- if (unlikely(CTX_IS_ZOMBIE(ctx))) goto stop_monitoring;
++ if (unlikely(ctx->ctx_state == PFM_CTX_ZOMBIE)) goto stop_monitoring;
+
+ /*
+ * sanity test. Should never happen
+@@ -5106,10 +5143,9 @@
+ if (PMC_OVFL_NOTIFY(ctx, i)) ovfl_notify |= 1UL << i;
+ }
+
+- DPRINT_ovfl(("ctx_pmd[%d].val=0x%lx old_val=0x%lx pmd=0x%lx ovfl_pmds=0x%lx "
+- "ovfl_notify=0x%lx\n",
+- i, ctx->ctx_pmds[i].val, old_val,
+- ia64_get_pmd(i) & pmu_conf.ovfl_val, ovfl_pmds, ovfl_notify));
++ DPRINT_ovfl(("ctx_pmd[%d].val=0x%lx old_val=0x%lx pmd=0x%lx ovfl_pmds=0x%lx ovfl_notify=0x%lx smpl_pmds=0x%lx\n",
++ i, ctx->ctx_pmds[i].val, old_val,
++ ia64_get_pmd(i) & pmu_conf.ovfl_val, ovfl_pmds, ovfl_notify, smpl_pmds));
+ }
+
+ /*
+@@ -5128,7 +5164,7 @@
+ */
+ if (has_smpl) {
+ unsigned long start_cycles, end_cycles;
+- unsigned long pmd_mask, smpl_pmds;
++ unsigned long pmd_mask;
+ int j, k, ret = 0;
+ int this_cpu = smp_processor_id();
+
+@@ -5257,7 +5293,7 @@
+ */
+ if (ovfl_ctrl.bits.mask_monitoring) {
+ pfm_mask_monitoring(task);
+- CTX_MASKED(ctx);
++ ctx->ctx_state = PFM_CTX_MASKED;
+ }
+
+ /*
+@@ -5553,19 +5589,18 @@
+ pfm_set_psr_pp();
+ ia64_srlz_i();
+ }
+- { unsigned long val;
+- val = ia64_get_pmc(4);
+- if ((val & (1UL<<23)) == 0UL) printk("perfmon: PMU off: pmc4=0x%lx\n", val);
+- }
+ }
+
+ void
+ pfm_syst_wide_update_task(struct task_struct *task, unsigned long info, int is_ctxswin)
+ {
+ unsigned long start, end;
++
+ pfm_stats[smp_processor_id()].pfm_sysupdt_count++;
+ start = ia64_get_itc();
++
+ pfm_do_syst_wide_update_task(task, info, is_ctxswin);
++
+ end = ia64_get_itc();
+ pfm_stats[smp_processor_id()].pfm_sysupdt_cycles += end-start;
+ }
+@@ -5591,7 +5626,7 @@
+ */
+ flags = pfm_protect_ctx_ctxsw(ctx);
+
+- if (CTX_IS_ZOMBIE(ctx)) {
++ if (ctx->ctx_state == PFM_CTX_ZOMBIE) {
+ struct pt_regs *regs = ia64_task_regs(task);
+
+ pfm_clear_psr_up();
+@@ -5840,7 +5875,7 @@
+ BUG_ON(psr & IA64_PSR_I);
+ #endif
+
+- if (unlikely(CTX_IS_ZOMBIE(ctx))) {
++ if (unlikely(ctx->ctx_state == PFM_CTX_ZOMBIE)) {
+ struct pt_regs *regs = ia64_task_regs(task);
+
+ BUG_ON(ctx->ctx_smpl_hdr);
+Index: linux-2.6.0-test5/arch/ia64/kernel/perfmon_hpsim.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/kernel/perfmon_hpsim.h 2003-09-27 11:38:18.435725728 +0800
++++ linux-2.6.0-test5/arch/ia64/kernel/perfmon_hpsim.h 2003-09-27 11:38:19.437573424 +0800
+@@ -0,0 +1,75 @@
++/*
++ * This file contains the HP SKI Simulator PMU register description tables
++ * and pmc checkers used by perfmon.c.
++ *
++ * Copyright (C) 2002-2003 Hewlett Packard Co
++ * Stephane Eranian <eranian@hpl.hp.com>
++ *
++ * File mostly contributed by Ian Wienand <ianw@gelato.unsw.edu.au>
++ *
++ * This file is included as a dummy template so the kernel does not
++ * try to initalize registers the simulator can't handle.
++ *
++ * Note the simulator does not (currently) implement these registers, i.e.,
++ * they do not count anything. But you can read/write them.
++ */
++
++#define RDEP(x) (1UL<<(x))
++
++#ifndef CONFIG_IA64_HP_SIM
++#error "This file should only be included for the HP Simulator"
++#endif
++
++static pfm_reg_desc_t pfm_hpsim_pmc_desc[PMU_MAX_PMCS]={
++/* pmc0 */ { PFM_REG_CONTROL , 0, 0x1UL, -1UL, NULL, NULL, {0UL, 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmc1 */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL, 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmc2 */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL, 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmc3 */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL, 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmc4 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(4), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmc5 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(5), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmc6 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(6), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmc7 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(7), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmc8 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(8), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmc9 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(9), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmc10 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(10), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmc11 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(11), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmc12 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(12), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmc13 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(13), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmc14 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(14), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmc15 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(15), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++ { PFM_REG_END , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */
++};
++
++static pfm_reg_desc_t pfm_hpsim_pmd_desc[PMU_MAX_PMDS]={
++/* pmd0 */ { PFM_REG_BUFFER, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmd1 */ { PFM_REG_BUFFER, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmd2 */ { PFM_REG_BUFFER, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmd3 */ { PFM_REG_BUFFER, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmd4 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(4),0UL, 0UL, 0UL}},
++/* pmd5 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(5),0UL, 0UL, 0UL}},
++/* pmd6 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(6),0UL, 0UL, 0UL}},
++/* pmd7 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(7),0UL, 0UL, 0UL}},
++/* pmd8 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(8),0UL, 0UL, 0UL}},
++/* pmd9 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(9),0UL, 0UL, 0UL}},
++/* pmd10 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}},
++/* pmd11 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
++/* pmd12 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
++/* pmd13 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(13),0UL, 0UL, 0UL}},
++/* pmd14 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(14),0UL, 0UL, 0UL}},
++/* pmd15 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(15),0UL, 0UL, 0UL}},
++ { PFM_REG_END , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */
++};
++
++/*
++ * impl_pmcs, impl_pmds are computed at runtime to minimize errors!
++ */
++static pmu_config_t pmu_conf={
++ .pmu_name = "hpsim",
++ .pmu_family = 0x7, /* ski emulator reports as Itanium */
++ .enabled = 0,
++ .ovfl_val = (1UL << 32) - 1,
++ .num_ibrs = 0, /* does not use */
++ .num_dbrs = 0, /* does not use */
++ .pmd_desc = pfm_hpsim_pmd_desc,
++ .pmc_desc = pfm_hpsim_pmc_desc
++};
+Index: linux-2.6.0-test5/arch/ia64/kernel/salinfo.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/kernel/salinfo.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/kernel/salinfo.c 2003-09-27 11:38:19.439573120 +0800
+@@ -5,6 +5,7 @@
+ *
+ * Copyright (c) 2001 Silicon Graphics, Inc. All rights reserved.
+ *
++ * 09/11/2003 jbarnes@sgi.com updated for 2.6
+ * 10/30/2001 jbarnes@sgi.com copied much of Stephane's palinfo
+ * code to create this file
+ */
+@@ -59,7 +60,7 @@
+ *sdir = create_proc_read_entry (salinfo_entries[i].name, 0, salinfo_dir,
+ salinfo_read, (void *)salinfo_entries[i].feature);
+ if (*sdir)
+- *sdir->owner = THIS_MODULE;
++ (*sdir)->owner = THIS_MODULE;
+ sdir++;
+ }
+ *sdir++ = salinfo_dir;
+Index: linux-2.6.0-test5/arch/ia64/kernel/smpboot.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/kernel/smpboot.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/kernel/smpboot.c 2003-09-27 11:38:19.443572512 +0800
+@@ -534,8 +534,8 @@
+ printk(KERN_INFO "SMP mode deactivated.\n");
+ cpus_clear(cpu_online_map);
+ cpus_clear(phys_cpu_present_map);
+- cpu_set(1, cpu_online_map);
+- cpu_set(1, phys_cpu_present_map);
++ cpu_set(0, cpu_online_map);
++ cpu_set(0, phys_cpu_present_map);
+ return;
+ }
+ }
+Index: linux-2.6.0-test5/arch/ia64/kernel/time.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/kernel/time.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/kernel/time.c 2003-09-27 11:38:19.447571904 +0800
+@@ -17,6 +17,7 @@
+ #include <linux/time.h>
+ #include <linux/interrupt.h>
+ #include <linux/efi.h>
++#include <linux/profile.h>
+ #include <linux/timex.h>
+
+ #include <asm/delay.h>
+@@ -39,29 +40,6 @@
+ #endif
+
+ static void
+-do_profile (unsigned long ip)
+-{
+- extern cpumask_t prof_cpu_mask;
+-
+- if (!prof_buffer)
+- return;
+-
+- if (!cpu_isset(smp_processor_id(), prof_cpu_mask))
+- return;
+-
+- ip -= (unsigned long) _stext;
+- ip >>= prof_shift;
+- /*
+- * Don't ignore out-of-bounds IP values silently, put them into the last
+- * histogram slot, so if present, they will show up as a sharp peak.
+- */
+- if (ip > prof_len - 1)
+- ip = prof_len - 1;
+-
+- atomic_inc((atomic_t *) &prof_buffer[ip]);
+-}
+-
+-static void
+ itc_reset (void)
+ {
+ }
+@@ -199,6 +177,52 @@
+ tv->tv_usec = usec;
+ }
+
++/*
++ * The profiling function is SMP safe. (nothing can mess
++ * around with "current", and the profiling counters are
++ * updated with atomic operations). This is especially
++ * useful with a profiling multiplier != 1
++ */
++static inline void
++ia64_do_profile (struct pt_regs * regs)
++{
++ unsigned long ip, slot;
++ extern cpumask_t prof_cpu_mask;
++
++ profile_hook(regs);
++
++ if (user_mode(regs))
++ return;
++
++ if (!prof_buffer)
++ return;
++
++ ip = instruction_pointer(regs);
++ /* Conserve space in histogram by encoding slot bits in address
++ * bits 2 and 3 rather than bits 0 and 1.
++ */
++ slot = ip & 3;
++ ip = (ip & ~3UL) + 4*slot;
++
++ /*
++ * Only measure the CPUs specified by /proc/irq/prof_cpu_mask.
++ * (default is all CPUs.)
++ */
++ if (!cpu_isset(smp_processor_id(), prof_cpu_mask))
++ return;
++
++ ip -= (unsigned long) &_stext;
++ ip >>= prof_shift;
++ /*
++ * Don't ignore out-of-bounds IP values silently,
++ * put them into the last histogram slot, so if
++ * present, they will show up as a sharp peak.
++ */
++ if (ip > prof_len-1)
++ ip = prof_len-1;
++ atomic_inc((atomic_t *)&prof_buffer[ip]);
++}
++
+ static irqreturn_t
+ timer_interrupt (int irq, void *dev_id, struct pt_regs *regs)
+ {
+@@ -210,14 +234,9 @@
+ printk(KERN_ERR "Oops: timer tick before it's due (itc=%lx,itm=%lx)\n",
+ ia64_get_itc(), new_itm);
+
++ ia64_do_profile(regs);
++
+ while (1) {
+- /*
+- * Do kernel PC profiling here. We multiply the instruction number by
+- * four so that we can use a prof_shift of 2 to get instruction-level
+- * instead of just bundle-level accuracy.
+- */
+- if (!user_mode(regs))
+- do_profile(regs->cr_iip + 4*ia64_psr(regs)->ri);
+
+ #ifdef CONFIG_SMP
+ smp_do_timer(regs);
+Index: linux-2.6.0-test5/arch/ia64/kernel/traps.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/kernel/traps.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/kernel/traps.c 2003-09-27 11:38:19.452571144 +0800
+@@ -568,10 +568,10 @@
+ }
+ siginfo.si_signo = SIGTRAP;
+ siginfo.si_errno = 0;
+- siginfo.si_flags = 0;
+- siginfo.si_isr = 0;
+- siginfo.si_addr = (void *) ifa;
+- siginfo.si_imm = 0;
++ siginfo.si_addr = (void *) ifa;
++ siginfo.si_imm = 0;
++ siginfo.si_flags = __ISR_VALID;
++ siginfo.si_isr = isr;
+ force_sig_info(SIGTRAP, &siginfo, current);
+ return;
+
+Index: linux-2.6.0-test5/arch/ia64/kernel/unwind.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/kernel/unwind.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/kernel/unwind.c 2003-09-27 11:38:19.474567800 +0800
+@@ -1171,9 +1171,10 @@
+ static inline unw_hash_index_t
+ hash (unsigned long ip)
+ {
+-# define magic 0x9e3779b97f4a7c16 /* based on (sqrt(5)/2-1)*2^64 */
++# define hashmagic 0x9e3779b97f4a7c16 /* based on (sqrt(5)/2-1)*2^64 */
+
+- return (ip >> 4)*magic >> (64 - UNW_LOG_HASH_SIZE);
++ return (ip >> 4)*hashmagic >> (64 - UNW_LOG_HASH_SIZE);
++#undef hashmagic
+ }
+
+ static inline long
+Index: linux-2.6.0-test5/arch/ia64/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/Makefile 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/Makefile 2003-09-27 11:38:19.475567648 +0800
+@@ -65,6 +65,7 @@
+ drivers-$(CONFIG_IA64_HP_SIM) += arch/ia64/hp/sim/
+ drivers-$(CONFIG_IA64_HP_ZX1) += arch/ia64/hp/common/ arch/ia64/hp/zx1/
+ drivers-$(CONFIG_IA64_GENERIC) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ arch/ia64/hp/sim/
++drivers-$(CONFIG_OPROFILE) += arch/ia64/oprofile/
+
+ boot := arch/ia64/hp/sim/boot
+
+Index: linux-2.6.0-test5/arch/ia64/mm/discontig.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/mm/discontig.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/mm/discontig.c 2003-09-27 11:38:19.479567040 +0800
+@@ -13,7 +13,6 @@
+ #include <linux/kernel.h>
+ #include <linux/mm.h>
+ #include <linux/bootmem.h>
+-#include <linux/mmzone.h>
+ #include <linux/acpi.h>
+ #include <linux/efi.h>
+
+@@ -23,10 +22,10 @@
+ */
+ #define GRANULEROUNDUP(n) (((n)+IA64_GRANULE_SIZE-1) & ~(IA64_GRANULE_SIZE-1))
+
+-static struct ia64_node_data *node_data[NR_NODES];
+-static long boot_pg_data[8*NR_NODES+sizeof(pg_data_t)] __initdata;
+-static pg_data_t *pg_data_ptr[NR_NODES] __initdata;
+-static bootmem_data_t bdata[NR_NODES][NR_BANKS_PER_NODE+1] __initdata;
++static struct ia64_node_data *node_data[MAX_NUMNODES];
++static long boot_pg_data[8*MAX_NUMNODES+sizeof(pg_data_t)] __initdata;
++static pg_data_t *pg_data_ptr[MAX_NUMNODES] __initdata;
++static bootmem_data_t bdata[MAX_NUMNODES][NR_BANKS_PER_NODE+1] __initdata;
+
+ extern int filter_rsvd_memory (unsigned long start, unsigned long end, void *arg);
+
+Index: linux-2.6.0-test5/arch/ia64/mm/hugetlbpage.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/mm/hugetlbpage.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/mm/hugetlbpage.c 2003-09-27 11:38:19.482566584 +0800
+@@ -297,14 +297,21 @@
+ + (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
+ page = find_get_page(mapping, idx);
+ if (!page) {
++ /* charge the fs quota first */
++ if (hugetlb_get_quota(mapping)) {
++ ret = -ENOMEM;
++ goto out;
++ }
+ page = alloc_hugetlb_page();
+ if (!page) {
++ hugetlb_put_quota(mapping);
+ ret = -ENOMEM;
+ goto out;
+ }
+ ret = add_to_page_cache(page, mapping, idx, GFP_ATOMIC);
+ unlock_page(page);
+ if (ret) {
++ hugetlb_put_quota(mapping);
+ free_huge_page(page);
+ goto out;
+ }
+Index: linux-2.6.0-test5/arch/ia64/mm/numa.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/mm/numa.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/mm/numa.c 2003-09-27 11:38:19.484566280 +0800
+@@ -15,7 +15,6 @@
+ #include <linux/mm.h>
+ #include <linux/init.h>
+ #include <linux/bootmem.h>
+-#include <linux/mmzone.h>
+ #include <asm/numa.h>
+
+ /*
+@@ -29,7 +28,7 @@
+ * This is a matrix with "distances" between nodes, they should be
+ * proportional to the memory access latency ratios.
+ */
+-u8 numa_slit[NR_NODES * NR_NODES];
++u8 numa_slit[MAX_NUMNODES * MAX_NUMNODES];
+
+ /* Identify which cnode a physical address resides on */
+ int
+Index: linux-2.6.0-test5/arch/ia64/oprofile/init.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/oprofile/init.c 2003-09-27 11:38:18.436725576 +0800
++++ linux-2.6.0-test5/arch/ia64/oprofile/init.c 2003-09-27 11:38:19.484566280 +0800
+@@ -0,0 +1,25 @@
++/**
++ * @file init.c
++ *
++ * @remark Copyright 2002 OProfile authors
++ * @remark Read the file COPYING
++ *
++ * @author John Levon <levon@movementarian.org>
++ */
++
++#include <linux/kernel.h>
++#include <linux/oprofile.h>
++#include <linux/init.h>
++#include <linux/errno.h>
++
++extern void timer_init(struct oprofile_operations ** ops);
++
++int __init oprofile_arch_init(struct oprofile_operations ** ops)
++{
++ return -ENODEV;
++}
++
++
++void oprofile_arch_exit(void)
++{
++}
+Index: linux-2.6.0-test5/arch/ia64/oprofile/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/oprofile/Kconfig 2003-09-27 11:38:18.436725576 +0800
++++ linux-2.6.0-test5/arch/ia64/oprofile/Kconfig 2003-09-27 11:38:19.484566280 +0800
+@@ -0,0 +1,22 @@
++
++menu "Profiling support"
++ depends on EXPERIMENTAL
++
++config PROFILING
++ bool "Profiling support (EXPERIMENTAL)"
++ help
++ Say Y here to enable the extended profiling support mechanisms used
++ by profilers such as OProfile.
++
++config OPROFILE
++ tristate "OProfile system profiling (EXPERIMENTAL)"
++ depends on PROFILING
++ help
++ OProfile is a profiling system capable of profiling the
++ whole system, include the kernel, kernel modules, libraries,
++ and applications.
++
++ If unsure, say N.
++
++endmenu
++
+Index: linux-2.6.0-test5/arch/ia64/oprofile/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/oprofile/Makefile 2003-09-27 11:38:18.436725576 +0800
++++ linux-2.6.0-test5/arch/ia64/oprofile/Makefile 2003-09-27 11:38:19.485566128 +0800
+@@ -0,0 +1,9 @@
++obj-$(CONFIG_OPROFILE) += oprofile.o
++
++DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \
++ oprof.o cpu_buffer.o buffer_sync.o \
++ event_buffer.o oprofile_files.o \
++ oprofilefs.o oprofile_stats.o \
++ timer_int.o )
++
++oprofile-y := $(DRIVER_OBJS) init.o
+Index: linux-2.6.0-test5/arch/ia64/scripts/toolchain-flags
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/scripts/toolchain-flags 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/scripts/toolchain-flags 2003-09-27 11:38:19.486565976 +0800
+@@ -20,7 +20,7 @@
+ EOF
+ fi
+
+-if ! $CC -c $dir/check-model.c -o $out 2>&1 | grep -q 'attribute directive ignored'
++if ! $CC -c $dir/check-model.c -o $out 2>&1 | grep __model__ | grep -q attrib
+ then
+ CPPFLAGS="$CPPFLAGS -DHAVE_MODEL_SMALL_ATTRIBUTE"
+ fi
+Index: linux-2.6.0-test5/arch/ia64/sn/io/drivers/ioconfig_bus.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/sn/io/drivers/ioconfig_bus.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/sn/io/drivers/ioconfig_bus.c 2003-09-27 11:38:19.490565368 +0800
+@@ -24,7 +24,7 @@
+ #include <asm/sn/invent.h>
+ #include <asm/sn/hcl.h>
+ #include <asm/sn/labelcl.h>
+-#include <asm//sn/sn_sal.h>
++#include <asm/sn/sn_sal.h>
+ #include <asm/sn/addrs.h>
+ #include <asm/sn/ioconfig_bus.h>
+
+@@ -157,7 +157,7 @@
+ char *name;
+ char *temp;
+ char *next;
+- char *current;
++ char *curr;
+ char *line;
+ struct ascii_moduleid *moduleid;
+
+@@ -166,10 +166,10 @@
+ name = kmalloc(125, GFP_KERNEL);
+ memset(name, 0, 125);
+ moduleid = table;
+- current = file_contents;
+- while (nextline(current, &next, line)){
++ curr = file_contents;
++ while (nextline(curr, &next, line)){
+
+- DBG("current 0x%lx next 0x%lx\n", current, next);
++ DBG("curr 0x%lx next 0x%lx\n", curr, next);
+
+ temp = line;
+ /*
+@@ -182,7 +182,7 @@
+ break;
+
+ if (*temp == '\n') {
+- current = next;
++ curr = next;
+ memset(line, 0, 256);
+ continue;
+ }
+@@ -191,7 +191,7 @@
+ * Skip comment lines
+ */
+ if (*temp == '#') {
+- current = next;
++ curr = next;
+ memset(line, 0, 256);
+ continue;
+ }
+@@ -204,7 +204,7 @@
+ DBG("Found %s\n", name);
+ moduleid++;
+ free_entry++;
+- current = next;
++ curr = next;
+ memset(line, 0, 256);
+ }
+
+Index: linux-2.6.0-test5/arch/ia64/sn/io/machvec/iomv.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/sn/io/machvec/iomv.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/sn/io/machvec/iomv.c 2003-09-27 11:38:19.491565216 +0800
+@@ -6,13 +6,13 @@
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+
+-#include <linux/pci.h>
+ #include <linux/module.h>
+ #include <asm/io.h>
+ #include <asm/delay.h>
+ #include <asm/sn/simulator.h>
+ #include <asm/sn/pda.h>
+ #include <asm/sn/sn_cpuid.h>
++#include <asm/sn/sn2/shub_mmr.h>
+
+ /**
+ * sn_io_addr - convert an in/out port to an i/o address
+Index: linux-2.6.0-test5/arch/ia64/sn/io/machvec/pci_bus_cvlink.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/sn/io/machvec/pci_bus_cvlink.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/sn/io/machvec/pci_bus_cvlink.c 2003-09-27 11:38:19.498564152 +0800
+@@ -544,7 +544,7 @@
+ pci_read_config_byte(device_dev, PCI_INTERRUPT_PIN,
+ (unsigned char *)&lines);
+
+- irqpdaindr->current = device_dev;
++ irqpdaindr->curr = device_dev;
+ intr_handle = pciio_intr_alloc(device_vertex, NULL, lines, device_vertex);
+
+ irq = intr_handle->pi_irq;
+Index: linux-2.6.0-test5/arch/ia64/sn/io/machvec/pci_dma.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/sn/io/machvec/pci_dma.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/sn/io/machvec/pci_dma.c 2003-09-27 11:38:19.504563240 +0800
+@@ -597,7 +597,7 @@
+ if (!sn_dma_supported(dev, dma_mask))
+ return 0;
+
+- dev->dma_mask = dma_mask;
++ *dev->dma_mask = dma_mask;
+ return 1;
+ }
+ EXPORT_SYMBOL(sn_dma_set_mask);
+Index: linux-2.6.0-test5/arch/ia64/sn/io/sn2/ml_SN_intr.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/sn/io/sn2/ml_SN_intr.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/sn/io/sn2/ml_SN_intr.c 2003-09-27 11:38:19.507562784 +0800
+@@ -39,6 +39,7 @@
+ #include <asm/sn/sn2/shubio.h>
+ #include <asm/sal.h>
+ #include <asm/sn/sn_sal.h>
++#include <asm/sn/sn2/shub_mmr.h>
+
+ extern irqpda_t *irqpdaindr;
+ extern cnodeid_t master_node_get(vertex_hdl_t vhdl);
+@@ -174,8 +175,8 @@
+ min_shared = 256;
+ for (i=IA64_SN2_FIRST_DEVICE_VECTOR; i < IA64_SN2_LAST_DEVICE_VECTOR; i++) {
+ /* Share with the same device class */
+- if (irqpdaindr->current->vendor == irqpdaindr->device_dev[i]->vendor &&
+- irqpdaindr->current->device == irqpdaindr->device_dev[i]->device &&
++ if (irqpdaindr->curr->vendor == irqpdaindr->device_dev[i]->vendor &&
++ irqpdaindr->curr->device == irqpdaindr->device_dev[i]->device &&
+ irqpdaindr->share_count[i] < min_shared) {
+ min_shared = irqpdaindr->share_count[i];
+ bit = i;
+Index: linux-2.6.0-test5/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c 2003-09-27 11:38:19.511562176 +0800
+@@ -26,7 +26,6 @@
+ #include <asm/sn/pci/pci_defs.h>
+ #include <asm/sn/prio.h>
+ #include <asm/sn/xtalk/xbow.h>
+-#include <asm/sn/ioc3.h>
+ #include <asm/sn/io.h>
+ #include <asm/sn/sn_private.h>
+
+Index: linux-2.6.0-test5/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c 2003-09-27 11:38:19.514561720 +0800
+@@ -27,7 +27,6 @@
+ #include <asm/sn/pci/pci_defs.h>
+ #include <asm/sn/prio.h>
+ #include <asm/sn/xtalk/xbow.h>
+-#include <asm/sn/ioc3.h>
+ #include <asm/sn/io.h>
+ #include <asm/sn/sn_private.h>
+
+Index: linux-2.6.0-test5/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c 2003-09-27 11:38:19.547556704 +0800
+@@ -31,7 +31,6 @@
+ #include <asm/sn/pci/pci_defs.h>
+ #include <asm/sn/prio.h>
+ #include <asm/sn/xtalk/xbow.h>
+-#include <asm/sn/ioc3.h>
+ #include <asm/sn/io.h>
+ #include <asm/sn/sn_private.h>
+
+Index: linux-2.6.0-test5/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c 2003-09-27 11:38:19.563554272 +0800
+@@ -26,7 +26,6 @@
+ #include <asm/sn/pci/pci_defs.h>
+ #include <asm/sn/prio.h>
+ #include <asm/sn/xtalk/xbow.h>
+-#include <asm/sn/ioc3.h>
+ #include <asm/sn/io.h>
+ #include <asm/sn/sn_private.h>
+
+Index: linux-2.6.0-test5/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c 2003-09-27 11:38:19.565553968 +0800
+@@ -26,7 +26,6 @@
+ #include <asm/sn/pci/pci_defs.h>
+ #include <asm/sn/prio.h>
+ #include <asm/sn/xtalk/xbow.h>
+-#include <asm/sn/ioc3.h>
+ #include <asm/sn/io.h>
+ #include <asm/sn/sn_private.h>
+
+Index: linux-2.6.0-test5/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c 2003-09-27 11:38:19.579551840 +0800
+@@ -26,7 +26,6 @@
+ #include <asm/sn/pci/pci_defs.h>
+ #include <asm/sn/prio.h>
+ #include <asm/sn/xtalk/xbow.h>
+-#include <asm/sn/ioc3.h>
+ #include <asm/sn/io.h>
+ #include <asm/sn/sn_private.h>
+
+Index: linux-2.6.0-test5/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c 2003-09-27 11:38:19.586550776 +0800
+@@ -26,7 +26,6 @@
+ #include <asm/sn/pci/pci_defs.h>
+ #include <asm/sn/prio.h>
+ #include <asm/sn/xtalk/xbow.h>
+-#include <asm/sn/ioc3.h>
+ #include <asm/sn/io.h>
+ #include <asm/sn/sn_private.h>
+
+Index: linux-2.6.0-test5/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c 2003-09-27 11:38:19.602548344 +0800
+@@ -27,7 +27,6 @@
+ #include <asm/sn/pci/pci_defs.h>
+ #include <asm/sn/prio.h>
+ #include <asm/sn/xtalk/xbow.h>
+-#include <asm/sn/ioc3.h>
+ #include <asm/sn/io.h>
+ #include <asm/sn/sn_private.h>
+
+Index: linux-2.6.0-test5/arch/ia64/sn/io/sn2/pic.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/sn/io/sn2/pic.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/sn/io/sn2/pic.c 2003-09-27 11:38:19.605547888 +0800
+@@ -26,7 +26,6 @@
+ #include <asm/sn/pci/pci_defs.h>
+ #include <asm/sn/prio.h>
+ #include <asm/sn/xtalk/xbow.h>
+-#include <asm/sn/ioc3.h>
+ #include <asm/sn/io.h>
+ #include <asm/sn/sn_private.h>
+
+Index: linux-2.6.0-test5/arch/ia64/sn/io/sn2/shub.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/sn/io/sn2/shub.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/sn/io/sn2/shub.c 2003-09-27 11:38:19.610547128 +0800
+@@ -34,6 +34,8 @@
+ #include <asm/sal.h>
+ #include <asm/sn/sn_sal.h>
+ #include <asm/sn/sndrv.h>
++#include <asm/sn/sn2/shubio.h>
++#include <asm/sn/sn2/shub_mmr.h>
+
+ /*
+ * Shub WAR for Xbridge Little Endian problem:
+@@ -491,7 +493,7 @@
+ spin_lock_init(&sn_linkstats_lock);
+ sn_linkstats = kmalloc(numnodes * sizeof(struct s_linkstats), GFP_KERNEL);
+ sn_linkstats_reset(60000UL); /* default 60 second update interval */
+- kernel_thread(linkstatd_thread, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++ kernel_thread(linkstatd_thread, NULL, CLONE_KERNEL);
+
+ return 0;
+ }
+Index: linux-2.6.0-test5/arch/ia64/sn/kernel/irq.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/sn/kernel/irq.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/sn/kernel/irq.c 2003-09-27 11:38:19.613546672 +0800
+@@ -35,7 +35,6 @@
+ #include <linux/init.h>
+ #include <linux/sched.h>
+ #include <linux/vmalloc.h>
+-#include <asm/current.h>
+ #include <linux/irq.h>
+ #include <linux/interrupt.h>
+ #include <linux/slab.h>
+@@ -44,7 +43,6 @@
+ #include <asm/sn/sgi.h>
+ #include <asm/sn/iograph.h>
+ #include <asm/sn/invent.h>
+-#include <linux/devfs_fs_kernel.h>
+ #include <asm/sn/hcl.h>
+ #include <asm/sn/types.h>
+ #include <asm/sn/pci/bridge.h>
+@@ -62,6 +60,7 @@
+ #include <asm/processor.h>
+ #include <asm/system.h>
+ #include <asm/bitops.h>
++#include <asm/sn/sn2/shub_mmr.h>
+
+ int irq_to_bit_pos(int irq);
+ static void force_interrupt(int irq);
+Index: linux-2.6.0-test5/arch/m68k/kernel/signal.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/m68k/kernel/signal.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/m68k/kernel/signal.c 2003-09-27 11:38:19.621545456 +0800
+@@ -1082,7 +1082,7 @@
+ continue;
+
+ case SIGTSTP: case SIGTTIN: case SIGTTOU:
+- if (is_orphaned_pgrp(current->pgrp))
++ if (is_orphaned_pgrp(process_group(current)))
+ continue;
+ /* FALLTHRU */
+
+Index: linux-2.6.0-test5/arch/m68knommu/kernel/signal.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/m68knommu/kernel/signal.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/m68knommu/kernel/signal.c 2003-09-27 11:38:19.628544392 +0800
+@@ -841,7 +841,7 @@
+ continue;
+
+ case SIGTSTP: case SIGTTIN: case SIGTTOU:
+- if (is_orphaned_pgrp(current->pgrp))
++ if (is_orphaned_pgrp(process_group(current)))
+ continue;
+ /* FALLTHRU */
+
+Index: linux-2.6.0-test5/arch/mips/jazz/setup.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/mips/jazz/setup.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/mips/jazz/setup.c 2003-09-27 11:38:19.632543784 +0800
+@@ -9,6 +9,7 @@
+ * Copyright (C) 2001 MIPS Technologies, Inc.
+ */
+ #include <linux/config.h>
++#include <linux/eisa.h>
+ #include <linux/hdreg.h>
+ #include <linux/init.h>
+ #include <linux/ioport.h>
+Index: linux-2.6.0-test5/arch/mips/kernel/irixelf.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/mips/kernel/irixelf.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/mips/kernel/irixelf.c 2003-09-27 11:38:19.641542416 +0800
+@@ -1088,6 +1088,7 @@
+ elf.e_ident[EI_CLASS] = ELFCLASS32;
+ elf.e_ident[EI_DATA] = ELFDATA2LSB;
+ elf.e_ident[EI_VERSION] = EV_CURRENT;
++ elf.e_ident[EI_OSABI] = ELF_OSABI;
+ memset(elf.e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD);
+
+ elf.e_type = ET_CORE;
+@@ -1129,7 +1130,7 @@
+ prstatus.pr_sighold = current->blocked.sig[0];
+ psinfo.pr_pid = prstatus.pr_pid = current->pid;
+ psinfo.pr_ppid = prstatus.pr_ppid = current->parent->pid;
+- psinfo.pr_pgrp = prstatus.pr_pgrp = current->pgrp;
++ psinfo.pr_pgrp = prstatus.pr_pgrp = process_group(current);
+ psinfo.pr_sid = prstatus.pr_sid = current->session;
+ prstatus.pr_utime.tv_sec = CT_TO_SECS(current->utime);
+ prstatus.pr_utime.tv_usec = CT_TO_USECS(current->utime);
+Index: linux-2.6.0-test5/arch/mips/kernel/irixsig.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/mips/kernel/irixsig.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/mips/kernel/irixsig.c 2003-09-27 11:38:19.646541656 +0800
+@@ -582,7 +582,7 @@
+ p = list_entry(_p,struct task_struct,sibling);
+ if ((type == P_PID) && p->pid != pid)
+ continue;
+- if ((type == P_PGID) && p->pgrp != pid)
++ if ((type == P_PGID) && process_group(p) != pid)
+ continue;
+ if ((p->exit_signal != SIGCHLD))
+ continue;
+Index: linux-2.6.0-test5/arch/mips/kernel/linux32.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/mips/kernel/linux32.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/mips/kernel/linux32.c 2003-09-27 11:38:19.658539832 +0800
+@@ -71,14 +71,17 @@
+ {
+ struct compat_stat tmp;
+
++ if (!new_valid_dev(stat->dev) || !new_valid_dev(stat->rdev))
++ return -EOVERFLOW;
++
+ memset(&tmp, 0, sizeof(tmp));
+- tmp.st_dev = stat->dev;
++ tmp.st_dev = new_encode_dev(stat->dev);
+ tmp.st_ino = stat->ino;
+ tmp.st_mode = stat->mode;
+ tmp.st_nlink = stat->nlink;
+ SET_STAT_UID(tmp, stat->uid);
+ SET_STAT_GID(tmp, stat->gid);
+- tmp.st_rdev = stat->rdev;
++ tmp.st_rdev = new_encode_dev(stat->rdev);
+ tmp.st_size = stat->size;
+ tmp.st_atime = stat->atime.tv_sec;
+ tmp.st_mtime = stat->mtime.tv_sec;
+Index: linux-2.6.0-test5/arch/mips/kernel/mips_ksyms.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/mips/kernel/mips_ksyms.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/mips/kernel/mips_ksyms.c 2003-09-27 11:38:19.660539528 +0800
+@@ -43,10 +43,6 @@
+
+ EXPORT_SYMBOL(mips_machtype);
+
+-#ifdef CONFIG_EISA
+-EXPORT_SYMBOL(EISA_bus);
+-#endif
+-
+ /*
+ * String functions
+ */
+Index: linux-2.6.0-test5/arch/mips/kernel/setup.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/mips/kernel/setup.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/mips/kernel/setup.c 2003-09-27 11:38:19.665538768 +0800
+@@ -44,15 +44,6 @@
+ struct screen_info screen_info;
+ #endif
+
+-/*
+- * Set if box has EISA slots.
+- */
+-#ifdef CONFIG_EISA
+-int EISA_bus;
+-
+-EXPORT_SYMBOL(EISA_bus);
+-#endif
+-
+ #if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE)
+ extern struct fd_ops no_fd_ops;
+ struct fd_ops *fd_ops;
+Index: linux-2.6.0-test5/arch/mips/kernel/sysirix.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/mips/kernel/sysirix.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/mips/kernel/sysirix.c 2003-09-27 11:38:19.679536640 +0800
+@@ -803,11 +803,11 @@
+ printk("[%s:%d] setpgrp(%d) ", current->comm, current->pid, flags);
+ #endif
+ if(!flags)
+- error = current->pgrp;
++ error = process_group(current);
+ else
+ error = sys_setsid();
+ #ifdef DEBUG_PROCGRPS
+- printk("returning %d\n", current->pgrp);
++ printk("returning %d\n", process_group(current));
+ #endif
+
+ return error;
+@@ -1187,13 +1187,7 @@
+
+ #undef DEBUG_XSTAT
+
+-static inline u32
+-linux_to_irix_dev_t (dev_t t)
+-{
+- return MAJOR (t) << 18 | MINOR (t);
+-}
+-
+-static inline int irix_xstat32_xlate(struct kstat *stat, void *ubuf)
++static int irix_xstat32_xlate(struct kstat *stat, void *ubuf)
+ {
+ struct xstat32 {
+ u32 st_dev, st_pad1[3], st_ino, st_mode, st_nlink, st_uid, st_gid;
+@@ -1206,13 +1200,15 @@
+ u32 st_pad4[8];
+ } ub;
+
+- ub.st_dev = linux_to_irix_dev_t(stat->dev);
++ if (!sysv_valid_dev(stat->dev) || !sysv_valid_dev(stat->rdev))
++ return -EOVERFLOW;
++ ub.st_dev = sysv_encode_dev(stat->dev);
+ ub.st_ino = stat->ino;
+ ub.st_mode = stat->mode;
+ ub.st_nlink = stat->nlink;
+ SET_STAT_UID(ub, stat->uid);
+ SET_STAT_GID(ub, stat->gid);
+- ub.st_rdev = linux_to_irix_dev_t(stat->rdev);
++ ub.st_rdev = sysv_encode_dev(stat->rdev);
+ #if BITS_PER_LONG == 32
+ if (stat->size > MAX_NON_LFS)
+ return -EOVERFLOW;
+@@ -1231,7 +1227,7 @@
+ return copy_to_user(ubuf, &ub, sizeof(ub)) ? -EFAULT : 0;
+ }
+
+-static inline void irix_xstat64_xlate(struct kstat *stat, void *ubuf)
++static int irix_xstat64_xlate(struct kstat *stat, void *ubuf)
+ {
+ struct xstat64 {
+ u32 st_dev; s32 st_pad1[3];
+@@ -1248,14 +1244,17 @@
+ s32 st_pad4[8];
+ } ks;
+
+- ks.st_dev = linux_to_irix_dev_t(stat->dev);
++ if (!sysv_valid_dev(stat->dev) || !sysv_valid_dev(stat->rdev))
++ return -EOVERFLOW;
++
++ ks.st_dev = sysv_encode_dev(stat->dev);
+ ks.st_pad1[0] = ks.st_pad1[1] = ks.st_pad1[2] = 0;
+ ks.st_ino = (unsigned long long) stat->ino;
+ ks.st_mode = (u32) stat->mode;
+ ks.st_nlink = (u32) stat->nlink;
+ ks.st_uid = (s32) stat->uid;
+ ks.st_gid = (s32) stat->gid;
+- ks.st_rdev = linux_to_irix_dev_t (stat->rdev);
++ ks.st_rdev = sysv_encode_dev (stat->rdev);
+ ks.st_pad2[0] = ks.st_pad2[1] = 0;
+ ks.st_size = (long long) stat->size;
+ ks.st_pad3 = 0;
+@@ -1275,7 +1274,7 @@
+ ks.st_pad4[4] = ks.st_pad4[5] = ks.st_pad4[6] = ks.st_pad4[7] = 0;
+
+ /* Now write it all back. */
+- copy_to_user(ubuf, &ks, sizeof(struct xstat64));
++ return copy_to_user(ubuf, &ub, sizeof(ub)) ? -EFAULT : 0;
+ }
+
+ asmlinkage int irix_xstat(int version, char *filename, struct stat *statbuf)
+@@ -1295,8 +1294,7 @@
+ retval = irix_xstat32_xlate(&stat, statbuf);
+ break;
+ case 3:
+- irix_xstat64_xlate(&stat, statbuf);
+- retval = 0; /* Really? */
++ retval = irix_xstat64_xlate(&stat, statbuf);
+ break;
+ default:
+ retval = -EINVAL;
+@@ -1323,8 +1321,7 @@
+ error = irix_xstat32_xlate(&stat, statbuf);
+ break;
+ case 3:
+- irix_xstat64_xlate(&stat, statbuf);
+- error = 0;
++ error = irix_xstat64_xlate(&stat, statbuf);
+ break;
+ default:
+ error = -EINVAL;
+@@ -1350,8 +1347,7 @@
+ error = irix_xstat32_xlate(&stat, statbuf);
+ break;
+ case 3:
+- irix_xstat64_xlate(&stat, statbuf);
+- error = 0;
++ error = irix_xstat64_xlate(&stat, statbuf);
+ break;
+ default:
+ error = -EINVAL;
+@@ -1360,17 +1356,17 @@
+ return error;
+ }
+
+-extern asmlinkage int sys_mknod(const char * filename, int mode, dev_t dev);
++extern asmlinkage int sys_mknod(const char * filename, int mode, unsigned dev);
+
+-asmlinkage int irix_xmknod(int ver, char *filename, int mode, dev_t dev)
++asmlinkage int irix_xmknod(int ver, char *filename, int mode, unsigned dev)
+ {
+ int retval;
+-
+ printk("[%s:%d] Wheee.. irix_xmknod(%d,%s,%x,%x)\n",
+- current->comm, current->pid, ver, filename, mode, (int) dev);
++ current->comm, current->pid, ver, filename, mode, dev);
+
+ switch(ver) {
+ case 2:
++ /* shouldn't we convert here as well as on stat()? */
+ retval = sys_mknod(filename, mode, dev);
+ break;
+
+Index: linux-2.6.0-test5/arch/mips/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/mips/Makefile 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/mips/Makefile 2003-09-27 11:38:19.685535728 +0800
+@@ -58,7 +58,6 @@
+ cflags-$(CONFIG_KGDB) += -g
+ cflags-$(CONFIG_SB1XXX_CORELIS) += -mno-sched-prolog -fno-omit-frame-pointer
+
+-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_warning = $(shell if $(CC) $(1) -c -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi)
+
+ #
+Index: linux-2.6.0-test5/arch/mips/mm/ioremap.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/mips/mm/ioremap.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/mips/mm/ioremap.c 2003-09-27 11:38:19.687535424 +0800
+@@ -162,7 +162,7 @@
+ if (!area)
+ return NULL;
+ addr = area->addr;
+- if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) {
++ if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
+ vunmap(addr);
+ return NULL;
+ }
+Index: linux-2.6.0-test5/arch/mips/sgi-ip22/ip22-eisa.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/mips/sgi-ip22/ip22-eisa.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/mips/sgi-ip22/ip22-eisa.c 2003-09-27 11:38:19.689535120 +0800
+@@ -20,6 +20,7 @@
+ */
+
+ #include <linux/config.h>
++#include <linux/eisa.h>
+ #include <linux/types.h>
+ #include <linux/init.h>
+ #include <linux/irq.h>
+Index: linux-2.6.0-test5/arch/mips/sni/setup.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/mips/sni/setup.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/mips/sni/setup.c 2003-09-27 11:38:19.691534816 +0800
+@@ -8,6 +8,7 @@
+ * Copyright (C) 1996, 1997, 1998, 2000, 2003 by Ralf Baechle
+ */
+ #include <linux/config.h>
++#include <linux/eisa.h>
+ #include <linux/hdreg.h>
+ #include <linux/ioport.h>
+ #include <linux/sched.h>
+Index: linux-2.6.0-test5/arch/parisc/defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/defconfig 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/defconfig 2003-09-27 11:38:19.695534208 +0800
+@@ -150,24 +150,25 @@
+ CONFIG_SCSI_LASI700=y
+ CONFIG_53C700_MEM_MAPPED=y
+ CONFIG_53C700_LE_ON_BE=y
+-# CONFIG_SCSI_NCR53C7xx is not set
+-# CONFIG_SCSI_SYM53C8XX_2 is not set
++CONFIG_SCSI_SYM53C8XX_2=y
++CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
++CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
++CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
++# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+ CONFIG_SCSI_ZALON=y
+-# CONFIG_SCSI_NCR53C8XX is not set
+-CONFIG_SCSI_SYM53C8XX=y
+ CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
+ CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
+ CONFIG_SCSI_NCR53C8XX_SYNC=20
+ # CONFIG_SCSI_NCR53C8XX_PROFILE is not set
+-# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set
+ # CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set
+ # CONFIG_SCSI_PCI2000 is not set
+ # CONFIG_SCSI_PCI2220I 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_DC395x is not set
+ # CONFIG_SCSI_DC390T is not set
+-# CONFIG_SCSI_U14_34F is not set
+ # CONFIG_SCSI_NSP32 is not set
+ # CONFIG_SCSI_DEBUG is not set
+
+@@ -374,7 +375,6 @@
+ # CONFIG_SERIO_CT82C710 is not set
+ # CONFIG_SERIO_PARKBD is not set
+ CONFIG_HP_SDC=y
+-CONFIG_HIL_MLC=y
+
+ #
+ # Input Device Drivers
+Index: linux-2.6.0-test5/arch/parisc/hpux/fs.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/hpux/fs.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/hpux/fs.c 2003-09-27 11:38:19.697533904 +0800
+@@ -123,14 +123,19 @@
+ {
+ struct hpux_stat64 tmp;
+
++ /* we probably want a different split here - is hpux 12:20? */
++
++ if (!new_valid_dev(stat->dev) || !new_valid_dev(stat->rdev))
++ return -EOVERFLOW;
++
+ memset(&tmp, 0, sizeof(tmp));
+- tmp.st_dev = stat->dev;
++ tmp.st_dev = new_encode_dev(stat->dev);
+ tmp.st_ino = stat->ino;
+ tmp.st_mode = stat->mode;
+ tmp.st_nlink = stat->nlink;
+ tmp.st_uid = stat->uid;
+ tmp.st_gid = stat->gid;
+- tmp.st_rdev = stat->rdev;
++ tmp.st_rdev = new_encode_dev(stat->rdev);
+ tmp.st_size = stat->size;
+ tmp.st_atime = stat->atime.tv_sec;
+ tmp.st_mtime = stat->mtime.tv_sec;
+Index: linux-2.6.0-test5/arch/parisc/hpux/sys_hpux.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/hpux/sys_hpux.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/hpux/sys_hpux.c 2003-09-27 11:38:19.704532840 +0800
+@@ -272,7 +272,7 @@
+ break ;
+ case 2:
+ /* ustat(): */
+- return( hpux_ustat((dev_t)n, (struct hpux_ustat *)ubuf) );
++ return( hpux_ustat(new_decode_dev(n), (struct hpux_ustat *)ubuf) );
+ break ;
+ case 3:
+ /* setuname():
+Index: linux-2.6.0-test5/arch/parisc/hpux/wrappers.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/hpux/wrappers.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/hpux/wrappers.S 2003-09-27 11:38:19.707532384 +0800
+@@ -21,17 +21,20 @@
+ */
+
+ #ifdef __LP64__
+-#warning Must be changed for PA64
++#warning PA64 support needs more work...did first cut
+ #endif
+
+ #include <asm/offsets.h>
++#include <asm/assembly.h>
++#include <asm/signal.h>
+
++#ifdef __LP64__
++ .level 2.0w
++#else
+ .level 1.1
++#endif
+ .text
+
+-#include <asm/assembly.h>
+-#include <asm/signal.h>
+-
+ /* These should probably go in a header file somewhere.
+ * They are duplicated in kernel/wrappers.S
+ * Possibly we should consider consolidating these
+@@ -41,41 +44,41 @@
+ #ifdef __LP64__
+ #warning NEEDS WORK for 64-bit
+ #endif
+- stw %r3, PT_GR3(\regs)
+- stw %r4, PT_GR4(\regs)
+- stw %r5, PT_GR5(\regs)
+- stw %r6, PT_GR6(\regs)
+- stw %r7, PT_GR7(\regs)
+- stw %r8, PT_GR8(\regs)
+- stw %r9, PT_GR9(\regs)
+- stw %r10,PT_GR10(\regs)
+- stw %r11,PT_GR11(\regs)
+- stw %r12,PT_GR12(\regs)
+- stw %r13,PT_GR13(\regs)
+- stw %r14,PT_GR14(\regs)
+- stw %r15,PT_GR15(\regs)
+- stw %r16,PT_GR16(\regs)
+- stw %r17,PT_GR17(\regs)
+- stw %r18,PT_GR18(\regs)
++ STREG %r3, PT_GR3(\regs)
++ STREG %r4, PT_GR4(\regs)
++ STREG %r5, PT_GR5(\regs)
++ STREG %r6, PT_GR6(\regs)
++ STREG %r7, PT_GR7(\regs)
++ STREG %r8, PT_GR8(\regs)
++ STREG %r9, PT_GR9(\regs)
++ STREG %r10,PT_GR10(\regs)
++ STREG %r11,PT_GR11(\regs)
++ STREG %r12,PT_GR12(\regs)
++ STREG %r13,PT_GR13(\regs)
++ STREG %r14,PT_GR14(\regs)
++ STREG %r15,PT_GR15(\regs)
++ STREG %r16,PT_GR16(\regs)
++ STREG %r17,PT_GR17(\regs)
++ STREG %r18,PT_GR18(\regs)
+ .endm
+
+ .macro reg_restore regs
+- ldw PT_GR3(\regs), %r3
+- ldw PT_GR4(\regs), %r4
+- ldw PT_GR5(\regs), %r5
+- ldw PT_GR6(\regs), %r6
+- ldw PT_GR7(\regs), %r7
+- ldw PT_GR8(\regs), %r8
+- ldw PT_GR9(\regs), %r9
+- ldw PT_GR10(\regs),%r10
+- ldw PT_GR11(\regs),%r11
+- ldw PT_GR12(\regs),%r12
+- ldw PT_GR13(\regs),%r13
+- ldw PT_GR14(\regs),%r14
+- ldw PT_GR15(\regs),%r15
+- ldw PT_GR16(\regs),%r16
+- ldw PT_GR17(\regs),%r17
+- ldw PT_GR18(\regs),%r18
++ LDREG PT_GR3(\regs), %r3
++ LDREG PT_GR4(\regs), %r4
++ LDREG PT_GR5(\regs), %r5
++ LDREG PT_GR6(\regs), %r6
++ LDREG PT_GR7(\regs), %r7
++ LDREG PT_GR8(\regs), %r8
++ LDREG PT_GR9(\regs), %r9
++ LDREG PT_GR10(\regs),%r10
++ LDREG PT_GR11(\regs),%r11
++ LDREG PT_GR12(\regs),%r12
++ LDREG PT_GR13(\regs),%r13
++ LDREG PT_GR14(\regs),%r14
++ LDREG PT_GR15(\regs),%r15
++ LDREG PT_GR16(\regs),%r16
++ LDREG PT_GR17(\regs),%r17
++ LDREG PT_GR18(\regs),%r18
+ .endm
+
+
+@@ -88,18 +91,18 @@
+ ;! pointer in task
+ reg_save %r1
+
+- stw %r2,-20(%r30)
++ STREG %r2,-20(%r30)
+ ldo 64(%r30),%r30
+- stw %r2,PT_GR19(%r1) ;! save for child
+- stw %r30,PT_GR21(%r1) ;! save for child
++ STREG %r2,PT_GR19(%r1) ;! save for child
++ STREG %r30,PT_GR21(%r1) ;! save for child
+
+- ldw PT_GR30(%r1),%r25
+- mtctl %r25,%cr29
++ LDREG PT_GR30(%r1),%r25
++ mtctl %r25,%cr29
+ copy %r1,%r24
+ bl sys_clone,%r2
+ ldi SIGCHLD,%r26
+
+- ldw -84(%r30),%r2
++ LDREG -84(%r30),%r2
+ fork_return:
+ ldo -64(%r30),%r30
+ ldo TASK_REGS-TASK_SZ_ALGN-64(%r30),%r1 ;! get pt regs
+@@ -116,14 +119,14 @@
+ * know the difference. We can fix this later if necessary.
+ */
+
+- ldo -1024(%r0),%r1
++ ldo -1024(%r0),%r1
+ comb,>>=,n %r28,%r1,fork_exit /* just let the syscall exit handle it */
+- or,= %r28,%r0,%r0
+- or,tr %r0,%r0,%r29 /* r28 <> 0, we are parent, set r29 to 0 */
+- ldo 1(%r0),%r29 /* r28 == 0, we are child, set r29 to 1 */
++ or,= %r28,%r0,%r0
++ or,tr %r0,%r0,%r29 /* r28 <> 0, we are parent, set r29 to 0 */
++ ldo 1(%r0),%r29 /* r28 == 0, we are child, set r29 to 1 */
+
+ fork_exit:
+- bv %r0(%r2)
++ bv %r0(%r2)
+ nop
+
+ /* Set the return value for the child */
+@@ -134,7 +137,7 @@
+ nop
+ #endif
+
+- ldw TASK_PT_GR19-TASK_SZ_ALGN-128(%r30),%r2
++ LDREG TASK_PT_GR19-TASK_SZ_ALGN-128(%r30),%r2
+ b fork_return
+ copy %r0,%r28
+
+@@ -157,17 +160,17 @@
+
+ /* Store arg0, arg1 and arg2 so that hpux_execve will find them */
+
+- stw %r26,PT_GR26(%r1)
+- stw %r25,PT_GR25(%r1)
+- stw %r24,PT_GR24(%r1)
++ STREG %r26,PT_GR26(%r1)
++ STREG %r25,PT_GR25(%r1)
++ STREG %r24,PT_GR24(%r1)
+
+- stw %r2,-20(%r30)
++ STREG %r2,-20(%r30)
+ ldo 64(%r30),%r30
+ bl hpux_execve,%r2
+ copy %r1,%arg0
+
+ ldo -64(%r30),%r30
+- ldw -20(%r30),%r2
++ LDREG -20(%r30),%r2
+
+ /* If exec succeeded we need to load the args */
+
+@@ -175,10 +178,10 @@
+ comb,>>= %r28,%r1,exec_error
+ copy %r2,%r19
+ ldo -TASK_SZ_ALGN-64(%r30),%r1 ;! get task ptr
+- ldw TASK_PT_GR26(%r1),%r26
+- ldw TASK_PT_GR25(%r1),%r25
+- ldw TASK_PT_GR24(%r1),%r24
+- ldw TASK_PT_GR23(%r1),%r23
++ LDREG TASK_PT_GR26(%r1),%r26
++ LDREG TASK_PT_GR25(%r1),%r25
++ LDREG TASK_PT_GR24(%r1),%r24
++ LDREG TASK_PT_GR23(%r1),%r23
+ copy %r0,%r2 /* Flag to syscall_exit not to clear args */
+
+ exec_error:
+@@ -191,7 +194,7 @@
+ /* HP-UX expects pipefd's returned in r28 & r29 */
+
+ hpux_pipe_wrapper:
+- stw %r2,-20(%r30)
++ STREG %r2,-20(%r30)
+ ldo 64(%r30),%r30
+ bl hpux_pipe,%r2
+ ldo -56(%r30),%r26 /* pass local array to hpux_pipe */
+@@ -199,12 +202,12 @@
+
+ ldo -1024(%r0),%r1
+ comb,>>= %r28,%r1,pipe_exit /* let syscall exit handle it */
+- ldw -84(%r30),%r2
++ LDREG -84(%r30),%r2
+
+ /* if success, load fd's from stack array */
+
+- ldw -56(%r30),%r28
+- ldw -52(%r30),%r29
++ LDREG -56(%r30),%r28
++ LDREG -52(%r30),%r29
+
+ pipe_exit:
+ bv %r0(%r2)
+@@ -251,4 +254,4 @@
+
+ hpux_unimplemented_wrapper:
+ b hpux_unimplemented
+- stw %r22,-64(%r30) /* overwrite arg8 with syscall number */
++ STREG %r22,-64(%r30) /* overwrite arg8 with syscall number */
+Index: linux-2.6.0-test5/arch/parisc/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/Kconfig 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/Kconfig 2003-09-27 11:38:19.709532080 +0800
+@@ -184,7 +184,7 @@
+
+ source "drivers/md/Kconfig"
+
+-#source drivers/message/fusion/Kconfig
++source drivers/message/fusion/Kconfig
+
+ #source drivers/ieee1394/Kconfig
+
+Index: linux-2.6.0-test5/arch/parisc/kernel/cache.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/kernel/cache.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/kernel/cache.c 2003-09-27 11:38:19.712531624 +0800
+@@ -232,7 +232,8 @@
+
+ if (!page->mapping)
+ return;
+-
++ /* check shared list first if it's not empty...it's usually
++ * the shortest */
+ list_for_each(l, &page->mapping->i_mmap_shared) {
+ struct vm_area_struct *mpnt;
+ unsigned long off;
+@@ -257,6 +258,33 @@
+ /* All user shared mappings should be equivalently mapped,
+ * so once we've flushed one we should be ok
+ */
++ return;
++ }
++
++ /* then check private mapping list for read only shared mappings
++ * which are flagged by VM_MAYSHARE */
++ list_for_each(l, &page->mapping->i_mmap) {
++ struct vm_area_struct *mpnt;
++ unsigned long off;
++
++ mpnt = list_entry(l, struct vm_area_struct, shared);
++
++
++ if (mpnt->vm_mm != mm || !(mpnt->vm_flags & VM_MAYSHARE))
++ continue;
++
++ if (page->index < mpnt->vm_pgoff)
++ continue;
++
++ off = page->index - mpnt->vm_pgoff;
++ if (off >= (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT)
++ continue;
++
++ flush_cache_page(mpnt, mpnt->vm_start + (off << PAGE_SHIFT));
++
++ /* All user shared mappings should be equivalently mapped,
++ * so once we've flushed one we should be ok
++ */
+ break;
+ }
+ }
+Index: linux-2.6.0-test5/arch/parisc/kernel/drivers.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/kernel/drivers.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/kernel/drivers.c 2003-09-27 11:38:19.717530864 +0800
+@@ -447,7 +447,7 @@
+ #define MAX_NATIVE_DEVICES 64
+ #define NATIVE_DEVICE_OFFSET 0x1000
+
+-#define FLEX_MASK (unsigned long)0xfffffffffffc0000
++#define FLEX_MASK F_EXTEND(0xfffc0000)
+ #define IO_IO_LOW offsetof(struct bc_module, io_io_low)
+ #define IO_IO_HIGH offsetof(struct bc_module, io_io_high)
+ #define READ_IO_IO_LOW(dev) (unsigned long)(signed int)__raw_readl(dev->hpa + IO_IO_LOW)
+@@ -514,7 +514,7 @@
+ } while(!devices_found && hpa < io_io_high);
+ }
+
+-#define CENTRAL_BUS_ADDR (unsigned long) 0xfffffffffff80000
++#define CENTRAL_BUS_ADDR F_EXTEND(0xfff80000)
+
+ /**
+ * walk_central_bus - Find devices attached to the central bus
+Index: linux-2.6.0-test5/arch/parisc/kernel/irq.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/kernel/irq.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/kernel/irq.c 2003-09-27 11:38:19.723529952 +0800
+@@ -22,7 +22,7 @@
+ */
+ #include <linux/bitops.h>
+ #include <linux/config.h>
+-#include <asm/pdc.h>
++#include <linux/eisa.h>
+ #include <linux/errno.h>
+ #include <linux/init.h>
+ #include <linux/signal.h>
+@@ -39,6 +39,7 @@
+ #include <linux/spinlock.h>
+
+ #include <asm/cache.h>
++#include <asm/pdc.h>
+
+ #undef DEBUG_IRQ
+ #undef PARISC_IRQ_CR16_COUNTS
+@@ -842,6 +843,10 @@
+ return irq_found;
+ }
+
++unsigned int probe_irq_mask(unsigned long irqs)
++{
++ return 0;
++}
+
+ void __init init_IRQ(void)
+ {
+Index: linux-2.6.0-test5/arch/parisc/kernel/module.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/kernel/module.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/kernel/module.c 2003-09-27 11:38:19.729529040 +0800
+@@ -41,6 +41,13 @@
+ return -ENOEXEC; \
+ }
+
++/* Maximum number of GOT entries. We use a long displacement ldd from
++ * the bottom of the table, which has a maximum signed displacement of
++ * 0x3fff; however, since we're only going forward, this becomes
++ * 0x1fff, and thus, since each GOT entry is 8 bytes long we can have
++ * at most 1023 entries */
++#define MAX_GOTS 1023
++
+ /* three functions to determine where in the module core
+ * or init pieces the location is */
+ static inline int is_init(struct module *me, void *loc)
+@@ -300,11 +307,14 @@
+ got = me->module_core + me->arch.got_offset;
+ for (i = 0; got[i].addr; i++)
+ if (got[i].addr == value)
+- return i * sizeof(struct got_entry);
++ goto out;
+
+ BUG_ON(++me->arch.got_count > me->arch.got_max);
+
+ got[i].addr = value;
++ out:
++ DEBUGP("GOT ENTRY %d[%x] val %lx\n", i, i*sizeof(struct got_entry),
++ value);
+ return i * sizeof(struct got_entry);
+ }
+ #endif /* __LP64__ */
+@@ -387,7 +397,7 @@
+ stub->insns[2] = 0xe820d000; /* bve (%r1) */
+ stub->insns[3] = 0x537b0030; /* ldd 18(%dp),%dp */
+
+- stub->insns[0] |= reassemble_14(rrsel(get_got(me, value, addend),0));
++ stub->insns[0] |= reassemble_14(get_got(me, value, addend) & 0x3fff);
+ }
+ else
+ {
+@@ -516,6 +526,9 @@
+ case R_PARISC_PCREL22F:
+ /* 22-bit PC relative address; only defined for pa20 */
+ val = get_stub(me, val, addend, 0, is_init(me, loc));
++ DEBUGP("STUB FOR %s loc %lx+%lx at %lx\n",
++ strtab + sym->st_name, (unsigned long)loc, addend,
++ val)
+ val = (val - dot - 8)/4;
+ CHECK_RELOC(val, 22);
+ *loc = (*loc & ~0x3ff1ffd) | reassemble_22(val);
+@@ -618,6 +631,9 @@
+ val = get_stub(me, val, addend, 0,
+ is_init(me, loc));
+ }
++ DEBUGP("STUB FOR %s loc %lx, val %lx+%lx at %lx\n",
++ strtab + sym->st_name, loc, sym->st_value,
++ addend, val);
+ /* FIXME: local symbols work as long as the
+ * core and init pieces aren't separated too
+ * far. If this is ever broken, you will trip
+@@ -646,6 +662,9 @@
+ /* 64-bit function address */
+ if(is_local(me, (void *)(val + addend))) {
+ *loc64 = get_fdesc(me, val+addend);
++ DEBUGP("FDESC for %s at %p points to %lx\n",
++ strtab + sym->st_name, *loc64,
++ ((struct fdesc_entry *)*loc64)->addr);
+ } else {
+ /* if the symbol is not local to this
+ * module then val+addend is a pointer
+@@ -711,8 +730,13 @@
+ }
+ }
+
+- printk("module %s: strtab %p, symhdr %p\n",
++ DEBUGP("module %s: strtab %p, symhdr %p\n",
+ me->name, strtab, symhdr);
++
++ if(me->arch.got_count > MAX_GOTS) {
++ printk(KERN_ERR "%s: Global Offset Table overflow (used %ld, allowed %d\n", me->name, me->arch.got_count, MAX_GOTS);
++ return -EINVAL;
++ }
+
+ /* no symbol table */
+ if(symhdr == NULL)
+Index: linux-2.6.0-test5/arch/parisc/kernel/parisc_ksyms.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/kernel/parisc_ksyms.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/kernel/parisc_ksyms.c 2003-09-27 11:38:19.731528736 +0800
+@@ -37,13 +37,11 @@
+ #include <asm/irq.h>
+ EXPORT_SYMBOL(enable_irq);
+ EXPORT_SYMBOL(disable_irq);
++EXPORT_SYMBOL(probe_irq_mask);
+
+ #include <asm/processor.h>
+ EXPORT_SYMBOL(kernel_thread);
+ EXPORT_SYMBOL(boot_cpu_data);
+-#ifdef CONFIG_EISA
+-EXPORT_SYMBOL(EISA_bus);
+-#endif
+
+ #include <linux/pm.h>
+ EXPORT_SYMBOL(pm_power_off);
+@@ -201,6 +199,9 @@
+ EXPORT_SYMBOL(__lshrdi3);
+ EXPORT_SYMBOL(__muldi3);
+
++asmlinkage void * __canonicalize_funcptr_for_compare(void *);
++EXPORT_SYMBOL(__canonicalize_funcptr_for_compare);
++
+ #ifdef __LP64__
+ extern void __divdi3(void);
+ extern void __udivdi3(void);
+Index: linux-2.6.0-test5/arch/parisc/kernel/pci.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/kernel/pci.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/kernel/pci.c 2003-09-27 11:38:19.736527976 +0800
+@@ -10,6 +10,7 @@
+ * Copyright (C) 1999-2001 Grant Grundler
+ */
+ #include <linux/config.h>
++#include <linux/eisa.h>
+ #include <linux/init.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+@@ -25,7 +26,7 @@
+ #define DEBUG_CONFIG 0
+
+ #if DEBUG_CONFIG
+-# define DBGC(x...) printk(KERN_DEBUG x)
++# define DBGC(x...) printk(KERN_DEBUG x)
+ #else
+ # define DBGC(x...)
+ #endif
+@@ -38,13 +39,15 @@
+ #endif
+
+ /* To be used as: mdelay(pci_post_reset_delay);
+-**
+-** post_reset is the time the kernel should stall to prevent anyone from
+-** accessing the PCI bus once #RESET is de-asserted.
+-** PCI spec somewhere says 1 second but with multi-PCI bus systems,
+-** this makes the boot time much longer than necessary.
+-** 20ms seems to work for all the HP PCI implementations to date.
+-*/
++ *
++ * post_reset is the time the kernel should stall to prevent anyone from
++ * accessing the PCI bus once #RESET is de-asserted.
++ * PCI spec somewhere says 1 second but with multi-PCI bus systems,
++ * this makes the boot time much longer than necessary.
++ * 20ms seems to work for all the HP PCI implementations to date.
++ *
++ * XXX: turn into a #defined constant in <asm/pci.h> ?
++ */
+ int pci_post_reset_delay = 50;
+
+ struct pci_port_ops *pci_port;
+@@ -52,9 +55,7 @@
+
+ int pci_hba_count = 0;
+
+-/*
+-** parisc_pci_hba used by pci_port->in/out() ops to lookup bus data.
+-*/
++/* parisc_pci_hba used by pci_port->in/out() ops to lookup bus data. */
+ #define PCI_HBA_MAX 32
+ struct pci_hba_data *parisc_pci_hba[PCI_HBA_MAX];
+
+@@ -129,8 +130,6 @@
+ /* Called from pci_do_scan_bus() *after* walking a bus but before walking PPBs. */
+ void pcibios_fixup_bus(struct pci_bus *bus)
+ {
+- ASSERT(pci_bios != NULL);
+-
+ if (pci_bios->fixup_bus) {
+ pci_bios->fixup_bus(bus);
+ } else {
+@@ -145,64 +144,26 @@
+ }
+
+
+-/*
+-** Used in drivers/pci/quirks.c
+-*/
++/* Used in drivers/pci/quirks.c */
+ struct pci_fixup pcibios_fixups[] = { {0} };
+
+
+ /*
+-** called by drivers/pci/setup.c:pdev_fixup_irq()
+-*/
+-void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
+-{
+-/*
+-** updates IRQ_LINE cfg register to reflect PCI-PCI bridge skewing.
+-**
+-** Calling path for Alpha is:
+-** alpha/kernel/pci.c:common_init_pci(swizzle_func, pci_map_irq_func )
+-** drivers/pci/setup.c:pci_fixup_irqs()
+-** drivers/pci/setup.c:pci_fixup_irq() (for each PCI device)
+-** invoke swizzle and map functions
+-** alpha/kernel/pci.c:pcibios_update_irq()
+-**
+-** Don't need this for PA legacy PDC systems.
+-**
+-** On PAT PDC systems, We only support one "swizzle" for any number
+-** of PCI-PCI bridges deep. That's how bit3 PCI expansion chassis
+-** are implemented. The IRQ lines are "skewed" for all devices but
+-** *NOT* routed through the PCI-PCI bridge. Ie any device "0" will
+-** share an IRQ line. Legacy PDC is expecting this IRQ line routing
+-** as well.
+-**
+-** Unfortunately, PCI spec allows the IRQ lines to be routed
+-** around the PCI bridge as long as the IRQ lines are skewed
+-** based on the device number...<sigh>...
+-**
+-** Lastly, dino.c might be able to use pci_fixup_irq() to
+-** support RS-232 and PS/2 children. Not sure how but it's
+-** something to think about.
+-*/
+-}
+-
+-
+-/*
+-** Called by pci_set_master() - a driver interface.
+-**
+-** Legacy PDC guarantees to set:
+-** Map Memory BAR's into PA IO space.
+-** Map Expansion ROM BAR into one common PA IO space per bus.
+-** Map IO BAR's into PCI IO space.
+-** Command (see below)
+-** Cache Line Size
+-** Latency Timer
+-** Interrupt Line
+-** PPB: secondary latency timer, io/mmio base/limit,
+-** bus numbers, bridge control
+-**
+-*/
+-void
+-pcibios_set_master(struct pci_dev *dev)
++ * Called by pci_set_master() - a driver interface.
++ *
++ * Legacy PDC guarantees to set:
++ * Map Memory BAR's into PA IO space.
++ * Map Expansion ROM BAR into one common PA IO space per bus.
++ * Map IO BAR's into PCI IO space.
++ * Command (see below)
++ * Cache Line Size
++ * Latency Timer
++ * Interrupt Line
++ * PPB: secondary latency timer, io/mmio base/limit,
++ * bus numbers, bridge control
++ *
++ */
++void pcibios_set_master(struct pci_dev *dev)
+ {
+ u8 lat;
+
+@@ -214,43 +175,36 @@
+ ** HP generally has fewer devices on the bus than other architectures.
+ ** upper byte is PCI_LATENCY_TIMER.
+ */
+- pci_write_config_word(dev, PCI_CACHE_LINE_SIZE,
++ pci_write_config_word(dev, PCI_CACHE_LINE_SIZE,
+ (0x80 << 8) | (L1_CACHE_BYTES / sizeof(u32)));
+ }
+
+
+-void __init
+-pcibios_init_bus(struct pci_bus *bus)
++void __init pcibios_init_bus(struct pci_bus *bus)
+ {
+ struct pci_dev *dev = bus->self;
++ unsigned short bridge_ctl;
+
+ /* We deal only with pci controllers and pci-pci bridges. */
+- if (dev && (dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
++ if (!dev || (dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
+ return;
+-
+- if (dev) {
+- unsigned short bridge_ctl;
+-
+- /* PCI-PCI bridge - set the cache line and default latency
+- (32) for primary and secondary buses. */
+- pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 32);
+-
+- /* Read bridge control */
+- pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &bridge_ctl);
+- pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bridge_ctl
+- | PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR);
+
+- }
++ /* PCI-PCI bridge - set the cache line and default latency
++ (32) for primary and secondary buses. */
++ pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 32);
++
++ pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &bridge_ctl);
++ bridge_ctl |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR;
++ pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bridge_ctl);
+ }
+
+
+-/*
+-** KLUGE: Link the child and parent resources - generic PCI didn't
+-*/
++/* KLUGE: Link the child and parent resources - generic PCI didn't */
+ static void
+ pcibios_link_hba_resources( struct resource *hba_res, struct resource *r)
+ {
+ if (!r->parent) {
++ printk(KERN_EMERG "PCI: Tell willy he's wrong\n");
+ r->parent = hba_res;
+
+ /* reverse link is harder *sigh* */
+@@ -268,14 +222,9 @@
+ }
+ }
+
+-/*
+-** called by drivers/pci/setup-res.c:pci_setup_bridge().
+-*/
+-void __devinit pcibios_resource_to_bus(
+- struct pci_dev *dev,
+- struct pci_bus_region *region,
+- struct resource *res
+- )
++/* called by drivers/pci/setup-bus.c:pci_setup_bridge(). */
++void __devinit pcibios_resource_to_bus(struct pci_dev *dev,
++ struct pci_bus_region *region, struct resource *res)
+ {
+ struct pci_bus *bus = dev->bus;
+ struct pci_hba_data *hba = HBA_DATA(bus->dev->platform_data);
+@@ -313,17 +262,16 @@
+ #endif
+
+ /*
+-** pcibios align resources() is called everytime generic PCI code
+-** wants to generate a new address. The process of looking for
+-** an available address, each candidate is first "aligned" and
+-** then checked if the resource is available until a match is found.
+-**
+-** Since we are just checking candidates, don't use any fields other
+-** than res->start.
+-*/
+-void __devinit
+-pcibios_align_resource(void *data, struct resource *res,
+- unsigned long size, unsigned long alignment)
++ * pcibios align resources() is called every time generic PCI code
++ * wants to generate a new address. The process of looking for
++ * an available address, each candidate is first "aligned" and
++ * then checked if the resource is available until a match is found.
++ *
++ * Since we are just checking candidates, don't use any fields other
++ * than res->start.
++ */
++void pcibios_align_resource(void *data, struct resource *res,
++ unsigned long size, unsigned long alignment)
+ {
+ unsigned long mask, align;
+
+@@ -332,10 +280,6 @@
+ res->parent, res->start, res->end,
+ (int) res->flags, size, alignment);
+
+- /* has resource already been aligned/assigned? */
+- if (res->parent)
+- return;
+-
+ /* If it's not IO, then it's gotta be MEM */
+ align = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
+
+@@ -344,32 +288,26 @@
+ res->start += mask;
+ res->start &= ~mask;
+
+- /*
+- ** WARNING : caller is expected to update "end" field.
+- ** We can't since it might really represent the *size*.
+- ** The difference is "end = start + size" vs "end += start".
+- */
++ /* The caller updates the end field, we don't. */
+ }
+
+
+-int __devinit
+-pcibios_enable_device(struct pci_dev *dev, int mask)
++/*
++ * A driver is enabling the device. We make sure that all the appropriate
++ * bits are set to allow the device to operate as the driver is expecting.
++ * We enable the port IO and memory IO bits if the device has any BARs of
++ * that type, and we enable the PERR and SERR bits unconditionally.
++ * Drivers that do not need parity (eg graphics and possibly networking)
++ * can clear these bits if they want.
++ */
++int pcibios_enable_device(struct pci_dev *dev, int mask)
+ {
+ u16 cmd;
+ int idx;
+
+- /*
+- ** The various platform PDC's (aka "BIOS" for PCs) don't
+- ** enable all the same bits. We just make sure they are here.
+- */
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
+
+- /*
+- ** See if any resources have been allocated
+- ** While "regular" PCI devices only use 0-5, Bridges use a few
+- ** beyond that for window registers.
+- */
+- for (idx=0; idx<DEVICE_COUNT_RESOURCE; idx++) {
++ for (idx = 0; idx < DEVICE_COUNT_RESOURCE; idx++) {
+ struct resource *r = &dev->resource[idx];
+
+ /* only setup requested resources */
+@@ -382,14 +320,6 @@
+ cmd |= PCI_COMMAND_MEMORY;
+ }
+
+- /*
+- ** Enable System error and Parity Error reporting by default.
+- ** Devices that do NOT want those behaviors should clear them
+- ** (eg PCI graphics, possibly networking).
+- ** Interfaces like SCSI certainly should not. We want the
+- ** system to crash if a system or parity error is detected.
+- ** At least until the device driver can recover from such an error.
+- */
+ cmd |= (PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
+
+ #if 0
+@@ -402,30 +332,15 @@
+ return 0;
+ }
+
+-void __init
+-pcibios_setup_host_bridge(struct pci_bus *bus)
+-{
+- ASSERT(pci_bios != NULL);
+
+-#if 0
+- if (pci_bios)
+- {
+- if (pci_bios->setup_host_bridge) {
+- (*pci_bios->setup_host_bridge)(bus);
+- }
+- }
+-#endif
+-}
+-
+-
+-/*
+-** PARISC specific (unfortunately)
+-*/
++/* PA-RISC specific */
+ void pcibios_register_hba(struct pci_hba_data *hba)
+ {
+- ASSERT(pci_hba_count < PCI_HBA_MAX);
++ if (pci_hba_count >= PCI_HBA_MAX) {
++ printk(KERN_ERR "PCI: Too many Host Bus Adapters\n");
++ return;
++ }
+
+- /* pci_port->in/out() uses parisc_pci_hba to lookup parameter. */
+ parisc_pci_hba[pci_hba_count] = hba;
+ hba->hba_num = pci_hba_count++;
+ }
+Index: linux-2.6.0-test5/arch/parisc/kernel/process.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/kernel/process.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/kernel/process.c 2003-09-27 11:38:19.738527672 +0800
+@@ -19,7 +19,6 @@
+ #include <linux/sched.h>
+ #include <linux/stddef.h>
+ #include <linux/unistd.h>
+-#include <linux/version.h>
+
+ #include <asm/io.h>
+ #include <asm/offsets.h>
+Index: linux-2.6.0-test5/arch/parisc/kernel/real2.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/kernel/real2.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/kernel/real2.S 2003-09-27 11:38:19.740527368 +0800
+@@ -123,7 +123,7 @@
+ nop
+
+ restore_control_regs:
+- load32 PA(save_cr_space + (N_SAVED_REGS * REG_SZ)), %r26
++ load32 PA(save_cr_space+(N_SAVED_REGS*REG_SZ)), %r26
+ POP_CR(%cr15, %r26)
+ POP_CR(%cr31, %r26)
+ POP_CR(%cr30, %r26)
+@@ -275,6 +275,7 @@
+ nop
+
+ #endif
++
+ .export pc_in_user_space
+ .text
+ /* Doesn't belong here but I couldn't find a nicer spot. */
+@@ -283,3 +284,17 @@
+ bv,n 0(%rp)
+ nop
+
++
++ .export __canonicalize_funcptr_for_compare
++ .text
++ /* http://lists.parisc-linux.org/hypermail/parisc-linux/10916.html
++ ** GCC 3.3 and later has a new function in libgcc.a for
++ ** comparing function pointers.
++ */
++__canonicalize_funcptr_for_compare:
++#ifdef __LP64__
++ bve (%r2)
++#else
++ bv %r0(%r2)
++#endif
++ copy %r26,%r28
+Index: linux-2.6.0-test5/arch/parisc/kernel/setup.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/kernel/setup.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/kernel/setup.c 2003-09-27 11:38:19.744526760 +0800
+@@ -52,10 +52,6 @@
+ struct proc_dir_entry * proc_runway_root = NULL;
+ struct proc_dir_entry * proc_gsc_root = NULL;
+
+-#ifdef CONFIG_EISA
+-int EISA_bus; /* This has to go somewhere in architecture specific code. */
+-#endif
+-
+ void __init setup_cmdline(char **cmdline_p)
+ {
+ extern unsigned int boot_args[];
+Index: linux-2.6.0-test5/arch/parisc/kernel/signal.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/kernel/signal.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/kernel/signal.c 2003-09-27 11:38:19.748526152 +0800
+@@ -13,7 +13,6 @@
+ * arch/parisc/hpux/signal.c when we figure out how to do them.
+ */
+
+-#include <linux/version.h>
+ #include <linux/sched.h>
+ #include <linux/mm.h>
+ #include <linux/smp.h>
+@@ -458,6 +457,8 @@
+ if (in_syscall) {
+ /* Check the return code */
+ switch (regs->gr[28]) {
++ case -ERESTART_RESTARTBLOCK:
++ current_thread_info()->restart_block.fn = do_no_restart_syscall;
+ case -ERESTARTNOHAND:
+ DBG(("ERESTARTNOHAND: returning -EINTR\n"));
+ regs->gr[28] = -EINTR;
+@@ -495,7 +496,8 @@
+ /* Did we come from a system call? */
+ if (in_syscall) {
+ /* Restart the system call - no handlers present */
+- if (regs->gr[28] == -ERESTARTNOHAND ||
++ if (regs->gr[28] == -ERESTART_RESTARTBLOCK ||
++ regs->gr[28] == -ERESTARTNOHAND ||
+ regs->gr[28] == -ERESTARTSYS ||
+ regs->gr[28] == -ERESTARTNOINTR) {
+ /* Hooray for delayed branching. We don't
+Index: linux-2.6.0-test5/arch/parisc/kernel/syscall.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/kernel/syscall.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/kernel/syscall.S 2003-09-27 11:38:19.753525392 +0800
+@@ -483,7 +483,7 @@
+ ENTRY_SAME(madvise)
+ ENTRY_SAME(clone_wrapper) /* 120 */
+ ENTRY_SAME(setdomainname)
+- ENTRY_SAME(sendfile)
++ ENTRY_DIFF(sendfile)
+ /* struct sockaddr... */
+ ENTRY_SAME(recvfrom)
+ /* struct timex contains longs */
+@@ -592,7 +592,7 @@
+ ENTRY_SAME(ni_syscall)
+ ENTRY_SAME(ni_syscall) /* 205 */
+ ENTRY_SAME(gettid)
+- ENTRY_SAME(readahead)
++ ENTRY_OURS(readahead)
+ ENTRY_SAME(ni_syscall) /* tkill */
+
+ ENTRY_SAME(sendfile64)
+Index: linux-2.6.0-test5/arch/parisc/kernel/sys_parisc32.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/kernel/sys_parisc32.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/kernel/sys_parisc32.c 2003-09-27 11:38:19.762524024 +0800
+@@ -46,6 +46,7 @@
+ #include <linux/namei.h>
+ #include <linux/vfs.h>
+ #include <linux/ptrace.h>
++#include <linux/swap.h>
+
+ #include <asm/types.h>
+ #include <asm/uaccess.h>
+@@ -373,18 +374,16 @@
+ return copy_to_user(u, &t32, sizeof t32);
+ }
+
+-static int
+-get_compat_timeval(struct compat_timeval *u, struct timeval *t)
++static inline long get_ts32(struct timespec *o, struct compat_timeval *i)
+ {
+- int err;
+- struct compat_timeval t32;
++ long usec;
+
+- if ((err = copy_from_user(&t32, u, sizeof t32)) == 0)
+- {
+- t->tv_sec = t32.tv_sec;
+- t->tv_usec = t32.tv_usec;
+- }
+- return err;
++ if (__get_user(o->tv_sec, &i->tv_sec))
++ return -EFAULT;
++ if (__get_user(usec, &i->tv_usec))
++ return -EFAULT;
++ o->tv_nsec = usec * 1000;
++ return 0;
+ }
+
+ asmlinkage long sys32_time(compat_time_t *tloc)
+@@ -418,39 +417,39 @@
+ return 0;
+ }
+
+-asmlinkage int
+-sys32_settimeofday(struct compat_timespec *tv, struct timezone *tz)
++asmlinkage
++int sys32_settimeofday(struct compat_timeval *tv, struct timezone *tz)
+ {
+- struct timeval ktv;
+- struct timezone ktz;
+- extern int do_sys_settimeofday(struct timespec *tv, struct timezone *tz);
++ struct timespec kts;
++ struct timezone ktz;
+
+- if (tv) {
+- if (get_compat_timeval(tv, &ktv))
+- return -EFAULT;
+- }
+- if (tz) {
+- if (copy_from_user(&ktz, tz, sizeof(ktz)))
+- return -EFAULT;
+- }
++ if (tv) {
++ if (get_ts32(&kts, tv))
++ return -EFAULT;
++ }
++ if (tz) {
++ if (copy_from_user(&ktz, tz, sizeof(ktz)))
++ return -EFAULT;
++ }
+
+- return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL);
++ return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
+ }
+
+ int cp_compat_stat(struct kstat *stat, struct compat_stat *statbuf)
+ {
+ int err;
+
+- if (stat->size > MAX_NON_LFS)
++ if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) ||
++ !new_valid_dev(stat->rdev))
+ return -EOVERFLOW;
+
+- err = put_user(stat->dev, &statbuf->st_dev);
++ err = put_user(new_encode_dev(stat->dev), &statbuf->st_dev);
+ err |= put_user(stat->ino, &statbuf->st_ino);
+ err |= put_user(stat->mode, &statbuf->st_mode);
+ err |= put_user(stat->nlink, &statbuf->st_nlink);
+ err |= put_user(0, &statbuf->st_reserved1);
+ err |= put_user(0, &statbuf->st_reserved2);
+- err |= put_user(stat->rdev, &statbuf->st_rdev);
++ err |= put_user(new_encode_dev(stat->rdev), &statbuf->st_rdev);
+ err |= put_user(stat->size, &statbuf->st_size);
+ err |= put_user(stat->atime.tv_sec, &statbuf->st_atime);
+ err |= put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
+@@ -1089,6 +1088,27 @@
+ return err;
+ }
+
++
++extern asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
++asmlinkage int sys32_sendfile(int out_fd, int in_fd, compat_off_t *offset, s32 count)
++{
++ mm_segment_t old_fs = get_fs();
++ int ret;
++ off_t of;
++
++ if (offset && get_user(of, offset))
++ return -EFAULT;
++
++ set_fs(KERNEL_DS);
++ ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count);
++ set_fs(old_fs);
++
++ if (offset && put_user(of, offset))
++ return -EFAULT;
++
++ return ret;
++}
++
+ /* EXPORT/UNEXPORT */
+ struct nfsctl_export32 {
+ char ex_client[NFSCLNT_IDMAX+1];
+Index: linux-2.6.0-test5/arch/parisc/kernel/sys_parisc.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/kernel/sys_parisc.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/kernel/sys_parisc.c 2003-09-27 11:38:19.766523416 +0800
+@@ -30,8 +30,6 @@
+ {
+ struct vm_area_struct *vma;
+
+- if (!addr)
+- addr = TASK_UNMAPPED_BASE;
+ addr = PAGE_ALIGN(addr);
+
+ for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
+@@ -46,17 +44,38 @@
+
+ #define DCACHE_ALIGN(addr) (((addr) + (SHMLBA - 1)) &~ (SHMLBA - 1))
+
+-static unsigned long get_shared_area(struct inode *inode, unsigned long addr,
+- unsigned long len, unsigned long pgoff)
++/*
++ * We need to know the offset to use. Old scheme was to look for
++ * existing mapping and use the same offset. New scheme is to use the
++ * address of the kernel data structure as the seed for the offset.
++ * We'll see how that works...
++ */
++#if 0
++static int get_offset(struct address_space *mapping)
++{
++ struct vm_area_struct *vma = list_entry(mapping->i_mmap_shared.next,
++ struct vm_area_struct, shared);
++ return (vma->vm_start + ((pgoff - vma->vm_pgoff) << PAGE_SHIFT)) &
++ (SHMLBA - 1);
++}
++#else
++/* The mapping is cacheline aligned, so there's no information in the bottom
++ * few bits of the address. We're looking for 10 bits (4MB / 4k), so let's
++ * drop the bottom 8 bits and use bits 8-17.
++ */
++static int get_offset(struct address_space *mapping)
+ {
+- struct vm_area_struct *vma, *first_vma;
+- int offset;
++ int offset = (int) mapping << (PAGE_SHIFT - 8);
++ return offset & 0x3FF000;
++}
++#endif
+
+- first_vma = list_entry(inode->i_mapping->i_mmap_shared.next, struct vm_area_struct, shared);
+- offset = (first_vma->vm_start + ((pgoff - first_vma->vm_pgoff) << PAGE_SHIFT)) & (SHMLBA - 1);
++static unsigned long get_shared_area(struct address_space *mapping,
++ unsigned long addr, unsigned long len, unsigned long pgoff)
++{
++ struct vm_area_struct *vma;
++ int offset = get_offset(mapping);
+
+- if (!addr)
+- addr = TASK_UNMAPPED_BASE;
+ addr = DCACHE_ALIGN(addr - offset) + offset;
+
+ for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
+@@ -74,17 +93,17 @@
+ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
+ unsigned long len, unsigned long pgoff, unsigned long flags)
+ {
+- struct inode *inode = NULL;
++ struct inode *inode;
+
+ if (len > TASK_SIZE)
+ return -ENOMEM;
++ if (!addr)
++ addr = TASK_UNMAPPED_BASE;
+
+- if (filp) {
+- inode = filp->f_dentry->d_inode;
+- }
++ inode = filp ? filp->f_dentry->d_inode : NULL;
+
+- if (inode && (flags & MAP_SHARED) && (!list_empty(&inode->i_mapping->i_mmap_shared))) {
+- addr = get_shared_area(inode, addr, len, pgoff);
++ if (inode && (flags & MAP_SHARED)) {
++ addr = get_shared_area(inode->i_mapping, addr, len, pgoff);
+ } else {
+ addr = get_unshared_area(addr, len);
+ }
+@@ -185,6 +204,7 @@
+ size_t count, loff_t pos);
+ extern asmlinkage ssize_t sys_pwrite64(unsigned int fd, const char *buf,
+ size_t count, loff_t pos);
++extern asmlinkage ssize_t sys_readahead(int fd, loff_t offset, size_t count);
+
+ asmlinkage ssize_t parisc_pread64(unsigned int fd, char *buf, size_t count,
+ unsigned int high, unsigned int low)
+@@ -198,6 +218,11 @@
+ return sys_pwrite64(fd, buf, count, (loff_t)high << 32 | low);
+ }
+
++asmlinkage ssize_t parisc_readahead(int fd, unsigned int high, unsigned int low,
++ size_t count)
++{
++ return sys_readahead(fd, (loff_t)high << 32 | low, count);
++}
+
+ /*
+ * FIXME, please remove this crap as soon as possible
+@@ -271,7 +296,7 @@
+ tbuf.shm_cpid = sbuf->shm_cpid;
+ tbuf.shm_lpid = sbuf->shm_lpid;
+ tbuf.shm_nattch = sbuf->shm_nattch;
+- return copy_to_user(buf, &tbuf, sizeof tbuf);
++ return copy_to_user(buf, &tbuf, sizeof tbuf) ? -EFAULT : 0;
+ }
+
+ int sys_msgctl_broken(int msqid, int cmd, struct msqid_ds *buf)
+Index: linux-2.6.0-test5/arch/parisc/kernel/traps.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/kernel/traps.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/kernel/traps.c 2003-09-27 11:38:19.771522656 +0800
+@@ -221,6 +221,8 @@
+ return;
+ }
+
++ oops_in_progress = 1;
++
+ /* Amuse the user in a SPARC fashion */
+ printk(
+ " _______________________________ \n"
+@@ -414,6 +416,8 @@
+ {
+ static spinlock_t terminate_lock = SPIN_LOCK_UNLOCKED;
+
++ oops_in_progress = 1;
++
+ set_eiem(0);
+ local_irq_disable();
+ spin_lock(&terminate_lock);
+Index: linux-2.6.0-test5/arch/parisc/kernel/vmlinux.lds.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/kernel/vmlinux.lds.S 2003-09-27 11:38:18.438725272 +0800
++++ linux-2.6.0-test5/arch/parisc/kernel/vmlinux.lds.S 2003-09-27 11:38:19.772522504 +0800
+@@ -0,0 +1,125 @@
++#include <linux/config.h>
++#include <asm-generic/vmlinux.lds.h>
++
++/* ld script to make hppa Linux kernel */
++#ifndef CONFIG_PARISC64
++OUTPUT_FORMAT("elf32-hppa-linux")
++OUTPUT_ARCH(hppa)
++#else
++OUTPUT_FORMAT("elf64-hppa-linux")
++OUTPUT_ARCH(hppa:hppa2.0w)
++#endif
++
++ENTRY(_stext)
++#ifndef CONFIG_PARISC64
++jiffies = jiffies_64 + 4;
++#else
++jiffies = jiffies_64;
++#endif
++SECTIONS
++{
++
++ . = 0x10100000;
++
++ _text = .; /* Text and read-only data */
++ .text BLOCK(16) : {
++ *(.text*)
++ *(.PARISC.unwind)
++ *(.fixup)
++ *(.lock.text) /* out-of-line lock text */
++ *(.gnu.warning)
++ } = 0
++
++ _etext = .; /* End of text section */
++
++ . = ALIGN(16); /* Exception table */
++ __start___ex_table = .;
++ __ex_table : { *(__ex_table) }
++ __stop___ex_table = .;
++
++ RODATA
++
++ .data BLOCK(8192) : { /* Data without special */
++ data_start = .;
++ *(.data)
++ }
++
++#ifdef CONFIG_PARISC64
++ . = ALIGN(16); /* Linkage tables */
++ .opd : { *(.opd) } PROVIDE (__gp = .);
++ .plt : { *(.plt) }
++ .dlt : { *(.dlt) }
++#endif
++
++ . = ALIGN(16384);
++ __init_begin = .;
++ .init.text : {
++ _sinittext = .;
++ *(.init.text)
++ _einittext = .;
++ }
++ .init.data : { *(.init.data) }
++ . = ALIGN(16);
++ __setup_start = .;
++ .init.setup : { *(.init.setup) }
++ __setup_end = .;
++ __start___param =.;
++ __param : { *(__param) }
++ __stop___param = .;
++ __initcall_start = .;
++ .initcall.init : {
++ *(.initcall1.init)
++ *(.initcall2.init)
++ *(.initcall3.init)
++ *(.initcall4.init)
++ *(.initcall5.init)
++ *(.initcall6.init)
++ *(.initcall7.init)
++ }
++ __initcall_end = .;
++ __con_initcall_start = .;
++ .con_initcall.init : { *(.con_initcall.init) }
++ __con_initcall_end = .;
++ SECURITY_INIT
++ . = ALIGN(4096);
++ __initramfs_start = .;
++ .init.ramfs : { *(.init.ramfs) }
++ __initramfs_end = .;
++ . = ALIGN(32);
++ __per_cpu_start = .;
++ .data.percpu : { *(.data.percpu) }
++ __per_cpu_end = .;
++ . = ALIGN(4096);
++ __init_end = .;
++
++ init_task BLOCK(16384) : { *(init_task) } /* The initial task and kernel stack */
++
++ _edata = .; /* End of data section */
++
++
++ .bss : { *(.bss) *(COMMON) } /* BSS */
++
++
++ _end = . ;
++
++ /* Stabs debugging sections. */
++ .stab 0 : { *(.stab) }
++ .stabstr 0 : { *(.stabstr) }
++ .stab.excl 0 : { *(.stab.excl) }
++ .stab.exclstr 0 : { *(.stab.exclstr) }
++ .stab.index 0 : { *(.stab.index) }
++ .stab.indexstr 0 : { *(.stab.indexstr) }
++ .comment 0 : { *(.comment) }
++ .note 0 : { *(.note) }
++
++#ifdef CONFIG_PARISC64
++ /* temporary hack until binutils is fixed to not emit these
++ for static binaries */
++ /DISCARD/ : {
++ *(.dynsym)
++ *(.dynstr)
++ *(.dynamic)
++ *(.hash)
++ }
++#endif
++}
+Index: linux-2.6.0-test5/arch/parisc/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/Makefile 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/Makefile 2003-09-27 11:38:19.773522352 +0800
+@@ -16,7 +16,7 @@
+ # Modified for PA-RISC Linux by Paul Lahaie, Alex deVries,
+ # Mike Shaver, Helge Deller and Martin K. Petersen
+ #
+-
++NM = sh arch/parisc/nm
+ ifdef CONFIG_PARISC64
+ CROSS_COMPILE := hppa64-linux-
+ UTS_MACHINE := parisc64
+Index: linux-2.6.0-test5/arch/parisc/mm/ioremap.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/mm/ioremap.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/mm/ioremap.c 2003-09-27 11:38:19.775522048 +0800
+@@ -159,7 +159,7 @@
+ if (!area)
+ return NULL;
+ addr = area->addr;
+- if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) {
++ if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
+ vfree(addr);
+ return NULL;
+ }
+Index: linux-2.6.0-test5/arch/parisc/nm
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/nm 2003-09-27 11:38:18.438725272 +0800
++++ linux-2.6.0-test5/arch/parisc/nm 2003-09-27 11:38:19.776521896 +0800
+@@ -0,0 +1,6 @@
++#!/bin/sh
++##
++# Hack to have an nm which removes the local symbols. We also rely
++# on this nm being hidden out of the ordinarily executable path
++##
++${CROSS_COMPILE}nm $* | grep -v '.LC*[0-9]*$'
+Index: linux-2.6.0-test5/arch/ppc64/boot/install.sh
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/boot/install.sh 2003-09-27 11:38:18.438725272 +0800
++++ linux-2.6.0-test5/arch/ppc64/boot/install.sh 2003-09-27 11:38:19.776521896 +0800
+@@ -0,0 +1,41 @@
++#!/bin/sh
++#
++# arch/ppc64/boot/install.sh
++#
++# This file is subject to the terms and conditions of the GNU General Public
++# License. See the file "COPYING" in the main directory of this archive
++# for more details.
++#
++# Copyright (C) 1995 by Linus Torvalds
++#
++# Blatantly stolen from in arch/i386/boot/install.sh by Dave Hansen
++#
++# "make install" script for ppc64 architecture
++#
++# Arguments:
++# $1 - kernel version
++# $2 - kernel image file
++# $3 - kernel map file
++# $4 - default install path (blank if root directory)
++#
++
++# User may have a custom install script
++
++if [ -x ~/bin/installkernel ]; then exec ~/bin/installkernel "$@"; fi
++if [ -x /sbin/installkernel ]; then exec /sbin/installkernel "$@"; fi
++
++# Default install
++
++# this should work for both the pSeries zImage and the iSeries vmlinux.sm
++image_name=`basename $2`
++
++if [ -f $4/$image_name ]; then
++ mv $4/$image_name $4/$image_name.old
++fi
++
++if [ -f $4/System.map ]; then
++ mv $4/System.map $4/System.old
++fi
++
++cat $2 > $4/$image_name
++cp $3 $4/System.map
+Index: linux-2.6.0-test5/arch/ppc64/boot/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/boot/Makefile 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/boot/Makefile 2003-09-27 11:38:19.779521440 +0800
+@@ -122,5 +122,7 @@
+ awk '{printf "unsigned long vmlinux_memsize = 0x%s;\n", substr($$1,8)}' \
+ >> $(obj)/imagesize.c
+
++install: $(CONFIGURE) $(obj)/$(BOOTIMAGE)
++ sh -x $(src)/install.sh "$(KERNELRELEASE)" "$(obj)/$(BOOTIMAGE)" "$(TOPDIR)/System.map" "$(INSTALL_PATH)"
+
+ clean-files := $(patsubst $(obj)/%,%, $(obj-boot))
+Index: linux-2.6.0-test5/arch/ppc64/defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/defconfig 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/defconfig 2003-09-27 11:38:19.783520832 +0800
+@@ -8,11 +8,13 @@
+ CONFIG_EARLY_PRINTK=y
+ CONFIG_COMPAT=y
+ CONFIG_FRAME_POINTER=y
++CONFIG_FORCE_MAX_ZONEORDER=13
+
+ #
+ # Code maturity level options
+ #
+ CONFIG_EXPERIMENTAL=y
++# CONFIG_BROKEN is not set
+
+ #
+ # General setup
+@@ -21,11 +23,14 @@
+ CONFIG_SYSVIPC=y
+ # CONFIG_BSD_PROCESS_ACCT is not set
+ CONFIG_SYSCTL=y
+-CONFIG_LOG_BUF_SHIFT=15
++CONFIG_LOG_BUF_SHIFT=16
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
+ # CONFIG_EMBEDDED is not set
+ CONFIG_KALLSYMS=y
+ CONFIG_FUTEX=y
+ CONFIG_EPOLL=y
++CONFIG_IOSCHED_NOOP=y
+ CONFIG_IOSCHED_AS=y
+ CONFIG_IOSCHED_DEADLINE=y
+
+@@ -72,7 +77,6 @@
+ #
+ # Generic Driver Options
+ #
+-# CONFIG_FW_LOADER is not set
+
+ #
+ # Memory Technology Devices (MTD)
+@@ -99,7 +103,7 @@
+ # CONFIG_BLK_DEV_UMEM is not set
+ CONFIG_BLK_DEV_LOOP=y
+ # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+-CONFIG_BLK_DEV_NBD=y
++CONFIG_BLK_DEV_NBD=m
+ CONFIG_BLK_DEV_RAM=y
+ CONFIG_BLK_DEV_RAM_SIZE=4096
+ CONFIG_BLK_DEV_INITRD=y
+@@ -127,9 +131,9 @@
+ #
+ # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+ #
+-# CONFIG_SCSI_MULTI_LUN is not set
+-# CONFIG_SCSI_REPORT_LUNS is not set
+-# CONFIG_SCSI_CONSTANTS is not set
++CONFIG_SCSI_MULTI_LUN=y
++CONFIG_SCSI_REPORT_LUNS=y
++CONFIG_SCSI_CONSTANTS=y
+ # CONFIG_SCSI_LOGGING is not set
+
+ #
+@@ -178,7 +182,8 @@
+ CONFIG_MD_RAID1=y
+ CONFIG_MD_RAID5=y
+ # CONFIG_MD_MULTIPATH is not set
+-# CONFIG_BLK_DEV_DM is not set
++CONFIG_BLK_DEV_DM=y
++CONFIG_DM_IOCTL_V4=y
+
+ #
+ # Fusion MPT device support
+@@ -206,9 +211,8 @@
+ CONFIG_PACKET=y
+ # CONFIG_PACKET_MMAP is not set
+ # CONFIG_NETLINK_DEV is not set
+-# CONFIG_NETFILTER is not set
+ CONFIG_UNIX=y
+-# CONFIG_NET_KEY is not set
++CONFIG_NET_KEY=m
+ CONFIG_INET=y
+ CONFIG_IP_MULTICAST=y
+ # CONFIG_IP_ADVANCED_ROUTER is not set
+@@ -217,13 +221,17 @@
+ # CONFIG_NET_IPGRE is not set
+ # CONFIG_IP_MROUTE is not set
+ # CONFIG_ARPD is not set
+-# CONFIG_INET_ECN is not set
++CONFIG_INET_ECN=y
+ CONFIG_SYN_COOKIES=y
+-# CONFIG_INET_AH is not set
+-# CONFIG_INET_ESP is not set
+-# CONFIG_INET_IPCOMP is not set
++CONFIG_INET_AH=m
++CONFIG_INET_ESP=m
++CONFIG_INET_IPCOMP=m
+ # CONFIG_IPV6 is not set
+-# CONFIG_XFRM_USER is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_NETFILTER is not set
++CONFIG_XFRM=y
++CONFIG_XFRM_USER=m
+
+ #
+ # SCTP Configuration (EXPERIMENTAL)
+@@ -233,8 +241,6 @@
+ # CONFIG_ATM is not set
+ # CONFIG_VLAN_8021Q is not set
+ # CONFIG_LLC is not set
+-# CONFIG_DECNET is not set
+-# CONFIG_BRIDGE is not set
+ # CONFIG_X25 is not set
+ # CONFIG_LAPB is not set
+ # CONFIG_NET_DIVERT is not set
+@@ -258,10 +264,10 @@
+ # ARCnet devices
+ #
+ # CONFIG_ARCNET is not set
+-# CONFIG_DUMMY is not set
+-# CONFIG_BONDING is not set
++CONFIG_DUMMY=m
++CONFIG_BONDING=m
+ # CONFIG_EQUALIZER is not set
+-# CONFIG_TUN is not set
++CONFIG_TUN=m
+ # CONFIG_ETHERTAP is not set
+
+ #
+@@ -312,6 +318,7 @@
+ # CONFIG_HAMACHI is not set
+ # CONFIG_YELLOWFIN is not set
+ # CONFIG_R8169 is not set
++# CONFIG_SIS190 is not set
+ # CONFIG_SK98LIN is not set
+ # CONFIG_TIGON3 is not set
+
+@@ -321,7 +328,14 @@
+ # CONFIG_IXGB is not set
+ # CONFIG_FDDI is not set
+ # CONFIG_HIPPI is not set
+-# CONFIG_PPP is not set
++CONFIG_PPP=m
++# CONFIG_PPP_MULTILINK is not set
++# CONFIG_PPP_FILTER is not set
++CONFIG_PPP_ASYNC=m
++CONFIG_PPP_SYNC_TTY=m
++CONFIG_PPP_DEFLATE=m
++CONFIG_PPP_BSDCOMP=m
++CONFIG_PPPOE=m
+ # CONFIG_SLIP is not set
+
+ #
+@@ -489,26 +503,32 @@
+ # File systems
+ #
+ CONFIG_EXT2_FS=y
+-# CONFIG_EXT2_FS_XATTR is not set
++CONFIG_EXT2_FS_XATTR=y
++CONFIG_EXT2_FS_POSIX_ACL=y
++# CONFIG_EXT2_FS_SECURITY is not set
+ CONFIG_EXT3_FS=y
+-# CONFIG_EXT3_FS_XATTR is not set
++CONFIG_EXT3_FS_XATTR=y
++CONFIG_EXT3_FS_POSIX_ACL=y
++# CONFIG_EXT3_FS_SECURITY is not set
+ CONFIG_JBD=y
+ # CONFIG_JBD_DEBUG is not set
++CONFIG_FS_MBCACHE=y
+ CONFIG_REISERFS_FS=y
+ # CONFIG_REISERFS_CHECK is not set
+ # CONFIG_REISERFS_PROC_INFO is not set
+ CONFIG_JFS_FS=y
+-# CONFIG_JFS_POSIX_ACL is not set
++CONFIG_JFS_POSIX_ACL=y
+ # CONFIG_JFS_DEBUG is not set
+ # CONFIG_JFS_STATISTICS is not set
+-CONFIG_XFS_FS=y
++CONFIG_FS_POSIX_ACL=y
++CONFIG_XFS_FS=m
+ # CONFIG_XFS_RT is not set
+ # CONFIG_XFS_QUOTA is not set
+-# CONFIG_XFS_POSIX_ACL is not set
++CONFIG_XFS_POSIX_ACL=y
+ # CONFIG_MINIX_FS is not set
+ # CONFIG_ROMFS_FS is not set
+ # CONFIG_QUOTA is not set
+-CONFIG_AUTOFS_FS=y
++CONFIG_AUTOFS_FS=m
+ # CONFIG_AUTOFS4_FS is not set
+
+ #
+@@ -517,7 +537,7 @@
+ CONFIG_ISO9660_FS=y
+ # CONFIG_JOLIET is not set
+ # CONFIG_ZISOFS is not set
+-# CONFIG_UDF_FS is not set
++CONFIG_UDF_FS=m
+
+ #
+ # DOS/FAT/NT Filesystems
+@@ -533,8 +553,9 @@
+ CONFIG_PROC_FS=y
+ # CONFIG_DEVFS_FS is not set
+ CONFIG_DEVPTS_FS=y
+-# CONFIG_DEVPTS_FS_XATTR is not set
+-# CONFIG_TMPFS is not set
++CONFIG_DEVPTS_FS_XATTR=y
++# CONFIG_DEVPTS_FS_SECURITY is not set
++CONFIG_TMPFS=y
+ CONFIG_RAMFS=y
+
+ #
+@@ -546,7 +567,7 @@
+ # CONFIG_BEFS_FS is not set
+ # CONFIG_BFS_FS is not set
+ # CONFIG_EFS_FS is not set
+-# CONFIG_CRAMFS is not set
++CONFIG_CRAMFS=y
+ # CONFIG_VXFS_FS is not set
+ # CONFIG_HPFS_FS is not set
+ # CONFIG_QNX4FS_FS is not set
+@@ -561,15 +582,16 @@
+ CONFIG_NFS_V4=y
+ CONFIG_NFSD=y
+ CONFIG_NFSD_V3=y
+-# CONFIG_NFSD_V4 is not set
++CONFIG_NFSD_V4=y
+ CONFIG_NFSD_TCP=y
+ CONFIG_LOCKD=y
+ CONFIG_LOCKD_V4=y
+ CONFIG_EXPORTFS=y
+ CONFIG_SUNRPC=y
+-# CONFIG_SUNRPC_GSS is not set
++CONFIG_SUNRPC_GSS=m
++CONFIG_RPCSEC_GSS_KRB5=m
+ # CONFIG_SMB_FS is not set
+-CONFIG_CIFS=y
++CONFIG_CIFS=m
+ # CONFIG_NCP_FS is not set
+ # CONFIG_CODA_FS is not set
+ # CONFIG_INTERMEZZO_FS is not set
+@@ -705,6 +727,7 @@
+ CONFIG_XMON=y
+ CONFIG_XMON_DEFAULT=y
+ # CONFIG_PPCDBG is not set
++# CONFIG_DEBUG_INFO is not set
+
+ #
+ # Security options
+@@ -714,9 +737,27 @@
+ #
+ # Cryptographic options
+ #
+-# CONFIG_CRYPTO is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_HMAC=y
++CONFIG_CRYPTO_NULL=m
++CONFIG_CRYPTO_MD4=m
++CONFIG_CRYPTO_MD5=m
++CONFIG_CRYPTO_SHA1=m
++CONFIG_CRYPTO_SHA256=m
++CONFIG_CRYPTO_SHA512=m
++CONFIG_CRYPTO_DES=m
++CONFIG_CRYPTO_BLOWFISH=m
++CONFIG_CRYPTO_TWOFISH=m
++CONFIG_CRYPTO_SERPENT=m
++CONFIG_CRYPTO_AES=m
++CONFIG_CRYPTO_CAST5=m
++CONFIG_CRYPTO_CAST6=m
++CONFIG_CRYPTO_DEFLATE=m
++CONFIG_CRYPTO_TEST=m
+
+ #
+ # Library routines
+ #
+ CONFIG_CRC32=y
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=m
+Index: linux-2.6.0-test5/arch/ppc64/kernel/asm-offsets.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/asm-offsets.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/asm-offsets.c 2003-09-27 11:38:19.787520224 +0800
+@@ -83,9 +83,7 @@
+ DEFINE(PACALPQUEUE, offsetof(struct paca_struct, lpQueuePtr));
+ DEFINE(PACATOC, offsetof(struct paca_struct, xTOC));
+ DEFINE(PACAEXCSP, offsetof(struct paca_struct, exception_sp));
+- DEFINE(PACAHRDWINTSTACK, offsetof(struct paca_struct, xHrdIntStack));
+ DEFINE(PACAPROCENABLED, offsetof(struct paca_struct, xProcEnabled));
+- DEFINE(PACAHRDWINTCOUNT, offsetof(struct paca_struct, xHrdIntCount));
+ DEFINE(PACADEFAULTDECR, offsetof(struct paca_struct, default_decr));
+ DEFINE(PACAPROFENABLED, offsetof(struct paca_struct, prof_enabled));
+ DEFINE(PACAPROFLEN, offsetof(struct paca_struct, prof_len));
+Index: linux-2.6.0-test5/arch/ppc64/kernel/chrp_setup.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/chrp_setup.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/chrp_setup.c 2003-09-27 11:38:19.790519768 +0800
+@@ -72,6 +72,7 @@
+
+ extern void find_and_init_phbs(void);
+
++extern void pSeries_get_boot_time(struct rtc_time *rtc_time);
+ extern void pSeries_get_rtc_time(struct rtc_time *rtc_time);
+ extern int pSeries_set_rtc_time(struct rtc_time *rtc_time);
+ void pSeries_calibrate_decr(void);
+@@ -256,7 +257,7 @@
+ ppc_md.power_off = rtas_power_off;
+ ppc_md.halt = rtas_halt;
+
+- ppc_md.get_boot_time = pSeries_get_rtc_time;
++ ppc_md.get_boot_time = pSeries_get_boot_time;
+ ppc_md.get_rtc_time = pSeries_get_rtc_time;
+ ppc_md.set_rtc_time = pSeries_set_rtc_time;
+ ppc_md.calibrate_decr = pSeries_calibrate_decr;
+Index: linux-2.6.0-test5/arch/ppc64/kernel/eeh.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/eeh.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/eeh.c 2003-09-27 11:38:19.795519008 +0800
+@@ -115,8 +115,17 @@
+ ret = rtas_call(ibm_read_slot_reset_state, 3, 3, rets,
+ dn->eeh_config_addr, BUID_HI(dn->phb->buid), BUID_LO(dn->phb->buid));
+ if (ret == 0 && rets[1] == 1 && rets[0] >= 2) {
+- panic("EEH: MMIO failure (%ld) on device:\n %s %s\n",
+- rets[0], pci_name(dev), dev->dev.name);
++ /*
++ * XXX We should create a separate sysctl for this.
++ *
++ * Since the panic_on_oops sysctl is used to halt
++ * the system in light of potential corruption, we
++ * can use it here.
++ */
++ if (panic_on_oops)
++ panic("EEH: MMIO failure (%ld) on device:\n%s\n", rets[0], pci_name(dev));
++ else
++ printk("EEH: MMIO failure (%ld) on device:\n%s\n", rets[0], pci_name(dev));
+ }
+ }
+ eeh_false_positives++;
+Index: linux-2.6.0-test5/arch/ppc64/kernel/head.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/head.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/head.S 2003-09-27 11:38:19.811516576 +0800
+@@ -40,6 +40,15 @@
+ #define DO_SOFT_DISABLE
+ #endif
+
++/* copy saved SOFTE bit or EE bit from saved MSR depending
++ * if we are doing soft-disable or not
++ */
++#ifdef DO_SOFT_DISABLE
++#define DO_COPY_EE() ld r20,SOFTE(r1)
++#else
++#define DO_COPY_EE() rldicl r20,r23,49,63
++#endif
++
+ /*
+ * hcall interface to pSeries LPAR
+ */
+@@ -618,11 +627,7 @@
+ ld r4,_DAR(r1)
+ ld r5,_DSISR(r1)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+-#ifdef DO_SOFT_DISABLE
+- ld r20,SOFTE(r1) /* Copy saved SOFTE bit */
+-#else
+- rldicl r20,r23,49,63 /* copy EE bit from saved MSR */
+-#endif
++ DO_COPY_EE()
+ li r6,0x300
+ bl .save_remaining_regs
+ bl .do_page_fault
+@@ -644,12 +649,9 @@
+ or. r3,r3,r3 /* Check return code */
+ beq fast_exception_return /* Return if we succeeded */
+ addi r3,r1,STACK_FRAME_OVERHEAD
+-#ifdef DO_SOFT_DISABLE
+- ld r20,SOFTE(r1)
+-#else
+- rldicl r20,r23,49,63 /* copy EE bit from saved MSR */
+-#endif
++ DO_COPY_EE()
+ li r6,0x380
++ li r5,0
+ bl .save_remaining_regs
+ bl .do_page_fault
+ b .ret_from_except
+@@ -670,13 +672,9 @@
+ bl .do_hash_page_ISI /* Try to handle as hpte fault */
+ 1:
+ mr r4,r22
+- mr r5,r23
++ rlwinm r5,r23,0,4,4 /* We only care about PR in error_code */
+ addi r3,r1,STACK_FRAME_OVERHEAD
+-#ifdef DO_SOFT_DISABLE
+- ld r20,SOFTE(r1)
+-#else
+- rldicl r20,r23,49,63 /* copy EE bit from saved MSR */
+-#endif
++ DO_COPY_EE()
+ li r6,0x400
+ bl .save_remaining_regs
+ bl .do_page_fault
+@@ -692,12 +690,9 @@
+ beq+ fast_exception_return /* Return if we succeeded */
+
+ addi r3,r1,STACK_FRAME_OVERHEAD
+-#ifdef DO_SOFT_DISABLE
+- ld r20,SOFTE(r1)
+-#else
+- rldicl r20,r23,49,63 /* copy EE bit from saved MSR */
+-#endif
++ DO_COPY_EE()
+ li r6,0x480
++ li r5,0
+ bl .save_remaining_regs
+ bl .do_page_fault
+ b .ret_from_except
+@@ -710,70 +705,14 @@
+ li r20,0
+ li r6,0x500
+ bl .save_remaining_regs
+- /* Determine if need to run do_irq on a hardware interrupt stack */
+- /* The first invocation of do_irq will occur on the kernel */
+- /* stack in the current stack */
+- /* All other invocations of do_irq will run on the hardware */
+- /* interrupt stack associated with the PACA of the current */
+- /* processor. */
+- /* */
+- /* The call to do_irq will preserve the value of r14 - r31 */
+- /* */
+-/*
+- * XXX turn off interrupt stacks until the thread_info stuff is fixed.
+- * Otherwise we end up setting need_resched etc bits in the interrupt
+- * stack and they never get seen when we return to the process stack - Anton
+- */
+-#if 0
+- lbz r21,PACAHRDWINTCOUNT(r13) /* get hardware interrupt cnt */
+- cmpi 0,r21,1 /* */
+- addi r21,r21,1 /* incr hardware interrupt cnt*/
+- stb r21,PACAHRDWINTCOUNT(r13) /* */
+- bne 2f /* */
+-
+- mr r14,r1 /* preserve current r1 */
+- ld r1,PACAHRDWINTSTACK(r13) /* */
+- std r14,0(r1) /* set the back chain */
+ bl .do_IRQ
+- lbz r22,PACAHRDWINTCOUNT(r13) /* get hardware interrupt cnt */
+- cmp 0,r22,r21 /* debug test */
+- bne 3f
+- subi r21,r21,1
+- stb r21,PACAHRDWINTCOUNT(r13) /* */
+- mr r1,r14 /* */
+ b .ret_from_except
+-#endif
+-
+-2:
+- bl .do_IRQ
+-
+-#if 0
+- lbz r22,PACAHRDWINTCOUNT(r13) /* get hardware interrupt cnt */
+- cmp 0,r22,r21 /* debug test */
+- bne 3f /* */
+- subi r21,r21,1 /* decr hardware interrupt cnt*/
+- stb r21,PACAHRDWINTCOUNT(r13) /* */
+-#endif
+-
+- b .ret_from_except
+-
+-3:
+- /* error - counts out of sync */
+-#ifdef CONFIG_XMON
+- bl .xmon
+-#endif
+-4: b 4b
+-
+
+ .globl Alignment_common
+ Alignment_common:
+ EXCEPTION_PROLOG_COMMON
+ addi r3,r1,STACK_FRAME_OVERHEAD
+-#ifdef DO_SOFT_DISABLE
+- ld r20,SOFTE(r1)
+-#else
+- rldicl r20,r23,49,63 /* copy EE bit from saved MSR */
+-#endif
++ DO_COPY_EE()
+ li r6,0x600
+ bl .save_remaining_regs
+ bl .AlignmentException
+@@ -783,11 +722,7 @@
+ ProgramCheck_common:
+ EXCEPTION_PROLOG_COMMON
+ addi r3,r1,STACK_FRAME_OVERHEAD
+-#ifdef DO_SOFT_DISABLE
+- ld r20,SOFTE(r1)
+-#else
+- rldicl r20,r23,49,63 /* copy EE bit from saved MSR */
+-#endif
++ DO_COPY_EE()
+ li r6,0x700
+ bl .save_remaining_regs
+ bl .ProgramCheckException
+@@ -798,11 +733,7 @@
+ EXCEPTION_PROLOG_COMMON
+ bne .load_up_fpu /* if from user, just load it up */
+ addi r3,r1,STACK_FRAME_OVERHEAD
+-#ifdef DO_SOFT_DISABLE
+- ld r20,SOFTE(r1)
+-#else
+- rldicl r20,r23,49,63 /* copy EE bit from saved MSR */
+-#endif
++ DO_COPY_EE()
+ li r6,0x800
+ bl .save_remaining_regs
+ bl .KernelFPUnavailableException
+@@ -818,11 +749,7 @@
+ beq+ HardwareInterrupt_entry
+ 1:
+ #endif
+-#ifdef DO_SOFT_DISABLE
+- ld r20,SOFTE(r1)
+-#else
+- rldicl r20,r23,49,63 /* copy EE bit from saved MSR */
+-#endif
++ DO_COPY_EE()
+ li r6,0xC00
+ bl .save_remaining_regs
+ bl .DoSyscall
+@@ -1866,18 +1793,6 @@
+ li r5,0
+ std r0,PACAKSAVE(r13)
+
+- /* ptr to hardware interrupt stack for boot processor */
+- LOADADDR(r3, hardware_int_paca0)
+- li r5,PAGE_SIZE
+- sldi r5,r5,3
+- subi r5,r5,STACK_FRAME_OVERHEAD
+-
+- add r3,r3,r5
+- std r3,PACAHRDWINTSTACK(r13)
+-
+- li r3,0
+- stb r3,PACAHRDWINTCOUNT(r13)
+-
+ /* Restore the parms passed in from the bootloader. */
+ mr r3,r31
+ mr r4,r30
+@@ -1999,10 +1914,6 @@
+ ioremap_dir:
+ .space 4096
+
+- .globl hardware_int_paca0
+-hardware_int_paca0:
+- .space 8*PAGE_SIZE
+-
+ /* 1 page segment table per cpu (max 48, cpu0 allocated at STAB0_PHYS_ADDR) */
+ .globl stab_array
+ stab_array:
+Index: linux-2.6.0-test5/arch/ppc64/kernel/htab.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/htab.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/htab.c 2003-09-27 11:38:19.814516120 +0800
+@@ -197,7 +197,7 @@
+ if (!pgd_none(*pg)) {
+
+ pm = pmd_offset(pg, ea);
+- if (!pmd_none(*pm)) {
++ if (pmd_present(*pm)) {
+ pt = pte_offset_kernel(pm, ea);
+ pte = *pt;
+ if (!pte_present(pte))
+@@ -436,8 +436,12 @@
+ if (user_region && cpus_equal(mm->cpu_vm_mask, tmp))
+ local = 1;
+
+- ptep = find_linux_pte(pgdir, ea);
+- ret = __hash_page(ea, access, vsid, ptep, trap, local);
++ ret = hash_huge_page(mm, access, ea, vsid, local);
++ if (ret < 0) {
++ ptep = find_linux_pte(pgdir, ea);
++ ret = __hash_page(ea, access, vsid, ptep, trap, local);
++ }
++
+ spin_unlock(&mm->page_table_lock);
+
+ return ret;
+Index: linux-2.6.0-test5/arch/ppc64/kernel/irq.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/irq.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/irq.c 2003-09-27 11:38:19.820515208 +0800
+@@ -39,6 +39,7 @@
+ #include <linux/irq.h>
+ #include <linux/proc_fs.h>
+ #include <linux/random.h>
++#include <linux/kallsyms.h>
+
+ #include <asm/uaccess.h>
+ #include <asm/bitops.h>
+@@ -350,14 +351,11 @@
+ return 0;
+ }
+
+-extern char *ppc_find_proc_name(unsigned *p, char *buf, unsigned buflen);
+-
+-static inline void handle_irq_event(int irq, struct pt_regs *regs,
+- struct irqaction *action)
++static inline int handle_irq_event(int irq, struct pt_regs *regs,
++ struct irqaction *action)
+ {
+ int status = 0;
+ int retval = 0;
+- struct irqaction *first_action = action;
+
+ if (!(action->flags & SA_INTERRUPT))
+ local_irq_enable();
+@@ -370,28 +368,88 @@
+ if (status & SA_SAMPLE_RANDOM)
+ add_interrupt_randomness(irq);
+ local_irq_disable();
+- if (retval != 1) {
+- static int count = 100;
+- char name_buf[256];
+- if (count) {
+- count--;
+- if (retval) {
+- printk("irq event %d: bogus retval mask %x\n",
+- irq, retval);
+- } else {
+- printk("irq %d: nobody cared!\n", irq);
+- }
+- dump_stack();
+- printk("handlers:\n");
+- action = first_action;
+- do {
+- printk("[<%p>]", action->handler);
+- printk(" (%s)\n",
+- ppc_find_proc_name((unsigned *)action->handler, name_buf, 256));
+- action = action->next;
+- } while (action);
+- }
++ return retval;
++}
++
++static void __report_bad_irq(int irq, irq_desc_t *desc, irqreturn_t action_ret)
++{
++ struct irqaction *action;
++
++ if (action_ret != IRQ_HANDLED && action_ret != IRQ_NONE) {
++ printk(KERN_ERR "irq event %d: bogus return value %x\n",
++ irq, action_ret);
++ } else {
++ printk(KERN_ERR "irq %d: nobody cared!\n", irq);
++ }
++ dump_stack();
++ printk(KERN_ERR "handlers:\n");
++ action = desc->action;
++ do {
++ printk(KERN_ERR "[<%p>]", action->handler);
++ print_symbol(" (%s)",
++ (unsigned long)action->handler);
++ printk("\n");
++ action = action->next;
++ } while (action);
++}
++
++static void report_bad_irq(int irq, irq_desc_t *desc, irqreturn_t action_ret)
++{
++ static int count = 100;
++
++ if (count) {
++ count--;
++ __report_bad_irq(irq, desc, action_ret);
++ }
++}
++
++static int noirqdebug;
++
++static int __init noirqdebug_setup(char *str)
++{
++ noirqdebug = 1;
++ printk("IRQ lockup detection disabled\n");
++ return 1;
++}
++
++__setup("noirqdebug", noirqdebug_setup);
++
++/*
++ * If 99,900 of the previous 100,000 interrupts have not been handled then
++ * assume that the IRQ is stuck in some manner. Drop a diagnostic and try to
++ * turn the IRQ off.
++ *
++ * (The other 100-of-100,000 interrupts may have been a correctly-functioning
++ * device sharing an IRQ with the failing one)
++ *
++ * Called under desc->lock
++ */
++static void note_interrupt(int irq, irq_desc_t *desc, irqreturn_t action_ret)
++{
++ if (action_ret != IRQ_HANDLED) {
++ desc->irqs_unhandled++;
++ if (action_ret != IRQ_NONE)
++ report_bad_irq(irq, desc, action_ret);
+ }
++
++ desc->irq_count++;
++ if (desc->irq_count < 100000)
++ return;
++
++ desc->irq_count = 0;
++ if (desc->irqs_unhandled > 99900) {
++ /*
++ * The interrupt is stuck
++ */
++ __report_bad_irq(irq, desc, action_ret);
++ /*
++ * Now kill the IRQ
++ */
++ printk(KERN_EMERG "Disabling IRQ #%d\n", irq);
++ desc->status |= IRQ_DISABLED;
++ desc->handler->disable(irq);
++ }
++ desc->irqs_unhandled = 0;
+ }
+
+ /*
+@@ -462,10 +520,13 @@
+ * SMP environment.
+ */
+ for (;;) {
++ irqreturn_t action_ret;
++
+ spin_unlock(&desc->lock);
+- handle_irq_event(irq, regs, action);
++ action_ret = handle_irq_event(irq, regs, action);
+ spin_lock(&desc->lock);
+-
++ if (!noirqdebug)
++ note_interrupt(irq, desc, action_ret);
+ if (likely(!(desc->status & IRQ_PENDING)))
+ break;
+ desc->status &= ~IRQ_PENDING;
+Index: linux-2.6.0-test5/arch/ppc64/kernel/ppc_ksyms.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/ppc_ksyms.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/ppc_ksyms.c 2003-09-27 11:38:19.822514904 +0800
+@@ -49,8 +49,6 @@
+
+ extern int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
+ extern int do_signal(sigset_t *, struct pt_regs *);
+-extern int register_ioctl32_conversion(unsigned int cmd, int (*handler)(unsigned int, unsigned int, unsigned long, struct file *));
+-extern int unregister_ioctl32_conversion(unsigned int cmd);
+
+ int abs(int);
+
+@@ -66,9 +64,6 @@
+ EXPORT_SYMBOL(synchronize_irq);
+ #endif /* CONFIG_SMP */
+
+-EXPORT_SYMBOL(register_ioctl32_conversion);
+-EXPORT_SYMBOL(unregister_ioctl32_conversion);
+-
+ EXPORT_SYMBOL(isa_io_base);
+ EXPORT_SYMBOL(pci_io_base);
+
+Index: linux-2.6.0-test5/arch/ppc64/kernel/process.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/process.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/process.c 2003-09-27 11:38:19.827514144 +0800
+@@ -32,6 +32,7 @@
+ #include <linux/init_task.h>
+ #include <linux/prctl.h>
+ #include <linux/ptrace.h>
++#include <linux/kallsyms.h>
+
+ #include <asm/pgtable.h>
+ #include <asm/uaccess.h>
+@@ -130,12 +131,9 @@
+ return last;
+ }
+
+-char *ppc_find_proc_name(unsigned *p, char *buf, unsigned buflen);
+-
+ void show_regs(struct pt_regs * regs)
+ {
+ int i;
+- char name_buf[256];
+
+ printk("NIP: %016lX XER: %016lX LR: %016lX\n",
+ regs->nip, regs->xer, regs->link);
+@@ -170,8 +168,7 @@
+ * above info out without failing
+ */
+ printk("NIP [%016lx] ", regs->nip);
+- printk("%s\n", ppc_find_proc_name((unsigned *)regs->nip,
+- name_buf, 256));
++ print_symbol("%s\n", regs->nip);
+ show_stack(current, (unsigned long *)regs->gpr[1]);
+ }
+
+@@ -385,102 +382,6 @@
+ return error;
+ }
+
+-void initialize_paca_hardware_interrupt_stack(void)
+-{
+- int i;
+- unsigned long stack;
+- unsigned long end_of_stack =0;
+-
+- for (i=1; i < NR_CPUS; i++) {
+- if (!cpu_possible(i))
+- continue;
+- /* Carve out storage for the hardware interrupt stack */
+- stack = __get_free_pages(GFP_ATOMIC, get_order(8*PAGE_SIZE));
+-
+- if ( !stack ) {
+- printk("ERROR, cannot find space for hardware stack.\n");
+- panic(" no hardware stack ");
+- }
+-
+-
+- /* Store the stack value in the PACA for the processor */
+- paca[i].xHrdIntStack = stack + (8*PAGE_SIZE) - STACK_FRAME_OVERHEAD;
+- paca[i].xHrdIntCount = 0;
+-
+- }
+-
+- /*
+- * __get_free_pages() might give us a page > KERNBASE+256M which
+- * is mapped with large ptes so we can't set up the guard page.
+- */
+- if (cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE)
+- return;
+-
+- for (i=0; i < NR_CPUS; i++) {
+- if (!cpu_possible(i))
+- continue;
+- /* set page at the top of stack to be protected - prevent overflow */
+- end_of_stack = paca[i].xHrdIntStack - (8*PAGE_SIZE - STACK_FRAME_OVERHEAD);
+- ppc_md.hpte_updateboltedpp(PP_RXRX,end_of_stack);
+- }
+-}
+-
+-char *ppc_find_proc_name(unsigned *p, char *buf, unsigned buflen)
+-{
+- unsigned long tb_flags;
+- unsigned short name_len;
+- unsigned long tb_start, code_start, code_ptr, code_offset;
+- unsigned int code_len;
+- unsigned long end;
+-
+- strcpy(buf, "Unknown");
+- code_ptr = (unsigned long)p;
+- code_offset = 0;
+-
+- /* handle functions in text and init sections */
+- if (((unsigned long)p >= (unsigned long)_stext) &&
+- ((unsigned long)p < (unsigned long)_etext))
+- end = (unsigned long)_etext;
+- else if (((unsigned long)p >= (unsigned long)__init_begin) &&
+- ((unsigned long)p < (unsigned long)__init_end))
+- end = (unsigned long)__init_end;
+- else
+- return buf;
+-
+- while ((unsigned long)p < end) {
+- if (*p == 0) {
+- tb_start = (unsigned long)p;
+- ++p; /* Point to traceback flags */
+- tb_flags = *((unsigned long *)p);
+- p += 2; /* Skip over traceback flags */
+- if (tb_flags & TB_NAME_PRESENT) {
+- if (tb_flags & TB_PARMINFO)
+- ++p; /* skip over parminfo data */
+- if (tb_flags & TB_HAS_TBOFF) {
+- code_len = *p; /* get code length */
+- code_start = tb_start - code_len;
+- code_offset = code_ptr - code_start + 1;
+- if (code_offset > 0x100000)
+- break;
+- ++p; /* skip over code size */
+- }
+- name_len = *((unsigned short *)p);
+- if (name_len > (buflen-20))
+- name_len = buflen-20;
+- memcpy(buf, ((char *)p)+2, name_len);
+- buf[name_len] = 0;
+- if (code_offset)
+- sprintf(buf+name_len, "+0x%lx",
+- code_offset-1);
+- }
+- break;
+- }
+- ++p;
+- }
+-
+- return buf;
+-}
+-
+ /*
+ * These bracket the sleeping functions..
+ */
+@@ -520,7 +421,6 @@
+ unsigned long ip;
+ unsigned long stack_page = (unsigned long)p->thread_info;
+ int count = 0;
+- char name_buf[256];
+ unsigned long sp = (unsigned long)_sp;
+
+ if (!p)
+@@ -539,8 +439,7 @@
+ if (__get_user(ip, (unsigned long *)(sp + 16)))
+ break;
+ printk("[%016lx] ", ip);
+- printk("%s\n", ppc_find_proc_name((unsigned *)ip,
+- name_buf, 256));
++ print_symbol("%s\n", ip);
+ } while (count++ < 32);
+ }
+
+Index: linux-2.6.0-test5/arch/ppc64/kernel/pSeries_lpar.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/pSeries_lpar.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/pSeries_lpar.c 2003-09-27 11:38:19.831513536 +0800
+@@ -36,18 +36,6 @@
+ #include <asm/tlb.h>
+ #include <asm/hvcall.h>
+
+-
+-long plpar_pte_enter(unsigned long flags,
+- unsigned long ptex,
+- unsigned long new_pteh, unsigned long new_ptel,
+- unsigned long *old_pteh_ret, unsigned long *old_ptel_ret)
+-{
+- unsigned long dummy, ret;
+- ret = plpar_hcall(H_ENTER, flags, ptex, new_pteh, new_ptel,
+- old_pteh_ret, old_ptel_ret, &dummy);
+- return(ret);
+-}
+-
+ long plpar_pte_remove(unsigned long flags,
+ unsigned long ptex,
+ unsigned long avpn,
+@@ -83,7 +71,6 @@
+ tce_ret, &dummy, &dummy);
+ }
+
+-
+ long plpar_tce_put(unsigned long liobn,
+ unsigned long ioba,
+ unsigned long tceval)
+@@ -104,10 +91,9 @@
+ unsigned long len,
+ const char *buffer)
+ {
+- unsigned long dummy;
+ unsigned long *lbuf = (unsigned long *)buffer; /* ToDo: alignment? */
+- return plpar_hcall(H_PUT_TERM_CHAR, termno, len,
+- lbuf[0], lbuf[1], &dummy, &dummy, &dummy);
++ return plpar_hcall_norets(H_PUT_TERM_CHAR, termno, len, lbuf[0],
++ lbuf[1]);
+ }
+
+ static void tce_build_pSeriesLP(struct TceTable *tbl, long tcenum,
+@@ -287,12 +273,11 @@
+
+ int hvc_put_chars(int index, const char *buf, int count)
+ {
+- unsigned long dummy;
+ unsigned long *lbuf = (unsigned long *) buf;
+ long ret;
+
+- ret = plpar_hcall(H_PUT_TERM_CHAR, index, count, lbuf[0], lbuf[1],
+- &dummy, &dummy, &dummy);
++ ret = plpar_hcall_norets(H_PUT_TERM_CHAR, index, count, lbuf[0],
++ lbuf[1]);
+ if (ret == H_Success)
+ return count;
+ if (ret == H_Busy)
+@@ -318,7 +303,6 @@
+
+
+
+-
+ long pSeries_lpar_hpte_insert(unsigned long hpte_group,
+ unsigned long va, unsigned long prpn,
+ int secondary, unsigned long hpteflags,
+@@ -329,6 +313,7 @@
+ unsigned long flags;
+ unsigned long slot;
+ HPTE lhpte;
++ unsigned long dummy0, dummy1;
+
+ /* Fill in the local HPTE with absolute rpn, avpn and flags */
+ lhpte.dw1.dword1 = 0;
+@@ -348,7 +333,6 @@
+
+ /* Now fill in the actual HPTE */
+ /* Set CEC cookie to 0 */
+- /* Large page = 0 */
+ /* Zero page = 0 */
+ /* I-cache Invalidate = 0 */
+ /* I-cache synchronize = 0 */
+@@ -359,19 +343,8 @@
+ if (hpteflags & (_PAGE_GUARDED|_PAGE_NO_CACHE))
+ lhpte.dw1.flags.flags &= ~_PAGE_COHERENT;
+
+- __asm__ __volatile__ (
+- H_ENTER_r3
+- "mr 4, %2\n"
+- "mr 5, %3\n"
+- "mr 6, %4\n"
+- "mr 7, %5\n"
+- HSC
+- "mr %0, 3\n"
+- "mr %1, 4\n"
+- : "=r" (lpar_rc), "=r" (slot)
+- : "r" (flags), "r" (hpte_group), "r" (lhpte.dw0.dword0),
+- "r" (lhpte.dw1.dword1)
+- : "r3", "r4", "r5", "r6", "r7", "cc");
++ lpar_rc = plpar_hcall(H_ENTER, flags, hpte_group, lhpte.dw0.dword0,
++ lhpte.dw1.dword1, &slot, &dummy0, &dummy1);
+
+ if (lpar_rc == H_PTEG_Full)
+ return -1;
+Index: linux-2.6.0-test5/arch/ppc64/kernel/pSeries_pci.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/pSeries_pci.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/pSeries_pci.c 2003-09-27 11:38:19.836512776 +0800
+@@ -427,6 +427,7 @@
+
+ void pcibios_name_device(struct pci_dev *dev)
+ {
++#if 0
+ struct device_node *dn;
+
+ /*
+@@ -446,6 +447,7 @@
+ }
+ }
+ }
++#endif
+ }
+
+ void __init pcibios_fixup_device_resources(struct pci_dev *dev,
+Index: linux-2.6.0-test5/arch/ppc64/kernel/rtas.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/rtas.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/rtas.c 2003-09-27 11:38:19.839512320 +0800
+@@ -24,6 +24,7 @@
+ #include <asm/machdep.h>
+ #include <asm/paca.h>
+ #include <asm/page.h>
++#include <asm/param.h>
+ #include <asm/system.h>
+ #include <asm/abs_addr.h>
+ #include <asm/udbg.h>
+@@ -178,6 +179,26 @@
+ return (ulong)((nret > 0) ? rtas_args->rets[0] : 0);
+ }
+
++/* Given an RTAS status code of 990n compute the hinted delay of 10^n
++ * (last digit) milliseconds. For now we bound at n=3 (1 sec).
++ */
++unsigned int
++rtas_extended_busy_delay_time(int status)
++{
++ int order = status - 9900;
++ unsigned int ms;
++
++ if (order < 0)
++ order = 0; /* RTC depends on this for -2 clock busy */
++ else if (order > 3)
++ order = 3; /* bound */
++
++ /* Use microseconds for reasonable accuracy */
++ for (ms = 1000; order > 0; order--)
++ ms = ms * 10;
++ return ms / (1000000/HZ); /* round down is fine */
++}
++
+ #define FLASH_BLOCK_LIST_VERSION (1UL)
+ static void
+ rtas_flash_firmware(void)
+Index: linux-2.6.0-test5/arch/ppc64/kernel/rtc.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/rtc.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/rtc.c 2003-09-27 11:38:19.843511712 +0800
+@@ -35,6 +35,7 @@
+ #include <linux/spinlock.h>
+ #include <linux/bcd.h>
+
++#include <asm/hardirq.h>
+ #include <asm/io.h>
+ #include <asm/uaccess.h>
+ #include <asm/system.h>
+@@ -340,20 +341,63 @@
+ #endif
+
+ #ifdef CONFIG_PPC_PSERIES
++#define MAX_RTC_WAIT 5000 /* 5 sec */
++#define RTAS_CLOCK_BUSY (-2)
++void pSeries_get_boot_time(struct rtc_time *rtc_tm)
++{
++ unsigned long ret[8];
++ int error, wait_time;
++ unsigned long max_wait_tb;
++
++ max_wait_tb = __get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT;
++ do {
++ error = rtas_call(rtas_token("get-time-of-day"), 0, 8, (void *)&ret);
++ if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) {
++ wait_time = rtas_extended_busy_delay_time(error);
++ /* This is boot time so we spin. */
++ udelay(wait_time*1000);
++ error = RTAS_CLOCK_BUSY;
++ }
++ } while (error == RTAS_CLOCK_BUSY && (__get_tb() < max_wait_tb));
++
++ if (error != 0) {
++ printk(KERN_WARNING "error: reading the clock failed (%d)\n",
++ error);
++ return;
++ }
++
++ rtc_tm->tm_sec = ret[5];
++ rtc_tm->tm_min = ret[4];
++ rtc_tm->tm_hour = ret[3];
++ rtc_tm->tm_mday = ret[2];
++ rtc_tm->tm_mon = ret[1] - 1;
++ rtc_tm->tm_year = ret[0] - 1900;
++}
++
++/* NOTE: get_rtc_time will get an error if executed in interrupt context
++ * and if a delay is needed to read the clock. In this case we just
++ * silently return without updating rtc_tm.
++ */
+ void pSeries_get_rtc_time(struct rtc_time *rtc_tm)
+ {
+ unsigned long ret[8];
+- int error;
+- int count;
++ int error, wait_time;
++ unsigned long max_wait_tb;
+
+- /*
+- * error -2 is clock busy, we keep retrying a few times to see
+- * if it will come good -- paulus
+- */
+- count = 0;
++ max_wait_tb = __get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT;
+ do {
+ error = rtas_call(rtas_token("get-time-of-day"), 0, 8, (void *)&ret);
+- } while (error == -2 && ++count < 1000);
++ if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) {
++ if (in_interrupt()) {
++ printk(KERN_WARNING "error: reading clock would delay interrupt\n");
++ return; /* delay not allowed */
++ }
++ wait_time = rtas_extended_busy_delay_time(error);
++ set_current_state(TASK_INTERRUPTIBLE);
++ schedule_timeout(wait_time);
++ error = RTAS_CLOCK_BUSY;
++ }
++ } while (error == RTAS_CLOCK_BUSY && (__get_tb() < max_wait_tb));
+
+ if (error != 0) {
+ printk(KERN_WARNING "error: reading the clock failed (%d)\n",
+@@ -371,20 +415,24 @@
+
+ int pSeries_set_rtc_time(struct rtc_time *tm)
+ {
+- int error;
+- int count;
++ int error, wait_time;
++ unsigned long max_wait_tb;
+
+- /*
+- * error -2 is clock busy, we keep retrying a few times to see
+- * if it will come good -- paulus
+- */
+- count = 0;
++ max_wait_tb = __get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT;
+ do {
+ error = rtas_call(rtas_token("set-time-of-day"), 7, 1, NULL,
+ tm->tm_year + 1900, tm->tm_mon + 1,
+ tm->tm_mday, tm->tm_hour, tm->tm_min,
+ tm->tm_sec, 0);
+- } while (error == -2 && ++count < 1000);
++ if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) {
++ if (in_interrupt())
++ return 1; /* probably decrementer */
++ wait_time = rtas_extended_busy_delay_time(error);
++ set_current_state(TASK_INTERRUPTIBLE);
++ schedule_timeout(wait_time);
++ error = RTAS_CLOCK_BUSY;
++ }
++ } while (error == RTAS_CLOCK_BUSY && (__get_tb() < max_wait_tb));
+
+ if (error != 0)
+ printk(KERN_WARNING "error: setting the clock failed (%d)\n",
+Index: linux-2.6.0-test5/arch/ppc64/kernel/semaphore.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/semaphore.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/semaphore.c 2003-09-27 11:38:19.845511408 +0800
+@@ -21,6 +21,7 @@
+ #include <asm/semaphore.h>
+ #include <asm/errno.h>
+
++#if 0
+ /*
+ * Atomically update sem->count.
+ * This does the equivalent of the following:
+@@ -75,9 +76,8 @@
+ struct task_struct *tsk = current;
+ DECLARE_WAITQUEUE(wait, tsk);
+
+- tsk->state = TASK_UNINTERRUPTIBLE;
++ __set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+ add_wait_queue_exclusive(&sem->wait, &wait);
+- smp_wmb();
+
+ /*
+ * Try to get the semaphore. If the count is > 0, then we've
+@@ -87,10 +87,10 @@
+ */
+ while (__sem_update_count(sem, -1) <= 0) {
+ schedule();
+- tsk->state = TASK_UNINTERRUPTIBLE;
++ set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+ }
+ remove_wait_queue(&sem->wait, &wait);
+- tsk->state = TASK_RUNNING;
++ __set_task_state(tsk, TASK_RUNNING);
+
+ /*
+ * If there are any more sleepers, wake one of them up so
+@@ -106,9 +106,8 @@
+ struct task_struct *tsk = current;
+ DECLARE_WAITQUEUE(wait, tsk);
+
+- tsk->state = TASK_INTERRUPTIBLE;
++ __set_task_state(tsk, TASK_INTERRUPTIBLE);
+ add_wait_queue_exclusive(&sem->wait, &wait);
+- smp_wmb();
+
+ while (__sem_update_count(sem, -1) <= 0) {
+ if (signal_pending(current)) {
+@@ -122,10 +121,148 @@
+ break;
+ }
+ schedule();
+- tsk->state = TASK_INTERRUPTIBLE;
++ set_task_state(tsk, TASK_INTERRUPTIBLE);
+ }
+- tsk->state = TASK_RUNNING;
+ remove_wait_queue(&sem->wait, &wait);
++ __set_task_state(tsk, TASK_RUNNING);
++
+ wake_up(&sem->wait);
+ return retval;
+ }
++#else
++
++static __inline__ int atomic_add_negative(int i, atomic_t *v)
++{
++ if (atomic_add_return(i, v) < 0)
++ return 1;
++ else
++ return 0;
++}
++
++void __up(struct semaphore *sem)
++{
++ wake_up(&sem->wait);
++}
++
++void __down(struct semaphore * sem)
++{
++ struct task_struct *tsk = current;
++ DECLARE_WAITQUEUE(wait, tsk);
++ unsigned long flags;
++
++ tsk->state = TASK_UNINTERRUPTIBLE;
++ spin_lock_irqsave(&sem->wait.lock, flags);
++ add_wait_queue_exclusive_locked(&sem->wait, &wait);
++
++ sem->sleepers++;
++ for (;;) {
++ int sleepers = sem->sleepers;
++
++ /*
++ * Add "everybody else" into it. They aren't
++ * playing, because we own the spinlock in
++ * the wait_queue_head.
++ */
++ if (!atomic_add_negative(sleepers - 1, &sem->count)) {
++ sem->sleepers = 0;
++ break;
++ }
++ sem->sleepers = 1; /* us - see -1 above */
++ spin_unlock_irqrestore(&sem->wait.lock, flags);
++
++ schedule();
++
++ spin_lock_irqsave(&sem->wait.lock, flags);
++ tsk->state = TASK_UNINTERRUPTIBLE;
++ }
++ remove_wait_queue_locked(&sem->wait, &wait);
++ wake_up_locked(&sem->wait);
++ spin_unlock_irqrestore(&sem->wait.lock, flags);
++ tsk->state = TASK_RUNNING;
++}
++
++int __down_interruptible(struct semaphore * sem)
++{
++ int retval = 0;
++ struct task_struct *tsk = current;
++ DECLARE_WAITQUEUE(wait, tsk);
++ unsigned long flags;
++
++ tsk->state = TASK_INTERRUPTIBLE;
++ spin_lock_irqsave(&sem->wait.lock, flags);
++ add_wait_queue_exclusive_locked(&sem->wait, &wait);
++
++ sem->sleepers++;
++ for (;;) {
++ int sleepers = sem->sleepers;
++
++ /*
++ * With signals pending, this turns into
++ * the trylock failure case - we won't be
++ * sleeping, and we* can't get the lock as
++ * it has contention. Just correct the count
++ * and exit.
++ */
++ if (signal_pending(current)) {
++ retval = -EINTR;
++ sem->sleepers = 0;
++ atomic_add(sleepers, &sem->count);
++ break;
++ }
++
++ /*
++ * Add "everybody else" into it. They aren't
++ * playing, because we own the spinlock in
++ * wait_queue_head. The "-1" is because we're
++ * still hoping to get the semaphore.
++ */
++ if (!atomic_add_negative(sleepers - 1, &sem->count)) {
++ sem->sleepers = 0;
++ break;
++ }
++ sem->sleepers = 1; /* us - see -1 above */
++ spin_unlock_irqrestore(&sem->wait.lock, flags);
++
++ schedule();
++
++ spin_lock_irqsave(&sem->wait.lock, flags);
++ tsk->state = TASK_INTERRUPTIBLE;
++ }
++ remove_wait_queue_locked(&sem->wait, &wait);
++ wake_up_locked(&sem->wait);
++ spin_unlock_irqrestore(&sem->wait.lock, flags);
++
++ tsk->state = TASK_RUNNING;
++ return retval;
++}
++
++/*
++ * Trylock failed - make sure we correct for
++ * having decremented the count.
++ *
++ * We could have done the trylock with a
++ * single "cmpxchg" without failure cases,
++ * but then it wouldn't work on a 386.
++ */
++int __down_trylock(struct semaphore * sem)
++{
++ int sleepers;
++ unsigned long flags;
++
++ spin_lock_irqsave(&sem->wait.lock, flags);
++ sleepers = sem->sleepers + 1;
++ sem->sleepers = 0;
++
++ /*
++ * Add "everybody else" and us into it. They aren't
++ * playing, because we own the spinlock in the
++ * wait_queue_head.
++ */
++ if (!atomic_add_negative(sleepers, &sem->count)) {
++ wake_up_locked(&sem->wait);
++ }
++
++ spin_unlock_irqrestore(&sem->wait.lock, flags);
++ return 1;
++}
++#endif
+Index: linux-2.6.0-test5/arch/ppc64/kernel/stab.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/stab.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/stab.c 2003-09-27 11:38:19.848510952 +0800
+@@ -221,15 +221,18 @@
+ }
+
+ static inline void __ste_allocate(unsigned long esid, unsigned long vsid,
+- int kernel_segment)
++ int kernel_segment, mm_context_t context)
+ {
+ if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) {
++ int large = 0;
++
+ #ifndef CONFIG_PPC_ISERIES
+ if (REGION_ID(esid << SID_SHIFT) == KERNEL_REGION_ID)
+- make_slbe(esid, vsid, 1, kernel_segment);
+- else
++ large = 1;
++ else if (REGION_ID(esid << SID_SHIFT) == USER_REGION_ID)
++ large = in_hugepage_area(context, esid << SID_SHIFT);
+ #endif
+- make_slbe(esid, vsid, 0, kernel_segment);
++ make_slbe(esid, vsid, large, kernel_segment);
+ } else {
+ unsigned char top_entry, stab_entry, *segments;
+
+@@ -255,6 +258,7 @@
+ {
+ unsigned long vsid, esid;
+ int kernel_segment = 0;
++ mm_context_t context;
+
+ PMC_SW_PROCESSOR(stab_faults);
+
+@@ -266,16 +270,18 @@
+ if (REGION_ID(ea) >= KERNEL_REGION_ID) {
+ kernel_segment = 1;
+ vsid = get_kernel_vsid(ea);
++ context = REGION_ID(ea);
+ } else {
+- struct mm_struct *mm = current->mm;
+- if (mm)
+- vsid = get_vsid(mm->context, ea);
+- else
++ if (! current->mm)
+ return 1;
++
++ context = current->mm->context;
++
++ vsid = get_vsid(context, ea);
+ }
+
+ esid = GET_ESID(ea);
+- __ste_allocate(esid, vsid, kernel_segment);
++ __ste_allocate(esid, vsid, kernel_segment, context);
+ if (!(cur_cpu_spec->cpu_features & CPU_FTR_SLB)) {
+ /* Order update */
+ asm volatile("sync":::"memory");
+@@ -302,7 +308,7 @@
+ for (esid = 0; esid < 16; esid++) {
+ unsigned long ea = esid << SID_SHIFT;
+ vsid = get_vsid(mm->context, ea);
+- __ste_allocate(esid, vsid, 0);
++ __ste_allocate(esid, vsid, 0, mm->context);
+ }
+ } else {
+ unsigned long pc = KSTK_EIP(tsk);
+@@ -316,7 +322,7 @@
+ (REGION_ID(pc) >= KERNEL_REGION_ID))
+ return;
+ vsid = get_vsid(mm->context, pc);
+- __ste_allocate(GET_ESID(pc), vsid, 0);
++ __ste_allocate(GET_ESID(pc), vsid, 0, mm->context);
+ }
+
+ if (stack && (pc_segment != stack_segment)) {
+@@ -324,7 +330,7 @@
+ (REGION_ID(stack) >= KERNEL_REGION_ID))
+ return;
+ vsid = get_vsid(mm->context, stack);
+- __ste_allocate(GET_ESID(stack), vsid, 0);
++ __ste_allocate(GET_ESID(stack), vsid, 0, mm->context);
+ }
+ }
+
+Index: linux-2.6.0-test5/arch/ppc64/kernel/syscalls.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/syscalls.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/syscalls.c 2003-09-27 11:38:19.851510496 +0800
+@@ -1,5 +1,5 @@
+ /*
+- * linux/arch/ppc/kernel/sys_ppc.c
++ * linux/arch/ppc64/kernel/sys_ppc.c
+ *
+ * PowerPC version
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+@@ -40,7 +40,6 @@
+ #include <asm/uaccess.h>
+ #include <asm/ipc.h>
+ #include <asm/semaphore.h>
+-#include <asm/ppcdebug.h>
+ #include <asm/time.h>
+
+ extern unsigned long wall_jiffies;
+@@ -79,6 +78,7 @@
+ case SEMCTL: {
+ union semun fourth;
+
++ ret = -EINVAL;
+ if (!ptr)
+ break;
+ if ((ret = get_user(fourth.__pad, (void **)ptr)))
+@@ -94,6 +94,7 @@
+ case 0: {
+ struct ipc_kludge tmp;
+
++ ret = -EINVAL;
+ if (!ptr)
+ break;
+ if ((ret = copy_from_user(&tmp,
+@@ -127,6 +128,7 @@
+ break;
+ }
+ case 1: /* iBCS2 emulator entry point */
++ ret = -EINVAL;
+ if (!segment_eq(get_fs(), get_ds()))
+ break;
+ ret = sys_shmat (first, (char *) ptr, second,
+Index: linux-2.6.0-test5/arch/ppc64/kernel/sys_ppc32.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/sys_ppc32.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/sys_ppc32.c 2003-09-27 11:38:19.871507456 +0800
+@@ -748,16 +748,16 @@
+ {
+ int err;
+
+- if (stat->size > MAX_NON_LFS)
+- return -EOVERFLOW;
++ if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) ||
++ !new_valid_dev(stat->rdev))
+
+- err = put_user(stat->dev, &statbuf->st_dev);
++ err = put_user(new_encode_dev(stat->dev), &statbuf->st_dev);
+ err |= put_user(stat->ino, &statbuf->st_ino);
+ err |= put_user(stat->mode, &statbuf->st_mode);
+ err |= put_user(stat->nlink, &statbuf->st_nlink);
+ err |= put_user(stat->uid, &statbuf->st_uid);
+ err |= put_user(stat->gid, &statbuf->st_gid);
+- err |= put_user(stat->rdev, &statbuf->st_rdev);
++ err |= put_user(new_encode_dev(stat->rdev), &statbuf->st_rdev);
+ err |= put_user(stat->size, &statbuf->st_size);
+ err |= put_user(stat->atime.tv_sec, &statbuf->st_atime);
+ err |= put_user(0, &statbuf->__unused1);
+@@ -1243,16 +1243,19 @@
+ }
+
+
+-struct msgbuf32 { s32 mtype; char mtext[1]; };
++struct msgbuf32 {
++ compat_long_t mtype;
++ char mtext[1];
++};
+
+ struct semid_ds32 {
+ struct ipc_perm sem_perm;
+ compat_time_t sem_otime;
+ compat_time_t sem_ctime;
+- u32 sem_base;
+- u32 sem_pending;
+- u32 sem_pending_last;
+- u32 undo;
++ compat_uptr_t sem_base;
++ compat_uptr_t sem_pending;
++ compat_uptr_t sem_pending_last;
++ compat_uptr_t undo;
+ unsigned short sem_nsems;
+ };
+
+@@ -1262,21 +1265,20 @@
+ compat_time_t sem_otime;
+ unsigned int __unused2;
+ compat_time_t sem_ctime;
+- u32 sem_nsems;
+- u32 __unused3;
+- u32 __unused4;
++ compat_ulong_t sem_nsems;
++ compat_ulong_t __unused3;
++ compat_ulong_t __unused4;
+ };
+
+-struct msqid_ds32
+-{
++struct msqid_ds32 {
+ struct ipc_perm msg_perm;
+- u32 msg_first;
+- u32 msg_last;
++ compat_uptr_t msg_first;
++ compat_uptr_t msg_last;
+ compat_time_t msg_stime;
+ compat_time_t msg_rtime;
+ compat_time_t msg_ctime;
+- u32 msg_lcbytes;
+- u32 msg_lqbytes;
++ compat_ulong_t msg_lcbytes;
++ compat_ulong_t msg_lqbytes;
+ unsigned short msg_cbytes;
+ unsigned short msg_qnum;
+ unsigned short msg_qbytes;
+@@ -1292,13 +1294,13 @@
+ compat_time_t msg_rtime;
+ unsigned int __unused3;
+ compat_time_t msg_ctime;
+- unsigned int msg_cbytes;
+- unsigned int msg_qnum;
+- unsigned int msg_qbytes;
++ compat_ulong_t msg_cbytes;
++ compat_ulong_t msg_qnum;
++ compat_ulong_t msg_qbytes;
+ compat_pid_t msg_lspid;
+ compat_pid_t msg_lrpid;
+- unsigned int __unused4;
+- unsigned int __unused5;
++ compat_ulong_t __unused4;
++ compat_ulong_t __unused5;
+ };
+
+ struct shmid_ds32 {
+@@ -1311,8 +1313,8 @@
+ compat_ipc_pid_t shm_lpid;
+ unsigned short shm_nattch;
+ unsigned short __unused;
+- unsigned int __unused2;
+- unsigned int __unused3;
++ compat_uptr_t __unused2;
++ compat_uptr_t __unused3;
+ };
+
+ struct shmid64_ds32 {
+@@ -1327,9 +1329,9 @@
+ compat_size_t shm_segsz;
+ compat_pid_t shm_cpid;
+ compat_pid_t shm_lpid;
+- unsigned int shm_nattch;
+- unsigned int __unused5;
+- unsigned int __unused6;
++ compat_ulong_t shm_nattch;
++ compat_ulong_t __unused5;
++ compat_ulong_t __unused6;
+ };
+
+ /*
+@@ -1350,7 +1352,7 @@
+ err = -EFAULT;
+ if (get_user(pad, (u32 *)uptr))
+ return err;
+- if (third == SETVAL)
++ if ((third & ~IPC_64) == SETVAL)
+ fourth.val = (int)pad;
+ else
+ fourth.__pad = (void *)A(pad);
+Index: linux-2.6.0-test5/arch/ppc64/kernel/time.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/time.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/time.c 2003-09-27 11:38:19.877506544 +0800
+@@ -307,6 +307,15 @@
+ return 1;
+ }
+
++/*
++ * Scheduler clock - returns current time in nanosec units.
++ *
++ * This is wrong, but my CPUs run at 1GHz, so nyer nyer.
++ */
++unsigned long long sched_clock(void)
++{
++ return get_tb();
++}
+
+ /*
+ * This version of gettimeofday has microsecond resolution.
+Index: linux-2.6.0-test5/arch/ppc64/kernel/vmlinux.lds.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/vmlinux.lds.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/vmlinux.lds.S 2003-09-27 11:38:19.878506392 +0800
+@@ -137,4 +137,9 @@
+ . = ALIGN(4096);
+ _end = . ;
+ PROVIDE (end = .);
++
++ /* Sections to be discarded. */
++ /DISCARD/ : {
++ *(.exitcall.exit)
++ }
+ }
+Index: linux-2.6.0-test5/arch/ppc64/kernel/xics.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/xics.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/xics.c 2003-09-27 11:38:19.883505632 +0800
+@@ -267,6 +267,15 @@
+ irq, call_status);
+ return;
+ }
++
++ /* Have to set XIVE to 0xff to be able to remove a slot */
++ call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, default_server,
++ 0xff);
++ if (call_status != 0) {
++ printk("xics_disable_irq: irq=%x: ibm_set_xive(0xff) returned %lx\n",
++ irq, call_status);
++ return;
++ }
+ }
+
+ void xics_end_irq(u_int irq)
+@@ -375,12 +384,12 @@
+ int i;
+ unsigned long intr_size = 0;
+ struct device_node *np;
+- uint *ireg, ilen, indx=0;
++ uint *ireg, ilen, indx = 0;
+ unsigned long intr_base = 0;
+ struct xics_interrupt_node {
+- unsigned long long addr;
+- unsigned long long size;
+- } inodes[NR_CPUS*2];
++ unsigned long addr;
++ unsigned long size;
++ } inodes[NR_CPUS];
+
+ ppc64_boot_msg(0x20, "XICS Init");
+
+Index: linux-2.6.0-test5/arch/ppc64/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/Makefile 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/Makefile 2003-09-27 11:38:19.884505480 +0800
+@@ -18,7 +18,13 @@
+ LDFLAGS := -m elf64ppc
+ LDFLAGS_vmlinux := -Bstatic -e $(KERNELLOAD) -Ttext $(KERNELLOAD)
+ CFLAGS += -msoft-float -pipe -Wno-uninitialized -mminimal-toc \
+- -mtraceback=full -mcpu=power4
++ -mcpu=power4
++
++have_zero_bss := $(shell if $(CC) -fno-zero-initialized-in-bss -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo y; else echo n; fi)
++
++ifeq ($(have_zero_bss),y)
++CFLAGS += -fno-zero-initialized-in-bss
++endif
+
+ head-y := arch/ppc64/kernel/head.o
+
+@@ -39,6 +45,12 @@
+ rm -f .config arch/ppc64/defconfig
+ cp -f arch/ppc64/configs/$(@:config=defconfig) arch/ppc64/defconfig
+
++bootimage-$(CONFIG_PPC_PSERIES) := zImage
++bootimage-$(CONFIG_PPC_ISERIES) := vmlinux.sm
++BOOTIMAGE := $(bootimage-y)
++install: vmlinux
++ $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) $@
++
+ archclean:
+ $(Q)$(MAKE) $(clean)=$(boot)
+
+Index: linux-2.6.0-test5/arch/ppc64/mm/fault.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/mm/fault.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/mm/fault.c 2003-09-27 11:38:19.887505024 +0800
+@@ -46,8 +46,10 @@
+ void bad_page_fault(struct pt_regs *, unsigned long, int);
+
+ /*
+- * For 600- and 800-family processors, the error_code parameter is DSISR
+- * for a data fault, SRR1 for an instruction fault.
++ * The error_code parameter is
++ * - DSISR for a non-SLB data access fault,
++ * - SRR1 & 0x08000000 for a non-SLB instruction access fault
++ * - 0 any SLB fault.
+ */
+ void do_page_fault(struct pt_regs *regs, unsigned long address,
+ unsigned long error_code)
+@@ -58,17 +60,6 @@
+ unsigned long code = SEGV_MAPERR;
+ unsigned long is_write = error_code & 0x02000000;
+
+- /*
+- * Fortunately the bit assignments in SRR1 for an instruction
+- * fault and DSISR for a data fault are mostly the same for the
+- * bits we are interested in. But there are some bits which
+- * indicate errors in DSISR but can validly be set in SRR1.
+- */
+- if (regs->trap == 0x400)
+- error_code &= 0x48200000;
+- else if (regs->trap != 0x300) /* ensure error_code is 0 on SLB miss */
+- error_code = 0;
+-
+ #ifdef CONFIG_DEBUG_KERNEL
+ if (debugger_fault_handler && (regs->trap == 0x300 ||
+ regs->trap == 0x380)) {
+Index: linux-2.6.0-test5/arch/ppc64/mm/hugetlbpage.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/mm/hugetlbpage.c 2003-09-27 11:38:18.439725120 +0800
++++ linux-2.6.0-test5/arch/ppc64/mm/hugetlbpage.c 2003-09-27 11:38:19.889504720 +0800
+@@ -0,0 +1,925 @@
++/*
++ * PPC64 (POWER4) Huge TLB Page Support for Kernel.
++ *
++ * Copyright (C) 2003 David Gibson, IBM Corporation.
++ *
++ * Based on the IA-32 version:
++ * Copyright (C) 2002, Rohit Seth <rohit.seth@intel.com>
++ */
++
++#include <linux/config.h>
++#include <linux/init.h>
++#include <linux/fs.h>
++#include <linux/mm.h>
++#include <linux/hugetlb.h>
++#include <linux/pagemap.h>
++#include <linux/smp_lock.h>
++#include <linux/slab.h>
++#include <linux/module.h>
++#include <linux/err.h>
++#include <linux/sysctl.h>
++#include <asm/mman.h>
++#include <asm/pgalloc.h>
++#include <asm/tlb.h>
++#include <asm/tlbflush.h>
++#include <asm/mmu_context.h>
++#include <asm/machdep.h>
++#include <asm/cputable.h>
++#include <asm/tlb.h>
++#include <asm/rmap.h>
++
++#include <linux/sysctl.h>
++
++int htlbpage_max;
++
++/* This lock protects the two counters and list below */
++static spinlock_t htlbpage_lock = SPIN_LOCK_UNLOCKED;
++
++static int htlbpage_free; /* = 0 */
++static int htlbpage_total; /* = 0 */
++static struct list_head hugepage_freelists[MAX_NUMNODES];
++
++static void enqueue_huge_page(struct page *page)
++{
++ list_add(&page->list,
++ &hugepage_freelists[page_zone(page)->zone_pgdat->node_id]);
++}
++
++/* XXX make this a sysctl */
++unsigned long largepage_roundrobin = 1;
++
++static struct page *dequeue_huge_page(void)
++{
++ static int nid = 0;
++ struct page *page = NULL;
++ int i;
++
++ if (!largepage_roundrobin)
++ nid = numa_node_id();
++
++ for (i = 0; i < numnodes; i++) {
++ if (!list_empty(&hugepage_freelists[nid]))
++ break;
++ nid = (nid + 1) % numnodes;
++ }
++
++ if (!list_empty(&hugepage_freelists[nid])) {
++ page = list_entry(hugepage_freelists[nid].next, struct page, list);
++ list_del(&page->list);
++ }
++
++ if (largepage_roundrobin)
++ nid = (nid + 1) % numnodes;
++
++ return page;
++}
++
++static struct page *alloc_fresh_huge_page(void)
++{
++ static int nid = 0;
++ struct page *page;
++
++ page = alloc_pages_node(nid, GFP_HIGHUSER, HUGETLB_PAGE_ORDER);
++ if (!page)
++ return NULL;
++
++ nid = page_zone(page)->zone_pgdat->node_id;
++ nid = (nid + 1) % numnodes;
++ return page;
++}
++
++/* HugePTE layout:
++ *
++ * 31 30 ... 15 14 13 12 10 9 8 7 6 5 4 3 2 1 0
++ * PFN>>12..... - - - - - - HASH_IX.... 2ND HASH RW - HG=1
++ */
++
++#define HUGEPTE_SHIFT 15
++#define _HUGEPAGE_PFN 0xffff8000
++#define _HUGEPAGE_BAD 0x00007f00
++#define _HUGEPAGE_HASHPTE 0x00000008
++#define _HUGEPAGE_SECONDARY 0x00000010
++#define _HUGEPAGE_GROUP_IX 0x000000e0
++#define _HUGEPAGE_HPTEFLAGS (_HUGEPAGE_HASHPTE | _HUGEPAGE_SECONDARY | \
++ _HUGEPAGE_GROUP_IX)
++#define _HUGEPAGE_RW 0x00000004
++
++typedef struct {unsigned int val;} hugepte_t;
++#define hugepte_val(hugepte) ((hugepte).val)
++#define __hugepte(x) ((hugepte_t) { (x) } )
++#define hugepte_pfn(x) \
++ ((unsigned long)(hugepte_val(x)>>HUGEPTE_SHIFT) << HUGETLB_PAGE_ORDER)
++#define mk_hugepte(page,wr) __hugepte( \
++ ((page_to_pfn(page)>>HUGETLB_PAGE_ORDER) << HUGEPTE_SHIFT ) \
++ | (!!(wr) * _HUGEPAGE_RW) | _PMD_HUGEPAGE )
++
++#define hugepte_bad(x) ( !(hugepte_val(x) & _PMD_HUGEPAGE) || \
++ (hugepte_val(x) & _HUGEPAGE_BAD) )
++#define hugepte_page(x) pfn_to_page(hugepte_pfn(x))
++#define hugepte_none(x) (!(hugepte_val(x) & _HUGEPAGE_PFN))
++
++
++static void free_huge_page(struct page *page);
++static void flush_hash_hugepage(mm_context_t context, unsigned long ea,
++ hugepte_t pte, int local);
++
++static inline unsigned int hugepte_update(hugepte_t *p, unsigned int clr,
++ unsigned int set)
++{
++ unsigned int old, tmp;
++
++ __asm__ __volatile__(
++ "1: lwarx %0,0,%3 # pte_update\n\
++ andc %1,%0,%4 \n\
++ or %1,%1,%5 \n\
++ stwcx. %1,0,%3 \n\
++ bne- 1b"
++ : "=&r" (old), "=&r" (tmp), "=m" (*p)
++ : "r" (p), "r" (clr), "r" (set), "m" (*p)
++ : "cc" );
++ return old;
++}
++
++static inline void set_hugepte(hugepte_t *ptep, hugepte_t pte)
++{
++ hugepte_update(ptep, ~_HUGEPAGE_HPTEFLAGS,
++ hugepte_val(pte) & ~_HUGEPAGE_HPTEFLAGS);
++}
++
++static struct page *alloc_hugetlb_page(void)
++{
++ int i;
++ struct page *page;
++
++ spin_lock(&htlbpage_lock);
++ page = dequeue_huge_page();
++ if (!page) {
++ spin_unlock(&htlbpage_lock);
++ return NULL;
++ }
++
++ htlbpage_free--;
++ spin_unlock(&htlbpage_lock);
++ set_page_count(page, 1);
++ page->lru.prev = (void *)free_huge_page;
++ for (i = 0; i < (HPAGE_SIZE/PAGE_SIZE); ++i)
++ clear_highpage(&page[i]);
++ return page;
++}
++
++static hugepte_t *hugepte_alloc(struct mm_struct *mm, unsigned long addr)
++{
++ pgd_t *pgd;
++ pmd_t *pmd = NULL;
++
++ BUG_ON(!in_hugepage_area(mm->context, addr));
++
++ pgd = pgd_offset(mm, addr);
++ pmd = pmd_alloc(mm, pgd, addr);
++
++ /* We shouldn't find a (normal) PTE page pointer here */
++ BUG_ON(!pmd_none(*pmd) && !pmd_hugepage(*pmd));
++
++ return (hugepte_t *)pmd;
++}
++
++static hugepte_t *hugepte_offset(struct mm_struct *mm, unsigned long addr)
++{
++ pgd_t *pgd;
++ pmd_t *pmd = NULL;
++
++ BUG_ON(!in_hugepage_area(mm->context, addr));
++
++ pgd = pgd_offset(mm, addr);
++ pmd = pmd_offset(pgd, addr);
++
++ /* We shouldn't find a (normal) PTE page pointer here */
++ BUG_ON(!pmd_none(*pmd) && !pmd_hugepage(*pmd));
++
++ return (hugepte_t *)pmd;
++}
++
++static void setup_huge_pte(struct mm_struct *mm, struct page *page,
++ hugepte_t *ptep, int write_access)
++{
++ hugepte_t entry;
++ int i;
++
++ mm->rss += (HPAGE_SIZE / PAGE_SIZE);
++ entry = mk_hugepte(page, write_access);
++ for (i = 0; i < HUGEPTE_BATCH_SIZE; i++)
++ set_hugepte(ptep+i, entry);
++}
++
++static void teardown_huge_pte(hugepte_t *ptep)
++{
++ int i;
++
++ for (i = 0; i < HUGEPTE_BATCH_SIZE; i++)
++ pmd_clear((pmd_t *)(ptep+i));
++}
++
++/*
++ * This function checks for proper alignment of input addr and len parameters.
++ */
++int is_aligned_hugepage_range(unsigned long addr, unsigned long len)
++{
++ if (len & ~HPAGE_MASK)
++ return -EINVAL;
++ if (addr & ~HPAGE_MASK)
++ return -EINVAL;
++ if (! is_hugepage_only_range(addr, len))
++ return -EINVAL;
++ return 0;
++}
++
++static void do_slbia(void *unused)
++{
++ asm volatile ("isync; slbia; isync":::"memory");
++}
++
++/* Activate the low hpage region for 32bit processes. mmap_sem must
++ * be held*/
++static int open_32bit_htlbpage_range(struct mm_struct *mm)
++{
++ struct vm_area_struct *vma;
++ unsigned long addr;
++
++ if (mm->context & CONTEXT_LOW_HPAGES)
++ return 0; /* The window is already open */
++
++ /* Check no VMAs are in the region */
++ vma = find_vma(mm, TASK_HPAGE_BASE_32);
++
++ if (vma && (vma->vm_start < TASK_HPAGE_END_32))
++ return -EBUSY;
++
++ /* Clean up any leftover PTE pages in the region */
++ spin_lock(&mm->page_table_lock);
++ for (addr = TASK_HPAGE_BASE_32; addr < TASK_HPAGE_END_32;
++ addr += PMD_SIZE) {
++ pgd_t *pgd = pgd_offset(mm, addr);
++ pmd_t *pmd = pmd_offset(pgd, addr);
++
++ if (! pmd_none(*pmd)) {
++ struct page *page = pmd_page(*pmd);
++ pte_t *pte = (pte_t *)pmd_page_kernel(*pmd);
++ int i;
++
++ /* No VMAs, so there should be no PTEs, check
++ * just in case. */
++ for (i = 0; i < PTRS_PER_PTE; i++) {
++ BUG_ON(! pte_none(*pte));
++ pte++;
++ }
++
++ pmd_clear(pmd);
++ pgtable_remove_rmap(page);
++ pte_free(page);
++ }
++ }
++ spin_unlock(&mm->page_table_lock);
++
++ /* FIXME: do we need to scan for PTEs too? */
++
++ mm->context |= CONTEXT_LOW_HPAGES;
++
++ /* the context change must make it to memory before the slbia,
++ * so that further SLB misses do the right thing. */
++ mb();
++
++ on_each_cpu(do_slbia, NULL, 0, 1);
++
++ return 0;
++}
++
++int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
++ struct vm_area_struct *vma)
++{
++ hugepte_t *src_pte, *dst_pte, entry;
++ struct page *ptepage;
++ unsigned long addr = vma->vm_start;
++ unsigned long end = vma->vm_end;
++
++ while (addr < end) {
++ BUG_ON(! in_hugepage_area(src->context, addr));
++ BUG_ON(! in_hugepage_area(dst->context, addr));
++
++ dst_pte = hugepte_alloc(dst, addr);
++ if (!dst_pte)
++ return -ENOMEM;
++
++ src_pte = hugepte_offset(src, addr);
++ entry = *src_pte;
++
++ if ((addr % HPAGE_SIZE) == 0) {
++ /* This is the first hugepte in a batch */
++ ptepage = hugepte_page(entry);
++ get_page(ptepage);
++ dst->rss += (HPAGE_SIZE / PAGE_SIZE);
++ }
++ set_hugepte(dst_pte, entry);
++
++
++ addr += PMD_SIZE;
++ }
++ return 0;
++}
++
++int
++follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
++ struct page **pages, struct vm_area_struct **vmas,
++ unsigned long *position, int *length, int i)
++{
++ unsigned long vpfn, vaddr = *position;
++ int remainder = *length;
++
++ WARN_ON(!is_vm_hugetlb_page(vma));
++
++ vpfn = vaddr/PAGE_SIZE;
++ while (vaddr < vma->vm_end && remainder) {
++ BUG_ON(!in_hugepage_area(mm->context, vaddr));
++
++ if (pages) {
++ hugepte_t *pte;
++ struct page *page;
++
++ pte = hugepte_offset(mm, vaddr);
++
++ /* hugetlb should be locked, and hence, prefaulted */
++ WARN_ON(!pte || hugepte_none(*pte));
++
++ page = &hugepte_page(*pte)[vpfn % (HPAGE_SIZE/PAGE_SIZE)];
++
++ WARN_ON(!PageCompound(page));
++
++ get_page(page);
++ pages[i] = page;
++ }
++
++ if (vmas)
++ vmas[i] = vma;
++
++ vaddr += PAGE_SIZE;
++ ++vpfn;
++ --remainder;
++ ++i;
++ }
++
++ *length = remainder;
++ *position = vaddr;
++
++ return i;
++}
++
++struct page *
++follow_huge_addr(struct mm_struct *mm,
++ struct vm_area_struct *vma, unsigned long address, int write)
++{
++ return NULL;
++}
++
++struct vm_area_struct *hugepage_vma(struct mm_struct *mm, unsigned long addr)
++{
++ return NULL;
++}
++
++int pmd_huge(pmd_t pmd)
++{
++ return pmd_hugepage(pmd);
++}
++
++struct page *
++follow_huge_pmd(struct mm_struct *mm, unsigned long address,
++ pmd_t *pmd, int write)
++{
++ struct page *page;
++
++ BUG_ON(! pmd_hugepage(*pmd));
++
++ page = hugepte_page(*(hugepte_t *)pmd);
++ if (page) {
++ page += ((address & ~HPAGE_MASK) >> PAGE_SHIFT);
++ get_page(page);
++ }
++ return page;
++}
++
++static void free_huge_page(struct page *page)
++{
++ BUG_ON(page_count(page));
++ BUG_ON(page->mapping);
++
++ INIT_LIST_HEAD(&page->list);
++
++ spin_lock(&htlbpage_lock);
++ enqueue_huge_page(page);
++ htlbpage_free++;
++ spin_unlock(&htlbpage_lock);
++}
++
++void huge_page_release(struct page *page)
++{
++ if (!put_page_testzero(page))
++ return;
++
++ free_huge_page(page);
++}
++
++void unmap_hugepage_range(struct vm_area_struct *vma,
++ unsigned long start, unsigned long end)
++{
++ struct mm_struct *mm = vma->vm_mm;
++ unsigned long addr;
++ hugepte_t *ptep;
++ struct page *page;
++ int local = 0;
++ cpumask_t tmp;
++
++ WARN_ON(!is_vm_hugetlb_page(vma));
++ BUG_ON((start % HPAGE_SIZE) != 0);
++ BUG_ON((end % HPAGE_SIZE) != 0);
++
++ /* XXX are there races with checking cpu_vm_mask? - Anton */
++ tmp = cpumask_of_cpu(smp_processor_id());
++ if (cpus_equal(vma->vm_mm->cpu_vm_mask, tmp))
++ local = 1;
++
++ for (addr = start; addr < end; addr += HPAGE_SIZE) {
++ hugepte_t pte;
++
++ BUG_ON(!in_hugepage_area(mm->context, addr));
++
++ ptep = hugepte_offset(mm, addr);
++ if (!ptep || hugepte_none(*ptep))
++ continue;
++
++ pte = *ptep;
++ page = hugepte_page(pte);
++ teardown_huge_pte(ptep);
++
++ if (hugepte_val(pte) & _HUGEPAGE_HASHPTE)
++ flush_hash_hugepage(mm->context, addr,
++ pte, local);
++
++ huge_page_release(page);
++ }
++
++ mm->rss -= (end - start) >> PAGE_SHIFT;
++}
++
++void zap_hugepage_range(struct vm_area_struct *vma,
++ unsigned long start, unsigned long length)
++{
++ struct mm_struct *mm = vma->vm_mm;
++
++ spin_lock(&mm->page_table_lock);
++ unmap_hugepage_range(vma, start, start + length);
++ spin_unlock(&mm->page_table_lock);
++}
++
++int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma)
++{
++ struct mm_struct *mm = current->mm;
++ unsigned long addr;
++ int ret = 0;
++
++ WARN_ON(!is_vm_hugetlb_page(vma));
++ BUG_ON((vma->vm_start % HPAGE_SIZE) != 0);
++ BUG_ON((vma->vm_end % HPAGE_SIZE) != 0);
++
++ spin_lock(&mm->page_table_lock);
++ for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) {
++ unsigned long idx;
++ hugepte_t *pte = hugepte_alloc(mm, addr);
++ struct page *page;
++
++ BUG_ON(!in_hugepage_area(mm->context, addr));
++
++ if (!pte) {
++ ret = -ENOMEM;
++ goto out;
++ }
++ if (!hugepte_none(*pte))
++ continue;
++
++ idx = ((addr - vma->vm_start) >> HPAGE_SHIFT)
++ + (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
++ page = find_get_page(mapping, idx);
++ if (!page) {
++ page = alloc_hugetlb_page();
++ if (!page) {
++ ret = -ENOMEM;
++ goto out;
++ }
++ ret = add_to_page_cache(page, mapping, idx, GFP_ATOMIC);
++ unlock_page(page);
++ if (ret) {
++ free_huge_page(page);
++ goto out;
++ }
++ }
++ setup_huge_pte(mm, page, pte, vma->vm_flags & VM_WRITE);
++ }
++out:
++ spin_unlock(&mm->page_table_lock);
++ return ret;
++}
++
++/* Because we have an exclusive hugepage region which lies within the
++ * normal user address space, we have to take special measures to make
++ * non-huge mmap()s evade the hugepage reserved region. */
++unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
++ unsigned long len, unsigned long pgoff,
++ unsigned long flags)
++{
++ struct mm_struct *mm = current->mm;
++ struct vm_area_struct *vma;
++ unsigned long start_addr;
++
++ if (len > TASK_SIZE)
++ return -ENOMEM;
++
++ if (addr) {
++ addr = PAGE_ALIGN(addr);
++ vma = find_vma(mm, addr);
++ if (TASK_SIZE - len >= addr &&
++ (!vma || addr + len <= vma->vm_start) &&
++ !is_hugepage_only_range(addr,len))
++ return addr;
++ }
++ start_addr = addr = mm->free_area_cache;
++
++full_search:
++ for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
++ /* At this point: (!vma || addr < vma->vm_end). */
++ if (TASK_SIZE - len < addr) {
++ /*
++ * Start a new search - just in case we missed
++ * some holes.
++ */
++ if (start_addr != TASK_UNMAPPED_BASE) {
++ start_addr = addr = TASK_UNMAPPED_BASE;
++ goto full_search;
++ }
++ return -ENOMEM;
++ }
++ if (!vma || addr + len <= vma->vm_start) {
++ if (is_hugepage_only_range(addr, len)) {
++ if (addr < TASK_HPAGE_END_32)
++ addr = TASK_HPAGE_END_32;
++ else
++ addr = TASK_HPAGE_END;
++
++ continue;
++ }
++ /*
++ * Remember the place where we stopped the search:
++ */
++ mm->free_area_cache = addr + len;
++ return addr;
++ }
++ addr = vma->vm_end;
++ }
++}
++
++
++unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
++ unsigned long len, unsigned long pgoff,
++ unsigned long flags)
++{
++ struct vm_area_struct *vma;
++ unsigned long base, end;
++
++ if (len & ~HPAGE_MASK)
++ return -EINVAL;
++
++ if (!(cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE))
++ return -EINVAL;
++
++ if (test_thread_flag(TIF_32BIT)) {
++ int err;
++
++ err = open_32bit_htlbpage_range(current->mm);
++ if (err)
++ return err; /* Should this just be EINVAL? */
++
++ base = TASK_HPAGE_BASE_32;
++ end = TASK_HPAGE_END_32;
++ } else {
++ base = TASK_HPAGE_BASE;
++ end = TASK_HPAGE_END;
++ }
++
++ if (!in_hugepage_area(current->mm->context, addr)
++ || (addr & (HPAGE_SIZE - 1)))
++ addr = base;
++
++ for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
++ /* At this point: (!vma || addr < vma->vm_end). */
++ if (addr + len > end)
++ return -ENOMEM;
++ if (!vma || (addr + len) <= vma->vm_start)
++ return addr;
++ addr = ALIGN(vma->vm_end, HPAGE_SIZE);
++
++ /* Because we're in an exclusively hugepage region,
++ * this alignment shouldn't have skipped over any
++ * other vmas */
++ }
++}
++
++static inline unsigned long computeHugeHptePP(unsigned int hugepte)
++{
++ unsigned long flags = 0x2;
++
++ if (! (hugepte & _HUGEPAGE_RW))
++ flags |= 0x1;
++ return flags;
++}
++
++int hash_huge_page(struct mm_struct *mm, unsigned long access,
++ unsigned long ea, unsigned long vsid, int local)
++{
++ hugepte_t *ptep;
++ unsigned long va, vpn;
++ int is_write;
++ hugepte_t old_pte, new_pte;
++ unsigned long hpteflags, prpn;
++ long slot;
++
++ /* Is this for us? */
++ if (!in_hugepage_area(mm->context, ea))
++ return -1;
++
++ ea &= ~(HPAGE_SIZE-1);
++
++ /* We have to find the first hugepte in the batch, since
++ * that's the one that will store the HPTE flags */
++ ptep = hugepte_offset(mm, ea);
++
++ /* Search the Linux page table for a match with va */
++ va = (vsid << 28) | (ea & 0x0fffffff);
++ vpn = va >> HPAGE_SHIFT;
++
++ /*
++ * If no pte found or not present, send the problem up to
++ * do_page_fault
++ */
++ if (unlikely(!ptep || hugepte_none(*ptep)))
++ return 1;
++
++ BUG_ON(hugepte_bad(*ptep));
++
++ /*
++ * Check the user's access rights to the page. If access should be
++ * prevented then send the problem up to do_page_fault.
++ */
++ is_write = access & _PAGE_RW;
++ if (unlikely(is_write && !(hugepte_val(*ptep) & _HUGEPAGE_RW)))
++ return 1;
++
++ /*
++ * At this point, we have a pte (old_pte) which can be used to build
++ * or update an HPTE. There are 2 cases:
++ *
++ * 1. There is a valid (present) pte with no associated HPTE (this is
++ * the most common case)
++ * 2. There is a valid (present) pte with an associated HPTE. The
++ * current values of the pp bits in the HPTE prevent access
++ * because we are doing software DIRTY bit management and the
++ * page is currently not DIRTY.
++ */
++
++ old_pte = *ptep;
++ new_pte = old_pte;
++
++ hpteflags = computeHugeHptePP(hugepte_val(new_pte));
++
++ /* Check if pte already has an hpte (case 2) */
++ if (unlikely(hugepte_val(old_pte) & _HUGEPAGE_HASHPTE)) {
++ /* There MIGHT be an HPTE for this pte */
++ unsigned long hash, slot;
++
++ hash = hpt_hash(vpn, 1);
++ if (hugepte_val(old_pte) & _HUGEPAGE_SECONDARY)
++ hash = ~hash;
++ slot = (hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP;
++ slot += (hugepte_val(old_pte) & _HUGEPAGE_GROUP_IX) >> 5;
++
++ if (ppc_md.hpte_updatepp(slot, hpteflags, va, 1, local) == -1)
++ hugepte_val(old_pte) &= ~_HUGEPAGE_HPTEFLAGS;
++ }
++
++ if (likely(!(hugepte_val(old_pte) & _HUGEPAGE_HASHPTE))) {
++ unsigned long hash = hpt_hash(vpn, 1);
++ unsigned long hpte_group;
++
++ prpn = hugepte_pfn(old_pte);
++
++repeat:
++ hpte_group = ((hash & htab_data.htab_hash_mask) *
++ HPTES_PER_GROUP) & ~0x7UL;
++
++ /* Update the linux pte with the HPTE slot */
++ hugepte_val(new_pte) &= ~_HUGEPAGE_HPTEFLAGS;
++ hugepte_val(new_pte) |= _HUGEPAGE_HASHPTE;
++
++ /* Add in WIMG bits */
++ /* XXX We should store these in the pte */
++ hpteflags |= _PAGE_COHERENT;
++
++ slot = ppc_md.hpte_insert(hpte_group, va, prpn, 0,
++ hpteflags, 0, 1);
++
++ /* Primary is full, try the secondary */
++ if (unlikely(slot == -1)) {
++ hugepte_val(new_pte) |= _HUGEPAGE_SECONDARY;
++ hpte_group = ((~hash & htab_data.htab_hash_mask) *
++ HPTES_PER_GROUP) & ~0x7UL;
++ slot = ppc_md.hpte_insert(hpte_group, va, prpn,
++ 1, hpteflags, 0, 1);
++ if (slot == -1) {
++ if (mftb() & 0x1)
++ hpte_group = ((hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL;
++
++ ppc_md.hpte_remove(hpte_group);
++ goto repeat;
++ }
++ }
++
++ if (unlikely(slot == -2))
++ panic("hash_huge_page: pte_insert failed\n");
++
++ hugepte_val(new_pte) |= (slot<<5) & _HUGEPAGE_GROUP_IX;
++
++ /*
++ * No need to use ldarx/stdcx here because all who
++ * might be updating the pte will hold the
++ * page_table_lock or the hash_table_lock
++ * (we hold both)
++ */
++ *ptep = new_pte;
++ }
++
++ return 0;
++}
++
++static void flush_hash_hugepage(mm_context_t context, unsigned long ea,
++ hugepte_t pte, int local)
++{
++ unsigned long vsid, vpn, va, hash, secondary, slot;
++
++ BUG_ON(hugepte_bad(pte));
++ BUG_ON(!in_hugepage_area(context, ea));
++
++ vsid = get_vsid(context, ea);
++
++ va = (vsid << 28) | (ea & 0x0fffffff);
++ vpn = va >> LARGE_PAGE_SHIFT;
++ hash = hpt_hash(vpn, 1);
++ secondary = !!(hugepte_val(pte) & _HUGEPAGE_SECONDARY);
++ if (secondary)
++ hash = ~hash;
++ slot = (hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP;
++ slot += (hugepte_val(pte) & _HUGEPAGE_GROUP_IX) >> 5;
++
++ ppc_md.hpte_invalidate(slot, va, 1, local);
++}
++
++static void split_and_free_hugepage(struct page *page)
++{
++ int j;
++ struct page *map;
++
++ map = page;
++ htlbpage_total--;
++ for (j = 0; j < (HPAGE_SIZE / PAGE_SIZE); j++) {
++ map->flags &= ~(1 << PG_locked | 1 << PG_error | 1 << PG_referenced |
++ 1 << PG_dirty | 1 << PG_active | 1 << PG_reserved |
++ 1 << PG_private | 1<< PG_writeback);
++ set_page_count(map, 0);
++ map++;
++ }
++ set_page_count(page, 1);
++ __free_pages(page, HUGETLB_PAGE_ORDER);
++}
++
++int set_hugetlb_mem_size(int count)
++{
++ int lcount;
++ struct page *page;
++
++ if (!(cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE))
++ return 0;
++
++ if (count < 0)
++ lcount = count;
++ else
++ lcount = count - htlbpage_total;
++
++ if (lcount == 0)
++ return htlbpage_total;
++ if (lcount > 0) { /* Increase the mem size. */
++ while (lcount--) {
++ page = alloc_fresh_huge_page();
++ if (page == NULL)
++ break;
++ spin_lock(&htlbpage_lock);
++ enqueue_huge_page(page);
++ htlbpage_free++;
++ htlbpage_total++;
++ spin_unlock(&htlbpage_lock);
++ }
++ return htlbpage_total;
++ }
++ /* Shrink the memory size. */
++ while (lcount++) {
++ page = alloc_hugetlb_page();
++ if (page == NULL)
++ break;
++ spin_lock(&htlbpage_lock);
++ split_and_free_hugepage(page);
++ spin_unlock(&htlbpage_lock);
++ }
++ return htlbpage_total;
++}
++
++int hugetlb_sysctl_handler(ctl_table *table, int write,
++ struct file *file, void *buffer, size_t *length)
++{
++ proc_dointvec(table, write, file, buffer, length);
++ htlbpage_max = set_hugetlb_mem_size(htlbpage_max);
++ return 0;
++}
++
++static int __init hugetlb_setup(char *s)
++{
++ if (sscanf(s, "%d", &htlbpage_max) <= 0)
++ htlbpage_max = 0;
++ return 1;
++}
++__setup("hugepages=", hugetlb_setup);
++
++static int __init hugetlb_init(void)
++{
++ int i;
++ struct page *page;
++
++ if (cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE) {
++ for (i = 0; i < MAX_NUMNODES; ++i)
++ INIT_LIST_HEAD(&hugepage_freelists[i]);
++
++ for (i = 0; i < htlbpage_max; ++i) {
++ page = alloc_fresh_huge_page();
++ if (!page)
++ break;
++ spin_lock(&htlbpage_lock);
++ enqueue_huge_page(page);
++ spin_unlock(&htlbpage_lock);
++ }
++ htlbpage_max = htlbpage_free = htlbpage_total = i;
++ printk("Total HugeTLB memory allocated, %d\n", htlbpage_free);
++ } else {
++ htlbpage_max = 0;
++ printk("CPU does not support HugeTLB\n");
++ }
++
++ return 0;
++}
++module_init(hugetlb_init);
++
++int hugetlb_report_meminfo(char *buf)
++{
++ return sprintf(buf,
++ "HugePages_Total: %5d\n"
++ "HugePages_Free: %5d\n"
++ "Hugepagesize: %5lu kB\n",
++ htlbpage_total,
++ htlbpage_free,
++ HPAGE_SIZE/1024);
++}
++
++/* This is advisory only, so we can get away with accesing
++ * htlbpage_free without taking the lock. */
++int is_hugepage_mem_enough(size_t size)
++{
++ return (size + ~HPAGE_MASK)/HPAGE_SIZE <= htlbpage_free;
++}
++
++/*
++ * We cannot handle pagefaults against hugetlb pages at all. They cause
++ * handle_mm_fault() to try to instantiate regular-sized pages in the
++ * hugegpage VMA. do_page_fault() is supposed to trap this, so BUG is we get
++ * this far.
++ */
++static struct page *hugetlb_nopage(struct vm_area_struct *vma,
++ unsigned long address, int unused)
++{
++ BUG();
++ return NULL;
++}
++
++struct vm_operations_struct hugetlb_vm_ops = {
++ .nopage = hugetlb_nopage,
++};
+Index: linux-2.6.0-test5/arch/ppc64/mm/init.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/mm/init.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/mm/init.c 2003-09-27 11:38:19.894503960 +0800
+@@ -290,7 +290,7 @@
+
+ if (!pgd_none(*pgd)) {
+ pmd = pmd_offset(pgd, vmaddr);
+- if (!pmd_none(*pmd)) {
++ if (pmd_present(*pmd)) {
+ ptep = pte_offset_kernel(pmd, vmaddr);
+ /* Check if HPTE might exist and flush it if so */
+ pte = __pte(pte_update(ptep, _PAGE_HPTEFLAGS, 0));
+@@ -298,6 +298,7 @@
+ flush_hash_page(context, vmaddr, pte, local);
+ }
+ }
++ WARN_ON(pmd_hugepage(*pmd));
+ }
+ }
+
+@@ -348,7 +349,7 @@
+ pmd_end = (start + PMD_SIZE) & PMD_MASK;
+ if (pmd_end > end)
+ pmd_end = end;
+- if (!pmd_none(*pmd)) {
++ if (pmd_present(*pmd)) {
+ ptep = pte_offset_kernel(pmd, start);
+ do {
+ if (pte_val(*ptep) & _PAGE_HASHPTE) {
+@@ -367,6 +368,7 @@
+ ++ptep;
+ } while (start < pmd_end);
+ } else {
++ WARN_ON(pmd_hugepage(*pmd));
+ start = pmd_end;
+ }
+ ++pmd;
+@@ -540,8 +542,6 @@
+ }
+ module_init(setup_kcore);
+
+-void initialize_paca_hardware_interrupt_stack(void);
+-
+ void __init mem_init(void)
+ {
+ #ifndef CONFIG_DISCONTIGMEM
+@@ -608,9 +608,6 @@
+ #endif
+ mem_init_done = 1;
+
+- /* set the last page of each hardware interrupt stack to be protected */
+- initialize_paca_hardware_interrupt_stack();
+-
+ #ifdef CONFIG_PPC_ISERIES
+ create_virtual_bus_tce_table();
+ #endif
+Index: linux-2.6.0-test5/arch/ppc64/mm/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/mm/Makefile 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/mm/Makefile 2003-09-27 11:38:19.896503656 +0800
+@@ -6,3 +6,4 @@
+
+ obj-y := fault.o init.o extable.o imalloc.o
+ obj-$(CONFIG_DISCONTIGMEM) += numa.o
++obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
+Index: linux-2.6.0-test5/arch/ppc64/mm/numa.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/mm/numa.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/mm/numa.c 2003-09-27 11:38:19.898503352 +0800
+@@ -24,18 +24,21 @@
+ int numa_cpu_lookup_table[NR_CPUS] = { [ 0 ... (NR_CPUS - 1)] = -1};
+ int numa_memory_lookup_table[MAX_MEMORY >> MEMORY_INCREMENT_SHIFT] =
+ { [ 0 ... ((MAX_MEMORY >> MEMORY_INCREMENT_SHIFT) - 1)] = -1};
+-unsigned long numa_cpumask_lookup_table[MAX_NUMNODES];
++cpumask_t numa_cpumask_lookup_table[MAX_NUMNODES];
+ int nr_cpus_in_node[MAX_NUMNODES] = { [0 ... (MAX_NUMNODES -1)] = 0};
+
+ struct pglist_data node_data[MAX_NUMNODES];
+ bootmem_data_t plat_node_bdata[MAX_NUMNODES];
+
++EXPORT_SYMBOL(node_data);
++EXPORT_SYMBOL(numa_memory_lookup_table);
++
+ static inline void map_cpu_to_node(int cpu, int node)
+ {
+ dbg("cpu %d maps to domain %d\n", cpu, node);
+ numa_cpu_lookup_table[cpu] = node;
+- if (!(numa_cpumask_lookup_table[node] & 1UL << cpu)) {
+- numa_cpumask_lookup_table[node] |= 1UL << cpu;
++ if (!(cpu_isset(cpu, numa_cpumask_lookup_table[node]))) {
++ cpu_set(cpu, numa_cpumask_lookup_table[node]);
+ nr_cpus_in_node[node]++;
+ }
+ }
+Index: linux-2.6.0-test5/arch/ppc64/xmon/xmon.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/xmon/xmon.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/xmon/xmon.c 2003-09-27 11:38:19.922499704 +0800
+@@ -15,6 +15,8 @@
+ #include <linux/mm.h>
+ #include <linux/reboot.h>
+ #include <linux/delay.h>
++#include <linux/kallsyms.h>
++
+ #include <asm/ptrace.h>
+ #include <asm/string.h>
+ #include <asm/prom.h>
+@@ -27,6 +29,7 @@
+ #include <asm/paca.h>
+ #include <asm/ppcdebug.h>
+ #include <asm/cputable.h>
++
+ #include "nonstdio.h"
+ #include "privinst.h"
+
+@@ -59,7 +62,6 @@
+ unsigned instr;
+ unsigned long count;
+ unsigned char enabled;
+- char funcname[64]; /* function name for humans */
+ };
+
+ #define NBPTS 16
+@@ -79,14 +81,9 @@
+ static int bsesc(void);
+ static void dump(void);
+ static void prdump(unsigned long, long);
+-#ifdef __MWERKS__
+-static void prndump(unsigned, int);
+-static int nvreadb(unsigned);
+-#endif
+ static int ppc_inst_dump(unsigned long, long);
+ void print_address(unsigned long);
+ static int getsp(void);
+-static void dump_hash_table(void);
+ static void backtrace(struct pt_regs *);
+ static void excprint(struct pt_regs *);
+ static void prregs(struct pt_regs *);
+@@ -106,7 +103,6 @@
+ static unsigned long read_spr(int);
+ static void write_spr(int, unsigned long);
+ static void super_regs(void);
+-static void print_sysmap(void);
+ static void remove_bpts(void);
+ static void insert_bpts(void);
+ static struct bpt *at_breakpoint(unsigned long pc);
+@@ -158,7 +154,6 @@
+ dd dump double values\n\
+ e print exception information\n\
+ f flush cache\n\
+- h dump hash table\n\
+ m examine/change memory\n\
+ mm move a block of memory\n\
+ ms set a block of memory\n\
+@@ -183,6 +178,13 @@
+
+ static struct pt_regs *xmon_regs[NR_CPUS];
+
++void __xmon_print_symbol(const char *fmt, unsigned long address);
++#define xmon_print_symbol(fmt, addr) \
++do { \
++ __check_printsym_format(fmt, ""); \
++ __xmon_print_symbol(fmt, addr); \
++} while(0)
++
+ /*
+ * Stuff for reading and writing memory safely
+ */
+@@ -211,42 +213,6 @@
+ no functions have been called from the current function.
+ */
+
+-/*
+- A traceback table typically follows each function.
+- The find_tb_table() func will fill in this struct. Note that the struct
+- is not an exact match with the encoded table defined by the ABI. It is
+- defined here more for programming convenience.
+- */
+-struct tbtable {
+- unsigned long flags; /* flags: */
+-#define TBTAB_FLAGSGLOBALLINK (1L<<47)
+-#define TBTAB_FLAGSISEPROL (1L<<46)
+-#define TBTAB_FLAGSHASTBOFF (1L<<45)
+-#define TBTAB_FLAGSINTPROC (1L<<44)
+-#define TBTAB_FLAGSHASCTL (1L<<43)
+-#define TBTAB_FLAGSTOCLESS (1L<<42)
+-#define TBTAB_FLAGSFPPRESENT (1L<<41)
+-#define TBTAB_FLAGSNAMEPRESENT (1L<<38)
+-#define TBTAB_FLAGSUSESALLOCA (1L<<37)
+-#define TBTAB_FLAGSSAVESCR (1L<<33)
+-#define TBTAB_FLAGSSAVESLR (1L<<32)
+-#define TBTAB_FLAGSSTORESBC (1L<<31)
+-#define TBTAB_FLAGSFIXUP (1L<<30)
+-#define TBTAB_FLAGSPARMSONSTK (1L<<0)
+- unsigned char fp_saved; /* num fp regs saved f(32-n)..f31 */
+- unsigned char gpr_saved; /* num gpr's saved */
+- unsigned char fixedparms; /* num fixed point parms */
+- unsigned char floatparms; /* num float parms */
+- unsigned char parminfo[32]; /* types of args. null terminated */
+-#define TBTAB_PARMFIXED 1
+-#define TBTAB_PARMSFLOAT 2
+-#define TBTAB_PARMDFLOAT 3
+- unsigned int tb_offset; /* offset from start of func */
+- unsigned long funcstart; /* addr of start of function */
+- char name[64]; /* name of function (null terminated)*/
+-};
+-static int find_tb_table(unsigned long codeaddr, struct tbtable *tab);
+-
+ #define SURVEILLANCE_TOKEN 9000
+
+ static inline void disable_surveillance(void)
+@@ -304,8 +270,7 @@
+ std 29,232(%0)\n\
+ std 30,240(%0)\n\
+ std 31,248(%0)" : : "b" (®s));
+- /* Fetch the link reg for this stack frame.
+- NOTE: the prev printf fills in the lr. */
++
+ regs.nip = regs.link = ((unsigned long *)(regs.gpr[1]))[2];
+ regs.msr = get_msr();
+ regs.ctr = get_ctr();
+@@ -380,7 +345,9 @@
+ xmon_trace[smp_processor_id()] = BRSTEP;
+ regs->msr |= MSR_SE;
+ } else {
+- printf("Stopped at breakpoint %x (%lx %s)\n", (bp - bpts)+1, bp->address, bp->funcname);
++ printf("Stopped at breakpoint %x (%lx ", (bp - bpts) + 1,
++ bp->address);
++ xmon_print_symbol("%s)\n", bp->address);
+ xmon(regs);
+ }
+ return 1;
+@@ -578,9 +545,6 @@
+ else
+ excprint(excp);
+ break;
+- case 'M':
+- print_sysmap();
+- break;
+ case 'S':
+ super_regs();
+ break;
+@@ -590,9 +554,6 @@
+ case 'f':
+ cacheflush();
+ break;
+- case 'h':
+- dump_hash_table();
+- break;
+ case 's':
+ case 'x':
+ case EOF:
+@@ -773,7 +734,6 @@
+ unsigned long a;
+ int mode, i;
+ struct bpt *bp;
+- struct tbtable tab;
+
+ cmd = inchar();
+ switch (cmd) {
+@@ -829,7 +789,9 @@
+ if (bp == 0) {
+ printf("No breakpoint at %x\n", a);
+ } else {
+- printf("Cleared breakpoint %x (%lx %s)\n", (bp - bpts)+1, bp->address, bp->funcname);
++ printf("Cleared breakpoint %x (%lx ",
++ (bp - bpts) + 1, bp->address);
++ xmon_print_symbol("%s)\n", bp->address);
+ bp->enabled = 0;
+ }
+ }
+@@ -863,8 +825,11 @@
+ printf(" inst %.16lx %8x\n", iabr.address & ~3,
+ iabr.count);
+ for (bp = bpts, bpnum = 1; bp < &bpts[NBPTS]; ++bp, ++bpnum)
+- if (bp->enabled)
+- printf("%2x trap %.16lx %8x %s\n", bpnum, bp->address, bp->count, bp->funcname);
++ if (bp->enabled) {
++ printf("%2x trap %.16lx %8x ",
++ bpnum, bp->address, bp->count);
++ xmon_print_symbol("%s\n", bp->address);
++ }
+ break;
+ }
+ bp = at_breakpoint(a);
+@@ -881,14 +846,9 @@
+ bp->address = a;
+ bp->count = 0;
+ scanhex(&bp->count);
+- /* Find the function name just once. */
+- bp->funcname[0] = '\0';
+- if (find_tb_table(bp->address, &tab) && tab.name[0]) {
+- /* Got a nice name for it. */
+- int delta = bp->address - tab.funcstart;
+- sprintf(bp->funcname, "%s+0x%x", tab.name, delta);
+- }
+- printf("Set breakpoint %2x trap %.16lx %8x %s\n", (bp-bpts)+1, bp->address, bp->count, bp->funcname);
++ printf("Set breakpoint %2x trap %.16lx %8x ", (bp-bpts) + 1,
++ bp->address, bp->count);
++ xmon_print_symbol("%s\n", bp->address);
+ break;
+ }
+ }
+@@ -925,7 +885,6 @@
+ unsigned long lr;
+ unsigned long stack[3];
+ struct pt_regs regs;
+- struct tbtable tab;
+ int framecount;
+ char *funcname;
+ /* declare these as raw ptrs so we don't get func descriptors */
+@@ -971,17 +930,11 @@
+ break;
+ printf("exception: %lx %s regs %lx\n", regs.trap, getvecname(regs.trap), sp+112);
+ printf(" %.16lx", regs.nip);
+- if ((regs.nip & 0xffffffff00000000UL) &&
+- find_tb_table(regs.nip, &tab)) {
+- int delta = regs.nip-tab.funcstart;
+- if (delta < 0)
+- printf(" <unknown code>");
+- else
+- printf(" %s+0x%x", tab.name, delta);
+- }
++ if (regs.nip & 0xffffffff00000000UL)
++ xmon_print_symbol(" %s", regs.nip);
+ printf("\n");
+ if (regs.gpr[1] < sp) {
+- printf("<Stack drops into 32-bit userspace %.16lx>\n", regs.gpr[1]);
++ printf("<Stack drops into userspace %.16lx>\n", regs.gpr[1]);
+ break;
+ }
+
+@@ -989,13 +942,8 @@
+ if (mread(sp, stack, sizeof(stack)) != sizeof(stack))
+ break;
+ } else {
+- if (stack[2] && find_tb_table(stack[2], &tab)) {
+- int delta = stack[2]-tab.funcstart;
+- if (delta < 0)
+- printf(" <unknown code>");
+- else
+- printf(" %s+0x%x", tab.name, delta);
+- }
++ if (stack[2])
++ xmon_print_symbol(" %s", stack[2]);
+ printf("\n");
+ }
+ if (stack[0] && stack[0] <= sp) {
+@@ -1024,8 +972,6 @@
+ void
+ excprint(struct pt_regs *fp)
+ {
+- struct task_struct *c;
+- struct tbtable tab;
+ unsigned long flags;
+
+ spin_lock_irqsave(&exception_print_lock, flags);
+@@ -1034,21 +980,13 @@
+ printf("cpu %d: ", smp_processor_id());
+ #endif /* CONFIG_SMP */
+
+- printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(fp->trap), fp);
++ printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(fp->trap), fp);
+ printf(" pc: %lx", fp->nip);
+- if (find_tb_table(fp->nip, &tab) && tab.name[0]) {
+- /* Got a nice name for it */
+- int delta = fp->nip - tab.funcstart;
+- printf(" (%s+0x%x)", tab.name, delta);
+- }
+- printf("\n");
++ xmon_print_symbol(" (%s)\n", fp->nip);
++
+ printf(" lr: %lx", fp->link);
+- if (find_tb_table(fp->link, &tab) && tab.name[0]) {
+- /* Got a nice name for it */
+- int delta = fp->link - tab.funcstart;
+- printf(" (%s+0x%x)", tab.name, delta);
+- }
+- printf("\n");
++ xmon_print_symbol(" (%s)\n", fp->link);
++
+ printf(" sp: %lx\n", fp->gpr[1]);
+ printf(" msr: %lx\n", fp->msr);
+
+@@ -1057,13 +995,11 @@
+ printf(" dsisr: %lx\n", fp->dsisr);
+ }
+
+- /* XXX: need to copy current or we die. Why? */
+- c = current;
+- printf(" current = 0x%lx\n", c);
++ printf(" current = 0x%lx\n", current);
+ printf(" paca = 0x%lx\n", get_paca());
+- if (c) {
+- printf(" current = %lx, pid = %ld, comm = %s\n",
+- c, c->pid, c->comm);
++ if (current) {
++ printf(" pid = %ld, comm = %s\n",
++ current->pid, current->comm);
+ }
+
+ spin_unlock_irqrestore(&exception_print_lock, flags);
+@@ -1153,14 +1089,6 @@
+ extern char dec_exc;
+
+ void
+-print_sysmap(void)
+-{
+- extern char *sysmap;
+- if ( sysmap )
+- printf("System.map: \n%s", sysmap);
+-}
+-
+-void
+ super_regs()
+ {
+ int i, cmd;
+@@ -1228,152 +1156,6 @@
+ scannl();
+ }
+
+-#ifndef CONFIG_PPC64BRIDGE
+-static void
+-dump_hash_table_seg(unsigned seg, unsigned start, unsigned end)
+-{
+- extern void *Hash;
+- extern unsigned long Hash_size;
+- unsigned *htab = Hash;
+- unsigned hsize = Hash_size;
+- unsigned v, hmask, va, last_va;
+- int found, last_found, i;
+- unsigned *hg, w1, last_w2, last_va0;
+-
+- last_found = 0;
+- hmask = hsize / 64 - 1;
+- va = start;
+- start = (start >> 12) & 0xffff;
+- end = (end >> 12) & 0xffff;
+- for (v = start; v < end; ++v) {
+- found = 0;
+- hg = htab + (((v ^ seg) & hmask) * 16);
+- w1 = 0x80000000 | (seg << 7) | (v >> 10);
+- for (i = 0; i < 8; ++i, hg += 2) {
+- if (*hg == w1) {
+- found = 1;
+- break;
+- }
+- }
+- if (!found) {
+- w1 ^= 0x40;
+- hg = htab + ((~(v ^ seg) & hmask) * 16);
+- for (i = 0; i < 8; ++i, hg += 2) {
+- if (*hg == w1) {
+- found = 1;
+- break;
+- }
+- }
+- }
+- if (!(last_found && found && (hg[1] & ~0x180) == last_w2 + 4096)) {
+- if (last_found) {
+- if (last_va != last_va0)
+- printf(" ... %x", last_va);
+- printf("\n");
+- }
+- if (found) {
+- printf("%x to %x", va, hg[1]);
+- last_va0 = va;
+- }
+- last_found = found;
+- }
+- if (found) {
+- last_w2 = hg[1] & ~0x180;
+- last_va = va;
+- }
+- va += 4096;
+- }
+- if (last_found)
+- printf(" ... %x\n", last_va);
+-}
+-
+-#else /* CONFIG_PPC64BRIDGE */
+-static void
+-dump_hash_table_seg(unsigned seg, unsigned start, unsigned end)
+-{
+- extern void *Hash;
+- extern unsigned long Hash_size;
+- unsigned *htab = Hash;
+- unsigned hsize = Hash_size;
+- unsigned v, hmask, va, last_va;
+- int found, last_found, i;
+- unsigned *hg, w1, last_w2, last_va0;
+-
+- last_found = 0;
+- hmask = hsize / 128 - 1;
+- va = start;
+- start = (start >> 12) & 0xffff;
+- end = (end >> 12) & 0xffff;
+- for (v = start; v < end; ++v) {
+- found = 0;
+- hg = htab + (((v ^ seg) & hmask) * 32);
+- w1 = 1 | (seg << 12) | ((v & 0xf800) >> 4);
+- for (i = 0; i < 8; ++i, hg += 4) {
+- if (hg[1] == w1) {
+- found = 1;
+- break;
+- }
+- }
+- if (!found) {
+- w1 ^= 2;
+- hg = htab + ((~(v ^ seg) & hmask) * 32);
+- for (i = 0; i < 8; ++i, hg += 4) {
+- if (hg[1] == w1) {
+- found = 1;
+- break;
+- }
+- }
+- }
+- if (!(last_found && found && (hg[3] & ~0x180) == last_w2 + 4096)) {
+- if (last_found) {
+- if (last_va != last_va0)
+- printf(" ... %x", last_va);
+- printf("\n");
+- }
+- if (found) {
+- printf("%x to %x", va, hg[3]);
+- last_va0 = va;
+- }
+- last_found = found;
+- }
+- if (found) {
+- last_w2 = hg[3] & ~0x180;
+- last_va = va;
+- }
+- va += 4096;
+- }
+- if (last_found)
+- printf(" ... %x\n", last_va);
+-}
+-#endif /* CONFIG_PPC64BRIDGE */
+-
+-static unsigned long hash_ctx;
+-static unsigned long hash_start;
+-static unsigned long hash_end;
+-
+-static void
+-dump_hash_table()
+-{
+- int seg;
+- unsigned seg_start, seg_end;
+-
+- hash_ctx = 0;
+- hash_start = 0;
+- hash_end = 0xfffff000;
+- scanhex(&hash_ctx);
+- scanhex(&hash_start);
+- scanhex(&hash_end);
+- printf("Mappings for context %x\n", hash_ctx);
+- seg_start = hash_start;
+- for (seg = hash_start >> 28; seg <= hash_end >> 28; ++seg) {
+- seg_end = (seg << 28) | 0x0ffff000;
+- if (seg_end > hash_end)
+- seg_end = hash_end;
+- dump_hash_table_seg((hash_ctx << 4) + seg, seg_start, seg_end);
+- seg_start = seg_end + 0x1000;
+- }
+-}
+-
+ int
+ mread(unsigned long adrs, void *buf, int size)
+ {
+@@ -2073,111 +1855,52 @@
+ lineptr = str;
+ }
+
+-
+-/* Starting at codeaddr scan forward for a tbtable and fill in the
+- given table. Return non-zero if successful at doing something.
+- */
+-static int
+-find_tb_table(unsigned long codeaddr, struct tbtable *tab)
++/* xmon version of __print_symbol */
++void __xmon_print_symbol(const char *fmt, unsigned long address)
+ {
+- unsigned long codeaddr_max;
+- unsigned long tbtab_start;
+- int nr;
+- int instr;
+- int num_parms;
++ char *modname;
++ const char *name;
++ unsigned long offset, size;
++ char namebuf[128];
+
+- /* don't look for traceback table in userspace */
+- if (codeaddr < PAGE_OFFSET)
+- return 0;
++ if (setjmp(bus_error_jmp) == 0) {
++ debugger_fault_handler = handle_fault;
++ sync();
++ name = kallsyms_lookup(address, &size, &offset, &modname,
++ namebuf);
++ sync();
++ /* wait a little while to see if we get a machine check */
++ __delay(200);
++ } else {
++ name = "symbol lookup failed";
++ }
+
+- if (tab == NULL)
+- return 0;
+- memset(tab, 0, sizeof(tab));
++ debugger_fault_handler = 0;
+
+- /* Scan instructions starting at codeaddr for 128k max */
+- for (codeaddr_max = codeaddr + 128*1024*4;
+- codeaddr < codeaddr_max;
+- codeaddr += 4) {
+- nr = mread(codeaddr, &instr, 4);
+- if (nr != 4)
+- return 0; /* Bad read. Give up promptly. */
+- if (instr == 0) {
+- /* table should follow. */
+- int version;
+- unsigned long flags;
+- tbtab_start = codeaddr; /* save it to compute func start addr */
+- codeaddr += 4;
+- nr = mread(codeaddr, &flags, 8);
+- if (nr != 8)
+- return 0; /* Bad read or no tb table. */
+- tab->flags = flags;
+- version = (flags >> 56) & 0xff;
+- if (version != 0)
+- continue; /* No tb table here. */
+- /* Now, like the version, some of the flags are values
+- that are more conveniently extracted... */
+- tab->fp_saved = (flags >> 24) & 0x3f;
+- tab->gpr_saved = (flags >> 16) & 0x3f;
+- tab->fixedparms = (flags >> 8) & 0xff;
+- tab->floatparms = (flags >> 1) & 0x7f;
+- codeaddr += 8;
+- num_parms = tab->fixedparms + tab->floatparms;
+- if (num_parms) {
+- unsigned int parminfo;
+- int parm;
+- if (num_parms > 32)
+- return 1; /* incomplete */
+- nr = mread(codeaddr, &parminfo, 4);
+- if (nr != 4)
+- return 1; /* incomplete */
+- /* decode parminfo...32 bits.
+- A zero means fixed. A one means float and the
+- following bit determines single (0) or double (1).
+- */
+- for (parm = 0; parm < num_parms; parm++) {
+- if (parminfo & 0x80000000) {
+- parminfo <<= 1;
+- if (parminfo & 0x80000000)
+- tab->parminfo[parm] = TBTAB_PARMDFLOAT;
+- else
+- tab->parminfo[parm] = TBTAB_PARMSFLOAT;
+- } else {
+- tab->parminfo[parm] = TBTAB_PARMFIXED;
+- }
+- parminfo <<= 1;
+- }
+- codeaddr += 4;
+- }
+- if (flags & TBTAB_FLAGSHASTBOFF) {
+- nr = mread(codeaddr, &tab->tb_offset, 4);
+- if (nr != 4)
+- return 1; /* incomplete */
+- if (tab->tb_offset > 0) {
+- tab->funcstart = tbtab_start - tab->tb_offset;
+- }
+- codeaddr += 4;
+- }
+- /* hand_mask appears to be always be omitted. */
+- if (flags & TBTAB_FLAGSHASCTL) {
+- /* Assume this will never happen for C or asm */
+- return 1; /* incomplete */
+- }
+- if (flags & TBTAB_FLAGSNAMEPRESENT) {
+- short namlen;
+- nr = mread(codeaddr, &namlen, 2);
+- if (nr != 2)
+- return 1; /* incomplete */
+- if (namlen >= sizeof(tab->name))
+- namlen = sizeof(tab->name)-1;
+- codeaddr += 2;
+- nr = mread(codeaddr, tab->name, namlen);
+- tab->name[namlen] = '\0';
+- codeaddr += namlen;
+- }
+- return 1;
+- }
++ if (!name) {
++ char addrstr[sizeof("0x%lx") + (BITS_PER_LONG*3/10)];
++
++ sprintf(addrstr, "0x%lx", address);
++ printf(fmt, addrstr);
++ return;
++ }
++
++ if (modname) {
++ /* This is pretty small. */
++ char buffer[sizeof("%s+%#lx/%#lx [%s]")
++ + strlen(name) + 2*(BITS_PER_LONG*3/10)
++ + strlen(modname)];
++
++ sprintf(buffer, "%s+%#lx/%#lx [%s]",
++ name, offset, size, modname);
++ printf(fmt, buffer);
++ } else {
++ char buffer[sizeof("%s+%#lx/%#lx")
++ + strlen(name) + 2*(BITS_PER_LONG*3/10)];
++
++ sprintf(buffer, "%s+%#lx/%#lx", name, offset, size);
++ printf(fmt, buffer);
+ }
+- return 0; /* hit max...sorry. */
+ }
+
+ void
+Index: linux-2.6.0-test5/arch/ppc/boot/ld.script
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc/boot/ld.script 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc/boot/ld.script 2003-09-27 11:38:19.924499400 +0800
+@@ -82,6 +82,7 @@
+ *(__ksymtab)
+ *(__ksymtab_strings)
+ *(__bug_table)
++ *(__kcrctab)
+ }
+
+ }
+Index: linux-2.6.0-test5/arch/ppc/kernel/align.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc/kernel/align.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc/kernel/align.c 2003-09-27 11:38:19.927498944 +0800
+@@ -21,11 +21,11 @@
+ unsigned char flags;
+ };
+
+-#if defined(CONFIG_4xx)
++#if defined(CONFIG_4xx) || defined(CONFIG_POWER4)
+ #define OPCD(inst) (((inst) & 0xFC000000) >> 26)
+ #define RS(inst) (((inst) & 0x03E00000) >> 21)
+ #define RA(inst) (((inst) & 0x001F0000) >> 16)
+-#define IS_DFORM(code) ((code) >= 32 && (code) <= 55)
++#define IS_XFORM(code) ((code) == 31)
+ #endif
+
+ #define INVALID { 0, 0 }
+@@ -61,9 +61,9 @@
+ { 4, ST+F+S }, /* 00 0 1010: stfs */
+ { 8, ST+F }, /* 00 0 1011: stfd */
+ INVALID, /* 00 0 1100 */
+- INVALID, /* 00 0 1101 */
++ INVALID, /* 00 0 1101: ld/ldu/lwa */
+ INVALID, /* 00 0 1110 */
+- INVALID, /* 00 0 1111 */
++ INVALID, /* 00 0 1111: std/stdu */
+ { 4, LD+U }, /* 00 1 0000: lwzu */
+ INVALID, /* 00 1 0001 */
+ { 4, ST+U }, /* 00 1 0010: stwu */
+@@ -80,12 +80,12 @@
+ INVALID, /* 00 1 1101 */
+ INVALID, /* 00 1 1110 */
+ INVALID, /* 00 1 1111 */
+- INVALID, /* 01 0 0000 */
++ INVALID, /* 01 0 0000: ldx */
+ INVALID, /* 01 0 0001 */
+- INVALID, /* 01 0 0010 */
++ INVALID, /* 01 0 0010: stdx */
+ INVALID, /* 01 0 0011 */
+ INVALID, /* 01 0 0100 */
+- INVALID, /* 01 0 0101: lwax?? */
++ INVALID, /* 01 0 0101: lwax */
+ INVALID, /* 01 0 0110 */
+ INVALID, /* 01 0 0111 */
+ { 0, LD+HARD }, /* 01 0 1000: lswx */
+@@ -96,12 +96,12 @@
+ INVALID, /* 01 0 1101 */
+ INVALID, /* 01 0 1110 */
+ INVALID, /* 01 0 1111 */
+- INVALID, /* 01 1 0000 */
++ INVALID, /* 01 1 0000: ldux */
+ INVALID, /* 01 1 0001 */
+- INVALID, /* 01 1 0010 */
++ INVALID, /* 01 1 0010: stdux */
+ INVALID, /* 01 1 0011 */
+ INVALID, /* 01 1 0100 */
+- INVALID, /* 01 1 0101: lwaux?? */
++ INVALID, /* 01 1 0101: lwaux */
+ INVALID, /* 01 1 0110 */
+ INVALID, /* 01 1 0111 */
+ INVALID, /* 01 1 1000 */
+@@ -157,9 +157,9 @@
+ { 4, ST+F+S }, /* 11 0 1010: stfsx */
+ { 8, ST+F }, /* 11 0 1011: stfdx */
+ INVALID, /* 11 0 1100 */
+- INVALID, /* 11 0 1101 */
++ INVALID, /* 11 0 1101: lmd */
+ INVALID, /* 11 0 1110 */
+- INVALID, /* 11 0 1111 */
++ INVALID, /* 11 0 1111: stmd */
+ { 4, LD+U }, /* 11 1 0000: lwzux */
+ INVALID, /* 11 1 0001 */
+ { 4, ST+U }, /* 11 1 0010: stwux */
+@@ -184,7 +184,7 @@
+ fix_alignment(struct pt_regs *regs)
+ {
+ int instr, nb, flags;
+-#if defined(CONFIG_4xx)
++#if defined(CONFIG_4xx) || defined(CONFIG_POWER4)
+ int opcode, f1, f2, f3;
+ #endif
+ int i, t;
+@@ -199,9 +199,11 @@
+
+ CHECK_FULL_REGS(regs);
+
+-#if defined(CONFIG_4xx)
++#if defined(CONFIG_4xx) || defined(CONFIG_POWER4)
+ /* The 4xx-family processors have no DSISR register,
+ * so we emulate it.
++ * The POWER4 has a DSISR register but doesn't set it on
++ * an alignment fault. -- paulus
+ */
+
+ instr = *((unsigned int *)regs->nip);
+@@ -209,7 +211,7 @@
+ reg = RS(instr);
+ areg = RA(instr);
+
+- if (IS_DFORM(opcode)) {
++ if (!IS_XFORM(opcode)) {
+ f1 = 0;
+ f2 = (instr & 0x04000000) >> 26;
+ f3 = (instr & 0x78000000) >> 27;
+Index: linux-2.6.0-test5/arch/ppc/kernel/asm-offsets.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc/kernel/asm-offsets.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc/kernel/asm-offsets.c 2003-09-27 11:38:19.930498488 +0800
+@@ -52,6 +52,7 @@
+ DEFINE(THREAD_VR0, offsetof(struct thread_struct, vr[0]));
+ DEFINE(THREAD_VRSAVE, offsetof(struct thread_struct, vrsave));
+ DEFINE(THREAD_VSCR, offsetof(struct thread_struct, vscr));
++ DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr));
+ #endif /* CONFIG_ALTIVEC */
+ /* Interrupt register frame */
+ DEFINE(STACK_FRAME_OVERHEAD, STACK_FRAME_OVERHEAD);
+@@ -101,7 +102,7 @@
+ DEFINE(_XER, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, xer));
+ DEFINE(_DAR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dar));
+ DEFINE(_DSISR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dsisr));
+- /* The PowerPC 400-class processors have neither the DAR nor the DSISR
++ /* The PowerPC 400-class & Book-E processors have neither the DAR nor the DSISR
+ * SPRs. Hence, we overload them to hold the similar DEAR and ESR SPRs
+ * for such processors. For critical interrupts we use them to
+ * hold SRR0 and SRR1.
+Index: linux-2.6.0-test5/arch/ppc/kernel/head.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc/kernel/head.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc/kernel/head.S 2003-09-27 11:38:19.941496816 +0800
+@@ -915,7 +915,9 @@
+ /* enable use of AltiVec after return */
+ oris r9,r9,MSR_VEC@h
+ mfspr r5,SPRG3 /* current task's THREAD (phys) */
++ li r4,1
+ li r10,THREAD_VSCR
++ stw r4,THREAD_USED_VR(r5)
+ lvx vr0,r10,r5
+ mtvscr vr0
+ REST_32VR(0,r10,r5)
+Index: linux-2.6.0-test5/arch/ppc/kernel/misc.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc/kernel/misc.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc/kernel/misc.S 2003-09-27 11:38:19.948495752 +0800
+@@ -1379,7 +1379,7 @@
+ .long sys_clock_gettime
+ .long sys_clock_getres
+ .long sys_clock_nanosleep
+- .long sys_ni_syscall /* reserved for swapcontext */
++ .long sys_swapcontext
+ .long sys_tgkill /* 250 */
+ .long sys_utimes
+ .long sys_statfs64
+Index: linux-2.6.0-test5/arch/ppc/kernel/process.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc/kernel/process.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc/kernel/process.c 2003-09-27 11:38:19.953494992 +0800
+@@ -415,6 +415,7 @@
+ memset(current->thread.vr, 0, sizeof(current->thread.vr));
+ memset(¤t->thread.vscr, 0, sizeof(current->thread.vscr));
+ current->thread.vrsave = 0;
++ current->thread.used_vr = 0;
+ #endif /* CONFIG_ALTIVEC */
+ }
+
+Index: linux-2.6.0-test5/arch/ppc/kernel/signal.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc/kernel/signal.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc/kernel/signal.c 2003-09-27 11:38:19.959494080 +0800
+@@ -41,18 +41,6 @@
+
+ #define GP_REGS_SIZE min(sizeof(elf_gregset_t), sizeof(struct pt_regs))
+
+-/*
+- * These are the flags in the MSR that the user is allowed to change
+- * by modifying the saved value of the MSR on the stack. SE and BE
+- * should not be in this list since gdb may want to change these. I.e,
+- * you should be able to step out of a signal handler to see what
+- * instruction executes next after the signal handler completes.
+- * Alternately, if you stepped into a signal handler, you should be
+- * able to continue 'til the next breakpoint from within the signal
+- * handler, even if the handler returns.
+- */
+-#define MSR_USERCHANGE (MSR_FE0 | MSR_FE1)
+-
+ int do_signal(sigset_t *oldset, struct pt_regs *regs);
+
+ /*
+@@ -72,8 +60,8 @@
+ spin_unlock_irq(¤t->sighand->siglock);
+
+ regs->result = -EINTR;
+- regs->ccr |= 0x10000000;
+ regs->gpr[3] = EINTR;
++ regs->ccr |= 0x10000000;
+ while (1) {
+ current->state = TASK_INTERRUPTIBLE;
+ schedule();
+@@ -103,8 +91,8 @@
+ spin_unlock_irq(¤t->sighand->siglock);
+
+ regs->result = -EINTR;
+- regs->ccr |= 0x10000000;
+ regs->gpr[3] = EINTR;
++ regs->ccr |= 0x10000000;
+ while (1) {
+ current->state = TASK_INTERRUPTIBLE;
+ schedule();
+@@ -164,305 +152,389 @@
+ *
+ */
+ struct sigregs {
+- elf_gregset_t gp_regs;
+- double fp_regs[ELF_NFPREG];
+- unsigned long tramp[2];
++ struct mcontext mctx; /* all the register values */
+ /* Programs using the rs6000/xcoff abi can save up to 19 gp regs
+ and 18 fp regs below sp before decrementing it. */
+ int abigap[56];
+ };
+
+-struct rt_sigframe
+-{
+- unsigned long _unused[2];
+- struct siginfo *pinfo;
+- void *puc;
+- struct siginfo info;
+- struct ucontext uc;
+-};
+-
++/* We use the mc_pad field for the signal return trampoline. */
++#define tramp mc_pad
+
+ /*
+ * When we have rt signals to deliver, we set up on the
+ * user stack, going down from the original stack pointer:
+- * a sigregs struct
+- * one rt_sigframe struct (siginfo + ucontext)
+- * a gap of __SIGNAL_FRAMESIZE bytes
++ * one rt_sigframe struct (siginfo + ucontext + ABI gap)
++ * a gap of __SIGNAL_FRAMESIZE+16 bytes
++ * (the +16 is to get the siginfo and ucontext in the same
++ * positions as in older kernels).
+ *
+ * Each of these things must be a multiple of 16 bytes in size.
+ *
+ */
+-int sys_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
+- struct pt_regs *regs)
++struct rt_sigframe
+ {
+- struct rt_sigframe __user *rt_sf;
+- struct sigcontext sigctx;
+- struct sigregs __user *sr;
+- elf_gregset_t saved_regs; /* an array of ELF_NGREG unsigned longs */
+- sigset_t set;
+- stack_t st;
++ struct siginfo info;
++ struct ucontext uc;
++ /* Programs using the rs6000/xcoff abi can save up to 19 gp regs
++ and 18 fp regs below sp before decrementing it. */
++ int abigap[56];
++};
+
+- rt_sf = (struct rt_sigframe __user *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
+- if (copy_from_user(&sigctx, &rt_sf->uc.uc_mcontext, sizeof(sigctx))
+- || copy_from_user(&set, &rt_sf->uc.uc_sigmask, sizeof(set))
+- || copy_from_user(&st, &rt_sf->uc.uc_stack, sizeof(st)))
+- goto badframe;
+- sigdelsetmask(&set, ~_BLOCKABLE);
+- spin_lock_irq(¤t->sighand->siglock);
+- current->blocked = set;
+- recalc_sigpending();
+- spin_unlock_irq(¤t->sighand->siglock);
++/*
++ * Save the current user registers on the user stack.
++ * We only save the altivec registers if the process has used
++ * altivec instructions at some point.
++ */
++static int
++save_user_regs(struct pt_regs *regs, struct mcontext *frame, int sigret)
++{
++ /* save general and floating-point registers */
++ CHECK_FULL_REGS(regs);
+ if (regs->msr & MSR_FP)
+ giveup_fpu(current);
++ if (__copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE)
++ || __copy_to_user(&frame->mc_fregs, current->thread.fpr,
++ ELF_NFPREG * sizeof(double)))
++ return 1;
+
+- /* restore registers -
+- * sigctx is initialized to point to the
+- * preamble frame (where registers are stored)
+- * see handle_signal()
++ current->thread.fpscr = 0; /* turn off all fp exceptions */
++
++#ifdef CONFIG_ALTIVEC
++ /* save altivec registers */
++ if (current->thread.used_vr) {
++ if (regs->msr & MSR_VEC)
++ giveup_altivec(current);
++ if (__copy_to_user(&frame->mc_vregs, current->thread.vr,
++ ELF_NVRREG * sizeof(vector128)))
++ return 1;
++ /* set MSR_VEC in the saved MSR value to indicate that
++ frame->mc_vregs contains valid data */
++ if (__put_user(regs->msr | MSR_VEC, &frame->mc_gregs[PT_MSR]))
++ return 1;
++ }
++ /* else assert((regs->msr & MSR_VEC) == 0) */
++
++ /* We always copy to/from vrsave, it's 0 if we don't have or don't
++ * use altivec. Since VSCR only contains 32 bits saved in the least
++ * significant bits of a vector, we "cheat" and stuff VRSAVE in the
++ * most significant bits of that same vector. --BenH
+ */
+- sr = (struct sigregs __user *) sigctx.regs;
+- if (copy_from_user(saved_regs, &sr->gp_regs, sizeof(sr->gp_regs)))
+- goto badframe;
+- saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE)
+- | (saved_regs[PT_MSR] & MSR_USERCHANGE);
+- memcpy(regs, saved_regs, GP_REGS_SIZE);
+- if (copy_from_user(current->thread.fpr, &sr->fp_regs,
+- sizeof(sr->fp_regs)))
+- goto badframe;
++ if (__put_user(current->thread.vrsave, (u32 *)&frame->mc_vregs[32]))
++ return 1;
++#endif /* CONFIG_ALTIVEC */
++
++ if (sigret) {
++ /* Set up the sigreturn trampoline: li r0,sigret; sc */
++ if (__put_user(0x38000000UL + sigret, &frame->tramp[0])
++ || __put_user(0x44000002UL, &frame->tramp[1]))
++ return 1;
++ flush_icache_range((unsigned long) &frame->tramp[0],
++ (unsigned long) &frame->tramp[2]);
++ }
+
+- sigreturn_exit(regs); /* doesn't return here */
+ return 0;
++}
+
+-badframe:
+- do_exit(SIGSEGV);
++/*
++ * Restore the current user register values from the user stack,
++ * (except for MSR).
++ */
++static int
++restore_user_regs(struct pt_regs *regs, struct mcontext __user *sr)
++{
++#ifdef CONFIG_ALTIVEC
++ unsigned long msr;
++#endif
++
++ /* copy up to but not including MSR */
++ if (__copy_from_user(regs, &sr->mc_gregs, PT_MSR * sizeof(elf_greg_t)))
++ return 1;
++ /* copy from orig_r3 (the word after the MSR) up to the end */
++ if (__copy_from_user(®s->orig_gpr3, &sr->mc_gregs[PT_ORIG_R3],
++ GP_REGS_SIZE - PT_ORIG_R3 * sizeof(elf_greg_t)))
++ return 1;
++
++ /* force the process to reload the FP registers from
++ current->thread when it next does FP instructions */
++ regs->msr &= ~MSR_FP;
++ if (__copy_from_user(current->thread.fpr, &sr->mc_fregs,
++ sizeof(sr->mc_fregs)))
++ return 1;
++
++#ifdef CONFIG_ALTIVEC
++ /* force the process to reload the altivec registers from
++ current->thread when it next does altivec instructions */
++ regs->msr &= ~MSR_VEC;
++ if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_VEC) != 0) {
++ /* restore altivec registers from the stack */
++ if (__copy_from_user(current->thread.vr, &sr->mc_vregs,
++ sizeof(sr->mc_vregs)))
++ return 1;
++ } else if (current->thread.used_vr)
++ memset(¤t->thread.vr, 0, sizeof(current->thread.vr));
++
++ /* Always get VRSAVE back */
++ if (__get_user(current->thread.vrsave, (u32 *)&sr->mc_vregs[32]))
++ return 1;
++#endif /* CONFIG_ALTIVEC */
++
++ return 0;
+ }
+
++/*
++ * Restore the user process's signal mask
++ */
+ static void
+-setup_rt_frame(struct pt_regs *regs, struct sigregs __user *frame,
+- signed long newsp)
++restore_sigmask(sigset_t *set)
+ {
+- struct rt_sigframe __user *rt_sf = (struct rt_sigframe __user *) newsp;
++ sigdelsetmask(set, ~_BLOCKABLE);
++ spin_lock_irq(¤t->sighand->siglock);
++ current->blocked = *set;
++ recalc_sigpending();
++ spin_unlock_irq(¤t->sighand->siglock);
++}
+
+- /* Set up preamble frame */
+- if (verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
++/*
++ * Set up a signal frame for a "real-time" signal handler
++ * (one which gets siginfo).
++ */
++static void
++handle_rt_signal(unsigned long sig, struct k_sigaction *ka,
++ siginfo_t *info, sigset_t *oldset, struct pt_regs * regs,
++ unsigned long newsp)
++{
++ struct rt_sigframe __user *rt_sf;
++ struct mcontext __user *frame;
++ unsigned long origsp = newsp;
++
++ /* Set up Signal Frame */
++ /* Put a Real Time Context onto stack */
++ newsp -= sizeof(*rt_sf);
++ rt_sf = (struct rt_sigframe __user *) newsp;
++
++ /* create a stack frame for the caller of the handler */
++ newsp -= __SIGNAL_FRAMESIZE + 16;
++
++ if (verify_area(VERIFY_WRITE, (void __user *) newsp, origsp - newsp))
+ goto badframe;
+- CHECK_FULL_REGS(regs);
+- if (regs->msr & MSR_FP)
+- giveup_fpu(current);
+- if (__copy_to_user(&frame->gp_regs, regs, GP_REGS_SIZE)
+- || __copy_to_user(&frame->fp_regs, current->thread.fpr,
+- ELF_NFPREG * sizeof(double))
+- /* Set up to return from user space.
+- It calls the sc exception at offset 0x9999
+- for sys_rt_sigreturn().
+- */
+- || __put_user(0x38000000UL + __NR_rt_sigreturn, &frame->tramp[0])
+- || __put_user(0x44000002UL, &frame->tramp[1])) /* sc */
++
++ /* Put the siginfo & fill in most of the ucontext */
++ if (copy_siginfo_to_user(&rt_sf->info, info)
++ || __put_user(0, &rt_sf->uc.uc_flags)
++ || __put_user(0, &rt_sf->uc.uc_link)
++ || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp)
++ || __put_user(sas_ss_flags(regs->gpr[1]),
++ &rt_sf->uc.uc_stack.ss_flags)
++ || __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size)
++ || __put_user(&rt_sf->uc.uc_mcontext, &rt_sf->uc.uc_regs)
++ || __copy_to_user(&rt_sf->uc.uc_oldsigmask, oldset, sizeof(*oldset))
++ || __copy_to_user(&rt_sf->uc.uc_sigmask, oldset, sizeof(*oldset)))
+ goto badframe;
+- flush_icache_range((unsigned long) &frame->tramp[0],
+- (unsigned long) &frame->tramp[2]);
+- current->thread.fpscr = 0; /* turn off all fp exceptions */
+
+- /* Retrieve rt_sigframe from stack and
+- set up registers for signal handler
+- */
+- newsp -= __SIGNAL_FRAMESIZE;
+- if (put_user(regs->gpr[1], (unsigned long __user *)newsp)
+- || get_user(regs->nip, &rt_sf->uc.uc_mcontext.handler)
+- || get_user(regs->gpr[3], &rt_sf->uc.uc_mcontext.signal)
+- || get_user(regs->gpr[4], (unsigned long __user *)&rt_sf->pinfo)
+- || get_user(regs->gpr[5], (unsigned long __user *)&rt_sf->puc))
++ /* Save user registers on the stack */
++ frame = &rt_sf->uc.uc_mcontext;
++ if (save_user_regs(regs, frame, __NR_rt_sigreturn))
+ goto badframe;
+
++ if (put_user(regs->gpr[1], (unsigned long __user *)newsp))
++ goto badframe;
+ regs->gpr[1] = newsp;
++ regs->gpr[3] = sig;
++ regs->gpr[4] = (unsigned long) &rt_sf->info;
++ regs->gpr[5] = (unsigned long) &rt_sf->uc;
+ regs->gpr[6] = (unsigned long) rt_sf;
++ regs->nip = (unsigned long) ka->sa.sa_handler;
+ regs->link = (unsigned long) frame->tramp;
++ regs->trap = 0;
+
+ return;
+
+ badframe:
+ #if DEBUG_SIG
+- printk("badframe in setup_rt_frame, regs=%p frame=%p newsp=%lx\n",
++ printk("badframe in handle_rt_signal, regs=%p frame=%p newsp=%lx\n",
+ regs, frame, newsp);
+ #endif
+- do_exit(SIGSEGV);
++ if (sig == SIGSEGV)
++ ka->sa.sa_handler = SIG_DFL;
++ force_sig(SIGSEGV, current);
+ }
+
+-/*
+- * Do a signal return; undo the signal stack.
+- */
+-int sys_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
+- struct pt_regs *regs)
++static int do_setcontext(struct ucontext __user *ucp, struct pt_regs *regs)
+ {
+- struct sigcontext __user *sc;
+- struct sigcontext sigctx;
+- struct sigregs __user *sr;
+- elf_gregset_t saved_regs; /* an array of ELF_NGREG unsigned longs */
+ sigset_t set;
+
+- sc = (struct sigcontext __user *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
+- if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
+- goto badframe;
++ if (__copy_from_user(&set, &ucp->uc_sigmask, sizeof(set)))
++ return -EFAULT;
++ restore_sigmask(&set);
+
+- set.sig[0] = sigctx.oldmask;
+-#if _NSIG_WORDS > 1
+- set.sig[1] = sigctx._unused[3];
+-#endif
+- sigdelsetmask(&set, ~_BLOCKABLE);
+- spin_lock_irq(¤t->sighand->siglock);
+- current->blocked = set;
+- recalc_sigpending();
+- spin_unlock_irq(¤t->sighand->siglock);
+- if (regs->msr & MSR_FP )
+- giveup_fpu(current);
++ if (restore_user_regs(regs, &ucp->uc_mcontext))
++ return -EFAULT;
+
+- /* restore registers */
+- sr = (struct sigregs __user *) sigctx.regs;
+- if (copy_from_user(saved_regs, &sr->gp_regs, sizeof(sr->gp_regs)))
+- goto badframe;
+- saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE)
+- | (saved_regs[PT_MSR] & MSR_USERCHANGE);
+- memcpy(regs, saved_regs, GP_REGS_SIZE);
++ return 0;
++}
+
+- if (copy_from_user(current->thread.fpr, &sr->fp_regs,
+- sizeof(sr->fp_regs)))
+- goto badframe;
++int sys_swapcontext(struct ucontext __user *old_ctx,
++ struct ucontext __user *new_ctx,
++ int r5, int r6, int r7, int r8, struct pt_regs *regs)
++{
++ unsigned char tmp;
++
++ if (old_ctx != NULL) {
++ if (verify_area(VERIFY_WRITE, old_ctx, sizeof(*old_ctx))
++ || save_user_regs(regs, &old_ctx->uc_mcontext, 0)
++ || __copy_to_user(&old_ctx->uc_sigmask,
++ ¤t->blocked, sizeof(sigset_t))
++ /* the next 2 things aren't strictly necessary */
++ || __copy_to_user(&old_ctx->uc_oldsigmask,
++ ¤t->blocked, sizeof(sigset_t))
++ || __put_user(&old_ctx->uc_mcontext, &old_ctx->uc_regs))
++ return -EFAULT;
++ }
++ if (new_ctx == NULL)
++ return 0;
++ if (verify_area(VERIFY_READ, new_ctx, sizeof(*new_ctx))
++ || __get_user(tmp, (u8 *) new_ctx)
++ || __get_user(tmp, (u8 *) (new_ctx + 1) - 1))
++ return -EFAULT;
++
++ /*
++ * If we get a fault copying the context into the kernel's
++ * image of the user's registers, we can't just return -EFAULT
++ * because the user's registers will be corrupted. For instance
++ * the NIP value may have been updated but not some of the
++ * other registers. Given that we have done the verify_area
++ * and successfully read the first and last bytes of the region
++ * above, this should only happen in an out-of-memory situation
++ * or if another thread unmaps the region containing the context.
++ * We kill the task with a SIGSEGV in this situation.
++ */
++ if (do_setcontext(new_ctx, regs))
++ do_exit(SIGSEGV);
++ sigreturn_exit(regs);
++ /* doesn't actually return back to here */
++ return 0;
++}
++
++int sys_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
++ struct pt_regs *regs)
++{
++ struct rt_sigframe __user *rt_sf;
++
++ rt_sf = (struct rt_sigframe __user *)
++ (regs->gpr[1] + __SIGNAL_FRAMESIZE + 16);
++ if (verify_area(VERIFY_READ, rt_sf, sizeof(struct rt_sigframe)))
++ goto bad;
++ if (do_setcontext(&rt_sf->uc, regs))
++ goto bad;
++
++ /*
++ * It's not clear whether or why it is desirable to save the
++ * sigaltstack setting on signal delivery and restore it on
++ * signal return. But other architectures do this and we have
++ * always done it up until now so it is probably better not to
++ * change it. -- paulus
++ */
++ do_sigaltstack(&rt_sf->uc.uc_stack, NULL, regs->gpr[1]);
+
+ sigreturn_exit(regs); /* doesn't return here */
+ return 0;
+
+-badframe:
+- do_exit(SIGSEGV);
+-}
++ bad:
++ force_sig(SIGSEGV, current);
++ return 0;
++}
+
+ /*
+- * Set up a signal frame.
++ * OK, we're invoking a handler
+ */
+ static void
+-setup_frame(struct pt_regs *regs, struct sigregs __user *frame,
+- unsigned long newsp)
++handle_signal(unsigned long sig, struct k_sigaction *ka,
++ siginfo_t *info, sigset_t *oldset, struct pt_regs * regs,
++ unsigned long newsp)
+ {
+- struct sigcontext __user *sc = (struct sigcontext __user *) newsp;
++ struct sigcontext __user *sc;
++ struct sigregs __user *frame;
++ unsigned long origsp = newsp;
+
+- if (verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
++ /* Set up Signal Frame */
++ newsp -= sizeof(struct sigregs);
++ frame = (struct sigregs __user *) newsp;
++
++ /* Put a sigcontext on the stack */
++ newsp -= sizeof(*sc);
++ sc = (struct sigcontext __user *) newsp;
++
++ /* create a stack frame for the caller of the handler */
++ newsp -= __SIGNAL_FRAMESIZE;
++
++ if (verify_area(VERIFY_WRITE, (void *) newsp, origsp - newsp))
+ goto badframe;
+- CHECK_FULL_REGS(regs);
+- if (regs->msr & MSR_FP)
+- giveup_fpu(current);
+- if (__copy_to_user(&frame->gp_regs, regs, GP_REGS_SIZE)
+- || __copy_to_user(&frame->fp_regs, current->thread.fpr,
+- ELF_NFPREG * sizeof(double))
+- || __put_user(0x38000000UL + __NR_sigreturn, &frame->tramp[0])
+- || __put_user(0x44000002UL, &frame->tramp[1])) /* sc */
++
++#if _NSIG != 64
++#error "Please adjust handle_signal()"
++#endif
++ if (__put_user((unsigned long) ka->sa.sa_handler, &sc->handler)
++ || __put_user(oldset->sig[0], &sc->oldmask)
++ || __put_user(oldset->sig[1], &sc->_unused[3])
++ || __put_user((struct pt_regs *)frame, &sc->regs)
++ || __put_user(sig, &sc->signal))
+ goto badframe;
+- flush_icache_range((unsigned long) &frame->tramp[0],
+- (unsigned long) &frame->tramp[2]);
+- current->thread.fpscr = 0; /* turn off all fp exceptions */
+
+- newsp -= __SIGNAL_FRAMESIZE;
+- if (put_user(regs->gpr[1], (unsigned long __user *)newsp)
+- || get_user(regs->nip, &sc->handler)
+- || get_user(regs->gpr[3], &sc->signal))
++ if (save_user_regs(regs, &frame->mctx, __NR_sigreturn))
++ goto badframe;
++
++ if (put_user(regs->gpr[1], (unsigned long *)newsp))
+ goto badframe;
+ regs->gpr[1] = newsp;
++ regs->gpr[3] = sig;
+ regs->gpr[4] = (unsigned long) sc;
+- regs->link = (unsigned long) frame->tramp;
++ regs->nip = (unsigned long) ka->sa.sa_handler;
++ regs->link = (unsigned long) frame->mctx.tramp;
++ regs->trap = 0;
+
+ return;
+
+ badframe:
+ #if DEBUG_SIG
+- printk("badframe in setup_frame, regs=%p frame=%p newsp=%lx\n",
+- regs, frame, newsp);
++ printk("badframe in handle_signal, regs=%p frame=%lx newsp=%lx\n",
++ regs, frame, *newspp);
+ #endif
+- do_exit(SIGSEGV);
++ if (sig == SIGSEGV)
++ ka->sa.sa_handler = SIG_DFL;
++ force_sig(SIGSEGV, current);
+ }
+
+ /*
+- * OK, we're invoking a handler
++ * Do a signal return; undo the signal stack.
+ */
+-static void
+-handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
+- struct pt_regs * regs, unsigned long *newspp, unsigned long frame)
++int sys_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
++ struct pt_regs *regs)
+ {
+ struct sigcontext __user *sc;
+- struct rt_sigframe __user *rt_sf;
+- struct k_sigaction *ka = ¤t->sighand->action[sig-1];
++ struct sigcontext sigctx;
++ struct mcontext __user *sr;
++ sigset_t set;
+
+- if (TRAP(regs) == 0x0C00 /* System Call! */
+- && ((int)regs->result == -ERESTARTNOHAND ||
+- (int)regs->result == -ERESTART_RESTARTBLOCK ||
+- ((int)regs->result == -ERESTARTSYS &&
+- !(ka->sa.sa_flags & SA_RESTART)))) {
+- if ((int)regs->result == -ERESTART_RESTARTBLOCK)
+- current_thread_info()->restart_block.fn
+- = do_no_restart_syscall;
+- regs->result = -EINTR;
+- regs->gpr[3] = EINTR;
+- regs->ccr |= 0x10000000;
+- }
++ sc = (struct sigcontext __user *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
++ if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
++ goto badframe;
+
+- /* Set up Signal Frame */
+- if (ka->sa.sa_flags & SA_SIGINFO) {
+- /* Put a Real Time Context onto stack */
+- *newspp -= sizeof(*rt_sf);
+- rt_sf = (struct rt_sigframe __user *) *newspp;
+- if (verify_area(VERIFY_WRITE, rt_sf, sizeof(*rt_sf)))
+- goto badframe;
+-
+- if (__put_user((unsigned long) ka->sa.sa_handler, &rt_sf->uc.uc_mcontext.handler)
+- || __put_user(&rt_sf->info, &rt_sf->pinfo)
+- || __put_user(&rt_sf->uc, &rt_sf->puc)
+- /* Put the siginfo */
+- || copy_siginfo_to_user(&rt_sf->info, info)
+- /* Create the ucontext */
+- || __put_user(0, &rt_sf->uc.uc_flags)
+- || __put_user(0, &rt_sf->uc.uc_link)
+- || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp)
+- || __put_user(sas_ss_flags(regs->gpr[1]),
+- &rt_sf->uc.uc_stack.ss_flags)
+- || __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size)
+- || __copy_to_user(&rt_sf->uc.uc_sigmask, oldset, sizeof(*oldset))
+- /* mcontext.regs points to preamble register frame */
+- || __put_user((struct pt_regs *)frame, &rt_sf->uc.uc_mcontext.regs)
+- || __put_user(sig, &rt_sf->uc.uc_mcontext.signal))
+- goto badframe;
+- } else {
+- /* Put a sigcontext on the stack */
+- *newspp -= sizeof(*sc);
+- sc = (struct sigcontext __user *) *newspp;
+- if (verify_area(VERIFY_WRITE, sc, sizeof(*sc)))
+- goto badframe;
+-
+- if (__put_user((unsigned long) ka->sa.sa_handler, &sc->handler)
+- || __put_user(oldset->sig[0], &sc->oldmask)
+-#if _NSIG_WORDS > 1
+- || __put_user(oldset->sig[1], &sc->_unused[3])
+-#endif
+- || __put_user((struct pt_regs *)frame, &sc->regs)
+- || __put_user(sig, &sc->signal))
+- goto badframe;
+- }
++ set.sig[0] = sigctx.oldmask;
++ set.sig[1] = sigctx._unused[3];
++ restore_sigmask(&set);
+
+- if (ka->sa.sa_flags & SA_ONESHOT)
+- ka->sa.sa_handler = SIG_DFL;
++ sr = (struct mcontext *) sigctx.regs;
++ if (verify_area(VERIFY_READ, sr, sizeof(*sr))
++ || restore_user_regs(regs, sr))
++ goto badframe;
+
+- if (!(ka->sa.sa_flags & SA_NODEFER)) {
+- spin_lock_irq(¤t->sighand->siglock);
+- sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask);
+- sigaddset(¤t->blocked,sig);
+- recalc_sigpending();
+- spin_unlock_irq(¤t->sighand->siglock);
+- }
+- return;
++ sigreturn_exit(regs); /* doesn't return */
++ return 0;
+
+ badframe:
+-#if DEBUG_SIG
+- printk("badframe in handle_signal, regs=%p frame=%lx newsp=%lx\n",
+- regs, frame, *newspp);
+- printk("sc=%p sig=%d ka=%p info=%p oldset=%p\n", sc, sig, ka, info, oldset);
+-#endif
+- do_exit(SIGSEGV);
++ force_sig(SIGSEGV, current);
++ return 0;
+ }
+
+ /*
+@@ -475,7 +547,7 @@
+ siginfo_t info;
+ struct k_sigaction *ka;
+ unsigned long frame, newsp;
+- int signr;
++ int signr, ret;
+
+ if (!oldset)
+ oldset = ¤t->blocked;
+@@ -483,40 +555,65 @@
+ newsp = frame = 0;
+
+ signr = get_signal_to_deliver(&info, regs, NULL);
+- if (signr > 0) {
+- ka = ¤t->sighand->action[signr-1];
+- if ( (ka->sa.sa_flags & SA_ONSTACK)
+- && (! on_sig_stack(regs->gpr[1])))
+- newsp = (current->sas_ss_sp + current->sas_ss_size);
+- else
+- newsp = regs->gpr[1];
+- newsp = frame = newsp - sizeof(struct sigregs);
+
+- /* Whee! Actually deliver the signal. */
+- handle_signal(signr, &info, oldset, regs, &newsp, frame);
+- }
++ ka = (signr == 0)? NULL: ¤t->sighand->action[signr-1];
+
+- if (TRAP(regs) == 0x0C00) { /* System Call! */
+- if ((int)regs->result == -ERESTARTNOHAND ||
+- (int)regs->result == -ERESTARTSYS ||
+- (int)regs->result == -ERESTARTNOINTR) {
+- regs->gpr[3] = regs->orig_gpr3;
++ if (TRAP(regs) == 0x0C00 /* System Call! */
++ && regs->ccr & 0x10000000 /* error signalled */
++ && ((ret = regs->gpr[3]) == ERESTARTSYS
++ || ret == ERESTARTNOHAND || ret == ERESTARTNOINTR
++ || ret == ERESTART_RESTARTBLOCK)) {
++
++ if (signr > 0
++ && (ret == ERESTARTNOHAND || ret == ERESTART_RESTARTBLOCK
++ || (ret == ERESTARTSYS
++ && !(ka->sa.sa_flags & SA_RESTART)))) {
++ /* make the system call return an EINTR error */
++ regs->result = -EINTR;
++ regs->gpr[3] = EINTR;
++ /* note that the cr0.SO bit is already set */
++ /* clear any restart function that was set */
++ if (ret == ERESTART_RESTARTBLOCK)
++ current_thread_info()->restart_block.fn
++ = do_no_restart_syscall;
++ } else {
+ regs->nip -= 4; /* Back up & retry system call */
+ regs->result = 0;
+- } else if ((int)regs->result == -ERESTART_RESTARTBLOCK) {
+- regs->gpr[0] = __NR_restart_syscall;
+- regs->nip -= 4;
+- regs->result = 0;
++ regs->trap = 0;
++ if (ret == ERESTART_RESTARTBLOCK)
++ regs->gpr[0] = __NR_restart_syscall;
++ else
++ regs->gpr[3] = regs->orig_gpr3;
+ }
+ }
+
+- if (newsp == frame)
++ if (signr == 0)
+ return 0; /* no signals delivered */
+
++ if ((ka->sa.sa_flags & SA_ONSTACK) && current->sas_ss_size
++ && !on_sig_stack(regs->gpr[1]))
++ newsp = current->sas_ss_sp + current->sas_ss_size;
++ else
++ newsp = regs->gpr[1];
++ newsp &= ~0xfUL;
++
++ /* Whee! Actually deliver the signal. */
+ if (ka->sa.sa_flags & SA_SIGINFO)
+- setup_rt_frame(regs, (struct sigregs __user *) frame, newsp);
++ handle_rt_signal(signr, ka, &info, oldset, regs, newsp);
+ else
+- setup_frame(regs, (struct sigregs __user *) frame, newsp);
++ handle_signal(signr, ka, &info, oldset, regs, newsp);
++
++ if (ka->sa.sa_flags & SA_ONESHOT)
++ ka->sa.sa_handler = SIG_DFL;
++
++ if (!(ka->sa.sa_flags & SA_NODEFER)) {
++ spin_lock_irq(¤t->sighand->siglock);
++ sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask);
++ sigaddset(¤t->blocked, signr);
++ recalc_sigpending();
++ spin_unlock_irq(¤t->sighand->siglock);
++ }
++
+ return 1;
+ }
+
+Index: linux-2.6.0-test5/arch/ppc/kernel/time.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc/kernel/time.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc/kernel/time.c 2003-09-27 11:38:19.964493320 +0800
+@@ -83,6 +83,7 @@
+ unsigned tb_ticks_per_jiffy;
+ unsigned tb_to_us;
+ unsigned tb_last_stamp;
++unsigned long tb_to_ns_scale;
+
+ extern unsigned long wall_jiffies;
+
+@@ -309,6 +310,7 @@
+ tb_to_us = 0x418937;
+ } else {
+ ppc_md.calibrate_decr();
++ tb_to_ns_scale = mulhwu(tb_to_us, 1000 << 10);
+ }
+
+ /* Now that the decrementer is calibrated, it can be used in case the
+@@ -432,3 +434,26 @@
+ return mlt;
+ }
+
++unsigned long long sched_clock(void)
++{
++ unsigned long lo, hi, hi2;
++ unsigned long long tb;
++
++ if (!__USE_RTC()) {
++ do {
++ hi = get_tbu();
++ lo = get_tbl();
++ hi2 = get_tbu();
++ } while (hi2 != hi);
++ tb = ((unsigned long long) hi << 32) | lo;
++ tb = (tb * tb_to_ns_scale) >> 10;
++ } else {
++ do {
++ hi = get_rtcu();
++ lo = get_rtcl();
++ hi2 = get_rtcu();
++ } while (hi2 != hi);
++ tb = ((unsigned long long) hi) * 1000000000 + lo;
++ }
++ return tb;
++}
+Index: linux-2.6.0-test5/arch/ppc/kernel/traps.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc/kernel/traps.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc/kernel/traps.c 2003-09-27 11:38:19.968492712 +0800
+@@ -95,14 +95,19 @@
+ }
+
+ void
+-_exception(int signr, struct pt_regs *regs)
++_exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
+ {
+- if (!user_mode(regs))
+- {
++ siginfo_t info;
++
++ if (!user_mode(regs)) {
+ debugger(regs);
+ die("Exception in kernel mode", regs, signr);
+ }
+- force_sig(signr, current);
++ info.si_signo = signr;
++ info.si_errno = 0;
++ info.si_code = code;
++ info.si_addr = (void *) addr;
++ force_sig_info(signr, &info, current);
+ }
+
+ /*
+@@ -154,12 +159,40 @@
+ return 0;
+ }
+
++#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
++/* On 4xx, the reason for the machine check or program exception
++ is in the ESR. */
++#define get_reason(regs) ((regs)->dsisr)
++#define REASON_FP 0
++#define REASON_ILLEGAL ESR_PIL
++#define REASON_PRIVILEGED ESR_PPR
++#define REASON_TRAP ESR_PTR
++
++/* single-step stuff */
++#define single_stepping(regs) (current->thread.dbcr0 & DBCR0_IC)
++#define clear_single_step(regs) (current->thread.dbcr0 &= ~DBCR0_IC)
++
++#else
++/* On non-4xx, the reason for the machine check or program
++ exception is in the MSR. */
++#define get_reason(regs) ((regs)->msr)
++#define REASON_FP 0x100000
++#define REASON_ILLEGAL 0x80000
++#define REASON_PRIVILEGED 0x40000
++#define REASON_TRAP 0x20000
++
++#define single_stepping(regs) ((regs)->msr & MSR_SE)
++#define clear_single_step(regs) ((regs)->msr &= ~MSR_SE)
++#endif
++
+ void
+ MachineCheckException(struct pt_regs *regs)
+ {
++ unsigned long reason = get_reason(regs);
++
+ if (user_mode(regs)) {
+ regs->msr |= MSR_RI;
+- _exception(SIGSEGV, regs);
++ _exception(SIGBUS, regs, BUS_ADRERR, regs->nip);
+ return;
+ }
+
+@@ -178,10 +211,18 @@
+ if (check_io_access(regs))
+ return;
+
+-#ifndef CONFIG_4xx
+- printk(KERN_CRIT "Machine check in kernel mode.\n");
+- printk(KERN_CRIT "Caused by (from SRR1=%lx): ", regs->msr);
+- switch (regs->msr & 0x601F0000) {
++#ifdef CONFIG_4xx
++ if (reason & ESR_IMCP) {
++ printk("Instruction");
++ mtspr(SPRN_ESR, reason & ~ESR_IMCP);
++ } else
++ printk("Data");
++ printk(" machine check in kernel mode.\n");
++
++#else /* !CONFIG_4xx */
++ printk("Machine check in kernel mode.\n");
++ printk("Caused by (from SRR1=%lx): ", reason);
++ switch (reason & 0x601F0000) {
+ case 0x80000:
+ printk("Machine check signal\n");
+ break;
+@@ -208,15 +249,6 @@
+ default:
+ printk("Unknown values in msr\n");
+ }
+-
+-#else /* CONFIG_4xx */
+- /* Note that the ESR gets stored in regs->dsisr on 4xx. */
+- if (regs->dsisr & ESR_MCI) {
+- printk(KERN_CRIT "Instruction");
+- mtspr(SPRN_ESR, regs->dsisr & ~ESR_MCI);
+- } else
+- printk(KERN_CRIT "Data");
+- printk(" machine check in kernel mode.\n");
+ #endif /* CONFIG_4xx */
+
+ debugger(regs);
+@@ -238,7 +270,7 @@
+ {
+ printk("Bad trap at PC: %lx, MSR: %lx, vector=%lx %s\n",
+ regs->nip, regs->msr, regs->trap, print_tainted());
+- _exception(SIGTRAP, regs);
++ _exception(SIGTRAP, regs, 0, 0);
+ }
+
+ void
+@@ -246,13 +278,13 @@
+ {
+ if (debugger_iabr_match(regs))
+ return;
+- _exception(SIGTRAP, regs);
++ _exception(SIGTRAP, regs, TRAP_BRKPT, 0);
+ }
+
+ void
+ RunModeException(struct pt_regs *regs)
+ {
+- _exception(SIGTRAP, regs);
++ _exception(SIGTRAP, regs, 0, 0);
+ }
+
+ /* Illegal instruction emulation support. Originally written to
+@@ -271,17 +303,17 @@
+ static int
+ emulate_instruction(struct pt_regs *regs)
+ {
+- uint instword;
+- uint rd;
+- uint retval;
++ u32 instword;
++ u32 rd;
++ int retval;
+
+- retval = EINVAL;
++ retval = -EINVAL;
+
+ if (!user_mode(regs))
+ return retval;
+ CHECK_FULL_REGS(regs);
+
+- if (get_user(instword, (uint __user *)(regs->nip)))
++ if (get_user(instword, (u32 __user *)(regs->nip)))
+ return -EFAULT;
+
+ /* Emulate the mfspr rD, PVR.
+@@ -290,10 +322,23 @@
+ rd = (instword >> 21) & 0x1f;
+ regs->gpr[rd] = mfspr(PVR);
+ retval = 0;
+- }
+- if (retval == 0)
+ regs->nip += 4;
+- return(retval);
++ }
++ return retval;
++}
++
++/*
++ * After we have successfully emulated an instruction, we have to
++ * check if the instruction was being single-stepped, and if so,
++ * pretend we got a single-step exception. This was pointed out
++ * by Kumar Gala. -- paulus
++ */
++static void emulate_single_step(struct pt_regs *regs)
++{
++ if (single_stepping(regs)) {
++ clear_single_step(regs);
++ _exception(SIGTRAP, regs, TRAP_TRACE, 0);
++ }
+ }
+
+ /*
+@@ -349,29 +394,47 @@
+ void
+ ProgramCheckException(struct pt_regs *regs)
+ {
+- int errcode;
+-
+-#if defined(CONFIG_4xx)
+- unsigned int esr = regs->dsisr;
+- int isbpt = esr & ESR_PTR;
++ unsigned int reason = get_reason(regs);
+ extern int do_mathemu(struct pt_regs *regs);
+
+ #ifdef CONFIG_MATH_EMULATION
+- if (!isbpt && do_mathemu(regs) == 0)
++ /* (reason & REASON_ILLEGAL) would be the obvious thing here,
++ * but there seems to be a hardware bug on the 405GP (RevD)
++ * that means ESR is sometimes set incorrectly - either to
++ * ESR_DST (!?) or 0. In the process of chasing this with the
++ * hardware people - not sure if it can happen on any illegal
++ * instruction or only on FP instructions, whether there is a
++ * pattern to occurences etc. -dgibson 31/Mar/2003 */
++ if (!(reason & REASON_TRAP) && do_mathemu(regs) == 0) {
++ emulate_single_step(regs);
+ return;
++ }
+ #endif /* CONFIG_MATH_EMULATION */
+
+-#else /* ! CONFIG_4xx */
+- int isbpt = regs->msr & 0x20000;
+-
+- if (regs->msr & 0x100000) {
++ if (reason & REASON_FP) {
+ /* IEEE FP exception */
+- _exception(SIGFPE, regs);
++ int code = 0;
++ u32 fpscr;
++
++ if (regs->msr & MSR_FP)
++ giveup_fpu(current);
++ fpscr = current->thread.fpscr;
++ fpscr &= fpscr << 22; /* mask summary bits with enables */
++ if (fpscr & FPSCR_VX)
++ code = FPE_FLTINV;
++ else if (fpscr & FPSCR_OX)
++ code = FPE_FLTOVF;
++ else if (fpscr & FPSCR_UX)
++ code = FPE_FLTUND;
++ else if (fpscr & FPSCR_ZX)
++ code = FPE_FLTDIV;
++ else if (fpscr & FPSCR_XX)
++ code = FPE_FLTRES;
++ _exception(SIGFPE, regs, code, regs->nip);
+ return;
+ }
+-#endif /* ! CONFIG_4xx */
+
+- if (isbpt) {
++ if (reason & REASON_TRAP) {
+ /* trap exception */
+ if (debugger_bpt(regs))
+ return;
+@@ -379,17 +442,21 @@
+ regs->nip += 4;
+ return;
+ }
+- _exception(SIGTRAP, regs);
++ _exception(SIGTRAP, regs, TRAP_BRKPT, 0);
+ return;
+ }
+
+- /* Try to emulate it if we should. */
+- if ((errcode = emulate_instruction(regs))) {
+- if (errcode == -EFAULT)
+- _exception(SIGBUS, regs);
+- else
+- _exception(SIGILL, regs);
++ if (reason & REASON_PRIVILEGED) {
++ /* Try to emulate it if we should. */
++ if (emulate_instruction(regs) == 0) {
++ emulate_single_step(regs);
++ return;
++ }
++ _exception(SIGILL, regs, ILL_PRVOPC, regs->nip);
++ return;
+ }
++
++ _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
+ }
+
+ void
+@@ -398,7 +465,7 @@
+ regs->msr &= ~MSR_SE; /* Turn off 'trace' bit */
+ if (debugger_sstep(regs))
+ return;
+- _exception(SIGTRAP, regs);
++ _exception(SIGTRAP, regs, TRAP_TRACE, 0);
+ }
+
+ void
+@@ -414,12 +481,12 @@
+ if (fixed == -EFAULT) {
+ /* fixed == -EFAULT means the operand address was bad */
+ if (user_mode(regs))
+- force_sig(SIGSEGV, current);
++ _exception(SIGSEGV, regs, SEGV_ACCERR, regs->dar);
+ else
+ bad_page_fault(regs, regs->dar, SIGSEGV);
+ return;
+ }
+- _exception(SIGBUS, regs);
++ _exception(SIGBUS, regs, BUS_ADRALN, regs->dar);
+ }
+
+ void
+@@ -470,16 +537,17 @@
+ #endif
+ if (errcode) {
+ if (errcode > 0)
+- _exception(SIGFPE, regs);
++ _exception(SIGFPE, regs, 0, 0);
+ else if (errcode == -EFAULT)
+- _exception(SIGSEGV, regs);
++ _exception(SIGSEGV, regs, 0, 0);
+ else
+- _exception(SIGILL, regs);
+- }
++ _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
++ } else
++ emulate_single_step(regs);
+ }
+ #endif /* CONFIG_8xx */
+
+-#if defined(CONFIG_4xx)
++#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+
+ void DebugException(struct pt_regs *regs, unsigned long debug_status)
+ {
+@@ -487,7 +555,7 @@
+ if (debug_status & DBSR_TIE) { /* trap instruction*/
+ if (!user_mode(regs) && debugger_bpt(regs))
+ return;
+- _exception(SIGTRAP, regs);
++ _exception(SIGTRAP, regs, 0, 0);
+
+ }
+ #endif
+@@ -495,10 +563,10 @@
+ if (!user_mode(regs) && debugger_sstep(regs))
+ return;
+ current->thread.dbcr0 &= ~DBCR0_IC;
+- _exception(SIGTRAP, regs);
++ _exception(SIGTRAP, regs, TRAP_TRACE, 0);
+ }
+ }
+-#endif /* CONFIG_4xx */
++#endif /* CONFIG_4xx || CONFIG_BOOKE */
+
+ #if !defined(CONFIG_TAU_INT)
+ void
+Index: linux-2.6.0-test5/arch/ppc/mm/cachemap.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc/mm/cachemap.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc/mm/cachemap.c 2003-09-27 11:38:19.970492408 +0800
+@@ -101,7 +101,7 @@
+ if (! area)
+ goto out;
+
+- va = VMALLOC_VMADDR(area->addr);
++ va = (unsigned long) area->addr;
+
+ flags = _PAGE_KERNEL | _PAGE_NO_CACHE;
+
+Index: linux-2.6.0-test5/arch/ppc/mm/pgtable.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc/mm/pgtable.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc/mm/pgtable.c 2003-09-27 11:38:19.974491800 +0800
+@@ -195,7 +195,7 @@
+ area = get_vm_area(size, VM_IOREMAP);
+ if (area == 0)
+ return NULL;
+- v = VMALLOC_VMADDR(area->addr);
++ v = (unsigned long) area->addr;
+ } else {
+ v = (ioremap_bot -= size);
+ }
+Index: linux-2.6.0-test5/arch/ppc/platforms/pmac_setup.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc/platforms/pmac_setup.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc/platforms/pmac_setup.c 2003-09-27 11:38:19.979491040 +0800
+@@ -107,7 +107,7 @@
+
+ extern int pmac_newworld;
+
+-#define DEFAULT_ROOT_DEVICE 0x0801 /* sda1 - slightly silly choice */
++#define DEFAULT_ROOT_DEVICE Root_SDA1 /* sda1 - slightly silly choice */
+
+ extern void zs_kgdb_hook(int tty_num);
+ static void ohare_init(void);
+Index: linux-2.6.0-test5/arch/s390/kernel/compat_linux.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/s390/kernel/compat_linux.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/s390/kernel/compat_linux.c 2003-09-27 11:38:19.998488152 +0800
+@@ -1316,13 +1316,16 @@
+ {
+ int err;
+
+- err = put_user(stat->dev, &statbuf->st_dev);
++ if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev))
++ return -EOVERFLOW;
++
++ err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev);
+ err |= put_user(stat->ino, &statbuf->st_ino);
+ err |= put_user(stat->mode, &statbuf->st_mode);
+ err |= put_user(stat->nlink, &statbuf->st_nlink);
+ err |= put_user(high2lowuid(stat->uid), &statbuf->st_uid);
+ err |= put_user(high2lowgid(stat->gid), &statbuf->st_gid);
+- err |= put_user(stat->rdev, &statbuf->st_rdev);
++ err |= put_user(old_encode_dev(stat->rdev), &statbuf->st_rdev);
+ err |= put_user(stat->size, &statbuf->st_size);
+ err |= put_user(stat->atime.tv_sec, &statbuf->st_atime);
+ err |= put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
+@@ -2543,8 +2546,7 @@
+ }
+
+ struct stat64_emu31 {
+- unsigned char __pad0[6];
+- unsigned short st_dev;
++ unsigned long long st_dev;
+ unsigned int __pad1;
+ #define STAT64_HAS_BROKEN_ST_INO 1
+ u32 __st_ino;
+@@ -2552,8 +2554,7 @@
+ unsigned int st_nlink;
+ u32 st_uid;
+ u32 st_gid;
+- unsigned char __pad2[6];
+- unsigned short st_rdev;
++ unsigned long long st_rdev;
+ unsigned int __pad3;
+ long st_size;
+ u32 st_blksize;
+@@ -2569,93 +2570,55 @@
+ unsigned long st_ino;
+ };
+
+-static inline int
+-putstat64 (struct stat64_emu31 *ubuf, struct stat *kbuf)
++static int cp_stat64(struct stat64_emu31 *ubuf, struct kstat *stat)
+ {
+- struct stat64_emu31 tmp;
+-
+- memset(&tmp, 0, sizeof(tmp));
+-
+- tmp.st_dev = (unsigned short)kbuf->st_dev;
+- tmp.st_ino = kbuf->st_ino;
+- tmp.__st_ino = (u32)kbuf->st_ino;
+- tmp.st_mode = kbuf->st_mode;
+- tmp.st_nlink = (unsigned int)kbuf->st_nlink;
+- tmp.st_uid = kbuf->st_uid;
+- tmp.st_gid = kbuf->st_gid;
+- tmp.st_rdev = (unsigned short)kbuf->st_rdev;
+- tmp.st_size = kbuf->st_size;
+- tmp.st_blksize = (u32)kbuf->st_blksize;
+- tmp.st_blocks = (u32)kbuf->st_blocks;
+- tmp.st_atime = (u32)kbuf->st_atime;
+- tmp.st_mtime = (u32)kbuf->st_mtime;
+- tmp.st_ctime = (u32)kbuf->st_ctime;
++ struct stat64_emu31 tmp;
+
+- return copy_to_user(ubuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
+-}
++ memset(&tmp, 0, sizeof(tmp));
+
+-extern asmlinkage long sys_newstat(char * filename, struct stat * statbuf);
++ tmp.st_dev = huge_encode_dev(stat->dev);
++ tmp.st_ino = stat->ino;
++ tmp.__st_ino = (u32)stat->ino;
++ tmp.st_mode = stat->mode;
++ tmp.st_nlink = (unsigned int)stat->nlink;
++ tmp.uid = stat->uid;
++ tmp.gid = stat->gid;
++ tmp.st_rdev = huge_encode_dev(stat->rdev);
++ tmp.st_size = stat->st_size;
++ tmp.st_blksize = (u32)stat->blksize;
++ tmp.st_blocks = (u32)stat->blocks;
++ tmp.st_atime = (u32)stat->atime.tv_sec;
++ tmp.st_mtime = (u32)stat->mtime.tv_sec;
++ tmp.st_ctime = (u32)stat->ctime.tv_sec;
++
++ return copy_to_user(ubuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
++}
+
+ asmlinkage long sys32_stat64(char * filename, struct stat64_emu31 * statbuf, long flags)
+ {
+- int ret;
+- struct stat s;
+- char * tmp;
+- int err;
+- mm_segment_t old_fs = get_fs();
+-
+- tmp = getname(filename);
+- err = PTR_ERR(tmp);
+- if (IS_ERR(tmp))
+- return err;
+-
+- set_fs (KERNEL_DS);
+- ret = sys_newstat(tmp, &s);
+- set_fs (old_fs);
+- putname(tmp);
+- if (putstat64 (statbuf, &s))
+- return -EFAULT;
+- return ret;
++ struct kstat stat;
++ int ret = vfs_stat(filename, &stat);
++ if (!ret)
++ ret = cp_stat64(statbuf, &stat);
++ return ret;
+ }
+
+-extern asmlinkage long sys_newlstat(char * filename, struct stat * statbuf);
+-
+ asmlinkage long sys32_lstat64(char * filename, struct stat64_emu31 * statbuf, long flags)
+ {
+- int ret;
+- struct stat s;
+- char * tmp;
+- int err;
+- mm_segment_t old_fs = get_fs();
+-
+- tmp = getname(filename);
+- err = PTR_ERR(tmp);
+- if (IS_ERR(tmp))
+- return err;
+-
+- set_fs (KERNEL_DS);
+- ret = sys_newlstat(tmp, &s);
+- set_fs (old_fs);
+- putname(tmp);
+- if (putstat64 (statbuf, &s))
+- return -EFAULT;
+- return ret;
++ struct kstat stat;
++ int ret = vfs_lstat(filename, &stat);
++ if (!ret)
++ ret = cp_stat64(statbuf, &stat);
++ return ret;
+ }
+
+-extern asmlinkage long sys_newfstat(unsigned int fd, struct stat * statbuf);
+-
+ asmlinkage long sys32_fstat64(unsigned long fd, struct stat64_emu31 * statbuf, long flags)
+ {
+- int ret;
+- struct stat s;
+- mm_segment_t old_fs = get_fs();
+-
+- set_fs (KERNEL_DS);
+- ret = sys_newfstat(fd, &s);
+- set_fs (old_fs);
+- if (putstat64 (statbuf, &s))
+- return -EFAULT;
+- return ret;
++ struct kstat stat;
++ int ret = vfs_fstat(fd, &stat);
++ if (!ret)
++ ret = cp_stat64(statbuf, &stat);
++ return ret;
+ }
+
+ /*
+Index: linux-2.6.0-test5/arch/s390/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/s390/Makefile 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/s390/Makefile 2003-09-27 11:38:19.999488000 +0800
+@@ -13,8 +13,6 @@
+ # Copyright (C) 1994 by Linus Torvalds
+ #
+
+-check_gcc = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi)
+-
+ ifdef CONFIG_ARCH_S390_31
+ LDFLAGS := -m elf_s390
+ CFLAGS += -m31
+Index: linux-2.6.0-test5/arch/s390/mm/ioremap.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/s390/mm/ioremap.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/s390/mm/ioremap.c 2003-09-27 11:38:20.001487696 +0800
+@@ -124,7 +124,7 @@
+ if (!area)
+ return NULL;
+ addr = area->addr;
+- if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) {
++ if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
+ vfree(addr);
+ return NULL;
+ }
+Index: linux-2.6.0-test5/arch/sh/boot/compressed/misc.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sh/boot/compressed/misc.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sh/boot/compressed/misc.c 2003-09-27 11:38:20.003487392 +0800
+@@ -105,8 +105,8 @@
+ {
+ void *p;
+
+- if (size <0) error("Malloc error\n");
+- if (free_mem_ptr == 0) error("Memory error\n");
++ if (size <0) error("Malloc error");
++ if (free_mem_ptr == 0) error("Memory error");
+
+ free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
+
+@@ -114,7 +114,7 @@
+ free_mem_ptr += size;
+
+ if (free_mem_ptr >= free_mem_end_ptr)
+- error("\nOut of memory\n");
++ error("Out of memory");
+
+ return p;
+ }
+@@ -180,7 +180,7 @@
+ static int fill_inbuf(void)
+ {
+ if (insize != 0) {
+- error("ran out of input data\n");
++ error("ran out of input data");
+ }
+
+ inbuf = input_data;
+Index: linux-2.6.0-test5/arch/sh/kernel/setup.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sh/kernel/setup.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sh/kernel/setup.c 2003-09-27 11:38:20.008486632 +0800
+@@ -353,7 +353,7 @@
+ sh_console_init();
+ #endif
+
+- ROOT_DEV = ORIG_ROOT_DEV;
++ ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
+
+ #ifdef CONFIG_BLK_DEV_RAM
+ rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
+Index: linux-2.6.0-test5/arch/sh/mm/init.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sh/mm/init.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sh/mm/init.c 2003-09-27 11:38:20.011486176 +0800
+@@ -51,8 +51,8 @@
+ #endif
+
+ #ifdef CONFIG_DISCONTIGMEM
+-pg_data_t discontig_page_data[NR_NODES];
+-bootmem_data_t discontig_node_bdata[NR_NODES];
++pg_data_t discontig_page_data[MAX_NUMNODES];
++bootmem_data_t discontig_node_bdata[MAX_NUMNODES];
+ #endif
+
+ void show_mem(void)
+Index: linux-2.6.0-test5/arch/sh/mm/ioremap.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sh/mm/ioremap.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sh/mm/ioremap.c 2003-09-27 11:38:20.012486024 +0800
+@@ -149,7 +149,7 @@
+ if (!area)
+ return NULL;
+ addr = area->addr;
+- if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) {
++ if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
+ vfree(addr);
+ return NULL;
+ }
+Index: linux-2.6.0-test5/arch/sparc64/defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sparc64/defconfig 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sparc64/defconfig 2003-09-27 11:38:20.021484656 +0800
+@@ -1,13 +1,15 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++CONFIG_64BIT=y
+ CONFIG_MMU=y
+
+ #
+ # Code maturity level options
+ #
+ CONFIG_EXPERIMENTAL=y
+-CONFIG_BROKEN=y
++CONFIG_CLEAN_COMPILE=y
++CONFIG_STANDALONE=y
+
+ #
+ # General setup
+@@ -17,6 +19,7 @@
+ # CONFIG_BSD_PROCESS_ACCT is not set
+ CONFIG_SYSCTL=y
+ CONFIG_LOG_BUF_SHIFT=15
++# CONFIG_IKCONFIG is not set
+ # CONFIG_EMBEDDED is not set
+ CONFIG_KALLSYMS=y
+ CONFIG_FUTEX=y
+@@ -51,6 +54,10 @@
+ CONFIG_US3_FREQ=m
+ CONFIG_US2E_FREQ=m
+ CONFIG_CPU_FREQ_PROC_INTF=y
++CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
++# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
++CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+ CONFIG_CPU_FREQ_GOV_USERSPACE=m
+ # CONFIG_CPU_FREQ_24_API is not set
+ CONFIG_SPARC64=y
+@@ -67,7 +74,6 @@
+ # CONFIG_PCI_LEGACY_PROC is not set
+ # CONFIG_PCI_NAMES is not set
+ CONFIG_SUN_OPENPROMFS=m
+-CONFIG_KCORE_ELF=y
+ CONFIG_SPARC32_COMPAT=y
+ CONFIG_COMPAT=y
+ CONFIG_BINFMT_ELF32=y
+@@ -102,8 +108,6 @@
+ # Graphics support
+ #
+ CONFIG_FB=y
+-# CONFIG_FB_CIRRUS is not set
+-# CONFIG_FB_PM2 is not set
+ # CONFIG_FB_CYBER2000 is not set
+ # CONFIG_FB_IMSTT is not set
+ # CONFIG_FB_BW2 is not set
+@@ -119,7 +123,6 @@
+ # CONFIG_FB_3DFX is not set
+ # CONFIG_FB_VOODOO1 is not set
+ # CONFIG_FB_TRIDENT is not set
+-# CONFIG_FB_PM3 is not set
+ CONFIG_FB_SBUS=y
+ CONFIG_FB_FFB=y
+ # CONFIG_FB_TCX is not set
+@@ -274,6 +277,7 @@
+ # SCSI device support
+ #
+ CONFIG_SCSI=y
++CONFIG_SCSI_PROC_FS=y
+
+ #
+ # SCSI support type (disk, tape, CD-ROM)
+@@ -309,7 +313,6 @@
+ # CONFIG_AIC79XX_DEBUG_ENABLE is not set
+ CONFIG_AIC79XX_DEBUG_MASK=0
+ # CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
+-# CONFIG_SCSI_DPT_I2O is not set
+ # CONFIG_SCSI_ADVANSYS is not set
+ # CONFIG_SCSI_MEGARAID is not set
+ # CONFIG_SCSI_BUSLOGIC is not set
+@@ -319,7 +322,7 @@
+ CONFIG_SCSI_EATA_PIO=m
+ # CONFIG_SCSI_FUTURE_DOMAIN is not set
+ # CONFIG_SCSI_GDTH is not set
+-# CONFIG_SCSI_INITIO is not set
++CONFIG_SCSI_IPS=m
+ CONFIG_SCSI_INIA100=m
+ CONFIG_SCSI_PPA=m
+ CONFIG_SCSI_IMM=m
+@@ -330,15 +333,12 @@
+ CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+ CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+ # CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+-# CONFIG_SCSI_PCI2000 is not set
+-# CONFIG_SCSI_PCI2220I is not set
+ CONFIG_SCSI_QLOGIC_ISP=m
+ CONFIG_SCSI_QLOGIC_FC=y
+ CONFIG_SCSI_QLOGIC_FC_FIRMWARE=y
+ # CONFIG_SCSI_QLOGIC_1280 is not set
+ CONFIG_SCSI_QLOGICPTI=m
+ CONFIG_SCSI_DC395x=m
+-# CONFIG_SCSI_DC390T is not set
+ # CONFIG_SCSI_NSP32 is not set
+ CONFIG_SCSI_DEBUG=m
+ CONFIG_SCSI_SUNESP=y
+@@ -474,6 +474,7 @@
+ CONFIG_BRIDGE=m
+ CONFIG_NETFILTER=y
+ # CONFIG_NETFILTER_DEBUG is not set
++CONFIG_BRIDGE_NETFILTER=y
+
+ #
+ # IP: Netfilter Configuration
+@@ -486,6 +487,7 @@
+ CONFIG_IP_NF_QUEUE=m
+ CONFIG_IP_NF_IPTABLES=m
+ CONFIG_IP_NF_MATCH_LIMIT=m
++CONFIG_IP_NF_MATCH_IPRANGE=m
+ CONFIG_IP_NF_MATCH_MAC=m
+ CONFIG_IP_NF_MATCH_PKTTYPE=m
+ CONFIG_IP_NF_MATCH_MARK=m
+@@ -501,16 +503,16 @@
+ CONFIG_IP_NF_MATCH_HELPER=m
+ CONFIG_IP_NF_MATCH_STATE=m
+ CONFIG_IP_NF_MATCH_CONNTRACK=m
+-CONFIG_IP_NF_MATCH_UNCLEAN=m
+ CONFIG_IP_NF_MATCH_OWNER=m
+ CONFIG_IP_NF_MATCH_PHYSDEV=m
+ CONFIG_IP_NF_FILTER=m
+ CONFIG_IP_NF_TARGET_REJECT=m
+-CONFIG_IP_NF_TARGET_MIRROR=m
+ CONFIG_IP_NF_NAT=m
+ CONFIG_IP_NF_NAT_NEEDED=y
+ CONFIG_IP_NF_TARGET_MASQUERADE=m
+ CONFIG_IP_NF_TARGET_REDIRECT=m
++CONFIG_IP_NF_TARGET_NETMAP=m
++CONFIG_IP_NF_TARGET_SAME=m
+ CONFIG_IP_NF_NAT_LOCAL=y
+ CONFIG_IP_NF_NAT_SNMP_BASIC=m
+ CONFIG_IP_NF_NAT_IRC=m
+@@ -522,6 +524,7 @@
+ CONFIG_IP_NF_TARGET_ECN=m
+ CONFIG_IP_NF_TARGET_DSCP=m
+ CONFIG_IP_NF_TARGET_MARK=m
++CONFIG_IP_NF_TARGET_CLASSIFY=m
+ CONFIG_IP_NF_TARGET_LOG=m
+ CONFIG_IP_NF_TARGET_ULOG=m
+ CONFIG_IP_NF_TARGET_TCPMSS=m
+@@ -558,21 +561,27 @@
+ # DECnet: Netfilter Configuration
+ #
+ CONFIG_DECNET_NF_GRABULATOR=m
++
++#
++# Bridge: Netfilter Configuration
++#
+ CONFIG_BRIDGE_NF_EBTABLES=m
++CONFIG_BRIDGE_EBT_BROUTE=m
+ CONFIG_BRIDGE_EBT_T_FILTER=m
+ CONFIG_BRIDGE_EBT_T_NAT=m
+-CONFIG_BRIDGE_EBT_BROUTE=m
+-CONFIG_BRIDGE_EBT_LOG=m
+-CONFIG_BRIDGE_EBT_IP=m
++CONFIG_BRIDGE_EBT_802_3=m
+ CONFIG_BRIDGE_EBT_ARP=m
+-CONFIG_BRIDGE_EBT_VLAN=m
++CONFIG_BRIDGE_EBT_IP=m
+ CONFIG_BRIDGE_EBT_MARK=m
+ CONFIG_BRIDGE_EBT_PKTTYPE=m
+ CONFIG_BRIDGE_EBT_STP=m
+-CONFIG_BRIDGE_EBT_SNAT=m
++CONFIG_BRIDGE_EBT_VLAN=m
++CONFIG_BRIDGE_EBT_ARPREPLY=m
+ CONFIG_BRIDGE_EBT_DNAT=m
+-CONFIG_BRIDGE_EBT_REDIRECT=m
+ CONFIG_BRIDGE_EBT_MARK_T=m
++CONFIG_BRIDGE_EBT_REDIRECT=m
++CONFIG_BRIDGE_EBT_SNAT=m
++CONFIG_BRIDGE_EBT_LOG=m
+ CONFIG_XFRM=y
+ CONFIG_XFRM_USER=m
+
+@@ -781,7 +790,6 @@
+ # Token Ring devices (depends on LLC=y)
+ #
+ CONFIG_NET_FC=y
+-# CONFIG_IPHASE5526 is not set
+ # CONFIG_RCPCI is not set
+ CONFIG_SHAPER=m
+
+@@ -830,8 +838,6 @@
+ #
+ # AX.25 network device drivers
+ #
+-# CONFIG_MKISS is not set
+-# CONFIG_6PACK is not set
+ # CONFIG_BPQETHER is not set
+ # CONFIG_BAYCOM_SER_FDX is not set
+ # CONFIG_BAYCOM_SER_HDX is not set
+@@ -875,7 +881,6 @@
+ #
+ # Old SIR device drivers
+ #
+-# CONFIG_IRTTY_OLD is not set
+ # CONFIG_IRPORT_SIR is not set
+
+ #
+@@ -886,7 +891,6 @@
+ # FIR device drivers
+ #
+ # CONFIG_USB_IRDA is not set
+-# CONFIG_TOSHIBA_OLD is not set
+ # CONFIG_TOSHIBA_FIR is not set
+ # CONFIG_VLSI_FIR is not set
+
+@@ -896,11 +900,6 @@
+ CONFIG_ISDN_BOOL=y
+
+ #
+-# Old ISDN4Linux
+-#
+-# CONFIG_ISDN is not set
+-
+-#
+ # CAPI subsystem
+ #
+ CONFIG_ISDN_CAPI=m
+@@ -1000,7 +999,6 @@
+ CONFIG_I2C_PHILIPSPAR=m
+ CONFIG_SCx200_ACB=m
+ CONFIG_I2C_ALGOPCF=m
+-# CONFIG_I2C_ELEKTOR is not set
+ CONFIG_I2C_CHARDEV=m
+
+ #
+@@ -1198,7 +1196,6 @@
+ #
+ # Video For Linux
+ #
+-CONFIG_VIDEO_PROC_FS=y
+
+ #
+ # Video Adapters
+@@ -1214,7 +1211,6 @@
+ CONFIG_TUNER_3036=m
+ # CONFIG_VIDEO_STRADIS is not set
+ # CONFIG_VIDEO_ZORAN is not set
+-# CONFIG_VIDEO_ZR36120 is not set
+ CONFIG_VIDEO_SAA7134=m
+ CONFIG_VIDEO_MXB=m
+ CONFIG_VIDEO_DPC=m
+@@ -1247,7 +1243,6 @@
+ CONFIG_DVB_GRUNDIG_29504_401=m
+ CONFIG_DVB_MT312=m
+ CONFIG_DVB_VES1820=m
+-# CONFIG_DVB_TDA1004X is not set
+
+ #
+ # Supported SAA7146 based PCI Adapters
+@@ -1262,7 +1257,6 @@
+ # Supported USB Adapters
+ #
+ # CONFIG_DVB_TTUSB_BUDGET is not set
+-# CONFIG_DVB_TTUSB_DEC is not set
+
+ #
+ # Supported FlexCopII (B2C2) Adapters
+@@ -1430,7 +1424,7 @@
+ #
+ # USB Network adaptors
+ #
+-CONFIG_USB_AX8817X=m
++CONFIG_USB_AX8817X_STANDALONE=m
+ CONFIG_USB_CATC=m
+ CONFIG_USB_KAWETH=m
+ CONFIG_USB_PEGASUS=m
+@@ -1455,6 +1449,11 @@
+ CONFIG_USB_CDCETHER=y
+
+ #
++# USB Network Adapters
++#
++CONFIG_USB_AX8817X=y
++
++#
+ # USB port drivers
+ #
+ CONFIG_USB_USS720=m
+Index: linux-2.6.0-test5/arch/sparc64/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sparc64/Kconfig 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sparc64/Kconfig 2003-09-27 11:38:20.029483440 +0800
+@@ -29,7 +29,8 @@
+ smartcard reader, if present. Say Y to enable support for these.
+
+ config VT
+- bool
++ bool "Virtual terminal" if EMBEDDED
++ select INPUT
+ default y
+ ---help---
+ If you say Y here, you will get support for terminal devices with
+@@ -59,7 +60,8 @@
+ shiny Linux system :-)
+
+ config VT_CONSOLE
+- bool
++ bool "Support for console on virtual terminal" if EMBEDDED
++ depends on VT
+ default y
+ ---help---
+ The system console is the device which receives all kernel messages
+@@ -83,16 +85,6 @@
+ bool
+ default y
+
+-config HUGETLB_PAGE
+- bool "SPARC64 Huge TLB Page Support"
+- help
+- This enables support for huge pages. User space applications
+- can make use of this support with the sys_alloc_hugepages and
+- sys_free_hugepages system calls. If your applications are
+- huge page aware, then say Y here.
+-
+- Otherwise, say N.
+-
+ config SMP
+ bool "Symmetric multi-processing support"
+ ---help---
+@@ -832,12 +824,19 @@
+ best used in conjunction with the NMI watchdog so that spinlock
+ deadlocks are also debuggable.
+
++config LOCKMETER
++ bool "Kernel lock metering"
++ depends on SMP && !PREEMPT
++ help
++ Say Y to enable kernel lock metering, which adds overhead to SMP locks,
++ but allows you to see various statistics using the lockstat command.
++
+ # We have a custom atomic_dec_and_lock() implementation but it's not
+ # compatible with spinlock debugging so we need to fall back on
+ # the generic version in that case.
+ config HAVE_DEC_LOCK
+ bool
+- depends on !DEBUG_SPINLOCK
++ depends on !DEBUG_SPINLOCK && !LOCKMETER
+ default y
+
+ config DEBUG_SPINLOCK_SLEEP
+Index: linux-2.6.0-test5/arch/sparc64/kernel/setup.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sparc64/kernel/setup.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sparc64/kernel/setup.c 2003-09-27 11:38:20.034482680 +0800
+@@ -517,7 +517,7 @@
+
+ if (!root_flags)
+ root_mountflags &= ~MS_RDONLY;
+- ROOT_DEV = root_dev;
++ ROOT_DEV = old_decode_dev(root_dev);
+ #ifdef CONFIG_BLK_DEV_INITRD
+ rd_image_start = ram_flags & RAMDISK_IMAGE_START_MASK;
+ rd_prompt = ((ram_flags & RAMDISK_PROMPT_FLAG) != 0);
+Index: linux-2.6.0-test5/arch/sparc64/kernel/sys_sparc32.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sparc64/kernel/sys_sparc32.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sparc64/kernel/sys_sparc32.c 2003-09-27 11:38:20.053479792 +0800
+@@ -1304,16 +1304,17 @@
+ {
+ int err;
+
+- if (stat->size > MAX_NON_LFS)
++ if (stat->size > MAX_NON_LFS || !old_valid_dev(stat->dev) ||
++ !old_valid_dev(stat->rdev))
+ return -EOVERFLOW;
+
+- err = put_user(stat->dev, &statbuf->st_dev);
++ err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev);
+ err |= put_user(stat->ino, &statbuf->st_ino);
+ err |= put_user(stat->mode, &statbuf->st_mode);
+ err |= put_user(stat->nlink, &statbuf->st_nlink);
+ err |= put_user(high2lowuid(stat->uid), &statbuf->st_uid);
+ err |= put_user(high2lowgid(stat->gid), &statbuf->st_gid);
+- err |= put_user(stat->rdev, &statbuf->st_rdev);
++ err |= put_user(old_encode_dev(stat->rdev), &statbuf->st_rdev);
+ err |= put_user(stat->size, &statbuf->st_size);
+ err |= put_user(stat->atime.tv_sec, &statbuf->st_atime);
+ err |= put_user(0, &statbuf->__unused1);
+Index: linux-2.6.0-test5/arch/sparc64/kernel/time.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sparc64/kernel/time.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sparc64/kernel/time.c 2003-09-27 11:38:20.062478424 +0800
+@@ -416,6 +416,7 @@
+ unsigned long timer_tick_compare;
+
+ static unsigned long timer_ticks_per_usec_quotient;
++static unsigned long timer_ticks_per_nsec_quotient;
+
+ #define TICK_SIZE (tick_nsec / 1000)
+
+@@ -1051,12 +1052,18 @@
+ #endif
+
+ /* The quotient formula is taken from the IA64 port. */
++#define SPARC64_USEC_PER_CYC_SHIFT 30UL
++#define SPARC64_NSEC_PER_CYC_SHIFT 30UL
+ void __init time_init(void)
+ {
+ unsigned long clock = sparc64_init_timers(timer_interrupt);
+
+ timer_ticks_per_usec_quotient =
+- (((1000000UL << 30) +
++ (((1000000UL << SPARC64_USEC_PER_CYC_SHIFT) +
++ (clock / 2)) / clock);
++
++ timer_ticks_per_nsec_quotient =
++ (((NSEC_PER_SEC << SPARC64_NSEC_PER_CYC_SHIFT) +
+ (clock / 2)) / clock);
+
+ #ifdef CONFIG_CPU_FREQ
+@@ -1072,7 +1079,16 @@
+ ticks += timer_tick_offset;
+ ticks -= timer_tick_compare;
+
+- return (ticks * timer_ticks_per_usec_quotient) >> 30UL;
++ return (ticks * timer_ticks_per_usec_quotient)
++ >> SPARC64_USEC_PER_CYC_SHIFT;
++}
++
++unsigned long long sched_clock(void)
++{
++ unsigned long ticks = tick_ops->get_tick();
++
++ return (ticks * timer_ticks_per_nsec_quotient)
++ >> SPARC64_NSEC_PER_CYC_SHIFT;
+ }
+
+ int do_settimeofday(struct timespec *tv)
+Index: linux-2.6.0-test5/arch/sparc64/lib/rwlock.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sparc64/lib/rwlock.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sparc64/lib/rwlock.S 2003-09-27 11:38:20.063478272 +0800
+@@ -63,5 +63,33 @@
+ be,pt %icc, 99b
+ membar #StoreLoad | #StoreStore
+ ba,a,pt %xcc, 1b
++
++ .globl __read_trylock
++__read_trylock: /* %o0 = lock_ptr */
++ ldsw [%o0], %g5
++ brlz,pn %g5, 100f
++ add %g5, 1, %g7
++ cas [%o0], %g5, %g7
++ cmp %g5, %g7
++ bne,pn %icc, __read_trylock
++ membar #StoreLoad | #StoreStore
++ retl
++ mov 1, %o0
++
++ .globl __write_trylock
++__write_trylock: /* %o0 = lock_ptr */
++ sethi %hi(0x80000000), %g2
++1: lduw [%o0], %g5
++4: brnz,pn %g5, 100f
++ or %g5, %g2, %g7
++ cas [%o0], %g5, %g7
++ cmp %g5, %g7
++ bne,pn %icc, 1b
++ membar #StoreLoad | #StoreStore
++ retl
++ mov 1, %o0
++100: retl
++ mov 0, %o0
++
+ rwlock_impl_end:
+
+Index: linux-2.6.0-test5/arch/sparc64/mm/init.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sparc64/mm/init.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sparc64/mm/init.c 2003-09-27 11:38:20.077476144 +0800
+@@ -1706,10 +1706,6 @@
+ unsigned long addr, last;
+ int i;
+
+-#ifndef CONFIG_SMP
+- cpu_data(0).udelay_val = loops_per_jiffy;
+-#endif
+-
+ i = last_valid_pfn >> ((22 - PAGE_SHIFT) + 6);
+ i += 1;
+ sparc64_valid_addr_bitmap = (unsigned long *)
+Index: linux-2.6.0-test5/arch/sparc64/solaris/fs.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sparc64/solaris/fs.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sparc64/solaris/fs.c 2003-09-27 11:38:20.083475232 +0800
+@@ -28,9 +28,6 @@
+
+ #include "conv.h"
+
+-#define R4_DEV(DEV) ((DEV & 0xff) | ((DEV & 0xff00) << 10))
+-#define R4_MAJOR(DEV) (((DEV) >> 18) & 0x3fff)
+-#define R4_MINOR(DEV) ((DEV) & 0x3ffff)
+ #define R3_VERSION 1
+ #define R4_VERSION 2
+
+@@ -84,15 +81,17 @@
+
+ static inline int putstat(struct sol_stat *ubuf, struct kstat *kbuf)
+ {
+- if (kbuf->size > MAX_NON_LFS)
++ if (kbuf->size > MAX_NON_LFS ||
++ !sysv_valid_dev(kbuf->dev) ||
++ !sysv_valid_dev(kbuf->rdev))
+ return -EOVERFLOW;
+- if (put_user (R4_DEV(kbuf->dev), &ubuf->st_dev) ||
++ if (put_user (sysv_encode_dev(kbuf->dev), &ubuf->st_dev) ||
+ __put_user (kbuf->ino, &ubuf->st_ino) ||
+ __put_user (kbuf->mode, &ubuf->st_mode) ||
+ __put_user (kbuf->nlink, &ubuf->st_nlink) ||
+ __put_user (kbuf->uid, &ubuf->st_uid) ||
+ __put_user (kbuf->gid, &ubuf->st_gid) ||
+- __put_user (R4_DEV(kbuf->rdev), &ubuf->st_rdev) ||
++ __put_user (sysv_encode_dev(kbuf->rdev), &ubuf->st_rdev) ||
+ __put_user (kbuf->size, &ubuf->st_size) ||
+ __put_user (kbuf->atime.tv_sec, &ubuf->st_atime.tv_sec) ||
+ __put_user (kbuf->atime.tv_nsec, &ubuf->st_atime.tv_nsec) ||
+@@ -109,13 +108,15 @@
+
+ static inline int putstat64(struct sol_stat64 *ubuf, struct kstat *kbuf)
+ {
+- if (put_user (R4_DEV(kbuf->dev), &ubuf->st_dev) ||
++ if (!sysv_valid_dev(kbuf->dev) || !sysv_valid_dev(kbuf->rdev))
++ return -EOVERFLOW;
++ if (put_user (sysv_encode_dev(kbuf->dev), &ubuf->st_dev) ||
+ __put_user (kbuf->ino, &ubuf->st_ino) ||
+ __put_user (kbuf->mode, &ubuf->st_mode) ||
+ __put_user (kbuf->nlink, &ubuf->st_nlink) ||
+ __put_user (kbuf->uid, &ubuf->st_uid) ||
+ __put_user (kbuf->gid, &ubuf->st_gid) ||
+- __put_user (R4_DEV(kbuf->rdev), &ubuf->st_rdev) ||
++ __put_user (sysv_encode_dev(kbuf->rdev), &ubuf->st_rdev) ||
+ __put_user (kbuf->size, &ubuf->st_size) ||
+ __put_user (kbuf->atime.tv_sec, &ubuf->st_atime.tv_sec) ||
+ __put_user (kbuf->atime.tv_nsec, &ubuf->st_atime.tv_nsec) ||
+@@ -245,13 +246,16 @@
+
+ asmlinkage int solaris_mknod(u32 path, u32 mode, s32 dev)
+ {
+- int (*sys_mknod)(const char *,int,dev_t) =
+- (int (*)(const char *,int,dev_t))SYS(mknod);
+- int major, minor;
+-
+- if ((major = R4_MAJOR(dev)) > 255 ||
+- (minor = R4_MINOR(dev)) > 255) return -EINVAL;
+- return sys_mknod((const char *)A(path), mode, MKDEV(major,minor));
++ int (*sys_mknod)(const char *,int,unsigned) =
++ (int (*)(const char *,int,unsigned))SYS(mknod);
++ int major = sysv_major(dev);
++ int minor = sysv_minor(dev);
++
++ /* minor is guaranteed to be OK for MKDEV, major might be not */
++ if (major > 0xfff)
++ return -EINVAL;
++ return sys_mknod((const char *)A(path), mode,
++ new_encode_dev(MKDEV(major,minor)));
+ }
+
+ asmlinkage int solaris_xmknod(int vers, u32 path, u32 mode, s32 dev)
+@@ -403,6 +407,8 @@
+ if (j > 15) j = 15;
+ if (IS_RDONLY(inode)) i = 1;
+ if (mnt->mnt_flags & MNT_NOSUID) i |= 2;
++ if (!sysv_valid_dev(inode->i_sb->s_dev))
++ return -EOVERFLOW;
+ if (put_user (s.f_bsize, &ss->f_bsize) ||
+ __put_user (0, &ss->f_frsize) ||
+ __put_user (s.f_blocks, &ss->f_blocks) ||
+@@ -411,7 +417,7 @@
+ __put_user (s.f_files, &ss->f_files) ||
+ __put_user (s.f_ffree, &ss->f_ffree) ||
+ __put_user (s.f_ffree, &ss->f_favail) ||
+- __put_user (R4_DEV(inode->i_sb->s_dev), &ss->f_fsid) ||
++ __put_user (sysv_encode_dev(inode->i_sb->s_dev), &ss->f_fsid) ||
+ __copy_to_user (ss->f_basetype,p,j) ||
+ __put_user (0, (char *)&ss->f_basetype[j]) ||
+ __put_user (s.f_namelen, &ss->f_namemax) ||
+@@ -437,6 +443,8 @@
+ if (j > 15) j = 15;
+ if (IS_RDONLY(inode)) i = 1;
+ if (mnt->mnt_flags & MNT_NOSUID) i |= 2;
++ if (!sysv_valid_dev(inode->i_sb->s_dev))
++ return -EOVERFLOW;
+ if (put_user (s.f_bsize, &ss->f_bsize) ||
+ __put_user (0, &ss->f_frsize) ||
+ __put_user (s.f_blocks, &ss->f_blocks) ||
+@@ -445,7 +453,7 @@
+ __put_user (s.f_files, &ss->f_files) ||
+ __put_user (s.f_ffree, &ss->f_ffree) ||
+ __put_user (s.f_ffree, &ss->f_favail) ||
+- __put_user (R4_DEV(inode->i_sb->s_dev), &ss->f_fsid) ||
++ __put_user (sysv_encode_dev(inode->i_sb->s_dev), &ss->f_fsid) ||
+ __copy_to_user (ss->f_basetype,p,j) ||
+ __put_user (0, (char *)&ss->f_basetype[j]) ||
+ __put_user (s.f_namelen, &ss->f_namemax) ||
+Index: linux-2.6.0-test5/arch/sparc64/solaris/misc.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sparc64/solaris/misc.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sparc64/solaris/misc.c 2003-09-27 11:38:20.089474320 +0800
+@@ -392,7 +392,7 @@
+
+ switch (cmd) {
+ case 0: /* getpgrp */
+- return current->pgrp;
++ return process_group(current);
+ case 1: /* setpgrp */
+ {
+ int (*sys_setpgid)(pid_t,pid_t) =
+@@ -403,7 +403,7 @@
+ ret = sys_setpgid(0, 0);
+ if (ret) return ret;
+ current->tty = NULL;
+- return current->pgrp;
++ return process_group(current);
+ }
+ case 2: /* getsid */
+ {
+Index: linux-2.6.0-test5/arch/sparc/boot/btfixupprep.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sparc/boot/btfixupprep.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sparc/boot/btfixupprep.c 2003-09-27 11:38:20.093473712 +0800
+@@ -171,6 +171,8 @@
+ }
+ } else if (buffer[nbase+4] != '_')
+ continue;
++ if (!strcmp (sect, ".text.exit"))
++ continue;
+ if (strcmp (sect, ".text") &&
+ strcmp (sect, ".init.text") &&
+ strcmp (sect, ".fixup") &&
+Index: linux-2.6.0-test5/arch/sparc/kernel/setup.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sparc/kernel/setup.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sparc/kernel/setup.c 2003-09-27 11:38:20.096473256 +0800
+@@ -321,7 +321,7 @@
+
+ if (!root_flags)
+ root_mountflags &= ~MS_RDONLY;
+- ROOT_DEV = root_dev;
++ ROOT_DEV = old_decode_dev(root_dev);
+ #ifdef CONFIG_BLK_DEV_INITRD
+ rd_image_start = ram_flags & RAMDISK_IMAGE_START_MASK;
+ rd_prompt = ((ram_flags & RAMDISK_PROMPT_FLAG) != 0);
+Index: linux-2.6.0-test5/arch/sparc/kernel/sun4d_smp.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sparc/kernel/sun4d_smp.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sparc/kernel/sun4d_smp.c 2003-09-27 11:38:20.100472648 +0800
+@@ -343,11 +343,11 @@
+ unsigned long a3 asm("i3") = arg3;
+ unsigned long a4 asm("i4") = arg4;
+ unsigned long a5 asm("i5") = arg5;
+-
+- __asm__ __volatile__("
+- std %0, [%6]
+- std %2, [%6 + 8]
+- std %4, [%6 + 16]" : :
++
++ __asm__ __volatile__(
++ "std %0, [%6]\n\t"
++ "std %2, [%6 + 8]\n\t"
++ "std %4, [%6 + 16]\n\t" : :
+ "r"(f), "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a5),
+ "r" (&ccall_info.func));
+ }
+Index: linux-2.6.0-test5/arch/sparc/lib/checksum.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sparc/lib/checksum.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sparc/lib/checksum.S 2003-09-27 11:38:20.106471736 +0800
+@@ -145,36 +145,39 @@
+ .globl C_LABEL(__csum_partial_copy_start), C_LABEL(__csum_partial_copy_end)
+ C_LABEL(__csum_partial_copy_start):
+
+-#define EX(x,y,a,b,z) \
++/* Work around cpp -rob */
++#define ALLOC #alloc
++#define EXECINSTR #execinstr
++#define EX(x,y,a,b) \
+ 98: x,y; \
+- .section .fixup,z##alloc,z##execinstr; \
++ .section .fixup,ALLOC,EXECINSTR; \
+ .align 4; \
+ 99: ba 30f; \
+ a, b, %o3; \
+- .section __ex_table,z##alloc; \
++ .section __ex_table,ALLOC; \
+ .align 4; \
+ .word 98b, 99b; \
+ .text; \
+ .align 4
+
+-#define EX2(x,y,z) \
++#define EX2(x,y) \
+ 98: x,y; \
+- .section __ex_table,z##alloc; \
++ .section __ex_table,ALLOC; \
+ .align 4; \
+ .word 98b, 30f; \
+ .text; \
+ .align 4
+
+-#define EX3(x,y,z) \
++#define EX3(x,y) \
+ 98: x,y; \
+- .section __ex_table,z##alloc; \
++ .section __ex_table,ALLOC; \
+ .align 4; \
+ .word 98b, 96f; \
+ .text; \
+ .align 4
+
+-#define EXT(start,end,handler,z) \
+- .section __ex_table,z##alloc; \
++#define EXT(start,end,handler) \
++ .section __ex_table,ALLOC; \
+ .align 4; \
+ .word start, 0, end, handler; \
+ .text; \
+@@ -247,21 +250,21 @@
+ cc_end_cruft:
+ be 1f
+ andcc %o3, 4, %g0
+- EX(ldd [%o0 + 0x00], %g2, and %o3, 0xf,#)
++ EX(ldd [%o0 + 0x00], %g2, and %o3, 0xf)
+ add %o1, 8, %o1
+ addcc %g2, %g7, %g7
+ add %o0, 8, %o0
+ addxcc %g3, %g7, %g7
+- EX2(st %g2, [%o1 - 0x08],#)
++ EX2(st %g2, [%o1 - 0x08])
+ addx %g0, %g7, %g7
+ andcc %o3, 4, %g0
+- EX2(st %g3, [%o1 - 0x04],#)
++ EX2(st %g3, [%o1 - 0x04])
+ 1: be 1f
+ andcc %o3, 3, %o3
+- EX(ld [%o0 + 0x00], %g2, add %o3, 4,#)
++ EX(ld [%o0 + 0x00], %g2, add %o3, 4)
+ add %o1, 4, %o1
+ addcc %g2, %g7, %g7
+- EX2(st %g2, [%o1 - 0x04],#)
++ EX2(st %g2, [%o1 - 0x04])
+ addx %g0, %g7, %g7
+ andcc %o3, 3, %g0
+ add %o0, 4, %o0
+@@ -271,14 +274,14 @@
+ subcc %o3, 2, %o3
+ b 4f
+ or %g0, %g0, %o4
+-2: EX(lduh [%o0 + 0x00], %o4, add %o3, 2,#)
++2: EX(lduh [%o0 + 0x00], %o4, add %o3, 2)
+ add %o0, 2, %o0
+- EX2(sth %o4, [%o1 + 0x00],#)
++ EX2(sth %o4, [%o1 + 0x00])
+ be 6f
+ add %o1, 2, %o1
+ sll %o4, 16, %o4
+-4: EX(ldub [%o0 + 0x00], %o5, add %g0, 1,#)
+- EX2(stb %o5, [%o1 + 0x00],#)
++4: EX(ldub [%o0 + 0x00], %o5, add %g0, 1)
++ EX2(stb %o5, [%o1 + 0x00])
+ sll %o5, 8, %o5
+ or %o5, %o4, %o4
+ 6: addcc %o4, %g7, %g7
+@@ -295,9 +298,9 @@
+ andcc %o0, 0x2, %g0
+ be 1f
+ andcc %o0, 0x4, %g0
+- EX(lduh [%o0 + 0x00], %g4, add %g1, 0,#)
++ EX(lduh [%o0 + 0x00], %g4, add %g1, 0)
+ sub %g1, 2, %g1
+- EX2(sth %g4, [%o1 + 0x00],#)
++ EX2(sth %g4, [%o1 + 0x00])
+ add %o0, 2, %o0
+ sll %g4, 16, %g4
+ addcc %g4, %g7, %g7
+@@ -311,9 +314,9 @@
+ or %g3, %g7, %g7
+ 1: be 3f
+ andcc %g1, 0xffffff80, %g0
+- EX(ld [%o0 + 0x00], %g4, add %g1, 0,#)
++ EX(ld [%o0 + 0x00], %g4, add %g1, 0)
+ sub %g1, 4, %g1
+- EX2(st %g4, [%o1 + 0x00],#)
++ EX2(st %g4, [%o1 + 0x00])
+ add %o0, 4, %o0
+ addcc %g4, %g7, %g7
+ add %o1, 4, %o1
+@@ -342,7 +345,7 @@
+ CSUMCOPY_BIGCHUNK(%o0,%o1,%g7,0x20,%o4,%o5,%g2,%g3,%g4,%g5,%o2,%o3)
+ CSUMCOPY_BIGCHUNK(%o0,%o1,%g7,0x40,%o4,%o5,%g2,%g3,%g4,%g5,%o2,%o3)
+ CSUMCOPY_BIGCHUNK(%o0,%o1,%g7,0x60,%o4,%o5,%g2,%g3,%g4,%g5,%o2,%o3)
+-10: EXT(5b, 10b, 20f,#) ! note for exception handling
++10: EXT(5b, 10b, 20f) ! note for exception handling
+ sub %g1, 128, %g1 ! detract from length
+ addx %g0, %g7, %g7 ! add in last carry bit
+ andcc %g1, 0xffffff80, %g0 ! more to csum?
+@@ -367,7 +370,7 @@
+ CSUMCOPY_LASTCHUNK(%o0,%o1,%g7,0x28,%g2,%g3,%g4,%g5)
+ CSUMCOPY_LASTCHUNK(%o0,%o1,%g7,0x18,%g2,%g3,%g4,%g5)
+ CSUMCOPY_LASTCHUNK(%o0,%o1,%g7,0x08,%g2,%g3,%g4,%g5)
+-12: EXT(cctbl, 12b, 22f,#) ! note for exception table handling
++12: EXT(cctbl, 12b, 22f) ! note for exception table handling
+ addx %g0, %g7, %g7
+ andcc %o3, 0xf, %g0 ! check for low bits set
+ ccte: bne cc_end_cruft ! something left, handle it out of band
+@@ -378,7 +381,7 @@
+ CSUMCOPY_BIGCHUNK_ALIGNED(%o0,%o1,%g7,0x20,%o4,%o5,%g2,%g3,%g4,%g5,%o2,%o3)
+ CSUMCOPY_BIGCHUNK_ALIGNED(%o0,%o1,%g7,0x40,%o4,%o5,%g2,%g3,%g4,%g5,%o2,%o3)
+ CSUMCOPY_BIGCHUNK_ALIGNED(%o0,%o1,%g7,0x60,%o4,%o5,%g2,%g3,%g4,%g5,%o2,%o3)
+-11: EXT(ccdbl, 11b, 21f,#) ! note for exception table handling
++11: EXT(ccdbl, 11b, 21f) ! note for exception table handling
+ sub %g1, 128, %g1 ! detract from length
+ addx %g0, %g7, %g7 ! add in last carry bit
+ andcc %g1, 0xffffff80, %g0 ! more to csum?
+@@ -395,9 +398,9 @@
+ be,a 1f
+ srl %g1, 1, %g4
+ sub %g1, 1, %g1
+- EX(ldub [%o0], %g5, add %g1, 1,#)
++ EX(ldub [%o0], %g5, add %g1, 1)
+ add %o0, 1, %o0
+- EX2(stb %g5, [%o1],#)
++ EX2(stb %g5, [%o1])
+ srl %g1, 1, %g4
+ add %o1, 1, %o1
+ 1: cmp %g4, 0
+@@ -406,34 +409,34 @@
+ andcc %o0, 2, %g0
+ be,a 1f
+ srl %g4, 1, %g4
+- EX(lduh [%o0], %o4, add %g1, 0,#)
++ EX(lduh [%o0], %o4, add %g1, 0)
+ sub %g1, 2, %g1
+ srl %o4, 8, %g2
+ sub %g4, 1, %g4
+- EX2(stb %g2, [%o1],#)
++ EX2(stb %g2, [%o1])
+ add %o4, %g5, %g5
+- EX2(stb %o4, [%o1 + 1],#)
++ EX2(stb %o4, [%o1 + 1])
+ add %o0, 2, %o0
+ srl %g4, 1, %g4
+ add %o1, 2, %o1
+ 1: cmp %g4, 0
+ be,a 2f
+ andcc %g1, 2, %g0
+- EX3(ld [%o0], %o4,#)
++ EX3(ld [%o0], %o4)
+ 5: srl %o4, 24, %g2
+ srl %o4, 16, %g3
+- EX2(stb %g2, [%o1],#)
++ EX2(stb %g2, [%o1])
+ srl %o4, 8, %g2
+- EX2(stb %g3, [%o1 + 1],#)
++ EX2(stb %g3, [%o1 + 1])
+ add %o0, 4, %o0
+- EX2(stb %g2, [%o1 + 2],#)
++ EX2(stb %g2, [%o1 + 2])
+ addcc %o4, %g5, %g5
+- EX2(stb %o4, [%o1 + 3],#)
++ EX2(stb %o4, [%o1 + 3])
+ addx %g5, %g0, %g5 ! I am now to lazy to optimize this (question it
+ add %o1, 4, %o1 ! is worthy). Maybe some day - with the sll/srl
+ subcc %g4, 1, %g4 ! tricks
+ bne,a 5b
+- EX3(ld [%o0], %o4,#)
++ EX3(ld [%o0], %o4)
+ sll %g5, 16, %g2
+ srl %g5, 16, %g5
+ srl %g2, 16, %g2
+@@ -441,19 +444,19 @@
+ add %g2, %g5, %g5
+ 2: be,a 3f
+ andcc %g1, 1, %g0
+- EX(lduh [%o0], %o4, and %g1, 3,#)
++ EX(lduh [%o0], %o4, and %g1, 3)
+ andcc %g1, 1, %g0
+ srl %o4, 8, %g2
+ add %o0, 2, %o0
+- EX2(stb %g2, [%o1],#)
++ EX2(stb %g2, [%o1])
+ add %g5, %o4, %g5
+- EX2(stb %o4, [%o1 + 1],#)
++ EX2(stb %o4, [%o1 + 1])
+ add %o1, 2, %o1
+ 3: be,a 1f
+ sll %g5, 16, %o4
+- EX(ldub [%o0], %g2, add %g0, 1,#)
++ EX(ldub [%o0], %g2, add %g0, 1)
+ sll %g2, 8, %o4
+- EX2(stb %g2, [%o1],#)
++ EX2(stb %g2, [%o1])
+ add %g5, %o4, %g5
+ sll %g5, 16, %o4
+ 1: addcc %o4, %g5, %g5
+Index: linux-2.6.0-test5/arch/sparc/lib/copy_user.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sparc/lib/copy_user.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sparc/lib/copy_user.S 2003-09-27 11:38:20.110471128 +0800
+@@ -16,41 +16,44 @@
+ #include <asm/asmmacro.h>
+ #include <asm/page.h>
+
+-#define EX(x,y,a,b,z) \
++/* Work around cpp -rob */
++#define ALLOC #alloc
++#define EXECINSTR #execinstr
++#define EX(x,y,a,b) \
+ 98: x,y; \
+- .section .fixup,z##alloc,z##execinstr; \
++ .section .fixup,ALLOC,EXECINSTR; \
+ .align 4; \
+ 99: ba fixupretl; \
+ a, b, %g3; \
+- .section __ex_table,z##alloc; \
++ .section __ex_table,ALLOC; \
+ .align 4; \
+ .word 98b, 99b; \
+ .text; \
+ .align 4
+
+-#define EX2(x,y,c,d,e,a,b,z) \
++#define EX2(x,y,c,d,e,a,b) \
+ 98: x,y; \
+- .section .fixup,z##alloc,z##execinstr; \
++ .section .fixup,ALLOC,EXECINSTR; \
+ .align 4; \
+ 99: c, d, e; \
+ ba fixupretl; \
+ a, b, %g3; \
+- .section __ex_table,z##alloc; \
++ .section __ex_table,ALLOC; \
+ .align 4; \
+ .word 98b, 99b; \
+ .text; \
+ .align 4
+
+-#define EXO2(x,y,z) \
+-98: x,##y; \
+- .section __ex_table,z##alloc; \
++#define EXO2(x,y) \
++98: x, y; \
++ .section __ex_table,ALLOC; \
+ .align 4; \
+ .word 98b, 97f; \
+ .text; \
+ .align 4
+
+-#define EXT(start,end,handler,z) \
+- .section __ex_table,z##alloc; \
++#define EXT(start,end,handler) \
++ .section __ex_table,ALLOC; \
+ .align 4; \
+ .word start, 0, end, handler; \
+ .text; \
+@@ -121,23 +124,23 @@
+ be 4f
+ andcc %o1, 2, %g0
+
+- EXO2(ldub [%o1], %g2,#)
++ EXO2(ldub [%o1], %g2)
+ add %o1, 1, %o1
+- EXO2(stb %g2, [%o0],#)
++ EXO2(stb %g2, [%o0])
+ sub %o2, 1, %o2
+ bne 3f
+ add %o0, 1, %o0
+
+- EXO2(lduh [%o1], %g2,#)
++ EXO2(lduh [%o1], %g2)
+ add %o1, 2, %o1
+- EXO2(sth %g2, [%o0],#)
++ EXO2(sth %g2, [%o0])
+ sub %o2, 2, %o2
+ b 3f
+ add %o0, 2, %o0
+ 4:
+- EXO2(lduh [%o1], %g2,#)
++ EXO2(lduh [%o1], %g2)
+ add %o1, 2, %o1
+- EXO2(sth %g2, [%o0],#)
++ EXO2(sth %g2, [%o0])
+ sub %o2, 2, %o2
+ b 3f
+ add %o0, 2, %o0
+@@ -160,9 +163,9 @@
+ be 2f
+ mov %o2, %g1
+
+- EXO2(ld [%o1], %o4,#)
++ EXO2(ld [%o1], %o4)
+ sub %g1, 4, %g1
+- EXO2(st %o4, [%o0],#)
++ EXO2(st %o4, [%o0])
+ add %o1, 4, %o1
+ add %o0, 4, %o0
+ 2:
+@@ -177,7 +180,7 @@
+ MOVE_BIGCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
+ MOVE_BIGCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
+ 80:
+- EXT(5b, 80b, 50f,#)
++ EXT(5b, 80b, 50f)
+ subcc %g7, 128, %g7
+ add %o1, 128, %o1
+ bne 5b
+@@ -204,37 +207,37 @@
+ MOVE_LASTCHUNK(o1, o0, 0x10, g2, g3, g4, g5)
+ MOVE_LASTCHUNK(o1, o0, 0x00, g2, g3, g4, g5)
+ copy_user_table_end:
+- EXT(copy_user_table, copy_user_table_end, 51f,#)
++ EXT(copy_user_table, copy_user_table_end, 51f)
+ be copy_user_last7
+ andcc %g1, 4, %g0
+
+- EX(ldd [%o1], %g2, and %g1, 0xf,#)
++ EX(ldd [%o1], %g2, and %g1, 0xf)
+ add %o0, 8, %o0
+ add %o1, 8, %o1
+- EX(st %g2, [%o0 - 0x08], and %g1, 0xf,#)
+- EX2(st %g3, [%o0 - 0x04], and %g1, 0xf, %g1, sub %g1, 4,#)
++ EX(st %g2, [%o0 - 0x08], and %g1, 0xf)
++ EX2(st %g3, [%o0 - 0x04], and %g1, 0xf, %g1, sub %g1, 4)
+ copy_user_last7:
+ be 1f
+ andcc %g1, 2, %g0
+
+- EX(ld [%o1], %g2, and %g1, 7,#)
++ EX(ld [%o1], %g2, and %g1, 7)
+ add %o1, 4, %o1
+- EX(st %g2, [%o0], and %g1, 7,#)
++ EX(st %g2, [%o0], and %g1, 7)
+ add %o0, 4, %o0
+ 1:
+ be 1f
+ andcc %g1, 1, %g0
+
+- EX(lduh [%o1], %g2, and %g1, 3,#)
++ EX(lduh [%o1], %g2, and %g1, 3)
+ add %o1, 2, %o1
+- EX(sth %g2, [%o0], and %g1, 3,#)
++ EX(sth %g2, [%o0], and %g1, 3)
+ add %o0, 2, %o0
+ 1:
+ be 1f
+ nop
+
+- EX(ldub [%o1], %g2, add %g0, 1,#)
+- EX(stb %g2, [%o0], add %g0, 1,#)
++ EX(ldub [%o1], %g2, add %g0, 1)
++ EX(stb %g2, [%o0], add %g0, 1)
+ 1:
+ retl
+ clr %o0
+@@ -245,7 +248,7 @@
+ MOVE_BIGALIGNCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
+ MOVE_BIGALIGNCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
+ 81:
+- EXT(ldd_std, 81b, 52f,#)
++ EXT(ldd_std, 81b, 52f)
+ subcc %g7, 128, %g7
+ add %o1, 128, %o1
+ bne ldd_std
+@@ -274,9 +277,9 @@
+ be 10f
+ nop
+
+- EXO2(ldub [%o1], %g2,#)
++ EXO2(ldub [%o1], %g2)
+ add %o1, 1, %o1
+- EXO2(stb %g2, [%o0],#)
++ EXO2(stb %g2, [%o0])
+ sub %o2, 1, %o2
+ andcc %o2, 0xfffffff0, %o3
+ be short_end
+@@ -285,7 +288,7 @@
+ MOVE_HALFCHUNK(o1, o0, 0x00, g2, g3, g4, g5)
+ MOVE_HALFCHUNK(o1, o0, 0x08, g2, g3, g4, g5)
+ 82:
+- EXT(10b, 82b, 53f,#)
++ EXT(10b, 82b, 53f)
+ subcc %o3, 0x10, %o3
+ add %o1, 0x10, %o1
+ bne 10b
+@@ -303,7 +306,7 @@
+ MOVE_SHORTCHUNK(o1, o0, -0x0e, g2, g3)
+ MOVE_SHORTCHUNK(o1, o0, -0x10, g2, g3)
+ 83:
+- EXT(byte_chunk, 83b, 54f,#)
++ EXT(byte_chunk, 83b, 54f)
+ subcc %o3, 0x10, %o3
+ add %o1, 0x10, %o1
+ bne byte_chunk
+@@ -328,11 +331,11 @@
+ MOVE_SHORTCHUNK(o1, o0, 0x02, g2, g3)
+ MOVE_SHORTCHUNK(o1, o0, 0x00, g2, g3)
+ short_table_end:
+- EXT(84b, short_table_end, 55f,#)
++ EXT(84b, short_table_end, 55f)
+ be 1f
+ nop
+- EX(ldub [%o1], %g2, add %g0, 1,#)
+- EX(stb %g2, [%o0], add %g0, 1,#)
++ EX(ldub [%o1], %g2, add %g0, 1)
++ EX(stb %g2, [%o0], add %g0, 1)
+ 1:
+ retl
+ clr %o0
+@@ -344,11 +347,11 @@
+ be 1f
+ andcc %o2, 4, %g0
+
+- EXO2(ld [%o1 + 0x00], %g2,#)
+- EXO2(ld [%o1 + 0x04], %g3,#)
++ EXO2(ld [%o1 + 0x00], %g2)
++ EXO2(ld [%o1 + 0x04], %g3)
+ add %o1, 8, %o1
+- EXO2(st %g2, [%o0 + 0x00],#)
+- EX(st %g3, [%o0 + 0x04], sub %o2, 4,#)
++ EXO2(st %g2, [%o0 + 0x00])
++ EX(st %g3, [%o0 + 0x04], sub %o2, 4)
+ add %o0, 8, %o0
+ 1:
+ b copy_user_last7
+Index: linux-2.6.0-test5/arch/sparc/lib/memset.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sparc/lib/memset.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sparc/lib/memset.S 2003-09-27 11:38:20.112470824 +0800
+@@ -10,20 +10,23 @@
+ #include <asm/cprefix.h>
+ #include <asm/ptrace.h>
+
+-#define EX(x,y,a,b,z) \
++/* Work around cpp -rob */
++#define ALLOC #alloc
++#define EXECINSTR #execinstr
++#define EX(x,y,a,b) \
+ 98: x,y; \
+- .section .fixup,z##alloc,z##execinstr; \
++ .section .fixup,ALLOC,EXECINSTR; \
+ .align 4; \
+ 99: ba 30f; \
+ a, b, %o0; \
+- .section __ex_table,z##alloc; \
++ .section __ex_table,ALLOC; \
+ .align 4; \
+ .word 98b, 99b; \
+ .text; \
+ .align 4
+
+-#define EXT(start,end,handler,z) \
+- .section __ex_table,z##alloc; \
++#define EXT(start,end,handler) \
++ .section __ex_table,ALLOC; \
+ .align 4; \
+ .word start, 0, end, handler; \
+ .text; \
+@@ -74,13 +77,13 @@
+ 3:
+ cmp %o2, 3
+ be 2f
+- EX(stb %g3, [%o0], sub %o1, 0,#)
++ EX(stb %g3, [%o0], sub %o1, 0)
+
+ cmp %o2, 2
+ be 2f
+- EX(stb %g3, [%o0 + 0x01], sub %o1, 1,#)
++ EX(stb %g3, [%o0 + 0x01], sub %o1, 1)
+
+- EX(stb %g3, [%o0 + 0x02], sub %o1, 2,#)
++ EX(stb %g3, [%o0 + 0x02], sub %o1, 2)
+ 2:
+ sub %o2, 4, %o2
+ add %o1, %o2, %o1
+@@ -101,7 +104,7 @@
+ be 2f
+ mov %g3, %g2
+
+- EX(st %g3, [%o0], sub %o1, 0,#)
++ EX(st %g3, [%o0], sub %o1, 0)
+ sub %o1, 4, %o1
+ add %o0, 4, %o0
+ 2:
+@@ -113,7 +116,7 @@
+ subcc %o3, 128, %o3
+ ZERO_BIG_BLOCK(%o0, 0x40, %g2)
+ 11:
+- EXT(10b, 11b, 20f,#)
++ EXT(10b, 11b, 20f)
+ bne 10b
+ add %o0, 128, %o0
+
+@@ -138,17 +141,17 @@
+ be 1f
+ andcc %o1, 2, %g0
+
+- EX(st %g3, [%o0], and %o1, 7,#)
++ EX(st %g3, [%o0], and %o1, 7)
+ add %o0, 4, %o0
+ 1:
+ be 1f
+ andcc %o1, 1, %g0
+
+- EX(sth %g3, [%o0], and %o1, 3,#)
++ EX(sth %g3, [%o0], and %o1, 3)
+ add %o0, 2, %o0
+ 1:
+ bne,a 8f
+- EX(stb %g3, [%o0], and %o1, 1,#)
++ EX(stb %g3, [%o0], and %o1, 1)
+ 8:
+ retl
+ clr %o0
+@@ -161,7 +164,7 @@
+ add %o0, 1, %o0
+ subcc %o1, 1, %o1
+ bne,a 8b
+- EX(stb %g3, [%o0 - 1], add %o1, 1,#)
++ EX(stb %g3, [%o0 - 1], add %o1, 1)
+ 0:
+ retl
+ clr %o0
+Index: linux-2.6.0-test5/arch/sparc/math-emu/sfp-util.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sparc/math-emu/sfp-util.h 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sparc/math-emu/sfp-util.h 2003-09-27 11:38:20.113470672 +0800
+@@ -4,8 +4,8 @@
+ #include <asm/byteorder.h>
+
+ #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+- __asm__ ("addcc %r4,%5,%1
+- addx %r2,%3,%0" \
++ __asm__ ("addcc %r4,%5,%1\n\t" \
++ "addx %r2,%3,%0\n" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%rJ" ((USItype)(ah)), \
+@@ -14,8 +14,8 @@
+ "rI" ((USItype)(bl)) \
+ : "cc")
+ #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+- __asm__ ("subcc %r4,%5,%1
+- subx %r2,%3,%0" \
++ __asm__ ("subcc %r4,%5,%1\n\t" \
++ "subx %r2,%3,%0\n" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "rJ" ((USItype)(ah)), \
+@@ -25,46 +25,46 @@
+ : "cc")
+
+ #define umul_ppmm(w1, w0, u, v) \
+- __asm__ ("! Inlined umul_ppmm
+- wr %%g0,%2,%%y ! SPARC has 0-3 delay insn after a wr
+- sra %3,31,%%g2 ! Don't move this insn
+- and %2,%%g2,%%g2 ! Don't move this insn
+- andcc %%g0,0,%%g1 ! Don't move this insn
+- mulscc %%g1,%3,%%g1
+- mulscc %%g1,%3,%%g1
+- mulscc %%g1,%3,%%g1
+- mulscc %%g1,%3,%%g1
+- mulscc %%g1,%3,%%g1
+- mulscc %%g1,%3,%%g1
+- mulscc %%g1,%3,%%g1
+- mulscc %%g1,%3,%%g1
+- mulscc %%g1,%3,%%g1
+- mulscc %%g1,%3,%%g1
+- mulscc %%g1,%3,%%g1
+- mulscc %%g1,%3,%%g1
+- mulscc %%g1,%3,%%g1
+- mulscc %%g1,%3,%%g1
+- mulscc %%g1,%3,%%g1
+- mulscc %%g1,%3,%%g1
+- mulscc %%g1,%3,%%g1
+- mulscc %%g1,%3,%%g1
+- mulscc %%g1,%3,%%g1
+- mulscc %%g1,%3,%%g1
+- mulscc %%g1,%3,%%g1
+- mulscc %%g1,%3,%%g1
+- mulscc %%g1,%3,%%g1
+- mulscc %%g1,%3,%%g1
+- mulscc %%g1,%3,%%g1
+- mulscc %%g1,%3,%%g1
+- mulscc %%g1,%3,%%g1
+- mulscc %%g1,%3,%%g1
+- mulscc %%g1,%3,%%g1
+- mulscc %%g1,%3,%%g1
+- mulscc %%g1,%3,%%g1
+- mulscc %%g1,%3,%%g1
+- mulscc %%g1,0,%%g1
+- add %%g1,%%g2,%0
+- rd %%y,%1" \
++ __asm__ ("! Inlined umul_ppmm\n\t" \
++ "wr %%g0,%2,%%y ! SPARC has 0-3 delay insn after a wr\n\t" \
++ "sra %3,31,%%g2 ! Don't move this insn\n\t" \
++ "and %2,%%g2,%%g2 ! Don't move this insn\n\t" \
++ "andcc %%g0,0,%%g1 ! Don't move this insn\n\t" \
++ "mulscc %%g1,%3,%%g1\n\t" \
++ "mulscc %%g1,%3,%%g1\n\t" \
++ "mulscc %%g1,%3,%%g1\n\t" \
++ "mulscc %%g1,%3,%%g1\n\t" \
++ "mulscc %%g1,%3,%%g1\n\t" \
++ "mulscc %%g1,%3,%%g1\n\t" \
++ "mulscc %%g1,%3,%%g1\n\t" \
++ "mulscc %%g1,%3,%%g1\n\t" \
++ "mulscc %%g1,%3,%%g1\n\t" \
++ "mulscc %%g1,%3,%%g1\n\t" \
++ "mulscc %%g1,%3,%%g1\n\t" \
++ "mulscc %%g1,%3,%%g1\n\t" \
++ "mulscc %%g1,%3,%%g1\n\t" \
++ "mulscc %%g1,%3,%%g1\n\t" \
++ "mulscc %%g1,%3,%%g1\n\t" \
++ "mulscc %%g1,%3,%%g1\n\t" \
++ "mulscc %%g1,%3,%%g1\n\t" \
++ "mulscc %%g1,%3,%%g1\n\t" \
++ "mulscc %%g1,%3,%%g1\n\t" \
++ "mulscc %%g1,%3,%%g1\n\t" \
++ "mulscc %%g1,%3,%%g1\n\t" \
++ "mulscc %%g1,%3,%%g1\n\t" \
++ "mulscc %%g1,%3,%%g1\n\t" \
++ "mulscc %%g1,%3,%%g1\n\t" \
++ "mulscc %%g1,%3,%%g1\n\t" \
++ "mulscc %%g1,%3,%%g1\n\t" \
++ "mulscc %%g1,%3,%%g1\n\t" \
++ "mulscc %%g1,%3,%%g1\n\t" \
++ "mulscc %%g1,%3,%%g1\n\t" \
++ "mulscc %%g1,%3,%%g1\n\t" \
++ "mulscc %%g1,%3,%%g1\n\t" \
++ "mulscc %%g1,%3,%%g1\n\t" \
++ "mulscc %%g1,0,%%g1\n\t" \
++ "add %%g1,%%g2,%0\n\t" \
++ "rd %%y,%1\n" \
+ : "=r" ((USItype)(w1)), \
+ "=r" ((USItype)(w0)) \
+ : "%rI" ((USItype)(u)), \
+@@ -74,30 +74,30 @@
+ /* It's quite necessary to add this much assembler for the sparc.
+ The default udiv_qrnnd (in C) is more than 10 times slower! */
+ #define udiv_qrnnd(q, r, n1, n0, d) \
+- __asm__ ("! Inlined udiv_qrnnd
+- mov 32,%%g1
+- subcc %1,%2,%%g0
+-1: bcs 5f
+- addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb
+- sub %1,%2,%1 ! this kills msb of n
+- addx %1,%1,%1 ! so this can't give carry
+- subcc %%g1,1,%%g1
+-2: bne 1b
+- subcc %1,%2,%%g0
+- bcs 3f
+- addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb
+- b 3f
+- sub %1,%2,%1 ! this kills msb of n
+-4: sub %1,%2,%1
+-5: addxcc %1,%1,%1
+- bcc 2b
+- subcc %%g1,1,%%g1
+-! Got carry from n. Subtract next step to cancel this carry.
+- bne 4b
+- addcc %0,%0,%0 ! shift n1n0 and a 0-bit in lsb
+- sub %1,%2,%1
+-3: xnor %0,0,%0
+- ! End of inline udiv_qrnnd" \
++ __asm__ ("! Inlined udiv_qrnnd\n\t" \
++ "mov 32,%%g1\n\t" \
++ "subcc %1,%2,%%g0\n\t" \
++ "1: bcs 5f\n\t" \
++ "addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n\t" \
++ "sub %1,%2,%1 ! this kills msb of n\n\t" \
++ "addx %1,%1,%1 ! so this can't give carry\n\t" \
++ "subcc %%g1,1,%%g1\n\t" \
++ "2: bne 1b\n\t" \
++ "subcc %1,%2,%%g0\n\t" \
++ "bcs 3f\n\t" \
++ "addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n\t" \
++ "b 3f\n\t" \
++ "sub %1,%2,%1 ! this kills msb of n\n\t" \
++ "4: sub %1,%2,%1\n\t" \
++ "5: addxcc %1,%1,%1\n\t" \
++ "bcc 2b\n\t" \
++ "subcc %%g1,1,%%g1\n\t" \
++ "! Got carry from n. Subtract next step to cancel this carry.\n\t" \
++ "bne 4b\n\t" \
++ "addcc %0,%0,%0 ! shift n1n0 and a 0-bit in lsb\n\t" \
++ "sub %1,%2,%1\n\t" \
++ "3: xnor %0,0,%0\n\t" \
++ "! End of inline udiv_qrnnd\n" \
+ : "=&r" ((USItype)(q)), \
+ "=&r" ((USItype)(r)) \
+ : "r" ((USItype)(d)), \
+Index: linux-2.6.0-test5/arch/sparc/mm/srmmu.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sparc/mm/srmmu.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sparc/mm/srmmu.c 2003-09-27 11:38:20.132467784 +0800
+@@ -330,9 +330,6 @@
+ offset = bit_map_string_get(&srmmu_nocache_map,
+ size >> SRMMU_NOCACHE_BITMAP_SHIFT,
+ align >> SRMMU_NOCACHE_BITMAP_SHIFT);
+-/* P3 */ /* printk("srmmu: get size %d align %d, got %d (0x%x)\n",
+- size >> SRMMU_NOCACHE_BITMAP_SHIFT, align >> SRMMU_NOCACHE_BITMAP_SHIFT,
+- offset, offset); */
+ if (offset == -1) {
+ printk("srmmu: out of nocache %d: %d/%d\n",
+ size, (int) srmmu_nocache_size,
+@@ -385,7 +382,6 @@
+ offset = (vaddr - SRMMU_NOCACHE_VADDR) >> SRMMU_NOCACHE_BITMAP_SHIFT;
+ size = size >> SRMMU_NOCACHE_BITMAP_SHIFT;
+
+-/* P3 */ /* printk("srmmu: free off %d (0x%x) size %d\n", offset, offset, size); */
+ bit_map_clear(&srmmu_nocache_map, offset, size);
+ }
+
+@@ -447,9 +443,6 @@
+ paddr = __pa((unsigned long)srmmu_nocache_pool);
+ vaddr = SRMMU_NOCACHE_VADDR;
+
+-/* P3 */ printk("srmmu: pool 0x%x vaddr 0x%x bitmap 0x%x bits %d (0x%x)\n",
+- (int)srmmu_nocache_pool, vaddr, srmmu_nocache_bitmap, bitmap_bits, bitmap_bits);
+-
+ while (vaddr < srmmu_nocache_end) {
+ pgd = pgd_offset_k(vaddr);
+ pmd = srmmu_pmd_offset(__nocache_fix(pgd), vaddr);
+Index: linux-2.6.0-test5/arch/um/config.release
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/config.release 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/config.release 2003-09-27 11:38:20.135467328 +0800
+@@ -228,7 +228,6 @@
+ CONFIG_EXT2_FS=y
+ CONFIG_SYSV_FS=m
+ CONFIG_UDF_FS=m
+-# CONFIG_UDF_RW is not set
+ CONFIG_UFS_FS=m
+ # CONFIG_UFS_FS_WRITE is not set
+
+Index: linux-2.6.0-test5/arch/um/defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/defconfig 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/defconfig 2003-09-27 11:38:20.138466872 +0800
+@@ -3,29 +3,19 @@
+ #
+ CONFIG_USERMODE=y
+ CONFIG_MMU=y
+-CONFIG_SWAP=y
+ CONFIG_UID16=y
+ CONFIG_RWSEM_GENERIC_SPINLOCK=y
+-CONFIG_CONFIG_LOG_BUF_SHIFT=14
+-
+-#
+-# Code maturity level options
+-#
+-CONFIG_EXPERIMENTAL=y
+
+ #
+-# General Setup
++# UML-specific options
+ #
+ CONFIG_MODE_TT=y
+ CONFIG_MODE_SKAS=y
+ CONFIG_NET=y
+-CONFIG_SYSVIPC=y
+-CONFIG_BSD_PROCESS_ACCT=y
+-CONFIG_SYSCTL=y
+-CONFIG_BINFMT_AOUT=y
+ CONFIG_BINFMT_ELF=y
+ CONFIG_BINFMT_MISC=y
+ CONFIG_HOSTFS=y
++CONFIG_HPPFS=y
+ CONFIG_MCONSOLE=y
+ CONFIG_MAGIC_SYSRQ=y
+ # CONFIG_HOST_2G_2G is not set
+@@ -38,10 +28,38 @@
+ CONFIG_KERNEL_STACK_ORDER=2
+
+ #
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_CLEAN_COMPILE=y
++CONFIG_STANDALONE=y
++CONFIG_BROKEN_ON_SMP=y
++
++#
++# General setup
++#
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_BSD_PROCESS_ACCT=y
++CONFIG_SYSCTL=y
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_IKCONFIG is not set
++# CONFIG_EMBEDDED is not set
++CONFIG_KALLSYMS=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++
++#
+ # Loadable module support
+ #
+-CONFIG_MODULES=y
+-# CONFIG_KMOD is not set
++# CONFIG_MODULES is not set
++
++#
++# Generic Driver Options
++#
+
+ #
+ # Character Devices
+@@ -69,6 +87,7 @@
+ #
+ CONFIG_BLK_DEV_UBD=y
+ # CONFIG_BLK_DEV_UBD_SYNC is not set
++CONFIG_BLK_DEV_COW_COMMON=y
+ CONFIG_BLK_DEV_LOOP=y
+ CONFIG_BLK_DEV_NBD=y
+ CONFIG_BLK_DEV_RAM=y
+@@ -78,7 +97,7 @@
+ CONFIG_NETDEVICES=y
+
+ #
+-# Network Devices
++# UML Network Devices
+ #
+ CONFIG_UML_NET=y
+ CONFIG_UML_NET_ETHERTAP=y
+@@ -88,22 +107,6 @@
+ CONFIG_UML_NET_MCAST=y
+ # CONFIG_UML_NET_PCAP is not set
+ CONFIG_UML_NET_SLIRP=y
+-CONFIG_DUMMY=y
+-# CONFIG_BONDING is not set
+-# CONFIG_EQUALIZER is not set
+-CONFIG_TUN=y
+-# CONFIG_ETHERTAP is not set
+-CONFIG_PPP=y
+-# CONFIG_PPP_MULTILINK is not set
+-# CONFIG_PPP_ASYNC is not set
+-# CONFIG_PPP_SYNC_TTY is not set
+-# CONFIG_PPP_DEFLATE is not set
+-# CONFIG_PPP_BSDCOMP is not set
+-# CONFIG_PPPOE is not set
+-CONFIG_SLIP=y
+-# CONFIG_SLIP_COMPRESSED is not set
+-# CONFIG_SLIP_SMART is not set
+-# CONFIG_SLIP_MODE_SLIP6 is not set
+
+ #
+ # Networking support
+@@ -115,8 +118,6 @@
+ 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_NET_KEY is not set
+ CONFIG_INET=y
+@@ -130,8 +131,11 @@
+ # CONFIG_SYN_COOKIES is not set
+ # CONFIG_INET_AH is not set
+ # CONFIG_INET_ESP is not set
+-# CONFIG_XFRM_USER is not set
++# CONFIG_INET_IPCOMP is not set
+ # CONFIG_IPV6 is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_NETFILTER is not set
+
+ #
+ # SCTP Configuration (EXPERIMENTAL)
+@@ -141,8 +145,6 @@
+ # CONFIG_ATM is not set
+ # CONFIG_VLAN_8021Q is not set
+ # CONFIG_LLC is not set
+-# CONFIG_DECNET is not set
+-# CONFIG_BRIDGE is not set
+ # CONFIG_X25 is not set
+ # CONFIG_LAPB is not set
+ # CONFIG_NET_DIVERT is not set
+@@ -160,6 +162,10 @@
+ # Network testing
+ #
+ # CONFIG_NET_PKTGEN is not set
++CONFIG_DUMMY=y
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++CONFIG_TUN=y
+
+ #
+ # Ethernet (10 or 100Mbit)
+@@ -171,6 +177,22 @@
+ #
+
+ #
++# Ethernet (10000 Mbit)
++#
++CONFIG_PPP=y
++# CONFIG_PPP_MULTILINK is not set
++# CONFIG_PPP_FILTER is not set
++# CONFIG_PPP_ASYNC is not set
++# CONFIG_PPP_SYNC_TTY is not set
++# CONFIG_PPP_DEFLATE is not set
++# CONFIG_PPP_BSDCOMP is not set
++# CONFIG_PPPOE is not set
++CONFIG_SLIP=y
++# CONFIG_SLIP_COMPRESSED is not set
++# CONFIG_SLIP_SMART is not set
++# CONFIG_SLIP_MODE_SLIP6 is not set
++
++#
+ # Wireless LAN (non-hamradio)
+ #
+ # CONFIG_NET_RADIO is not set
+@@ -188,66 +210,82 @@
+ #
+ # File systems
+ #
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_JBD is not set
++CONFIG_REISERFS_FS=y
++# CONFIG_REISERFS_CHECK is not set
++# CONFIG_REISERFS_PROC_INFO is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_XFS_FS is not set
++CONFIG_MINIX_FS=y
++# CONFIG_ROMFS_FS is not set
+ CONFIG_QUOTA=y
+ # CONFIG_QFMT_V1 is not set
+ # CONFIG_QFMT_V2 is not set
+ CONFIG_QUOTACTL=y
+-CONFIG_AUTOFS_FS=m
+-CONFIG_AUTOFS4_FS=m
+-CONFIG_REISERFS_FS=m
+-# CONFIG_REISERFS_CHECK is not set
+-# CONFIG_REISERFS_PROC_INFO is not set
++CONFIG_AUTOFS_FS=y
++CONFIG_AUTOFS4_FS=y
++
++#
++# CD-ROM/DVD Filesystems
++#
++CONFIG_ISO9660_FS=y
++# CONFIG_JOLIET is not set
++# CONFIG_ZISOFS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_DEVFS_FS=y
++CONFIG_DEVFS_MOUNT=y
++# CONFIG_DEVFS_DEBUG is not set
++CONFIG_DEVPTS_FS=y
++# CONFIG_DEVPTS_FS_XATTR is not set
++# CONFIG_TMPFS is not set
++CONFIG_RAMFS=y
++
++#
++# Miscellaneous filesystems
++#
+ # CONFIG_ADFS_FS is not set
+ # CONFIG_AFFS_FS is not set
+ # CONFIG_HFS_FS is not set
+ # CONFIG_BEFS_FS is not set
+ # CONFIG_BFS_FS is not set
+-# CONFIG_EXT3_FS is not set
+-# CONFIG_JBD is not set
+-CONFIG_FAT_FS=m
+-CONFIG_MSDOS_FS=m
+-CONFIG_VFAT_FS=m
+ # CONFIG_EFS_FS is not set
+ CONFIG_JFFS_FS=y
+ CONFIG_JFFS_FS_VERBOSE=0
+-CONFIG_JFFS_PROC_FS=y
+ # CONFIG_JFFS2_FS is not set
+ # CONFIG_CRAMFS is not set
+-# CONFIG_TMPFS is not set
+-CONFIG_RAMFS=y
+-CONFIG_ISO9660_FS=m
+-# CONFIG_JOLIET is not set
+-# CONFIG_ZISOFS is not set
+-# CONFIG_JFS_FS is not set
+-CONFIG_MINIX_FS=m
+ # CONFIG_VXFS_FS is not set
+-# CONFIG_NTFS_FS is not set
+ # CONFIG_HPFS_FS is not set
+-CONFIG_PROC_FS=y
+-CONFIG_DEVFS_FS=y
+-CONFIG_DEVFS_MOUNT=y
+-# CONFIG_DEVFS_DEBUG is not set
+-CONFIG_DEVPTS_FS=y
+ # CONFIG_QNX4FS_FS is not set
+-# CONFIG_ROMFS_FS is not set
+-CONFIG_EXT2_FS=y
+-# CONFIG_EXT2_FS_XATTR is not set
+ # CONFIG_SYSV_FS is not set
+-# CONFIG_UDF_FS is not set
+ # CONFIG_UFS_FS is not set
+-# CONFIG_XFS_FS is not set
+
+ #
+ # Network File Systems
+ #
+-# CONFIG_CODA_FS is not set
+-# CONFIG_INTERMEZZO_FS is not set
+ # CONFIG_NFS_FS is not set
+ # CONFIG_NFSD is not set
+ # CONFIG_EXPORTFS is not set
+-# CONFIG_CIFS is not set
+ # CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
+ # CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
+ # CONFIG_AFS_FS is not set
+
+ #
+@@ -317,28 +355,7 @@
+ #
+ # SCSI support
+ #
+-CONFIG_SCSI=y
+-CONFIG_GENERIC_ISA_DMA=y
+-
+-#
+-# SCSI support type (disk, tape, CD-ROM)
+-#
+-CONFIG_BLK_DEV_SD=y
+-CONFIG_SD_EXTRA_DEVS=40
+-CONFIG_CHR_DEV_ST=y
+-CONFIG_BLK_DEV_SR=y
+-CONFIG_BLK_DEV_SR_VENDOR=y
+-CONFIG_SR_EXTRA_DEVS=2
+-CONFIG_CHR_DEV_SG=y
+-
+-#
+-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+-#
+-CONFIG_SCSI_DEBUG_QUEUES=y
+-CONFIG_SCSI_MULTI_LUN=y
+-CONFIG_SCSI_CONSTANTS=y
+-CONFIG_SCSI_LOGGING=y
+-CONFIG_SCSI_DEBUG=y
++# CONFIG_SCSI is not set
+
+ #
+ # Multi-device support (RAID and LVM)
+@@ -360,6 +377,7 @@
+ CONFIG_MTD_BLOCK=y
+ # CONFIG_FTL is not set
+ # CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
+
+ #
+ # RAM/ROM/Flash chip drivers
+@@ -374,20 +392,21 @@
+ #
+ # Mapping drivers for chip access
+ #
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+
+ #
+ # Self-contained MTD device drivers
+ #
+ # CONFIG_MTD_SLRAM is not set
+ # CONFIG_MTD_MTDRAM is not set
+-CONFIG_MTD_BLKMTD=m
++CONFIG_MTD_BLKMTD=y
+
+ #
+ # 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_DOC2001PLUS is not set
+
+ #
+ # NAND Flash Device Drivers
+Index: linux-2.6.0-test5/arch/um/drivers/chan_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/chan_kern.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/drivers/chan_kern.c 2003-09-27 11:38:20.141466416 +0800
+@@ -8,6 +8,7 @@
+ #include <linux/list.h>
+ #include <linux/slab.h>
+ #include <linux/tty.h>
++#include <linux/string.h>
+ #include <linux/tty_flip.h>
+ #include <asm/irq.h>
+ #include "chan_kern.h"
+Index: linux-2.6.0-test5/arch/um/drivers/chan_user.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/chan_user.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/drivers/chan_user.c 2003-09-27 11:38:20.144465960 +0800
+@@ -188,8 +188,8 @@
+ if(!isatty(fd)) return;
+
+ pid = tcgetpgrp(fd);
+- if(!CHOOSE_MODE(is_tracer_winch(pid, fd, device_data), 0) &&
+- (pid == -1)){
++ if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd,
++ device_data) && (pid == -1)){
+ thread = winch_tramp(fd, device_data, &thread_fd);
+ if(fd != -1){
+ register_winch_irq(thread_fd, fd, thread, device_data);
+Index: linux-2.6.0-test5/arch/um/drivers/cow.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/cow.h 2003-09-27 11:38:18.441724816 +0800
++++ linux-2.6.0-test5/arch/um/drivers/cow.h 2003-09-27 11:38:20.144465960 +0800
+@@ -0,0 +1,40 @@
++#ifndef __COW_H__
++#define __COW_H__
++
++#include <asm/types.h>
++
++#if __BYTE_ORDER == __BIG_ENDIAN
++# define ntohll(x) (x)
++# define htonll(x) (x)
++#elif __BYTE_ORDER == __LITTLE_ENDIAN
++# define ntohll(x) bswap_64(x)
++# define htonll(x) bswap_64(x)
++#else
++#error "__BYTE_ORDER not defined"
++#endif
++
++extern int init_cow_file(int fd, char *cow_file, char *backing_file,
++ int sectorsize, int *bitmap_offset_out,
++ unsigned long *bitmap_len_out, int *data_offset_out);
++
++extern int file_reader(__u64 offset, char *buf, int len, void *arg);
++extern int read_cow_header(int (*reader)(__u64, char *, int, void *),
++ void *arg, __u32 *magic_out,
++ char **backing_file_out, time_t *mtime_out,
++ __u64 *size_out, int *sectorsize_out,
++ int *bitmap_offset_out);
++
++extern int write_cow_header(char *cow_file, int fd, char *backing_file,
++ int sectorsize, long long *size);
++
++extern void cow_sizes(__u64 size, int sectorsize, int bitmap_offset,
++ unsigned long *bitmap_len_out, int *data_offset_out);
++
++#endif
++
++/*
++ * ---------------------------------------------------------------------------
++ * Local variables:
++ * c-file-style: "linux"
++ * End:
++ */
+Index: linux-2.6.0-test5/arch/um/drivers/cow_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/cow_kern.c 2003-09-27 11:38:18.441724816 +0800
++++ linux-2.6.0-test5/arch/um/drivers/cow_kern.c 2003-09-27 11:38:20.145465808 +0800
+@@ -0,0 +1,628 @@
++#define COW_MAJOR 60
++#define MAJOR_NR COW_MAJOR
++
++#include <linux/stddef.h>
++#include <linux/kernel.h>
++#include <linux/ctype.h>
++#include <linux/stat.h>
++#include <linux/vmalloc.h>
++#include <linux/blkdev.h>
++#include <linux/blk.h>
++#include <linux/fs.h>
++#include <linux/genhd.h>
++#include <linux/devfs_fs.h>
++#include <asm/uaccess.h>
++#include "2_5compat.h"
++#include "cow.h"
++#include "ubd_user.h"
++
++#define COW_SHIFT 4
++
++struct cow {
++ int count;
++ char *cow_path;
++ dev_t cow_dev;
++ struct block_device *cow_bdev;
++ char *backing_path;
++ dev_t backing_dev;
++ struct block_device *backing_bdev;
++ int sectorsize;
++ unsigned long *bitmap;
++ unsigned long bitmap_len;
++ int bitmap_offset;
++ int data_offset;
++ devfs_handle_t devfs;
++ struct semaphore sem;
++ struct semaphore io_sem;
++ atomic_t working;
++ spinlock_t io_lock;
++ struct buffer_head *bh;
++ struct buffer_head *bhtail;
++ void *end_io;
++};
++
++#define DEFAULT_COW { \
++ .count = 0, \
++ .cow_path = NULL, \
++ .cow_dev = 0, \
++ .backing_path = NULL, \
++ .backing_dev = 0, \
++ .bitmap = NULL, \
++ .bitmap_len = 0, \
++ .bitmap_offset = 0, \
++ .data_offset = 0, \
++ .devfs = NULL, \
++ .working = ATOMIC_INIT(0), \
++ .io_lock = SPIN_LOCK_UNLOCKED, \
++}
++
++#define MAX_DEV (8)
++#define MAX_MINOR (MAX_DEV << COW_SHIFT)
++
++struct cow cow_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_COW };
++
++/* Not modified by this driver */
++static int blk_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = BLOCK_SIZE };
++static int hardsect_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 512 };
++
++/* Protected by cow_lock */
++static int sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 0 };
++
++static struct hd_struct cow_part[MAX_MINOR] =
++ { [ 0 ... MAX_MINOR - 1 ] = { 0, 0, 0 } };
++
++/* Protected by io_request_lock */
++static request_queue_t *cow_queue;
++
++static int cow_open(struct inode *inode, struct file *filp);
++static int cow_release(struct inode * inode, struct file * file);
++static int cow_ioctl(struct inode * inode, struct file * file,
++ unsigned int cmd, unsigned long arg);
++static int cow_revalidate(kdev_t rdev);
++
++static struct block_device_operations cow_blops = {
++ .open = cow_open,
++ .release = cow_release,
++ .ioctl = cow_ioctl,
++ .revalidate = cow_revalidate,
++};
++
++/* Initialized in an initcall, and unchanged thereafter */
++devfs_handle_t cow_dir_handle;
++
++#define INIT_GENDISK(maj, name, parts, shift, bsizes, max, blops) \
++{ \
++ .major = maj, \
++ .major_name = name, \
++ .minor_shift = shift, \
++ .max_p = 1 << shift, \
++ .part = parts, \
++ .sizes = bsizes, \
++ .nr_real = max, \
++ .real_devices = NULL, \
++ .next = NULL, \
++ .fops = blops, \
++ .de_arr = NULL, \
++ .flags = 0 \
++}
++
++static spinlock_t cow_lock = SPIN_LOCK_UNLOCKED;
++
++static struct gendisk cow_gendisk = INIT_GENDISK(MAJOR_NR, "cow", cow_part,
++ COW_SHIFT, sizes, MAX_DEV,
++ &cow_blops);
++
++static int cow_add(int n)
++{
++ struct cow *dev = &cow_dev[n];
++ char name[sizeof("nnnnnn\0")];
++ int err = -ENODEV;
++
++ if(dev->cow_path == NULL)
++ goto out;
++
++ sprintf(name, "%d", n);
++ dev->devfs = devfs_register(cow_dir_handle, name, DEVFS_FL_REMOVABLE,
++ MAJOR_NR, n << COW_SHIFT, S_IFBLK |
++ S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
++ &cow_blops, NULL);
++
++ init_MUTEX_LOCKED(&dev->sem);
++ init_MUTEX(&dev->io_sem);
++
++ return(0);
++
++out:
++ return(err);
++}
++
++/*
++* Add buffer_head to back of pending list
++*/
++static void cow_add_bh(struct cow *cow, struct buffer_head *bh)
++{
++ unsigned long flags;
++
++ spin_lock_irqsave(&cow->io_lock, flags);
++ if(cow->bhtail != NULL){
++ cow->bhtail->b_reqnext = bh;
++ cow->bhtail = bh;
++ }
++ else {
++ cow->bh = bh;
++ cow->bhtail = bh;
++ }
++ spin_unlock_irqrestore(&cow->io_lock, flags);
++}
++
++/*
++* Grab first pending buffer
++*/
++static struct buffer_head *cow_get_bh(struct cow *cow)
++{
++ struct buffer_head *bh;
++
++ spin_lock_irq(&cow->io_lock);
++ bh = cow->bh;
++ if(bh != NULL){
++ if(bh == cow->bhtail)
++ cow->bhtail = NULL;
++ cow->bh = bh->b_reqnext;
++ bh->b_reqnext = NULL;
++ }
++ spin_unlock_irq(&cow->io_lock);
++
++ return(bh);
++}
++
++static void cow_handle_bh(struct cow *cow, struct buffer_head *bh,
++ struct buffer_head **cow_bh, int ncow_bh)
++{
++ int i;
++
++ if(ncow_bh > 0)
++ ll_rw_block(WRITE, ncow_bh, cow_bh);
++
++ for(i = 0; i < ncow_bh ; i++){
++ wait_on_buffer(cow_bh[i]);
++ brelse(cow_bh[i]);
++ }
++
++ ll_rw_block(WRITE, 1, &bh);
++ brelse(bh);
++}
++
++static struct buffer_head *cow_new_bh(struct cow *dev, int sector)
++{
++ struct buffer_head *bh;
++
++ sector = (dev->bitmap_offset + sector / 8) / dev->sectorsize;
++ bh = getblk(dev->cow_dev, sector, dev->sectorsize);
++ memcpy(bh->b_data, dev->bitmap + sector / (8 * sizeof(dev->bitmap[0])),
++ dev->sectorsize);
++ return(bh);
++}
++
++/* Copied from loop.c, needed to avoid deadlocking in make_request. */
++
++static int cow_thread(void *data)
++{
++ struct cow *dev = data;
++ struct buffer_head *bh;
++
++ daemonize();
++ exit_files(current);
++
++ sprintf(current->comm, "cow%d", dev - cow_dev);
++
++ spin_lock_irq(¤t->sigmask_lock);
++ sigfillset(¤t->blocked);
++ flush_signals(current);
++ spin_unlock_irq(¤t->sigmask_lock);
++
++ atomic_inc(&dev->working);
++
++ current->policy = SCHED_OTHER;
++ current->nice = -20;
++
++ current->flags |= PF_NOIO;
++
++ /*
++ * up sem, we are running
++ */
++ up(&dev->sem);
++
++ for(;;){
++ int start, len, nbh, i, update_bitmap = 0;
++ struct buffer_head *cow_bh[2];
++
++ down_interruptible(&dev->io_sem);
++ /*
++ * could be upped because of tear-down, not because of
++ * pending work
++ */
++ if(!atomic_read(&dev->working))
++ break;
++
++ bh = cow_get_bh(dev);
++ if(bh == NULL){
++ printk(KERN_ERR "cow: missing bh\n");
++ continue;
++ }
++
++ start = bh->b_blocknr * bh->b_size / dev->sectorsize;
++ len = bh->b_size / dev->sectorsize;
++ for(i = 0; i < len ; i++){
++ if(ubd_test_bit(start +ni,
++ (unsigned char *) dev->bitmap))
++ continue;
++
++ update_bitmap = 1;
++ ubd_set_bit(start + i, (unsigned char *) dev->bitmap);
++ }
++
++ cow_bh[0] = NULL;
++ cow_bh[1] = NULL;
++ nbh = 0;
++ if(update_bitmap){
++ cow_bh[0] = cow_new_bh(dev, start);
++ nbh++;
++ if(start / dev->sectorsize !=
++ (start + len) / dev->sectorsize){
++ cow_bh[1] = cow_new_bh(dev, start + len);
++ nbh++;
++ }
++ }
++
++ bh->b_dev = dev->cow_dev;
++ bh->b_blocknr += dev->data_offset / dev->sectorsize;
++
++ cow_handle_bh(dev, bh, cow_bh, nbh);
++
++ /*
++ * upped both for pending work and tear-down, lo_pending
++ * will hit zero then
++ */
++ if(atomic_dec_and_test(&dev->working))
++ break;
++ }
++
++ up(&dev->sem);
++ return(0);
++}
++
++static int cow_make_request(request_queue_t *q, int rw, struct buffer_head *bh)
++{
++ struct cow *dev;
++ int n, minor;
++
++ minor = MINOR(bh->b_rdev);
++ n = minor >> COW_SHIFT;
++ dev = &cow_dev[n];
++
++ dev->end_io = NULL;
++ if(ubd_test_bit(bh->b_rsector, (unsigned char *) dev->bitmap)){
++ bh->b_rdev = dev->cow_dev;
++ bh->b_rsector += dev->data_offset / dev->sectorsize;
++ }
++ else if(rw == WRITE){
++ bh->b_dev = dev->cow_dev;
++ bh->b_blocknr += dev->data_offset / dev->sectorsize;
++
++ cow_add_bh(dev, bh);
++ up(&dev->io_sem);
++ return(0);
++ }
++ else {
++ bh->b_rdev = dev->backing_dev;
++ }
++
++ return(1);
++}
++
++int cow_init(void)
++{
++ int i;
++
++ cow_dir_handle = devfs_mk_dir (NULL, "cow", NULL);
++ if (devfs_register_blkdev(MAJOR_NR, "cow", &cow_blops)) {
++ printk(KERN_ERR "cow: unable to get major %d\n", MAJOR_NR);
++ return -1;
++ }
++ read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB) read-ahead */
++ blksize_size[MAJOR_NR] = blk_sizes;
++ blk_size[MAJOR_NR] = sizes;
++ INIT_HARDSECT(hardsect_size, MAJOR_NR, hardsect_sizes);
++
++ cow_queue = BLK_DEFAULT_QUEUE(MAJOR_NR);
++ blk_init_queue(cow_queue, NULL);
++ INIT_ELV(cow_queue, &cow_queue->elevator);
++ blk_queue_make_request(cow_queue, cow_make_request);
++
++ add_gendisk(&cow_gendisk);
++
++ for(i=0;i<MAX_DEV;i++)
++ cow_add(i);
++
++ return(0);
++}
++
++__initcall(cow_init);
++
++static int reader(__u64 start, char *buf, int count, void *arg)
++{
++ dev_t dev = *((dev_t *) arg);
++ struct buffer_head *bh;
++ __u64 block;
++ int cur, offset, left, n, blocksize = get_hardsect_size(dev);
++
++ if(blocksize == 0)
++ panic("Zero blocksize");
++
++ block = start / blocksize;
++ offset = start % blocksize;
++ left = count;
++ cur = 0;
++ while(left > 0){
++ n = (left > blocksize) ? blocksize : left;
++
++ bh = bread(dev, block, (n < 512) ? 512 : n);
++ if(bh == NULL)
++ return(-EIO);
++
++ n -= offset;
++ memcpy(&buf[cur], bh->b_data + offset, n);
++ block++;
++ left -= n;
++ cur += n;
++ offset = 0;
++ brelse(bh);
++ }
++
++ return(count);
++}
++
++static int cow_open(struct inode *inode, struct file *filp)
++{
++ int (*dev_ioctl)(struct inode *, struct file *, unsigned int,
++ unsigned long);
++ mm_segment_t fs;
++ struct cow *dev;
++ __u64 size;
++ __u32 magic;
++ time_t mtime;
++ char *backing_file;
++ int n, offset, err = 0;
++
++ n = DEVICE_NR(inode->i_rdev);
++ if(n >= MAX_DEV)
++ return(-ENODEV);
++ dev = &cow_dev[n];
++ offset = n << COW_SHIFT;
++
++ spin_lock(&cow_lock);
++
++ if(dev->count == 0){
++ dev->cow_dev = name_to_kdev_t(dev->cow_path);
++ if(dev->cow_dev == 0){
++ printk(KERN_ERR "cow_open - name_to_kdev_t(\"%s\") "
++ "failed\n", dev->cow_path);
++ err = -ENODEV;
++ }
++
++ dev->backing_dev = name_to_kdev_t(dev->backing_path);
++ if(dev->backing_dev == 0){
++ printk(KERN_ERR "cow_open - name_to_kdev_t(\"%s\") "
++ "failed\n", dev->backing_path);
++ err = -ENODEV;
++ }
++
++ if(err)
++ goto out;
++
++ dev->cow_bdev = bdget(dev->cow_dev);
++ if(dev->cow_bdev == NULL){
++ printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n",
++ dev->cow_path);
++ err = -ENOMEM;
++ }
++ dev->backing_bdev = bdget(dev->backing_dev);
++ if(dev->backing_bdev == NULL){
++ printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n",
++ dev->backing_path);
++ err = -ENOMEM;
++ }
++
++ if(err)
++ goto out;
++
++ err = blkdev_get(dev->cow_bdev, FMODE_READ|FMODE_WRITE, 0,
++ BDEV_RAW);
++ if(err){
++ printk("cow_open - blkdev_get of COW device failed, "
++ "error = %d\n", err);
++ goto out;
++ }
++
++ err = blkdev_get(dev->backing_bdev, FMODE_READ, 0, BDEV_RAW);
++ if(err){
++ printk("cow_open - blkdev_get of backing device "
++ "failed, error = %d\n", err);
++ goto out;
++ }
++
++ err = read_cow_header(reader, &dev->cow_dev, &magic,
++ &backing_file, &mtime, &size,
++ &dev->sectorsize, &dev->bitmap_offset);
++ if(err){
++ printk(KERN_ERR "cow_open - read_cow_header failed, "
++ "err = %d\n", err);
++ goto out;
++ }
++
++ cow_sizes(size, dev->sectorsize, dev->bitmap_offset,
++ &dev->bitmap_len, &dev->data_offset);
++ dev->bitmap = (void *) vmalloc(dev->bitmap_len);
++ if(dev->bitmap == NULL){
++ err = -ENOMEM;
++ printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
++ goto out;
++ }
++ flush_tlb_kernel_vm();
++
++ err = reader(dev->bitmap_offset, (char *) dev->bitmap,
++ dev->bitmap_len, &dev->cow_dev);
++ if(err < 0){
++ printk(KERN_ERR "Failed to read COW bitmap\n");
++ vfree(dev->bitmap);
++ goto out;
++ }
++
++ dev_ioctl = dev->backing_bdev->bd_op->ioctl;
++ fs = get_fs();
++ set_fs(KERNEL_DS);
++ err = (*dev_ioctl)(inode, filp, BLKGETSIZE,
++ (unsigned long) &sizes[offset]);
++ set_fs(fs);
++ if(err){
++ printk(KERN_ERR "cow_open - BLKGETSIZE failed, "
++ "error = %d\n", err);
++ goto out;
++ }
++
++ kernel_thread(cow_thread, dev,
++ CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++ down(&dev->sem);
++ }
++ dev->count++;
++out:
++ spin_unlock(&cow_lock);
++ return(err);
++}
++
++static int cow_release(struct inode * inode, struct file * file)
++{
++ struct cow *dev;
++ int n, err;
++
++ n = DEVICE_NR(inode->i_rdev);
++ if(n >= MAX_DEV)
++ return(-ENODEV);
++ dev = &cow_dev[n];
++
++ spin_lock(&cow_lock);
++
++ if(--dev->count > 0)
++ goto out;
++
++ err = blkdev_put(dev->cow_bdev, BDEV_RAW);
++ if(err)
++ printk("cow_release - blkdev_put of cow device failed, "
++ "error = %d\n", err);
++ bdput(dev->cow_bdev);
++ dev->cow_bdev = 0;
++
++ err = blkdev_put(dev->backing_bdev, BDEV_RAW);
++ if(err)
++ printk("cow_release - blkdev_put of backing device failed, "
++ "error = %d\n", err);
++ bdput(dev->backing_bdev);
++ dev->backing_bdev = 0;
++
++out:
++ spin_unlock(&cow_lock);
++ return(0);
++}
++
++static int cow_ioctl(struct inode * inode, struct file * file,
++ unsigned int cmd, unsigned long arg)
++{
++ struct cow *dev;
++ int (*dev_ioctl)(struct inode *, struct file *, unsigned int,
++ unsigned long);
++ int n;
++
++ n = DEVICE_NR(inode->i_rdev);
++ if(n >= MAX_DEV)
++ return(-ENODEV);
++ dev = &cow_dev[n];
++
++ dev_ioctl = dev->backing_bdev->bd_op->ioctl;
++ return((*dev_ioctl)(inode, file, cmd, arg));
++}
++
++static int cow_revalidate(kdev_t rdev)
++{
++ printk(KERN_ERR "Need to implement cow_revalidate\n");
++ return(0);
++}
++
++static int parse_unit(char **ptr)
++{
++ char *str = *ptr, *end;
++ int n = -1;
++
++ if(isdigit(*str)) {
++ n = simple_strtoul(str, &end, 0);
++ if(end == str)
++ return(-1);
++ *ptr = end;
++ }
++ else if (('a' <= *str) && (*str <= 'h')) {
++ n = *str - 'a';
++ str++;
++ *ptr = str;
++ }
++ return(n);
++}
++
++static int cow_setup(char *str)
++{
++ struct cow *dev;
++ char *cow_name, *backing_name;
++ int unit;
++
++ unit = parse_unit(&str);
++ if(unit < 0){
++ printk(KERN_ERR "cow_setup - Couldn't parse unit number\n");
++ return(1);
++ }
++
++ if(*str != '='){
++ printk(KERN_ERR "cow_setup - Missing '=' after unit "
++ "number\n");
++ return(1);
++ }
++ str++;
++
++ cow_name = str;
++ backing_name = strchr(str, ',');
++ if(backing_name == NULL){
++ printk(KERN_ERR "cow_setup - missing backing device name\n");
++ return(0);
++ }
++ *backing_name = '\0';
++ backing_name++;
++
++ spin_lock(&cow_lock);
++
++ dev = &cow_dev[unit];
++ dev->cow_path = cow_name;
++ dev->backing_path = backing_name;
++
++ spin_unlock(&cow_lock);
++ return(0);
++}
++
++__setup("cow", cow_setup);
++
++/*
++ * Overrides for Emacs so that we follow Linus's tabbing style.
++ * Emacs will notice this stuff at the end of the file and automatically
++ * adjust the settings for this buffer only. This must remain at the end
++ * of the file.
++ * ---------------------------------------------------------------------------
++ * Local variables:
++ * c-file-style: "linux"
++ * End:
++ */
+Index: linux-2.6.0-test5/arch/um/drivers/cow_sys.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/cow_sys.h 2003-09-27 11:38:18.441724816 +0800
++++ linux-2.6.0-test5/arch/um/drivers/cow_sys.h 2003-09-27 11:38:20.146465656 +0800
+@@ -0,0 +1,48 @@
++#ifndef __COW_SYS_H__
++#define __COW_SYS_H__
++
++#include "kern_util.h"
++#include "user_util.h"
++#include "os.h"
++#include "user.h"
++
++static inline void *cow_malloc(int size)
++{
++ return(um_kmalloc(size));
++}
++
++static inline void cow_free(void *ptr)
++{
++ kfree(ptr);
++}
++
++#define cow_printf printk
++
++static inline char *cow_strdup(char *str)
++{
++ return(uml_strdup(str));
++}
++
++static inline int cow_seek_file(int fd, __u64 offset)
++{
++ return(os_seek_file(fd, offset));
++}
++
++static inline int cow_file_size(char *file, __u64 *size_out)
++{
++ return(os_file_size(file, size_out));
++}
++
++static inline int cow_write_file(int fd, char *buf, int size)
++{
++ return(os_write_file(fd, buf, size));
++}
++
++#endif
++
++/*
++ * ---------------------------------------------------------------------------
++ * Local variables:
++ * c-file-style: "linux"
++ * End:
++ */
+Index: linux-2.6.0-test5/arch/um/drivers/cow_user.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/cow_user.c 2003-09-27 11:38:18.441724816 +0800
++++ linux-2.6.0-test5/arch/um/drivers/cow_user.c 2003-09-27 11:38:20.147465504 +0800
+@@ -0,0 +1,296 @@
++#include <stddef.h>
++#include <string.h>
++#include <errno.h>
++#include <unistd.h>
++#include <byteswap.h>
++#include <sys/stat.h>
++#include <sys/time.h>
++#include <sys/param.h>
++#include <netinet/in.h>
++
++#include "cow.h"
++#include "cow_sys.h"
++
++#define PATH_LEN_V1 256
++
++struct cow_header_v1 {
++ int magic;
++ int version;
++ char backing_file[PATH_LEN_V1];
++ time_t mtime;
++ __u64 size;
++ int sectorsize;
++};
++
++#define PATH_LEN_V2 MAXPATHLEN
++
++struct cow_header_v2 {
++ unsigned long magic;
++ unsigned long version;
++ char backing_file[PATH_LEN_V2];
++ time_t mtime;
++ __u64 size;
++ int sectorsize;
++};
++
++union cow_header {
++ struct cow_header_v1 v1;
++ struct cow_header_v2 v2;
++};
++
++#define COW_MAGIC 0x4f4f4f4d /* MOOO */
++#define COW_VERSION 2
++
++void cow_sizes(__u64 size, int sectorsize, int bitmap_offset,
++ unsigned long *bitmap_len_out, int *data_offset_out)
++{
++ *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
++
++ *data_offset_out = bitmap_offset + *bitmap_len_out;
++ *data_offset_out = (*data_offset_out + sectorsize - 1) / sectorsize;
++ *data_offset_out *= sectorsize;
++}
++
++static int absolutize(char *to, int size, char *from)
++{
++ char save_cwd[256], *slash;
++ int remaining;
++
++ if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
++ cow_printf("absolutize : unable to get cwd - errno = %d\n",
++ errno);
++ return(-1);
++ }
++ slash = strrchr(from, '/');
++ if(slash != NULL){
++ *slash = '\0';
++ if(chdir(from)){
++ *slash = '/';
++ cow_printf("absolutize : Can't cd to '%s' - "
++ "errno = %d\n", from, errno);
++ return(-1);
++ }
++ *slash = '/';
++ if(getcwd(to, size) == NULL){
++ cow_printf("absolutize : unable to get cwd of '%s' - "
++ "errno = %d\n", from, errno);
++ return(-1);
++ }
++ remaining = size - strlen(to);
++ if(strlen(slash) + 1 > remaining){
++ cow_printf("absolutize : unable to fit '%s' into %d "
++ "chars\n", from, size);
++ return(-1);
++ }
++ strcat(to, slash);
++ }
++ else {
++ if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){
++ cow_printf("absolutize : unable to fit '%s' into %d "
++ "chars\n", from, size);
++ return(-1);
++ }
++ strcpy(to, save_cwd);
++ strcat(to, "/");
++ strcat(to, from);
++ }
++ chdir(save_cwd);
++ return(0);
++}
++
++int write_cow_header(char *cow_file, int fd, char *backing_file,
++ int sectorsize, long long *size)
++{
++ struct cow_header_v2 *header;
++ struct stat64 buf;
++ int err;
++
++ err = cow_seek_file(fd, 0);
++ if(err != 0){
++ cow_printf("write_cow_header - lseek failed, errno = %d\n",
++ errno);
++ return(-errno);
++ }
++
++ err = -ENOMEM;
++ header = cow_malloc(sizeof(*header));
++ if(header == NULL){
++ cow_printf("Failed to allocate COW V2 header\n");
++ goto out;
++ }
++ header->magic = htonl(COW_MAGIC);
++ header->version = htonl(COW_VERSION);
++
++ err = -EINVAL;
++ if(strlen(backing_file) > sizeof(header->backing_file) - 1){
++ cow_printf("Backing file name \"%s\" is too long - names are "
++ "limited to %d characters\n", backing_file,
++ sizeof(header->backing_file) - 1);
++ goto out_free;
++ }
++
++ if(absolutize(header->backing_file, sizeof(header->backing_file),
++ backing_file))
++ goto out_free;
++
++ err = stat64(header->backing_file, &buf);
++ if(err < 0){
++ cow_printf("Stat of backing file '%s' failed, errno = %d\n",
++ header->backing_file, errno);
++ err = -errno;
++ goto out_free;
++ }
++
++ err = cow_file_size(header->backing_file, size);
++ if(err){
++ cow_printf("Couldn't get size of backing file '%s', "
++ "errno = %d\n", header->backing_file, -*size);
++ goto out_free;
++ }
++
++ header->mtime = htonl(buf.st_mtime);
++ header->size = htonll(*size);
++ header->sectorsize = htonl(sectorsize);
++
++ err = write(fd, header, sizeof(*header));
++ if(err != sizeof(*header)){
++ cow_printf("Write of header to new COW file '%s' failed, "
++ "errno = %d\n", cow_file, errno);
++ goto out_free;
++ }
++ err = 0;
++ out_free:
++ cow_free(header);
++ out:
++ return(err);
++}
++
++int file_reader(__u64 offset, char *buf, int len, void *arg)
++{
++ int fd = *((int *) arg);
++
++ return(pread(fd, buf, len, offset));
++}
++
++int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
++ __u32 *magic_out, char **backing_file_out,
++ time_t *mtime_out, __u64 *size_out,
++ int *sectorsize_out, int *bitmap_offset_out)
++{
++ union cow_header *header;
++ char *file;
++ int err, n;
++ unsigned long version, magic;
++
++ header = cow_malloc(sizeof(*header));
++ if(header == NULL){
++ cow_printf("read_cow_header - Failed to allocate header\n");
++ return(-ENOMEM);
++ }
++ err = -EINVAL;
++ n = (*reader)(0, (char *) header, sizeof(*header), arg);
++ if(n < offsetof(typeof(header->v1), backing_file)){
++ cow_printf("read_cow_header - short header\n");
++ goto out;
++ }
++
++ magic = header->v1.magic;
++ if(magic == COW_MAGIC) {
++ version = header->v1.version;
++ }
++ else if(magic == ntohl(COW_MAGIC)){
++ version = ntohl(header->v1.version);
++ }
++ /* No error printed because the non-COW case comes through here */
++ else goto out;
++
++ *magic_out = COW_MAGIC;
++
++ if(version == 1){
++ if(n < sizeof(header->v1)){
++ cow_printf("read_cow_header - failed to read V1 "
++ "header\n");
++ goto out;
++ }
++ *mtime_out = header->v1.mtime;
++ *size_out = header->v1.size;
++ *sectorsize_out = header->v1.sectorsize;
++ *bitmap_offset_out = sizeof(header->v1);
++ file = header->v1.backing_file;
++ }
++ else if(version == 2){
++ if(n < sizeof(header->v2)){
++ cow_printf("read_cow_header - failed to read V2 "
++ "header\n");
++ goto out;
++ }
++ *mtime_out = ntohl(header->v2.mtime);
++ *size_out = ntohll(header->v2.size);
++ *sectorsize_out = ntohl(header->v2.sectorsize);
++ *bitmap_offset_out = sizeof(header->v2);
++ file = header->v2.backing_file;
++ }
++ else {
++ cow_printf("read_cow_header - invalid COW version\n");
++ goto out;
++ }
++ err = -ENOMEM;
++ *backing_file_out = cow_strdup(file);
++ if(*backing_file_out == NULL){
++ cow_printf("read_cow_header - failed to allocate backing "
++ "file\n");
++ goto out;
++ }
++ err = 0;
++ out:
++ cow_free(header);
++ return(err);
++}
++
++int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize,
++ int *bitmap_offset_out, unsigned long *bitmap_len_out,
++ int *data_offset_out)
++{
++ __u64 size, offset;
++ char zero = 0;
++ int err;
++
++ err = write_cow_header(cow_file, fd, backing_file, sectorsize, &size);
++ if(err)
++ goto out;
++
++ cow_sizes(size, sectorsize, sizeof(struct cow_header_v2),
++ bitmap_len_out, data_offset_out);
++ *bitmap_offset_out = sizeof(struct cow_header_v2);
++
++ offset = *data_offset_out + size - sizeof(zero);
++ err = cow_seek_file(fd, offset);
++ if(err != 0){
++ cow_printf("cow bitmap lseek failed : errno = %d\n", errno);
++ goto out;
++ }
++
++ /* does not really matter how much we write it is just to set EOF
++ * this also sets the entire COW bitmap
++ * to zero without having to allocate it
++ */
++ err = cow_write_file(fd, &zero, sizeof(zero));
++ if(err != sizeof(zero)){
++ err = -EINVAL;
++ cow_printf("Write of bitmap to new COW file '%s' failed, "
++ "errno = %d\n", cow_file, errno);
++ goto out;
++ }
++
++ return(0);
++
++ out:
++ return(err);
++}
++
++/*
++ * ---------------------------------------------------------------------------
++ * Local variables:
++ * c-file-style: "linux"
++ * End:
++ */
+Index: linux-2.6.0-test5/arch/um/drivers/hostaudio_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/hostaudio_kern.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/drivers/hostaudio_kern.c 2003-09-27 11:38:20.149465200 +0800
+@@ -11,6 +11,7 @@
+ #include "linux/fs.h"
+ #include "linux/sound.h"
+ #include "linux/soundcard.h"
++#include "asm/uaccess.h"
+ #include "kern_util.h"
+ #include "init.h"
+ #include "hostaudio.h"
+@@ -22,7 +23,7 @@
+ #ifndef MODULE
+ static int set_dsp(char *name, int *add)
+ {
+- dsp = uml_strdup(name);
++ dsp = name;
+ return(0);
+ }
+
+@@ -34,7 +35,7 @@
+
+ static int set_mixer(char *name, int *add)
+ {
+- mixer = uml_strdup(name);
++ mixer = name;
+ return(0);
+ }
+
+@@ -51,23 +52,55 @@
+ loff_t *ppos)
+ {
+ struct hostaudio_state *state = file->private_data;
++ void *kbuf;
++ int err;
+
+ #ifdef DEBUG
+ printk("hostaudio: read called, count = %d\n", count);
+ #endif
+
+- return(hostaudio_read_user(state, buffer, count, ppos));
++ kbuf = kmalloc(count, GFP_KERNEL);
++ if(kbuf == NULL)
++ return(-ENOMEM);
++
++ err = hostaudio_read_user(state, kbuf, count, ppos);
++ if(err < 0)
++ goto out;
++
++ if(copy_to_user(buffer, kbuf, err))
++ err = -EFAULT;
++
++ out:
++ kfree(kbuf);
++ return(err);
+ }
+
+ static ssize_t hostaudio_write(struct file *file, const char *buffer,
+ size_t count, loff_t *ppos)
+ {
+ struct hostaudio_state *state = file->private_data;
++ void *kbuf;
++ int err;
+
+ #ifdef DEBUG
+ printk("hostaudio: write called, count = %d\n", count);
+ #endif
+- return(hostaudio_write_user(state, buffer, count, ppos));
++
++ kbuf = kmalloc(count, GFP_KERNEL);
++ if(kbuf == NULL)
++ return(-ENOMEM);
++
++ err = -EFAULT;
++ if(copy_from_user(kbuf, buffer, count))
++ goto out;
++
++ err = hostaudio_write_user(state, kbuf, count, ppos);
++ if(err < 0)
++ goto out;
++
++ out:
++ kfree(kbuf);
++ return(err);
+ }
+
+ static unsigned int hostaudio_poll(struct file *file,
+@@ -86,12 +119,43 @@
+ unsigned int cmd, unsigned long arg)
+ {
+ struct hostaudio_state *state = file->private_data;
++ unsigned long data = 0;
++ int err;
+
+ #ifdef DEBUG
+ printk("hostaudio: ioctl called, cmd = %u\n", cmd);
+ #endif
++ switch(cmd){
++ case SNDCTL_DSP_SPEED:
++ case SNDCTL_DSP_STEREO:
++ case SNDCTL_DSP_GETBLKSIZE:
++ case SNDCTL_DSP_CHANNELS:
++ case SNDCTL_DSP_SUBDIVIDE:
++ case SNDCTL_DSP_SETFRAGMENT:
++ if(get_user(data, (int *) arg))
++ return(-EFAULT);
++ break;
++ default:
++ break;
++ }
++
++ err = hostaudio_ioctl_user(state, cmd, (unsigned long) &data);
++
++ switch(cmd){
++ case SNDCTL_DSP_SPEED:
++ case SNDCTL_DSP_STEREO:
++ case SNDCTL_DSP_GETBLKSIZE:
++ case SNDCTL_DSP_CHANNELS:
++ case SNDCTL_DSP_SUBDIVIDE:
++ case SNDCTL_DSP_SETFRAGMENT:
++ if(put_user(data, (int *) arg))
++ return(-EFAULT);
++ break;
++ default:
++ break;
++ }
+
+- return(hostaudio_ioctl_user(state, cmd, arg));
++ return(err);
+ }
+
+ static int hostaudio_open(struct inode *inode, struct file *file)
+@@ -225,7 +289,8 @@
+
+ static int __init hostaudio_init_module(void)
+ {
+- printk(KERN_INFO "UML Audio Relay\n");
++ printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n",
++ dsp, mixer);
+
+ module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1);
+ if(module_data.dev_audio < 0){
+Index: linux-2.6.0-test5/arch/um/drivers/line.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/line.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/drivers/line.c 2003-09-27 11:38:20.154464440 +0800
+@@ -6,8 +6,8 @@
+ #include "linux/sched.h"
+ #include "linux/slab.h"
+ #include "linux/list.h"
++#include "linux/interrupt.h"
+ #include "linux/devfs_fs_kernel.h"
+-#include "asm/irq.h"
+ #include "asm/uaccess.h"
+ #include "chan_kern.h"
+ #include "irq_user.h"
+@@ -16,16 +16,18 @@
+ #include "user_util.h"
+ #include "kern_util.h"
+ #include "os.h"
++#include "irq_kern.h"
+
+ #define LINE_BUFSIZE 4096
+
+-void line_interrupt(int irq, void *data, struct pt_regs *unused)
++irqreturn_t line_interrupt(int irq, void *data, struct pt_regs *unused)
+ {
+ struct line *dev = data;
+
+ if(dev->count > 0)
+ chan_interrupt(&dev->chan_list, &dev->task, dev->tty, irq,
+ dev);
++ return IRQ_HANDLED;
+ }
+
+ void line_timer_cb(void *arg)
+@@ -136,20 +138,22 @@
+ return(len);
+ }
+
+-void line_write_interrupt(int irq, void *data, struct pt_regs *unused)
++irqreturn_t line_write_interrupt(int irq, void *data, struct pt_regs *unused)
+ {
+ struct line *dev = data;
+ struct tty_struct *tty = dev->tty;
+ int err;
+
+ err = flush_buffer(dev);
+- if(err == 0) return;
++ if(err == 0)
++ return(IRQ_NONE);
+ else if(err < 0){
+ dev->head = dev->buffer;
+ dev->tail = dev->buffer;
+ }
+
+- if(tty == NULL) return;
++ if(tty == NULL)
++ return(IRQ_NONE);
+
+ if(test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&
+ (tty->ldisc.write_wakeup != NULL))
+@@ -161,9 +165,9 @@
+ * writes.
+ */
+
+- if (waitqueue_active(&tty->write_wait))
++ if(waitqueue_active(&tty->write_wait))
+ wake_up_interruptible(&tty->write_wait);
+-
++ return(IRQ_HANDLED);
+ }
+
+ int line_write_room(struct tty_struct *tty)
+@@ -369,7 +373,7 @@
+
+ dev = simple_strtoul(name, &end, 0);
+ if((*end != '\0') || (end == name)){
+- *error_out = "line_setup failed to parse device number";
++ *error_out = "line_get_config failed to parse device number";
+ return(0);
+ }
+
+@@ -379,15 +383,15 @@
+ }
+
+ line = &lines[dev];
++
+ down(&line->sem);
+-
+ if(!line->valid)
+ CONFIG_CHUNK(str, size, n, "none", 1);
+ else if(line->count == 0)
+ CONFIG_CHUNK(str, size, n, line->init_str, 1);
+ else n = chan_config_string(&line->chan_list, str, size, error_out);
+-
+ up(&line->sem);
++
+ return(n);
+ }
+
+@@ -412,7 +416,8 @@
+ return NULL;
+
+ driver->driver_name = line_driver->name;
+- driver->name = line_driver->devfs_name;
++ driver->name = line_driver->device_name;
++ driver->devfs_name = line_driver->devfs_name;
+ driver->major = line_driver->major;
+ driver->minor_start = line_driver->minor_start;
+ driver->type = line_driver->type;
+@@ -432,7 +437,7 @@
+
+ for(i = 0; i < nlines; i++){
+ if(!lines[i].valid)
+- tty_unregister_devfs(driver, i);
++ tty_unregister_device(driver, i);
+ }
+
+ mconsole_register_dev(&line_driver->mc);
+@@ -465,24 +470,25 @@
+ struct line *line;
+ };
+
+-void winch_interrupt(int irq, void *data, struct pt_regs *unused)
++irqreturn_t winch_interrupt(int irq, void *data, struct pt_regs *unused)
+ {
+ struct winch *winch = data;
+ struct tty_struct *tty;
+ int err;
+ char c;
+
+- err = generic_read(winch->fd, &c, NULL);
+- if(err < 0){
+- if(err != -EAGAIN){
+- printk("winch_interrupt : read failed, errno = %d\n",
+- -err);
+- printk("fd %d is losing SIGWINCH support\n",
+- winch->tty_fd);
+- free_irq(irq, data);
+- return;
++ if(winch->fd != -1){
++ err = generic_read(winch->fd, &c, NULL);
++ if(err < 0){
++ if(err != -EAGAIN){
++ printk("winch_interrupt : read failed, "
++ "errno = %d\n", -err);
++ printk("fd %d is losing SIGWINCH support\n",
++ winch->tty_fd);
++ return(IRQ_HANDLED);
++ }
++ goto out;
+ }
+- goto out;
+ }
+ tty = winch->line->tty;
+ if(tty != NULL){
+@@ -492,7 +498,9 @@
+ kill_pg(tty->pgrp, SIGWINCH, 1);
+ }
+ out:
+- reactivate_fd(winch->fd, WINCH_IRQ);
++ if(winch->fd != -1)
++ reactivate_fd(winch->fd, WINCH_IRQ);
++ return(IRQ_HANDLED);
+ }
+
+ DECLARE_MUTEX(winch_handler_sem);
+@@ -529,7 +537,10 @@
+
+ list_for_each(ele, &winch_handlers){
+ winch = list_entry(ele, struct winch, list);
+- close(winch->fd);
++ if(winch->fd != -1){
++ deactivate_fd(winch->fd, WINCH_IRQ);
++ close(winch->fd);
++ }
+ if(winch->pid != -1)
+ os_kill_process(winch->pid, 1);
+ }
+Index: linux-2.6.0-test5/arch/um/drivers/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/Makefile 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/drivers/Makefile 2003-09-27 11:38:20.155464288 +0800
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
++# Copyright (C) 2000, 2002, 2003 Jeff Dike (jdike@karaya.com)
+ # Licensed under the GPL
+ #
+
+@@ -39,6 +39,8 @@
+ obj-$(CONFIG_TTY_CHAN) += tty.o
+ obj-$(CONFIG_XTERM_CHAN) += xterm.o xterm_kern.o
+ obj-$(CONFIG_UML_WATCHDOG) += harddog.o
++obj-$(CONFIG_BLK_DEV_COW) += cow_kern.o
++obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o
+
+ obj-y += stdio_console.o $(CHAN_OBJS)
+
+@@ -46,7 +48,7 @@
+
+ USER_OBJS := $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) fd.o \
+ null.o pty.o tty.o xterm.o
+-USER_OBJS := $(foreach file,$(USER_OBJS),arch/um/drivers/$(file))
++USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
+
+ $(USER_OBJS) : %.o: %.c
+ $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
+Index: linux-2.6.0-test5/arch/um/drivers/mconsole_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/mconsole_kern.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/drivers/mconsole_kern.c 2003-09-27 11:38:20.159463680 +0800
+@@ -27,6 +27,7 @@
+ #include "init.h"
+ #include "os.h"
+ #include "umid.h"
++#include "irq_kern.h"
+
+ static int do_unlink_socket(struct notifier_block *notifier,
+ unsigned long what, void *data)
+@@ -67,7 +68,7 @@
+
+ DECLARE_WORK(mconsole_work, mc_work_proc, NULL);
+
+-void mconsole_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++irqreturn_t mconsole_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+ {
+ int fd;
+ struct mconsole_entry *new;
+@@ -88,6 +89,7 @@
+ }
+ if(!list_empty(&mc_requests)) schedule_work(&mconsole_work);
+ reactivate_fd(fd, MCONSOLE_IRQ);
++ return(IRQ_HANDLED);
+ }
+
+ void mconsole_version(struct mc_request *req)
+@@ -100,20 +102,34 @@
+ mconsole_reply(req, version, 0, 0);
+ }
+
++void mconsole_log(struct mc_request *req)
++{
++ int len;
++ char *ptr = req->request.data;
++
++ ptr += strlen("log");
++ while(isspace(*ptr)) ptr++;
++
++ len = ptr - req->request.data;
++ printk("%.*s", len, ptr);
++ mconsole_reply(req, "", 0, 0);
++}
++
+ #define UML_MCONSOLE_HELPTEXT \
+-"Commands:
+- version - Get kernel version
+- help - Print this message
+- halt - Halt UML
+- reboot - Reboot UML
+- config <dev>=<config> - Add a new device to UML;
+- same syntax as command line
+- config <dev> - Query the configuration of a device
+- remove <dev> - Remove a device from UML
+- sysrq <letter> - Performs the SysRq action controlled by the letter
+- cad - invoke the Ctl-Alt-Del handler
+- stop - pause the UML; it will do nothing until it receives a 'go'
+- go - continue the UML after a 'stop'
++"Commands: \n\
++ version - Get kernel version \n\
++ help - Print this message \n\
++ halt - Halt UML \n\
++ reboot - Reboot UML \n\
++ config <dev>=<config> - Add a new device to UML; \n\
++ same syntax as command line \n\
++ config <dev> - Query the configuration of a device \n\
++ remove <dev> - Remove a device from UML \n\
++ sysrq <letter> - Performs the SysRq action controlled by the letter \n\
++ cad - invoke the Ctl-Alt-Del handler \n\
++ stop - pause the UML; it will do nothing until it receives a 'go' \n\
++ go - continue the UML after a 'stop' \n\
++ log <string> - make UML enter <string> into the kernel log\n\
+ "
+
+ void mconsole_help(struct mc_request *req)
+@@ -302,7 +318,7 @@
+ if(umid_file_name("mconsole", file, sizeof(file))) return(-1);
+ snprintf(mconsole_socket_name, sizeof(file), "%s", file);
+
+- sock = create_unix_socket(file, sizeof(file));
++ sock = create_unix_socket(file, sizeof(file), 1);
+ if (sock < 0){
+ printk("Failed to initialize management console\n");
+ return(1);
+Index: linux-2.6.0-test5/arch/um/drivers/mconsole_user.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/mconsole_user.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/drivers/mconsole_user.c 2003-09-27 11:38:20.161463376 +0800
+@@ -28,6 +28,7 @@
+ { "cad", mconsole_cad, 1 },
+ { "stop", mconsole_stop, 0 },
+ { "go", mconsole_go, 1 },
++ { "log", mconsole_log, 1 },
+ };
+
+ /* Initialized in mconsole_init, which is an initcall */
+@@ -139,6 +140,7 @@
+ memcpy(reply.data, str, len);
+ reply.data[len] = '\0';
+ total -= len;
++ str += len;
+ reply.len = len + 1;
+
+ len = sizeof(reply) + reply.len - sizeof(reply.data);
+Index: linux-2.6.0-test5/arch/um/drivers/mmapper_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/mmapper_kern.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/drivers/mmapper_kern.c 2003-09-27 11:38:20.163463072 +0800
+@@ -120,7 +120,10 @@
+ printk(KERN_INFO "Mapper v0.1\n");
+
+ v_buf = (char *) find_iomem("mmapper", &mmapper_size);
+- if(mmapper_size == 0) return(0);
++ if(mmapper_size == 0){
++ printk(KERN_ERR "mmapper_init - find_iomem failed\n");
++ return(0);
++ }
+
+ p_buf = __pa(v_buf);
+
+Index: linux-2.6.0-test5/arch/um/drivers/net_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/net_kern.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/drivers/net_kern.c 2003-09-27 11:38:20.168462312 +0800
+@@ -26,6 +26,7 @@
+ #include "mconsole_kern.h"
+ #include "init.h"
+ #include "irq_user.h"
++#include "irq_kern.h"
+
+ static spinlock_t opened_lock = SPIN_LOCK_UNLOCKED;
+ LIST_HEAD(opened);
+@@ -61,14 +62,14 @@
+ return pkt_len;
+ }
+
+-void uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++irqreturn_t uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+ {
+ struct net_device *dev = dev_id;
+ struct uml_net_private *lp = dev->priv;
+ int err;
+
+ if(!netif_running(dev))
+- return;
++ return(IRQ_NONE);
+
+ spin_lock(&lp->lock);
+ while((err = uml_net_rx(dev)) > 0) ;
+@@ -83,6 +84,7 @@
+
+ out:
+ spin_unlock(&lp->lock);
++ return(IRQ_HANDLED);
+ }
+
+ static int uml_net_open(struct net_device *dev)
+@@ -252,37 +254,6 @@
+ #endif
+ }
+
+-/*
+- * default do nothing hard header packet routines for struct net_device init.
+- * real ethernet transports will overwrite with real routines.
+- */
+-static int uml_net_hard_header(struct sk_buff *skb, struct net_device *dev,
+- unsigned short type, void *daddr, void *saddr, unsigned len)
+-{
+- return(0); /* no change */
+-}
+-
+-static int uml_net_rebuild_header(struct sk_buff *skb)
+-{
+- return(0); /* ignore */
+-}
+-
+-static int uml_net_header_cache(struct neighbour *neigh, struct hh_cache *hh)
+-{
+- return(-1); /* fail */
+-}
+-
+-static void uml_net_header_cache_update(struct hh_cache *hh,
+- struct net_device *dev, unsigned char * haddr)
+-{
+- /* ignore */
+-}
+-
+-static int uml_net_header_parse(struct sk_buff *skb, unsigned char *haddr)
+-{
+- return(0); /* nothing */
+-}
+-
+ static spinlock_t devices_lock = SPIN_LOCK_UNLOCKED;
+ static struct list_head devices = LIST_HEAD_INIT(devices);
+
+@@ -292,7 +263,7 @@
+ struct uml_net *device;
+ struct net_device *dev;
+ struct uml_net_private *lp;
+- int err, size;
++ int save, err, size;
+
+ size = transport->private_size + sizeof(struct uml_net_private) +
+ sizeof(((struct uml_net_private *) 0)->user);
+@@ -334,12 +305,6 @@
+ snprintf(dev->name, sizeof(dev->name), "eth%d", n);
+ device->dev = dev;
+
+- dev->hard_header = uml_net_hard_header;
+- dev->rebuild_header = uml_net_rebuild_header;
+- dev->hard_header_cache = uml_net_header_cache;
+- dev->header_cache_update= uml_net_header_cache_update;
+- dev->hard_header_parse = uml_net_header_parse;
+-
+ (*transport->kern->init)(dev, init);
+
+ dev->mtu = transport->user->max_packet;
+@@ -362,21 +327,29 @@
+ return 1;
+ lp = dev->priv;
+
+- INIT_LIST_HEAD(&lp->list);
+- spin_lock_init(&lp->lock);
+- lp->dev = dev;
+- lp->fd = -1;
+- lp->mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0 };
+- lp->have_mac = device->have_mac;
+- lp->protocol = transport->kern->protocol;
+- lp->open = transport->user->open;
+- lp->close = transport->user->close;
+- lp->remove = transport->user->remove;
+- lp->read = transport->kern->read;
+- lp->write = transport->kern->write;
+- lp->add_address = transport->user->add_address;
+- lp->delete_address = transport->user->delete_address;
+- lp->set_mtu = transport->user->set_mtu;
++ /* lp.user is the first four bytes of the transport data, which
++ * has already been initialized. This structure assignment will
++ * overwrite that, so we make sure that .user gets overwritten with
++ * what it already has.
++ */
++ save = lp->user[0];
++ *lp = ((struct uml_net_private)
++ { .list = LIST_HEAD_INIT(lp->list),
++ .lock = SPIN_LOCK_UNLOCKED,
++ .dev = dev,
++ .fd = -1,
++ .mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0},
++ .have_mac = device->have_mac,
++ .protocol = transport->kern->protocol,
++ .open = transport->user->open,
++ .close = transport->user->close,
++ .remove = transport->user->remove,
++ .read = transport->kern->read,
++ .write = transport->kern->write,
++ .add_address = transport->user->add_address,
++ .delete_address = transport->user->delete_address,
++ .set_mtu = transport->user->set_mtu,
++ .user = { save } });
+
+ init_timer(&lp->tl);
+ lp->tl.function = uml_net_user_timer_expire;
+@@ -609,7 +582,8 @@
+ unregister_netdev(dev);
+
+ list_del(&device->list);
+- free_netdev(device);
++ kfree(device);
++ free_netdev(dev);
+ return(0);
+ }
+
+Index: linux-2.6.0-test5/arch/um/drivers/port_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/port_kern.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/drivers/port_kern.c 2003-09-27 11:38:20.171461856 +0800
+@@ -6,6 +6,7 @@
+ #include "linux/list.h"
+ #include "linux/sched.h"
+ #include "linux/slab.h"
++#include "linux/interrupt.h"
+ #include "linux/irq.h"
+ #include "linux/spinlock.h"
+ #include "linux/errno.h"
+@@ -14,6 +15,7 @@
+ #include "kern_util.h"
+ #include "kern.h"
+ #include "irq_user.h"
++#include "irq_kern.h"
+ #include "port.h"
+ #include "init.h"
+ #include "os.h"
+@@ -44,7 +46,7 @@
+ struct port_list *port;
+ };
+
+-static void pipe_interrupt(int irq, void *data, struct pt_regs *regs)
++static irqreturn_t pipe_interrupt(int irq, void *data, struct pt_regs *regs)
+ {
+ struct connection *conn = data;
+ int fd;
+@@ -52,7 +54,7 @@
+ fd = os_rcv_fd(conn->socket[0], &conn->helper_pid);
+ if(fd < 0){
+ if(fd == -EAGAIN)
+- return;
++ return(IRQ_NONE);
+
+ printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n",
+ -fd);
+@@ -65,6 +67,7 @@
+ list_add(&conn->list, &conn->port->connections);
+
+ up(&conn->port->sem);
++ return(IRQ_HANDLED);
+ }
+
+ static int port_accept(struct port_list *port)
+@@ -138,12 +141,13 @@
+
+ DECLARE_WORK(port_work, port_work_proc, NULL);
+
+-static void port_interrupt(int irq, void *data, struct pt_regs *regs)
++static irqreturn_t port_interrupt(int irq, void *data, struct pt_regs *regs)
+ {
+ struct port_list *port = data;
+
+ port->has_connection = 1;
+ schedule_work(&port_work);
++ return(IRQ_HANDLED);
+ }
+
+ void *port_data(int port_num)
+Index: linux-2.6.0-test5/arch/um/drivers/ssl.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/ssl.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/drivers/ssl.c 2003-09-27 11:38:20.173461552 +0800
+@@ -53,8 +53,9 @@
+
+ static struct line_driver driver = {
+ .name = "UML serial line",
+- .devfs_name = "tts/%d",
+- .major = TTYAUX_MAJOR,
++ .device_name = "ttS",
++ .devfs_name = "tts/",
++ .major = TTY_MAJOR,
+ .minor_start = 64,
+ .type = TTY_DRIVER_TYPE_SERIAL,
+ .subtype = 0,
+Index: linux-2.6.0-test5/arch/um/drivers/stdio_console.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/stdio_console.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/drivers/stdio_console.c 2003-09-27 11:38:20.176461096 +0800
+@@ -83,7 +83,8 @@
+
+ static struct line_driver driver = {
+ .name = "UML console",
+- .devfs_name = "vc/%d",
++ .device_name = "tty",
++ .devfs_name = "vc/",
+ .major = TTY_MAJOR,
+ .minor_start = 0,
+ .type = TTY_DRIVER_TYPE_CONSOLE,
+@@ -159,6 +160,15 @@
+
+ static int con_init_done = 0;
+
++static struct tty_operations console_ops = {
++ .open = con_open,
++ .close = con_close,
++ .write = con_write,
++ .chars_in_buffer = chars_in_buffer,
++ .set_termios = set_termios,
++ .write_room = line_write_room,
++};
++
+ int stdio_init(void)
+ {
+ char *new_title;
+@@ -166,7 +176,8 @@
+ printk(KERN_INFO "Initializing stdio console driver\n");
+
+ console_driver = line_register_devfs(&console_lines, &driver,
+- &console_ops, vts, sizeof(vts)/sizeof(vts[0]));
++ &console_ops, vts,
++ sizeof(vts)/sizeof(vts[0]));
+
+ lines_init(vts, sizeof(vts)/sizeof(vts[0]));
+
+@@ -188,15 +199,6 @@
+ if(con_init_done) up(&vts[console->index].sem);
+ }
+
+-static struct tty_operations console_ops = {
+- .open = con_open,
+- .close = con_close,
+- .write = con_write,
+- .chars_in_buffer = chars_in_buffer,
+- .set_termios = set_termios,
+- .write_room = line_write_room,
+-};
+-
+ static struct tty_driver *console_device(struct console *c, int *index)
+ {
+ *index = c->index;
+@@ -212,12 +214,14 @@
+ console_device, console_setup,
+ CON_PRINTBUFFER);
+
+-static void __init stdio_console_init(void)
++static int __init stdio_console_init(void)
+ {
+ INIT_LIST_HEAD(&vts[0].chan_list);
+ list_add(&init_console_chan.list, &vts[0].chan_list);
+ register_console(&stdiocons);
++ return(0);
+ }
++
+ console_initcall(stdio_console_init);
+
+ static int console_chan_setup(char *str)
+Index: linux-2.6.0-test5/arch/um/drivers/ubd_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/ubd_kern.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/drivers/ubd_kern.c 2003-09-27 11:38:20.183460032 +0800
+@@ -8,6 +8,13 @@
+ * old style ubd by setting UBD_SHIFT to 0
+ * 2002-09-27...2002-10-18 massive tinkering for 2.5
+ * partitions have changed in 2.5
++ * 2003-01-29 more tinkering for 2.5.59-1
++ * This should now address the sysfs problems and has
++ * the symlink for devfs to allow for booting with
++ * the common /dev/ubd/discX/... names rather than
++ * only /dev/ubdN/discN this version also has lots of
++ * clean ups preparing for ubd-many.
++ * James McMechan
+ */
+
+ #define MAJOR_NR UBD_MAJOR
+@@ -40,6 +47,7 @@
+ #include "mconsole_kern.h"
+ #include "init.h"
+ #include "irq_user.h"
++#include "irq_kern.h"
+ #include "ubd_user.h"
+ #include "2_5compat.h"
+ #include "os.h"
+@@ -67,7 +75,7 @@
+ static request_queue_t *ubd_queue;
+
+ /* Protected by ubd_lock */
+-static int fake_major = 0;
++static int fake_major = MAJOR_NR;
+
+ static struct gendisk *ubd_gendisk[MAX_DEV];
+ static struct gendisk *fake_gendisk[MAX_DEV];
+@@ -96,12 +104,12 @@
+
+ struct ubd {
+ char *file;
+- int is_dir;
+ int count;
+ int fd;
+ __u64 size;
+ struct openflags boot_openflags;
+ struct openflags openflags;
++ int no_cow;
+ struct cow cow;
+ };
+
+@@ -115,12 +123,12 @@
+
+ #define DEFAULT_UBD { \
+ .file = NULL, \
+- .is_dir = 0, \
+ .count = 0, \
+ .fd = -1, \
+ .size = -1, \
+ .boot_openflags = OPEN_FLAGS, \
+ .openflags = OPEN_FLAGS, \
++ .no_cow = 0, \
+ .cow = DEFAULT_COW, \
+ }
+
+@@ -128,8 +136,10 @@
+
+ static int ubd0_init(void)
+ {
+- if(ubd_dev[0].file == NULL)
+- ubd_dev[0].file = "root_fs";
++ struct ubd *dev = &ubd_dev[0];
++
++ if(dev->file == NULL)
++ dev->file = "root_fs";
+ return(0);
+ }
+
+@@ -196,19 +206,39 @@
+ " Create ide0 entries that map onto ubd devices.\n\n"
+ );
+
++static int parse_unit(char **ptr)
++{
++ char *str = *ptr, *end;
++ int n = -1;
++
++ if(isdigit(*str)) {
++ n = simple_strtoul(str, &end, 0);
++ if(end == str)
++ return(-1);
++ *ptr = end;
++ }
++ else if (('a' <= *str) && (*str <= 'h')) {
++ n = *str - 'a';
++ str++;
++ *ptr = str;
++ }
++ return(n);
++}
++
+ static int ubd_setup_common(char *str, int *index_out)
+ {
++ struct ubd *dev;
+ struct openflags flags = global_openflags;
+ char *backing_file;
+ int n, err;
+
+ if(index_out) *index_out = -1;
+- n = *str++;
++ n = *str;
+ if(n == '='){
+- static int fake_major_allowed = 1;
+ char *end;
+ int major;
+
++ str++;
+ if(!strcmp(str, "sync")){
+ global_openflags.s = 1;
+ return(0);
+@@ -220,20 +250,14 @@
+ return(1);
+ }
+
+- if(!fake_major_allowed){
+- printk(KERN_ERR "Can't assign a fake major twice\n");
+- return(1);
+- }
+-
+ err = 1;
+ spin_lock(&ubd_lock);
+- if(!fake_major_allowed){
++ if(fake_major != MAJOR_NR){
+ printk(KERN_ERR "Can't assign a fake major twice\n");
+ goto out1;
+ }
+
+ fake_major = major;
+- fake_major_allowed = 0;
+
+ printk(KERN_INFO "Setting extra ubd major number to %d\n",
+ major);
+@@ -243,25 +267,23 @@
+ return(err);
+ }
+
+- if(n < '0'){
+- printk(KERN_ERR "ubd_setup : index out of range\n"); }
+-
+- if((n >= '0') && (n <= '9')) n -= '0';
+- else if((n >= 'a') && (n <= 'z')) n -= 'a';
+- else {
+- printk(KERN_ERR "ubd_setup : device syntax invalid\n");
++ n = parse_unit(&str);
++ if(n < 0){
++ printk(KERN_ERR "ubd_setup : couldn't parse unit number "
++ "'%s'\n", str);
+ return(1);
+ }
+ if(n >= MAX_DEV){
+- printk(KERN_ERR "ubd_setup : index out of range "
+- "(%d devices)\n", MAX_DEV);
++ printk(KERN_ERR "ubd_setup : index %d out of range "
++ "(%d devices)\n", n, MAX_DEV);
+ return(1);
+ }
+
+ err = 1;
+ spin_lock(&ubd_lock);
+
+- if(ubd_dev[n].file != NULL){
++ dev = &ubd_dev[n];
++ if(dev->file != NULL){
+ printk(KERN_ERR "ubd_setup : device already configured\n");
+ goto out2;
+ }
+@@ -276,6 +298,11 @@
+ flags.s = 1;
+ str++;
+ }
++ if (*str == 'd'){
++ dev->no_cow = 1;
++ str++;
++ }
++
+ if(*str++ != '='){
+ printk(KERN_ERR "ubd_setup : Expected '='\n");
+ goto out2;
+@@ -284,14 +311,17 @@
+ err = 0;
+ backing_file = strchr(str, ',');
+ if(backing_file){
+- *backing_file = '\0';
+- backing_file++;
++ if(dev->no_cow)
++ printk(KERN_ERR "Can't specify both 'd' and a "
++ "cow file\n");
++ else {
++ *backing_file = '\0';
++ backing_file++;
++ }
+ }
+- ubd_dev[n].file = str;
+- if(ubd_is_dir(ubd_dev[n].file))
+- ubd_dev[n].is_dir = 1;
+- ubd_dev[n].cow.file = backing_file;
+- ubd_dev[n].boot_openflags = flags;
++ dev->file = str;
++ dev->cow.file = backing_file;
++ dev->boot_openflags = flags;
+ out2:
+ spin_unlock(&ubd_lock);
+ return(err);
+@@ -321,8 +351,7 @@
+ static int fakehd_set = 0;
+ static int fakehd(char *str)
+ {
+- printk(KERN_INFO
+- "fakehd : Changing ubd name to \"hd\".\n");
++ printk(KERN_INFO "fakehd : Changing ubd name to \"hd\".\n");
+ fakehd_set = 1;
+ return 1;
+ }
+@@ -391,9 +420,10 @@
+ do_ubd_request(ubd_queue);
+ }
+
+-static void ubd_intr(int irq, void *dev, struct pt_regs *unused)
++static irqreturn_t ubd_intr(int irq, void *dev, struct pt_regs *unused)
+ {
+ ubd_handler();
++ return(IRQ_HANDLED);
+ }
+
+ /* Only changed by ubd_init, which is an initcall. */
+@@ -429,16 +459,18 @@
+ static int ubd_open_dev(struct ubd *dev)
+ {
+ struct openflags flags;
+- int err, n, create_cow, *create_ptr;
++ char **back_ptr;
++ int err, create_cow, *create_ptr;
+
++ dev->openflags = dev->boot_openflags;
+ create_cow = 0;
+ create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL;
+- dev->fd = open_ubd_file(dev->file, &dev->openflags, &dev->cow.file,
++ back_ptr = dev->no_cow ? NULL : &dev->cow.file;
++ dev->fd = open_ubd_file(dev->file, &dev->openflags, back_ptr,
+ &dev->cow.bitmap_offset, &dev->cow.bitmap_len,
+ &dev->cow.data_offset, create_ptr);
+
+ if((dev->fd == -ENOENT) && create_cow){
+- n = dev - ubd_dev;
+ dev->fd = create_cow_file(dev->file, dev->cow.file,
+ dev->openflags, 1 << 9,
+ &dev->cow.bitmap_offset,
+@@ -455,7 +487,10 @@
+ if(dev->cow.file != NULL){
+ err = -ENOMEM;
+ dev->cow.bitmap = (void *) vmalloc(dev->cow.bitmap_len);
+- if(dev->cow.bitmap == NULL) goto error;
++ if(dev->cow.bitmap == NULL){
++ printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
++ goto error;
++ }
+ flush_tlb_kernel_vm();
+
+ err = read_cow_bitmap(dev->fd, dev->cow.bitmap,
+@@ -481,17 +516,31 @@
+
+ {
+ struct gendisk *disk;
++ char from[sizeof("ubd/nnnnn\0")], to[sizeof("discnnnnn/disc\0")];
++ int err;
+
+ disk = alloc_disk(1 << UBD_SHIFT);
+- if (!disk)
+- return -ENOMEM;
++ if(disk == NULL)
++ return(-ENOMEM);
+
+ disk->major = major;
+ disk->first_minor = unit << UBD_SHIFT;
+ disk->fops = &ubd_blops;
+ set_capacity(disk, size / 512);
+- sprintf(disk->disk_name, "ubd");
+- sprintf(disk->devfs_name, "ubd/disc%d", unit);
++ if(major == MAJOR_NR){
++ sprintf(disk->disk_name, "ubd%d", unit);
++ sprintf(disk->devfs_name, "ubd/disc%d", unit);
++ sprintf(from, "ubd/%d", unit);
++ sprintf(to, "disc%d/disc", unit);
++ err = devfs_mk_symlink(from, to);
++ if(err)
++ printk("ubd_new_disk failed to make link from %s to "
++ "%s, error = %d\n", from, to, err);
++ }
++ else {
++ sprintf(disk->disk_name, "ubd_fake%d", unit);
++ sprintf(disk->devfs_name, "ubd_fake/disc%d", unit);
++ }
+
+ disk->private_data = &ubd_dev[unit];
+ disk->queue = ubd_queue;
+@@ -506,10 +555,7 @@
+ struct ubd *dev = &ubd_dev[n];
+ int err;
+
+- if(dev->is_dir)
+- return(-EISDIR);
+-
+- if (!dev->file)
++ if(dev->file == NULL)
+ return(-ENODEV);
+
+ if (ubd_open_dev(dev))
+@@ -523,7 +569,7 @@
+ if(err)
+ return(err);
+
+- if(fake_major)
++ if(fake_major != MAJOR_NR)
+ ubd_new_disk(fake_major, dev->size, n,
+ &fake_gendisk[n]);
+
+@@ -561,42 +607,42 @@
+ return(err);
+ }
+
+-static int ubd_get_config(char *dev, char *str, int size, char **error_out)
++static int ubd_get_config(char *name, char *str, int size, char **error_out)
+ {
+- struct ubd *ubd;
++ struct ubd *dev;
+ char *end;
+- int major, n = 0;
++ int n, len = 0;
+
+- major = simple_strtoul(dev, &end, 0);
+- if((*end != '\0') || (end == dev)){
+- *error_out = "ubd_get_config : didn't parse major number";
++ n = simple_strtoul(name, &end, 0);
++ if((*end != '\0') || (end == name)){
++ *error_out = "ubd_get_config : didn't parse device number";
+ return(-1);
+ }
+
+- if((major >= MAX_DEV) || (major < 0)){
+- *error_out = "ubd_get_config : major number out of range";
++ if((n >= MAX_DEV) || (n < 0)){
++ *error_out = "ubd_get_config : device number out of range";
+ return(-1);
+ }
+
+- ubd = &ubd_dev[major];
++ dev = &ubd_dev[n];
+ spin_lock(&ubd_lock);
+
+- if(ubd->file == NULL){
+- CONFIG_CHUNK(str, size, n, "", 1);
++ if(dev->file == NULL){
++ CONFIG_CHUNK(str, size, len, "", 1);
+ goto out;
+ }
+
+- CONFIG_CHUNK(str, size, n, ubd->file, 0);
++ CONFIG_CHUNK(str, size, len, dev->file, 0);
+
+- if(ubd->cow.file != NULL){
+- CONFIG_CHUNK(str, size, n, ",", 0);
+- CONFIG_CHUNK(str, size, n, ubd->cow.file, 1);
++ if(dev->cow.file != NULL){
++ CONFIG_CHUNK(str, size, len, ",", 0);
++ CONFIG_CHUNK(str, size, len, dev->cow.file, 1);
+ }
+- else CONFIG_CHUNK(str, size, n, "", 1);
++ else CONFIG_CHUNK(str, size, len, "", 1);
+
+ out:
+ spin_unlock(&ubd_lock);
+- return(n);
++ return(len);
+ }
+
+ static int ubd_remove(char *str)
+@@ -604,11 +650,9 @@
+ struct ubd *dev;
+ int n, err = -ENODEV;
+
+- if(!isdigit(*str))
+- return(err); /* it should be a number 0-7/a-h */
++ n = parse_unit(&str);
+
+- n = *str - '0';
+- if(n >= MAX_DEV)
++ if((n < 0) || (n >= MAX_DEV))
+ return(err);
+
+ dev = &ubd_dev[n];
+@@ -669,7 +713,7 @@
+
+ elevator_init(ubd_queue, &elevator_noop);
+
+- if (fake_major != 0) {
++ if (fake_major != MAJOR_NR) {
+ char name[sizeof("ubd_nnn\0")];
+
+ snprintf(name, sizeof(name), "ubd_%d", fake_major);
+@@ -714,15 +758,9 @@
+ {
+ struct gendisk *disk = inode->i_bdev->bd_disk;
+ struct ubd *dev = disk->private_data;
+- int err = -EISDIR;
+-
+- if(dev->is_dir == 1)
+- goto out;
++ int err = 0;
+
+- err = 0;
+ if(dev->count == 0){
+- dev->openflags = dev->boot_openflags;
+-
+ err = ubd_open_dev(dev);
+ if(err){
+ printk(KERN_ERR "%s: Can't open \"%s\": errno = %d\n",
+@@ -796,15 +834,6 @@
+
+ if(req->rq_status == RQ_INACTIVE) return(1);
+
+- if(dev->is_dir){
+- strcpy(req->buffer, "HOSTFS:");
+- strcat(req->buffer, dev->file);
+- spin_lock(&ubd_io_lock);
+- end_request(req, 1);
+- spin_unlock(&ubd_io_lock);
+- return(1);
+- }
+-
+ if((rq_data_dir(req) == WRITE) && !dev->openflags.w){
+ printk("Write attempted on readonly ubd device %s\n",
+ disk->disk_name);
+Index: linux-2.6.0-test5/arch/um/drivers/ubd_user.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/ubd_user.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/drivers/ubd_user.c 2003-09-27 11:38:20.188459272 +0800
+@@ -24,142 +24,24 @@
+ #include "user.h"
+ #include "ubd_user.h"
+ #include "os.h"
++#include "cow.h"
+
+ #include <endian.h>
+ #include <byteswap.h>
+-#if __BYTE_ORDER == __BIG_ENDIAN
+-# define ntohll(x) (x)
+-# define htonll(x) (x)
+-#elif __BYTE_ORDER == __LITTLE_ENDIAN
+-# define ntohll(x) bswap_64(x)
+-# define htonll(x) bswap_64(x)
+-#else
+-#error "__BYTE_ORDER not defined"
+-#endif
+-
+-#define PATH_LEN_V1 256
+-
+-struct cow_header_v1 {
+- int magic;
+- int version;
+- char backing_file[PATH_LEN_V1];
+- time_t mtime;
+- __u64 size;
+- int sectorsize;
+-};
+-
+-#define PATH_LEN_V2 MAXPATHLEN
+-
+-struct cow_header_v2 {
+- unsigned long magic;
+- unsigned long version;
+- char backing_file[PATH_LEN_V2];
+- time_t mtime;
+- __u64 size;
+- int sectorsize;
+-};
+-
+-union cow_header {
+- struct cow_header_v1 v1;
+- struct cow_header_v2 v2;
+-};
+-
+-#define COW_MAGIC 0x4f4f4f4d /* MOOO */
+-#define COW_VERSION 2
+-
+-static void sizes(__u64 size, int sectorsize, int bitmap_offset,
+- unsigned long *bitmap_len_out, int *data_offset_out)
+-{
+- *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
+-
+- *data_offset_out = bitmap_offset + *bitmap_len_out;
+- *data_offset_out = (*data_offset_out + sectorsize - 1) / sectorsize;
+- *data_offset_out *= sectorsize;
+-}
+-
+-static int read_cow_header(int fd, int *magic_out, char **backing_file_out,
+- time_t *mtime_out, __u64 *size_out,
+- int *sectorsize_out, int *bitmap_offset_out)
+-{
+- union cow_header *header;
+- char *file;
+- int err, n;
+- unsigned long version, magic;
+-
+- header = um_kmalloc(sizeof(*header));
+- if(header == NULL){
+- printk("read_cow_header - Failed to allocate header\n");
+- return(-ENOMEM);
+- }
+- err = -EINVAL;
+- n = read(fd, header, sizeof(*header));
+- if(n < offsetof(typeof(header->v1), backing_file)){
+- printk("read_cow_header - short header\n");
+- goto out;
+- }
+-
+- magic = header->v1.magic;
+- if(magic == COW_MAGIC) {
+- version = header->v1.version;
+- }
+- else if(magic == ntohl(COW_MAGIC)){
+- version = ntohl(header->v1.version);
+- }
+- else goto out;
+-
+- *magic_out = COW_MAGIC;
+-
+- if(version == 1){
+- if(n < sizeof(header->v1)){
+- printk("read_cow_header - failed to read V1 header\n");
+- goto out;
+- }
+- *mtime_out = header->v1.mtime;
+- *size_out = header->v1.size;
+- *sectorsize_out = header->v1.sectorsize;
+- *bitmap_offset_out = sizeof(header->v1);
+- file = header->v1.backing_file;
+- }
+- else if(version == 2){
+- if(n < sizeof(header->v2)){
+- printk("read_cow_header - failed to read V2 header\n");
+- goto out;
+- }
+- *mtime_out = ntohl(header->v2.mtime);
+- *size_out = ntohll(header->v2.size);
+- *sectorsize_out = ntohl(header->v2.sectorsize);
+- *bitmap_offset_out = sizeof(header->v2);
+- file = header->v2.backing_file;
+- }
+- else {
+- printk("read_cow_header - invalid COW version\n");
+- goto out;
+- }
+- err = -ENOMEM;
+- *backing_file_out = uml_strdup(file);
+- if(*backing_file_out == NULL){
+- printk("read_cow_header - failed to allocate backing file\n");
+- goto out;
+- }
+- err = 0;
+- out:
+- kfree(header);
+- return(err);
+-}
+
+ static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
+ {
+- struct stat buf1, buf2;
++ struct stat64 buf1, buf2;
+
+ if(from_cmdline == NULL) return(1);
+ if(!strcmp(from_cmdline, from_cow)) return(1);
+
+- if(stat(from_cmdline, &buf1) < 0){
++ if(stat64(from_cmdline, &buf1) < 0){
+ printk("Couldn't stat '%s', errno = %d\n", from_cmdline,
+ errno);
+ return(1);
+ }
+- if(stat(from_cow, &buf2) < 0){
++ if(stat64(from_cow, &buf2) < 0){
+ printk("Couldn't stat '%s', errno = %d\n", from_cow, errno);
+ return(1);
+ }
+@@ -215,118 +97,6 @@
+ return(0);
+ }
+
+-static int absolutize(char *to, int size, char *from)
+-{
+- char save_cwd[256], *slash;
+- int remaining;
+-
+- if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
+- printk("absolutize : unable to get cwd - errno = %d\n", errno);
+- return(-1);
+- }
+- slash = strrchr(from, '/');
+- if(slash != NULL){
+- *slash = '\0';
+- if(chdir(from)){
+- *slash = '/';
+- printk("absolutize : Can't cd to '%s' - errno = %d\n",
+- from, errno);
+- return(-1);
+- }
+- *slash = '/';
+- if(getcwd(to, size) == NULL){
+- printk("absolutize : unable to get cwd of '%s' - "
+- "errno = %d\n", from, errno);
+- return(-1);
+- }
+- remaining = size - strlen(to);
+- if(strlen(slash) + 1 > remaining){
+- printk("absolutize : unable to fit '%s' into %d "
+- "chars\n", from, size);
+- return(-1);
+- }
+- strcat(to, slash);
+- }
+- else {
+- if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){
+- printk("absolutize : unable to fit '%s' into %d "
+- "chars\n", from, size);
+- return(-1);
+- }
+- strcpy(to, save_cwd);
+- strcat(to, "/");
+- strcat(to, from);
+- }
+- chdir(save_cwd);
+- return(0);
+-}
+-
+-static int write_cow_header(char *cow_file, int fd, char *backing_file,
+- int sectorsize, long long *size)
+-{
+- struct cow_header_v2 *header;
+- struct stat64 buf;
+- int err;
+-
+- err = os_seek_file(fd, 0);
+- if(err != 0){
+- printk("write_cow_header - lseek failed, errno = %d\n", errno);
+- return(-errno);
+- }
+-
+- err = -ENOMEM;
+- header = um_kmalloc(sizeof(*header));
+- if(header == NULL){
+- printk("Failed to allocate COW V2 header\n");
+- goto out;
+- }
+- header->magic = htonl(COW_MAGIC);
+- header->version = htonl(COW_VERSION);
+-
+- err = -EINVAL;
+- if(strlen(backing_file) > sizeof(header->backing_file) - 1){
+- printk("Backing file name \"%s\" is too long - names are "
+- "limited to %d characters\n", backing_file,
+- sizeof(header->backing_file) - 1);
+- goto out_free;
+- }
+-
+- if(absolutize(header->backing_file, sizeof(header->backing_file),
+- backing_file))
+- goto out_free;
+-
+- err = stat64(header->backing_file, &buf);
+- if(err < 0){
+- printk("Stat of backing file '%s' failed, errno = %d\n",
+- header->backing_file, errno);
+- err = -errno;
+- goto out_free;
+- }
+-
+- err = os_file_size(header->backing_file, size);
+- if(err){
+- printk("Couldn't get size of backing file '%s', errno = %d\n",
+- header->backing_file, -*size);
+- goto out_free;
+- }
+-
+- header->mtime = htonl(buf.st_mtime);
+- header->size = htonll(*size);
+- header->sectorsize = htonl(sectorsize);
+-
+- err = write(fd, header, sizeof(*header));
+- if(err != sizeof(*header)){
+- printk("Write of header to new COW file '%s' failed, "
+- "errno = %d\n", cow_file, errno);
+- goto out_free;
+- }
+- err = 0;
+- out_free:
+- kfree(header);
+- out:
+- return(err);
+-}
+-
+ int open_ubd_file(char *file, struct openflags *openflags,
+ char **backing_file_out, int *bitmap_offset_out,
+ unsigned long *bitmap_len_out, int *data_offset_out,
+@@ -346,10 +116,17 @@
+ if((fd = os_open_file(file, *openflags, mode)) < 0)
+ return(fd);
+ }
++
++ err = os_lock_file(fd, openflags->w);
++ if(err){
++ printk("Failed to lock '%s', errno = %d\n", file, -err);
++ goto error;
++ }
++
+ if(backing_file_out == NULL) return(fd);
+
+- err = read_cow_header(fd, &magic, &backing_file, &mtime, &size,
+- §orsize, bitmap_offset_out);
++ err = read_cow_header(file_reader, &fd, &magic, &backing_file, &mtime,
++ &size, §orsize, bitmap_offset_out);
+ if(err && (*backing_file_out != NULL)){
+ printk("Failed to read COW header from COW file \"%s\", "
+ "errno = %d\n", file, err);
+@@ -376,12 +153,12 @@
+ if(err) goto error;
+ }
+
+- sizes(size, sectorsize, *bitmap_offset_out, bitmap_len_out,
+- data_offset_out);
++ cow_sizes(size, sectorsize, *bitmap_offset_out, bitmap_len_out,
++ data_offset_out);
+
+ return(fd);
+ error:
+- close(fd);
++ os_close_file(fd);
+ return(err);
+ }
+
+@@ -389,10 +166,7 @@
+ int sectorsize, int *bitmap_offset_out,
+ unsigned long *bitmap_len_out, int *data_offset_out)
+ {
+- __u64 blocks;
+- long zero;
+- int err, fd, i;
+- long long size;
++ int err, fd;
+
+ flags.c = 1;
+ fd = open_ubd_file(cow_file, &flags, NULL, NULL, NULL, NULL, NULL);
+@@ -403,29 +177,12 @@
+ goto out;
+ }
+
+- err = write_cow_header(cow_file, fd, backing_file, sectorsize, &size);
+- if(err) goto out_close;
+-
+- blocks = (size + sectorsize - 1) / sectorsize;
+- blocks = (blocks + sizeof(long) * 8 - 1) / (sizeof(long) * 8);
+- zero = 0;
+- for(i = 0; i < blocks; i++){
+- err = write(fd, &zero, sizeof(zero));
+- if(err != sizeof(zero)){
+- printk("Write of bitmap to new COW file '%s' failed, "
+- "errno = %d\n", cow_file, errno);
+- goto out_close;
+- }
+- }
+-
+- sizes(size, sectorsize, sizeof(struct cow_header_v2),
+- bitmap_len_out, data_offset_out);
+- *bitmap_offset_out = sizeof(struct cow_header_v2);
+-
+- return(fd);
+-
+- out_close:
+- close(fd);
++ err = init_cow_file(fd, cow_file, backing_file, sectorsize,
++ bitmap_offset_out, bitmap_len_out,
++ data_offset_out);
++ if(!err)
++ return(fd);
++ os_close_file(fd);
+ out:
+ return(err);
+ }
+@@ -448,14 +205,6 @@
+ else return(n);
+ }
+
+-int ubd_is_dir(char *file)
+-{
+- struct stat64 buf;
+-
+- if(stat64(file, &buf) < 0) return(0);
+- return(S_ISDIR(buf.st_mode));
+-}
+-
+ void do_io(struct io_thread_req *req)
+ {
+ char *buf;
+Index: linux-2.6.0-test5/arch/um/drivers/xterm.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/xterm.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/drivers/xterm.c 2003-09-27 11:38:20.190458968 +0800
+@@ -108,7 +108,7 @@
+ }
+ close(fd);
+
+- fd = create_unix_socket(file, sizeof(file));
++ fd = create_unix_socket(file, sizeof(file), 1);
+ if(fd < 0){
+ printk("xterm_open : create_unix_socket failed, errno = %d\n",
+ -fd);
+Index: linux-2.6.0-test5/arch/um/drivers/xterm_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/xterm_kern.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/drivers/xterm_kern.c 2003-09-27 11:38:20.192458664 +0800
+@@ -5,9 +5,12 @@
+
+ #include "linux/errno.h"
+ #include "linux/slab.h"
++#include "linux/signal.h"
++#include "linux/interrupt.h"
+ #include "asm/semaphore.h"
+ #include "asm/irq.h"
+ #include "irq_user.h"
++#include "irq_kern.h"
+ #include "kern_util.h"
+ #include "os.h"
+ #include "xterm.h"
+@@ -19,17 +22,18 @@
+ int new_fd;
+ };
+
+-static void xterm_interrupt(int irq, void *data, struct pt_regs *regs)
++static irqreturn_t xterm_interrupt(int irq, void *data, struct pt_regs *regs)
+ {
+ struct xterm_wait *xterm = data;
+ int fd;
+
+ fd = os_rcv_fd(xterm->fd, &xterm->pid);
+ if(fd == -EAGAIN)
+- return;
++ return(IRQ_NONE);
+
+ xterm->new_fd = fd;
+ up(&xterm->sem);
++ return(IRQ_HANDLED);
+ }
+
+ int xterm_fd(int socket, int *pid_out)
+Index: linux-2.6.0-test5/arch/um/dyn.lds.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/dyn.lds.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/dyn.lds.S 2003-09-27 11:38:20.194458360 +0800
+@@ -15,7 +15,11 @@
+ . = ALIGN(4096); /* Init code and data */
+ _stext = .;
+ __init_begin = .;
+- .text.init : { *(.text.init) }
++ .init.text : {
++ _sinittext = .;
++ *(.init.text)
++ _einittext = .;
++ }
+
+ . = ALIGN(4096);
+
+@@ -67,7 +71,7 @@
+
+ #include "asm/common.lds.S"
+
+- .data.init : { *(.data.init) }
++ init.data : { *(.init.data) }
+
+ /* Ensure the __preinit_array_start label is properly aligned. We
+ could instead move the label definition inside the section, but
+Index: linux-2.6.0-test5/arch/um/include/irq_kern.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/include/irq_kern.h 2003-09-27 11:38:18.442724664 +0800
++++ linux-2.6.0-test5/arch/um/include/irq_kern.h 2003-09-27 11:38:20.195458208 +0800
+@@ -0,0 +1,28 @@
++/*
++ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
++ * Licensed under the GPL
++ */
++
++#ifndef __IRQ_KERN_H__
++#define __IRQ_KERN_H__
++
++#include "linux/interrupt.h"
++
++extern int um_request_irq(unsigned int irq, int fd, int type,
++ irqreturn_t (*handler)(int, void *,
++ struct pt_regs *),
++ unsigned long irqflags, const char * devname,
++ void *dev_id);
++
++#endif
++
++/*
++ * Overrides for Emacs so that we follow Linus's tabbing style.
++ * Emacs will notice this stuff at the end of the file and automatically
++ * adjust the settings for this buffer only. This must remain at the end
++ * of the file.
++ * ---------------------------------------------------------------------------
++ * Local variables:
++ * c-file-style: "linux"
++ * End:
++ */
+Index: linux-2.6.0-test5/arch/um/include/kern_util.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/include/kern_util.h 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/include/kern_util.h 2003-09-27 11:38:20.197457904 +0800
+@@ -63,10 +63,9 @@
+ extern void *syscall_sp(void *t);
+ extern void syscall_trace(void);
+ extern int hz(void);
+-extern void idle_timer(void);
++extern void uml_idle_timer(void);
+ extern unsigned int do_IRQ(int irq, union uml_pt_regs *regs);
+ extern int external_pid(void *t);
+-extern int pid_to_processor_id(int pid);
+ extern void boot_timer_handler(int sig);
+ extern void interrupt_end(void);
+ extern void initial_thread_cb(void (*proc)(void *), void *arg);
+@@ -90,9 +89,7 @@
+ extern char *uml_strdup(char *string);
+ extern void unprotect_kernel_mem(void);
+ extern void protect_kernel_mem(void);
+-extern void set_kmem_end(unsigned long);
+ extern void uml_cleanup(void);
+-extern int pid_to_processor_id(int pid);
+ extern void set_current(void *t);
+ extern void lock_signalled_task(void *t);
+ extern void IPI_handler(int cpu);
+@@ -101,7 +98,9 @@
+ extern int clear_user_proc(void *buf, int size);
+ extern int copy_to_user_proc(void *to, void *from, int size);
+ extern int copy_from_user_proc(void *to, void *from, int size);
++extern int strlen_user_proc(char *str);
+ extern void bus_handler(int sig, union uml_pt_regs *regs);
++extern void winch(int sig, union uml_pt_regs *regs);
+ extern long execute_syscall(void *r);
+ extern int smp_sigio_handler(void);
+ extern void *get_current(void);
+Index: linux-2.6.0-test5/arch/um/include/line.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/include/line.h 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/include/line.h 2003-09-27 11:38:20.199457600 +0800
+@@ -9,12 +9,14 @@
+ #include "linux/list.h"
+ #include "linux/workqueue.h"
+ #include "linux/tty.h"
++#include "linux/interrupt.h"
+ #include "asm/semaphore.h"
+ #include "chan_user.h"
+ #include "mconsole_kern.h"
+
+ struct line_driver {
+ char *name;
++ char *device_name;
+ char *devfs_name;
+ short major;
+ short minor_start;
+@@ -67,8 +69,9 @@
+
+ #define LINES_INIT(n) { num : n }
+
+-extern void line_interrupt(int irq, void *data, struct pt_regs *unused);
+-extern void line_write_interrupt(int irq, void *data, struct pt_regs *unused);
++extern irqreturn_t line_interrupt(int irq, void *data, struct pt_regs *unused);
++extern irqreturn_t line_write_interrupt(int irq, void *data,
++ struct pt_regs *unused);
+ extern void line_close(struct line *lines, struct tty_struct *tty);
+ extern int line_open(struct line *lines, struct tty_struct *tty,
+ struct chan_opts *opts);
+Index: linux-2.6.0-test5/arch/um/include/mconsole.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/include/mconsole.h 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/include/mconsole.h 2003-09-27 11:38:20.200457448 +0800
+@@ -77,6 +77,7 @@
+ extern void mconsole_cad(struct mc_request *req);
+ extern void mconsole_stop(struct mc_request *req);
+ extern void mconsole_go(struct mc_request *req);
++extern void mconsole_log(struct mc_request *req);
+
+ extern int mconsole_get_request(int fd, struct mc_request *req);
+ extern int mconsole_notify(char *sock_name, int type, const void *data,
+Index: linux-2.6.0-test5/arch/um/include/mem.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/include/mem.h 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/include/mem.h 2003-09-27 11:38:20.202457144 +0800
+@@ -13,7 +13,6 @@
+ };
+
+ extern void set_usable_vm(unsigned long start, unsigned long end);
+-extern void set_kmem_end(unsigned long new);
+
+ #endif
+
+Index: linux-2.6.0-test5/arch/um/include/mem_user.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/include/mem_user.h 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/include/mem_user.h 2003-09-27 11:38:20.203456992 +0800
+@@ -51,9 +51,6 @@
+
+ extern int init_mem_user(void);
+ extern int create_mem_file(unsigned long len);
+-extern void setup_range(int fd, char *driver, unsigned long start,
+- unsigned long pfn, unsigned long total, int need_vm,
+- struct mem_region *region, void *reserved);
+ extern void setup_memory(void *entry);
+ extern unsigned long find_iomem(char *driver, unsigned long *len_out);
+ extern int init_maps(struct mem_region *region);
+Index: linux-2.6.0-test5/arch/um/include/os.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/include/os.h 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/include/os.h 2003-09-27 11:38:20.204456840 +0800
+@@ -103,10 +103,11 @@
+ extern int os_shutdown_socket(int fd, int r, int w);
+ extern void os_close_file(int fd);
+ extern int os_rcv_fd(int fd, int *helper_pid_out);
+-extern int create_unix_socket(char *file, int len);
++extern int create_unix_socket(char *file, int len, int close_on_exec);
+ extern int os_connect_socket(char *name);
+ extern int os_file_type(char *file);
+ extern int os_file_mode(char *file, struct openflags *mode_out);
++extern int os_lock_file(int fd, int excl);
+
+ extern unsigned long os_process_pc(int pid);
+ extern int os_process_parent(int pid);
+@@ -120,6 +121,7 @@
+ extern int os_protect_memory(void *addr, unsigned long len,
+ int r, int w, int x);
+ extern int os_unmap_memory(void *addr, int len);
++extern void os_flush_stdout(void);
+
+ #endif
+
+Index: linux-2.6.0-test5/arch/um/include/sysdep-i386/sigcontext.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/include/sysdep-i386/sigcontext.h 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/include/sysdep-i386/sigcontext.h 2003-09-27 11:38:20.206456536 +0800
+@@ -28,8 +28,8 @@
+ */
+ #define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0)
+
+-/* These are General Protection and Page Fault */
+-#define SEGV_IS_FIXABLE(trap) ((trap == 13) || (trap == 14))
++/* This is Page Fault */
++#define SEGV_IS_FIXABLE(trap) (trap == 14)
+
+ #define SC_SEGV_IS_FIXABLE(sc) (SEGV_IS_FIXABLE(SC_TRAPNO(sc)))
+
+Index: linux-2.6.0-test5/arch/um/include/ubd_user.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/include/ubd_user.h 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/include/ubd_user.h 2003-09-27 11:38:20.207456384 +0800
+@@ -39,7 +39,6 @@
+ extern int write_ubd_fs(int fd, char *buffer, int len);
+ extern int start_io_thread(unsigned long sp, int *fds_out);
+ extern void do_io(struct io_thread_req *req);
+-extern int ubd_is_dir(char *file);
+
+ static inline int ubd_test_bit(__u64 bit, unsigned char *data)
+ {
+Index: linux-2.6.0-test5/arch/um/include/user.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/include/user.h 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/include/user.h 2003-09-27 11:38:20.209456080 +0800
+@@ -14,7 +14,7 @@
+ extern void kfree(void *ptr);
+ extern int in_aton(char *str);
+ extern int open_gdb_chan(void);
+-
++extern int strlcpy(char *, const char *, int);
+ #endif
+
+ /*
+Index: linux-2.6.0-test5/arch/um/include/user_util.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/include/user_util.h 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/include/user_util.h 2003-09-27 11:38:20.210455928 +0800
+@@ -59,7 +59,6 @@
+ extern void *add_signal_handler(int sig, void (*handler)(int));
+ extern int start_fork_tramp(void *arg, unsigned long temp_stack,
+ int clone_flags, int (*tramp)(void *));
+-extern int clone_and_wait(int (*fn)(void *), void *arg, void *sp, int flags);
+ extern int linux_main(int argc, char **argv);
+ extern void set_cmdline(char *cmd);
+ extern void input_cb(void (*proc)(void *), void *arg, int arg_len);
+@@ -90,7 +89,8 @@
+ extern int arch_fixup(unsigned long address, void *sc_ptr);
+ extern void forward_pending_sigio(int target);
+ extern int can_do_skas(void);
+-
++extern void arch_init_thread(void);
++
+ #endif
+
+ /*
+Index: linux-2.6.0-test5/arch/um/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/Kconfig 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/Kconfig 2003-09-27 11:38:20.213455472 +0800
+@@ -61,6 +61,20 @@
+
+ config NET
+ bool "Networking support"
++ help
++ Unless you really know what you are doing, you should say Y here.
++ The reason is that some programs need kernel networking support even
++ when running on a stand-alone machine that isn't connected to any
++ other computer. If you are upgrading from an older kernel, you
++ should consider updating your networking tools too because changes
++ in the kernel and the tools often go hand in hand. The tools are
++ contained in the package net-tools, the location and version number
++ of which are given in Documentation/Changes.
++
++ For a general introduction to Linux networking, it is highly
++ recommended to read the NET-HOWTO, available from
++ <http://www.tldp.org/docs.html#howto>.
++
+
+ source "fs/Kconfig.binfmt"
+
+@@ -105,6 +119,16 @@
+ config MAGIC_SYSRQ
+ bool "Magic SysRq key"
+ depends on MCONSOLE
++ help
++ If you say Y here, you will have some control over the system even
++ if the system crashes for example during kernel debugging (e.g., you
++ will be able to flush the buffer cache to disk, reboot the system
++ immediately or dump some status information). This is accomplished
++ by pressing various keys while holding SysRq (Alt+PrintScreen). It
++ also works on a serial console (on PC hardware at least), if you
++ send a BREAK and then within 5 seconds a command keypress. The
++ keys are documented in Documentation/sysrq.txt. Don't say Y
++ unless you really know what this hack does.
+
+ config HOST_2G_2G
+ bool "2G/2G host address space split"
+@@ -239,6 +263,10 @@
+ config PT_PROXY
+ bool "Enable ptrace proxy"
+ depends on XTERM_CHAN && DEBUG_INFO
++ help
++ This option enables a debugging interface which allows gdb to debug
++ the kernel without needing to actually attach to kernel threads.
++ If you want to do kernel debugging, say Y here; otherwise say N.
+
+ config GPROF
+ bool "Enable gprof support"
+Index: linux-2.6.0-test5/arch/um/Kconfig_block
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/Kconfig_block 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/Kconfig_block 2003-09-27 11:38:20.214455320 +0800
+@@ -29,6 +29,20 @@
+ wise choice too. In all other cases (for example, if you're just
+ playing around with User-Mode Linux) you can choose N.
+
++# Turn this back on when the driver actually works
++#
++#config BLK_DEV_COW
++# tristate "COW block device"
++# help
++# This is a layered driver which sits above two other block devices.
++# One is read-only, and the other is a read-write layer which stores
++# all changes. This provides the illusion that the read-only layer
++# can be mounted read-write and changed.
++
++config BLK_DEV_COW_COMMON
++ bool
++ default BLK_DEV_COW || BLK_DEV_UBD
++
+ config BLK_DEV_LOOP
+ tristate "Loopback device support"
+
+Index: linux-2.6.0-test5/arch/um/Kconfig_net
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/Kconfig_net 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/Kconfig_net 2003-09-27 11:38:20.218454712 +0800
+@@ -1,5 +1,5 @@
+
+-menu "Network Devices"
++menu "UML Network Devices"
+ depends on NET
+
+ # UML virtual driver
+@@ -176,73 +176,5 @@
+
+ Startup example: "eth0=slirp,FE:FD:01:02:03:04,/usr/local/bin/slirp"
+
+-
+-# Below are hardware-independent drivers mirrored from
+-# drivers/net/Config.in. It would be nice if Linux
+-# had HW independent drivers separated from the other
+-# but it does not. Until then each non-ISA/PCI arch
+-# needs to provide it's own menu of network drivers
+-config DUMMY
+- tristate "Dummy net driver support"
+-
+-config BONDING
+- tristate "Bonding driver support"
+-
+-config EQUALIZER
+- tristate "EQL (serial line load balancing) support"
+-
+-config TUN
+- tristate "Universal TUN/TAP device driver support"
+-
+-config ETHERTAP
+- tristate "Ethertap network tap (OBSOLETE)"
+- depends on EXPERIMENTAL && NETLINK
+-
+-config PPP
+- tristate "PPP (point-to-point protocol) support"
+-
+-config PPP_MULTILINK
+- bool "PPP multilink support (EXPERIMENTAL)"
+- depends on PPP && EXPERIMENTAL
+-
+-config PPP_FILTER
+- bool "PPP filtering"
+- depends on PPP && FILTER
+-
+-config PPP_ASYNC
+- tristate "PPP support for async serial ports"
+- depends on PPP
+-
+-config PPP_SYNC_TTY
+- tristate "PPP support for sync tty ports"
+- depends on PPP
+-
+-config PPP_DEFLATE
+- tristate "PPP Deflate compression"
+- depends on PPP
+-
+-config PPP_BSDCOMP
+- tristate "PPP BSD-Compress compression"
+- depends on PPP
+-
+-config PPPOE
+- tristate "PPP over Ethernet (EXPERIMENTAL)"
+- depends on PPP && EXPERIMENTAL
+-
+-config SLIP
+- tristate "SLIP (serial line) support"
+-
+-config SLIP_COMPRESSED
+- bool "CSLIP compressed headers"
+- depends on SLIP=y
+-
+-config SLIP_SMART
+- bool "Keepalive and linefill"
+- depends on SLIP=y
+-
+-config SLIP_MODE_SLIP6
+- bool "Six bit SLIP encapsulation"
+- depends on SLIP=y
+-
+ endmenu
+
+Index: linux-2.6.0-test5/arch/um/kernel/config.c.in
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/config.c.in 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/config.c.in 2003-09-27 11:38:20.219454560 +0800
+@@ -7,9 +7,7 @@
+ #include <stdlib.h>
+ #include "init.h"
+
+-static __initdata char *config = "
+-CONFIG
+-";
++static __initdata char *config = "CONFIG";
+
+ static int __init print_config(char *line, int *add)
+ {
+Index: linux-2.6.0-test5/arch/um/kernel/init_task.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/init_task.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/init_task.c 2003-09-27 11:38:20.221454256 +0800
+@@ -17,6 +17,7 @@
+ struct mm_struct init_mm = INIT_MM(init_mm);
+ static struct files_struct init_files = INIT_FILES;
+ static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
++static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
+
+ /*
+ * Initial task structure.
+@@ -38,26 +39,12 @@
+ __attribute__((__section__(".data.init_task"))) =
+ { INIT_THREAD_INFO(init_task) };
+
+-struct task_struct *alloc_task_struct(void)
+-{
+- return((struct task_struct *)
+- __get_free_pages(GFP_KERNEL, CONFIG_KERNEL_STACK_ORDER));
+-}
+-
+ void unprotect_stack(unsigned long stack)
+ {
+ protect_memory(stack, (1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE,
+ 1, 1, 0, 1);
+ }
+
+-void free_task_struct(struct task_struct *task)
+-{
+- /* free_pages decrements the page counter and only actually frees
+- * the pages if they are now not accessed by anything.
+- */
+- free_pages((unsigned long) task, CONFIG_KERNEL_STACK_ORDER);
+-}
+-
+ /*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+Index: linux-2.6.0-test5/arch/um/kernel/irq.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/irq.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/irq.c 2003-09-27 11:38:20.227453344 +0800
+@@ -28,6 +28,7 @@
+ #include "user_util.h"
+ #include "kern_util.h"
+ #include "irq_user.h"
++#include "irq_kern.h"
+
+ static void register_irq_proc (unsigned int irq);
+
+@@ -82,65 +83,52 @@
+ end_none
+ };
+
+-/* Not changed */
+-volatile unsigned long irq_err_count;
+-
+ /*
+ * Generic, controller-independent functions:
+ */
+
+-int get_irq_list(char *buf)
++int show_interrupts(struct seq_file *p, void *v)
+ {
+ int i, j;
+- unsigned long flags;
+ struct irqaction * action;
+- char *p = buf;
++ unsigned long flags;
+
+- p += sprintf(p, " ");
+- for (j=0; j<num_online_cpus(); j++)
+- p += sprintf(p, "CPU%d ",j);
+- *p++ = '\n';
++ seq_printf(p, " ");
++ for (j=0; j<NR_CPUS; j++)
++ if (cpu_online(j))
++ seq_printf(p, "CPU%d ",j);
++ seq_putc(p, '\n');
+
+ for (i = 0 ; i < NR_IRQS ; i++) {
+ spin_lock_irqsave(&irq_desc[i].lock, flags);
+ action = irq_desc[i].action;
+ if (!action)
+- goto end;
+- p += sprintf(p, "%3d: ",i);
++ goto skip;
++ seq_printf(p, "%3d: ",i);
+ #ifndef CONFIG_SMP
+- p += sprintf(p, "%10u ", kstat_irqs(i));
++ seq_printf(p, "%10u ", kstat_irqs(i));
+ #else
+- for (j = 0; j < num_online_cpus(); j++)
+- p += sprintf(p, "%10u ",
+- kstat_cpu(cpu_logical_map(j)).irqs[i]);
++ for (j = 0; j < NR_CPUS; j++)
++ if (cpu_online(j))
++ seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+ #endif
+- p += sprintf(p, " %14s", irq_desc[i].handler->typename);
+- p += sprintf(p, " %s", action->name);
++ seq_printf(p, " %14s", irq_desc[i].handler->typename);
++ seq_printf(p, " %s", action->name);
+
+ for (action=action->next; action; action = action->next)
+- p += sprintf(p, ", %s", action->name);
+- *p++ = '\n';
+- end:
++ seq_printf(p, ", %s", action->name);
++
++ seq_putc(p, '\n');
++skip:
+ spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+ }
+- p += sprintf(p, "\n");
+-#ifdef notdef
+-#ifdef CONFIG_SMP
+- p += sprintf(p, "LOC: ");
+- for (j = 0; j < num_online_cpus(); j++)
+- p += sprintf(p, "%10u ",
+- apic_timer_irqs[cpu_logical_map(j)]);
+- p += sprintf(p, "\n");
+-#endif
+-#endif
+- p += sprintf(p, "ERR: %10lu\n", irq_err_count);
+- return p - buf;
+-}
+-
++ seq_printf(p, "NMI: ");
++ for (j = 0; j < NR_CPUS; j++)
++ if (cpu_online(j))
++ seq_printf(p, "%10u ", nmi_count(j));
++ seq_putc(p, '\n');
+
+-int show_interrupts(struct seq_file *p, void *v)
+-{
+- return(0);
++ return 0;
+ }
+
+ /*
+@@ -281,13 +269,12 @@
+ * 0 return value means that this irq is already being
+ * handled by some other CPU. (or is disabled)
+ */
+- int cpu = smp_processor_id();
+ irq_desc_t *desc = irq_desc + irq;
+ struct irqaction * action;
+ unsigned int status;
+
+ irq_enter();
+- kstat_cpu(cpu).irqs[irq]++;
++ kstat_this_cpu.irqs[irq]++;
+ spin_lock(&desc->lock);
+ desc->handler->ack(irq);
+ /*
+@@ -384,7 +371,7 @@
+ */
+
+ int request_irq(unsigned int irq,
+- void (*handler)(int, void *, struct pt_regs *),
++ irqreturn_t (*handler)(int, void *, struct pt_regs *),
+ unsigned long irqflags,
+ const char * devname,
+ void *dev_id)
+@@ -430,15 +417,19 @@
+ }
+
+ int um_request_irq(unsigned int irq, int fd, int type,
+- void (*handler)(int, void *, struct pt_regs *),
++ irqreturn_t (*handler)(int, void *, struct pt_regs *),
+ unsigned long irqflags, const char * devname,
+ void *dev_id)
+ {
+- int retval;
++ int err;
+
+- retval = request_irq(irq, handler, irqflags, devname, dev_id);
+- if(retval) return(retval);
+- return(activate_fd(irq, fd, type, dev_id));
++ err = request_irq(irq, handler, irqflags, devname, dev_id);
++ if(err)
++ return(err);
++
++ if(fd != -1)
++ err = activate_fd(irq, fd, type, dev_id);
++ return(err);
+ }
+
+ /* this was setup_x86_irq but it seems pretty generic */
+@@ -654,7 +645,7 @@
+ return -EINVAL;
+ tmp = *mask;
+ for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) {
+- int j = sprintf(page, "%04hx", cpus_coerce(tmp));
++ int j = sprintf(page, "%04hx", (short) cpus_coerce(tmp));
+ len += j;
+ page += j;
+ cpus_shift_right(tmp, tmp, 16);
+Index: linux-2.6.0-test5/arch/um/kernel/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/Makefile 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/Makefile 2003-09-27 11:38:20.228453192 +0800
+@@ -21,6 +21,8 @@
+ obj-$(CONFIG_MODE_TT) += tt/
+ obj-$(CONFIG_MODE_SKAS) += skas/
+
++clean-files := config.c
++
+ user-objs-$(CONFIG_TTY_LOG) += tty_log.o
+
+ USER_OBJS := $(filter %_user.o,$(obj-y)) $(user-objs-y) config.o helper.o \
+@@ -45,17 +47,13 @@
+ $(obj)/frame.o: $(src)/frame.c
+ $(CC) $(CFLAGS_$(notdir $@)) -c -o $@ $<
+
+-QUOTE = 'my $$config=`cat $(TOPDIR)/.config`; $$config =~ s/"/\\"/g ; while(<STDIN>) { $$_ =~ s/CONFIG/$$config/; print $$_ }'
++QUOTE = 'my $$config=`cat $(TOPDIR)/.config`; $$config =~ s/"/\\"/g ; $$config =~ s/\n/\\n"\n"/g ; while(<STDIN>) { $$_ =~ s/CONFIG/$$config/; print $$_ }'
+
+ $(obj)/config.c : $(src)/config.c.in $(TOPDIR)/.config
+ $(PERL) -e $(QUOTE) < $(src)/config.c.in > $@
+
+ $(obj)/config.o : $(obj)/config.c
+
+-clean:
+- rm -f config.c
+- for dir in $(subdir-y) ; do $(MAKE) -C $$dir clean; done
+-
+ modules:
+
+ fastdep:
+Index: linux-2.6.0-test5/arch/um/kernel/mem.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/mem.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/mem.c 2003-09-27 11:38:20.234452280 +0800
+@@ -119,11 +119,6 @@
+ return(kmem_top);
+ }
+
+-void set_kmem_end(unsigned long new)
+-{
+- kmem_top = new;
+-}
+-
+ #ifdef CONFIG_HIGHMEM
+ /* Changed during early boot */
+ pte_t *kmap_pte;
+@@ -218,7 +213,7 @@
+ if(regions[i] == NULL) break;
+ }
+ if(i == NREGIONS){
+- printk("setup_range : no free regions\n");
++ printk("setup_one_range : no free regions\n");
+ i = -1;
+ goto out;
+ }
+@@ -227,7 +222,9 @@
+ fd = create_mem_file(len);
+
+ if(region == NULL){
+- region = alloc_bootmem_low_pages(sizeof(*region));
++ if(kmalloc_ok)
++ region = kmalloc(sizeof(*region), GFP_KERNEL);
++ else region = alloc_bootmem_low_pages(sizeof(*region));
+ if(region == NULL)
+ panic("Failed to allocating mem_region");
+ }
+@@ -528,9 +525,9 @@
+ return(NREGIONS);
+ }
+
+-void setup_range(int fd, char *driver, unsigned long start, unsigned long pfn,
+- unsigned long len, int need_vm, struct mem_region *region,
+- void *reserved)
++static void setup_range(int fd, char *driver, unsigned long start,
++ unsigned long pfn, unsigned long len, int need_vm,
++ struct mem_region *region, void *reserved)
+ {
+ int i, cur;
+
+Index: linux-2.6.0-test5/arch/um/kernel/mem_user.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/mem_user.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/mem_user.c 2003-09-27 11:38:20.236451976 +0800
+@@ -111,6 +111,11 @@
+ offset = 0;
+ }
+
++ if(offset >= region->len){
++ printf("%ld bytes of physical memory is insufficient\n",
++ region->len);
++ exit(1);
++ }
+ loc = mmap(start, region->len - offset, PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_FIXED, region->fd, offset);
+ if(loc != start){
+@@ -122,26 +127,26 @@
+
+ static int __init parse_iomem(char *str, int *add)
+ {
+- struct stat buf;
++ struct stat64 buf;
+ char *file, *driver;
+ int fd;
+
+ driver = str;
+ file = strchr(str,',');
+ if(file == NULL){
+- printk("parse_iomem : failed to parse iomem\n");
++ printf("parse_iomem : failed to parse iomem\n");
+ return(1);
+ }
+ *file = '\0';
+ file++;
+ fd = os_open_file(file, of_rdwr(OPENFLAGS()), 0);
+ if(fd < 0){
+- printk("parse_iomem - Couldn't open io file, errno = %d\n",
++ printf("parse_iomem - Couldn't open io file, errno = %d\n",
+ errno);
+ return(1);
+ }
+- if(fstat(fd, &buf) < 0) {
+- printk("parse_iomem - cannot fstat file, errno = %d\n", errno);
++ if(fstat64(fd, &buf) < 0) {
++ printf("parse_iomem - cannot fstat file, errno = %d\n", errno);
+ return(1);
+ }
+ add_iomem(driver, fd, buf.st_size);
+Index: linux-2.6.0-test5/arch/um/kernel/process.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/process.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/process.c 2003-09-27 11:38:20.239451520 +0800
+@@ -72,7 +72,6 @@
+ SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
+ set_handler(SIGUSR2, (__sighandler_t) sig_handler,
+ SA_NOMASK | flags, -1);
+- (void) CHOOSE_MODE(signal(SIGCHLD, SIG_IGN), (void *) 0);
+ signal(SIGHUP, SIG_IGN);
+
+ init_irq_signals(altstack);
+@@ -127,7 +126,8 @@
+ if(err < 0) panic("Waiting for outer trampoline failed - errno = %d",
+ errno);
+ if(!WIFSIGNALED(status) || (WTERMSIG(status) != SIGKILL))
+- panic("outer trampoline didn't exit with SIGKILL");
++ panic("outer trampoline didn't exit with SIGKILL, "
++ "status = %d", status);
+
+ return(arg.pid);
+ }
+Index: linux-2.6.0-test5/arch/um/kernel/process_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/process_kern.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/process_kern.c 2003-09-27 11:38:20.241451216 +0800
+@@ -52,17 +52,12 @@
+
+ struct task_struct *get_task(int pid, int require)
+ {
+- struct task_struct *task, *ret;
++ struct task_struct *ret;
+
+- ret = NULL;
+ read_lock(&tasklist_lock);
+- for_each_process(task){
+- if(task->pid == pid){
+- ret = task;
+- break;
+- }
+- }
++ ret = find_task_by_pid(pid);
+ read_unlock(&tasklist_lock);
++
+ if(require && (ret == NULL)) panic("get_task couldn't find a task\n");
+ return(ret);
+ }
+@@ -103,13 +98,14 @@
+
+ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+ {
+- struct task_struct *p;
++ int pid;
+
+ current->thread.request.u.thread.proc = fn;
+ current->thread.request.u.thread.arg = arg;
+- p = do_fork(CLONE_VM | flags, 0, NULL, 0, NULL, NULL);
+- if(IS_ERR(p)) panic("do_fork failed in kernel_thread");
+- return(p->pid);
++ pid = do_fork(CLONE_VM | flags, 0, NULL, 0, NULL, NULL);
++ if(pid < 0)
++ panic("do_fork failed in kernel_thread, errno = %d", pid);
++ return(pid);
+ }
+
+ void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+@@ -129,7 +125,7 @@
+ { external_pid(task), task });
+ }
+
+-void *switch_to(void *prev, void *next, void *last)
++void *_switch_to(void *prev, void *next, void *last)
+ {
+ return(CHOOSE_MODE(switch_to_tt(prev, next),
+ switch_to_skas(prev, next)));
+@@ -149,7 +145,7 @@
+ void exit_thread(void)
+ {
+ CHOOSE_MODE(exit_thread_tt(), exit_thread_skas());
+- unprotect_stack((unsigned long) current->thread_info);
++ unprotect_stack((unsigned long) current_thread);
+ }
+
+ void *get_current(void)
+@@ -157,6 +153,10 @@
+ return(current);
+ }
+
++void prepare_to_copy(struct task_struct *tsk)
++{
++}
++
+ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
+ unsigned long stack_top, struct task_struct * p,
+ struct pt_regs *regs)
+@@ -190,7 +190,7 @@
+
+ void default_idle(void)
+ {
+- idle_timer();
++ uml_idle_timer();
+
+ atomic_inc(&init_mm.mm_count);
+ current->mm = &init_mm;
+@@ -363,10 +363,15 @@
+ return(clear_user(buf, size));
+ }
+
++int strlen_user_proc(char *str)
++{
++ return(strlen_user(str));
++}
++
+ int smp_sigio_handler(void)
+ {
+ #ifdef CONFIG_SMP
+- int cpu = current->thread_info->cpu;
++ int cpu = current_thread->cpu;
+ IPI_handler(cpu);
+ if(cpu != 0)
+ return(1);
+@@ -381,7 +386,7 @@
+
+ int cpu(void)
+ {
+- return(current->thread_info->cpu);
++ return(current_thread->cpu);
+ }
+
+ /*
+Index: linux-2.6.0-test5/arch/um/kernel/ptrace.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/ptrace.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/ptrace.c 2003-09-27 11:38:20.244450760 +0800
+@@ -311,11 +311,8 @@
+
+ /* the 0x80 provides a way for the tracing parent to distinguish
+ between a syscall stop and SIGTRAP delivery */
+- current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
+- ? 0x80 : 0);
+- current->state = TASK_STOPPED;
+- notify_parent(current, SIGCHLD);
+- schedule();
++ ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
++ ? 0x80 : 0));
+
+ /*
+ * this isn't the same as continuing with a signal, but it will do
+Index: linux-2.6.0-test5/arch/um/kernel/sigio_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/sigio_kern.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/sigio_kern.c 2003-09-27 11:38:20.245450608 +0800
+@@ -6,18 +6,21 @@
+ #include "linux/kernel.h"
+ #include "linux/list.h"
+ #include "linux/slab.h"
+-#include "asm/irq.h"
++#include "linux/signal.h"
++#include "linux/interrupt.h"
+ #include "init.h"
+ #include "sigio.h"
+ #include "irq_user.h"
++#include "irq_kern.h"
+
+ /* Protected by sigio_lock() called from write_sigio_workaround */
+ static int sigio_irq_fd = -1;
+
+-void sigio_interrupt(int irq, void *data, struct pt_regs *unused)
++irqreturn_t sigio_interrupt(int irq, void *data, struct pt_regs *unused)
+ {
+ read_sigio_fd(sigio_irq_fd);
+ reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ);
++ return(IRQ_HANDLED);
+ }
+
+ int write_sigio_irq(int fd)
+Index: linux-2.6.0-test5/arch/um/kernel/signal_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/signal_kern.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/signal_kern.c 2003-09-27 11:38:20.248450152 +0800
+@@ -36,7 +36,7 @@
+ if(sig == SIGSEGV){
+ struct k_sigaction *ka;
+
+- ka = ¤t->sig->action[SIGSEGV - 1];
++ ka = ¤t->sighand->action[SIGSEGV - 1];
+ ka->sa.sa_handler = SIG_DFL;
+ }
+ force_sig(SIGSEGV, current);
+@@ -142,7 +142,7 @@
+ return(0);
+
+ /* Whee! Actually deliver the signal. */
+- ka = ¤t->sig->action[sig -1 ];
++ ka = ¤t->sighand->action[sig -1 ];
+ err = handle_signal(regs, sig, ka, &info, oldset, error);
+ if(!err) return(1);
+
+@@ -201,7 +201,7 @@
+ }
+ }
+
+-int sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize)
++int sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize)
+ {
+ sigset_t saveset, newset;
+
+@@ -227,6 +227,42 @@
+ }
+ }
+
++int sys_sigaction(int sig, const struct old_sigaction __user *act,
++ struct old_sigaction __user *oact)
++{
++ struct k_sigaction new_ka, old_ka;
++ int ret;
++
++ if (act) {
++ old_sigset_t mask;
++ if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
++ __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
++ __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
++ return -EFAULT;
++ __get_user(new_ka.sa.sa_flags, &act->sa_flags);
++ __get_user(mask, &act->sa_mask);
++ siginitset(&new_ka.sa.sa_mask, mask);
++ }
++
++ ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
++
++ if (!ret && oact) {
++ if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
++ __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
++ __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
++ return -EFAULT;
++ __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
++ __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
++ }
++
++ return ret;
++}
++
++int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
++{
++ return(do_sigaltstack(uss, uoss, PT_REGS_SP(¤t->thread.regs)));
++}
++
+ static int copy_sc_from_user(struct pt_regs *to, void *from,
+ struct arch_frame_data *arch)
+ {
+@@ -239,8 +275,8 @@
+
+ int sys_sigreturn(struct pt_regs regs)
+ {
+- void *sc = sp_to_sc(PT_REGS_SP(¤t->thread.regs));
+- void *mask = sp_to_mask(PT_REGS_SP(¤t->thread.regs));
++ void __user *sc = sp_to_sc(PT_REGS_SP(¤t->thread.regs));
++ void __user *mask = sp_to_mask(PT_REGS_SP(¤t->thread.regs));
+ int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
+
+ spin_lock_irq(¤t->sighand->siglock);
+@@ -257,7 +293,8 @@
+
+ int sys_rt_sigreturn(struct pt_regs regs)
+ {
+- struct ucontext *uc = sp_to_uc(PT_REGS_SP(¤t->thread.regs));
++ unsigned long sp = PT_REGS_SP(¤t->thread.regs);
++ struct ucontext __user *uc = sp_to_uc(sp);
+ void *fp;
+ int sig_size = _NSIG_WORDS * sizeof(unsigned long);
+
+Index: linux-2.6.0-test5/arch/um/kernel/skas/include/mode.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/skas/include/mode.h 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/skas/include/mode.h 2003-09-27 11:38:20.250449848 +0800
+@@ -20,6 +20,7 @@
+ extern void halt_skas(void);
+ extern void reboot_skas(void);
+ extern void kill_off_processes_skas(void);
++extern int is_skas_winch(int pid, int fd, void *data);
+
+ #endif
+
+Index: linux-2.6.0-test5/arch/um/kernel/skas/include/uaccess.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/skas/include/uaccess.h 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/skas/include/uaccess.h 2003-09-27 11:38:20.252449544 +0800
+@@ -19,7 +19,7 @@
+ #define access_ok_skas(type, addr, size) \
+ ((segment_eq(get_fs(), KERNEL_DS)) || \
+ (((unsigned long) (addr) < TASK_SIZE) && \
+- ((unsigned long) (addr) + (size) < TASK_SIZE)))
++ ((unsigned long) (addr) + (size) <= TASK_SIZE)))
+
+ static inline int verify_area_skas(int type, const void * addr,
+ unsigned long size)
+Index: linux-2.6.0-test5/arch/um/kernel/skas/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/skas/Makefile 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/skas/Makefile 2003-09-27 11:38:20.253449392 +0800
+@@ -7,18 +7,22 @@
+ process_kern.o syscall_kern.o syscall_user.o time.o tlb.o trap_user.o \
+ sys-$(SUBARCH)/
+
++host-progs := util/mk_ptregs
++clean-files := include/skas_ptregs.h
++
+ USER_OBJS = $(filter %_user.o,$(obj-y)) process.o time.o
+ USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
+
+-include/skas_ptregs.h : util/mk_ptregs
+- util/mk_ptregs > $@
+-
+-util/mk_ptregs :
+- $(MAKE) -C util
++$(TOPDIR)/arch/um/include/skas_ptregs.h : $(src)/util/mk_ptregs
++ @echo -n ' Generating $@'
++ @$< > $@.tmp
++ @if [ -r $@ ] && cmp -s $@ $@.tmp; then \
++ echo ' (unchanged)'; \
++ rm -f $@.tmp; \
++ else \
++ echo ' (updated)'; \
++ mv -f $@.tmp $@; \
++ fi
+
+ $(USER_OBJS) : %.o: %.c
+ $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
+-
+-clean :
+- $(MAKE) -C util clean
+- $(RM) -f include/skas_ptregs.h
+Index: linux-2.6.0-test5/arch/um/kernel/skas/process.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/skas/process.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/skas/process.c 2003-09-27 11:38:20.257448784 +0800
+@@ -4,6 +4,7 @@
+ */
+
+ #include <stdlib.h>
++#include <unistd.h>
+ #include <errno.h>
+ #include <signal.h>
+ #include <setjmp.h>
+@@ -24,6 +25,16 @@
+ #include "os.h"
+ #include "proc_mm.h"
+ #include "skas_ptrace.h"
++#include "chan_user.h"
++
++int is_skas_winch(int pid, int fd, void *data)
++{
++ if(pid != getpid())
++ return(0);
++
++ register_winch_irq(-1, fd, -1, data);
++ return(1);
++}
+
+ unsigned long exec_regs[FRAME_SIZE];
+ unsigned long exec_fp_regs[HOST_FP_SIZE];
+@@ -48,11 +59,11 @@
+ int err, syscall_nr, status;
+
+ syscall_nr = PT_SYSCALL_NR(regs->skas.regs);
++ UPT_SYSCALL_NR(regs) = syscall_nr;
+ if(syscall_nr < 1){
+ relay_signal(SIGTRAP, regs);
+ return;
+ }
+- UPT_SYSCALL_NR(regs) = syscall_nr;
+
+ err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid);
+ if(err < 0)
+@@ -72,8 +83,6 @@
+ handle_syscall(regs);
+ }
+
+-int userspace_pid;
+-
+ static int userspace_tramp(void *arg)
+ {
+ init_new_thread_signals(0);
+@@ -83,6 +92,8 @@
+ return(0);
+ }
+
++int userspace_pid;
++
+ void start_userspace(void)
+ {
+ void *stack;
+@@ -149,6 +160,7 @@
+ case SIGILL:
+ case SIGBUS:
+ case SIGFPE:
++ case SIGWINCH:
+ user_signal(WSTOPSIG(status), regs);
+ break;
+ default:
+@@ -328,7 +340,8 @@
+ int new_mm(int from)
+ {
+ struct proc_mm_op copy;
+- int n, fd = os_open_file("/proc/mm", of_write(OPENFLAGS()), 0);
++ int n, fd = os_open_file("/proc/mm",
++ of_cloexec(of_write(OPENFLAGS())), 0);
+
+ if(fd < 0)
+ return(-errno);
+@@ -342,6 +355,7 @@
+ printk("new_mm : /proc/mm copy_segments failed, "
+ "errno = %d\n", errno);
+ }
++
+ return(fd);
+ }
+
+Index: linux-2.6.0-test5/arch/um/kernel/skas/process_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/skas/process_kern.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/skas/process_kern.c 2003-09-27 11:38:20.259448480 +0800
+@@ -61,9 +61,8 @@
+ thread_wait(¤t->thread.mode.skas.switch_buf,
+ current->thread.mode.skas.fork_buf);
+
+-#ifdef CONFIG_SMP
+- schedule_tail(NULL);
+-#endif
++ if(current->thread.prev_sched != NULL)
++ schedule_tail(current->thread.prev_sched);
+ current->thread.prev_sched = NULL;
+
+ n = run_kernel_thread(fn, arg, ¤t->thread.exec_buf);
+@@ -93,9 +92,8 @@
+ current->thread.mode.skas.fork_buf);
+
+ force_flush_all();
+-#ifdef CONFIG_SMP
+- schedule_tail(current->thread.prev_sched);
+-#endif
++ if(current->thread.prev_sched != NULL)
++ schedule_tail(current->thread.prev_sched);
+ current->thread.prev_sched = NULL;
+ unblock_signals();
+
+@@ -136,7 +134,7 @@
+
+ void init_idle_skas(void)
+ {
+- cpu_tasks[current->thread_info->cpu].pid = os_getpid();
++ cpu_tasks[current_thread->cpu].pid = os_getpid();
+ default_idle();
+ }
+
+@@ -164,7 +162,7 @@
+ capture_signal_stack();
+
+ init_new_thread_signals(1);
+- idle_timer();
++ uml_idle_timer();
+
+ init_task.thread.request.u.thread.proc = start_kernel_proc;
+ init_task.thread.request.u.thread.arg = NULL;
+Index: linux-2.6.0-test5/arch/um/kernel/skas/util/mk_ptregs.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/skas/util/mk_ptregs.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/skas/util/mk_ptregs.c 2003-09-27 11:38:20.261448176 +0800
+@@ -1,3 +1,4 @@
++#include <stdio.h>
+ #include <asm/ptrace.h>
+ #include <asm/user.h>
+
+Index: linux-2.6.0-test5/arch/um/kernel/smp.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/smp.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/smp.c 2003-09-27 11:38:20.264447720 +0800
+@@ -22,7 +22,7 @@
+ #include "os.h"
+
+ /* CPU online map, set by smp_boot_cpus */
+-unsigned long cpu_online_map = cpumask_of_cpu(0);
++unsigned long cpu_online_map = CPU_MASK_NONE;
+
+ /* Per CPU bogomips and other parameters
+ * The only piece used here is the ipi pipe, which is set before SMP is
+@@ -97,15 +97,15 @@
+
+ printk(KERN_INFO "Stopping all CPUs...");
+ for(i = 0; i < num_online_cpus(); i++){
+- if(i == current->thread_info->cpu)
++ if(i == current_thread->cpu)
+ continue;
+ write(cpu_data[i].ipi_pipe[1], "S", 1);
+ }
+ printk("done\n");
+ }
+
+-static cpumask_t smp_commenced_mask;
+-static cpumask_t smp_callin_map = CPU_MASK_NONE;
++static cpumask_t smp_commenced_mask = CPU_MASK_NONE;
++static cpumask_t cpu_callin_map = CPU_MASK_NONE;
+
+ static int idle_proc(void *cpup)
+ {
+@@ -120,12 +120,12 @@
+ current->thread.mode.tt.extern_pid);
+
+ wmb();
+- if (cpu_test_and_set(cpu, &smp_callin_map)) {
++ if (cpu_test_and_set(cpu, cpu_callin_map)) {
+ printk("huh, CPU#%d already present??\n", cpu);
+ BUG();
+ }
+
+- while (!cpu_isset(cpu, &smp_commenced_mask))
++ while (!cpu_isset(cpu, smp_commenced_mask))
+ cpu_relax();
+
+ cpu_set(cpu, cpu_online_map);
+@@ -140,8 +140,11 @@
+
+ current->thread.request.u.thread.proc = idle_proc;
+ current->thread.request.u.thread.arg = (void *) cpu;
+- new_task = do_fork(CLONE_VM | CLONE_IDLETASK, 0, NULL, 0, NULL, NULL);
+- if(IS_ERR(new_task)) panic("do_fork failed in idle_thread");
++ new_task = copy_process(CLONE_VM | CLONE_IDLETASK, 0, NULL, 0, NULL,
++ NULL);
++ if(IS_ERR(new_task))
++ panic("copy_process failed in idle_thread, error = %ld",
++ PTR_ERR(new_task));
+
+ cpu_tasks[cpu] = ((struct cpu_task)
+ { .pid = new_task->thread.mode.tt.extern_pid,
+@@ -150,6 +153,7 @@
+ CHOOSE_MODE(write(new_task->thread.mode.tt.switch_pipe[1], &c,
+ sizeof(c)),
+ ({ panic("skas mode doesn't support SMP"); }));
++ wake_up_forked_process(new_task);
+ return(new_task);
+ }
+
+@@ -157,15 +161,16 @@
+ {
+ struct task_struct *idle;
+ unsigned long waittime;
+- int err, cpu;
++ int err, cpu, me = smp_processor_id();
+
+- cpu_set(0, cpu_online_map);
+- cpu_set(0, smp_callin_map);
++ cpu_clear(me, cpu_online_map);
++ cpu_set(me, cpu_online_map);
++ cpu_set(me, cpu_callin_map);
+
+- err = os_pipe(cpu_data[0].ipi_pipe, 1, 1);
++ err = os_pipe(cpu_data[me].ipi_pipe, 1, 1);
+ if(err) panic("CPU#0 failed to create IPI pipe, errno = %d", -err);
+
+- activate_ipi(cpu_data[0].ipi_pipe[0],
++ activate_ipi(cpu_data[me].ipi_pipe[0],
+ current->thread.mode.tt.extern_pid);
+
+ for(cpu = 1; cpu < ncpus; cpu++){
+@@ -177,10 +182,10 @@
+ unhash_process(idle);
+
+ waittime = 200000000;
+- while (waittime-- && !cpu_isset(cpu, smp_callin_map))
++ while (waittime-- && !cpu_isset(cpu, cpu_callin_map))
+ cpu_relax();
+
+- if (cpu_isset(cpu, smp_callin_map))
++ if (cpu_isset(cpu, cpu_callin_map))
+ printk("done\n");
+ else printk("failed\n");
+ }
+@@ -270,7 +275,7 @@
+ info = _info;
+
+ for (i=0;i<NR_CPUS;i++)
+- if((i != current->thread_info->cpu) &&
++ if((i != current_thread->cpu) &&
+ cpu_isset(i, cpu_online_map))
+ write(cpu_data[i].ipi_pipe[1], "C", 1);
+
+Index: linux-2.6.0-test5/arch/um/kernel/syscall_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/syscall_kern.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/syscall_kern.c 2003-09-27 11:38:20.267447264 +0800
+@@ -35,39 +35,40 @@
+
+ long sys_fork(void)
+ {
+- struct task_struct *p;
++ long ret;
+
+ current->thread.forking = 1;
+- p = do_fork(SIGCHLD, 0, NULL, 0, NULL, NULL);
++ ret = do_fork(SIGCHLD, 0, NULL, 0, NULL, NULL);
+ current->thread.forking = 0;
+- return(IS_ERR(p) ? PTR_ERR(p) : p->pid);
++ return(ret);
+ }
+
+-long sys_clone(unsigned long clone_flags, unsigned long newsp)
++long sys_clone(unsigned long clone_flags, unsigned long newsp,
++ int *parent_tid, int *child_tid)
+ {
+- struct task_struct *p;
++ long ret;
+
+ current->thread.forking = 1;
+- p = do_fork(clone_flags, newsp, NULL, 0, NULL, NULL);
++ ret = do_fork(clone_flags, newsp, NULL, 0, parent_tid, child_tid);
+ current->thread.forking = 0;
+- return(IS_ERR(p) ? PTR_ERR(p) : p->pid);
++ return(ret);
+ }
+
+ long sys_vfork(void)
+ {
+- struct task_struct *p;
++ long ret;
+
+ current->thread.forking = 1;
+- p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0, NULL, NULL);
++ ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0, NULL,
++ NULL);
+ current->thread.forking = 0;
+- return(IS_ERR(p) ? PTR_ERR(p) : p->pid);
++ return(ret);
+ }
+
+ /* common code for old and new mmaps */
+-static inline long do_mmap2(
+- unsigned long addr, unsigned long len,
+- unsigned long prot, unsigned long flags,
+- unsigned long fd, unsigned long pgoff)
++long do_mmap2(struct mm_struct *mm, unsigned long addr, unsigned long len,
++ unsigned long prot, unsigned long flags, unsigned long fd,
++ unsigned long pgoff)
+ {
+ int error = -EBADF;
+ struct file * file = NULL;
+@@ -93,7 +94,7 @@
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long pgoff)
+ {
+- return do_mmap2(addr, len, prot, flags, fd, pgoff);
++ return do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
+ }
+
+ /*
+@@ -120,7 +121,8 @@
+ if (offset & ~PAGE_MASK)
+ goto out;
+
+- err = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
++ err = do_mmap2(current->mm, addr, len, prot, flags, fd,
++ offset >> PAGE_SHIFT);
+ out:
+ return err;
+ }
+@@ -141,37 +143,6 @@
+ return error;
+ }
+
+-int sys_sigaction(int sig, const struct old_sigaction *act,
+- struct old_sigaction *oact)
+-{
+- struct k_sigaction new_ka, old_ka;
+- int ret;
+-
+- if (act) {
+- old_sigset_t mask;
+- if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
+- __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+- __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+- return -EFAULT;
+- __get_user(new_ka.sa.sa_flags, &act->sa_flags);
+- __get_user(mask, &act->sa_mask);
+- siginitset(&new_ka.sa.sa_mask, mask);
+- }
+-
+- ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+-
+- if (!ret && oact) {
+- if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
+- __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+- __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+- return -EFAULT;
+- __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+- __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+- }
+-
+- return ret;
+-}
+-
+ /*
+ * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+ *
+@@ -253,7 +224,7 @@
+ return sys_shmctl (first, second,
+ (struct shmid_ds *) ptr);
+ default:
+- return -EINVAL;
++ return -ENOSYS;
+ }
+ }
+
+@@ -302,11 +273,6 @@
+ return error;
+ }
+
+-int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
+-{
+- return(do_sigaltstack(uss, uoss, PT_REGS_SP(¤t->thread.regs)));
+-}
+-
+ long execute_syscall(void *r)
+ {
+ return(CHOOSE_MODE_PROC(execute_syscall_tt, execute_syscall_skas, r));
+Index: linux-2.6.0-test5/arch/um/kernel/sys_call_table.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/sys_call_table.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/sys_call_table.c 2003-09-27 11:38:20.273446352 +0800
+@@ -219,15 +219,30 @@
+ extern syscall_handler_t sys_gettid;
+ extern syscall_handler_t sys_readahead;
+ extern syscall_handler_t sys_tkill;
++extern syscall_handler_t sys_setxattr;
++extern syscall_handler_t sys_lsetxattr;
++extern syscall_handler_t sys_fsetxattr;
++extern syscall_handler_t sys_getxattr;
++extern syscall_handler_t sys_lgetxattr;
++extern syscall_handler_t sys_fgetxattr;
++extern syscall_handler_t sys_listxattr;
++extern syscall_handler_t sys_llistxattr;
++extern syscall_handler_t sys_flistxattr;
++extern syscall_handler_t sys_removexattr;
++extern syscall_handler_t sys_lremovexattr;
++extern syscall_handler_t sys_fremovexattr;
+ extern syscall_handler_t sys_sendfile64;
+ extern syscall_handler_t sys_futex;
+ extern syscall_handler_t sys_sched_setaffinity;
+ extern syscall_handler_t sys_sched_getaffinity;
++extern syscall_handler_t sys_set_thread_area;
++extern syscall_handler_t sys_get_thread_area;
+ extern syscall_handler_t sys_io_setup;
+ extern syscall_handler_t sys_io_destroy;
+ extern syscall_handler_t sys_io_getevents;
+ extern syscall_handler_t sys_io_submit;
+ extern syscall_handler_t sys_io_cancel;
++extern syscall_handler_t sys_fadvise64;
+ extern syscall_handler_t sys_exit_group;
+ extern syscall_handler_t sys_lookup_dcookie;
+ extern syscall_handler_t sys_epoll_create;
+@@ -235,6 +250,20 @@
+ extern syscall_handler_t sys_epoll_wait;
+ extern syscall_handler_t sys_remap_file_pages;
+ extern syscall_handler_t sys_set_tid_address;
++extern syscall_handler_t sys_timer_create;
++extern syscall_handler_t sys_timer_settime;
++extern syscall_handler_t sys_timer_gettime;
++extern syscall_handler_t sys_timer_getoverrun;
++extern syscall_handler_t sys_timer_delete;
++extern syscall_handler_t sys_clock_settime;
++extern syscall_handler_t sys_clock_gettime;
++extern syscall_handler_t sys_clock_getres;
++extern syscall_handler_t sys_clock_nanosleep;
++extern syscall_handler_t sys_statfs64;
++extern syscall_handler_t sys_fstatfs64;
++extern syscall_handler_t sys_tgkill;
++extern syscall_handler_t sys_utimes;
++extern syscall_handler_t sys_fadvise64_64;
+
+ #ifdef CONFIG_NFSD
+ #define NFSSERVCTL sys_nfsservctl
+@@ -246,7 +275,7 @@
+ extern syscall_handler_t um_time;
+ extern syscall_handler_t um_stime;
+
+-#define LAST_GENERIC_SYSCALL __NR_set_tid_address
++#define LAST_GENERIC_SYSCALL __NR_fadvise64_64
+
+ #if LAST_GENERIC_SYSCALL > LAST_ARCH_SYSCALL
+ #define LAST_SYSCALL LAST_GENERIC_SYSCALL
+@@ -455,32 +484,37 @@
+ [ __NR_stat64 ] = sys_stat64,
+ [ __NR_lstat64 ] = sys_lstat64,
+ [ __NR_fstat64 ] = sys_fstat64,
+- [ __NR_fcntl64 ] = sys_fcntl64,
+ [ __NR_getdents64 ] = sys_getdents64,
++ [ __NR_fcntl64 ] = sys_fcntl64,
++ [ 223 ] = sys_ni_syscall,
+ [ __NR_gettid ] = sys_gettid,
+ [ __NR_readahead ] = sys_readahead,
+- [ __NR_setxattr ] = sys_ni_syscall,
+- [ __NR_lsetxattr ] = sys_ni_syscall,
+- [ __NR_fsetxattr ] = sys_ni_syscall,
+- [ __NR_getxattr ] = sys_ni_syscall,
+- [ __NR_lgetxattr ] = sys_ni_syscall,
+- [ __NR_fgetxattr ] = sys_ni_syscall,
+- [ __NR_listxattr ] = sys_ni_syscall,
+- [ __NR_llistxattr ] = sys_ni_syscall,
+- [ __NR_flistxattr ] = sys_ni_syscall,
+- [ __NR_removexattr ] = sys_ni_syscall,
+- [ __NR_lremovexattr ] = sys_ni_syscall,
+- [ __NR_fremovexattr ] = sys_ni_syscall,
++ [ __NR_setxattr ] = sys_setxattr,
++ [ __NR_lsetxattr ] = sys_lsetxattr,
++ [ __NR_fsetxattr ] = sys_fsetxattr,
++ [ __NR_getxattr ] = sys_getxattr,
++ [ __NR_lgetxattr ] = sys_lgetxattr,
++ [ __NR_fgetxattr ] = sys_fgetxattr,
++ [ __NR_listxattr ] = sys_listxattr,
++ [ __NR_llistxattr ] = sys_llistxattr,
++ [ __NR_flistxattr ] = sys_flistxattr,
++ [ __NR_removexattr ] = sys_removexattr,
++ [ __NR_lremovexattr ] = sys_lremovexattr,
++ [ __NR_fremovexattr ] = sys_fremovexattr,
+ [ __NR_tkill ] = sys_tkill,
+ [ __NR_sendfile64 ] = sys_sendfile64,
+ [ __NR_futex ] = sys_futex,
+ [ __NR_sched_setaffinity ] = sys_sched_setaffinity,
+ [ __NR_sched_getaffinity ] = sys_sched_getaffinity,
++ [ __NR_set_thread_area ] = sys_ni_syscall,
++ [ __NR_get_thread_area ] = sys_ni_syscall,
+ [ __NR_io_setup ] = sys_io_setup,
+ [ __NR_io_destroy ] = sys_io_destroy,
+ [ __NR_io_getevents ] = sys_io_getevents,
+ [ __NR_io_submit ] = sys_io_submit,
+ [ __NR_io_cancel ] = sys_io_cancel,
++ [ __NR_fadvise64 ] = sys_fadvise64,
++ [ 251 ] = sys_ni_syscall,
+ [ __NR_exit_group ] = sys_exit_group,
+ [ __NR_lookup_dcookie ] = sys_lookup_dcookie,
+ [ __NR_epoll_create ] = sys_epoll_create,
+@@ -488,6 +522,20 @@
+ [ __NR_epoll_wait ] = sys_epoll_wait,
+ [ __NR_remap_file_pages ] = sys_remap_file_pages,
+ [ __NR_set_tid_address ] = sys_set_tid_address,
++ [ __NR_timer_create ] = sys_timer_create,
++ [ __NR_timer_settime ] = sys_timer_settime,
++ [ __NR_timer_gettime ] = sys_timer_gettime,
++ [ __NR_timer_getoverrun ] = sys_timer_getoverrun,
++ [ __NR_timer_delete ] = sys_timer_delete,
++ [ __NR_clock_settime ] = sys_clock_settime,
++ [ __NR_clock_gettime ] = sys_clock_gettime,
++ [ __NR_clock_getres ] = sys_clock_getres,
++ [ __NR_clock_nanosleep ] = sys_clock_nanosleep,
++ [ __NR_statfs64 ] = sys_statfs64,
++ [ __NR_fstatfs64 ] = sys_fstatfs64,
++ [ __NR_tgkill ] = sys_tgkill,
++ [ __NR_utimes ] = sys_utimes,
++ [ __NR_fadvise64_64 ] = sys_fadvise64_64,
+
+ ARCH_SYSCALLS
+ [ LAST_SYSCALL + 1 ... NR_syscalls ] =
+Index: linux-2.6.0-test5/arch/um/kernel/sysrq.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/sysrq.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/sysrq.c 2003-09-27 11:38:20.274446200 +0800
+@@ -53,6 +53,14 @@
+ show_trace((unsigned long *)esp);
+ }
+
++void show_stack(struct task_struct *task, unsigned long *sp)
++{
++ if(task)
++ show_trace_task(task);
++ else
++ show_trace(sp);
++}
++
+ /*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+Index: linux-2.6.0-test5/arch/um/kernel/time.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/time.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/time.c 2003-09-27 11:38:20.276445896 +0800
+@@ -15,12 +15,16 @@
+ #include "process.h"
+ #include "signal_user.h"
+ #include "time_user.h"
++#include "kern_constants.h"
+
+ extern struct timeval xtime;
+
++struct timeval local_offset = { 0, 0 };
++
+ void timer(void)
+ {
+ gettimeofday(&xtime, NULL);
++ timeradd(&xtime, &local_offset, &xtime);
+ }
+
+ void set_interval(int timer_type)
+@@ -65,7 +69,7 @@
+ errno);
+ }
+
+-void idle_timer(void)
++void uml_idle_timer(void)
+ {
+ if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR)
+ panic("Couldn't unset SIGVTALRM handler");
+@@ -82,8 +86,6 @@
+ set_interval(ITIMER_VIRTUAL);
+ }
+
+-struct timeval local_offset = { 0, 0 };
+-
+ void do_gettimeofday(struct timeval *tv)
+ {
+ unsigned long flags;
+@@ -100,7 +102,7 @@
+ unsigned long flags;
+ struct timeval tv_in;
+
+- if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
++ if ((unsigned long) tv->tv_nsec >= UM_NSEC_PER_SEC)
+ return -EINVAL;
+
+ tv_in.tv_sec = tv->tv_sec;
+@@ -110,6 +112,8 @@
+ gettimeofday(&now, NULL);
+ timersub(&tv_in, &now, &local_offset);
+ time_unlock(flags);
++
++ return(0);
+ }
+
+ void idle_sleep(int secs)
+Index: linux-2.6.0-test5/arch/um/kernel/time_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/time_kern.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/time_kern.c 2003-09-27 11:38:20.277445744 +0800
+@@ -38,7 +38,7 @@
+
+ void timer_irq(union uml_pt_regs *regs)
+ {
+- int cpu = current->thread_info->cpu, ticks = missed_ticks[cpu];
++ int cpu = current_thread->cpu, ticks = missed_ticks[cpu];
+
+ if(!timer_irq_inited) return;
+ missed_ticks[cpu] = 0;
+@@ -55,12 +55,13 @@
+ do_timer(®s);
+ }
+
+-void um_timer(int irq, void *dev, struct pt_regs *regs)
++irqreturn_t um_timer(int irq, void *dev, struct pt_regs *regs)
+ {
+ do_timer(regs);
+- write_seqlock(&xtime_lock);
++ write_seqlock_irq(&xtime_lock);
+ timer();
+- write_sequnlock(&xtime_lock);
++ write_sequnlock_irq(&xtime_lock);
++ return(IRQ_HANDLED);
+ }
+
+ long um_time(int * tloc)
+@@ -78,12 +79,12 @@
+ long um_stime(int * tptr)
+ {
+ int value;
+- struct timeval new;
++ struct timespec new;
+
+ if (get_user(value, tptr))
+ return -EFAULT;
+ new.tv_sec = value;
+- new.tv_usec = 0;
++ new.tv_nsec = 0;
+ do_settimeofday(&new);
+ return 0;
+ }
+@@ -122,9 +123,11 @@
+ void timer_handler(int sig, union uml_pt_regs *regs)
+ {
+ #ifdef CONFIG_SMP
++ local_irq_disable();
+ update_process_times(user_context(UPT_SP(regs)));
++ local_irq_enable();
+ #endif
+- if(current->thread_info->cpu == 0)
++ if(current_thread->cpu == 0)
+ timer_irq(regs);
+ }
+
+Index: linux-2.6.0-test5/arch/um/kernel/trap_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/trap_kern.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/trap_kern.c 2003-09-27 11:38:20.280445288 +0800
+@@ -16,6 +16,7 @@
+ #include "asm/tlbflush.h"
+ #include "asm/a.out.h"
+ #include "asm/current.h"
++#include "asm/irq.h"
+ #include "user_util.h"
+ #include "kern_util.h"
+ #include "kern.h"
+@@ -51,7 +52,7 @@
+ if(is_write && !(vma->vm_flags & VM_WRITE))
+ goto out;
+ page = address & PAGE_MASK;
+- if(page == (unsigned long) current->thread_info + PAGE_SIZE)
++ if(page == (unsigned long) current_thread + PAGE_SIZE)
+ panic("Kernel stack overflow");
+ pgd = pgd_offset(mm, page);
+ pmd = pmd_offset(pgd, page);
+@@ -180,6 +181,11 @@
+ else relay_signal(sig, regs);
+ }
+
++void winch(int sig, union uml_pt_regs *regs)
++{
++ do_IRQ(WINCH_IRQ, regs);
++}
++
+ void trap_init(void)
+ {
+ }
+Index: linux-2.6.0-test5/arch/um/kernel/trap_user.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/trap_user.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/trap_user.c 2003-09-27 11:38:20.281445136 +0800
+@@ -82,6 +82,8 @@
+ .is_irq = 0 },
+ [ SIGILL ] { .handler = relay_signal,
+ .is_irq = 0 },
++ [ SIGWINCH ] { .handler = winch,
++ .is_irq = 1 },
+ [ SIGBUS ] { .handler = bus_handler,
+ .is_irq = 0 },
+ [ SIGSEGV] { .handler = segv_handler,
+Index: linux-2.6.0-test5/arch/um/kernel/tt/exec_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/tt/exec_kern.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/tt/exec_kern.c 2003-09-27 11:38:20.283444832 +0800
+@@ -47,17 +47,17 @@
+ do_exit(SIGKILL);
+ }
+
+- if(current->thread_info->cpu == 0)
++ if(current_thread->cpu == 0)
+ forward_interrupts(new_pid);
+ current->thread.request.op = OP_EXEC;
+ current->thread.request.u.exec.pid = new_pid;
+- unprotect_stack((unsigned long) current->thread_info);
++ unprotect_stack((unsigned long) current_thread);
+ os_usr1_process(os_getpid());
+
+ enable_timer();
+ free_page(stack);
+ protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 1, 0, 1);
+- task_protections((unsigned long) current->thread_info);
++ task_protections((unsigned long) current_thread);
+ force_flush_all();
+ unblock_signals();
+ }
+Index: linux-2.6.0-test5/arch/um/kernel/tt/include/uaccess.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/tt/include/uaccess.h 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/tt/include/uaccess.h 2003-09-27 11:38:20.284444680 +0800
+@@ -46,18 +46,20 @@
+
+ static inline int copy_from_user_tt(void *to, const void *from, int n)
+ {
+- return(access_ok_tt(VERIFY_READ, from, n) ?
+- __do_copy_from_user(to, from, n,
+- ¤t->thread.fault_addr,
+- ¤t->thread.fault_catcher) : n);
++ if(!access_ok_tt(VERIFY_READ, from, n))
++ return(n);
++
++ return(__do_copy_from_user(to, from, n, ¤t->thread.fault_addr,
++ ¤t->thread.fault_catcher));
+ }
+
+ static inline int copy_to_user_tt(void *to, const void *from, int n)
+ {
+- return(access_ok_tt(VERIFY_WRITE, to, n) ?
+- __do_copy_to_user(to, from, n,
+- ¤t->thread.fault_addr,
+- ¤t->thread.fault_catcher) : n);
++ if(!access_ok_tt(VERIFY_WRITE, to, n))
++ return(n);
++
++ return(__do_copy_to_user(to, from, n, ¤t->thread.fault_addr,
++ ¤t->thread.fault_catcher));
+ }
+
+ extern int __do_strncpy_from_user(char *dst, const char *src, size_t n,
+@@ -67,7 +69,9 @@
+ {
+ int n;
+
+- if(!access_ok_tt(VERIFY_READ, src, 1)) return(-EFAULT);
++ if(!access_ok_tt(VERIFY_READ, src, 1))
++ return(-EFAULT);
++
+ n = __do_strncpy_from_user(dst, src, count,
+ ¤t->thread.fault_addr,
+ ¤t->thread.fault_catcher);
+@@ -87,10 +91,11 @@
+
+ static inline int clear_user_tt(void *mem, int len)
+ {
+- return(access_ok_tt(VERIFY_WRITE, mem, len) ?
+- __do_clear_user(mem, len,
+- ¤t->thread.fault_addr,
+- ¤t->thread.fault_catcher) : len);
++ if(!access_ok_tt(VERIFY_WRITE, mem, len))
++ return(len);
++
++ return(__do_clear_user(mem, len, ¤t->thread.fault_addr,
++ ¤t->thread.fault_catcher));
+ }
+
+ extern int __do_strnlen_user(const char *str, unsigned long n,
+Index: linux-2.6.0-test5/arch/um/kernel/tt/process_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/tt/process_kern.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/tt/process_kern.c 2003-09-27 11:38:20.289443920 +0800
+@@ -104,7 +104,10 @@
+
+ void release_thread_tt(struct task_struct *task)
+ {
+- os_kill_process(task->thread.mode.tt.extern_pid, 0);
++ int pid = task->thread.mode.tt.extern_pid;
++
++ if(os_getpid() != pid)
++ os_kill_process(pid, 0);
+ }
+
+ void exit_thread_tt(void)
+@@ -125,27 +128,27 @@
+ UPT_SC(¤t->thread.regs.regs) = (void *) (&sig + 1);
+ suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
+
+- block_signals();
++ force_flush_all();
++ if(current->thread.prev_sched != NULL)
++ schedule_tail(current->thread.prev_sched);
++ current->thread.prev_sched = NULL;
++
+ init_new_thread_signals(1);
+-#ifdef CONFIG_SMP
+- schedule_tail(current->thread.prev_sched);
+-#endif
+ enable_timer();
+ free_page(current->thread.temp_stack);
+ set_cmdline("(kernel thread)");
+- force_flush_all();
+
+- current->thread.prev_sched = NULL;
+ change_sig(SIGUSR1, 1);
+ change_sig(SIGVTALRM, 1);
+ change_sig(SIGPROF, 1);
+- unblock_signals();
++ local_irq_enable();
+ if(!run_kernel_thread(fn, arg, ¤t->thread.exec_buf))
+ do_exit(0);
+ }
+
+ static int new_thread_proc(void *stack)
+ {
++ local_irq_disable();
+ init_new_thread_stack(stack, new_thread_handler);
+ os_usr1_process(os_getpid());
+ return(0);
+@@ -165,35 +168,32 @@
+ UPT_SC(¤t->thread.regs.regs) = (void *) (&sig + 1);
+ suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
+
+-#ifdef CONFIG_SMP
+- schedule_tail(NULL);
+-#endif
++ force_flush_all();
++ if(current->thread.prev_sched != NULL)
++ schedule_tail(current->thread.prev_sched);
++ current->thread.prev_sched = NULL;
++
+ enable_timer();
+ change_sig(SIGVTALRM, 1);
+ local_irq_enable();
+- force_flush_all();
+ if(current->mm != current->parent->mm)
+ protect_memory(uml_reserved, high_physmem - uml_reserved, 1,
+ 1, 0, 1);
+- task_protections((unsigned long) current->thread_info);
+-
+- current->thread.prev_sched = NULL;
++ task_protections((unsigned long) current_thread);
+
+ free_page(current->thread.temp_stack);
++ local_irq_disable();
+ change_sig(SIGUSR1, 0);
+ set_user_mode(current);
+ }
+
+-static int sigusr1 = SIGUSR1;
+-
+ int fork_tramp(void *stack)
+ {
+- int sig = sigusr1;
+-
+ local_irq_disable();
++ arch_init_thread();
+ init_new_thread_stack(stack, finish_fork_handler);
+
+- kill(os_getpid(), sig);
++ os_usr1_process(os_getpid());
+ return(0);
+ }
+
+@@ -377,8 +377,8 @@
+
+ pages = (1 << CONFIG_KERNEL_STACK_ORDER);
+
+- start = (unsigned long) current->thread_info + PAGE_SIZE;
+- end = (unsigned long) current + PAGE_SIZE * pages;
++ start = (unsigned long) current_thread + PAGE_SIZE;
++ end = (unsigned long) current_thread + PAGE_SIZE * pages;
+ protect_memory(uml_reserved, start - uml_reserved, 1, w, 1, 1);
+ protect_memory(end, high_physmem - end, 1, w, 1, 1);
+
+Index: linux-2.6.0-test5/arch/um/kernel/tt/ptproxy/proxy.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/tt/ptproxy/proxy.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/tt/ptproxy/proxy.c 2003-09-27 11:38:20.292443464 +0800
+@@ -293,10 +293,10 @@
+ }
+
+ char gdb_init_string[] =
+-"att 1
+-b panic
+-b stop
+-handle SIGWINCH nostop noprint pass
++"att 1 \n\
++b panic \n\
++b stop \n\
++handle SIGWINCH nostop noprint pass \n\
+ ";
+
+ int start_debugger(char *prog, int startup, int stop, int *fd_out)
+Index: linux-2.6.0-test5/arch/um/kernel/tt/tracer.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/tt/tracer.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/tt/tracer.c 2003-09-27 11:38:20.296442856 +0800
+@@ -39,7 +39,7 @@
+ return(0);
+
+ register_winch_irq(tracer_winch[0], fd, -1, data);
+- return(0);
++ return(1);
+ }
+
+ static void tracer_winch_handler(int sig)
+@@ -401,7 +401,7 @@
+
+ if(!strcmp(line, "go")) debug_stop = 0;
+ else if(!strcmp(line, "parent")) debug_parent = 1;
+- else printk("Unknown debug option : '%s'\n", line);
++ else printf("Unknown debug option : '%s'\n", line);
+
+ line = next;
+ }
+Index: linux-2.6.0-test5/arch/um/kernel/tt/uaccess_user.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/tt/uaccess_user.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/tt/uaccess_user.c 2003-09-27 11:38:20.297442704 +0800
+@@ -8,15 +8,20 @@
+ #include <string.h>
+ #include "user_util.h"
+ #include "uml_uaccess.h"
++#include "task.h"
++#include "kern_util.h"
+
+ int __do_copy_from_user(void *to, const void *from, int n,
+ void **fault_addr, void **fault_catcher)
+ {
++ struct tt_regs save = TASK_REGS(get_current())->tt;
+ unsigned long fault;
+ int faulted;
+
+ fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
+ __do_copy, &faulted);
++ TASK_REGS(get_current())->tt = save;
++
+ if(!faulted) return(0);
+ else return(n - (fault - (unsigned long) from));
+ }
+@@ -29,11 +34,14 @@
+ int __do_strncpy_from_user(char *dst, const char *src, unsigned long count,
+ void **fault_addr, void **fault_catcher)
+ {
++ struct tt_regs save = TASK_REGS(get_current())->tt;
+ unsigned long fault;
+ int faulted;
+
+ fault = __do_user_copy(dst, src, count, fault_addr, fault_catcher,
+ __do_strncpy, &faulted);
++ TASK_REGS(get_current())->tt = save;
++
+ if(!faulted) return(strlen(dst));
+ else return(-1);
+ }
+@@ -46,11 +54,14 @@
+ int __do_clear_user(void *mem, unsigned long len,
+ void **fault_addr, void **fault_catcher)
+ {
++ struct tt_regs save = TASK_REGS(get_current())->tt;
+ unsigned long fault;
+ int faulted;
+
+ fault = __do_user_copy(mem, NULL, len, fault_addr, fault_catcher,
+ __do_clear, &faulted);
++ TASK_REGS(get_current())->tt = save;
++
+ if(!faulted) return(0);
+ else return(len - (fault - (unsigned long) mem));
+ }
+@@ -58,6 +69,7 @@
+ int __do_strnlen_user(const char *str, unsigned long n,
+ void **fault_addr, void **fault_catcher)
+ {
++ struct tt_regs save = TASK_REGS(get_current())->tt;
+ int ret;
+ unsigned long *faddrp = (unsigned long *)fault_addr;
+ jmp_buf jbuf;
+@@ -71,6 +83,8 @@
+ }
+ *fault_addr = NULL;
+ *fault_catcher = NULL;
++
++ TASK_REGS(get_current())->tt = save;
+ return ret;
+ }
+
+Index: linux-2.6.0-test5/arch/um/kernel/um_arch.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/um_arch.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/um_arch.c 2003-09-27 11:38:20.301442096 +0800
+@@ -38,13 +38,18 @@
+ #include "mode_kern.h"
+ #include "mode.h"
+
+-#define DEFAULT_COMMAND_LINE "root=6200"
++#define DEFAULT_COMMAND_LINE "root=ubd0"
+
+ struct cpuinfo_um boot_cpu_data = {
+ .loops_per_jiffy = 0,
+ .ipi_pipe = { -1, -1 }
+ };
+
++/* Placeholder to make UML link until the vsyscall stuff is actually
++ * implemented
++ */
++void *__kernel_vsyscall;
++
+ unsigned long thread_saved_pc(struct task_struct *task)
+ {
+ return(os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas,
+@@ -61,10 +66,14 @@
+ return 0;
+ #endif
+
+- seq_printf(m, "bogomips\t: %lu.%02lu\n",
++ seq_printf(m, "processor\t: %d\n", index);
++ seq_printf(m, "vendor_id\t: User Mode Linux\n");
++ seq_printf(m, "model name\t: UML\n");
++ seq_printf(m, "mode\t\t: %s\n", CHOOSE_MODE("tt", "skas"));
++ seq_printf(m, "host\t\t: %s\n", host_info);
++ seq_printf(m, "bogomips\t: %lu.%02lu\n\n",
+ loops_per_jiffy/(500000/HZ),
+ (loops_per_jiffy/(5000/HZ)) % 100);
+- seq_printf(m, "host\t\t: %s\n", host_info);
+
+ return(0);
+ }
+@@ -134,12 +143,12 @@
+ if(umid != NULL){
+ snprintf(argv1_begin,
+ (argv1_end - argv1_begin) * sizeof(*ptr),
+- "(%s)", umid);
++ "(%s) ", umid);
+ ptr = &argv1_begin[strlen(argv1_begin)];
+ }
+ else ptr = argv1_begin;
+
+- snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), " [%s]", cmd);
++ snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), "[%s]", cmd);
+ memset(argv1_begin + strlen(argv1_begin), '\0',
+ argv1_end - argv1_begin - strlen(argv1_begin));
+ #endif
+@@ -179,7 +188,7 @@
+ static int __init uml_ncpus_setup(char *line, int *add)
+ {
+ if (!sscanf(line, "%d", &ncpus)) {
+- printk("Couldn't parse [%s]\n", line);
++ printf("Couldn't parse [%s]\n", line);
+ return -1;
+ }
+
+@@ -210,7 +219,7 @@
+
+ static int __init mode_tt_setup(char *line, int *add)
+ {
+- printk("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
++ printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
+ return(0);
+ }
+
+@@ -221,7 +230,7 @@
+
+ static int __init mode_tt_setup(char *line, int *add)
+ {
+- printk("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
++ printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
+ return(0);
+ }
+
+@@ -369,6 +378,7 @@
+ 2 * PAGE_SIZE;
+
+ task_protections((unsigned long) &init_thread_info);
++ os_flush_stdout();
+
+ return(CHOOSE_MODE(start_uml_tt(), start_uml_skas()));
+ }
+Index: linux-2.6.0-test5/arch/um/kernel/umid.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/umid.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/umid.c 2003-09-27 11:38:20.303441792 +0800
+@@ -33,18 +33,19 @@
+ static int umid_is_random = 1;
+ static int umid_inited = 0;
+
+-static int make_umid(void);
++static int make_umid(int (*printer)(const char *fmt, ...));
+
+-static int __init set_umid(char *name, int is_random)
++static int __init set_umid(char *name, int is_random,
++ int (*printer)(const char *fmt, ...))
+ {
+ if(umid_inited){
+- printk("Unique machine name can't be set twice\n");
++ (*printer)("Unique machine name can't be set twice\n");
+ return(-1);
+ }
+
+ if(strlen(name) > UMID_LEN - 1)
+- printk("Unique machine name is being truncated to %s "
+- "characters\n", UMID_LEN);
++ (*printer)("Unique machine name is being truncated to %s "
++ "characters\n", UMID_LEN);
+ strlcpy(umid, name, sizeof(umid));
+
+ umid_is_random = is_random;
+@@ -54,7 +55,7 @@
+
+ static int __init set_umid_arg(char *name, int *add)
+ {
+- return(set_umid(name, 0));
++ return(set_umid(name, 0, printf));
+ }
+
+ __uml_setup("umid=", set_umid_arg,
+@@ -67,7 +68,7 @@
+ {
+ int n;
+
+- if(!umid_inited && make_umid()) return(-1);
++ if(!umid_inited && make_umid(printk)) return(-1);
+
+ n = strlen(uml_dir) + strlen(umid) + strlen(name) + 1;
+ if(n > len){
+@@ -92,14 +93,14 @@
+ fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))),
+ 0644);
+ if(fd < 0){
+- printk("Open of machine pid file \"%s\" failed - "
++ printf("Open of machine pid file \"%s\" failed - "
+ "errno = %d\n", file, -fd);
+ return 0;
+ }
+
+ sprintf(pid, "%d\n", os_getpid());
+ if(write(fd, pid, strlen(pid)) != strlen(pid))
+- printk("Write of pid file failed - errno = %d\n", errno);
++ printf("Write of pid file failed - errno = %d\n", errno);
+ close(fd);
+ return 0;
+ }
+@@ -197,7 +198,7 @@
+ if((strlen(name) > 0) && (name[strlen(name) - 1] != '/')){
+ uml_dir = malloc(strlen(name) + 1);
+ if(uml_dir == NULL){
+- printk("Failed to malloc uml_dir - error = %d\n",
++ printf("Failed to malloc uml_dir - error = %d\n",
+ errno);
+ uml_dir = name;
+ return(0);
+@@ -217,7 +218,7 @@
+ char *home = getenv("HOME");
+
+ if(home == NULL){
+- printk("make_uml_dir : no value in environment for "
++ printf("make_uml_dir : no value in environment for "
+ "$HOME\n");
+ exit(1);
+ }
+@@ -239,25 +240,25 @@
+ strcpy(uml_dir, dir);
+
+ if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){
+- printk("Failed to mkdir %s - errno = %i\n", uml_dir, errno);
++ printf("Failed to mkdir %s - errno = %i\n", uml_dir, errno);
+ return(-1);
+ }
+ return 0;
+ }
+
+-static int __init make_umid(void)
++static int __init make_umid(int (*printer)(const char *fmt, ...))
+ {
+ int fd, err;
+ char tmp[strlen(uml_dir) + UMID_LEN + 1];
+
+ strlcpy(tmp, uml_dir, sizeof(tmp));
+
+- if(*umid == 0){
++ if(!umid_inited){
+ strcat(tmp, "XXXXXX");
+ fd = mkstemp(tmp);
+ if(fd < 0){
+- printk("make_umid - mkstemp failed, errno = %d\n",
+- errno);
++ (*printer)("make_umid - mkstemp failed, errno = %d\n",
++ errno);
+ return(1);
+ }
+
+@@ -267,7 +268,7 @@
+ * for directories.
+ */
+ unlink(tmp);
+- set_umid(&tmp[strlen(uml_dir)], 1);
++ set_umid(&tmp[strlen(uml_dir)], 1, printer);
+ }
+
+ sprintf(tmp, "%s%s", uml_dir, umid);
+@@ -275,14 +276,14 @@
+ if((err = mkdir(tmp, 0777)) < 0){
+ if(errno == EEXIST){
+ if(not_dead_yet(tmp)){
+- printk("umid '%s' is in use\n", umid);
++ (*printer)("umid '%s' is in use\n", umid);
+ return(-1);
+ }
+ err = mkdir(tmp, 0777);
+ }
+ }
+ if(err < 0){
+- printk("Failed to create %s - errno = %d\n", umid, errno);
++ (*printer)("Failed to create %s - errno = %d\n", umid, errno);
+ return(-1);
+ }
+
+@@ -295,7 +296,13 @@
+ );
+
+ __uml_postsetup(make_uml_dir);
+-__uml_postsetup(make_umid);
++
++static int __init make_umid_setup(void)
++{
++ return(make_umid(printf));
++}
++
++__uml_postsetup(make_umid_setup);
+ __uml_postsetup(create_pid_file);
+
+ /*
+Index: linux-2.6.0-test5/arch/um/kernel/user_util.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/user_util.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/user_util.c 2003-09-27 11:38:20.306441336 +0800
+@@ -119,17 +119,6 @@
+ }
+ }
+
+-int clone_and_wait(int (*fn)(void *), void *arg, void *sp, int flags)
+-{
+- int pid;
+-
+- pid = clone(fn, sp, flags, arg);
+- if(pid < 0) return(-1);
+- wait_for_stop(pid, SIGSTOP, PTRACE_CONT, NULL);
+- ptrace(PTRACE_CONT, pid, 0, 0);
+- return(pid);
+-}
+-
+ int raw(int fd, int complain)
+ {
+ struct termios tt;
+Index: linux-2.6.0-test5/arch/um/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/Makefile 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/Makefile 2003-09-27 11:38:20.309440880 +0800
+@@ -24,15 +24,17 @@
+ # Have to precede the include because the included Makefiles reference them.
+ SYMLINK_HEADERS = include/asm-um/archparam.h include/asm-um/system.h \
+ include/asm-um/sigcontext.h include/asm-um/processor.h \
+- include/asm-um/ptrace.h include/asm-um/arch-signal.h
++ include/asm-um/ptrace.h include/asm-um/arch-signal.h \
++ include/asm-um/module.h
+
+ ARCH_SYMLINKS = include/asm-um/arch $(ARCH_DIR)/include/sysdep $(ARCH_DIR)/os \
+ $(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h
+
+ GEN_HEADERS += $(ARCH_DIR)/include/task.h $(ARCH_DIR)/include/kern_constants.h
+
+-include $(ARCH_DIR)/Makefile-$(SUBARCH)
+-include $(ARCH_DIR)/Makefile-os-$(OS)
++.PHONY: sys_prepare
++sys_prepare:
++ @:
+
+ MAKEFILE-$(CONFIG_MODE_TT) += Makefile-tt
+ MAKEFILE-$(CONFIG_MODE_SKAS) += Makefile-skas
+@@ -41,6 +43,9 @@
+ include $(addprefix $(ARCH_DIR)/,$(MAKEFILE-y))
+ endif
+
++include $(ARCH_DIR)/Makefile-$(SUBARCH)
++include $(ARCH_DIR)/Makefile-os-$(OS)
++
+ EXTRAVERSION := $(EXTRAVERSION)-1um
+
+ ARCH_INCLUDE = -I$(ARCH_DIR)/include
+@@ -52,14 +57,14 @@
+
+ CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
+ -D_LARGEFILE64_SOURCE $(ARCH_INCLUDE) -Derrno=kernel_errno \
+- $(MODE_INCLUDE)
++ -Dsigprocmask=kernel_sigprocmask $(MODE_INCLUDE)
+
+ LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
+
+ SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000)
+
+ ifeq ($(CONFIG_MODE_SKAS), y)
+-$(SYS_HEADERS) : $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
++$(SYS_HEADERS) : $(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h
+ endif
+
+ include/linux/version.h: arch/$(ARCH)/Makefile
+@@ -98,17 +103,17 @@
+ CONFIG_KERNEL_STACK_ORDER ?= 2
+ STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] )
+
+-AFLAGS_vmlinux.lds.o = -U$(SUBARCH) \
++AFLAGS_vmlinux.lds.o = $(shell echo -U$(SUBARCH) \
+ -DSTART=$$(($(TOP_ADDR) - $(SIZE))) -DELF_ARCH=$(ELF_ARCH) \
+ -DELF_FORMAT=\"$(ELF_FORMAT)\" $(CPP_MODE_TT) \
+- -DKERNEL_STACK_SIZE=$(STACK_SIZE)
++ -DKERNEL_STACK_SIZE=$(STACK_SIZE))
+
+-AFLAGS_$(LD_SCRIPT-y:.s=).o = $(AFLAGS_vmlinux.lds.o) -P -C -Uum
++export AFLAGS_$(LD_SCRIPT-y:.s=).o = $(AFLAGS_vmlinux.lds.o) -P -C -Uum
+
+ LD_SCRIPT-y := $(ARCH_DIR)/$(LD_SCRIPT-y)
+
+-$(LD_SCRIPT-y) : $(LD_SCRIPT-y:.s=.S) scripts FORCE
+- $(call if_changed_dep,as_s_S)
++#$(LD_SCRIPT-y) : $(LD_SCRIPT-y:.s=.S) scripts FORCE
++# $(call if_changed_dep,as_s_S)
+
+ linux: vmlinux $(LD_SCRIPT-y)
+ $(CC) -Wl,-T,$(LD_SCRIPT-y) $(LINK-y) $(LINK_WRAPS) \
+@@ -116,6 +121,7 @@
+
+ USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
+ USER_CFLAGS := $(patsubst -Derrno=kernel_errno,,$(USER_CFLAGS))
++USER_CFLAGS := $(patsubst -Dsigprocmask=kernel_sigprocmask,,$(USER_CFLAGS))
+ USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
+ $(MODE_INCLUDE)
+
+@@ -123,9 +129,10 @@
+ USER_CFLAGS += -D_GNU_SOURCE
+
+ CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/uml.lds.s \
+- $(ARCH_DIR)/dyn_link.ld.s $(GEN_HEADERS)
++ $(ARCH_DIR)/dyn_link.ld.s $(ARCH_DIR)/include/uml-config.h \
++ $(GEN_HEADERS)
+
+-$(ARCH_DIR)/main.o: $(ARCH_DIR)/main.c
++$(ARCH_DIR)/main.o: $(ARCH_DIR)/main.c sys_prepare
+ $(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
+
+ archmrproper:
+@@ -161,19 +168,23 @@
+ $(ARCH_DIR)/os:
+ cd $(ARCH_DIR) && ln -sf os-$(OS) os
+
+-$(ARCH_DIR)/include/uml-config.h :
++$(ARCH_DIR)/include/uml-config.h : $(TOPDIR)/include/linux/autoconf.h
+ sed 's/ CONFIG/ UML_CONFIG/' $(TOPDIR)/include/linux/autoconf.h > $@
+
++filechk_$(ARCH_DIR)/include/task.h := $(ARCH_DIR)/util/mk_task
++
+ $(ARCH_DIR)/include/task.h : $(ARCH_DIR)/util/mk_task
+- $< > $@
++ $(call filechk,$@)
++
++filechk_$(ARCH_DIR)/include/kern_constants.h := $(ARCH_DIR)/util/mk_constants
+
+ $(ARCH_DIR)/include/kern_constants.h : $(ARCH_DIR)/util/mk_constants
+- $< > $@
++ $(call filechk,$@)
+
+-$(ARCH_DIR)/util/mk_task : $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h \
+- $(ARCH_DIR)/util FORCE ;
++$(ARCH_DIR)/util/mk_task $(ARCH_DIR)/util/mk_constants : $(ARCH_DIR)/util \
++ sys_prepare FORCE ;
+
+ $(ARCH_DIR)/util: FORCE
+- @$(call descend,$@,)
++ $(MAKE) -f scripts/Makefile.build obj=$@
+
+-export SUBARCH USER_CFLAGS OS
++export SUBARCH USER_CFLAGS OS
+Index: linux-2.6.0-test5/arch/um/Makefile-i386
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/Makefile-i386 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/Makefile-i386 2003-09-27 11:38:20.310440728 +0800
+@@ -16,22 +16,28 @@
+
+ SYS_HEADERS = $(SYS_DIR)/sc.h $(SYS_DIR)/thread.h
+
++sys_prepare: $(SYS_DIR)/sc.h
++
+ prepare: $(SYS_HEADERS)
+
++filechk_$(SYS_DIR)/sc.h := $(SYS_UTIL_DIR)/mk_sc
++
+ $(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc
+- $< > $@
++ $(call filechk,$@)
++
++filechk_$(SYS_DIR)/thread.h := $(SYS_UTIL_DIR)/mk_thread
+
+ $(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread
+- $< > $@
++ $(call filechk,$@)
+
+-$(SYS_UTIL_DIR)/mk_sc: FORCE ;
+- @$(call descend,$(SYS_UTIL_DIR),$@)
++$(SYS_UTIL_DIR)/mk_sc: scripts/fixdep include/config/MARKER FORCE ;
++ +@$(call descend,$(SYS_UTIL_DIR),$@)
+
+-$(SYS_UTIL_DIR)/mk_thread: $(ARCH_SYMLINKS) $(GEN_HEADERS) FORCE ;
+- @$(call descend,$(SYS_UTIL_DIR),$@)
++$(SYS_UTIL_DIR)/mk_thread: $(ARCH_SYMLINKS) $(GEN_HEADERS) sys_prepare FORCE ;
++ +@$(call descend,$(SYS_UTIL_DIR),$@)
+
+ $(SYS_UTIL_DIR): include/asm FORCE
+- @$(call descend,$@,)
++ +@$(call descend,$@,)
+
+ sysclean :
+ rm -f $(SYS_HEADERS)
+Index: linux-2.6.0-test5/arch/um/Makefile-skas
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/Makefile-skas 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/Makefile-skas 2003-09-27 11:38:20.311440576 +0800
+@@ -14,7 +14,7 @@
+ LINK_SKAS = -Wl,-rpath,/lib
+ LD_SCRIPT_SKAS = dyn.lds.s
+
+-GEN_HEADERS += $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
++GEN_HEADERS += $(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h
+
+-$(ARCH_DIR)/kernel/skas/include/skas_ptregs.h :
+- $(MAKE) -C $(ARCH_DIR)/kernel/skas include/skas_ptregs.h
++$(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h :
++ $(call descend,$(ARCH_DIR)/kernel/skas,$@)
+Index: linux-2.6.0-test5/arch/um/os-Linux/drivers/tuntap_user.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/os-Linux/drivers/tuntap_user.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/os-Linux/drivers/tuntap_user.c 2003-09-27 11:38:20.314440120 +0800
+@@ -142,7 +142,7 @@
+ return(-errno);
+ }
+ memset(&ifr, 0, sizeof(ifr));
+- ifr.ifr_flags = IFF_TAP;
++ ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+ strlcpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name));
+ if(ioctl(pri->fd, TUNSETIFF, (void *) &ifr) < 0){
+ printk("TUNSETIFF failed, errno = %d", errno);
+Index: linux-2.6.0-test5/arch/um/os-Linux/file.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/os-Linux/file.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/os-Linux/file.c 2003-09-27 11:38:20.316439816 +0800
+@@ -315,7 +315,7 @@
+ return(new);
+ }
+
+-int create_unix_socket(char *file, int len)
++int create_unix_socket(char *file, int len, int close_on_exec)
+ {
+ struct sockaddr_un addr;
+ int sock, err;
+@@ -327,6 +327,10 @@
+ return(-errno);
+ }
+
++ if(close_on_exec && fcntl(sock, F_SETFD, 1) < 0)
++ printk("create_unix_socket : Setting FD_CLOEXEC failed, "
++ "errno = %d", errno);
++
+ addr.sun_family = AF_UNIX;
+
+ /* XXX Be more careful about overflow */
+@@ -342,6 +346,37 @@
+ return(sock);
+ }
+
++void os_flush_stdout(void)
++{
++ fflush(stdout);
++}
++
++int os_lock_file(int fd, int excl)
++{
++ int type = excl ? F_WRLCK : F_RDLCK;
++ struct flock lock = ((struct flock) { .l_type = type,
++ .l_whence = SEEK_SET,
++ .l_start = 0,
++ .l_len = 0 } );
++ int err, save;
++
++ err = fcntl(fd, F_SETLK, &lock);
++ if(!err)
++ goto out;
++
++ save = -errno;
++ err = fcntl(fd, F_GETLK, &lock);
++ if(err){
++ err = -errno;
++ goto out;
++ }
++
++ printk("F_SETLK failed, file already locked by pid %d\n", lock.l_pid);
++ err = save;
++ out:
++ return(err);
++}
++
+ /*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+Index: linux-2.6.0-test5/arch/um/sys-i386/bugs.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/sys-i386/bugs.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/sys-i386/bugs.c 2003-09-27 11:38:20.318439512 +0800
+@@ -8,6 +8,7 @@
+ #include <errno.h>
+ #include <string.h>
+ #include <sys/signal.h>
++#include <asm/ldt.h>
+ #include "kern_util.h"
+ #include "user.h"
+ #include "sysdep/ptrace.h"
+@@ -16,8 +17,8 @@
+ #define MAXTOKEN 64
+
+ /* Set during early boot */
+-int cpu_has_cmov = 1;
+-int cpu_has_xmm = 0;
++int host_has_cmov = 1;
++int host_has_xmm = 0;
+
+ static char token(int fd, char *buf, int len, char stop)
+ {
+@@ -104,6 +105,25 @@
+ return(1);
+ }
+
++static void disable_lcall(void)
++{
++ struct modify_ldt_ldt_s ldt;
++ int err;
++
++ bzero(&ldt, sizeof(ldt));
++ ldt.entry_number = 7;
++ ldt.base_addr = 0;
++ ldt.limit = 0;
++ err = modify_ldt(1, &ldt, sizeof(ldt));
++ if(err)
++ printk("Failed to disable lcall7 - errno = %d\n", errno);
++}
++
++void arch_init_thread(void)
++{
++ disable_lcall();
++}
++
+ void arch_check_bugs(void)
+ {
+ int have_it;
+@@ -113,8 +133,8 @@
+ "checks\n");
+ return;
+ }
+- if(check_cpu_feature("cmov", &have_it)) cpu_has_cmov = have_it;
+- if(check_cpu_feature("xmm", &have_it)) cpu_has_xmm = have_it;
++ if(check_cpu_feature("cmov", &have_it)) host_has_cmov = have_it;
++ if(check_cpu_feature("xmm", &have_it)) host_has_xmm = have_it;
+ }
+
+ int arch_handle_signal(int sig, union uml_pt_regs *regs)
+@@ -130,18 +150,18 @@
+ if((*((char *) ip) != 0x0f) || ((*((char *) (ip + 1)) & 0xf0) != 0x40))
+ return(0);
+
+- if(cpu_has_cmov == 0)
++ if(host_has_cmov == 0)
+ panic("SIGILL caused by cmov, which this processor doesn't "
+ "implement, boot a filesystem compiled for older "
+ "processors");
+- else if(cpu_has_cmov == 1)
++ else if(host_has_cmov == 1)
+ panic("SIGILL caused by cmov, which this processor claims to "
+ "implement");
+- else if(cpu_has_cmov == -1)
++ else if(host_has_cmov == -1)
+ panic("SIGILL caused by cmov, couldn't tell if this processor "
+ "implements it, boot a filesystem compiled for older "
+ "processors");
+- else panic("Bad value for cpu_has_cmov (%d)", cpu_has_cmov);
++ else panic("Bad value for host_has_cmov (%d)", host_has_cmov);
+ return(0);
+ }
+
+Index: linux-2.6.0-test5/arch/um/sys-i386/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/sys-i386/Makefile 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/sys-i386/Makefile 2003-09-27 11:38:20.319439360 +0800
+@@ -1,7 +1,8 @@
+-obj-y = bugs.o checksum.o extable.o fault.o ksyms.o ldt.o module.o \
+- ptrace.o ptrace_user.o semaphore.o sigcontext.o syscalls.o sysrq.o
++obj-y = bugs.o checksum.o extable.o fault.o ksyms.o ldt.o ptrace.o \
++ ptrace_user.o semaphore.o sigcontext.o syscalls.o sysrq.o
+
+ obj-$(CONFIG_HIGHMEM) += highmem.o
++obj-$(CONFIG_MODULES) += module.o
+
+ USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o
+ USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
+@@ -9,6 +10,8 @@
+ SYMLINKS = semaphore.c highmem.c module.c
+ SYMLINKS := $(foreach f,$(SYMLINKS),$(src)/$f)
+
++clean-files := $(SYMLINKS)
++
+ semaphore.c-dir = kernel
+ highmem.c-dir = mm
+ module.c-dir = kernel
+@@ -24,8 +27,7 @@
+ $(SYMLINKS):
+ $(call make_link,$@)
+
+-clean:
+- $(MAKE) -C util clean
++subdir- := util
+
+ fastdep:
+
+Index: linux-2.6.0-test5/arch/um/uml.lds.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/uml.lds.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/uml.lds.S 2003-09-27 11:38:20.321439056 +0800
+@@ -26,7 +26,11 @@
+ . = ALIGN(4096); /* Init code and data */
+ _stext = .;
+ __init_begin = .;
+- .text.init : { *(.text.init) }
++ .init.text : {
++ _sinittext = .;
++ *(.init.text)
++ _einittext = .;
++ }
+ . = ALIGN(4096);
+ .text :
+ {
+@@ -38,7 +42,7 @@
+
+ #include "asm/common.lds.S"
+
+- .data.init : { *(.data.init) }
++ init.data : { *(init.data) }
+ .data :
+ {
+ . = ALIGN(KERNEL_STACK_SIZE); /* init_task */
+Index: linux-2.6.0-test5/arch/um/util/mk_constants_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/util/mk_constants_kern.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/util/mk_constants_kern.c 2003-09-27 11:38:20.322438904 +0800
+@@ -1,5 +1,6 @@
+ #include "linux/kernel.h"
+ #include "linux/stringify.h"
++#include "linux/time.h"
+ #include "asm/page.h"
+
+ extern void print_head(void);
+@@ -11,6 +12,7 @@
+ {
+ print_head();
+ print_constant_int("UM_KERN_PAGE_SIZE", PAGE_SIZE);
++
+ print_constant_str("UM_KERN_EMERG", KERN_EMERG);
+ print_constant_str("UM_KERN_ALERT", KERN_ALERT);
+ print_constant_str("UM_KERN_CRIT", KERN_CRIT);
+@@ -19,6 +21,8 @@
+ print_constant_str("UM_KERN_NOTICE", KERN_NOTICE);
+ print_constant_str("UM_KERN_INFO", KERN_INFO);
+ print_constant_str("UM_KERN_DEBUG", KERN_DEBUG);
++
++ print_constant_int("UM_NSEC_PER_SEC", NSEC_PER_SEC);
+ print_tail();
+ return(0);
+ }
+Index: linux-2.6.0-test5/arch/x86_64/boot/compressed/head.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/x86_64/boot/compressed/head.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/x86_64/boot/compressed/head.S 2003-09-27 11:38:20.324438600 +0800
+@@ -26,6 +26,7 @@
+ .code32
+ .text
+
++#define IN_BOOTLOADER
+ #include <linux/linkage.h>
+ #include <asm/segment.h>
+
+Index: linux-2.6.0-test5/arch/x86_64/boot/compressed/misc.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/x86_64/boot/compressed/misc.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/x86_64/boot/compressed/misc.c 2003-09-27 11:38:20.327438144 +0800
+@@ -9,6 +9,7 @@
+ * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
+ */
+
++#define IN_BOOTLOADER
+ #include "miscsetup.h"
+ #include <asm/io.h>
+
+@@ -116,8 +117,8 @@
+ {
+ void *p;
+
+- if (size <0) error("Malloc error\n");
+- if (free_mem_ptr <= 0) error("Memory error\n");
++ if (size <0) error("Malloc error");
++ if (free_mem_ptr <= 0) error("Memory error");
+
+ free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
+
+@@ -125,7 +126,7 @@
+ free_mem_ptr += size;
+
+ if (free_mem_ptr >= free_mem_end_ptr)
+- error("\nOut of memory\n");
++ error("Out of memory");
+
+ return p;
+ }
+@@ -215,7 +216,7 @@
+ static int fill_inbuf(void)
+ {
+ if (insize != 0) {
+- error("ran out of input data\n");
++ error("ran out of input data");
+ }
+
+ inbuf = input_data;
+@@ -280,9 +281,9 @@
+ void setup_normal_output_buffer(void)
+ {
+ #ifdef STANDARD_MEMORY_BIOS_CALL
+- if (EXT_MEM_K < 1024) error("Less than 2MB of memory.\n");
++ if (EXT_MEM_K < 1024) error("Less than 2MB of memory");
+ #else
+- if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < 1024) error("Less than 2MB of memory.\n");
++ if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < 1024) error("Less than 2MB of memory");
+ #endif
+ output_data = (char *)0x100000; /* Points to 1M */
+ free_mem_end_ptr = (long)real_mode;
+@@ -297,9 +298,9 @@
+ {
+ high_buffer_start = (uch *)(((ulg)&end) + HEAP_SIZE);
+ #ifdef STANDARD_MEMORY_BIOS_CALL
+- if (EXT_MEM_K < (3*1024)) error("Less than 4MB of memory.\n");
++ if (EXT_MEM_K < (3*1024)) error("Less than 4MB of memory");
+ #else
+- if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < (3*1024)) error("Less than 4MB of memory.\n");
++ if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < (3*1024)) error("Less than 4MB of memory");
+ #endif
+ mv->low_buffer_start = output_data = (char *)LOW_BUFFER_START;
+ low_buffer_end = ((unsigned int)real_mode > LOW_BUFFER_MAX
+Index: linux-2.6.0-test5/arch/x86_64/ia32/ia32_ioctl.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/x86_64/ia32/ia32_ioctl.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/x86_64/ia32/ia32_ioctl.c 2003-09-27 11:38:20.334437080 +0800
+@@ -35,7 +35,7 @@
+ real_tty = (struct tty_struct *)file->private_data;
+ if (!real_tty)
+ return -EINVAL;
+- return put_user(real_tty->device, ptr);
++ return put_user(tty_devnum(real_tty), ptr);
+ }
+
+
+Index: linux-2.6.0-test5/arch/x86_64/ia32/sys_ia32.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/x86_64/ia32/sys_ia32.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/x86_64/ia32/sys_ia32.c 2003-09-27 11:38:20.348434952 +0800
+@@ -89,27 +89,18 @@
+ #define low2highgid(gid) ((gid) == (u16)-1) ? (gid_t)-1 : (gid_t)(gid)
+ extern int overflowuid,overflowgid;
+
+-
+-extern asmlinkage long sys_newstat(char * filename, struct stat * statbuf);
+-extern asmlinkage long sys_newlstat(char * filename, struct stat * statbuf);
+-extern asmlinkage long sys_newfstat(unsigned int fd, struct stat * statbuf);
+-
+-
+-extern asmlinkage long sys_newstat(char * filename, struct stat * statbuf);
+-extern asmlinkage long sys_newlstat(char * filename, struct stat * statbuf);
+-extern asmlinkage long sys_newfstat(unsigned int fd, struct stat * statbuf);
+-
+-
+ int cp_compat_stat(struct kstat *kbuf, struct compat_stat *ubuf)
+ {
++ if (!old_valid_dev(kbuf->dev) || !old_valid_dev(kbuf->rdev))
++ return -EOVERFLOW;
+ if (verify_area(VERIFY_WRITE, ubuf, sizeof(struct compat_stat)) ||
+- __put_user (kbuf->dev, &ubuf->st_dev) ||
++ __put_user (old_encode_dev(kbuf->dev), &ubuf->st_dev) ||
+ __put_user (kbuf->ino, &ubuf->st_ino) ||
+ __put_user (kbuf->mode, &ubuf->st_mode) ||
+ __put_user (kbuf->nlink, &ubuf->st_nlink) ||
+ __put_user (kbuf->uid, &ubuf->st_uid) ||
+ __put_user (kbuf->gid, &ubuf->st_gid) ||
+- __put_user (kbuf->rdev, &ubuf->st_rdev) ||
++ __put_user (old_encode_dev(kbuf->rdev), &ubuf->st_rdev) ||
+ __put_user (kbuf->size, &ubuf->st_size) ||
+ __put_user (kbuf->atime.tv_sec, &ubuf->st_atime) ||
+ __put_user (kbuf->atime.tv_nsec, &ubuf->st_atime_nsec) ||
+@@ -127,26 +118,26 @@
+ support for 64bit inode numbers. */
+
+ static int
+-putstat64(struct stat64 *ubuf, struct stat *kbuf)
++cp_stat64(struct stat64 *ubuf, struct kstat *stat)
+ {
+ if (verify_area(VERIFY_WRITE, ubuf, sizeof(struct stat64)) ||
+- __put_user (kbuf->st_dev, &ubuf->st_dev) ||
+- __put_user (kbuf->st_ino, &ubuf->__st_ino) ||
+- __put_user (kbuf->st_ino, &ubuf->st_ino) ||
+- __put_user (kbuf->st_mode, &ubuf->st_mode) ||
+- __put_user (kbuf->st_nlink, &ubuf->st_nlink) ||
+- __put_user (kbuf->st_uid, &ubuf->st_uid) ||
+- __put_user (kbuf->st_gid, &ubuf->st_gid) ||
+- __put_user (kbuf->st_rdev, &ubuf->st_rdev) ||
+- __put_user (kbuf->st_size, &ubuf->st_size) ||
+- __put_user (kbuf->st_atime, &ubuf->st_atime) ||
+- __put_user (kbuf->st_atime_nsec, &ubuf->st_atime_nsec) ||
+- __put_user (kbuf->st_mtime, &ubuf->st_mtime) ||
+- __put_user (kbuf->st_mtime_nsec, &ubuf->st_mtime_nsec) ||
+- __put_user (kbuf->st_ctime, &ubuf->st_ctime) ||
+- __put_user (kbuf->st_ctime_nsec, &ubuf->st_ctime_nsec) ||
+- __put_user (kbuf->st_blksize, &ubuf->st_blksize) ||
+- __put_user (kbuf->st_blocks, &ubuf->st_blocks))
++ __put_user(huge_encode_dev(stat->dev), &ubuf->st_dev) ||
++ __put_user (stat->ino, &ubuf->__st_ino) ||
++ __put_user (stat->ino, &ubuf->st_ino) ||
++ __put_user (stat->mode, &ubuf->st_mode) ||
++ __put_user (stat->nlink, &ubuf->st_nlink) ||
++ __put_user (stat->uid, &ubuf->st_uid) ||
++ __put_user (stat->gid, &ubuf->st_gid) ||
++ __put_user (huge_encode_dev(stat->rdev), &ubuf->st_rdev) ||
++ __put_user (stat->size, &ubuf->st_size) ||
++ __put_user (stat->atime.tv_sec, &ubuf->st_atime) ||
++ __put_user (stat->atime.tv_nsec, &ubuf->st_atime_nsec) ||
++ __put_user (stat->mtime.tv_sec, &ubuf->st_mtime) ||
++ __put_user (stat->mtime.tv_nsec, &ubuf->st_mtime_nsec) ||
++ __put_user (stat->ctime.tv_sec, &ubuf->st_ctime) ||
++ __put_user (stat->ctime.tv_nsec, &ubuf->st_ctime_nsec) ||
++ __put_user (stat->blksize, &ubuf->st_blksize) ||
++ __put_user (stat->blocks, &ubuf->st_blocks))
+ return -EFAULT;
+ return 0;
+ }
+@@ -154,50 +145,33 @@
+ asmlinkage long
+ sys32_stat64(char * filename, struct stat64 *statbuf)
+ {
+- int ret;
+- struct stat s;
+- mm_segment_t old_fs = get_fs();
+-
+- set_fs (KERNEL_DS);
+- ret = sys_newstat(filename, &s);
+- set_fs (old_fs);
+- if (putstat64 (statbuf, &s))
+- return -EFAULT;
++ struct kstat stat;
++ int ret = vfs_stat(filename, &stat);
++ if (!ret)
++ ret = cp_stat64(statbuf, &stat);
+ return ret;
+ }
+
+ asmlinkage long
+ sys32_lstat64(char * filename, struct stat64 *statbuf)
+ {
+- int ret;
+- struct stat s;
+- mm_segment_t old_fs = get_fs();
+-
+- set_fs (KERNEL_DS);
+- ret = sys_newlstat(filename, &s);
+- set_fs (old_fs);
+- if (putstat64 (statbuf, &s))
+- return -EFAULT;
++ struct kstat stat;
++ int ret = vfs_lstat(filename, &stat);
++ if (!ret)
++ ret = cp_stat64(statbuf, &stat);
+ return ret;
+ }
+
+ asmlinkage long
+ sys32_fstat64(unsigned int fd, struct stat64 *statbuf)
+ {
+- int ret;
+- struct stat s;
+- mm_segment_t old_fs = get_fs();
+-
+- set_fs (KERNEL_DS);
+- ret = sys_newfstat(fd, &s);
+- set_fs (old_fs);
+- if (putstat64 (statbuf, &s))
+- return -EFAULT;
++ struct kstat stat;
++ int ret = vfs_fstat(fd, &stat);
++ if (!ret)
++ ret = cp_stat64(statbuf, &stat);
+ return ret;
+ }
+
+-
+-
+ /*
+ * Linux/i386 didn't use to be able to handle more than
+ * 4 system call parameters, so these system calls used a memory
+@@ -1476,7 +1450,7 @@
+
+ extern int sys_ustat(dev_t, struct ustat *);
+
+-long sys32_ustat(dev_t dev, struct ustat32 *u32p)
++long sys32_ustat(unsigned dev, struct ustat32 *u32p)
+ {
+ struct ustat u;
+ mm_segment_t seg;
+Index: linux-2.6.0-test5/arch/x86_64/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/x86_64/Kconfig 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/x86_64/Kconfig 2003-09-27 11:38:20.352434344 +0800
+@@ -171,14 +171,6 @@
+
+ See <file:Documentation/mtrr.txt> for more information.
+
+-config HUGETLB_PAGE
+- bool "Huge TLB Page Support"
+- help
+- This enables support for huge pages. User space applications
+- can make use of this support with the hugetlbfs file system
+- To actually use it you need to pass an hugepages= argument
+- to the kernel at boot time.
+-
+ config SMP
+ bool "Symmetric multi-processing support"
+ ---help---
+Index: linux-2.6.0-test5/arch/x86_64/kernel/pci-gart.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/x86_64/kernel/pci-gart.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/x86_64/kernel/pci-gart.c 2003-09-27 11:38:20.358433432 +0800
+@@ -76,7 +76,6 @@
+ #define EMERGENCY_PAGES 32 /* = 128KB */
+
+ #ifdef CONFIG_AGP
+-extern int agp_init(void);
+ #define AGPEXTERN extern
+ #else
+ #define AGPEXTERN
+Index: linux-2.6.0-test5/arch/x86_64/kernel/setup.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/x86_64/kernel/setup.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/x86_64/kernel/setup.c 2003-09-27 11:38:20.365432368 +0800
+@@ -64,7 +64,7 @@
+ unsigned long mmu_cr4_features;
+ EXPORT_SYMBOL_GPL(mmu_cr4_features);
+
+-int acpi_disabled __initdata = 0;
++int acpi_disabled = 0;
+
+ /* For PCI or other memory-mapped resources */
+ unsigned long pci_mem_start = 0x10000000;
+@@ -317,7 +317,7 @@
+ {
+ unsigned long low_mem_size;
+
+- ROOT_DEV = ORIG_ROOT_DEV;
++ ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
+ drive_info = DRIVE_INFO;
+ screen_info = SCREEN_INFO;
+ edid_info = EDID_INFO;
+Index: linux-2.6.0-test5/arch/x86_64/kernel/time.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/x86_64/kernel/time.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/x86_64/kernel/time.c 2003-09-27 11:38:20.370431608 +0800
+@@ -370,6 +370,19 @@
+ return IRQ_HANDLED;
+ }
+
++/* RED-PEN: calculation is done in 32bits with multiply for performance
++ and could overflow, it may be better (but slower)to use an 64bit division. */
++unsigned long long sched_clock(void)
++{
++ unsigned long a;
++
++ if (__vxtime.mode == VXTIME_HPET)
++ return (hpet_readl(HPET_COUNTER) * vxtime.quot) >> 32;
++
++ rdtscll(a);
++ return (a * vxtime.tsc_quot) >> 32;
++}
++
+ unsigned long get_cmos_time(void)
+ {
+ unsigned int timeout, year, mon, day, hour, min, sec;
+Index: linux-2.6.0-test5/arch/x86_64/mm/ioremap.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/x86_64/mm/ioremap.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/x86_64/mm/ioremap.c 2003-09-27 11:38:20.373431152 +0800
+@@ -159,7 +159,7 @@
+ if (!area)
+ return NULL;
+ addr = area->addr;
+- if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) {
++ if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
+ vunmap(addr);
+ return NULL;
+ }
+Index: linux-2.6.0-test5/CREDITS
+===================================================================
+--- linux-2.6.0-test5.orig/CREDITS 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/CREDITS 2003-09-27 11:38:20.394427960 +0800
+@@ -1394,7 +1394,8 @@
+ N: Marcel Holtmann
+ E: marcel@holtmann.org
+ W: http://www.holtmann.org
+-D: Author of the Linux Bluetooth Subsystem PC Card drivers
++D: Author and maintainer of the various Bluetooth HCI drivers
++D: Various other Bluetooth related patches, cleanups and fixes
+ S: Germany
+
+ N: Rob W. W. Hooft
+@@ -2795,7 +2796,7 @@
+ D: Dosemu
+
+ N: Duncan Sands
+-E: duncan.sands@wanadoo.fr
++E: duncan.sands@free.fr
+ W: http://topo.math.u-psud.fr/~sands
+ D: Alcatel SpeedTouch USB driver
+ S: 69 rue Dunois
+@@ -3460,11 +3461,11 @@
+ S: England
+
+ N: Chris Wright
+-E: chris@wirex.com
++E: chrisw@osdl.org
+ D: hacking on LSM framework and security modules.
+-S: c/o WireX
+-S: 920 SW 3rd, Ste. 100
+-S: Portland, OR 97204
++S: c/o OSDL
++S: 12725 SW Millikan Way, Suite 400
++S: Beaverton, OR 97005
+ S: USA
+
+ N: Frank Xia
+Index: linux-2.6.0-test5/crypto/proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/crypto/proc.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/crypto/proc.c 2003-09-27 11:38:20.396427656 +0800
+@@ -57,6 +57,7 @@
+
+ switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) {
+ case CRYPTO_ALG_TYPE_CIPHER:
++ seq_printf(m, "type : cipher\n");
+ seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
+ seq_printf(m, "min keysize : %u\n",
+ alg->cra_cipher.cia_min_keysize);
+@@ -65,10 +66,17 @@
+ break;
+
+ case CRYPTO_ALG_TYPE_DIGEST:
++ seq_printf(m, "type : digest\n");
+ seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
+ seq_printf(m, "digestsize : %u\n",
+ alg->cra_digest.dia_digestsize);
+ break;
++ case CRYPTO_ALG_TYPE_COMPRESS:
++ seq_printf(m, "type : compression\n");
++ break;
++ default:
++ seq_printf(m, "type : unknown\n");
++ break;
+ }
+
+ seq_putc(m, '\n');
+Index: linux-2.6.0-test5/Documentation/00-INDEX
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/00-INDEX 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/Documentation/00-INDEX 2003-09-27 11:38:20.399427200 +0800
+@@ -64,8 +64,10 @@
+ - plain ASCII listing of all the nodes in /dev/ with major minor #'s
+ digiboard.txt
+ - info on the Digiboard PC/X{i,e,eve} multiport boards.
++digidgap.txt
++ - info about the Digiboard EPCA PCI (DGAP) serial boards.
+ digiepca.txt
+- - info on Digi Intl. {PC,PCI,EISA}Xx and Xem series cards.
++ - info on Digi Intl. {ISA,EISA}Xx and Xem ISA series cards.
+ dnotify.txt
+ - info about directory notification in Linux.
+ driver-model.txt
+@@ -116,8 +118,6 @@
+ - listing of various WWW + books that document kernel internals.
+ kernel-parameters.txt
+ - summary listing of command line / boot prompt args for the kernel.
+-kmod.txt
+- - info on the kernel module loader/unloader (kerneld replacement).
+ ldm.txt
+ - a brief description of LDM (Windows Dynamic Disks).
+ locks.txt
+@@ -144,8 +144,6 @@
+ - script to make /dev entries for SMART controllers (see cciss.txt)
+ mkdev.ida
+ - script to make /dev entries for Intelligent Disk Array Controllers.
+-modules.txt
+- - short guide on how to make kernel parts into loadable modules
+ moxa-smartio
+ - info on installing/using Moxa multiport serial driver.
+ mtrr.txt
+Index: linux-2.6.0-test5/Documentation/as-iosched.txt
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/as-iosched.txt 2003-09-27 11:38:18.445724208 +0800
++++ linux-2.6.0-test5/Documentation/as-iosched.txt 2003-09-27 11:38:20.400427048 +0800
+@@ -0,0 +1,53 @@
++Anticipatory IO scheduler
++-------------------------
++Nick Piggin <piggin@cyberone.com.au> 13 Sep 2003
++
++Attention! Database servers, especially those using "TCQ" disks should
++investigate performance with the 'deadline' IO scheduler. Any system with high
++disk performance requirements should do so, in fact.
++
++If you see unusual performance characteristics of your disk systems, or you
++see big performance regressions versus the deadline scheduler, please email
++me. Database users don't bother unless you're willing to test a lot of patches
++from me ;) its a known issue.
++
++
++Selecting IO schedulers
++-----------------------
++To choose IO schedulers at boot time, use the argument 'elevator=deadline'.
++'noop' and 'as' (the default) are also available. IO schedulers are assigned
++globally at boot time only presently.
++
++
++Tuning the anticipatory IO scheduler
++------------------------------------
++When using 'as', the anticipatory IO scheduler there are 5 parameters under
++/sys/block/*/iosched/. All are units of milliseconds.
++
++The parameters are:
++* read_expire
++ Controls how long until a request becomes "expired". It also controls the
++ interval between which expired requests are served, so set to 50, a request
++ might take anywhere < 100ms to be serviced _if_ it is the next on the
++ expired list. Obviously it won't make the disk go faster. The result
++ basically equates to the timeslice a single reader gets in the presence of
++ other IO. 100*((seek time / read_expire) + 1) is very roughly the %
++ streaming read efficiency your disk should get with multiple readers.
++
++* read_batch_expire
++ Controls how much time a batch of reads is given before pending writes are
++ served. Higher value is more efficient. This might be set below read_expire
++ if writes are to be given higher priority than reads, but reads are to be
++ as efficient as possible when there are no writes. Generally though, it
++ should be some multiple of read_expire.
++
++* write_expire, and
++* write_batch_expire are equivalent to the above, for writes.
++
++* antic_expire
++ Controls the maximum amount of time we can anticipate a good read before
++ giving up. Many other factors may cause anticipation to be stopped early,
++ or some processes will not be "anticipated" at all. Should be a bit higher
++ for big seek time devices though not a linear correspondence - most
++ processes have only a few ms thinktime.
++
+Index: linux-2.6.0-test5/Documentation/block/biodoc.txt
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/block/biodoc.txt 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/Documentation/block/biodoc.txt 2003-09-27 11:38:20.415424768 +0800
+@@ -6,6 +6,8 @@
+ Suparna Bhattacharya <suparna@in.ibm.com>
+
+ Last Updated May 2, 2002
++September 2003: Updated I/O Scheduler portions
++ Nick Piggin <piggin@cyberone.com.au>
+
+ Introduction:
+
+@@ -220,42 +222,8 @@
+ It also makes it possible to completely hide the implementation details of
+ the i/o scheduler from block drivers.
+
+-New routines to be used instead of accessing the queue directly:
+-
+-elv_add_request: Should be called to queue a request
+-elv_next_request: Should be called to pull of the next request to be serviced
+- of the queue. It takes care of several things like skipping active requests,
+- invoking the command pre-builder etc.
+-
+-Some new plugins:
+-e->elevator_next_req_fn
+- Plugin called to extract the next request to service from the
+- queue
+-e->elevator_add_req_fn
+- Plugin called to add a new request to the queue
+-e->elevator_init_fn
+- Plugin called when initializing the queue
+-e->elevator_exit_fn
+- Plugin called when destrying the queue
+-
+-Elevator Linus and Elevator noop are the existing combinations that can be
+-directly used, but a driver can provide relevant callbacks, in case
+-it needs to do something different.
+-
+-Elevator noop only attempts to merge requests, but doesn't reorder (sort)
+-them. Even merging requires a linear scan today (except for the last merged
+-hint case discussed later) though, which takes take up some CPU cycles.
+-
+-[Note: Merging usually helps in general, because there's usually non-trivial
+-command overhead associated with setting up and starting a command. Sorting,
+-on the other hand, may not be relevant for intelligent devices that reorder
+-requests anyway]
+-
+-Elevator Linus attempts merging as well as sorting of requests on the queue.
+-The sorting happens via an insert scan whenever a request comes in.
+-Often some sorting still makes sense as the depth which most hardware can
+-handle may be less than the queue lengths during i/o loads.
+-
++I/O scheduler wrappers are to be used instead of accessing the queue directly.
++See section 4. The I/O scheduler for details.
+
+ 1.2 Tuning Based on High level code capabilities
+
+@@ -317,32 +285,6 @@
+ requests. Some bits in the bi_rw flags field in the bio structure are
+ intended to be used for this priority information.
+
+- Jens has an implementation of a simple deadline i/o scheduler that
+- makes a best effort attempt to start requests within a given expiry
+- time limit, along with trying to optimize disk seeks as in the current
+- elevator. It does this by sorting a request on two lists, one by
+- the deadline and one by the sector order. It employs a policy that
+- follows sector ordering as long as a deadline is not violated, and
+- tries to keep up with deadlines in so far as it can batch up to at
+- least a certain minimum number of sector ordered requests to reduce
+- arbitrary disk seeks. This implementation is constructed in a way
+- that makes it possible to support advanced compound i/o schedulers
+- as a combination of several low level schedulers with an overall
+- class-independent scheduler layered above.
+-
+-The current elevator scheme provides a latency bound over how many future
+-requests can "pass" (get placed before) a given request, and this bound
+-is determined by the request type (read, write). However, it doesn't
+-prioritize a new request over existing requests in the queue based on its
+-latency requirement. A new request could of course get serviced before
+-earlier requests based on the position on disk which it accesses. This is
+-due to the sort/merge in the basic elevator scan logic, but irrespective
+-of the request's own priority/latency value. Interestingly the elevator
+-sequence or the latency bound setting of the new request is unaffected by the
+-number of existing requests it has passed, i.e. doesn't depend on where
+-it is positioned in the queue, but only on the number of requests that pass
+-it in the future.
+-
+
+ 1.3 Direct Access to Low level Device/Driver Capabilities (Bypass mode)
+ (e.g Diagnostics, Systems Management)
+@@ -964,7 +906,74 @@
+
+
+ 4. The I/O scheduler
++I/O schedulers are now per queue. They should be runtime switchable and modular
++but aren't yet. Jens has most bits to do this, but the sysfs implementation is
++missing.
++
++A block layer call to the i/o scheduler follows the convention elv_xxx(). This
++calls elevator_xxx_fn in the elevator switch (drivers/block/elevator.c). Oh,
++xxx and xxx might not match exactly, but use your imagination. If an elevator
++doesn't implement a function, the switch does nothing or some minimal house
++keeping work.
++
++4.1. I/O scheduler API
++
++The functions an elevator may implement are: (* are mandatory)
++elevator_merge_fn called to query requests for merge with a bio
++
++elevator_merge_req_fn " " " with another request
++
++elevator_merged_fn called when a request in the scheduler has been
++ involved in a merge. It is used in the deadline
++ scheduler for example, to reposition the request
++ if its sorting order has changed.
++
++*elevator_next_req_fn returns the next scheduled request, or NULL
++ if there are none (or none are ready).
++
++*elevator_add_req_fn called to add a new request into the scheduler
++
++elevator_queue_empty_fn returns true if the merge queue is empty.
++ Drivers shouldn't use this, but rather check
++ if elv_next_request is NULL (without losing the
++ request if one exists!)
++
++elevator_remove_req_fn This is called when a driver claims ownership of
++ the target request - it now belongs to the
++ driver. It must not be modified or merged.
++ Drivers must not lose the request! A subsequent
++ call of elevator_next_req_fn must return the
++ _next_ request.
++
++elevator_requeue_req_fn called to add a request to the scheduler. This
++ is used when the request has alrnadebeen
++ returned by elv_next_request, but hasn't
++ completed. If this is not implemented then
++ elevator_add_req_fn is called instead.
++
++elevator_former_req_fn
++elevator_latter_req_fn These return the request before or after the
++ one specified in disk sort order. Used by the
++ block layer to find merge possibilities.
++
++elevator_completed_req_fn called when a request is completed. This might
++ come about due to being merged with another or
++ when the device completes the request.
++
++elevator_may_queue_fn returns true if the scheduler wants to allow the
++ current context to queue a new request even if
++ it is over the queue limit. This must be used
++ very carefully!!
++
++elevator_set_req_fn
++elevator_put_req_fn Must be used to allocate and free any elevator
++ specific storate for a request.
++
++elevator_init_fn
++elevator_exit_fn Allocate and free any elevator specific storage
++ for a queue.
+
++4.2 I/O scheduler implementation
+ The generic i/o scheduler algorithm attempts to sort/merge/batch requests for
+ optimal disk scan and request servicing performance (based on generic
+ principles and device capabilities), optimized for:
+@@ -974,49 +983,58 @@
+
+ Characteristics:
+
+-i. Linked list for O(n) insert/merge (linear scan) right now
+-
+-This is just the same as it was in 2.4.
+-
+-There is however an added level of abstraction in the operations for adding
+-and extracting a request to/from the queue, which makes it possible to
+-try out alternative queue structures without changes to the users of the queue.
+-Some things like head-active are thus now handled within elv_next_request
+-making it possible to mark more than one request to be left alone.
+-
+-Aside:
+-1. The use of a merge hash was explored to reduce merge times and to make
+- elevator_noop close to noop by avoiding the scan for merge. However the
+- complexity and locking issues introduced wasn't desirable especially as
+- with multi-page bios the incidence of merges is expected to be lower.
+-2. The use of binomial/fibonacci heaps was explored to reduce the scan time;
+- however the idea was given up due to the complexity and added weight of
+- data structures, complications for handling barriers, as well as the
+- advantage of O(1) extraction and deletion (performance critical path) with
+- the existing list implementation vs heap based implementations.
+-
+-ii. Utilizes max_phys/hw_segments, and max_request_size parameters, to merge
+- within the limits that the device can handle (See 3.2.2)
+-
+-iii. Last merge hint
+-
+-In 2.5, information about the last merge is saved as a hint for the subsequent
+-request. This way, if sequential data is coming down the pipe, the hint can
+-be used to speed up merges without going through a scan.
++i. Binary tree
++AS and deadline i/o schedulers use red black binary trees for disk position
++sorting and searching, and a fifo linked list for time-based searching. This
++gives good scalability and good availablility of information. Requests are
++almost always dispatched in disk sort order, so a cache is kept of the next
++request in sort order to prevent binary tree lookups.
++
++This arrangement is not a generic block layer characteristic however, so
++elevators may implement queues as they please.
++
++ii. Last merge hint
++The last merge hint is part of the generic queue layer. I/O schedulers must do
++some management on it. For the most part, the most important thing is to make
++sure q->last_merge is cleared (set to NULL) when the request on it is no longer
++a candidate for merging (for example if it has been sent to the driver).
++
++The last merge performed is cached as a hint for the subsequent request. If
++sequential data is being submitted, the hint is used to perform merges without
++any scanning. This is not sufficient when there are multiple processes doing
++I/O though, so a "merge hash" is used by some schedulers.
++
++iii. Merge hash
++AS and deadline use a hash table indexed by the last sector of a request. This
++enables merging code to quickly look up "back merge" candidates, even when
++multiple I/O streams are being performed at once on one disk.
++
++"Front merges", a new request being merged at the front of an existing request,
++are far less common than "back merges" due to the nature of most I/O patterns.
++Front merges are handled by the binary trees in AS and deadline schedulers.
+
+ iv. Handling barrier cases
++A request with flags REQ_HARDBARRIER or REQ_SOFTBARRIER must not be ordered
++around. That is, they must be processed after all older requests, and before
++any newer ones. This includes merges!
++
++In AS and deadline schedulers, barriers have the effect of flushing the reorder
++queue. The performance cost of this will vary from nothing to a lot depending
++on i/o patterns and device characteristics. Obviously they won't improve
++performance, so their use should be kept to a minimum.
++
++v. Handling insertion position directives
++A request may be inserted with a position directive. The directives are one of
++ELEVATOR_INSERT_BACK, ELEVATOR_INSERT_FRONT, ELEVATOR_INSERT_SORT.
++
++ELEVATOR_INSERT_SORT is a general directive for non-barrier requests.
++ELEVATOR_INSERT_BACK is used to insert a barrier to the back of the queue.
++ELEVATOR_INSERT_FRONT is used to insert a barrier to the front of the queue, and
++overrides the ordering requested by any previous barriers. In practice this is
++harmless and required, because it is used for SCSI requeueing. This does not
++require flushing the reorder queue, so does not impose a performance penalty.
+
+-As mentioned earlier, barrier support is new to 2.5, and the i/o scheduler
+-has been modified accordingly.
+-
+-When a barrier comes in, then since insert happens in the form of a
+-linear scan, starting from the end, it just needs to be ensured that this
+-and future scans stops barrier point. This is achieved by skipping the
+-entire merge/scan logic for a barrier request, so it gets placed at the
+-end of the queue, and specifying a zero latency for the request containing
+-the bio so that no future requests can pass it.
+-
+-v. Plugging the queue to batch requests in anticipation of opportunities for
++vi. Plugging the queue to batch requests in anticipation of opportunities for
+ merge/sort optimizations
+
+ This is just the same as in 2.4 so far, though per-device unplugging
+@@ -1051,6 +1069,12 @@
+ blk_kick_queue() to unplug a specific queue (right away ?)
+ or optionally, all queues, is in the plan.
+
++4.3 I/O contexts
++I/O contexts provide a dynamically allocated per process data area. They may
++be used in I/O schedulers, and in the block layer (could be used for IO statis,
++priorities for example). See *io_context in drivers/block/ll_rw_blk.c, and
++as-iosched.c for an example of usage in an i/o scheduler.
++
+
+ 5. Scalability related changes
+
+Index: linux-2.6.0-test5/Documentation/cachetlb.txt
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/cachetlb.txt 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/Documentation/cachetlb.txt 2003-09-27 11:38:20.420424008 +0800
+@@ -165,15 +165,7 @@
+
+ Here are the routines, one by one:
+
+-1) void flush_cache_all(void)
+-
+- The most severe flush of all. After this interface runs,
+- the entire cpu cache is flushed.
+-
+- This is usually invoked when the kernel page tables are
+- changed, since such translations are "global" in nature.
+-
+-2) void flush_cache_mm(struct mm_struct *mm)
++1) void flush_cache_mm(struct mm_struct *mm)
+
+ This interface flushes an entire user address space from
+ the caches. That is, after running, there will be no cache
+@@ -183,7 +175,7 @@
+ page table operations such as what happens during
+ fork, exit, and exec.
+
+-3) void flush_cache_range(struct vm_area_struct *vma,
++2) void flush_cache_range(struct vm_area_struct *vma,
+ unsigned long start, unsigned long end)
+
+ Here we are flushing a specific range of (user) virtual
+@@ -200,7 +192,7 @@
+ call flush_cache_page (see below) for each entry which may be
+ modified.
+
+-4) void flush_cache_page(struct vm_area_struct *vma, unsigned long addr)
++3) void flush_cache_page(struct vm_area_struct *vma, unsigned long addr)
+
+ This time we need to remove a PAGE_SIZE sized range
+ from the cache. The 'vma' is the backing structure used by
+@@ -215,6 +207,30 @@
+
+ This is used primarily during fault processing.
+
++4) void flush_cache_kmaps(void)
++
++ This routine need only be implemented if the platform utilizes
++ highmem. It will be called right before all of the kmaps
++ are invalidated.
++
++ After running, there will be no entries in the cache for
++ the kernel virtual address range PKMAP_ADDR(0) to
++ PKMAP_ADDR(LAST_PKMAP).
++
++ This routing should be implemented in asm/highmem.h
++
++5) void flush_cache_vmap(unsigned long start, unsigned long end)
++ void flush_cache_vunmap(unsigned long start, unsigned long end)
++
++ Here in these two interfaces we are flushing a specific range
++ of (kernel) virtual addresses from the cache. After running,
++ there will be no entries in the cache for the kernel address
++ space for virtual addresses in the range 'start' to 'end'.
++
++ The first of these two routines is invoked after map_vm_area()
++ has installed the page table entries. The second is invoked
++ before unmap_vm_area() deletes the page table entries.
++
+ There exists another whole class of cpu cache issues which currently
+ require a whole different set of interfaces to handle properly.
+ The biggest problem is that of virtual aliasing in the data cache
+@@ -317,6 +333,26 @@
+ dirty. Again, see sparc64 for examples of how
+ to deal with this.
+
++ void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
++ unsigned long user_vaddr,
++ void *dst, void *src, int len)
++ void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
++ unsigned long user_vaddr,
++ void *dst, void *src, int len)
++ When the kernel needs to copy arbitrary data in and out
++ of arbitrary user pages (f.e. for ptrace()) it will use
++ these two routines.
++
++ The page has been kmap()'d, and flush_cache_page() has
++ just been called for the user mapping of this page (if
++ necessary).
++
++ Any necessary cache flushing or other coherency operations
++ that need to occur should happen here. If the processor's
++ instruction cache does not snoop cpu stores, it is very
++ likely that you will need to flush the instruction cache
++ for copy_to_user_page().
++
+ void flush_icache_range(unsigned long start, unsigned long end)
+ When the kernel stores into addresses that it will execute
+ out of (eg when loading modules), this function is called.
+@@ -324,17 +360,6 @@
+ If the icache does not snoop stores then this routine will need
+ to flush it.
+
+- void flush_icache_user_range(struct vm_area_struct *vma,
+- struct page *page, unsigned long addr, int len)
+- This is called when the kernel stores into addresses that are
+- part of the address space of a user process (which may be some
+- other process than the current process). The addr argument
+- gives the virtual address in that process's address space,
+- page is the page which is being modified, and len indicates
+- how many bytes have been modified. The modified region must
+- not cross a page boundary. Currently this is only called from
+- kernel/ptrace.c.
+-
+ void flush_icache_page(struct vm_area_struct *vma, struct page *page)
+ All the functionality of flush_icache_page can be implemented in
+ flush_dcache_page and update_mmu_cache. In 2.7 the hope is to
+Index: linux-2.6.0-test5/Documentation/Changes
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/Changes 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/Documentation/Changes 2003-09-27 11:38:20.424423400 +0800
+@@ -52,7 +52,7 @@
+ o Gnu make 3.78 # make --version
+ o binutils 2.12 # ld -v
+ o util-linux 2.10o # fdformat --version
+-o module-init-tools 0.9.9 # depmod -V
++o module-init-tools 0.9.10 # depmod -V
+ o e2fsprogs 1.29 # tune2fs
+ o jfsutils 1.1.3 # fsck.jfs -V
+ o reiserfsprogs 3.6.3 # reiserfsck -V 2>&1|grep reiserfsprogs
+@@ -62,7 +62,7 @@
+ o PPP 2.4.0 # pppd --version
+ o isdn4k-utils 3.1pre1 # isdnctrl 2>&1|grep version
+ o nfs-utils 1.0.5 # showmount --version
+-o procps 2.0.9 # ps --version
++o procps 3.1.13 # ps --version
+ o oprofile 0.5.3 # oprofiled --version
+
+ Kernel compilation
+Index: linux-2.6.0-test5/Documentation/devices.txt
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/devices.txt 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/Documentation/devices.txt 2003-09-27 11:38:20.448419752 +0800
+@@ -581,10 +581,9 @@
+ Partitions are handled the same way as for the first
+ interface (see major number 3).
+
+- 23 char Digiboard serial card - alternate devices
+- 0 = /dev/cud0 Callout device for ttyD0
+- 1 = /dev/cud1 Callout device for ttyD1
+- ...
++ 23 char Digiboard serial card - EPCA PCI (DGAP) driver.
++ 0-255 DGAP management devices.
++
+ block Mitsumi proprietary CD-ROM
+ 0 = /dev/mcd Mitsumi CD-ROM
+
+Index: linux-2.6.0-test5/Documentation/digiboard.txt
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/digiboard.txt 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/Documentation/digiboard.txt 2003-09-27 11:38:20.452419144 +0800
+@@ -17,6 +17,9 @@
+
+ Bernhard Kaindl (bkaindl@netway.at) 6. April 1997.
+
++As of the 2.6 Linux kernel, Digi International no longer supports
++this version of the driver.
++
+ Configuring the Driver
+ ----------------------
+
+Index: linux-2.6.0-test5/Documentation/digidgap.txt
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/digidgap.txt 2003-09-27 11:38:18.445724208 +0800
++++ linux-2.6.0-test5/Documentation/digidgap.txt 2003-09-27 11:38:20.452419144 +0800
+@@ -0,0 +1,18 @@
++=============================================================================
++
++ Digi Acceleport EPCA PCI (DGAP) Driver Installation Guide
++ for Linux Kernel 2.6
++ Copyright (C) 2003, Digi International
++============================================================================
++
++ This driver supports the Digi Acceleport Xr, Xr920, Xr422, XEM, C/X
++ and EPC/X PCI cards.
++
++ This driver requires the DGAP Tools package to be installed.
++
++ The Tools package can be found at http://www.digi.com
++
++ Once the Tools package is installed, run /usr/sbin/dgap_config to
++ set up the driver.
++
++============================================================================
+Index: linux-2.6.0-test5/Documentation/digiepca.txt
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/digiepca.txt 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/Documentation/digiepca.txt 2003-09-27 11:38:20.454418840 +0800
+@@ -2,19 +2,23 @@
+ ----------------------------
+ The Digi Intl. epca driver for Linux supports the following boards:
+
+-Digi PC/Xem, PC/Xr, PC/Xe, PC/Xi, PC/Xeve
+-Digi EISA/Xem, PCI/Xem, PCI/Xr
++Digi PC/Xem, PC/Xr, PC/Xe, PC/Xi, PC/Xeve ISA boards.
++Digi EISA/Xem.
+
+ Limitations:
+ ------------
+-Currently the driver only autoprobes for supported PCI boards.
++This driver no longer supports PCI Digi products.
++Use the new Digi DGAP driver instead.
++For more information read Documentation/digidgap.txt
++
++As of the 2.6 Linux kernel, Digi International no longer supports
++this version of the driver.
+
+ The Linux MAKEDEV command does not support generating the Digiboard
+ Devices. Users executing digiConfig to setup EISA and PC series cards
+ will have their device nodes automatically constructed (cud?? for ~CLOCAL,
+ and ttyD?? for CLOCAL). Users wishing to boot their board from the LILO
+-prompt, or those users booting PCI cards may use buildDIGI to construct
+-the necessary nodes.
++prompt may use buildDIGI to construct the necessary nodes.
+
+ Notes:
+ ------
+@@ -26,11 +30,6 @@
+ Device names start at 0 and continue up. Beware of this as previous Digi
+ drivers started device names with 1.
+
+-PCI boards are auto-detected and configured by the driver. PCI boards will
+-be allocated device numbers (internally) beginning with the lowest PCI slot
+-first. In other words a PCI card in slot 3 will always have higher device
+-nodes than a PCI card in slot 1.
+-
+ LILO config examples:
+ ---------------------
+ Using LILO's APPEND command, a string of comma separated identifiers or
+@@ -45,10 +44,8 @@
+ I/O Port where card is configured (in HEX if using string identifiers),
+ Base of memory window (in HEX if using string identifiers),
+
+-NOTE : PCI boards are auto-detected and configured. Do not attempt to
+-configure PCI boards with the LILO append command. If you wish to override
+-previous configuration data (As set by digiConfig), but you do not wish to
+-configure any specific card (Example if there are PCI cards in the system)
++NOTE : If you wish to override previous configuration data
++(As set by digiConfig), but you do not wish to configure any specific card
+ the following override command will accomplish this:
+ -> append="digi=2"
+
+@@ -59,7 +56,7 @@
+
+ Supporting Tools:
+ -----------------
+-Supporting tools include digiDload, digiConfig, buildPCI, and ditty. See
++Supporting tools include digiDload, digiConfig, and ditty. See
+ /usr/src/linux/Documentation/README.epca.dir/user.doc for more details. Note,
+ this driver REQUIRES that digiDload be executed prior to it being used.
+ Failure to do this will result in an ENODEV error.
+Index: linux-2.6.0-test5/Documentation/DocBook/gadget.tmpl
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/DocBook/gadget.tmpl 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/Documentation/DocBook/gadget.tmpl 2003-09-27 11:38:20.459418080 +0800
+@@ -468,6 +468,15 @@
+ information.
+ </para>
+
++<para>For users of Intel's PXA 2xx series processors,
++a <filename>pxa2xx_udc</filename> driver is available.
++</para>
++
++<para>At this writing, there are people at work on drivers in
++this framework for several other USB device controllers,
++with plans to make many of them be widely available.
++</para>
++
+ <!-- !Edrivers/usb/gadget/net2280.c -->
+
+ <para>A partial USB simulator,
+@@ -500,7 +509,7 @@
+
+ <para>There's an <emphasis>ethernet</emphasis> gadget
+ driver, which implements one of the most useful
+-<emphasis>Communications Device Class</emphasis> models.
++<emphasis>Communications Device Class</emphasis> (CDC) models.
+ One of the standards for cable modem interoperability even
+ specifies the use of this ethernet model as one of two
+ mandatory options.
+@@ -509,6 +518,11 @@
+ It provides access to a network where the gadget's CPU is one host,
+ which could easily be bridging, routing, or firewalling
+ access to other networks.
++Since some hardware can't fully implement the CDC Ethernet
++requirements, this driver also implements a "good parts only"
++subset of CDC Ethernet.
++(That subset doesn't advertise itself as CDC Ethernet,
++to avoid creating problems.)
+ </para>
+
+ <para>There is also support for user mode gadget drivers,
+@@ -522,6 +536,17 @@
+ won't require new kernel mode software.
+ </para>
+
++<para>There's a USB Mass Storage class driver, which provides
++a different solution for interoperability with systems such
++as MS-Windows and MacOS.
++That <emphasis>File-backed Storage</emphasis> driver uses a
++file or block device as backing store for a drive,
++like the <filename>loop</filename> driver.
++The USB host uses the BBB, CB, or CBI versions of the mass
++storage class specification, using transparent SCSI commands
++to access the data from the backing store.
++</para>
++
+ <para>Support for other kinds of gadget is expected to
+ be developed and contributed
+ over time, as this driver framework evolves.
+Index: linux-2.6.0-test5/Documentation/DocBook/writing_usb_driver.tmpl
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/DocBook/writing_usb_driver.tmpl 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/Documentation/DocBook/writing_usb_driver.tmpl 2003-09-27 11:38:20.465417168 +0800
+@@ -209,7 +209,7 @@
+ The driver now needs to verify that this device is actually one that it
+ can accept. If so, it returns 0.
+ If not, or if any error occurs during initialization, an errorcode
+- (such as <literal>-ENOMEM<literal> or <literal>-ENODEV<literal>)
++ (such as <literal>-ENOMEM</literal> or <literal>-ENODEV</literal>)
+ is returned from the probe function.
+ </para>
+ <para>
+@@ -327,6 +327,7 @@
+ talk to the device, the release function in the driver is called. In this
+ function we decrement our private usage count and wait for possible
+ pending writes:
++ </para>
+ <programlisting>
+ /* decrement our usage count for the device */
+ --skel->open_count;
+Index: linux-2.6.0-test5/Documentation/fb/neofb.txt
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/fb/neofb.txt 2003-09-27 11:38:18.445724208 +0800
++++ linux-2.6.0-test5/Documentation/fb/neofb.txt 2003-09-27 11:38:20.465417168 +0800
+@@ -0,0 +1,27 @@
++the neofb framebuffer driver supports the following Neomagic chipsets:
++
++NM2070 MagicGraph 128
++NM2090 MagicGraph 128V
++NM2093 MagicGraph 128ZV
++NM2097 MagicGraph 128ZV+
++NM2160 MagicGraph 128XD
++NM2200 MagicGraph 256AV
++NM2230 MagicGraph 256AV+
++NM2360 MagicGraph 256ZX
++NM2380 MagicGraph 256XL+
++
++with the following options:
++
++disabled Disable this driver's initialization.
++internal Enable output on internal LCD Display.
++external Enable output on external CRT.
++nostretch Disable stretching of modes smaller than LCD.
++nopciburst Disable PCI burst mode.
++libretto Force Libretto 100/110 800x480 LCD.
++picturebook Force Picturebook 1024x480 LCD.
++
++at the boot prompt:
++ video=neofb:picturebook
++
++as a module:
++ modprobe neofb picturebook=1
+Index: linux-2.6.0-test5/Documentation/i386/kgdb/andthen
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/i386/kgdb/andthen 2003-09-27 11:38:18.445724208 +0800
++++ linux-2.6.0-test5/Documentation/i386/kgdb/andthen 2003-09-27 11:38:20.466417016 +0800
+@@ -0,0 +1,100 @@
++
++define set_andthen
++ set var $thp=0
++ set var $thp=(struct kgdb_and_then_struct *)&kgdb_data[0]
++ set var $at_size = (sizeof kgdb_data)/(sizeof *$thp)
++ set var $at_oc=kgdb_and_then_count
++ set var $at_cc=$at_oc
++end
++
++define andthen_next
++ set var $at_cc=$arg0
++end
++
++define andthen
++ andthen_set_edge
++ if ($at_cc >= $at_oc)
++ printf "Outside window. Window size is %d\n",($at_oc-$at_low)
++ else
++ printf "%d: ",$at_cc
++ output *($thp+($at_cc++ % $at_size ))
++ printf "\n"
++ end
++end
++define andthen_set_edge
++ set var $at_oc=kgdb_and_then_count
++ set var $at_low = $at_oc - $at_size
++ if ($at_low < 0 )
++ set var $at_low = 0
++ end
++ if (( $at_cc > $at_oc) || ($at_cc < $at_low))
++ printf "Count outside of window, setting count to "
++ if ($at_cc >= $at_oc)
++ set var $at_cc = $at_oc
++ else
++ set var $at_cc = $at_low
++ end
++ printf "%d\n",$at_cc
++ end
++end
++
++define beforethat
++ andthen_set_edge
++ if ($at_cc <= $at_low)
++ printf "Outside window. Window size is %d\n",($at_oc-$at_low)
++ else
++ printf "%d: ",$at_cc-1
++ output *($thp+(--$at_cc % $at_size ))
++ printf "\n"
++ end
++end
++
++document andthen_next
++ andthen_next <count>
++ . sets the number of the event to display next. If this event
++ . is not in the event pool, either andthen or beforethat will
++ . correct it to the nearest event pool edge. The event pool
++ . ends at the last event recorded and begins <number of events>
++ . prior to that. If beforethat is used next, it will display
++ . event <count> -1.
++.
++ andthen commands are: set_andthen, andthen_next, andthen and beforethat
++end
++
++
++document andthen
++ andthen
++. displays the next event in the list. <set_andthen> sets up to display
++. the oldest saved event first.
++. <count> (optional) count of the event to display.
++. note the number of events saved is specified at configure time.
++. if events are saved between calls to andthen the index will change
++. but the displayed event will be the next one (unless the event buffer
++. is overrun).
++.
++. andthen commands are: set_andthen, andthen_next, andthen and beforethat
++end
++
++document set_andthen
++ set_andthen
++. sets up to use the <andthen> and <beforethat> commands.
++. if you have defined your own struct, use the above and
++. then enter the following:
++. p $thp=(struct kgdb_and_then_structX *)&kgdb_data[0]
++. where <kgdb_and_then_structX> is the name of your structure.
++.
++. andthen commands are: set_andthen, andthen_next, andthen and beforethat
++end
++
++document beforethat
++ beforethat
++. displays the next prior event in the list. <set_andthen> sets up to
++. display the last occuring event first.
++.
++. note the number of events saved is specified at configure time.
++. if events are saved between calls to beforethat the index will change
++. but the displayed event will be the next one (unless the event buffer
++. is overrun).
++.
++. andthen commands are: set_andthen, andthen_next, andthen and beforethat
++end
+Index: linux-2.6.0-test5/Documentation/i386/kgdb/debug-nmi.txt
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/i386/kgdb/debug-nmi.txt 2003-09-27 11:38:18.446724056 +0800
++++ linux-2.6.0-test5/Documentation/i386/kgdb/debug-nmi.txt 2003-09-27 11:38:20.466417016 +0800
+@@ -0,0 +1,37 @@
++Subject: Debugging with NMI
++Date: Mon, 12 Jul 1999 11:28:31 -0500
++From: David Grothe <dave@gcom.com>
++Organization: Gcom, Inc
++To: David Grothe <dave@gcom.com>
++
++Kernel hackers:
++
++Maybe this is old hat, but it is new to me --
++
++On an ISA bus machine, if you short out the A1 and B1 pins of an ISA
++slot you will generate an NMI to the CPU. This interrupts even a
++machine that is hung in a loop with interrupts disabled. Used in
++conjunction with kgdb <
++ftp://ftp.gcom.com/pub/linux/src/kgdb-2.3.35/kgdb-2.3.35.tgz > you can
++gain debugger control of a machine that is hung in the kernel! Even
++without kgdb the kernel will print a stack trace so you can find out
++where it was hung.
++
++The A1/B1 pins are directly opposite one another and the farthest pins
++towards the bracket end of the ISA bus socket. You can stick a paper
++clip or multi-meter probe between them to short them out.
++
++I had a spare ISA bus to PC104 bus adapter around. The PC104 end of the
++board consists of two rows of wire wrap pins. So I wired a push button
++between the A1/B1 pins and now have an ISA board that I can stick into
++any ISA bus slot for debugger entry.
++
++Microsoft has a circuit diagram of a PCI card at
++http://www.microsoft.com/hwdev/DEBUGGING/DMPSW.HTM. If you want to
++build one you will have to mail them and ask for the PAL equations.
++Nobody makes one comercially.
++
++[THIS TIP COMES WITH NO WARRANTY WHATSOEVER. It works for me, but if
++your machine catches fire, it is your problem, not mine.]
++
++-- Dave (the kgdb guy)
+Index: linux-2.6.0-test5/Documentation/i386/kgdb/gdb-globals.txt
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/i386/kgdb/gdb-globals.txt 2003-09-27 11:38:18.446724056 +0800
++++ linux-2.6.0-test5/Documentation/i386/kgdb/gdb-globals.txt 2003-09-27 11:38:20.467416864 +0800
+@@ -0,0 +1,71 @@
++Sender: akale@veritas.com
++Date: Fri, 23 Jun 2000 19:26:35 +0530
++From: "Amit S. Kale" <akale@veritas.com>
++Organization: Veritas Software (India)
++To: Dave Grothe <dave@gcom.com>, linux-kernel@vger.rutgers.edu
++CC: David Milburn <dmilburn@wirespeed.com>,
++ "Edouard G. Parmelan" <Edouard.Parmelan@quadratec.fr>,
++ ezannoni@cygnus.com, Keith Owens <kaos@ocs.com.au>
++Subject: Re: Module debugging using kgdb
++
++Dave Grothe wrote:
++>
++> Amit:
++>
++> There is a 2.4.0 version of kgdb on our ftp site:
++> ftp://ftp.gcom.com/pub/linux/src/kgdb. I mirrored your version of gdb
++> and loadmodule.sh there.
++>
++> Have a look at the README file and see if I go it right. If not, send
++> me some corrections and I will update it.
++>
++> Does your version of gdb solve the global variable problem?
++
++Yes.
++Thanks to Elena Zanoni, gdb (developement version) can now calculate
++correctly addresses of dynamically loaded object files. I have not been
++following gdb developement for sometime and am not sure when symbol
++address calculation fix is going to appear in a gdb stable version.
++
++Elena, any idea when the fix will make it to a prebuilt gdb from a
++redhat release?
++
++For the time being I have built a gdb developement version. It can be
++used for module debugging with loadmodule.sh script.
++
++The problem with calculating of module addresses with previous versions
++of gdb was as follows:
++gdb did not use base address of a section while calculating address of
++a symbol in the section in an object file loaded via 'add-symbol-file'.
++It used address of .text segment instead. Due to this addresses of
++symbols in .data, .bss etc. (e.g. global variables) were calculated incorrectly.
++
++Above mentioned fix allow gdb to use base address of a segment while
++calculating address of a symbol in it. It adds a parameter '-s' to
++'add-symbol-file' command for specifying base address of a segment.
++
++loadmodule.sh script works as follows.
++
++1. Copy a module file to target machine.
++2. Load the module on the target machine using insmod with -m parameter.
++insmod produces a module load map which contains base addresses of all
++sections in the module and addresses of symbols in the module file.
++3. Find all sections and their base addresses in the module from
++the module map.
++4. Generate a script that loads the module file. The script uses
++'add-symbol-file' and specifies address of text segment followed by
++addresses of all segments in the module.
++
++Here is an example gdb script produced by loadmodule.sh script.
++
++add-symbol-file foo 0xd082c060 -s .text.lock 0xd08cbfb5
++-s .fixup 0xd08cfbdf -s .rodata 0xd08cfde0 -s __ex_table 0xd08e3b38
++-s .data 0xd08e3d00 -s .bss 0xd08ec8c0 -s __ksymtab 0xd08ee838
++
++With this command gdb can calculate addresses of symbols in ANY segment
++in a module file.
++
++Regards.
++--
++Amit Kale
++Veritas Software ( http://www.veritas.com )
+Index: linux-2.6.0-test5/Documentation/i386/kgdb/gdbinit
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/i386/kgdb/gdbinit 2003-09-27 11:38:18.446724056 +0800
++++ linux-2.6.0-test5/Documentation/i386/kgdb/gdbinit 2003-09-27 11:38:20.467416864 +0800
+@@ -0,0 +1,14 @@
++shell echo -e "\003" >/dev/ttyS0
++set remotebaud 38400
++target remote /dev/ttyS0
++define si
++stepi
++printf "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n", $eax, $ebx, $ecx, $edx
++printf "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n", $esi, $edi, $ebp, $esp
++x/i $eip
++end
++define ni
++nexti
++printf "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n", $eax, $ebx, $ecx, $edx
++printf "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n", $esi, $edi, $ebp, $esp
++x/i $eip
+Index: linux-2.6.0-test5/Documentation/i386/kgdb/gdbinit.hw
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/i386/kgdb/gdbinit.hw 2003-09-27 11:38:18.446724056 +0800
++++ linux-2.6.0-test5/Documentation/i386/kgdb/gdbinit.hw 2003-09-27 11:38:20.468416712 +0800
+@@ -0,0 +1,117 @@
++
++#Using ia-32 hardware breakpoints.
++#
++#4 hardware breakpoints are available in ia-32 processors. These breakpoints
++#do not need code modification. They are set using debug registers.
++#
++#Each hardware breakpoint can be of one of the
++#three types: execution, write, access.
++#1. An Execution breakpoint is triggered when code at the breakpoint address is
++#executed.
++#2. A write breakpoint ( aka watchpoints ) is triggered when memory location
++#at the breakpoint address is written.
++#3. An access breakpoint is triggered when memory location at the breakpoint
++#address is either read or written.
++#
++#As hardware breakpoints are available in limited number, use software
++#breakpoints ( br command in gdb ) instead of execution hardware breakpoints.
++#
++#Length of an access or a write breakpoint defines length of the datatype to
++#be watched. Length is 1 for char, 2 short , 3 int.
++#
++#For placing execution, write and access breakpoints, use commands
++#hwebrk, hwwbrk, hwabrk
++#To remove a breakpoint use hwrmbrk command.
++#
++#These commands take following types of arguments. For arguments associated
++#with each command, use help command.
++#1. breakpointno: 0 to 3
++#2. length: 1 to 3
++#3. address: Memory location in hex ( without 0x ) e.g c015e9bc
++#
++#Use the command exinfo to find which hardware breakpoint occured.
++
++#hwebrk breakpointno address
++define hwebrk
++ maintenance packet Y$arg0,0,0,$arg1
++end
++document hwebrk
++ hwebrk <breakpointno> <address>
++ Places a hardware execution breakpoint
++ <breakpointno> = 0 - 3
++ <address> = Hex digits without leading "0x".
++end
++
++#hwwbrk breakpointno length address
++define hwwbrk
++ maintenance packet Y$arg0,1,$arg1,$arg2
++end
++document hwwbrk
++ hwwbrk <breakpointno> <length> <address>
++ Places a hardware write breakpoint
++ <breakpointno> = 0 - 3
++ <length> = 1 (1 byte), 2 (2 byte), 3 (4 byte)
++ <address> = Hex digits without leading "0x".
++end
++
++#hwabrk breakpointno length address
++define hwabrk
++ maintenance packet Y$arg0,1,$arg1,$arg2
++end
++document hwabrk
++ hwabrk <breakpointno> <length> <address>
++ Places a hardware access breakpoint
++ <breakpointno> = 0 - 3
++ <length> = 1 (1 byte), 2 (2 byte), 3 (4 byte)
++ <address> = Hex digits without leading "0x".
++end
++
++#hwrmbrk breakpointno
++define hwrmbrk
++ maintenance packet y$arg0
++end
++document hwrmbrk
++ hwrmbrk <breakpointno>
++ <breakpointno> = 0 - 3
++ Removes a hardware breakpoint
++end
++
++define reboot
++ maintenance packet r
++end
++#exinfo
++define exinfo
++ maintenance packet qE
++end
++document exinfo
++ exinfo
++ Gives information about a breakpoint.
++end
++define get_th
++ p $th=(struct thread_info *)((int)$esp & ~8191)
++end
++document get_th
++ get_tu
++ Gets and prints the current thread_info pointer, Defines th to be it.
++end
++define get_cu
++ p $cu=((struct thread_info *)((int)$esp & ~8191))->task
++end
++document get_cu
++ get_cu
++ Gets and print the "current" value. Defines $cu to be it.
++end
++define int_off
++ set var $flags=$eflags
++ set $eflags=$eflags&~0x200
++ end
++define int_on
++ set var $eflags|=$flags&0x200
++ end
++document int_off
++ saves the current interrupt state and clears the processor interrupt
++ flag. Use int_on to restore the saved flag.
++end
++document int_on
++ Restores the interrupt flag saved by int_off.
++end
+Index: linux-2.6.0-test5/Documentation/i386/kgdb/gdbinit-modules
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/i386/kgdb/gdbinit-modules 2003-09-27 11:38:18.446724056 +0800
++++ linux-2.6.0-test5/Documentation/i386/kgdb/gdbinit-modules 2003-09-27 11:38:20.468416712 +0800
+@@ -0,0 +1,146 @@
++#
++# Usefull GDB user-command to debug Linux Kernel Modules with gdbstub.
++#
++# This don't work for Linux-2.0 or older.
++#
++# Author Edouard G. Parmelan <Edouard.Parmelan@quadratec.fr>
++#
++#
++# Fri Apr 30 20:33:29 CEST 1999
++# First public release.
++#
++# Major cleanup after experiment Linux-2.0 kernel without success.
++# Symbols of a module are not in the correct order, I can't explain
++# why :(
++#
++# Fri Mar 19 15:41:40 CET 1999
++# Initial version.
++#
++# Thu Jan 6 16:29:03 CST 2000
++# A little fixing by Dave Grothe <dave@gcom.com>
++#
++# Mon Jun 19 09:33:13 CDT 2000
++# Alignment changes from Edouard Parmelan
++#
++# The basic idea is to find where insmod load the module and inform
++# GDB to load the symbol table of the module with the GDB command
++# ``add-symbol-file <object> <address>''.
++#
++# The Linux kernel holds the list of all loaded modules in module_list,
++# this list end with &kernel_module (exactly with module->next == NULL,
++# but the last module is not a real module).
++#
++# Insmod allocates the struct module before the object file. Since
++# Linux-2.1, this structure contain his size. The real address of
++# the object file is then (char*)module + module->size_of_struct.
++#
++# You can use three user functions ``mod-list'', ``mod-print-symbols''
++# and ``add-module-symbols''.
++#
++# mod-list list all loaded modules with the format:
++# <module-address> <module-name>
++#
++# As soon as you have found the address of your module, you can
++# print its exported symbols (mod-print-symbols) or inform GDB to add
++# symbols from your module file (mod-add-symbols).
++#
++# The argument that you give to mod-print-symbols or mod-add-symbols
++# is the <module-address> from the mod-list command.
++#
++# When using the mod-add-symbols command you must also give the full
++# pathname of the modules object code file.
++#
++# The command mod-add-lis is an example of how to make this easier.
++# You can edit this macro to contain the path name of your own
++# favorite module and then use it as a shorthand to load it. You
++# still need the module-address, however.
++#
++# The internal function ``mod-validate'' set the GDB variable $mod
++# as a ``struct module*'' if the kernel known the module otherwise
++# $mod is set to NULL. This ensure to not add symbols for a wrong
++# address.
++#
++# Have a nice hacking day !
++#
++#
++define mod-list
++ set $mod = (struct module*)module_list
++ # the last module is the kernel, ignore it
++ while $mod != &kernel_module
++ printf "%p\t%s\n", (long)$mod, ($mod)->name
++ set $mod = $mod->next
++ end
++end
++document mod-list
++List all modules in the form: <module-address> <module-name>
++Use the <module-address> as the argument for the other
++mod-commands: mod-print-symbols, mod-add-symbols.
++end
++
++define mod-validate
++ set $mod = (struct module*)module_list
++ while ($mod != $arg0) && ($mod != &kernel_module)
++ set $mod = $mod->next
++ end
++ if $mod == &kernel_module
++ set $mod = 0
++ printf "%p is not a module\n", $arg0
++ end
++end
++document mod-validate
++mod-validate <module-address>
++Internal user-command used to validate the module parameter.
++If <module> is a real loaded module, set $mod to it otherwise set $mod to 0.
++end
++
++
++define mod-print-symbols
++ mod-validate $arg0
++ if $mod != 0
++ set $i = 0
++ while $i < $mod->nsyms
++ set $sym = $mod->syms[$i]
++ printf "%p\t%s\n", $sym->value, $sym->name
++ set $i = $i + 1
++ end
++ end
++end
++document mod-print-symbols
++mod-print-symbols <module-address>
++Print all exported symbols of the module. see mod-list
++end
++
++
++define mod-add-symbols-align
++ mod-validate $arg0
++ if $mod != 0
++ set $mod_base = ($mod->size_of_struct + (long)$mod)
++ if ($arg2 != 0) && (($mod_base & ($arg2 - 1)) != 0)
++ set $mod_base = ($mod_base | ($arg2 - 1)) + 1
++ end
++ add-symbol-file $arg1 $mod_base
++ end
++end
++document mod-add-symbols-align
++mod-add-symbols-align <module-address> <object file path name> <align>
++Load the symbols table of the module from the object file where
++first section aligment is <align>.
++To retreive alignment, use `objdump -h <object file path name>'.
++end
++
++define mod-add-symbols
++ mod-add-symbols-align $arg0 $arg1 sizeof(long)
++end
++document mod-add-symbols
++mod-add-symbols <module-address> <object file path name>
++Load the symbols table of the module from the object file.
++Default alignment is 4. See mod-add-symbols-align.
++end
++
++define mod-add-lis
++ mod-add-symbols-align $arg0 /usr/src/LiS/streams.o 16
++end
++document mod-add-lis
++mod-add-lis <module-address>
++Does mod-add-symbols <module-address> /usr/src/LiS/streams.o
++end
+Index: linux-2.6.0-test5/Documentation/i386/kgdb/kgdbeth.txt
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/i386/kgdb/kgdbeth.txt 2003-09-27 11:38:18.446724056 +0800
++++ linux-2.6.0-test5/Documentation/i386/kgdb/kgdbeth.txt 2003-09-27 11:38:20.469416560 +0800
+@@ -0,0 +1,118 @@
++KGDB over ethernet
++==================
++
++Authors
++-------
++
++Robert Walsh <rjwalsh@durables.org> (2.6 port)
++wangdi <wangdi@clusterfs.com> (2.6 port)
++San Mehat (original 2.4 code)
++
++
++Introduction
++------------
++
++KGDB supports debugging over ethernet. Only a limited set of ethernet
++devices are supported right now, but adding support for new devices
++should not be too complicated. See "New Devices" below for details.
++
++
++Terminology
++-----------
++
++This document uses the following terms:
++
++ TARGET: the machine being debugged.
++ HOST: the machine running gdb.
++
++
++Usage
++-----
++
++You need to use the following command-line options on the TARGET kernel:
++
++ gdbeth=DEVICENUM
++ gdbeth_remoteip=HOSTIPADDR
++ gdbeth_remotemac=REMOTEMAC
++ gdbeth_localmac=LOCALMAC
++
++kgdbeth=DEVICENUM sets the ethernet device number to listen on for
++debugging packets. e.g. kgdbeth=0 listens on eth0.
++
++kgdbeth_remoteip=HOSTIPADDR sets the IP address of the HOST machine.
++Only packets originating from this IP address will be accepted by the
++debugger. e.g. kgdbeth_remoteip=192.168.2.2
++
++kgdbeth_remotemac=REMOTEMAC sets the ethernet address of the HOST machine.
++e.g. kgdbeth_remotemac=00:07:70:12:4E:F5
++
++kgdbeth_localmac=LOCALMAC sets the ethernet address of the TARGET machine.
++e.g. kgdbeth_localmac=00:10:9F:18:21:3C
++
++You can also set the following command-line option on the TARGET kernel:
++
++ kgdbeth_listenport=PORT
++
++kgdbeth_listenport sets the UDP port to listen on for gdb debugging
++packets. The default value is "6443". e.g. kgdbeth_listenport=7654
++causes the kernel to listen on UDP port 7654 for debugging packets.
++
++On the HOST side, run gdb as normal and use a remote UDP host as the
++target:
++
++ % gdb ./vmlinux
++ GNU gdb Red Hat Linux (5.3post-0.20021129.18rh)
++ Copyright 2003 Free Software Foundation, Inc.
++ GDB is free software, covered by the GNU General Public License, and you are
++ welcome to change it and/or distribute copies of it under certain conditions.
++ Type "show copying" to see the conditions.
++ There is absolutely no warranty for GDB. Type "show warranty" for details.
++ This GDB was configured as "i386-redhat-linux-gnu"...
++ (gdb) target remote udp:HOSTNAME:6443
++
++You can now continue as if you were debugging over a serial line.
++
++Observations
++------------
++
++I've used this with NFS and various other network applications (ssh,
++etc.) and it's doesn't appear to interfere with their operation in
++any way. It doesn't seem to effect the NIC it uses - i.e. you don't
++need a dedicated NIC for this.
++
++Limitations
++-----------
++
++In the inital release of this code you _must_ break into the system with the
++debugger by hand, early after boot, as described above.
++
++Otherwise, the first time the kernel tries to enter the debugger (say, via an
++oops or a BUG), the kgdb stub will doublefault and die because things aren't
++fully set up yet.
++
++Supported devices
++-----------------
++
++Right now, the following drivers are supported:
++
++ e100 driver (drivers/net/e100/*)
++ 3c59x driver (drivers/net/3c59x.c)
++
++
++New devices
++-----------
++
++Supporting a new device is straightforward. Just add a "poll" routine to
++the driver and hook it into the poll_controller field in the netdevice
++structure. For an example, look in drivers/net/3c59x.c and search
++for CONFIG_KGDB (two places.)
++
++The poll routine is usually quite simple - it's usually enough to just
++disable interrupts, call the device's interrupt routine and re-enable
++interrupts again.
++
++
++Bug reports
++-----------
++
++Send bug reports to Robert Walsh <rjwalsh@durables.org>.
+Index: linux-2.6.0-test5/Documentation/i386/kgdb/kgdb.txt
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/i386/kgdb/kgdb.txt 2003-09-27 11:38:18.446724056 +0800
++++ linux-2.6.0-test5/Documentation/i386/kgdb/kgdb.txt 2003-09-27 11:38:20.471416256 +0800
+@@ -0,0 +1,775 @@
++Last edit: <20030806.1637.12>
++This file has information specific to the i386 kgdb option. Other
++platforms with the kgdb option may behave in a similar fashion.
++
++New features:
++============
++20030806.1557.37
++This version was made against the 2.6.0-test2 kernel. We have made the
++following changes:
++
++- The getthread() code in the stub calls find_task_by_pid(). It fails
++ if we are early in the bring up such that the pid arrays have yet to
++ be allocated. We have added a line to kernel/pid.c to make
++ "kgdb_pid_init_done" true once the arrays are allocated. This way the
++ getthread() code knows not to call. This is only used by the thread
++ debugging stuff and threads will not yet exist at this point in the
++ boot.
++
++- For some reason, gdb was not asking for a new thread list when the
++ "info thread" command was given. We changed to the newer version of
++ the thread info command and gdb now seems to ask when needed. Result,
++ we now get all threads in the thread list.
++
++- We now respond to the ThreadExtraInfo request from gdb with the thread
++ name from task_struct .comm. This then appears in the thread list.
++ Thoughts on additional options for this are welcome. Things such as
++ "has BKL" and "Preempted" come to mind. I think we could have a flag
++ word that could enable different bits of info here.
++
++- We now honor, sort of, the C and S commands. These are continue and
++ single set after delivering a signal. We ignore the signal and do the
++ requested action. This only happens when we told gdb that a signal
++ was the reason for entry, which is only done on memory faults. The
++ result is that you can now continue into the Oops.
++
++- We changed the -g to -gdwarf-2. This seems to be the same as -ggdb,
++ but it is more exact on what language to use.
++
++- We added two dwarf2 include files and a bit of code at the end of
++ entry.S. This does not yet work, so it is disabled. Still we want to
++ keep track of the code and "maybe" someone out there can fix it.
++
++- Randy Dunlap sent some fix ups for this file which are now merged.
++
++- Hugh Dickins sent a fix to a bit of code in traps.c that prevents a
++ compiler warning if CONFIG_KGDB is off (now who would do that :).
++
++- Andrew Morton sent a fix for the serial driver which is now merged.
++
++- Andrew also sent a change to the stub around the cpu managment code
++ which is also merged.
++
++- Andrew also sent a patch to make "f" as well as "g" work as SysRq
++ commands to enter kgdb, merged.
++
++- If CONFIG_KGDB and CONFIG_DEBUG_SPINLOCKS are both set we added a
++ "who" field to the spinlock data struct. This is filled with
++ "current" when ever the spinlock suceeds. Useful if you want to know
++ who has the lock.
++
++_ And last, but not least, we fixed the "get_cu" macro to properly get
++ the current value of "current".
++
++New features:
++============
++20030505.1827.27
++We are starting to align with the sourceforge version, at least in
++commands. To this end, the boot command string to start kgdb at
++boot time has been changed from "kgdb" to "gdb".
++
++Andrew Morton sent a couple of patches which are now included as follows:
++1.) We now return a flag to the interrupt handler.
++2.) We no longer use smp_num_cpus (a conflict with the lock meter).
++3.) And from William Lee Irwin III <wli@holomorphy.com> code to make
++ sure high-mem is set up before we attempt to register our interrupt
++ handler.
++We now include asm/kgdb.h from config.h so you will most likely never
++have to include it. It also 'NULLS' the kgdb macros you might have in
++your code when CONFIG_KGDB is not defined. This allows you to just
++turn off CONFIG_KGDB to turn off all the kgdb_ts() calls and such.
++This include is conditioned on the machine being an x86 so as to not
++mess with other archs.
++
++20020801.1129.03
++This is currently the version for the 2.4.18 (and beyond?) kernel.
++
++We have several new "features" beginning with this version:
++
++1.) Kgdb now syncs the "other" CPUs with a cross-CPU NMI. No more
++ waiting and it will pull that guy out of an IRQ off spin lock :)
++
++2.) We doctored up the code that tells where a task is waiting and
++ included it so that the "info thread" command will show a bit more
++ than "schedule()". Try it...
++
++3.) Added the ability to call a function from gdb. All the standard gdb
++ issues apply, i.e. if you hit a breakpoint in the function, you are
++ not allowed to call another (gdb limitation, not kgdb). To help
++ this capability we added a memory allocation function. Gdb does not
++ return this memory (it is used for strings that you pass to that function
++ you are calling from gdb) so we fixed up a way to allow you to
++ manually return the memory (see below).
++
++4.) Kgdb time stamps (kgdb_ts()) are enhanced to expand what was the
++ interrupt flag to now also include the preemption count and the
++ "in_interrupt" info. The flag is now called "with_pif" to indicate
++ the order, preempt_count, in_interrupt, flag. The preempt_count is
++ shifted left by 4 bits so you can read the count in hex by dropping
++ the low order digit. In_interrupt is in bit 1, and the flag is in
++ bit 0.
++
++5.) The command: "p kgdb_info" is now expanded and prints something
++ like:
++(gdb) p kgdb_info
++$2 = {used_malloc = 0, called_from = 0xc0107506, entry_tsc = 67468627259,
++ errcode = 0, vector = 3, print_debug_info = 0, hold_on_sstep = 1,
++ cpus_waiting = {{task = 0xc027a000, pid = 32768, hold = 0,
++ regs = 0xc027bf84}, {task = 0x0, pid = 0, hold = 0, regs = 0x0}}}
++
++ Things to note here: a.) used_malloc is the amount of memory that
++ has been malloc'ed to do calls from gdb. You can reclaim this
++ memory like this: "p kgdb_info.used_malloc=0" Cool, huh? b.)
++ cpus_waiting is now "sized" by the number of CPUs you enter at
++ configure time in the kgdb configure section. This is NOT used
++ anywhere else in the system, but it is "nice" here. c.) The task's
++ "pid" is now in the structure. This is the pid you will need to use
++ to decode to the thread id to get gdb to look at that thread.
++ Remember that the "info thread" command prints a list of threads
++ wherein it numbers each thread with its reference number followed
++ by the thread's pid. Note that the per-CPU idle threads actually
++ have pids of 0 (yes, there is more than one pid 0 in an SMP system).
++ To avoid confusion, kgdb numbers these threads with numbers beyond
++ the MAX_PID. That is why you see 32768 and above.
++
++6.) A subtle change, we now provide the complete register set for tasks
++ that are active on the other CPUs. This allows better trace back on
++ those tasks.
++
++ And, let's mention what we could not fix. Back-trace from all but the
++ thread that we trapped will, most likely, have a bogus entry in it.
++ The problem is that gdb does not recognize the entry code for
++ functions that use "current" near (at all?) the entry. The compiler
++ is putting the "current" decode as the first two instructions of the
++ function where gdb expects to find %ebp changing code. Back trace
++ also has trouble with interrupt frames. I am talking with Daniel
++ Jacobowitz about some way to fix this, but don't hold your breath.
++
++20011220.0050.35
++Major enhancement with this version is the ability to hold one or more
++CPUs in an SMP system while allowing the others to continue. Also, by
++default only the current CPU is enabled on single-step commands (please
++note that gdb issues single-step commands at times other than when you
++use the si command).
++
++Another change is to collect some useful information in
++a global structure called "kgdb_info". You should be able to just:
++
++p kgdb_info
++
++although I have seen cases where the first time this is done gdb just
++prints the first member but prints the whole structure if you then enter
++CR (carriage return or enter). This also works:
++
++p *&kgdb_info
++
++Here is a sample:
++(gdb) p kgdb_info
++$4 = {called_from = 0xc010732c, entry_tsc = 32804123790856, errcode = 0,
++ vector = 3, print_debug_info = 0}
++
++"Called_from" is the return address from the current entry into kgdb.
++Sometimes it is useful to know why you are in kgdb, for example, was
++it an NMI or a real breakpoint? The simple way to interrogate this
++return address is:
++
++l *0xc010732c
++
++which will print the surrounding few lines of source code.
++
++"Entry_tsc" is the CPU TSC on entry to kgdb (useful to compare to the
++kgdb_ts entries).
++
++"errcode" and "vector" are other entry parameters which may be helpful on
++some traps.
++
++"print_debug_info" is the internal debugging kgdb print enable flag. Yes,
++you can modify it.
++
++In SMP systems kgdb_info also includes the "cpus_waiting" structure and
++"hold_on_step":
++
++(gdb) p kgdb_info
++$7 = {called_from = 0xc0112739, entry_tsc = 1034936624074, errcode = 0,
++ vector = 2, print_debug_info = 0, hold_on_sstep = 1, cpus_waiting = {{
++ task = 0x0, hold = 0, regs = 0x0}, {task = 0xc71b8000, hold = 0,
++ regs = 0xc71b9f70}, {task = 0x0, hold = 0, regs = 0x0}, {task = 0x0,
++ hold = 0, regs = 0x0}, {task = 0x0, hold = 0, regs = 0x0}, {task = 0x0,
++ hold = 0, regs = 0x0}, {task = 0x0, hold = 0, regs = 0x0}, {task = 0x0,
++ hold = 0, regs = 0x0}}}
++
++"Cpus_waiting" has an entry for each CPU other than the current one that
++has been stopped. Each entry contains the task_struct address for that
++CPU, the address of the regs for that task and a hold flag. All these
++have the proper typing so that, for example:
++
++p *kgdb_info.cpus_waiting[1].regs
++
++will print the registers for CPU 1.
++
++"Hold_on_sstep" is a new feature with this version and comes up set or
++true. What this means is that whenever kgdb is asked to single-step all
++other CPUs are held (i.e. not allowed to execute). The flag applies to
++all but the current CPU and, again, can be changed:
++
++p kgdb_info.hold_on_sstep=0
++
++restores the old behavior of letting all CPUs run during single-stepping.
++
++Likewise, each CPU has a "hold" flag, which if set, locks that CPU out
++of execution. Note that this has some risk in cases where the CPUs need
++to communicate with each other. If kgdb finds no CPU available on exit,
++it will push a message thru gdb and stay in kgdb. Note that it is legal
++to hold the current CPU as long as at least one CPU can execute.
++
++20010621.1117.09
++This version implements an event queue. Events are signaled by calling
++a function in the kgdb stub and may be examined from gdb. See EVENTS
++below for details. This version also tightens up the interrupt and SMP
++handling to not allow interrupts on the way to kgdb from a breakpoint
++trap. It is fine to allow these interrupts for user code, but not
++system debugging.
++
++Version
++=======
++
++This version of the kgdb package was developed and tested on
++kernel version 2.4.16. It will not install on any earlier kernels.
++It is possible that it will continue to work on later versions
++of 2.4 and then versions of 2.5 (I hope).
++
++
++Debugging Setup
++===============
++
++Designate one machine as the "development" machine. This is the
++machine on which you run your compiles and which has your source
++code for the kernel. Designate a second machine as the "target"
++machine. This is the machine that will run your experimental
++kernel.
++
++The two machines will be connected together via a serial line out
++one or the other of the COM ports of the PC. You will need the
++appropriate modem eliminator (null modem) cable(s) for this.
++
++Decide on which tty port you want the machines to communicate, then
++connect them up back-to-back using the null modem cable. COM1 is
++/dev/ttyS0 and COM2 is /dev/ttyS1. You should test this connection
++with the two machines prior to trying to debug a kernel. Once you
++have it working, on the TARGET machine, enter:
++
++setserial /dev/ttyS0 (or what ever tty you are using)
++
++and record the port address and the IRQ number.
++
++On the DEVELOPMENT machine you need to apply the patch for the kgdb
++hooks. You have probably already done that if you are reading this
++file.
++
++On your DEVELOPMENT machine, go to your kernel source directory and do
++"make Xconfig" where X is one of "x", "menu", or "". If you are
++configuring in the standard serial driver, it must not be a module.
++Either yes or no is ok, but making the serial driver a module means it
++will initialize after kgdb has set up the UART interrupt code and may
++cause a failure of the control-C option discussed below. The configure
++question for the serial driver is under the "Character devices" heading
++and is:
++
++"Standard/generic (8250/16550 and compatible UARTs) serial support"
++
++Go down to the kernel debugging menu item and open it up. Enable the
++kernel kgdb stub code by selecting that item. You can also choose to
++turn on the "-ggdb -O1" compile options. The -ggdb causes the compiler
++to put more debug info (like local symbols) in the object file. On the
++i386 -g and -ggdb are the same so this option just reduces to "O1". The
++-O1 reduces the optimization level. This may be helpful in some cases,
++be aware, however, that this may also mask the problem you are looking
++for.
++
++The baud rate. Default is 115200. What ever you choose be sure that
++the host machine is set to the same speed. I recommend the default.
++
++The port. This is the I/O address of the serial UART that you should
++have gotten using setserial as described above. The standard COM1 port
++(3f8) using IRQ 4 is default. COM2 is 2f8 which by convention uses IRQ
++3.
++
++The port IRQ (see above).
++
++Stack overflow test. This option makes a minor change in the trap,
++system call and interrupt code to detect stack overflow and transfer
++control to kgdb if it happens. (Some platforms have this in the
++baseline code, but the i386 does not.)
++
++You can also configure the system to recognize the boot option
++"console=kgdb" which if given will cause all console output during
++booting to be put thru gdb as well as other consoles. This option
++requires that gdb and kgdb be connected prior to sending console output
++so, if they are not, a breakpoint is executed to force the connection.
++This will happen before any kernel output (it is going thru gdb, right),
++and will stall the boot until the connection is made.
++
++You can also configure in a patch to SysRq to enable the kGdb SysRq.
++This request generates a breakpoint. Since the serial port IRQ line is
++set up after any serial drivers, it is possible that this command will
++work when the control-C will not.
++
++Save and exit the Xconfig program. Then do "make clean" , "make dep"
++and "make bzImage" (or whatever target you want to make). This gets the
++kernel compiled with the "-g" option set -- necessary for debugging.
++
++You have just built the kernel on your DEVELOPMENT machine that you
++intend to run on your TARGET machine.
++
++To install this new kernel, use the following installation procedure.
++Remember, you are on the DEVELOPMENT machine patching the kernel source
++for the kernel that you intend to run on the TARGET machine.
++
++Copy this kernel to your target machine using your usual procedures. I
++usually arrange to copy development:
++/usr/src/linux/arch/i386/boot/bzImage to /vmlinuz on the TARGET machine
++via a LAN based NFS access. That is, I run the cp command on the target
++and copy from the development machine via the LAN. Run Lilo (see "man
++lilo" for details on how to set this up) on the new kernel on the target
++machine so that it will boot! Then boot the kernel on the target
++machine.
++
++On the DEVELOPMENT machine, create a file called .gdbinit in the
++directory /usr/src/linux. An example .gdbinit file looks like this:
++
++shell echo -e "\003" >/dev/ttyS0
++set remotebaud 38400 (or what ever speed you have chosen)
++target remote /dev/ttyS0
++
++
++Change the "echo" and "target" definition so that it specifies the tty
++port that you intend to use. Change the "remotebaud" definition to
++match the data rate that you are going to use for the com line.
++
++You are now ready to try it out.
++
++Boot your target machine with "kgdb" in the boot command i.e. something
++like:
++
++lilo> test kgdb
++
++or if you also want console output thru gdb:
++
++lilo> test kgdb console=kgdb
++
++You should see the lilo message saying it has loaded the kernel and then
++all output stops. The kgdb stub is trying to connect with gdb. Start
++gdb something like this:
++
++
++On your DEVELOPMENT machine, cd /usr/src/linux and enter "gdb vmlinux".
++When gdb gets the symbols loaded it will read your .gdbinit file and, if
++everything is working correctly, you should see gdb print out a few
++lines indicating that a breakpoint has been taken. It will actually
++show a line of code in the target kernel inside the kgdb activation
++code.
++
++The gdb interaction should look something like this:
++
++ linux-dev:/usr/src/linux# gdb vmlinux
++ GDB is free software and you are welcome to distribute copies of it
++ under certain conditions; type "show copying" to see the conditions.
++ There is absolutely no warranty for GDB; type "show warranty" for details.
++ GDB 4.15.1 (i486-slackware-linux),
++ Copyright 1995 Free Software Foundation, Inc...
++ breakpoint () at i386-stub.c:750
++ 750 }
++ (gdb)
++
++You can now use whatever gdb commands you like to set breakpoints.
++Enter "continue" to start your target machine executing again. At this
++point the target system will run at full speed until it encounters
++your breakpoint or gets a segment violation in the kernel, or whatever.
++
++If you have the kgdb console enabled when you continue, gdb will print
++out all the console messages.
++
++The above example caused a breakpoint relatively early in the boot
++process. For the i386 kgdb it is possible to code a break instruction
++as the first C-language point in init/main.c, i.e. as the first instruction
++in start_kernel(). This could be done as follows:
++
++#include <asm/kgdb.h>
++ breakpoint();
++
++This breakpoint() is really a function that sets up the breakpoint and
++single-step hardware trap cells and then executes a breakpoint. Any
++early hard coded breakpoint will need to use this function. Once the
++trap cells are set up they need not be set again, but doing it again
++does not hurt anything, so you don't need to be concerned about which
++breakpoint is hit first. Once the trap cells are set up (and the kernel
++sets them up in due course even if breakpoint() is never called) the
++macro:
++
++BREAKPOINT;
++
++will generate an inline breakpoint. This may be more useful as it stops
++the processor at the instruction instead of in a function a step removed
++from the location of interest. In either case <asm/kgdb.h> must be
++included to define both breakpoint() and BREAKPOINT.
++
++Triggering kgdbstub at other times
++==================================
++
++Often you don't need to enter the debugger until much later in the boot
++or even after the machine has been running for some time. Once the
++kernel is booted and interrupts are on, you can force the system to
++enter the debugger by sending a control-C to the debug port. This is
++what the first line of the recommended .gdbinit file does. This allows
++you to start gdb any time after the system is up as well as when the
++system is already at a breakpoint. (In the case where the system is
++already at a breakpoint the control-C is not needed, however, it will
++be ignored by the target so no harm is done. Also note the the echo
++command assumes that the port speed is already set. This will be true
++once gdb has connected, but it is best to set the port speed before you
++run gdb.)
++
++Another simple way to do this is to put the following file in you ~/bin
++directory:
++
++#!/bin/bash
++echo -e "\003" > /dev/ttyS0
++
++Here, the ttyS0 should be replaced with what ever port you are using.
++The "\003" is control-C. Once you are connected with gdb, you can enter
++control-C at the command prompt.
++
++An alternative way to get control to the debugger is to enable the kGdb
++SysRq command. Then you would enter Alt-SysRq-g (all three keys at the
++same time, but push them down in the order given). To refresh your
++memory of the available SysRq commands try Alt-SysRq-=. Actually any
++undefined command could replace the "=", but I like to KNOW that what I
++am pushing will never be defined.
++
++Debugging hints
++===============
++
++You can break into the target machine at any time from the development
++machine by typing ^C (see above paragraph). If the target machine has
++interrupts enabled this will stop it in the kernel and enter the
++debugger.
++
++There is unfortunately no way of breaking into the kernel if it is
++in a loop with interrupts disabled, so if this happens to you then
++you need to place exploratory breakpoints or printk's into the kernel
++to find out where it is looping. The exploratory breakpoints can be
++entered either thru gdb or hard coded into the source. This is very
++handy if you do something like:
++
++if (<it hurts>) BREAKPOINT;
++
++
++There is a copy of an e-mail in the Documentation/i386/kgdb/ directory
++(debug-nmi.txt) which describes how to create an NMI on an ISA bus
++machine using a paper clip. I have a sophisticated version of this made
++by wiring a push button switch into a PC104/ISA bus adapter card. The
++adapter card nicely furnishes wire wrap pins for all the ISA bus
++signals.
++
++When you are done debugging the kernel on the target machine it is a
++good idea to leave it in a running state. This makes reboots faster,
++bypassing the fsck. So do a gdb "continue" as the last gdb command if
++this is possible. To terminate gdb itself on the development machine
++and leave the target machine running, first clear all breakpoints and
++continue, then type ^Z to suspend gdb and then kill it with "kill %1" or
++something similar.
++
++If gdbstub Does Not Work
++========================
++
++If it doesn't work, you will have to troubleshoot it. Do the easy
++things first like double checking your cabling and data rates. You
++might try some non-kernel based programs to see if the back-to-back
++connection works properly. Just something simple like cat /etc/hosts
++>/dev/ttyS0 on one machine and cat /dev/ttyS0 on the other will tell you
++if you can send data from one machine to the other. Make sure it works
++in both directions. There is no point in tearing out your hair in the
++kernel if the line doesn't work.
++
++All of the real action takes place in the file
++/usr/src/linux/arch/i386/kernel/kgdb_stub.c. That is the code on the target
++machine that interacts with gdb on the development machine. In gdb you can
++turn on a debug switch with the following command:
++
++ set remotedebug
++
++This will print out the protocol messages that gdb is exchanging with
++the target machine.
++
++Another place to look is /usr/src/arch/i386/lib/kgdb_serial.c. This is
++the code that talks to the serial port on the target side. There might
++be a problem there. In particular there is a section of this code that
++tests the UART which will tell you what UART you have if you define
++"PRNT" (just remove "_off" from the #define PRNT_off). To view this
++report you will need to boot the system without any beakpoints. This
++allows the kernel to run to the point where it calls kgdb to set up
++interrupts. At this time kgdb will test the UART and print out the type
++it finds. (You need to wait so that the printks are actually being
++printed. Early in the boot they are cached, waiting for the console to
++be enabled. Also, if kgdb is entered thru a breakpoint it is possible
++to cause a dead lock by calling printk when the console is locked. The
++stub thus avoids doing printks from breakpoints, especially in the
++serial code.) At this time, if the UART fails to do the expected thing,
++kgdb will print out (using printk) information on what failed. (These
++messages will be buried in all the other boot up messages. Look for
++lines that start with "gdb_hook_interrupt:". You may want to use dmesg
++once the system is up to view the log. If this fails or if you still
++don't connect, review your answers for the port address. Use:
++
++setserial /dev/ttyS0
++
++to get the current port and IRQ information. This command will also
++tell you what the system found for the UART type. The stub recognizes
++the following UART types:
++
++16450, 16550, and 16550A
++
++If you are really desperate you can use printk debugging in the
++kgdbstub code in the target kernel until you get it working. In particular,
++there is a global variable in /usr/src/linux/arch/i386/kernel/kgdb_stub.c
++named "remote_debug". Compile your kernel with this set to 1, rather
++than 0 and the debug stub will print out lots of stuff as it does
++what it does. Likewise there are debug printks in the kgdb_serial.c
++code that can be turned on with simple changes in the macro defines.
++
++
++Debugging Loadable Modules
++==========================
++
++This technique comes courtesy of Edouard Parmelan
++<Edouard.Parmelan@quadratec.fr>
++
++When you run gdb, enter the command
++
++source gdbinit-modules
++
++This will read in a file of gdb macros that was installed in your
++kernel source directory when kgdb was installed. This file implements
++the following commands:
++
++mod-list
++ Lists the loaded modules in the form <module-address> <module-name>
++
++mod-print-symbols <module-address>
++ Prints all the symbols in the indicated module.
++
++mod-add-symbols <module-address> <object-file-path-name>
++ Loads the symbols from the object file and associates them
++ with the indicated module.
++
++After you have loaded the module that you want to debug, use the command
++mod-list to find the <module-address> of your module. Then use that
++address in the mod-add-symbols command to load your module's symbols.
++From that point onward you can debug your module as if it were a part
++of the kernel.
++
++The file gdbinit-modules also contains a command named mod-add-lis as
++an example of how to construct a command of your own to load your
++favorite module. The idea is to "can" the pathname of the module
++in the command so you don't have to type so much.
++
++Threads
++=======
++
++Each process in a target machine is seen as a gdb thread. gdb thread
++related commands (info threads, thread n) can be used.
++
++ia-32 hardware breakpoints
++==========================
++
++kgdb stub contains support for hardware breakpoints using debugging features
++of ia-32(x86) processors. These breakpoints do not need code modification.
++They use debugging registers. 4 hardware breakpoints are available in ia-32
++processors.
++
++Each hardware breakpoint can be of one of the following three types.
++
++1. Execution breakpoint - An Execution breakpoint is triggered when code
++ at the breakpoint address is executed.
++
++ As limited number of hardware breakpoints are available, it is
++ advisable to use software breakpoints ( break command ) instead
++ of execution hardware breakpoints, unless modification of code
++ is to be avoided.
++
++2. Write breakpoint - A write breakpoint is triggered when memory
++ location at the breakpoint address is written.
++
++ A write or can be placed for data of variable length. Length of
++ a write breakpoint indicates length of the datatype to be
++ watched. Length is 1 for 1 byte data , 2 for 2 byte data, 3 for
++ 4 byte data.
++
++3. Access breakpoint - An access breakpoint is triggered when memory
++ location at the breakpoint address is either read or written.
++
++ Access breakpoints also have lengths similar to write breakpoints.
++
++IO breakpoints in ia-32 are not supported.
++
++Since gdb stub at present does not use the protocol used by gdb for hardware
++breakpoints, hardware breakpoints are accessed through gdb macros. gdb macros
++for hardware breakpoints are described below.
++
++hwebrk - Places an execution breakpoint
++ hwebrk breakpointno address
++hwwbrk - Places a write breakpoint
++ hwwbrk breakpointno length address
++hwabrk - Places an access breakpoint
++ hwabrk breakpointno length address
++hwrmbrk - Removes a breakpoint
++ hwrmbrk breakpointno
++exinfo - Tells whether a software or hardware breakpoint has occurred.
++ Prints number of the hardware breakpoint if a hardware breakpoint has
++ occurred.
++
++Arguments required by these commands are as follows
++breakpointno - 0 to 3
++length - 1 to 3
++address - Memory location in hex digits ( without 0x ) e.g c015e9bc
++
++SMP support
++==========
++
++When a breakpoint occurs or user issues a break ( Ctrl + C ) to gdb
++client, all the processors are forced to enter the debugger. Current
++thread corresponds to the thread running on the processor where
++breakpoint occurred. Threads running on other processor(s) appear
++similar to other non-running threads in the 'info threads' output.
++Within the kgdb stub there is a structure "waiting_cpus" in which kgdb
++records the values of "current" and "regs" for each CPU other than the
++one that hit the breakpoint. "current" is a pointer to the task
++structure for the task that CPU is running, while "regs" points to the
++saved registers for the task. This structure can be examined with the
++gdb "p" command.
++
++ia-32 hardware debugging registers on all processors are set to same
++values. Hence any hardware breakpoints may occur on any processor.
++
++gdb troubleshooting
++===================
++
++1. gdb hangs
++Kill it. restart gdb. Connect to target machine.
++
++2. gdb cannot connect to target machine (after killing a gdb and
++restarting another) If the target machine was not inside debugger when
++you killed gdb, gdb cannot connect because the target machine won't
++respond. In this case echo "Ctrl+C"(ASCII 3) to the serial line.
++e.g. echo -e "\003" > /dev/ttyS1
++This forces that target machine into the debugger, after which you
++can connect.
++
++3. gdb cannot connect even after echoing Ctrl+C into serial line
++Try changing serial line settings min to 1 and time to 0
++e.g. stty min 1 time 0 < /dev/ttyS1
++Try echoing again
++
++Check serial line speed and set it to correct value if required
++e.g. stty ispeed 115200 ospeed 115200 < /dev/ttyS1
++
++EVENTS
++======
++
++Ever want to know the order of things happening? Which CPU did what and
++when? How did the spinlock get the way it is? Then events are for
++you. Events are defined by calls to an event collection interface and
++saved for later examination. In this case, kgdb events are saved by a
++very fast bit of code in kgdb which is fully SMP and interrupt protected
++and they are examined by using gdb to display them. Kgdb keeps only
++the last N events, where N must be a power of two and is defined at
++configure time.
++
++
++Events are signaled to kgdb by calling:
++
++kgdb_ts(data0,data1)
++
++For each call kgdb records each call in an array along with other info.
++Here is the array definition:
++
++struct kgdb_and_then_struct {
++#ifdef CONFIG_SMP
++ int on_cpu;
++#endif
++ long long at_time;
++ int from_ln;
++ char * in_src;
++ void *from;
++ int with_if;
++ int data0;
++ int data1;
++};
++
++For SMP machines the CPU is recorded, for all machines the TSC is
++recorded (gets a time stamp) as well as the line number and source file
++the call was made from. The address of the (from), the "if" (interrupt
++flag) and the two data items are also recorded. The macro kgdb_ts casts
++the types to int, so you can put any 32-bit values here. There is a
++configure option to select the number of events you want to keep. A
++nice number might be 128, but you can keep up to 1024 if you want. The
++number must be a power of two. An "andthen" macro library is provided
++for gdb to help you look at these events. It is also possible to define
++a different structure for the event storage and cast the data to this
++structure. For example the following structure is defined in kgdb:
++
++struct kgdb_and_then_struct2 {
++#ifdef CONFIG_SMP
++ int on_cpu;
++#endif
++ long long at_time;
++ int from_ln;
++ char * in_src;
++ void *from;
++ int with_if;
++ struct task_struct *t1;
++ struct task_struct *t2;
++};
++
++If you use this for display, the data elements will be displayed as
++pointers to task_struct entries. You may want to define your own
++structure to use in casting. You should only change the last two items
++and you must keep the structure size the same. Kgdb will handle these
++as 32-bit ints, but within that constraint you can define a structure to
++cast to any 32-bit quantity. This need only be available to gdb and is
++only used for casting in the display code.
++
++Final Items
++===========
++
++I picked up this code from Amit S. Kale and enhanced it.
++
++If you make some really cool modification to this stuff, or if you
++fix a bug, please let me know.
++
++George Anzinger
++<george@mvista.com>
++
++Amit S. Kale
++<akale@veritas.com>
++
++(First kgdb by David Grothe <dave@gcom.com>)
++
++(modified by Tigran Aivazian <tigran@sco.com>)
++ Putting gdbstub into the kernel config menu.
++
++(modified by Scott Foehner <sfoehner@engr.sgi.com>)
++ Hooks for entering gdbstub at boot time.
++
++(modified by Amit S. Kale <akale@veritas.com>)
++ Threads, ia-32 hw debugging, mp support, console support,
++ nmi watchdog handling.
++
++(modified by George Anzinger <george@mvista.com>)
++ Extended threads to include the idle threads.
++ Enhancements to allow breakpoint() at first C code.
++ Use of module_init() and __setup() to automate the configure.
++ Enhanced the cpu "collection" code to work in early bring-up.
++ Added ability to call functions from gdb
++ Print info thread stuff without going back to schedule()
++ Now collect the "other" cpus with an IPI/ NMI.
+Index: linux-2.6.0-test5/Documentation/i386/kgdb/loadmodule.sh
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/i386/kgdb/loadmodule.sh 2003-09-27 11:38:18.446724056 +0800
++++ linux-2.6.0-test5/Documentation/i386/kgdb/loadmodule.sh 2003-09-27 11:38:20.472416104 +0800
+@@ -0,0 +1,78 @@
++#/bin/sh
++# This script loads a module on a target machine and generates a gdb script.
++# source generated gdb script to load the module file at appropriate addresses
++# in gdb.
++#
++# Usage:
++# Loading the module on target machine and generating gdb script)
++# [foo]$ loadmodule.sh <modulename>
++#
++# Loading the module file into gdb
++# (gdb) source <gdbscriptpath>
++#
++# Modify following variables according to your setup.
++# TESTMACHINE - Name of the target machine
++# GDBSCRIPTS - The directory where a gdb script will be generated
++#
++# Author: Amit S. Kale (akale@veritas.com).
++#
++# If you run into problems, please check files pointed to by following
++# variables.
++# ERRFILE - /tmp/<modulename>.errs contains stderr output of insmod
++# MAPFILE - /tmp/<modulename>.map contains stdout output of insmod
++# GDBSCRIPT - $GDBSCRIPTS/load<modulename> gdb script.
++
++TESTMACHINE=foo
++GDBSCRIPTS=/home/bar
++
++if [ $# -lt 1 ] ; then {
++ echo Usage: $0 modulefile
++ exit
++} ; fi
++
++MODULEFILE=$1
++MODULEFILEBASENAME=`basename $1`
++
++if [ $MODULEFILE = $MODULEFILEBASENAME ] ; then {
++ MODULEFILE=`pwd`/$MODULEFILE
++} fi
++
++ERRFILE=/tmp/$MODULEFILEBASENAME.errs
++MAPFILE=/tmp/$MODULEFILEBASENAME.map
++GDBSCRIPT=$GDBSCRIPTS/load$MODULEFILEBASENAME
++
++function findaddr() {
++ local ADDR=0x$(echo "$SEGMENTS" | \
++ grep "$1" | sed 's/^[^ ]*[ ]*[^ ]*[ ]*//' | \
++ sed 's/[ ]*[^ ]*$//')
++ echo $ADDR
++}
++
++function checkerrs() {
++ if [ "`cat $ERRFILE`" != "" ] ; then {
++ cat $ERRFILE
++ exit
++ } fi
++}
++
++#load the module
++echo Copying $MODULEFILE to $TESTMACHINE
++rcp $MODULEFILE root@${TESTMACHINE}:
++
++echo Loading module $MODULEFILE
++rsh -l root $TESTMACHINE /sbin/insmod -m ./`basename $MODULEFILE` \
++ > $MAPFILE 2> $ERRFILE
++checkerrs
++
++SEGMENTS=`head -n 11 $MAPFILE | tail -n 10`
++TEXTADDR=$(findaddr "\\.text[^.]")
++LOADSTRING="add-symbol-file $MODULEFILE $TEXTADDR"
++SEGADDRS=`echo "$SEGMENTS" | awk '//{
++ if ($1 != ".text" && $1 != ".this" &&
++ $1 != ".kstrtab" && $1 != ".kmodtab") {
++ print " -s " $1 " 0x" $3 " "
++ }
++}'`
++LOADSTRING="$LOADSTRING $SEGADDRS"
++echo Generating script $GDBSCRIPT
++echo $LOADSTRING > $GDBSCRIPT
+Index: linux-2.6.0-test5/Documentation/kernel-parameters.txt
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/kernel-parameters.txt 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/Documentation/kernel-parameters.txt 2003-09-27 11:38:20.480414888 +0800
+@@ -393,7 +393,7 @@
+ See Documentation/ide.txt.
+
+ idle= [HW]
+- Format: poll
++ Format: idle=poll or idle=halt
+
+ in2000= [HW,SCSI]
+ See header of drivers/scsi/in2000.c.
+@@ -786,8 +786,14 @@
+ before loading.
+ See Documentation/ramdisk.txt.
+
++ psmouse_imps2 [HW,MOUSE] Probe only for Intellimouse PS2 mouse protocol extensions
++
+ psmouse_noext [HW,MOUSE] Disable probing for PS2 mouse protocol extensions
+
++ psmouse_resetafter=
++ [HW,MOUSE] Try to reset Synaptics Touchpad after so many
++ bad packets (0 = never).
++
+ pss= [HW,OSS] Personal Sound System (ECHO ESC614)
+ Format: <io>,<mss_io>,<mss_irq>,<mss_dma>,<mpu_io>,<mpu_irq>
+
+Index: linux-2.6.0-test5/Documentation/magic-number.txt
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/magic-number.txt 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/Documentation/magic-number.txt 2003-09-27 11:38:20.484414280 +0800
+@@ -134,6 +134,9 @@
+ HDLCDRV_MAGIC 0x5ac6e778 hdlcdrv_state include/linux/hdlcdrv.h
+ EPCA_MAGIC 0x5c6df104 channel include/linux/epca.h
+ PCXX_MAGIC 0x5c6df104 channel drivers/char/pcxx.h
++DGAP_BOARD_MAGIC 0x5c6df104 board_t drivers/char/digi/dgap/dgap_driver.h
++DGAP_CHANNEL_MAGIC 0x6c6df104 channel_t drivers/char/digi/dgap/dgap_driver.h
++DGAP_UNIT_MAGIC 0x7c6df104 un_t drivers/char/digi/dgap/dgap_driver.h
+ KV_MAGIC 0x5f4b565f kernel_vars_s include/asm-mips64/sn/klkernvars.h
+ I810_STATE_MAGIC 0x63657373 i810_state sound/oss/i810_audio.c
+ TRIDENT_STATE_MAGIC 0x63657373 trient_state sound/oss/trident.c
+Index: linux-2.6.0-test5/Documentation/networking/bonding.txt
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/networking/bonding.txt 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/Documentation/networking/bonding.txt 2003-09-27 11:38:20.494412760 +0800
+@@ -527,9 +527,9 @@
+
+ 1) Bonding information files
+ ----------------------------
+-The bonding driver information files reside in the /proc/net/bond* directories.
++The bonding driver information files reside in the /proc/net/bonding directory.
+
+-Sample contents of /proc/net/bond0/info after the driver is loaded with
++Sample contents of /proc/net/bonding/bond0 after the driver is loaded with
+ parameters of mode=0 and miimon=1000 is shown below.
+
+ Bonding Mode: load balancing (round-robin)
+Index: linux-2.6.0-test5/Documentation/networking/ifenslave.c
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/networking/ifenslave.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/Documentation/networking/ifenslave.c 2003-09-27 11:38:20.504411240 +0800
+@@ -140,6 +140,7 @@
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <sys/ioctl.h>
++#include <linux/if.h>
+ #include <net/if_arp.h>
+ #include <linux/if_ether.h>
+ #include <linux/if_bonding.h>
+Index: linux-2.6.0-test5/Documentation/video4linux/Zoran
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/video4linux/Zoran 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/Documentation/video4linux/Zoran 2003-09-27 11:38:20.510410328 +0800
+@@ -28,7 +28,7 @@
+ * Philips saa7111 TV decoder
+ * Philips saa7185 TV encoder
+ Drivers to use: videodev, i2c-core, i2c-algo-bit,
+- videocodec, saa7111, saa7185, zr36060, zoran
++ videocodec, saa7111, saa7185, zr36060, zr36067
+ Inputs/outputs: Composite and S-video
+ Norms: PAL, SECAM (720x576 @ 25 fps), NTSC (720x480 @ 29.97 fps)
+ Card number: 7
+@@ -39,7 +39,7 @@
+ * Brooktree bt819 TV decoder
+ * Brooktree bt856 TV encoder
+ Drivers to use: videodev, i2c-core, i2c-algo-bit,
+- videocodec, bt819, bt856, zr36060, zoran
++ videocodec, bt819, bt856, zr36060, zr36067
+ Inputs/outputs: Composite and S-video
+ Norms: PAL (720x576 @ 25 fps), NTSC (720x480 @ 29.97 fps)
+ Card number: 5
+@@ -50,7 +50,7 @@
+ * Philips saa7114 TV decoder
+ * Analog Devices adv7170 TV encoder
+ Drivers to use: videodev, i2c-core, i2c-algo-bit,
+- videocodec, saa7114, adv7170, zr36060, zoran
++ videocodec, saa7114, adv7170, zr36060, zr36067
+ Inputs/outputs: Composite and S-video
+ Norms: PAL (720x576 @ 25 fps), NTSC (720x480 @ 29.97 fps)
+ Card number: 6
+@@ -61,7 +61,7 @@
+ * Philips saa7110a TV decoder
+ * Analog Devices adv7176 TV encoder
+ Drivers to use: videodev, i2c-core, i2c-algo-bit,
+- videocodec, saa7110, adv7175, zr36060, zoran
++ videocodec, saa7110, adv7175, zr36060, zr36067
+ Inputs/outputs: Composite, S-video and Internal
+ Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps)
+ Card number: 1
+@@ -72,7 +72,7 @@
+ * Philips saa7110a TV decoder
+ * Analog Devices adv7176 TV encoder
+ Drivers to use: videodev, i2c-core, i2c-algo-bit,
+- videocodec, sa7110, adv7175, zr36060, zoran
++ videocodec, sa7110, adv7175, zr36060, zr36067
+ Inputs/outputs: Composite, S-video and Internal
+ Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps)
+ Card number: 2
+@@ -84,7 +84,7 @@
+ * Micronas vpx3220a TV decoder
+ * mse3000 TV encoder or Analog Devices adv7176 TV encoder *
+ Drivers to use: videodev, i2c-core, i2c-algo-bit,
+- videocodec, vpx3220, mse3000/adv7175, zr36050, zr36016, zoran
++ videocodec, vpx3220, mse3000/adv7175, zr36050, zr36016, zr36067
+ Inputs/outputs: Composite, S-video and Internal
+ Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps)
+ Card number: 0
+@@ -96,7 +96,7 @@
+ * Micronas vpx3225d/vpx3220a/vpx3216b TV decoder
+ * Analog Devices adv7176 TV encoder
+ Drivers to use: videodev, i2c-core, i2c-algo-bit,
+- videocodec, vpx3220/vpx3224, adv7175, zr36050, zr36016, zoran
++ videocodec, vpx3220/vpx3224, adv7175, zr36050, zr36016, zr36067
+ Inputs/outputs: Composite, S-video and Internal
+ Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps)
+ Card number: 3
+@@ -108,7 +108,7 @@
+ * Micronas vpx3225d/vpx3220a/vpx3216b TV decoder
+ * Analog Devices adv7176 TV encoder
+ Drivers to use: videodev, i2c-core, i2c-algo-bit,
+- videocodec, vpx3220/vpx3224, adv7175, zr36050, zr36015, zoran
++ videocodec, vpx3220/vpx3224, adv7175, zr36050, zr36015, zr36067
+ Inputs/outputs: Composite, S-video and Internal
+ Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps)
+ Card number: 4
+@@ -229,16 +229,16 @@
+
+ 2. How do I get this damn thing to work
+
+-Load zoran.o. If it can't autodetect your card, use the card=X insmod
++Load zr36067.o. If it can't autodetect your card, use the card=X insmod
+ option with X being the card number as given in the previous section.
+ To have more than one card, use card=X1[,X2[,X3,[X4[..]]]]
+
+ To automate this, add the following to your /etc/modules.conf:
+
+-options zoran card=X1[,X2[,X3[,X4[..]]]]
+-alias char-major-81-0 zoran
++options zr36067 card=X1[,X2[,X3[,X4[..]]]]
++alias char-major-81-0 zr36067
+
+-One thing to keep in mind is that this doesn't load zoran.o itself yet. It
++One thing to keep in mind is that this doesn't load zr36067.o itself yet. It
+ just automates loading. If you start using xawtv, the device won't load on
+ some systems, since you're trying to load modules as a user, which is not
+ allowed ("permission denied"). A quick workaround is to add 'Load "v4l"' to
+@@ -500,7 +500,7 @@
+ 7. It hangs/crashes/fails/whatevers! Help!
+
+ Make sure that the card has its own interrupts (see /proc/interrupts), check
+-the output of dmesg at high verbosity (load zoran.o/zr36067.o with debug=2,
++the output of dmesg at high verbosity (load zr36067.o with debug=2,
+ load all other modules with debug=1). Check that your mainboard is favorable
+ (see question 2) and if not, test the card in another computer. Also see the
+ notes given in question 3 and try lowering quality/buffersize/capturesize
+Index: linux-2.6.0-test5/drivers/acpi/ec.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/acpi/ec.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/acpi/ec.c 2003-09-27 11:38:20.516409416 +0800
+@@ -32,7 +32,7 @@
+ #include <asm/io.h>
+ #include <acpi/acpi_bus.h>
+ #include <acpi/acpi_drivers.h>
+-
++#include <acpi/actypes.h>
+
+ #define _COMPONENT ACPI_EC_COMPONENT
+ ACPI_MODULE_NAME ("acpi_ec")
+@@ -412,7 +412,10 @@
+ * The EC object is in the handler context and is needed
+ * when calling the acpi_ec_space_handler.
+ */
+- *return_context = handler_context;
++ if(function == ACPI_REGION_DEACTIVATE)
++ *return_context = NULL;
++ else
++ *return_context = handler_context;
+
+ return AE_OK;
+ }
+Index: linux-2.6.0-test5/drivers/acpi/events/evregion.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/acpi/events/evregion.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/acpi/events/evregion.c 2003-09-27 11:38:20.522408504 +0800
+@@ -382,7 +382,7 @@
+ union acpi_operand_object *obj_desc;
+ union acpi_operand_object **last_obj_ptr;
+ acpi_adr_space_setup region_setup;
+- void *region_context;
++ void **region_context;
+ union acpi_operand_object *region_obj2;
+ acpi_status status;
+
+@@ -394,7 +394,7 @@
+ if (!region_obj2) {
+ return_VOID;
+ }
+- region_context = region_obj2->extra.region_context;
++ region_context = ®ion_obj2->extra.region_context;
+
+ /* Get the address handler from the region object */
+
+@@ -450,7 +450,7 @@
+
+ region_setup = handler_obj->address_space.setup;
+ status = region_setup (region_obj, ACPI_REGION_DEACTIVATE,
+- handler_obj->address_space.context, ®ion_context);
++ handler_obj->address_space.context, region_context);
+
+ /* Init routine may fail, Just ignore errors */
+
+Index: linux-2.6.0-test5/drivers/acpi/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/acpi/Kconfig 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/acpi/Kconfig 2003-09-27 11:38:20.526407896 +0800
+@@ -3,34 +3,14 @@
+ #
+
+ menu "ACPI (Advanced Configuration and Power Interface) Support"
+-
+-config ACPI_HT
+- bool "ACPI Processor Enumeration for HT"
+- depends on X86
+- default y
+- ---help---
+- ACPI enumerates both logical (a.k.a. Hyper-Threaded -- HT)
+- and physical processors. It is designed to obsolete several older
+- specifications, including the MultiProcessor Specification (MPS),
+- which supported only physical processors.
+-
+- CONFIG_ACPI_HT includes the minimal ACPI boot-time code
+- necessary to enumerate logical processors and enable HT.
+-
+- CONFIG_ACPI includes CONFIG_ACPI_HT, plus IO APIC enumeration,
+- and the hooks to run the ACPI AML interpreter for run-time events.
+-
+- When CONFIG_ACPI is selected, the command-line option "acpi=ht"
+- is available to run just the ACPI boot-time code -- just as if
+- only CONFIG_ACPI_HT were selected.
+-
+- Note that "acpi=off" can be used to disable all ACPI code in the kernel.
+-
+-config ACPI
+- bool "Full ACPI Support"
+ depends on !X86_VISWS
+ depends on !IA64_HP_SIM
+- depends on IA64 || (X86 || ACPI_HT)
++ depends on IA64 || X86
++
++config ACPI
++ bool "ACPI Support"
++ depends on IA64 || X86
++
+ default y
+ ---help---
+ Advanced Configuration and Power Interface (ACPI) support for
+@@ -60,14 +40,47 @@
+ available at:
+ <http://www.acpi.info>
+
++config ACPI_HT_ONLY
++ bool "Restrict ACPI to minimum boot code to enable HT"
++ depends on X86
++ depends on ACPI
++ depends on SMP
++ default n
++ ---help---
++ ACPI enumerates both logical (a.k.a. Hyper-Threaded -- HT)
++ and physical processors. It is designed to obsolete several older
++ specifications, including the MultiProcessor Specification (MPS),
++ which supported only physical processors.
++
++ CONFIG_ACPI_HT_ONLY includes just the minimal ACPI boot-time code
++ necessary to enumerate logical processors and enable HT.
++
++ CONFIG_ACPI includes this, plus IO APIC enumeration,
++ and the hooks to run the ACPI AML interpreter for run-time events.
++
++ When CONFIG_ACPI is selected, the command-line option "acpi=ht"
++ is available to run just the ACPI boot-time code -- just as if
++ only CONFIG_ACPI_HT_ONLY were selected.
++
++ Note that "acpi=off" can be used to disable all ACPI code in the kernel.
++
++
+ config ACPI_BOOT
+ bool
+- depends on ACPI || ACPI_HT
++ depends on ACPI
++ default y
++
++config ACPI_INTERPRETER
++ bool
++ depends on ACPI
++ depends on !IA64_SGI_SN
++ depends on !ACPI_HT_ONLY
+ default y
+
+ config ACPI_SLEEP
+ bool "Sleep States (EXPERIMENTAL)"
+ depends on X86 && ACPI
++ depends on ACPI_INTERPRETER
+ depends on EXPERIMENTAL && PM
+ select SOFTWARE_SUSPEND
+ default y
+@@ -94,7 +107,8 @@
+
+ config ACPI_AC
+ tristate "AC Adapter"
+- depends on X86 && ACPI
++ depends on X86
++ depends on ACPI_INTERPRETER
+ default m
+ help
+ This driver adds support for the AC Adapter object, which indicates
+@@ -103,7 +117,8 @@
+
+ config ACPI_BATTERY
+ tristate "Battery"
+- depends on X86 && ACPI
++ depends on X86
++ depends on ACPI_INTERPRETER
+ default m
+ help
+ This driver adds support for battery information through
+@@ -112,7 +127,7 @@
+
+ config ACPI_BUTTON
+ tristate "Button"
+- depends on ACPI
++ depends on ACPI_INTERPRETER
+ depends on !IA64_SGI_SN
+ default m
+ help
+@@ -124,7 +139,7 @@
+
+ config ACPI_FAN
+ tristate "Fan"
+- depends on ACPI
++ depends on ACPI_INTERPRETER
+ depends on !IA64_SGI_SN
+ default m
+ help
+@@ -133,7 +148,7 @@
+
+ config ACPI_PROCESSOR
+ tristate "Processor"
+- depends on ACPI
++ depends on ACPI_INTERPRETER
+ depends on !IA64_SGI_SN
+ default m
+ help
+@@ -153,14 +168,15 @@
+
+ config ACPI_NUMA
+ bool "NUMA support"
+- depends on ACPI
++ depends on ACPI_INTERPRETER
+ depends on NUMA
+ depends on !X86_64
+ default y if IA64_GENERIC || IA64_SGI_SN2
+
+ config ACPI_ASUS
+ tristate "ASUS/Medion Laptop Extras"
+- depends on X86 && ACPI
++ depends on X86
++ depends on ACPI_INTERPRETER
+ default m
+ ---help---
+ This driver provides support for extra features of ACPI-compatible
+@@ -186,7 +202,8 @@
+
+ config ACPI_TOSHIBA
+ tristate "Toshiba Laptop Extras"
+- depends on X86 && ACPI
++ depends on X86
++ depends on ACPI_INTERPRETER
+ default m
+ ---help---
+ This driver adds support for access to certain system settings
+@@ -213,7 +230,7 @@
+
+ config ACPI_DEBUG
+ bool "Debug Statements"
+- depends on ACPI
++ depends on ACPI_INTERPRETER
+ depends on !IA64_SGI_SN
+ default n
+ help
+@@ -223,19 +240,14 @@
+
+ config ACPI_BUS
+ bool
+- depends on ACPI
+- depends on !IA64_SGI_SN
+- default y
+-
+-config ACPI_INTERPRETER
+- bool
+- depends on ACPI
++ depends on ACPI_INTERPRETER
+ depends on !IA64_SGI_SN
+ default y
+
+ config ACPI_EC
+ bool
+- depends on X86 && ACPI
++ depends on X86
++ depends on ACPI_INTERPRETER
+ default y
+ help
+ This driver is required on some systems for the proper operation of
+@@ -244,19 +256,19 @@
+
+ config ACPI_POWER
+ bool
+- depends on ACPI
++ depends on ACPI_INTERPRETER
+ depends on !IA64_SGI_SN
+ default y
+
+ config ACPI_PCI
+ bool
+- depends on ACPI
++ depends on ACPI_INTERPRETER
+ depends on !IA64_SGI_SN
+ default PCI
+
+ config ACPI_SYSTEM
+ bool
+- depends on ACPI
++ depends on ACPI_INTERPRETER
+ depends on !IA64_SGI_SN
+ default y
+ help
+@@ -265,7 +277,7 @@
+
+ config ACPI_EFI
+ bool
+- depends on ACPI
++ depends on ACPI_INTERPRETER
+ depends on IA64
+ default y
+
+Index: linux-2.6.0-test5/drivers/acpi/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/acpi/Makefile 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/acpi/Makefile 2003-09-27 11:38:20.527407744 +0800
+@@ -18,7 +18,7 @@
+ # ACPI Boot-Time Table Parsing
+ #
+ obj-$(CONFIG_ACPI_BOOT) += tables.o
+-obj-$(CONFIG_ACPI) += blacklist.o
++obj-$(CONFIG_ACPI_INTERPRETER) += blacklist.o
+
+ #
+ # ACPI Core Subsystem (Interpreter)
+Index: linux-2.6.0-test5/drivers/acpi/pci_link.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/acpi/pci_link.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/acpi/pci_link.c 2003-09-27 11:38:20.533406832 +0800
+@@ -220,7 +220,6 @@
+ return AE_CTRL_TERMINATE;
+ }
+
+-
+ static int
+ acpi_pci_link_get_current (
+ struct acpi_pci_link *link)
+@@ -279,6 +278,28 @@
+ return_VALUE(result);
+ }
+
++static int
++acpi_pci_link_try_get_current (
++ struct acpi_pci_link *link,
++ int irq)
++{
++ int result;
++
++ ACPI_FUNCTION_TRACE("acpi_pci_link_try_get_current");
++
++ result = acpi_pci_link_get_current(link);
++ if (result && link->irq.active) {
++ return_VALUE(result);
++ }
++
++ if (!link->irq.active) {
++ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "No active IRQ resource found\n"));
++ printk(KERN_WARNING "_CRS returns NULL! Using IRQ %d for device (%s [%s]).\n", irq, acpi_device_name(link->device), acpi_device_bid(link->device));
++ link->irq.active = irq;
++ }
++
++ return 0;
++}
+
+ static int
+ acpi_pci_link_set (
+@@ -294,6 +315,7 @@
+ struct acpi_buffer buffer = {sizeof(resource)+1, &resource};
+ int i = 0;
+ int valid = 0;
++ int resource_type = 0;
+
+ ACPI_FUNCTION_TRACE("acpi_pci_link_set");
+
+@@ -317,20 +339,32 @@
+ }
+ }
+
++ /* If IRQ<=15, first try with a "normal" IRQ descriptor. If that fails, try with
++ * an extended one */
++ if (irq <= 15) {
++ resource_type = ACPI_RSTYPE_IRQ;
++ } else {
++ resource_type = ACPI_RSTYPE_EXT_IRQ;
++ }
++
++retry_programming:
++
+ memset(&resource, 0, sizeof(resource));
+
+ /* NOTE: PCI interrupts are always level / active_low / shared. But not all
+ interrupts > 15 are PCI interrupts. Rely on the ACPI IRQ definition for
+ parameters */
+- if (irq <= 15) {
++ switch(resource_type) {
++ case ACPI_RSTYPE_IRQ:
+ resource.res.id = ACPI_RSTYPE_IRQ;
+ resource.res.length = sizeof(struct acpi_resource);
+ resource.res.data.irq.edge_level = link->irq.edge_level;
+ resource.res.data.irq.active_high_low = link->irq.active_high_low;
+ resource.res.data.irq.number_of_interrupts = 1;
+ resource.res.data.irq.interrupts[0] = irq;
+- }
+- else {
++ break;
++
++ case ACPI_RSTYPE_EXT_IRQ:
+ resource.res.id = ACPI_RSTYPE_EXT_IRQ;
+ resource.res.length = sizeof(struct acpi_resource);
+ resource.res.data.extended_irq.producer_consumer = ACPI_CONSUMER;
+@@ -339,11 +373,21 @@
+ resource.res.data.extended_irq.number_of_interrupts = 1;
+ resource.res.data.extended_irq.interrupts[0] = irq;
+ /* ignore resource_source, it's optional */
++ break;
+ }
+ resource.end.id = ACPI_RSTYPE_END_TAG;
+
+ /* Attempt to set the resource */
+ status = acpi_set_current_resources(link->handle, &buffer);
++
++ /* if we failed and IRQ <= 15, try again with an extended descriptor */
++ if (ACPI_FAILURE(status) && (resource_type == ACPI_RSTYPE_IRQ)) {
++ resource_type = ACPI_RSTYPE_EXT_IRQ;
++ printk(PREFIX "Retrying with extended IRQ descriptor\n");
++ goto retry_programming;
++ }
++
++ /* check for total failure */
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _SRS\n"));
+ return_VALUE(-ENODEV);
+@@ -361,7 +405,7 @@
+ }
+
+ /* Make sure the active IRQ is the one we requested. */
+- result = acpi_pci_link_get_current(link);
++ result = acpi_pci_link_try_get_current(link, irq);
+ if (result) {
+ return_VALUE(result);
+ }
+@@ -458,14 +502,14 @@
+ irq = link->irq.possible[0];
+ }
+
+- /*
+- * Select the best IRQ. This is done in reverse to promote
+- * the use of IRQs 9, 10, 11, and >15.
+- */
+- for (i=(link->irq.possible_count-1); i>0; i--) {
+- if (acpi_irq_penalty[irq] > acpi_irq_penalty[link->irq.possible[i]])
+- irq = link->irq.possible[i];
+- }
++ /*
++ * Select the best IRQ. This is done in reverse to promote
++ * the use of IRQs 9, 10, 11, and >15.
++ */
++ for (i=(link->irq.possible_count-1); i>0; i--) {
++ if (acpi_irq_penalty[irq] > acpi_irq_penalty[link->irq.possible[i]])
++ irq = link->irq.possible[i];
++ }
+
+ /* Attempt to enable the link device at this IRQ. */
+ if (acpi_pci_link_set(link, irq)) {
+@@ -574,10 +618,6 @@
+ else
+ printk(" %d", link->irq.possible[i]);
+ }
+- if (!link->irq.active)
+- printk(", disabled");
+- else if (!found)
+- printk(", enabled at IRQ %d", link->irq.active);
+ printk(")\n");
+
+ /* TBD: Acquire/release lock */
+Index: linux-2.6.0-test5/drivers/acpi/sleep/main.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/acpi/sleep/main.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/acpi/sleep/main.c 2003-09-27 11:38:20.535406528 +0800
+@@ -41,7 +41,6 @@
+
+ static int acpi_pm_prepare(u32 state)
+ {
+- int error = 0;
+ u32 acpi_state = acpi_suspend_states[state];
+
+ if (!sleep_states[acpi_state])
+@@ -56,21 +55,9 @@
+ acpi_set_firmware_waking_vector(
+ (acpi_physical_address) acpi_wakeup_address);
+ }
+-
+ ACPI_FLUSH_CPU_CACHE();
+-
+- /* Do arch specific saving of state. */
+- if (state > PM_SUSPEND_STANDBY) {
+- if ((error = acpi_save_state_mem()))
+- goto Err;
+- }
+-
+ acpi_enter_sleep_state_prep(acpi_state);
+-
+ return 0;
+- Err:
+- acpi_set_firmware_waking_vector(0);
+- return error;
+ }
+
+
+@@ -90,6 +77,15 @@
+ u32 acpi_state = acpi_suspend_states[state];
+
+ ACPI_FLUSH_CPU_CACHE();
++
++ /* Do arch specific saving of state. */
++ if (state > PM_SUSPEND_STANDBY) {
++ int error = acpi_save_state_mem();
++ if (error)
++ return error;
++ }
++
++
+ local_irq_save(flags);
+ switch (state)
+ {
+@@ -114,6 +110,15 @@
+ local_irq_restore(flags);
+ printk(KERN_DEBUG "Back to C!\n");
+
++ /* restore processor state
++ * We should only be here if we're coming back from STR or STD.
++ * And, in the case of the latter, the memory image should have already
++ * been loaded from disk.
++ */
++ if (state > PM_SUSPEND_STANDBY)
++ acpi_restore_state_mem();
++
++
+ return ACPI_SUCCESS(status) ? 0 : -EFAULT;
+ }
+
+@@ -130,14 +135,6 @@
+ {
+ acpi_leave_sleep_state(state);
+
+- /* restore processor state
+- * We should only be here if we're coming back from STR or STD.
+- * And, in the case of the latter, the memory image should have already
+- * been loaded from disk.
+- */
+- if (state > ACPI_STATE_S1)
+- acpi_restore_state_mem();
+-
+ /* reset firmware waking vector */
+ acpi_set_firmware_waking_vector((acpi_physical_address) 0);
+
+@@ -149,6 +146,20 @@
+ }
+
+
++int acpi_suspend(u32 acpi_state)
++{
++ u32 states[] = {
++ [1] = PM_SUSPEND_STANDBY,
++ [3] = PM_SUSPEND_MEM,
++ [4] = PM_SUSPEND_DISK,
++ };
++
++ if (acpi_state <= 4 && states[acpi_state])
++ return pm_suspend(states[acpi_state]);
++ return -EINVAL;
++}
++
++
+ static struct pm_ops acpi_pm_ops = {
+ .prepare = acpi_pm_prepare,
+ .enter = acpi_pm_enter,
+Index: linux-2.6.0-test5/drivers/acpi/sleep/proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/acpi/sleep/proc.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/acpi/sleep/proc.c 2003-09-27 11:38:20.538406072 +0800
+@@ -13,12 +13,71 @@
+
+ #include "sleep.h"
+
++#define ACPI_SYSTEM_FILE_SLEEP "sleep"
+ #define ACPI_SYSTEM_FILE_ALARM "alarm"
+
+ #define _COMPONENT ACPI_SYSTEM_COMPONENT
+ ACPI_MODULE_NAME ("sleep")
+
+
++static int acpi_system_sleep_seq_show(struct seq_file *seq, void *offset)
++{
++ int i;
++
++ ACPI_FUNCTION_TRACE("acpi_system_sleep_seq_show");
++
++ for (i = 0; i <= ACPI_STATE_S5; i++) {
++ if (sleep_states[i]) {
++ seq_printf(seq,"S%d ", i);
++ if (i == ACPI_STATE_S4 && acpi_gbl_FACS->S4bios_f)
++ seq_printf(seq, "S4bios ");
++ }
++ }
++
++ seq_puts(seq, "\n");
++
++ return 0;
++}
++
++static int acpi_system_sleep_open_fs(struct inode *inode, struct file *file)
++{
++ return single_open(file, acpi_system_sleep_seq_show, PDE(inode)->data);
++}
++
++static int
++acpi_system_write_sleep (
++ struct file *file,
++ const char *buffer,
++ size_t count,
++ loff_t *ppos)
++{
++ char str[12];
++ u32 state = 0;
++ int error = 0;
++
++ if (count > sizeof(str) - 1)
++ goto Done;
++ memset(str,0,sizeof(str));
++ if (copy_from_user(str, buffer, count))
++ return -EFAULT;
++
++ /* Check for S4 bios request */
++ if (!strcmp(str,"4b")) {
++ error = acpi_suspend(4);
++ goto Done;
++ }
++ state = simple_strtoul(str, NULL, 0);
++#ifdef CONFIG_SOFTWARE_SUSPEND
++ if (state == 4) {
++ software_suspend();
++ goto Done;
++ }
++#endif
++ error = acpi_suspend(state);
++ Done:
++ return error ? error : count;
++}
++
+ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
+ {
+ u32 sec, min, hr;
+@@ -294,6 +353,14 @@
+ }
+
+
++static struct file_operations acpi_system_sleep_fops = {
++ .open = acpi_system_sleep_open_fs,
++ .read = seq_read,
++ .write = acpi_system_write_sleep,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
+ static struct file_operations acpi_system_alarm_fops = {
+ .open = acpi_system_alarm_open_fs,
+ .read = seq_read,
+@@ -307,6 +374,12 @@
+ {
+ struct proc_dir_entry *entry = NULL;
+
++ /* 'sleep' [R/W]*/
++ entry = create_proc_entry(ACPI_SYSTEM_FILE_SLEEP,
++ S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir);
++ if (entry)
++ entry->proc_fops = &acpi_system_sleep_fops;
++
+ /* 'alarm' [R/W] */
+ entry = create_proc_entry(ACPI_SYSTEM_FILE_ALARM,
+ S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir);
+Index: linux-2.6.0-test5/drivers/acpi/sleep/sleep.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/acpi/sleep/sleep.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/acpi/sleep/sleep.h 2003-09-27 11:38:20.539405920 +0800
+@@ -1,5 +1,4 @@
+
+ extern u8 sleep_states[];
+-
+-extern acpi_status acpi_suspend (u32 state);
++extern int acpi_suspend (u32 state);
+
+Index: linux-2.6.0-test5/drivers/acpi/utilities/utdelete.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/acpi/utilities/utdelete.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/acpi/utilities/utdelete.c 2003-09-27 11:38:20.544405160 +0800
+@@ -417,6 +417,8 @@
+ union acpi_generic_state *state_list = NULL;
+ union acpi_generic_state *state;
+
++ union acpi_operand_object *tmp;
++
+
+ ACPI_FUNCTION_TRACE_PTR ("ut_update_object_reference", object);
+
+@@ -448,8 +450,15 @@
+ switch (ACPI_GET_OBJECT_TYPE (object)) {
+ case ACPI_TYPE_DEVICE:
+
+- acpi_ut_update_ref_count (object->device.system_notify, action);
+- acpi_ut_update_ref_count (object->device.device_notify, action);
++ tmp = object->device.system_notify;
++ if(tmp && tmp->common.reference_count<=1 && action == REF_DECREMENT)
++ object->device.system_notify = NULL;
++ acpi_ut_update_ref_count (tmp, action);
++
++ tmp = object->device.device_notify;
++ if(tmp && tmp->common.reference_count <=1 && action == REF_DECREMENT)
++ object->device.device_notify = NULL;
++ acpi_ut_update_ref_count (tmp, action);
+ break;
+
+
+@@ -467,6 +476,9 @@
+ */
+ status = acpi_ut_create_update_state_and_push (
+ object->package.elements[i], action, &state_list);
++ tmp = object->package.elements[i];
++ if(tmp && tmp->common.reference_count<=1 && action == REF_DECREMENT) /*reference count didn't refresh now*/
++ object->package.elements[i] = NULL;
+ if (ACPI_FAILURE (status)) {
+ goto error_exit;
+ }
+@@ -478,6 +490,9 @@
+
+ status = acpi_ut_create_update_state_and_push (
+ object->buffer_field.buffer_obj, action, &state_list);
++ tmp = object->buffer_field.buffer_obj;
++ if( tmp && tmp->common.reference_count <=1 && action == REF_DECREMENT)/*reference count didn't refresh now*/
++ object->buffer_field.buffer_obj = NULL;
+ if (ACPI_FAILURE (status)) {
+ goto error_exit;
+ }
+@@ -491,6 +506,9 @@
+ if (ACPI_FAILURE (status)) {
+ goto error_exit;
+ }
++ tmp = object->field.region_obj;
++ if( tmp && tmp->common.reference_count <=1 && action == REF_DECREMENT)/*reference count didn't refresh now*/
++ object->field.region_obj = NULL;
+ break;
+
+
+@@ -501,12 +519,18 @@
+ if (ACPI_FAILURE (status)) {
+ goto error_exit;
+ }
++ tmp = object->bank_field.bank_obj;
++ if( tmp && tmp->common.reference_count <=1 && action == REF_DECREMENT)/*reference count didn't refresh now*/
++ object->bank_field.bank_obj = NULL;
+
+ status = acpi_ut_create_update_state_and_push (
+ object->bank_field.region_obj, action, &state_list);
+ if (ACPI_FAILURE (status)) {
+ goto error_exit;
+ }
++ tmp = object->bank_field.region_obj;
++ if( tmp && tmp->common.reference_count <=1 && action == REF_DECREMENT)/*reference count didn't refresh now*/
++ object->bank_field.region_obj = NULL;
+ break;
+
+
+@@ -517,12 +541,18 @@
+ if (ACPI_FAILURE (status)) {
+ goto error_exit;
+ }
++ tmp = object->index_field.index_obj;
++ if( tmp && tmp->common.reference_count <=1 && action == REF_DECREMENT)/*reference count didn't refresh now*/
++ object->index_field.index_obj = NULL;
+
+ status = acpi_ut_create_update_state_and_push (
+ object->index_field.data_obj, action, &state_list);
+ if (ACPI_FAILURE (status)) {
+ goto error_exit;
+ }
++ tmp = object->index_field.data_obj;
++ if( tmp && tmp->common.reference_count <=1 && action == REF_DECREMENT)/*reference count didn't refresh now*/
++ object->index_field.data_obj = NULL;
+ break;
+
+
+Index: linux-2.6.0-test5/drivers/atm/eni.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/atm/eni.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/atm/eni.c 2003-09-27 11:38:20.561402576 +0800
+@@ -2272,8 +2272,6 @@
+
+ DPRINTK("eni_init_one\n");
+
+- MOD_INC_USE_COUNT; /* @@@ we don't support unloading yet */
+-
+ if (pci_enable_device(pci_dev)) {
+ error = -EIO;
+ goto out0;
+@@ -2307,7 +2305,6 @@
+ out1:
+ kfree(eni_dev);
+ out0:
+- MOD_DEC_USE_COUNT; /* @@@ we don't support unloading yet */
+ return error;
+ }
+
+@@ -2351,16 +2348,7 @@
+ }
+
+
+-static void __exit eni_cleanup(void)
+-{
+- /*
+- * Well, there's no way to get rid of the driver yet, so we don't
+- * have to clean up, right ? :-)
+- */
+-}
+-
+-
+ module_init(eni_init);
+-module_exit(eni_cleanup);
++/* @@@ since exit routine not defined, this module can not be unloaded */
+
+ MODULE_LICENSE("GPL");
+Index: linux-2.6.0-test5/drivers/atm/firestream.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/atm/firestream.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/atm/firestream.c 2003-09-27 11:38:20.576400296 +0800
+@@ -250,7 +250,7 @@
+ };
+
+
+-struct reginit_item PHY_NTC_INIT[] __initdata = {
++struct reginit_item PHY_NTC_INIT[] __devinitdata = {
+ { PHY_CLEARALL, 0x40 },
+ { 0x12, 0x0001 },
+ { 0x13, 0x7605 },
+@@ -1282,9 +1282,7 @@
+ .open = fs_open,
+ .close = fs_close,
+ .send = fs_send,
+-#if 0
+ .owner = THIS_MODULE,
+-#endif
+ /* ioctl: fs_ioctl, */
+ /* getsockopt: fs_getsockopt, */
+ /* setsockopt: fs_setsockopt, */
+@@ -1296,7 +1294,7 @@
+ };
+
+
+-static void __init undocumented_pci_fix (struct pci_dev *pdev)
++static void __devinit undocumented_pci_fix (struct pci_dev *pdev)
+ {
+ int tint;
+
+@@ -1320,13 +1318,13 @@
+ * PHY routines *
+ **************************************************************************/
+
+-static void __init write_phy (struct fs_dev *dev, int regnum, int val)
++static void __devinit write_phy (struct fs_dev *dev, int regnum, int val)
+ {
+ submit_command (dev, &dev->hp_txq, QE_CMD_PRP_WR | QE_CMD_IMM_INQ,
+ regnum, val, 0);
+ }
+
+-static int __init init_phy (struct fs_dev *dev, struct reginit_item *reginit)
++static int __devinit init_phy (struct fs_dev *dev, struct reginit_item *reginit)
+ {
+ int i;
+
+@@ -1382,7 +1380,7 @@
+ }
+ }
+
+-static void __init *aligned_kmalloc (int size, int flags, int alignment)
++static void __devinit *aligned_kmalloc (int size, int flags, int alignment)
+ {
+ void *t;
+
+@@ -1399,7 +1397,7 @@
+ return NULL;
+ }
+
+-static int __init init_q (struct fs_dev *dev,
++static int __devinit init_q (struct fs_dev *dev,
+ struct queue *txq, int queue, int nentries, int is_rq)
+ {
+ int sz = nentries * sizeof (struct FS_QENTRY);
+@@ -1435,7 +1433,7 @@
+ }
+
+
+-static int __init init_fp (struct fs_dev *dev,
++static int __devinit init_fp (struct fs_dev *dev,
+ struct freepool *fp, int queue, int bufsize, int nr_buffers)
+ {
+ func_enter ();
+@@ -1655,7 +1653,7 @@
+ }
+ #endif
+
+-static int __init fs_init (struct fs_dev *dev)
++static int __devinit fs_init (struct fs_dev *dev)
+ {
+ struct pci_dev *pci_dev;
+ int isr, to;
+@@ -1890,7 +1888,7 @@
+ return 0;
+ }
+
+-static int __init firestream_init_one (struct pci_dev *pci_dev,
++static int __devinit firestream_init_one (struct pci_dev *pci_dev,
+ const struct pci_device_id *ent)
+ {
+ struct atm_dev *atm_dev;
+Index: linux-2.6.0-test5/drivers/atm/idt77252.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/atm/idt77252.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/atm/idt77252.c 2003-09-27 11:38:20.600396648 +0800
+@@ -147,7 +147,8 @@
+ .phy_put = idt77252_phy_put,
+ .phy_get = idt77252_phy_get,
+ .change_qos = idt77252_change_qos,
+- .proc_read = idt77252_proc_read
++ .proc_read = idt77252_proc_read,
++ .owner = THIS_MODULE
+ };
+
+ static struct idt77252_dev *idt77252_chain = NULL;
+@@ -2544,7 +2545,6 @@
+ }
+
+ set_bit(ATM_VF_READY, &vcc->flags);
+- MOD_INC_USE_COUNT;
+
+ up(&card->mutex);
+ return 0;
+@@ -2631,7 +2631,6 @@
+ free_scq(card, vc->scq);
+ }
+
+- MOD_DEC_USE_COUNT;
+ up(&card->mutex);
+ }
+
+Index: linux-2.6.0-test5/drivers/atm/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/atm/Kconfig 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/atm/Kconfig 2003-09-27 11:38:20.605395888 +0800
+@@ -241,7 +241,7 @@
+
+ config ATM_AMBASSADOR
+ tristate "Madge Ambassador (Collage PCI 155 Server)"
+- depends on PCI && ATM && BROKEN_ON_SMP
++ depends on PCI && ATM
+ help
+ This is a driver for ATMizer based ATM card produced by Madge
+ Networks Ltd. Say Y (or M to compile as a module named ambassador)
+Index: linux-2.6.0-test5/drivers/atm/lanai.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/atm/lanai.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/atm/lanai.c 2003-09-27 11:38:20.628392392 +0800
+@@ -2242,7 +2242,6 @@
+ printk(KERN_ERR DEV_LABEL ": can't allocate interrupt\n");
+ goto error_vcctable;
+ }
+- MOD_INC_USE_COUNT; /* At this point we can't fail */
+ mb(); /* Make sure that all that made it */
+ intr_enable(lanai, INT_ALL & ~(INT_PING | INT_WAKE));
+ /* 3.11: initialize loop mode (i.e. turn looping off) */
+@@ -2312,7 +2311,6 @@
+ service_buffer_deallocate(lanai);
+ iounmap((void *) lanai->base);
+ kfree(lanai);
+- MOD_DEC_USE_COUNT;
+ }
+
+ /* close a vcc */
+@@ -2686,7 +2684,8 @@
+ .phy_put = NULL,
+ .phy_get = NULL,
+ .change_qos = lanai_change_qos,
+- .proc_read = lanai_proc_read
++ .proc_read = lanai_proc_read,
++ .owner = THIS_MODULE
+ };
+
+ /* initialize one probed card */
+Index: linux-2.6.0-test5/drivers/atm/uPD98402.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/atm/uPD98402.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/atm/uPD98402.c 2003-09-27 11:38:20.630392088 +0800
+@@ -246,7 +246,7 @@
+ };
+
+
+-int __init uPD98402_init(struct atm_dev *dev)
++int uPD98402_init(struct atm_dev *dev)
+ {
+ DPRINTK("phy_init\n");
+ dev->phy = &uPD98402_ops;
+@@ -254,22 +254,13 @@
+ }
+
+
+-#ifdef MODULE
+ MODULE_LICENSE("GPL");
+
+ EXPORT_SYMBOL(uPD98402_init);
+
+-
+-int init_module(void)
++static __init int uPD98402_module_init(void)
+ {
+- MOD_INC_USE_COUNT;
+ return 0;
+ }
+-
+-
+-void cleanup_module(void)
+-{
+- /* Nay */
+-}
+-
+-#endif
++module_init(uPD98402_module_init);
++/* module_exit not defined so not unloadable */
+Index: linux-2.6.0-test5/drivers/atm/zatm.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/atm/zatm.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/atm/zatm.c 2003-09-27 11:38:20.641390416 +0800
+@@ -1619,11 +1619,10 @@
+ out:
+ kfree(zatm_dev);
+
+- /* XXX: currently the driver is not unloadable.. */
+- MOD_INC_USE_COUNT;
+ return 0;
+ }
+
+ MODULE_LICENSE("GPL");
+
+ module_init(zatm_module_init);
++/* module_exit not defined so not unloadable */
+Index: linux-2.6.0-test5/drivers/base/core.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/base/core.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/base/core.c 2003-09-27 11:38:20.645389808 +0800
+@@ -225,28 +225,30 @@
+ dev->kobj.parent = &parent->kobj;
+
+ if ((error = kobject_add(&dev->kobj)))
+- goto register_done;
+-
+- /* now take care of our own registration */
+-
++ goto Error;
++ if ((error = device_pm_add(dev)))
++ goto PMError;
++ if ((error = bus_add_device(dev)))
++ goto BusError;
+ down_write(&devices_subsys.rwsem);
+ if (parent)
+ list_add_tail(&dev->node,&parent->children);
+ up_write(&devices_subsys.rwsem);
+
+- bus_add_device(dev);
+-
+- device_pm_add(dev);
+-
+ /* notify platform of device entry */
+ if (platform_notify)
+ platform_notify(dev);
+-
+- register_done:
+- if (error && parent)
+- put_device(parent);
++ Done:
+ put_device(dev);
+ return error;
++ BusError:
++ device_pm_remove(dev);
++ PMError:
++ kobject_unregister(&dev->kobj);
++ Error:
++ if (parent)
++ put_device(parent);
++ goto Done;
+ }
+
+
+@@ -312,8 +314,6 @@
+ {
+ struct device * parent = dev->parent;
+
+- device_pm_remove(dev);
+-
+ down_write(&devices_subsys.rwsem);
+ if (parent)
+ list_del_init(&dev->node);
+@@ -324,14 +324,11 @@
+ */
+ if (platform_notify_remove)
+ platform_notify_remove(dev);
+-
+ bus_remove_device(dev);
+-
++ device_pm_remove(dev);
+ kobject_del(&dev->kobj);
+-
+ if (parent)
+ put_device(parent);
+-
+ }
+
+ /**
+Index: linux-2.6.0-test5/drivers/base/power/main.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/base/power/main.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/base/power/main.c 2003-09-27 11:38:20.646389656 +0800
+@@ -36,12 +36,14 @@
+
+ static inline void device_pm_hold(struct device * dev)
+ {
+- atomic_inc(&dev->power.pm_users);
++ if (dev)
++ atomic_inc(&dev->power.pm_users);
+ }
+
+ static inline void device_pm_release(struct device * dev)
+ {
+- atomic_inc(&dev->power.pm_users);
++ if (dev)
++ atomic_dec(&dev->power.pm_users);
+ }
+
+
+@@ -61,11 +63,9 @@
+ void device_pm_set_parent(struct device * dev, struct device * parent)
+ {
+ struct device * old_parent = dev->power.pm_parent;
+- if (old_parent)
+- device_pm_release(old_parent);
++ device_pm_release(old_parent);
+ dev->power.pm_parent = parent;
+- if (parent)
+- device_pm_hold(parent);
++ device_pm_hold(parent);
+ }
+ EXPORT_SYMBOL(device_pm_set_parent);
+
+@@ -91,6 +91,7 @@
+ dev->bus ? dev->bus->name : "No Bus", dev->kobj.name);
+ down(&dpm_sem);
+ dpm_sysfs_remove(dev);
++ device_pm_release(dev->power.pm_parent);
+ list_del(&dev->power.entry);
+ up(&dpm_sem);
+ }
+Index: linux-2.6.0-test5/drivers/base/power/power.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/base/power/power.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/base/power/power.h 2003-09-27 11:38:20.648389352 +0800
+@@ -58,7 +58,8 @@
+ /*
+ * resume.c
+ */
+-extern int dpm_resume(void);
++
++extern void dpm_resume(void);
+ extern void dpm_power_up(void);
+ extern int resume_device(struct device *);
+
+Index: linux-2.6.0-test5/drivers/base/power/resume.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/base/power/resume.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/base/power/resume.c 2003-09-27 11:38:20.649389200 +0800
+@@ -28,6 +28,19 @@
+ }
+
+
++
++void dpm_resume(void)
++{
++ while(!list_empty(&dpm_off)) {
++ struct list_head * entry = dpm_off.next;
++ struct device * dev = to_device(entry);
++ list_del_init(entry);
++ resume_device(dev);
++ list_add_tail(entry,&dpm_active);
++ }
++}
++
++
+ /**
+ * device_resume - Restore state of each device in system.
+ *
+@@ -38,13 +51,7 @@
+ void device_resume(void)
+ {
+ down(&dpm_sem);
+- while(!list_empty(&dpm_off)) {
+- struct list_head * entry = dpm_off.next;
+- struct device * dev = to_device(entry);
+- list_del_init(entry);
+- resume_device(dev);
+- list_add_tail(entry,&dpm_active);
+- }
++ dpm_resume();
+ up(&dpm_sem);
+ }
+
+Index: linux-2.6.0-test5/drivers/base/power/suspend.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/base/power/suspend.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/base/power/suspend.c 2003-09-27 11:38:20.651388896 +0800
+@@ -81,14 +81,18 @@
+ while(!list_empty(&dpm_active)) {
+ struct list_head * entry = dpm_active.prev;
+ struct device * dev = to_device(entry);
+- if ((error = suspend_device(dev,state)))
+- goto Error;
++ if ((error = suspend_device(dev,state))) {
++ if (error != -EAGAIN)
++ goto Error;
++ else
++ error = 0;
++ }
+ }
+ Done:
+ up(&dpm_sem);
+ return error;
+ Error:
+- device_resume();
++ dpm_resume();
+ goto Done;
+ }
+
+Index: linux-2.6.0-test5/drivers/block/acsi.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/acsi.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/block/acsi.c 2003-09-27 11:38:20.663387072 +0800
+@@ -1729,10 +1729,14 @@
+ for( i = 0; i < NDevices; ++i ) {
+ struct gendisk *disk = acsi_gendisk[i];
+ sprintf(disk->disk_name, "ad%c", 'a'+i);
++ aip = &acsi_info[NDevices];
++ sprintf(disk->devfs_name, "ad/target%d/lun%d", aip->target, aip->lun);
+ disk->major = ACSI_MAJOR;
+ disk->first_minor = i << 4;
+- if (acsi_info[i].type != HARDDISK)
++ if (acsi_info[i].type != HARDDISK) {
+ disk->minors = 1;
++ strcat(disk->devfs_name, "/disc");
++ }
+ disk->fops = &acsi_fops;
+ disk->private_data = &acsi_info[i];
+ set_capacity(disk, acsi_info[i].size);
+Index: linux-2.6.0-test5/drivers/block/as-iosched.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/as-iosched.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/block/as-iosched.c 2003-09-27 11:38:20.675385248 +0800
+@@ -162,7 +162,7 @@
+ unsigned long expires;
+
+ unsigned int is_sync;
+- enum arq_state state; /* debug only */
++ enum arq_state state;
+ };
+
+ #define RQ_DATA(rq) ((struct as_rq *) (rq)->elevator_private)
+@@ -344,11 +344,19 @@
+ }
+ }
+
+-static struct as_rq *__as_add_arq_rb(struct as_data *ad, struct as_rq *arq)
++/*
++ * Add the request to the rb tree if it is unique. If there is an alias (an
++ * existing request against the same sector), which can happen when using
++ * direct IO, then return the alias.
++ */
++static struct as_rq *as_add_arq_rb(struct as_data *ad, struct as_rq *arq)
+ {
+ struct rb_node **p = &ARQ_RB_ROOT(ad, arq)->rb_node;
+ struct rb_node *parent = NULL;
+ struct as_rq *__arq;
++ struct request *rq = arq->request;
++
++ arq->rb_key = rq_rb_key(rq);
+
+ while (*p) {
+ parent = *p;
+@@ -363,28 +371,9 @@
+ }
+
+ rb_link_node(&arq->rb_node, parent, p);
+- return 0;
+-}
+-
+-static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq);
+-/*
+- * Add the request to the rb tree if it is unique. If there is an alias (an
+- * existing request against the same sector), which can happen when using
+- * direct IO, then move the alias to the dispatch list and then add the
+- * request.
+- */
+-static void as_add_arq_rb(struct as_data *ad, struct as_rq *arq)
+-{
+- struct as_rq *alias;
+- struct request *rq = arq->request;
+-
+- arq->rb_key = rq_rb_key(rq);
+-
+- /* This can be caused by direct IO */
+- while ((alias = __as_add_arq_rb(ad, arq)))
+- as_move_to_dispatch(ad, alias);
+-
+ rb_insert_color(&arq->rb_node, ARQ_RB_ROOT(ad, arq));
++
++ return NULL;
+ }
+
+ static inline void as_del_arq_rb(struct as_data *ad, struct as_rq *arq)
+@@ -1021,6 +1010,7 @@
+ }
+ }
+ }
++
+ /*
+ * as_remove_request is called when a driver has finished with a request.
+ * This should be only called for dispatched requests, but for some reason
+@@ -1095,6 +1085,7 @@
+ */
+ static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq)
+ {
++ struct list_head *insert;
+ const int data_dir = arq->is_sync;
+
+ BUG_ON(!ON_RB(&arq->rb_node));
+@@ -1109,8 +1100,6 @@
+ ad->last_sector[data_dir] = arq->request->sector
+ + arq->request->nr_sectors;
+
+- ad->nr_dispatched++;
+-
+ if (data_dir == REQ_SYNC) {
+ /* In case we have to anticipate after this */
+ copy_io_context(&ad->io_context, &arq->io_context);
+@@ -1131,12 +1120,33 @@
+ * take it off the sort and fifo list, add to dispatch queue
+ */
+ as_remove_queued_request(ad->q, arq->request);
+- list_add_tail(&arq->request->queuelist, ad->dispatch);
++
++ insert = ad->dispatch->prev;
++
++ while (!list_empty(&arq->request->queuelist)) {
++ struct request *rq = list_entry_rq(arq->request->queuelist.next);
++ struct as_rq *__arq = RQ_DATA(rq);
++
++ list_move_tail(&rq->queuelist, ad->dispatch);
++
++ if (__arq->io_context && __arq->io_context->aic)
++ atomic_inc(&__arq->io_context->aic->nr_dispatched);
++
++ WARN_ON(__arq->state != AS_RQ_QUEUED);
++ __arq->state = AS_RQ_DISPATCHED;
++
++ ad->nr_dispatched++;
++ }
++
++ list_add(&arq->request->queuelist, insert);
+ if (arq->io_context && arq->io_context->aic)
+ atomic_inc(&arq->io_context->aic->nr_dispatched);
+
+ WARN_ON(arq->state != AS_RQ_QUEUED);
+ arq->state = AS_RQ_DISPATCHED;
++
++ ad->nr_dispatched++;
++
+ }
+
+ /*
+@@ -1290,10 +1300,31 @@
+ }
+
+ /*
++ * Add arq to a list behind alias
++ */
++static inline void
++as_add_aliased_request(struct as_data *ad, struct as_rq *arq, struct as_rq *alias)
++{
++ /*
++ * Another request with the same start sector on the rbtree.
++ * Link this request to that sector. They are untangled in
++ * as_move_to_dispatch
++ */
++ list_add_tail(&arq->request->queuelist, &alias->request->queuelist);
++
++ /*
++ * Don't want to have to handle merges.
++ */
++ as_remove_merge_hints(ad->q, arq);
++
++}
++
++/*
+ * add arq to rbtree and fifo
+ */
+ static void as_add_request(struct as_data *ad, struct as_rq *arq)
+ {
++ struct as_rq *alias;
+ int data_dir;
+
+ if (rq_data_dir(arq->request) == READ
+@@ -1310,15 +1341,40 @@
+ as_update_iohist(arq->io_context->aic, arq->request);
+ }
+
+- as_add_arq_rb(ad, arq);
++ alias = as_add_arq_rb(ad, arq);
++ if (!alias) {
++ /*
++ * set expire time (only used for reads) and add to fifo list
++ */
++ arq->expires = jiffies + ad->fifo_expire[data_dir];
++ list_add_tail(&arq->fifo, &ad->fifo_list[data_dir]);
++
++ if (rq_mergeable(arq->request)) {
++ as_add_arq_hash(ad, arq);
++
++ if (!ad->q->last_merge)
++ ad->q->last_merge = arq->request;
++ }
++ as_update_arq(ad, arq); /* keep state machine up to date */
++
++ } else {
++ as_add_aliased_request(ad, arq, alias);
++ /*
++ * have we been anticipating this request?
++ * or does it come from the same process as the one we are
++ * anticipating for?
++ */
++ if (ad->antic_status == ANTIC_WAIT_REQ
++ || ad->antic_status == ANTIC_WAIT_NEXT) {
++ if (as_can_break_anticipation(ad, arq))
++ as_antic_stop(ad);
++ }
++ }
++
++
++
+
+- /*
+- * set expire time (only used for reads) and add to fifo list
+- */
+- arq->expires = jiffies + ad->fifo_expire[data_dir];
+- list_add_tail(&arq->fifo, &ad->fifo_list[data_dir]);
+ arq->state = AS_RQ_QUEUED;
+- as_update_arq(ad, arq); /* keep state machine up to date */
+ }
+
+ /*
+@@ -1352,6 +1408,11 @@
+ struct as_data *ad = q->elevator.elevator_data;
+ struct as_rq *arq = RQ_DATA(rq);
+
++ /* barriers must flush the reorder queue */
++ if (unlikely(rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)
++ && where == ELEVATOR_INSERT_SORT))
++ where = ELEVATOR_INSERT_BACK;
++
+ switch (where) {
+ case ELEVATOR_INSERT_BACK:
+ while (ad->next_arq[REQ_SYNC])
+@@ -1359,7 +1420,9 @@
+
+ while (ad->next_arq[REQ_ASYNC])
+ as_move_to_dispatch(ad, ad->next_arq[REQ_ASYNC]);
++
+ list_add_tail(&rq->queuelist, ad->dispatch);
++ as_antic_stop(ad);
+ break;
+ case ELEVATOR_INSERT_FRONT:
+ list_add(&rq->queuelist, ad->dispatch);
+@@ -1373,13 +1436,6 @@
+ printk("%s: bad insert point %d\n", __FUNCTION__,where);
+ return;
+ }
+-
+- if (rq_mergeable(rq)) {
+- as_add_arq_hash(ad, arq);
+-
+- if (!q->last_merge)
+- q->last_merge = rq;
+- }
+ }
+
+ /*
+@@ -1494,8 +1550,18 @@
+ * if the merge was a front merge, we need to reposition request
+ */
+ if (rq_rb_key(req) != arq->rb_key) {
++ struct as_rq *alias;
++
++ /*
++ * Note! We should really be moving any old aliased requests
++ * off this request and try to insert them into the rbtree. We
++ * currently don't bother. Ditto the next function.
++ */
+ as_del_arq_rb(ad, arq);
+- as_add_arq_rb(ad, arq);
++ if ((alias = as_add_arq_rb(ad, arq)) ) {
++ list_del_init(&arq->fifo);
++ as_add_aliased_request(ad, arq, alias);
++ }
+ /*
+ * Note! At this stage of this and the next function, our next
+ * request may not be optimal - eg the request may have "grown"
+@@ -1525,8 +1591,12 @@
+ as_add_arq_hash(ad, arq);
+
+ if (rq_rb_key(req) != arq->rb_key) {
++ struct as_rq *alias;
+ as_del_arq_rb(ad, arq);
+- as_add_arq_rb(ad, arq);
++ if ((alias = as_add_arq_rb(ad, arq)) ) {
++ list_del_init(&arq->fifo);
++ as_add_aliased_request(ad, arq, alias);
++ }
+ }
+
+ /*
+@@ -1865,7 +1935,7 @@
+ .elevator_exit_fn = as_exit,
+
+ .elevator_ktype = &as_ktype,
+- .elevator_name = "anticipatory scheduling",
++ .elevator_name = "anticipatory",
+ };
+
+ EXPORT_SYMBOL(iosched_as);
+Index: linux-2.6.0-test5/drivers/block/cciss.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/cciss.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/block/cciss.c 2003-09-27 11:38:20.695382208 +0800
+@@ -243,7 +243,7 @@
+ * Get us a file in /proc/cciss that says something about each controller.
+ * Create /proc/cciss if it doesn't exist yet.
+ */
+-static void __init cciss_procinit(int i)
++static void __devinit cciss_procinit(int i)
+ {
+ struct proc_dir_entry *pde;
+
+@@ -754,16 +754,24 @@
+ status = -ENOMEM;
+ goto cleanup1;
+ }
+- if (copy_from_user(ioc, (void *) arg, sizeof(*ioc)))
+- return -EFAULT;
++ if (copy_from_user(ioc, (void *) arg, sizeof(*ioc))) {
++ status = -EFAULT;
++ goto cleanup1;
++ }
+ if ((ioc->buf_size < 1) &&
+- (ioc->Request.Type.Direction != XFER_NONE))
+- return -EINVAL;
++ (ioc->Request.Type.Direction != XFER_NONE)) {
++ status = -EINVAL;
++ goto cleanup1;
++ }
+ /* Check kmalloc limits using all SGs */
+- if (ioc->malloc_size > MAX_KMALLOC_SIZE)
+- return -EINVAL;
+- if (ioc->buf_size > ioc->malloc_size * MAXSGENTRIES)
+- return -EINVAL;
++ if (ioc->malloc_size > MAX_KMALLOC_SIZE) {
++ status = -EINVAL;
++ goto cleanup1;
++ }
++ if (ioc->buf_size > ioc->malloc_size * MAXSGENTRIES) {
++ status = -EINVAL;
++ goto cleanup1;
++ }
+ buff = (unsigned char **) kmalloc(MAXSGENTRIES *
+ sizeof(char *), GFP_KERNEL);
+ if (!buff) {
+@@ -2427,7 +2435,7 @@
+ * stealing all these major device numbers.
+ * returns the number of block devices registered.
+ */
+-static int __init cciss_init_one(struct pci_dev *pdev,
++static int __devinit cciss_init_one(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+ {
+ request_queue_t *q;
+@@ -2531,6 +2539,7 @@
+ struct gendisk *disk = hba[i]->gendisk[j];
+
+ sprintf(disk->disk_name, "cciss/c%dd%d", i, j);
++ sprintf(disk->devfs_name, "cciss/host%d/target%d", i, j);
+ disk->major = COMPAQ_CISS_MAJOR + i;
+ disk->first_minor = j << NWD_SHIFT;
+ disk->fops = &cciss_fops;
+Index: linux-2.6.0-test5/drivers/block/cfq-iosched.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/cfq-iosched.c 2003-09-27 11:38:18.447723904 +0800
++++ linux-2.6.0-test5/drivers/block/cfq-iosched.c 2003-09-27 11:38:20.697381904 +0800
+@@ -0,0 +1,707 @@
++/*
++ * linux/drivers/block/cfq-iosched.c
++ *
++ * CFQ, or complete fairness queueing, disk scheduler.
++ *
++ * Based on ideas from a previously unfinished io
++ * scheduler (round robin per-process disk scheduling) and Andrea Arcangeli.
++ *
++ * Copyright (C) 2003 Jens Axboe <axboe@suse.de>
++ */
++#include <linux/kernel.h>
++#include <linux/fs.h>
++#include <linux/blkdev.h>
++#include <linux/elevator.h>
++#include <linux/bio.h>
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/init.h>
++#include <linux/compiler.h>
++#include <linux/hash.h>
++#include <linux/rbtree.h>
++#include <linux/mempool.h>
++
++/*
++ * tunables
++ */
++static int cfq_quantum = 4;
++static int cfq_queued = 8;
++
++#define CFQ_QHASH_SHIFT 6
++#define CFQ_QHASH_ENTRIES (1 << CFQ_QHASH_SHIFT)
++#define list_entry_qhash(entry) list_entry((entry), struct cfq_queue, cfq_hash)
++
++#define CFQ_MHASH_SHIFT 8
++#define CFQ_MHASH_BLOCK(sec) ((sec) >> 3)
++#define CFQ_MHASH_ENTRIES (1 << CFQ_MHASH_SHIFT)
++#define CFQ_MHASH_FN(sec) (hash_long(CFQ_MHASH_BLOCK((sec)),CFQ_MHASH_SHIFT))
++#define ON_MHASH(crq) !list_empty(&(crq)->hash)
++#define rq_hash_key(rq) ((rq)->sector + (rq)->nr_sectors)
++#define list_entry_hash(ptr) list_entry((ptr), struct cfq_rq, hash)
++
++#define list_entry_cfqq(ptr) list_entry((ptr), struct cfq_queue, cfq_list)
++
++#define RQ_DATA(rq) ((struct cfq_rq *) (rq)->elevator_private)
++
++static kmem_cache_t *crq_pool;
++static kmem_cache_t *cfq_pool;
++static mempool_t *cfq_mpool;
++
++struct cfq_data {
++ struct list_head rr_list;
++ struct list_head *dispatch;
++ struct list_head *cfq_hash;
++
++ struct list_head *crq_hash;
++
++ unsigned int busy_queues;
++ unsigned int max_queued;
++
++ mempool_t *crq_pool;
++};
++
++struct cfq_queue {
++ struct list_head cfq_hash;
++ struct list_head cfq_list;
++ struct rb_root sort_list;
++ int pid;
++ int queued[2];
++#if 0
++ /*
++ * with a simple addition like this, we can do io priorities. almost.
++ * does need a split request free list, too.
++ */
++ int io_prio
++#endif
++};
++
++struct cfq_rq {
++ struct rb_node rb_node;
++ sector_t rb_key;
++
++ struct request *request;
++
++ struct cfq_queue *cfq_queue;
++
++ struct list_head hash;
++};
++
++static void cfq_put_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq);
++static struct cfq_queue *cfq_find_cfq_hash(struct cfq_data *cfqd, int pid);
++static void cfq_dispatch_sort(struct list_head *head, struct cfq_rq *crq);
++
++/*
++ * lots of deadline iosched dupes, can be abstracted later...
++ */
++static inline void __cfq_del_crq_hash(struct cfq_rq *crq)
++{
++ list_del_init(&crq->hash);
++}
++
++static inline void cfq_del_crq_hash(struct cfq_rq *crq)
++{
++ if (ON_MHASH(crq))
++ __cfq_del_crq_hash(crq);
++}
++
++static void cfq_remove_merge_hints(request_queue_t *q, struct cfq_rq *crq)
++{
++ cfq_del_crq_hash(crq);
++
++ if (q->last_merge == crq->request)
++ q->last_merge = NULL;
++}
++
++static inline void cfq_add_crq_hash(struct cfq_data *cfqd, struct cfq_rq *crq)
++{
++ struct request *rq = crq->request;
++
++ BUG_ON(ON_MHASH(crq));
++
++ list_add(&crq->hash, &cfqd->crq_hash[CFQ_MHASH_FN(rq_hash_key(rq))]);
++}
++
++static struct request *cfq_find_rq_hash(struct cfq_data *cfqd, sector_t offset)
++{
++ struct list_head *hash_list = &cfqd->crq_hash[CFQ_MHASH_FN(offset)];
++ struct list_head *entry, *next = hash_list->next;
++
++ while ((entry = next) != hash_list) {
++ struct cfq_rq *crq = list_entry_hash(entry);
++ struct request *__rq = crq->request;
++
++ next = entry->next;
++
++ BUG_ON(!ON_MHASH(crq));
++
++ if (!rq_mergeable(__rq)) {
++ __cfq_del_crq_hash(crq);
++ continue;
++ }
++
++ if (rq_hash_key(__rq) == offset)
++ return __rq;
++ }
++
++ return NULL;
++}
++
++/*
++ * rb tree support functions
++ */
++#define RB_NONE (2)
++#define RB_EMPTY(node) ((node)->rb_node == NULL)
++#define RB_CLEAR(node) ((node)->rb_color = RB_NONE)
++#define RB_CLEAR_ROOT(root) ((root)->rb_node = NULL)
++#define ON_RB(node) ((node)->rb_color != RB_NONE)
++#define rb_entry_crq(node) rb_entry((node), struct cfq_rq, rb_node)
++#define rq_rb_key(rq) (rq)->sector
++
++static inline void cfq_del_crq_rb(struct cfq_queue *cfqq, struct cfq_rq *crq)
++{
++ if (ON_RB(&crq->rb_node)) {
++ cfqq->queued[rq_data_dir(crq->request)]--;
++ rb_erase(&crq->rb_node, &cfqq->sort_list);
++ crq->cfq_queue = NULL;
++ }
++}
++
++static struct cfq_rq *
++__cfq_add_crq_rb(struct cfq_queue *cfqq, struct cfq_rq *crq)
++{
++ struct rb_node **p = &cfqq->sort_list.rb_node;
++ struct rb_node *parent = NULL;
++ struct cfq_rq *__crq;
++
++ while (*p) {
++ parent = *p;
++ __crq = rb_entry_crq(parent);
++
++ if (crq->rb_key < __crq->rb_key)
++ p = &(*p)->rb_left;
++ else if (crq->rb_key > __crq->rb_key)
++ p = &(*p)->rb_right;
++ else
++ return __crq;
++ }
++
++ rb_link_node(&crq->rb_node, parent, p);
++ return 0;
++}
++
++static void
++cfq_add_crq_rb(struct cfq_data *cfqd, struct cfq_queue *cfqq,struct cfq_rq *crq)
++{
++ struct request *rq = crq->request;
++ struct cfq_rq *__alias;
++
++ crq->rb_key = rq_rb_key(rq);
++ cfqq->queued[rq_data_dir(rq)]++;
++retry:
++ __alias = __cfq_add_crq_rb(cfqq, crq);
++ if (!__alias) {
++ rb_insert_color(&crq->rb_node, &cfqq->sort_list);
++ crq->cfq_queue = cfqq;
++ return;
++ }
++
++ cfq_del_crq_rb(cfqq, __alias);
++ cfq_dispatch_sort(cfqd->dispatch, __alias);
++ goto retry;
++}
++
++static struct request *
++cfq_find_rq_rb(struct cfq_data *cfqd, sector_t sector)
++{
++ struct cfq_queue *cfqq = cfq_find_cfq_hash(cfqd, current->tgid);
++ struct rb_node *n;
++
++ if (!cfqq)
++ goto out;
++
++ n = cfqq->sort_list.rb_node;
++ while (n) {
++ struct cfq_rq *crq = rb_entry_crq(n);
++
++ if (sector < crq->rb_key)
++ n = n->rb_left;
++ else if (sector > crq->rb_key)
++ n = n->rb_right;
++ else
++ return crq->request;
++ }
++
++out:
++ return NULL;
++}
++
++static void cfq_remove_request(request_queue_t *q, struct request *rq)
++{
++ struct cfq_data *cfqd = q->elevator.elevator_data;
++ struct cfq_rq *crq = RQ_DATA(rq);
++
++ if (crq) {
++ struct cfq_queue *cfqq = crq->cfq_queue;
++
++ cfq_remove_merge_hints(q, crq);
++ list_del_init(&rq->queuelist);
++
++ if (cfqq) {
++ cfq_del_crq_rb(cfqq, crq);
++
++ if (RB_EMPTY(&cfqq->sort_list))
++ cfq_put_queue(cfqd, cfqq);
++ }
++ }
++}
++
++static int
++cfq_merge(request_queue_t *q, struct request **req, struct bio *bio)
++{
++ struct cfq_data *cfqd = q->elevator.elevator_data;
++ struct request *__rq;
++ int ret;
++
++ ret = elv_try_last_merge(q, bio);
++ if (ret != ELEVATOR_NO_MERGE) {
++ __rq = q->last_merge;
++ goto out_insert;
++ }
++
++ __rq = cfq_find_rq_hash(cfqd, bio->bi_sector);
++ if (__rq) {
++ BUG_ON(__rq->sector + __rq->nr_sectors != bio->bi_sector);
++
++ if (elv_rq_merge_ok(__rq, bio)) {
++ ret = ELEVATOR_BACK_MERGE;
++ goto out;
++ }
++ }
++
++ __rq = cfq_find_rq_rb(cfqd, bio->bi_sector + bio_sectors(bio));
++ if (__rq) {
++ if (elv_rq_merge_ok(__rq, bio)) {
++ ret = ELEVATOR_FRONT_MERGE;
++ goto out;
++ }
++ }
++
++ return ELEVATOR_NO_MERGE;
++out:
++ q->last_merge = __rq;
++out_insert:
++ *req = __rq;
++ return ret;
++}
++
++static void cfq_merged_request(request_queue_t *q, struct request *req)
++{
++ struct cfq_data *cfqd = q->elevator.elevator_data;
++ struct cfq_rq *crq = RQ_DATA(req);
++
++ cfq_del_crq_hash(crq);
++ cfq_add_crq_hash(cfqd, crq);
++
++ if (ON_RB(&crq->rb_node) && (rq_rb_key(req) != crq->rb_key)) {
++ struct cfq_queue *cfqq = crq->cfq_queue;
++
++ cfq_del_crq_rb(cfqq, crq);
++ cfq_add_crq_rb(cfqd, cfqq, crq);
++ }
++
++ q->last_merge = req;
++}
++
++static void
++cfq_merged_requests(request_queue_t *q, struct request *req,
++ struct request *next)
++{
++ cfq_merged_request(q, req);
++ cfq_remove_request(q, next);
++}
++
++static void cfq_dispatch_sort(struct list_head *head, struct cfq_rq *crq)
++{
++ struct list_head *entry = head;
++ struct request *__rq;
++
++ if (!list_empty(head)) {
++ __rq = list_entry_rq(head->next);
++
++ if (crq->request->sector < __rq->sector) {
++ entry = head->prev;
++ goto link;
++ }
++ }
++
++ while ((entry = entry->prev) != head) {
++ __rq = list_entry_rq(entry);
++
++ if (crq->request->sector <= __rq->sector)
++ break;
++ }
++
++link:
++ list_add_tail(&crq->request->queuelist, entry);
++}
++
++static inline void
++__cfq_dispatch_requests(request_queue_t *q, struct cfq_data *cfqd,
++ struct cfq_queue *cfqq)
++{
++ struct cfq_rq *crq = rb_entry_crq(rb_first(&cfqq->sort_list));
++
++ cfq_del_crq_rb(cfqq, crq);
++ cfq_remove_merge_hints(q, crq);
++ cfq_dispatch_sort(cfqd->dispatch, crq);
++}
++
++static int cfq_dispatch_requests(request_queue_t *q, struct cfq_data *cfqd)
++{
++ struct cfq_queue *cfqq;
++ struct list_head *entry, *tmp;
++ int ret, queued, good_queues;
++
++ if (list_empty(&cfqd->rr_list))
++ return 0;
++
++ queued = ret = 0;
++restart:
++ good_queues = 0;
++ list_for_each_safe(entry, tmp, &cfqd->rr_list) {
++ cfqq = list_entry_cfqq(cfqd->rr_list.next);
++
++ BUG_ON(RB_EMPTY(&cfqq->sort_list));
++
++ __cfq_dispatch_requests(q, cfqd, cfqq);
++
++ if (RB_EMPTY(&cfqq->sort_list))
++ cfq_put_queue(cfqd, cfqq);
++ else
++ good_queues++;
++
++ queued++;
++ ret = 1;
++ }
++
++ if ((queued < cfq_quantum) && good_queues)
++ goto restart;
++
++ return ret;
++}
++
++static struct request *cfq_next_request(request_queue_t *q)
++{
++ struct cfq_data *cfqd = q->elevator.elevator_data;
++ struct request *rq;
++
++ if (!list_empty(cfqd->dispatch)) {
++ struct cfq_rq *crq;
++dispatch:
++ rq = list_entry_rq(cfqd->dispatch->next);
++
++ BUG_ON(q->last_merge == rq);
++ crq = RQ_DATA(rq);
++ if (crq)
++ BUG_ON(ON_MHASH(crq));
++
++ return rq;
++ }
++
++ if (cfq_dispatch_requests(q, cfqd))
++ goto dispatch;
++
++ return NULL;
++}
++
++static inline struct cfq_queue *
++__cfq_find_cfq_hash(struct cfq_data *cfqd, int pid, const int hashval)
++{
++ struct list_head *hash_list = &cfqd->cfq_hash[hashval];
++ struct list_head *entry;
++
++ list_for_each(entry, hash_list) {
++ struct cfq_queue *__cfqq = list_entry_qhash(entry);
++
++ if (__cfqq->pid == pid)
++ return __cfqq;
++ }
++
++ return NULL;
++}
++
++static struct cfq_queue *cfq_find_cfq_hash(struct cfq_data *cfqd, int pid)
++{
++ const int hashval = hash_long(current->tgid, CFQ_QHASH_SHIFT);
++
++ return __cfq_find_cfq_hash(cfqd, pid, hashval);
++}
++
++static void cfq_put_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq)
++{
++ cfqd->busy_queues--;
++ list_del(&cfqq->cfq_list);
++ list_del(&cfqq->cfq_hash);
++ mempool_free(cfqq, cfq_mpool);
++}
++
++static struct cfq_queue *cfq_get_queue(struct cfq_data *cfqd, int pid)
++{
++ const int hashval = hash_long(current->tgid, CFQ_QHASH_SHIFT);
++ struct cfq_queue *cfqq = __cfq_find_cfq_hash(cfqd, pid, hashval);
++
++ if (!cfqq) {
++ cfqq = mempool_alloc(cfq_mpool, GFP_NOIO);
++
++ INIT_LIST_HEAD(&cfqq->cfq_hash);
++ INIT_LIST_HEAD(&cfqq->cfq_list);
++ RB_CLEAR_ROOT(&cfqq->sort_list);
++
++ cfqq->pid = pid;
++ cfqq->queued[0] = cfqq->queued[1] = 0;
++ list_add(&cfqq->cfq_hash, &cfqd->cfq_hash[hashval]);
++ }
++
++ return cfqq;
++}
++
++static void cfq_enqueue(struct cfq_data *cfqd, struct cfq_rq *crq)
++{
++ struct cfq_queue *cfqq;
++
++ cfqq = cfq_get_queue(cfqd, current->tgid);
++
++ cfq_add_crq_rb(cfqd, cfqq, crq);
++
++ if (list_empty(&cfqq->cfq_list)) {
++ list_add(&cfqq->cfq_list, &cfqd->rr_list);
++ cfqd->busy_queues++;
++ }
++}
++
++static void
++cfq_insert_request(request_queue_t *q, struct request *rq, int where)
++{
++ struct cfq_data *cfqd = q->elevator.elevator_data;
++ struct cfq_rq *crq = RQ_DATA(rq);
++
++ switch (where) {
++ case ELEVATOR_INSERT_BACK:
++ while (cfq_dispatch_requests(q, cfqd))
++ ;
++ list_add_tail(&rq->queuelist, cfqd->dispatch);
++ break;
++ case ELEVATOR_INSERT_FRONT:
++ list_add(&rq->queuelist, cfqd->dispatch);
++ break;
++ case ELEVATOR_INSERT_SORT:
++ BUG_ON(!blk_fs_request(rq));
++ cfq_enqueue(cfqd, crq);
++ break;
++ default:
++ printk("%s: bad insert point %d\n", __FUNCTION__,where);
++ return;
++ }
++
++ if (rq_mergeable(rq)) {
++ cfq_add_crq_hash(cfqd, crq);
++
++ if (!q->last_merge)
++ q->last_merge = rq;
++ }
++}
++
++static int cfq_queue_empty(request_queue_t *q)
++{
++ struct cfq_data *cfqd = q->elevator.elevator_data;
++
++ if (list_empty(cfqd->dispatch) && list_empty(&cfqd->rr_list))
++ return 1;
++
++ return 0;
++}
++
++static struct request *
++cfq_former_request(request_queue_t *q, struct request *rq)
++{
++ struct cfq_rq *crq = RQ_DATA(rq);
++ struct rb_node *rbprev = rb_prev(&crq->rb_node);
++
++ if (rbprev)
++ return rb_entry_crq(rbprev)->request;
++
++ return NULL;
++}
++
++static struct request *
++cfq_latter_request(request_queue_t *q, struct request *rq)
++{
++ struct cfq_rq *crq = RQ_DATA(rq);
++ struct rb_node *rbnext = rb_next(&crq->rb_node);
++
++ if (rbnext)
++ return rb_entry_crq(rbnext)->request;
++
++ return NULL;
++}
++
++static int cfq_may_queue(request_queue_t *q, int rw)
++{
++ struct cfq_data *cfqd = q->elevator.elevator_data;
++ struct cfq_queue *cfqq;
++ int ret = 1;
++
++ if (!cfqd->busy_queues)
++ goto out;
++
++ cfqq = cfq_find_cfq_hash(cfqd, current->tgid);
++ if (cfqq) {
++ int limit = (q->nr_requests - cfq_queued) / cfqd->busy_queues;
++
++ if (limit < 3)
++ limit = 3;
++ else if (limit > cfqd->max_queued)
++ limit = cfqd->max_queued;
++
++ if (cfqq->queued[rw] > limit)
++ ret = 0;
++ }
++out:
++ return ret;
++}
++
++static void cfq_put_request(request_queue_t *q, struct request *rq)
++{
++ struct cfq_data *cfqd = q->elevator.elevator_data;
++ struct cfq_rq *crq = RQ_DATA(rq);
++
++ if (crq) {
++ BUG_ON(q->last_merge == rq);
++ BUG_ON(ON_MHASH(crq));
++
++ mempool_free(crq, cfqd->crq_pool);
++ rq->elevator_private = NULL;
++ }
++}
++
++static int cfq_set_request(request_queue_t *q, struct request *rq, int gfp_mask)
++{
++ struct cfq_data *cfqd = q->elevator.elevator_data;
++ struct cfq_rq *crq = mempool_alloc(cfqd->crq_pool, gfp_mask);
++
++ if (crq) {
++ RB_CLEAR(&crq->rb_node);
++ crq->request = rq;
++ crq->cfq_queue = NULL;
++ INIT_LIST_HEAD(&crq->hash);
++ rq->elevator_private = crq;
++ return 0;
++ }
++
++ return 1;
++}
++
++static void cfq_exit(request_queue_t *q, elevator_t *e)
++{
++ struct cfq_data *cfqd = e->elevator_data;
++
++ e->elevator_data = NULL;
++ mempool_destroy(cfqd->crq_pool);
++ kfree(cfqd->crq_hash);
++ kfree(cfqd->cfq_hash);
++ kfree(cfqd);
++}
++
++static int cfq_init(request_queue_t *q, elevator_t *e)
++{
++ struct cfq_data *cfqd;
++ int i;
++
++ cfqd = kmalloc(sizeof(*cfqd), GFP_KERNEL);
++ if (!cfqd)
++ return -ENOMEM;
++
++ memset(cfqd, 0, sizeof(*cfqd));
++ INIT_LIST_HEAD(&cfqd->rr_list);
++
++ cfqd->crq_hash = kmalloc(sizeof(struct list_head) * CFQ_MHASH_ENTRIES, GFP_KERNEL);
++ if (!cfqd->crq_hash)
++ goto out_crqhash;
++
++ cfqd->cfq_hash = kmalloc(sizeof(struct list_head) * CFQ_QHASH_ENTRIES, GFP_KERNEL);
++ if (!cfqd->cfq_hash)
++ goto out_cfqhash;
++
++ cfqd->crq_pool = mempool_create(BLKDEV_MIN_RQ, mempool_alloc_slab, mempool_free_slab, crq_pool);
++ if (!cfqd->crq_pool)
++ goto out_crqpool;
++
++ for (i = 0; i < CFQ_MHASH_ENTRIES; i++)
++ INIT_LIST_HEAD(&cfqd->crq_hash[i]);
++ for (i = 0; i < CFQ_QHASH_ENTRIES; i++)
++ INIT_LIST_HEAD(&cfqd->cfq_hash[i]);
++
++ cfqd->dispatch = &q->queue_head;
++ e->elevator_data = cfqd;
++
++ /*
++ * just set it to some high value, we want anyone to be able to queue
++ * some requests. fairness is handled differently
++ */
++ cfqd->max_queued = q->nr_requests;
++ q->nr_requests = 8192;
++
++ return 0;
++out_crqpool:
++ kfree(cfqd->cfq_hash);
++out_cfqhash:
++ kfree(cfqd->crq_hash);
++out_crqhash:
++ kfree(cfqd);
++ return -ENOMEM;
++}
++
++static int __init cfq_slab_setup(void)
++{
++ crq_pool = kmem_cache_create("crq_pool", sizeof(struct cfq_rq), 0, 0,
++ NULL, NULL);
++
++ if (!crq_pool)
++ panic("cfq_iosched: can't init crq pool\n");
++
++ cfq_pool = kmem_cache_create("cfq_pool", sizeof(struct cfq_queue), 0, 0,
++ NULL, NULL);
++
++ if (!cfq_pool)
++ panic("cfq_iosched: can't init cfq pool\n");
++
++ cfq_mpool = mempool_create(64, mempool_alloc_slab, mempool_free_slab, cfq_pool);
++
++ if (!cfq_mpool)
++ panic("cfq_iosched: can't init cfq mpool\n");
++
++ return 0;
++}
++
++subsys_initcall(cfq_slab_setup);
++
++elevator_t iosched_cfq = {
++ .elevator_name = "cfq",
++ .elevator_merge_fn = cfq_merge,
++ .elevator_merged_fn = cfq_merged_request,
++ .elevator_merge_req_fn = cfq_merged_requests,
++ .elevator_next_req_fn = cfq_next_request,
++ .elevator_add_req_fn = cfq_insert_request,
++ .elevator_remove_req_fn = cfq_remove_request,
++ .elevator_queue_empty_fn = cfq_queue_empty,
++ .elevator_former_req_fn = cfq_former_request,
++ .elevator_latter_req_fn = cfq_latter_request,
++ .elevator_set_req_fn = cfq_set_request,
++ .elevator_put_req_fn = cfq_put_request,
++ .elevator_may_queue_fn = cfq_may_queue,
++ .elevator_init_fn = cfq_init,
++ .elevator_exit_fn = cfq_exit,
++};
++
++EXPORT_SYMBOL(iosched_cfq);
+Index: linux-2.6.0-test5/drivers/block/DAC960.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/DAC960.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/block/DAC960.c 2003-09-27 11:38:20.759372480 +0800
+@@ -71,7 +71,7 @@
+ {
+ struct gendisk *disk = inode->i_bdev->bd_disk;
+ DAC960_Controller_T *p = disk->queue->queuedata;
+- int drive_nr = (int)disk->private_data;
++ int drive_nr = (long)disk->private_data;
+
+ if (p->FirmwareType == DAC960_V1_Controller) {
+ if (p->V1.LogicalDriveInformation[drive_nr].
+@@ -96,7 +96,7 @@
+ {
+ struct gendisk *disk = inode->i_bdev->bd_disk;
+ DAC960_Controller_T *p = disk->queue->queuedata;
+- int drive_nr = (int)disk->private_data;
++ int drive_nr = (long)disk->private_data;
+ struct hd_geometry g, *loc = (struct hd_geometry *)arg;
+
+ if (cmd != HDIO_GETGEO || !loc)
+@@ -136,7 +136,7 @@
+ static int DAC960_media_changed(struct gendisk *disk)
+ {
+ DAC960_Controller_T *p = disk->queue->queuedata;
+- int drive_nr = (int)disk->private_data;
++ int drive_nr = (long)disk->private_data;
+
+ if (!p->LogicalDriveInitiallyAccessible[drive_nr])
+ return 1;
+@@ -146,7 +146,7 @@
+ static int DAC960_revalidate_disk(struct gendisk *disk)
+ {
+ DAC960_Controller_T *p = disk->queue->queuedata;
+- int unit = (int)disk->private_data;
++ int unit = (long)disk->private_data;
+
+ set_capacity(disk, disk_size(p, unit));
+ return 0;
+@@ -1603,6 +1603,26 @@
+ DAC960PU/PD/PL 3.51 and above
+ DAC960PU/PD/PL/P 2.73 and above
+ */
++#if defined(CONFIG_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 (1-channel) or D040348 (2-channel) or D040349 (3-channel)
++ KZPAC: D040395 (1-channel) or D040396 (2-channel) or D040397 (3-channel)
++ */
++# define FIRMWARE_27X "2.70"
++#else
++# define FIRMWARE_27X "2.73"
++#endif
++
+ if (Enquiry2->FirmwareID.MajorVersion == 0)
+ {
+ Enquiry2->FirmwareID.MajorVersion =
+@@ -1622,7 +1642,7 @@
+ (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,
+@@ -2485,7 +2505,7 @@
+
+ disk->queue = RequestQueue;
+ sprintf(disk->disk_name, "rd/c%dd%d", Controller->ControllerNumber, n);
+- sprintf(disk->devfs_name, "rd/c%dd%d", Controller->ControllerNumber, n);
++ sprintf(disk->devfs_name, "rd/host%d/target%d", Controller->ControllerNumber, n);
+ disk->major = MajorNumber;
+ disk->first_minor = n << DAC960_MaxPartitionsBits;
+ disk->fops = &DAC960_BlockDeviceOperations;
+@@ -2708,12 +2728,12 @@
+ break;
+ }
+
+- pci_set_drvdata(PCI_Device, (void *)((int)Controller->ControllerNumber));
++ pci_set_drvdata(PCI_Device, (void *)((long)Controller->ControllerNumber));
+ for (i = 0; i < DAC960_MaxLogicalDrives; i++) {
+ Controller->disks[i] = alloc_disk(1<<DAC960_MaxPartitionsBits);
+ if (!Controller->disks[i])
+ goto Failure;
+- Controller->disks[i]->private_data = (void *)i;
++ Controller->disks[i]->private_data = (void *)((long)i);
+ }
+ init_waitqueue_head(&Controller->CommandWaitQueue);
+ init_waitqueue_head(&Controller->HealthStatusWaitQueue);
+@@ -3097,7 +3117,7 @@
+
+ static void DAC960_Remove(struct pci_dev *PCI_Device)
+ {
+- int Controller_Number = (int)pci_get_drvdata(PCI_Device);
++ int Controller_Number = (long)pci_get_drvdata(PCI_Device);
+ DAC960_Controller_T *Controller = DAC960_Controllers[Controller_Number];
+ if (Controller != NULL)
+ DAC960_FinalizeController(Controller);
+@@ -3272,7 +3292,7 @@
+ Command->CommandType = DAC960_WriteCommand;
+ }
+ Command->Completion = Request->waiting;
+- Command->LogicalDriveNumber = (int)Request->rq_disk->private_data;
++ Command->LogicalDriveNumber = (long)Request->rq_disk->private_data;
+ Command->BlockNumber = Request->sector;
+ Command->BlockCount = Request->nr_sectors;
+ Command->Request = Request;
+Index: linux-2.6.0-test5/drivers/block/deadline-iosched.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/deadline-iosched.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/block/deadline-iosched.c 2003-09-27 11:38:20.766371416 +0800
+@@ -287,8 +287,11 @@
+ * add drq to rbtree and fifo
+ */
+ static inline void
+-deadline_add_request(struct deadline_data *dd, struct deadline_rq *drq)
++deadline_add_request(struct request_queue *q, struct request *rq)
+ {
++ struct deadline_data *dd = q->elevator.elevator_data;
++ struct deadline_rq *drq = RQ_DATA(rq);
++
+ const int data_dir = rq_data_dir(drq->request);
+
+ deadline_add_drq_rb(dd, drq);
+@@ -297,6 +300,13 @@
+ */
+ drq->expires = jiffies + dd->fifo_expire[data_dir];
+ list_add_tail(&drq->fifo, &dd->fifo_list[data_dir]);
++
++ if (rq_mergeable(rq)) {
++ deadline_add_drq_hash(dd, drq);
++
++ if (!q->last_merge)
++ q->last_merge = rq;
++ }
+ }
+
+ /*
+@@ -616,7 +626,11 @@
+ deadline_insert_request(request_queue_t *q, struct request *rq, int where)
+ {
+ struct deadline_data *dd = q->elevator.elevator_data;
+- struct deadline_rq *drq = RQ_DATA(rq);
++
++ /* barriers must flush the reorder queue */
++ if (unlikely(rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)
++ && where == ELEVATOR_INSERT_SORT))
++ where = ELEVATOR_INSERT_BACK;
+
+ switch (where) {
+ case ELEVATOR_INSERT_BACK:
+@@ -629,19 +643,12 @@
+ break;
+ case ELEVATOR_INSERT_SORT:
+ BUG_ON(!blk_fs_request(rq));
+- deadline_add_request(dd, drq);
++ deadline_add_request(q, rq);
+ break;
+ default:
+ printk("%s: bad insert point %d\n", __FUNCTION__,where);
+ return;
+ }
+-
+- if (rq_mergeable(rq)) {
+- deadline_add_drq_hash(dd, drq);
+-
+- if (!q->last_merge)
+- q->last_merge = rq;
+- }
+ }
+
+ static int deadline_queue_empty(request_queue_t *q)
+Index: linux-2.6.0-test5/drivers/block/floppy.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/floppy.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/block/floppy.c 2003-09-27 11:38:20.800366248 +0800
+@@ -219,6 +219,7 @@
+ */
+
+ static spinlock_t floppy_lock = SPIN_LOCK_UNLOCKED;
++static struct completion device_release;
+
+ static unsigned short virtual_dma_port=0x3f0;
+ irqreturn_t floppy_interrupt(int irq, void *dev_id, struct pt_regs * regs);
+@@ -2152,18 +2153,20 @@
+
+ static void bad_flp_intr(void)
+ {
++ int err_count;
++
+ if (probing){
+ DRS->probed_format++;
+ if (!next_valid_format())
+ return;
+ }
+- (*errors)++;
+- INFBOUND(DRWE->badness, *errors);
+- if (*errors > DP->max_errors.abort)
++ err_count = ++(*errors);
++ INFBOUND(DRWE->badness, err_count);
++ if (err_count > DP->max_errors.abort)
+ cont->done(0);
+- if (*errors > DP->max_errors.reset)
++ if (err_count > DP->max_errors.reset)
+ FDCS->reset = 1;
+- else if (*errors > DP->max_errors.recal)
++ else if (err_count > DP->max_errors.recal)
+ DRS->track = NEED_2_RECAL;
+ }
+
+@@ -4203,9 +4206,17 @@
+
+ static int have_no_fdc= -ENODEV;
+
++static void floppy_device_release(struct device *dev)
++{
++ complete(&device_release);
++}
++
+ static struct platform_device floppy_device = {
+ .name = "floppy",
+ .id = 0,
++ .dev = {
++ .release = floppy_device_release,
++ }
+ };
+
+ static struct kobject *floppy_find(dev_t dev, int *part, void *data)
+@@ -4576,11 +4587,15 @@
+ void cleanup_module(void)
+ {
+ int drive;
+-
++
++ init_completion(&device_release);
+ platform_device_unregister(&floppy_device);
+ blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
+ unregister_blkdev(FLOPPY_MAJOR, "fd");
++
+ for (drive = 0; drive < N_DRIVE; drive++) {
++ del_timer_sync(&motor_off_timer[drive]);
++
+ if ((allowed_drive_mask & (1 << drive)) &&
+ fdc_state[FDC(drive)].version != FDC_NONE) {
+ del_gendisk(disks[drive]);
+@@ -4590,9 +4605,17 @@
+ }
+ devfs_remove("floppy");
+
++ del_timer_sync(&fd_timeout);
++ del_timer_sync(&fd_timer);
+ blk_cleanup_queue(floppy_queue);
++
++ if (usage_count)
++ floppy_release_irq_and_dma();
++
+ /* eject disk, if any */
+ fd_eject(0);
++
++ wait_for_completion(&device_release);
+ }
+
+ MODULE_PARM(floppy,"s");
+Index: linux-2.6.0-test5/drivers/block/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/Kconfig 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/block/Kconfig 2003-09-27 11:38:20.805365488 +0800
+@@ -44,7 +44,7 @@
+
+ config BLK_DEV_PS2
+ tristate "PS/2 ESDI hard disk support"
+- depends on MCA
++ depends on MCA && MCA_LEGACY
+ help
+ Say Y here if you have a PS/2 machine with a MCA bus and an ESDI
+ hard disk.
+Index: linux-2.6.0-test5/drivers/block/Kconfig.iosched
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/Kconfig.iosched 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/block/Kconfig.iosched 2003-09-27 11:38:20.806365336 +0800
+@@ -27,3 +27,10 @@
+ a disk at any one time, its behaviour is almost identical to the
+ anticipatory I/O scheduler and so is a good choice.
+
++config IOSCHED_CFQ
++ bool "CFQ I/O scheduler" if EMBEDDED
++ default y
++ ---help---
++ The CFQ I/O scheduler tries to distribute bandwidth equally
++ among all processes in the system. It should provide a fair
++ working environment, suitable for desktop systems.
+Index: linux-2.6.0-test5/drivers/block/ll_rw_blk.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/ll_rw_blk.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/block/ll_rw_blk.c 2003-09-27 11:38:20.826362296 +0800
+@@ -458,16 +458,19 @@
+ if (!bqt)
+ return;
+
+- BUG_ON(bqt->busy);
+- BUG_ON(!list_empty(&bqt->busy_list));
++ if (atomic_dec_and_test(&bqt->refcnt)) {
++ BUG_ON(bqt->busy);
++ BUG_ON(!list_empty(&bqt->busy_list));
+
+- kfree(bqt->tag_index);
+- bqt->tag_index = NULL;
++ kfree(bqt->tag_index);
++ bqt->tag_index = NULL;
+
+- kfree(bqt->tag_map);
+- bqt->tag_map = NULL;
++ kfree(bqt->tag_map);
++ bqt->tag_map = NULL;
++
++ kfree(bqt);
++ }
+
+- kfree(bqt);
+ q->queue_tags = NULL;
+ q->queue_flags &= ~(1 << QUEUE_FLAG_QUEUED);
+ }
+@@ -503,6 +506,9 @@
+ for (i = depth; i < bits * BLK_TAGS_PER_LONG; i++)
+ __set_bit(i, tags->tag_map);
+
++ INIT_LIST_HEAD(&tags->busy_list);
++ tags->busy = 0;
++ atomic_set(&tags->refcnt, 1);
+ return 0;
+ fail:
+ kfree(tags->tag_index);
+@@ -514,19 +520,18 @@
+ * @q: the request queue for the device
+ * @depth: the maximum queue depth supported
+ **/
+-int blk_queue_init_tags(request_queue_t *q, int depth)
++int blk_queue_init_tags(request_queue_t *q, int depth,
++ struct blk_queue_tag *tags)
+ {
+- struct blk_queue_tag *tags;
+-
+- tags = kmalloc(sizeof(struct blk_queue_tag),GFP_ATOMIC);
+- if (!tags)
+- goto fail;
+-
+- if (init_tag_map(q, tags, depth))
+- goto fail;
++ if (!tags) {
++ tags = kmalloc(sizeof(struct blk_queue_tag), GFP_ATOMIC);
++ if (!tags)
++ goto fail;
+
+- INIT_LIST_HEAD(&tags->busy_list);
+- tags->busy = 0;
++ if (init_tag_map(q, tags, depth))
++ goto fail;
++ } else
++ atomic_inc(&tags->refcnt);
+
+ /*
+ * assign it, all done
+@@ -1016,7 +1021,13 @@
+ void blk_plug_device(request_queue_t *q)
+ {
+ WARN_ON(!irqs_disabled());
+- if (!blk_queue_plugged(q)) {
++
++ /*
++ * don't plug a stopped queue, it must be paired with blk_start_queue()
++ * which will restart the queueing
++ */
++ if (!blk_queue_plugged(q)
++ && !test_bit(QUEUE_FLAG_STOPPED, &q->queue_flags)) {
+ spin_lock(&blk_plug_lock);
+ list_add_tail(&q->plug_list, &blk_plug_list);
+ mod_timer(&q->unplug_timer, jiffies + q->unplug_delay);
+@@ -1239,6 +1250,8 @@
+ &iosched_as;
+ #elif defined(CONFIG_IOSCHED_DEADLINE)
+ &iosched_deadline;
++#elif defined(CONFIG_IOSCHED_CFQ)
++ &iosched_cfq;
+ #elif defined(CONFIG_IOSCHED_NOOP)
+ &elevator_noop;
+ #else
+@@ -1257,6 +1270,10 @@
+ if (!strcmp(str, "as"))
+ chosen_elevator = &iosched_as;
+ #endif
++#ifdef CONFIG_IOSCHED_CFQ
++ if (!strcmp(str, "cfq"))
++ chosen_elevator = &iosched_cfq;
++#endif
+ #ifdef CONFIG_IOSCHED_NOOP
+ if (!strcmp(str, "noop"))
+ chosen_elevator = &elevator_noop;
+@@ -1769,25 +1786,50 @@
+ }
+
+ /**
+- * blk_congestion_wait - wait for a queue to become uncongested
++ * blk_congestion_wait_wq - wait for a queue to become uncongested,
+ * @rw: READ or WRITE
+ * @timeout: timeout in jiffies
++ * @wait : wait queue entry to use for waiting or async notification
++ * (NULL defaults to synchronous behaviour)
+ *
+ * Waits for up to @timeout jiffies for a queue (any queue) to exit congestion.
+ * If no queues are congested then just wait for the next request to be
+ * returned.
++ *
++ * If the wait queue parameter specifies an async i/o callback,
++ * then instead of blocking, just register the callback on the wait
++ * queue for async notification when the queue gets uncongested.
+ */
+-void blk_congestion_wait(int rw, long timeout)
++int blk_congestion_wait_wq(int rw, long timeout, wait_queue_t *wait)
+ {
+- DEFINE_WAIT(wait);
+ wait_queue_head_t *wqh = &congestion_wqh[rw];
++ DEFINE_WAIT(local_wait);
++
++ if (!wait)
++ wait = &local_wait;
+
+ blk_run_queues();
+- prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE);
++ prepare_to_wait(wqh, wait, TASK_UNINTERRUPTIBLE);
++ if (!is_sync_wait(wait)) {
++ /*
++ * if we've queued an async wait queue
++ * callback do not block; just tell the
++ * caller to return and retry later when
++ * the callback is notified
++ */
++ return -EIOCBRETRY;
++ }
+ io_schedule_timeout(timeout);
+- finish_wait(wqh, &wait);
++ finish_wait(wqh, wait);
++ return 0;
+ }
+
++void blk_congestion_wait(int rw, long timeout)
++{
++ blk_congestion_wait_wq(rw, timeout, NULL);
++}
++
++
+ /*
+ * Has to be called with the request spinlock acquired
+ */
+Index: linux-2.6.0-test5/drivers/block/loop.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/loop.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/block/loop.c 2003-09-27 11:38:20.835360928 +0800
+@@ -757,7 +757,7 @@
+ blk_queue_merge_bvec(lo->lo_queue, q->merge_bvec_fn);
+ }
+
+- kernel_thread(loop_thread, lo, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++ kernel_thread(loop_thread, lo, CLONE_KERNEL);
+ down(&lo->lo_sem);
+
+ fput(file);
+@@ -931,9 +931,9 @@
+ return error;
+ memset(info, 0, sizeof(*info));
+ info->lo_number = lo->lo_number;
+- info->lo_device = stat.dev;
++ info->lo_device = huge_encode_dev(stat.dev);
+ info->lo_inode = stat.ino;
+- info->lo_rdevice = lo->lo_device ? stat.rdev : stat.dev;
++ info->lo_rdevice = huge_encode_dev(lo->lo_device ? stat.rdev : stat.dev);
+ info->lo_offset = lo->lo_offset;
+ info->lo_sizelimit = lo->lo_sizelimit;
+ info->lo_flags = lo->lo_flags;
+Index: linux-2.6.0-test5/drivers/block/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/Makefile 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/block/Makefile 2003-09-27 11:38:20.836360776 +0800
+@@ -18,6 +18,7 @@
+ obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o
+ obj-$(CONFIG_IOSCHED_AS) += as-iosched.o
+ obj-$(CONFIG_IOSCHED_DEADLINE) += deadline-iosched.o
++obj-$(CONFIG_IOSCHED_CFQ) += cfq-iosched.o
+ obj-$(CONFIG_MAC_FLOPPY) += swim3.o
+ obj-$(CONFIG_BLK_DEV_FD) += floppy.o
+ obj-$(CONFIG_BLK_DEV_FD98) += floppy98.o
+Index: linux-2.6.0-test5/drivers/block/ps2esdi.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/ps2esdi.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/block/ps2esdi.c 2003-09-27 11:38:20.844359560 +0800
+@@ -62,8 +62,6 @@
+
+ static void reset_ctrl(void);
+
+-int ps2esdi_init(void);
+-
+ static int ps2esdi_geninit(void);
+
+ static void do_ps2esdi_request(request_queue_t * q);
+@@ -141,7 +139,7 @@
+ static struct gendisk *ps2esdi_gendisk[2];
+
+ /* initialization routine called by ll_rw_blk.c */
+-int __init ps2esdi_init(void)
++static int __init ps2esdi_init(void)
+ {
+
+ int error = 0;
+@@ -169,9 +167,11 @@
+ return 0;
+ } /* ps2esdi_init */
+
++#ifndef MODULE
++
+ module_init(ps2esdi_init);
+
+-#ifdef MODULE
++#else
+
+ static int cyl[MAX_HD] = {-1,-1};
+ static int head[MAX_HD] = {-1, -1};
+@@ -187,7 +187,7 @@
+ int drive;
+
+ for(drive = 0; drive < MAX_HD; drive++) {
+- struct ps2_esdi_i_struct *info = &ps2esdi_info[drive];
++ struct ps2esdi_i_struct *info = &ps2esdi_info[drive];
+
+ if (cyl[drive] != -1) {
+ info->cyl = info->lzone = cyl[drive];
+@@ -204,6 +204,7 @@
+
+ void
+ cleanup_module(void) {
++ int i;
+ if(ps2esdi_slot) {
+ mca_mark_as_unused(ps2esdi_slot);
+ mca_set_adapter_procfn(ps2esdi_slot, NULL, NULL);
+@@ -421,6 +422,7 @@
+ disk->major = PS2ESDI_MAJOR;
+ disk->first_minor = i<<6;
+ sprintf(disk->disk_name, "ed%c", 'a'+i);
++ sprintf(disk->devfs_name, "ed/target%d", i);
+ disk->fops = &ps2esdi_fops;
+ ps2esdi_gendisk[i] = disk;
+ }
+Index: linux-2.6.0-test5/drivers/block/rd.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/rd.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/block/rd.c 2003-09-27 11:38:20.848358952 +0800
+@@ -1,15 +1,15 @@
+ /*
+ * ramdisk.c - Multiple RAM disk driver - gzip-loading version - v. 0.8 beta.
+- *
+- * (C) Chad Page, Theodore Ts'o, et. al, 1995.
++ *
++ * (C) Chad Page, Theodore Ts'o, et. al, 1995.
+ *
+ * This RAM disk is designed to have filesystems created on it and mounted
+- * just like a regular floppy disk.
+- *
++ * just like a regular floppy disk.
++ *
+ * It also does something suggested by Linus: use the buffer cache as the
+ * RAM disk data. This makes it possible to dynamically allocate the RAM disk
+- * buffer - with some consequences I have to deal with as I write this.
+- *
++ * buffer - with some consequences I have to deal with as I write this.
++ *
+ * This code is based on the original ramdisk.c, written mostly by
+ * Theodore Ts'o (TYT) in 1991. The code was largely rewritten by
+ * Chad Page to use the buffer cache to store the RAM disk data in
+@@ -33,7 +33,7 @@
+ *
+ * Added initrd: Werner Almesberger & Hans Lermen, Feb '96
+ *
+- * 4/25/96 : Made RAM disk size a parameter (default is now 4 MB)
++ * 4/25/96 : Made RAM disk size a parameter (default is now 4 MB)
+ * - Chad Page
+ *
+ * Add support for fs images split across >1 disk, Paul Gortmaker, Mar '98
+@@ -60,7 +60,7 @@
+ #include <asm/uaccess.h>
+
+ /* The RAM disk size is now a parameter */
+-#define NUM_RAMDISKS 16 /* This cannot be overridden (yet) */
++#define NUM_RAMDISKS 16 /* This cannot be overridden (yet) */
+
+ /* Various static variables go here. Most are used only in the RAM disk code.
+ */
+@@ -73,7 +73,7 @@
+ * Parameters for the boot-loading of the RAM disk. These are set by
+ * init/main.c (from arguments to the kernel command line) or from the
+ * architecture-specific setup routine (from the stored boot sector
+- * information).
++ * information).
+ */
+ int rd_size = CONFIG_BLK_DEV_RAM_SIZE; /* Size of the RAM disks */
+ /*
+@@ -94,7 +94,7 @@
+ * 2000 Transmeta Corp.
+ * aops copied from ramfs.
+ */
+-static int ramdisk_readpage(struct file *file, struct page * page)
++static int ramdisk_readpage(struct file *file, struct page *page)
+ {
+ if (!PageUptodate(page)) {
+ void *kaddr = kmap_atomic(page, KM_USER0);
+@@ -108,7 +108,8 @@
+ return 0;
+ }
+
+-static int ramdisk_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
++static int ramdisk_prepare_write(struct file *file, struct page *page,
++ unsigned offset, unsigned to)
+ {
+ if (!PageUptodate(page)) {
+ void *kaddr = kmap_atomic(page, KM_USER0);
+@@ -122,7 +123,8 @@
+ return 0;
+ }
+
+-static int ramdisk_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to)
++static int ramdisk_commit_write(struct file *file, struct page *page,
++ unsigned offset, unsigned to)
+ {
+ return 0;
+ }
+@@ -212,7 +214,7 @@
+ * 19-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Added devfs support
+ *
+ */
+-static int rd_make_request(request_queue_t * q, struct bio *bio)
++static int rd_make_request(request_queue_t *q, struct bio *bio)
+ {
+ struct block_device *bdev = bio->bi_bdev;
+ struct address_space * mapping = bdev->bd_inode->i_mapping;
+@@ -242,7 +244,8 @@
+ return 0;
+ }
+
+-static int rd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
++static int rd_ioctl(struct inode *inode, struct file *file,
++ unsigned int cmd, unsigned long arg)
+ {
+ int error;
+ struct block_device *bdev = inode->i_bdev;
+@@ -250,9 +253,11 @@
+ if (cmd != BLKFLSBUF)
+ return -EINVAL;
+
+- /* special: we want to release the ramdisk memory,
+- it's not like with the other blockdevices where
+- this ioctl only flushes away the buffer cache. */
++ /*
++ * special: we want to release the ramdisk memory, it's not like with
++ * the other blockdevices where this ioctl only flushes away the buffer
++ * cache
++ */
+ error = -EBUSY;
+ down(&bdev->bd_sem);
+ if (bdev->bd_openers <= 2) {
+@@ -268,7 +273,7 @@
+ .memory_backed = 1, /* Does not contribute to dirty memory */
+ };
+
+-static int rd_open(struct inode * inode, struct file * filp)
++static int rd_open(struct inode *inode, struct file *filp)
+ {
+ unsigned unit = iminor(inode);
+
+@@ -295,12 +300,14 @@
+ .ioctl = rd_ioctl,
+ };
+
+-/* Before freeing the module, invalidate all of the protected buffers! */
+-static void __exit rd_cleanup (void)
++/*
++ * Before freeing the module, invalidate all of the protected buffers!
++ */
++static void __exit rd_cleanup(void)
+ {
+ int i;
+
+- for (i = 0 ; i < NUM_RAMDISKS; i++) {
++ for (i = 0; i < NUM_RAMDISKS; i++) {
+ struct block_device *bdev = rd_bdev[i];
+ rd_bdev[i] = NULL;
+ if (bdev) {
+@@ -311,17 +318,19 @@
+ put_disk(rd_disks[i]);
+ }
+ devfs_remove("rd");
+- unregister_blkdev(RAMDISK_MAJOR, "ramdisk" );
++ unregister_blkdev(RAMDISK_MAJOR, "ramdisk");
+ }
+
+-/* This is the registration and initialization section of the RAM disk driver */
+-static int __init rd_init (void)
++/*
++ * This is the registration and initialization section of the RAM disk driver
++ */
++static int __init rd_init(void)
+ {
+ int i;
+ int err = -ENOMEM;
+
+ if (rd_blocksize > PAGE_SIZE || rd_blocksize < 512 ||
+- (rd_blocksize & (rd_blocksize-1))) {
++ (rd_blocksize & (rd_blocksize-1))) {
+ printk("RAMDISK: wrong blocksize %d, reverting to defaults\n",
+ rd_blocksize);
+ rd_blocksize = BLOCK_SIZE;
+@@ -362,8 +371,8 @@
+
+ /* rd_size is given in kB */
+ printk("RAMDISK driver initialized: "
+- "%d RAM disks of %dK size %d blocksize\n",
+- NUM_RAMDISKS, rd_size, rd_blocksize);
++ "%d RAM disks of %dK size %d blocksize\n",
++ NUM_RAMDISKS, rd_size, rd_blocksize);
+
+ return 0;
+ out_queue:
+Index: linux-2.6.0-test5/drivers/block/scsi_ioctl.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/scsi_ioctl.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/block/scsi_ioctl.c 2003-09-27 11:38:20.852358344 +0800
+@@ -319,7 +319,7 @@
+ return -EFAULT;
+ if (in_len > PAGE_SIZE || out_len > PAGE_SIZE)
+ return -EINVAL;
+- if (get_user(opcode, sic->data))
++ if (get_user(opcode, (int *)sic->data))
+ return -EFAULT;
+
+ bytes = max(in_len, out_len);
+Index: linux-2.6.0-test5/drivers/block/umem.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/umem.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/block/umem.c 2003-09-27 11:38:20.861356976 +0800
+@@ -52,7 +52,6 @@
+
+ #include <linux/fcntl.h> /* O_ACCMODE */
+ #include <linux/hdreg.h> /* HDIO_GETGEO */
+-#include <linux/devfs_fs_kernel.h>
+
+ #include <linux/umem.h>
+
+@@ -1204,11 +1203,10 @@
+ goto out;
+ }
+
+- devfs_mk_dir("umem");
+-
+ for (i = 0; i < num_cards; i++) {
+ struct gendisk *disk = mm_gendisk[i];
+ sprintf(disk->disk_name, "umem%c", 'a'+i);
++ sprintf(disk->devfs_name, "umem/card%d", i);
+ spin_lock_init(&cards[i].lock);
+ disk->major = major_nr;
+ disk->first_minor = i << MM_SHIFT;
+@@ -1245,7 +1243,6 @@
+ del_gendisk(mm_gendisk[i]);
+ put_disk(mm_gendisk[i]);
+ }
+- devfs_remove("umem");
+
+ pci_unregister_driver(&mm_pci_driver);
+
+Index: linux-2.6.0-test5/drivers/block/xd.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/xd.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/block/xd.c 2003-09-27 11:38:20.870355608 +0800
+@@ -45,7 +45,6 @@
+ #include <linux/ioport.h>
+ #include <linux/init.h>
+ #include <linux/wait.h>
+-#include <linux/devfs_fs_kernel.h>
+ #include <linux/blkdev.h>
+ #include <linux/blkpg.h>
+
+@@ -182,7 +181,6 @@
+ if (!xd_queue)
+ goto out1a;
+
+- devfs_mk_dir("xd");
+ if (xd_detect(&controller,&address)) {
+
+ printk("Detected a%s controller (type %d) at address %06x\n",
+@@ -213,6 +211,7 @@
+ disk->major = XT_DISK_MAJOR;
+ disk->first_minor = i<<6;
+ sprintf(disk->disk_name, "xd%c", i+'a');
++ sprintf(disk->devfs_name, "xd/target%d", i);
+ disk->fops = &xd_fops;
+ disk->private_data = p;
+ disk->queue = xd_queue;
+@@ -249,7 +248,6 @@
+ out3:
+ release_region(xd_iobase,4);
+ out2:
+- devfs_remove("xd");
+ blk_cleanup_queue(xd_queue);
+ out1a:
+ unregister_blkdev(XT_DISK_MAJOR, "xd");
+@@ -1064,7 +1062,6 @@
+ }
+ blk_cleanup_queue(xd_queue);
+ release_region(xd_iobase,4);
+- devfs_remove("xd");
+ if (xd_drives) {
+ free_irq(xd_irq, NULL);
+ free_dma(xd_dma);
+Index: linux-2.6.0-test5/drivers/block/z2ram.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/z2ram.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/block/z2ram.c 2003-09-27 11:38:20.874355000 +0800
+@@ -354,6 +354,7 @@
+ z2ram_gendisk->first_minor = 0;
+ z2ram_gendisk->fops = &z2_fops;
+ sprintf(z2ram_gendisk->disk_name, "z2ram");
++ strcpy(z2ram_gendisk->devfs_name, z2ram_gendisk->disk_name);
+
+ z2ram_gendisk->queue = z2_queue;
+ add_disk(z2ram_gendisk);
+Index: linux-2.6.0-test5/drivers/bluetooth/hci_usb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/bluetooth/hci_usb.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/bluetooth/hci_usb.c 2003-09-27 11:38:20.880354088 +0800
+@@ -302,7 +302,8 @@
+ hci_usb_bulk_rx_submit(husb);
+
+ #ifdef CONFIG_BT_USB_SCO
+- hci_usb_isoc_rx_submit(husb);
++ if (husb->isoc_iface)
++ hci_usb_isoc_rx_submit(husb);
+ #endif
+ } else {
+ clear_bit(HCI_RUNNING, &hdev->flags);
+Index: linux-2.6.0-test5/drivers/cdrom/gscd.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/cdrom/gscd.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/cdrom/gscd.c 2003-09-27 11:38:20.885353328 +0800
+@@ -965,7 +965,7 @@
+
+ gscd_queue = blk_init_queue(do_gscd_request, &gscd_lock);
+ if (!gscd_queue) {
+- ret -ENOMEM;
++ ret = -ENOMEM;
+ goto err_out3;
+ }
+
+Index: linux-2.6.0-test5/drivers/cdrom/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/cdrom/Kconfig 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/cdrom/Kconfig 2003-09-27 11:38:20.889352720 +0800
+@@ -267,7 +267,7 @@
+
+ config CDU535
+ tristate "Sony CDU535 CDROM support"
+- depends on CD_NO_IDESCSI && BROKEN_ON_SMP
++ depends on CD_NO_IDESCSI
+ ---help---
+ This is the driver for the older Sony CDU-535 and CDU-531 CD-ROM
+ drives. Please read the file <file:Documentation/cdrom/sonycd535>.
+Index: linux-2.6.0-test5/drivers/cdrom/sonycd535.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/cdrom/sonycd535.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/cdrom/sonycd535.c 2003-09-27 11:38:20.902350744 +0800
+@@ -36,6 +36,10 @@
+ * module_init & module_exit.
+ * Torben Mathiasen <tmm@image.dk>
+ *
++ * September 2003 - Fix SMP support by removing cli/sti calls.
++ * Using spinlocks with a wait_queue instead.
++ * Felipe Damasio <felipewd@terra.com.br>
++ *
+ * Things to do:
+ * - handle errors and status better, put everything into a single word
+ * - use interrupts (code mostly there, but a big hole still missing)
+@@ -340,10 +344,14 @@
+ if (sony535_irq_used <= 0) { /* poll */
+ yield();
+ } else { /* Interrupt driven */
+- cli();
++ DEFINE_WAIT(wait);
++
++ spin_lock_irq(&sonycd535_lock);
+ enable_interrupts();
+- interruptible_sleep_on(&cdu535_irq_wait);
+- sti();
++ prepare_to_wait(&cdu535_irq_wait, &wait, TASK_INTERRUPTIBLE);
++ spin_unlock_irq(&sonycd535_lock);
++ schedule();
++ finish_wait(&cdu535_irq_wait, &wait);
+ }
+ }
+
+@@ -804,14 +812,14 @@
+
+ block = req->sector;
+ nsect = req->nr_sectors;
+- if (!(req->flags & REQ_CMD))
+- continue; /* FIXME */
++ if (!blk_fs_request(req)) {
++ end_request(req, 0);
++ continue;
++ }
+ if (rq_data_dir(req) == WRITE) {
+ end_request(req, 0);
+ continue;
+ }
+- if (rq_data_dir(req) != READ)
+- panic("Unknown SONY CD cmd");
+ /*
+ * If the block address is invalid or the request goes beyond
+ * the end of the media, return an error.
+@@ -888,8 +896,10 @@
+ }
+ if (readStatus == BAD_STATUS) {
+ /* Sleep for a while, then retry */
+- current->state = TASK_INTERRUPTIBLE;
++ set_current_state(TASK_INTERRUPTIBLE);
++ spin_unlock_irq(&sonycd535_lock);
+ schedule_timeout(RETRY_FOR_BAD_STATUS*HZ/10);
++ spin_lock_irq(&sonycd535_lock);
+ }
+ #if DEBUG > 0
+ printk(CDU535_MESSAGE_NAME
+@@ -1473,7 +1483,7 @@
+ /* look for the CD-ROM, follows the procedure in the DOS driver */
+ inb(select_unit_reg);
+ /* wait for 40 18 Hz ticks (reverse-engineered from DOS driver) */
+- current->state = TASK_INTERRUPTIBLE;
++ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout((HZ+17)*40/18);
+ inb(result_reg);
+
+Index: linux-2.6.0-test5/drivers/char/agp/alpha-agp.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/agp/alpha-agp.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/agp/alpha-agp.c 2003-09-27 11:38:20.904350440 +0800
+@@ -183,7 +183,7 @@
+ alpha_bridge->dev = pdev;
+ alpha_bridge->mode = agp->capability.lw;
+
+- printk(KERN_INFO "Detected AGP on hose %d\n", agp->hose->index);
++ printk(KERN_INFO PFX "Detected AGP on hose %d\n", agp->hose->index);
+ return agp_add_bridge(alpha_bridge);
+
+ fail:
+Index: linux-2.6.0-test5/drivers/char/agp/amd64-agp.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/agp/amd64-agp.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/agp/amd64-agp.c 2003-09-27 11:38:20.909349680 +0800
+@@ -8,6 +8,7 @@
+ * work is done in the northbridge(s).
+ */
+
++#include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/pci.h>
+ #include <linux/init.h>
+@@ -252,15 +253,15 @@
+ static int not_first_call;
+ u32 pfn, c;
+ if (aper == 0) {
+- printk(KERN_ERR "No aperture\n");
++ printk(KERN_ERR PFX "No aperture\n");
+ return 0;
+ }
+ if (size < 32*1024*1024) {
+- printk(KERN_ERR "Aperture too small (%d MB)\n", size>>20);
++ printk(KERN_ERR PFX "Aperture too small (%d MB)\n", size>>20);
+ return 0;
+ }
+ if (aper + size > 0xffffffff) {
+- printk(KERN_ERR "Aperture out of bounds\n");
++ printk(KERN_ERR PFX "Aperture out of bounds\n");
+ return 0;
+ }
+ pfn = aper >> PAGE_SHIFT;
+@@ -268,7 +269,7 @@
+ if (!pfn_valid(pfn + c))
+ break;
+ if (!PageReserved(pfn_to_page(pfn + c))) {
+- printk(KERN_ERR "Aperture pointing to RAM\n");
++ printk(KERN_ERR PFX "Aperture pointing to RAM\n");
+ return 0;
+ }
+ }
+@@ -279,7 +280,7 @@
+ Maybe better to use pci_assign_resource/pci_enable_device instead trusting
+ the bridges? */
+ if (!not_first_call && request_mem_region(aper, size, "aperture") < 0) {
+- printk(KERN_ERR "Aperture conflicts with PCI mapping.\n");
++ printk(KERN_ERR PFX "Aperture conflicts with PCI mapping.\n");
+ return 0;
+ }
+
+@@ -328,7 +329,7 @@
+ pci_read_config_dword(agp, 0x10, &aper_low);
+ pci_read_config_dword(agp, 0x14, &aper_hi);
+ aper = (aper_low & ~((1<<22)-1)) | ((u64)aper_hi << 32);
+- printk(KERN_INFO "Aperture from AGP @ %Lx size %u MB\n", aper, 32 << order);
++ printk(KERN_INFO PFX "Aperture from AGP @ %Lx size %u MB\n", aper, 32 << order);
+ if (order < 0 || !aperture_valid(aper, (32*1024*1024)<<order))
+ return -1;
+
+@@ -347,17 +348,17 @@
+ while ((loop_dev = pci_find_device(PCI_VENDOR_ID_AMD, 0x1103, loop_dev))
+ != NULL) {
+ if (fix_northbridge(loop_dev, pdev, cap_ptr) < 0) {
+- printk("No usable aperture found.\n");
++ printk(KERN_INFO PFX "No usable aperture found.\n");
+ #ifdef __x86_64__
+ /* should port this to i386 */
+- printk("Consider rebooting with iommu=memaper=2 to get a good aperture.\n");
++ printk(KERN_INFO PFX "Consider rebooting with iommu=memaper=2 to get a good aperture.\n");
+ #endif
+ return -1;
+ }
+ hammers[i++] = loop_dev;
+ nr_garts = i;
+ if (i == MAX_HAMMER_GARTS) {
+- printk(KERN_INFO "Too many northbridges for AGP\n");
++ printk(KERN_INFO PFX "Too many northbridges for AGP\n");
+ return -1;
+ }
+ }
+@@ -495,14 +496,14 @@
+ int err = 0;
+ if (agp_off)
+ return -EINVAL;
+- if (pci_module_init(&agp_amd64_pci_driver) == 0) {
++ if (pci_module_init(&agp_amd64_pci_driver) > 0) {
+ struct pci_dev *dev;
+ if (!agp_try_unsupported && !agp_try_unsupported_boot) {
+- printk(KERN_INFO "No supported AGP bridge found.\n");
++ printk(KERN_INFO PFX "No supported AGP bridge found.\n");
+ #ifdef MODULE
+- printk(KERN_INFO "You can try agp_try_unsupported=1\n");
++ printk(KERN_INFO PFX "You can try agp_try_unsupported=1\n");
+ #else
+- printk(KERN_INFO "You can boot with agp=try_unsupported\n");
++ printk(KERN_INFO PFX "You can boot with agp=try_unsupported\n");
+ #endif
+ return -ENODEV;
+ }
+Index: linux-2.6.0-test5/drivers/char/agp/ati-agp.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/agp/ati-agp.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/agp/ati-agp.c 2003-09-27 11:38:20.913349072 +0800
+@@ -214,7 +214,7 @@
+ /*
+ pci_read_config_dword(agp_bridge.dev, AGP_APBASE, &temp);
+ agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+- printk(KERN_INFO "IGP320 gart_bus_addr: %x\n", agp_bridge.gart_bus_addr);
++ printk(KERN_INFO PFX "IGP320 gart_bus_addr: %x\n", agp_bridge.gart_bus_addr);
+ */
+ OUTREG32(ati_generic_private.registers, ATI_GART_FEATURE_ID, 0x60000);
+
+@@ -226,8 +226,6 @@
+ OUTREG32(ati_generic_private.registers, ATI_GART_BASE,
+ agp_bridge->gatt_bus_addr);
+
+- /* Flush the tlb */
+- OUTREG32(ati_generic_private.registers, ATI_GART_CACHE_CNTRL, 1);
+ return 0;
+ }
+
+@@ -491,7 +489,7 @@
+ agp_put_bridge(bridge);
+ }
+
+-static struct pci_device_id agp_ati_pci_table[] __initdata = {
++static struct pci_device_id agp_ati_pci_table[] = {
+ {
+ .class = (PCI_CLASS_BRIDGE_HOST << 8),
+ .class_mask = ~0,
+Index: linux-2.6.0-test5/drivers/char/agp/backend.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/agp/backend.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/agp/backend.c 2003-09-27 11:38:20.916348616 +0800
+@@ -26,7 +26,6 @@
+ * TODO:
+ * - Allocate more than order 0 pages to avoid too much linear map splitting.
+ */
+-#include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/pci.h>
+ #include <linux/init.h>
+@@ -34,6 +33,7 @@
+ #include <linux/miscdevice.h>
+ #include <linux/pm.h>
+ #include <linux/agp_backend.h>
++#include <linux/agpgart.h>
+ #include <linux/vmalloc.h>
+ #include <asm/io.h>
+ #include "agp.h"
+@@ -318,6 +318,7 @@
+ {
+ }
+
++#ifdef MODULE
+ static __init int agp_setup(char *s)
+ {
+ if (!strcmp(s,"off"))
+@@ -327,6 +328,7 @@
+ return 1;
+ }
+ __setup("agp=", agp_setup);
++#endif
+
+ MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");
+ MODULE_DESCRIPTION("AGP GART driver");
+Index: linux-2.6.0-test5/drivers/char/agp/hp-agp.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/agp/hp-agp.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/agp/hp-agp.c 2003-09-27 11:38:20.920348008 +0800
+@@ -42,6 +42,8 @@
+ /* AGP bridge need not be PCI device, but DRM thinks it is. */
+ static struct pci_dev fake_bridge_dev;
+
++static int hp_zx1_gart_found;
++
+ static struct aper_size_info_fixed hp_zx1_sizes[] =
+ {
+ {0, 0, 0}, /* filled in by hp_zx1_fetch_size() */
+@@ -386,8 +388,6 @@
+ struct agp_bridge_data *bridge;
+ int error;
+
+- printk(KERN_INFO PFX "Detected HP ZX1 AGP chipset (ioc=%lx, lba=%lx)\n", ioc_hpa, lba_hpa);
+-
+ error = hp_zx1_ioc_init(ioc_hpa, lba_hpa);
+ if (error)
+ return error;
+@@ -416,7 +416,7 @@
+
+ status = hp_acpi_csr_space(obj, &lba_hpa, &length);
+ if (ACPI_FAILURE(status))
+- return 1;
++ return AE_OK;
+
+ /* Look for an enclosing IOC scope and find its CSR space */
+ handle = obj;
+@@ -436,7 +436,7 @@
+ else {
+ printk(KERN_ERR PFX "Detected HP ZX1 "
+ "AGP LBA but no IOC.\n");
+- return status;
++ return AE_OK;
+ }
+ }
+ }
+@@ -446,22 +446,28 @@
+ } while (ACPI_SUCCESS(status));
+
+ if (hp_zx1_setup(sba_hpa + HP_ZX1_IOC_OFFSET, lba_hpa))
+- return 1;
+- return 0;
++ return AE_OK;
++
++ printk(KERN_INFO PFX "Detected HP ZX1 %s AGP chipset (ioc=%lx, lba=%lx)\n",
++ (char *) context, sba_hpa + HP_ZX1_IOC_OFFSET, lba_hpa);
++
++ hp_zx1_gart_found = 1;
++ return AE_CTRL_TERMINATE;
+ }
+
+ static int __init
+ agp_hp_init (void)
+ {
+- acpi_status status;
+
+- status = acpi_get_devices("HWP0003", zx1_gart_probe, "HWP0003 AGP LBA", NULL);
+- if (!(ACPI_SUCCESS(status))) {
+- agp_bridge->type = NOT_SUPPORTED;
+- printk(KERN_INFO PFX "Failed to initialize zx1 AGP.\n");
+- return -ENODEV;
+- }
+- return 0;
++ acpi_get_devices("HWP0003", zx1_gart_probe, "HWP0003", NULL);
++ if (hp_zx1_gart_found)
++ return 0;
++
++ acpi_get_devices("HWP0007", zx1_gart_probe, "HWP0007", NULL);
++ if (hp_zx1_gart_found)
++ return 0;
++
++ return -ENODEV;
+ }
+
+ static void __exit
+Index: linux-2.6.0-test5/drivers/char/agp/intel-agp.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/agp/intel-agp.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/agp/intel-agp.c 2003-09-27 11:38:20.931346336 +0800
+@@ -445,7 +445,7 @@
+ num_entries = A_SIZE_FIX(temp)->num_entries;
+
+ if (pg_start < intel_i830_private.gtt_entries) {
+- printk (KERN_DEBUG "pg_start == 0x%.8lx,intel_i830_private.gtt_entries == 0x%.8x\n",
++ printk (KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_i830_private.gtt_entries == 0x%.8x\n",
+ pg_start,intel_i830_private.gtt_entries);
+
+ printk (KERN_INFO PFX "Trying to insert into local/stolen memory\n");
+Index: linux-2.6.0-test5/drivers/char/agp/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/agp/Kconfig 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/agp/Kconfig 2003-09-27 11:38:20.933346032 +0800
+@@ -80,8 +80,8 @@
+ tristate "Intel 440LX/BX/GX, I8xx and E7x05 chipset support"
+ depends on AGP && X86 && !X86_64
+ help
+- This option gives you AGP support for the GLX component of
+- XFree86 4.x on Intel 440LX/BX/GX, 815, 820, 830, 840, 845, 850, 860
++ This option gives you AGP support for the GLX component of XFree86 4.x
++ on Intel 440LX/BX/GX, 815, 820, 830, 840, 845, 850, 860, 875,
+ E7205 and E7505 chipsets and full support for the 810, 815, 830M, 845G,
+ 852GM, 855GM and 865G integrated graphics chipsets.
+
+Index: linux-2.6.0-test5/drivers/char/agp/nvidia-agp.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/agp/nvidia-agp.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/agp/nvidia-agp.c 2003-09-27 11:38:20.937345424 +0800
+@@ -196,7 +196,7 @@
+ pci_read_config_dword(nvidia_private.dev_1,
+ NVIDIA_1_WBC, &wbc_reg);
+ if ((signed)(end - jiffies) <= 0) {
+- printk(KERN_ERR
++ printk(KERN_ERR PFX
+ "TLB flush took more than 3 seconds.\n");
+ }
+ } while (wbc_reg & nvidia_private.wbc_mask);
+Index: linux-2.6.0-test5/drivers/char/agp/sis-agp.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/agp/sis-agp.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/agp/sis-agp.c 2003-09-27 11:38:20.939345120 +0800
+@@ -215,7 +215,7 @@
+ agp_put_bridge(bridge);
+ }
+
+-static struct pci_device_id agp_sis_pci_table[] __initdata = {
++static struct pci_device_id agp_sis_pci_table[] = {
+ {
+ .class = (PCI_CLASS_BRIDGE_HOST << 8),
+ .class_mask = ~0,
+Index: linux-2.6.0-test5/drivers/char/agp/uninorth-agp.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/agp/uninorth-agp.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/agp/uninorth-agp.c 2003-09-27 11:38:20.943344512 +0800
+@@ -350,7 +350,7 @@
+ agp_put_bridge(bridge);
+ }
+
+-static struct pci_device_id agp_uninorth_pci_table[] __initdata = {
++static struct pci_device_id agp_uninorth_pci_table[] = {
+ {
+ .class = (PCI_CLASS_BRIDGE_HOST << 8),
+ .class_mask = ~0,
+Index: linux-2.6.0-test5/drivers/char/agp/via-agp.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/agp/via-agp.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/agp/via-agp.c 2003-09-27 11:38:20.946344056 +0800
+@@ -432,7 +432,7 @@
+ agp_put_bridge(bridge);
+ }
+
+-static struct pci_device_id agp_via_pci_table[] __initdata = {
++static struct pci_device_id agp_via_pci_table[] = {
+ {
+ .class = (PCI_CLASS_BRIDGE_HOST << 8),
+ .class_mask = ~0,
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/dgap_conf.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/dgap_conf.h 2003-09-27 11:38:18.448723752 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/dgap_conf.h 2003-09-27 11:38:20.947343904 +0800
+@@ -0,0 +1,283 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ * Scott H Kilau <Scott_Kilau at digi dot com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2, or (at your option)
++ * any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
++ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
++ * PURPOSE. See the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ *****************************************************************************
++ *
++ * dgap_conf.h - Header file for installations and parse files.
++ *
++ * $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++ *
++ * NOTE: THIS IS A SHARED HEADER. DO NOT CHANGE CODING STYLE!!!
++ */
++
++#ifndef _DGAP_CONF_H
++#define _DGAP_CONF_H
++
++#define NULLNODE 0 /* header node, not used */
++#define BNODE 1 /* Board node */
++#define LNODE 2 /* Line node */
++#define CNODE 3 /* Concentrator node */
++#define MNODE 4 /* EBI Module node */
++#define TNODE 5 /* tty name prefix node */
++#define CUNODE 6 /* cu name prefix (non-SCO) */
++#define PNODE 7 /* trans. print prefix node */
++#define JNODE 8 /* maJor number node */
++#define ANODE 9 /* altpin */
++#define TSNODE 10 /* tty structure size */
++#define CSNODE 11 /* channel structure size */
++#define BSNODE 12 /* board structure size */
++#define USNODE 13 /* unit schedule structure size */
++#define FSNODE 14 /* f2200 structure size */
++#define VSNODE 15 /* size of VPIX structures */
++#define INTRNODE 16 /* enable interrupt */
++
++/* Enumeration of tokens */
++#define BEGIN 1
++#define END 2
++#define BOARD 10
++
++#define EPCFS 11 /* start of EPC family definitions */
++#define ICX 11
++#define MCX 13
++#define PCX 14
++#define IEPC 15
++#define EEPC 16
++#define MEPC 17
++#define IPCM 18
++#define EPCM 19
++#define MPCM 20
++#define PEPC 21
++#define PPCM 22
++#ifdef CP
++#define ICP 23
++#define ECP 24
++#define MCP 25
++#endif
++#define EPCFE 25 /* end of EPC family definitions */
++#define PC2E 26
++#define PC4E 27
++#define PC4E8K 28
++#define PC8E 29
++#define PC8E8K 30
++#define PC16E 31
++#define MC2E8K 34
++#define MC4E8K 35
++#define MC8E8K 36
++
++#define AVANFS 42 /* start of Avanstar family definitions */
++#define A8P 42
++#define A16P 43
++#define AVANFE 43 /* end of Avanstar family definitions */
++
++#define DA2000FS 44 /* start of AccelePort 2000 family definitions */
++#define DA22 44 /* AccelePort 2002 */
++#define DA24 45 /* AccelePort 2004 */
++#define DA28 46 /* AccelePort 2008 */
++#define DA216 47 /* AccelePort 2016 */
++#define DAR4 48 /* AccelePort RAS 4 port */
++#define DAR8 49 /* AccelePort RAS 8 port */
++#define DDR24 50 /* DataFire RAS 24 port */
++#define DDR30 51 /* DataFire RAS 30 port */
++#define DDR48 52 /* DataFire RAS 48 port */
++#define DDR60 53 /* DataFire RAS 60 port */
++#define DA2000FE 53 /* end of AccelePort 2000/RAS family definitions */
++
++#define PCXRFS 106 /* start of PCXR family definitions */
++#define APORT4 106
++#define APORT8 107
++#define PAPORT4 108
++#define PAPORT8 109
++#define APORT4_920I 110
++#define APORT8_920I 111
++#define APORT4_920P 112
++#define APORT8_920P 113
++#define APORT2_920P 114
++#define PCXRFE 117 /* end of PCXR family definitions */
++
++#define LINE 82
++#ifdef T1
++#define T1M 83
++#define E1M 84
++#endif
++#define CONC 64
++#define CX 65
++#define EPC 66
++#define MOD 67
++#define PORTS 68
++#define METHOD 69
++#define CUSTOM 70
++#define BASIC 71
++#define STATUS 72
++#define MODEM 73
++/* The following tokens can appear in multiple places */
++#define SPEED 74
++#define NPORTS 75
++#define ID 76
++#define CABLE 77
++#define CONNECT 78
++#define IO 79
++#define MEM 80
++#define DPSZ 81
++
++#define TTYN 90
++#define CU 91
++#define PRINT 92
++#define XPRINT 93
++#define CMAJOR 94
++#define ALTPIN 95
++#define STARTO 96
++#define USEINTR 97
++
++#define TTSIZ 100
++#define CHSIZ 101
++#define BSSIZ 102
++#define UNTSIZ 103
++#define F2SIZ 104
++#define VPSIZ 105
++
++#define TOTAL_BOARD 2
++#define CURRENT_BRD 4
++#define BOARD_TYPE 6
++#define IO_ADDRESS 8
++#define MEM_ADDRESS 10
++
++#define FIELDS_PER_PAGE 18
++
++#define TB_FIELD 1
++#define CB_FIELD 3
++#define BT_FIELD 5
++#define IO_FIELD 7
++#define ID_FIELD 8
++#define ME_FIELD 9
++#define TTY_FIELD 11
++#define CU_FIELD 13
++#define PR_FIELD 15
++#define MPR_FIELD 17
++
++#define MAX_FIELD 512
++
++#define INIT 0
++#define NITEMS 128
++#define MAX_ITEM 512
++
++#define DSCRINST 1
++#define DSCRNUM 3
++#define ALTPINQ 5
++#define SSAVE 7
++
++#define DSCR "32"
++#define ONETONINE "123456789"
++#define ALL "1234567890"
++
++
++struct cnode {
++ struct cnode *next;
++ int type;
++ int numbrd;
++
++ union {
++ struct {
++ char type; /* Board Type */
++ short port; /* I/O Address */
++ char *portstr; /* I/O Address in string */
++ long addr; /* Memory Address */
++ char *addrstr; /* Memory Address in string */
++ char nport; /* Number of Ports */
++ char *id; /* tty id */
++ int start; /* start of tty counting */
++ char *method; /* Install method */
++ char v_type;
++ char v_port;
++ char v_addr;
++ char v_nport;
++ char v_id;
++ char v_start;
++ char v_method;
++ char line1;
++ char line2;
++ char conc1; /* total concs in line1 */
++ char conc2; /* total concs in line2 */
++ char module1; /* total modules for line1 */
++ char module2; /* total modules for line2 */
++ char *status; /* config status */
++ char *dimstatus; /* Y/N */
++ int status_index; /* field pointer */
++ } board;
++
++ struct {
++ char *cable;
++ char v_cable;
++ char speed;
++ char v_speed;
++ } line;
++
++ struct {
++ char type;
++ char *connect;
++ char speed;
++ char nport;
++ char *id;
++ char *idstr;
++ int start;
++ char v_type;
++ char v_connect;
++ char v_speed;
++ char v_nport;
++ char v_id;
++ char v_start;
++ } conc;
++
++ struct {
++ char type;
++ char nport;
++ char *id;
++ char *idstr;
++ int start;
++ char v_type;
++ char v_nport;
++ char v_id;
++ char v_start;
++ } module;
++
++ char *ttyname;
++
++ char *cuname;
++
++ char *printname;
++
++ int majornumber;
++
++ int altpin;
++
++ int ttysize;
++
++ int chsize;
++
++ int bssize;
++
++ int unsize;
++
++ int f2size;
++
++ int vpixsize;
++
++ int useintr;
++ } u;
++};
++
++#endif
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/dgap_downld.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/dgap_downld.h 2003-09-27 11:38:18.448723752 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/dgap_downld.h 2003-09-27 11:38:20.947343904 +0800
+@@ -0,0 +1,69 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ * Scott H Kilau <Scott_Kilau at digi dot com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2, or (at your option)
++ * any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
++ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
++ * PURPOSE. See the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++ *
++ * NOTE: THIS IS A SHARED HEADER. DO NOT CHANGE CODING STYLE!!!
++ *
++ */
++
++/*
++** downld.h
++** - describes the interface between the user level download process
++** and the concentrator download driver.
++*/
++
++#ifndef _DGAP_DOWNLD_H_
++#define _DGAP_DOWNLD_H_
++
++
++struct fepimg {
++ int type; /* board type */
++ int len; /* length of image */
++ char fepimage[1]; /* begining of image */
++};
++
++struct downldio {
++ unsigned int req_type; /* FEP or concentrator */
++ unsigned int bdid; /* opaque board identifier */
++ union {
++ struct downld_t dl; /* download structure */
++ struct fepimg fi; /* fep/bios image structure */
++ } image;
++};
++
++#define DIGI_DLREQ_GET (('d'<<8) | 220)
++#define DIGI_DLREQ_SET (('d'<<8) | 221)
++
++#define DIGI_DL_NUKE (('d'<<8) | 222) /* Not really a dl request, but
++ dangerous enuff to not put in
++ digi.h */
++/* Packed bits of intarg for DIGI_DL_NUKE */
++#define DIGI_NUKE_RESET_ALL (1 << 31)
++#define DIGI_NUKE_INHIBIT_POLLER (1 << 30)
++#define DIGI_NUKE_BRD_NUMB 0x0f
++
++
++
++#define DLREQ_BIOS 0
++#define DLREQ_FEP 1
++#define DLREQ_CONC 2
++#define DLREQ_CONFIG 3
++#define DLREQ_DEVCREATE 4
++
++#endif
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/dgap_driver.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/dgap_driver.c 2003-09-27 11:38:18.448723752 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/dgap_driver.c 2003-09-27 11:38:20.950343448 +0800
+@@ -0,0 +1,1561 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ * Scott H Kilau <Scott_Kilau at digi dot com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2, or (at your option)
++ * any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
++ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
++ * PURPOSE. See the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ *
++ * NOTE TO LINUX KERNEL HACKERS: DO NOT REFORMAT THIS CODE!
++ *
++ * This is shared code between Digi's CVS archive and the
++ * Linux Kernel sources.
++ * Changing the source just for reformatting needlessly breaks
++ * our CVS diff history.
++ *
++ * Send any bug fixes/changes to: Eng.Linux at digi dot com.
++ * Thank you.
++ *
++ */
++
++char *dgap_version = "$Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $";
++
++/*
++ * Our driver specific include files.
++ */
++#include "dgap_driver.h"
++#include "dgap_proc.h"
++#include "dgap_pci.h"
++#include "dgap_fep5.h"
++#include "dgap_tty.h"
++#include "dgap_conf.h"
++#include "dgap_parse.h"
++#include "dgap_mgmt.h"
++
++
++/*
++ * Because this driver is supported on older versions of Linux
++ * as well, lets be safe, and just make sure on this one.
++ */
++#if defined(MODULE_LICENSE)
++ MODULE_LICENSE("GPL");
++#endif
++
++MODULE_AUTHOR("Digi International, http://www.digi.com");
++MODULE_DESCRIPTION("Driver for the Digi International EPCA PCI based product line");
++MODULE_SUPPORTED_DEVICE("dgap");
++
++/*
++ * insmod command line overrideable parameters
++ *
++ * NOTE: we use a set of macros to create the variables, which allows
++ * us to specify the variable type, name, initial value, and description.
++ */
++PARM_INT(debug, 0x00, "Driver debugging level");
++PARM_INT(rawreadok, 1, "Bypass flip buffers on input");
++PARM_INT(trcbuf_size, 0x100000, "Debugging trace buffer size. 1M default.");
++
++/*
++ * A generic list of Product names, PCI Vendor ID, and PCI Device ID.
++ */
++struct board_id {
++ uint config_type;
++ uchar *name;
++ u16 vendor;
++ u16 device;
++ uint maxports;
++ u16 dpatype;
++};
++
++static struct board_id Ids[] =
++{
++ { PPCM, PCI_DEVICE_XEM_NAME, DIGI_VID,
++ PCI_DEVICE_XEM_DID, 64, (T_PCXM | T_PCLITE | T_PCIBUS) },
++
++ { PCX, PCI_DEVICE_CX_NAME, DIGI_VID,
++ PCI_DEVICE_CX_DID, 128, (T_CX | T_PCIBUS) },
++
++ { PCX, PCI_DEVICE_CX_IBM_NAME, DIGI_VID,
++ PCI_DEVICE_CX_IBM_DID,128, (T_CX | T_PCIBUS) },
++
++ { PEPC, PCI_DEVICE_EPCJ_NAME, DIGI_VID,
++ PCI_DEVICE_EPCJ_DID, 224, (T_EPC | T_PCIBUS) },
++
++ { APORT2_920P, PCI_DEVICE_920_2_NAME, DIGI_VID,
++ PCI_DEVICE_920_2_DID, 2, (T_PCXR | T_PCLITE | T_PCIBUS) },
++
++ { APORT4_920P, PCI_DEVICE_920_4_NAME, DIGI_VID,
++ PCI_DEVICE_920_4_DID, 4, (T_PCXR | T_PCLITE | T_PCIBUS) },
++
++ { APORT8_920P, PCI_DEVICE_920_8_NAME, DIGI_VID,
++ PCI_DEVICE_920_8_DID, 8, (T_PCXR | T_PCLITE | T_PCIBUS) },
++
++ { PAPORT8, PCI_DEVICE_XR_NAME, DIGI_VID,
++ PCI_DEVICE_XR_DID, 8, (T_PCXR | T_PCLITE | T_PCIBUS) },
++
++ { PAPORT8, PCI_DEVICE_XRJ_NAME, DIGI_VID,
++ PCI_DEVICE_XRJ_DID, 8, (T_PCXR | T_PCLITE | T_PCIBUS) },
++
++ { PAPORT8, PCI_DEVICE_XR_422_NAME, DIGI_VID,
++ PCI_DEVICE_XR_422_DID,8, (T_PCXR | T_PCLITE | T_PCIBUS) },
++
++ { PAPORT8, PCI_DEVICE_XR_IBM_NAME, DIGI_VID,
++ PCI_DEVICE_XR_IBM_DID, 8, (T_PCXR | T_PCLITE | T_PCIBUS) },
++
++};
++#define NIDS (sizeof(Ids)/sizeof(struct board_id))
++
++
++char *dgap_state_text[] = {
++ "Board Failed",
++ "Configuration for board not found.\n\t\t\t Use /usr/bin/dgap_config to configure board.",
++ "Board Found",
++ "Need Reset",
++ "Finished Reset",
++ "Need Config",
++ "Finished Config",
++ "Need Device Creation",
++ "Requested Device Creation",
++ "Finished Device Creation",
++ "Need BIOS Load",
++ "Requested BIOS",
++ "Doing BIOS Load",
++ "Finished BIOS Load",
++ "Need FEP Load",
++ "Requested FEP",
++ "Doing FEP Load",
++ "Finished FEP Load",
++ "Board READY",
++};
++
++char *dgap_driver_state_text[] = {
++ "Driver Initialized",
++ "Driver needs configuration load.",
++ "Driver requested configuration from download daemon.",
++ "Driver Ready."
++};
++
++
++/**************************************************************************
++ *
++ * protos for this file
++ *
++ */
++
++/* Driver load/unload functions */
++int dgap_init_module(void);
++void dgap_cleanup_module(void);
++int dgap_start(void);
++int dgap_finalize_board_init(struct board_t *brd);
++
++static void dgap_init_globals(void);
++static int dgap_scan(void);
++static int dgap_found_board(struct pci_dev *pdev, int id);
++static void dgap_cleanup_board(struct board_t *brd);
++static void dgap_poll_handler(ulong dummy);
++
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++
++static irqreturn_t dgap_intr(int irq, void *voidbrd, struct pt_regs *regs);
++module_init(dgap_init_module);
++module_exit(dgap_cleanup_module);
++
++#else
++
++static void dgap_intr(int irq, void *voidbrd, struct pt_regs *regs);
++/*
++ * Older 2.4 kernels do not support module_init/exit calls.
++ * So we do it this way for now.
++ */
++int init_module(void);
++void cleanup_module(void);
++#define dgap_init_module init_module
++#define dgap_cleanup_module cleanup_module
++
++#endif
++
++
++/*
++ * File operations permitted on Control/Management major.
++ */
++static struct file_operations BoardFops =
++{
++ owner: THIS_MODULE,
++ read: NULL,
++ write: NULL,
++ ioctl: dgap_mgmt_ioctl,
++ mmap: NULL,
++ open: dgap_mgmt_open,
++ release: dgap_mgmt_close
++};
++
++
++/*
++ * Statics/Globals
++ */
++struct board_t *dgap_Board[MAXBOARDS];
++uchar dgap_NumBoards;
++spinlock_t dgap_global_lock = SPIN_LOCK_UNLOCKED;
++ulong dgap_poll_counter = 0;
++static int dgap_Major_Control_Registered = FALSE;
++int dgap_driver_state = DRIVER_INITIALIZED;
++
++spinlock_t dgap_dl_lock = SPIN_LOCK_UNLOCKED;
++wait_queue_head_t dgap_dl_wait;
++int dgap_dl_action;
++
++/* Poller stuff */
++static spinlock_t dgap_poll_lock = SPIN_LOCK_UNLOCKED; /* Poll scheduling lock */
++static ulong dgap_poll_time; /* Time of next poll */
++static ulong dgap_poll_tick = 20; /* Poll interval - 20 ms */
++static struct timer_list dgap_poll_timer = { function: dgap_poll_handler };
++
++static char *dgap_config_buf; /* The config file buffer */
++
++
++/************************************************************************
++ *
++ * Driver load/unload functions
++ *
++ ************************************************************************/
++
++/*
++ * init_module()
++ *
++ * Module load. This is where it all starts.
++ */
++int dgap_init_module(void)
++{
++ APR(("%s, Digi International Part Number %s\n", DG_NAME, DG_PART));
++ return dgap_start();
++}
++
++
++/*
++ * Start of driver.
++ */
++int dgap_start(void)
++{
++ int rc = 0;
++ unsigned long flags;
++
++ /* make sure that the globals are init'd before we do anything else */
++ dgap_init_globals();
++
++ dgap_NumBoards = 0;
++
++ APR(("For the tools package or updated drivers please visit http://www.digi.com\n"));
++
++ /*
++ * Register our base character device into the kernel.
++ * This allows the download daemon to connect to the downld device
++ * before any of the boards are init'ed.
++ */
++ if (!dgap_Major_Control_Registered) {
++ /*
++ * Register management/dpa devices
++ */
++ rc = register_chrdev(DIGI_DGAP_MAJOR, "dgap", &BoardFops);
++ if (rc < 0) {
++ APR(("Can't register dgap driver device (%d)\n", rc));
++ return (rc);
++ }
++ dgap_Major_Control_Registered = TRUE;
++ }
++
++ /*
++ * Register our basic stuff in /proc/dgap
++ */
++ dgap_proc_register_basic_prescan();
++
++ /*
++ * Init any global tty stuff.
++ */
++ dgap_tty_preinit();
++
++ /*
++ * Find and configure all the cards
++ */
++ rc = dgap_scan();
++
++ /*
++ * If something went wrong in the scan, bail out of driver.
++ */
++ if (rc) {
++ dgap_cleanup_module();
++ }
++ else {
++ /* Start the poller */
++ if (dgap_NumBoards > 0) {
++ DGAP_LOCK(dgap_poll_lock, flags);
++ dgap_poll_time = jiffies + dgap_jiffies_from_ms(dgap_poll_tick);
++ dgap_poll_timer.expires = dgap_poll_time;
++ DGAP_UNLOCK(dgap_poll_lock, flags);
++
++ add_timer(&dgap_poll_timer);
++
++ }
++
++ dgap_driver_state = DRIVER_NEED_CONFIG_LOAD;
++ }
++
++ return (rc);
++}
++
++
++
++int dgap_after_config_loaded(void)
++{
++ int i = 0;
++ int rc = 0;
++
++ /*
++ * Register our ttys, now that we have the config loaded.
++ */
++ for (i = 0; i < dgap_NumBoards; ++i) {
++
++ /*
++ * Initialize KME waitqueues...
++ */
++ init_waitqueue_head(&(dgap_Board[i]->kme_wait));
++
++ /*
++ * allocate flip buffer for board.
++ */
++ dgap_Board[i]->flipbuf = dgap_driver_kzmalloc(MYFLIPLEN, GFP_ATOMIC);
++ }
++
++ dgap_proc_register_basic_postscan();
++
++ dgap_proc_register_fep();
++
++ return (rc);
++}
++
++
++
++/*
++ * dgap_cleanup_module()
++ *
++ * Module unload. This is where it all ends.
++ */
++void dgap_cleanup_module(void)
++{
++ int i;
++ ulong lock_flags;
++
++ /* Turn off poller right away. */
++ DGAP_LOCK(dgap_poll_lock, lock_flags );
++ del_timer_sync( &dgap_poll_timer );
++ DGAP_UNLOCK(dgap_poll_lock, lock_flags );
++
++ dgap_proc_unregister_all();
++
++ if (dgap_Major_Control_Registered)
++ unregister_chrdev(DIGI_DGAP_MAJOR, "dgap");
++
++ if (dgap_config_buf)
++ kfree(dgap_config_buf);
++
++ for (i = 0; i < dgap_NumBoards; ++i) {
++ dgap_tty_uninit(dgap_Board[i]);
++ dgap_cleanup_board(dgap_Board[i]);
++ }
++
++ dgap_tty_post_uninit();
++
++#if defined(DGAP_TRACER)
++ /* last thing, make sure we release the tracebuffer */
++ dgap_tracer_free();
++#endif
++}
++
++
++/*
++ * dgap_cleanup_board()
++ *
++ * Free all the memory associated with a board
++ */
++static void dgap_cleanup_board(struct board_t *brd)
++{
++ int i = 0;
++
++ if(!brd || brd->magic != DGAP_BOARD_MAGIC)
++ return;
++
++ if (brd->intr_used && brd->irq)
++ free_irq(brd->irq, brd);
++
++ tasklet_kill(&brd->helper_tasklet);
++
++ if (brd->re_map_port) {
++ DGAP_IOUNMAP(brd->re_map_port);
++ brd->re_map_port = 0;
++ }
++
++ if (brd->re_map_membase) {
++ DGAP_IOUNMAP(brd->re_map_membase);
++ brd->re_map_membase = 0;
++ }
++
++ if (brd->msgbuf_head) {
++ unsigned long flags;
++
++ DGAP_LOCK(dgap_global_lock, flags);
++ brd->msgbuf = NULL;
++ printk(brd->msgbuf_head);
++ DGAP_VFREE(brd->msgbuf_head);
++ brd->msgbuf_head = NULL;
++ DGAP_UNLOCK(dgap_global_lock, flags);
++ }
++
++ /* Free all allocated channels structs */
++ for (i = 0; i < MAXPORTS ; i++) {
++ if (brd->channels[i]) {
++ kfree(brd->channels[i]);
++ brd->channels[i] = NULL;
++ }
++ }
++
++ if (brd->flipbuf)
++ kfree(brd->flipbuf);
++
++ dgap_Board[brd->boardnum] = NULL;
++
++ DGAP_VFREE(brd);
++}
++
++
++/*
++ * dgap_init_globals()
++ *
++ * This is where we initialize the globals from the static insmod
++ * configuration variables. These are declared near the head of
++ * this file.
++ */
++static void dgap_init_globals(void)
++{
++ int i = 0;
++
++ dgap_rawreadok = rawreadok;
++ dgap_trcbuf_size = trcbuf_size;
++ dgap_debug = debug;
++
++ for (i = 0; i < MAXBOARDS; i++) {
++ dgap_Board[i] = NULL;
++ }
++
++ init_timer( &dgap_poll_timer );
++
++ init_waitqueue_head(&dgap_dl_wait);
++ dgap_dl_action = 0;
++}
++
++
++/*
++ * dgap_ioctl_name() : Returns a text version of each ioctl value.
++ */
++char *dgap_ioctl_name(int cmd)
++{
++ switch(cmd) {
++
++ case TCGETA: return("TCGETA");
++ case TCGETS: return("TCGETS");
++ case TCSETA: return("TCSETA");
++ case TCSETS: return("TCSETS");
++ case TCSETAW: return("TCSETAW");
++ case TCSETSW: return("TCSETSW");
++ case TCSETAF: return("TCSETAF");
++ case TCSETSF: return("TCSETSF");
++ case TCSBRK: return("TCSBRK");
++ case TCXONC: return("TCXONC");
++ case TCFLSH: return("TCFLSH");
++ case TIOCGSID: return("TIOCGSID");
++
++ case TIOCGETD: return("TIOCGETD");
++ case TIOCSETD: return("TIOCSETD");
++ case TIOCGWINSZ: return("TIOCGWINSZ");
++ case TIOCSWINSZ: return("TIOCSWINSZ");
++
++ case TIOCMGET: return("TIOCMGET");
++ case TIOCMSET: return("TIOCMSET");
++ case TIOCMBIS: return("TIOCMBIS");
++ case TIOCMBIC: return("TIOCMBIC");
++
++ /* from digi.h */
++ case DIGI_SETA: return("DIGI_SETA");
++ case DIGI_SETAW: return("DIGI_SETAW");
++ case DIGI_SETAF: return("DIGI_SETAF");
++ case DIGI_SETFLOW: return("DIGI_SETFLOW");
++ case DIGI_SETAFLOW: return("DIGI_SETAFLOW");
++ case DIGI_GETFLOW: return("DIGI_GETFLOW");
++ case DIGI_GETAFLOW: return("DIGI_GETAFLOW");
++ case DIGI_GETA: return("DIGI_GETA");
++ case DIGI_GEDELAY: return("DIGI_GEDELAY");
++ case DIGI_SEDELAY: return("DIGI_SEDELAY");
++#if 0
++ case DIGI_GETCUSTOMBAUD: return("DIGI_GETCUSTOMBAUD");
++ case DIGI_SETCUSTOMBAUD: return("DIGI_SETCUSTOMBAUD");
++#endif
++ case TIOCMODG: return("TIOCMODG");
++ case TIOCMODS: return("TIOCMODS");
++ case TIOCSDTR: return("TIOCSDTR");
++ case TIOCCDTR: return("TIOCCDTR");
++
++ default: return("unknown");
++ }
++}
++
++
++
++void dgap_do_config_load(uchar *uaddr, int len)
++{
++ int orig_len = len;
++ char *to_addr;
++ char *from_addr = uaddr;
++ static char buf[U2BSIZE];
++ int n;
++
++ to_addr = dgap_config_buf = dgap_driver_kzmalloc(len + 1, GFP_ATOMIC);
++ if (!dgap_config_buf) {
++ DPR_INIT(("dgap_do_config_load - unable to allocate memory for file\n"));
++ dgap_driver_state = DRIVER_NEED_CONFIG_LOAD;
++ return;
++ }
++
++ n = U2BSIZE;
++ while (len) {
++
++ if (n > len)
++ n = len;
++
++ if (copy_from_user((char *) &buf, from_addr, n) == -1 ) {
++ /* TODO, SOMETHING SANE */
++ return;
++ }
++
++ /* Copy data from buffer to kernel memory */
++ memcpy(to_addr, buf, n);
++
++ /* increment counts */
++ len -= n;
++ to_addr += n;
++ from_addr += n;
++ n = U2BSIZE;
++ }
++
++ dgap_config_buf[orig_len] = '\0';
++
++ to_addr = dgap_config_buf;
++ dgap_parsefile(&to_addr, TRUE);
++
++ DPR_INIT(("dgap_config_load() finish\n"));
++
++ return;
++}
++
++
++/*
++ * Remap PCI memory.
++ */
++static void dgap_do_remap(struct board_t *brd)
++{
++
++ if (!brd || brd->magic != DGAP_BOARD_MAGIC)
++ return;
++
++ brd->re_map_port = DGAP_IOREMAP((brd->membase + PCI_IO_OFFSET), 0x200000);
++ brd->re_map_membase = DGAP_IOREMAP(brd->membase, 0x200000);
++
++ DPR_INIT(("remapped io: 0x%p remapped mem: 0x%p\n",
++ brd->re_map_port, brd->re_map_membase));
++}
++
++
++/*=======================================================================
++ *
++ * usertoboard - copy from user space to board space.
++ *
++ *=======================================================================*/
++
++int dgap_usertoboard(struct board_t *brd, char *to_addr, char *from_addr, int len)
++{
++ static char buf[U2BSIZE];
++ int n = U2BSIZE;
++
++ if (!brd || brd->magic != DGAP_BOARD_MAGIC)
++ return(-EFAULT);
++
++ while (len) {
++ if (n > len)
++ n = len;
++
++ if (copy_from_user((char *) &buf, from_addr, n) == -1 ) {
++ return(-EFAULT);
++ }
++
++ /* Copy data from buffer to card memory */
++ memcpy_toio(to_addr, buf, n);
++
++ /* increment counts */
++ len -= n;
++ to_addr += n;
++ from_addr += n;
++ n = U2BSIZE;
++ }
++ return(0);
++}
++
++
++void dgap_do_bios_load(struct board_t *brd, uchar *ubios, int len)
++{
++ u32 bios;
++ uchar *addr = brd->re_map_membase;
++ int i;
++
++ if (!brd || brd->magic != DGAP_BOARD_MAGIC)
++ return;
++
++ DPR_INIT(("dgap_do_bios_load() start\n"));
++
++ /*
++ * clear POST area
++ */
++ for (i = 0; i < 16; i++)
++ writeb(0, addr + POSTAREA + i);
++
++ /*
++ * Download bios
++ */
++ bios = 0x1000;
++ if (dgap_usertoboard(brd, addr + bios, ubios, len) == -1 ) {
++ brd->state = BOARD_FAILED;
++ brd->dpastatus = BD_NOFEP;
++ return;
++ }
++
++ writel(0x0bf00401, addr);
++ writel(0, (addr + 4));
++
++ /* Clear the reset, and change states. */
++ writeb(FEPCLR, brd->re_map_port);
++ brd->state = WAIT_BIOS_LOAD;
++}
++
++
++static void dgap_do_wait_for_bios(struct board_t *brd)
++{
++ uchar *addr;
++ u16 word;
++
++ if (!brd || brd->magic != DGAP_BOARD_MAGIC)
++ return;
++
++ addr = brd->re_map_membase;
++ word = readw(addr + POSTAREA);
++
++ /* Check to see if BIOS thinks board is good. (GD). */
++ if (word == *(u16 *) "GD") {
++ DPR_INIT(("GOT GD in memory, moving states.\n"));
++ brd->state = FINISHED_BIOS_LOAD;
++ return;
++ }
++
++ /* Give up on board after too long of time taken */
++ if (brd->wait_for_bios++ > 5000) {
++ u16 err1 = readw(addr + SEQUENCE);
++ u16 err2 = readw(addr + ERROR);
++ APR(("***WARNING*** %s failed diagnostics. Error #(%x,%x).\n",
++ brd->name, err1, err2));
++ brd->state = BOARD_FAILED;
++ brd->dpastatus = BD_NOFEP;
++ }
++}
++
++void dgap_do_fep_load(struct board_t *brd, uchar *ufep, int len)
++{
++ u32 fepos;
++ uchar *addr;
++
++ if (!brd || brd->magic != DGAP_BOARD_MAGIC)
++ return;
++
++ addr = brd->re_map_membase;
++
++ DPR_INIT(("dgap_do_fep_load() for board %s : start\n", brd->name));
++
++ /*
++ * Download FEP
++ */
++
++ /* TODO: don't hard code this stuff */
++ fepos = 0x1000;
++
++ if (dgap_usertoboard(brd, addr + fepos, ufep, len) == -1 ) {
++ brd->state = BOARD_FAILED;
++ brd->dpastatus = BD_NOFEP;
++ return;
++ }
++
++ /*
++ * If board is a concentrator product, we need to give
++ * it its config string describing how the concentrators look.
++ */
++ if ((brd->type == PCX) || (brd->type == PEPC)) {
++ uchar string[100];
++ uchar *config, *xconfig;
++ int i = 0;
++
++ xconfig = dgap_create_config_string(brd, string);
++
++ /* Write string to board memory */
++ config = addr + CONFIG;
++ for (; i < CONFIGSIZE; i++, config++, xconfig++) {
++ writeb(*xconfig, config);
++ if ((*xconfig & 0xff) == 0xff)
++ break;
++ }
++ }
++
++ writel(0xbfc01004, (addr + 0xc34));
++ writel(0x3, (addr + 0xc30));
++
++ /* change states. */
++ brd->state = WAIT_FEP_LOAD;
++
++ DPR_INIT(("dgap_do_fep_load() for board %s : finish\n", brd->name));
++
++}
++
++
++static void dgap_do_wait_for_fep(struct board_t *brd)
++{
++ uchar *addr;
++ u16 word;
++
++ if (!brd || brd->magic != DGAP_BOARD_MAGIC) {
++ return;
++ }
++
++ addr = brd->re_map_membase;
++
++ if (!addr) {
++ APR(("dgap_do_wait_for_fep() addr is NULL\n"));
++ brd->state = BOARD_FAILED;
++ brd->dpastatus = BD_NOFEP;
++ return;
++ }
++
++ DPR_INIT(("dgap_do_wait_for_fep() for board %s : start. addr: %p\n", brd->name, addr));
++
++ word = readw(addr + FEPSTAT);
++
++ /* Check to see if FEP is up and running now. */
++ if (word == *(u16 *) "OS") {
++ DPR_INIT(("GOT OS in memory for board %s, moving states.\n", brd->name));
++ brd->state = FINISHED_FEP_LOAD;
++ return;
++ }
++
++ /* Give up on board after too long of time taken */
++ if (brd->wait_for_fep++ > 5000) {
++ u16 err1 = readw(addr + SEQUENCE);
++ u16 err2 = readw(addr + ERROR);
++ APR(("***WARNING*** FEPOS for %s not functioning. Error #(%x,%x).\n",
++ brd->name, err1, err2));
++ brd->state = BOARD_FAILED;
++ brd->dpastatus = BD_NOFEP;
++ }
++
++ DPR_INIT(("dgap_do_wait_for_fep() for board %s : finish\n", brd->name));
++}
++
++
++static void dgap_do_reset_board(struct board_t *brd)
++{
++ uchar check;
++ u32 check1;
++ u32 check2;
++ int i = 0;
++
++ if (!brd || brd->magic != DGAP_BOARD_MAGIC)
++ return;
++
++ DPR_INIT(("dgap_do_reset_board() start\n"));
++
++ /* FEPRST does not vary among supported boards */
++ writeb(FEPRST, brd->re_map_port);
++
++ for (i = 0; i <= 1000; i++) {
++ check = readb(brd->re_map_port) & 0xe;
++ if (check == FEPRST)
++ break;
++ udelay(10);
++
++ }
++ if (i > 1000) {
++ APR(("*** WARNING *** Board not resetting... Failing board.\n"));
++ brd->state = BOARD_FAILED;
++ brd->dpastatus = BD_NOFEP;
++ goto failed;
++ }
++
++ /*
++ * Make sure there really is memory out there.
++ */
++ writel(0xa55a3cc3, (brd->re_map_membase + LOWMEM));
++ writel(0x5aa5c33c, (brd->re_map_membase + HIGHMEM));
++ check1 = readl(brd->re_map_membase + LOWMEM);
++ check2 = readl(brd->re_map_membase + HIGHMEM);
++
++ if ((check1 != 0xa55a3cc3) || (check2 != 0x5aa5c33c)) {
++ APR(("*** Warning *** No memory at %p for board.\n", brd->re_map_membase));
++ brd->state = BOARD_FAILED;
++ brd->dpastatus = BD_NOFEP;
++ goto failed;
++ }
++
++ if (brd->state != BOARD_FAILED)
++ brd->state = FINISHED_RESET;
++
++failed:
++ DPR_INIT(("dgap_do_reset_board() finish\n"));
++}
++
++
++void dgap_do_conc_load(struct board_t *brd, uchar *uaddr, int len)
++{
++ char *vaddr;
++ u16 offset = 0;
++ struct downld_t *to_dp;
++
++ if (!brd || brd->magic != DGAP_BOARD_MAGIC)
++ return;
++
++ vaddr = brd->re_map_membase;
++
++ if (!vaddr)
++ return;
++
++ offset = readw((u16 *) (vaddr + DOWNREQ));
++ to_dp = (struct downld_t *) (vaddr + (int) offset);
++
++ memcpy_toio((char *) to_dp, uaddr, sizeof(struct downld_t));
++
++ /* Tell card we have data for it */
++ writew(0, vaddr + (DOWNREQ));
++
++ brd->conc_dl_status = NO_PENDING_CONCENTRATOR_REQUESTS;
++
++}
++
++
++/*
++ * Our board poller function.
++ */
++static void poll_tasklet(unsigned long data)
++{
++ struct board_t *bd = (struct board_t *) data;
++ ulong lock_flags;
++ ulong lock_flags2;
++ u32 head, tail;
++ char *vaddr;
++ u16 *chk_addr;
++ u16 check = 0;
++
++ if (!bd || bd->magic != DGAP_BOARD_MAGIC) {
++ APR(("poll_tasklet() - NULL or bad bd.\n"));
++ return;
++ }
++
++ if (bd->inhibit_poller)
++ return;
++
++ DGAP_LOCK(bd->bd_lock, lock_flags);
++
++ vaddr = bd->re_map_membase;
++
++ /*
++ * If board is ready, parse deeper to see if there is anything to do.
++ */
++ if (bd->state == BOARD_READY) {
++
++ struct ev_t *eaddr = NULL;
++
++ if (!bd->re_map_membase) {
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++ return;
++ }
++ if (!bd->re_map_port) {
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++ return;
++ }
++
++ if (!bd->nasync) {
++ goto out;
++ }
++
++ /*
++ * If this is a CX or EPCX, we need to see if the firmware
++ * is requesting a concentrator image from us.
++ */
++ if ((bd->type == PCX) || (bd->type == PEPC)) {
++ chk_addr = (u16 *) (vaddr + DOWNREQ);
++ check = readw(chk_addr);
++ /* Nonzero if FEP is requesting concentrator image. */
++ if (check) {
++ if (bd->conc_dl_status == NO_PENDING_CONCENTRATOR_REQUESTS)
++ bd->conc_dl_status = NEED_CONCENTRATOR;
++ /*
++ * Signal downloader, its got some work to do.
++ */
++ DGAP_LOCK(dgap_dl_lock, lock_flags2);
++ if (dgap_dl_action != 1) {
++ dgap_dl_action = 1;
++ wake_up_interruptible(&dgap_dl_wait);
++ }
++ DGAP_UNLOCK(dgap_dl_lock, lock_flags2);
++
++ }
++ }
++
++ eaddr = (struct ev_t *) (vaddr + EVBUF);
++
++ /* Get our head and tail */
++ head = readw(&(eaddr->ev_head));
++ tail = readw(&(eaddr->ev_tail));
++
++ /*
++ * If there is an event pending. Go service it.
++ */
++ if (head != tail) {
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++ dgap_event(bd);
++ DGAP_LOCK(bd->bd_lock, lock_flags);
++ }
++
++out:
++ /*
++ * If board is doing interrupts, ACK the interrupt.
++ */
++ if (bd && bd->intr_running) {
++ readb(bd->re_map_port + 2);
++ }
++
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++ return;
++ }
++
++ /* Our state machine to get the board up and running */
++
++ /* Reset board */
++ if (bd->state == NEED_RESET) {
++ dgap_do_reset_board(bd);
++ }
++
++ /* Move to next state */
++ if (bd->state == FINISHED_RESET) {
++ bd->state = NEED_CONFIG;
++ }
++
++ if (bd->state == NEED_CONFIG) {
++ /*
++ * Match this board to a config the user created for us.
++ */
++ bd->bd_config = dgap_find_config(bd->type);
++
++ /*
++ * Register the ttys (if any) into the kernel.
++ */
++ if (bd->bd_config) {
++ bd->state = FINISHED_CONFIG;
++ }
++ else {
++ bd->state = CONFIG_NOT_FOUND;
++ }
++ }
++
++ /* Move to next state */
++ if (bd->state == FINISHED_CONFIG) {
++ bd->state = NEED_DEVICE_CREATION;
++ }
++
++ /* Move to next state */
++ if (bd->state == NEED_DEVICE_CREATION) {
++ /*
++ * Signal downloader, its got some work to do.
++ */
++ DGAP_LOCK(dgap_dl_lock, lock_flags2);
++ if (dgap_dl_action != 1) {
++ dgap_dl_action = 1;
++ wake_up_interruptible(&dgap_dl_wait);
++ }
++ DGAP_UNLOCK(dgap_dl_lock, lock_flags2);
++ }
++
++ /* Move to next state */
++ if (bd->state == FINISHED_DEVICE_CREATION) {
++ bd->state = NEED_BIOS_LOAD;
++ }
++
++ /* Move to next state */
++ if (bd->state == NEED_BIOS_LOAD) {
++ /*
++ * Signal downloader, its got some work to do.
++ */
++ DGAP_LOCK(dgap_dl_lock, lock_flags2);
++ if (dgap_dl_action != 1) {
++ dgap_dl_action = 1;
++ wake_up_interruptible(&dgap_dl_wait);
++ }
++ DGAP_UNLOCK(dgap_dl_lock, lock_flags2);
++ }
++
++ /* Wait for BIOS to test board... */
++ if (bd->state == WAIT_BIOS_LOAD) {
++ dgap_do_wait_for_bios(bd);
++ }
++
++ /* Move to next state */
++ if (bd->state == FINISHED_BIOS_LOAD) {
++ bd->state = NEED_FEP_LOAD;
++
++ /*
++ * Signal downloader, its got some work to do.
++ */
++ DGAP_LOCK(dgap_dl_lock, lock_flags2);
++ if (dgap_dl_action != 1) {
++ dgap_dl_action = 1;
++ wake_up_interruptible(&dgap_dl_wait);
++ }
++ DGAP_UNLOCK(dgap_dl_lock, lock_flags2);
++ }
++
++ /* Wait for FEP to load on board... */
++ if (bd->state == WAIT_FEP_LOAD) {
++ dgap_do_wait_for_fep(bd);
++ }
++
++ /* Move to next state */
++ if (bd->state == FINISHED_FEP_LOAD) {
++
++ /*
++ * Do tty device initialization.
++ */
++ int rc = dgap_tty_init(bd);
++ if (rc < 0) {
++ dgap_tty_uninit(bd);
++ APR(("Can't init tty devices (%d)\n", rc));
++ bd->state = BOARD_FAILED;
++ bd->dpastatus = BD_NOFEP;
++ }
++ else {
++ bd->state = BOARD_READY;
++ bd->dpastatus = BD_RUNNING;
++
++ /*
++ * If user requested the board to run in interrupt mode,
++ * go and set it up on the board.
++ */
++ if (bd->intr_used) {
++ writew(1, (bd->re_map_membase + ENABLE_INTR));
++ /*
++ * Tell the board to poll the UARTS as fast as possible.
++ */
++ writew(FEPPOLL_MIN, (bd->re_map_membase + FEPPOLL));
++ bd->intr_running = 1;
++ }
++ }
++ }
++
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++}
++
++
++/*****************************************************************************
++*
++* Function:
++*
++* dgap_poll_handler
++*
++* Author:
++*
++* Scott H Kilau
++*
++* Parameters:
++*
++* dummy -- ignored
++*
++* Return Values:
++*
++* none
++*
++* Description:
++*
++* As each timer expires, it determines (a) whether the "transmit"
++* waiter needs to be woken up, and (b) whether the poller needs to
++* be rescheduled.
++*
++******************************************************************************/
++
++static void dgap_poll_handler(ulong dummy)
++{
++ int i;
++ struct board_t *brd;
++ unsigned long lock_flags;
++ unsigned long lock_flags2;
++
++ dgap_poll_counter++;
++
++
++ /*
++ * If driver needs the config file still,
++ * keep trying to wake up the downloader to
++ * send us the file.
++ */
++ if (dgap_driver_state == DRIVER_NEED_CONFIG_LOAD) {
++ /*
++ * Signal downloader, its got some work to do.
++ */
++ DGAP_LOCK(dgap_dl_lock, lock_flags2);
++ if (dgap_dl_action != 1) {
++ dgap_dl_action = 1;
++ wake_up_interruptible(&dgap_dl_wait);
++ }
++ DGAP_UNLOCK(dgap_dl_lock, lock_flags2);
++ goto schedule_poller;
++ }
++ /*
++ * Do not start the board state machine until
++ * driver tells us its up and running, and has
++ * everything it needs.
++ */
++ else if (dgap_driver_state != DRIVER_READY) {
++ goto schedule_poller;
++ }
++
++ /*
++ * If we have just 1 board, or the system is not SMP,
++ * then use the typical old style poller.
++ * Otherwise, use our new tasklet based poller, which should
++ * speed things up for multiple boards.
++ */
++ if ( (dgap_NumBoards == 1) || (DGAP_NUM_CPUS <= 1) ) {
++ for (i = 0; i < dgap_NumBoards; i++) {
++
++ brd = dgap_Board[i];
++
++ if (brd->state == BOARD_FAILED) {
++ continue;
++ }
++ if (!brd->intr_running) {
++ /* Call the real board poller directly */
++ poll_tasklet((unsigned long) brd);
++ }
++ }
++ }
++ else {
++ /* Go thru each board, kicking off a tasklet for each if needed */
++ for (i = 0; i < dgap_NumBoards; i++) {
++ brd = dgap_Board[i];
++
++ /*
++ * Attempt to grab the board lock.
++ *
++ * If we can't get it, no big deal, the next poll will get it.
++ * Basically, I just really don't want to spin in here, because I want
++ * to kick off my tasklets as fast as I can, and then get out the poller.
++ */
++ if (!spin_trylock(&brd->bd_lock)) {
++ continue;
++ }
++
++ /* If board is in a failed state, don't bother scheduling a tasklet */
++ if (brd->state == BOARD_FAILED) {
++ spin_unlock(&brd->bd_lock);
++ continue;
++ }
++
++ /* Schedule a poll helper task */
++ if (!brd->intr_running) {
++ tasklet_schedule(&brd->helper_tasklet);
++ }
++
++ /*
++ * Can't do DGAP_UNLOCK here, as we don't have
++ * lock_flags because we did a trylock above.
++ */
++ spin_unlock(&brd->bd_lock);
++ }
++ }
++
++schedule_poller:
++
++ /*
++ * Schedule ourself back at the nominal wakeup interval.
++ */
++ if (dgap_NumBoards > 0) {
++ ulong time;
++
++ DGAP_LOCK(dgap_poll_lock, lock_flags );
++ dgap_poll_time += dgap_jiffies_from_ms(dgap_poll_tick);
++
++ time = dgap_poll_time - jiffies;
++
++ if ((ulong) time >= 2 * dgap_poll_tick) {
++ dgap_poll_time = jiffies + dgap_jiffies_from_ms(dgap_poll_tick);
++ }
++
++ dgap_poll_timer.expires = dgap_poll_time;
++ DGAP_UNLOCK(dgap_poll_lock, lock_flags );
++
++ add_timer(&dgap_poll_timer);
++ }
++
++}
++
++
++/*
++ * dgap_scan()
++ *
++ * Scan for all boards
++ *
++ * Because of the way the PCI device list is scanned, we will always detect
++ * boards in the order that they are listed in the Ids table defined near the
++ * top of this file.
++ *
++ */
++static int dgap_scan(void)
++{
++ int id;
++ int rc = 0;
++ int i;
++
++ for (id = 0; id < NIDS; id++) {
++ struct pci_dev *pdev;
++
++ pdev = NULL;
++ while ((pdev = pci_find_device(Ids[id].vendor,
++ Ids[id].device, pdev))) {
++
++ rc = dgap_found_board(pdev, id);
++ if (rc == 0) {
++ dgap_NumBoards++;
++ }
++ }
++ }
++
++ for (i = 0; i < dgap_NumBoards ; i++) {
++ unsigned long flags;
++
++ if(!dgap_Board[i])
++ continue;
++
++ DPR_INIT(("dgap_scan(%d) - printing out the msgbuf\n", i));
++ DGAP_LOCK(dgap_global_lock, flags);
++ dgap_Board[i]->msgbuf = NULL;
++ printk(dgap_Board[i]->msgbuf_head);
++ DGAP_VFREE(dgap_Board[i]->msgbuf_head);
++ dgap_Board[i]->msgbuf_head = NULL;
++ DGAP_UNLOCK(dgap_global_lock, flags);
++ if (rc) {
++ dgap_cleanup_board(dgap_Board[i]);
++ APR(("dgap_finalize_board_init failed - %d\n", rc));
++ }
++ }
++
++ if (!dgap_NumBoards) {
++ DPR_INIT(("dgap_scan() - returning ENODEV\n"));
++ return(-ENODEV);
++ } else {
++ DPR_INIT(("dgap_scan() - done\n"));
++ return(0);
++ }
++}
++
++
++/*
++ * dgap_found_board()
++ *
++ * A board has been found, init it.
++ */
++static int dgap_found_board(struct pci_dev *pdev, int id)
++{
++ struct board_t *brd;
++ DGAP_PCI_IRQ_TYPE pci_irq;
++ int i = 0;
++
++ /* get the board structure and prep it */
++ brd = dgap_Board[dgap_NumBoards] =
++ (struct board_t *) DGAP_VMALLOC(sizeof(struct board_t));
++ if (!brd) {
++ return(-ENOMEM);
++ }
++ memset(brd, 0, sizeof(struct board_t));
++
++ /* make a temporary message buffer for the boot messages */
++ brd->msgbuf = brd->msgbuf_head =
++ (char *) DGAP_VMALLOC(sizeof(char) * 8192);
++ if(!brd->msgbuf) {
++ DGAP_VFREE(brd);
++ return(-ENOMEM);
++ }
++ memset(brd->msgbuf_head, 0, sizeof(sizeof(char) * 8192));
++
++ /* store the info for the board we've found */
++ brd->magic = DGAP_BOARD_MAGIC;
++ brd->boardnum = dgap_NumBoards;
++ brd->firstminor = 0;
++ brd->vendor = Ids[id].vendor;
++ brd->device = Ids[id].device;
++ brd->name = Ids[id].name;
++ brd->maxports = Ids[id].maxports;
++ brd->type = Ids[id].config_type;
++ brd->dpatype = Ids[id].dpatype;
++ brd->dpastatus = BD_NOFEP;
++
++ DGAP_SPINLOCK_INIT(brd->bd_lock);
++
++ brd->state = BOARD_FOUND;
++ brd->runwait = 0;
++ brd->inhibit_poller = FALSE;
++ brd->wait_for_bios = 0;
++ brd->wait_for_fep = 0;
++
++ for (i = 0; i < MAXPORTS; i++) {
++ brd->channels[i] = NULL;
++ }
++
++ /* store which card & revision we have */
++ pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &brd->subvendor);
++ pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &brd->subdevice);
++ pci_read_config_byte(pdev, PCI_REVISION_ID, &brd->rev);
++
++ pci_irq = pdev->irq;
++ brd->irq = pci_irq;
++
++ /* get the PCI Base Address Registers */
++
++ /* Xr Jupiter and EPC use BAR 2 */
++ if (brd->device == PCI_DEVICE_XRJ_DID || brd->device == PCI_DEVICE_EPCJ_DID) {
++ brd->membase = pci_resource_start(pdev, 2);
++ brd->membase_end = pci_resource_end(pdev, 2);
++ }
++ /* Everyone else uses BAR 0 */
++ else {
++ brd->membase = pci_resource_start(pdev, 0);
++ brd->membase_end = pci_resource_end(pdev, 0);
++ }
++
++ if (brd->membase & 1)
++ brd->membase &= ~3;
++ else
++ brd->membase &= ~15;
++
++ /*
++ * On the PCI boards, there is no IO space allocated
++ * The I/O registers will be in the first 3 bytes of the
++ * upper 2MB of the 4MB memory space. The board memory
++ * will be mapped into the low 2MB of the 4MB memory space
++ */
++ brd->port = brd->membase + PCI_IO_OFFSET;
++ brd->port_end = brd->port + PCI_IO_SIZE;
++
++
++ /*
++ * Special initialization for non-PLX boards
++ */
++ if (brd->device != PCI_DEVICE_XRJ_DID && brd->device != PCI_DEVICE_EPCJ_DID) {
++
++ pci_write_config_byte(pdev, 0x40, 0);
++ pci_write_config_byte(pdev, 0x46, 0);
++
++ /* Limit burst length to 2 doubleword transactions */
++ pci_write_config_byte(pdev, 0x42, 1);
++ }
++
++ /* init our poll helper tasklet */
++ tasklet_init(&brd->helper_tasklet, poll_tasklet, (unsigned long) brd);
++
++ /* Log the information about the board */
++ dgap_mbuf(brd, DRVSTR": board %d: %s (rev %d), irq %d\n",
++ dgap_NumBoards, brd->name, brd->rev, brd->irq);
++
++ dgap_do_remap(brd);
++
++ brd->state = NEED_RESET;
++
++ return(0);
++}
++
++
++int dgap_finalize_board_init(struct board_t *brd) {
++
++ int rc;
++
++ DPR_INIT(("dgap_finalize_board_init() - start\n"));
++
++ if (!brd || brd->magic != DGAP_BOARD_MAGIC)
++ return(-ENODEV);
++
++ DPR_INIT(("dgap_finalize_board_init() - start #2\n"));
++
++ brd->use_interrupts = dgap_config_get_useintr(brd);
++
++ /*
++ * Set up our interrupt handler if we are set to do interrupts.
++ */
++ if (brd->use_interrupts && brd->irq) {
++
++ rc = request_irq(brd->irq, dgap_intr, SA_SHIRQ, "DGAP", brd);
++
++ if (rc) {
++ dgap_mbuf(brd, DRVSTR": Failed to hook IRQ %d. Board will work in poll mode.\n",
++ brd->irq);
++ brd->intr_used = 0;
++ }
++ else
++ brd->intr_used = 1;
++ } else {
++ brd->intr_used = 0;
++ }
++
++ return(0);
++}
++
++
++/*
++ * dgap_intr()
++ *
++ * Driver interrupt handler.
++ */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++static irqreturn_t dgap_intr(int irq, void *voidbrd, struct pt_regs *regs)
++#else
++static void dgap_intr(int irq, void *voidbrd, struct pt_regs *regs)
++#endif
++{
++ struct board_t *brd = (struct board_t *) voidbrd;
++
++ if (!brd) {
++ APR(("Received interrupt (%d) with null board associated\n", irq));
++ DGAP_IRQ_RETURN(IRQ_NONE);
++ }
++
++ /*
++ * Check to make sure its for us.
++ */
++ if (brd->magic != DGAP_BOARD_MAGIC) {
++ APR(("Received interrupt (%d) with a board pointer that wasn't ours!\n", irq));
++ DGAP_IRQ_RETURN(IRQ_NONE);
++ }
++
++ brd->intr_count++;
++
++ /*
++ * Schedule tasklet to run at a better time.
++ */
++ tasklet_schedule(&brd->helper_tasklet);
++
++ DGAP_IRQ_RETURN(IRQ_HANDLED);
++}
++
++
++/************************************************************************
++ *
++ * Utility functions
++ *
++ ************************************************************************/
++
++
++/*
++ * dgap_driver_kzmalloc()
++ *
++ * Malloc and clear memory,
++ */
++void *dgap_driver_kzmalloc(size_t size, int priority)
++{
++ void *p = kmalloc(size, priority);
++ if(p)
++ memset(p, 0, size);
++ return(p);
++}
++
++
++/*
++ * dgap_mbuf()
++ *
++ * Used to print to the message buffer during board init.
++ */
++void dgap_mbuf(struct board_t *brd, const char *fmt, ...) {
++ va_list ap;
++ char buf[1024];
++ int i;
++ unsigned long flags;
++
++ DGAP_LOCK(dgap_global_lock, flags);
++
++ /* Format buf using fmt and arguments contained in ap. */
++ va_start(ap, fmt);
++ i = vsprintf(buf, fmt, ap);
++ va_end(ap);
++
++ DPR((buf));
++
++ if (!brd || !brd->msgbuf) {
++ printk(buf);
++ DGAP_UNLOCK(dgap_global_lock, flags);
++ return;
++ }
++
++ memcpy(brd->msgbuf, buf, strlen(buf));
++ brd->msgbuf += strlen(buf);
++ *brd->msgbuf = (char) NULL;
++
++ DGAP_UNLOCK(dgap_global_lock, flags);
++}
++
++
++
++/*
++ * dgap_sleep()
++ *
++ * Put the driver to sleep for "ticks" clock ticks
++ *
++ * Returns 0 if timed out, !0 (showing signal) if interrupted by a signal.
++ */
++int dgap_sleep(int ticks)
++{
++ current->state = TASK_INTERRUPTIBLE;
++ if (HZ == 1000)
++ ticks *= 10;
++ schedule_timeout(ticks);
++ return (signal_pending(current));
++}
++
++
++/*
++ * dgap_ms_sleep()
++ *
++ * Put the driver to sleep for x ms's
++ *
++ * Returns 0 if timed out, !0 (showing signal) if interrupted by a signal.
++ */
++int dgap_ms_sleep(u32 ms)
++{
++ current->state = TASK_INTERRUPTIBLE;
++ schedule_timeout((ms * HZ) / 1000);
++ return (signal_pending(current));
++}
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/dgap_driver.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/dgap_driver.h 2003-09-27 11:38:18.448723752 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/dgap_driver.h 2003-09-27 11:38:20.952343144 +0800
+@@ -0,0 +1,809 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ * Scott H Kilau <Scott_Kilau at digi dot com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2, or (at your option)
++ * any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
++ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
++ * PURPOSE. See the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * NOTE: THIS IS A SHARED HEADER. DO NOT CHANGE CODING STYLE!!!
++ *
++ *************************************************************************
++ *
++ * Driver includes
++ *
++ *************************************************************************/
++
++#ifndef __DGAP_DRIVER_H
++#define __DGAP_DRIVER_H
++
++#define TRC_TO_CONSOLE 1
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/timer.h>
++#include <linux/errno.h>
++#include <linux/socket.h>
++#include <linux/in.h>
++#include <linux/ioport.h>
++#include <linux/version.h>
++#include <linux/slab.h>
++#include <linux/interrupt.h>
++#include <asm/irq.h>
++
++#include <linux/pci.h>
++
++#include <linux/major.h>
++#include <linux/signal.h>
++
++#include <linux/mm.h>
++
++#include <linux/sched.h>
++#include <linux/delay.h>
++#include <linux/stddef.h>
++#include <asm/atomic.h>
++#include <asm/bitops.h>
++#include <asm/io.h>
++#include <asm/byteorder.h>
++#include <asm/system.h>
++
++#include <linux/tty.h>
++#include <linux/termios.h>
++#include <linux/poll.h>
++#include <linux/types.h>
++
++#include <linux/serial.h> /* for struct async_serial */
++
++#include "dgap_types.h" /* Additional types needed by header files */
++#include "digi.h"
++
++#include "dgap_pci.h"
++#include "dgap_fep5.h"
++#include "dgap_conf.h"
++
++/*************************************************************************
++ *
++ * Driver defines
++ *
++ *************************************************************************/
++
++/*
++ * Driver identification, error and debugging statments
++ *
++ * In theory, you can change all occurances of "digi" in the next
++ * three lines, and the driver printk's will all automagically change.
++ *
++ * APR((fmt, args, ...)); Always prints message
++ * DPR((fmt, args, ...)); Only prints if DGAP_TRACER is defined at
++ * compile time and dgap_debug!=0
++ */
++#define PROCSTR "dgap" /* /proc entries */
++#define DEVSTR "/dev/dg/dgap" /* /dev entries */
++#define DRVSTR "dgap" /* Driver name string
++ * displayed by APR */
++#define APR(args) do { PRINTF_TO_KMEM(args); printk(DRVSTR": "); printk args; \
++ } while (0)
++#define RAPR(args) do { PRINTF_TO_KMEM(args); printk args; } while (0)
++
++/*
++ * Debugging levels can be set using debug insmod variable
++ * They can also be compiled out completely.
++ */
++
++#define DBG_INIT (dgap_debug & 0x01)
++#define DBG_BASIC (dgap_debug & 0x02)
++#define DBG_CORE (dgap_debug & 0x04)
++
++#define DBG_OPEN (dgap_debug & 0x08)
++#define DBG_CLOSE (dgap_debug & 0x10)
++#define DBG_READ (dgap_debug & 0x20)
++#define DBG_WRITE (dgap_debug & 0x40)
++
++#define DBG_IOCTL (dgap_debug & 0x80)
++
++#define DBG_PROC (dgap_debug & 0x100)
++#define DBG_PARAM (dgap_debug & 0x200)
++#define DBG_PSCAN (dgap_debug & 0x400)
++#define DBG_EVENT (dgap_debug & 0x800)
++
++#define DBG_DRAIN (dgap_debug & 0x1000)
++#define DBG_CARR (dgap_debug & 0x2000)
++
++#define DBG_MGMT (dgap_debug & 0x4000)
++
++
++#if defined(DGAP_TRACER)
++
++# if defined(TRC_TO_KMEM)
++/* Choose one: */
++# define TRC_ON_OVERFLOW_WRAP_AROUND
++# undef TRC_ON_OVERFLOW_SHIFT_BUFFER
++# endif //TRC_TO_KMEM
++
++# define TRC_MAXMSG 1024
++# define TRC_OVERFLOW "(OVERFLOW)"
++# define TRC_DTRC "/usr/bin/dtrc"
++
++#if defined TRC_TO_CONSOLE
++#define PRINTF_TO_CONSOLE(args) { printk(DRVSTR": "); printk args; }
++#else //!defined TRACE_TO_CONSOLE
++#define PRINTF_TO_CONSOLE(args)
++#endif
++
++#if defined TRC_TO_KMEM
++#define PRINTF_TO_KMEM(args) dgap_tracef args
++#else //!defined TRC_TO_KMEM
++#define PRINTF_TO_KMEM(args)
++#endif
++
++#define TRC(args) { PRINTF_TO_KMEM(args); PRINTF_TO_CONSOLE(args) }
++
++# define DPR_INIT(ARGS) if (DBG_INIT) TRC(ARGS)
++# define DPR_BASIC(ARGS) if (DBG_BASIC) TRC(ARGS)
++# define DPR_CORE(ARGS) if (DBG_CORE) TRC(ARGS)
++# define DPR_OPEN(ARGS) if (DBG_OPEN) TRC(ARGS)
++# define DPR_CLOSE(ARGS) if (DBG_CLOSE) TRC(ARGS)
++# define DPR_READ(ARGS) if (DBG_READ) TRC(ARGS)
++# define DPR_WRITE(ARGS) if (DBG_WRITE) TRC(ARGS)
++# define DPR_IOCTL(ARGS) if (DBG_IOCTL) TRC(ARGS)
++# define DPR_PROC(ARGS) if (DBG_PROC) TRC(ARGS)
++# define DPR_PARAM(ARGS) if (DBG_PARAM) TRC(ARGS)
++# define DPR_PSCAN(ARGS) if (DBG_PSCAN) TRC(ARGS)
++# define DPR_EVENT(ARGS) if (DBG_EVENT) TRC(ARGS)
++# define DPR_DRAIN(ARGS) if (DBG_DRAIN) TRC(ARGS)
++# define DPR_CARR(ARGS) if (DBG_CARR) TRC(ARGS)
++# define DPR_MGMT(ARGS) if (DBG_MGMT) TRC(ARGS)
++
++# define DPR(ARGS) if (dgap_debug) TRC(ARGS)
++# define P(X) dgap_tracef(#X "=%p\n", X)
++# define X(X) dgap_tracef(#X "=%x\n", X)
++
++#else//!defined DGAP_TRACER
++
++#define PRINTF_TO_KMEM(args)
++# define TRC(ARGS)
++# define DPR_INIT(ARGS)
++# define DPR_BASIC(ARGS)
++# define DPR_CORE(ARGS)
++# define DPR_OPEN(ARGS)
++# define DPR_CLOSE(ARGS)
++# define DPR_READ(ARGS)
++# define DPR_WRITE(ARGS)
++# define DPR_IOCTL(ARGS)
++# define DPR_PROC(ARGS)
++# define DPR_PARAM(ARGS)
++# define DPR_PSCAN(ARGS)
++# define DPR_EVENT(ARGS)
++# define DPR_DRAIN(ARGS)
++# define DPR_CARR(ARGS)
++# define DPR_MGMT(ARGS)
++
++# define DPR(args)
++
++#endif//DGAP_TRACER
++
++/* Number of boards we support at once. */
++#define MAXBOARDS 32
++#define MAXPORTS 224
++#define MAXTTYNAMELEN 200
++
++/* Our 3 magic numbers for our board, channel and unit structs */
++#define DGAP_BOARD_MAGIC 0x5c6df104
++#define DGAP_CHANNEL_MAGIC 0x6c6df104
++#define DGAP_UNIT_MAGIC 0x7c6df104
++
++/* Serial port types */
++#define DGAP_SERIAL 0
++#define DGAP_PRINT 1
++
++#define SERIAL_TYPE_NORMAL 1
++
++/* 4 extra for alignment play space */
++#define WRITEBUFLEN ((4096) + 4)
++#define MYFLIPLEN N_TTY_BUF_SIZE
++
++#define SBREAK_TIME 0x25
++#define U2BSIZE 0x400
++#define dgap_jiffies_from_ms(a) (((a) * HZ) / 1000)
++
++/*
++ * Our major for the mgmt devices.
++ *
++ * We can use 22, because Digi was allocated 22 and 23 for the epca driver.
++ * 22 has now become obsolete now that the "cu" devices have
++ * been removed from 2.6.
++ * Also, this *IS* the epca driver, just PCI only now.
++ */
++#ifndef DIGI_DGAP_MAJOR
++# define DIGI_DGAP_MAJOR 22
++#endif
++
++/*
++ * The parameters we use to define the periods of the moving averages.
++ */
++#define MA_PERIOD (HZ / 10)
++#define SMA_DUR (1 * HZ)
++#define EMA_DUR (1 * HZ)
++#define SMA_NPERIODS (SMA_DUR / MA_PERIOD)
++#define EMA_NPERIODS (EMA_DUR / MA_PERIOD)
++
++/*
++ * Define a local default termios struct. All ports will be created
++ * with this termios initially. This is the same structure that is defined
++ * as the default in tty_io.c with the same settings overriden as in serial.c
++ *
++ * In short, this should match the internal serial ports' defaults.
++ */
++#define DEFAULT_IFLAGS (ICRNL | IXON)
++#define DEFAULT_OFLAGS (OPOST | ONLCR)
++#define DEFAULT_CFLAGS (B9600 | CS8 | CREAD | HUPCL | CLOCAL)
++#define DEFAULT_LFLAGS (ISIG | ICANON | ECHO | ECHOE | ECHOK | \
++ ECHOCTL | ECHOKE | IEXTEN)
++
++
++/*************************************************************************
++ *
++ * Utility defines - should be defined elsewhere, but be paranoid
++ *
++ *************************************************************************/
++
++#if !defined(KERNEL_VERSION) /* defined in version.h in later kernels */
++# define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
++#endif
++
++/* The number of elements in an array */
++#if !defined(asizeof)
++# define asizeof(X) (sizeof(X) / sizeof(X[0]))
++#endif
++
++/*
++ * All the possible states the driver can be while being loaded.
++ */
++enum {
++ DRIVER_INITIALIZED = 0,
++ DRIVER_NEED_CONFIG_LOAD,
++ DRIVER_REQUESTED_CONFIG,
++ DRIVER_READY
++};
++
++/*
++ * All the possible states the board can be while booting up.
++ */
++enum {
++ BOARD_FAILED = 0,
++ CONFIG_NOT_FOUND,
++ BOARD_FOUND,
++ NEED_RESET,
++ FINISHED_RESET,
++ NEED_CONFIG,
++ FINISHED_CONFIG,
++ NEED_DEVICE_CREATION,
++ REQUESTED_DEVICE_CREATION,
++ FINISHED_DEVICE_CREATION,
++ NEED_BIOS_LOAD,
++ REQUESTED_BIOS,
++ WAIT_BIOS_LOAD,
++ FINISHED_BIOS_LOAD,
++ NEED_FEP_LOAD,
++ REQUESTED_FEP,
++ WAIT_FEP_LOAD,
++ FINISHED_FEP_LOAD,
++ BOARD_READY
++};
++
++/*
++ * All the possible states that a requested concentrator image can be in.
++ */
++enum {
++ NO_PENDING_CONCENTRATOR_REQUESTS = 0,
++ NEED_CONCENTRATOR,
++ REQUESTED_CONCENTRATOR
++};
++
++extern char *dgap_state_text[];
++extern char *dgap_driver_state_text[];
++
++
++/*************************************************************************
++ *
++ * Some API's changed at linux version 2.1.x. I'm not sure exactly
++ * when they changed during the 2.1.x development, but it doesn't
++ * matter to us. Create some macros to preserve compatibility.
++ *
++ * Here you can see what has changed between 2.0 and 2.1+. If you
++ * are reading/writing this file, you should be well aware of these
++ * macros or you won't be able to follow whats going on. The
++ * alternative was #ifdef spaghetti.
++ */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++# include <asm/irq.h>
++# include <asm/bitops.h>
++# include <asm/io.h>
++# include <asm/uaccess.h>
++# include <linux/gfp.h>
++
++# define DGAP_get_free_page(x) (get_zeroed_page(GFP_ATOMIC))
++# define DGAP_VMALLOC(x) (kmalloc((x), GFP_ATOMIC))
++# define DGAP_VFREE(x) (kfree(x))
++
++# define DGAP_MAJOR(x) (imajor(x))
++# define DGAP_MINOR(x) (iminor(x))
++# define DGAP_TTY_MAJOR(x) (MAJOR(x))
++# define DGAP_TTY_MINOR(x) (MINOR(x))
++
++# define DGAP_NUM_CPUS (num_online_cpus())
++
++# define DGAP_MOD_INC_USE_COUNT(rtn) (rtn = 1)
++# define DGAP_MOD_DEC_USE_COUNT
++
++# define DGAP_IRQ_RETURN(x) return x;
++
++
++# define DGAP_SPINLOCK_INIT(x) spin_lock_init(&(x))
++
++# define DGAP_IOREMAP(ADDR, LEN) ioremap(ADDR, LEN)
++# define DGAP_IOUNMAP(ADDR) iounmap(ADDR)
++# define COPY_FROM_USER(DST,SRC,LEN) copy_from_user(DST,SRC,LEN)
++# define COPY_TO_USER(DST,SRC,LEN) copy_to_user(DST,SRC,LEN)
++# define GET_USER(A1,A2) get_user(A1,(unsigned int *)A2)
++# define PUT_USER(A1,A2) put_user(A1,(unsigned long *)A2)
++
++# define READ_PROTO struct file *file, char *buf, size_t count,loff_t *ppos
++# define READ_ARGS file, buf, count, ppos
++# define READ_RETURN_T ssize_t
++
++# define WRITE_PROTO struct file *file, const char *buf, size_t count, \
++ loff_t *ppos
++# define WRITE_ARGS file, buf, count, ppos
++# define WRITE_RETURN_T ssize_t
++
++# define CLOSE_RETURN_T int
++# define CLOSE_RETURN(X) return(X)
++
++# define PARM_I_RDEV file->f_dentry->d_inode->i_rdev
++# define GET_POS() *ppos
++# define ADD_POS(AMT) *ppos += (AMT)
++# define SET_POS(AMT) *ppos = (AMT)
++
++# define DGAP_PCI_IRQ_TYPE uint
++# define PCI_PRESENT() pci_present()
++
++# define PARM_STR(VAR, INIT, DESC) \
++ static char *VAR = INIT; \
++ char *dgap_##VAR; \
++ MODULE_PARM(VAR, "s"); \
++ MODULE_PARM_DESC(VAR, DESC);
++
++# define PARM_INT(VAR, INIT, DESC) \
++ static int VAR = INIT; \
++ int dgap_##VAR; \
++ MODULE_PARM(VAR, "i"); \
++ MODULE_PARM_DESC(VAR, DESC);
++
++# define PARM_ULONG(VAR, INIT, DESC) \
++ static ulong VAR = INIT; \
++ ulong dgap_##VAR; \
++ MODULE_PARM(VAR, "l"); \
++ MODULE_PARM_DESC(VAR, DESC);
++
++# define DGAP_LOCK(x,y) spin_lock_irqsave(&(x), y)
++# define DGAP_UNLOCK(x,y) spin_unlock_irqrestore(&(x), y)
++//# define DGAP_LOCK(x,y) spin_lock(&(x))
++//# define DGAP_UNLOCK(x,y) spin_unlock(&(x))
++# define DGAP_TRYLOCK(x,y) spin_trylock(&(x))
++
++# define DGAP_PROCID() smp_processor_id()
++
++/*
++ * In some revisions within the 2.4 kernel series, there is a patch
++ * which changes the behavior of a failed open. In 2.0 and 2.2 and
++ * most 2.4 revisions, a failed open will be followed _always_ by
++ * a call to the driver's close routine. In some 2.4 revisions,
++ * the close will not be called (and therefore driver use counts
++ * will be too high, and ports may become unusable).
++ *
++ * In the case that the ALT_FAIL_OPEN code is allowed to exist,
++ * some new parameters are required, like ALT_FAIL_OPEN_DEFAULT.
++ */
++# define ALLOW_ALT_FAIL_OPEN 0
++# define ALT_FAIL_OPEN_DEFAULT 0
++
++
++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
++
++# include <asm/uaccess.h>
++
++# define DGAP_get_free_page(x) (get_free_page(GFP_KERNEL))
++# define DGAP_VMALLOC(x) (vmalloc(x))
++# define DGAP_VFREE(x) (vfree(x))
++
++# define DGAP_MAJOR(x) (MAJOR((x)->i_rdev))
++# define DGAP_MINOR(x) (MINOR((x)->i_rdev))
++# define DGAP_TTY_MAJOR(x) (MAJOR(x))
++# define DGAP_TTY_MINOR(x) (MINOR(x))
++
++# define DGAP_NUM_CPUS (smp_num_cpus)
++
++# define DGAP_MOD_INC_USE_COUNT(rtn) \
++ { \
++ MOD_INC_USE_COUNT; \
++ rtn = 1; \
++ }
++
++# define DGAP_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT
++
++# define DGAP_IRQ_RETURN(x) return;
++
++# define DGAP_SPINLOCK_INIT(x) spin_lock_init(&(x))
++
++# define DGAP_IOREMAP(ADDR, LEN) ioremap(ADDR, LEN)
++# define DGAP_IOUNMAP(ADDR) iounmap(ADDR)
++# define COPY_FROM_USER(DST,SRC,LEN) copy_from_user(DST,SRC,LEN)
++# define COPY_TO_USER(DST,SRC,LEN) copy_to_user(DST,SRC,LEN)
++# define GET_USER(A1,A2) get_user(A1,(unsigned int *)A2)
++# define PUT_USER(A1,A2) put_user(A1,(unsigned long *)A2)
++
++# define READ_PROTO struct file *file, char *buf, size_t count,loff_t *ppos
++# define READ_ARGS file, buf, count, ppos
++# define READ_RETURN_T ssize_t
++
++# define WRITE_PROTO struct file *file, const char *buf, size_t count, \
++ loff_t *ppos
++# define WRITE_ARGS file, buf, count, ppos
++# define WRITE_RETURN_T ssize_t
++
++# define CLOSE_RETURN_T int
++# define CLOSE_RETURN(X) return(X)
++
++# define PARM_I_RDEV file->f_dentry->d_inode->i_rdev
++# define GET_POS() *ppos
++# define ADD_POS(AMT) *ppos += (AMT)
++# define SET_POS(AMT) *ppos = (AMT)
++
++# define DGAP_PCI_IRQ_TYPE uint
++# define PCI_PRESENT() pci_present()
++
++# define PARM_STR(VAR, INIT, DESC) \
++ static char *VAR = INIT; \
++ char *dgap_##VAR; \
++ MODULE_PARM(VAR, "s"); \
++ MODULE_PARM_DESC(VAR, DESC);
++
++# define PARM_INT(VAR, INIT, DESC) \
++ static int VAR = INIT; \
++ int dgap_##VAR; \
++ MODULE_PARM(VAR, "i"); \
++ MODULE_PARM_DESC(VAR, DESC);
++
++# define PARM_ULONG(VAR, INIT, DESC) \
++ static ulong VAR = INIT; \
++ ulong dgap_##VAR; \
++ MODULE_PARM(VAR, "l"); \
++ MODULE_PARM_DESC(VAR, DESC);
++
++# define DGAP_LOCK(x,y) spin_lock_irqsave(&(x), y);
++# define DGAP_UNLOCK(x,y) spin_unlock_irqrestore(&(x), y);
++
++# define DGAP_PROCID() smp_processor_id()
++
++/*
++ * In some revisions within the 2.4 kernel series, there is a patch
++ * which changes the behavior of a failed open. In 2.0 and 2.2 and
++ * most 2.4 revisions, a failed open will be followed _always_ by
++ * a call to the driver's close routine. In some 2.4 revisions,
++ * the close will not be called (and therefore driver use counts
++ * will be too high, and ports may become unusable).
++ *
++ * In the case that the ALT_FAIL_OPEN code is allowed to exist,
++ * some new parameters are required, like ALT_FAIL_OPEN_DEFAULT.
++ */
++# define ALLOW_ALT_FAIL_OPEN 1
++# define ALT_FAIL_OPEN_DEFAULT 0
++
++#else
++
++# error "this driver does not support anything below the 2.4 kernel series."
++
++#endif
++
++
++/*
++ * Modem line constants are defined as macros because DSR and
++ * DCD are swapable using the ditty altpin option.
++ */
++#define D_CD(ch) ch->ch_cd /* Carrier detect */
++#define D_DSR(ch) ch->ch_dsr /* Data set ready */
++#define D_RTS(ch) DM_RTS /* Request to send */
++#define D_CTS(ch) DM_CTS /* Clear to send */
++#define D_RI(ch) DM_RI /* Ring indicator */
++#define D_DTR(ch) DM_DTR /* Data terminal ready */
++
++
++/*************************************************************************
++ *
++ * Structures and closely related defines.
++ *
++ *************************************************************************/
++
++
++/*
++ * A structure to hold a statistics counter. We also
++ * compute moving averages for this counter.
++ */
++struct macounter
++{
++ u32 cnt; /* Total count */
++ ulong accum; /* Acuumulator per period */
++ ulong sma; /* Simple moving average */
++ ulong ema; /* Exponential moving average */
++};
++
++
++/*
++ * Per-board information
++ */
++struct board_t
++{
++ int magic; /* Board Magic number. */
++ int boardnum; /* Board number: 0-3 */
++ int firstminor; /* First minor, e.g. 0, 30, 60 */
++
++ int type; /* Type of board */
++ char *name; /* Product Name */
++ u16 vendor; /* PCI vendor ID */
++ u16 device; /* PCI device ID */
++ u16 subvendor; /* PCI subsystem vendor ID */
++ u16 subdevice; /* PCI subsystem device ID */
++ uchar rev; /* PCI revision ID */
++ u16 maxports; /* MAX ports this board can handle */
++
++ spinlock_t bd_lock; /* Used to protect board */
++
++ u32 state; /* State of card. */
++
++ struct tasklet_struct helper_tasklet; /* Poll helper tasklet */
++
++ u32 wait_for_bios;
++ u32 wait_for_fep;
++
++ struct cnode * bd_config; /* Config of board */
++
++ u16 nasync; /* Number of ports on card */
++
++ u32 use_interrupts; /* Should we be interrupt driven? */
++ u32 irq; /* Interrupt request number */
++ u32 intr_count; /* Count of interrupts */
++ u32 intr_used; /* Non-zero if using interrupts */
++ u32 intr_running; /* Non-zero if FEP knows its doing interrupts */
++
++ ulong port; /* Start of base io port of the card */
++ ulong port_end; /* End of base io port of the card */
++ ulong membase; /* Start of base memory of the card */
++ ulong membase_end; /* End of base memory of the card */
++
++ uchar *re_map_port; /* Remapped io port of the card */
++ uchar *re_map_membase;/* Remapped memory of the card */
++
++ uchar runwait; /* # Processes waiting for FEP */
++ uchar inhibit_poller; /* Tells the poller to leave us alone */
++
++ struct channel_t *channels[MAXPORTS]; /* array of pointers to our channels. */
++
++ struct tty_driver SerialDriver;
++ char SerialName[200];
++ struct tty_driver PrintDriver;
++ char PrintName[200];
++
++ u32 dgap_Major_Serial_Registered;
++ u32 dgap_Major_TransparentPrint_Registered;
++
++ u32 dgap_Serial_Major;
++ u32 dgap_TransparentPrint_Major;
++
++ u32 TtyRefCnt;
++
++ struct bs_t *bd_bs; /* Base structure pointer */
++
++ char *flipbuf; /* Our flip buffer, alloced if board is found */
++
++ u16 dpatype; /* The board "type", as defined by DPA */
++ u16 dpastatus; /* The board "status", as defined by DPA */
++ wait_queue_head_t kme_wait; /* Needed for DPA support */
++
++ u32 conc_dl_status; /* Status of any pending conc download */
++ /*
++ * Mgmt data.
++ */
++ char *msgbuf_head;
++ char *msgbuf;
++
++};
++
++
++
++/************************************************************************
++ * Unit flag definitions for un_flags.
++ ************************************************************************/
++#define UN_ISOPEN 0x0001 /* Device is open */
++#define UN_CLOSING 0x0002 /* Line is being closed */
++#define UN_IMM 0x0004 /* Service immediately */
++#define UN_BUSY 0x0008 /* Some work this channel */
++#define UN_BREAKI 0x0010 /* Input break received */
++#define UN_PWAIT 0x0020 /* Printer waiting for terminal */
++#define UN_TIME 0x0040 /* Waiting on time */
++#define UN_EMPTY 0x0080 /* Waiting output queue empty */
++#define UN_LOW 0x0100 /* Waiting output low water mark*/
++#define UN_EXCL_OPEN 0x0200 /* Open for exclusive use */
++#define UN_WOPEN 0x0400 /* Device waiting for open */
++#define UN_WIOCTL 0x0800 /* Device waiting for open */
++#define UN_HANGUP 0x8000 /* Carrier lost */
++
++
++/************************************************************************
++ * Structure for terminal or printer unit.
++ ************************************************************************/
++struct un_t {
++ int magic; /* Unit Magic Number. */
++ struct channel_t *un_ch;
++ u32 un_time;
++ u32 un_type;
++ u32 un_open_count; /* Counter of opens to port */
++ struct tty_struct *un_tty;/* Pointer to unit tty structure */
++ u32 un_flags; /* Unit flags */
++ wait_queue_head_t un_flags_wait; /* Place to sleep to wait on unit */
++ u32 un_dev; /* Minor device number */
++ tcflag_t un_oflag; /* oflags being done on board */
++ tcflag_t un_lflag; /* lflags being done on board */
++};
++
++
++/************************************************************************
++ * Device flag definitions for ch_flags.
++ ************************************************************************/
++#define CH_PRON 0x0001 /* Printer on string */
++#define CH_OUT 0x0002 /* Dial-out device open */
++#define CH_STOP 0x0004 /* Output is stopped */
++#define CH_STOPI 0x0008 /* Input is stopped */
++#define CH_CD 0x0010 /* Carrier is present */
++#define CH_FCAR 0x0020 /* Carrier forced on */
++
++#define CH_RXBLOCK 0x0080 /* Enable rx blocked flag */
++#define CH_WLOW 0x0100 /* Term waiting low event */
++#define CH_WEMPTY 0x0200 /* Term waiting empty event */
++#define CH_RENABLE 0x0400 /* Buffer just emptied */
++#define CH_RACTIVE 0x0800 /* Process active in xxread() */
++#define CH_RWAIT 0x1000 /* Process waiting in xxread() */
++#define CH_HANGUP 0x8000 /* Hangup received */
++
++
++/************************************************************************
++ * Channel information structure.
++ ************************************************************************/
++struct channel_t {
++ int magic; /* Channel Magic Number */
++ struct bs_t *ch_bs; /* Base structure pointer */
++ struct cm_t *ch_cm; /* Command queue pointer */
++ struct board_t *ch_bd; /* Board structure pointer */
++ unsigned char *ch_vaddr; /* FEP memory origin */
++ unsigned char *ch_taddr; /* Write buffer origin */
++ unsigned char *ch_raddr; /* Read buffer origin */
++ struct digi_t ch_digi; /* Transparent Print structure */
++ struct un_t ch_tun; /* Terminal unit info */
++ struct un_t ch_pun; /* Printer unit info */
++
++ spinlock_t ch_lock; /* provide for serialization */
++ wait_queue_head_t ch_flags_wait;
++
++ u32 pscan_state;
++ uchar pscan_savechar;
++
++ u32 ch_portnum; /* Port number, 0 offset. */
++ u32 ch_open_count; /* open count */
++ u32 ch_flags; /* Channel flags */
++
++
++ u32 ch_close_delay; /* How long we should drop RTS/DTR for */
++
++ u32 ch_cpstime; /* Time for CPS calculations */
++
++ tcflag_t ch_c_iflag; /* channel iflags */
++ tcflag_t ch_c_cflag; /* channel cflags */
++ tcflag_t ch_c_oflag; /* channel oflags */
++ tcflag_t ch_c_lflag; /* channel lflags */
++
++ u16 ch_fepiflag; /* FEP tty iflags */
++ u16 ch_fepcflag; /* FEP tty cflags */
++ u16 ch_fepoflag; /* FEP tty oflags */
++ u16 ch_wopen; /* Waiting for open process cnt */
++ u16 ch_tstart; /* Transmit buffer start */
++ u16 ch_tsize; /* Transmit buffer size */
++ u16 ch_rstart; /* Receive buffer start */
++ u16 ch_rsize; /* Receive buffer size */
++ u16 ch_rdelay; /* Receive delay time */
++
++ u16 ch_tlw; /* Our currently set low water mark */
++
++ u16 ch_cook; /* Output character mask */
++
++ uchar ch_card; /* Card channel is on */
++ uchar ch_stopc; /* Stop character */
++ uchar ch_startc; /* Start character */
++
++ uchar ch_mostat; /* FEP output modem status */
++ uchar ch_mistat; /* FEP input modem status */
++ uchar ch_mforce; /* Modem values to be forced */
++ uchar ch_mval; /* Force values */
++ uchar ch_fepstopc; /* FEP stop character */
++ uchar ch_fepstartc; /* FEP start character */
++
++ uchar ch_astopc; /* Auxiliary Stop character */
++ uchar ch_astartc; /* Auxiliary Start character */
++ uchar ch_fepastopc; /* Auxiliary FEP stop char */
++ uchar ch_fepastartc; /* Auxiliary FEP start char */
++
++ uchar ch_hflow; /* FEP hardware handshake */
++ uchar ch_dsr; /* stores real dsr value */
++ uchar ch_cd; /* stores real cd value */
++ uchar ch_tx_win; /* channel tx buffer window */
++ uchar ch_rx_win; /* channel rx buffer window */
++ u32 ch_info; /* Additional channel specific information */
++};
++
++
++/*************************************************************************
++ *
++ * Prototypes for non-static functions used in more than one module
++ *
++ *************************************************************************/
++
++int dgap_lock_poller(struct board_t *brd);
++void dgap_unlock_poller(struct board_t *brd);
++void dgap_mbuf(struct board_t *brd, const char *fmt, ...);
++int dgap_sleep(int ticks);
++int dgap_ms_sleep(u32 ms);
++
++int dgap_tty_brdinit(struct board_t *brd);
++void dgap_tty_brduninit(struct board_t *brd);
++
++void *dgap_driver_kzmalloc(size_t size, int priority);
++
++char *get_event_text(u32);
++char *get_msignal_text(u32);
++
++char *dgap_ioctl_name(int cmd);
++
++#if defined(DGAP_TRACER)
++void dgap_tracef(const char *fmt, ...);
++void dgap_tracer_free(void);
++#endif
++
++void dgap_proc_unregister_all(void);
++void dgap_proc_register_basic(void);
++int dgap_finalize_board_init(struct board_t *brd);
++
++void dgap_do_bios_load(struct board_t *brd, uchar *ubios, int len);
++void dgap_do_fep_load(struct board_t *brd, uchar *ufep, int len);
++void dgap_do_conc_load(struct board_t *brd, uchar *uaddr, int len);
++void dgap_do_config_load(uchar *uaddr, int len);
++
++int dgap_after_config_loaded(void);
++
++extern spinlock_t dgap_dl_lock;
++extern wait_queue_head_t dgap_dl_wait;
++extern int dgap_dl_action;
++
++extern int dgap_driver_state;
++
++#endif
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/dgap_fep5.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/dgap_fep5.h 2003-09-27 11:38:18.448723752 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/dgap_fep5.h 2003-09-27 11:38:20.954342840 +0800
+@@ -0,0 +1,247 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ * Scott H Kilau <Scott_Kilau at digi dot com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2, or (at your option)
++ * any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
++ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
++ * PURPOSE. See the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * NOTE: THIS IS A SHARED HEADER. DO NOT CHANGE CODING STYLE!!!
++ *
++ ************************************************************************
++ *** FEP Version 5 dependent definitions
++ ************************************************************************/
++
++#ifndef __DGAP_FEP5_H
++#define __DGAP_FEP5_H
++
++#include "dgap_types.h"
++
++/************************************************************************
++ * FEP memory offsets
++ ************************************************************************/
++#define START 0x0004L /* Execution start address */
++
++#define CMDBUF 0x0d10L /* Command (cm_t) structure offset */
++#define CMDSTART 0x0400L /* Start of command buffer */
++#define CMDMAX 0x0800L /* End of command buffer */
++
++#define EVBUF 0x0d18L /* Event (ev_t) structure */
++#define EVSTART 0x0800L /* Start of event buffer */
++#define EVMAX 0x0c00L /* End of event buffer */
++#define FEP5_PLUS 0x0E40 /* ASCII '5' and ASCII 'A' is here */
++#define ECS_SEG 0x0E44 /* Segment of the extended channel structure */
++#define LINE_SPEED 0x10 /* Offset into ECS_SEG for line speed */
++ /* if the fep has extended capabilities */
++
++/* BIOS MAGIC SPOTS */
++#define ERROR 0x0C14L /* BIOS error code */
++#define SEQUENCE 0x0C12L /* BIOS sequence indicator */
++#define POSTAREA 0x0C00L /* POST complete message area */
++
++/* FEP MAGIC SPOTS */
++#define FEPSTAT POSTAREA /* OS here when FEP comes up */
++#define NCHAN 0x0C02L /* number of ports FEP sees */
++#define PANIC 0x0C10L /* PANIC area for FEP */
++#define KMEMEM 0x0C30L /* Memory for KME use */
++#define CONFIG 0x0CD0L /* Concentrator configuration info */
++#define CONFIGSIZE 0x0030 /* configuration info size */
++#define DOWNREQ 0x0D00 /* Download request buffer pointer */
++
++#define CHANBUF 0x1000L /* Async channel (bs_t) structs */
++#define FEPOSSIZE 0x1FFF /* 8K FEPOS */
++
++#define XEMPORTS 0xC02 /*
++ * Offset in board memory where FEP5 stores
++ * how many ports it has detected.
++ * NOTE: FEP5 reports 64 ports when the user
++ * has the cable in EBI OUT instead of EBI IN.
++ */
++
++#define FEPCLR 0x00
++#define FEPMEM 0x02
++#define FEPRST 0x04
++#define FEPINT 0x08
++#define FEPMASK 0x0e
++#define FEPWIN 0x80
++
++#define LOWMEM 0x0100
++#define HIGHMEM 0x7f00
++
++#define FEPTIMEOUT 200000
++
++#define ENABLE_INTR 0x0e04 /* Enable interrupts flag */
++#define FEPPOLL_MIN 1 /* minimum of 1 millisecond */
++#define FEPPOLL_MAX 20 /* maximum of 20 milliseconds */
++#define FEPPOLL 0x0c26 /* Fep event poll interval */
++
++#define IALTPIN 0x0080 /* Input flag to swap DSR <-> DCD */
++
++/************************************************************************
++ * Command structure definition.
++ ************************************************************************/
++struct cm_t {
++ volatile unsigned short cm_head; /* Command buffer head offset */
++ volatile unsigned short cm_tail; /* Command buffer tail offset */
++ volatile unsigned short cm_start; /* start offset of buffer */
++ volatile unsigned short cm_max; /* last offset of buffer */
++};
++
++/************************************************************************
++ * Event structure definition.
++ ************************************************************************/
++struct ev_t {
++ volatile unsigned short ev_head; /* Command buffer head offset */
++ volatile unsigned short ev_tail; /* Command buffer tail offset */
++ volatile unsigned short ev_start; /* start offset of buffer */
++ volatile unsigned short ev_max; /* last offset of buffer */
++};
++
++/************************************************************************
++ * Download buffer structure.
++ ************************************************************************/
++struct downld_t {
++ uchar dl_type; /* Header */
++ uchar dl_seq; /* Download sequence */
++ ushort dl_srev; /* Software revision number */
++ ushort dl_lrev; /* Low revision number */
++ ushort dl_hrev; /* High revision number */
++ ushort dl_seg; /* Start segment address */
++ ushort dl_size; /* Number of bytes to download */
++ uchar dl_data[1024]; /* Download data */
++};
++
++/************************************************************************
++ * Per channel buffer structure
++ ************************************************************************
++ * Base Structure Entries Usage Meanings to Host *
++ * *
++ * W = read write R = read only *
++ * C = changed by commands only *
++ * U = unknown (may be changed w/o notice) *
++ ************************************************************************/
++struct bs_t {
++ volatile unsigned short tp_jmp; /* Transmit poll jump */
++ volatile unsigned short tc_jmp; /* Cooked procedure jump */
++ volatile unsigned short ri_jmp; /* Not currently used */
++ volatile unsigned short rp_jmp; /* Receive poll jump */
++
++ volatile unsigned short tx_seg; /* W Tx segment */
++ volatile unsigned short tx_head; /* W Tx buffer head offset */
++ volatile unsigned short tx_tail; /* R Tx buffer tail offset */
++ volatile unsigned short tx_max; /* W Tx buffer size - 1 */
++
++ volatile unsigned short rx_seg; /* W Rx segment */
++ volatile unsigned short rx_head; /* W Rx buffer head offset */
++ volatile unsigned short rx_tail; /* R Rx buffer tail offset */
++ volatile unsigned short rx_max; /* W Rx buffer size - 1 */
++
++ volatile unsigned short tx_lw; /* W Tx buffer low water mark */
++ volatile unsigned short rx_lw; /* W Rx buffer low water mark */
++ volatile unsigned short rx_hw; /* W Rx buffer high water mark */
++ volatile unsigned short incr; /* W Increment to next channel */
++
++ volatile unsigned short fepdev; /* U SCC device base address */
++ volatile unsigned short edelay; /* W Exception delay */
++ volatile unsigned short blen; /* W Break length */
++ volatile unsigned short btime; /* U Break complete time */
++
++ volatile unsigned short iflag; /* C UNIX input flags */
++ volatile unsigned short oflag; /* C UNIX output flags */
++ volatile unsigned short cflag; /* C UNIX control flags */
++ volatile unsigned short wfill[13]; /* U Reserved for expansion */
++
++ volatile unsigned char num; /* U Channel number */
++ volatile unsigned char ract; /* U Receiver active counter */
++ volatile unsigned char bstat; /* U Break status bits */
++ volatile unsigned char tbusy; /* W Transmit busy */
++ volatile unsigned char iempty; /* W Transmit empty event enable */
++ volatile unsigned char ilow; /* W Transmit low-water event enable */
++ volatile unsigned char idata; /* W Receive data interrupt enable */
++ volatile unsigned char eflag; /* U Host event flags */
++
++ volatile unsigned char tflag; /* U Transmit flags */
++ volatile unsigned char rflag; /* U Receive flags */
++ volatile unsigned char xmask; /* U Transmit ready flags */
++ volatile unsigned char xval; /* U Transmit ready value */
++ volatile unsigned char m_stat; /* RC Modem status bits */
++ volatile unsigned char m_change; /* U Modem bits which changed */
++ volatile unsigned char m_int; /* W Modem interrupt enable bits */
++ volatile unsigned char m_last; /* U Last modem status */
++
++ volatile unsigned char mtran; /* C Unreported modem trans */
++ volatile unsigned char orun; /* C Buffer overrun occurred */
++ volatile unsigned char astartc; /* W Auxiliary Xon char */
++ volatile unsigned char astopc; /* W Auxiliary Xoff char */
++ volatile unsigned char startc; /* W Xon character */
++ volatile unsigned char stopc; /* W Xoff character */
++ volatile unsigned char vnextc; /* W Vnext character */
++ volatile unsigned char hflow; /* C Software flow control */
++
++ volatile unsigned char fillc; /* U Delay Fill character */
++ volatile unsigned char ochar; /* U Saved output character */
++ volatile unsigned char omask; /* U Output character mask */
++
++ volatile unsigned char bfill[13]; /* U Reserved for expansion */
++
++ volatile unsigned char scc[16]; /* U SCC registers */
++};
++
++
++/************************************************************************
++ * FEP supported functions
++ ************************************************************************/
++#define SRLOW 0xe0 /* Set receive low water */
++#define SRHIGH 0xe1 /* Set receive high water */
++#define FLUSHTX 0xe2 /* Flush transmit buffer */
++#define PAUSETX 0xe3 /* Pause data transmission */
++#define RESUMETX 0xe4 /* Resume data transmission */
++#define SMINT 0xe5 /* Set Modem Interrupt */
++#define SAFLOWC 0xe6 /* Set Aux. flow control chars */
++#define SBREAK 0xe8 /* Send break */
++#define SMODEM 0xe9 /* Set 8530 modem control lines */
++#define SIFLAG 0xea /* Set UNIX iflags */
++#define SFLOWC 0xeb /* Set flow control characters */
++#define STLOW 0xec /* Set transmit low water mark */
++#define RPAUSE 0xee /* Pause recieve */
++#define RRESUME 0xef /* Resume receive */
++#define BUFSETALL 0xf2 /* Set Tx & Rx buffer size avail*/
++#define SOFLAG 0xf3 /* Set UNIX oflags */
++#define SHFLOW 0xf4 /* Set hardware handshake */
++#define SCFLAG 0xf5 /* Set UNIX cflags */
++#define SVNEXT 0xf6 /* Set VNEXT character */
++#define SPINTFC 0xfc /* Set VNEXT character */
++
++
++/************************************************************************
++ * Event flags.
++ ************************************************************************/
++#define IFBREAK 0x01 /* Break received */
++#define IFTLW 0x02 /* Transmit low water */
++#define IFTEM 0x04 /* Transmitter empty */
++#define IFDATA 0x08 /* Receive data present */
++#define IFMODEM 0x20 /* Modem status change */
++
++/************************************************************************
++ * Modem flags
++ ************************************************************************/
++# define DM_RTS 0x02 /* Request to send */
++# define DM_CD 0x80 /* Carrier detect */
++# define DM_DSR 0x20 /* Data set ready */
++# define DM_CTS 0x10 /* Clear to send */
++# define DM_RI 0x40 /* Ring indicator */
++# define DM_DTR 0x01 /* Data terminal ready */
++
++
++
++#endif
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/dgap_mgmt.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/dgap_mgmt.c 2003-09-27 11:38:18.448723752 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/dgap_mgmt.c 2003-09-27 11:38:20.955342688 +0800
+@@ -0,0 +1,719 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ * Scott H Kilau <Scott_Kilau at digi dot com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2, or (at your option)
++ * any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
++ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
++ * PURPOSE. See the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ *
++ * NOTE TO LINUX KERNEL HACKERS: DO NOT REFORMAT THIS CODE!
++ *
++ * This is shared code between Digi's CVS archive and the
++ * Linux Kernel sources.
++ * Changing the source just for reformatting needlessly breaks
++ * our CVS diff history.
++ *
++ * Send any bug fixes/changes to: Eng.Linux at digi dot com.
++ * Thank you.
++ *
++ */
++
++/************************************************************************
++ *
++ * This file implements the mgmt functionality for the
++ * FEP5 based product lines.
++ *
++ ************************************************************************
++ * $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++ */
++
++#define __NO_VERSION__
++#include "dgap_driver.h"
++#include <linux/ctype.h>
++#include "dgap_types.h"
++#include "dgap_fep5.h"
++#include "dgap_parse.h"
++#include "dgap_mgmt.h"
++#include "dgap_downld.h"
++#include "dgap_tty.h"
++
++#include <linux/tty_driver.h>
++#include <linux/tty_flip.h>
++
++/*
++ * external variables
++ */
++extern int dgap_debug;
++extern spinlock_t dgap_global_lock;
++extern int dgap_NumBoards;
++extern struct board_t *dgap_Board[];
++
++/* This holds the status of the KME buffer */
++static int dgap_kmebusy = 0;
++
++/* Our "in use" variables, to enforce 1 open only */
++static int dgap_mgmt_in_use = 0;
++static int dgap_downld_in_use = 0;
++
++
++/*
++ * dgap_mgmt_open()
++ *
++ * Open the mgmt/downld/dpa device
++ */
++int dgap_mgmt_open(struct inode *inode, struct file *file)
++{
++ unsigned long lock_flags;
++ unsigned int minor = DGAP_MINOR(inode);
++
++ DPR_MGMT(("dgap_mgmt_open start.\n"));
++
++ DGAP_LOCK(dgap_global_lock, lock_flags);
++
++ /* mgmt device */
++ if (minor == MGMT_MGMT) {
++ /* Only allow 1 open at a time on mgmt device */
++ if (dgap_mgmt_in_use) {
++ DGAP_UNLOCK(dgap_global_lock, lock_flags);
++ return (-EBUSY);
++ }
++ dgap_mgmt_in_use++;
++ }
++ /* downld device */
++ else if (minor == MGMT_DOWNLD) {
++ /* Only allow 1 open at a time on downld device */
++ if (dgap_downld_in_use) {
++ DGAP_UNLOCK(dgap_global_lock, lock_flags);
++ return (-EBUSY);
++ }
++ dgap_downld_in_use++;
++ }
++ else {
++ DGAP_UNLOCK(dgap_global_lock, lock_flags);
++ return (-ENXIO);
++ }
++
++ DGAP_UNLOCK(dgap_global_lock, lock_flags);
++
++ DPR_MGMT(("dgap_mgmt_open finish.\n"));
++
++ return 0;
++}
++
++/*
++ * dgap_mgmt_close()
++ *
++ * Open the mgmt/dpa device
++ */
++int dgap_mgmt_close(struct inode *inode, struct file *file)
++{
++ unsigned long lock_flags;
++ unsigned int minor = DGAP_MINOR(inode);
++
++ DPR_MGMT(("dgap_mgmt_close start.\n"));
++
++ DGAP_LOCK(dgap_global_lock, lock_flags);
++
++ /* mgmt device */
++ if (minor == MGMT_MGMT) {
++ if (dgap_mgmt_in_use) {
++ dgap_mgmt_in_use = 0;
++ }
++ }
++ /* downld device */
++ else if (minor == MGMT_DOWNLD) {
++ if (dgap_downld_in_use) {
++ dgap_downld_in_use = 0;
++ }
++ }
++
++ DGAP_UNLOCK(dgap_global_lock, lock_flags);
++
++ DPR_MGMT(("dgap_mgmt_close finish.\n"));
++
++ return 0;
++}
++
++
++/*
++ * dgap_mgmt_ioctl()
++ *
++ * ioctl the mgmt/dpa device
++ */
++
++int dgap_mgmt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
++{
++ unsigned long lock_flags;
++ int error = 0;
++ int i = 0;
++ struct board_t *brd;
++ static struct downldio dlio;
++
++ DPR_MGMT(("dgap_mgmt_ioctl start.\n"));
++
++ switch (cmd) {
++
++ case DIGI_DLREQ_GET:
++ {
++
++get_service:
++
++ DGAP_LOCK(dgap_global_lock, lock_flags);
++
++ if (dgap_driver_state == DRIVER_NEED_CONFIG_LOAD) {
++
++ dgap_driver_state = DRIVER_REQUESTED_CONFIG;
++
++ dlio.req_type = DLREQ_CONFIG;
++ dlio.bdid = 0;
++ dlio.image.fi.type = 0;
++
++ DGAP_UNLOCK(dgap_global_lock, lock_flags);
++
++ if (copy_to_user((void *) arg, &dlio, sizeof(struct downldio))) {
++ DGAP_LOCK(dgap_global_lock, lock_flags);
++ dgap_driver_state = DRIVER_NEED_CONFIG_LOAD;
++ DGAP_UNLOCK(dgap_global_lock, lock_flags);
++ return(-EFAULT);
++ }
++
++ return(0);
++ }
++
++ DGAP_UNLOCK(dgap_global_lock, lock_flags);
++
++ /*
++ * Loop thru each board.
++ * Check state, force state machine to start running.
++ */
++ for (i = 0; i < dgap_NumBoards; i++ ) {
++
++ brd = dgap_Board[i];
++
++ DGAP_LOCK(brd->bd_lock, lock_flags);
++
++ switch (brd->state) {
++
++ case NEED_DEVICE_CREATION:
++
++ /*
++ * Let go of lock, tty_register() (and us also)
++ * does a non-atomic malloc, so it would be
++ * possible to deadlock the system if the
++ * malloc went to sleep.
++ */
++ DGAP_UNLOCK(brd->bd_lock, lock_flags);
++ dgap_tty_register(brd);
++ DGAP_LOCK(brd->bd_lock, lock_flags);
++ dgap_finalize_board_init(brd);
++
++ brd->state = REQUESTED_DEVICE_CREATION;
++
++ dlio.req_type = DLREQ_DEVCREATE;
++ dlio.bdid = i;
++ dlio.image.fi.type = brd->dpatype;
++
++ DGAP_UNLOCK(brd->bd_lock, lock_flags);
++
++ if (copy_to_user((void *) arg, &dlio, sizeof(struct downldio))) {
++ DGAP_LOCK(brd->bd_lock, lock_flags);
++ brd->state = NEED_DEVICE_CREATION;
++ DGAP_UNLOCK(brd->bd_lock, lock_flags);
++ return(-EFAULT);
++ }
++
++ return(0);
++
++ case NEED_BIOS_LOAD:
++
++ brd->state = REQUESTED_BIOS;
++
++ dlio.req_type = DLREQ_BIOS;
++ dlio.bdid = i;
++ dlio.image.fi.type = brd->dpatype;
++
++ DGAP_UNLOCK(brd->bd_lock, lock_flags);
++ if (copy_to_user((void *) arg, &dlio, sizeof(struct downldio))) {
++ DGAP_LOCK(brd->bd_lock, lock_flags);
++ brd->state = NEED_BIOS_LOAD;
++ DGAP_UNLOCK(brd->bd_lock, lock_flags);
++ return(-EFAULT);
++ }
++
++ return(0);
++
++ case NEED_FEP_LOAD:
++ brd->state = REQUESTED_FEP;
++
++ dlio.req_type = DLREQ_FEP;
++ dlio.bdid = i;
++ dlio.image.fi.type = brd->dpatype;
++
++ DGAP_UNLOCK(brd->bd_lock, lock_flags);
++
++ if (copy_to_user((void *) arg, &dlio, sizeof(struct downldio))) {
++ DGAP_LOCK(brd->bd_lock, lock_flags);
++ brd->state = NEED_FEP_LOAD;
++ DGAP_UNLOCK(brd->bd_lock, lock_flags);
++ return(-EFAULT);
++ }
++ return(0);
++
++ default:
++ DGAP_UNLOCK(brd->bd_lock, lock_flags);
++ break;
++
++ }
++
++ DGAP_LOCK(brd->bd_lock, lock_flags);
++
++ switch (brd->conc_dl_status) {
++
++ case NEED_CONCENTRATOR:
++ {
++ u16 offset = 0;
++ char *vaddr;
++ struct downld_t *to_dp;
++
++ vaddr = brd->re_map_membase;
++ if (!vaddr) {
++ brd->conc_dl_status = NO_PENDING_CONCENTRATOR_REQUESTS;
++ DGAP_UNLOCK(brd->bd_lock, lock_flags);
++ break;
++ }
++
++ dlio.req_type = DLREQ_CONC;
++ dlio.bdid = i;
++
++ offset = readw((u16 *) (vaddr + DOWNREQ));
++ to_dp = (struct downld_t *) (vaddr + (int) offset);
++
++ if (!to_dp) {
++ brd->conc_dl_status = NO_PENDING_CONCENTRATOR_REQUESTS;
++ DGAP_UNLOCK(brd->bd_lock, lock_flags);
++ break;
++ }
++
++ memcpy(&dlio.image.dl, to_dp, sizeof(struct downld_t));
++
++ brd->conc_dl_status = REQUESTED_CONCENTRATOR;
++
++ DGAP_UNLOCK(brd->bd_lock, lock_flags);
++
++ if (copy_to_user((void *) arg, &dlio, sizeof(struct downldio))) {
++ DGAP_LOCK(brd->bd_lock, lock_flags);
++ brd->conc_dl_status = NEED_CONCENTRATOR;
++ DGAP_UNLOCK(brd->bd_lock, lock_flags);
++ return(-EFAULT);
++ }
++
++ return(0);
++ }
++
++ default:
++ DGAP_UNLOCK(brd->bd_lock, lock_flags);
++ break;
++ }
++ }
++
++ /*
++ * Go to sleep waiting for the driver to signal an event to us.
++ */
++ error = wait_event_interruptible(dgap_dl_wait, (dgap_dl_action));
++
++ DGAP_LOCK(dgap_dl_lock, lock_flags);
++ dgap_dl_action = 0;
++ DGAP_UNLOCK(dgap_dl_lock, lock_flags);
++
++ /* Break out of ioctl if user cancelled us */
++ if (error)
++ break;
++
++ goto get_service;
++
++ }
++
++ case DIGI_DLREQ_SET:
++ {
++ uchar *uaddr = NULL;
++
++ if (copy_from_user((char *) &dlio, (char *) arg, sizeof(struct downldio))) {
++ return (-EFAULT);
++ }
++
++ if (dlio.req_type == DLREQ_CONFIG) {
++
++ uaddr = (uchar *) arg +
++ (int) ( ((struct downldio *)0)->image.fi.fepimage);
++
++ dgap_do_config_load(uaddr, dlio.image.fi.len);
++ dgap_after_config_loaded();
++
++ DGAP_LOCK(dgap_global_lock, lock_flags);
++ dgap_driver_state = DRIVER_READY;
++ DGAP_UNLOCK(dgap_global_lock, lock_flags);
++
++ break;
++
++ }
++
++ if (dlio.bdid < 0 || dlio.bdid > dgap_NumBoards) {
++ return(-ENXIO);
++ }
++
++ brd = dgap_Board[dlio.bdid];
++
++ switch(dlio.req_type) {
++
++ case DLREQ_BIOS:
++ if (brd->state == BOARD_FAILED || brd->state == BOARD_READY) {
++ break;
++ }
++
++ if (dlio.image.fi.type == -1) {
++ DGAP_LOCK(brd->bd_lock, lock_flags);
++ brd->state = BOARD_FAILED;
++ brd->dpastatus = BD_NOBIOS;
++ DGAP_UNLOCK(brd->bd_lock, lock_flags);
++ break;
++ }
++
++
++ uaddr = (uchar *) arg +
++ (int) ( ((struct downldio *)0)->image.fi.fepimage);
++
++ dgap_do_bios_load(brd, uaddr, dlio.image.fi.len);
++
++ break;
++ case DLREQ_FEP:
++ if (brd->state == BOARD_FAILED || brd->state == BOARD_READY) {
++ break;
++ }
++
++ if (dlio.image.fi.type == -1) {
++ DGAP_LOCK(brd->bd_lock, lock_flags);
++ brd->state = BOARD_FAILED;
++ brd->dpastatus = BD_NOBIOS;
++ DGAP_UNLOCK(brd->bd_lock, lock_flags);
++ break;
++ }
++
++ uaddr = (uchar *) arg +
++ (int) ( ((struct downldio *)0)->image.fi.fepimage);
++
++ dgap_do_fep_load(brd, uaddr, dlio.image.fi.len);
++
++ break;
++
++ case DLREQ_CONC:
++
++ if (brd->state == BOARD_FAILED) {
++ break;
++ }
++
++ if (dlio.image.fi.type == -1) {
++ break;
++ }
++
++ uaddr = (char *) &dlio.image.dl;
++ dgap_do_conc_load(brd, uaddr, sizeof(struct downld_t));
++
++ break;
++
++ case DLREQ_DEVCREATE:
++ if (brd->state == BOARD_FAILED || brd->state == BOARD_READY) {
++ break;
++ }
++
++ DGAP_LOCK(brd->bd_lock, lock_flags);
++ brd->state = FINISHED_DEVICE_CREATION;
++ DGAP_UNLOCK(brd->bd_lock, lock_flags);
++
++ break;
++
++ }
++
++ break;
++ }
++
++
++ case DIGI_GETDD:
++ {
++ /*
++ * This returns the total number of boards
++ * in the system, as well as driver version
++ * and has space for a reserved entry
++ */
++ struct digi_dinfo ddi;
++
++ DGAP_LOCK(dgap_global_lock, lock_flags);
++
++ ddi.dinfo_nboards = dgap_NumBoards;
++ sprintf(ddi.dinfo_version, "%s", DG_PART);
++
++ DGAP_UNLOCK(dgap_global_lock, lock_flags);
++
++ DPR_MGMT(("DIGI_GETDD returning numboards: %lu version: %s\n",
++ ddi.dinfo_nboards, ddi.dinfo_version));
++
++ copy_to_user((char *) arg, &ddi, sizeof (ddi));
++ break;
++ }
++
++ case DIGI_GETBD:
++ {
++ int brd;
++ int error = 0;
++
++ struct digi_info di;
++
++ if (copy_from_user(&brd, (unsigned int *) arg, sizeof(int))) {
++ return(-EFAULT);
++ }
++
++ if ((error = verify_area(VERIFY_WRITE, (char*) arg, sizeof(di)))) {
++ return (error);
++ }
++
++ DPR_MGMT(("DIGI_GETBD asking about board: %d\n", brd));
++
++ if ((brd < 0) || (brd > dgap_NumBoards) || (dgap_NumBoards == 0))
++ return (-ENODEV);
++
++ memset(&di, 0, sizeof(di));
++
++ di.info_bdnum = brd;
++
++ DGAP_LOCK(dgap_Board[brd]->bd_lock, lock_flags);
++
++ di.info_bdtype = dgap_Board[brd]->dpatype;
++ di.info_bdstate = dgap_Board[brd]->dpastatus;
++ di.info_ioport = (ulong) dgap_Board[brd]->port;
++ di.info_physaddr = (ulong) dgap_Board[brd]->membase;
++ di.info_physsize = (ulong) dgap_Board[brd]->membase - dgap_Board[brd]->membase_end;
++ if (dgap_Board[brd]->state != BOARD_FAILED)
++ di.info_nports = dgap_Board[brd]->nasync;
++ else
++ di.info_nports = 0;
++
++ DGAP_UNLOCK(dgap_Board[brd]->bd_lock, lock_flags);
++
++ DPR_MGMT(("DIGI_GETBD returning type: %x state: %x ports: %x size: %lx\n",
++ di.info_bdtype, di.info_bdstate, di.info_nports, di.info_physsize));
++
++ copy_to_user((char *) arg, &di, sizeof (di));
++ break;
++ }
++
++ case DIGI_KME:
++ {
++ int itmp, jtmp;
++ unchar *memaddr = NULL;
++ struct rw_t kme;
++ struct rw_t *mp = NULL;
++ int brd = 0;
++ struct board_t *bd;
++
++ /* This ioctl takes an argument of type 'rw_t'
++ * and uses it to interact with the KME struct
++ * located on the digiboard itself.
++ */
++ if ((error = verify_area(VERIFY_READ, (char*)arg, sizeof(kme))))
++ return(error);
++
++ copy_from_user(&kme, (char*)arg, sizeof(kme));
++
++ if (kme.rw_size > 128)
++ kme.rw_size = 128;
++
++ brd = kme.rw_board;
++
++ DPR_MGMT(("dgap_mgmt: DIGI_KME: %s asked for board %d\n", current->comm, brd));
++
++ /* Sanity Checking... */
++ if ((brd < 0) || (brd > dgap_NumBoards) || (dgap_NumBoards == 0))
++ return (-ENODEV);
++
++ bd = dgap_Board[brd];
++
++ DGAP_LOCK(dgap_Board[brd]->bd_lock, lock_flags);
++
++ if (bd->state != BOARD_READY) {
++ DGAP_UNLOCK(dgap_Board[brd]->bd_lock, lock_flags);
++ return(-ENODEV);
++ }
++
++ memaddr = bd->re_map_membase;
++
++ DGAP_UNLOCK(dgap_Board[brd]->bd_lock, lock_flags);
++
++ /* If the concentrator number is 0... */
++ if (kme.rw_conc == 0 && kme.rw_addr < 0x100000) {
++ int page = 0;
++ int addr = kme.rw_addr;
++ int size = kme.rw_size;
++ caddr_t data = (caddr_t) kme.rw_data;
++
++ while ((itmp = size)) {
++
++ switch (kme.rw_req) {
++ case RW_READ:
++ {
++ register caddr_t cp1 = (char *)memaddr + addr;
++ register caddr_t cp2 = kme.rw_data;
++
++ DPR_MGMT(("RW_READ CARDMEM - page=%d rw_addr=0x%lx rw_size=%x\n",
++ page, kme.rw_addr, kme.rw_size));
++
++ for (jtmp = 0; jtmp < itmp; jtmp++) {
++ *cp2++ = readb(cp1++);
++ }
++ }
++
++ break;
++
++ case RW_WRITE:
++ {
++ register caddr_t cp1 = memaddr + addr;
++ register caddr_t cp2 = data;
++
++ DPR_MGMT(("RW_WRITE CARDMEM - page=%d rw_addr=0x%lx rw_size=%d\n",
++ page, kme.rw_addr, kme.rw_size));
++
++ for (jtmp = 0; jtmp < itmp; jtmp++) {
++ writeb(*cp2++, cp1++);
++ }
++ }
++ break;
++ }
++
++ addr += itmp;
++ data += itmp;
++ size -= itmp;
++
++ }
++
++ }
++ else {
++
++ /*
++ * Read/Write memory in a REMOTE CONCENTRATOR..
++ * There is only 1 buffer, so do mutual
++ * exclusion to make sure only one KME
++ * request is pending...
++ */
++
++ mp = (struct rw_t *) (memaddr + KMEMEM);
++
++ while (dgap_kmebusy != 0) {
++ dgap_kmebusy = 2;
++ error = wait_event_interruptible(bd->kme_wait, (!dgap_kmebusy));
++ if (error)
++ goto endkme;
++ }
++
++ dgap_kmebusy = 1;
++
++ /* Copy KME request to the board.. */
++
++ mp->rw_board = kme.rw_board;
++ mp->rw_conc = kme.rw_conc;
++ mp->rw_reserved = kme.rw_reserved;
++ memcpy(&mp->rw_addr, &kme.rw_addr, sizeof(int));
++ memcpy(&mp->rw_size, &kme.rw_size, sizeof(short));
++
++ if(kme.rw_req == RW_WRITE) {
++ register caddr_t cp1 = (caddr_t) mp->rw_data;
++ register caddr_t cp2 = (caddr_t) kme.rw_data;
++
++ DPR_MGMT(("RW_WRITE CONCMEM - rw_addr=0x%lx rw_size=%d\n",
++ kme.rw_addr, kme.rw_size));
++
++ for (jtmp = 0; jtmp < (int) kme.rw_size; jtmp++) {
++ writeb(*cp2++, cp1++);
++ }
++ }
++
++ /* EXECUTE REQUEST */
++
++ mp->rw_req = kme.rw_req;
++
++ /*
++ * Wait for the board to process the
++ * request, but limit the wait to 2 secs
++ */
++
++ for (itmp = jiffies + (2 * HZ); mp->rw_req;) {
++ if(jiffies >= itmp) {
++ error = ENXIO;
++ /* Set request back to 0.. */
++ mp->rw_req = 0;
++ goto endkme;
++ }
++
++ schedule_timeout(HZ / 10);
++ }
++
++ /*
++ * Since this portion of code is looksee
++ * ported from the HPUX EMUX code, i'm
++ * leaving OUT a portion of that code where
++ * the HP/UX code actually puts the process
++ * to sleep for some reason
++ */
++ if (mp->rw_size < kme.rw_size)
++ memcpy(&kme.rw_size, &mp->rw_size, sizeof(short));
++
++ /* Copy the READ data back to the source buffer... */
++ if (kme.rw_req == RW_READ) {
++ register caddr_t cp1 = (caddr_t) mp->rw_data;
++ register caddr_t cp2 = (caddr_t) kme.rw_data;
++
++ DPR_MGMT(("RW_READ CONCMEM - rw_addr=0x%lx rw_size=%d\n",
++ kme.rw_addr, kme.rw_size));
++
++ for (jtmp = 0; jtmp < (int) kme.rw_size; jtmp++) {
++ *cp2++ = readb(cp1++);
++ }
++ }
++
++ /*
++ * Common exit point for code sharing the
++ * kme buffer. Before exiting, always wake
++ * another process waiting for the buffer
++ */
++
++ endkme:
++
++ if (dgap_kmebusy != 1)
++ wake_up_interruptible(&bd->kme_wait);
++ dgap_kmebusy = 0;
++ if(error == ENXIO)
++ return(-EINVAL);
++ }
++
++ /* Copy the whole (Possibly Modified) mess */
++ /* back out to user space... */
++
++ if (!error) {
++ copy_to_user((char *) arg, &kme, sizeof(kme));
++ return(0);
++ }
++ }
++ }
++
++ DPR_MGMT(("dgap_mgmt_ioctl finish.\n"));
++
++ return 0;
++}
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/dgap_mgmt.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/dgap_mgmt.h 2003-09-27 11:38:18.448723752 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/dgap_mgmt.h 2003-09-27 11:38:20.956342536 +0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ * Scott H Kilau <Scott_Kilau at digi dot com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2, or (at your option)
++ * any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
++ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
++ * PURPOSE. See the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * NOTE: THIS IS A SHARED HEADER. DO NOT CHANGE CODING STYLE!!!
++ */
++
++#ifndef __DGAP_MGMT_H
++#define __DGAP_MGMT_H
++
++#define MGMT_MGMT 0
++#define MGMT_DOWNLD 1
++
++int dgap_mgmt_open(struct inode *inode, struct file *file);
++int dgap_mgmt_close(struct inode *inode, struct file *file);
++int dgap_mgmt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
++
++#endif
++
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/dgap_parse.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/dgap_parse.c 2003-09-27 11:38:18.448723752 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/dgap_parse.c 2003-09-27 11:38:20.958342232 +0800
+@@ -0,0 +1,1299 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ * Scott H Kilau <Scott_Kilau at digi dot com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2, or (at your option)
++ * any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
++ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
++ * PURPOSE. See the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ *
++ * NOTE TO LINUX KERNEL HACKERS: DO NOT REFORMAT THIS CODE!
++ *
++ * This is shared code between Digi's CVS archive and the
++ * Linux Kernel sources.
++ * Changing the source just for reformatting needlessly breaks
++ * our CVS diff history.
++ *
++ * Send any bug fixes/changes to: Eng.Linux at digi dot com.
++ * Thank you.
++ *
++ *
++ *****************************************************************************
++ *
++ * dgap_parse.c - Parses the configuration information from the input file.
++ *
++ * $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++ *
++ */
++
++#define __NO_VERSION__
++#include <linux/ctype.h>
++#include "dgap_types.h"
++#include "dgap_fep5.h"
++#include "dgap_driver.h"
++#include "dgap_conf.h"
++
++/*
++ * Function prototypes.
++ */
++static int dgap_gettok(char **in, struct cnode *p);
++static char *dgap_getword(char **in);
++static char *dgap_savestring(char *s);
++static struct cnode *dgap_newnode(int t);
++static int dgap_checknode(struct cnode *p);
++static void dgap_err(char *s);
++
++/*
++ * Any needed external variables...
++ */
++extern int dgap_debug;
++
++/*
++ * Our needed internal static variables...
++ */
++static struct cnode dgap_head;
++#define MAXCWORD 200
++static char dgap_cword[MAXCWORD];
++
++struct toklist {
++ int token;
++ char *string;
++};
++
++static struct toklist tlist[] = {
++ { BEGIN, "config_begin" },
++ { END, "config_end" },
++ { BOARD, "board" },
++ { PCX, "Digi_AccelePort_C/X_PCI" }, /* C/X_PCI */
++ { PEPC, "Digi_AccelePort_EPC/X_PCI" }, /* EPC/X_PCI */
++ { PPCM, "Digi_AccelePort_Xem_PCI" }, /* PCI/Xem */
++ { APORT2_920P, "Digi_AccelePort_2r_920_PCI" },
++ { APORT4_920P, "Digi_AccelePort_4r_920_PCI" },
++ { APORT8_920P, "Digi_AccelePort_8r_920_PCI" },
++ { PAPORT4, "Digi_AccelePort_4r_PCI(EIA-232/RS-422)" },
++ { PAPORT8, "Digi_AccelePort_8r_PCI(EIA-232/RS-422)" },
++ { IO, "io" },
++ { LINE, "line" },
++ { CONC, "conc" },
++ { CONC, "concentrator" },
++ { CX, "cx" },
++ { EPC, "epc" },
++ { MOD, "module" },
++ { ID, "id" },
++ { STARTO, "start" },
++ { SPEED, "speed" },
++ { CABLE, "cable" },
++ { CONNECT, "connect" },
++ { METHOD, "method" },
++ { STATUS, "status" },
++ { CUSTOM, "Custom" },
++ { BASIC, "Basic" },
++ { MEM, "mem" },
++ { MEM, "memory" },
++ { PORTS, "ports" },
++ { MODEM, "modem" },
++ { NPORTS, "nports" },
++ { TTYN, "ttyname" },
++ { CU, "cuname" },
++ { PRINT, "prname" },
++ { CMAJOR, "major" },
++ { ALTPIN, "altpin" },
++ { USEINTR, "useintr" },
++ { TTSIZ, "ttysize" },
++ { CHSIZ, "chsize" },
++ { BSSIZ, "boardsize" },
++ { UNTSIZ, "schedsize" },
++ { F2SIZ, "f2200size" },
++ { VPSIZ, "vpixsize" },
++ { 0, NULL }
++};
++
++
++/*
++ * Parse a configuration file read into memory as a string.
++ */
++int dgap_parsefile(char **in, int Remove)
++{
++ struct cnode *p, *brd, *line, *conc;
++ int rc;
++ char *s = NULL, *s2 = NULL;
++ int linecnt = 0;
++
++ p = &dgap_head;
++ brd = line = conc = NULL;
++
++ /* perhaps we are adding to an existing list? */
++ while (p->next != NULL) {
++ p = p->next;
++ }
++
++ /* file must start with a BEGIN */
++ while ( (rc = dgap_gettok(in,p)) != BEGIN ) {
++ if (rc == 0) {
++ dgap_err("unexpected EOF");
++ return(-1);
++ }
++ }
++
++ for (; ; ) {
++ rc = dgap_gettok(in,p);
++ if (rc == 0) {
++ dgap_err("unexpected EOF");
++ return(-1);
++ }
++
++ switch (rc) {
++ case 0:
++ dgap_err("unexpected end of file");
++ return(-1);
++
++ case BEGIN: /* should only be 1 begin */
++ dgap_err("unexpected config_begin\n");
++ return(-1);
++
++ case END:
++ return(0);
++
++ case BOARD: /* board info */
++ if (dgap_checknode(p))
++ return(-1);
++ if ( (p->next = dgap_newnode(BNODE)) == NULL ) {
++ dgap_err("out of memory");
++ return(-1);
++ }
++ p = p->next;
++
++ p->u.board.status = dgap_savestring("No");
++ line = conc = NULL;
++ brd = p;
++ linecnt = -1;
++ break;
++
++ case APORT2_920P: /* AccelePort_4 */
++ if (p->type != BNODE) {
++ dgap_err("unexpected Digi_2r_920 string");
++ return(-1);
++ }
++ p->u.board.type = APORT2_920P;
++ p->u.board.v_type = 1;
++ DPR_INIT(("Adding Digi_2r_920 PCI to config...\n"));
++ break;
++
++ case APORT4_920P: /* AccelePort_4 */
++ if (p->type != BNODE) {
++ dgap_err("unexpected Digi_4r_920 string");
++ return(-1);
++ }
++ p->u.board.type = APORT4_920P;
++ p->u.board.v_type = 1;
++ DPR_INIT(("Adding Digi_4r_920 PCI to config...\n"));
++ break;
++
++ case APORT8_920P: /* AccelePort_8 */
++ if (p->type != BNODE) {
++ dgap_err("unexpected Digi_8r_920 string");
++ return(-1);
++ }
++ p->u.board.type = APORT8_920P;
++ p->u.board.v_type = 1;
++ DPR_INIT(("Adding Digi_8r_920 PCI to config...\n"));
++ break;
++
++ case PAPORT4: /* AccelePort_4 PCI */
++ if (p->type != BNODE) {
++ dgap_err("unexpected Digi_4r(PCI) string");
++ return(-1);
++ }
++ p->u.board.type = PAPORT4;
++ p->u.board.v_type = 1;
++ DPR_INIT(("Adding Digi_4r PCI to config...\n"));
++ break;
++
++ case PAPORT8: /* AccelePort_8 PCI */
++ if (p->type != BNODE) {
++ dgap_err("unexpected Digi_8r string");
++ return(-1);
++ }
++ p->u.board.type = PAPORT8;
++ p->u.board.v_type = 1;
++ DPR_INIT(("Adding Digi_8r PCI to config...\n"));
++ break;
++
++ case PCX: /* PCI C/X */
++ if (p->type != BNODE) {
++ dgap_err("unexpected Digi_C/X_(PCI) string");
++ return(-1);
++ }
++ p->u.board.type = PCX;
++ p->u.board.v_type = 1;
++ p->u.board.conc1 = 0;
++ p->u.board.conc2 = 0;
++ p->u.board.module1 = 0;
++ p->u.board.module2 = 0;
++ DPR_INIT(("Adding PCI C/X to config...\n"));
++ break;
++
++ case PEPC: /* PCI EPC/X */
++ if (p->type != BNODE) {
++ dgap_err("unexpected \"Digi_EPC/X_(PCI)\" string");
++ return(-1);
++ }
++ p->u.board.type = PEPC;
++ p->u.board.v_type = 1;
++ p->u.board.conc1 = 0;
++ p->u.board.conc2 = 0;
++ p->u.board.module1 = 0;
++ p->u.board.module2 = 0;
++ DPR_INIT(("Adding PCI EPC/X to config...\n"));
++ break;
++
++ case PPCM: /* PCI/Xem */
++ if (p->type != BNODE) {
++ dgap_err("unexpected PCI/Xem string");
++ return(-1);
++ }
++ p->u.board.type = PPCM;
++ p->u.board.v_type = 1;
++ p->u.board.conc1 = 0;
++ p->u.board.conc2 = 0;
++ DPR_INIT(("Adding PCI XEM to config...\n"));
++ break;
++
++ case IO: /* i/o port */
++ if (p->type != BNODE) {
++ dgap_err("IO port only vaild for boards");
++ return(-1);
++ }
++ s = dgap_getword(in);
++ if (s == NULL) {
++ dgap_err("unexpected end of file");
++ return(-1);
++ }
++ p->u.board.portstr = dgap_savestring(s);
++ p->u.board.port = (short)simple_strtol(s, &s2, 0);
++ if ((short)strlen(s) > (short)(s2 - s)) {
++ dgap_err("bad number for IO port");
++ return(-1);
++ }
++ p->u.board.v_port = 1;
++ DPR_INIT(("Adding IO (%s) to config...\n", s));
++ break;
++
++ case MEM: /* memory address */
++ if (p->type != BNODE) {
++ dgap_err("memory address only vaild for boards");
++ return(-1);
++ }
++ s = dgap_getword(in);
++ if (s == NULL) {
++ dgap_err("unexpected end of file");
++ return(-1);
++ }
++ p->u.board.addrstr = dgap_savestring(s);
++ p->u.board.addr = simple_strtoul(s, &s2, 0);
++ if ((int)strlen(s) > (int)(s2 - s)) {
++ dgap_err("bad number for memory address");
++ return(-1);
++ }
++ p->u.board.v_addr = 1;
++ DPR_INIT(("Adding MEM (%s) to config...\n", s));
++ break;
++
++ case METHOD:
++ if (p->type != BNODE) {
++ dgap_err("install method only vaild for boards");
++ return(-1);
++ }
++ s = dgap_getword(in);
++ if (s == NULL) {
++ dgap_err("unexpected end of file");
++ return(-1);
++ }
++ p->u.board.method = dgap_savestring(s);
++ p->u.board.v_method = 1;
++ DPR_INIT(("Adding METHOD (%s) to config...\n", s));
++ break;
++
++ case STATUS:
++ if (p->type != BNODE) {
++ dgap_err("config status only vaild for boards");
++ return(-1);
++ }
++ s = dgap_getword(in);
++ if (s == NULL) {
++ dgap_err("unexpected end of file");
++ return(-1);
++ }
++ p->u.board.status = dgap_savestring(s);
++ DPR_INIT(("Adding STATUS (%s) to config...\n", s));
++ break;
++
++ case NPORTS: /* number of ports */
++ if (p->type == BNODE) {
++ s = dgap_getword(in);
++ if (s == NULL) {
++ dgap_err("unexpected end of file");
++ return(-1);
++ }
++ p->u.board.nport = (char)simple_strtol(s, &s2, 0);
++ if ((int)strlen(s) > (int)(s2 - s)) {
++ dgap_err("bad number for number of ports");
++ return(-1);
++ }
++ p->u.board.v_nport = 1;
++ } else if (p->type == CNODE) {
++ s = dgap_getword(in);
++ if (s == NULL) {
++ dgap_err("unexpected end of file");
++ return(-1);
++ }
++ p->u.conc.nport = (char)simple_strtol(s, &s2, 0);
++ if ((int)strlen(s) > (int)(s2 - s)) {
++ dgap_err("bad number for number of ports");
++ return(-1);
++ }
++ p->u.conc.v_nport = 1;
++ } else if (p->type == MNODE) {
++ s = dgap_getword(in);
++ if (s == NULL) {
++ dgap_err("unexpected end of file");
++ return(-1);
++ }
++ p->u.module.nport = (char)simple_strtol(s, &s2, 0);
++ if ((int)strlen(s) > (int)(s2 - s)) {
++ dgap_err("bad number for number of ports");
++ return(-1);
++ }
++ p->u.module.v_nport = 1;
++ } else {
++ dgap_err("nports only valid for concentrators or modules");
++ return(-1);
++ }
++ DPR_INIT(("Adding NPORTS (%s) to config...\n", s));
++ break;
++
++ case ID: /* letter ID used in tty name */
++ s = dgap_getword(in);
++ if (s == NULL) {
++ dgap_err("unexpected end of file");
++ return(-1);
++ }
++
++ p->u.board.status = dgap_savestring(s);
++
++ if (p->type == CNODE) {
++ p->u.conc.id = dgap_savestring(s);
++ p->u.conc.v_id = 1;
++ } else if (p->type == MNODE) {
++ p->u.module.id = dgap_savestring(s);
++ p->u.module.v_id = 1;
++ } else {
++ dgap_err("id only valid for concentrators or modules");
++ return(-1);
++ }
++ DPR_INIT(("Adding ID (%s) to config...\n", s));
++ break;
++
++ case STARTO: /* start offset of ID */
++ if (p->type == BNODE) {
++ s = dgap_getword(in);
++ if (s == NULL) {
++ dgap_err("unexpected end of file");
++ return(-1);
++ }
++ p->u.board.start = simple_strtol(s, &s2, 0);
++ if ((int)strlen(s) > (int)(s2 - s)) {
++ dgap_err("bad number for start of tty count");
++ return(-1);
++ }
++ p->u.board.v_start = 1;
++ } else if (p->type == CNODE) {
++ s = dgap_getword(in);
++ if (s == NULL) {
++ dgap_err("unexpected end of file");
++ return(-1);
++ }
++ p->u.conc.start = simple_strtol(s, &s2, 0);
++ if ((int)strlen(s) > (int)(s2 - s)) {
++ dgap_err("bad number for start of tty count");
++ return(-1);
++ }
++ p->u.conc.v_start = 1;
++ } else if (p->type == MNODE) {
++ s = dgap_getword(in);
++ if (s == NULL) {
++ dgap_err("unexpected end of file");
++ return(-1);
++ }
++ p->u.module.start = simple_strtol(s, &s2, 0);
++ if ((int)strlen(s) > (int)(s2 - s)) {
++ dgap_err("bad number for start of tty count");
++ return(-1);
++ }
++ p->u.module.v_start = 1;
++ } else {
++ dgap_err("start only valid for concentrators or modules");
++ return(-1);
++ }
++ DPR_INIT(("Adding START (%s) to config...\n", s));
++ break;
++
++ case TTYN: /* tty name prefix */
++ if (dgap_checknode(p))
++ return(-1);
++ if ( (p->next = dgap_newnode(TNODE)) == NULL ) {
++ dgap_err("out of memory");
++ return(-1);
++ }
++ p = p->next;
++ if ( (s = dgap_getword(in)) == NULL ) {
++ dgap_err("unexpeced end of file");
++ return(-1);
++ }
++ if ( (p->u.ttyname = dgap_savestring(s)) == NULL ) {
++ dgap_err("out of memory");
++ return(-1);
++ }
++ DPR_INIT(("Adding TTY (%s) to config...\n", s));
++ break;
++
++ case CU: /* cu name prefix */
++ if (dgap_checknode(p))
++ return(-1);
++ if ( (p->next = dgap_newnode(CUNODE)) == NULL ) {
++ dgap_err("out of memory");
++ return(-1);
++ }
++ p = p->next;
++ if ( (s = dgap_getword(in)) == NULL ) {
++ dgap_err("unexpeced end of file");
++ return(-1);
++ }
++ if ( (p->u.cuname = dgap_savestring(s)) == NULL ) {
++ dgap_err("out of memory");
++ return(-1);
++ }
++ DPR_INIT(("Adding CU (%s) to config...\n", s));
++ break;
++
++ case LINE: /* line information */
++ if (dgap_checknode(p))
++ return(-1);
++ if (brd == NULL) {
++ dgap_err("must specify board before line info");
++ return(-1);
++ }
++ switch (brd->u.board.type) {
++ case PPCM:
++ dgap_err("line not vaild for PC/em");
++ return(-1);
++ }
++ if ( (p->next = dgap_newnode(LNODE)) == NULL ) {
++ dgap_err("out of memory");
++ return(-1);
++ }
++ p = p->next;
++ conc = NULL;
++ line = p;
++ linecnt++;
++ DPR_INIT(("Adding LINE to config...\n"));
++ break;
++
++ case CONC: /* concentrator information */
++ if (dgap_checknode(p))
++ return(-1);
++ if (line == NULL) {
++ dgap_err("must specify line info before concentrator");
++ return(-1);
++ }
++ if ( (p->next = dgap_newnode(CNODE)) == NULL ) {
++ dgap_err("out of memory");
++ return(-1);
++ }
++ p = p->next;
++ conc = p;
++ if (linecnt)
++ brd->u.board.conc2++;
++ else
++ brd->u.board.conc1++;
++
++ DPR_INIT(("Adding CONC to config...\n"));
++ break;
++
++ case CX: /* c/x type concentrator */
++ if (p->type != CNODE) {
++ dgap_err("cx only valid for concentrators");
++ return(-1);
++ }
++ p->u.conc.type = CX;
++ p->u.conc.v_type = 1;
++ DPR_INIT(("Adding CX to config...\n"));
++ break;
++
++ case EPC: /* epc type concentrator */
++ if (p->type != CNODE) {
++ dgap_err("cx only valid for concentrators");
++ return(-1);
++ }
++ p->u.conc.type = EPC;
++ p->u.conc.v_type = 1;
++ DPR_INIT(("Adding EPC to config...\n"));
++ break;
++
++ case MOD: /* EBI module */
++ if (dgap_checknode(p))
++ return(-1);
++ if (brd == NULL) {
++ dgap_err("must specify board info before EBI modules");
++ return(-1);
++ }
++ switch (brd->u.board.type) {
++ case PPCM:
++ linecnt = 0;
++ break;
++ default:
++ if (conc == NULL) {
++ dgap_err("must specify concentrator info before EBI module");
++ return(-1);
++ }
++ }
++ if ( (p->next = dgap_newnode(MNODE)) == NULL ) {
++ dgap_err("out of memory");
++ return(-1);
++ }
++ p = p->next;
++ if (linecnt)
++ brd->u.board.module2++;
++ else
++ brd->u.board.module1++;
++
++ DPR_INIT(("Adding MOD to config...\n"));
++ break;
++
++ case PORTS: /* ports type EBI module */
++ if (p->type != MNODE) {
++ dgap_err("ports only valid for EBI modules");
++ return(-1);
++ }
++ p->u.module.type = PORTS;
++ p->u.module.v_type = 1;
++ DPR_INIT(("Adding PORTS to config...\n"));
++ break;
++
++ case MODEM: /* ports type EBI module */
++ if (p->type != MNODE) {
++ dgap_err("modem only valid for modem modules");
++ return(-1);
++ }
++ p->u.module.type = MODEM;
++ p->u.module.v_type = 1;
++ DPR_INIT(("Adding MODEM to config...\n"));
++ break;
++
++ case CABLE:
++ if (p->type == LNODE) {
++ if ((s = dgap_getword(in)) == NULL) {
++ dgap_err("unexpected end of file");
++ return(-1);
++ }
++ p->u.line.cable = dgap_savestring(s);
++ p->u.line.v_cable = 1;
++ }
++ DPR_INIT(("Adding CABLE (%s) to config...\n", s));
++ break;
++
++ case SPEED: /* sync line speed indication */
++ if (p->type == LNODE) {
++ s = dgap_getword(in);
++ if (s == NULL) {
++ dgap_err("unexpected end of file");
++ return(-1);
++ }
++ p->u.line.speed = (char)simple_strtol(s, &s2, 0);
++ if ((short)strlen(s) > (short)(s2 - s)) {
++ dgap_err("bad number for line speed");
++ return(-1);
++ }
++ p->u.line.v_speed = 1;
++ } else if (p->type == CNODE) {
++ s = dgap_getword(in);
++ if (s == NULL) {
++ dgap_err("unexpected end of file");
++ return(-1);
++ }
++ p->u.conc.speed = (char)simple_strtol(s, &s2, 0);
++ if ((short)strlen(s) > (short)(s2 - s)) {
++ dgap_err("bad number for line speed");
++ return(-1);
++ }
++ p->u.conc.v_speed = 1;
++ } else {
++ dgap_err("speed valid only for lines or concentrators.");
++ return(-1);
++ }
++ DPR_INIT(("Adding SPEED (%s) to config...\n", s));
++ break;
++
++ case CONNECT:
++ if (p->type == CNODE) {
++ if ((s = dgap_getword(in)) == NULL) {
++ dgap_err("unexpected end of file");
++ return(-1);
++ }
++ p->u.conc.connect = dgap_savestring(s);
++ p->u.conc.v_connect = 1;
++ }
++ DPR_INIT(("Adding CONNECT (%s) to config...\n", s));
++ break;
++ case PRINT: /* transparent print name prefix */
++ if (dgap_checknode(p))
++ return(-1);
++ if ( (p->next = dgap_newnode(PNODE)) == NULL ) {
++ dgap_err("out of memory");
++ return(-1);
++ }
++ p = p->next;
++ if ( (s = dgap_getword(in)) == NULL ) {
++ dgap_err("unexpeced end of file");
++ return(-1);
++ }
++ if ( (p->u.printname = dgap_savestring(s)) == NULL ) {
++ dgap_err("out of memory");
++ return(-1);
++ }
++ DPR_INIT(("Adding PRINT (%s) to config...\n", s));
++ break;
++
++ case CMAJOR: /* major number */
++ if (dgap_checknode(p))
++ return(-1);
++ if ( (p->next = dgap_newnode(JNODE)) == NULL ) {
++ dgap_err("out of memory");
++ return(-1);
++ }
++ p = p->next;
++ s = dgap_getword(in);
++ if (s == NULL) {
++ dgap_err("unexpected end of file");
++ return(-1);
++ }
++ p->u.majornumber = simple_strtol(s, &s2, 0);
++ if ((int)strlen(s) > (int)(s2 - s)) {
++ dgap_err("bad number for major number");
++ return(-1);
++ }
++ DPR_INIT(("Adding CMAJOR (%s) to config...\n", s));
++ break;
++
++ case ALTPIN: /* altpin setting */
++ if (dgap_checknode(p))
++ return(-1);
++ if ( (p->next = dgap_newnode(ANODE)) == NULL ) {
++ dgap_err("out of memory");
++ return(-1);
++ }
++ p = p->next;
++ s = dgap_getword(in);
++ if (s == NULL) {
++ dgap_err("unexpected end of file");
++ return(-1);
++ }
++ p->u.altpin = simple_strtol(s, &s2, 0);
++ if ((int)strlen(s) > (int)(s2 - s)) {
++ dgap_err("bad number for altpin");
++ return(-1);
++ }
++ DPR_INIT(("Adding ALTPIN (%s) to config...\n", s));
++ break;
++
++ case USEINTR: /* enable interrupt setting */
++ if (dgap_checknode(p))
++ return(-1);
++ if ( (p->next = dgap_newnode(INTRNODE)) == NULL ) {
++ dgap_err("out of memory");
++ return(-1);
++ }
++ p = p->next;
++ s = dgap_getword(in);
++ if (s == NULL) {
++ dgap_err("unexpected end of file");
++ return(-1);
++ }
++ p->u.useintr = simple_strtol(s, &s2, 0);
++ if ((int)strlen(s) > (int)(s2 - s)) {
++ dgap_err("bad number for useintr");
++ return(-1);
++ }
++ DPR_INIT(("Adding USEINTR (%s) to config...\n", s));
++ break;
++
++ case TTSIZ: /* size of tty structure */
++ if (dgap_checknode(p))
++ return(-1);
++ if ( (p->next = dgap_newnode(TSNODE)) == NULL ) {
++ dgap_err("out of memory");
++ return(-1);
++ }
++ p = p->next;
++ s = dgap_getword(in);
++ if (s == NULL) {
++ dgap_err("unexpected end of file");
++ return(-1);
++ }
++ p->u.ttysize = simple_strtol(s, &s2, 0);
++ if ((int)strlen(s) > (int)(s2 - s)) {
++ dgap_err("bad number for ttysize");
++ return(-1);
++ }
++ DPR_INIT(("Adding TTSIZ (%s) to config...\n", s));
++ break;
++
++ case CHSIZ: /* channel structure size */
++ if (dgap_checknode(p))
++ return(-1);
++ if ( (p->next = dgap_newnode(CSNODE)) == NULL ) {
++ dgap_err("out of memory");
++ return(-1);
++ }
++ p = p->next;
++ s = dgap_getword(in);
++ if (s == NULL) {
++ dgap_err("unexpected end of file");
++ return(-1);
++ }
++ p->u.chsize = simple_strtol(s, &s2, 0);
++ if ((int)strlen(s) > (int)(s2 - s)) {
++ dgap_err("bad number for chsize");
++ return(-1);
++ }
++ DPR_INIT(("Adding CHSIZE (%s) to config...\n", s));
++ break;
++
++ case BSSIZ: /* board structure size */
++ if (dgap_checknode(p))
++ return(-1);
++ if ( (p->next = dgap_newnode(BSNODE)) == NULL ) {
++ dgap_err("out of memory");
++ return(-1);
++ }
++ p = p->next;
++ s = dgap_getword(in);
++ if (s == NULL) {
++ dgap_err("unexpected end of file");
++ return(-1);
++ }
++ p->u.bssize = simple_strtol(s, &s2, 0);
++ if ((int)strlen(s) > (int)(s2 - s)) {
++ dgap_err("bad number for bssize");
++ return(-1);
++ }
++ DPR_INIT(("Adding BSSIZ (%s) to config...\n", s));
++ break;
++
++ case UNTSIZ: /* sched structure size */
++ if (dgap_checknode(p))
++ return(-1);
++ if ( (p->next = dgap_newnode(USNODE)) == NULL ) {
++ dgap_err("out of memory");
++ return(-1);
++ }
++ p = p->next;
++ s = dgap_getword(in);
++ if (s == NULL) {
++ dgap_err("unexpected end of file");
++ return(-1);
++ }
++ p->u.unsize = simple_strtol(s, &s2, 0);
++ if ((int)strlen(s) > (int)(s2 - s)) {
++ dgap_err("bad number for schedsize");
++ return(-1);
++ }
++ DPR_INIT(("Adding UNTSIZ (%s) to config...\n", s));
++ break;
++
++ case F2SIZ: /* f2200 structure size */
++ if (dgap_checknode(p))
++ return(-1);
++ if ( (p->next = dgap_newnode(FSNODE)) == NULL ) {
++ dgap_err("out of memory");
++ return(-1);
++ }
++ p = p->next;
++ s = dgap_getword(in);
++ if (s == NULL) {
++ dgap_err("unexpected end of file");
++ return(-1);
++ }
++ p->u.f2size = simple_strtol(s, &s2, 0);
++ if ((int)strlen(s) > (int)(s2 - s)) {
++ dgap_err("bad number for f2200size");
++ return(-1);
++ }
++ DPR_INIT(("Adding F2SIZ (%s) to config...\n", s));
++ break;
++
++ case VPSIZ: /* vpix structure size */
++ if (dgap_checknode(p))
++ return(-1);
++ if ( (p->next = dgap_newnode(VSNODE)) == NULL ) {
++ dgap_err("out of memory");
++ return(-1);
++ }
++ p = p->next;
++ s = dgap_getword(in);
++ if (s == NULL) {
++ dgap_err("unexpected end of file");
++ return(-1);
++ }
++ p->u.vpixsize = simple_strtol(s, &s2, 0);
++ if ((int)strlen(s) > (int)(s2 - s)) {
++ dgap_err("bad number for vpixsize");
++ return(-1);
++ }
++ DPR_INIT(("Adding VPSIZ (%s) to config...\n", s));
++ break;
++ }
++ }
++}
++
++
++/*
++ * sindex: much like index(), but it looks for a match of any character in
++ * the group, and returns that position. If the first character is a ^, then
++ * this will match the first occurence not in that group.
++ */
++static char *sindex (char *string, char *group)
++{
++ char *ptr;
++
++ if (!string || !group)
++ return (char *) NULL;
++
++ if (*group == '^') {
++ group++;
++ for (; *string; string++) {
++ for (ptr = group; *ptr; ptr++) {
++ if (*ptr == *string)
++ break;
++ }
++ if (*ptr == '\0')
++ return string;
++ }
++ }
++ else {
++ for (; *string; string++) {
++ for (ptr = group; *ptr; ptr++) {
++ if (*ptr == *string)
++ return string;
++ }
++ }
++ }
++
++ return (char *) NULL;
++}
++
++
++/*
++ * Get a token from the input file; return 0 if end of file is reached
++ */
++static int dgap_gettok(char **in, struct cnode *p)
++{
++ char *w;
++ struct toklist *t;
++
++ if (strstr(dgap_cword, "boar")) {
++ w = dgap_getword(in);
++ snprintf(dgap_cword, MAXCWORD, "%s", w);
++ for (t = tlist; t->token != 0; t++) {
++ if ( !strcmp(w, t->string)) {
++ return(t->token);
++ }
++ }
++ dgap_err("board !!type not specified");
++ return(1);
++ }
++ else {
++ while ( (w = dgap_getword(in)) != NULL ) {
++ snprintf(dgap_cword, MAXCWORD, "%s", w);
++ for (t = tlist; t->token != 0; t++) {
++ if ( !strcmp(w, t->string) )
++ return(t->token);
++ }
++ }
++ return(0);
++ }
++}
++
++
++/*
++ * get a word from the input stream, also keep track of current line number.
++ * words are separated by whitespace.
++ */
++static char *dgap_getword(char **in)
++{
++ char *ret_ptr = *in;
++
++ char *ptr = sindex(*in, " \t\n");
++
++ /* If no word found, return null */
++ if (!ptr)
++ return NULL;
++
++ /* Mark new location for our buffer */
++ *ptr = '\0';
++ *in = ptr + 1;
++
++ /* Eat any extra spaces/tabs/newlines that might be present */
++ while (*in && **in && ((**in == ' ') || (**in == '\t') || (**in == '\n'))) {
++ **in = '\0';
++ *in = *in + 1;
++ }
++
++ return ret_ptr;
++}
++
++
++/*
++ * print an error message, giving the line number in the file where
++ * the error occurred.
++ */
++static void dgap_err(char *s)
++{
++ printk("DGAP: parse: %s\n", s);
++}
++
++
++/*
++ * allocate a new configuration node of type t
++ */
++static struct cnode *dgap_newnode(int t)
++{
++ struct cnode *n;
++ if ( (n = (struct cnode *) kmalloc(sizeof(struct cnode ), GFP_ATOMIC) ) != NULL) {
++ memset( (char *)n, 0, sizeof(struct cnode ) );
++ n->type = t;
++ }
++ return(n);
++}
++
++
++/*
++ * dgap_checknode: see if all the necessary info has been supplied for a node
++ * before creating the next node.
++ */
++static int dgap_checknode(struct cnode *p)
++{
++ switch (p->type) {
++ case BNODE:
++ if (p->u.board.v_type == 0) {
++ dgap_err("board type !not specified");
++ return(1);
++ }
++
++ return(0);
++
++ case LNODE:
++ if (p->u.line.v_speed == 0) {
++ dgap_err("line speed not specified");
++ return(1);
++ }
++ return(0);
++
++ case CNODE:
++ if (p->u.conc.v_type == 0) {
++ dgap_err("concentrator type not specified");
++ return(1);
++ }
++ if (p->u.conc.v_speed == 0) {
++ dgap_err("concentrator line speed not specified");
++ return(1);
++ }
++ if (p->u.conc.v_nport == 0) {
++ dgap_err("number of ports on concentrator not specified");
++ return(1);
++ }
++ if (p->u.conc.v_id == 0) {
++ dgap_err("concentrator id letter not specified");
++ return(1);
++ }
++ return(0);
++
++ case MNODE:
++ if (p->u.module.v_type == 0) {
++ dgap_err("EBI module type not specified");
++ return(1);
++ }
++ if (p->u.module.v_nport == 0) {
++ dgap_err("number of ports on EBI module not specified");
++ return(1);
++ }
++ if (p->u.module.v_id == 0) {
++ dgap_err("EBI module id letter not specified");
++ return(1);
++ }
++ return(0);
++ }
++ return(0);
++}
++
++/*
++ * save a string somewhere
++ */
++static char *dgap_savestring(char *s)
++{
++ char *p;
++ if ( (p = kmalloc(strlen(s) + 1, GFP_ATOMIC) ) != NULL) {
++ strcpy(p, s);
++ }
++ return(p);
++}
++
++
++/*
++ * Given a board pointer, returns whether we should use interrupts or not.
++ */
++u32 dgap_config_get_useintr(struct board_t *bd)
++{
++ struct cnode *p = NULL;
++
++ if (!bd)
++ return(0);
++
++ for (p = bd->bd_config; p; p = p->next) {
++ switch (p->type) {
++ case INTRNODE:
++ /*
++ * check for pcxr types.
++ */
++ return p->u.useintr;
++ default:
++ break;
++ }
++ }
++
++ /* If not found, then don't turn on interrupts. */
++ return 0;
++}
++
++
++/*
++ * Given a board pointer, returns whether we turn on altpin or not.
++ */
++u32 dgap_config_get_altpin(struct board_t *bd)
++{
++ struct cnode *p = NULL;
++
++ if (!bd)
++ return(0);
++
++ for (p = bd->bd_config; p; p = p->next) {
++ switch (p->type) {
++ case ANODE:
++ /*
++ * check for pcxr types.
++ */
++ return p->u.altpin;
++ default:
++ break;
++ }
++ }
++
++ /* If not found, then don't turn on interrupts. */
++ return 0;
++}
++
++
++
++/*
++ * Given a specific type of board, if found, detached link and
++ * returns the first occurance in the list.
++ */
++struct cnode *dgap_find_config(int type)
++{
++ struct cnode *p, *prev = NULL, *prev2 = NULL, *found = NULL;
++
++ p = &dgap_head;
++
++ while (p->next != NULL) {
++ prev = p;
++ p = p->next;
++
++ if (p->type == BNODE) {
++ if (p->u.board.type == type) {
++ DPR_INIT(("Matched type in config file\n"));
++
++ found = p;
++ /*
++ * Keep walking thru the list till we find the next board.
++ */
++ while (p->next != NULL) {
++ prev2 = p;
++ p = p->next;
++ if (p->type == BNODE) {
++
++ /*
++ * Mark the end of our 1 board chain of configs.
++ */
++ prev2->next = NULL;
++
++ /*
++ * Link the "next" board to the previous board,
++ * effectively "unlinking" our board from the main config.
++ */
++ prev->next = p;
++
++ return found;
++ }
++ }
++ /*
++ * It must be the last board in the list.
++ */
++ prev->next = NULL;
++ return found;
++ }
++ }
++ }
++ return NULL;
++}
++
++/*
++ * Given a board pointer, walks the config link, counting up
++ * all ports user specified should be on the board.
++ * (This does NOT mean they are all actually present right now tho)
++ */
++u32 dgap_config_get_number_of_ports(struct board_t *bd)
++{
++ int count = 0;
++ struct cnode *p = NULL;
++
++ if (!bd)
++ return(0);
++
++ for (p = bd->bd_config; p; p = p->next) {
++
++ switch (p->type) {
++ case BNODE:
++ /*
++ * check for pcxr types.
++ */
++ if (p->u.board.type > EPCFE)
++ count += p->u.board.nport;
++ break;
++ case CNODE:
++ count += p->u.conc.nport;
++ break;
++ case MNODE:
++ count += p->u.module.nport;
++ break;
++ }
++ }
++ return (count);
++}
++
++char *dgap_create_config_string(struct board_t *bd, char *string)
++{
++ char *ptr = string;
++ struct cnode *p = NULL;
++
++ if (!bd) {
++ *ptr = 0xff;
++ return string;
++ }
++
++ for (p = bd->bd_config; p; p = p->next) {
++
++ switch (p->type) {
++ case LNODE:
++ *ptr = '\0';
++ ptr++;
++ *ptr = p->u.line.speed;
++ ptr++;
++ break;
++ case CNODE:
++ *ptr = p->u.conc.nport;
++ ptr++;
++ *ptr = p->u.conc.speed;
++ ptr++;
++ break;
++ }
++ }
++
++ *ptr = 0xff;
++ return string;
++}
++
++
++
++char *dgap_get_config_letters(struct board_t *bd, char *string)
++{
++ int found = FALSE;
++ char *ptr = string;
++ struct cnode *cptr = NULL;
++ int len = 0;
++ int left = MAXTTYNAMELEN;
++
++ if (!bd) {
++ return "<NULL>";
++ }
++
++ for (cptr = bd->bd_config; cptr; cptr = cptr->next) {
++
++ if ((cptr->type == BNODE) &&
++ ((cptr->u.board.type == APORT2_920P) || (cptr->u.board.type == APORT4_920P) ||
++ (cptr->u.board.type == APORT8_920P) || (cptr->u.board.type == PAPORT4) ||
++ (cptr->u.board.type == PAPORT8))) {
++
++ found = TRUE;
++ }
++
++ if (cptr->type == TNODE && found == TRUE) {
++ char *ptr1;
++ if (strstr(cptr->u.ttyname, "tty")) {
++ ptr1 = cptr->u.ttyname;
++ ptr1 += 3;
++ }
++ else {
++ ptr1 = cptr->u.ttyname;
++ }
++ if (ptr1) {
++ len = snprintf(ptr, left, "%s", ptr1);
++ left -= len;
++ ptr += len;
++ if (left <= 0)
++ break;
++ }
++ }
++
++ if (cptr->type == CNODE) {
++ if (cptr->u.conc.id) {
++ len = snprintf(ptr, left, "%s", cptr->u.conc.id);
++ left -= len;
++ ptr += len;
++ if (left <= 0)
++ break;
++ }
++ }
++
++ if (cptr->type == MNODE) {
++ if (cptr->u.module.id) {
++ len = snprintf(ptr, left, "%s", cptr->u.module.id);
++ left -= len;
++ ptr += len;
++ if (left <= 0)
++ break;
++ }
++ }
++ }
++
++ return string;
++}
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/dgap_parse.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/dgap_parse.h 2003-09-27 11:38:18.448723752 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/dgap_parse.h 2003-09-27 11:38:20.959342080 +0800
+@@ -0,0 +1,35 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ * Scott H Kilau <Scott_Kilau at digi dot com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2, or (at your option)
++ * any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
++ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
++ * PURPOSE. See the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * NOTE: THIS IS A SHARED HEADER. DO NOT CHANGE CODING STYLE!!!
++ */
++
++#ifndef _DGAP_PARSE_H
++#define _DGAP_PARSE_H
++
++#include "dgap_driver.h"
++
++int dgap_parsefile(char **in, int Remove);
++struct cnode *dgap_find_config(int type);
++u32 dgap_config_get_number_of_ports(struct board_t *bd);
++char *dgap_create_config_string(struct board_t *bd, char *string);
++char *dgap_get_config_letters(struct board_t *bd, char *string);
++u32 dgap_config_get_useintr(struct board_t *bd);
++u32 dgap_config_get_altpin(struct board_t *bd);
++
++#endif
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/dgap_pci.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/dgap_pci.h 2003-09-27 11:38:18.448723752 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/dgap_pci.h 2003-09-27 11:38:20.960341928 +0800
+@@ -0,0 +1,83 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ * Scott H Kilau <Scott_Kilau at digi dot com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2, or (at your option)
++ * any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
++ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
++ * PURPOSE. See the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * NOTE: THIS IS A SHARED HEADER. DO NOT CHANGE CODING STYLE!!!
++ */
++
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
++
++#ifndef __DGAP_PCI_H
++#define __DGAP_PCI_H
++
++#define PCIMAX 32 /* maximum number of PCI boards */
++
++#define DIGI_VID 0x114F
++
++#define PCI_DEVICE_EPC_DID 0x0002
++#define PCI_DEVICE_XEM_DID 0x0004
++#define PCI_DEVICE_XR_DID 0x0005
++#define PCI_DEVICE_CX_DID 0x0006
++#define PCI_DEVICE_XRJ_DID 0x0009 /* PLX-based Xr adapter */
++#define PCI_DEVICE_XR_IBM_DID 0x0011 /* IBM 8-port Async Adapter */
++#define PCI_DEVICE_XR_422_DID 0x0012 /* Xr-422 */
++#define PCI_DEVICE_920_2_DID 0x0034 /* XR-Plus 920 K, 2 port */
++#define PCI_DEVICE_920_4_DID 0x0026 /* XR-Plus 920 K, 4 port */
++#define PCI_DEVICE_920_8_DID 0x0027 /* XR-Plus 920 K, 8 port */
++#define PCI_DEVICE_EPCJ_DID 0x000a /* PLX 9060 chip for PCI */
++#define PCI_DEVICE_CX_IBM_DID 0x001b /* IBM 128-port Async Adapter */
++
++#define PCI_DEVICE_XEM_NAME "AccelePort XEM"
++#define PCI_DEVICE_CX_NAME "AccelePort CX"
++#define PCI_DEVICE_XR_NAME "AccelePort Xr"
++#define PCI_DEVICE_XRJ_NAME "AccelePort Xr (PLX)"
++#define PCI_DEVICE_920_2_NAME "AccelePort Xr920 2 port"
++#define PCI_DEVICE_920_4_NAME "AccelePort Xr920 4 port"
++#define PCI_DEVICE_920_8_NAME "AccelePort Xr920 8 port"
++#define PCI_DEVICE_XR_422_NAME "AccelePort Xr 422"
++#define PCI_DEVICE_EPCJ_NAME "AccelePort EPC (PLX)"
++#define PCI_DEVICE_XR_IBM_NAME "AccelePort Xr (IBM)"
++#define PCI_DEVICE_CX_IBM_NAME "AccelePort CX (IBM)"
++
++/*
++ * On the PCI boards, there is no IO space allocated
++ * The I/O registers will be in the first 3 bytes of the
++ * upper 2MB of the 4MB memory space. The board memory
++ * will be mapped into the low 2MB of the 4MB memory space
++ */
++
++/* Potential location of PCI Bios from E0000 to FFFFF*/
++#define PCI_BIOS_SIZE 0x00020000
++
++/* Size of Memory and I/O for PCI (4MB) */
++#define PCI_RAM_SIZE 0x00400000
++
++/* Size of Memory (2MB) */
++#define PCI_MEM_SIZE 0x00200000
++
++/* Max PCI Window Size (2MB) */
++#define PCI_WIN_SIZE 0x00200000
++
++#define PCI_WIN_SHIFT 21 /* 21 bits max */
++
++/* Offset of I/0 in Memory (2MB) */
++#define PCI_IO_OFFSET 0x00200000
++
++/* Size of IO (2MB) */
++#define PCI_IO_SIZE 0x00200000
++
++#endif
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/dgap_proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/dgap_proc.c 2003-09-27 11:38:18.448723752 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/dgap_proc.c 2003-09-27 11:38:20.961341776 +0800
+@@ -0,0 +1,700 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ * Scott H Kilau <Scott_Kilau at digi dot com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2, or (at your option)
++ * any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
++ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
++ * PURPOSE. See the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ *
++ * NOTE TO LINUX KERNEL HACKERS: DO NOT REFORMAT THIS CODE!
++ *
++ * This is shared code between Digi's CVS archive and the
++ * Linux Kernel sources.
++ * Changing the source just for reformatting needlessly breaks
++ * our CVS diff history.
++ *
++ * Send any bug fixes/changes to: Eng.Linux at digi dot com.
++ * Thank you.
++ *
++ */
++
++/************************************************************************
++ *
++ * /proc/dgap/{*} functions
++ *
++ ************************************************************************/
++#define __NO_VERSION__
++#include "dgap_driver.h"
++#include "dgap_parse.h"
++#include "dgap_mgmt.h"
++#include <linux/ctype.h>
++#include <linux/proc_fs.h>
++
++/* external variables */
++extern int dgap_debug;
++extern struct board_t *dgap_Board[MAXBOARDS];
++extern uchar dgap_NumBoards;
++extern u32 dgap_poll_counter;
++
++
++/*
++ * OK, here's the deal with /proc files. We want to use the
++ * simple (yet inefficient) interface to /proc where we just get
++ * a buffer and fill it in. Otherwise, we'd have to provide the
++ * full set of functions for a /proc driver.
++ *
++ * When we get called, "buf" points to a single free page which
++ * we can write into. If you are careful, you can write up
++ * to PAGE_SIZE (4096) bytes into it. But to be paranoid,
++ * Linux lies and says the "count" is only PROC_BLOK_SIZE (3072).
++ *
++ * In any case, its easiest to make several /proc/dgap/ entries
++ * if you want to print out more info than can fit in a page.
++ *
++ * Here's some further information. We are trying to be compatible
++ * with 2.0.xx and 2.1.xx. There have been improvements in 2.1.x
++ * in this area, but it still isn't perfect. Anyway, our hands
++ * are tied by the 2.0.x limitations. For example, you cannot
++ * pass private data to the get_info (2.0.x) routines. Therefore,
++ * you cannot make a generic function to print the data for one
++ * board. If you want to do this, you have to make a wrapper
++ * function, one function name per board number. Yech!
++ */
++
++ #define PROC_READ_PROTO \
++ char *buf, char **start, off_t fpos, int count, \
++ int *eof, void *private
++
++ #define PROC_READ_ARGS \
++ buf, start, fpos, count, eof, private
++
++
++/*
++ * Make wrappers for per-board entries. Gag me. Sorry,
++ * 2.0.x forced us into this since it has no way to pass
++ * private data to the read_proc (get_info, actually).
++ */
++/* FIXME - Fix this, we can convert away from this now */
++#define PROCWRAP_FUNCTION(FUNC, NUM) \
++ static int \
++ FUNC ## NUM (PROC_READ_PROTO) \
++ { \
++ return FUNC(NUM, PROC_READ_ARGS); \
++ }
++
++#define PROCWRAP_FUNC(FUNC,NUM) \
++ FUNC ## tbl[NUM]
++
++#define PROCWRAP_FUNCTIONS(FUNC) \
++ PROCWRAP_FUNCTION(FUNC, 0) \
++ PROCWRAP_FUNCTION(FUNC, 1) \
++ PROCWRAP_FUNCTION(FUNC, 2) \
++ PROCWRAP_FUNCTION(FUNC, 3) \
++ PROCWRAP_FUNCTION(FUNC, 4) \
++ PROCWRAP_FUNCTION(FUNC, 5) \
++ PROCWRAP_FUNCTION(FUNC, 6) \
++ PROCWRAP_FUNCTION(FUNC, 7) \
++ PROCWRAP_FUNCTION(FUNC, 8) \
++ PROCWRAP_FUNCTION(FUNC, 9) \
++ PROCWRAP_FUNCTION(FUNC, 10) \
++ PROCWRAP_FUNCTION(FUNC, 11) \
++ PROCWRAP_FUNCTION(FUNC, 12) \
++ PROCWRAP_FUNCTION(FUNC, 13) \
++ PROCWRAP_FUNCTION(FUNC, 14) \
++ PROCWRAP_FUNCTION(FUNC, 15) \
++ PROCWRAP_FUNCTION(FUNC, 16) \
++ PROCWRAP_FUNCTION(FUNC, 17) \
++ PROCWRAP_FUNCTION(FUNC, 18) \
++ PROCWRAP_FUNCTION(FUNC, 19) \
++ PROCWRAP_FUNCTION(FUNC, 20) \
++ PROCWRAP_FUNCTION(FUNC, 21) \
++ PROCWRAP_FUNCTION(FUNC, 22) \
++ PROCWRAP_FUNCTION(FUNC, 23) \
++ PROCWRAP_FUNCTION(FUNC, 24) \
++ PROCWRAP_FUNCTION(FUNC, 25) \
++ PROCWRAP_FUNCTION(FUNC, 26) \
++ PROCWRAP_FUNCTION(FUNC, 27) \
++ PROCWRAP_FUNCTION(FUNC, 28) \
++ PROCWRAP_FUNCTION(FUNC, 29) \
++ PROCWRAP_FUNCTION(FUNC, 30) \
++ PROCWRAP_FUNCTION(FUNC, 31) \
++
++#define PROCWRAP_TBL(FUNC) \
++ static read_proc_t * FUNC ## tbl[MAXBOARDS] = \
++ { \
++ FUNC ## 0, \
++ FUNC ## 1, \
++ FUNC ## 2, \
++ FUNC ## 3, \
++ FUNC ## 4, \
++ FUNC ## 5, \
++ FUNC ## 6, \
++ FUNC ## 7, \
++ FUNC ## 8, \
++ FUNC ## 9, \
++ FUNC ## 10, \
++ FUNC ## 11, \
++ FUNC ## 12, \
++ FUNC ## 13, \
++ FUNC ## 14, \
++ FUNC ## 15, \
++ FUNC ## 16, \
++ FUNC ## 17, \
++ FUNC ## 18, \
++ FUNC ## 19, \
++ FUNC ## 20, \
++ FUNC ## 21, \
++ FUNC ## 22, \
++ FUNC ## 23, \
++ FUNC ## 24, \
++ FUNC ## 25, \
++ FUNC ## 26, \
++ FUNC ## 27, \
++ FUNC ## 28, \
++ FUNC ## 29, \
++ FUNC ## 30, \
++ FUNC ## 31, \
++ };
++
++#define PROCWRAPPERS(FUNC) \
++ PROCWRAP_FUNCTIONS(FUNC) \
++ PROCWRAP_TBL(FUNC)
++
++
++/*
++ * /proc/dgap/<boardno>/tty
++ */
++static struct proc_dir_entry *ProcDgAPTTY[MAXBOARDS];
++
++static int dgap_proc_tty(int brdno, PROC_READ_PROTO)
++{
++ struct board_t *brd;
++ char *p = buf;
++
++ DPR_PROC(("dgap_proc_tty count=%d fpos=%ld\n", count, fpos));
++
++ brd = dgap_Board[brdno];
++
++ if(!brd)
++ return(-EINVAL);
++
++ /* Prepare the Header Labels */
++ p += sprintf(p, " Receive Statistics "
++ "Transmit Statistics\n");
++ p += sprintf(p, "%2s %19s %7s %19s %7s %s\n",
++ "Ch", "Chars Rx", "RxCPS",
++ "Chars Tx", "TxCPS", " Line Status Flags");
++
++ DPR_PROC(("dgap_proc_tty returns %d\n", p-buf));
++
++ return(p-buf);
++}
++
++PROCWRAPPERS(dgap_proc_tty)
++
++
++/*
++ * /proc/dgap/<boardno>/ttys
++ */
++static struct proc_dir_entry *ProcDgAPTTYs[MAXBOARDS];
++
++static int dgap_proc_ttys(int brdno, PROC_READ_PROTO)
++{
++ struct board_t *brd;
++ char *p = buf;
++
++ DPR_PROC(("dgap_proc_ttys count=%d fpos=%ld\n", count, fpos));
++
++ brd = dgap_Board[brdno];
++
++ if(!brd)
++ return(-EINVAL);
++
++ p += sprintf(p, "Chan\t&tty\tflags\n");
++
++ DPR_PROC(("dgap_proc_ttys returns %d\n", p-buf));
++
++ return(p-buf);
++}
++
++PROCWRAPPERS(dgap_proc_ttys)
++
++
++/*
++ * /proc/dgap/<boardno>/info
++ *
++ * Variables compatible with the shell
++ */
++static struct proc_dir_entry *ProcDgAPBrdInfo[MAXBOARDS];
++
++static int dgap_proc_brd_info(int brdno, PROC_READ_PROTO)
++{
++ struct board_t *brd;
++ char *p = buf;
++ char *name;
++
++ DPR_PROC(("dgap_proc_brd_info\n"));
++
++ brd = dgap_Board[brdno];
++
++ if(!brd)
++ return(-EINVAL);
++
++ name = brd->name;
++
++ p += sprintf(p, "Board Name = %s\n", name);
++ p += sprintf(p, "Board Type = %d\n", brd->type);
++
++ /*
++ * report some things about the PCI bus that are important
++ * to some applications
++ */
++ p += sprintf(p, "Vendor ID = 0x%x\n", brd->vendor);
++ p += sprintf(p, "Device ID = 0x%x\n", brd->device);
++ p += sprintf(p, "Subvendor ID = 0x%x\n", brd->subvendor);
++ p += sprintf(p, "Subdevice ID = 0x%x\n", brd->subdevice);
++
++ /*
++ * report the physical addresses assigned to us when we got
++ * registered
++ */
++ p += sprintf(p, "IO Port = 0x%lx\n", brd->port);
++ p += sprintf(p, "Memory Base Address = 0x%lx\n", brd->membase);
++ p += sprintf(p, "Remapped IO Port Address = 0x%p\n", brd->re_map_port);
++ p += sprintf(p, "Remapped Memory Base Address = 0x%p\n", brd->re_map_membase);
++
++ p += sprintf(p, "Current state of board = %s\n", dgap_state_text[brd->state]);
++ p += sprintf(p, "Interrupt #: %d. Times interrupted: %d\n",
++ brd->irq, brd->intr_count);
++ p += sprintf(p, "Majors allocated to board = TTY: %d PR: %d\n",
++ brd->SerialDriver.major, brd->PrintDriver.major);
++
++ /*
++ * report available resources on the card
++ */
++
++ return(p-buf);
++}
++
++PROCWRAPPERS(dgap_proc_brd_info)
++
++
++/*
++ * /proc/dgap/info
++ *
++ * Variables compatible with the shell
++ */
++static struct proc_dir_entry *ProcDgAPInfo;
++
++static int dgap_proc_info(PROC_READ_PROTO)
++{
++ char *p = buf;
++
++ DPR_PROC(("dgap_proc_info\n"));
++ p += sprintf(p, "Max Boards = %d\n", MAXBOARDS);
++ p += sprintf(p, "Current number of boards = %d\n", dgap_NumBoards);
++ p += sprintf(p, "Poll counter = %d\n", dgap_poll_counter);
++ p += sprintf(p, "State of driver: %s\n", dgap_driver_state_text[dgap_driver_state]);
++ return(p-buf);
++}
++
++/*
++ * /proc/dgap/<boardno>/mknod
++ */
++static struct proc_dir_entry *ProcDgAPBrdMknod[MAXBOARDS];
++
++static int mknod_tty_cmd(char *buf, char *nodename,
++ int major, int firstminor, int count, int start)
++{
++ return sprintf(buf, "dgap_mknod\t%s\t\t%d\t%d\t%d\t%d\n",
++ nodename, major, firstminor, count, start);
++}
++
++
++static int dgap_proc_brd_mknod(int brdno, PROC_READ_PROTO)
++{
++ struct board_t *brd = dgap_Board[brdno];
++ int bn;
++ char *p = buf;
++ struct cnode *cptr = NULL;
++ char str[100];
++ int found = FALSE;
++ int ncount = 0;
++ int starto = 0;
++
++ DPR_PROC(("dgap_proc_brd_mknod(%d) %d\n", brdno, count));
++
++ if(!brd)
++ return(-ENODEV);
++
++ bn = brd->boardnum;
++
++
++ /*
++ * Output the boilerplate at the top of the shell script
++ */
++ p += sprintf(p, "#!/bin/sh\n\n");
++
++ p += sprintf(p, "# /proc/dgap/mknod [-d]\n");
++ p += sprintf(p, "#\tMake DGAP device nodes.\n");
++ p += sprintf(p, "#\t-d deletes all existing nodes first\n\n");
++
++ p += sprintf(p, "PATH=" SBINDIR ":$PATH\n");
++
++ p += sprintf(p, "[ -d %s ] || mkdir -p -m 755 %s\n",
++ DEVSTR, DEVSTR);
++
++ p += sprintf(p, "[ \"$1\" != -d ] || rm -rf %s/* || exit 1\n",
++ DEVSTR);
++
++ p += sprintf(p, "cd %s || exit 2\n\n", DEVSTR);
++
++ /*
++ * For each board, output the device information in
++ * a handy table format...
++ */
++ p += sprintf(p, "#\t\tNAME\t\tMAJOR\tMINOR\tCOUNT\tSTART\n");
++
++
++ for (cptr = brd->bd_config; cptr; cptr = cptr->next) {
++
++ if ((cptr->type == BNODE) &&
++ ((cptr->u.board.type == APORT2_920P) || (cptr->u.board.type == APORT4_920P) ||
++ (cptr->u.board.type == APORT8_920P) || (cptr->u.board.type == PAPORT4) ||
++ (cptr->u.board.type == PAPORT8))) {
++
++ found = TRUE;
++ if (cptr->u.board.start)
++ starto = cptr->u.board.start;
++ else
++ starto = 1;
++ }
++
++ if (cptr->type == TNODE && found == TRUE) {
++ char *ptr1;
++ if (strstr(cptr->u.ttyname, "tty")) {
++ ptr1 = cptr->u.ttyname;
++ ptr1 += 3;
++ }
++ else {
++ ptr1 = cptr->u.ttyname;
++ }
++
++ /* TTY devices */
++ sprintf(str, "tty%s%%p", ptr1);
++
++ p += mknod_tty_cmd(p, str,
++ brd->SerialDriver.major,
++ 0, dgap_config_get_number_of_ports(brd), starto);
++
++ /* PR devices */
++ sprintf(str, "pr%s%%p", ptr1);
++
++ p += mknod_tty_cmd(p, str,
++ brd->PrintDriver.major,
++ 0, dgap_config_get_number_of_ports(brd), starto);
++ }
++
++ if (cptr->type == CNODE) {
++
++ sprintf(str, "tty%s%%p", cptr->u.conc.id);
++
++ /* TTY devices */
++ p += mknod_tty_cmd(p, str,
++ brd->SerialDriver.major,
++ ncount, cptr->u.conc.nport,
++ cptr->u.conc.start ? cptr->u.conc.start : 1);
++
++ sprintf(str, "pr%s%%p", cptr->u.conc.id);
++
++ p += mknod_tty_cmd(p, str,
++ brd->PrintDriver.major,
++ ncount, cptr->u.conc.nport,
++ cptr->u.conc.start ? cptr->u.conc.start : 1);
++
++ ncount += cptr->u.conc.nport;
++ }
++
++ if (cptr->type == MNODE) {
++
++ sprintf(str, "tty%s%%p", cptr->u.module.id);
++
++ /* TTY devices */
++ p += mknod_tty_cmd(p, str,
++ brd->SerialDriver.major,
++ ncount, cptr->u.module.nport,
++ cptr->u.module.start ? cptr->u.module.start : 1);
++
++ sprintf(str, "pr%s%%p", cptr->u.module.id);
++
++ p += mknod_tty_cmd(p, str,
++ brd->PrintDriver.major,
++ ncount, cptr->u.module.nport,
++ cptr->u.module.start ? cptr->u.module.start : 1);
++
++ ncount += cptr->u.module.nport;
++
++ }
++ }
++
++ return(p-buf);
++}
++
++PROCWRAPPERS(dgap_proc_brd_mknod)
++
++
++/*
++ * /proc/dgap/mknod
++ */
++static struct proc_dir_entry *ProcDgAPMknod;
++
++static int dgap_proc_mknod(PROC_READ_PROTO)
++{
++ char *p = buf;
++
++ DPR_PROC(("dgap_proc_mknod\n"));
++
++ p += sprintf(p, "#!/bin/sh\n\n");
++
++ p += sprintf(p, "#\t/proc/dgap/mknod [-d]\n");
++ p += sprintf(p, "#\t\tMake DGAP device nodes.\n");
++ p += sprintf(p, "#\t\t-d deletes all existing nodes first\n\n");
++
++ p += sprintf(p, "if [ \"$1\" != -d ]\nthen\n\texit 1\nfi\n");
++
++ p += sprintf(p, "if [ -d %s ]\nthen\n", DEVSTR);
++
++ p += sprintf(p, "\tcd %s\n", DEVSTR);
++
++ /* Delete all our ttys */
++ p += sprintf(p, "\tfor i in tty*\n");
++ p += sprintf(p, "\tdo\n");
++
++ p += sprintf(p, "\t\tif [ \"$i\" != \"tty*\" ]\n");
++ p += sprintf(p, "\t\tthen\n");
++
++ p += sprintf(p, "\t\t\trm -rf $i\n");
++ p += sprintf(p, "\t\t\trm -rf /dev/$i\n");
++
++ p += sprintf(p, "\t\tfi\n");
++
++ p += sprintf(p, "\tdone\n");
++
++ /* Delete all our prs */
++ p += sprintf(p, "\tfor i in pr*\n");
++ p += sprintf(p, "\tdo\n");
++
++ p += sprintf(p, "\t\tif [ \"$i\" != \"pr*\" ]\n");
++ p += sprintf(p, "\t\tthen\n");
++
++ p += sprintf(p, "\t\t\trm -rf $i\n");
++ p += sprintf(p, "\t\t\trm -rf /dev/$i\n");
++
++ p += sprintf(p, "\t\tfi\n");
++
++ p += sprintf(p, "\tdone\n");
++
++ p += sprintf(p, "fi\n");
++
++ /* Delete anything that was left. */
++ p += sprintf(p, "rm -rf %s/*\n", DEVSTR);
++
++ p += sprintf(p, "for i in /proc/dgap/*/mknod\n");
++ p += sprintf(p, "do\n");
++
++ p += sprintf(p, "\tif [ \"$i\" != \"/proc/dgap/*/mknod\" ]\n");
++ p += sprintf(p, "\tthen\n");
++
++ p += sprintf(p, "\t\t$i\n");
++
++ p += sprintf(p, "\tfi\n");
++
++ p += sprintf(p, "done\n");
++
++ p += sprintf(p, "#\tCreate the management device.\n\n");
++ p += mknod_tty_cmd(p, "/dev/dg/dgap/mgmt", DIGI_DGAP_MAJOR, MGMT_MGMT, 1, 0);
++ p += mknod_tty_cmd(p, "/dev/dg/dgap/downld", DIGI_DGAP_MAJOR, MGMT_DOWNLD, 1, 0);
++
++ return (p-buf);
++}
++
++
++/*
++ * The directory entries /proc/dgap/<boardnum>
++ */
++static struct proc_dir_entry *ProcDgAPBrd[MAXBOARDS];
++
++/*
++ * The directory entry /proc/dgap
++ */
++static struct proc_dir_entry *ProcDgAP;
++
++/*
++ * Gee, the proc I/F for drivers is *still* not well done in 2.1.x.
++ *
++ * In any event, we'll *make* a better interface here and then
++ * use it to abstract the differences between 2.0.x and 2.1.x
++ *
++ * Unfortunately, the *best* interface would also allow you
++ * to pass in "private" data. But that can't be supported
++ * on 2.0.x, so that is why this interface is just "better".
++ */
++
++static struct proc_dir_entry *better_create_proc_entry(
++ const char *name, mode_t mode, unsigned long size,
++ read_proc_t *read_proc, struct proc_dir_entry *parent)
++{
++ struct proc_dir_entry *pde;
++
++ pde = create_proc_entry(name, mode, parent);
++ if (!pde) return NULL;
++
++ if (size)
++ pde->size = size;
++ if (read_proc)
++ pde->read_proc = read_proc;
++
++ return pde;
++}
++
++static void better_remove_proc_entry(struct proc_dir_entry *pde)
++{
++ if (!pde) return;
++
++ remove_proc_entry(pde->name, pde->parent);
++}
++
++
++/*
++ * Register the basic /proc/dgap files that appear whenever
++ * the driver is loaded.
++ */
++void dgap_proc_register_basic_prescan(void)
++{
++ char *buf;
++ int size;
++
++ /* Register /proc/dgap */
++ ProcDgAP = better_create_proc_entry(PROCSTR, S_IFDIR, 0, NULL, 0);
++
++ /* Register /proc/dgap/info */
++ ProcDgAPInfo = better_create_proc_entry( "info", 0, 0,
++ dgap_proc_info, ProcDgAP);
++
++ /*
++ * Compute size of /proc/dgap/mknod output, fixup
++ * proc_dir_entry for it, then register it.
++ */
++ buf = kmalloc(4096, GFP_KERNEL);
++ if (buf) {
++ size = dgap_proc_mknod(buf, NULL, 0, 4096, 0, 0);
++ } else
++ size = 0;
++ kfree(buf);
++
++ ProcDgAPMknod =
++ better_create_proc_entry("mknod", S_IFREG | S_IRUGO | S_IXUGO,
++ size, dgap_proc_mknod, ProcDgAP);
++}
++
++
++
++/*
++ * Register the basic /proc/dgap files that appear whenever
++ * the driver is loaded.
++ */
++void dgap_proc_register_basic_postscan(void)
++{
++ char *buf;
++ int size;
++ int i;
++
++ /*
++ * Register /proc/dgap/<boardnum> directories
++ * and the /proc/dgap/<boardnum>/info files
++ */
++ for (i = 0; i < dgap_NumBoards; ++i) {
++ char name[2];
++
++ name[0] = i + '0';
++ name[1] = 0;
++ ProcDgAPBrd[i] = better_create_proc_entry(name, S_IFDIR, 0,
++ NULL, ProcDgAP);
++
++ ProcDgAPBrdInfo[i] = better_create_proc_entry("info", 0, 0,
++ PROCWRAP_FUNC(dgap_proc_brd_info, i),
++ ProcDgAPBrd[i]);
++
++ /*
++ * Compute size of /proc/dgap/<boardno>/mknod output, fixup
++ * proc_dir_entry for it, then register it.
++ */
++ buf = kmalloc(4096, GFP_ATOMIC);
++ if (buf) {
++ size = dgap_proc_brd_mknod(i, buf, NULL, 0, 4096, 0, 0);
++ } else
++ size = 0;
++ kfree(buf);
++
++ ProcDgAPBrdMknod[i] = better_create_proc_entry("mknod",
++ S_IFREG | S_IRUGO | S_IXUGO, size,
++ PROCWRAP_FUNC(dgap_proc_brd_mknod, i),
++ ProcDgAPBrd[i]);
++ }
++}
++
++
++/*
++ * Register the proc devices that appear only if we are
++ * loading up a fep.
++ */
++void dgap_proc_register_fep(void)
++{
++ int i;
++
++ for (i = 0; i < dgap_NumBoards; ++i) {
++
++ ProcDgAPTTYs[i] = better_create_proc_entry( "ttys", 0, 0,
++ PROCWRAP_FUNC(dgap_proc_ttys, i),
++ ProcDgAPBrd[i]);
++
++ ProcDgAPTTY[i] = better_create_proc_entry( "tty", 0, 0,
++ PROCWRAP_FUNC(dgap_proc_tty, i),
++ ProcDgAPBrd[i]);
++ }
++}
++
++/*
++ * Unregister all of our /proc/dgap/{*} devices
++ */
++void dgap_proc_unregister_all(void)
++{
++ int i;
++
++#define NUKE_ONE(PDE) \
++ if (PDE) { better_remove_proc_entry(PDE); PDE = NULL; } else
++
++ for (i = 0; i < dgap_NumBoards; ++i) {
++ NUKE_ONE(ProcDgAPTTY[i]);
++ NUKE_ONE(ProcDgAPTTYs[i]);
++ NUKE_ONE(ProcDgAPBrdMknod[i]);
++ NUKE_ONE(ProcDgAPBrdInfo[i]);
++ NUKE_ONE(ProcDgAPBrd[i]);
++ }
++
++ NUKE_ONE(ProcDgAPMknod);
++ NUKE_ONE(ProcDgAPInfo);
++
++ NUKE_ONE(ProcDgAP);
++}
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/dgap_proc.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/dgap_proc.h 2003-09-27 11:38:18.449723600 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/dgap_proc.h 2003-09-27 11:38:20.962341624 +0800
+@@ -0,0 +1,32 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ * Scott H Kilau <Scott_Kilau at digi dot com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2, or (at your option)
++ * any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
++ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
++ * PURPOSE. See the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * NOTE: THIS IS A SHARED HEADER. DO NOT CHANGE CODING STYLE!!!
++ */
++
++#ifndef __DGAP_PROC_H
++#define __DGAP_PROC_H
++
++#include "dgap_driver.h"
++
++void dgap_proc_unregister_all(void);
++void dgap_proc_register_basic_prescan(void);
++void dgap_proc_register_basic_postscan(void);
++void dgap_proc_register_fep(void);
++
++#endif
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/dgap_trace.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/dgap_trace.c 2003-09-27 11:38:18.449723600 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/dgap_trace.c 2003-09-27 11:38:20.962341624 +0800
+@@ -0,0 +1,182 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ * Scott H Kilau <Scott_Kilau at digi dot com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2, or (at your option)
++ * any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
++ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
++ * PURPOSE. See the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ *
++ * NOTE TO LINUX KERNEL HACKERS: DO NOT REFORMAT THIS CODE!
++ *
++ * This is shared code between Digi's CVS archive and the
++ * Linux Kernel sources.
++ * Changing the source just for reformatting needlessly breaks
++ * our CVS diff history.
++ *
++ * Send any bug fixes/changes to: Eng.Linux at digi dot com.
++ * Thank you.
++ *
++ */
++
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
++
++#define __NO_VERSION__
++#include "dgap_driver.h"
++#define TRC_TO_CONSOLE 1
++
++
++
++#include <linux/vmalloc.h>
++
++/* file level globals */
++static char *dgap_trcbuf; /* the ringbuffer */
++
++#if defined(TRC_TO_KMEM)
++static int dgap_trcbufi = 0; /* index of the tilde at the end of */
++#endif
++
++extern int dgap_trcbuf_size; /* size of the ringbuffer */
++
++#if defined(TRC_TO_KMEM)
++static spinlock_t dgap_tracef_lock = SPIN_LOCK_UNLOCKED;
++#endif
++
++
++#if !defined(TRC_TO_KMEM) && !defined(TRC_TO_CONSOLE)
++void dgap_tracef(const char *fmt, ...)
++{
++ return;
++}
++
++#else /* !defined(TRC_TO_KMEM) && !defined(TRC_TO_CONSOLE) */
++
++void dgap_tracef(const char *fmt, ...)
++{
++ va_list ap;
++ char buf[TRC_MAXMSG+1];
++ size_t lenbuf;
++ int i;
++ static int failed = FALSE;
++# if defined(TRC_TO_KMEM)
++ unsigned long flags;
++#endif
++
++ if(failed)
++ return;
++# if defined(TRC_TO_KMEM)
++ DGAP_LOCK(dgap_tracef_lock, flags);
++#endif
++
++ /* Format buf using fmt and arguments contained in ap. */
++ va_start(ap, fmt);
++ i = vsprintf(buf, fmt, ap);
++ va_end(ap);
++ lenbuf = strlen(buf);
++
++# if defined(TRC_TO_KMEM)
++ {
++ static int initd=0;
++
++ /*
++ * Now, in addition to (or instead of) printing this stuff out
++ * (which is a buffered operation), also tuck it away into a
++ * corner of memory which can be examined post-crash in kdb.
++ */
++ if (!initd) {
++ dgap_trcbuf = (char *) vmalloc(dgap_trcbuf_size);
++ if(!dgap_trcbuf) {
++ failed = TRUE;
++ printk("dgap: tracing init failed!\n");
++ return;
++ }
++
++ memset(dgap_trcbuf, '\0', dgap_trcbuf_size);
++ dgap_trcbufi = 0;
++ initd++;
++
++ printk("dgap: tracing enabled - " TRC_DTRC
++ " 0x%lx 0x%x\n",
++ (unsigned long)dgap_trcbuf,
++ dgap_trcbuf_size);
++ }
++
++# if defined(TRC_ON_OVERFLOW_WRAP_AROUND)
++ /*
++ * This is the less CPU-intensive way to do things. We simply
++ * wrap around before we fall off the end of the buffer. A
++ * tilde (~) demarcates the current end of the trace.
++ *
++ * This method should be used if you are concerned about race
++ * conditions as it is less likely to affect the timing of
++ * things.
++ */
++
++ if (dgap_trcbufi + lenbuf >= dgap_trcbuf_size) {
++ /* We are wrapping, so wipe out the last tilde. */
++ dgap_trcbuf[dgap_trcbufi] = '\0';
++ /* put the new string at the beginning of the buffer */
++ dgap_trcbufi = 0;
++ }
++
++ strcpy(&dgap_trcbuf[dgap_trcbufi], buf);
++ dgap_trcbufi += lenbuf;
++ dgap_trcbuf[dgap_trcbufi] = '~';
++
++# elif defined(TRC_ON_OVERFLOW_SHIFT_BUFFER)
++ /*
++ * This is the more CPU-intensive way to do things. If we
++ * venture into the last 1/8 of the buffer, we shift the
++ * last 7/8 of the buffer forward, wiping out the first 1/8.
++ * Advantage: No wrap-around, only truncation from the
++ * beginning.
++ *
++ * This method should not be used if you are concerned about
++ * timing changes affecting the behaviour of the driver (ie,
++ * race conditions).
++ */
++ strcpy(&dgap_trcbuf[dgap_trcbufi], buf);
++ dgap_trcbufi += lenbuf;
++ dgap_trcbuf[dgap_trcbufi] = '~';
++ dgap_trcbuf[dgap_trcbufi+1] = '\0';
++
++ /* If we're near the end of the trace buffer... */
++ if (dgap_trcbufi > (dgap_trcbuf_size/8)*7) {
++ /* Wipe out the first eighth to make some more room. */
++ strcpy(dgap_trcbuf, &dgap_trcbuf[dgap_trcbuf_size/8]);
++ dgap_trcbufi = strlen(dgap_trcbuf)-1;
++ /* Plop overflow message at the top of the buffer. */
++ bcopy(TRC_OVERFLOW, dgap_trcbuf, strlen(TRC_OVERFLOW));
++ }
++# else
++# error "TRC_ON_OVERFLOW_WRAP_AROUND or TRC_ON_OVERFLOW_SHIFT_BUFFER?"
++# endif
++ }
++ DGAP_UNLOCK(dgap_tracef_lock, flags);
++
++# endif /* defined(TRC_TO_KMEM) */
++}
++
++#endif /* !defined(TRC_TO_KMEM) && !defined(TRC_TO_CONSOLE) */
++
++
++/*
++ * dgap_tracer_free()
++ *
++ *
++ */
++void dgap_tracer_free(void)
++{
++ if(dgap_trcbuf)
++ vfree(dgap_trcbuf);
++}
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/dgap_trace.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/dgap_trace.h 2003-09-27 11:38:18.449723600 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/dgap_trace.h 2003-09-27 11:38:20.963341472 +0800
+@@ -0,0 +1,36 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ * Scott H Kilau <Scott_Kilau at digi dot com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2, or (at your option)
++ * any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
++ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
++ * PURPOSE. See the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * NOTE: THIS IS A SHARED HEADER. DO NOT CHANGE CODING STYLE!!!
++ *
++ *****************************************************************************
++ * Header file for dgap_trace.c
++ *
++ * $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++ */
++
++#ifndef __DGAP_TRACE_H
++#define __DGAP_TRACE_H
++
++#include "dgap_driver.h"
++
++void dgap_tracef(const char *fmt, ...);
++void dgap_tracer_free(void);
++
++#endif
++
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/dgap_tty.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/dgap_tty.c 2003-09-27 11:38:18.449723600 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/dgap_tty.c 2003-09-27 11:38:20.970340408 +0800
+@@ -0,0 +1,3935 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ * Scott H Kilau <Scott_Kilau at digi dot com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2, or (at your option)
++ * any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
++ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
++ * PURPOSE. See the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ *
++ * NOTE TO LINUX KERNEL HACKERS: DO NOT REFORMAT THIS CODE!
++ *
++ * This is shared code between Digi's CVS archive and the
++ * Linux Kernel sources.
++ * Changing the source just for reformatting needlessly breaks
++ * our CVS diff history.
++ *
++ * Send any bug fixes/changes to: Eng.Linux at digi dot com.
++ * Thank you.
++ */
++
++/************************************************************************
++ *
++ * This file implements the tty driver functionality for the
++ * FEP5 based product lines.
++ *
++ ************************************************************************
++ *
++ * $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++ */
++
++#include "dgap_driver.h"
++#include <linux/ctype.h>
++#include "dgap_types.h"
++#include "dgap_fep5.h"
++#include "dgap_parse.h"
++
++#include <linux/tty_driver.h>
++#include <linux/tty_flip.h>
++
++#ifndef _POSIX_VDISABLE
++#define _POSIX_VDISABLE '\0'
++#endif
++
++/*
++ * external variables
++ */
++extern int dgap_debug;
++extern int dgap_rawreadok;
++extern spinlock_t dgap_global_lock;
++
++/*
++ * internal variables
++ */
++static struct board_t *dgap_BoardsByMajor[256];
++static u32 dgap_count = 500;
++static uchar *dgap_TmpWriteBuf = NULL;
++static DECLARE_MUTEX(dgap_TmpWriteSem);
++
++/*
++ * Default transparent print information.
++ */
++static struct digi_t digi_init = {
++ DIGI_COOK, /* Flags */
++ 100, /* Max CPS */
++ 50, /* Max chars in print queue */
++ 100, /* Printer buffer size */
++ 4, /* size of printer on string */
++ 4, /* size of printer off string */
++ "\033[5i", /* ANSI printer on string ] */
++ "\033[4i", /* ANSI printer off string ] */
++ "ansi" /* default terminal type */
++};
++
++
++/*
++ * Define a local default termios struct. All ports will be created
++ * with this termios initially.
++ *
++ * This defines a raw port at 9600 baud, 8 data bits, no parity,
++ * 1 stop bit.
++ */
++static struct termios DefaultTermios =
++{
++ c_iflag: (DEFAULT_IFLAGS), /* iflags */
++ c_oflag: (DEFAULT_OFLAGS), /* oflags */
++ c_cflag: (DEFAULT_CFLAGS), /* cflags */
++ c_lflag: (DEFAULT_LFLAGS), /* lflags */
++ c_cc: INIT_C_CC,
++ c_line: 0,
++};
++
++/* Our function prototypes */
++static void dgap_cmdb(struct channel_t *ch, uchar cmd, uchar byte1, uchar byte2, u32 ncmds);
++static void dgap_cmdw(struct channel_t *ch, uchar cmd, u16 word, u32 ncmds);
++static int dgap_tty_open(struct tty_struct *tty, struct file *file);
++static void dgap_tty_close(struct tty_struct *tty, struct file *file);
++static int block_til_ready(struct tty_struct *tty, struct file *file, struct channel_t *ch);
++static void dgap_carrier(struct channel_t *ch);
++static int dgap_tty_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg);
++static int dgap_tty_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count);
++static int dgap_tty_digigeta(struct tty_struct *tty, struct digi_t *retinfo);
++static int dgap_tty_digiseta(struct tty_struct *tty, struct digi_t *new_info);
++static int dgap_tty_write_room(struct tty_struct* tty);
++static void dgap_tty_put_char(struct tty_struct *tty, unsigned char c);
++static void dgap_tty_set_termios(struct tty_struct *tty, struct termios *old_termios);
++static int dgap_tty_chars_in_buffer(struct tty_struct* tty);
++static void dgap_tty_start(struct tty_struct *tty);
++static void dgap_tty_stop(struct tty_struct *tty);
++static void dgap_tty_throttle(struct tty_struct *tty);
++static void dgap_tty_unthrottle(struct tty_struct *tty);
++static void dgap_tty_flush_chars(struct tty_struct *tty);
++static void dgap_tty_flush_buffer(struct tty_struct *tty);
++static void dgap_tty_hangup(struct tty_struct *tty);
++static int dgap_wait_for_drain(struct tty_struct *tty);
++static int dgap_set_modem_info(struct tty_struct *tty, unsigned int command, unsigned int *value);
++static int dgap_get_modem_info(struct channel_t *ch, unsigned int *value);
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++ static int dgap_tty_tiocmget(struct tty_struct *tty, struct file *file);
++ static int dgap_tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear);
++#endif
++
++
++/************************************************************************
++ *
++ * TTY Initialization/Cleanup Functions
++ *
++ ************************************************************************/
++
++/*
++ * dgap_tty_preinit()
++ *
++ * Initialize any global tty related data before we download any boards.
++ */
++int dgap_tty_preinit(void)
++{
++ unsigned long flags;
++
++ DGAP_LOCK(dgap_global_lock, flags);
++
++ /*
++ * Allocate a buffer for doing the copy from user space to
++ * kernel space in dgap_input(). We only use one buffer and
++ * control access to it with a semaphore. If we are paging, we
++ * are already in trouble so one buffer won't hurt much anyway.
++ */
++ dgap_TmpWriteBuf = kmalloc(WRITEBUFLEN, GFP_ATOMIC);
++
++ if (!dgap_TmpWriteBuf) {
++ DGAP_UNLOCK(dgap_global_lock, flags);
++ DPR_INIT(("unable to allocate tmp write buf"));
++ return (-ENOMEM);
++ }
++
++ DGAP_UNLOCK(dgap_global_lock, flags);
++ return(0);
++}
++
++
++/*
++ * dgap_tty_register()
++ *
++ * Init the tty subsystem for this board.
++ */
++int dgap_tty_register(struct board_t *brd)
++{
++ int rc = 0;
++ char buf[MAXTTYNAMELEN];
++ char *ptr;
++
++ DPR_INIT(("tty_register start"));
++
++ buf[0] = '\0';
++
++ ptr = dgap_get_config_letters(brd, buf);
++
++ memset(&brd->SerialDriver, 0, sizeof(struct tty_driver));
++ memset(&brd->PrintDriver, 0, sizeof(struct tty_driver));
++
++ brd->SerialDriver.magic = TTY_DRIVER_MAGIC;
++
++ snprintf(brd->SerialName, MAXTTYNAMELEN, "tty[%s]", buf[0] != '\0' ? buf : "");
++ brd->SerialDriver.name = brd->SerialName;
++ brd->SerialDriver.name_base = 0;
++ brd->SerialDriver.major = 0;
++ brd->SerialDriver.minor_start = 0;
++ brd->SerialDriver.num = MAXPORTS;
++ brd->SerialDriver.type = TTY_DRIVER_TYPE_SERIAL;
++ brd->SerialDriver.subtype = SERIAL_TYPE_NORMAL;
++ brd->SerialDriver.init_termios = DefaultTermios;
++ brd->SerialDriver.flags = (TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS);
++ brd->SerialDriver.driver_name = DRVSTR;
++
++ /*
++ * The kernel wants space to store pointers to
++ * tty_struct's and termios's.
++ */
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++ brd->SerialDriver.ttys = dgap_driver_kzmalloc(MAXPORTS * sizeof(struct tty_struct *), GFP_KERNEL);
++ if (!brd->SerialDriver.ttys)
++ return(-ENOMEM);
++
++ brd->SerialDriver.refcount = brd->TtyRefCnt;
++#else
++ brd->SerialDriver.table = dgap_driver_kzmalloc(MAXPORTS * sizeof(struct tty_struct *), GFP_KERNEL);
++ if (!brd->SerialDriver.table)
++ return(-ENOMEM);
++
++ brd->SerialDriver.refcount = &brd->TtyRefCnt;
++
++#endif
++
++ brd->SerialDriver.termios = dgap_driver_kzmalloc(MAXPORTS * sizeof(struct termios *), GFP_KERNEL);
++
++ if (!brd->SerialDriver.termios)
++ return(-ENOMEM);
++
++ brd->SerialDriver.termios_locked = dgap_driver_kzmalloc(MAXPORTS * sizeof(struct termios *), GFP_KERNEL);
++
++ if (!brd->SerialDriver.termios_locked)
++ return(-ENOMEM);
++
++ /*
++ * Entry points for driver. Called by the kernel from
++ * tty_io.c and n_tty.c.
++ */
++ brd->SerialDriver.open = dgap_tty_open;
++ brd->SerialDriver.close = dgap_tty_close;
++ brd->SerialDriver.ioctl = dgap_tty_ioctl;
++ brd->SerialDriver.write = dgap_tty_write;
++ brd->SerialDriver.write_room = dgap_tty_write_room;
++ brd->SerialDriver.put_char = dgap_tty_put_char;
++ brd->SerialDriver.set_termios = dgap_tty_set_termios;
++ brd->SerialDriver.chars_in_buffer = dgap_tty_chars_in_buffer;
++ brd->SerialDriver.stop = dgap_tty_stop;
++ brd->SerialDriver.start = dgap_tty_start;
++ brd->SerialDriver.throttle = dgap_tty_throttle;
++ brd->SerialDriver.unthrottle = dgap_tty_unthrottle;
++ brd->SerialDriver.flush_chars = dgap_tty_flush_chars;
++ brd->SerialDriver.flush_buffer = dgap_tty_flush_buffer;
++ brd->SerialDriver.hangup = dgap_tty_hangup;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++ brd->SerialDriver.owner = THIS_MODULE;
++ brd->SerialDriver.tiocmget = dgap_tty_tiocmget;
++ brd->SerialDriver.tiocmset = dgap_tty_tiocmset;
++#endif
++
++ /*
++ * If we're doing transparent print, we have to do all of the above
++ * again, seperately so we don't get the LD confused about what major
++ * we are when we get into the dgap_tty_open() routine.
++ */
++ brd->PrintDriver.magic = TTY_DRIVER_MAGIC;
++ snprintf(brd->PrintName, MAXTTYNAMELEN, "pr[%s]", buf[0] != '\0' ? buf : "");
++ brd->PrintDriver.name = brd->PrintName;
++ brd->PrintDriver.name_base = 0;
++ brd->PrintDriver.major = 0;
++ brd->PrintDriver.minor_start = 0;
++ brd->PrintDriver.num = MAXPORTS;
++ brd->PrintDriver.type = TTY_DRIVER_TYPE_SERIAL;
++ brd->PrintDriver.subtype = SERIAL_TYPE_NORMAL;
++ brd->PrintDriver.init_termios = DefaultTermios;
++ brd->PrintDriver.flags = (TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS);
++ brd->PrintDriver.driver_name = DRVSTR;
++
++ /*
++ * The kernel wants space to store pointers to
++ * tty_struct's and termios's. Must be seperate from
++ * the Serial Driver so we don't get confused
++ */
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++ brd->PrintDriver.ttys = dgap_driver_kzmalloc(MAXPORTS * sizeof(struct tty_struct *), GFP_KERNEL);
++ if (!brd->PrintDriver.ttys)
++ return(-ENOMEM);
++
++ brd->PrintDriver.refcount = brd->TtyRefCnt;
++#else
++ brd->PrintDriver.table = dgap_driver_kzmalloc(MAXPORTS * sizeof(struct tty_struct *), GFP_KERNEL);
++ if (!brd->PrintDriver.table)
++ return(-ENOMEM);
++
++ brd->PrintDriver.refcount = &brd->TtyRefCnt;
++
++#endif
++
++ brd->PrintDriver.termios = dgap_driver_kzmalloc(MAXPORTS * sizeof(struct termios *), GFP_KERNEL);
++
++ if (!brd->PrintDriver.termios)
++ return(-ENOMEM);
++
++ brd->PrintDriver.termios_locked = dgap_driver_kzmalloc(MAXPORTS * sizeof(struct termios *), GFP_KERNEL);
++
++ if (!brd->PrintDriver.termios_locked)
++ return(-ENOMEM);
++
++ /*
++ * Entry points for driver. Called by the kernel from
++ * tty_io.c and n_tty.c.
++ */
++ brd->PrintDriver.open = dgap_tty_open;
++ brd->PrintDriver.close = dgap_tty_close;
++ brd->PrintDriver.ioctl = dgap_tty_ioctl;
++ brd->PrintDriver.write = dgap_tty_write;
++ brd->PrintDriver.write_room = dgap_tty_write_room;
++ brd->PrintDriver.put_char = dgap_tty_put_char;
++ brd->PrintDriver.set_termios = dgap_tty_set_termios;
++ brd->PrintDriver.chars_in_buffer = dgap_tty_chars_in_buffer;
++ brd->PrintDriver.stop = dgap_tty_stop;
++ brd->PrintDriver.start = dgap_tty_start;
++ brd->PrintDriver.throttle = dgap_tty_throttle;
++ brd->PrintDriver.unthrottle = dgap_tty_unthrottle;
++ brd->PrintDriver.flush_chars = dgap_tty_flush_chars;
++ brd->PrintDriver.flush_buffer = dgap_tty_flush_buffer;
++ brd->PrintDriver.hangup = dgap_tty_hangup;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++ brd->SerialDriver.owner = THIS_MODULE;
++ brd->PrintDriver.tiocmget = dgap_tty_tiocmget;
++ brd->PrintDriver.tiocmset = dgap_tty_tiocmset;
++#endif
++
++ if (!brd->dgap_Major_Serial_Registered) {
++ /* Register tty devices */
++ rc = tty_register_driver(&brd->SerialDriver);
++ if (rc < 0) {
++ APR(("Can't register tty device (%d)\n", rc));
++ return(rc);
++ }
++ brd->dgap_Major_Serial_Registered = TRUE;
++ dgap_BoardsByMajor[brd->SerialDriver.major] = brd;
++ brd->dgap_Serial_Major = brd->SerialDriver.major;
++ }
++
++ if (!brd->dgap_Major_TransparentPrint_Registered) {
++ /* Register Transparent Print devices */
++ rc = tty_register_driver(&brd->PrintDriver);
++ if (rc < 0) {
++ APR(("Can't register Transparent Print device (%d)\n", rc));
++ return(rc);
++ }
++ brd->dgap_Major_TransparentPrint_Registered = TRUE;
++ dgap_BoardsByMajor[brd->PrintDriver.major] = brd;
++ brd->dgap_TransparentPrint_Major = brd->PrintDriver.major;
++ }
++
++ DPR_INIT(("DGAP REGISTER TTY: MAJORS: %d %d\n", brd->SerialDriver.major,
++ brd->PrintDriver.major));
++
++ return (rc);
++}
++
++
++/*
++ * dgap_tty_init()
++ *
++ * Init the tty subsystem. Called once per board after board has been
++ * downloaded and init'ed.
++ */
++int dgap_tty_init(struct board_t *brd)
++{
++ int i;
++ int tlw;
++ uint true_count = 0;
++ uchar *vaddr;
++ uchar modem = 0;
++ struct channel_t *ch;
++ struct bs_t *bs;
++ struct cm_t *cm;
++
++ if (!brd)
++ return (-ENXIO);
++
++ DPR_INIT(("dgap_tty_init start\n"));
++
++ /*
++ * Initialize board structure elements.
++ */
++
++ vaddr = brd->re_map_membase;
++ true_count = readw((vaddr + NCHAN));
++
++ brd->nasync = dgap_config_get_number_of_ports(brd);
++
++ if (!brd->nasync) {
++ brd->nasync = brd->maxports;
++ }
++
++ if (brd->nasync > brd->maxports) {
++ brd->nasync = brd->maxports;
++ }
++
++ if (true_count != brd->nasync) {
++ if ((brd->type == PPCM) && (true_count == 64)) {
++ APR(("***WARNING**** %s configured for %d ports, has %d ports.\nPlease make SURE the EBI cable running from the card\nto each EM module is plugged into EBI IN!\n",
++ brd->name, brd->nasync, true_count));
++ }
++ else if ((brd->type == PPCM) && (true_count == 0)) {
++ APR(("***WARNING**** %s configured for %d ports, has %d ports.\nPlease make SURE the EBI cable running from the card\nto each EM module is plugged into EBI IN!\n",
++ brd->name, brd->nasync, true_count));
++ }
++ else {
++ APR(("***WARNING**** %s configured for %d ports, has %d ports.\n",
++ brd->name, brd->nasync, true_count));
++ }
++
++ brd->nasync = true_count;
++
++ /* If no ports, don't bother going any further */
++ if (!brd->nasync) {
++ brd->state = BOARD_FAILED;
++ brd->dpastatus = BD_NOFEP;
++ return(-ENXIO);
++ }
++ }
++
++ /*
++ * Allocate channel memory that might not have been allocated
++ * when the driver was first loaded.
++ */
++ for (i = 0; i < brd->nasync; i++) {
++ if (!brd->channels[i]) {
++ brd->channels[i] = dgap_driver_kzmalloc(sizeof(struct channel_t), GFP_ATOMIC);
++ if (!brd->channels[i]) {
++ DPR_CORE(("%s:%d Unable to allocate memory for channel struct\n",
++ __FILE__, __LINE__));
++ }
++ }
++ }
++
++ ch = brd->channels[0];
++ vaddr = brd->re_map_membase;
++
++ bs = (struct bs_t *) ((ulong) vaddr + CHANBUF);
++ cm = (struct cm_t *) ((ulong) vaddr + CMDBUF);
++
++ brd->bd_bs = bs;
++
++ /* Set up channel variables */
++ for (i = 0; i < brd->nasync; i++, ch = brd->channels[i], bs++) {
++
++ if (!brd->channels[i])
++ continue;
++
++ DGAP_SPINLOCK_INIT(ch->ch_lock);
++
++ /* Store all our magic numbers */
++ ch->magic = DGAP_CHANNEL_MAGIC;
++ ch->ch_tun.magic = DGAP_UNIT_MAGIC;
++ ch->ch_pun.magic = DGAP_UNIT_MAGIC;
++
++ ch->ch_vaddr = vaddr;
++ ch->ch_bs = bs;
++ ch->ch_cm = cm;
++ ch->ch_bd = brd;
++ ch->ch_portnum = i;
++ ch->ch_digi = digi_init;
++
++ /*
++ * Set up digi dsr and dcd bits based on altpin flag.
++ */
++ if (dgap_config_get_altpin(brd)) {
++ ch->ch_dsr = DM_CD;
++ ch->ch_cd = DM_DSR;
++ ch->ch_digi.digi_flags |= DIGI_ALTPIN;
++ }
++ else {
++ ch->ch_cd = DM_CD;
++ ch->ch_dsr = DM_DSR;
++ }
++
++ ch->ch_taddr = vaddr + ((ch->ch_bs->tx_seg) << 4);
++ ch->ch_raddr = vaddr + ((ch->ch_bs->rx_seg) << 4);
++ ch->ch_tx_win = 0;
++ ch->ch_rx_win = 0;
++ ch->ch_tsize = readw(&(ch->ch_bs->tx_max)) + 1;
++ ch->ch_rsize = readw(&(ch->ch_bs->rx_max)) + 1;
++ ch->ch_tstart = 0;
++ ch->ch_rstart = 0;
++
++ /* .25 second delay */
++ ch->ch_close_delay = 250;
++
++ /*
++ * Set queue water marks, interrupt mask,
++ * and general tty parameters.
++ */
++ ch->ch_tlw = tlw = ch->ch_tsize >= 2000 ? ((ch->ch_tsize * 5) / 8) : ch->ch_tsize / 2;
++
++ dgap_cmdw(ch, STLOW, tlw, 0);
++
++ dgap_cmdw(ch, SRLOW, ch->ch_rsize / 2, 0);
++
++ dgap_cmdw(ch, SRHIGH, 7 * ch->ch_rsize / 8, 0);
++
++ ch->ch_mistat = readb(&(ch->ch_bs->m_stat));
++
++ init_waitqueue_head(&ch->ch_flags_wait);
++ init_waitqueue_head(&ch->ch_tun.un_flags_wait);
++ init_waitqueue_head(&ch->ch_pun.un_flags_wait);
++
++ /* Turn on all modem interrupts for now */
++ modem = (DM_CD | DM_DSR | DM_CTS | DM_RI);
++ writeb(modem, &(ch->ch_bs->m_int));
++ }
++
++ /*
++ * Set edelay to 0 if interrupts are turned on,
++ * otherwise set edelay to the usual 100.
++ */
++ if (brd->intr_used)
++ writew(0, &(brd->bd_bs->edelay));
++ else
++ writew(100, &(brd->bd_bs->edelay));
++
++ writeb(1, &(brd->bd_bs->idata));
++
++ DPR_INIT(("dgap_tty_init finish\n"));
++
++ return (0);
++}
++
++
++/*
++ * dgap_tty_post_uninit()
++ *
++ * UnInitialize any global tty related data.
++ */
++void dgap_tty_post_uninit(void)
++{
++ if (dgap_TmpWriteBuf) {
++ kfree(dgap_TmpWriteBuf);
++ dgap_TmpWriteBuf = NULL;
++ }
++}
++
++
++/*
++ * dgap_tty_uninit()
++ *
++ * Uninitialize the TTY portion of this driver. Free all memory and
++ * resources.
++ */
++void dgap_tty_uninit(struct board_t *brd)
++{
++ if (brd->dgap_Major_Serial_Registered) {
++ dgap_BoardsByMajor[brd->SerialDriver.major] = NULL;
++ brd->dgap_Serial_Major = 0;
++ tty_unregister_driver(&brd->SerialDriver);
++ brd->dgap_Major_Serial_Registered = FALSE;
++ }
++
++ if (brd->dgap_Major_TransparentPrint_Registered) {
++ dgap_BoardsByMajor[brd->PrintDriver.major] = 0;
++ brd->dgap_TransparentPrint_Major = 0;
++ tty_unregister_driver(&brd->PrintDriver);
++ brd->dgap_Major_TransparentPrint_Registered = FALSE;
++ }
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++ if (brd->SerialDriver.ttys) {
++ kfree(brd->SerialDriver.ttys);
++ brd->SerialDriver.ttys = NULL;
++ }
++ if (brd->PrintDriver.ttys) {
++ kfree(brd->PrintDriver.ttys);
++ brd->PrintDriver.ttys = NULL;
++ }
++#else
++ if (brd->SerialDriver.table) {
++ kfree(brd->SerialDriver.table);
++ brd->SerialDriver.table = NULL;
++ }
++ if (brd->PrintDriver.table) {
++ kfree(brd->PrintDriver.table);
++ brd->PrintDriver.table = NULL;
++ }
++#endif
++}
++
++
++/*=======================================================================
++ *
++ * dgap_cmdb - Sends a 2 byte command to the FEP.
++ *
++ * ch - Pointer to channel structure.
++ * cmd - Command to be sent.
++ * byte1 - Integer containing first byte to be sent.
++ * byte2 - Integer containing second byte to be sent.
++ * ncmds - Wait until ncmds or fewer cmds are left
++ * in the cmd buffer before returning.
++ *
++ *=======================================================================*/
++void dgap_cmdb(struct channel_t *ch, uchar cmd, uchar byte1, uchar byte2, u32 ncmds)
++{
++ char *vaddr = NULL;
++ struct cm_t *cm_addr = NULL;
++ u16 head;
++ u16 tail;
++ u32 count;
++ u32 n;
++
++ if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++ return;
++
++ /*
++ * Check if board is still alive.
++ */
++ if (ch->ch_bd->state == BOARD_FAILED) {
++ DPR_CORE(("%s:%d board is in failed state.\n", __FILE__, __LINE__));
++ return;
++ }
++
++ /*
++ * Make sure the pointers are in range before
++ * writing to the FEP memory.
++ */
++ vaddr = ch->ch_bd->re_map_membase;
++
++ if (!vaddr)
++ return;
++
++ cm_addr = (struct cm_t *) (vaddr + CMDBUF);
++ head = readw(&(cm_addr->cm_head));
++
++ /*
++ * Forget it if pointers out of range.
++ */
++ if (head >= (CMDMAX - CMDSTART) || (head & 03)) {
++ DPR_CORE(("%s:%d pointers out of range, failing board!\n", __FILE__, __LINE__));
++ ch->ch_bd->state = BOARD_FAILED;
++ return;
++ }
++
++ /*
++ * Put the data in the circular command buffer.
++ */
++ writeb(cmd, (char *) (vaddr + head + CMDSTART + 0));
++ writeb((uchar) ch->ch_portnum, (char *) (vaddr + head + CMDSTART + 1));
++ writeb(byte1, (char *) (vaddr + head + CMDSTART + 2));
++ writeb(byte2, (char *) (vaddr + head + CMDSTART + 3));
++
++ head = (head + 4) & (CMDMAX - CMDSTART - 4);
++
++ writew(head, &(cm_addr->cm_head));
++
++ /*
++ * Wait if necessary before updating the head
++ * pointer to limit the number of outstanding
++ * commands to the FEP. If the time spent waiting
++ * is outlandish, declare the FEP dead.
++ */
++ for (count = dgap_count ;;) {
++
++ head = readw(&(cm_addr->cm_head));
++ tail = readw(&(cm_addr->cm_tail));
++
++ n = (head - tail) & (CMDMAX - CMDSTART - 4);
++
++ if (n <= ncmds * sizeof(struct cm_t))
++ break;
++
++ if (--count == 0) {
++ DPR_CORE(("%s:%d failing board.\n",__FILE__, __LINE__));
++ ch->ch_bd->state = BOARD_FAILED;
++ return;
++ }
++ udelay(10);
++ }
++}
++
++
++/*=======================================================================
++ *
++ * dgap_cmdw - Sends a 1 word command to the FEP.
++ *
++ * ch - Pointer to channel structure.
++ * cmd - Command to be sent.
++ * word - Integer containing word to be sent.
++ * ncmds - Wait until ncmds or fewer cmds are left
++ * in the cmd buffer before returning.
++ *
++ *=======================================================================*/
++void dgap_cmdw(struct channel_t *ch, uchar cmd, u16 word, u32 ncmds)
++{
++ char *vaddr = NULL;
++ struct cm_t *cm_addr = NULL;
++ u16 head;
++ u16 tail;
++ u32 count;
++ u32 n;
++
++ if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++ return;
++
++ /*
++ * Check if board is still alive.
++ */
++ if (ch->ch_bd->state == BOARD_FAILED) {
++ DPR_CORE(("%s:%d board is failed!\n", __FILE__, __LINE__));
++ return;
++ }
++
++ /*
++ * Make sure the pointers are in range before
++ * writing to the FEP memory.
++ */
++ vaddr = ch->ch_bd->re_map_membase;
++ if (!vaddr)
++ return;
++
++ cm_addr = (struct cm_t *) (vaddr + CMDBUF);
++ head = readw(&(cm_addr->cm_head));
++
++ /*
++ * Forget it if pointers out of range.
++ */
++ if (head >= (CMDMAX - CMDSTART) || (head & 03)) {
++ DPR_CORE(("%s:%d Pointers out of range. Failing board.\n",__FILE__, __LINE__));
++ ch->ch_bd->state = BOARD_FAILED;
++ return;
++ }
++
++ /*
++ * Put the data in the circular command buffer.
++ */
++ writeb(cmd, (char *) (vaddr + head + CMDSTART + 0));
++ writeb((uchar) ch->ch_portnum, (char *) (vaddr + head + CMDSTART + 1));
++ writew((u16) word, (char *) (vaddr + head + CMDSTART + 2));
++
++ head = (head + 4) & (CMDMAX - CMDSTART - 4);
++
++ writew(head, &(cm_addr->cm_head));
++
++ /*
++ * Wait if necessary before updating the head
++ * pointer to limit the number of outstanding
++ * commands to the FEP. If the time spent waiting
++ * is outlandish, declare the FEP dead.
++ */
++ for (count = dgap_count ;;) {
++
++ head = readw(&(cm_addr->cm_head));
++ tail = readw(&(cm_addr->cm_tail));
++
++ n = (head - tail) & (CMDMAX - CMDSTART - 4);
++
++ if (n <= ncmds * sizeof(struct cm_t))
++ break;
++
++ if (--count == 0) {
++ DPR_CORE(("%s:%d Failing board.\n",__FILE__, __LINE__));
++ ch->ch_bd->state = BOARD_FAILED;
++ return;
++ }
++ udelay(10);
++ }
++}
++
++
++/*=======================================================================
++ *
++ * dgap_wmove - Write data to FEP buffer.
++ *
++ * ch - Pointer to channel structure.
++ * buf - Poiter to characters to be moved.
++ * cnt - Number of characters to move.
++ *
++ *=======================================================================*/
++void dgap_wmove(struct channel_t *ch, char *buf, u32 cnt)
++{
++ int n;
++ char *taddr;
++ struct bs_t *bs;
++ u32 head;
++
++ if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++ return;
++
++ /*
++ * Check parameters.
++ */
++ bs = ch->ch_bs;
++ head = readw(&(bs->tx_head));
++
++ /*
++ * If pointers are out of range, just return.
++ */
++ if ((cnt > ch->ch_tsize) || (unsigned)(head - ch->ch_tstart) >= ch->ch_tsize) {
++ DPR_CORE(("%s:%d pointer out of range", __FILE__, __LINE__));
++ return;
++ }
++
++ /*
++ * If the write wraps over the top of the circular buffer,
++ * move the portion up to the wrap point, and reset the
++ * pointers to the bottom.
++ */
++ n = ch->ch_tstart + ch->ch_tsize - head;
++
++ if (cnt >= n) {
++ cnt -= n;
++ taddr = ch->ch_taddr + head;
++ memcpy_toio(taddr, buf, n);
++ head = ch->ch_tstart;
++ buf += n;
++ }
++
++ /*
++ * Move rest of data.
++ */
++ taddr = ch->ch_taddr + head;
++ n = cnt;
++ memcpy_toio(taddr, buf, n);
++ head += cnt;
++
++ writew(head, &(bs->tx_head));
++}
++
++
++
++/*=======================================================================
++ *
++ * dgap_param - Set Digi parameters.
++ *
++ * struct tty_struct * - TTY for port.
++ *
++ *=======================================================================*/
++int dgap_param(struct tty_struct *tty)
++{
++ struct termios *ts;
++ struct board_t *bd;
++ struct channel_t *ch;
++ struct bs_t *bs;
++ struct un_t *un;
++ u32 head;
++ u32 cflag;
++ u32 iflag;
++ uchar mval;
++ uchar hflow;
++
++ if (!tty || tty->magic != TTY_MAGIC) {
++ return (-ENXIO);
++ }
++
++ un = (struct un_t *) tty->driver_data;
++ if (!un || un->magic != DGAP_UNIT_MAGIC) {
++ return (-ENXIO);
++ }
++
++ ch = un->un_ch;
++ if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) {
++ return (-ENXIO);
++ }
++
++ bd = ch->ch_bd;
++ if (!bd || bd->magic != DGAP_BOARD_MAGIC) {
++ return (-ENXIO);
++ }
++
++ bs = ch->ch_bs;
++ if (bs == 0) {
++ return (-ENXIO);
++ }
++
++ DPR_PARAM(("param start: tdev: %x cflags: %x oflags: %x iflags: %x\n",
++ ch->ch_tun.un_dev, ch->ch_c_cflag, ch->ch_c_oflag, ch->ch_c_iflag));
++
++ ts = tty->termios;
++
++ /*
++ * If baud rate is zero, flush queues, and set mval to drop DTR.
++ */
++ if ((ch->ch_c_cflag & (CBAUD)) == 0) {
++
++ /* flush rx */
++ head = readw(&(ch->ch_bs->rx_head));
++ writew(head, &(ch->ch_bs->rx_tail));
++
++ /* flush tx */
++ head = readw(&(ch->ch_bs->tx_head));
++ /* Okay to have channel and board locks held calling this */
++ dgap_cmdw( ch, FLUSHTX, (u16) head, 0 );
++
++ /* Drop RTS and DTR */
++ ch->ch_mostat &= ~(D_RTS(ch)|D_DTR(ch));
++ dgap_cmdb( ch, SMODEM, 0, D_DTR(ch)|D_RTS(ch), 0 );
++
++ mval = 0;
++ }
++ else {
++ /*
++ * Set baud rate, character size, and parity.
++ */
++
++ /*
++ * CBAUD has bit position 0x1000 set these days to indicate Linux
++ * baud rate remap.
++ * We use a different bit assignment for high speed. Clear this
++ * bit out while grabbing the parts of "cflag" we want.
++ */
++ cflag = ch->ch_c_cflag & ((CBAUD ^ CBAUDEX) | PARODD | PARENB | CSTOPB | CSIZE);
++
++ /*
++ * HUPCL bit is used by FEP to indicate fast baud
++ * table is to be used.
++ */
++ if ((ch->ch_digi.digi_flags & DIGI_FAST) || (ch->ch_c_cflag & CBAUDEX))
++ cflag |= HUPCL;
++
++
++ if ((ch->ch_c_cflag & CBAUDEX) && !(ch->ch_digi.digi_flags & DIGI_FAST)) {
++ /*
++ * The below code is trying to guarantee that only baud rates
++ * 115200, 230400, 460800, 921600 are remapped. We use exclusive or
++ * because the various baud rates share common bit positions
++ * and therefore can't be tested for easily.
++ */
++ tcflag_t tcflag = (ch->ch_c_cflag & CBAUD) | CBAUDEX;
++ int baudpart = 0;
++
++ /* Map high speed requests to index into FEP's baud table */
++ switch (tcflag) {
++ case B57600 :
++ baudpart = 1;
++ break;
++#ifdef B76800
++ case B76800 :
++ baudpart = 2;
++ break;
++#endif
++ case B115200 :
++ baudpart = 3;
++ break;
++ case B230400 :
++ baudpart = 9;
++ break;
++ case B460800 :
++ baudpart = 11;
++ break;
++#ifdef B921600
++ case B921600 :
++ baudpart = 12;
++ break;
++#endif
++ default:
++ baudpart = 0;
++ }
++
++ if (baudpart)
++ cflag = (cflag & ~(CBAUD | CBAUDEX)) | baudpart;
++ }
++
++ cflag &= 0xffff;
++
++ if (cflag != ch->ch_fepcflag) {
++ ch->ch_fepcflag = (u16) (cflag & 0xffff);
++
++ /* Okay to have channel and board locks held calling this */
++ dgap_cmdw(ch, SCFLAG, (u16) cflag, 0);
++ }
++
++ mval = D_DTR(ch) | D_RTS(ch);
++ }
++
++ /*
++ * Get input flags.
++ */
++ iflag = ch->ch_c_iflag & (IGNBRK | BRKINT | IGNPAR | PARMRK | INPCK | ISTRIP | IXON | IXANY | IXOFF);
++
++ if ((ch->ch_startc == _POSIX_VDISABLE) || (ch->ch_stopc == _POSIX_VDISABLE)) {
++ iflag &= ~(IXON | IXOFF);
++ ch->ch_c_iflag &= ~(IXON | IXOFF);
++ }
++
++ if (ch->ch_digi.digi_flags & DIGI_ALTPIN)
++ iflag |= IALTPIN ;
++
++ if (iflag != ch->ch_fepiflag) {
++ ch->ch_fepiflag = iflag;
++
++ /* Okay to have channel and board locks held calling this */
++ dgap_cmdw(ch, SIFLAG, (u16) ch->ch_fepiflag, 0);
++ }
++
++ /*
++ * Select hardware handshaking.
++ */
++ hflow = 0;
++
++ if (ch->ch_c_cflag & CRTSCTS) {
++ hflow |= (D_RTS(ch) | D_CTS(ch));
++ }
++ if (ch->ch_digi.digi_flags & RTSPACE)
++ hflow |= D_RTS(ch);
++ if (ch->ch_digi.digi_flags & DTRPACE)
++ hflow |= D_DTR(ch);
++ if (ch->ch_digi.digi_flags & CTSPACE)
++ hflow |= D_CTS(ch);
++ if (ch->ch_digi.digi_flags & DSRPACE)
++ hflow |= D_DSR(ch);
++ if (ch->ch_digi.digi_flags & DCDPACE)
++ hflow |= D_CD(ch);
++
++ if (hflow != ch->ch_hflow) {
++ ch->ch_hflow = hflow;
++
++ /* Okay to have channel and board locks held calling this */
++ dgap_cmdb(ch, SHFLOW, (uchar) hflow, 0xff, 0);
++ }
++
++ /*
++ * Set modem control lines.
++ */
++ mval ^= ch->ch_mforce & (mval ^ ch->ch_mval);
++
++ if (ch->ch_mostat ^ mval) {
++ ch->ch_mostat = mval;
++
++ /* Okay to have channel and board locks held calling this */
++ dgap_cmdb(ch, SMODEM, (uchar) mval, D_RTS(ch)|D_DTR(ch), 0);
++ }
++
++ /*
++ * Read modem signals, and then call carrier function.
++ */
++ ch->ch_mistat = readb(&(bs->m_stat));
++ dgap_carrier(ch);
++
++ /*
++ * Set the start and stop characters.
++ */
++ if (ch->ch_startc != ch->ch_fepstartc || ch->ch_stopc != ch->ch_fepstopc) {
++ ch->ch_fepstartc = ch->ch_startc;
++ ch->ch_fepstopc = ch->ch_stopc;
++
++ /* Okay to have channel and board locks held calling this */
++ dgap_cmdb(ch, SFLOWC, ch->ch_fepstartc, ch->ch_fepstopc, 0);
++ }
++
++ /*
++ * Set the Auxiliary start and stop characters.
++ */
++ if (ch->ch_astartc != ch->ch_fepastartc || ch->ch_astopc != ch->ch_fepastopc) {
++ ch->ch_fepastartc = ch->ch_astartc;
++ ch->ch_fepastopc = ch->ch_astopc;
++
++ /* Okay to have channel and board locks held calling this */
++ dgap_cmdb(ch, SAFLOWC, ch->ch_fepastartc, ch->ch_fepastopc, 0);
++ }
++
++ DPR_PARAM(("param finish\n"));
++
++ return (0);
++}
++
++
++/*
++ * parity_scan()
++ *
++ * Convert the FEP5 way of reporting parity errors and breaks into
++ * the Linux line discipline way.
++ */
++static void parity_scan(struct channel_t *ch, unsigned char *cbuf, unsigned char *fbuf, int *len)
++{
++ int l = *len;
++ int count = 0;
++ unsigned char *in, *cout, *fout;
++ unsigned char c;
++
++ in = cbuf;
++ cout = cbuf;
++ fout = fbuf;
++
++ DPR_PSCAN(("parity_scan start\n"));
++
++ if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++ return;
++
++ while (l--) {
++ c = *in++;
++ switch (ch->pscan_state) {
++ default:
++ /* reset to sanity and fall through */
++ ch->pscan_state = 0;
++
++ case 0:
++ /* No FF seen yet */
++ if (c == (unsigned char) '\377') {
++ /* delete this character from stream */
++ ch->pscan_state = 1;
++ } else {
++ *cout++ = c;
++ *fout++ = TTY_NORMAL;
++ count += 1;
++ }
++ break;
++
++ case 1:
++ /* first FF seen */
++ if (c == (unsigned char) '\377') {
++ /* doubled ff, transform to single ff */
++ *cout++ = c;
++ *fout++ = TTY_NORMAL;
++ count += 1;
++ ch->pscan_state = 0;
++ } else {
++ /* save value examination in next state */
++ ch->pscan_savechar = c;
++ ch->pscan_state = 2;
++ }
++ break;
++
++ case 2:
++ /* third character of ff sequence */
++
++ *cout++ = c;
++
++ if (ch->pscan_savechar == 0x0) {
++
++ if (c == 0x0) {
++ DPR_PSCAN(("parity_scan in 3rd char of ff seq. c: %x setting break.\n", c));
++ *fout++ = TTY_BREAK;
++ }
++ else {
++ DPR_PSCAN(("parity_scan in 3rd char of ff seq. c: %x setting parity.\n", c));
++ *fout++ = TTY_PARITY;
++ }
++ }
++ else {
++ DPR_PSCAN(("%s:%d Logic Error.\n", __FILE__, __LINE__));
++ }
++
++ count += 1;
++ ch->pscan_state = 0;
++ }
++ }
++ *len = count;
++ DPR_PSCAN(("parity_scan finish\n"));
++}
++
++
++/*=======================================================================
++ *
++ * dgap_input - Process received data.
++ *
++ * ch - Pointer to channel structure.
++ *
++ *=======================================================================*/
++void dgap_input(struct channel_t *ch)
++{
++ struct board_t *bd;
++ struct bs_t *bs;
++ struct tty_struct *tp;
++ uint rmask;
++ uint head;
++ uint tail;
++ int data_len;
++ ulong lock_flags;
++ ulong lock_flags2;
++ int flip_len;
++ int len = 0;
++ int n = 0;
++ char *buf;
++ uchar tmpchar;
++ int s = 0;
++
++ if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++ return;
++
++ tp = ch->ch_tun.un_tty;
++
++ bs = ch->ch_bs;
++ if (!bs) {
++ return;
++ }
++
++ bd = ch->ch_bd;
++ if(!bd || bd->magic != DGAP_BOARD_MAGIC)
++ return;
++
++ DPR_READ(("dgap_input start\n"));
++
++ DGAP_LOCK(bd->bd_lock, lock_flags);
++ DGAP_LOCK(ch->ch_lock, lock_flags2);
++
++ /*
++ * Figure the number of characters in the buffer.
++ * Exit immediately if none.
++ */
++
++ rmask = ch->ch_rsize - 1;
++
++ head = readw(&(bs->rx_head));
++ head &= rmask;
++ tail = readw(&(bs->rx_tail));
++ tail &= rmask;
++
++ data_len = (head - tail) & rmask;
++
++ if (data_len == 0) {
++ writeb(1, &(bs->idata));
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++ DPR_READ(("No data on port %d\n", ch->ch_portnum));
++ return;
++ }
++
++ /*
++ * If the device is not open, or CREAD is off, flush
++ * input data and return immediately.
++ */
++ if (!tp || (tp->magic != TTY_MAGIC) || !(ch->ch_tun.un_flags & UN_ISOPEN) ||
++ !(tp->termios->c_cflag & CREAD) || (ch->ch_tun.un_flags & UN_CLOSING)) {
++
++ DPR_READ(("input. dropping %d bytes on port %d...\n", data_len, ch->ch_portnum));
++ DPR_READ(("input. tp: %p tp->magic: %x MAGIC:%x ch flags: %x\n",
++ tp, tp ? tp->magic : 0, TTY_MAGIC, ch->ch_tun.un_flags));
++ writew(head, &(bs->rx_tail));
++ writeb(1, &(bs->idata));
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++ return;
++ }
++
++ /*
++ * If we are throttled, simply don't read any data.
++ */
++ if (ch->ch_flags & CH_RXBLOCK) {
++ writeb(1, &(bs->idata));
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++ DPR_READ(("Port %d throttled, not reading any data. head: %x tail: %x\n",
++ ch->ch_portnum, head, tail));
++ return;
++ }
++
++ /*
++ * Ignore oruns.
++ */
++ tmpchar = readb(&(bs->orun));
++ if (tmpchar) {
++ writeb(0, &(bs->orun));
++ }
++
++ DPR_READ(("dgap_input start 2\n"));
++
++ /*
++ * If the rxbuf is empty and we are not throttled, put as much
++ * as we can directly into the linux TTY flip buffer.
++ * The dgap_rawreadok case takes advantage of carnal knowledge that
++ * the char_buf and the flag_buf are next to each other and
++ * are each of (2 * TTY_FLIPBUF_SIZE) size.
++ *
++ * NOTE: if(!tty->real_raw), the call to ldisc.receive_buf
++ * actually still uses the flag buffer, so you can't
++ * use it for input data
++ */
++ if (dgap_rawreadok) {
++ if (tp->real_raw) {
++ flip_len = MYFLIPLEN;
++ }
++ else {
++ flip_len = 2 * TTY_FLIPBUF_SIZE;
++ }
++ }
++ else {
++ flip_len = TTY_FLIPBUF_SIZE - tp->flip.count;
++ }
++
++ len = min(data_len, flip_len);
++ len = min(len, (N_TTY_BUF_SIZE - 1) - tp->read_cnt);
++
++ if (len <= 0) {
++ writeb(1, &(bs->idata));
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++ DPR_READ(("dgap_input 1 - finish\n"));
++ return;
++ }
++
++ /*
++ * If we're bypassing flip buffers on rx, we can blast it
++ * right into the beginning of the buffer.
++ */
++ if (dgap_rawreadok) {
++ if (tp->real_raw) {
++ buf = ch->ch_bd->flipbuf;
++ }
++ else {
++ buf = tp->flip.char_buf;
++ }
++ }
++ else {
++ buf = tp->flip.char_buf_ptr;
++ }
++
++ n = len;
++
++ /*
++ * n now contains the most amount of data we can copy,
++ * bounded either by the flip buffer size or the amount
++ * of data the card actually has pending...
++ */
++ while (n) {
++
++ s = ((head >= tail) ? head : ch->ch_rsize) - tail;
++ s = min(s, n);
++
++ if (s <= 0)
++ break;
++
++
++ memcpy_fromio(buf, (char *) ch->ch_raddr + tail, s);
++
++ tail += s;
++ buf += s;
++ n -= s;
++ /* Flip queue if needed */
++ tail &= rmask;
++ }
++
++ /*
++ * In high performance mode, we don't have to update
++ * flag_buf or any of the counts or pointers into flip buf.
++ */
++ if (!dgap_rawreadok) {
++ if (I_PARMRK(tp)) {
++ parity_scan(ch, tp->flip.char_buf_ptr,
++ tp->flip.flag_buf_ptr, &len);
++ }
++ else {
++ memset(tp->flip.flag_buf_ptr, 0, len);
++ }
++
++ tp->flip.char_buf_ptr += len;
++ tp->flip.flag_buf_ptr += len;
++ tp->flip.count += len;
++
++ }
++ else if (!tp->real_raw) {
++ if (I_PARMRK(tp)) {
++ parity_scan(ch, tp->flip.char_buf,
++ tp->flip.flag_buf, &len);
++ } else {
++ memset(tp->flip.flag_buf, 0, len);
++ }
++ }
++
++ /*
++ * If we're doing raw reads, jam it right into the
++ * line disc bypassing the flip buffers.
++ */
++ if (dgap_rawreadok) {
++ if (tp->real_raw) {
++ writew(tail, &(bs->rx_tail));
++ writeb(1, &(bs->idata));
++
++ /* !!! WE *MUST* LET GO OF ALL LOCKS BEFORE CALLING RECEIVE BUF !!! */
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++ DPR_READ(("dgap_input. %d real_raw len:%d calling receive_buf for buffer for board %d\n",
++ __LINE__, len, ch->ch_bd->boardnum));
++ tp->ldisc.receive_buf(tp, ch->ch_bd->flipbuf, NULL, len);
++ }
++ else {
++ writew(tail, &(bs->rx_tail));
++ writeb(1, &(bs->idata));
++
++ /* !!! WE *MUST* LET GO OF ALL LOCKS BEFORE CALLING RECEIVE BUF !!! */
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++ DPR_READ(("dgap_input. %d not real_raw len:%d calling receive_buf for buffer for board %d\n",
++ __LINE__, len, ch->ch_bd->boardnum));
++ tp->ldisc.receive_buf(tp, tp->flip.char_buf, tp->flip.flag_buf, len);
++ }
++ }
++ else {
++ writew(tail, &(bs->rx_tail));
++ writeb(1, &(bs->idata));
++
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++ DPR_READ(("dgap_input. %d not dgap_read raw okay scheduling flip\n", __LINE__));
++ tty_schedule_flip(tp);
++ }
++
++ DPR_READ(("dgap_input - finish\n"));
++}
++
++
++
++/*=======================================================================
++ *
++ * dgap_event - FEP to host event processing routine.
++ *
++ * bd - Board of current event.
++ *
++ *=======================================================================*/
++int dgap_event(struct board_t *bd)
++{
++ struct channel_t *ch;
++ ulong lock_flags;
++ ulong lock_flags2;
++ struct bs_t *bs;
++ uchar *event;
++ uchar *vaddr = NULL;
++ struct ev_t *eaddr = NULL;
++ uint head;
++ uint tail;
++ int port;
++ int reason;
++ int modem;
++ int b1;
++
++ if (!bd || bd->magic != DGAP_BOARD_MAGIC)
++ return (-ENXIO);
++
++ DGAP_LOCK(bd->bd_lock, lock_flags);
++
++ vaddr = bd->re_map_membase;
++
++ if (!vaddr) {
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++ return (-ENXIO);
++ }
++
++ eaddr = (struct ev_t *) (vaddr + EVBUF);
++
++ /* Get our head and tail */
++ head = readw(&(eaddr->ev_head));
++ tail = readw(&(eaddr->ev_tail));
++
++ /*
++ * Forget it if pointers out of range.
++ */
++
++ if (head >= EVMAX - EVSTART || tail >= EVMAX - EVSTART ||
++ (head | tail) & 03) {
++ DPR_EVENT(("should be calling xxfail %d\n", __LINE__));
++ /* Let go of board lock */
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++ return (-ENXIO);
++ }
++
++ /*
++ * Loop to process all the events in the buffer.
++ */
++ while (tail != head) {
++
++ /*
++ * Get interrupt information.
++ */
++
++ event = bd->re_map_membase + tail + EVSTART;
++
++ port = event[0];
++ reason = event[1];
++ modem = event[2];
++ b1 = event[3];
++
++ DPR_EVENT(("event: jiffies: %ld port: %d reason: %x modem: %x\n",
++ jiffies, port, reason, modem));
++
++ /*
++ * Make sure the interrupt is valid.
++ */
++ if ( port >= bd->nasync) {
++ goto next;
++ }
++
++ if (!(reason & (IFMODEM | IFBREAK | IFTLW | IFTEM | IFDATA))) {
++ goto next;
++ }
++
++ ch = bd->channels[port];
++
++ if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) {
++ goto next;
++ }
++
++ /*
++ * If we have made it here, the event was valid.
++ * Lock down the channel.
++ */
++ DGAP_LOCK(ch->ch_lock, lock_flags2);
++
++ bs = ch->ch_bs;
++
++ if (!bs) {
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ goto next;
++ }
++
++ /*
++ * Process received data.
++ */
++ if (reason & IFDATA) {
++
++ /*
++ * ALL LOCKS *MUST* BE DROPPED BEFORE CALLING INPUT!
++ * input could send some data to ld, which in turn
++ * could do a callback to one of our other functions.
++ */
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++ dgap_input(ch);
++
++ DGAP_LOCK(bd->bd_lock, lock_flags);
++ DGAP_LOCK(ch->ch_lock, lock_flags2);
++
++ if (ch->ch_flags & CH_RACTIVE)
++ ch->ch_flags |= CH_RENABLE;
++ else
++ writeb(1, &(bs->idata));
++
++ if (ch->ch_flags & CH_RWAIT) {
++ ch->ch_flags &= ~CH_RWAIT;
++
++ wake_up_interruptible(&ch->ch_tun.un_flags_wait);
++ }
++ }
++
++ /*
++ * Process Modem change signals.
++ */
++ if (reason & IFMODEM) {
++ ch->ch_mistat = modem;
++ dgap_carrier(ch);
++ }
++
++ /*
++ * Process break.
++ */
++ if (reason & IFBREAK) {
++
++ DPR_EVENT(("got IFBREAK\n"));
++
++ if (ch->ch_tun.un_tty) {
++ /* A break has been indicated */
++ ch->ch_tun.un_tty->flip.count++;
++ *ch->ch_tun.un_tty->flip.flag_buf_ptr++ = TTY_BREAK;
++ *ch->ch_tun.un_tty->flip.char_buf_ptr++ = 0;
++ tty_schedule_flip(ch->ch_tun.un_tty);
++ }
++ }
++
++ /*
++ * Process Transmit low.
++ */
++ if (reason & IFTLW) {
++
++ DPR_EVENT(("event: got low event\n"));
++
++ if (ch->ch_tun.un_flags & UN_LOW) {
++ ch->ch_tun.un_flags &= ~UN_LOW;
++
++ if (ch->ch_tun.un_flags & UN_ISOPEN) {
++ if ((ch->ch_tun.un_tty->flags &
++ (1 << TTY_DO_WRITE_WAKEUP)) &&
++ ch->ch_tun.un_tty->ldisc.write_wakeup)
++ {
++ (ch->ch_tun.un_tty->ldisc.write_wakeup)(ch->ch_tun.un_tty);
++ }
++ wake_up_interruptible(&ch->ch_tun.un_tty->write_wait);
++ wake_up_interruptible(&ch->ch_tun.un_flags_wait);
++
++ DPR_EVENT(("event: Got low event. jiffies: %lu\n", jiffies));
++ }
++ }
++
++ if (ch->ch_pun.un_flags & UN_LOW) {
++ ch->ch_pun.un_flags &= ~UN_LOW;
++ if (ch->ch_pun.un_flags & UN_ISOPEN) {
++ if ((ch->ch_pun.un_tty->flags &
++ (1 << TTY_DO_WRITE_WAKEUP)) &&
++ ch->ch_pun.un_tty->ldisc.write_wakeup)
++ {
++ (ch->ch_pun.un_tty->ldisc.write_wakeup)(ch->ch_pun.un_tty);
++ }
++ wake_up_interruptible(&ch->ch_pun.un_tty->write_wait);
++ wake_up_interruptible(&ch->ch_pun.un_flags_wait);
++ }
++ }
++
++ if (ch->ch_flags & CH_WLOW) {
++ ch->ch_flags &= ~CH_WLOW;
++ wake_up_interruptible(&ch->ch_flags_wait);
++ }
++ }
++
++ /*
++ * Process Transmit empty.
++ */
++ if (reason & IFTEM) {
++ DPR_EVENT(("event: got empty event\n"));
++
++ if (ch->ch_tun.un_flags & UN_EMPTY) {
++ ch->ch_tun.un_flags &= ~UN_EMPTY;
++ if (ch->ch_tun.un_flags & UN_ISOPEN) {
++ if ((ch->ch_tun.un_tty->flags &
++ (1 << TTY_DO_WRITE_WAKEUP)) &&
++ ch->ch_tun.un_tty->ldisc.write_wakeup)
++ {
++ (ch->ch_tun.un_tty->ldisc.write_wakeup)(ch->ch_tun.un_tty);
++ }
++ wake_up_interruptible(&ch->ch_tun.un_tty->write_wait);
++ wake_up_interruptible(&ch->ch_tun.un_flags_wait);
++ }
++ }
++
++ if (ch->ch_pun.un_flags & UN_EMPTY) {
++ ch->ch_pun.un_flags &= ~UN_EMPTY;
++ if (ch->ch_pun.un_flags & UN_ISOPEN) {
++ if ((ch->ch_pun.un_tty->flags &
++ (1 << TTY_DO_WRITE_WAKEUP)) &&
++ ch->ch_pun.un_tty->ldisc.write_wakeup)
++ {
++ (ch->ch_pun.un_tty->ldisc.write_wakeup)(ch->ch_pun.un_tty);
++ }
++ wake_up_interruptible(&ch->ch_pun.un_tty->write_wait);
++ wake_up_interruptible(&ch->ch_pun.un_flags_wait);
++ }
++ }
++
++
++ if (ch->ch_flags & CH_WEMPTY) {
++ ch->ch_flags &= ~CH_WEMPTY;
++ wake_up_interruptible(&ch->ch_flags_wait);
++ }
++ }
++
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++
++next:
++ tail = (tail + 4) & (EVMAX - EVSTART - 4);
++ }
++
++ writew(tail, &(eaddr->ev_tail));
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++ return (0);
++}
++
++
++/************************************************************************
++ * Determines when CARRIER changes state and takes appropriate
++ * action.
++ ************************************************************************/
++void dgap_carrier(struct channel_t *ch)
++{
++ struct board_t *bd;
++
++ int virt_carrier = 0;
++ int phys_carrier = 0;
++
++ DPR_CARR(("dgap_carrier called...\n"));
++
++ if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++ return;
++
++ bd = ch->ch_bd;
++
++ if (!bd || bd->magic != DGAP_BOARD_MAGIC)
++ return;
++
++ /* Make sure altpin is always set correctly */
++ if (ch->ch_digi.digi_flags & DIGI_ALTPIN) {
++ ch->ch_dsr = DM_CD;
++ ch->ch_cd = DM_DSR;
++ }
++ else {
++ ch->ch_dsr = DM_DSR;
++ ch->ch_cd = DM_CD;
++ }
++
++ if (ch->ch_mistat & D_CD(ch)) {
++ DPR_CARR(("mistat: %x D_CD: %x\n", ch->ch_mistat, D_CD(ch)));
++ phys_carrier = 1;
++ }
++
++ if (ch->ch_digi.digi_flags & DIGI_FORCEDCD) {
++ virt_carrier = 1;
++ }
++
++ if (ch->ch_c_cflag & CLOCAL) {
++ virt_carrier = 1;
++ }
++
++
++ DPR_CARR(("DCD: physical: %d virt: %d\n", phys_carrier, virt_carrier));
++
++ /*
++ * Test for a VIRTUAL carrier transition to HIGH.
++ */
++ if (((ch->ch_flags & CH_FCAR) == 0) && (virt_carrier == 1)) {
++
++ /*
++ * When carrier rises, wake any threads waiting
++ * for carrier in the open routine.
++ */
++
++ DPR_CARR(("carrier: virt DCD rose\n"));
++
++ if (waitqueue_active(&(ch->ch_flags_wait)))
++ wake_up_interruptible(&ch->ch_flags_wait);
++ }
++
++ /*
++ * Test for a PHYSICAL carrier transition to HIGH.
++ */
++ if (((ch->ch_flags & CH_CD) == 0) && (phys_carrier == 1)) {
++
++ /*
++ * When carrier rises, wake any threads waiting
++ * for carrier in the open routine.
++ */
++
++ DPR_CARR(("carrier: physical DCD rose\n"));
++
++ if (waitqueue_active(&(ch->ch_flags_wait)))
++ wake_up_interruptible(&ch->ch_flags_wait);
++ }
++
++ /*
++ * Test for a PHYSICAL transition to low, so long as we aren't
++ * currently ignoring physical transitions (which is what "virtual
++ * carrier" indicates).
++ *
++ * The transition of the virtual carrier to low really doesn't
++ * matter... it really only means "ignore carrier state", not
++ * "make pretend that carrier is there".
++ */
++ if ((virt_carrier == 0) && ((ch->ch_flags & CH_CD) != 0) &&
++ (phys_carrier == 0))
++ {
++
++ /*
++ * When carrier drops:
++ *
++ * Drop carrier on all open units.
++ *
++ * Flush queues, waking up any task waiting in the
++ * line discipline.
++ *
++ * Send a hangup to the control terminal.
++ *
++ * Enable all select calls.
++ */
++ if (waitqueue_active(&(ch->ch_flags_wait)))
++ wake_up_interruptible(&ch->ch_flags_wait);
++
++ if (ch->ch_tun.un_open_count > 0) {
++ DPR_CARR(("Sending tty hangup\n"));
++ tty_hangup(ch->ch_tun.un_tty);
++ }
++
++ if (ch->ch_pun.un_open_count > 0) {
++ DPR_CARR(("Sending pr hangup\n"));
++ tty_hangup(ch->ch_pun.un_tty);
++ }
++ }
++
++ /*
++ * Make sure that our cached values reflect the current reality.
++ */
++ if (virt_carrier == 1)
++ ch->ch_flags |= CH_FCAR;
++ else
++ ch->ch_flags &= ~CH_FCAR;
++
++ if (phys_carrier == 1)
++ ch->ch_flags |= CH_CD;
++ else
++ ch->ch_flags &= ~CH_CD;
++}
++
++
++/************************************************************************
++ *
++ * TTY Entry points and helper functions
++ *
++ ************************************************************************/
++
++/*
++ * dgap_tty_open()
++ *
++ */
++static int dgap_tty_open(struct tty_struct *tty, struct file *file)
++{
++ struct board_t *brd;
++ struct channel_t *ch;
++ struct un_t *un;
++ struct bs_t *bs;
++ uint major = 0;
++ uint minor = 0;
++ int rc = 0;
++ ulong lock_flags;
++ ulong lock_flags2;
++ u32 head;
++
++ DGAP_MOD_INC_USE_COUNT(rc);
++ if (!rc) {
++ return -ENXIO;
++ }
++
++ rc = 0;
++
++ major = DGAP_TTY_MAJOR(tty->device);
++ minor = DGAP_TTY_MINOR(tty->device);
++
++ if (major > 255) {
++ DGAP_MOD_DEC_USE_COUNT;
++ return -ENXIO;
++ }
++
++ /* Get board pointer from our array of majors we have allocated */
++ brd = dgap_BoardsByMajor[major];
++ if (!brd) {
++ DGAP_MOD_DEC_USE_COUNT;
++ return -ENXIO;
++ }
++
++ DGAP_LOCK(brd->bd_lock, lock_flags);
++
++ /* If board is not ready yet, bail. */
++ /* TODO: Maybe sleep here, instead of bailing right away? */
++ if (brd->state != BOARD_READY) {
++ DGAP_UNLOCK(brd->bd_lock, lock_flags);
++ DGAP_MOD_DEC_USE_COUNT;
++ return -ENXIO;
++ }
++
++ /* If opened device is greater than our number of ports, bail. */
++ if (DGAP_TTY_MINOR(tty->device) > brd->nasync) {
++ DGAP_UNLOCK(brd->bd_lock, lock_flags);
++ DGAP_MOD_DEC_USE_COUNT;
++ return -ENXIO;
++ }
++
++ ch = brd->channels[minor];
++ if (!ch) {
++ DGAP_UNLOCK(brd->bd_lock, lock_flags);
++ DGAP_MOD_DEC_USE_COUNT;
++ return -ENXIO;
++ }
++
++ /* Grab channel lock */
++ DGAP_LOCK(ch->ch_lock, lock_flags2);
++
++ /* Figure out our type */
++ if (major == brd->dgap_Serial_Major) {
++ un = &brd->channels[minor]->ch_tun;
++ un->un_type = DGAP_SERIAL;
++ }
++ else if (major == brd->dgap_TransparentPrint_Major) {
++ un = &brd->channels[minor]->ch_pun;
++ un->un_type = DGAP_PRINT;
++ }
++ else {
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(brd->bd_lock, lock_flags);
++ DPR_OPEN(("%d Unknown TYPE!\n", __LINE__));
++ return -ENXIO;
++ }
++
++ /* Store our unit into driver_data, so we always have it available. */
++ tty->driver_data = un;
++
++ DPR_OPEN(("Open called. MAJOR: %d MINOR:%d unit: %p NAME: %s\n",
++ DGAP_TTY_MAJOR(tty->device), DGAP_TTY_MINOR(tty->device), un, brd->name));
++
++ /*
++ * Error if channel info pointer is 0.
++ */
++ if ((bs = ch->ch_bs) == 0) {
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(brd->bd_lock, lock_flags);
++ DPR_OPEN(("%d BS is 0!\n", __LINE__));
++ return -ENXIO;
++ }
++
++ DPR_OPEN(("%d: tflag=%x pflag=%x\n", __LINE__, ch->ch_tun.un_flags, ch->ch_pun.un_flags));
++
++ /*
++ * Initialize tty's
++ */
++ if (!(un->un_flags & UN_ISOPEN)) {
++ /* Store important variables. */
++ un->un_ch = brd->channels[minor];
++ un->un_dev = minor;
++ un->un_tty = tty;
++
++ /* Maybe do something here to the TTY struct as well? */
++ }
++
++ /*
++ * Initialize if neither terminal or printer is open.
++ */
++ if (!((ch->ch_tun.un_flags | ch->ch_pun.un_flags) & UN_ISOPEN)) {
++
++ DPR_OPEN(("dgap_open: initializing channel in open...\n"));
++
++ ch->ch_mforce = 0;
++ ch->ch_mval = 0;
++
++ /*
++ * Flush input queue.
++ */
++ head = readw(&(bs->rx_head));
++ writew(head, &(bs->rx_tail));
++
++ ch->ch_flags = 0;
++ ch->pscan_state = 0;
++ ch->pscan_savechar = 0;
++
++ ch->ch_c_cflag = tty->termios->c_cflag;
++ ch->ch_c_iflag = tty->termios->c_iflag;
++ ch->ch_c_oflag = tty->termios->c_oflag;
++ ch->ch_c_lflag = tty->termios->c_lflag;
++ ch->ch_startc = tty->termios->c_cc[VSTART];
++ ch->ch_stopc = tty->termios->c_cc[VSTOP];
++
++ /* TODO: flush our TTY struct here? */
++ }
++
++ dgap_carrier(ch);
++ /*
++ * Run param in case we changed anything
++ */
++ dgap_param(tty);
++
++ /*
++ * follow protocol for opening port
++ */
++
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(brd->bd_lock, lock_flags);
++
++ rc = block_til_ready(tty, file, ch);
++
++ if (rc) {
++ DPR_OPEN(("dgap_tty_open returning after block_til_ready "
++ "with %d\n", rc));
++ }
++
++ /* No going back now, increment our unit and channel counters */
++ DGAP_LOCK(ch->ch_lock, lock_flags);
++ ch->ch_open_count++;
++ un->un_open_count++;
++ un->un_flags |= (UN_ISOPEN);
++ DGAP_UNLOCK(ch->ch_lock, lock_flags);
++
++ DPR_OPEN(("dgap_tty_open finished\n"));
++ return (rc);
++}
++
++
++/*
++ * block_til_ready()
++ *
++ * Wait for DCD, if needed.
++ */
++static int block_til_ready(struct tty_struct *tty, struct file *file, struct channel_t *ch)
++{
++ int retval = 0;
++ struct un_t *un = NULL;
++ ulong lock_flags;
++ uint old_ch_flags = 0;
++
++ if (!tty || tty->magic != TTY_MAGIC || !file || !ch || ch->magic != DGAP_CHANNEL_MAGIC) {
++ return (-ENXIO);
++ }
++
++ un = tty->driver_data;
++ if (!un || un->magic != DGAP_UNIT_MAGIC) {
++ return (-ENXIO);
++ }
++
++ DPR_OPEN(("block_til_ready - before block.\n"));
++
++ DGAP_LOCK(ch->ch_lock, lock_flags);
++
++ ch->ch_wopen++;
++
++ /* Loop forever */
++ while (1) {
++
++ /*
++ * If board has failed somehow during our sleep, bail with error.
++ */
++ if (ch->ch_bd->state == BOARD_FAILED) {
++ retval = -ENXIO;
++ break;
++ }
++
++ /* If tty was hung up, break out of loop and set error. */
++ if (tty_hung_up_p(file)) {
++ retval = -EAGAIN;
++ break;
++ }
++
++ /*
++ * If either unit is in the middle of the fragile part of close,
++ * we just cannot touch the channel safely.
++ * Go back to sleep, knowing that when the channel can be
++ * touched safely, the close routine will signal the
++ * ch_wait_flags to wake us back up.
++ */
++ if (!((ch->ch_tun.un_flags | ch->ch_pun.un_flags) & UN_CLOSING)) {
++
++ /*
++ * Our conditions to leave cleanly and happily:
++ * 1) NONBLOCKING on the tty is set.
++ * 2) CLOCAL is set.
++ * 3) DCD (fake or real) is active.
++ */
++
++ if (file->f_flags & O_NONBLOCK) {
++ break;
++ }
++
++ if (tty->flags & (1 << TTY_IO_ERROR)) {
++ break;
++ }
++
++ if (ch->ch_flags & CH_CD) {
++ DPR_OPEN(("%d: ch_flags: %x\n", __LINE__, ch->ch_flags));
++ break;
++ }
++
++ if (ch->ch_flags & CH_FCAR) {
++ DPR_OPEN(("%d: ch_flags: %x\n", __LINE__, ch->ch_flags));
++ break;
++ }
++ }
++
++ /*
++ * If there is a signal pending, the user probably
++ * interrupted (ctrl-c) us.
++ * Leave loop with error set.
++ */
++ if (signal_pending(current)) {
++ DPR_OPEN(("%d: signal pending...\n", __LINE__));
++ retval = -ERESTARTSYS;
++ break;
++ }
++
++ DPR_OPEN(("block_til_ready - blocking.\n"));
++
++ /*
++ * Store the channel flags before we let go of channel lock
++ */
++ old_ch_flags = ch->ch_flags;
++
++ /*
++ * Let go of channel lock before calling schedule.
++ * Our poller will get any FEP events and wake us up when DCD
++ * eventually goes active.
++ */
++
++ DGAP_UNLOCK(ch->ch_lock, lock_flags);
++
++ DPR_OPEN(("Going to sleep...\n"));
++
++ /*
++ * Wait for something in the ch_flags to change from the current value.
++ */
++ retval = wait_event_interruptible(ch->ch_flags_wait, (old_ch_flags != ch->ch_flags));
++
++ DPR_OPEN(("After sleep... retval: %x\n", retval));
++
++ /*
++ * We got woken up for some reason.
++ * Before looping around, grab our channel lock.
++ */
++ DGAP_LOCK(ch->ch_lock, lock_flags);
++ }
++
++ ch->ch_wopen--;
++
++ DGAP_UNLOCK(ch->ch_lock, lock_flags);
++
++ DPR_OPEN(("block_til_ready - after blocking.\n"));
++
++ if (retval) {
++ DPR_OPEN(("block_til_ready - done. error. retval: %x\n", retval));
++ return(retval);
++ }
++
++ DPR_OPEN(("block_til_ready - done no error. jiffies: %lu\n", jiffies));
++
++ return(0);
++}
++
++
++/*
++ * dgap_tty_hangup()
++ *
++ * Hangup the port. Like a close, but don't wait for output to drain.
++ */
++static void dgap_tty_hangup(struct tty_struct *tty)
++{
++ struct board_t *bd;
++ struct channel_t *ch;
++ struct un_t *un;
++
++ if (!tty || tty->magic != TTY_MAGIC)
++ return;
++
++ un = tty->driver_data;
++ if (!un || un->magic != DGAP_UNIT_MAGIC)
++ return;
++
++ ch = un->un_ch;
++ if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++ return;
++
++ bd = ch->ch_bd;
++ if (!bd || bd->magic != DGAP_BOARD_MAGIC)
++ return;
++
++ DPR_CLOSE(("dgap_hangup called. ch->ch_open_count: %d un->un_open_count: %d\n",
++ ch->ch_open_count, un->un_open_count));
++
++ /* flush the transmit queues */
++ dgap_tty_flush_buffer(tty);
++
++ DPR_CLOSE(("dgap_hangup finished. ch->ch_open_count: %d un->un_open_count: %d\n",
++ ch->ch_open_count, un->un_open_count));
++}
++
++
++
++/*
++ * dgap_tty_close()
++ *
++ */
++static void dgap_tty_close(struct tty_struct *tty, struct file *file)
++{
++ struct board_t *bd;
++ struct channel_t *ch;
++ struct un_t *un;
++ struct termios *ts;
++ ulong lock_flags;
++ int rc = 0;
++
++ if (!tty || tty->magic != TTY_MAGIC)
++ return;
++
++ un = tty->driver_data;
++ if (!un || un->magic != DGAP_UNIT_MAGIC)
++ return;
++
++ ch = un->un_ch;
++ if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++ return;
++
++ bd = ch->ch_bd;
++ if (!bd || bd->magic != DGAP_BOARD_MAGIC)
++ return;
++
++ ts = tty->termios;
++
++ DPR_CLOSE(("Close called\n"));
++
++ DGAP_LOCK(ch->ch_lock, lock_flags);
++
++ /*
++ * Determine if this is the last close or not - and if we agree about
++ * which type of close it is with the Line Discipline
++ */
++ if ((tty->count == 1) && (un->un_open_count != 1)) {
++ /*
++ * Uh, oh. tty->count is 1, which means that the tty
++ * structure will be freed. un_open_count should always
++ * be one in these conditions. If it's greater than
++ * one, we've got real problems, since it means the
++ * serial port won't be shutdown.
++ */
++ APR(("tty->count is 1, un open count is %d\n", un->un_open_count));
++ un->un_open_count = 1;
++ }
++
++ if (--un->un_open_count < 0) {
++ APR(("bad serial port open count of %d\n", un->un_open_count));
++ un->un_open_count = 0;
++ }
++
++ ch->ch_open_count--;
++
++ if (ch->ch_open_count && un->un_open_count) {
++ DPR_CLOSE(("dgap_tty_close: not last close ch: %d un:%d\n",
++ ch->ch_open_count, un->un_open_count));
++
++ DGAP_MOD_DEC_USE_COUNT;
++ DGAP_UNLOCK(ch->ch_lock, lock_flags);
++ return;
++ }
++
++ /* OK, its the last close on the unit */
++ DPR_CLOSE(("dgap_tty_close - last close on unit procedures\n"));
++
++ un->un_flags |= UN_CLOSING;
++
++ tty->closing = 1;
++
++ /*
++ * Only officially close channel if count is 0 and
++ * DIGI_PRINTER bit is not set.
++ */
++ if ((ch->ch_open_count == 0) && !(ch->ch_digi.digi_flags & DIGI_PRINTER)) {
++
++ ch->ch_flags &= ~(CH_RXBLOCK);
++
++ DGAP_UNLOCK(ch->ch_lock, lock_flags);
++
++ /* wait for output to drain */
++ /* This will also return if we take an interrupt */
++
++ DPR_CLOSE(("Calling wait_for_drain\n"));
++ rc = dgap_wait_for_drain(tty);
++ DPR_CLOSE(("After calling wait_for_drain\n"));
++
++ if (rc) {
++ DPR_BASIC(("dgap_tty_close - bad return: %d ", rc));
++ }
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++ if (tty->driver->flush_buffer) {
++ DPR_CLOSE(("Calling driver flush buffer\n"));
++ tty->driver->flush_buffer(tty);
++ }
++#else
++ if (tty->driver.flush_buffer) {
++ DPR_CLOSE(("Calling driver flush buffer\n"));
++ tty->driver.flush_buffer(tty);
++ }
++#endif
++ if (tty->ldisc.flush_buffer) {
++ DPR_CLOSE(("Calling ldisc flush buffer\n"));
++ tty->ldisc.flush_buffer(tty);
++ }
++
++ DGAP_LOCK(ch->ch_lock, lock_flags);
++
++ tty->closing = 0;
++
++ /*
++ * If we have HUPCL set, lower DTR and RTS
++ */
++ if (ch->ch_c_cflag & HUPCL ) {
++ DPR_CLOSE(("Close. HUPCL set, dropping DTR/RTS\n"));
++ ch->ch_mostat &= ~(D_RTS(ch)|D_DTR(ch));
++ dgap_cmdb( ch, SMODEM, 0, D_DTR(ch)|D_RTS(ch), 0 );
++
++ /*
++ * Go to sleep to ensure RTS/DTR
++ * have been dropped for modems to see it.
++ */
++ if (ch->ch_close_delay) {
++ DPR_CLOSE(("Close. Sleeping for RTS/DTR drop\n"));
++
++ DGAP_UNLOCK(ch->ch_lock, lock_flags);
++ dgap_ms_sleep(ch->ch_close_delay);
++ DGAP_LOCK(ch->ch_lock, lock_flags);
++
++ DPR_CLOSE(("Close. After sleeping for RTS/DTR drop\n"));
++ }
++ }
++
++ ch->pscan_state = 0;
++ ch->pscan_savechar = 0;
++ }
++
++ /*
++ * turn off print device when closing print device.
++ */
++ if ((un->un_type == DGAP_PRINT) && (ch->ch_flags & CH_PRON) ) {
++ dgap_wmove(ch, ch->ch_digi.digi_offstr,
++ (int) ch->ch_digi.digi_offlen);
++ ch->ch_flags &= ~CH_PRON;
++ }
++
++ un->un_tty = 0;
++ un->un_flags &= ~(UN_ISOPEN | UN_CLOSING);
++
++ DPR_CLOSE(("Close. Doing wakeups\n"));
++ wake_up_interruptible(&ch->ch_flags_wait);
++ wake_up_interruptible(&un->un_flags_wait);
++
++ DGAP_MOD_DEC_USE_COUNT;
++
++ DGAP_UNLOCK(ch->ch_lock, lock_flags);
++
++ DPR_BASIC(("dgap_tty_close - complete\n"));
++}
++
++
++/*
++ * dgap_tty_chars_in_buffer()
++ *
++ * Return number of characters that have not been transmitted yet.
++ *
++ * This routine is used by the line discipline to determine if there
++ * is data waiting to be transmitted/drained/flushed or not.
++ */
++static int dgap_tty_chars_in_buffer(struct tty_struct *tty)
++{
++ struct board_t *bd = NULL;
++ struct channel_t *ch = NULL;
++ struct un_t *un = NULL;
++ struct bs_t *bs = NULL;
++ uchar tbusy;
++ u16 thead, ttail, tmask, chead, ctail;
++ u32 chars = 0;
++ ulong lock_flags = 0;
++ ulong lock_flags2 = 0;
++
++ if (tty == NULL)
++ return(0);
++
++ un = tty->driver_data;
++ if (!un || un->magic != DGAP_UNIT_MAGIC)
++ return (0);
++
++ ch = un->un_ch;
++ if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++ return (0);
++
++ bd = ch->ch_bd;
++ if (!bd || bd->magic != DGAP_BOARD_MAGIC)
++ return (0);
++
++ bs = ch->ch_bs;
++ if (!bs)
++ return (0);
++
++ DGAP_LOCK(bd->bd_lock, lock_flags);
++ DGAP_LOCK(ch->ch_lock, lock_flags2);
++
++ tmask = (ch->ch_tsize - 1);
++
++ /* Get Transmit queue pointers */
++ thead = readw(&(bs->tx_head)) & tmask;
++ ttail = readw(&(bs->tx_tail)) & tmask;
++
++ /* Get tbusy flag */
++ tbusy = readb(&(bs->tbusy));
++
++ /* Get Command queue pointers */
++ chead = readw(&(ch->ch_cm->cm_head));
++ ctail = readw(&(ch->ch_cm->cm_tail));
++
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++ /*
++ * The only way we know for sure if there is no pending
++ * data left to be transferred, is if:
++ * 1) Transmit head and tail are equal (empty).
++ * 2) Command queue head and tail are equal (empty).
++ * 3) The "TBUSY" flag is 0. (Transmitter not busy).
++ */
++ if ((ttail == thead) && (tbusy == 0) && (chead == ctail)) {
++ chars = 0;
++ }
++ else {
++ if (thead >= ttail)
++ chars = thead - ttail;
++ else
++ chars = thead - ttail + ch->ch_tsize;
++ /*
++ * Fudge factor here.
++ * If chars is zero, we know that the command queue had
++ * something in it or tbusy was set. Because we cannot
++ * be sure if there is still some data to be transmitted,
++ * lets lie, and tell ld we have 1 byte left.
++ */
++ if (chars == 0)
++ chars = 1;
++ }
++
++ DPR_WRITE(("dgap_tty_chars_in_buffer. Port: %x - %d (head: %d tail: %d tsize: %d)\n",
++ ch->ch_portnum, chars, thead, ttail, ch->ch_tsize));
++
++ return(chars);
++}
++
++
++static int dgap_wait_for_drain(struct tty_struct *tty)
++{
++ struct channel_t *ch;
++ struct un_t *un;
++ struct bs_t *bs;
++ int ret = -EIO;
++ u32 count = 1;
++ ulong lock_flags = 0;
++
++ if (!tty || tty->magic != TTY_MAGIC)
++ return ret;
++
++ un = tty->driver_data;
++ if (!un || un->magic != DGAP_UNIT_MAGIC)
++ return ret;
++
++ ch = un->un_ch;
++ if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++ return ret;
++
++ bs = ch->ch_bs;
++ if (!bs)
++ return ret;
++
++ ret = 0;
++
++ DPR_DRAIN(("dgap_wait_for_drain start\n"));
++
++ /* Loop until data is drained */
++ while (count != 0) {
++
++ count = dgap_tty_chars_in_buffer(tty);
++
++ if (count == 0)
++ break;
++
++ /* Set flag waiting for drain */
++ DGAP_LOCK(ch->ch_lock, lock_flags);
++ un->un_flags |= UN_EMPTY;
++ writeb(1, &(bs->iempty));
++ DGAP_UNLOCK(ch->ch_lock, lock_flags);
++
++ /* Go to sleep till we get woken up */
++ ret = wait_event_interruptible(un->un_flags_wait, ((un->un_flags & UN_EMPTY) == 0));
++
++ /* If ret is non-zero, user ctrl-c'ed us */
++ if (ret)
++ break;
++ }
++
++ DGAP_LOCK(ch->ch_lock, lock_flags);
++ un->un_flags &= ~(UN_EMPTY);
++ DGAP_UNLOCK(ch->ch_lock, lock_flags);
++
++ DPR_DRAIN(("dgap_wait_for_drain finish\n"));
++
++ return (ret);
++}
++
++
++/*
++ * dgap_maxcps_room
++ *
++ * Reduces bytes_available to the max number of characters
++ * that can be sent currently given the maxcps value, and
++ * returns the new bytes_available. This only affects printer
++ * output.
++ */
++static int maxcps_room(struct tty_struct *tty, int bytes_available)
++{
++ struct channel_t *ch = NULL;
++ struct un_t *un = NULL;
++
++ if (tty == NULL)
++ return (bytes_available);
++
++ un = tty->driver_data;
++ if (!un || un->magic != DGAP_UNIT_MAGIC)
++ return (bytes_available);
++
++ ch = un->un_ch;
++ if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++ return (bytes_available);
++
++ /*
++ * If its not the Transparent print device, return
++ * the full data amount.
++ */
++ if (un->un_type != DGAP_PRINT)
++ return (bytes_available);
++
++ if (ch->ch_digi.digi_maxcps > 0 && ch->ch_digi.digi_bufsize > 0 ) {
++ int cps_limit = 0;
++ unsigned long current_time = jiffies;
++ unsigned long buffer_time = current_time +
++ (HZ * ch->ch_digi.digi_bufsize) / ch->ch_digi.digi_maxcps;
++
++ if (ch->ch_cpstime < current_time) {
++ /* buffer is empty */
++ ch->ch_cpstime = current_time; /* reset ch_cpstime */
++ cps_limit = ch->ch_digi.digi_bufsize;
++ }
++ else if (ch->ch_cpstime < buffer_time) {
++ /* still room in the buffer */
++ cps_limit = ((buffer_time - ch->ch_cpstime) * ch->ch_digi.digi_maxcps) / HZ;
++ }
++ else {
++ /* no room in the buffer */
++ cps_limit = 0;
++ }
++
++ bytes_available = min(cps_limit, bytes_available);
++ }
++
++ return (bytes_available);
++}
++
++
++/*
++ * dgap_tty_write_room()
++ *
++ * Return space available in Tx buffer
++ */
++static int dgap_tty_write_room(struct tty_struct *tty)
++{
++ struct channel_t *ch = NULL;
++ struct un_t *un = NULL;
++ struct bs_t *bs = NULL;
++ u16 head, tail, tmask;
++ int ret = 0;
++ ulong lock_flags = 0;
++
++ if (tty == NULL || dgap_TmpWriteBuf == NULL)
++ return(0);
++
++ un = tty->driver_data;
++ if (!un || un->magic != DGAP_UNIT_MAGIC)
++ return (0);
++
++ ch = un->un_ch;
++ if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++ return (0);
++
++ bs = ch->ch_bs;
++ if (!bs)
++ return (0);
++
++ DGAP_LOCK(ch->ch_lock, lock_flags);
++
++ tmask = ch->ch_tsize - 1;
++ head = readw(&(bs->tx_head)) & tmask;
++ tail = readw(&(bs->tx_tail)) & tmask;
++
++ if ((ret = tail - head - 1) < 0)
++ ret += ch->ch_tsize;
++
++ /* Limit printer to maxcps */
++ ret = maxcps_room(tty, ret);
++
++ /*
++ * If we are printer device, leave space for
++ * possibly both the on and off strings.
++ */
++ if (un->un_type == DGAP_PRINT) {
++ if (!(ch->ch_flags & CH_PRON))
++ ret -= ch->ch_digi.digi_onlen;
++ ret -= ch->ch_digi.digi_offlen;
++ }
++ else {
++ if (ch->ch_flags & CH_PRON)
++ ret -= ch->ch_digi.digi_offlen;
++ }
++
++ if (ret < 0)
++ ret = 0;
++
++ if ((ret <= ch->ch_tlw) && ((un->un_flags & UN_LOW) == 0)) {
++ un->un_flags |= UN_LOW;
++ writeb(1, &(bs->ilow));
++ }
++ else if ((un->un_flags & UN_EMPTY) == 0) {
++ un->un_flags |= UN_EMPTY;
++ writeb(1, &(bs->iempty));
++ }
++ else {
++ un->un_flags |= UN_EMPTY;
++ writeb(1, &(bs->iempty));
++ }
++
++ DGAP_UNLOCK(ch->ch_lock, lock_flags);
++
++ DPR_WRITE(("dgap_tty_write_room - %d tail: %d head: %d\n", ret, tail, head));
++
++ return(ret);
++}
++
++
++/*
++ * dgap_tty_put_char()
++ *
++ * Put a character into ch->ch_buf
++ *
++ * - used by the line discipline for OPOST processing
++ */
++static void dgap_tty_put_char(struct tty_struct *tty, unsigned char c)
++{
++ /*
++ * Simply call tty_write.
++ */
++ DPR_WRITE(("dgap_tty_put_char called\n"));
++ dgap_tty_write(tty, 0, &c, 1);
++ return;
++}
++
++
++/*
++ * dgap_tty_write()
++ *
++ * Take data from the user or kernel and send it out to the FEP.
++ * In here exists all the Transparent Print magic as well.
++ */
++static int dgap_tty_write(struct tty_struct *tty, int from_user, const unsigned char *buf,
++ int count)
++{
++ struct channel_t *ch = NULL;
++ struct un_t *un = NULL;
++ struct bs_t *bs = NULL;
++ char *vaddr = NULL;
++ u16 head, tail, tmask, remain;
++ int bufcount = 0, n = 0;
++ int orig_count = 0;
++
++ if (tty == NULL || dgap_TmpWriteBuf == NULL)
++ return(0);
++
++ un = tty->driver_data;
++ if (!un || un->magic != DGAP_UNIT_MAGIC)
++ return (0);
++
++ ch = un->un_ch;
++ if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++ return (0);
++
++ bs = ch->ch_bs;
++ if (!bs)
++ return (0);
++
++ DPR_WRITE(("dgap_tty_write: Port: %x tty=%x user=%d len=%d\n",
++ ch->ch_portnum, (int) tty, from_user, count));
++
++ /*
++ * Store original amount of characters passed in.
++ * This helps to figure out if we should ask the FEP
++ * to send us an event when it has more space available.
++ */
++ orig_count = count;
++
++ /*
++ * If data is coming from user space, copy it into a temporary
++ * buffer so we don't get swapped out while doing the copy to
++ * the board.
++ */
++ if (from_user) {
++ /* we're allowed to block if it's from_user */
++ if (down_interruptible(&dgap_TmpWriteSem)) {
++ return(-EINTR);
++ }
++ /* if we get a non-zero return, we couldn't lock, bail. */
++ if (!spin_trylock(&ch->ch_lock)) {
++ DPR_WRITE(("Unable to get lock\n"));
++ up(&dgap_TmpWriteSem);
++ return(-EAGAIN);
++ }
++ }
++ else {
++ /* if we get a non-zero return, we couldn't lock, bail. */
++ if (!spin_trylock(&ch->ch_lock)) {
++ DPR_WRITE(("Unable to get lock\n"));
++ return(-EAGAIN);
++ }
++ }
++
++ /* Get our space available for the channel from the board */
++ tmask = ch->ch_tsize - 1;
++ head = readw(&(bs->tx_head)) & tmask;
++ tail = readw(&(bs->tx_tail)) & tmask;
++
++ if ((bufcount = tail - head - 1) < 0)
++ bufcount += ch->ch_tsize;
++
++ DPR_WRITE(("%d: bufcount: %x count: %x tail: %x head: %x tmask: %x\n",
++ __LINE__, bufcount, count, tail, head, tmask));
++
++ /*
++ * Limit printer output to maxcps overall, with bursts allowed
++ * up to bufsize characters.
++ */
++ bufcount = maxcps_room(tty, bufcount);
++
++ /*
++ * Take minimum of what the user wants to send, and the
++ * space available in the FEP buffer.
++ */
++ count = min(count, bufcount);
++
++ /*
++ * Bail if no space left.
++ */
++ if (count <= 0)
++ goto out;
++
++ /*
++ * Output the printer ON string, if we are in terminal mode, but
++ * need to be in printer mode.
++ */
++ if ((un->un_type == DGAP_PRINT) && !(ch->ch_flags & CH_PRON)) {
++ dgap_wmove(ch, ch->ch_digi.digi_onstr,
++ (int) ch->ch_digi.digi_onlen);
++ head = readw(&(bs->tx_head)) & tmask;
++ ch->ch_flags |= CH_PRON;
++ }
++
++ /*
++ * On the other hand, output the printer OFF string, if we are
++ * currently in printer mode, but need to output to the terminal.
++ */
++ if ((un->un_type != DGAP_PRINT) && (ch->ch_flags & CH_PRON)) {
++ dgap_wmove(ch, ch->ch_digi.digi_offstr,
++ (int) ch->ch_digi.digi_offlen);
++ head = readw(&(bs->tx_head)) & tmask;
++ ch->ch_flags &= ~CH_PRON;
++ }
++
++ if (from_user) {
++ /*
++ * If there is nothing left to copy, or I can't handle any more data, leave.
++ */
++ if (count <= 0) {
++ goto out;
++ }
++
++ count = min(count, WRITEBUFLEN);
++
++ /*
++ * copy_from_user() returns the number
++ * of bytes that could *NOT* be copied.
++ */
++ spin_unlock(&ch->ch_lock);
++ count -= copy_from_user(dgap_TmpWriteBuf, buf, count);
++ spin_lock(&ch->ch_lock);
++ if (!count) {
++ spin_unlock(&ch->ch_lock);
++ up(&dgap_TmpWriteSem);
++ return(-EFAULT);
++ }
++
++ buf = dgap_TmpWriteBuf;
++ }
++
++ n = count;
++
++ /*
++ * If the write wraps over the top of the circular buffer,
++ * move the portion up to the wrap point, and reset the
++ * pointers to the bottom.
++ */
++ remain = ch->ch_tstart + ch->ch_tsize - head;
++
++ if (n >= remain) {
++ n -= remain;
++ vaddr = ch->ch_taddr + head;
++ memcpy_toio(vaddr, buf, remain);
++ head = ch->ch_tstart;
++ buf += remain;
++ }
++
++ if (n > 0) {
++
++ /*
++ * Move rest of data.
++ */
++ vaddr = ch->ch_taddr + head;
++ remain = n;
++
++ memcpy_toio(vaddr, buf, remain);
++ head += remain;
++
++ }
++
++ if (count) {
++ head &= tmask;
++ writew(head, &(bs->tx_head));
++ }
++
++out:
++
++ /*
++ * If we are doing an incomplete write, we need to tell
++ * the FEP to send us an event when we have more space available.
++ *
++ * If we are over the low water mark, then we can use that.
++ * If we are under the low water mark, just wait for the empty event.
++ */
++ if (count != orig_count) {
++
++ if ((bufcount = tail - head - 1) < 0)
++ bufcount += ch->ch_tsize;
++
++ if ((bufcount <= ch->ch_tlw) && ((un->un_flags & UN_LOW) == 0)) {
++ un->un_flags |= UN_LOW;
++ writeb(1, &(bs->ilow));
++ }
++ else if ((un->un_flags & UN_EMPTY) == 0) {
++ un->un_flags |= UN_EMPTY;
++ writeb(1, &(bs->iempty));
++ }
++ else {
++ un->un_flags |= UN_EMPTY;
++ writeb(1, &(bs->iempty));
++ }
++ }
++ else {
++ /*
++ * If this is the print device, and the
++ * printer is still on, we need to turn it
++ * off before going idle. If the buffer is
++ * non-empty, wait until it goes empty.
++ * Otherwise turn it off right now.
++ */
++ if ((un->un_type == DGAP_PRINT) && (ch->ch_flags & CH_PRON)) {
++ tail = readw(&(bs->tx_tail)) & tmask;
++
++ if (tail != head) {
++ un->un_flags |= UN_EMPTY;
++ writeb(1, &(bs->iempty));
++ }
++ else {
++ dgap_wmove(ch, ch->ch_digi.digi_offstr,
++ (int) ch->ch_digi.digi_offlen);
++ head = readw(&(bs->tx_head)) & tmask;
++ ch->ch_flags &= ~CH_PRON;
++ }
++ }
++ }
++
++ /* Update printer buffer empty time. */
++ if ((un->un_type == DGAP_PRINT) && (ch->ch_digi.digi_maxcps > 0)
++ && (ch->ch_digi.digi_bufsize > 0)) {
++ ch->ch_cpstime += (HZ * count) / ch->ch_digi.digi_maxcps;
++ }
++
++ if (from_user) {
++ spin_unlock(&ch->ch_lock);
++ up(&dgap_TmpWriteSem);
++ }
++ else {
++ spin_unlock(&ch->ch_lock);
++ }
++
++ DPR_WRITE(("Write finished - Write %d bytes of %d.\n", count, orig_count));
++
++ return (count);
++}
++
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++
++/*
++ * Return modem signals to ld.
++ */
++static int dgap_tty_tiocmget(struct tty_struct *tty, struct file *file)
++{
++ struct channel_t *ch;
++ struct un_t *un;
++ int result = -EIO;
++ uchar mstat = 0;
++ ulong lock_flags = 0;
++
++ if (!tty || tty->magic != TTY_MAGIC)
++ return result;
++
++ un = tty->driver_data;
++ if (!un || un->magic != DGAP_UNIT_MAGIC)
++ return result;
++
++ ch = un->un_ch;
++ if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++ return result;
++
++ DPR_IOCTL(("dgap_tty_tiocmget start\n"));
++
++ DGAP_LOCK(ch->ch_lock, lock_flags);
++
++ mstat = readb(&(ch->ch_bs->m_stat));
++
++ DGAP_UNLOCK(ch->ch_lock, lock_flags);
++
++ result = 0;
++
++ if (mstat & D_DTR(ch))
++ result |= TIOCM_DTR;
++ if (mstat & D_RTS(ch))
++ result |= TIOCM_RTS;
++ if (mstat & D_CTS(ch))
++ result |= TIOCM_CTS;
++ if (mstat & D_DSR(ch))
++ result |= TIOCM_DSR;
++ if (mstat & D_RI(ch))
++ result |= TIOCM_RI;
++ if (mstat & D_CD(ch))
++ result |= TIOCM_CD;
++
++ DPR_IOCTL(("dgap_tty_tiocmget finish\n"));
++
++ return result;
++}
++
++
++/*
++ * dgap_tty_tiocmset()
++ *
++ * Set modem signals, called by ld.
++ */
++static int dgap_tty_tiocmset(struct tty_struct *tty, struct file *file,
++ unsigned int set, unsigned int clear)
++{
++ struct board_t *bd;
++ struct channel_t *ch;
++ struct un_t *un;
++ int ret = -EIO;
++ int mflag = 0;
++ ulong lock_flags = 0;
++ ulong lock_flags2 = 0;
++
++ if (!tty || tty->magic != TTY_MAGIC)
++ return ret;
++
++ un = tty->driver_data;
++ if (!un || un->magic != DGAP_UNIT_MAGIC)
++ return ret;
++
++ ch = un->un_ch;
++ if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++ return ret;
++
++ bd = ch->ch_bd;
++ if (!bd || bd->magic != DGAP_BOARD_MAGIC)
++ return ret;
++
++ DPR_IOCTL(("dgap_tty_tiocmset start\n"));
++
++ ch->ch_mforce = D_DTR(ch)|D_RTS(ch);
++
++ if (set & TIOCM_RTS) {
++ mflag |= D_RTS(ch);
++ }
++
++ if (set & TIOCM_DTR) {
++ mflag |= D_DTR(ch);
++ }
++
++ if (clear & TIOCM_RTS) {
++ mflag &= ~(D_RTS(ch));
++ }
++
++ if (clear & TIOCM_DTR) {
++ mflag &= ~(D_DTR(ch));
++ }
++
++ ch->ch_mval = mflag;
++
++ DGAP_LOCK(bd->bd_lock, lock_flags);
++ DGAP_LOCK(ch->ch_lock, lock_flags2);
++
++ dgap_param(tty);
++
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++ DPR_IOCTL(("dgap_tty_tiocmset finish\n"));
++
++ return (0);
++}
++
++#endif /* LINUX 2,6,0 */
++
++
++/*
++ * Return modem signals to ld.
++ */
++static int dgap_get_modem_info(struct channel_t *ch, unsigned int *value)
++{
++ int result = 0;
++ uchar mstat = 0;
++ ulong lock_flags = 0;
++
++ DPR_IOCTL(("dgap_get_modem_info start\n"));
++
++ if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++ return(-ENXIO);
++
++ DGAP_LOCK(ch->ch_lock, lock_flags);
++
++ mstat = readb(&(ch->ch_bs->m_stat));
++
++ DGAP_UNLOCK(ch->ch_lock, lock_flags);
++
++ result = 0;
++
++ if (mstat & D_DTR(ch))
++ result |= TIOCM_DTR;
++ if (mstat & D_RTS(ch))
++ result |= TIOCM_RTS;
++ if (mstat & D_CTS(ch))
++ result |= TIOCM_CTS;
++ if (mstat & D_DSR(ch))
++ result |= TIOCM_DSR;
++ if (mstat & D_RI(ch))
++ result |= TIOCM_RI;
++ if (mstat & D_CD(ch))
++ result |= TIOCM_CD;
++
++ put_user(result, value);
++
++ DPR_IOCTL(("dgap_get_modem_info finish\n"));
++ return(0);
++}
++
++
++/*
++ * dgap_set_modem_info()
++ *
++ * Set modem signals, called by ld.
++ */
++static int dgap_set_modem_info(struct tty_struct *tty, unsigned int command, unsigned int *value)
++{
++ struct board_t *bd;
++ struct channel_t *ch;
++ struct un_t *un;
++ int ret = -ENXIO;
++ unsigned int arg = 0;
++ ulong lock_flags = 0;
++ ulong lock_flags2 = 0;
++
++ if (!tty || tty->magic != TTY_MAGIC)
++ return ret;
++
++ un = tty->driver_data;
++ if (!un || un->magic != DGAP_UNIT_MAGIC)
++ return ret;
++
++ ch = un->un_ch;
++ if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++ return ret;
++
++ bd = ch->ch_bd;
++ if (!bd || bd->magic != DGAP_BOARD_MAGIC)
++ return ret;
++
++ ret = 0;
++
++ DPR_IOCTL(("dgap_set_modem_info() start\n"));
++
++ ret = verify_area(VERIFY_READ, value, sizeof(int));
++ if (ret)
++ return(ret);
++
++ GET_USER(arg, value);
++
++ switch (command) {
++ case TIOCMBIS:
++ if (arg & TIOCM_RTS) {
++ ch->ch_mforce |= D_RTS(ch);
++ ch->ch_mval |= D_RTS(ch);
++ }
++
++ if (arg & TIOCM_DTR) {
++ ch->ch_mforce |= D_DTR(ch);
++ ch->ch_mval |= D_DTR(ch);
++ }
++
++ break;
++
++ case TIOCMBIC:
++ if (arg & TIOCM_RTS) {
++ ch->ch_mforce |= D_RTS(ch);
++ ch->ch_mval &= ~(D_RTS(ch));
++ }
++
++ if (arg & TIOCM_DTR) {
++ ch->ch_mforce |= D_DTR(ch);
++ ch->ch_mval &= ~(D_DTR(ch));
++ }
++
++ break;
++
++ case TIOCMSET:
++ ch->ch_mforce = D_DTR(ch)|D_RTS(ch);
++
++ if (arg & TIOCM_RTS) {
++ ch->ch_mval |= D_RTS(ch);
++ }
++ else {
++ ch->ch_mval &= ~(D_RTS(ch));
++ }
++
++ if (arg & TIOCM_DTR) {
++ ch->ch_mval |= (D_DTR(ch));
++ }
++ else {
++ ch->ch_mval &= ~(D_DTR(ch));
++ }
++
++ break;
++
++ default:
++ return(-EINVAL);
++ }
++
++ DGAP_LOCK(bd->bd_lock, lock_flags);
++ DGAP_LOCK(ch->ch_lock, lock_flags2);
++
++ dgap_param(tty);
++
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++ DPR_IOCTL(("dgap_set_modem_info finish\n"));
++
++ return (0);
++}
++
++
++/*
++ * dgap_tty_digigeta()
++ *
++ * Ioctl to get the information for ditty.
++ *
++ *
++ *
++ */
++static int dgap_tty_digigeta(struct tty_struct *tty, struct digi_t *retinfo)
++{
++ struct channel_t *ch;
++ struct un_t *un;
++ struct digi_t tmp;
++ ulong lock_flags = 0;
++
++ if (!retinfo)
++ return (-EFAULT);
++
++ if (!tty || tty->magic != TTY_MAGIC)
++ return (-EFAULT);
++
++ un = tty->driver_data;
++ if (!un || un->magic != DGAP_UNIT_MAGIC)
++ return (-EFAULT);
++
++ ch = un->un_ch;
++ if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++ return (-EFAULT);
++
++ memset(&tmp, 0, sizeof(tmp));
++
++ DGAP_LOCK(ch->ch_lock, lock_flags);
++ memcpy(&tmp, &ch->ch_digi, sizeof(tmp));
++ DGAP_UNLOCK(ch->ch_lock, lock_flags);
++
++ if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
++ return (-EFAULT);
++
++ return (0);
++}
++
++
++/*
++ * dgap_tty_digiseta()
++ *
++ * Ioctl to set the information for ditty.
++ *
++ *
++ *
++ */
++static int dgap_tty_digiseta(struct tty_struct *tty, struct digi_t *new_info)
++{
++ struct board_t *bd;
++ struct channel_t *ch;
++ struct un_t *un;
++ struct digi_t new_digi;
++ ulong lock_flags = 0;
++ unsigned long lock_flags2;
++
++ DPR_IOCTL(("DIGI_SETA start\n"));
++
++ if (!tty || tty->magic != TTY_MAGIC)
++ return (-EFAULT);
++
++ un = tty->driver_data;
++ if (!un || un->magic != DGAP_UNIT_MAGIC)
++ return (-EFAULT);
++
++ ch = un->un_ch;
++ if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++ return (-EFAULT);
++
++ bd = ch->ch_bd;
++ if (!bd || bd->magic != DGAP_BOARD_MAGIC)
++ return (-EFAULT);
++
++ if (copy_from_user(&new_digi, new_info, sizeof(struct digi_t))) {
++ DPR_IOCTL(("DIGI_SETA failed copy_from_user\n"));
++ return(-EFAULT);
++ }
++
++ DGAP_LOCK(bd->bd_lock, lock_flags);
++ DGAP_LOCK(ch->ch_lock, lock_flags2);
++
++ memcpy(&ch->ch_digi, new_info, sizeof(struct digi_t));
++
++ if (ch->ch_digi.digi_maxcps < 1)
++ ch->ch_digi.digi_maxcps = 1;
++
++ if (ch->ch_digi.digi_maxcps > 10000)
++ ch->ch_digi.digi_maxcps = 10000;
++
++ if (ch->ch_digi.digi_bufsize < 10)
++ ch->ch_digi.digi_bufsize = 10;
++
++ if (ch->ch_digi.digi_maxchar < 1)
++ ch->ch_digi.digi_maxchar = 1;
++
++ if (ch->ch_digi.digi_maxchar > ch->ch_digi.digi_bufsize)
++ ch->ch_digi.digi_maxchar = ch->ch_digi.digi_bufsize;
++
++ if (ch->ch_digi.digi_onlen > DIGI_PLEN)
++ ch->ch_digi.digi_onlen = DIGI_PLEN;
++
++ if (ch->ch_digi.digi_offlen > DIGI_PLEN)
++ ch->ch_digi.digi_offlen = DIGI_PLEN;
++
++ dgap_param(tty);
++
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++ DPR_IOCTL(("DIGI_SETA finish\n"));
++
++ return(0);
++}
++
++
++/*
++ * dgap_set_termios()
++ */
++static void dgap_tty_set_termios(struct tty_struct *tty, struct termios *old_termios)
++{
++ struct board_t *bd;
++ struct channel_t *ch;
++ struct un_t *un;
++ unsigned long lock_flags;
++ unsigned long lock_flags2;
++
++ if (!tty || tty->magic != TTY_MAGIC)
++ return;
++
++ un = tty->driver_data;
++ if (!un || un->magic != DGAP_UNIT_MAGIC)
++ return;
++
++ ch = un->un_ch;
++ if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++ return;
++
++ bd = ch->ch_bd;
++ if (!bd || bd->magic != DGAP_BOARD_MAGIC)
++ return;
++
++ DGAP_LOCK(bd->bd_lock, lock_flags);
++ DGAP_LOCK(ch->ch_lock, lock_flags2);
++
++ ch->ch_c_cflag = tty->termios->c_cflag;
++ ch->ch_c_iflag = tty->termios->c_iflag;
++ ch->ch_c_oflag = tty->termios->c_oflag;
++ ch->ch_c_lflag = tty->termios->c_lflag;
++ ch->ch_startc = tty->termios->c_cc[VSTART];
++ ch->ch_stopc = tty->termios->c_cc[VSTOP];
++
++ dgap_carrier(ch);
++
++ dgap_param(tty);
++
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++}
++
++
++static void dgap_tty_throttle(struct tty_struct *tty)
++{
++ struct channel_t *ch;
++ struct un_t *un;
++ ulong lock_flags = 0;
++
++ if (!tty || tty->magic != TTY_MAGIC)
++ return;
++
++ un = tty->driver_data;
++ if (!un || un->magic != DGAP_UNIT_MAGIC)
++ return;
++
++ ch = un->un_ch;
++ if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++ return;
++
++ DPR_IOCTL(("dgap_tty_throttle start\n"));
++
++ DGAP_LOCK(ch->ch_lock, lock_flags);
++
++ ch->ch_flags |= (CH_RXBLOCK);
++#if 1
++ dgap_cmdw(ch, RPAUSE, 0, 0);
++#endif
++
++ DGAP_UNLOCK(ch->ch_lock, lock_flags);
++
++ DPR_IOCTL(("dgap_tty_throttle finish\n"));
++}
++
++
++static void dgap_tty_unthrottle(struct tty_struct *tty)
++{
++ struct channel_t *ch;
++ struct un_t *un;
++ ulong lock_flags = 0;
++
++
++ if (!tty || tty->magic != TTY_MAGIC)
++ return;
++
++ un = tty->driver_data;
++ if (!un || un->magic != DGAP_UNIT_MAGIC)
++ return;
++
++ ch = un->un_ch;
++ if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++ return;
++
++ DPR_IOCTL(("dgap_tty_unthrottle start\n"));
++
++ DGAP_LOCK(ch->ch_lock, lock_flags);
++
++ ch->ch_flags &= ~(CH_RXBLOCK);
++
++#if 1
++ dgap_cmdw(ch, RRESUME, 0, 0);
++#endif
++
++ DGAP_UNLOCK(ch->ch_lock, lock_flags);
++
++ DPR_IOCTL(("dgap_tty_unthrottle finish\n"));
++}
++
++
++static void dgap_tty_start(struct tty_struct *tty)
++{
++ struct board_t *bd;
++ struct channel_t *ch;
++ struct un_t *un;
++ ulong lock_flags = 0;
++ ulong lock_flags2 = 0;
++
++ if (!tty || tty->magic != TTY_MAGIC)
++ return;
++
++ un = tty->driver_data;
++ if (!un || un->magic != DGAP_UNIT_MAGIC)
++ return;
++
++ ch = un->un_ch;
++ if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++ return;
++
++ bd = ch->ch_bd;
++ if (!bd || bd->magic != DGAP_BOARD_MAGIC)
++ return;
++
++ DPR_IOCTL(("dgap_tty_start start\n"));
++
++ DGAP_LOCK(bd->bd_lock, lock_flags);
++ DGAP_LOCK(ch->ch_lock, lock_flags2);
++
++ dgap_cmdw(ch, RESUMETX, 0, 0);
++
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++ DPR_IOCTL(("dgap_tty_start finish\n"));
++}
++
++
++static void dgap_tty_stop(struct tty_struct *tty)
++{
++ struct board_t *bd;
++ struct channel_t *ch;
++ struct un_t *un;
++ ulong lock_flags = 0;
++ ulong lock_flags2 = 0;
++
++ if (!tty || tty->magic != TTY_MAGIC)
++ return;
++
++ un = tty->driver_data;
++ if (!un || un->magic != DGAP_UNIT_MAGIC)
++ return;
++
++ ch = un->un_ch;
++ if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++ return;
++
++ bd = ch->ch_bd;
++ if (!bd || bd->magic != DGAP_BOARD_MAGIC)
++ return;
++
++ DPR_IOCTL(("dgap_tty_stop start\n"));
++
++ DGAP_LOCK(bd->bd_lock, lock_flags);
++ DGAP_LOCK(ch->ch_lock, lock_flags2);
++
++ dgap_cmdw(ch, PAUSETX, 0, 0);
++
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++ DPR_IOCTL(("dgap_tty_stop finish\n"));
++}
++
++
++/*
++ * dgap_tty_flush_chars()
++ *
++ * Flush the cook buffer
++ *
++ * Note to self, and any other poor souls who venture here:
++ *
++ * flush in this case DOES NOT mean dispose of the data.
++ * instead, it means "stop buffering and send it if you
++ * haven't already." Just guess how I figured that out... SRW 2-Jun-98
++ *
++ * It is also always called in interrupt context - JAR 8-Sept-99
++ */
++static void dgap_tty_flush_chars(struct tty_struct *tty)
++{
++ struct board_t *bd;
++ struct channel_t *ch;
++ struct un_t *un;
++ ulong lock_flags = 0;
++ ulong lock_flags2 = 0;
++
++ if (!tty || tty->magic != TTY_MAGIC)
++ return;
++
++ un = tty->driver_data;
++ if (!un || un->magic != DGAP_UNIT_MAGIC)
++ return;
++
++ ch = un->un_ch;
++ if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++ return;
++
++ bd = ch->ch_bd;
++ if (!bd || bd->magic != DGAP_BOARD_MAGIC)
++ return;
++
++ DPR_IOCTL(("dgap_tty_flush_chars start\n"));
++
++ DGAP_LOCK(bd->bd_lock, lock_flags);
++ DGAP_LOCK(ch->ch_lock, lock_flags2);
++
++ /* TODO: Do something here */
++
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++ DPR_IOCTL(("dgap_tty_flush_chars finish\n"));
++}
++
++
++
++/*
++ * dgap_tty_flush_buffer()
++ *
++ * Flush Tx buffer (make in == out)
++ */
++static void dgap_tty_flush_buffer(struct tty_struct *tty)
++{
++ struct board_t *bd;
++ struct channel_t *ch;
++ struct un_t *un;
++ ulong lock_flags = 0;
++ ulong lock_flags2 = 0;
++ u16 head = 0;
++
++ if (!tty || tty->magic != TTY_MAGIC)
++ return;
++
++ un = tty->driver_data;
++ if (!un || un->magic != DGAP_UNIT_MAGIC)
++ return;
++
++ ch = un->un_ch;
++ if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++ return;
++
++ bd = ch->ch_bd;
++ if (!bd || bd->magic != DGAP_BOARD_MAGIC)
++ return;
++
++ DPR_IOCTL(("dgap_tty_flush_buffer on port: %d start\n", ch->ch_portnum));
++
++ DGAP_LOCK(bd->bd_lock, lock_flags);
++ DGAP_LOCK(ch->ch_lock, lock_flags2);
++
++ ch->ch_flags &= ~CH_STOP;
++ head = readw(&(ch->ch_bs->tx_head));
++ dgap_cmdw(ch, FLUSHTX, (u16) head, 0 );
++ dgap_cmdw(ch, RESUMETX, 0, 0);
++ if (ch->ch_tun.un_flags & (UN_LOW|UN_EMPTY)) {
++ ch->ch_tun.un_flags &= ~(UN_LOW|UN_EMPTY);
++ wake_up_interruptible(&ch->ch_tun.un_flags_wait);
++ }
++ if (ch->ch_pun.un_flags & (UN_LOW|UN_EMPTY)) {
++ ch->ch_pun.un_flags &= ~(UN_LOW|UN_EMPTY);
++ wake_up_interruptible(&ch->ch_pun.un_flags_wait);
++ }
++
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++ DPR_IOCTL(("dgap_tty_flush_buffer finish\n"));
++}
++
++
++
++/*****************************************************************************
++ *
++ * The IOCTL function and all of its helpers
++ *
++ *****************************************************************************/
++
++/*
++ * dgap_tty_ioctl()
++ *
++ * The usual assortment of ioctl's
++ */
++static int dgap_tty_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd,
++ unsigned long arg)
++{
++ struct board_t *bd;
++ struct channel_t *ch;
++ struct un_t *un;
++ int rc;
++ u16 head = 0;
++ ulong lock_flags = 0;
++ ulong lock_flags2 = 0;
++
++
++ if (!tty || tty->magic != TTY_MAGIC)
++ return (-ENODEV);
++
++ un = tty->driver_data;
++ if (!un || un->magic != DGAP_UNIT_MAGIC)
++ return (-ENODEV);
++
++ ch = un->un_ch;
++ if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++ return (-ENODEV);
++
++ bd = ch->ch_bd;
++ if (!bd || bd->magic != DGAP_BOARD_MAGIC)
++ return (-ENODEV);
++
++ DPR_IOCTL(("dgap_tty_ioctl start on port %d - cmd %s (%x), arg %lx\n",
++ ch->ch_portnum, dgap_ioctl_name(cmd), cmd, arg));
++
++ DGAP_LOCK(bd->bd_lock, lock_flags);
++ DGAP_LOCK(ch->ch_lock, lock_flags2);
++
++ if (un->un_open_count <= 0) {
++ DPR_BASIC(("dgap_tty_ioctl - unit not open.\n"));
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++ return(-EIO);
++ }
++
++ switch (cmd) {
++
++ /* Here are all the standard ioctl's that we MUST implement */
++
++ case TCSBRK:
++ /*
++ * TCSBRK is SVID version: non-zero arg --> no break
++ * this behaviour is exploited by tcdrain().
++ *
++ * According to POSIX.1 spec (7.2.2.1.2) breaks should be
++ * between 0.25 and 0.5 seconds so we'll ask for something
++ * in the middle: 0.375 seconds.
++ */
++ rc = tty_check_change(tty);
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++ if (rc) {
++ return(rc);
++ }
++
++ rc = dgap_wait_for_drain(tty);
++
++ if (rc) {
++ DPR_IOCTL(("dgap_tty_ioctl - bad return: %d ", rc));
++ return(-EINTR);
++ }
++
++ DGAP_LOCK(bd->bd_lock, lock_flags);
++ DGAP_LOCK(ch->ch_lock, lock_flags2);
++
++ if(((cmd == TCSBRK) && (!arg)) || (cmd == TCSBRKP)) {
++ dgap_cmdw(ch, SBREAK, (u16) SBREAK_TIME, 0);
++ }
++
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++ DPR_IOCTL(("dgap_tty_ioctl finish on port %d - cmd %s (%x), arg %lx\n",
++ ch->ch_portnum, dgap_ioctl_name(cmd), cmd, arg));
++
++ return(0);
++
++
++ case TCSBRKP:
++ /* support for POSIX tcsendbreak()
++
++ * According to POSIX.1 spec (7.2.2.1.2) breaks should be
++ * between 0.25 and 0.5 seconds so we'll ask for something
++ * in the middle: 0.375 seconds.
++ */
++ rc = tty_check_change(tty);
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++ if (rc) {
++ return(rc);
++ }
++
++ rc = dgap_wait_for_drain(tty);
++ if (rc) {
++ DPR_IOCTL(("dgap_tty_ioctl - bad return: %d ", rc));
++ return(-EINTR);
++ }
++
++ DGAP_LOCK(bd->bd_lock, lock_flags);
++ DGAP_LOCK(ch->ch_lock, lock_flags2);
++
++ dgap_cmdw(ch, SBREAK, (u16) SBREAK_TIME, 0);
++
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++ DPR_IOCTL(("dgap_tty_ioctl finish on port %d - cmd %s (%x), arg %lx\n",
++ ch->ch_portnum, dgap_ioctl_name(cmd), cmd, arg));
++
++ return(0);
++
++
++ case TIOCGSOFTCAR:
++ rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(long));
++ if (rc) {
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++ return(rc);
++ }
++ PUT_USER(C_CLOCAL(tty) ? 1 : 0, (unsigned long *) arg);
++
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++ return(0);
++
++ case TIOCSSOFTCAR:
++ GET_USER(arg, (unsigned long *) arg);
++ tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) | (arg ? CLOCAL : 0));
++
++ dgap_param(tty);
++
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++ return(0);
++
++ case TIOCMGET:
++ rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(unsigned int));
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++ if (rc) {
++ return(rc);
++ }
++ return(dgap_get_modem_info(ch, (unsigned int *) arg));
++
++ case TIOCMBIS:
++ case TIOCMBIC:
++ case TIOCMSET:
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++ return(dgap_set_modem_info(tty, cmd, (unsigned int *) arg));
++
++ /*
++ * Here are any additional ioctl's that we want to implement
++ */
++
++ case TCFLSH:
++ /*
++ * The linux tty driver doesn't have a flush
++ * input routine for the driver, assuming all backed
++ * up data is in the line disc. buffers. However,
++ * we all know that's not the case. Here, we
++ * act on the ioctl, but then lie and say we didn't
++ * so the line discipline will process the flush
++ * also.
++ */
++ rc = tty_check_change(tty);
++ if (rc) {
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++ return(rc);
++ }
++
++ if ((arg == TCIFLUSH) || (arg == TCIOFLUSH)) {
++ ch->ch_flags &= ~CH_STOP;
++ head = readw(&(ch->ch_bs->tx_head));
++ dgap_cmdw(ch, FLUSHTX, (u16) head, 0 );
++ dgap_cmdw(ch, RESUMETX, 0, 0);
++ if (ch->ch_tun.un_flags & (UN_LOW|UN_EMPTY)) {
++ ch->ch_tun.un_flags &= ~(UN_LOW|UN_EMPTY);
++ wake_up_interruptible(&ch->ch_tun.un_flags_wait);
++ }
++ if (ch->ch_pun.un_flags & (UN_LOW|UN_EMPTY)) {
++ ch->ch_pun.un_flags &= ~(UN_LOW|UN_EMPTY);
++ wake_up_interruptible(&ch->ch_pun.un_flags_wait);
++ }
++ }
++
++ if ((arg == TCOFLUSH) || (arg == TCIOFLUSH)) {
++ if (!(un->un_type == DGAP_PRINT)) {
++ head = readw(&(ch->ch_bs->rx_head));
++ writew(head, &(ch->ch_bs->rx_tail));
++ writeb(0, &(ch->ch_bs->orun));
++ }
++ }
++
++ /* pretend we didn't recognize this IOCTL */
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++ return(-ENOIOCTLCMD);
++
++#ifdef TIOCGETP
++ case TIOCGETP:
++#endif
++ case TCGETS:
++ case TCGETA:
++ if (tty->ldisc.ioctl) {
++ int retval = (-ENXIO);
++
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++ if (tty->termios) {
++ retval = ((tty->ldisc.ioctl) (tty, file, cmd, arg));
++ }
++
++ DPR_IOCTL(("dgap_tty_ioctl (LINE:%d) finish on port %d - cmd %s (%x), arg %lx\n",
++ __LINE__, ch->ch_portnum, dgap_ioctl_name(cmd), cmd, arg));
++ return(retval);
++ }
++
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++ DPR_IOCTL(("dgap_tty_ioctl (LINE:%d) finish on port %d - cmd %s (%x), arg %lx\n",
++ __LINE__, ch->ch_portnum, dgap_ioctl_name(cmd), cmd, arg));
++
++ return(-ENOIOCTLCMD);
++
++ case TCSETSF:
++ case TCSETSW:
++ /*
++ * The linux tty driver doesn't have a flush
++ * input routine for the driver, assuming all backed
++ * up data is in the line disc. buffers. However,
++ * we all know that's not the case. Here, we
++ * act on the ioctl, but then lie and say we didn't
++ * so the line discipline will process the flush
++ * also.
++ */
++ if (cmd == TCSETSF) {
++ /* flush rx */
++ ch->ch_flags &= ~CH_STOP;
++ head = readw(&(ch->ch_bs->rx_head));
++ writew(head, &(ch->ch_bs->rx_tail));
++ }
++
++ /* now wait for all the output to drain */
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++ rc = dgap_wait_for_drain(tty);
++ if (rc) {
++ DPR_IOCTL(("dgap_tty_ioctl - bad return: %d ", rc));
++ return(-EINTR);
++ }
++
++ DPR_IOCTL(("dgap_tty_ioctl finish on port %d - cmd %s (%x), arg %lx\n",
++ ch->ch_portnum, dgap_ioctl_name(cmd), cmd, arg));
++
++ /* pretend we didn't recognize this */
++ return(-ENOIOCTLCMD);
++
++ case TCSETAW:
++
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++ rc = dgap_wait_for_drain(tty);
++ if (rc) {
++ DPR_IOCTL(("dgap_tty_ioctl - bad return: %d ", rc));
++ return(-EINTR);
++ }
++
++ /* pretend we didn't recognize this */
++ return(-ENOIOCTLCMD);
++
++ case TCXONC:
++ /*
++ * The Linux Line Discipline (LD) would do this for us if we
++ * let it, but we have the special firmware options to do this
++ * the "right way" regardless of hardware or software flow
++ * control so we'll do it outselves instead of letting the LD
++ * do it.
++ */
++ rc = tty_check_change(tty);
++ if (rc) {
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++ return(rc);
++ }
++
++ DPR_IOCTL(("dxb_ioctl - in TCXONC - %d\n", cmd));
++ switch (arg) {
++
++ case TCOON:
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++ dgap_tty_start(tty);
++ return(0);
++ case TCOOFF:
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++ dgap_tty_stop(tty);
++ return(0);
++ case TCION:
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++ /* Make the ld do it */
++ return(-ENOIOCTLCMD);
++ case TCIOFF:
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++ /* Make the ld do it */
++ return(-ENOIOCTLCMD);
++ default:
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++ return(-EINVAL);
++ }
++
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++ return(-ENOIOCTLCMD);
++
++ case DIGI_GETA:
++ /* get information for ditty */
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++ return(dgap_tty_digigeta(tty, (struct digi_t *) arg));
++
++ case DIGI_SETAW:
++ case DIGI_SETAF:
++
++ /* set information for ditty */
++ if (cmd == (DIGI_SETAW)) {
++
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++ rc = dgap_wait_for_drain(tty);
++ if (rc) {
++ DPR_IOCTL(("dgap_tty_ioctl - bad return: %d ", rc));
++ return(-EINTR);
++ }
++ DGAP_LOCK(bd->bd_lock, lock_flags);
++ DGAP_LOCK(ch->ch_lock, lock_flags2);
++ }
++ else {
++ if (tty->ldisc.flush_buffer)
++ tty->ldisc.flush_buffer(tty);
++ }
++ /* fall thru */
++
++ case DIGI_SETA:
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++ return(dgap_tty_digiseta(tty, (struct digi_t *) arg));
++
++ default:
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++ DPR_IOCTL(("dgap_tty_ioctl - in default\n"));
++ DPR_IOCTL(("dgap_tty_ioctl end - cmd %s (%x), arg %lx\n",
++ dgap_ioctl_name(cmd), cmd, arg));
++
++ return(-ENOIOCTLCMD);
++ }
++
++ DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++ DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++ DPR_IOCTL(("dgap_tty_ioctl end - cmd %s (%x), arg %lx\n",
++ dgap_ioctl_name(cmd), cmd, arg));
++
++ return(0);
++}
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/dgap_tty.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/dgap_tty.h 2003-09-27 11:38:18.449723600 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/dgap_tty.h 2003-09-27 11:38:20.971340256 +0800
+@@ -0,0 +1,37 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ * Scott H Kilau <Scott_Kilau at digi dot com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2, or (at your option)
++ * any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
++ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
++ * PURPOSE. See the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * NOTE: THIS IS A SHARED HEADER. DO NOT CHANGE CODING STYLE!!!
++ */
++
++#ifndef __DGAP_TTY_H
++#define __DGAP_TTY_H
++
++#include "dgap_driver.h"
++
++int dgap_tty_register(struct board_t *brd);
++
++int dgap_tty_preinit(void);
++int dgap_tty_init(struct board_t *);
++
++void dgap_tty_post_uninit(void);
++void dgap_tty_uninit(struct board_t *);
++
++int dgap_event(struct board_t *);
++
++#endif
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/dgap_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/dgap_types.h 2003-09-27 11:38:18.449723600 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/dgap_types.h 2003-09-27 11:38:20.971340256 +0800
+@@ -0,0 +1,46 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ * Scott H Kilau <Scott_Kilau at digi dot com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2, or (at your option)
++ * any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
++ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
++ * PURPOSE. See the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * NOTE: THIS IS A SHARED HEADER. DO NOT CHANGE CODING STYLE!!!
++ */
++
++#ifndef __DGAP_TYPES_H
++#define __DGAP_TYPES_H
++
++#if defined(__KERNEL__)
++# include <linux/string.h>
++#endif
++
++#include <linux/types.h>
++
++#if !defined (TRUE)
++# define TRUE 1
++#endif
++
++#if !defined (FALSE)
++# define FALSE 0
++#endif
++
++#if !defined(NULL)
++# define NULL 0
++#endif
++
++/* Required for our shared headers! */
++typedef unsigned char uchar;
++
++#endif
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/digi.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/digi.h 2003-09-27 11:38:18.449723600 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/digi.h 2003-09-27 11:38:20.973339952 +0800
+@@ -0,0 +1,369 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ * Scott H Kilau <Scott_Kilau at digi dot com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2, or (at your option)
++ * any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
++ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
++ * PURPOSE. See the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++ *
++ * NOTE: THIS IS A SHARED HEADER. DO NOT CHANGE CODING STYLE!!!
++ */
++
++#ifndef __DIGI_H
++#define __DIGI_H
++
++/************************************************************************
++ *** Definitions for Digi ditty(1) command.
++ ************************************************************************/
++
++
++/*
++ * Copyright (c) 1988-96 Digi International Inc., All Rights Reserved.
++ */
++
++/************************************************************************
++ * This module provides application access to special Digi
++ * serial line enhancements which are not standard UNIX(tm) features.
++ ************************************************************************/
++
++#if !defined(TIOCMODG)
++
++#define TIOCMODG ('d'<<8) | 250 /* get modem ctrl state */
++#define TIOCMODS ('d'<<8) | 251 /* set modem ctrl state */
++
++#ifndef TIOCM_LE
++#define TIOCM_LE 0x01 /* line enable */
++#define TIOCM_DTR 0x02 /* data terminal ready */
++#define TIOCM_RTS 0x04 /* request to send */
++#define TIOCM_ST 0x08 /* secondary transmit */
++#define TIOCM_SR 0x10 /* secondary receive */
++#define TIOCM_CTS 0x20 /* clear to send */
++#define TIOCM_CAR 0x40 /* carrier detect */
++#define TIOCM_RNG 0x80 /* ring indicator */
++#define TIOCM_DSR 0x100 /* data set ready */
++#define TIOCM_RI TIOCM_RNG /* ring (alternate) */
++#define TIOCM_CD TIOCM_CAR /* carrier detect (alt) */
++#endif
++
++#endif
++
++#if !defined(TIOCMSET)
++#define TIOCMSET ('d'<<8) | 252 /* set modem ctrl state */
++#define TIOCMGET ('d'<<8) | 253 /* set modem ctrl state */
++#endif
++
++#if !defined(TIOCMBIC)
++#define TIOCMBIC ('d'<<8) | 254 /* set modem ctrl state */
++#define TIOCMBIS ('d'<<8) | 255 /* set modem ctrl state */
++#endif
++
++
++#if !defined(TIOCSDTR)
++#define TIOCSDTR ('e'<<8) | 0 /* set DTR */
++#define TIOCCDTR ('e'<<8) | 1 /* clear DTR */
++#endif
++
++/************************************************************************
++ * Ioctl command arguments for DIGI parameters.
++ ************************************************************************/
++#define DIGI_GETA ('e'<<8) | 94 /* Read params */
++
++#define DIGI_SETA ('e'<<8) | 95 /* Set params */
++#define DIGI_SETAW ('e'<<8) | 96 /* Drain & set params */
++#define DIGI_SETAF ('e'<<8) | 97 /* Drain, flush & set params */
++
++#define DIGI_KME ('e'<<8) | 98 /* Read/Write Host */
++ /* Adapter Memory */
++
++#define DIGI_GETFLOW ('e'<<8) | 99 /* Get startc/stopc flow */
++ /* control characters */
++#define DIGI_SETFLOW ('e'<<8) | 100 /* Set startc/stopc flow */
++ /* control characters */
++#define DIGI_GETAFLOW ('e'<<8) | 101 /* Get Aux. startc/stopc */
++ /* flow control chars */
++#define DIGI_SETAFLOW ('e'<<8) | 102 /* Set Aux. startc/stopc */
++ /* flow control chars */
++
++#define DIGI_GEDELAY ('d'<<8) | 246 /* Get edelay */
++#define DIGI_SEDELAY ('d'<<8) | 247 /* Set edelay */
++
++struct digiflow_t {
++ unsigned char startc; /* flow cntl start char */
++ unsigned char stopc; /* flow cntl stop char */
++};
++
++
++#ifdef FLOW_2200
++#define F2200_GETA ('e'<<8) | 104 /* Get 2x36 flow cntl flags */
++#define F2200_SETAW ('e'<<8) | 105 /* Set 2x36 flow cntl flags */
++#define F2200_MASK 0x03 /* 2200 flow cntl bit mask */
++#define FCNTL_2200 0x01 /* 2x36 terminal flow cntl */
++#define PCNTL_2200 0x02 /* 2x36 printer flow cntl */
++#define F2200_XON 0xf8
++#define P2200_XON 0xf9
++#define F2200_XOFF 0xfa
++#define P2200_XOFF 0xfb
++
++#define FXOFF_MASK 0x03 /* 2200 flow status mask */
++#define RCVD_FXOFF 0x01 /* 2x36 Terminal XOFF rcvd */
++#define RCVD_PXOFF 0x02 /* 2x36 Printer XOFF rcvd */
++#endif
++
++/************************************************************************
++ * Values for digi_flags
++ ************************************************************************/
++#define DIGI_IXON 0x0001 /* Handle IXON in the FEP */
++#define DIGI_FAST 0x0002 /* Fast baud rates */
++#define RTSPACE 0x0004 /* RTS input flow control */
++#define CTSPACE 0x0008 /* CTS output flow control */
++#define DSRPACE 0x0010 /* DSR output flow control */
++#define DCDPACE 0x0020 /* DCD output flow control */
++#define DTRPACE 0x0040 /* DTR input flow control */
++#define DIGI_COOK 0x0080 /* Cooked processing done in FEP */
++#define DIGI_FORCEDCD 0x0100 /* Force carrier */
++#define DIGI_ALTPIN 0x0200 /* Alternate RJ-45 pin config */
++#define DIGI_AIXON 0x0400 /* Aux flow control in fep */
++#define DIGI_PRINTER 0x0800 /* Hold port open for flow cntrl*/
++#define DIGI_PP_INPUT 0x1000 /* Change parallel port to input*/
++#define DIGI_422 0x4000 /* for 422/232 selectable panel */
++
++/************************************************************************
++ * These options are not supported on the comxi.
++ ************************************************************************/
++#define DIGI_COMXI (DIGI_FAST|DIGI_COOK|DSRPACE|DCDPACE|DTRPACE)
++
++#define DIGI_PLEN 28 /* String length */
++#define DIGI_TSIZ 10 /* Terminal string len */
++
++/************************************************************************
++ * Structure used with ioctl commands for DIGI parameters.
++ ************************************************************************/
++struct digi_t {
++ unsigned short digi_flags; /* Flags (see above) */
++ unsigned short digi_maxcps; /* Max printer CPS */
++ unsigned short digi_maxchar; /* Max chars in print queue */
++ unsigned short digi_bufsize; /* Buffer size */
++ unsigned char digi_onlen; /* Length of ON string */
++ unsigned char digi_offlen; /* Length of OFF string */
++ char digi_onstr[DIGI_PLEN]; /* Printer on string */
++ char digi_offstr[DIGI_PLEN]; /* Printer off string */
++ char digi_term[DIGI_TSIZ]; /* terminal string */
++};
++
++/************************************************************************
++ * KME definitions and structures.
++ ************************************************************************/
++#define RW_IDLE 0 /* Operation complete */
++#define RW_READ 1 /* Read Concentrator Memory */
++#define RW_WRITE 2 /* Write Concentrator Memory */
++
++struct rw_t {
++ unsigned char rw_req; /* Request type */
++ unsigned char rw_board; /* Host Adapter board number */
++ unsigned char rw_conc; /* Concentrator number */
++ unsigned char rw_reserved; /* Reserved for expansion */
++ unsigned long rw_addr; /* Address in concentrator */
++ unsigned short rw_size; /* Read/write request length */
++ unsigned char rw_data[128]; /* Data to read/write */
++};
++
++/***********************************************************************
++ * Shrink Buffer and Board Information definitions and structures.
++
++ ************************************************************************/
++ /* Board type return codes */
++#define PCXI_TYPE 1 /* Board type at the designated port is a PC/Xi */
++#define PCXM_TYPE 2 /* Board type at the designated port is a PC/Xm */
++#define PCXE_TYPE 3 /* Board type at the designated port is a PC/Xe */
++#define MCXI_TYPE 4 /* Board type at the designated port is a MC/Xi */
++#define COMXI_TYPE 5 /* Board type at the designated port is a COM/Xi */
++
++ /* Non-Zero Result codes. */
++#define RESULT_NOBDFND 1 /* A Digi product at that port is not config installed */
++#define RESULT_NODESCT 2 /* A memory descriptor was not obtainable */
++#define RESULT_NOOSSIG 3 /* FEP/OS signature was not detected on the board */
++#define RESULT_TOOSML 4 /* Too small an area to shrink. */
++#define RESULT_NOCHAN 5 /* Channel structure for the board was not found */
++
++struct shrink_buf_struct {
++ unsigned long shrink_buf_vaddr; /* Virtual address of board */
++ unsigned long shrink_buf_phys; /* Physical address of board */
++ unsigned long shrink_buf_bseg; /* Amount of board memory */
++ unsigned long shrink_buf_hseg; /* '186 Begining of Dual-Port */
++
++ unsigned long shrink_buf_lseg; /* '186 Begining of freed memory */
++ unsigned long shrink_buf_mseg; /* Linear address from start of
++ dual-port were freed memory
++ begins, host viewpoint. */
++
++ unsigned long shrink_buf_bdparam; /* Parameter for xxmemon and
++ xxmemoff */
++
++ unsigned long shrink_buf_reserva; /* Reserved */
++ unsigned long shrink_buf_reservb; /* Reserved */
++ unsigned long shrink_buf_reservc; /* Reserved */
++ unsigned long shrink_buf_reservd; /* Reserved */
++
++ unsigned char shrink_buf_result; /* Reason for call failing
++ Zero is Good return */
++ unsigned char shrink_buf_init; /* Non-Zero if it caused an
++ xxinit call. */
++
++ unsigned char shrink_buf_anports; /* Number of async ports */
++ unsigned char shrink_buf_snports; /* Number of sync ports */
++ unsigned char shrink_buf_type; /* Board type 1 = PC/Xi,
++ 2 = PC/Xm,
++ 3 = PC/Xe
++ 4 = MC/Xi
++ 5 = COMX/i */
++ unsigned char shrink_buf_card; /* Card number */
++
++};
++
++/************************************************************************
++ * Structure to get driver status information
++ ************************************************************************/
++struct digi_dinfo {
++ unsigned long dinfo_nboards; /* # boards configured */
++ char dinfo_reserved[12]; /* for future expansion */
++ char dinfo_version[16]; /* driver version */
++};
++
++#define DIGI_GETDD ('d'<<8) | 248 /* get driver info */
++
++/************************************************************************
++ * Structure used with ioctl commands for per-board information
++ *
++ * physsize and memsize differ when board has "windowed" memory
++ ************************************************************************/
++struct digi_info {
++ unsigned long info_bdnum; /* Board number (0 based) */
++ unsigned long info_ioport; /* io port address */
++ unsigned long info_physaddr; /* memory address */
++ unsigned long info_physsize; /* Size of host mem window */
++ unsigned long info_memsize; /* Amount of dual-port mem */
++ /* on board */
++ unsigned short info_bdtype; /* Board type */
++ unsigned short info_nports; /* number of ports */
++ char info_bdstate; /* board state */
++ char info_reserved[7]; /* for future expansion */
++};
++
++#define DIGI_GETBD ('d'<<8) | 249 /* get board info */
++
++struct digi_stat {
++ unsigned int info_chan; /* Channel number (0 based) */
++ unsigned int info_brd; /* Board number (0 based) */
++ unsigned long info_cflag; /* cflag for channel */
++ unsigned long info_iflag; /* iflag for channel */
++ unsigned long info_oflag; /* oflag for channel */
++ unsigned long info_mstat; /* mstat for channel */
++ unsigned long info_tx_data; /* tx_data for channel */
++ unsigned long info_rx_data; /* rx_data for channel */
++ unsigned long info_hflow; /* hflow for channel */
++ unsigned long info_reserved[8]; /* for future expansion */
++};
++
++#define DIGI_GETSTAT ('d'<<8) | 244 /* get board info */
++/************************************************************************
++ *
++ * Structure used with ioctl commands for per-channel information
++ *
++ ************************************************************************/
++struct digi_ch {
++ unsigned long info_bdnum; /* Board number (0 based) */
++ unsigned long info_channel; /* Channel index number */
++ unsigned long info_ch_cflag; /* Channel cflag */
++ unsigned long info_ch_iflag; /* Channel iflag */
++ unsigned long info_ch_oflag; /* Channel oflag */
++ unsigned long info_chsize; /* Channel structure size */
++ unsigned long info_sleep_stat; /* sleep status */
++ dev_t info_dev; /* device number */
++ unsigned char info_initstate; /* Channel init state */
++ unsigned char info_running; /* Channel running state */
++ long reserved[8]; /* reserved for future use */
++};
++
++/*
++* This structure is used with the DIGI_FEPCMD ioctl to
++* tell the driver which port to send the command for.
++*/
++struct digi_cmd {
++ int cmd;
++ int word;
++ int ncmds;
++ int chan; /* channel index (zero based) */
++ int bdid; /* board index (zero based) */
++};
++
++/*
++* info_sleep_stat defines
++*/
++#define INFO_RUNWAIT 0x0001
++#define INFO_WOPEN 0x0002
++#define INFO_TTIOW 0x0004
++#define INFO_CH_RWAIT 0x0008
++#define INFO_CH_WEMPTY 0x0010
++#define INFO_CH_WLOW 0x0020
++#define INFO_XXBUF_BUSY 0x0040
++
++#define DIGI_GETCH ('d'<<8) | 245 /* get board info */
++
++/* Board type definitions */
++
++#define SUBTYPE 0007
++#define T_PCXI 0000
++#define T_PCXM 0001
++#define T_PCXE 0002
++#define T_PCXR 0003
++#define T_SP 0004
++#define T_SP_PLUS 0005
++# define T_HERC 0000
++# define T_HOU 0001
++# define T_LON 0002
++# define T_CHA 0003
++#define FAMILY 0070
++#define T_COMXI 0000
++#define T_PCXX 0010
++#define T_CX 0020
++#define T_EPC 0030
++#define T_PCLITE 0040
++#define T_SPXX 0050
++#define T_AVXX 0060
++#define T_DXB 0070
++#define T_A2K_4_8 0070
++#define BUSTYPE 0700
++#define T_ISABUS 0000
++#define T_MCBUS 0100
++#define T_EISABUS 0200
++#define T_PCIBUS 0400
++
++/* Board State Definitions */
++
++#define BD_RUNNING 0x0
++#define BD_REASON 0x7f
++#define BD_NOTFOUND 0x1
++#define BD_NOIOPORT 0x2
++#define BD_NOMEM 0x3
++#define BD_NOBIOS 0x4
++#define BD_NOFEP 0x5
++#define BD_FAILED 0x6
++#define BD_ALLOCATED 0x7
++#define BD_TRIBOOT 0x8
++#define BD_BADKME 0x80
++
++#define DIGI_SPOLL ('d'<<8) | 254 /* change poller rate */
++
++#endif /* DIGI_H */
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/Makefile 2003-09-27 11:38:18.449723600 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/Makefile 2003-09-27 11:38:20.973339952 +0800
+@@ -0,0 +1,19 @@
++# Makefile for the in-kernel version of the DGAP driver.
++
++PACKAGE=dgap
++TRUE_VERSION="1.0-2"
++DGAP_PART_NUM=40002347_A-INKERNEL
++SBINDIR=/usr/sbin
++
++RPMNAME := $(PACKAGE)-$(TRUE_VERSION)
++PARTNUM := $(DGAP_PART_NUM)
++
++# Send in some extra things...
++EXTRA_CFLAGS += -DDGAP_TRACER -DSBINDIR=\"$(SBINDIR)\" \
++ -DDG_NAME=\"$(RPMNAME)\" -DDG_PART=\"$(PARTNUM)\"
++
++obj-$(CONFIG_DIGI_DGAP) += dgap.o
++
++dgap-objs := dgap_driver.o dgap_mgmt.o\
++ dgap_parse.o dgap_proc.o\
++ dgap_trace.o dgap_tty.o
+Index: linux-2.6.0-test5/drivers/char/drm/drm_drv.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/drm/drm_drv.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/drm/drm_drv.h 2003-09-27 11:38:20.982338584 +0800
+@@ -848,7 +848,7 @@
+ */
+
+ DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n",
+- current->pid, (long)dev->device, dev->open_count );
++ current->pid, (long)old_encode_dev(dev->device), dev->open_count );
+
+ if ( priv->lock_count && dev->lock.hw_lock &&
+ _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) &&
+@@ -983,7 +983,7 @@
+ ++priv->ioctl_count;
+
+ DRM_DEBUG( "pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
+- current->pid, cmd, nr, (long)dev->device,
++ current->pid, cmd, nr, (long)old_encode_dev(dev->device),
+ priv->authenticated );
+
+ if ( nr >= DRIVER_IOCTL_COUNT ) {
+Index: linux-2.6.0-test5/drivers/char/drm/drm_fops.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/drm/drm_fops.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/drm/drm_fops.h 2003-09-27 11:38:20.984338280 +0800
+@@ -111,7 +111,7 @@
+ drm_device_t *dev = priv->dev;
+
+ DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
+- current->pid, (long)dev->device, dev->open_count);
++ current->pid, (long)old_encode_dev(dev->device), dev->open_count);
+ return 0;
+ }
+
+@@ -122,7 +122,7 @@
+ drm_device_t *dev = priv->dev;
+ int retcode;
+
+- DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, (long)dev->device);
++ DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, (long)old_encode_dev(dev->device));
+ retcode = fasync_helper(fd, filp, on, &dev->buf_async);
+ if (retcode < 0) return retcode;
+ return 0;
+Index: linux-2.6.0-test5/drivers/char/drm/drm_proc.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/drm/drm_proc.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/drm/drm_proc.h 2003-09-27 11:38:20.989337520 +0800
+@@ -184,9 +184,9 @@
+
+ if (dev->unique) {
+ DRM_PROC_PRINT("%s 0x%lx %s\n",
+- dev->name, (long)dev->device, dev->unique);
++ dev->name, (long)old_encode_dev(dev->device), dev->unique);
+ } else {
+- DRM_PROC_PRINT("%s 0x%lx\n", dev->name, (long)dev->device);
++ DRM_PROC_PRINT("%s 0x%lx\n", dev->name, (long)old_encode_dev(dev->device));
+ }
+
+ if (len > request + offset) return request;
+Index: linux-2.6.0-test5/drivers/char/epca.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/epca.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/epca.c 2003-09-27 11:38:21.025332048 +0800
+@@ -3,8 +3,10 @@
+
+ Copyright (C) 1996 Digi International.
+
+- For technical support please email digiLinux@dgii.com or
+- call Digi tech support at (612) 912-3456
++ NOTE: As of the 2.6 Linux kernel, Digi International
++ no longer supports this version of the driver.
++ If you have a PCI EPCA DigiBoard, please use the DGAP
++ driver instead.
+
+ Much of this design and code came from epca.c which was
+ copyright (C) 1994, 1995 Troy De Jongh, and subsquently
+@@ -44,9 +46,12 @@
+ #include <asm/uaccess.h>
+ #include <asm/io.h>
+
+-#ifdef CONFIG_PCI
+-#define ENABLE_PCI
+-#endif /* CONFIG_PCI */
++/*
++ * NOTE: DO NOT enable PCI in this driver anymore!
++ * There is a new replacement for this driver for the PCI boards
++ * called DGAP which should be used instead.
++ */
++#undef ENABLE_PCI
+
+ #define putUser(arg1, arg2) put_user(arg1, (unsigned long *)arg2)
+ #define getUser(arg1, arg2) get_user(arg1, (unsigned int *)arg2)
+@@ -3868,7 +3873,7 @@
+ };
+
+
+-static int __init epca_init_one (struct pci_dev *pdev,
++static int __devinit epca_init_one (struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+ {
+ static int board_num = -1;
+Index: linux-2.6.0-test5/drivers/char/ftape/lowlevel/ftape-init.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/ftape/lowlevel/ftape-init.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/ftape/lowlevel/ftape-init.c 2003-09-27 11:38:21.028331592 +0800
+@@ -55,14 +55,24 @@
+ char ft_dat[] __initdata = "$Date: 2003/10/02 19:51:59 $";
+
+
++#ifndef CONFIG_FT_NO_TRACE_AT_ALL
++static int ft_tracing = -1;
++#endif
++
++
+ /* Called by modules package when installing the driver
+ * or by kernel during the initialization phase
+ */
+-int __init ftape_init(void)
++static int __init ftape_init(void)
+ {
+ TRACE_FUN(ft_t_flow);
+
+ #ifdef MODULE
++#ifndef CONFIG_FT_NO_TRACE_AT_ALL
++ if (ft_tracing != -1) {
++ ftape_tracing = ft_tracing;
++ }
++#endif
+ printk(KERN_INFO FTAPE_VERSION "\n");
+ if (TRACE_LEVEL >= ft_t_info) {
+ printk(
+@@ -112,13 +122,6 @@
+ #endif
+ TRACE_EXIT 0;
+ }
+-
+-#ifdef MODULE
+-
+-#ifndef CONFIG_FT_NO_TRACE_AT_ALL
+-static int ft_tracing = -1;
+-#endif
+-
+ #define FT_MOD_PARM(var,type,desc) \
+ MODULE_PARM(var,type); MODULE_PARM_DESC(var,desc)
+
+@@ -141,21 +144,7 @@
+ "QIC-117 driver for QIC-40/80/3010/3020 floppy tape drives.");
+ MODULE_LICENSE("GPL");
+
+-/* Called by modules package when installing the driver
+- */
+-int init_module(void)
+-{
+-#ifndef CONFIG_FT_NO_TRACE_AT_ALL
+- if (ft_tracing != -1) {
+- ftape_tracing = ft_tracing;
+- }
+-#endif
+- return ftape_init();
+-}
+-
+-/* Called by modules package when removing the driver
+- */
+-void cleanup_module(void)
++static void __exit ftape_exit(void)
+ {
+ TRACE_FUN(ft_t_flow);
+
+@@ -166,4 +155,6 @@
+ printk(KERN_INFO "ftape: unloaded.\n");
+ TRACE_EXIT;
+ }
+-#endif /* MODULE */
++
++module_init(ftape_init);
++module_exit(ftape_exit);
+Index: linux-2.6.0-test5/drivers/char/hvc_console.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/hvc_console.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/hvc_console.c 2003-09-27 11:38:21.030331288 +0800
+@@ -284,9 +284,6 @@
+ if (tty_register_driver(hvc_driver))
+ panic("Couldn't register hvc console driver\n");
+
+- for (i = 0; i < num; i++)
+- tty_register_device(hvc_driver, i, NULL);
+-
+ if (num > 0)
+ kernel_thread(khvcd, NULL, CLONE_KERNEL);
+
+Index: linux-2.6.0-test5/drivers/char/hw_random.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/hw_random.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/hw_random.c 2003-09-27 11:38:21.035330528 +0800
+@@ -149,7 +149,7 @@
+ * register a pci_driver, because someone else might one day
+ * want to register another driver on the same PCI id.
+ */
+-static struct pci_device_id rng_pci_tbl[] __initdata = {
++static struct pci_device_id rng_pci_tbl[] = {
+ { 0x1022, 0x7443, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_amd },
+ { 0x1022, 0x746b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_amd },
+
+Index: linux-2.6.0-test5/drivers/char/istallion.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/istallion.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/istallion.c 2003-09-27 11:38:21.070325208 +0800
+@@ -2303,7 +2303,7 @@
+
+ /*
+ * FIXME: There's a module removal race here: tty_hangup
+- * calls schedule_task which will call into this
++ * calls schedule_work which will call into this
+ * driver later.
+ */
+ portp = (stliport_t *) arg;
+@@ -2944,7 +2944,7 @@
+ ((portp->sigs & TIOCM_CD) == 0)) {
+ if (portp->flags & ASYNC_CHECK_CD) {
+ if (tty)
+- schedule_task(&portp->tqhangup);
++ schedule_work(&portp->tqhangup);
+ }
+ }
+ }
+Index: linux-2.6.0-test5/drivers/char/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/Kconfig 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/Kconfig 2003-09-27 11:38:21.080323688 +0800
+@@ -143,15 +143,33 @@
+ status of the Cyclades-Z ports. The default op mode is polling. If
+ unsure, say N.
+
++config DIGI_DGAP
++ tristate "Digi International EPCA PCI Acceleport Async Support"
++ depends on SERIAL_NONSTANDARD
++ ---help---
++ This is a driver for Digi International's Xr, Xem, C/X and EPC/X PCI
++ series of cards which provide multiple serial ports. You would need
++ something like this to connect more than two modems to your Linux
++ box, for instance in order to become a dial-in server.
++ This driver supports only the PCI versions of these cards.
++ If you have a card like this, say Y here and read the file
++ <file:Documentation/digidgap.txt>.
++
++ NOTE: There is another, separate driver for the EPCA ISA boards:
++ "Digiboard Intelligent ISA Async Support" below.
++
++ If you want to compile this driver as a module, say M here: the
++ module will be called dgap.
++
+ config DIGIEPCA
+- tristate "Digiboard Intelligent Async Support"
++ tristate "Digiboard Intelligent ISA Async Support"
+ depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP
+ ---help---
+- This is a driver for Digi International's Xx, Xeve, and Xem series
+- of cards which provide multiple serial ports. You would need
++ This is a driver for Digi International's Xx, Xeve, and Xem ISA
++ series of cards which provide multiple serial ports. You would need
+ something like this to connect more than two modems to your Linux
+ box, for instance in order to become a dial-in server. This driver
+- supports the original PC (ISA) boards as well as PCI, and EISA. If
++ supports the original PC (ISA) boards as well as EISA. If
+ you have a card like this, say Y here and read the file
+ <file:Documentation/digiepca.txt>.
+
+@@ -159,12 +177,12 @@
+ "Digiboard PC/Xx Support" below. You should (and can) only select
+ one of the two drivers.
+
+- If you want to compile this driver as a module, say M here and read
+- <file:Documentation/modules.txt>. The module will be called epca.
++ If you want to compile this driver as a module, say M here: the
++ module will be called epca.
+
+ config DIGI
+ tristate "Digiboard PC/Xx Support"
+- depends on SERIAL_NONSTANDARD && DIGIEPCA=n && BROKEN_ON_SMP
++ depends on SERIAL_NONSTANDARD && DIGIEPCA=n && BROKEN_ON_SMP && OBSOLETE
+ help
+ This is a driver for the Digiboard PC/Xe, PC/Xi, and PC/Xeve cards
+ that give you many serial ports. You would need something like this
+@@ -172,8 +190,8 @@
+ order to become a dial-in server. If you have a card like that, say
+ Y here and read the file <file:Documentation/digiboard.txt>.
+
+- If you want to compile this driver as a module, say M here and read
+- <file:Documentation/modules.txt>. The module will be called pcxx.
++ If you want to compile this driver as a module, say M here: the
++ module will be called pcxx.
+
+ config ESPSERIAL
+ tristate "Hayes ESP serial port support"
+@@ -352,7 +370,7 @@
+
+ config ISTALLION
+ tristate "Stallion EC8/64, ONboard, Brumby support"
+- depends on STALDRV && BROKEN
++ depends on STALDRV && BROKEN_ON_SMP
+ help
+ If you have an EasyConnection 8/64, ONboard, Brumby or Stallion
+ serial multiport card, say Y here. Make sure to read
+@@ -959,6 +977,7 @@
+ config MWAVE
+ tristate "ACP Modem (Mwave) support"
+ depends on X86
++ select SERIAL_8250
+ ---help---
+ The ACP modem (Mwave) for Linux is a WinModem. It is composed of a
+ kernel driver and a user level application. Together these components
+@@ -1001,6 +1020,7 @@
+
+ config HANGCHECK_TIMER
+ tristate "Hangcheck timer"
++ depends on X86_64 || X86
+ help
+ The hangcheck-timer module detects when the system has gone
+ out to lunch past a certain margin. It can reboot the system
+Index: linux-2.6.0-test5/drivers/char/keyboard.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/keyboard.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/keyboard.c 2003-09-27 11:38:21.088322472 +0800
+@@ -205,7 +205,7 @@
+ INPUT_KEYCODE(dev, scancode) = keycode;
+
+ for (i = 0; i < dev->keycodemax; i++)
+- if(INPUT_KEYCODE(dev, scancode) == oldkey)
++ if(keycode == oldkey)
+ break;
+ if (i == dev->keycodemax)
+ clear_bit(oldkey, dev->keybit);
+@@ -1058,6 +1058,9 @@
+ }
+ if (sysrq_down && down && !rep) {
+ handle_sysrq(kbd_sysrq_xlate[keycode], regs, tty);
++#ifdef CONFIG_KGDB_SYSRQ
++ sysrq_down = 0; /* in case we miss the "up" event */
++#endif
+ return;
+ }
+ #endif
+Index: linux-2.6.0-test5/drivers/char/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/Makefile 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/Makefile 2003-09-27 11:38:21.090322168 +0800
+@@ -7,7 +7,7 @@
+ #
+ FONTMAPFILE = cp437.uni
+
+-obj-y += mem.o tty_io.o n_tty.o tty_ioctl.o pty.o misc.o random.o
++obj-y += mem.o random.o tty_io.o n_tty.o tty_ioctl.o pty.o misc.o
+
+ obj-$(CONFIG_VT) += vt_ioctl.o vc_screen.o consolemap.o consolemap_deftbl.o selection.o keyboard.o
+ obj-$(CONFIG_HW_CONSOLE) += vt.o defkeymap.o
+@@ -18,6 +18,7 @@
+ obj-$(CONFIG_MOXA_INTELLIO) += moxa.o
+ obj-$(CONFIG_DIGI) += pcxx.o
+ obj-$(CONFIG_DIGIEPCA) += epca.o
++obj-$(CONFIG_DIGI_DGAP) += digi/dgap/
+ obj-$(CONFIG_CYCLADES) += cyclades.o
+ obj-$(CONFIG_STALLION) += stallion.o
+ obj-$(CONFIG_ISTALLION) += istallion.o
+Index: linux-2.6.0-test5/drivers/char/mem.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/mem.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/mem.c 2003-09-27 11:38:21.094321560 +0800
+@@ -680,18 +680,9 @@
+ S_IFCHR | devlist[i].mode, devlist[i].name);
+ }
+
+- rand_initialize();
+ #if defined (CONFIG_FB)
+ fbmem_init();
+ #endif
+- tty_init();
+-#ifdef CONFIG_M68K_PRINTER
+- lp_m68k_init();
+-#endif
+- misc_init();
+-#ifdef CONFIG_FTAPE
+- ftape_init();
+-#endif
+ return 0;
+ }
+
+Index: linux-2.6.0-test5/drivers/char/misc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/misc.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/misc.c 2003-09-27 11:38:21.097321104 +0800
+@@ -43,6 +43,7 @@
+ #include <linux/major.h>
+ #include <linux/slab.h>
+ #include <linux/proc_fs.h>
++#include <linux/seq_file.h>
+ #include <linux/devfs_fs_kernel.h>
+ #include <linux/stat.h>
+ #include <linux/init.h>
+@@ -53,7 +54,7 @@
+ /*
+ * Head entry for the doubly linked miscdevice list
+ */
+-static struct miscdevice misc_list = { 0, "head", NULL, &misc_list, &misc_list };
++static LIST_HEAD(misc_list);
+ static DECLARE_MUTEX(misc_sem);
+
+ /*
+@@ -73,30 +74,64 @@
+ extern int tosh_init(void);
+ extern int i8k_init(void);
+
+-static int misc_read_proc(char *buf, char **start, off_t offset,
+- int len, int *eof, void *private)
++#ifdef CONFIG_PROC_FS
++static void *misc_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+ struct miscdevice *p;
+- int written;
++ loff_t off = 0;
+
+- written=0;
+- for (p = misc_list.next; p != &misc_list && written < len; p = p->next) {
+- written += sprintf(buf+written, "%3i %s\n",p->minor, p->name ?: "");
+- if (written < offset) {
+- offset -= written;
+- written = 0;
+- }
+- }
+- *start = buf + offset;
+- written -= offset;
+- if(written > len) {
+- *eof = 0;
+- return len;
++ down(&misc_sem);
++ list_for_each_entry(p, &misc_list, list) {
++ if (*pos == off++)
++ return p;
+ }
+- *eof = 1;
+- return (written<0) ? 0 : written;
++ return NULL;
++}
++
++static void *misc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++{
++ struct list_head *n = ((struct miscdevice *)v)->list.next;
++
++ ++*pos;
++
++ return (n != &misc_list) ? list_entry(n, struct miscdevice, list)
++ : NULL;
++}
++
++static void misc_seq_stop(struct seq_file *seq, void *v)
++{
++ up(&misc_sem);
++}
++
++static int misc_seq_show(struct seq_file *seq, void *v)
++{
++ const struct miscdevice *p = v;
++
++ seq_printf(seq, "%3i %s\n", p->minor, p->name ? p->name : "");
++ return 0;
++}
++
++
++static struct seq_operations misc_seq_ops = {
++ .start = misc_seq_start,
++ .next = misc_seq_next,
++ .stop = misc_seq_stop,
++ .show = misc_seq_show,
++};
++
++static int misc_seq_open(struct inode *inode, struct file *file)
++{
++ return seq_open(file, &misc_seq_ops);
+ }
+
++static struct file_operations misc_proc_fops = {
++ .owner = THIS_MODULE,
++ .open = misc_seq_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = seq_release,
++};
++#endif
+
+ static int misc_open(struct inode * inode, struct file * file)
+ {
+@@ -107,21 +142,27 @@
+
+ down(&misc_sem);
+
+- c = misc_list.next;
+-
+- while ((c != &misc_list) && (c->minor != minor))
+- c = c->next;
+- if (c != &misc_list)
+- new_fops = fops_get(c->fops);
++ list_for_each_entry(c, &misc_list, list) {
++ if (c->minor == minor) {
++ new_fops = fops_get(c->fops);
++ break;
++ }
++ }
++
+ if (!new_fops) {
+ up(&misc_sem);
+ request_module("char-major-%d-%d", MISC_MAJOR, minor);
+ down(&misc_sem);
+- c = misc_list.next;
+- while ((c != &misc_list) && (c->minor != minor))
+- c = c->next;
+- if (c == &misc_list || (new_fops = fops_get(c->fops)) == NULL)
+- goto fail;
++
++ list_for_each_entry(c, &misc_list, list) {
++ if (c->minor == minor) {
++ new_fops = fops_get(c->fops);
++ if (!new_fops)
++ goto fail;
++ break;
++ }
++ }
++ goto fail;
+ }
+
+ err = 0;
+@@ -166,16 +207,12 @@
+ {
+ struct miscdevice *c;
+
+- if (misc->next || misc->prev)
+- return -EBUSY;
+ down(&misc_sem);
+- c = misc_list.next;
+-
+- while ((c != &misc_list) && (c->minor != misc->minor))
+- c = c->next;
+- if (c != &misc_list) {
+- up(&misc_sem);
+- return -EBUSY;
++ list_for_each_entry(c, &misc_list, list) {
++ if (c->minor == misc->minor) {
++ up(&misc_sem);
++ return -EBUSY;
++ }
+ }
+
+ if (misc->minor == MISC_DYNAMIC_MINOR) {
+@@ -205,10 +242,7 @@
+ * Add it to the front, so that later devices can "override"
+ * earlier defaults
+ */
+- misc->prev = &misc_list;
+- misc->next = misc_list.next;
+- misc->prev->next = misc;
+- misc->next->prev = misc;
++ list_add(&misc->list, &misc_list);
+ up(&misc_sem);
+ return 0;
+ }
+@@ -226,13 +260,12 @@
+ int misc_deregister(struct miscdevice * misc)
+ {
+ int i = misc->minor;
+- if (!misc->next || !misc->prev)
++
++ if (list_empty(&misc->list))
+ return -EINVAL;
++
+ down(&misc_sem);
+- misc->prev->next = misc->next;
+- misc->next->prev = misc->prev;
+- misc->next = NULL;
+- misc->prev = NULL;
++ list_del(&misc->list);
+ devfs_remove(misc->devfs_name);
+ if (i < DYNAMIC_MINORS && i>0) {
+ misc_minors[i>>3] &= ~(1 << (misc->minor & 7));
+@@ -244,9 +277,15 @@
+ EXPORT_SYMBOL(misc_register);
+ EXPORT_SYMBOL(misc_deregister);
+
+-int __init misc_init(void)
++static int __init misc_init(void)
+ {
+- create_proc_read_entry("misc", 0, 0, misc_read_proc, NULL);
++#ifdef CONFIG_PROC_FS
++ struct proc_dir_entry *ent;
++
++ ent = create_proc_entry("misc", 0, NULL);
++ if (ent)
++ ent->proc_fops = &misc_proc_fops;
++#endif
+ #ifdef CONFIG_MVME16x
+ rtc_MK48T08_init();
+ #endif
+@@ -281,3 +320,4 @@
+ }
+ return 0;
+ }
++module_init(misc_init);
+Index: linux-2.6.0-test5/drivers/char/mwave/mwavedd.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/mwave/mwavedd.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/mwave/mwavedd.c 2003-09-27 11:38:21.102320344 +0800
+@@ -293,8 +293,6 @@
+
+ case IOCTL_MW_GET_IPC: {
+ unsigned int ipcnum = (unsigned int) ioarg;
+- spinlock_t ipc_lock = SPIN_LOCK_UNLOCKED;
+- unsigned long flags;
+
+ PRINTK_3(TRACE_MWAVE,
+ "mwavedd::mwave_ioctl IOCTL_MW_GET_IPC"
+@@ -310,32 +308,29 @@
+ }
+
+ if (pDrvData->IPCs[ipcnum].bIsEnabled == TRUE) {
++ DECLARE_WAITQUEUE(wait, current);
++
+ PRINTK_2(TRACE_MWAVE,
+ "mwavedd::mwave_ioctl, thread for"
+ " ipc %x going to sleep\n",
+ ipcnum);
+-
+- spin_lock_irqsave(&ipc_lock, flags);
++ add_wait_queue(&pDrvData->IPCs[ipcnum].ipc_wait_queue, &wait);
++ pDrvData->IPCs[ipcnum].bIsHere = TRUE;
++ set_current_state(TASK_INTERRUPTIBLE);
+ /* check whether an event was signalled by */
+ /* the interrupt handler while we were gone */
+ if (pDrvData->IPCs[ipcnum].usIntCount == 1) { /* first int has occurred (race condition) */
+ pDrvData->IPCs[ipcnum].usIntCount = 2; /* first int has been handled */
+- spin_unlock_irqrestore(&ipc_lock, flags);
+ PRINTK_2(TRACE_MWAVE,
+ "mwavedd::mwave_ioctl"
+ " IOCTL_MW_GET_IPC ipcnum %x"
+ " handling first int\n",
+ ipcnum);
+ } else { /* either 1st int has not yet occurred, or we have already handled the first int */
+- pDrvData->IPCs[ipcnum].bIsHere = TRUE;
+-#warning "Sleeping on spinlock"
+- interruptible_sleep_on(&pDrvData->IPCs[ipcnum].ipc_wait_queue);
+- pDrvData->IPCs[ipcnum].bIsHere = FALSE;
++ schedule();
+ if (pDrvData->IPCs[ipcnum].usIntCount == 1) {
+- pDrvData->IPCs[ipcnum].
+- usIntCount = 2;
++ pDrvData->IPCs[ipcnum].usIntCount = 2;
+ }
+- spin_unlock_irqrestore(&ipc_lock, flags);
+ PRINTK_2(TRACE_MWAVE,
+ "mwavedd::mwave_ioctl"
+ " IOCTL_MW_GET_IPC ipcnum %x"
+@@ -343,6 +338,9 @@
+ " application\n",
+ ipcnum);
+ }
++ pDrvData->IPCs[ipcnum].bIsHere = FALSE;
++ remove_wait_queue(&pDrvData->IPCs[ipcnum].ipc_wait_queue, &wait);
++ set_current_state(TASK_RUNNING);
+ PRINTK_2(TRACE_MWAVE,
+ "mwavedd::mwave_ioctl IOCTL_MW_GET_IPC,"
+ " returning thread for ipc %x"
+Index: linux-2.6.0-test5/drivers/char/n_r3964.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/n_r3964.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/n_r3964.c 2003-09-27 11:38:21.112318824 +0800
+@@ -150,22 +150,18 @@
+ static int r3964_receive_room(struct tty_struct *tty);
+
+ static struct tty_ldisc tty_ldisc_N_R3964 = {
+- TTY_LDISC_MAGIC, /* magic */
+- "R3964", /* name */
+- 0, /* num */
+- 0, /* flags */
+- r3964_open, /* open */
+- r3964_close, /* close */
+- 0, /* flush_buffer */
+- 0, /* chars_in_buffer */
+- r3964_read, /* read */
+- r3964_write, /* write */
+- r3964_ioctl, /* ioctl */
+- r3964_set_termios, /* set_termios */
+- r3964_poll, /* poll */
+- r3964_receive_buf, /* receive_buf */
+- r3964_receive_room, /* receive_room */
+- 0 /* write_wakeup */
++ .owner = THIS_MODULE,
++ .magic = TTY_LDISC_MAGIC,
++ .name = "R3964",
++ .open = r3964_open,
++ .close = r3964_close,
++ .read = r3964_read,
++ .write = r3964_write,
++ .ioctl = r3964_ioctl,
++ .set_termios = r3964_set_termios,
++ .poll = r3964_poll,
++ .receive_buf = r3964_receive_buf,
++ .receive_room = r3964_receive_room,
+ };
+
+
+@@ -1070,8 +1066,6 @@
+ {
+ struct r3964_info *pInfo;
+
+- MOD_INC_USE_COUNT;
+-
+ TRACE_L("open");
+ TRACE_L("tty=%x, PID=%d, disc_data=%x",
+ (int)tty, current->pid, (int)tty->disc_data);
+@@ -1188,8 +1182,6 @@
+ TRACE_M("r3964_close - tx_buf kfree %x",(int)pInfo->tx_buf);
+ kfree(pInfo);
+ TRACE_M("r3964_close - info kfree %x",(int)pInfo);
+-
+- MOD_DEC_USE_COUNT;
+ }
+
+ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
+Index: linux-2.6.0-test5/drivers/char/n_tty.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/n_tty.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/n_tty.c 2003-09-27 11:38:21.120317608 +0800
+@@ -977,11 +977,11 @@
+ if (file->f_op->write != redirected_tty_write && current->tty == tty) {
+ if (tty->pgrp <= 0)
+ printk("read_chan: tty->pgrp <= 0!\n");
+- else if (current->pgrp != tty->pgrp) {
++ else if (process_group(current) != tty->pgrp) {
+ if (is_ignored(SIGTTIN) ||
+- is_orphaned_pgrp(current->pgrp))
++ is_orphaned_pgrp(process_group(current)))
+ return -EIO;
+- kill_pg(current->pgrp, SIGTTIN, 1);
++ kill_pg(process_group(current), SIGTTIN, 1);
+ return -ERESTARTSYS;
+ }
+ }
+Index: linux-2.6.0-test5/drivers/char/pcmcia/synclink_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/pcmcia/synclink_cs.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/pcmcia/synclink_cs.c 2003-09-27 11:38:21.149313200 +0800
+@@ -725,14 +725,6 @@
+ if (debug_level >= DEBUG_LEVEL_INFO)
+ printk("mgslpc_release(0x%p)\n", link);
+
+- if (link->open) {
+- if (debug_level >= DEBUG_LEVEL_INFO)
+- printk("synclink_cs: release postponed, '%s' still open\n",
+- link->dev->dev_name);
+- link->state |= DEV_STALE_CONFIG;
+- return;
+- }
+-
+ /* Unlink the device chain */
+ link->dev = NULL;
+ link->state &= ~DEV_CONFIG;
+Index: linux-2.6.0-test5/drivers/char/pcxx.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/pcxx.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/pcxx.c 2003-09-27 11:38:21.164310920 +0800
+@@ -12,11 +12,12 @@
+ * This driver does NOT support DigiBoard's fastcook FEP option and
+ * does not support the transparent print (i.e. digiprint) option.
+ *
+- * This Driver is currently maintained by Christoph Lameter (christoph@lameter.com)
+ *
+- * Please contact digi for support issues at digilnux@dgii.com.
+- * Some more information can be found at
+- * http://lameter.com/digi.
++ * NOTE: As of the 2.6 Linux kernel, Digi International
++ * no longer supports this version of the driver.
++ * If you have a PCI EPCA DigiBoard, please use the DGAP
++ * driver instead.
++ *
+ *
+ * 1.5.2 Fall 1995 Bug fixes by David Nugent
+ * 1.5.3 March 9, 1996 Christoph Lameter: Fixed 115.2K Support. Memory
+Index: linux-2.6.0-test5/drivers/char/random.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/random.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/random.c 2003-09-27 11:38:21.184307880 +0800
+@@ -253,6 +253,7 @@
+ #include <linux/genhd.h>
+ #include <linux/interrupt.h>
+ #include <linux/spinlock.h>
++#include <linux/percpu.h>
+
+ #include <asm/processor.h>
+ #include <asm/uaccess.h>
+@@ -281,6 +282,15 @@
+ static int random_write_wakeup_thresh = 128;
+
+ /*
++ * When the input pool goes over trickle_thresh, start dropping most
++ * samples to avoid wasting CPU time and reduce lock contention.
++ */
++
++static int trickle_thresh = DEFAULT_POOL_SIZE * 7;
++
++static DEFINE_PER_CPU(int, trickle_count) = 0;
++
++/*
+ * A pool of size .poolwords is stirred with a primitive polynomial
+ * of degree .poolwords over GF(2). The taps for various sizes are
+ * defined below. They are chosen to be evenly spaced (minimum RMS
+@@ -778,6 +788,11 @@
+ __s32 delta, delta2, delta3;
+ int entropy = 0;
+
++ /* if over the trickle threshold, use only 1 in 4096 samples */
++ if ( random_state->entropy_count > trickle_thresh &&
++ (__get_cpu_var(trickle_count)++ & 0xfff))
++ return;
++
+ #if defined (__i386__) || defined (__x86_64__)
+ if (cpu_has_tsc) {
+ __u32 high;
+@@ -1478,16 +1493,16 @@
+ }
+ }
+
+-void __init rand_initialize(void)
++static int __init rand_initialize(void)
+ {
+ int i;
+
+ if (create_entropy_store(DEFAULT_POOL_SIZE, &random_state))
+- return; /* Error, return */
++ goto err;
+ if (batch_entropy_init(BATCH_ENTROPY_SIZE, random_state))
+- return; /* Error, return */
++ goto err;
+ if (create_entropy_store(SECONDARY_POOL_SIZE, &sec_random_state))
+- return; /* Error, return */
++ goto err;
+ clear_entropy_store(random_state);
+ clear_entropy_store(sec_random_state);
+ init_std_data(random_state);
+@@ -1500,7 +1515,11 @@
+ memset(&mouse_timer_state, 0, sizeof(struct timer_rand_state));
+ memset(&extract_timer_state, 0, sizeof(struct timer_rand_state));
+ extract_timer_state.dont_count_entropy = 1;
++ return 0;
++err:
++ return -1;
+ }
++module_init(rand_initialize);
+
+ void rand_initialize_irq(int irq)
+ {
+Index: linux-2.6.0-test5/drivers/char/rio/rio_linux.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/rio/rio_linux.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/rio/rio_linux.c 2003-09-27 11:38:21.194306360 +0800
+@@ -234,14 +234,12 @@
+ support up to 64 bits on 64bit architectures. -- REW 20/06/99 */
+ long rio_irqmask = -1;
+
+-#ifndef TWO_ZERO
+ MODULE_AUTHOR("Rogier Wolff <R.E.Wolff@bitwizard.nl>, Patrick van de Lageweg <patrick@bitwizard.nl>");
+ MODULE_DESCRIPTION("RIO driver");
+ MODULE_LICENSE("GPL");
+ MODULE_PARM(rio_poll, "i");
+ MODULE_PARM(rio_debug, "i");
+ MODULE_PARM(rio_irqmask, "i");
+-#endif
+
+ static struct real_driver rio_real_driver = {
+ rio_disable_tx_interrupts,
+@@ -1034,13 +1032,6 @@
+ func_exit();
+ }
+
+-#ifdef TWO_ZERO
+-#define PDEV unsigned char pci_bus, unsigned pci_fun
+-#define pdev pci_bus, pci_fun
+-#else
+-#define PDEV struct pci_dev *pdev
+-#endif
+-
+
+ #ifdef CONFIG_PCI
+ /* This was written for SX, but applies to RIO too...
+@@ -1062,7 +1053,7 @@
+ EEprom. As the bit is read/write for the CPU, we can fix it here,
+ if we detect that it isn't set correctly. -- REW */
+
+-void fix_rio_pci (PDEV)
++void fix_rio_pci (struct pci_dev *pdev)
+ {
+ unsigned int hwbase;
+ unsigned long rebase;
+@@ -1095,12 +1086,7 @@
+ int okboard;
+
+ #ifdef CONFIG_PCI
+-#ifndef TWO_ZERO
+ struct pci_dev *pdev = NULL;
+-#else
+- unsigned char pci_bus, pci_fun;
+- /* in 2.2.x pdev is a pointer defining a PCI device. In 2.0 its the bus/fn */
+-#endif
+ unsigned int tint;
+ unsigned short tshort;
+ #endif
+@@ -1128,17 +1114,11 @@
+
+ #ifdef CONFIG_PCI
+ /* First look for the JET devices: */
+-#ifndef TWO_ZERO
+ while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX,
+ PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8,
+ pdev))) {
+ if (pci_enable_device(pdev)) continue;
+-#else
+- for (i=0;i< RIO_NBOARDS;i++) {
+- if (pcibios_find_device (PCI_VENDOR_ID_SPECIALIX,
+- PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, i,
+- &pci_bus, &pci_fun)) break;
+-#endif
++
+ /* Specialix has a whole bunch of cards with
+ 0x2000 as the device ID. They say its because
+ the standard requires it. Stupid standard. */
+@@ -1196,16 +1176,9 @@
+ } else {
+ iounmap((char*) (p->RIOHosts[p->RIONumHosts].Caddr));
+ }
+-
+-#ifdef TWO_ZERO
+- } /* We have two variants with the opening brace, so to prevent */
+-#else
+- } /* Emacs from getting confused we have two closing braces too. */
+-#endif
++ }
+
+ /* Then look for the older PCI card.... : */
+-#ifndef TWO_ZERO
+-
+
+ /* These older PCI cards have problems (only byte-mode access is
+ supported), which makes them a bit awkward to support.
+@@ -1219,12 +1192,6 @@
+ PCI_DEVICE_ID_SPECIALIX_RIO,
+ pdev))) {
+ if (pci_enable_device(pdev)) continue;
+-#else
+- for (i=0;i< RIO_NBOARDS;i++) {
+- if (pcibios_find_device (PCI_VENDOR_ID_SPECIALIX,
+- PCI_DEVICE_ID_SPECIALIX_RIO, i,
+- &pci_bus, &pci_fun)) break;
+-#endif
+
+ #ifdef CONFIG_RIO_OLDPCI
+ pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &tint);
+@@ -1272,11 +1239,7 @@
+ printk (KERN_ERR "Found an older RIO PCI card, but the driver is not "
+ "compiled to support it.\n");
+ #endif
+-#ifdef TWO_ZERO
+- } /* We have two variants with the opening brace, so to prevent */
+-#else
+- } /* Emacs from getting confused we have two closing braces too. */
+-#endif
++ }
+ #endif /* PCI */
+
+ /* Now probe for ISA cards... */
+Index: linux-2.6.0-test5/drivers/char/rocket.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/rocket.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/rocket.c 2003-09-27 11:38:21.219302560 +0800
+@@ -956,7 +956,7 @@
+ * Info->count is now 1; so it's safe to sleep now.
+ */
+ info->session = current->session;
+- info->pgrp = current->pgrp;
++ info->pgrp = process_group(current);
+
+ if ((info->flags & ROCKET_INITIALIZED) == 0) {
+ cp = &info->channel;
+Index: linux-2.6.0-test5/drivers/char/specialix.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/specialix.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/specialix.c 2003-09-27 11:38:21.236299976 +0800
+@@ -92,40 +92,7 @@
+ #include <linux/delay.h>
+ #include <linux/version.h>
+ #include <linux/pci.h>
+-
+-
+-/* ************************************************************** */
+-/* * This section can be removed when 2.0 becomes outdated.... * */
+-/* ************************************************************** */
+-
+-#if LINUX_VERSION_CODE < 131328 /* Less than 2.1.0 */
+-#define TWO_ZERO
+-#else
+-#if LINUX_VERSION_CODE < 131371 /* less than 2.1.43 */
+-/* This has not been extensively tested yet. Sorry. */
+-#warning "You're on your own between 2.1.0 and 2.1.43.... "
+-#warning "Please use a recent kernel."
+-#endif
+-#endif
+-
+-
+-#ifdef TWO_ZERO
+-#define Get_user(a,b) a = get_user(b)
+-#define copy_from_user(a,b,c) memcpy_fromfs(a,b,c)
+-#define copy_to_user(a,b,c) memcpy_tofs(a,b,c)
+-#define queue_task queue_task_irq_off
+-#else
+-#define Get_user(a,b) get_user(a,b)
+-#endif
+-
+-/* ************************************************************** */
+-/* * End of compatibility section.. * */
+-/* ************************************************************** */
+-
+-
+-#ifndef TWO_ZERO
+ #include <asm/uaccess.h>
+-#endif
+
+ #include "specialix_io8.h"
+ #include "cd1865.h"
+@@ -1733,7 +1700,7 @@
+ if (error)
+ return error;
+
+- Get_user(arg, (unsigned long *) value);
++ get_user(arg, (unsigned long *) value);
+ switch (cmd) {
+ case TIOCMBIS:
+ /* if (arg & TIOCM_RTS)
+@@ -1925,7 +1892,7 @@
+ (unsigned long *) arg);
+ return 0;
+ case TIOCSSOFTCAR:
+- Get_user(arg, (unsigned long *) arg);
++ get_user(arg, (unsigned long *) arg);
+ tty->termios->c_cflag =
+ ((tty->termios->c_cflag & ~CLOCAL) |
+ (arg ? CLOCAL : 0));
+Index: linux-2.6.0-test5/drivers/char/sx.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/sx.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/sx.c 2003-09-27 11:38:21.255297088 +0800
+@@ -2356,14 +2356,6 @@
+ func_exit();
+ }
+
+-#ifdef TWO_ZERO
+-#define PDEV unsigned char pci_bus, unsigned pci_fun
+-#define pdev pci_bus, pci_fun
+-#else
+-#define PDEV struct pci_dev *pdev
+-#endif
+-
+-
+ #ifdef CONFIG_PCI
+ /********************************************************
+ * Setting bit 17 in the CNTRL register of the PLX 9050 *
+@@ -2376,7 +2368,7 @@
+ EEprom. As the bit is read/write for the CPU, we can fix it here,
+ if we detect that it isn't set correctly. -- REW */
+
+-static void fix_sx_pci (PDEV, struct sx_board *board)
++static void fix_sx_pci (struct pci_dev *pdev, struct sx_board *board)
+ {
+ unsigned int hwbase;
+ unsigned long rebase;
+@@ -2406,12 +2398,7 @@
+ struct sx_board *board;
+
+ #ifdef CONFIG_PCI
+-#ifndef TWO_ZERO
+ struct pci_dev *pdev = NULL;
+-#else
+- unsigned char pci_bus, pci_fun;
+- /* in 2.2.x pdev is a pointer defining a PCI device. In 2.0 its the bus/fn */
+-#endif
+ unsigned int tint;
+ unsigned short tshort;
+ #endif
+@@ -2431,19 +2418,12 @@
+ }
+
+ #ifdef CONFIG_PCI
+-#ifndef TWO_ZERO
+ while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX,
+ PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8,
+ pdev))) {
+ if (pci_enable_device(pdev))
+ continue;
+-#else
+- for (i=0;i< SX_NBOARDS;i++) {
+- if (pcibios_find_device (PCI_VENDOR_ID_SPECIALIX,
+- PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, i,
+- &pci_bus, &pci_fun))
+- break;
+-#endif
++
+ /* Specialix has a whole bunch of cards with
+ 0x2000 as the device ID. They say its because
+ the standard requires it. Stupid standard. */
+Index: linux-2.6.0-test5/drivers/char/sysrq.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/sysrq.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/sysrq.c 2003-09-27 11:38:21.259296480 +0800
+@@ -35,9 +35,27 @@
+ #include <linux/spinlock.h>
+
+ #include <asm/ptrace.h>
++#ifdef CONFIG_KGDB_SYSRQ
++
++#define GDB_OP &kgdb_op
++static void kgdb_sysrq(int key, struct pt_regs *pt_regs, struct tty_struct *tty)
++{
++ printk("kgdb sysrq\n");
++ breakpoint();
++}
++
++static struct sysrq_key_op kgdb_op = {
++ .handler = kgdb_sysrq,
++ .help_msg = "kGdb|Fgdb",
++ .action_msg = "Debug breakpoint\n",
++};
++
++#else
++#define GDB_OP NULL
++#endif
++
+
+ extern void reset_vc(unsigned int);
+-extern struct list_head super_blocks;
+
+ /* Whether we react on sysrq keys or just ignore them */
+ int sysrq_enabled = 1;
+@@ -239,8 +257,8 @@
+ /* c */ NULL,
+ /* d */ NULL,
+ /* e */ &sysrq_term_op,
+-/* f */ NULL,
+-/* g */ NULL,
++/* f */ GDB_OP,
++/* g */ GDB_OP,
+ /* h */ NULL,
+ /* i */ &sysrq_kill_op,
+ /* j */ NULL,
+Index: linux-2.6.0-test5/drivers/char/tty_io.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/tty_io.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/tty_io.c 2003-09-27 11:38:21.276293896 +0800
+@@ -325,13 +325,13 @@
+ printk(KERN_WARNING "tty_check_change: tty->pgrp <= 0!\n");
+ return 0;
+ }
+- if (current->pgrp == tty->pgrp)
++ if (process_group(current) == tty->pgrp)
+ return 0;
+ if (is_ignored(SIGTTOU))
+ return 0;
+- if (is_orphaned_pgrp(current->pgrp))
++ if (is_orphaned_pgrp(process_group(current)))
+ return -EIO;
+- (void) kill_pg(current->pgrp,SIGTTOU,1);
++ (void) kill_pg(process_group(current), SIGTTOU, 1);
+ return -ERESTARTSYS;
+ }
+
+@@ -826,7 +826,6 @@
+ if(!tty)
+ goto fail_no_mem;
+ initialize_tty_struct(tty);
+- tty->device = MKDEV(driver->major, driver->minor_start) + idx;
+ tty->driver = driver;
+ tty->index = idx;
+ tty_line_name(driver, idx, tty->name);
+@@ -854,8 +853,6 @@
+ if (!o_tty)
+ goto free_mem_out;
+ initialize_tty_struct(o_tty);
+- o_tty->device = MKDEV(driver->other->major,
+- driver->other->minor_start) + idx;
+ o_tty->driver = driver->other;
+ o_tty->index = idx;
+ tty_line_name(driver->other, idx, o_tty->name);
+@@ -1406,7 +1403,7 @@
+ task_unlock(current);
+ current->tty_old_pgrp = 0;
+ tty->session = current->session;
+- tty->pgrp = current->pgrp;
++ tty->pgrp = process_group(current);
+ }
+ return 0;
+ }
+@@ -1580,7 +1577,7 @@
+ task_unlock(current);
+ current->tty_old_pgrp = 0;
+ tty->session = current->session;
+- tty->pgrp = current->pgrp;
++ tty->pgrp = process_group(current);
+ return 0;
+ }
+
+@@ -2423,7 +2420,7 @@
+ * Ok, now we can initialize the rest of the tty devices and can count
+ * on memory allocations, interrupts etc..
+ */
+-void __init tty_init(void)
++static int __init tty_init(void)
+ {
+ strcpy(tty_cdev.kobj.name, "dev.tty");
+ cdev_init(&tty_cdev, &tty_fops);
+@@ -2512,4 +2509,6 @@
+ #ifdef CONFIG_A2232
+ a2232board_init();
+ #endif
++ return 0;
+ }
++module_init(tty_init);
+Index: linux-2.6.0-test5/drivers/char/watchdog/alim1535_wdt.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/watchdog/alim1535_wdt.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/watchdog/alim1535_wdt.c 2003-09-27 11:38:21.279293440 +0800
+@@ -317,7 +317,7 @@
+ * want to register another driver on the same PCI id.
+ */
+
+-static struct pci_device_id ali_pci_tbl[] __initdata = {
++static struct pci_device_id ali_pci_tbl[] = {
+ { PCI_VENDOR_ID_AL, 1535, PCI_ANY_ID, PCI_ANY_ID,},
+ { 0, },
+ };
+Index: linux-2.6.0-test5/drivers/char/watchdog/amd7xx_tco.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/watchdog/amd7xx_tco.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/watchdog/amd7xx_tco.c 2003-09-27 11:38:21.283292832 +0800
+@@ -294,7 +294,7 @@
+ .fops = &amdtco_fops
+ };
+
+-static struct pci_device_id amdtco_pci_tbl[] __initdata = {
++static struct pci_device_id amdtco_pci_tbl[] = {
+ /* AMD 766 PCI_IDs here */
+ { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_OPUS_7443, PCI_ANY_ID, PCI_ANY_ID, },
+ { 0, }
+Index: linux-2.6.0-test5/drivers/char/watchdog/i810-tco.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/watchdog/i810-tco.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/watchdog/i810-tco.c 2003-09-27 11:38:21.286292376 +0800
+@@ -301,7 +301,7 @@
+ * register a pci_driver, because someone else might one day
+ * want to register another driver on the same PCI id.
+ */
+-static struct pci_device_id i810tco_pci_tbl[] __initdata = {
++static struct pci_device_id i810tco_pci_tbl[] = {
+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, PCI_ANY_ID, PCI_ANY_ID, },
+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0, PCI_ANY_ID, PCI_ANY_ID, },
+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, PCI_ANY_ID, PCI_ANY_ID, },
+Index: linux-2.6.0-test5/drivers/char/watchdog/wdt_pci.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/watchdog/wdt_pci.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/watchdog/wdt_pci.c 2003-09-27 11:38:21.290291768 +0800
+@@ -505,7 +505,7 @@
+ };
+
+
+-static int __init wdtpci_init_one (struct pci_dev *dev,
++static int __devinit wdtpci_init_one (struct pci_dev *dev,
+ const struct pci_device_id *ent)
+ {
+ static int dev_count = 0;
+Index: linux-2.6.0-test5/drivers/cpufreq/cpufreq.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/cpufreq/cpufreq.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/cpufreq/cpufreq.c 2003-09-27 11:38:21.298290552 +0800
+@@ -1,17 +1,16 @@
+ /*
+- * linux/kernel/cpufreq.c
++ * linux/drivers/cpufreq/cpufreq.c
+ *
+ * Copyright (C) 2001 Russell King
+ * (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
+ *
+- * $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
+- *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
++#include <linux/config.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+@@ -743,26 +742,9 @@
+ EXPORT_SYMBOL(cpufreq_get_policy);
+
+
+-/**
+- * cpufreq_set_policy - set a new CPUFreq policy
+- * @policy: policy to be set.
+- *
+- * Sets a new CPU frequency and voltage scaling policy.
+- */
+-int cpufreq_set_policy(struct cpufreq_policy *policy)
++static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_policy *policy)
+ {
+ int ret = 0;
+- struct cpufreq_policy *data;
+-
+- if (!policy)
+- return -EINVAL;
+-
+- data = cpufreq_cpu_get(policy->cpu);
+- if (!data)
+- return -EINVAL;
+-
+- /* lock this CPU */
+- down(&data->lock);
+
+ memcpy(&policy->cpuinfo,
+ &data->cpuinfo,
+@@ -829,6 +811,36 @@
+ }
+
+ error_out:
++ return ret;
++}
++
++/**
++ * cpufreq_set_policy - set a new CPUFreq policy
++ * @policy: policy to be set.
++ *
++ * Sets a new CPU frequency and voltage scaling policy.
++ */
++int cpufreq_set_policy(struct cpufreq_policy *policy)
++{
++ int ret = 0;
++ struct cpufreq_policy *data;
++
++ if (!policy)
++ return -EINVAL;
++
++ data = cpufreq_cpu_get(policy->cpu);
++ if (!data)
++ return -EINVAL;
++
++ /* lock this CPU */
++ down(&data->lock);
++
++ ret = __cpufreq_set_policy(data, policy);
++ data->user_policy.min = data->min;
++ data->user_policy.max = data->max;
++ data->user_policy.policy = data->policy;
++ data->user_policy.governor = data->governor;
++
+ up(&data->lock);
+ cpufreq_cpu_put(data);
+
+@@ -837,6 +849,41 @@
+ EXPORT_SYMBOL(cpufreq_set_policy);
+
+
++/**
++ * cpufreq_update_policy - re-evaluate an existing cpufreq policy
++ * @cpu: CPU which shall be re-evaluated
++ *
++ * Usefull for policy notifiers which have different necessities
++ * at different times.
++ */
++int cpufreq_update_policy(unsigned int cpu)
++{
++ struct cpufreq_policy *data = cpufreq_cpu_get(cpu);
++ struct cpufreq_policy policy;
++ int ret = 0;
++
++ if (!data)
++ return -ENODEV;
++
++ down(&data->lock);
++
++ memcpy(&policy,
++ &data,
++ sizeof(struct cpufreq_policy));
++ policy.min = data->user_policy.min;
++ policy.max = data->user_policy.max;
++ policy.policy = data->user_policy.policy;
++ policy.governor = data->user_policy.governor;
++
++ ret = __cpufreq_set_policy(data, &policy);
++
++ up(&data->lock);
++
++ cpufreq_cpu_put(data);
++ return ret;
++}
++EXPORT_SYMBOL(cpufreq_update_policy);
++
+
+ /*********************************************************************
+ * EXTERNALLY AFFECTING FREQUENCY CHANGES *
+Index: linux-2.6.0-test5/drivers/cpufreq/cpufreq_userspace.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/cpufreq/cpufreq_userspace.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/cpufreq/cpufreq_userspace.c 2003-09-27 11:38:21.302289944 +0800
+@@ -1,17 +1,16 @@
+ /*
+- * drivers/cpufreq/userspace.c
++ * linux/drivers/cpufreq/cpufreq_userspace.c
+ *
+ * Copyright (C) 2001 Russell King
+ * (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
+ *
+- * $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
+- *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
++#include <linux/config.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/smp.h>
+Index: linux-2.6.0-test5/drivers/eisa/eisa-bus.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/eisa/eisa-bus.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/eisa/eisa-bus.c 2003-09-27 11:38:21.306289336 +0800
+@@ -427,6 +427,11 @@
+
+ postcore_initcall (eisa_init);
+
++#ifndef CONFIG_EISA_ALWAYS
++int EISA_bus;
++EXPORT_SYMBOL(EISA_bus);
++#endif
++
+ EXPORT_SYMBOL (eisa_bus_type);
+ EXPORT_SYMBOL (eisa_driver_register);
+ EXPORT_SYMBOL (eisa_driver_unregister);
+Index: linux-2.6.0-test5/drivers/ide/ide.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/ide/ide.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/ide/ide.c 2003-09-27 11:38:21.325286448 +0800
+@@ -1800,27 +1800,26 @@
+
+ #ifdef CONFIG_BLK_DEV_PDC4030
+ static int __initdata probe_pdc4030;
+-extern void init_pdc4030(void);
+ #endif
+ #ifdef CONFIG_BLK_DEV_ALI14XX
+ static int __initdata probe_ali14xx;
+-extern void init_ali14xx(void);
++extern int ali14xx_init(void);
+ #endif
+ #ifdef CONFIG_BLK_DEV_UMC8672
+ static int __initdata probe_umc8672;
+-extern void init_umc8672(void);
++extern int umc8672_init(void);
+ #endif
+ #ifdef CONFIG_BLK_DEV_DTC2278
+ static int __initdata probe_dtc2278;
+-extern void init_dtc2278(void);
++extern int dtc2278_init(void);
+ #endif
+ #ifdef CONFIG_BLK_DEV_HT6560B
+ static int __initdata probe_ht6560b;
+-extern void init_ht6560b(void);
++extern int ht6560b_init(void);
+ #endif
+ #ifdef CONFIG_BLK_DEV_QD65XX
+ static int __initdata probe_qd65xx;
+-extern void init_qd65xx(void);
++extern int qd65xx_init(void);
+ #endif
+
+ static int __initdata is_chipset_set[MAX_HWIFS];
+@@ -2238,8 +2237,9 @@
+ #endif /* CONFIG_BLK_DEV_CMD640 */
+ #ifdef CONFIG_BLK_DEV_PDC4030
+ {
+- extern int ide_probe_for_pdc4030(void);
+- (void) ide_probe_for_pdc4030();
++ extern int pdc4030_init(void);
++ if (probe_pdc4030)
++ (void)pdc4030_init();
+ }
+ #endif /* CONFIG_BLK_DEV_PDC4030 */
+ #ifdef CONFIG_BLK_DEV_IDE_PMAC
+@@ -2595,29 +2595,25 @@
+
+ init_ide_data();
+
+-#ifdef CONFIG_BLK_DEV_PDC4030
+- if (probe_pdc4030)
+- init_pdc4030();
+-#endif
+ #ifdef CONFIG_BLK_DEV_ALI14XX
+ if (probe_ali14xx)
+- init_ali14xx();
++ (void)ali14xx_init();
+ #endif
+ #ifdef CONFIG_BLK_DEV_UMC8672
+ if (probe_umc8672)
+- init_umc8672();
++ (void)umc8672_init();
+ #endif
+ #ifdef CONFIG_BLK_DEV_DTC2278
+ if (probe_dtc2278)
+- init_dtc2278();
++ (void)dtc2278_init();
+ #endif
+ #ifdef CONFIG_BLK_DEV_HT6560B
+ if (probe_ht6560b)
+- init_ht6560b();
++ (void)ht6560b_init();
+ #endif
+ #ifdef CONFIG_BLK_DEV_QD65XX
+ if (probe_qd65xx)
+- init_qd65xx();
++ (void)qd65xx_init();
+ #endif
+
+ initializing = 1;
+Index: linux-2.6.0-test5/drivers/ide/ide-cd.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/ide/ide-cd.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/ide/ide-cd.c 2003-09-27 11:38:21.351282496 +0800
+@@ -2365,7 +2365,7 @@
+
+ /* Now try to get the total cdrom capacity. */
+ stat = cdrom_get_last_written(cdi, (long *) &toc->capacity);
+- if (stat)
++ if (stat || !toc->capacity)
+ stat = cdrom_read_capacity(drive, &toc->capacity, sense);
+ if (stat)
+ toc->capacity = 0x1fffff;
+Index: linux-2.6.0-test5/drivers/ide/ide-default.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/ide/ide-default.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/ide/ide-default.c 2003-09-27 11:38:21.353282192 +0800
+@@ -57,6 +57,14 @@
+ "driver with ide.c\n", drive->name);
+ return 1;
+ }
++
++ /* For the sake of the request layer, we must make sure we have a
++ * correct ready_stat value, that is 0 for ATAPI devices or we will
++ * fail any request like Power Management
++ */
++ if (drive->media != ide_disk)
++ drive->ready_stat = 0;
++
+ return 0;
+ }
+
+Index: linux-2.6.0-test5/drivers/ide/ide-floppy.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/ide/ide-floppy.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/ide/ide-floppy.c 2003-09-27 11:38:21.370279608 +0800
+@@ -156,7 +156,6 @@
+ int request_transfer; /* Bytes to transfer */
+ int actually_transferred; /* Bytes actually transferred */
+ int buffer_size; /* Size of our data buffer */
+- char *b_data; /* Pointer which runs on the buffers */
+ int b_count; /* Missing/Available data on the current buffer */
+ struct request *rq; /* The corresponding request */
+ u8 *buffer; /* Data buffer */
+@@ -515,9 +514,6 @@
+ u8 reserved[4];
+ } idefloppy_mode_parameter_header_t;
+
+-#define IDEFLOPPY_MIN(a,b) ((a)<(b) ? (a):(b))
+-#define IDEFLOPPY_MAX(a,b) ((a)>(b) ? (a):(b))
+-
+ /*
+ * Too bad. The drive wants to send us data which we are not ready to accept.
+ * Just throw it away.
+@@ -575,28 +571,31 @@
+ static void idefloppy_input_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, unsigned int bcount)
+ {
+ struct request *rq = pc->rq;
++ struct bio_vec *bvec;
+ struct bio *bio = rq->bio;
+- int count;
++ unsigned long flags;
++ char *data;
++ int count, i;
++
++ rq_for_each_bio(bio, rq) {
++ bio_for_each_segment(bvec, bio, i) {
++ if (!bcount)
++ break;
++
++ count = min(bvec->bv_len, bcount);
++ data = bvec_kmap_irq(bvec, &flags);
++ atapi_input_bytes(drive, data, count);
++ bcount -= count;
++ pc->b_count += count;
++ bvec_kunmap_irq(data, &flags);
+
+- while (bcount) {
+- if (pc->b_count == bio->bi_size) {
+- rq->sector += rq->current_nr_sectors;
+- rq->nr_sectors -= rq->current_nr_sectors;
+- idefloppy_do_end_request(drive, 1, 0);
+- if ((bio = rq->bio) != NULL)
+- pc->b_count = 0;
+- }
+- if (bio == NULL) {
+- printk(KERN_ERR "%s: bio == NULL in "
+- "idefloppy_input_buffers, bcount == %d\n",
+- drive->name, bcount);
+- idefloppy_discard_data(drive, bcount);
+- return;
+- }
+- count = IDEFLOPPY_MIN(bio->bi_size - pc->b_count, bcount);
+- atapi_input_bytes(drive, bio_data(bio) + pc->b_count, count);
+- bcount -= count;
+- pc->b_count += count;
++ idefloppy_do_end_request(drive, 1, count >> 9);
++ }
++ }
++
++ if (bcount) {
++ printk(KERN_ERR "%s: bio == NULL in idefloppy_input_buffers, bcount == %d\n", drive->name, bcount);
++ idefloppy_discard_data(drive, bcount);
+ }
+ }
+
+@@ -604,30 +603,30 @@
+ {
+ struct request *rq = pc->rq;
+ struct bio *bio = rq->bio;
+- int count;
+-
+- while (bcount) {
+- if (!pc->b_count) {
+- rq->sector += rq->current_nr_sectors;
+- rq->nr_sectors -= rq->current_nr_sectors;
+- idefloppy_do_end_request(drive, 1, 0);
+- if ((bio = rq->bio) != NULL) {
+- pc->b_data = bio_data(bio);
+- pc->b_count = bio->bi_size;
+- }
++ struct bio_vec *bvec;
++ unsigned long flags;
++ int count, i;
++ char *data;
++
++ rq_for_each_bio(bio, rq) {
++ bio_for_each_segment(bvec, bio, i) {
++ if (!bcount)
++ break;
++
++ count = min(bvec->bv_len, bcount);
++ data = bvec_kmap_irq(bvec, &flags);
++ atapi_output_bytes(drive, data, count);
++ bcount -= count;
++ pc->b_count += count;
++ bvec_kunmap_irq(data, &flags);
++
++ idefloppy_do_end_request(drive, 1, count >> 9);
+ }
+- if (bio == NULL) {
+- printk(KERN_ERR "%s: bio == NULL in "
+- "idefloppy_output_buffers, bcount == %d\n",
+- drive->name, bcount);
+- idefloppy_write_zeros(drive, bcount);
+- return;
+- }
+- count = IDEFLOPPY_MIN(pc->b_count, bcount);
+- atapi_output_bytes(drive, pc->b_data, count);
+- bcount -= count;
+- pc->b_data += count;
+- pc->b_count -= count;
++ }
++
++ if (bio == NULL) {
++ printk(KERN_ERR "%s: bio == NULL in idefloppy_output_buffers, bcount == %d\n", drive->name, bcount);
++ idefloppy_write_zeros(drive, bcount);
+ }
+ }
+
+@@ -732,7 +731,6 @@
+ pc->request_transfer = 0;
+ pc->buffer = pc->pc_buffer;
+ pc->buffer_size = IDEFLOPPY_PC_BUFFER_SIZE;
+- pc->b_data = NULL;
+ // pc->bio = NULL;
+ pc->callback = &idefloppy_pc_callback;
+ }
+@@ -1199,7 +1197,6 @@
+ put_unaligned(htonl(block), (unsigned int *) &pc->c[2]);
+ pc->callback = &idefloppy_rw_callback;
+ pc->rq = rq;
+- pc->b_data = rq->buffer;
+ pc->b_count = cmd == READ ? 0 : rq->bio->bi_size;
+ if (rq->flags & REQ_RW)
+ set_bit(PC_WRITING, &pc->flags);
+Index: linux-2.6.0-test5/drivers/ide/ide-io.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/ide/ide-io.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/ide/ide-io.c 2003-09-27 11:38:21.381277936 +0800
+@@ -928,13 +928,10 @@
+ *
+ * We let requests forced at head of queue with ide-preempt
+ * though. I hope that doesn't happen too much, hopefully not
+- * unless the subdriver triggers such a thing in it's own PM
++ * unless the subdriver triggers such a thing in its own PM
+ * state machine.
+ */
+ if (drive->blocked && !blk_pm_request(rq) && !(rq->flags & REQ_PREEMPT)) {
+-#ifdef DEBUG_PM
+- printk("%s: a request made it's way while we are power managing...\n", drive->name);
+-#endif
+ /* We clear busy, there should be no pending ATA command at this point. */
+ hwgroup->busy = 0;
+ break;
+@@ -1417,8 +1414,9 @@
+ }
+
+ spin_lock_irqsave(&ide_lock, flags);
+- if (action == ide_preempt || action == ide_head_wait) {
++ if (action == ide_preempt)
+ hwgroup->rq = NULL;
++ if (action == ide_preempt || action == ide_head_wait) {
+ where = ELEVATOR_INSERT_FRONT;
+ rq->flags |= REQ_PREEMPT;
+ }
+Index: linux-2.6.0-test5/drivers/ide/ide-tcq.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/ide/ide-tcq.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/ide/ide-tcq.c 2003-09-27 11:38:21.386277176 +0800
+@@ -596,7 +596,7 @@
+ * enable block tagging
+ */
+ if (!blk_queue_tagged(drive->queue))
+- blk_queue_init_tags(drive->queue, IDE_MAX_TAG);
++ blk_queue_init_tags(drive->queue, IDE_MAX_TAG, NULL);
+
+ /*
+ * check auto-poll support
+Index: linux-2.6.0-test5/drivers/ide/legacy/ali14xx.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/ide/legacy/ali14xx.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/ide/legacy/ali14xx.c 2003-09-27 11:38:21.389276720 +0800
+@@ -198,22 +198,12 @@
+ return t;
+ }
+
+-int __init probe_ali14xx (void)
++static int __init ali14xx_probe(void)
+ {
+- /* auto-detect IDE controller port */
+- if (!findPort()) {
+- printk(KERN_ERR "ali14xx: not found.\n");
+- return 1;
+- }
++ ide_hwif_t *hwif, *mate;
+
+- printk(KERN_DEBUG "ali14xx: base= 0x%03x, regOn = 0x%02x.\n", basePort, regOn);
+- ide_hwifs[0].chipset = ide_ali14xx;
+- ide_hwifs[1].chipset = ide_ali14xx;
+- ide_hwifs[0].tuneproc = &ali14xx_tune_drive;
+- ide_hwifs[1].tuneproc = &ali14xx_tune_drive;
+- ide_hwifs[0].mate = &ide_hwifs[1];
+- ide_hwifs[1].mate = &ide_hwifs[0];
+- ide_hwifs[1].channel = 1;
++ printk(KERN_DEBUG "ali14xx: base=0x%03x, regOn=0x%02x.\n",
++ basePort, regOn);
+
+ /* initialize controller registers */
+ if (!initRegisters()) {
+@@ -221,74 +211,59 @@
+ return 1;
+ }
+
+- probe_hwif_init(&ide_hwifs[0]);
+- probe_hwif_init(&ide_hwifs[1]);
++ hwif = &ide_hwifs[0];
++ mate = &ide_hwifs[1];
+
+- return 0;
+-}
++ hwif->chipset = ide_ali14xx;
++ hwif->tuneproc = &ali14xx_tune_drive;
++ hwif->mate = mate;
++
++ mate->chipset = ide_ali14xx;
++ mate->tuneproc = &ali14xx_tune_drive;
++ mate->mate = hwif;
++ mate->channel = 1;
+
+-static void ali14xx_release (void)
+-{
+- if (ide_hwifs[0].chipset != ide_ali14xx &&
+- ide_hwifs[1].chipset != ide_ali14xx)
+- return;
++ probe_hwif_init(hwif);
++ probe_hwif_init(mate);
+
+- ide_hwifs[0].chipset = ide_unknown;
+- ide_hwifs[1].chipset = ide_unknown;
+- ide_hwifs[0].tuneproc = NULL;
+- ide_hwifs[1].tuneproc = NULL;
+- ide_hwifs[0].mate = NULL;
+- ide_hwifs[1].mate = NULL;
++ return 0;
+ }
+
+-#ifndef MODULE
+-/*
+- * init_ali14xx:
+- *
+- * called by ide.c when parsing command line
+- */
+-
+-void __init init_ali14xx (void)
++/* Can be called directly from ide.c. */
++int __init ali14xx_init(void)
+ {
+ /* auto-detect IDE controller port */
+- if (findPort())
+- if (probe_ali14xx())
+- goto no_detect;
+- return;
+-
+-no_detect:
++ if (findPort()) {
++ if (ali14xx_probe())
++ return -ENODEV;
++ return 0;
++ }
+ printk(KERN_ERR "ali14xx: not found.\n");
+- ali14xx_release();
++ return -ENODEV;
+ }
+
+-#else
+-
+-MODULE_AUTHOR("see local file");
+-MODULE_DESCRIPTION("support of ALI 14XX IDE chipsets");
+-MODULE_LICENSE("GPL");
+-
+-static int __init ali14xx_mod_init(void)
++#ifdef MODULE
++static void __exit ali14xx_release_hwif(ide_hwif_t *hwif)
+ {
+- /* auto-detect IDE controller port */
+- if (findPort())
+- if (probe_ali14xx()) {
+- ali14xx_release();
+- return -ENODEV;
+- }
++ if (hwif->chipset != ide_ali14xx)
++ return;
+
+- if (ide_hwifs[0].chipset != ide_ali14xx &&
+- ide_hwifs[1].chipset != ide_ali14xx) {
+- ali14xx_release();
+- return -ENODEV;
+- }
+- return 0;
++ hwif->chipset = ide_unknown;
++ hwif->tuneproc = NULL;
++ hwif->mate = NULL;
++ hwif->channel = 0;
+ }
+-module_init(ali14xx_mod_init);
+
+-static void __exit ali14xx_mod_exit(void)
++static void __exit ali14xx_exit(void)
+ {
+- ali14xx_release();
++ ali14xx_release_hwif(&ide_hwifs[0]);
++ ali14xx_release_hwif(&ide_hwifs[1]);
+ }
+-module_exit(ali14xx_mod_exit);
++
++module_init(ali14xx_init);
++module_exit(ali14xx_exit);
+ #endif
+
++MODULE_AUTHOR("see local file");
++MODULE_DESCRIPTION("support of ALI 14XX IDE chipsets");
++MODULE_LICENSE("GPL");
+Index: linux-2.6.0-test5/drivers/ide/legacy/dtc2278.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/ide/legacy/dtc2278.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/ide/legacy/dtc2278.c 2003-09-27 11:38:21.392276264 +0800
+@@ -95,9 +95,16 @@
+ HWIF(drive)->drives[!drive->select.b.unit].io_32bit = 1;
+ }
+
+-void __init probe_dtc2278 (void)
++static int __init probe_dtc2278(void)
+ {
+ unsigned long flags;
++ ide_hwif_t *hwif, *mate;
++
++ hwif = &ide_hwifs[0];
++ mate = &ide_hwifs[1];
++
++ if (hwif->chipset != ide_unknown || mate->chipset != ide_unknown)
++ return 1;
+
+ local_irq_save(flags);
+ /*
+@@ -117,76 +124,60 @@
+ #endif
+ local_irq_restore(flags);
+
+- ide_hwifs[0].serialized = 1;
+- ide_hwifs[1].serialized = 1;
+- ide_hwifs[0].chipset = ide_dtc2278;
+- ide_hwifs[1].chipset = ide_dtc2278;
+- ide_hwifs[0].tuneproc = &tune_dtc2278;
+- ide_hwifs[0].drives[0].no_unmask = 1;
+- ide_hwifs[0].drives[1].no_unmask = 1;
+- ide_hwifs[1].drives[0].no_unmask = 1;
+- ide_hwifs[1].drives[1].no_unmask = 1;
+- ide_hwifs[0].mate = &ide_hwifs[1];
+- ide_hwifs[1].mate = &ide_hwifs[0];
+- ide_hwifs[1].channel = 1;
++ hwif->serialized = 1;
++ hwif->chipset = ide_dtc2278;
++ hwif->tuneproc = &tune_dtc2278;
++ hwif->drives[0].no_unmask = 1;
++ hwif->drives[1].no_unmask = 1;
++ hwif->mate = mate;
++
++ mate->serialized = 1;
++ mate->chipset = ide_dtc2278;
++ mate->drives[0].no_unmask = 1;
++ mate->drives[1].no_unmask = 1;
++ mate->mate = hwif;
++ mate->channel = 1;
++
++ probe_hwif_init(hwif);
++ probe_hwif_init(mate);
+
+- probe_hwif_init(&ide_hwifs[0]);
+- probe_hwif_init(&ide_hwifs[1]);
++ return 0;
+ }
+
+-static void dtc2278_release (void)
++/* Can be called directly from ide.c. */
++int __init dtc2278_init(void)
+ {
+- if (ide_hwifs[0].chipset != ide_dtc2278 &&
+- ide_hwifs[1].chipset != ide_dtc2278)
++ if (probe_dtc2278()) {
++ printk(KERN_ERR "dtc2278: ide interfaces already in use!\n");
++ return -EBUSY;
++ }
++ return 0;
++}
++
++#ifdef MODULE
++static void __exit dtc2278_release_hwif(ide_hwif_t *hwif)
++{
++ if (hwif->chipset != ide_dtc2278)
+ return;
+
+- ide_hwifs[0].serialized = 0;
+- ide_hwifs[1].serialized = 0;
+- ide_hwifs[0].chipset = ide_unknown;
+- ide_hwifs[1].chipset = ide_unknown;
+- ide_hwifs[0].tuneproc = NULL;
+- ide_hwifs[0].drives[0].no_unmask = 0;
+- ide_hwifs[0].drives[1].no_unmask = 0;
+- ide_hwifs[1].drives[0].no_unmask = 0;
+- ide_hwifs[1].drives[1].no_unmask = 0;
+- ide_hwifs[0].mate = NULL;
+- ide_hwifs[1].mate = NULL;
++ hwif->serialized = 0;
++ hwif->chipset = ide_unknown;
++ hwif->tuneproc = NULL;
++ hwif->drives[0].no_unmask = 0;
++ hwif->drives[1].no_unmask = 0;
++ hwif->mate = NULL;
+ }
+
+-#ifndef MODULE
+-/*
+- * init_dtc2278:
+- *
+- * called by ide.c when parsing command line
+- */
+-
+-void __init init_dtc2278 (void)
++static void __exit dtc2278_exit(void)
+ {
+- probe_dtc2278();
++ dtc2278_release_hwif(&ide_hwifs[0]);
++ dtc2278_release_hwif(&ide_hwifs[1]);
+ }
+
+-#else
++module_init(dtc2278_init);
++module_exit(dtc2278_exit);
++#endif
+
+ MODULE_AUTHOR("See Local File");
+ MODULE_DESCRIPTION("support of DTC-2278 VLB IDE chipsets");
+ MODULE_LICENSE("GPL");
+-
+-static int __init dtc2278_mod_init(void)
+-{
+- probe_dtc2278();
+- if (ide_hwifs[0].chipset != ide_dtc2278 &&
+- ide_hwifs[1].chipset != ide_dtc2278) {
+- dtc2278_release();
+- return -ENODEV;
+- }
+- return 0;
+-}
+-module_init(dtc2278_mod_init);
+-
+-static void __exit dtc2278_mod_exit(void)
+-{
+- dtc2278_release();
+-}
+-module_exit(dtc2278_mod_exit);
+-#endif
+-
+Index: linux-2.6.0-test5/drivers/ide/legacy/ht6560b.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/ide/legacy/ht6560b.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/ide/legacy/ht6560b.c 2003-09-27 11:38:21.395275808 +0800
+@@ -304,35 +304,16 @@
+ #endif
+ }
+
+-void ht6560b_release (void)
+-{
+- if (ide_hwifs[0].chipset != ide_ht6560b &&
+- ide_hwifs[1].chipset != ide_ht6560b)
+- return;
+-
+- ide_hwifs[0].chipset = ide_unknown;
+- ide_hwifs[1].chipset = ide_unknown;
+- ide_hwifs[0].tuneproc = NULL;
+- ide_hwifs[1].tuneproc = NULL;
+- ide_hwifs[0].selectproc = NULL;
+- ide_hwifs[1].selectproc = NULL;
+- ide_hwifs[0].serialized = 0;
+- ide_hwifs[1].serialized = 0;
+- ide_hwifs[0].mate = NULL;
+- ide_hwifs[1].mate = NULL;
+-
+- ide_hwifs[0].drives[0].drive_data = 0;
+- ide_hwifs[0].drives[1].drive_data = 0;
+- ide_hwifs[1].drives[0].drive_data = 0;
+- ide_hwifs[1].drives[1].drive_data = 0;
+- release_region(HT_CONFIG_PORT, 1);
+-}
+-
+-static int __init ht6560b_mod_init(void)
++/* Can be called directly from ide.c. */
++int __init ht6560b_init(void)
+ {
++ ide_hwif_t *hwif, *mate;
+ int t;
+
+- if (!request_region(HT_CONFIG_PORT, 1, ide_hwifs[0].name)) {
++ hwif = &ide_hwifs[0];
++ mate = &ide_hwifs[1];
++
++ if (!request_region(HT_CONFIG_PORT, 1, hwif->name)) {
+ printk(KERN_NOTICE "%s: HT_CONFIG_PORT not found\n",
+ __FUNCTION__);
+ return -ENODEV;
+@@ -343,39 +324,33 @@
+ goto release_region;
+ }
+
+- ide_hwifs[0].chipset = ide_ht6560b;
+- ide_hwifs[1].chipset = ide_ht6560b;
+- ide_hwifs[0].selectproc = &ht6560b_selectproc;
+- ide_hwifs[1].selectproc = &ht6560b_selectproc;
+- ide_hwifs[0].tuneproc = &tune_ht6560b;
+- ide_hwifs[1].tuneproc = &tune_ht6560b;
+- ide_hwifs[0].serialized = 1; /* is this needed? */
+- ide_hwifs[1].serialized = 1; /* is this needed? */
+- ide_hwifs[0].mate = &ide_hwifs[1];
+- ide_hwifs[1].mate = &ide_hwifs[0];
+- ide_hwifs[1].channel = 1;
++ hwif->chipset = ide_ht6560b;
++ hwif->selectproc = &ht6560b_selectproc;
++ hwif->tuneproc = &tune_ht6560b;
++ hwif->serialized = 1; /* is this needed? */
++ hwif->mate = mate;
++
++ mate->chipset = ide_ht6560b;
++ mate->selectproc = &ht6560b_selectproc;
++ mate->tuneproc = &tune_ht6560b;
++ mate->serialized = 1; /* is this needed? */
++ mate->mate = hwif;
++ mate->channel = 1;
+
+ /*
+ * Setting default configurations for drives
+ */
+ t = (HT_CONFIG_DEFAULT << 8);
+ t |= HT_TIMING_DEFAULT;
+- ide_hwifs[0].drives[0].drive_data = t;
+- ide_hwifs[0].drives[1].drive_data = t;
+- t |= (HT_SECONDARY_IF << 8);
+- ide_hwifs[1].drives[0].drive_data = t;
+- ide_hwifs[1].drives[1].drive_data = t;
++ hwif->drives[0].drive_data = t;
++ hwif->drives[1].drive_data = t;
+
+- probe_hwif_init(&ide_hwifs[0]);
+- probe_hwif_init(&ide_hwifs[1]);
++ t |= (HT_SECONDARY_IF << 8);
++ mate->drives[0].drive_data = t;
++ mate->drives[1].drive_data = t;
+
+-#ifdef MODULE
+- if (ide_hwifs[0].chipset != ide_ht6560b &&
+- ide_hwifs[1].chipset != ide_ht6560b) {
+- ht6560b_release();
+- return -ENODEV;
+- }
+-#endif
++ probe_hwif_init(hwif);
++ probe_hwif_init(mate);
+
+ return 0;
+
+@@ -384,24 +359,34 @@
+ return -ENODEV;
+ }
+
+-MODULE_AUTHOR("See Local File");
+-MODULE_DESCRIPTION("HT-6560B EIDE-controller support");
+-MODULE_LICENSE("GPL");
+-
+ #ifdef MODULE
+-static void __exit ht6560b_mod_exit(void)
++static void __exit ht6560b_release_hwif(ide_hwif_t *hwif)
+ {
+- ht6560b_release();
++ if (hwif->chipset != ide_ht6560b)
++ return;
++
++ hwif->chipset = ide_unknown;
++ hwif->tuneproc = NULL;
++ hwif->selectproc = NULL;
++ hwif->serialized = 0;
++ hwif->mate = NULL;
++ hwif->channel = 0;
++
++ hwif->drives[0].drive_data = 0;
++ hwif->drives[1].drive_data = 0;
+ }
+
+-module_init(ht6560b_mod_init);
+-module_exit(ht6560b_mod_exit);
+-#else
+-/*
+- * called by ide.c when parsing command line
+- */
+-void __init init_ht6560b (void)
++static void __exit ht6560b_exit(void)
+ {
+- ht6560b_mod_init(); /* ignore return value */
++ ht6560b_release_hwif(&ide_hwifs[0]);
++ ht6560b_release_hwif(&ide_hwifs[1]);
++ release_region(HT_CONFIG_PORT, 1);
+ }
++
++module_init(ht6560b_init);
++module_exit(ht6560b_exit);
+ #endif
++
++MODULE_AUTHOR("See Local File");
++MODULE_DESCRIPTION("HT-6560B EIDE-controller support");
++MODULE_LICENSE("GPL");
+Index: linux-2.6.0-test5/drivers/ide/legacy/pdc4030.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/ide/legacy/pdc4030.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/ide/legacy/pdc4030.c 2003-09-27 11:38:21.403274592 +0800
+@@ -147,8 +147,6 @@
+ return pdc4030_cmd(drive, PROMISE_IDENTIFY);
+ }
+
+-int enable_promise_support;
+-
+ /*
+ * setup_pdc4030()
+ * Completes the setup of a Promise DC4030 controller card, once found.
+@@ -296,33 +294,28 @@
+ }
+ }
+
+-
+-int __init ide_probe_for_pdc4030(void)
++int __init pdc4030_init(void)
+ {
+ unsigned int index;
+ ide_hwif_t *hwif;
+
+-#ifndef MODULE
+- if (enable_promise_support == 0)
+- return;
+-#endif
+-
+ for (index = 0; index < MAX_HWIFS; index++) {
+ hwif = &ide_hwifs[index];
+ if (hwif->chipset == ide_unknown && detect_pdc4030(hwif)) {
+ #ifndef MODULE
+ setup_pdc4030(hwif);
+ #else
+- return setup_pdc4030(hwif);
++ if (!setup_pdc4030(hwif))
++ return -ENODEV;
++ return 0;
+ #endif
+ }
+ }
+-#ifdef MODULE
+- return 0;
+-#endif
++ return -ENODEV;
+ }
+
+-static void __exit release_pdc4030(ide_hwif_t *hwif, ide_hwif_t *mate)
++#ifdef MODULE
++static void __exit pdc4030_release_hwif(ide_hwif_t *hwif)
+ {
+ hwif->chipset = ide_unknown;
+ hwif->selectproc = NULL;
+@@ -333,72 +326,24 @@
+ hwif->drives[1].keep_settings = 0;
+ hwif->drives[0].noprobe = 0;
+ hwif->drives[1].noprobe = 0;
+-
+- if (mate != NULL) {
+- mate->chipset = ide_unknown;
+- mate->selectproc = NULL;
+- mate->serialized = 0;
+- mate->drives[0].io_32bit = 0;
+- mate->drives[1].io_32bit = 0;
+- mate->drives[0].keep_settings = 0;
+- mate->drives[1].keep_settings = 0;
+- mate->drives[0].noprobe = 0;
+- mate->drives[1].noprobe = 0;
+- }
+ }
+
+-#ifndef MODULE
+-/*
+- * init_pdc4030:
+- *
+- * called by ide.c when parsing command line
+- */
+-
+-void __init init_pdc4030(void)
++static void __exit pdc4030_exit(void)
+ {
+- enable_promise_support = 1;
++ unsigned int index;
++
++ for (index = 0; index < MAX_HWIFS; index++)
++ pdc4030_release_hwif(&ide_hwifs[index]);
+ }
+
+-#else
++module_init(pdc4030_init);
++module_exit(pdc4030_exit);
++#endif
+
+ MODULE_AUTHOR("Peter Denison");
+ MODULE_DESCRIPTION("Support of Promise 4030 VLB series IDE chipsets");
+ MODULE_LICENSE("GPL");
+
+-static int __init pdc4030_mod_init(void)
+-{
+- if (enable_promise_support == 0)
+- enable_promise_support = 1;
+-
+- if (!ide_probe_for_pdc4030())
+- return -ENODEV;
+- return 0;
+-}
+-module_init(pdc4030_mod_init);
+-
+-static void __exit pdc4030_mod_exit(void)
+-{
+- unsigned int index;
+- ide_hwif_t *hwif;
+-
+- if (enable_promise_support == 0)
+- return;
+-
+- for (index = 0; index < MAX_HWIFS; index++) {
+- hwif = &ide_hwifs[index];
+- if (hwif->chipset == ide_pdc4030) {
+- ide_hwif_t *mate = &ide_hwifs[hwif->index+1];
+- if (mate->chipset == ide_pdc4030)
+- release_pdc4030(hwif, mate);
+- else
+- release_pdc4030(hwif, NULL);
+- }
+- }
+- enable_promise_support = 0;
+-}
+-module_exit(pdc4030_mod_exit);
+-#endif
+-
+ /*
+ * promise_read_intr() is the handler for disk read/multread interrupts
+ */
+Index: linux-2.6.0-test5/drivers/ide/legacy/qd65xx.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/ide/legacy/qd65xx.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/ide/legacy/qd65xx.c 2003-09-27 11:38:21.407273984 +0800
+@@ -338,12 +338,12 @@
+ * called to setup an ata channel : adjusts attributes & links for tuning
+ */
+
+-void __init qd_setup (int unit, int base, int config, unsigned int data0, unsigned int data1, void (*tuneproc) (ide_drive_t *, u8 pio))
++static void __init qd_setup(ide_hwif_t *hwif, int base, int config,
++ unsigned int data0, unsigned int data1,
++ void (*tuneproc) (ide_drive_t *, u8 pio))
+ {
+- ide_hwif_t *hwif = &ide_hwifs[unit];
+-
+ hwif->chipset = ide_qd65xx;
+- hwif->channel = unit;
++ hwif->channel = hwif->index;
+ hwif->select_data = base;
+ hwif->config_data = config;
+ hwif->drives[0].drive_data = data0;
+@@ -354,19 +354,20 @@
+ probe_hwif_init(hwif);
+ }
+
++#ifdef MODULE
+ /*
+ * qd_unsetup:
+ *
+ * called to unsetup an ata channel : back to default values, unlinks tuning
+ */
+-static void __exit qd_unsetup (int unit)
++static void __exit qd_unsetup(ide_hwif_t *hwif)
+ {
+- ide_hwif_t *hwif = &ide_hwifs[unit];
+ u8 config = hwif->config_data;
+ int base = hwif->select_data;
+ void *tuneproc = (void *) hwif->tuneproc;
+
+- if (!(hwif->chipset == ide_qd65xx)) return;
++ if (hwif->chipset != ide_qd65xx)
++ return;
+
+ printk(KERN_NOTICE "%s: back to defaults\n", hwif->name);
+
+@@ -381,13 +382,14 @@
+ qd_write_reg(QD6580_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
+ qd_write_reg(QD6580_DEF_DATA2, QD_TIMREG(&hwif->drives[1]));
+ } else {
+- qd_write_reg(unit?QD6580_DEF_DATA2:QD6580_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
++ qd_write_reg(hwif->channel ? QD6580_DEF_DATA2 : QD6580_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
+ }
+ } else {
+ printk(KERN_WARNING "Unknown qd65xx tuning fonction !\n");
+ printk(KERN_WARNING "keeping settings !\n");
+ }
+ }
++#endif
+
+ /*
+ * qd_probe:
+@@ -396,8 +398,9 @@
+ * return 1 if another qd may be probed
+ */
+
+-int __init qd_probe (int base)
++static int __init qd_probe(int base)
+ {
++ ide_hwif_t *hwif;
+ u8 config;
+ u8 unit;
+
+@@ -414,9 +417,8 @@
+
+ /* qd6500 found */
+
+- printk(KERN_NOTICE "%s: qd6500 at %#x\n",
+- ide_hwifs[unit].name, base);
+-
++ hwif = &ide_hwifs[unit];
++ printk(KERN_NOTICE "%s: qd6500 at %#x\n", hwif->name, base);
+ printk(KERN_DEBUG "qd6500: config=%#x, ID3=%u\n",
+ config, QD_ID3);
+
+@@ -425,8 +427,8 @@
+ return 1;
+ }
+
+- qd_setup(unit, base, config, QD6500_DEF_DATA,
+- QD6500_DEF_DATA, &qd6500_tune_drive);
++ qd_setup(hwif, base, config, QD6500_DEF_DATA, QD6500_DEF_DATA,
++ &qd6500_tune_drive);
+ return 1;
+ }
+
+@@ -448,25 +450,31 @@
+
+ if (control & QD_CONTR_SEC_DISABLED) {
+ /* secondary disabled */
++
++ hwif = &ide_hwifs[unit];
+ printk(KERN_INFO "%s: qd6580: single IDE board\n",
+- ide_hwifs[unit].name);
+- qd_setup(unit, base, config | (control << 8),
+- QD6580_DEF_DATA, QD6580_DEF_DATA2,
+- &qd6580_tune_drive);
++ hwif->name);
++ qd_setup(hwif, base, config | (control << 8),
++ QD6580_DEF_DATA, QD6580_DEF_DATA2,
++ &qd6580_tune_drive);
+ qd_write_reg(QD_DEF_CONTR,QD_CONTROL_PORT);
+
+ return 1;
+ } else {
++ ide_hwif_t *mate;
++
++ hwif = &ide_hwifs[0];
++ mate = &ide_hwifs[1];
+ /* secondary enabled */
+ printk(KERN_INFO "%s&%s: qd6580: dual IDE board\n",
+- ide_hwifs[0].name,ide_hwifs[1].name);
++ hwif->name, mate->name);
+
+- qd_setup(0, base, config | (control << 8),
+- QD6580_DEF_DATA, QD6580_DEF_DATA,
+- &qd6580_tune_drive);
+- qd_setup(1, base, config | (control << 8),
+- QD6580_DEF_DATA2, QD6580_DEF_DATA2,
+- &qd6580_tune_drive);
++ qd_setup(hwif, base, config | (control << 8),
++ QD6580_DEF_DATA, QD6580_DEF_DATA,
++ &qd6580_tune_drive);
++ qd_setup(mate, base, config | (control << 8),
++ QD6580_DEF_DATA2, QD6580_DEF_DATA2,
++ &qd6580_tune_drive);
+ qd_write_reg(QD_DEF_CONTR,QD_CONTROL_PORT);
+
+ return 0; /* no other qd65xx possible */
+@@ -476,38 +484,28 @@
+ return 1;
+ }
+
+-#ifndef MODULE
+-/*
+- * init_qd65xx:
+- *
+- * called by ide.c when parsing command line
+- */
+-
+-void __init init_qd65xx (void)
+-{
+- if (qd_probe(0x30)) qd_probe(0xb0);
+-}
+-
+-#else
+-
+-MODULE_AUTHOR("Samuel Thibault");
+-MODULE_DESCRIPTION("support of qd65xx vlb ide chipset");
+-MODULE_LICENSE("GPL");
+-
+-static int __init qd65xx_mod_init(void)
++/* Can be called directly from ide.c. */
++int __init qd65xx_init(void)
+ {
+- if (qd_probe(0x30)) qd_probe(0xb0);
++ if (qd_probe(0x30))
++ qd_probe(0xb0);
+ if (ide_hwifs[0].chipset != ide_qd65xx &&
+ ide_hwifs[1].chipset != ide_qd65xx)
+ return -ENODEV;
+ return 0;
+ }
+-module_init(qd65xx_mod_init);
+
+-static void __exit qd65xx_mod_exit(void)
++#ifdef MODULE
++static void __exit qd65xx_exit(void)
+ {
+- qd_unsetup(0);
+- qd_unsetup(1);
++ qd_unsetup(&ide_hwifs[0]);
++ qd_unsetup(&ide_hwifs[1]);
+ }
+-module_exit(qd65xx_mod_exit);
++
++module_init(qd65xx_init);
++module_exit(qd65xx_exit);
+ #endif
++
++MODULE_AUTHOR("Samuel Thibault");
++MODULE_DESCRIPTION("support of qd65xx vlb ide chipset");
++MODULE_LICENSE("GPL");
+Index: linux-2.6.0-test5/drivers/ide/legacy/umc8672.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/ide/legacy/umc8672.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/ide/legacy/umc8672.c 2003-09-27 11:38:21.410273528 +0800
+@@ -124,16 +124,16 @@
+ spin_unlock_irqrestore(&ide_lock, flags);
+ }
+
+-int __init probe_umc8672 (void)
++static int __init umc8672_probe(void)
+ {
+ unsigned long flags;
++ ide_hwif_t *hwif, *mate;
+
+- local_irq_save(flags);
+ if (!request_region(0x108, 2, "umc8672")) {
+- local_irq_restore(flags);
+ printk(KERN_ERR "umc8672: ports 0x108-0x109 already in use.\n");
+ return 1;
+ }
++ local_irq_save(flags);
+ outb_p(0x5A,0x108); /* enable umc */
+ if (in_umc (0xd5) != 0xa0) {
+ local_irq_restore(flags);
+@@ -146,82 +146,62 @@
+ umc_set_speeds (current_speeds);
+ local_irq_restore(flags);
+
+- ide_hwifs[0].chipset = ide_umc8672;
+- ide_hwifs[1].chipset = ide_umc8672;
+- ide_hwifs[0].tuneproc = &tune_umc;
+- ide_hwifs[1].tuneproc = &tune_umc;
+- ide_hwifs[0].mate = &ide_hwifs[1];
+- ide_hwifs[1].mate = &ide_hwifs[0];
+- ide_hwifs[1].channel = 1;
++ hwif = &ide_hwifs[0];
++ mate = &ide_hwifs[1];
+
+- probe_hwif_init(&ide_hwifs[0]);
+- probe_hwif_init(&ide_hwifs[1]);
++ hwif->chipset = ide_umc8672;
++ hwif->tuneproc = &tune_umc;
++ hwif->mate = mate;
++
++ mate->chipset = ide_umc8672;
++ mate->tuneproc = &tune_umc;
++ mate->mate = hwif;
++ mate->channel = 1;
++
++ probe_hwif_init(hwif);
++ probe_hwif_init(mate);
+
+ return 0;
+ }
+
+-static void umc8672_release (void)
++/* Can be called directly from ide.c. */
++int __init umc8672_init(void)
+ {
+- unsigned long flags;
++ if (umc8672_probe())
++ return -ENODEV;
++ return 0;
++}
+
+- local_irq_save(flags);
+- if (ide_hwifs[0].chipset != ide_umc8672 &&
+- ide_hwifs[1].chipset != ide_umc8672) {
+- local_irq_restore(flags);
++#ifdef MODULE
++static void __exit umc8672_release_hwif(ide_hwif_t *hwif)
++{
++ if (hwif->chipset != ide_umc8672)
+ return;
+- }
+
+- ide_hwifs[0].chipset = ide_unknown;
+- ide_hwifs[1].chipset = ide_unknown;
+- ide_hwifs[0].tuneproc = NULL;
+- ide_hwifs[1].tuneproc = NULL;
+- ide_hwifs[0].mate = NULL;
+- ide_hwifs[1].mate = NULL;
+- ide_hwifs[0].channel = 0;
+- ide_hwifs[1].channel = 0;
+-
+- outb_p(0xa5,0x108); /* disable umc */
+-
+- release_region(0x108, 2);
+- local_irq_restore(flags);
++ hwif->chipset = ide_unknown;
++ hwif->tuneproc = NULL;
++ hwif->mate = NULL;
++ hwif->channel = 0;
+ }
+
+-#ifndef MODULE
+-/*
+- * init_umc8672:
+- *
+- * called by ide.c when parsing command line
+- */
+-
+-void __init init_umc8672 (void)
++static void __exit umc8672_exit(void)
+ {
+- if (probe_umc8672())
+- printk(KERN_ERR "init_umc8672: umc8672 controller not found.\n");
+-}
++ unsigned long flags;
+
+-#else
++ umc8672_release_hwif(&ide_hwifs[0]);
++ umc8672_release_hwif(&ide_hwifs[1]);
+
+-MODULE_AUTHOR("Wolfram Podien");
+-MODULE_DESCRIPTION("Support for UMC 8672 IDE chipset");
+-MODULE_LICENSE("GPL");
++ local_irq_save(flags);
++ outb_p(0xa5, 0x108); /* disable umc */
++ local_irq_restore(flags);
+
+-static int __init umc8672_mod_init(void)
+-{
+- if (probe_umc8672())
+- return -ENODEV;
+- if (ide_hwifs[0].chipset != ide_umc8672 &&
+- ide_hwifs[1].chipset != ide_umc8672) {
+- umc8672_release();
+- return -ENODEV;
+- }
+- return 0;
++ release_region(0x108, 2);
+ }
+-module_init(umc8672_mod_init);
+
+-static void __exit umc8672_mod_exit(void)
+-{
+- umc8672_release();
+-}
+-module_exit(umc8672_mod_exit);
++module_init(umc8672_init);
++module_exit(umc8672_exit);
+ #endif
+
++MODULE_AUTHOR("Wolfram Podien");
++MODULE_DESCRIPTION("Support for UMC 8672 IDE chipset");
++MODULE_LICENSE("GPL");
+Index: linux-2.6.0-test5/drivers/ieee1394/nodemgr.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/ieee1394/nodemgr.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/ieee1394/nodemgr.c 2003-09-27 11:38:21.424271400 +0800
+@@ -1744,8 +1744,7 @@
+
+ sprintf(hi->daemon_name, "knodemgrd_%d", host->id);
+
+- hi->pid = kernel_thread(nodemgr_host_thread, hi,
+- CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++ hi->pid = kernel_thread(nodemgr_host_thread, hi, CLONE_KERNEL);
+
+ if (hi->pid < 0) {
+ HPSB_ERR ("NodeMgr: failed to start %s thread for %s",
+Index: linux-2.6.0-test5/drivers/input/evdev.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/evdev.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/evdev.c 2003-09-27 11:38:21.428270792 +0800
+@@ -208,7 +208,7 @@
+ struct evdev *evdev = list->evdev;
+ struct input_dev *dev = evdev->handle.dev;
+ struct input_absinfo abs;
+- int i, t, u;
++ int i, t, u, v;
+
+ if (!evdev->exist) return -ENODEV;
+
+@@ -239,14 +239,12 @@
+ case EVIOCSKEYCODE:
+ if (get_user(t, ((int *) arg) + 0)) return -EFAULT;
+ if (t < 0 || t > dev->keycodemax || !dev->keycodesize) return -EINVAL;
++ if (get_user(v, ((int *) arg) + 1)) return -EFAULT;
+ u = INPUT_KEYCODE(dev, t);
+- if (get_user(INPUT_KEYCODE(dev, t), ((int *) arg) + 1)) return -EFAULT;
+-
+- for (i = 0; i < dev->keycodemax; i++)
+- if(INPUT_KEYCODE(dev, t) == u) break;
++ INPUT_KEYCODE(dev, t) = v;
++ for (i = 0; i < dev->keycodemax; i++) if (v == u) break;
+ if (i == dev->keycodemax) clear_bit(u, dev->keybit);
+- set_bit(INPUT_KEYCODE(dev, t), dev->keybit);
+-
++ set_bit(v, dev->keybit);
+ return 0;
+
+ case EVIOCSFF:
+Index: linux-2.6.0-test5/drivers/input/input.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/input.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/input.c 2003-09-27 11:38:21.434269880 +0800
+@@ -426,8 +426,10 @@
+ init_timer(&dev->timer);
+ dev->timer.data = (long) dev;
+ dev->timer.function = input_repeat_key;
+- dev->rep[REP_DELAY] = HZ/4;
+- dev->rep[REP_PERIOD] = HZ/33;
++ if (!dev->rep[REP_DELAY])
++ dev->rep[REP_DELAY] = HZ/4;
++ if (!dev->rep[REP_PERIOD])
++ dev->rep[REP_PERIOD] = HZ/33;
+
+ INIT_LIST_HEAD(&dev->h_list);
+ list_add_tail(&dev->node, &input_dev_list);
+@@ -676,20 +678,10 @@
+ return (count > cnt) ? cnt : count;
+ }
+
+-#endif
+-
+-struct class input_class = {
+- .name = "input",
+-};
+-
+-static int __init input_init(void)
++static int __init input_proc_init(void)
+ {
+ struct proc_dir_entry *entry;
+- int retval = -ENOMEM;
+-
+- class_register(&input_class);
+
+-#ifdef CONFIG_PROC_FS
+ proc_bus_input_dir = proc_mkdir("input", proc_bus);
+ if (proc_bus_input_dir == NULL)
+ return -ENOMEM;
+@@ -708,7 +700,22 @@
+ return -ENOMEM;
+ }
+ entry->owner = THIS_MODULE;
++ return 0;
++}
++#else /* !CONFIG_PROC_FS */
++static inline int input_proc_init(void) { return 0; }
+ #endif
++
++struct class input_class = {
++ .name = "input",
++};
++
++static int __init input_init(void)
++{
++ int retval = -ENOMEM;
++
++ class_register(&input_class);
++ input_proc_init();
+ retval = register_chrdev(INPUT_MAJOR, "input", &input_fops);
+ if (retval) {
+ printk(KERN_ERR "input: unable to register char major %d", INPUT_MAJOR);
+@@ -730,11 +737,10 @@
+
+ static void __exit input_exit(void)
+ {
+-#ifdef CONFIG_PROC_FS
+ remove_proc_entry("devices", proc_bus_input_dir);
+ remove_proc_entry("handlers", proc_bus_input_dir);
+ remove_proc_entry("input", proc_bus);
+-#endif
++
+ devfs_remove("input");
+ unregister_chrdev(INPUT_MAJOR, "input");
+ class_unregister(&input_class);
+Index: linux-2.6.0-test5/drivers/input/joydev.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/joydev.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/joydev.c 2003-09-27 11:38:21.438269272 +0800
+@@ -466,13 +466,43 @@
+
+ static struct input_device_id joydev_ids[] = {
+ {
+- .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
++ .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT |
++ INPUT_DEVICE_ID_MATCH_BUS,
++ .evbit = { BIT(EV_ABS) },
++ .absbit = { BIT(ABS_X) },
++ .id = { .bustype = BUS_GAMEPORT },
++ }, /* anything connected to a gameport is a fair game */
++ {
++ .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT |
++ INPUT_DEVICE_ID_MATCH_BUS,
++ .evbit = { BIT(EV_ABS) },
++ .absbit = { BIT(ABS_X) },
++ .id = { .bustype = BUS_AMIGA },
++ }, /* amiga joystick does not report any special buttons but luckily it is
++ the only device rporting absolute coordinates on Amiga bus */
++ {
++ .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT |
++ INPUT_DEVICE_ID_MATCH_KEYBIT,
+ .evbit = { BIT(EV_ABS) },
+ .absbit = { BIT(ABS_X) },
++ .keybit = { BIT(BTN_TRIGGER) },
++ }, /* most joysticks have either BTN_TRIGGER or BTN_A or both */
++ {
++ .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT |
++ INPUT_DEVICE_ID_MATCH_KEYBIT,
++ .evbit = { BIT(EV_ABS) },
++ .absbit = { BIT(ABS_X) },
++ .keybit = { BIT(BTN_A) },
+ },
+ {
+ .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
+ .evbit = { BIT(EV_ABS) },
++ .absbit = { BIT(ABS_RX), BIT(ABS_RY) },
++ }, /* magellan and some others report only MISC buttons but we can identify
++ them by using special axis auch as RX/RY, ABS_WHEEL or ABS_THROTTLE */
++ {
++ .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
++ .evbit = { BIT(EV_ABS) },
+ .absbit = { BIT(ABS_WHEEL) },
+ },
+ {
+Index: linux-2.6.0-test5/drivers/input/joystick/db9.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/joystick/db9.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/joystick/db9.c 2003-09-27 11:38:21.443268512 +0800
+@@ -55,7 +55,9 @@
+ #define DB9_MULTI_0802 0x08
+ #define DB9_MULTI_0802_2 0x09
+ #define DB9_CD32_PAD 0x0A
+-#define DB9_MAX_PAD 0x0B
++#define DB9_SATURN_DPP 0x0B
++#define DB9_SATURN_DPP_2 0x0C
++#define DB9_MAX_PAD 0x0D
+
+ #define DB9_UP 0x01
+ #define DB9_DOWN 0x02
+@@ -69,10 +71,7 @@
+ #define DB9_NORMAL 0x0a
+ #define DB9_NOSELECT 0x08
+
+-#define DB9_SATURN0 0x00
+-#define DB9_SATURN1 0x02
+-#define DB9_SATURN2 0x04
+-#define DB9_SATURN3 0x06
++#define DB9_MAX_DEVICES 2
+
+ #define DB9_GENESIS6_DELAY 14
+ #define DB9_REFRESH_TIME HZ/100
+@@ -82,7 +81,7 @@
+ static int db9_3[] __initdata = { -1, 0 };
+
+ struct db9 {
+- struct input_dev dev[2];
++ struct input_dev dev[DB9_MAX_DEVICES];
+ struct timer_list timer;
+ struct pardevice *pd;
+ int mode;
+@@ -96,12 +95,247 @@
+ static short db9_genesis_btn[] = { BTN_START, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_MODE };
+ static short db9_cd32_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_START };
+
+-static char db9_buttons[DB9_MAX_PAD] = { 0, 1, 2, 4, 0, 6, 8, 8, 1, 1, 7 };
++static char db9_buttons[DB9_MAX_PAD] = { 0, 1, 2, 4, 0, 6, 8, 9, 1, 1, 7, 9, 9 };
+ static short *db9_btn[DB9_MAX_PAD] = { NULL, db9_multi_btn, db9_multi_btn, db9_genesis_btn, NULL, db9_genesis_btn,
+- db9_genesis_btn, db9_cd32_btn, db9_multi_btn, db9_multi_btn, db9_cd32_btn };
++ db9_genesis_btn, db9_cd32_btn, db9_multi_btn, db9_multi_btn, db9_cd32_btn,
++ db9_cd32_btn, db9_cd32_btn };
+ static char *db9_name[DB9_MAX_PAD] = { NULL, "Multisystem joystick", "Multisystem joystick (2 fire)", "Genesis pad",
+ NULL, "Genesis 5 pad", "Genesis 6 pad", "Saturn pad", "Multisystem (0.8.0.2) joystick",
+- "Multisystem (0.8.0.2-dual) joystick", "Amiga CD-32 pad" };
++ "Multisystem (0.8.0.2-dual) joystick", "Amiga CD-32 pad", "Saturn dpp", "Saturn dpp dual" };
++
++static const int db9_max_pads[DB9_MAX_PAD] = { 0, 1, 1, 1, 0, 1, 1, 6, 1, 2, 1, 6, 12 };
++static const int db9_num_axis[DB9_MAX_PAD] = { 0, 2, 2, 2, 0, 2, 2, 7, 2, 2, 2 ,7, 7 };
++static const short db9_abs[] = { ABS_X, ABS_Y, ABS_RX, ABS_RY, ABS_RZ, ABS_Z, ABS_HAT0X, ABS_HAT0Y, ABS_HAT1X, ABS_HAT1Y };
++static const int db9_bidirectional[DB9_MAX_PAD] = { 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0 };
++static const int db9_reverse[DB9_MAX_PAD] = { 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0 };
++
++/*
++ * Saturn controllers
++ */
++#define DB9_SATURN_DELAY 300
++static const int db9_saturn_byte[] = { 1, 1, 1, 2, 2, 2, 2, 2, 1 };
++static const unsigned char db9_saturn_mask[] = { 0x04, 0x01, 0x02, 0x40, 0x20, 0x10, 0x08, 0x80, 0x08 };
++
++/*
++ * db9_saturn_write_sub() writes 2 bit data.
++ */
++static void db9_saturn_write_sub(struct parport *port, int type, unsigned char data, int powered, int pwr_sub)
++{
++ unsigned char c;
++
++ switch (type) {
++ case 1: /* DPP1 */
++ c = 0x80 | 0x30 | (powered ? 0x08 : 0) | (pwr_sub ? 0x04 : 0) | data;
++ parport_write_data(port, c);
++ break;
++ case 2: /* DPP2 */
++ c = 0x40 | data << 4 | (powered ? 0x08 : 0) | (pwr_sub ? 0x04 : 0) | 0x03;
++ parport_write_data(port, c);
++ break;
++ case 0: /* DB9 */
++ c = ((((data & 2) ? 2 : 0) | ((data & 1) ? 4 : 0)) ^ 0x02) | !powered;
++ parport_write_control(port, c);
++ break;
++ }
++}
++
++/*
++ * gc_saturn_read_sub() reads 4 bit data.
++ */
++static unsigned char db9_saturn_read_sub(struct parport *port, int type)
++{
++ unsigned char data;
++
++ if (type) {
++ /* DPP */
++ data = parport_read_status(port) ^ 0x80;
++ return (data & 0x80 ? 1 : 0) | (data & 0x40 ? 2 : 0)
++ | (data & 0x20 ? 4 : 0) | (data & 0x10 ? 8 : 0);
++ } else {
++ /* DB9 */
++ data = parport_read_data(port) & 0x0f;
++ return (data & 0x8 ? 1 : 0) | (data & 0x4 ? 2 : 0)
++ | (data & 0x2 ? 4 : 0) | (data & 0x1 ? 8 : 0);
++ }
++}
++
++/*
++ * db9_saturn_read_analog() sends clock and reads 8 bit data.
++ */
++static unsigned char db9_saturn_read_analog(struct parport *port, int type, int powered)
++{
++ unsigned char data;
++
++ db9_saturn_write_sub(port, type, 0, powered, 0);
++ udelay(DB9_SATURN_DELAY);
++ data = db9_saturn_read_sub(port, type) << 4;
++ db9_saturn_write_sub(port, type, 2, powered, 0);
++ udelay(DB9_SATURN_DELAY);
++ data |= db9_saturn_read_sub(port, type);
++ return data;
++}
++
++/*
++ * db9_saturn_read_packet() reads whole saturn packet at connector
++ * and returns device identifier code.
++ */
++static unsigned char db9_saturn_read_packet(struct parport *port, unsigned char *data, int type, int powered)
++{
++ int i, j;
++ unsigned char tmp;
++
++ db9_saturn_write_sub(port, type, 3, powered, 0);
++ data[0] = db9_saturn_read_sub(port, type);
++ switch (data[0] & 0x0f) {
++ case 0xf:
++ /* 1111 no pad */
++ return data[0] = 0xff;
++ case 0x4: case 0x4 | 0x8:
++ /* ?100 : digital controller */
++ db9_saturn_write_sub(port, type, 0, powered, 1);
++ data[2] = db9_saturn_read_sub(port, type) << 4;
++ db9_saturn_write_sub(port, type, 2, powered, 1);
++ data[1] = db9_saturn_read_sub(port, type) << 4;
++ db9_saturn_write_sub(port, type, 1, powered, 1);
++ data[1] |= db9_saturn_read_sub(port, type);
++ db9_saturn_write_sub(port, type, 3, powered, 1);
++ /* data[2] |= db9_saturn_read_sub(port, type); */
++ data[2] |= data[0];
++ return data[0] = 0x02;
++ case 0x1:
++ /* 0001 : analog controller or multitap */
++ db9_saturn_write_sub(port, type, 2, powered, 0);
++ udelay(DB9_SATURN_DELAY);
++ data[0] = db9_saturn_read_analog(port, type, powered);
++ if (data[0] != 0x41) {
++ /* read analog controller */
++ for (i = 0; i < (data[0] & 0x0f); i++)
++ data[i + 1] = db9_saturn_read_analog(port, type, powered);
++ db9_saturn_write_sub(port, type, 3, powered, 0);
++ return data[0];
++ } else {
++ /* read multitap */
++ if (db9_saturn_read_analog(port, type, powered) != 0x60)
++ return data[0] = 0xff;
++ for (i = 0; i < 60; i += 10) {
++ data[i] = db9_saturn_read_analog(port, type, powered);
++ if (data[i] != 0xff)
++ /* read each pad */
++ for (j = 0; j < (data[i] & 0x0f); j++)
++ data[i + j + 1] = db9_saturn_read_analog(port, type, powered);
++ }
++ db9_saturn_write_sub(port, type, 3, powered, 0);
++ return 0x41;
++ }
++ case 0x0:
++ /* 0000 : mouse */
++ db9_saturn_write_sub(port, type, 2, powered, 0);
++ udelay(DB9_SATURN_DELAY);
++ tmp = db9_saturn_read_analog(port, type, powered);
++ if (tmp == 0xff) {
++ for (i = 0; i < 3; i++)
++ data[i + 1] = db9_saturn_read_analog(port, type, powered);
++ db9_saturn_write_sub(port, type, 3, powered, 0);
++ return data[0] = 0xe3;
++ }
++ default:
++ return data[0];
++ }
++}
++
++/*
++ * db9_saturn_report() analyzes packet and reports.
++ */
++static int db9_saturn_report(unsigned char id, unsigned char data[60], struct input_dev *dev, int n, int max_pads)
++{
++ int tmp, i, j;
++
++ tmp = (id == 0x41) ? 60 : 10;
++ for (j = 0; (j < tmp) && (n < max_pads); j += 10, n++) {
++ switch (data[j]) {
++ case 0x16: /* multi controller (analog 4 axis) */
++ input_report_abs(dev + n, db9_abs[5], data[j + 6]);
++ case 0x15: /* mission stick (analog 3 axis) */
++ input_report_abs(dev + n, db9_abs[3], data[j + 4]);
++ input_report_abs(dev + n, db9_abs[4], data[j + 5]);
++ case 0x13: /* racing controller (analog 1 axis) */
++ input_report_abs(dev + n, db9_abs[2], data[j + 3]);
++ case 0x34: /* saturn keyboard (udlr ZXC ASD QE Esc) */
++ case 0x02: /* digital pad (digital 2 axis + buttons) */
++ input_report_abs(dev + n, db9_abs[0], !(data[j + 1] & 128) - !(data[j + 1] & 64));
++ input_report_abs(dev + n, db9_abs[1], !(data[j + 1] & 32) - !(data[j + 1] & 16));
++ for (i = 0; i < 9; i++)
++ input_report_key(dev + n, db9_cd32_btn[i], ~data[j + db9_saturn_byte[i]] & db9_saturn_mask[i]);
++ break;
++ case 0x19: /* mission stick x2 (analog 6 axis + buttons) */
++ input_report_abs(dev + n, db9_abs[0], !(data[j + 1] & 128) - !(data[j + 1] & 64));
++ input_report_abs(dev + n, db9_abs[1], !(data[j + 1] & 32) - !(data[j + 1] & 16));
++ for (i = 0; i < 9; i++)
++ input_report_key(dev + n, db9_cd32_btn[i], ~data[j + db9_saturn_byte[i]] & db9_saturn_mask[i]);
++ input_report_abs(dev + n, db9_abs[2], data[j + 3]);
++ input_report_abs(dev + n, db9_abs[3], data[j + 4]);
++ input_report_abs(dev + n, db9_abs[4], data[j + 5]);
++ /*
++ input_report_abs(dev + n, db9_abs[8], (data[j + 6] & 128 ? 0 : 1) - (data[j + 6] & 64 ? 0 : 1));
++ input_report_abs(dev + n, db9_abs[9], (data[j + 6] & 32 ? 0 : 1) - (data[j + 6] & 16 ? 0 : 1));
++ */
++ input_report_abs(dev + n, db9_abs[6], data[j + 7]);
++ input_report_abs(dev + n, db9_abs[7], data[j + 8]);
++ input_report_abs(dev + n, db9_abs[5], data[j + 9]);
++ break;
++ case 0xd3: /* sankyo ff (analog 1 axis + stop btn) */
++ input_report_key(dev + n, BTN_A, data[j + 3] & 0x80);
++ input_report_abs(dev + n, db9_abs[2], data[j + 3] & 0x7f);
++ break;
++ case 0xe3: /* shuttle mouse (analog 2 axis + buttons. signed value) */
++ input_report_key(dev + n, BTN_START, data[j + 1] & 0x08);
++ input_report_key(dev + n, BTN_A, data[j + 1] & 0x04);
++ input_report_key(dev + n, BTN_C, data[j + 1] & 0x02);
++ input_report_key(dev + n, BTN_B, data[j + 1] & 0x01);
++ input_report_abs(dev + n, db9_abs[2], data[j + 2] ^ 0x80);
++ input_report_abs(dev + n, db9_abs[3], (0xff-(data[j + 3] ^ 0x80))+1); /* */
++ break;
++ case 0xff:
++ default: /* no pad */
++ input_report_abs(dev + n, db9_abs[0], 0);
++ input_report_abs(dev + n, db9_abs[1], 0);
++ for (i = 0; i < 9; i++)
++ input_report_key(dev + n, db9_cd32_btn[i], 0);
++ break;
++ }
++ }
++ return n;
++}
++
++static int db9_saturn(int mode, struct parport *port, struct input_dev *dev)
++{
++ unsigned char id, data[60];
++ int type, n, max_pads;
++ int tmp, i;
++
++ switch (mode) {
++ case DB9_SATURN_PAD:
++ type = 0;
++ n = 1;
++ break;
++ case DB9_SATURN_DPP:
++ type = 1;
++ n = 1;
++ break;
++ case DB9_SATURN_DPP_2:
++ type = 1;
++ n = 2;
++ break;
++ default:
++ return -1;
++ }
++ max_pads = min(db9_max_pads[mode], DB9_MAX_DEVICES);
++ for (tmp = 0, i = 0; i < n; i++) {
++ id = db9_saturn_read_packet(port, data, type + i, 1);
++ tmp = db9_saturn_report(id, data, dev, tmp, max_pads);
++ }
++ return 0;
++}
+
+ static void db9_timer(unsigned long private)
+ {
+@@ -222,28 +456,10 @@
+ break;
+
+ case DB9_SATURN_PAD:
++ case DB9_SATURN_DPP:
++ case DB9_SATURN_DPP_2:
+
+- parport_write_control(port, DB9_SATURN0);
+- data = parport_read_data(port);
+-
+- input_report_key(dev, BTN_Y, ~data & DB9_LEFT);
+- input_report_key(dev, BTN_Z, ~data & DB9_DOWN);
+- input_report_key(dev, BTN_TL, ~data & DB9_UP);
+- input_report_key(dev, BTN_TR, ~data & DB9_RIGHT);
+-
+- parport_write_control(port, DB9_SATURN2);
+- data = parport_read_data(port);
+-
+- input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
+- input_report_abs(dev, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1));
+-
+- parport_write_control(port, DB9_NORMAL);
+- data = parport_read_data(port);
+-
+- input_report_key(dev, BTN_A, ~data & DB9_LEFT);
+- input_report_key(dev, BTN_B, ~data & DB9_UP);
+- input_report_key(dev, BTN_C, ~data & DB9_DOWN);
+- input_report_key(dev, BTN_X, ~data & DB9_RIGHT);
++ db9_saturn(db9->mode, port, dev);
+ break;
+
+ case DB9_CD32_PAD:
+@@ -279,8 +495,10 @@
+ if (!db9->used++) {
+ parport_claim(db9->pd);
+ parport_write_data(port, 0xff);
+- parport_data_reverse(port);
+- parport_write_control(port, DB9_NORMAL);
++ if (db9_reverse[db9->mode]) {
++ parport_data_reverse(port);
++ parport_write_control(port, DB9_NORMAL);
++ }
+ mod_timer(&db9->timer, jiffies + DB9_REFRESH_TIME);
+ }
+
+@@ -321,11 +539,13 @@
+ return NULL;
+ }
+
+- if (!(pp->modes & PARPORT_MODE_TRISTATE) && config[1] != DB9_MULTI_0802) {
+- printk(KERN_ERR "db9.c: specified parport is not bidirectional\n");
+- return NULL;
++ if (db9_bidirectional[config[1]]) {
++ if (!(pp->modes & PARPORT_MODE_TRISTATE)) {
++ printk(KERN_ERR "db9.c: specified parport is not bidirectional\n");
++ return NULL;
++ }
+ }
+-
++
+ if (!(db9 = kmalloc(sizeof(struct db9), GFP_KERNEL)))
+ return NULL;
+ memset(db9, 0, sizeof(struct db9));
+@@ -343,7 +563,7 @@
+ return NULL;
+ }
+
+- for (i = 0; i < 1 + (db9->mode == DB9_MULTI_0802_2); i++) {
++ for (i = 0; i < (min(db9_max_pads[db9->mode], DB9_MAX_DEVICES)); i++) {
+
+ sprintf(db9->phys[i], "%s/input%d", db9->pd->port->name, i);
+
+@@ -359,14 +579,19 @@
+ db9->dev[i].id.version = 0x0100;
+
+ db9->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+- db9->dev[i].absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
+-
+ for (j = 0; j < db9_buttons[db9->mode]; j++)
+ set_bit(db9_btn[db9->mode][j], db9->dev[i].keybit);
+-
+- db9->dev[i].absmin[ABS_X] = -1; db9->dev[i].absmax[ABS_X] = 1;
+- db9->dev[i].absmin[ABS_Y] = -1; db9->dev[i].absmax[ABS_Y] = 1;
+-
++ for (j = 0; j < db9_num_axis[db9->mode]; j++) {
++ set_bit(db9_abs[j], db9->dev[i].absbit);
++ if (j < 2) {
++ db9->dev[i].absmin[db9_abs[j]] = -1;
++ db9->dev[i].absmax[db9_abs[j]] = 1;
++ } else {
++ db9->dev[i].absmin[db9_abs[j]] = 1;
++ db9->dev[i].absmax[db9_abs[j]] = 255;
++ db9->dev[i].absflat[db9_abs[j]] = 0;
++ }
++ }
+ input_register_device(db9->dev + i);
+ printk(KERN_INFO "input: %s on %s\n", db9->dev[i].name, db9->pd->port->name);
+ }
+@@ -419,7 +644,7 @@
+
+ for (i = 0; i < 3; i++)
+ if (db9_base[i]) {
+- for (j = 0; j < 1 + (db9_base[i]->mode == DB9_MULTI_0802_2); j++)
++ for (j = 0; j < min(db9_max_pads[db9_base[i]->mode], DB9_MAX_DEVICES); j++)
+ input_unregister_device(db9_base[i]->dev + j);
+ parport_unregister_device(db9_base[i]->pd);
+ }
+Index: linux-2.6.0-test5/drivers/input/joystick/iforce/iforce-packets.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/joystick/iforce/iforce-packets.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/joystick/iforce/iforce-packets.c 2003-09-27 11:38:21.447267904 +0800
+@@ -166,8 +166,7 @@
+ iforce->expect_packet = 0;
+ iforce->ecmd = cmd;
+ memcpy(iforce->edata, data, IFORCE_MAX_LENGTH);
+- if (waitqueue_active(&iforce->wait))
+- wake_up(&iforce->wait);
++ wake_up(&iforce->wait);
+ }
+ #endif
+
+@@ -264,7 +263,7 @@
+ set_current_state(TASK_INTERRUPTIBLE);
+ add_wait_queue(&iforce->wait, &wait);
+
+- if (usb_submit_urb(iforce->ctrl, GFP_KERNEL)) {
++ if (usb_submit_urb(iforce->ctrl, GFP_ATOMIC)) {
+ set_current_state(TASK_RUNNING);
+ remove_wait_queue(&iforce->wait, &wait);
+ return -1;
+Index: linux-2.6.0-test5/drivers/input/joystick/iforce/iforce-usb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/joystick/iforce/iforce-usb.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/joystick/iforce/iforce-usb.c 2003-09-27 11:38:21.449267600 +0800
+@@ -116,8 +116,7 @@
+
+ iforce_usb_xmit(iforce);
+
+- if (waitqueue_active(&iforce->wait))
+- wake_up(&iforce->wait);
++ wake_up(&iforce->wait);
+ }
+
+ static void iforce_usb_ctrl(struct urb *urb, struct pt_regs *regs)
+@@ -125,8 +124,7 @@
+ struct iforce *iforce = urb->context;
+ if (urb->status) return;
+ iforce->ecmd = 0xff00 | urb->actual_length;
+- if (waitqueue_active(&iforce->wait))
+- wake_up(&iforce->wait);
++ wake_up(&iforce->wait);
+ }
+
+ static int iforce_usb_probe(struct usb_interface *intf,
+Index: linux-2.6.0-test5/drivers/input/joystick/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/joystick/Kconfig 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/joystick/Kconfig 2003-09-27 11:38:21.454266840 +0800
+@@ -155,7 +155,8 @@
+
+ config JOYSTICK_WARRIOR
+ tristate "Logitech WingMan Warrior joystick"
+- depends on INPUT && INPUT_JOYSTICK && SERIO
++ depends on INPUT && INPUT_JOYSTICK
++ select SERIO
+ help
+ Say Y here if you have a Logitech WingMan Warrior joystick connected
+ to your computer's serial port.
+@@ -167,7 +168,8 @@
+
+ config JOYSTICK_MAGELLAN
+ tristate "LogiCad3d Magellan/SpaceMouse 6dof controllers"
+- depends on INPUT && INPUT_JOYSTICK && SERIO
++ depends on INPUT && INPUT_JOYSTICK
++ select SERIO
+ help
+ Say Y here if you have a Magellan or Space Mouse 6DOF controller
+ connected to your computer's serial port.
+@@ -179,7 +181,8 @@
+
+ config JOYSTICK_SPACEORB
+ tristate "SpaceTec SpaceOrb/Avenger 6dof controllers"
+- depends on INPUT && INPUT_JOYSTICK && SERIO
++ depends on INPUT && INPUT_JOYSTICK
++ select SERIO
+ help
+ Say Y here if you have a SpaceOrb 360 or SpaceBall Avenger 6DOF
+ controller connected to your computer's serial port.
+@@ -191,7 +194,8 @@
+
+ config JOYSTICK_SPACEBALL
+ tristate "SpaceTec SpaceBall 6dof controllers"
+- depends on INPUT && INPUT_JOYSTICK && SERIO
++ depends on INPUT && INPUT_JOYSTICK
++ select SERIO
+ help
+ Say Y here if you have a SpaceTec SpaceBall 2003/3003/4000 FLX
+ controller connected to your computer's serial port. For the
+@@ -204,7 +208,8 @@
+
+ config JOYSTICK_STINGER
+ tristate "Gravis Stinger gamepad"
+- depends on INPUT && INPUT_JOYSTICK && SERIO
++ depends on INPUT && INPUT_JOYSTICK
++ select SERIO
+ help
+ Say Y here if you have a Gravis Stinger connected to one of your
+ serial ports.
+@@ -216,7 +221,8 @@
+
+ config JOYSTICK_TWIDDLER
+ tristate "Twiddler as a joystick"
+- depends on INPUT && INPUT_JOYSTICK && SERIO
++ depends on INPUT && INPUT_JOYSTICK
++ select SERIO
+ help
+ Say Y here if you have a Handykey Twiddler connected to your
+ computer's serial port and want to use it as a joystick.
+Index: linux-2.6.0-test5/drivers/input/keyboard/atkbd.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/keyboard/atkbd.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/keyboard/atkbd.c 2003-09-27 11:38:21.459266080 +0800
+@@ -18,6 +18,7 @@
+ #include <linux/input.h>
+ #include <linux/serio.h>
+ #include <linux/workqueue.h>
++#include <linux/timer.h>
+
+ MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
+ MODULE_DESCRIPTION("AT and PS/2 keyboard driver");
+@@ -34,14 +35,14 @@
+
+ /*
+ * Scancode to keycode tables. These are just the default setting, and
+- * are loadable via an userland utility.
++ * are loadable via a userland utility.
+ */
+
+ static unsigned char atkbd_set2_keycode[512] = {
+ 0, 67, 65, 63, 61, 59, 60, 88, 0, 68, 66, 64, 62, 15, 41, 85,
+ 0, 56, 42,182, 29, 16, 2, 89, 0, 0, 44, 31, 30, 17, 3, 90,
+- 0, 46, 45, 32, 18, 5, 4, 91, 0, 57, 47, 33, 20, 19, 6, 0,
+- 0, 49, 48, 35, 34, 21, 7, 0, 0, 0, 50, 36, 22, 8, 9, 0,
++ 0, 46, 45, 32, 18, 5, 4, 91, 90, 57, 47, 33, 20, 19, 6, 0,
++ 91, 49, 48, 35, 34, 21, 7, 0, 0, 0, 50, 36, 22, 8, 9, 0,
+ 0, 51, 37, 23, 24, 11, 10, 0, 0, 52, 53, 38, 39, 25, 12, 0,
+ 122, 89, 40,120, 26, 13, 0, 0, 58, 54, 28, 27, 0, 43, 0, 0,
+ 85, 86, 90, 91, 92, 93, 14, 94, 95, 79,183, 75, 71,121, 0,123,
+@@ -70,7 +71,7 @@
+ 134, 46, 45, 32, 18, 5, 4, 63,135, 57, 47, 33, 20, 19, 6, 64,
+ 136, 49, 48, 35, 34, 21, 7, 65,137,100, 50, 36, 22, 8, 9, 66,
+ 125, 51, 37, 23, 24, 11, 10, 67,126, 52, 53, 38, 39, 25, 12, 68,
+- 113,114, 40, 84, 26, 13, 87, 99,100, 54, 28, 27, 43, 84, 88, 70,
++ 113,114, 40, 84, 26, 13, 87, 99, 97, 54, 28, 27, 43, 84, 88, 70,
+ 108,105,119,103,111,107, 14,110, 0, 79,106, 75, 71,109,102,104,
+ 82, 83, 80, 76, 77, 72, 69, 98, 0, 96, 81, 0, 78, 73, 55, 85,
+ 89, 90, 91, 92, 74,185,184,182, 0, 0, 0,125,126,127,112, 0,
+@@ -87,10 +88,10 @@
+ #define ATKBD_CMD_GSCANSET 0x11f0
+ #define ATKBD_CMD_SSCANSET 0x10f0
+ #define ATKBD_CMD_GETID 0x02f2
++#define ATKBD_CMD_SETREP 0x10f3
+ #define ATKBD_CMD_ENABLE 0x00f4
+ #define ATKBD_CMD_RESET_DIS 0x00f5
+ #define ATKBD_CMD_RESET_BAT 0x02ff
+-#define ATKBD_CMD_SETALL_MB 0x00f8
+ #define ATKBD_CMD_RESEND 0x00fe
+ #define ATKBD_CMD_EX_ENABLE 0x10ea
+ #define ATKBD_CMD_EX_SETLEDS 0x20eb
+@@ -114,23 +115,25 @@
+ unsigned char keycode[512];
+ struct input_dev dev;
+ struct serio *serio;
++ struct timer_list timer;
+ char name[64];
+ char phys[32];
+ unsigned char cmdbuf[4];
+ unsigned char cmdcnt;
+ unsigned char set;
+ unsigned char release;
++ int lastkey;
+ volatile signed char ack;
+ unsigned char emul;
+ unsigned short id;
+ unsigned char write;
+- unsigned char resend;
+ };
+
+ /*
+ * atkbd_interrupt(). Here takes place processing of data received from
+ * the keyboard into events.
+ */
++void dump_i8042_history(void);
+
+ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
+ unsigned int flags, struct pt_regs *regs)
+@@ -142,15 +145,13 @@
+ printk(KERN_DEBUG "atkbd.c: Received %02x flags %02x\n", data, flags);
+ #endif
+
+- if ((flags & (SERIO_FRAME | SERIO_PARITY)) && (~flags & SERIO_TIMEOUT) && !atkbd->resend && atkbd->write) {
++#if !defined(__i386__) && !defined (__x86_64__)
++ if ((flags & (SERIO_FRAME | SERIO_PARITY)) &&
++ (~flags & SERIO_TIMEOUT)) {
+ printk("atkbd.c: frame/parity error: %02x\n", flags);
+- serio_write(serio, ATKBD_CMD_RESEND);
+- atkbd->resend = 1;
+ goto out;
+ }
+-
+- if (!flags)
+- atkbd->resend = 0;
++#endif
+
+ switch (code) {
+ case ATKBD_RET_ACK:
+@@ -193,8 +194,18 @@
+ case ATKBD_KEY_UNKNOWN:
+ printk(KERN_WARNING "atkbd.c: Unknown key (set %d, scancode %#x, on %s) %s.\n",
+ atkbd->set, code, serio->phys, atkbd->release ? "released" : "pressed");
++ dump_i8042_history();
+ break;
+ default:
++#if 0
++ if (!atkbd->release) {
++ mod_timer(&atkbd->timer,
++ jiffies + (test_bit(atkbd->keycode[code],
++ atkbd->dev.key) ? HZ/33 : HZ/4) + HZ/100);
++ atkbd->lastkey = atkbd->keycode[code];
++ }
++#endif
++
+ input_regs(&atkbd->dev, regs);
+ input_report_key(&atkbd->dev, atkbd->keycode[code], !atkbd->release);
+ input_sync(&atkbd->dev);
+@@ -205,6 +216,13 @@
+ return IRQ_HANDLED;
+ }
+
++static void atkbd_force_key_up(unsigned long data)
++{
++ struct atkbd *atkbd = (void *) data;
++ input_report_key(&atkbd->dev, atkbd->lastkey, 0);
++ input_sync(&atkbd->dev);
++}
++
+ /*
+ * atkbd_sendbyte() sends a byte to the keyboard, and waits for
+ * acknowledge. It doesn't handle resends according to the keyboard
+@@ -214,7 +232,7 @@
+
+ static int atkbd_sendbyte(struct atkbd *atkbd, unsigned char byte)
+ {
+- int timeout = 10000; /* 100 msec */
++ int timeout = 20000; /* 200 msec */
+ atkbd->ack = 0;
+
+ #ifdef ATKBD_DEBUG
+@@ -322,6 +340,53 @@
+ }
+
+ /*
++ * atkbd_probe() probes for an AT keyboard on a serio port.
++ */
++
++static int atkbd_probe(struct atkbd *atkbd)
++{
++ unsigned char param[2];
++
++/*
++ * Some systems, where the bit-twiddling when testing the io-lines of the
++ * controller may confuse the keyboard need a full reset of the keyboard. On
++ * these systems the BIOS also usually doesn't do it for us.
++ */
++
++ if (atkbd_reset)
++ if (atkbd_command(atkbd, NULL, ATKBD_CMD_RESET_BAT))
++ printk(KERN_WARNING "atkbd.c: keyboard reset failed on %s\n", atkbd->serio->phys);
++
++/*
++ * Then we check the keyboard ID. We should get 0xab83 under normal conditions.
++ * Some keyboards report different values, but the first byte is always 0xab or
++ * 0xac. Some old AT keyboards don't report anything. If a mouse is connected, this
++ * should make sure we don't try to set the LEDs on it.
++ */
++
++ if (atkbd_command(atkbd, param, ATKBD_CMD_GETID)) {
++
++/*
++ * If the get ID command failed, we check if we can at least set the LEDs on
++ * the keyboard. This should work on every keyboard out there. It also turns
++ * the LEDs off, which we want anyway.
++ */
++ param[0] = 0;
++ if (atkbd_command(atkbd, param, ATKBD_CMD_SETLEDS))
++ return -1;
++ atkbd->id = 0xabba;
++ return 0;
++ }
++
++ if (param[0] != 0xab && param[0] != 0xac)
++ return -1;
++ atkbd->id = (param[0] << 8) | param[1];
++
++
++ return 0;
++}
++
++/*
+ * atkbd_set_3 checks if a keyboard has a working Set 3 support, and
+ * sets it into that. Unfortunately there are keyboards that can be switched
+ * to Set 3, but don't work well in that (BTC Multimedia ...)
+@@ -355,75 +420,26 @@
+ return 4;
+ }
+
+-/*
+- * Try to set the set we want.
+- */
++ if (atkbd_set != 3)
++ return 2;
+
+- param[0] = atkbd_set;
++ param[0] = 3;
+ if (atkbd_command(atkbd, param, ATKBD_CMD_SSCANSET))
+ return 2;
+
+-/*
+- * Read set number. Beware here. Some keyboards always send '2'
+- * or some other number regardless into what mode they have been
+- * attempted to be set. Other keyboards treat the '0' command as
+- * 'set to set 0', and not 'report current set' as they should.
+- * In that case we time out, and return 2.
+- */
+-
+ param[0] = 0;
+ if (atkbd_command(atkbd, param, ATKBD_CMD_GSCANSET))
+ return 2;
+
+-/*
+- * Here we return the set number the keyboard reports about
+- * itself.
+- */
++ if (param[0] != 3)
++ return 2;
+
+- return (param[0] == 3) ? 3 : 2;
++ return 3;
+ }
+
+-/*
+- * atkbd_probe() probes for an AT keyboard on a serio port.
+- */
+-
+-static int atkbd_probe(struct atkbd *atkbd)
++static int atkbd_enable(struct atkbd *atkbd)
+ {
+- unsigned char param[2];
+-
+-/*
+- * Some systems, where the bit-twiddling when testing the io-lines of the
+- * controller may confuse the keyboard need a full reset of the keyboard. On
+- * these systems the BIOS also usually doesn't do it for us.
+- */
+-
+- if (atkbd_reset)
+- if (atkbd_command(atkbd, NULL, ATKBD_CMD_RESET_BAT))
+- printk(KERN_WARNING "atkbd.c: keyboard reset failed on %s\n", atkbd->serio->phys);
+-
+-/*
+- * Then we check the keyboard ID. We should get 0xab83 under normal conditions.
+- * Some keyboards report different values, but the first byte is always 0xab or
+- * 0xac. Some old AT keyboards don't report anything.
+- */
+-
+- if (atkbd_command(atkbd, param, ATKBD_CMD_GETID)) {
+-
+-/*
+- * If the get ID command failed, we check if we can at least set the LEDs on
+- * the keyboard. This should work on every keyboard out there. It also turns
+- * the LEDs off, which we want anyway.
+- */
+- param[0] = 0;
+- if (atkbd_command(atkbd, param, ATKBD_CMD_SETLEDS))
+- return -1;
+- atkbd->id = 0xabba;
+- return 0;
+- }
+-
+- if (param[0] != 0xab && param[0] != 0xac)
+- return -1;
+- atkbd->id = (param[0] << 8) | param[1];
++ unsigned char param[1];
+
+ /*
+ * Set the LEDs to a defined state.
+@@ -434,21 +450,22 @@
+ return -1;
+
+ /*
+- * Disable autorepeat. We don't need it, as we do it in software anyway,
+- * because that way can get faster repeat, and have less system load (less
+- * accesses to the slow ISA hardware). If this fails, we don't care, and will
+- * just ignore the repeated keys.
++ * Set autorepeat to fastest possible.
+ */
+
+- atkbd_command(atkbd, NULL, ATKBD_CMD_SETALL_MB);
++ param[0] = 0;
++ if (atkbd_command(atkbd, param, ATKBD_CMD_SETREP))
++ return -1;
+
+ /*
+- * Last, we enable the keyboard to make sure that we get keypresses from it.
++ * Enable the keyboard to receive keystrokes.
+ */
+
+- if (atkbd_command(atkbd, NULL, ATKBD_CMD_ENABLE))
++ if (atkbd_command(atkbd, NULL, ATKBD_CMD_ENABLE)) {
+ printk(KERN_ERR "atkbd.c: Failed to enable keyboard on %s\n",
+ atkbd->serio->phys);
++ return -1;
++ }
+
+ return 0;
+ }
+@@ -473,6 +490,7 @@
+ struct atkbd *atkbd = serio->private;
+ input_unregister_device(&atkbd->dev);
+ serio_close(serio);
++ serio->private = NULL;
+ kfree(atkbd);
+ }
+
+@@ -505,6 +523,9 @@
+ atkbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
+ } else atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+
++ atkbd->dev.rep[REP_DELAY] = HZ/4 + HZ/50;
++ atkbd->dev.rep[REP_PERIOD] = HZ/33;
++
+ atkbd->serio = serio;
+
+ init_input_dev(&atkbd->dev);
+@@ -517,7 +538,12 @@
+
+ serio->private = atkbd;
+
++ init_timer(&atkbd->timer);
++ atkbd->timer.data = (long) atkbd;
++ atkbd->timer.function = atkbd_force_key_up;
++
+ if (serio_open(serio, dev)) {
++ serio->private = NULL;
+ kfree(atkbd);
+ return;
+ }
+@@ -526,11 +552,13 @@
+
+ if (atkbd_probe(atkbd)) {
+ serio_close(serio);
++ serio->private = NULL;
+ kfree(atkbd);
+ return;
+ }
+
+ atkbd->set = atkbd_set_3(atkbd);
++ atkbd_enable(atkbd);
+
+ } else {
+ atkbd->set = 2;
+Index: linux-2.6.0-test5/drivers/input/keyboard/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/keyboard/Kconfig 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/keyboard/Kconfig 2003-09-27 11:38:21.460265928 +0800
+@@ -14,7 +14,8 @@
+ config KEYBOARD_ATKBD
+ tristate "AT keyboard support" if EMBEDDED || !X86
+ default y
+- depends on INPUT && INPUT_KEYBOARD && SERIO
++ depends on INPUT && INPUT_KEYBOARD
++ select SERIO_I8042
+ help
+ Say Y here if you want to use a standard AT or PS/2 keyboard. Usually
+ you'll need this, unless you have a different type keyboard (USB, ADB
+@@ -30,7 +31,8 @@
+
+ config KEYBOARD_SUNKBD
+ tristate "Sun Type 4 and Type 5 keyboard support"
+- depends on INPUT && INPUT_KEYBOARD && SERIO
++ depends on INPUT && INPUT_KEYBOARD
++ select SERIO
+ help
+ Say Y here if you want to use a Sun Type 4 or Type 5 keyboard,
+ connected either to the Sun keyboard connector or to an serial
+@@ -43,7 +45,8 @@
+
+ config KEYBOARD_XTKBD
+ tristate "XT Keyboard support"
+- depends on INPUT && INPUT_KEYBOARD && SERIO
++ depends on INPUT && INPUT_KEYBOARD
++ select SERIO
+ help
+ Say Y here if you want to use the old IBM PC/XT keyboard (or
+ compatible) on your system. This is only possible with a
+@@ -57,7 +60,8 @@
+
+ config KEYBOARD_NEWTON
+ tristate "Newton keyboard"
+- depends on INPUT && INPUT_KEYBOARD && SERIO
++ depends on INPUT && INPUT_KEYBOARD
++ select SERIO
+ help
+ Say Y here if you have a Newton keyboard on a serial port.
+
+@@ -92,7 +96,8 @@
+
+ config KEYBOARD_98KBD
+ tristate "NEC PC-9800 Keyboard support"
+- depends on X86_PC9800 && INPUT && INPUT_KEYBOARD && SERIO
++ depends on X86_PC9800 && INPUT && INPUT_KEYBOARD
++ select SERIO
+ help
+ Say Y here if you want to use the NEC PC-9801/PC-9821 keyboard (or
+ compatible) on your system.
+Index: linux-2.6.0-test5/drivers/input/mouse/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/mouse/Kconfig 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/mouse/Kconfig 2003-09-27 11:38:21.463265472 +0800
+@@ -14,14 +14,13 @@
+ config MOUSE_PS2
+ tristate "PS/2 mouse"
+ default y
+- depends on INPUT && INPUT_MOUSE && SERIO
++ depends on INPUT && INPUT_MOUSE
++ select SERIO_I8042
+ ---help---
+ Say Y here if you have a PS/2 mouse connected to your system. This
+ includes the standard 2 or 3-button PS/2 mouse, as well as PS/2
+ mice with wheels and extra buttons, Microsoft, Logitech or Genius
+- compatible. Support for Synaptics TouchPads is also included.
+- For Synaptics TouchPad support in XFree86 you'll need this XFree86
+- driver: http://w1.894.telia.com/~u89404340/touchpad/index.html
++ compatible.
+
+ If unsure, say Y.
+
+@@ -30,9 +29,26 @@
+ The module will be called psmouse. If you want to compile it as a
+ module, say M here and read <file:Documentation/modules.txt>.
+
++config MOUSE_PS2_SYNAPTICS
++ bool "Synaptics TouchPad"
++ default n
++ depends on INPUT && INPUT_MOUSE && MOUSE_PS2
++ ---help---
++ Say Y here if you have a Synaptics TouchPad connected to your system.
++ This touchpad is found on many modern laptop computers.
++
++ Note that you also need a user space driver to interpret the data
++ generated by the kernel. A compatible driver for XFree86 is available
++ from http://w1.894.telia.com/~u89404340/touchpad/index.html
++
++ The gpm program is not yet able to interpret the data from this
++ driver, so if you need to use the touchpad in the console, you have to
++ say N for now.
++
+ config MOUSE_SERIAL
+ tristate "Serial mouse"
+- depends on INPUT && INPUT_MOUSE && SERIO
++ depends on INPUT && INPUT_MOUSE
++ select SERIO
+ ---help---
+ Say Y here if you have a serial (RS-232, COM port) mouse connected
+ to your system. This includes Sun, MouseSystems, Microsoft,
+Index: linux-2.6.0-test5/drivers/input/mouse/psmouse-base.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/mouse/psmouse-base.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/mouse/psmouse-base.c 2003-09-27 11:38:21.468264712 +0800
+@@ -17,30 +17,37 @@
+ #include <linux/input.h>
+ #include <linux/serio.h>
+ #include <linux/init.h>
++#include <linux/pm.h>
+ #include "psmouse.h"
+ #include "synaptics.h"
+ #include "logips2pp.h"
+
+ MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
+ MODULE_DESCRIPTION("PS/2 mouse driver");
++MODULE_PARM(psmouse_imps2, "1i");
++MODULE_PARM_DESC(psmouse_imps2, "Limit protocol extensions to the Intellimouse protocol.");
+ MODULE_PARM(psmouse_noext, "1i");
+ MODULE_PARM_DESC(psmouse_noext, "Disable any protocol extensions. Useful for KVM switches.");
+ MODULE_PARM(psmouse_resolution, "i");
+ MODULE_PARM_DESC(psmouse_resolution, "Resolution, in dpi.");
+ MODULE_PARM(psmouse_smartscroll, "i");
+ MODULE_PARM_DESC(psmouse_smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled.");
++MODULE_PARM(psmouse_resetafter, "i");
++MODULE_PARM_DESC(psmouse_resetafter, "Reset Synaptics Touchpad after so many bad packets (0 = never).");
+ MODULE_LICENSE("GPL");
+
+ #define PSMOUSE_LOGITECH_SMARTSCROLL 1
+
++static int psmouse_imps2;
+ static int psmouse_noext;
+ int psmouse_resolution;
+ int psmouse_smartscroll = PSMOUSE_LOGITECH_SMARTSCROLL;
++unsigned int psmouse_resetafter;
+
+-static char *psmouse_protocols[] = { "None", "PS/2", "PS2++", "PS2T++", "GenPS/2", "ImPS/2", "ImExPS/2", "Synaptics"};
++static char *psmouse_protocols[] = { "None", "PS/2", "PS2++", "PS2T++", "GenPS/2", "ImPS/2", "ImExPS/2", "SynPS/2"};
+
+ /*
+- * psmouse_process_packet() anlyzes the PS/2 mouse packet contents and
++ * psmouse_process_packet() analyzes the PS/2 mouse packet contents and
+ * reports relevant events to the input module.
+ */
+
+@@ -108,6 +115,9 @@
+ {
+ struct psmouse *psmouse = serio->private;
+
++ if (psmouse->state == PSMOUSE_IGNORE)
++ goto out;
++
+ if (psmouse->acking) {
+ switch (data) {
+ case PSMOUSE_RET_ACK:
+@@ -132,31 +142,46 @@
+ }
+
+ if (psmouse->pktcnt && time_after(jiffies, psmouse->last + HZ/2)) {
+- printk(KERN_WARNING "psmouse.c: Lost synchronization, throwing %d bytes away.\n", psmouse->pktcnt);
++ printk(KERN_WARNING "psmouse.c: %s at %s lost synchronization, throwing %d bytes away.\n",
++ psmouse->name, psmouse->phys, psmouse->pktcnt);
+ psmouse->pktcnt = 0;
+ }
+
+ psmouse->last = jiffies;
+ psmouse->packet[psmouse->pktcnt++] = data;
+
+- if (psmouse->pktcnt == 3 + (psmouse->type >= PSMOUSE_GENPS)) {
+- psmouse_process_packet(psmouse, regs);
+- psmouse->pktcnt = 0;
+- goto out;
++ if (psmouse->packet[0] == PSMOUSE_RET_BAT) {
++ if (psmouse->pktcnt == 1)
++ goto out;
++
++ if (psmouse->pktcnt == 2) {
++ if (psmouse->packet[1] == PSMOUSE_RET_ID) {
++ psmouse->state = PSMOUSE_IGNORE;
++ serio_rescan(serio);
++ goto out;
++ }
++ if (psmouse->type == PSMOUSE_SYNAPTICS) {
++ /* neither 0xAA nor 0x00 are valid first bytes
++ * for a packet in absolute mode
++ */
++ psmouse->pktcnt = 0;
++ goto out;
++ }
++ }
+ }
+
+- if (psmouse->pktcnt == 1 && psmouse->type == PSMOUSE_SYNAPTICS) {
++ if (psmouse->type == PSMOUSE_SYNAPTICS) {
+ /*
+ * The synaptics driver has its own resync logic,
+ * so it needs to receive all bytes one at a time.
+ */
+ synaptics_process_byte(psmouse, regs);
+- psmouse->pktcnt = 0;
+ goto out;
+ }
+
+- if (psmouse->pktcnt == 1 && psmouse->packet[0] == PSMOUSE_RET_BAT) {
+- serio_rescan(serio);
++ if (psmouse->pktcnt == 3 + (psmouse->type >= PSMOUSE_GENPS)) {
++ psmouse_process_packet(psmouse, regs);
++ psmouse->pktcnt = 0;
+ goto out;
+ }
+ out:
+@@ -200,7 +225,7 @@
+ psmouse->cmdcnt = receive;
+
+ if (command == PSMOUSE_CMD_RESET_BAT)
+- timeout = 2000000; /* 2 sec */
++ timeout = 4000000; /* 4 sec */
+
+ if (command & 0xff)
+ if (psmouse_sendbyte(psmouse, command & 0xff))
+@@ -227,7 +252,7 @@
+ for (i = 0; i < receive; i++)
+ param[i] = psmouse->cmdbuf[(receive - 1) - i];
+
+- if (psmouse->cmdcnt)
++ if (psmouse->cmdcnt)
+ return (psmouse->cmdcnt = 0) - 1;
+
+ return 0;
+@@ -250,66 +275,68 @@
+ if (psmouse_noext)
+ return PSMOUSE_PS2;
+
+-/*
+- * Try Synaptics TouchPad magic ID
+- */
++ if (!psmouse_imps2) {
+
+- param[0] = 0;
+- psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+- psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+- psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+- psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+- psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
+-
+- if (param[1] == 0x47) {
+- psmouse->vendor = "Synaptics";
+- psmouse->name = "TouchPad";
+- if (!synaptics_init(psmouse))
+- return PSMOUSE_SYNAPTICS;
+- else
+- return PSMOUSE_PS2;
+- }
++ /*
++ * Try Synaptics TouchPad magic ID
++ */
+
+-/*
+- * Try Genius NetMouse magic init.
+- */
++ param[0] = 0;
++ psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
++ psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
++ psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
++ psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
++ psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
++
++ if (param[1] == 0x47) {
++ psmouse->vendor = "Synaptics";
++ psmouse->name = "TouchPad";
++ if (!synaptics_init(psmouse))
++ return PSMOUSE_SYNAPTICS;
++ else
++ return PSMOUSE_PS2;
++ }
+
+- param[0] = 3;
+- psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+- psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
+- psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
+- psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
+- psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
++ /*
++ * Try Genius NetMouse magic init.
++ */
+
+- if (param[0] == 0x00 && param[1] == 0x33 && param[2] == 0x55) {
++ param[0] = 3;
++ psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
++ psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
++ psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
++ psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
++ psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
+
+- set_bit(BTN_EXTRA, psmouse->dev.keybit);
+- set_bit(BTN_SIDE, psmouse->dev.keybit);
+- set_bit(REL_WHEEL, psmouse->dev.relbit);
++ if (param[0] == 0x00 && param[1] == 0x33 && param[2] == 0x55) {
+
+- psmouse->vendor = "Genius";
+- psmouse->name = "Wheel Mouse";
+- return PSMOUSE_GENPS;
+- }
++ set_bit(BTN_EXTRA, psmouse->dev.keybit);
++ set_bit(BTN_SIDE, psmouse->dev.keybit);
++ set_bit(REL_WHEEL, psmouse->dev.relbit);
+
+-/*
+- * Try Logitech magic ID.
+- */
++ psmouse->vendor = "Genius";
++ psmouse->name = "Wheel Mouse";
++ return PSMOUSE_GENPS;
++ }
+
+- param[0] = 0;
+- psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+- psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
+- psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
+- psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
+- param[1] = 0;
+- psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
++ /*
++ * Try Logitech magic ID.
++ */
+
+- if (param[1]) {
+- int type = ps2pp_detect_model(psmouse, param);
+- if (type)
+- return type;
++ param[0] = 0;
++ psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
++ psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
++ psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
++ psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
++ param[1] = 0;
++ psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
++
++ if (param[1]) {
++ int type = ps2pp_detect_model(psmouse, param);
++ if (type)
++ return type;
++ }
+ }
+-
+ /*
+ * Try IntelliMouse magic init.
+ */
+@@ -450,14 +477,18 @@
+ */
+
+ psmouse_command(psmouse, param, PSMOUSE_CMD_SETSTREAM);
++}
+
+ /*
+- * Last, we enable the mouse so that we get reports from it.
++ * psmouse_activate() enables the mouse so that we get motion reports from it.
+ */
+
++static void psmouse_activate(struct psmouse *psmouse)
++{
+ if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_ENABLE))
+ printk(KERN_WARNING "psmouse.c: Failed to enable mouse on %s\n", psmouse->serio->phys);
+
++ psmouse->state = PSMOUSE_ACTIVATED;
+ }
+
+ /*
+@@ -478,13 +509,39 @@
+ static void psmouse_disconnect(struct serio *serio)
+ {
+ struct psmouse *psmouse = serio->private;
++
++ psmouse->state = PSMOUSE_IGNORE;
++ synaptics_disconnect(psmouse);
+ input_unregister_device(&psmouse->dev);
+ serio_close(serio);
+- synaptics_disconnect(psmouse);
+ kfree(psmouse);
+ }
+
+ /*
++ * Reinitialize mouse hardware after software suspend.
++ */
++
++static int psmouse_pm_callback(struct pm_dev *dev, pm_request_t request, void *data)
++{
++ struct psmouse *psmouse = dev->data;
++ struct serio_dev *ser_dev = psmouse->serio->dev;
++
++ synaptics_disconnect(psmouse);
++
++ /* We need to reopen the serio port to reinitialize the i8042 controller */
++ serio_close(psmouse->serio);
++ serio_open(psmouse->serio, ser_dev);
++
++ /* Probe and re-initialize the mouse */
++ psmouse_probe(psmouse);
++ psmouse_initialize(psmouse);
++ synaptics_pt_init(psmouse);
++ psmouse_activate(psmouse);
++
++ return 0;
++}
++
++/*
+ * psmouse_connect() is a callback from the serio module when
+ * an unhandled serio port is found.
+ */
+@@ -492,8 +549,10 @@
+ static void psmouse_connect(struct serio *serio, struct serio_dev *dev)
+ {
+ struct psmouse *psmouse;
++ struct pm_dev *pmdev;
+
+- if ((serio->type & SERIO_TYPE) != SERIO_8042)
++ if ((serio->type & SERIO_TYPE) != SERIO_8042 &&
++ (serio->type & SERIO_TYPE) != SERIO_PS_PSTHRU)
+ return;
+
+ if (!(psmouse = kmalloc(sizeof(struct psmouse), GFP_KERNEL)))
+@@ -506,6 +565,7 @@
+ psmouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+ psmouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
+
++ psmouse->state = PSMOUSE_NEW_DEVICE;
+ psmouse->serio = serio;
+ psmouse->dev.private = psmouse;
+
+@@ -522,6 +582,12 @@
+ return;
+ }
+
++ pmdev = pm_register(PM_SYS_DEV, PM_SYS_UNKNOWN, psmouse_pm_callback);
++ if (pmdev) {
++ psmouse->dev.pm_dev = pmdev;
++ pmdev->data = psmouse;
++ }
++
+ sprintf(psmouse->devname, "%s %s %s",
+ psmouse_protocols[psmouse->type], psmouse->vendor, psmouse->name);
+ sprintf(psmouse->phys, "%s/input0",
+@@ -539,6 +605,10 @@
+ printk(KERN_INFO "input: %s on %s\n", psmouse->devname, serio->phys);
+
+ psmouse_initialize(psmouse);
++
++ synaptics_pt_init(psmouse);
++
++ psmouse_activate(psmouse);
+ }
+
+ static struct serio_dev psmouse_dev = {
+@@ -549,6 +619,12 @@
+ };
+
+ #ifndef MODULE
++static int __init psmouse_imps2_setup(char *str)
++{
++ psmouse_imps2 = 1;
++ return 1;
++}
++
+ static int __init psmouse_noext_setup(char *str)
+ {
+ psmouse_noext = 1;
+@@ -567,9 +643,17 @@
+ return 1;
+ }
+
++static int __init psmouse_resetafter_setup(char *str)
++{
++ get_option(&str, &psmouse_resetafter);
++ return 1;
++}
++
++__setup("psmouse_imps2", psmouse_imps2_setup);
+ __setup("psmouse_noext", psmouse_noext_setup);
+ __setup("psmouse_resolution=", psmouse_resolution_setup);
+ __setup("psmouse_smartscroll=", psmouse_smartscroll_setup);
++__setup("psmouse_resetafter=", psmouse_resetafter_setup);
+
+ #endif
+
+Index: linux-2.6.0-test5/drivers/input/mouse/psmouse.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/mouse/psmouse.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/mouse/psmouse.h 2003-09-27 11:38:21.470264408 +0800
+@@ -13,9 +13,15 @@
+ #define PSMOUSE_CMD_RESET_BAT 0x02ff
+
+ #define PSMOUSE_RET_BAT 0xaa
++#define PSMOUSE_RET_ID 0x00
+ #define PSMOUSE_RET_ACK 0xfa
+ #define PSMOUSE_RET_NAK 0xfe
+
++/* psmouse states */
++#define PSMOUSE_NEW_DEVICE 0
++#define PSMOUSE_ACTIVATED 1
++#define PSMOUSE_IGNORE 2
++
+ struct psmouse {
+ void *private;
+ struct input_dev dev;
+@@ -29,6 +35,7 @@
+ unsigned char type;
+ unsigned char model;
+ unsigned long last;
++ unsigned char state;
+ char acking;
+ volatile char ack;
+ char error;
+@@ -36,16 +43,17 @@
+ char phys[32];
+ };
+
+-#define PSMOUSE_PS2 1
+-#define PSMOUSE_PS2PP 2
+-#define PSMOUSE_PS2TPP 3
+-#define PSMOUSE_GENPS 4
+-#define PSMOUSE_IMPS 5
+-#define PSMOUSE_IMEX 6
+-#define PSMOUSE_SYNAPTICS 7
++#define PSMOUSE_PS2 1
++#define PSMOUSE_PS2PP 2
++#define PSMOUSE_PS2TPP 3
++#define PSMOUSE_GENPS 4
++#define PSMOUSE_IMPS 5
++#define PSMOUSE_IMEX 6
++#define PSMOUSE_SYNAPTICS 7
+
+ int psmouse_command(struct psmouse *psmouse, unsigned char *param, int command);
+
+ extern int psmouse_smartscroll;
++extern unsigned int psmouse_resetafter;
+
+ #endif /* _PSMOUSE_H */
+Index: linux-2.6.0-test5/drivers/input/mouse/synaptics.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/mouse/synaptics.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/mouse/synaptics.c 2003-09-27 11:38:21.474263800 +0800
+@@ -1,6 +1,9 @@
+ /*
+ * Synaptics TouchPad PS/2 mouse driver
+ *
++ * 2003 Dmitry Torokhov <dtor@mail.ru>
++ * Added support for pass-through port
++ *
+ * 2003 Peter Osterlund <petero2@telia.com>
+ * Ported to 2.5 input device infrastructure.
+ *
+@@ -21,6 +24,7 @@
+
+ #include <linux/module.h>
+ #include <linux/input.h>
++#include <linux/serio.h>
+ #include "psmouse.h"
+ #include "synaptics.h"
+
+@@ -32,7 +36,7 @@
+ * Use the Synaptics extended ps/2 syntax to write a special command byte.
+ * special command: 0xE8 rr 0xE8 ss 0xE8 tt 0xE8 uu where (rr*64)+(ss*16)+(tt*4)+uu
+ * is the command. A 0xF3 or 0xE9 must follow (see synaptics_send_cmd
+- * and synaptics_set_mode)
++ * and synaptics_mode_cmd)
+ */
+ static int synaptics_special_cmd(struct psmouse *psmouse, unsigned char command)
+ {
+@@ -65,13 +69,13 @@
+ /*
+ * Set the synaptics touchpad mode byte by special commands
+ */
+-static int synaptics_set_mode(struct psmouse *psmouse, unsigned char mode)
++static int synaptics_mode_cmd(struct psmouse *psmouse, unsigned char mode)
+ {
+ unsigned char param[1];
+
+ if (synaptics_special_cmd(psmouse, mode))
+ return -1;
+- param[0] = 0x14;
++ param[0] = SYN_PS_SET_MODE2;
+ if (psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE))
+ return -1;
+ return 0;
+@@ -83,7 +87,7 @@
+
+ if (psmouse_command(psmouse, r, PSMOUSE_CMD_RESET_BAT))
+ return -1;
+- if (r[0] == 0xAA && r[1] == 0x00)
++ if (r[0] == PSMOUSE_RET_BAT && r[1] == PSMOUSE_RET_ID)
+ return 0;
+ return -1;
+ }
+@@ -92,13 +96,14 @@
+ * Read the model-id bytes from the touchpad
+ * see also SYN_MODEL_* macros
+ */
+-static int synaptics_model_id(struct psmouse *psmouse, unsigned long int *model_id)
++static int synaptics_model_id(struct psmouse *psmouse)
+ {
++ struct synaptics_data *priv = psmouse->private;
+ unsigned char mi[3];
+
+ if (synaptics_send_cmd(psmouse, SYN_QUE_MODEL, mi))
+ return -1;
+- *model_id = (mi[0]<<16) | (mi[1]<<8) | mi[2];
++ priv->model_id = (mi[0]<<16) | (mi[1]<<8) | mi[2];
+ return 0;
+ }
+
+@@ -106,47 +111,50 @@
+ * Read the capability-bits from the touchpad
+ * see also the SYN_CAP_* macros
+ */
+-static int synaptics_capability(struct psmouse *psmouse, unsigned long int *capability)
++static int synaptics_capability(struct psmouse *psmouse)
+ {
++ struct synaptics_data *priv = psmouse->private;
+ unsigned char cap[3];
+
+ if (synaptics_send_cmd(psmouse, SYN_QUE_CAPABILITIES, cap))
+ return -1;
+- *capability = (cap[0]<<16) | (cap[1]<<8) | cap[2];
+- if (SYN_CAP_VALID(*capability))
+- return 0;
+- return -1;
++ priv->capabilities = (cap[0]<<16) | (cap[1]<<8) | cap[2];
++ priv->ext_cap = 0;
++ if (!SYN_CAP_VALID(priv->capabilities))
++ return -1;
++
++ if (SYN_EXT_CAP_REQUESTS(priv->capabilities)) {
++ if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB, cap)) {
++ printk(KERN_ERR "Synaptics claims to have extended capabilities,"
++ " but I'm not able to read them.");
++ } else
++ priv->ext_cap = (cap[0]<<16) | (cap[1]<<8) | cap[2];
++ }
++ return 0;
+ }
+
+ /*
+ * Identify Touchpad
+ * See also the SYN_ID_* macros
+ */
+-static int synaptics_identify(struct psmouse *psmouse, unsigned long int *ident)
++static int synaptics_identify(struct psmouse *psmouse)
+ {
++ struct synaptics_data *priv = psmouse->private;
+ unsigned char id[3];
+
+ if (synaptics_send_cmd(psmouse, SYN_QUE_IDENTIFY, id))
+ return -1;
+- *ident = (id[0]<<16) | (id[1]<<8) | id[2];
+- if (SYN_ID_IS_SYNAPTICS(*ident))
++ priv->identity = (id[0]<<16) | (id[1]<<8) | id[2];
++ if (SYN_ID_IS_SYNAPTICS(priv->identity))
+ return 0;
+ return -1;
+ }
+
+-static int synaptics_enable_device(struct psmouse *psmouse)
+-{
+- if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_ENABLE))
+- return -1;
+- return 0;
+-}
+-
+ static void print_ident(struct synaptics_data *priv)
+ {
+ printk(KERN_INFO "Synaptics Touchpad, model: %ld\n", SYN_ID_MODEL(priv->identity));
+- printk(KERN_INFO " Firware: %ld.%ld\n", SYN_ID_MAJOR(priv->identity),
++ printk(KERN_INFO " Firmware: %ld.%ld\n", SYN_ID_MAJOR(priv->identity),
+ SYN_ID_MINOR(priv->identity));
+-
+ if (SYN_MODEL_ROT180(priv->model_id))
+ printk(KERN_INFO " 180 degree mounted touchpad\n");
+ if (SYN_MODEL_PORTRAIT(priv->model_id))
+@@ -159,38 +167,135 @@
+
+ if (SYN_CAP_EXTENDED(priv->capabilities)) {
+ printk(KERN_INFO " Touchpad has extended capability bits\n");
+- if (SYN_CAP_FOUR_BUTTON(priv->capabilities))
++ if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) &&
++ SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) <= 8)
++ printk(KERN_INFO " -> %d multi-buttons, i.e. besides standard buttons\n",
++ (int)(SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)));
++ else if (SYN_CAP_FOUR_BUTTON(priv->capabilities))
+ printk(KERN_INFO " -> four buttons\n");
+ if (SYN_CAP_MULTIFINGER(priv->capabilities))
+ printk(KERN_INFO " -> multifinger detection\n");
+ if (SYN_CAP_PALMDETECT(priv->capabilities))
+ printk(KERN_INFO " -> palm detection\n");
++ if (SYN_CAP_PASS_THROUGH(priv->capabilities))
++ printk(KERN_INFO " -> pass-through port\n");
+ }
+ }
+
+-static int query_hardware(struct psmouse *psmouse)
++static int synaptics_query_hardware(struct psmouse *psmouse)
+ {
+ struct synaptics_data *priv = psmouse->private;
+ int retries = 0;
++ int mode;
+
+ while ((retries++ < 3) && synaptics_reset(psmouse))
+ printk(KERN_ERR "synaptics reset failed\n");
+
+- if (synaptics_identify(psmouse, &priv->identity))
++ if (synaptics_identify(psmouse))
+ return -1;
+- if (synaptics_model_id(psmouse, &priv->model_id))
++ if (synaptics_model_id(psmouse))
+ return -1;
+- if (synaptics_capability(psmouse, &priv->capabilities))
++ if (synaptics_capability(psmouse))
+ return -1;
+- if (synaptics_set_mode(psmouse, (SYN_BIT_ABSOLUTE_MODE |
+- SYN_BIT_HIGH_RATE |
+- SYN_BIT_DISABLE_GESTURE |
+- SYN_BIT_W_MODE)))
++
++ mode = SYN_BIT_ABSOLUTE_MODE | SYN_BIT_HIGH_RATE;
++ if (SYN_ID_MAJOR(priv->identity) >= 4)
++ mode |= SYN_BIT_DISABLE_GESTURE;
++ if (SYN_CAP_EXTENDED(priv->capabilities))
++ mode |= SYN_BIT_W_MODE;
++ if (synaptics_mode_cmd(psmouse, mode))
+ return -1;
+
+- synaptics_enable_device(psmouse);
++ return 0;
++}
+
+- print_ident(priv);
++/*****************************************************************************
++ * Synaptics pass-through PS/2 port support
++ ****************************************************************************/
++static int synaptics_pt_open(struct serio *port)
++{
++ return 0;
++}
++
++static void synaptics_pt_close(struct serio *port)
++{
++}
++
++static int synaptics_pt_write(struct serio *port, unsigned char c)
++{
++ struct psmouse *parent = port->driver;
++ char rate_param = SYN_PS_CLIENT_CMD; /* indicates that we want pass-through port */
++
++ if (synaptics_special_cmd(parent, c))
++ return -1;
++ if (psmouse_command(parent, &rate_param, PSMOUSE_CMD_SETRATE))
++ return -1;
++ return 0;
++}
++
++static inline int synaptics_is_pt_packet(unsigned char *buf)
++{
++ return (buf[0] & 0xFC) == 0x84 && (buf[3] & 0xCC) == 0xC4;
++}
++
++static void synaptics_pass_pt_packet(struct serio *ptport, unsigned char *packet)
++{
++ struct psmouse *child = ptport->private;
++
++ if (child) {
++ if (child->state == PSMOUSE_ACTIVATED) {
++ serio_interrupt(ptport, packet[1], 0, NULL);
++ serio_interrupt(ptport, packet[4], 0, NULL);
++ serio_interrupt(ptport, packet[5], 0, NULL);
++ if (child->type >= PSMOUSE_GENPS)
++ serio_interrupt(ptport, packet[2], 0, NULL);
++ } else if (child->state != PSMOUSE_IGNORE) {
++ serio_interrupt(ptport, packet[1], 0, NULL);
++ }
++ }
++}
++
++int synaptics_pt_init(struct psmouse *psmouse)
++{
++ struct synaptics_data *priv = psmouse->private;
++ struct serio *port;
++ struct psmouse *child;
++
++ if (psmouse->type != PSMOUSE_SYNAPTICS)
++ return -1;
++ if (!SYN_CAP_EXTENDED(priv->capabilities))
++ return -1;
++ if (!SYN_CAP_PASS_THROUGH(priv->capabilities))
++ return -1;
++
++ priv->ptport = port = kmalloc(sizeof(struct serio), GFP_KERNEL);
++ if (!port) {
++ printk(KERN_ERR "synaptics: not enough memory to allocate serio port\n");
++ return -1;
++ }
++
++ memset(port, 0, sizeof(struct serio));
++ port->type = SERIO_PS_PSTHRU;
++ port->name = "Synaptics pass-through";
++ port->phys = "synaptics-pt/serio0";
++ port->write = synaptics_pt_write;
++ port->open = synaptics_pt_open;
++ port->close = synaptics_pt_close;
++ port->driver = psmouse;
++
++ printk(KERN_INFO "serio: %s port at %s\n", port->name, psmouse->phys);
++ serio_register_slave_port(port);
++
++ /* adjust the touchpad to child's choice of protocol */
++ child = port->private;
++ if (child && child->type >= PSMOUSE_GENPS) {
++ if (synaptics_mode_cmd(psmouse, (SYN_BIT_ABSOLUTE_MODE |
++ SYN_BIT_HIGH_RATE |
++ SYN_BIT_DISABLE_GESTURE |
++ SYN_BIT_FOUR_BYTE_CLIENT |
++ SYN_BIT_W_MODE)))
++ printk(KERN_INFO "synaptics: failed to enable 4-byte guest protocol\n");
++ }
+
+ return 0;
+ }
+@@ -209,44 +314,75 @@
+ set_bit(axis, dev->absbit);
+ }
+
++static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
++{
++ /*
++ * The x/y limits are taken from the Synaptics TouchPad interfacing Guide,
++ * which says that they should be valid regardless of the actual size of
++ * the sensor.
++ */
++ set_bit(EV_ABS, dev->evbit);
++ set_abs_params(dev, ABS_X, 1472, 5472, 0, 0);
++ set_abs_params(dev, ABS_Y, 1408, 4448, 0, 0);
++ set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
++
++ set_bit(EV_MSC, dev->evbit);
++ set_bit(MSC_GESTURE, dev->mscbit);
++
++ set_bit(EV_KEY, dev->evbit);
++ set_bit(BTN_LEFT, dev->keybit);
++ set_bit(BTN_RIGHT, dev->keybit);
++ set_bit(BTN_FORWARD, dev->keybit);
++ set_bit(BTN_BACK, dev->keybit);
++ if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)) {
++ switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) {
++ default:
++ /*
++ * if nExtBtn is greater than 8 it should be considered
++ * invalid and treated as 0
++ */
++ break;
++ case 8:
++ set_bit(BTN_7, dev->keybit);
++ set_bit(BTN_6, dev->keybit);
++ case 6:
++ set_bit(BTN_5, dev->keybit);
++ set_bit(BTN_4, dev->keybit);
++ case 4:
++ set_bit(BTN_3, dev->keybit);
++ set_bit(BTN_2, dev->keybit);
++ case 2:
++ set_bit(BTN_1, dev->keybit);
++ set_bit(BTN_0, dev->keybit);
++ break;
++ }
++ }
++
++ clear_bit(EV_REL, dev->evbit);
++ clear_bit(REL_X, dev->relbit);
++ clear_bit(REL_Y, dev->relbit);
++}
++
+ int synaptics_init(struct psmouse *psmouse)
+ {
+ struct synaptics_data *priv;
+
++#ifndef CONFIG_MOUSE_PS2_SYNAPTICS
++ return -1;
++#endif
++
+ psmouse->private = priv = kmalloc(sizeof(struct synaptics_data), GFP_KERNEL);
+ if (!priv)
+ return -1;
+ memset(priv, 0, sizeof(struct synaptics_data));
+
+- priv->inSync = 1;
+-
+- if (query_hardware(psmouse)) {
++ if (synaptics_query_hardware(psmouse)) {
+ printk(KERN_ERR "Unable to query/initialize Synaptics hardware.\n");
+ goto init_fail;
+ }
+
+- /*
+- * The x/y limits are taken from the Synaptics TouchPad interfacing Guide,
+- * which says that they should be valid regardless of the actual size of
+- * the senser.
+- */
+- set_bit(EV_ABS, psmouse->dev.evbit);
+- set_abs_params(&psmouse->dev, ABS_X, 1472, 5472, 0, 0);
+- set_abs_params(&psmouse->dev, ABS_Y, 1408, 4448, 0, 0);
+- set_abs_params(&psmouse->dev, ABS_PRESSURE, 0, 255, 0, 0);
+-
+- set_bit(EV_MSC, psmouse->dev.evbit);
+- set_bit(MSC_GESTURE, psmouse->dev.mscbit);
+-
+- set_bit(EV_KEY, psmouse->dev.evbit);
+- set_bit(BTN_LEFT, psmouse->dev.keybit);
+- set_bit(BTN_RIGHT, psmouse->dev.keybit);
+- set_bit(BTN_FORWARD, psmouse->dev.keybit);
+- set_bit(BTN_BACK, psmouse->dev.keybit);
+-
+- clear_bit(EV_REL, psmouse->dev.evbit);
+- clear_bit(REL_X, psmouse->dev.relbit);
+- clear_bit(REL_Y, psmouse->dev.relbit);
++ print_ident(priv);
++ set_input_params(&psmouse->dev, priv);
+
+ return 0;
+
+@@ -259,42 +395,89 @@
+ {
+ struct synaptics_data *priv = psmouse->private;
+
+- kfree(priv);
++ if (psmouse->type == PSMOUSE_SYNAPTICS && priv) {
++ synaptics_mode_cmd(psmouse, 0);
++ if (priv->ptport) {
++ serio_unregister_slave_port(priv->ptport);
++ kfree(priv->ptport);
++ }
++ kfree(priv);
++ }
+ }
+
+ /*****************************************************************************
+ * Functions to interpret the absolute mode packets
+ ****************************************************************************/
+
+-static void synaptics_parse_hw_state(struct synaptics_data *priv, struct synaptics_hw_state *hw)
++static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data *priv, struct synaptics_hw_state *hw)
+ {
+- unsigned char *buf = priv->proto_buf;
+-
+- hw->x = (((buf[3] & 0x10) << 8) |
+- ((buf[1] & 0x0f) << 8) |
+- buf[4]);
+- hw->y = (((buf[3] & 0x20) << 7) |
+- ((buf[1] & 0xf0) << 4) |
+- buf[5]);
+-
+- hw->z = buf[2];
+- hw->w = (((buf[0] & 0x30) >> 2) |
+- ((buf[0] & 0x04) >> 1) |
+- ((buf[3] & 0x04) >> 2));
+-
+- hw->left = (buf[0] & 0x01) ? 1 : 0;
+- hw->right = (buf[0] & 0x2) ? 1 : 0;
+ hw->up = 0;
+ hw->down = 0;
++ hw->b0 = 0;
++ hw->b1 = 0;
++ hw->b2 = 0;
++ hw->b3 = 0;
++ hw->b4 = 0;
++ hw->b5 = 0;
++ hw->b6 = 0;
++ hw->b7 = 0;
++
++ if (SYN_MODEL_NEWABS(priv->model_id)) {
++ hw->x = (((buf[3] & 0x10) << 8) |
++ ((buf[1] & 0x0f) << 8) |
++ buf[4]);
++ hw->y = (((buf[3] & 0x20) << 7) |
++ ((buf[1] & 0xf0) << 4) |
++ buf[5]);
++
++ hw->z = buf[2];
++ hw->w = (((buf[0] & 0x30) >> 2) |
++ ((buf[0] & 0x04) >> 1) |
++ ((buf[3] & 0x04) >> 2));
++
++ hw->left = (buf[0] & 0x01) ? 1 : 0;
++ hw->right = (buf[0] & 0x02) ? 1 : 0;
++ if (SYN_CAP_EXTENDED(priv->capabilities) &&
++ (SYN_CAP_FOUR_BUTTON(priv->capabilities))) {
++ hw->up = ((buf[3] & 0x01)) ? 1 : 0;
++ if (hw->left)
++ hw->up = !hw->up;
++ hw->down = ((buf[3] & 0x02)) ? 1 : 0;
++ if (hw->right)
++ hw->down = !hw->down;
++ }
++ if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) &&
++ ((buf[3] & 2) ? !hw->right : hw->right)) {
++ switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) {
++ default:
++ /*
++ * if nExtBtn is greater than 8 it should be
++ * considered invalid and treated as 0
++ */
++ break;
++ case 8:
++ hw->b7 = ((buf[5] & 0x08)) ? 1 : 0;
++ hw->b6 = ((buf[4] & 0x08)) ? 1 : 0;
++ case 6:
++ hw->b5 = ((buf[5] & 0x04)) ? 1 : 0;
++ hw->b4 = ((buf[4] & 0x04)) ? 1 : 0;
++ case 4:
++ hw->b3 = ((buf[5] & 0x02)) ? 1 : 0;
++ hw->b2 = ((buf[4] & 0x02)) ? 1 : 0;
++ case 2:
++ hw->b1 = ((buf[5] & 0x01)) ? 1 : 0;
++ hw->b0 = ((buf[4] & 0x01)) ? 1 : 0;
++ }
++ }
++ } else {
++ hw->x = (((buf[1] & 0x1f) << 8) | buf[2]);
++ hw->y = (((buf[4] & 0x1f) << 8) | buf[5]);
+
+- if (SYN_CAP_EXTENDED(priv->capabilities) &&
+- (SYN_CAP_FOUR_BUTTON(priv->capabilities))) {
+- hw->up = ((buf[3] & 0x01)) ? 1 : 0;
+- if (hw->left)
+- hw->up = !hw->up;
+- hw->down = ((buf[3] & 0x02)) ? 1 : 0;
+- if (hw->right)
+- hw->down = !hw->down;
++ hw->z = (((buf[0] & 0x30) << 2) | (buf[3] & 0x3F));
++ hw->w = (((buf[1] & 0x80) >> 4) | ((buf[0] & 0x04) >> 1));
++
++ hw->left = (buf[0] & 0x01) ? 1 : 0;
++ hw->right = (buf[0] & 0x02) ? 1 : 0;
+ }
+ }
+
+@@ -307,7 +490,7 @@
+ struct synaptics_data *priv = psmouse->private;
+ struct synaptics_hw_state hw;
+
+- synaptics_parse_hw_state(priv, &hw);
++ synaptics_parse_hw_state(psmouse->packet, priv, &hw);
+
+ if (hw.z > 0) {
+ int w_ok = 0;
+@@ -347,7 +530,28 @@
+ input_report_key(dev, BTN_RIGHT, hw.right);
+ input_report_key(dev, BTN_FORWARD, hw.up);
+ input_report_key(dev, BTN_BACK, hw.down);
+-
++ if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap))
++ switch(SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) {
++ default:
++ /*
++ * if nExtBtn is greater than 8 it should be considered
++ * invalid and treated as 0
++ */
++ break;
++ case 8:
++ input_report_key(dev, BTN_7, hw.b7);
++ input_report_key(dev, BTN_6, hw.b6);
++ case 6:
++ input_report_key(dev, BTN_5, hw.b5);
++ input_report_key(dev, BTN_4, hw.b4);
++ case 4:
++ input_report_key(dev, BTN_3, hw.b3);
++ input_report_key(dev, BTN_2, hw.b2);
++ case 2:
++ input_report_key(dev, BTN_1, hw.b1);
++ input_report_key(dev, BTN_0, hw.b0);
++ break;
++ }
+ input_sync(dev);
+ }
+
+@@ -355,35 +559,60 @@
+ {
+ struct input_dev *dev = &psmouse->dev;
+ struct synaptics_data *priv = psmouse->private;
+- unsigned char *pBuf = priv->proto_buf;
+- unsigned char u = psmouse->packet[0];
++ unsigned char data = psmouse->packet[psmouse->pktcnt - 1];
++ int newabs = SYN_MODEL_NEWABS(priv->model_id);
+
+ input_regs(dev, regs);
+
+- pBuf[priv->proto_buf_tail++] = u;
++ switch (psmouse->pktcnt) {
++ case 1:
++ if (newabs ? ((data & 0xC8) != 0x80) : ((data & 0xC0) != 0xC0)) {
++ printk(KERN_WARNING "Synaptics driver lost sync at 1st byte\n");
++ goto bad_sync;
++ }
++ break;
++ case 2:
++ if (!newabs && ((data & 0x60) != 0x00)) {
++ printk(KERN_WARNING "Synaptics driver lost sync at 2nd byte\n");
++ goto bad_sync;
++ }
++ break;
++ case 4:
++ if (newabs ? ((data & 0xC8) != 0xC0) : ((data & 0xC0) != 0x80)) {
++ printk(KERN_WARNING "Synaptics driver lost sync at 4th byte\n");
++ goto bad_sync;
++ }
++ break;
++ case 5:
++ if (!newabs && ((data & 0x60) != 0x00)) {
++ printk(KERN_WARNING "Synaptics driver lost sync at 5th byte\n");
++ goto bad_sync;
++ }
++ break;
++ default:
++ if (psmouse->pktcnt < 6)
++ break; /* Wait for full packet */
+
+- /* check first byte */
+- if ((priv->proto_buf_tail == 1) && ((u & 0xC8) != 0x80)) {
+- priv->inSync = 0;
+- priv->proto_buf_tail = 0;
+- printk(KERN_WARNING "Synaptics driver lost sync at 1st byte\n");
+- return;
+- }
+-
+- /* check 4th byte */
+- if ((priv->proto_buf_tail == 4) && ((u & 0xc8) != 0xc0)) {
+- priv->inSync = 0;
+- priv->proto_buf_tail = 0;
+- printk(KERN_WARNING "Synaptics driver lost sync at 4th byte\n");
+- return;
+- }
+-
+- if (priv->proto_buf_tail >= 6) { /* Full packet received */
+- if (!priv->inSync) {
+- priv->inSync = 1;
++ if (priv->out_of_sync) {
++ priv->out_of_sync = 0;
+ printk(KERN_NOTICE "Synaptics driver resynced.\n");
+ }
+- synaptics_process_packet(psmouse);
+- priv->proto_buf_tail = 0;
++
++ if (priv->ptport && synaptics_is_pt_packet(psmouse->packet))
++ synaptics_pass_pt_packet(priv->ptport, psmouse->packet);
++ else
++ synaptics_process_packet(psmouse);
++
++ psmouse->pktcnt = 0;
++ break;
++ }
++ return;
++
++ bad_sync:
++ priv->out_of_sync++;
++ psmouse->pktcnt = 0;
++ if (psmouse_resetafter > 0 && priv->out_of_sync == psmouse_resetafter) {
++ psmouse->state = PSMOUSE_IGNORE;
++ serio_rescan(psmouse->serio);
+ }
+ }
+Index: linux-2.6.0-test5/drivers/input/mouse/synaptics.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/mouse/synaptics.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/mouse/synaptics.h 2003-09-27 11:38:21.476263496 +0800
+@@ -12,6 +12,7 @@
+
+ extern void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs);
+ extern int synaptics_init(struct psmouse *psmouse);
++extern int synaptics_pt_init(struct psmouse *psmouse);
+ extern void synaptics_disconnect(struct psmouse *psmouse);
+
+ /* synaptics queries */
+@@ -22,12 +23,14 @@
+ #define SYN_QUE_SERIAL_NUMBER_PREFIX 0x06
+ #define SYN_QUE_SERIAL_NUMBER_SUFFIX 0x07
+ #define SYN_QUE_RESOLUTION 0x08
++#define SYN_QUE_EXT_CAPAB 0x09
+
+ /* synatics modes */
+ #define SYN_BIT_ABSOLUTE_MODE (1 << 7)
+ #define SYN_BIT_HIGH_RATE (1 << 6)
+ #define SYN_BIT_SLEEP_MODE (1 << 3)
+ #define SYN_BIT_DISABLE_GESTURE (1 << 2)
++#define SYN_BIT_FOUR_BYTE_CLIENT (1 << 1)
+ #define SYN_BIT_W_MODE (1 << 0)
+
+ /* synaptics model ID bits */
+@@ -42,11 +45,14 @@
+
+ /* synaptics capability bits */
+ #define SYN_CAP_EXTENDED(c) ((c) & (1 << 23))
++#define SYN_CAP_PASS_THROUGH(c) ((c) & (1 << 7))
+ #define SYN_CAP_SLEEP(c) ((c) & (1 << 4))
+ #define SYN_CAP_FOUR_BUTTON(c) ((c) & (1 << 3))
+ #define SYN_CAP_MULTIFINGER(c) ((c) & (1 << 1))
+ #define SYN_CAP_PALMDETECT(c) ((c) & (1 << 0))
+ #define SYN_CAP_VALID(c) ((((c) & 0x00ff00) >> 8) == 0x47)
++#define SYN_EXT_CAP_REQUESTS(c) ((((c) & 0x700000) >> 20) == 1)
++#define SYN_CAP_MULTI_BUTTON_NO(ec) (((ec) & 0x00f000) >> 12)
+
+ /* synaptics modes query bits */
+ #define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7))
+@@ -62,6 +68,10 @@
+ #define SYN_ID_MINOR(i) (((i) >> 16) & 0xff)
+ #define SYN_ID_IS_SYNAPTICS(i) ((((i) >> 8) & 0xff) == 0x47)
+
++/* synaptics special commands */
++#define SYN_PS_SET_MODE2 0x14
++#define SYN_PS_CLIENT_CMD 0x28
++
+ /*
+ * A structure to describe the state of the touchpad hardware (buttons and pad)
+ */
+@@ -75,21 +85,28 @@
+ int right;
+ int up;
+ int down;
++ int b0;
++ int b1;
++ int b2;
++ int b3;
++ int b4;
++ int b5;
++ int b6;
++ int b7;
+ };
+
+ struct synaptics_data {
+ /* Data read from the touchpad */
+ unsigned long int model_id; /* Model-ID */
+ unsigned long int capabilities; /* Capabilities */
++ unsigned long int ext_cap; /* Extended Capabilities */
+ unsigned long int identity; /* Identification */
+
+ /* Data for normal processing */
+- unsigned char proto_buf[6]; /* Buffer for Packet */
+- unsigned char last_byte; /* last received byte */
+- int inSync; /* Packets in sync */
+- int proto_buf_tail;
+-
++ unsigned int out_of_sync; /* # of packets out of sync */
+ int old_w; /* Previous w value */
++
++ struct serio *ptport; /* pass-through port */
+ };
+
+ #endif /* _SYNAPTICS_H */
+Index: linux-2.6.0-test5/drivers/input/serio/ambakmi.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/serio/ambakmi.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/serio/ambakmi.c 2003-09-27 11:38:21.478263192 +0800
+@@ -73,7 +73,7 @@
+ writeb(kmi->divisor, KMICLKDIV);
+ writeb(KMICR_EN, KMICR);
+
+- ret = request_irq(kmi->irq, amba_kmi_int, 0, kmi->io.phys, kmi);
++ ret = request_irq(kmi->irq, amba_kmi_int, 0, "kmi-pl050", kmi);
+ if (ret) {
+ printk(KERN_ERR "kmi: failed to claim IRQ%d\n", kmi->irq);
+ writeb(0, KMICR);
+@@ -108,11 +108,11 @@
+ kmi->io.write = amba_kmi_write;
+ kmi->io.open = amba_kmi_open;
+ kmi->io.close = amba_kmi_close;
+- kmi->io.name = dev->dev.name;
++ kmi->io.name = dev->dev.bus_id;
+ kmi->io.phys = dev->dev.bus_id;
+ kmi->io.driver = kmi;
+
+- kmi->res = request_mem_region(dev->res.start, KMI_SIZE, kmi->io.phys);
++ kmi->res = request_mem_region(dev->res.start, KMI_SIZE, "kmi-pl050");
+ if (!kmi->res) {
+ kfree(kmi);
+ return -EBUSY;
+@@ -147,14 +147,12 @@
+ return 0;
+ }
+
+-static int amba_kmi_resume(struct amba_device *dev, u32 level)
++static int amba_kmi_resume(struct amba_device *dev)
+ {
+ struct amba_kmi_port *kmi = amba_get_drvdata(dev);
+
+- if (level == RESUME_ENABLE) {
+- /* kick the serio layer to rescan this port */
+- serio_rescan(&kmi->io);
+- }
++ /* kick the serio layer to rescan this port */
++ serio_rescan(&kmi->io);
+
+ return 0;
+ }
+Index: linux-2.6.0-test5/drivers/input/serio/i8042.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/serio/i8042.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/serio/i8042.c 2003-09-27 11:38:21.485262128 +0800
+@@ -62,6 +62,7 @@
+ static unsigned char i8042_last_release;
+ static unsigned char i8042_mux_open;
+ struct timer_list i8042_timer;
++unsigned char i8042_history[16];
+
+ /*
+ * Shared IRQ's require a device pointer, but this driver doesn't support
+@@ -334,6 +335,14 @@
+ static char i8042_mux_short[4][16];
+ static char i8042_mux_phys[4][32];
+
++void dump_i8042_history(void) {
++ int i;
++ printk(KERN_WARNING "i8042 history: ");
++ for (i=0; i<sizeof(i8042_history); i++)
++ printk("%02x ", i8042_history[i]);
++ printk("\n");
++}
++
+ /*
+ * i8042_interrupt() is the most important function in this driver -
+ * it handles the interrupts from the i8042, and sends incoming bytes
+@@ -405,6 +414,8 @@
+ continue;
+ }
+
++ memmove(i8042_history, &i8042_history[1], sizeof(i8042_history)-1);
++ i8042_history[sizeof(i8042_history)-1] = data;
+ if (data > 0x7f) {
+ unsigned char index = (data & 0x7f) | (i8042_last_e0 << 7);
+ /* work around hardware that doubles key releases */
+Index: linux-2.6.0-test5/drivers/input/serio/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/serio/Kconfig 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/serio/Kconfig 2003-09-27 11:38:21.487261824 +0800
+@@ -2,7 +2,7 @@
+ # Input core configuration
+ #
+ config SERIO
+- tristate "Serial i/o support (needed for keyboard and mouse)"
++ tristate "Serial i/o support" if EMBEDDED || !X86
+ default y
+ ---help---
+ Say Yes here if you have any input device that uses serial I/O to
+@@ -21,7 +21,7 @@
+ config SERIO_I8042
+ tristate "i8042 PC Keyboard controller" if EMBEDDED || !X86
+ default y
+- depends on SERIO
++ select SERIO
+ ---help---
+ i8042 is the chip over which the standard AT keyboard and PS/2
+ mouse are connected to the computer. If you use these devices,
+Index: linux-2.6.0-test5/drivers/input/serio/serio.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/serio/serio.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/serio/serio.c 2003-09-27 11:38:21.490261368 +0800
+@@ -49,7 +49,9 @@
+
+ EXPORT_SYMBOL(serio_interrupt);
+ EXPORT_SYMBOL(serio_register_port);
++EXPORT_SYMBOL(serio_register_slave_port);
+ EXPORT_SYMBOL(serio_unregister_port);
++EXPORT_SYMBOL(serio_unregister_slave_port);
+ EXPORT_SYMBOL(serio_register_device);
+ EXPORT_SYMBOL(serio_unregister_device);
+ EXPORT_SYMBOL(serio_open);
+@@ -166,6 +168,17 @@
+ up(&serio_sem);
+ }
+
++/*
++ * Same as serio_register_port but does not try to acquire serio_sem.
++ * Should be used when registering a serio from other input device's
++ * connect() function.
++ */
++void serio_register_slave_port(struct serio *serio)
++{
++ list_add_tail(&serio->node, &serio_list);
++ serio_find_dev(serio);
++}
++
+ void serio_unregister_port(struct serio *serio)
+ {
+ down(&serio_sem);
+@@ -175,6 +188,18 @@
+ up(&serio_sem);
+ }
+
++/*
++ * Same as serio_unregister_port but does not try to acquire serio_sem.
++ * Should be used when unregistering a serio from other input device's
++ * disconnect() function.
++ */
++void serio_unregister_slave_port(struct serio *serio)
++{
++ list_del_init(&serio->node);
++ if (serio->dev && serio->dev->disconnect)
++ serio->dev->disconnect(serio);
++}
++
+ void serio_register_device(struct serio_dev *dev)
+ {
+ struct serio *serio;
+@@ -204,9 +229,11 @@
+ /* called from serio_dev->connect/disconnect methods under serio_sem */
+ int serio_open(struct serio *serio, struct serio_dev *dev)
+ {
+- if (serio->open(serio))
+- return -1;
+ serio->dev = dev;
++ if (serio->open(serio)) {
++ serio->dev = NULL;
++ return -1;
++ }
+ return 0;
+ }
+
+@@ -221,8 +248,7 @@
+ {
+ int pid;
+
+- pid = kernel_thread(serio_thread, NULL,
+- CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++ pid = kernel_thread(serio_thread, NULL, CLONE_KERNEL);
+
+ if (!pid) {
+ printk(KERN_WARNING "serio: Failed to start kseriod\n");
+Index: linux-2.6.0-test5/drivers/input/touchscreen/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/touchscreen/Kconfig 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/touchscreen/Kconfig 2003-09-27 11:38:21.491261216 +0800
+@@ -12,7 +12,8 @@
+
+ config TOUCHSCREEN_BITSY
+ tristate "Compaq iPAQ H3600 (Bitsy) touchscreen input driver"
+- depends on SA1100_BITSY && INPUT && INPUT_TOUCHSCREEN && SERIO
++ depends on SA1100_BITSY && INPUT && INPUT_TOUCHSCREEN
++ select SERIO
+ help
+ Say Y here if you have the h3600 (Bitsy) touchscreen.
+
+@@ -25,7 +26,8 @@
+
+ config TOUCHSCREEN_GUNZE
+ tristate "Gunze AHL-51S touchscreen"
+- depends on INPUT && INPUT_TOUCHSCREEN && SERIO
++ depends on INPUT && INPUT_TOUCHSCREEN
++ select SERIO
+ help
+ Say Y here if you have the Gunze AHL-51 touchscreen connected to
+ your system.
+Index: linux-2.6.0-test5/drivers/isdn/hardware/avm/avm_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/avm/avm_cs.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/avm/avm_cs.c 2003-09-27 11:38:21.496260456 +0800
+@@ -431,15 +431,6 @@
+
+ static void avmcs_release(dev_link_t *link)
+ {
+- /*
+- If the device is currently in use, we won't release until it
+- is actually closed.
+- */
+- if (link->open) {
+- link->state |= DEV_STALE_CONFIG;
+- return;
+- }
+-
+ b1pcmcia_delcard(link->io.BasePort1, link->irq.AssignedIRQ);
+
+ /* Unlink the device chain */
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/capifunc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/capifunc.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/capifunc.c 2003-09-27 11:38:21.506258936 +0800
+@@ -1,10 +1,10 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
+ *
+ * ISDN interface module for Eicon active cards DIVA.
+ * CAPI Interface common functions
+ *
+- * Copyright 2000-2002 by Armin Schindler (mac@melware.de)
+- * Copyright 2000-2002 Cytronics & Melware (info@melware.de)
++ * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
++ * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+@@ -25,10 +25,11 @@
+ DIVA_CAPI_ADAPTER *adapter = (DIVA_CAPI_ADAPTER *) NULL;
+ APPL *application = (APPL *) NULL;
+ byte max_appl = MAX_APPL;
++byte max_adapter = 0;
+ static CAPI_MSG *mapped_msg = (CAPI_MSG *) NULL;
+
+ byte UnMapController(byte);
+-char DRIVERRELEASE[32];
++char DRIVERRELEASE_CAPI[32];
+
+ extern void AutomaticLaw(DIVA_CAPI_ADAPTER *);
+ extern void callback(ENTITY *);
+@@ -45,7 +46,6 @@
+ static void DIRequest(ENTITY * e);
+ static DESCRIPTOR MAdapter;
+ static DESCRIPTOR DAdapter;
+-byte max_adapter = 0;
+ static byte ControllerMap[MAX_DESCRIPTORS + 1];
+
+
+@@ -59,16 +59,14 @@
+
+ extern void DIVA_DIDD_Read(DESCRIPTOR *, int);
+
+-static void no_printf(unsigned char *, ...);
+-
+-DIVA_DI_PRINTF dprintf = no_printf;
+-
+ /*
+ * debug
+ */
++static void no_printf(unsigned char *, ...);
+ #include "debuglib.c"
+ void xlog(char *x, ...)
+ {
++#ifndef DIVA_NO_DEBUGLIB
+ va_list ap;
+ if (myDriverDebugHandle.dbgMask & DL_XLOG) {
+ va_start(ap, x);
+@@ -81,6 +79,7 @@
+ }
+ va_end(ap);
+ }
++#endif
+ }
+
+ /*
+@@ -162,13 +161,14 @@
+ p = cards;
+ while (p) {
+ if (p->Id == num)
+- goto next_id;
++ break;
+ p = p->next;
+ }
++ if(!p) {
+ diva_os_leave_spin_lock(&ll_lock, &old_irql,
+ "find free id");
+ return (num);
+- next_id:
++ }
+ }
+ diva_os_leave_spin_lock(&ll_lock, &old_irql, "find free id");
+ return (999);
+@@ -315,10 +315,11 @@
+
+ /* if DATA_B3_IND, copy data too */
+ if (command == _DATA_B3_I) {
+- dword data = READ_DWORD(((byte *) & msg.info.data_b3_ind.Data));
++ dword data = READ_DWORD(&msg.info.data_b3_ind.Data);
+ memcpy(write + length, (void *) data, dlength);
+ }
+
++#ifndef DIVA_NO_DEBUGLIB
+ if (myDriverDebugHandle.dbgMask & DL_XLOG) {
+ switch (command) {
+ default:
+@@ -332,8 +333,8 @@
+ if (myDriverDebugHandle.dbgMask & DL_BLK) {
+ xlog("\x00\x02", &msg, 0x81, length);
+ for (i = 0; i < dlength; i += 256) {
+- DBG_BLK((((char *) msg.info.data_b3_ind.
+- Data) + i, ((dlength - i) < 256) ? (dlength - i) : 256))
++ DBG_BLK((((char *) READ_DWORD(&msg.info.data_b3_ind.Data)) + i,
++ ((dlength - i) < 256) ? (dlength - i) : 256))
+ if (!(myDriverDebugHandle.dbgMask & DL_PRV0))
+ break; /* not more if not explicitely requested */
+ }
+@@ -341,6 +342,7 @@
+ break;
+ }
+ }
++#endif
+
+ /* find the card structure for this controller */
+ if (!(card = find_card_by_ctrl(write[8] & 0x7f))) {
+@@ -719,7 +721,7 @@
+ }
+
+ /* profile information */
+- ctrl->profile.nbchannel = card->d.channels;
++ WRITE_WORD(&ctrl->profile.nbchannel, card->d.channels);
+ ctrl->profile.goptions = a->profile.Global_Options;
+ ctrl->profile.support1 = a->profile.B1_Protocols;
+ ctrl->profile.support2 = a->profile.B2_Protocols;
+@@ -745,17 +747,20 @@
+ {
+ APPL *this;
+ word bnum, xnum;
+- int i = 0, j = 0;
++ int i = 0;
++ unsigned char *p;
+ void *DataNCCI, *DataFlags, *ReceiveBuffer, *xbuffer_used;
+ void **xbuffer_ptr, **xbuffer_internal;
+ diva_os_spin_lock_magic_t old_irql;
++ unsigned int mem_len;
++
+
+ if (diva_os_in_irq()) {
+ DBG_ERR(("CAPI_REGISTER - in irq context !"))
+ return;
+ }
+
+- DBG_TRC(("application register"))
++ DBG_TRC(("application register Id=%d", appl))
+
+ if (appl > MAX_APPL) {
+ DBG_ERR(("CAPI_REGISTER - appl.Id exceeds MAX_APPL"))
+@@ -775,97 +780,47 @@
+ return; /* appl already registered */
+ }
+
+- if (!try_module_get(ctrl->owner)) {
+- printk(KERN_WARNING "%s: cannot reserve module\n", __FUNCTION__);
+- return;
+- }
+-
+ /* alloc memory */
+
+ bnum = rp->level3cnt * rp->datablkcnt;
+ xnum = rp->level3cnt * MAX_DATA_B3;
+
+- if (!(DataNCCI = diva_os_malloc(0, bnum * sizeof(word)))) {
+- DBG_ERR(("CAPI_REGISTER - memory allocation failed"))
+- module_put(ctrl->owner);
+- return;
+- }
+- memset(DataNCCI, 0, bnum * sizeof(word));
+-
+- if (!(DataFlags = diva_os_malloc(0, bnum * sizeof(word)))) {
+- DBG_ERR(("CAPI_REGISTER - memory allocation failed"))
+- diva_os_free(0, DataNCCI);
+- module_put(ctrl->owner);
+- return;
+- }
+- memset(DataFlags, 0, bnum * sizeof(word));
+-
+- if (!(ReceiveBuffer = diva_os_malloc(0, bnum * rp->datablklen))) {
+- DBG_ERR(("CAPI_REGISTER - memory allocation failed"))
+- diva_os_free(0, DataNCCI);
+- diva_os_free(0, DataFlags);
+- module_put(ctrl->owner);
+- return;
+- }
+- memset(ReceiveBuffer, 0, bnum * rp->datablklen);
+-
+- if (!(xbuffer_used = (byte *) diva_os_malloc(0, xnum))) {
+- DBG_ERR(("CAPI_REGISTER - memory allocation failed"))
+- diva_os_free(0, DataNCCI);
+- diva_os_free(0, DataFlags);
+- diva_os_free(0, ReceiveBuffer);
+- module_put(ctrl->owner);
+- return;
+- }
+- memset(xbuffer_used, 0, xnum);
++ mem_len = bnum * sizeof(word); /* DataNCCI */
++ mem_len += bnum * sizeof(word); /* DataFlags */
++ mem_len += bnum * rp->datablklen; /* ReceiveBuffer */
++ mem_len += xnum; /* xbuffer_used */
++ mem_len += xnum * sizeof(void *); /* xbuffer_ptr */
++ mem_len += xnum * sizeof(void *); /* xbuffer_internal */
++ mem_len += xnum * rp->datablklen; /* xbuffer_ptr[xnum] */
+
+- if (!(xbuffer_ptr = (void **) diva_os_malloc(0, xnum * sizeof(void *)))) {
++ if (!(p = diva_os_malloc(0, mem_len))) {
+ DBG_ERR(("CAPI_REGISTER - memory allocation failed"))
+- diva_os_free(0, DataNCCI);
+- diva_os_free(0, DataFlags);
+- diva_os_free(0, ReceiveBuffer);
+- diva_os_free(0, xbuffer_used);
+- module_put(ctrl->owner);
+ return;
+ }
+- memset(xbuffer_ptr, 0, xnum * sizeof(void *));
+-
+- if (!(xbuffer_internal = (void **) diva_os_malloc(0, xnum * sizeof(void *)))) {
+- DBG_ERR(("CAPI_REGISTER - memory allocation failed"))
+- diva_os_free(0, DataNCCI);
+- diva_os_free(0, DataFlags);
+- diva_os_free(0, ReceiveBuffer);
+- diva_os_free(0, xbuffer_used);
+- diva_os_free(0, xbuffer_ptr);
+- module_put(ctrl->owner);
+- return;
+- }
+- memset(xbuffer_internal, 0, xnum * sizeof(void *));
++ memset(p, 0, mem_len);
+
++ DataNCCI = (void *)p;
++ p += bnum * sizeof(word);
++ DataFlags = (void *)p;
++ p += bnum * sizeof(word);
++ ReceiveBuffer = (void *)p;
++ p += bnum * rp->datablklen;
++ xbuffer_used = (void *)p;
++ p += xnum;
++ xbuffer_ptr = (void **)p;
++ p += xnum * sizeof(void *);
++ xbuffer_internal = (void **)p;
++ p += xnum * sizeof(void *);
+ for (i = 0; i < xnum; i++) {
+- xbuffer_ptr[i] = diva_os_malloc(0, rp->datablklen);
+- if (!xbuffer_ptr[i]) {
+- DBG_ERR(("CAPI_REGISTER - memory allocation failed"))
+- if (i) {
+- for (j = 0; j < i; j++)
+- if (xbuffer_ptr[j])
+- diva_os_free(0, xbuffer_ptr [j]);
+- }
+- diva_os_free(0, DataNCCI);
+- diva_os_free(0, DataFlags);
+- diva_os_free(0, ReceiveBuffer);
+- diva_os_free(0, xbuffer_used);
+- diva_os_free(0, xbuffer_ptr);
+- diva_os_free(0, xbuffer_internal);
+- module_put(ctrl->owner);
+- return;
+- }
++ xbuffer_ptr[i] = (void *)p;
++ p += rp->datablklen;
+ }
+
+ DBG_LOG(("CAPI_REGISTER - Id = %d", appl))
+ DBG_LOG((" MaxLogicalConnections = %d", rp->level3cnt))
+ DBG_LOG((" MaxBDataBuffers = %d", rp->datablkcnt))
+ DBG_LOG((" MaxBDataLength = %d", rp->datablklen))
++ DBG_LOG((" Allocated Memory = %d", mem_len))
+
+ /* initialize application data */
+ diva_os_enter_spin_lock(&api_lock, &old_irql, "register_appl");
+@@ -875,9 +830,6 @@
+
+ this->Id = appl;
+
+- /* We do not need a list */
+- /* InitializeListHead(&this->s_function); */
+-
+ for (i = 0; i < max_adapter; i++) {
+ adapter[i].CIP_Mask[appl - 1] = 0;
+ }
+@@ -911,41 +863,24 @@
+ {
+ diva_os_spin_lock_magic_t old_irql;
+ APPL *this = &application[appl - 1];
+- int i = 0;
++
++ DBG_TRC(("application %d(%d) cleanup", this->Id, appl))
+
+ if (diva_os_in_irq()) {
+ DBG_ERR(("CAPI_RELEASE - in irq context !"))
+ return;
+ }
+- if (this->Id) {
+- DBG_TRC(("application %d cleanup", this->Id))
+- }
+
+ diva_os_enter_spin_lock(&api_lock, &old_irql, "release_appl");
+ if (this->Id) {
+ CapiRelease(this->Id);
+ if (this->DataNCCI)
+ diva_os_free(0, this->DataNCCI);
+- if (this->DataFlags)
+- diva_os_free(0, this->DataFlags);
+- if (this->ReceiveBuffer)
+- diva_os_free(0, this->ReceiveBuffer);
+- if (this->xbuffer_ptr) {
+- for (i = 0; i < (MAX_DATA_B3 * this->MaxNCCI); i++) {
+- if (this->xbuffer_ptr[i])
+- diva_os_free(0, this->xbuffer_ptr[i]);
+- }
+- diva_os_free(0, this->xbuffer_ptr);
+- }
+- if (this->xbuffer_internal)
+- diva_os_free(0, this->xbuffer_internal);
+- if (this->xbuffer_used)
+- diva_os_free(0, this->xbuffer_used);
++ this->DataNCCI = NULL;
+ this->Id = 0;
+ }
+ diva_os_leave_spin_lock(&api_lock, &old_irql, "release_appl");
+
+- module_put(ctrl->owner);
+ }
+
+ /*
+@@ -954,7 +889,7 @@
+ static u16 diva_send_message(struct capi_ctr *ctrl,
+ diva_os_message_buffer_s * dmb)
+ {
+- int i = 0, j = 0;
++ int i = 0;
+ word ret = 0;
+ diva_os_spin_lock_magic_t old_irql;
+ CAPI_MSG *msg = (CAPI_MSG *) DIVA_MESSAGE_BUFFER_DATA(dmb);
+@@ -971,6 +906,10 @@
+ }
+ DBG_PRV1(("Write - appl = %d, cmd = 0x%x", this->Id, command))
+
++ if (!this->Id) {
++ return CAPI_ILLAPPNR;
++ }
++
+ /* patch controller number */
+ msg->header.controller = ControllerMap[card->Id]
+ | (msg->header.controller & 0x80); /* preserve external controller bit */
+@@ -983,13 +922,17 @@
+ break;
+
+ case _DATA_B3_I | RESPONSE:
++#ifndef DIVA_NO_DEBUGLIB
+ if (myDriverDebugHandle.dbgMask & DL_BLK)
+ xlog("\x00\x02", msg, 0x80, clength);
++#endif
+ break;
+
+ case _DATA_B3_R:
++#ifndef DIVA_NO_DEBUGLIB
+ if (myDriverDebugHandle.dbgMask & DL_BLK)
+ xlog("\x00\x02", msg, 0x80, clength);
++#endif
+
+ if (clength == 24)
+ clength = 22; /* workaround for PPcom bug */
+@@ -1016,8 +959,10 @@
+ memcpy(this->xbuffer_ptr[i], &((__u8 *) msg)[clength],
+ READ_WORD(&msg->info.data_b3_req.Data_Length));
+
++#ifndef DIVA_NO_DEBUGLIB
+ if ((myDriverDebugHandle.dbgMask & DL_BLK)
+ && (myDriverDebugHandle.dbgMask & DL_XLOG)) {
++ int j;
+ for (j = 0; j <
+ READ_WORD(&msg->info.data_b3_req.Data_Length);
+ j += 256) {
+@@ -1028,6 +973,7 @@
+ break; /* not more if not explicitely requested */
+ }
+ }
++#endif
+ break;
+ }
+
+@@ -1091,7 +1037,7 @@
+ } else {
+ memcpy(&MAdapter, adapter, sizeof(MAdapter));
+ dprintf = (DIVA_DI_PRINTF) MAdapter.request;
+- DbgRegister("CAPI20", DRIVERRELEASE, DBG_DEFAULT);
++ DbgRegister("CAPI20", DRIVERRELEASE_CAPI, DBG_DEFAULT);
+ }
+ } else if ((adapter->type > 0) && (adapter->type < 16)) { /* IDI Adapter */
+ if (removal) {
+@@ -1119,7 +1065,7 @@
+ if (DIDD_Table[x].type == IDI_DIMAINT) { /* MAINT found */
+ memcpy(&MAdapter, &DIDD_Table[x], sizeof(DAdapter));
+ dprintf = (DIVA_DI_PRINTF) MAdapter.request;
+- DbgRegister("CAPI20", DRIVERRELEASE, DBG_DEFAULT);
++ DbgRegister("CAPI20", DRIVERRELEASE_CAPI, DBG_DEFAULT);
+ break;
+ }
+ }
+@@ -1130,7 +1076,7 @@
+ req.didd_notify.e.Req = 0;
+ req.didd_notify.e.Rc =
+ IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
+- req.didd_notify.info.callback = didd_callback;
++ req.didd_notify.info.callback = (void *)didd_callback;
+ req.didd_notify.info.context = 0;
+ DAdapter.request((ENTITY *) & req);
+ if (req.didd_notify.e.Rc != 0xff) {
+@@ -1260,4 +1206,7 @@
+ divacapi_remove_cards();
+
+ remove_main_structs();
++
++ diva_os_destroy_spin_lock(&api_lock, "capifunc");
++ diva_os_destroy_spin_lock(&ll_lock, "capifunc");
+ }
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/capifunc.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/capifunc.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/capifunc.h 2003-09-27 11:38:21.507258784 +0800
+@@ -1,10 +1,10 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
+ *
+ * ISDN interface module for Eicon active cards DIVA.
+ * CAPI Interface common functions
+ *
+- * Copyright 2000-2002 by Armin Schindler (mac@melware.de)
+- * Copyright 2000-2002 Cytronics & Melware (info@melware.de)
++ * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
++ * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+@@ -21,7 +21,7 @@
+
+ #define M_COMPANY "Eicon Networks"
+
+-extern char DRIVERRELEASE[];
++extern char DRIVERRELEASE_CAPI[];
+
+ typedef struct _diva_card {
+ int Id;
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/capimain.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/capimain.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/capimain.c 2003-09-27 11:38:21.509258480 +0800
+@@ -1,10 +1,10 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
+ *
+ * ISDN interface module for Eicon active cards DIVA.
+ * CAPI Interface
+ *
+- * Copyright 2000-2002 by Armin Schindler (mac@melware.de)
+- * Copyright 2000-2002 Cytronics & Melware (info@melware.de)
++ * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
++ * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+@@ -15,10 +15,7 @@
+ #include <linux/init.h>
+ #include <asm/uaccess.h>
+ #include <linux/smp_lock.h>
+-#include <linux/vmalloc.h>
+-#include <linux/sched.h>
+ #include <linux/skbuff.h>
+-#include <linux/delay.h>
+
+ #include "os_capi.h"
+
+@@ -29,7 +26,7 @@
+ #include "cp_vers.h"
+ #include "capifunc.h"
+
+-static char *main_revision = "$Revision: 1.1.4.1 $";
++static char *main_revision = "$Revision: 1.1.4.1 $";
+ static char *DRIVERNAME =
+ "Eicon DIVA - CAPI Interface driver (http://www.melware.net)";
+ static char *DRIVERLNAME = "divacapi";
+@@ -57,47 +54,6 @@
+ }
+
+ /*
+- * sleep for some milliseconds
+- */
+-void diva_os_sleep(dword mSec)
+-{
+- unsigned long timeout = HZ * mSec / 1000 + 1;
+-
+- set_current_state(TASK_UNINTERRUPTIBLE);
+- schedule_timeout(timeout);
+-}
+-
+-/*
+- * wait for some milliseconds
+- */
+-void diva_os_wait(dword mSec)
+-{
+- mdelay(mSec);
+-}
+-
+-/*
+- * alloc memory
+- */
+-void *diva_os_malloc(unsigned long flags, unsigned long size)
+-{
+- void *ret = NULL;
+- if (size) {
+- ret = (void *) vmalloc((unsigned int) size);
+- }
+- return (ret);
+-}
+-
+-/*
+- * free memory
+- */
+-void diva_os_free(unsigned long unused, void *ptr)
+-{
+- if (ptr) {
+- vfree(ptr);
+- }
+-}
+-
+-/*
+ * alloc a message buffer
+ */
+ diva_os_message_buffer_s *diva_os_alloc_message_buffer(unsigned long size,
+@@ -160,11 +116,11 @@
+ char tmprev[32];
+ int ret = 0;
+
+- sprintf(DRIVERRELEASE, "%d.%d%s", DRRELMAJOR, DRRELMINOR,
++ sprintf(DRIVERRELEASE_CAPI, "%d.%d%s", DRRELMAJOR, DRRELMINOR,
+ DRRELEXTRA);
+
+ printk(KERN_INFO "%s\n", DRIVERNAME);
+- printk(KERN_INFO "%s: Rel:%s Rev:", DRIVERLNAME, DRIVERRELEASE);
++ printk(KERN_INFO "%s: Rel:%s Rev:", DRIVERLNAME, DRIVERRELEASE_CAPI);
+ strcpy(tmprev, main_revision);
+ printk("%s Build: %s(%s)\n", getrev(tmprev),
+ diva_capi_common_code_build, DIVA_BUILD);
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/dadapter.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/dadapter.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/dadapter.c 2003-09-27 11:38:21.513257872 +0800
+@@ -49,8 +49,21 @@
+ Shadow IDI_DIMAINT
+ and 'shadow' debug stuff
+ -------------------------------------------------------------------------- */
+-static void no_printf (unsigned char * format, ...) { }
+-DIVA_DI_PRINTF dprintf = no_printf;
++static void no_printf (unsigned char * format, ...)
++{
++#ifdef EBUG
++ va_list ap;
++ va_start (ap, format);
++ debug((format, ap));
++ va_end (ap);
++#endif
++}
++
++/* -------------------------------------------------------------------------
++ Portable debug Library
++ ------------------------------------------------------------------------- */
++#include "debuglib.c"
++
+ static DESCRIPTOR MAdapter = {IDI_DIMAINT, /* Adapter Type */
+ 0x00, /* Channels */
+ 0x0000, /* Features */
+@@ -86,6 +99,7 @@
+ Should be called as last step, if driver does unload
+ -------------------------------------------------------------------------- */
+ void diva_didd_load_time_finit (void) {
++ diva_os_destroy_spin_lock (&didd_spin, "didd");
+ }
+ /* --------------------------------------------------------------------------
+ Called in order to register new adapter in adapter array
+@@ -349,7 +363,4 @@
+ int length) {
+ diva_didd_read_adapter_array (buffer, length);
+ }
+-/* -------------------------------------------------------------------------
+- Portable debug Library
+- ------------------------------------------------------------------------- */
+-#include "debuglib.c"
++
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/debug.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/debug.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/debug.c 2003-09-27 11:38:21.529255440 +0800
+@@ -2,7 +2,6 @@
+ #include "pc.h"
+ #include "di_defs.h"
+ #include "debug_if.h"
+-#include "linux/kernel.h"
+ #include "divasync.h"
+ #include "kst_ifc.h"
+ #include "maintidi.h"
+@@ -96,9 +95,9 @@
+
+ static byte *queueAllocMsg (MSG_QUEUE *Q, word size) {
+ /* Allocate 'size' bytes at tail of queue which will be filled later
+- * directly whith callers own message header info and/or message.
++ * directly with callers own message header info and/or message.
+ * An 'alloced' message is marked incomplete by oring the 'Size' field
+- * whith MSG_INCOMPLETE.
++ * with MSG_INCOMPLETE.
+ * This must be reset via queueCompleteMsg() after the message is filled.
+ * As long as a message is marked incomplete queuePeekMsg() will return
+ * a 'queue empty' condition when it reaches such a message. */
+@@ -160,7 +159,7 @@
+ }
+
+ static byte *queuePeekMsg (MSG_QUEUE *Q, word *size) {
+- /* Show the first valid message in queue BUT DONT free the message.
++ /* Show the first valid message in queue BUT DON'T free the message.
+ * After looking on the message contents it can be freed queueFreeMsg()
+ * or simply remain in message queue. */
+
+@@ -195,7 +194,7 @@
+ length: length of the message queue
+ do_init: perfor queue reset
+
+- return: zero on sucess, -1 on error
++ return: zero on success, -1 on error
+ */
+ int diva_maint_init (byte* base, unsigned long length, int do_init) {
+ if (dbg_queue || (!base) || (length < (4096*4))) {
+@@ -296,7 +295,7 @@
+
+ /*
+ INTERFACE:
+- Lock messafe queue and return the pointer to the first
++ Lock message queue and return the pointer to the first
+ entry.
+ */
+ diva_dbg_entry_head_t* diva_maint_get_message (word* size,
+@@ -725,12 +724,12 @@
+
+ if (clients[id].hDbg) {
+ *p++ = 1;
+- *p++ = (byte)clients[id].sec; /* save secounds */
++ *p++ = (byte)clients[id].sec; /* save seconds */
+ *p++ = (byte)(clients[id].sec >> 8);
+ *p++ = (byte)(clients[id].sec >> 16);
+ *p++ = (byte)(clients[id].sec >> 24);
+
+- *p++ = (byte)(clients[id].usec/1000); /* save msecounds */
++ *p++ = (byte)(clients[id].usec/1000); /* save mseconds */
+ *p++ = (byte)((clients[id].usec/1000) >> 8);
+ *p++ = (byte)((clients[id].usec/1000) >> 16);
+ *p++ = (byte)((clients[id].usec/1000) >> 24);
+@@ -1079,7 +1078,7 @@
+ }
+
+ /* ----------------------------------------------------------------
+- Low level interface for management interace client
++ Low level interface for management interface client
+ ---------------------------------------------------------------- */
+ /*
+ Return handle to client structure
+@@ -1462,7 +1461,7 @@
+ case DIVA_SUPER_TRACE_NOTIFY_STAT_CHANGE:
+ if (pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_STATISTICS) {
+ /*
+- Incoming Statistices
++ Incoming Statistics
+ */
+ if (channel->pInterfaceStat->inc.Calls) {
+ diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
+@@ -1498,7 +1497,7 @@
+ }
+
+ /*
+- Outgoing Statistices
++ Outgoing Statistics
+ */
+ if (channel->pInterfaceStat->outg.Calls) {
+ diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/debuglib.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/debuglib.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/debuglib.c 2003-09-27 11:38:21.532254984 +0800
+@@ -23,8 +23,15 @@
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
++
+ #include "debuglib.h"
++
++#ifdef DIVA_NO_DEBUGLIB
++static DIVA_DI_PRINTF dprintf;
++#else /* DIVA_NO_DEBUGLIB */
++
+ _DbgHandle_ myDriverDebugHandle = { 0 /*!Registered*/, DBG_HANDLE_VERSION };
++DIVA_DI_PRINTF dprintf = no_printf;
+ /*****************************************************************************/
+ #define DBG_FUNC(name) \
+ void \
+@@ -146,3 +153,4 @@
+ va_end(ap);
+ }
+ /*****************************************************************************/
++#endif /* DIVA_NO_DEBUGLIB */
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/debuglib.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/debuglib.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/debuglib.h 2003-09-27 11:38:21.535254528 +0800
+@@ -101,6 +101,34 @@
+ * with _KERNEL_DBG_PRINT_
+ */
+ #define DL_TO_KERNEL 0x40000000
++
++#ifdef DIVA_NO_DEBUGLIB
++#define myDbgPrint_LOG(x,...) do { } while(0);
++#define myDbgPrint_FTL(x,...) do { } while(0);
++#define myDbgPrint_ERR(x,...) do { } while(0);
++#define myDbgPrint_TRC(x,...) do { } while(0);
++#define myDbgPrint_MXLOG(x,...) do { } while(0);
++#define myDbgPrint_EVL(x,...) do { } while(0);
++#define myDbgPrint_REG(x,...) do { } while(0);
++#define myDbgPrint_MEM(x,...) do { } while(0);
++#define myDbgPrint_SPL(x,...) do { } while(0);
++#define myDbgPrint_IRP(x,...) do { } while(0);
++#define myDbgPrint_TIM(x,...) do { } while(0);
++#define myDbgPrint_BLK(x,...) do { } while(0);
++#define myDbgPrint_TAPI(x,...) do { } while(0);
++#define myDbgPrint_NDIS(x,...) do { } while(0);
++#define myDbgPrint_CONN(x,...) do { } while(0);
++#define myDbgPrint_STAT(x,...) do { } while(0);
++#define myDbgPrint_SEND(x,...) do { } while(0);
++#define myDbgPrint_RECV(x,...) do { } while(0);
++#define myDbgPrint_PRV0(x,...) do { } while(0);
++#define myDbgPrint_PRV1(x,...) do { } while(0);
++#define myDbgPrint_PRV2(x,...) do { } while(0);
++#define myDbgPrint_PRV3(x,...) do { } while(0);
++#define DBG_TEST(func,args) do { } while(0);
++#define DBG_EVL_ID(args) do { } while(0);
++
++#else /* DIVA_NO_DEBUGLIB */
+ /*
+ * define low level macros for formatted & raw debugging
+ */
+@@ -156,6 +184,9 @@
+ { if ( (myDriverDebugHandle.dbgMask) & (unsigned long)DL_EVL ) \
+ { myDbgPrint_EVL args ; \
+ } }
++
++#endif /* DIVA_NO_DEBUGLIB */
++
+ #define DBG_LOG(args) DBG_TEST(LOG, args)
+ #define DBG_FTL(args) DBG_TEST(FTL, args)
+ #define DBG_ERR(args) DBG_TEST(ERR, args)
+@@ -182,9 +213,16 @@
+ /*
+ * prototypes for debug register/deregister functions in "debuglib.c"
+ */
++#ifdef DIVA_NO_DEBUGLIB
++#define DbgRegister(name,tag, mask) do { } while(0)
++#define DbgDeregister() do { } while(0)
++#define DbgSetLevel(mask) do { } while(0)
++#else
++extern DIVA_DI_PRINTF dprintf;
+ extern int DbgRegister (char *drvName, char *drvTag, unsigned long dbgMask) ;
+ extern void DbgDeregister (void) ;
+ extern void DbgSetLevel (unsigned long dbgMask) ;
++#endif
+ /*
+ * driver internal structure for debug handling;
+ * in client drivers this structure is maintained in "debuglib.c",
+@@ -274,9 +312,11 @@
+ } CardTrace;
+ } u1;
+ } _DbgExtendedInfo_;
++#ifndef DIVA_NO_DEBUGLIB
+ /* -------------------------------------------------------------
+ Function used for xlog-style debug
+ ------------------------------------------------------------- */
+ #define XDI_USE_XLOG 1
+ void xdi_dbg_xlog (char* x, ...);
++#endif /* DIVA_NO_DEBUGLIB */
+ #endif /* __DEBUGLIB_H__ */
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/di.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/di.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/di.c 2003-09-27 11:38:21.545253008 +0800
+@@ -112,16 +112,14 @@
+ #ifdef USE_EXTENDED_DEBUGS
+ if ( !this )
+ {
+- ISDN_ADAPTER *io = (ISDN_ADAPTER *)a->io ;
+ DBG_FTL(("XDI: [%02x] !A%d ==> NULL entity ptr - try to ignore",
+- xdi_xlog_sec++, (int)io->ANum))
++ xdi_xlog_sec++, (int)((ISDN_ADAPTER *)a->io)->ANum))
+ e_no = look_req(a) ;
+ ReadyCount-- ;
+ continue ;
+ }
+ {
+- ISDN_ADAPTER *io = (ISDN_ADAPTER *)a->io ;
+- DBG_TRC((">A%d Id=0x%x Req=0x%x", io->ANum, this->Id, this->Req))
++ DBG_TRC((">A%d Id=0x%x Req=0x%x", ((ISDN_ADAPTER *)a->io)->ANum, this->Id, this->Req))
+ }
+ #else
+ dbug(dprintf("out:Req=%x,Id=%x,Ch=%x",this->Req,this->Id,this->ReqCh));
+@@ -563,8 +561,7 @@
+ int cancel_rc;
+ #ifdef USE_EXTENDED_DEBUGS
+ {
+- ISDN_ADAPTER *io = (ISDN_ADAPTER *)a->io ;
+- DBG_TRC(("<A%d Id=0x%x Rc=0x%x", io->ANum, Id, Rc))
++ DBG_TRC(("<A%d Id=0x%x Rc=0x%x", ((ISDN_ADAPTER *)a->io)->ANum, Id, Rc))
+ }
+ #else
+ dbug(dprintf("isdn_rc(Rc=%x,Id=%x,Ch=%x)",Rc,Id,Ch));
+@@ -767,8 +764,7 @@
+ byte* cma = 0;
+ #ifdef USE_EXTENDED_DEBUGS
+ {
+- ISDN_ADAPTER *io = (ISDN_ADAPTER *)a->io ;
+- DBG_TRC(("<A%d Id=0x%x Ind=0x%x", io->ANum, Id, Ind))
++ DBG_TRC(("<A%d Id=0x%x Ind=0x%x", ((ISDN_ADAPTER *)a->io)->ANum, Id, Ind))
+ }
+ #else
+ dbug(dprintf("isdn_ind(Ind=%x,Id=%x,Ch=%x)",Ind,Id,Ch));
+@@ -956,10 +952,10 @@
+ byte Id, byte Ch, byte Rc, byte cb, byte type) {
+ #if defined(XDI_USE_XLOG)
+ word LogInfo[4];
+- LogInfo[0] = (word)Adapter | (word)(xdi_xlog_sec++ << 8);
+- LogInfo[1] = (word)Id | (word)(Ch << 8);
+- LogInfo[2] = (word)Rc | (word)(type << 8);
+- LogInfo[3] = cb;
++ WRITE_WORD(&LogInfo[0], ((word)Adapter | (word)(xdi_xlog_sec++ << 8)));
++ WRITE_WORD(&LogInfo[1], ((word)Id | (word)(Ch << 8)));
++ WRITE_WORD(&LogInfo[2], ((word)Rc | (word)(type << 8)));
++ WRITE_WORD(&LogInfo[3], cb);
+ xdi_xlog ((byte*)&LogInfo[0], 221, sizeof(LogInfo));
+ #endif
+ }
+@@ -980,9 +976,9 @@
+ byte Ch, byte Req, byte type) {
+ #if defined(XDI_USE_XLOG)
+ word LogInfo[3];
+- LogInfo[0] = (word)Adapter | (word)(xdi_xlog_sec++ << 8);
+- LogInfo[1] = (word)Id | (word)(Ch << 8);
+- LogInfo[2] = (word)Req | (word)(type << 8);
++ WRITE_WORD(&LogInfo[0], ((word)Adapter | (word)(xdi_xlog_sec++ << 8)));
++ WRITE_WORD(&LogInfo[1], ((word)Id | (word)(Ch << 8)));
++ WRITE_WORD(&LogInfo[2], ((word)Req | (word)(type << 8)));
+ xdi_xlog ((byte*)&LogInfo[0], 220, sizeof(LogInfo));
+ #endif
+ }
+@@ -1024,10 +1020,10 @@
+ byte type) {
+ #if defined(XDI_USE_XLOG)
+ word LogInfo[4];
+- LogInfo[0] = (word)Adapter | (word)(xdi_xlog_sec++ << 8);
+- LogInfo[1] = (word)Id | (word)(Ch << 8);
+- LogInfo[2] = (word)Ind | (word)(type << 8);
+- LogInfo[3] = (word)rnr | (word)(rnr_valid << 8);
++ WRITE_WORD(&LogInfo[0], ((word)Adapter | (word)(xdi_xlog_sec++ << 8)));
++ WRITE_WORD(&LogInfo[1], ((word)Id | (word)(Ch << 8)));
++ WRITE_WORD(&LogInfo[2], ((word)Ind | (word)(type << 8)));
++ WRITE_WORD(&LogInfo[3], ((word)rnr | (word)(rnr_valid << 8)));
+ xdi_xlog ((byte*)&LogInfo[0], 222, sizeof(LogInfo));
+ #endif
+ }
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/diddfunc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/diddfunc.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/diddfunc.c 2003-09-27 11:38:21.547252704 +0800
+@@ -1,11 +1,11 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
+ *
+ * DIDD Interface module for Eicon active cards.
+ *
+ * Functions are in dadapter.c
+ *
+- * Copyright 2002 by Armin Schindler (mac@melware.de)
+- * Copyright 2002 Cytronics & Melware (info@melware.de)
++ * Copyright 2002-2003 by Armin Schindler (mac@melware.de)
++ * Copyright 2002-2003 Cytronics & Melware (info@melware.de)
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+@@ -23,7 +23,7 @@
+
+
+ extern void DIVA_DIDD_Read(void *, int);
+-extern char *DRIVERRELEASE;
++extern char *DRIVERRELEASE_DIDD;
+ static dword notify_handle;
+ static DESCRIPTOR _DAdapter;
+
+@@ -40,7 +40,7 @@
+ if (removal) {
+ DbgDeregister();
+ } else {
+- DbgRegister("DIDD", DRIVERRELEASE, DBG_DEFAULT);
++ DbgRegister("DIDD", DRIVERRELEASE_DIDD, DBG_DEFAULT);
+ }
+ }
+ return (NULL);
+@@ -65,14 +65,14 @@
+ req.didd_notify.e.Req = 0;
+ req.didd_notify.e.Rc =
+ IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
+- req.didd_notify.info.callback = didd_callback;
++ req.didd_notify.info.callback = (void *)didd_callback;
+ req.didd_notify.info.context = 0;
+ _DAdapter.request((ENTITY *) & req);
+ if (req.didd_notify.e.Rc != 0xff)
+ return (0);
+ notify_handle = req.didd_notify.info.handle;
+ } else if (DIDD_Table[x].type == IDI_DIMAINT) { /* MAINT found */
+- DbgRegister("DIDD", DRIVERRELEASE, DBG_DEFAULT);
++ DbgRegister("DIDD", DRIVERRELEASE_DIDD, DBG_DEFAULT);
+ }
+ }
+ return (dadapter);
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/diva.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/diva.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/diva.c 2003-09-27 11:38:21.553251792 +0800
+@@ -1,4 +1,4 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
+
+ #define CARDTYPE_H_WANT_DATA 1
+ #define CARDTYPE_H_WANT_IDI_DATA 0
+@@ -7,7 +7,6 @@
+
+ #include "platform.h"
+ #include "debuglib.h"
+-#include "diva_pci.h"
+ #include "cardtype.h"
+ #include "dlist.h"
+ #include "pc.h"
+@@ -15,19 +14,17 @@
+ #include "di.h"
+ #include "io.h"
+ #include "pc_maint.h"
+-
+ #include "xdi_msg.h"
+ #include "xdi_adapter.h"
++#include "diva_pci.h"
+ #include "diva.h"
+
+ #ifdef CONFIG_ISDN_DIVAS_PRIPCI
+ #include "os_pri.h"
+ #endif
+-#ifdef CONFIG_ISDN_DIVAS_4BRIPCI
+-#include "os_4bri.h"
+-#endif
+ #ifdef CONFIG_ISDN_DIVAS_BRIPCI
+ #include "os_bri.h"
++#include "os_4bri.h"
+ #endif
+
+ PISDN_ADAPTER IoAdapters[MAX_ADAPTER];
+@@ -78,6 +75,11 @@
+ struct pt_regs;
+
+ /*
++ * include queue functions
++ */
++#include "dlist.c"
++
++/*
+ ** LOCALS
+ */
+ diva_entity_queue_t adapter_queue;
+@@ -109,7 +111,7 @@
+ */
+ {CARDTYPE_DIVASRV_VOICE_P_30M_V2_PCI, diva_pri_init_card},
+ #endif
+-#ifdef CONFIG_ISDN_DIVAS_4BRIPCI
++#ifdef CONFIG_ISDN_DIVAS_BRIPCI
+ /*
+ 4BRI Rev 1 Cards
+ */
+@@ -126,8 +128,6 @@
+ {CARDTYPE_DIVASRV_B_2M_V2_PCI, diva_4bri_init_card},
+ {CARDTYPE_DIVASRV_B_2F_PCI, diva_4bri_init_card},
+ {CARDTYPE_DIVASRV_VOICE_B_2M_V2_PCI, diva_4bri_init_card},
+-#endif
+-#ifdef CONFIG_ISDN_DIVAS_BRIPCI
+ /*
+ BRI
+ */
+@@ -193,6 +193,7 @@
+ pdiva->controller = i + 1;
+ pdiva->xdi_adapter.ANum = pdiva->controller;
+ IoAdapters[i] = &pdiva->xdi_adapter;
++ diva_os_leave_spin_lock(&adapter_lock, &old_irql, "add card");
+ create_adapter_proc(pdiva); /* add adapter to proc file system */
+
+ DBG_LOG(("add %s:%d",
+@@ -200,6 +201,7 @@
+ [CardOrdinal].Name,
+ pdiva->controller))
+
++ diva_os_enter_spin_lock(&adapter_lock, &old_irql, "add card");
+ pa = pdiva;
+ for (j = 1; j < nr; j++) { /* slave adapters, if any */
+ pa = (diva_os_xdi_adapter_t *) diva_q_get_next(&pa->link);
+@@ -207,8 +209,11 @@
+ pa->controller = i + 1 + j;
+ pa->xdi_adapter.ANum = pa->controller;
+ IoAdapters[i + j] = &pa->xdi_adapter;
++ diva_os_leave_spin_lock(&adapter_lock, &old_irql, "add card");
+ DBG_LOG(("add slave adapter (%d)",
+- pa->controller)) create_adapter_proc(pa); /* add adapter to proc file system */
++ pa->controller))
++ create_adapter_proc(pa); /* add adapter to proc file system */
++ diva_os_enter_spin_lock(&adapter_lock, &old_irql, "add card");
+ } else {
+ DBG_ERR(("slave adapter problem"))
+ break;
+@@ -463,7 +468,8 @@
+ }
+ } else {
+ DBG_ERR(("A: A(%d) write error (%d)", a->controller,
+- length))}
++ length))
++ }
+
+ diva_os_free(0, data);
+
+@@ -564,7 +570,6 @@
+ Requests[31] = DivaIdiRequest31;
+ }
+
+-/* card: 1-based card number */
+ void diva_xdi_display_adapter_features(int card)
+ {
+ dword features;
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/divacapi.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/divacapi.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/divacapi.h 2003-09-27 11:38:21.566249816 +0800
+@@ -643,7 +643,7 @@
+ unsigned parity:2;
+ unsigned spare: 2;
+ unsigned stp: 1;
+- unsigned ch_len:2; // 3th octett in CAI
++ unsigned ch_len:2; /* 3th octett in CAI */
+ };
+
+
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/diva_didd.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/diva_didd.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/diva_didd.c 2003-09-27 11:38:21.569249360 +0800
+@@ -1,11 +1,11 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
+ *
+ * DIDD Interface module for Eicon active cards.
+ *
+ * Functions are in dadapter.c
+ *
+- * Copyright 2002 by Armin Schindler (mac@melware.de)
+- * Copyright 2002 Cytronics & Melware (info@melware.de)
++ * Copyright 2002-2003 by Armin Schindler (mac@melware.de)
++ * Copyright 2002-2003 Cytronics & Melware (info@melware.de)
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+@@ -23,14 +23,13 @@
+ #include "divasync.h"
+ #include "did_vers.h"
+
+-static char *main_revision = "$Revision: 1.1.4.1 $";
++static char *main_revision = "$Revision: 1.1.4.1 $";
+
+ static char *DRIVERNAME =
+ "Eicon DIVA - DIDD table (http://www.melware.net)";
+ static char *DRIVERLNAME = "divadidd";
+-char *DRIVERRELEASE = "2.0";
++char *DRIVERRELEASE_DIDD = "2.0";
+
+-static char *dir_in_proc_net = "isdn";
+ static char *main_proc_dir = "eicon";
+
+ MODULE_DESCRIPTION("DIDD table driver for diva drivers");
+@@ -48,12 +47,11 @@
+
+ extern void DIVA_DIDD_Read(void *, int);
+
+-static struct proc_dir_entry *proc_net_isdn;
+ static struct proc_dir_entry *proc_didd;
+-struct proc_dir_entry *proc_net_isdn_eicon = NULL;
++struct proc_dir_entry *proc_net_eicon = NULL;
+
+ EXPORT_SYMBOL_NOVERS(DIVA_DIDD_Read);
+-EXPORT_SYMBOL_NOVERS(proc_net_isdn_eicon);
++EXPORT_SYMBOL_NOVERS(proc_net_eicon);
+
+ static char *getrev(const char *revision)
+ {
+@@ -78,7 +76,7 @@
+ strcpy(tmprev, main_revision);
+ len += sprintf(page + len, "%s\n", DRIVERNAME);
+ len += sprintf(page + len, "name : %s\n", DRIVERLNAME);
+- len += sprintf(page + len, "release : %s\n", DRIVERRELEASE);
++ len += sprintf(page + len, "release : %s\n", DRIVERRELEASE_DIDD);
+ len += sprintf(page + len, "build : %s(%s)\n",
+ diva_didd_common_code_build, DIVA_BUILD);
+ len += sprintf(page + len, "revision : %s\n", getrev(tmprev));
+@@ -93,26 +91,12 @@
+
+ static int DIVA_INIT_FUNCTION create_proc(void)
+ {
+- struct proc_dir_entry *pe;
++ proc_net_eicon = create_proc_entry(main_proc_dir, S_IFDIR, proc_net);
+
+- for (pe = proc_net->subdir; pe; pe = pe->next) {
+- if (!memcmp(dir_in_proc_net, pe->name, pe->namelen)) {
+- proc_net_isdn = pe;
+- break;
+- }
+- }
+- if (!proc_net_isdn) {
+- proc_net_isdn =
+- create_proc_entry(dir_in_proc_net, S_IFDIR, proc_net);
+- }
+- proc_net_isdn_eicon =
+- create_proc_entry(main_proc_dir, S_IFDIR, proc_net_isdn);
+-
+- if (proc_net_isdn_eicon) {
+- if (
+- (proc_didd =
++ if (proc_net_eicon) {
++ if ((proc_didd =
+ create_proc_entry(DRIVERLNAME, S_IFREG | S_IRUGO,
+- proc_net_isdn_eicon))) {
++ proc_net_eicon))) {
+ proc_didd->read_proc = proc_read;
+ }
+ return (1);
+@@ -120,14 +104,10 @@
+ return (0);
+ }
+
+-static void remove_proc(void)
++static void DIVA_EXIT_FUNCTION remove_proc(void)
+ {
+- remove_proc_entry(DRIVERLNAME, proc_net_isdn_eicon);
+- remove_proc_entry(main_proc_dir, proc_net_isdn);
+-
+- if ((proc_net_isdn) && (!proc_net_isdn->subdir)) {
+- remove_proc_entry(dir_in_proc_net, proc_net);
+- }
++ remove_proc_entry(DRIVERLNAME, proc_net_eicon);
++ remove_proc_entry(main_proc_dir, proc_net);
+ }
+
+ static int DIVA_INIT_FUNCTION divadidd_init(void)
+@@ -136,7 +116,7 @@
+ int ret = 0;
+
+ printk(KERN_INFO "%s\n", DRIVERNAME);
+- printk(KERN_INFO "%s: Rel:%s Rev:", DRIVERLNAME, DRIVERRELEASE);
++ printk(KERN_INFO "%s: Rel:%s Rev:", DRIVERLNAME, DRIVERRELEASE_DIDD);
+ strcpy(tmprev, main_revision);
+ printk("%s Build:%s(%s)\n", getrev(tmprev),
+ diva_didd_common_code_build, DIVA_BUILD);
+@@ -151,7 +131,9 @@
+ if (!diddfunc_init()) {
+ printk(KERN_ERR "%s: failed to connect to DIDD.\n",
+ DRIVERLNAME);
++#ifdef MODULE
+ remove_proc();
++#endif
+ ret = -EIO;
+ goto out;
+ }
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/divamnt.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/divamnt.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/divamnt.c 2003-09-27 11:38:21.573248752 +0800
+@@ -1,10 +1,10 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
+ *
+ * Driver for Eicon DIVA Server ISDN cards.
+ * Maint module
+ *
+- * Copyright 2000-2002 by Armin Schindler (mac@melware.de)
+- * Copyright 2000-2002 Cytronics & Melware (info@melware.de)
++ * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
++ * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+@@ -19,7 +19,6 @@
+ #include <linux/poll.h>
+ #include <linux/proc_fs.h>
+ #include <linux/skbuff.h>
+-#include <linux/vmalloc.h>
+ #include <linux/devfs_fs_kernel.h>
+
+ #include "platform.h"
+@@ -28,16 +27,14 @@
+ #include "di_defs.h"
+ #include "debug_if.h"
+
+-static char *main_revision = "$Revision: 1.1.4.1 $";
++static char *main_revision = "$Revision: 1.1.4.1 $";
+
+-static int major = 241;
++static int major;
+
+ MODULE_DESCRIPTION("Maint driver for Eicon DIVA Server cards");
+ MODULE_AUTHOR("Cytronics & Melware, Eicon Networks");
+ MODULE_SUPPORTED_DEVICE("DIVA card driver");
+ MODULE_LICENSE("GPL");
+-MODULE_PARM(major, "i");
+-MODULE_PARM_DESC(major, "Major number for /dev/DivasMAINT");
+
+ int buffer_length = 128;
+ MODULE_PARM(buffer_length, "i");
+@@ -47,7 +44,8 @@
+ static char *DRIVERNAME =
+ "Eicon DIVA - MAINT module (http://www.melware.net)";
+ static char *DRIVERLNAME = "diva_mnt";
+-char *DRIVERRELEASE = "2.0";
++static char *DEVNAME = "DivasMAINT";
++char *DRIVERRELEASE_MNT = "2.0";
+
+ static wait_queue_head_t msgwaitq;
+ static DECLARE_MUTEX(opened_sem);
+@@ -77,18 +75,8 @@
+ }
+
+ /*
+- * memory alloc
++ * buffer alloc
+ */
+-void *diva_os_malloc(unsigned long flags, unsigned long size)
+-{
+- return (vmalloc(size));
+-}
+-void diva_os_free(unsigned long flags, void *ptr)
+-{
+- if (ptr) {
+- vfree(ptr);
+- }
+-}
+ void *diva_os_malloc_tbuffer(unsigned long flags, unsigned long size)
+ {
+ return (kmalloc(size, GFP_KERNEL));
+@@ -101,17 +89,6 @@
+ }
+
+ /*
+- * sleep msec
+- */
+-void diva_os_sleep(dword mSec)
+-{
+- unsigned long timeout = HZ * mSec / 1000 + 1;
+-
+- set_current_state(TASK_UNINTERRUPTIBLE);
+- schedule_timeout(timeout);
+-}
+-
+-/*
+ * kernel/user space copy functions
+ */
+ int diva_os_copy_to_user(void *os_handle, void *dst, const void *src,
+@@ -158,7 +135,7 @@
+ * /proc entries
+ */
+
+-extern struct proc_dir_entry *proc_net_isdn_eicon;
++extern struct proc_dir_entry *proc_net_eicon;
+ static struct proc_dir_entry *maint_proc_entry = NULL;
+
+ /*
+@@ -363,7 +340,7 @@
+ {
+ maint_proc_entry =
+ create_proc_entry("maint", S_IFREG | S_IRUGO | S_IWUSR,
+- proc_net_isdn_eicon);
++ proc_net_eicon);
+ if (!maint_proc_entry)
+ return (0);
+
+@@ -376,7 +353,7 @@
+ static void remove_maint_proc(void)
+ {
+ if (maint_proc_entry) {
+- remove_proc_entry("maint", proc_net_isdn_eicon);
++ remove_proc_entry("maint", proc_net_eicon);
+ maint_proc_entry = NULL;
+ }
+ }
+@@ -408,20 +385,20 @@
+
+ static void divas_maint_unregister_chrdev(void)
+ {
+- devfs_remove("DivasMAINT");
+- unregister_chrdev(major, "DivasMAINT");
++ devfs_remove(DEVNAME);
++ unregister_chrdev(major, DEVNAME);
+ }
+
+ static int DIVA_INIT_FUNCTION divas_maint_register_chrdev(void)
+ {
+- if (register_chrdev(major, "DivasMAINT", &divas_maint_fops))
++ if ((major = register_chrdev(0, DEVNAME, &divas_maint_fops)) < 0)
+ {
+ printk(KERN_ERR "%s: failed to create /dev entry.\n",
+ DRIVERLNAME);
+ return (0);
+ }
++ devfs_mk_cdev(MKDEV(major, 0), S_IFCHR|S_IRUSR|S_IWUSR, DEVNAME);
+
+- devfs_mk_cdev(MKDEV(major, 0), S_IFCHR|S_IRUSR|S_IWUSR, "DivasMAINT");
+ return (1);
+ }
+
+@@ -446,10 +423,9 @@
+ init_waitqueue_head(&msgwaitq);
+
+ printk(KERN_INFO "%s\n", DRIVERNAME);
+- printk(KERN_INFO "%s: Rel:%s Rev:", DRIVERLNAME, DRIVERRELEASE);
++ printk(KERN_INFO "%s: Rel:%s Rev:", DRIVERLNAME, DRIVERRELEASE_MNT);
+ strcpy(tmprev, main_revision);
+- printk("%s Build: %s Major: %d\n", getrev(tmprev), DIVA_BUILD,
+- major);
++ printk("%s Build: %s \n", getrev(tmprev), DIVA_BUILD);
+
+ if (!divas_maint_register_chrdev()) {
+ ret = -EIO;
+@@ -472,9 +448,9 @@
+ goto out;
+ }
+
+- printk(KERN_INFO "%s: trace buffer = %p - %d kBytes, %s \n",
+- DRIVERLNAME, buffer, buffer_length,
+- (diva_dbg_mem == 0) ? "internal" : "external");
++ printk(KERN_INFO "%s: trace buffer = %p - %d kBytes, %s (Major: %d)\n",
++ DRIVERLNAME, buffer, (buffer_length / 1024),
++ (diva_dbg_mem == 0) ? "internal" : "external", major);
+
+ out:
+ return (ret);
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/diva_pci.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/diva_pci.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/diva_pci.h 2003-09-27 11:38:21.575248448 +0800
+@@ -1,9 +1,12 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
+
+ #ifndef __DIVA_PCI_INTERFACE_H__
+ #define __DIVA_PCI_INTERFACE_H__
+
+-void *divasa_remap_pci_bar(unsigned long bar, unsigned long area_length);
++void *divasa_remap_pci_bar(diva_os_xdi_adapter_t *a,
++ int id,
++ unsigned long bar,
++ unsigned long area_length);
+ void divasa_unmap_pci_bar(void *bar);
+ unsigned long divasa_get_pci_irq(unsigned char bus,
+ unsigned char func, void *pci_dev_handle);
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/divasfunc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/divasfunc.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/divasfunc.c 2003-09-27 11:38:21.577248144 +0800
+@@ -1,9 +1,9 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
+ *
+ * Low level driver for Eicon DIVA Server ISDN cards.
+ *
+- * Copyright 2000-2002 by Armin Schindler (mac@melware.de)
+- * Copyright 2000-2002 Cytronics & Melware (info@melware.de)
++ * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
++ * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+@@ -21,6 +21,8 @@
+ #define DBG_MINIMUM (DL_LOG + DL_FTL + DL_ERR)
+ #define DBG_DEFAULT (DBG_MINIMUM + DL_XLOG + DL_REG)
+
++static int debugmask;
++
+ extern void DIVA_DIDD_Read(void *, int);
+
+ extern PISDN_ADAPTER IoAdapters[MAX_ADAPTER];
+@@ -28,7 +30,7 @@
+ #define MAX_DESCRIPTORS 32
+
+ extern void diva_run_trap_script(PISDN_ADAPTER IoAdapter, dword ANum);
+-extern char *DRIVERRELEASE;
++extern char *DRIVERRELEASE_DIVAS;
+
+ static dword notify_handle;
+ static DESCRIPTOR DAdapter;
+@@ -42,8 +44,6 @@
+ /* dummy debug function */
+ }
+
+-DIVA_DI_PRINTF dprintf = no_printf;
+-
+ #include "debuglib.c"
+
+ /*
+@@ -117,10 +117,11 @@
+ */
+ static void start_dbg(void)
+ {
+- DbgRegister("DIVAS", DRIVERRELEASE, DBG_DEFAULT);
++ DbgRegister("DIVAS", DRIVERRELEASE_DIVAS, (debugmask) ? debugmask : DBG_DEFAULT);
+ DBG_LOG(("DIVA ISDNXDI BUILD (%s[%s]-%s-%s)",
+ DIVA_BUILD, diva_xdi_common_code_build, __DATE__,
+- __TIME__))}
++ __TIME__))
++}
+
+ /*
+ * stop debug
+@@ -174,7 +175,7 @@
+ req.didd_notify.e.Req = 0;
+ req.didd_notify.e.Rc =
+ IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
+- req.didd_notify.info.callback = didd_callback;
++ req.didd_notify.info.callback = (void *)didd_callback;
+ req.didd_notify.info.context = 0;
+ DAdapter.request((ENTITY *) & req);
+ if (req.didd_notify.e.Rc != 0xff) {
+@@ -214,13 +215,19 @@
+ /*
+ * init
+ */
+-int DIVA_INIT_FUNCTION divasfunc_init(void)
++int DIVA_INIT_FUNCTION divasfunc_init(int dbgmask)
+ {
++ char *version;
++
++ debugmask = dbgmask;
++
+ if (!connect_didd()) {
+ DBG_ERR(("divasfunc: failed to connect to DIDD."))
+ return (0);
+ }
+
++ version = diva_xdi_common_code_build;
++
+ divasa_xdi_driver_entry();
+
+ return (1);
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/divasi.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/divasi.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/divasi.c 2003-09-27 11:38:21.582247384 +0800
+@@ -1,10 +1,10 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
+ *
+ * Driver for Eicon DIVA Server ISDN cards.
+ * User Mode IDI Interface
+ *
+- * Copyright 2000-2002 by Armin Schindler (mac@melware.de)
+- * Copyright 2000-2002 Cytronics & Melware (info@melware.de)
++ * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
++ * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+@@ -19,7 +19,6 @@
+ #include <linux/poll.h>
+ #include <linux/proc_fs.h>
+ #include <linux/skbuff.h>
+-#include <linux/vmalloc.h>
+ #include <linux/devfs_fs_kernel.h>
+
+ #include "platform.h"
+@@ -28,27 +27,27 @@
+ #include "um_xdi.h"
+ #include "um_idi.h"
+
+-static char *main_revision = "$Revision: 1.1.4.1 $";
++static char *main_revision = "$Revision: 1.1.4.1 $";
+
+-static int major = 242;
++static int major;
+
+ MODULE_DESCRIPTION("User IDI Interface for Eicon ISDN cards");
+ MODULE_AUTHOR("Cytronics & Melware, Eicon Networks");
+ MODULE_SUPPORTED_DEVICE("DIVA card driver");
+ MODULE_LICENSE("GPL");
+-MODULE_PARM(major, "i");
+-MODULE_PARM_DESC(major, "Major number for /dev/DivasIDI");
+
+ typedef struct _diva_um_idi_os_context {
+ wait_queue_head_t read_wait;
+ wait_queue_head_t close_wait;
+ struct timer_list diva_timer_id;
+ int aborted;
++ int adapter_nr;
+ } diva_um_idi_os_context_t;
+
+ static char *DRIVERNAME = "Eicon DIVA - User IDI (http://www.melware.net)";
+ static char *DRIVERLNAME = "diva_idi";
+-char *DRIVERRELEASE = "2.0";
++static char *DEVNAME = "DivasIDI";
++char *DRIVERRELEASE_IDI = "2.0";
+
+ extern int idifunc_init(void);
+ extern void idifunc_finit(void);
+@@ -83,32 +82,9 @@
+ static void diva_um_timer_function(unsigned long data);
+
+ /*
+- * malloc
+- */
+-void *diva_os_malloc(unsigned long flags, unsigned long size)
+-{
+- void *ret = NULL;
+-
+- if (size) {
+- ret = (void *) vmalloc((unsigned int) size);
+- }
+- return (ret);
+-}
+-
+-/*
+- * free
+- */
+-void diva_os_free(unsigned long unused, void *ptr)
+-{
+- if (ptr) {
+- vfree(ptr);
+- }
+-}
+-
+-/*
+ * proc entry
+ */
+-extern struct proc_dir_entry *proc_net_isdn_eicon;
++extern struct proc_dir_entry *proc_net_eicon;
+ static struct proc_dir_entry *um_idi_proc_entry = NULL;
+
+ static int
+@@ -120,10 +96,11 @@
+
+ len += sprintf(page + len, "%s\n", DRIVERNAME);
+ len += sprintf(page + len, "name : %s\n", DRIVERLNAME);
+- len += sprintf(page + len, "release : %s\n", DRIVERRELEASE);
++ len += sprintf(page + len, "release : %s\n", DRIVERRELEASE_IDI);
+ strcpy(tmprev, main_revision);
+ len += sprintf(page + len, "revision : %s\n", getrev(tmprev));
+ len += sprintf(page + len, "build : %s\n", DIVA_BUILD);
++ len += sprintf(page + len, "major : %d\n", major);
+
+ if (off + count >= len)
+ *eof = 1;
+@@ -137,7 +114,7 @@
+ {
+ um_idi_proc_entry = create_proc_entry(DRIVERLNAME,
+ S_IFREG | S_IRUGO | S_IWUSR,
+- proc_net_isdn_eicon);
++ proc_net_eicon);
+ if (!um_idi_proc_entry)
+ return (0);
+
+@@ -150,7 +127,7 @@
+ static void remove_um_idi_proc(void)
+ {
+ if (um_idi_proc_entry) {
+- remove_proc_entry(DRIVERLNAME, proc_net_isdn_eicon);
++ remove_proc_entry(DRIVERLNAME, proc_net_eicon);
+ um_idi_proc_entry = NULL;
+ }
+ }
+@@ -167,20 +144,20 @@
+
+ static void divas_idi_unregister_chrdev(void)
+ {
+- devfs_remove("DivasIDI");
+- unregister_chrdev(major, "DivasIDI");
++ devfs_remove(DEVNAME);
++ unregister_chrdev(major, DEVNAME);
+ }
+
+ static int DIVA_INIT_FUNCTION divas_idi_register_chrdev(void)
+ {
+- if (register_chrdev(major, "DivasIDI", &divas_idi_fops))
++ if ((major = register_chrdev(0, DEVNAME, &divas_idi_fops)) < 0)
+ {
+ printk(KERN_ERR "%s: failed to create /dev entry.\n",
+ DRIVERLNAME);
+ return (0);
+ }
++ devfs_mk_cdev(MKDEV(major, 0), S_IFCHR|S_IRUSR|S_IWUSR, DEVNAME);
+
+- devfs_mk_cdev(MKDEV(major, 0), S_IFCHR|S_IRUSR|S_IWUSR, "DivasIDI");
+ return (1);
+ }
+
+@@ -193,10 +170,9 @@
+ int ret = 0;
+
+ printk(KERN_INFO "%s\n", DRIVERNAME);
+- printk(KERN_INFO "%s: Rel:%s Rev:", DRIVERLNAME, DRIVERRELEASE);
++ printk(KERN_INFO "%s: Rel:%s Rev:", DRIVERLNAME, DRIVERRELEASE_IDI);
+ strcpy(tmprev, main_revision);
+- printk("%s Build: %s Major: %d\n", getrev(tmprev), DIVA_BUILD,
+- major);
++ printk("%s Build: %s\n", getrev(tmprev), DIVA_BUILD);
+
+ if (!divas_idi_register_chrdev()) {
+ ret = -EIO;
+@@ -219,6 +195,7 @@
+ ret = -EIO;
+ goto out;
+ }
++ printk(KERN_INFO "%s: started with major %d\n", DRIVERLNAME, major);
+
+ out:
+ return (ret);
+@@ -330,6 +307,7 @@
+ p_os->diva_timer_id.function = (void *) diva_um_timer_function;
+ p_os->diva_timer_id.data = (unsigned long) p_os;
+ p_os->aborted = 0;
++ p_os->adapter_nr = adapter_nr;
+ return (1);
+ }
+
+@@ -432,7 +410,8 @@
+
+ static int um_idi_release(struct inode *inode, struct file *file)
+ {
+- unsigned int adapter_nr = iminor(inode);
++ diva_um_idi_os_context_t *p_os;
++ unsigned int adapter_nr;
+ int ret = 0;
+
+ if (!(file->private_data)) {
+@@ -440,6 +419,14 @@
+ goto out;
+ }
+
++ if (!(p_os =
++ (diva_um_idi_os_context_t *) diva_um_id_get_os_context(file->private_data))) {
++ ret = -ENODEV;
++ goto out;
++ }
++
++ adapter_nr = p_os->adapter_nr;
++
+ if ((ret = remove_entity(file->private_data))) {
+ goto out;
+ }
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/divasmain.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/divasmain.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/divasmain.c 2003-09-27 11:38:21.589246320 +0800
+@@ -1,9 +1,9 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
+ *
+ * Low level driver for Eicon DIVA Server ISDN cards.
+ *
+- * Copyright 2000-2002 by Armin Schindler (mac@melware.de)
+- * Copyright 2000-2002 Cytronics & Melware (info@melware.de)
++ * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
++ * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+@@ -16,14 +16,12 @@
+ #include <linux/kernel.h>
+ #include <linux/sched.h>
+ #include <linux/unistd.h>
+-#include <linux/vmalloc.h>
+ #include <linux/devfs_fs_kernel.h>
+ #include <asm/uaccess.h>
+ #include <asm/io.h>
+ #include <linux/ioport.h>
+ #include <linux/workqueue.h>
+ #include <linux/pci.h>
+-#include <linux/delay.h>
+ #include <linux/smp_lock.h>
+ #include <linux/interrupt.h>
+ #include <linux/poll.h>
+@@ -37,36 +35,39 @@
+ #include "di_defs.h"
+ #include "divasync.h"
+ #include "diva.h"
+-#include "diva_pci.h"
+ #include "di.h"
+ #include "io.h"
+ #include "xdi_msg.h"
+ #include "xdi_adapter.h"
+ #include "xdi_vers.h"
+ #include "diva_dma.h"
++#include "diva_pci.h"
+
+-static char *main_revision = "$Revision: 1.1.4.1 $";
++static char *main_revision = "$Revision: 1.1.4.1 $";
+
+-int errno = 0;
+-static int major = 240;
++static int major;
++
++static int dbgmask;
+
+ MODULE_DESCRIPTION("Kernel driver for Eicon DIVA Server cards");
+ MODULE_AUTHOR("Cytronics & Melware, Eicon Networks");
+ MODULE_LICENSE("GPL");
+-MODULE_PARM(major, "i");
+-MODULE_PARM_DESC(major, "Major number for /dev/Divas");
++
++MODULE_PARM(dbgmask, "i");
++MODULE_PARM_DESC(dbgmask, "initial debug mask");
+
+ static char *DRIVERNAME =
+ "Eicon DIVA Server driver (http://www.melware.net)";
+ static char *DRIVERLNAME = "divas";
+-char *DRIVERRELEASE = "2.0";
++static char *DEVNAME = "Divas";
++char *DRIVERRELEASE_DIVAS = "2.0";
+
+ extern irqreturn_t diva_os_irq_wrapper(int irq, void *context,
+ struct pt_regs *regs);
+ extern int create_divas_proc(void);
+ extern void remove_divas_proc(void);
+ extern void diva_get_vserial_number(PISDN_ADAPTER IoAdapter, char *buf);
+-extern int divasfunc_init(void);
++extern int divasfunc_init(int dbgmask);
+ extern void divasfunc_exit(void);
+
+ typedef struct _diva_os_thread_dpc {
+@@ -185,19 +186,6 @@
+ return rev;
+ }
+
+-void diva_os_sleep(dword mSec)
+-{
+- unsigned long timeout = HZ * mSec / 1000 + 1;
+-
+- set_current_state(TASK_UNINTERRUPTIBLE);
+- schedule_timeout(timeout);
+-}
+-
+-void diva_os_wait(dword mSec)
+-{
+- mdelay(mSec);
+-}
+-
+ void diva_log_info(unsigned char *format, ...)
+ {
+ va_list args;
+@@ -215,29 +203,8 @@
+ char tmprev[32];
+
+ strcpy(tmprev, main_revision);
+- sprintf(p, "%s: %s(%s) %s(%s)\n", DRIVERLNAME, DRIVERRELEASE,
+- getrev(tmprev), diva_xdi_common_code_build, DIVA_BUILD);
+-}
+-
+-/*********************************************************
+- ** malloc / free
+- *********************************************************/
+-
+-void *diva_os_malloc(unsigned long flags, unsigned long size)
+-{
+- void *ret = NULL;
+-
+- if (size) {
+- ret = (void *) vmalloc((unsigned int) size);
+- }
+- return (ret);
+-}
+-
+-void diva_os_free(unsigned long unused, void *ptr)
+-{
+- if (ptr) {
+- vfree(ptr);
+- }
++ sprintf(p, "%s: %s(%s) %s(%s) major=%d\n", DRIVERLNAME, DRIVERRELEASE_DIVAS,
++ getrev(tmprev), diva_xdi_common_code_build, DIVA_BUILD, major);
+ }
+
+ /* --------------------------------------------------------------------------
+@@ -282,6 +249,7 @@
+ (diva_os_thread_dpc_t *) psoft_isr->object;
+
+ if (context && !context->card_failed) {
++ printk(KERN_ERR "%s: adapter %d trapped !\n", DRIVERLNAME, ANum + 1);
+ context->card_failed = ANum + 1;
+ schedule_work(&context->trap_script_task);
+ }
+@@ -505,8 +473,8 @@
+ *********************************************************/
+
+ int
+-diva_os_register_io_port(int on, unsigned long port, unsigned long length,
+- const char *name)
++diva_os_register_io_port(void *adapter, int on, unsigned long port,
++ unsigned long length, const char *name, int id)
+ {
+ if (on) {
+ if (!request_region(port, length, name)) {
+@@ -519,7 +487,7 @@
+ return (0);
+ }
+
+-void *divasa_remap_pci_bar(unsigned long bar, unsigned long area_length)
++void *divasa_remap_pci_bar(diva_os_xdi_adapter_t *a, int id, unsigned long bar, unsigned long area_length)
+ {
+ void *ret;
+
+@@ -772,20 +740,20 @@
+
+ static void divas_unregister_chrdev(void)
+ {
+- devfs_remove("Divas");
+- unregister_chrdev(major, "Divas");
++ devfs_remove(DEVNAME);
++ unregister_chrdev(major, DEVNAME);
+ }
+
+ static int DIVA_INIT_FUNCTION divas_register_chrdev(void)
+ {
+- if (register_chrdev(major, "Divas", &divas_fops))
++ if ((major = register_chrdev(0, DEVNAME, &divas_fops)) < 0)
+ {
+ printk(KERN_ERR "%s: failed to create /dev entry.\n",
+ DRIVERLNAME);
+ return (0);
+ }
++ devfs_mk_cdev(MKDEV(major, 0), S_IFCHR|S_IRUSR|S_IWUSR, DEVNAME);
+
+- devfs_mk_cdev(MKDEV(major, 0), S_IFCHR|S_IRUSR|S_IWUSR, "Divas");
+ return (1);
+ }
+
+@@ -877,23 +845,20 @@
+ int ret = 0;
+
+ printk(KERN_INFO "%s\n", DRIVERNAME);
+- printk(KERN_INFO "%s: Rel:%s Rev:", DRIVERLNAME, DRIVERRELEASE);
++ printk(KERN_INFO "%s: Rel:%s Rev:", DRIVERLNAME, DRIVERRELEASE_DIVAS);
+ strcpy(tmprev, main_revision);
+- printk("%s Build: %s(%s) Major: %d\n", getrev(tmprev),
+- diva_xdi_common_code_build, DIVA_BUILD, major);
++ printk("%s Build: %s(%s)\n", getrev(tmprev),
++ diva_xdi_common_code_build, DIVA_BUILD);
+ printk(KERN_INFO "%s: support for: ", DRIVERLNAME);
+ #ifdef CONFIG_ISDN_DIVAS_BRIPCI
+ printk("BRI/PCI ");
+ #endif
+-#ifdef CONFIG_ISDN_DIVAS_4BRIPCI
+- printk("4BRI/PCI ");
+-#endif
+ #ifdef CONFIG_ISDN_DIVAS_PRIPCI
+ printk("PRI/PCI ");
+ #endif
+- printk("\n");
++ printk("adapters\n");
+
+- if (!divasfunc_init()) {
++ if (!divasfunc_init(dbgmask)) {
+ printk(KERN_ERR "%s: failed to connect to DIDD.\n",
+ DRIVERLNAME);
+ ret = -EIO;
+@@ -901,15 +866,19 @@
+ }
+
+ if (!divas_register_chrdev()) {
++#ifdef MODULE
+ divasfunc_exit();
++#endif
+ ret = -EIO;
+ goto out;
+ }
+
+ if (!create_divas_proc()) {
++#ifdef MODULE
+ remove_divas_proc();
+ divas_unregister_chrdev();
+ divasfunc_exit();
++#endif
+ printk(KERN_ERR "%s: failed to create proc entry.\n",
+ DRIVERLNAME);
+ ret = -EIO;
+@@ -917,13 +886,16 @@
+ }
+
+ if ((ret = pci_module_init(&diva_pci_driver))) {
++#ifdef MODULE
+ remove_divas_proc();
+ divas_unregister_chrdev();
+ divasfunc_exit();
++#endif
+ printk(KERN_ERR "%s: failed to init pci driver.\n",
+ DRIVERLNAME);
+ goto out;
+ }
++ printk(KERN_INFO "%s: started with major %d\n", DRIVERLNAME, major);
+
+ out:
+ return (ret);
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/divasproc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/divasproc.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/divasproc.c 2003-09-27 11:38:21.592245864 +0800
+@@ -1,10 +1,10 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
+ *
+ * Low level driver for Eicon DIVA Server ISDN cards.
+ * /proc functions
+ *
+- * Copyright 2000-2002 by Armin Schindler (mac@melware.de)
+- * Copyright 2000-2002 Cytronics & Melware (info@melware.de)
++ * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
++ * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+@@ -15,7 +15,6 @@
+ #include <linux/kernel.h>
+ #include <linux/poll.h>
+ #include <linux/proc_fs.h>
+-#include <linux/interrupt.h>
+
+ #include "platform.h"
+ #include "debuglib.h"
+@@ -23,7 +22,6 @@
+ #undef ID_MASK
+ #undef N_DATA
+ #include "pc.h"
+-#include "diva_pci.h"
+ #include "di_defs.h"
+ #include "divasync.h"
+ #include "di.h"
+@@ -31,6 +29,7 @@
+ #include "xdi_msg.h"
+ #include "xdi_adapter.h"
+ #include "diva.h"
++#include "diva_pci.h"
+
+
+ extern PISDN_ADAPTER IoAdapters[MAX_ADAPTER];
+@@ -52,7 +51,7 @@
+ ** "divas" entry
+ */
+
+-extern struct proc_dir_entry *proc_net_isdn_eicon;
++extern struct proc_dir_entry *proc_net_eicon;
+ static struct proc_dir_entry *divas_proc_entry = NULL;
+
+ static ssize_t
+@@ -131,7 +130,7 @@
+ {
+ divas_proc_entry = create_proc_entry(divas_proc_name,
+ S_IFREG | S_IRUGO,
+- proc_net_isdn_eicon);
++ proc_net_eicon);
+ if (!divas_proc_entry)
+ return (0);
+
+@@ -144,7 +143,7 @@
+ void remove_divas_proc(void)
+ {
+ if (divas_proc_entry) {
+- remove_proc_entry(divas_proc_name, proc_net_isdn_eicon);
++ remove_proc_entry(divas_proc_name, proc_net_eicon);
+ divas_proc_entry = NULL;
+ }
+ }
+@@ -333,7 +332,8 @@
+ }
+ }
+ if ((!a->xdi_adapter.port) &&
+- ((!a->xdi_adapter.ram) || (!a->xdi_adapter.reset)
++ ((!a->xdi_adapter.ram) ||
++ (!a->xdi_adapter.reset)
+ || (!a->xdi_adapter.cfg))) {
+ if (!IoAdapter->irq_info.irq_nr) {
+ p = "slave";
+@@ -369,20 +369,14 @@
+ struct proc_dir_entry *de, *pe;
+ char tmp[16];
+
+- if (in_interrupt()) {
+- printk(KERN_ERR
+- "divasproc: create_proc in_interrupt, not creating\n");
+- return (1);
+- }
+-
+ sprintf(tmp, "%s%d", adapter_dir_name, a->controller);
+- if (!(de = create_proc_entry(tmp, S_IFDIR, proc_net_isdn_eicon)))
++ if (!(de = create_proc_entry(tmp, S_IFDIR, proc_net_eicon)))
+ return (0);
+ a->proc_adapter_dir = (void *) de;
+
+ if (!(pe =
+- create_proc_entry(info_proc_name, S_IFREG | S_IRUGO | S_IWUSR,
+- de))) return (0);
++ create_proc_entry(info_proc_name, S_IFREG | S_IRUGO | S_IWUSR, de)))
++ return (0);
+ a->proc_info = (void *) pe;
+ pe->write_proc = info_write;
+ pe->read_proc = info_read;
+@@ -429,7 +423,7 @@
+ (struct proc_dir_entry *) a->proc_adapter_dir);
+ }
+ sprintf(tmp, "%s%d", adapter_dir_name, a->controller);
+- remove_proc_entry(tmp, proc_net_isdn_eicon);
++ remove_proc_entry(tmp, proc_net_eicon);
+ DBG_TRC(("proc entry %s%d removed", adapter_dir_name,
+ a->controller));
+ }
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/dlist.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/dlist.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/dlist.c 2003-09-27 11:38:21.594245560 +0800
+@@ -1,4 +1,4 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
+
+ #include "platform.h"
+ #include "dlist.h"
+@@ -7,7 +7,7 @@
+ ** Initialize linked list
+ */
+
+-void diva_q_init(diva_entity_queue_t * q)
++static void diva_q_init(diva_entity_queue_t * q)
+ {
+ memset(q, 0x00, sizeof(*q));
+ }
+@@ -15,7 +15,7 @@
+ /*
+ ** Remove element from linked list
+ */
+-void diva_q_remove(diva_entity_queue_t * q, diva_entity_link_t * what)
++static void diva_q_remove(diva_entity_queue_t * q, diva_entity_link_t * what)
+ {
+ if (!what->prev) {
+ if ((q->head = what->next)) {
+@@ -36,7 +36,7 @@
+ /*
+ ** Add element to the tail of linked list
+ */
+-void diva_q_add_tail(diva_entity_queue_t * q, diva_entity_link_t * what)
++static void diva_q_add_tail(diva_entity_queue_t * q, diva_entity_link_t * what)
+ {
+ what->next = 0;
+ if (!q->head) {
+@@ -49,7 +49,7 @@
+ }
+ }
+
+-diva_entity_link_t *diva_q_find(const diva_entity_queue_t * q,
++static diva_entity_link_t *diva_q_find(const diva_entity_queue_t * q,
+ const void *what, diva_q_cmp_fn_t cmp_fn)
+ {
+ diva_entity_link_t *diva_current = q->head;
+@@ -64,35 +64,13 @@
+ return (diva_current);
+ }
+
+-diva_entity_link_t *diva_q_get_head(diva_entity_queue_t * q)
++static diva_entity_link_t *diva_q_get_head(diva_entity_queue_t * q)
+ {
+ return (q->head);
+ }
+
+-diva_entity_link_t *diva_q_get_tail(diva_entity_queue_t * q)
+-{
+- return (q->tail);
+-}
+-
+-diva_entity_link_t *diva_q_get_next(diva_entity_link_t * what)
++static diva_entity_link_t *diva_q_get_next(diva_entity_link_t * what)
+ {
+ return ((what) ? what->next : 0);
+ }
+
+-diva_entity_link_t *diva_q_get_prev(diva_entity_link_t * what)
+-{
+- return ((what) ? what->prev : 0);
+-}
+-
+-int diva_q_get_nr_of_entries(const diva_entity_queue_t * q)
+-{
+- int i = 0;
+- const diva_entity_link_t *diva_current = q->head;
+-
+- while (diva_current) {
+- i++;
+- diva_current = diva_current->next;
+- }
+-
+- return (i);
+-}
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/dlist.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/dlist.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/dlist.h 2003-09-27 11:38:21.595245408 +0800
+@@ -1,4 +1,4 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
+
+ #ifndef __DIVA_LINK_H__
+ #define __DIVA_LINK_H__
+@@ -17,16 +17,4 @@
+ typedef int (*diva_q_cmp_fn_t) (const void *what,
+ const diva_entity_link_t *);
+
+-void diva_q_remove(diva_entity_queue_t * q, diva_entity_link_t * what);
+-void diva_q_add_tail(diva_entity_queue_t * q, diva_entity_link_t * what);
+-diva_entity_link_t *diva_q_find(const diva_entity_queue_t * q,
+- const void *what, diva_q_cmp_fn_t cmp_fn);
+-
+-diva_entity_link_t *diva_q_get_head(diva_entity_queue_t * q);
+-diva_entity_link_t *diva_q_get_tail(diva_entity_queue_t * q);
+-diva_entity_link_t *diva_q_get_next(diva_entity_link_t * what);
+-diva_entity_link_t *diva_q_get_prev(diva_entity_link_t * what);
+-int diva_q_get_nr_of_entries(const diva_entity_queue_t * q);
+-void diva_q_init(diva_entity_queue_t * q);
+-
+ #endif
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/i4lididrv.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/i4lididrv.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/i4lididrv.c 2003-09-27 11:38:21.605243888 +0800
+@@ -293,7 +293,7 @@
+ {
+ int pid = 0;
+
+- pid = kernel_thread(divad_thread, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++ pid = kernel_thread(divad_thread, NULL, CLONE_KERNEL);
+ if (pid >= 0) {
+ divad_pid = pid;
+ }
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/idifunc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/idifunc.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/idifunc.c 2003-09-27 11:38:21.607243584 +0800
+@@ -1,10 +1,10 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
+ *
+ * Driver for Eicon DIVA Server ISDN cards.
+ * User Mode IDI Interface
+ *
+- * Copyright 2000-2002 by Armin Schindler (mac@melware.de)
+- * Copyright 2000-2002 Cytronics & Melware (info@melware.de)
++ * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
++ * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+@@ -19,7 +19,7 @@
+ #define DBG_MINIMUM (DL_LOG + DL_FTL + DL_ERR)
+ #define DBG_DEFAULT (DBG_MINIMUM + DL_XLOG + DL_REG)
+
+-extern char *DRIVERRELEASE;
++extern char *DRIVERRELEASE_IDI;
+
+ extern void DIVA_DIDD_Read(void *, int);
+ extern int diva_user_mode_idi_create_adapter(const DESCRIPTOR *, int);
+@@ -36,8 +36,6 @@
+ /* dummy debug function */
+ }
+
+-DIVA_DI_PRINTF dprintf = no_printf;
+-
+ #include "debuglib.c"
+
+ /*
+@@ -202,7 +200,7 @@
+ } else {
+ memcpy(&MAdapter, adapter, sizeof(MAdapter));
+ dprintf = (DIVA_DI_PRINTF) MAdapter.request;
+- DbgRegister("User IDI", DRIVERRELEASE, DBG_DEFAULT);
++ DbgRegister("User IDI", DRIVERRELEASE_IDI, DBG_DEFAULT);
+ }
+ } else if ((adapter->type > 0) && (adapter->type < 16)) { /* IDI Adapter */
+ if (removal) {
+@@ -233,7 +231,7 @@
+ req.didd_notify.e.Req = 0;
+ req.didd_notify.e.Rc =
+ IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
+- req.didd_notify.info.callback = didd_callback;
++ req.didd_notify.info.callback = (void *)didd_callback;
+ req.didd_notify.info.context = 0;
+ DAdapter.request((ENTITY *) & req);
+ if (req.didd_notify.e.Rc != 0xff) {
+@@ -244,7 +242,7 @@
+ } else if (DIDD_Table[x].type == IDI_DIMAINT) { /* MAINT found */
+ memcpy(&MAdapter, &DIDD_Table[x], sizeof(DAdapter));
+ dprintf = (DIVA_DI_PRINTF) MAdapter.request;
+- DbgRegister("User IDI", DRIVERRELEASE, DBG_DEFAULT);
++ DbgRegister("User IDI", DRIVERRELEASE_IDI, DBG_DEFAULT);
+ } else if ((DIDD_Table[x].type > 0)
+ && (DIDD_Table[x].type < 16)) { /* IDI Adapter found */
+ um_new_card(&DIDD_Table[x]);
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/io.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/io.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/io.c 2003-09-27 11:38:21.615242368 +0800
+@@ -72,10 +72,10 @@
+ */
+ static byte extended_xdi_features[DIVA_XDI_EXTENDED_FEATURES_MAX_SZ+1] = {
+ (DIVA_XDI_EXTENDED_FEATURES_VALID |
+- DIVA_XDI_EXTENDED_FEATURE_CMA |
+ DIVA_XDI_EXTENDED_FEATURE_SDRAM_BAR |
+ DIVA_XDI_EXTENDED_FEATURE_CAPI_PRMS |
+ #if defined(DIVA_IDI_RX_DMA)
++ DIVA_XDI_EXTENDED_FEATURE_CMA |
+ DIVA_XDI_EXTENDED_FEATURE_RX_DMA |
+ #endif
+ DIVA_XDI_EXTENDED_FEATURE_NO_CANCEL_RC),
+@@ -156,7 +156,8 @@
+ dump_trap_frame (PISDN_ADAPTER IoAdapter, byte *exceptionFrame)
+ {
+ MP_XCPTC *xcept = (MP_XCPTC *)exceptionFrame ;
+- dword *regs = &xcept->regs[0] ;
++ dword *regs;
++ regs = &xcept->regs[0] ;
+ DBG_FTL(("%s: ***************** CPU TRAPPED *****************",
+ &IoAdapter->Name[0]))
+ DBG_FTL(("Microcode: %s", &IoAdapter->ProtocolIdString[0]))
+@@ -567,26 +568,38 @@
+ /*------------------------------------------------------------------*/
+ byte mem_in (ADAPTER *a, void *addr)
+ {
+- byte* Base = (byte*)&((PISDN_ADAPTER)a->io)->ram[(unsigned long)addr] ;
+- return (*Base) ;
++ byte val;
++ volatile byte* Base;
++
++ Base = (volatile byte *)DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
++ val = *(Base + (unsigned long)addr);
++ DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
++ return (val);
+ }
+ word mem_inw (ADAPTER *a, void *addr)
+ {
+- word* Base = (word*)&((PISDN_ADAPTER)a->io)->ram[(unsigned long)addr] ;
+- return (READ_WORD(Base)) ;
++ word val;
++ volatile byte* Base;
++
++ Base = (volatile byte*)DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
++ val = READ_WORD((Base + (unsigned long)addr));
++ DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
++ return (val);
+ }
+ void mem_in_dw (ADAPTER *a, void *addr, dword* data, int dwords)
+ {
+- volatile dword* Base = (dword*)&((PISDN_ADAPTER)a->io)->ram[(unsigned long)addr] ;
++ volatile byte* Base = (volatile byte*)DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
+ while (dwords--) {
+- *data++ = READ_DWORD(Base);
+- Base++;
++ *data++ = READ_DWORD((Base + (unsigned long)addr));
++ addr+=4;
+ }
++ DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
+ }
+ void mem_in_buffer (ADAPTER *a, void *addr, void *buffer, word length)
+ {
+- byte* Base = (byte*)&((PISDN_ADAPTER)a->io)->ram[(unsigned long)addr] ;
+- memcpy (buffer, Base, length) ;
++ volatile byte* Base = (volatile byte*)DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
++ memcpy (buffer, (void *)(Base + (unsigned long)addr), length);
++ DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
+ }
+ void mem_look_ahead (ADAPTER *a, PBUFFER *RBuffer, ENTITY *e)
+ {
+@@ -598,99 +611,130 @@
+ }
+ void mem_out (ADAPTER *a, void *addr, byte data)
+ {
+- byte* Base = (byte*)&((PISDN_ADAPTER)a->io)->ram[(unsigned long)addr] ;
+- *Base = data ;
++ volatile byte* Base = (volatile byte*)DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
++ *(Base + (unsigned long)addr) = data ;
++ DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
+ }
+ void mem_outw (ADAPTER *a, void *addr, word data)
+ {
+- word* Base = (word*)&((PISDN_ADAPTER)a->io)->ram[(unsigned long)addr] ;
+- WRITE_WORD(Base, data);
++ volatile byte* Base = (volatile byte*)DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
++ WRITE_WORD((Base + (unsigned long)addr), data);
++ DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
+ }
+ void mem_out_dw (ADAPTER *a, void *addr, const dword* data, int dwords)
+ {
+- volatile dword* Base = (dword*)&((PISDN_ADAPTER)a->io)->ram[(unsigned long)addr] ;
++ volatile byte* Base = (volatile byte*)DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
+ while (dwords--) {
+- WRITE_DWORD(Base, *data);
+- Base++;
++ WRITE_DWORD((Base + (unsigned long)addr), *data);
++ addr+=4;
+ data++;
+ }
++ DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
+ }
+ void mem_out_buffer (ADAPTER *a, void *addr, void *buffer, word length)
+ {
+- byte* Base = (byte*)&((PISDN_ADAPTER)a->io)->ram[(unsigned long)addr] ;
+- memcpy (Base, buffer, length) ;
++ volatile byte* Base = (volatile byte*)DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
++ memcpy ((void *)(Base + (unsigned long)addr), buffer, length) ;
++ DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
+ }
+ void mem_inc (ADAPTER *a, void *addr)
+ {
+- byte* Base = (byte*)&((PISDN_ADAPTER)a->io)->ram[(unsigned long)addr] ;
+- byte x = *Base ;
+- *Base = x + 1 ;
++ volatile byte* Base = (volatile byte*)DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
++ byte x = *(Base + (unsigned long)addr);
++ *(Base + (unsigned long)addr) = x + 1 ;
++ DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
+ }
+ /*------------------------------------------------------------------*/
+ /* ram access functions for io-mapped cards */
+ /*------------------------------------------------------------------*/
+ byte io_in(ADAPTER * a, void * adr)
+ {
+- outppw(((PISDN_ADAPTER)a->io)->port+4, (word)(unsigned long)adr);
+- return inpp(((PISDN_ADAPTER)a->io)->port);
++ byte val;
++ byte *Port = (byte*)DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
++ outppw(Port + 4, (word)(unsigned long)adr);
++ val = inpp(Port);
++ DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
++ return(val);
+ }
+ word io_inw(ADAPTER * a, void * adr)
+ {
+- outppw(((PISDN_ADAPTER)a->io)->port+4, (word)(unsigned long)adr);
+- return inppw(((PISDN_ADAPTER)a->io)->port);
++ word val;
++ byte *Port = (byte*)DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
++ outppw(Port + 4, (word)(unsigned long)adr);
++ val = inppw(Port);
++ DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
++ return(val);
+ }
+ void io_in_buffer(ADAPTER * a, void * adr, void * buffer, word len)
+ {
++ byte *Port = (byte*)DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
+ byte* P = (byte*)buffer;
+ if ((long)adr & 1) {
+- outppw(((PISDN_ADAPTER)a->io)->port+4, (word)(unsigned long)adr);
+- *P = inpp(((PISDN_ADAPTER)a->io)->port);
++ outppw(Port+4, (word)(unsigned long)adr);
++ *P = inpp(Port);
+ P++;
+ adr = ((byte *) adr) + 1;
+ len--;
+- if (!len) return;
++ if (!len) {
++ DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
++ return;
+ }
+- outppw(((PISDN_ADAPTER)a->io)->port+4, (word)(unsigned long)adr);
+- inppw_buffer (((PISDN_ADAPTER)a->io)->port, P, len+1);
++ }
++ outppw(Port+4, (word)(unsigned long)adr);
++ inppw_buffer (Port, P, len+1);
++ DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
+ }
+ void io_look_ahead(ADAPTER * a, PBUFFER * RBuffer, ENTITY * e)
+ {
+- outppw(((PISDN_ADAPTER)a->io)->port+4, (word)(unsigned long)RBuffer);
+- ((PISDN_ADAPTER)a->io)->RBuffer.length = inppw(((PISDN_ADAPTER)a->io)->port);
+- inppw_buffer (((PISDN_ADAPTER)a->io)->port, ((PISDN_ADAPTER)a->io)->RBuffer.P, ((PISDN_ADAPTER)a->io)->RBuffer.length + 1);
++ byte *Port = (byte*)DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
++ outppw(Port+4, (word)(unsigned long)RBuffer);
++ ((PISDN_ADAPTER)a->io)->RBuffer.length = inppw(Port);
++ inppw_buffer (Port, ((PISDN_ADAPTER)a->io)->RBuffer.P, ((PISDN_ADAPTER)a->io)->RBuffer.length + 1);
+ e->RBuffer = (DBUFFER *) &(((PISDN_ADAPTER)a->io)->RBuffer);
++ DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
+ }
+ void io_out(ADAPTER * a, void * adr, byte data)
+ {
+- outppw(((PISDN_ADAPTER)a->io)->port+4, (word)(unsigned long)adr);
+- outpp(((PISDN_ADAPTER)a->io)->port, data);
++ byte *Port = (byte*)DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
++ outppw(Port+4, (word)(unsigned long)adr);
++ outpp(Port, data);
++ DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
+ }
+ void io_outw(ADAPTER * a, void * adr, word data)
+ {
+- outppw(((PISDN_ADAPTER)a->io)->port+4, (word)(unsigned long)adr);
+- outppw(((PISDN_ADAPTER)a->io)->port, data);
++ byte *Port = (byte*)DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
++ outppw(Port+4, (word)(unsigned long)adr);
++ outppw(Port, data);
++ DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
+ }
+ void io_out_buffer(ADAPTER * a, void * adr, void * buffer, word len)
+ {
++ byte *Port = (byte*)DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
+ byte* P = (byte*)buffer;
+ if ((long)adr & 1) {
+- outppw(((PISDN_ADAPTER)a->io)->port+4, (word)(unsigned long)adr);
+- outpp(((PISDN_ADAPTER)a->io)->port, *P);
++ outppw(Port+4, (word)(unsigned long)adr);
++ outpp(Port, *P);
+ P++;
+ adr = ((byte *) adr) + 1;
+ len--;
+- if (!len) return;
++ if (!len) {
++ DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
++ return;
++ }
+ }
+- outppw(((PISDN_ADAPTER)a->io)->port+4, (word)(unsigned long)adr);
+- outppw_buffer (((PISDN_ADAPTER)a->io)->port, P, len+1);
++ outppw(Port+4, (word)(unsigned long)adr);
++ outppw_buffer (Port, P, len+1);
++ DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
+ }
+ void io_inc(ADAPTER * a, void * adr)
+ {
+ byte x;
+- outppw(((PISDN_ADAPTER)a->io)->port+4, (word)(unsigned long)adr);
+- x = inpp(((PISDN_ADAPTER)a->io)->port);
+- outppw(((PISDN_ADAPTER)a->io)->port+4, (word)(unsigned long)adr);
+- outpp(((PISDN_ADAPTER)a->io)->port, x+1);
++ byte *Port = (byte*)DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
++ outppw(Port+4, (word)(unsigned long)adr);
++ x = inpp(Port);
++ outppw(Port+4, (word)(unsigned long)adr);
++ outpp(Port, x+1);
++ DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
+ }
+ /*------------------------------------------------------------------*/
+ /* OS specific functions related to queuing of entities */
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/io.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/io.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/io.h 2003-09-27 11:38:21.619241760 +0800
+@@ -40,14 +40,6 @@
+ PISDN_ADAPTER QuadroAdapter[4] ;
+ } ADAPTER_LIST_ENTRY, *PADAPTER_LIST_ENTRY ;
+ /* --------------------------------------------------------------------------
+- Special OS memory support structures
+- -------------------------------------------------------------------------- */
+-#define MAX_MAPPED_ENTRIES 8
+-typedef struct {
+- void * Address;
+- dword Length;
+-} ADAPTER_MEMORY ;
+-/* --------------------------------------------------------------------------
+ Configuration of XDI clients carried by XDI
+ -------------------------------------------------------------------------- */
+ #define DIVA_XDI_CAPI_CFG_1_DYNAMIC_L1_ON 0x01
+@@ -71,7 +63,6 @@
+ /*
+ remember mapped memory areas
+ */
+- ADAPTER_MEMORY MappedMemory[MAX_MAPPED_ENTRIES] ;
+ CARD_PROPERTIES Properties ;
+ dword cardType ;
+ dword protocol_id ; /* configured protocol identifier */
+@@ -97,6 +88,8 @@
+ dword MemoryBase ;
+ dword MemorySize ;
+ byte *Address ;
++ byte *Config ;
++ byte *Control ;
+ byte *reset ;
+ byte *port ;
+ byte *ram ;
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/Kconfig 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/Kconfig 2003-09-27 11:38:21.620241608 +0800
+@@ -12,7 +12,7 @@
+
+ config ISDN_DIVAS
+ tristate "Support Eicon DIVA Server cards"
+- depends on CAPI_EICON && PROC_FS && PCI && m
++ depends on CAPI_EICON && PROC_FS && PCI
+ help
+ Say Y here if you have an Eicon Networks DIVA Server PCI ISDN card.
+ In order to use this card, additional firmware is necessary, which
+@@ -24,12 +24,6 @@
+ help
+ Enable support for DIVA Server BRI-PCI.
+
+-config ISDN_DIVAS_4BRIPCI
+- bool "DIVA Server 4BRI/PCI support"
+- depends on ISDN_DIVAS
+- help
+- Enable support for DIVA Server 4BRI-PCI.
+-
+ config ISDN_DIVAS_PRIPCI
+ bool "DIVA Server PRI/PCI support"
+ depends on ISDN_DIVAS
+@@ -43,17 +37,17 @@
+ You need this to provide the CAPI interface
+ for DIVA Server cards.
+
+-config ISDN_DIVAS_MAINT
+- tristate "DIVA Maint driver support"
+- depends on ISDN_DIVAS
+- help
+- Enable Divas Maintainance driver.
+-
+ config ISDN_DIVAS_USERIDI
+ tristate "DIVA User-IDI interface support"
+ depends on ISDN_DIVAS
+ help
+ Enable support for user-mode IDI interface.
+
++config ISDN_DIVAS_MAINT
++ tristate "DIVA Maint driver support"
++ depends on ISDN_DIVAS && m
++ help
++ Enable Divas Maintainance driver.
++
+ endmenu
+
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/Makefile 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/Makefile 2003-09-27 11:38:21.622241304 +0800
+@@ -10,9 +10,8 @@
+ # Multipart objects.
+
+ divas-y := divasmain.o divasfunc.o di.o io.o istream.o \
+- diva.o dlist.o divasproc.o diva_dma.o
+-divas-$(CONFIG_ISDN_DIVAS_BRIPCI) += os_bri.o s_bri.o
+-divas-$(CONFIG_ISDN_DIVAS_4BRIPCI) += os_4bri.o s_4bri.o
++ diva.o divasproc.o diva_dma.o
++divas-$(CONFIG_ISDN_DIVAS_BRIPCI) += os_bri.o s_bri.o os_4bri.o s_4bri.o
+ divas-$(CONFIG_ISDN_DIVAS_PRIPCI) += os_pri.o s_pri.o
+
+ divacapi-y := capimain.o capifunc.o message.o capidtmf.o
+@@ -21,4 +20,4 @@
+
+ diva_mnt-y := divamnt.o mntfunc.o debug.o maintidi.o
+
+-diva_idi-y := divasi.o idifunc.o um_idi.o dqueue.o dlist.o
++diva_idi-y := divasi.o idifunc.o um_idi.o dqueue.o
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/message.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/message.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/message.c 2003-09-27 11:38:21.738223672 +0800
+@@ -3590,7 +3590,7 @@
+ {
+ if (plci->channels)
+ {
+- for (ncci = 1; ncci < MAX_NCCI+1; i++)
++ for (ncci = 1; ncci < MAX_NCCI+1; ncci++)
+ {
+ if ((a->ncci_plci[ncci] == plci->Id) && (a->ncci_state[ncci] == CONNECTED))
+ {
+@@ -6612,7 +6612,7 @@
+ ||(*data == DSP_UDATA_INDICATION_CTS_ON)) )
+ {
+ word conn_opt, ncpi_opt = 0x00;
+-// HexDump ("MDM N_UDATA:", plci->NL.RBuffer->length, data);
++/* HexDump ("MDM N_UDATA:", plci->NL.RBuffer->length, data); */
+
+ if (*data == DSP_UDATA_INDICATION_DCD_ON)
+ plci->ncpi_state |= NCPI_MDM_DCD_ON_RECEIVED;
+@@ -7813,15 +7813,15 @@
+
+ }
+ }
+- if(READ_WORD(bp_parms[0].info)==2 || // V.110 async
+- READ_WORD(bp_parms[0].info)==3 ) // V.110 sync
++ if(READ_WORD(bp_parms[0].info)==2 || /* V.110 async */
++ READ_WORD(bp_parms[0].info)==3 ) /* V.110 sync */
+ {
+ if(bp_parms[3].length){
+ dbug(1,dprintf("V.110,%d",READ_WORD(&bp_parms[3].info[1])));
+- switch(READ_WORD(&bp_parms[3].info[1])){ // Rate
++ switch(READ_WORD(&bp_parms[3].info[1])){ /* Rate */
+ case 0:
+ case 56000:
+- if(READ_WORD(bp_parms[0].info)==3){ //V.110 sync 56k
++ if(READ_WORD(bp_parms[0].info)==3){ /* V.110 sync 56k */
+ dbug(1,dprintf("56k sync HSCX"));
+ cai[1] = 8;
+ cai[2] = 0;
+@@ -7859,7 +7859,7 @@
+ return _B1_PARM_NOT_SUPPORTED;
+ }
+ cai[3] = 0;
+- if (cai[1] == 13) // v.110 async
++ if (cai[1] == 13) /* v.110 async */
+ {
+ if (bp_parms[3].length >= 8)
+ {
+@@ -7906,7 +7906,7 @@
+ }
+ WRITE_WORD(&cai[5],plci->appl->MaxDataLength);
+ dbug(1,dprintf("CAI[%d]=%x,%x,%x,%x,%x,%x", cai[0], cai[1], cai[2], cai[3], cai[4], cai[5], cai[6]));
+-//HexDump ("CAI", sizeof(cai), &cai[0]);
++/* HexDump ("CAI", sizeof(cai), &cai[0]); */
+
+ add_p(plci, CAI, cai);
+ return 0;
+@@ -8681,7 +8681,7 @@
+ DLC_MODEMPROT_DISABLE_COMPRESSION;
+ }
+ dlc[0] = (byte)(i - 1);
+-//HexDump ("DLC", sizeof(dlc), &dlc[0]);
++/* HexDump ("DLC", sizeof(dlc), &dlc[0]); */
+ add_p(plci, DLC, dlc);
+ return (0);
+ }
+@@ -8739,7 +8739,7 @@
+ {
+ ENTITY * e;
+ word l;
+-// word i;
++/* word i; */
+
+ if(!plci) return;
+ if(plci->adapter->adapter_disabled) return;
+@@ -8856,7 +8856,7 @@
+ }
+ else if (plci->send_disc == ncci)
+ {
+- //dprintf("N_DISC");
++ /* dprintf("N_DISC"); */
+ plci->NData[0].PLength = 0;
+ plci->NL.ReqCh = a->ncci_ch[ncci];
+ plci->NL.Req = plci->nl_req = N_DISC;
+@@ -9059,15 +9059,15 @@
+ for(k=0;k<=flen;k++,j++)
+ {
+ facility[j]=fty_i[i][k];
+-// dbug(1,dprintf("%x ",facility[j]));
++/* dbug(1,dprintf("%x ",facility[j])); */
+ }
+ }
+ facility[0] = len;
+ add_i[3] = facility;
+ }
+-// dbug(1,dprintf("FacArrLen=%d ",len));
++/* dbug(1,dprintf("FacArrLen=%d ",len)); */
+ len = add_i[0][0]+add_i[1][0]+add_i[2][0]+add_i[3][0];
+- len += 4; // calculate length of all
++ len += 4; /* calculate length of all */
+ return(len);
+ }
+
+@@ -9083,8 +9083,8 @@
+ channel = chi[chi[0]]&0x3;
+ dbug(1,dprintf("ExtDevON(Ch=0x%x)",channel));
+ voice_chi[2] = (channel) ? channel : 1;
+- add_p(plci,FTY,"\x02\x01\x07"); // B On, default on 1
+- add_p(plci,ESC,voice_chi); // Channel
++ add_p(plci,FTY,"\x02\x01\x07"); /* B On, default on 1 */
++ add_p(plci,ESC,voice_chi); /* Channel */
+ sig_req(plci,TEL_CTRL,0);
+ send_req(plci);
+ if(a->AdvSignalPLCI)
+@@ -9096,7 +9096,7 @@
+ void VoiceChannelOff(PLCI *plci)
+ {
+ dbug(1,dprintf("ExtDevOFF"));
+- add_p(plci,FTY,"\x02\x01\x08"); // B Off
++ add_p(plci,FTY,"\x02\x01\x08"); /* B Off */
+ sig_req(plci,TEL_CTRL,0);
+ send_req(plci);
+ if(plci->adapter->AdvSignalPLCI)
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/mntfunc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/mntfunc.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/mntfunc.c 2003-09-27 11:38:21.741223216 +0800
+@@ -1,10 +1,10 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
+ *
+ * Driver for Eicon DIVA Server ISDN cards.
+ * Maint module
+ *
+- * Copyright 2000,2001 by Armin Schindler (mac@melware.de)
+- * Copyright 2000,2001 Cytronics & Melware (info@melware.de)
++ * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
++ * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+@@ -17,7 +17,7 @@
+ #include "di_defs.h"
+ #include "debug_if.h"
+
+-extern char *DRIVERRELEASE;
++extern char *DRIVERRELEASE_MNT;
+
+ #define DBG_MINIMUM (DL_LOG + DL_FTL + DL_ERR)
+ #define DBG_DEFAULT (DBG_MINIMUM + DL_XLOG + DL_REG)
+@@ -45,8 +45,6 @@
+ /* dummy debug function */
+ }
+
+-DIVA_DI_PRINTF dprintf = no_printf;
+-
+ #include "debuglib.c"
+
+ /*
+@@ -73,7 +71,7 @@
+ } else {
+ memcpy(&MAdapter, adapter, sizeof(MAdapter));
+ dprintf = (DIVA_DI_PRINTF) MAdapter.request;
+- DbgRegister("MAINT", DRIVERRELEASE, DBG_DEFAULT);
++ DbgRegister("MAINT", DRIVERRELEASE_MNT, DBG_DEFAULT);
+ }
+ } else if ((adapter->type > 0) && (adapter->type < 16)) {
+ if (removal) {
+@@ -104,7 +102,7 @@
+ req.didd_notify.e.Req = 0;
+ req.didd_notify.e.Rc =
+ IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
+- req.didd_notify.info.callback = didd_callback;
++ req.didd_notify.info.callback = (void *)didd_callback;
+ req.didd_notify.info.context = 0;
+ DAdapter.request((ENTITY *) & req);
+ if (req.didd_notify.e.Rc != 0xff)
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/os_4bri.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/os_4bri.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/os_4bri.c 2003-09-27 11:38:21.749222000 +0800
+@@ -1,4 +1,4 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
+
+ #include "platform.h"
+ #include "debuglib.h"
+@@ -99,6 +99,40 @@
+ return (0);
+ }
+
++static void diva_4bri_set_addresses(diva_os_xdi_adapter_t *a)
++{
++ dword offset = a->resources.pci.qoffset;
++ dword c_offset = offset * a->xdi_adapter.ControllerNumber;
++
++ a->resources.pci.mem_type_id[MEM_TYPE_RAM] = 2;
++ a->resources.pci.mem_type_id[MEM_TYPE_ADDRESS] = 2;
++ a->resources.pci.mem_type_id[MEM_TYPE_CONTROL] = 2;
++ a->resources.pci.mem_type_id[MEM_TYPE_RESET] = 0;
++ a->resources.pci.mem_type_id[MEM_TYPE_CTLREG] = 3;
++ a->resources.pci.mem_type_id[MEM_TYPE_PROM] = 0;
++
++ /*
++ Set up hardware related pointers
++ */
++ a->xdi_adapter.Address = a->resources.pci.addr[2]; /* BAR2 SDRAM */
++ a->xdi_adapter.Address += c_offset;
++
++ a->xdi_adapter.Control = a->resources.pci.addr[2]; /* BAR2 SDRAM */
++
++ a->xdi_adapter.ram = a->resources.pci.addr[2]; /* BAR2 SDRAM */
++ a->xdi_adapter.ram += c_offset + (offset - MQ_SHARED_RAM_SIZE);
++
++ a->xdi_adapter.reset = a->resources.pci.addr[0]; /* BAR0 CONFIG */
++ /*
++ ctlReg contains the register address for the MIPS CPU reset control
++ */
++ a->xdi_adapter.ctlReg = a->resources.pci.addr[3]; /* BAR3 CNTRL */
++ /*
++ prom contains the register address for FPGA and EEPROM programming
++ */
++ a->xdi_adapter.prom = &a->xdi_adapter.reset[0x6E];
++}
++
+ /*
+ ** BAR0 - MEM - 0x100 - CONFIG MEM
+ ** BAR1 - I/O - 0x100 - UNUSED
+@@ -110,11 +144,11 @@
+ int diva_4bri_init_card(diva_os_xdi_adapter_t * a)
+ {
+ int bar, i;
++ byte *p;
+ PADAPTER_LIST_ENTRY quadro_list;
+ diva_os_xdi_adapter_t *diva_current;
+ diva_os_xdi_adapter_t *adapter_list[4];
+ PISDN_ADAPTER Slave;
+- dword offset;
+ unsigned long bar_length[sizeof(_4bri_bar_length) /
+ sizeof(_4bri_bar_length[0])];
+ int v2 = _4bri_is_rev_2_card(a->CardOrdinal);
+@@ -142,7 +176,7 @@
+ have to map any BAR before we can access it
+ */
+ if (!_4bri_get_serial_number(a)) {
+- DBG_ERR(("A: 4BRI can't ger Serial Number"))
++ DBG_ERR(("A: 4BRI can't get Serial Number"))
+ diva_4bri_cleanup_adapter(a);
+ return (-1);
+ }
+@@ -190,7 +224,7 @@
+ for (bar = 0; bar < 4; bar++) {
+ if (bar != 1) { /* ignore I/O */
+ a->resources.pci.addr[bar] =
+- divasa_remap_pci_bar(a->resources.pci.bar[bar],
++ divasa_remap_pci_bar(a, bar, a->resources.pci.bar[bar],
+ bar_length[bar]);
+ if (!a->resources.pci.addr[bar]) {
+ DBG_ERR(("A: 4BRI: can't map bar[%d]", bar))
+@@ -205,14 +239,15 @@
+ */
+ sprintf(&a->port_name[0], "DIVA 4BRI %ld", (long) a->xdi_adapter.serialNo);
+
+- if (diva_os_register_io_port(1, a->resources.pci.bar[1],
+- bar_length[1], &a->port_name[0])) {
++ if (diva_os_register_io_port(a, 1, a->resources.pci.bar[1],
++ bar_length[1], &a->port_name[0], 1)) {
+ DBG_ERR(("A: 4BRI: can't register bar[1]"))
+ diva_4bri_cleanup_adapter(a);
+ return (-1);
+ }
+
+- a->resources.pci.addr[1] = (void *) (unsigned long) a->resources.pci.bar[1];
++ a->resources.pci.addr[1] =
++ (void *) (unsigned long) a->resources.pci.bar[1];
+
+ /*
+ Set cleanup pointer for base adapter only, so slave adapter
+@@ -265,8 +300,8 @@
+ (PADAPTER_LIST_ENTRY) diva_os_malloc(0, sizeof(*quadro_list));
+ if (!(a->slave_list = quadro_list)) {
+ for (i = 0; i < (tasks - 1); i++) {
+- diva_os_free(0, a->slave_adapters[bar]);
+- a->slave_adapters[bar] = 0;
++ diva_os_free(0, a->slave_adapters[i]);
++ a->slave_adapters[i] = 0;
+ }
+ diva_4bri_cleanup_adapter(a);
+ return (-1);
+@@ -359,60 +394,39 @@
+ prepare_qBri_functions(&a->xdi_adapter);
+ }
+
++ for (i = 0; i < tasks; i++) {
++ diva_current = adapter_list[i];
++ if (i)
++ memcpy(&diva_current->resources, &a->resources, sizeof(divas_card_resources_t));
++ diva_current->resources.pci.qoffset = (a->xdi_adapter.MemorySize >> factor);
++ }
++
+ /*
+ Set up hardware related pointers
+ */
+ a->xdi_adapter.cfg = (void *) (unsigned long) a->resources.pci.bar[0]; /* BAR0 CONFIG */
+ a->xdi_adapter.port = (void *) (unsigned long) a->resources.pci.bar[1]; /* BAR1 */
+- a->xdi_adapter.Address = a->resources.pci.addr[2]; /* BAR2 SDRAM */
+- a->xdi_adapter.ctlReg =
+- (void *) (unsigned long) a->resources.pci.bar[3]; /* BAR3 CNTRL */
+-
+- a->xdi_adapter.reset = a->resources.pci.addr[0]; /* BAR0 CONFIG */
+- a->xdi_adapter.ram = a->resources.pci.addr[2]; /* BAR2 SDRAM */
+- /*
+- ctlReg contains the register address for the MIPS CPU reset control
+- */
+- a->xdi_adapter.ctlReg = a->resources.pci.addr[3]; /* BAR3 CNTRL */
+- /*
+- prom contains the register address for FPGA and EEPROM programming
+- */
+- a->xdi_adapter.prom = &a->xdi_adapter.reset[0x6E];
+- /*
+- reset contains the base address for the PLX 9054 register set
+- */
+- a->xdi_adapter.reset[PLX9054_INTCSR] = 0x00; /* disable PCI interrupts */
++ a->xdi_adapter.ctlReg = (void *) (unsigned long) a->resources.pci.bar[3]; /* BAR3 CNTRL */
+
+- /*
+- Replicate addresses to all instances, set shared memory
+- address for all instances
+- */
+ for (i = 0; i < tasks; i++) {
++ diva_current = adapter_list[i];
++ diva_4bri_set_addresses(diva_current);
+ Slave = a->xdi_adapter.QuadroList->QuadroAdapter[i];
+- offset =
+- Slave->ControllerNumber *
+- (a->xdi_adapter.MemorySize >> factor);
+- Slave->Address = &a->xdi_adapter.Address[offset];
+- Slave->ram = &a->xdi_adapter.ram[offset];
+- Slave->reset = a->xdi_adapter.reset;
+- Slave->ctlReg = a->xdi_adapter.ctlReg;
+- Slave->prom = a->xdi_adapter.prom;
+- Slave->reset = a->xdi_adapter.reset;
++ Slave->MultiMaster = &a->xdi_adapter;
+ Slave->sdram_bar = a->xdi_adapter.sdram_bar;
+- }
+- for (i = 0; i < tasks; i++) {
+- Slave = a->xdi_adapter.QuadroList->QuadroAdapter[i];
+- Slave->ram +=
+- ((a->xdi_adapter.MemorySize >> factor) -
+- MQ_SHARED_RAM_SIZE);
+- }
+- for (i = 1; i < tasks; i++) {
+- Slave = a->xdi_adapter.QuadroList->QuadroAdapter[i];
+- Slave->serialNo =
+- ((dword) (Slave->ControllerNumber << 24)) | a->
+- xdi_adapter.serialNo;
++ if (i) {
++ Slave->serialNo = ((dword) (Slave->ControllerNumber << 24)) |
++ a->xdi_adapter.serialNo;
+ Slave->cardType = a->xdi_adapter.cardType;
+ }
++ }
++
++ /*
++ reset contains the base address for the PLX 9054 register set
++ */
++ p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
++ p[PLX9054_INTCSR] = 0x00; /* disable PCI interrupts */
++ DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
+
+ /*
+ Set IRQ handler
+@@ -484,8 +498,7 @@
+ if (bar != 1) {
+ if (a->resources.pci.bar[bar]
+ && a->resources.pci.addr[bar]) {
+- divasa_unmap_pci_bar(a->resources.pci.
+- addr[bar]);
++ divasa_unmap_pci_bar(a->resources.pci.addr[bar]);
+ a->resources.pci.bar[bar] = 0;
+ a->resources.pci.addr[bar] = 0;
+ }
+@@ -496,12 +509,12 @@
+ Unregister I/O
+ */
+ if (a->resources.pci.bar[1] && a->resources.pci.addr[1]) {
+- diva_os_register_io_port(0, a->resources.pci.bar[1],
++ diva_os_register_io_port(a, 0, a->resources.pci.bar[1],
+ _4bri_is_rev_2_card(a->
+ CardOrdinal) ?
+ _4bri_v2_bar_length[1] :
+ _4bri_bar_length[1],
+- &a->port_name[0]);
++ &a->port_name[0], 1);
+ a->resources.pci.bar[1] = 0;
+ a->resources.pci.addr[1] = 0;
+ }
+@@ -776,23 +789,18 @@
+ a->xdi_mbox.
+ data_length);
+ if (a->xdi_mbox.data) {
+- byte *src =
+- a->xdi_adapter.Address;
+- byte *dst =
+- a->xdi_mbox.data;
+- dword len =
+- a->xdi_mbox.
+- data_length;
+-
+- src +=
+- cmd->command_data.
+- read_sdram.offset;
++ byte *p = DIVA_OS_MEM_ATTACH_ADDRESS(&a->xdi_adapter);
++ byte *src = p;
++ byte *dst = a->xdi_mbox.data;
++ dword len = a->xdi_mbox.data_length;
++
++ src += cmd->command_data.read_sdram.offset;
+
+ while (len--) {
+ *dst++ = *src++;
+ }
+- a->xdi_mbox.status =
+- DIVA_XDI_MBOX_BUSY;
++ DIVA_OS_MEM_DETACH_ADDRESS(&a->xdi_adapter, p);
++ a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
+ ret = 0;
+ }
+ }
+@@ -903,10 +911,12 @@
+ dword address,
+ const byte * data, dword length, dword limit)
+ {
+- byte *mem = IoAdapter->Address;
++ byte *p = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
++ byte *mem = p;
+
+ if (((address + length) >= limit) || !mem) {
+- DBG_ERR(("A: A(%d) write PRI address=0x%08lx",
++ DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
++ DBG_ERR(("A: A(%d) write 4BRI address=0x%08lx",
+ IoAdapter->ANum, address + length))
+ return (-1);
+ }
+@@ -916,6 +926,7 @@
+ *mem++ = *data++;
+ }
+
++ DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
+ return (0);
+ }
+
+@@ -926,16 +937,18 @@
+ volatile word *signature;
+ int started = 0;
+ int i;
++ byte *p;
+
+ /*
+ start adapter
+ */
+ start_qBri_hardware(IoAdapter);
+
++ p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
+ /*
+ wait for signature in shared memory (max. 3 seconds)
+ */
+- signature = (volatile word *) (&IoAdapter->ram[0x1E]);
++ signature = (volatile word *) (&p[0x1E]);
+
+ for (i = 0; i < 300; ++i) {
+ diva_os_wait(10);
+@@ -958,10 +971,12 @@
+ DBG_FTL(("%s: Adapter selftest failed, signature=%04x",
+ IoAdapter->Properties.Name,
+ READ_WORD(&signature[0])))
++ DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
+ (*(IoAdapter->trapFnc)) (IoAdapter);
+ IoAdapter->stop(IoAdapter);
+ return (-1);
+ }
++ DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
+
+ for (i = 0; i < IoAdapter->tasks; i++) {
+ IoAdapter->QuadroList->QuadroAdapter[i]->Initialized = 1;
+@@ -997,13 +1012,16 @@
+ #ifdef SUPPORT_INTERRUPT_TEST_ON_4BRI
+ int i;
+ ADAPTER *a = &IoAdapter->a;
++ byte *p;
+
+ IoAdapter->IrqCount = 0;
+
+ if (IoAdapter->ControllerNumber > 0)
+ return (-1);
+
+- IoAdapter->reset[PLX9054_INTCSR] = PLX9054_INT_ENABLE;
++ p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
++ p[PLX9054_INTCSR] = PLX9054_INT_ENABLE;
++ DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
+ /*
+ interrupt test
+ */
+@@ -1015,20 +1033,23 @@
+ return ((IoAdapter->IrqCount > 0) ? 0 : -1);
+ #else
+ dword volatile *qBriIrq;
++ byte *p;
+ /*
+ Reset on-board interrupt register
+ */
+ IoAdapter->IrqCount = 0;
+- qBriIrq =
+- (dword volatile *) (&IoAdapter->
+- ctlReg[_4bri_is_rev_2_card
++ p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
++ qBriIrq = (dword volatile *) (&p[_4bri_is_rev_2_card
+ (IoAdapter->
+ cardType) ? (MQ2_BREG_IRQ_TEST)
+ : (MQ_BREG_IRQ_TEST)]);
+
+ WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF);
++ DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
+
+- IoAdapter->reset[PLX9054_INTCSR] = PLX9054_INT_ENABLE;
++ p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
++ p[PLX9054_INTCSR] = PLX9054_INT_ENABLE;
++ DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
+
+ diva_os_wait(100);
+
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/os_bri.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/os_bri.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/os_bri.c 2003-09-27 11:38:21.755221088 +0800
+@@ -1,4 +1,4 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
+
+ #include "platform.h"
+ #include "debuglib.h"
+@@ -46,6 +46,27 @@
+ dword start_address, dword features);
+ static int diva_bri_stop_adapter(diva_os_xdi_adapter_t * a);
+
++static void diva_bri_set_addresses(diva_os_xdi_adapter_t * a)
++{
++ a->resources.pci.mem_type_id[MEM_TYPE_RAM] = 0;
++ a->resources.pci.mem_type_id[MEM_TYPE_CFG] = 1;
++ a->resources.pci.mem_type_id[MEM_TYPE_ADDRESS] = 2;
++ a->resources.pci.mem_type_id[MEM_TYPE_RESET] = 1;
++ a->resources.pci.mem_type_id[MEM_TYPE_PORT] = 2;
++ a->resources.pci.mem_type_id[MEM_TYPE_CTLREG] = 2;
++
++ a->xdi_adapter.ram = a->resources.pci.addr[0];
++ a->xdi_adapter.cfg = a->resources.pci.addr[1];
++ a->xdi_adapter.Address = a->resources.pci.addr[2];
++
++ a->xdi_adapter.reset = a->xdi_adapter.cfg;
++ a->xdi_adapter.port = a->xdi_adapter.Address;
++
++ a->xdi_adapter.ctlReg = a->xdi_adapter.port + M_PCI_RESET;
++
++ a->xdi_adapter.reset += 0x4C; /* PLX 9050 !! */
++}
++
+ /*
+ ** BAR0 - MEM Addr - 0x80 - NOT USED
+ ** BAR1 - I/O Addr - 0x80
+@@ -58,6 +79,7 @@
+ word cmd = 0, cmd_org;
+ byte Bus, Slot;
+ void *hdev;
++ byte *p;
+
+ /*
+ Set properties
+@@ -123,7 +145,7 @@
+ Map and register resources
+ */
+ if (!(a->resources.pci.addr[0] =
+- divasa_remap_pci_bar(a->resources.pci.bar[0],
++ divasa_remap_pci_bar(a, 0, a->resources.pci.bar[0],
+ bri_bar_length[0]))) {
+ DBG_ERR(("A: BRI, can't map BAR[0]"))
+ diva_bri_cleanup_adapter(a);
+@@ -133,8 +155,8 @@
+ sprintf(&a->port_name[0], "BRI %02x:%02x",
+ a->resources.pci.bus, a->resources.pci.func);
+
+- if (diva_os_register_io_port(1, a->resources.pci.bar[1],
+- bri_bar_length[1], &a->port_name[0])) {
++ if (diva_os_register_io_port(a, 1, a->resources.pci.bar[1],
++ bri_bar_length[1], &a->port_name[0], 1)) {
+ DBG_ERR(("A: BRI, can't register BAR[1]"))
+ diva_bri_cleanup_adapter(a);
+ return (-1);
+@@ -142,8 +164,8 @@
+ a->resources.pci.addr[1] = (void *) (unsigned long) a->resources.pci.bar[1];
+ a->resources.pci.length[1] = bri_bar_length[1];
+
+- if (diva_os_register_io_port(1, a->resources.pci.bar[2],
+- bar2_length, &a->port_name[0])) {
++ if (diva_os_register_io_port(a, 1, a->resources.pci.bar[2],
++ bar2_length, &a->port_name[0], 2)) {
+ DBG_ERR(("A: BRI, can't register BAR[2]"))
+ diva_bri_cleanup_adapter(a);
+ return (-1);
+@@ -152,6 +174,11 @@
+ a->resources.pci.length[2] = bar2_length;
+
+ /*
++ Set all memory areas
++ */
++ diva_bri_set_addresses(a);
++
++ /*
+ Get Serial Number
+ */
+ a->xdi_adapter.serialNo = diva_bri_get_serial_number(a);
+@@ -210,15 +237,9 @@
+ a->interface.cleanup_adapter_proc = diva_bri_cleanup_adapter;
+ a->interface.cmd_proc = diva_bri_cmd_card_proc;
+
+- a->xdi_adapter.cfg = a->resources.pci.addr[1];
+- a->xdi_adapter.Address = a->resources.pci.addr[2];
+-
+- a->xdi_adapter.reset = a->xdi_adapter.cfg;
+- a->xdi_adapter.port = a->xdi_adapter.Address;
+-
+- a->xdi_adapter.ctlReg = a->xdi_adapter.port + M_PCI_RESET;
+- a->xdi_adapter.reset += 0x4C; /* PLX 9050 !! */
+- outpp(a->xdi_adapter.reset, 0x41);
++ p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
++ outpp(p, 0x41);
++ DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
+
+ prepare_maestra_functions(&a->xdi_adapter);
+
+@@ -268,11 +289,11 @@
+
+ for (i = 1; i < 3; i++) {
+ if (a->resources.pci.addr[i] && a->resources.pci.bar[i]) {
+- diva_os_register_io_port(0,
++ diva_os_register_io_port(a, 0,
+ a->resources.pci.bar[i],
+ a->resources.pci.
+ length[i],
+- &a->port_name[0]);
++ &a->port_name[0], i);
+ a->resources.pci.addr[i] = 0;
+ a->resources.pci.bar[i] = 0;
+ }
+@@ -314,18 +335,20 @@
+ byte *confIO;
+ word serHi, serLo, *confMem;
+
+- confIO = (byte *) a->resources.pci.addr[1];
++ confIO = (byte *) DIVA_OS_MEM_ATTACH_CFG(&a->xdi_adapter);
+ serHi = (word) (inppw(&confIO[0x22]) & 0x0FFF);
+ serLo = (word) (inppw(&confIO[0x26]) & 0x0FFF);
+ serNo = ((dword) serHi << 16) | (dword) serLo;
++ DIVA_OS_MEM_DETACH_CFG(&a->xdi_adapter, confIO);
+
+ if ((serNo == 0) || (serNo == 0xFFFFFFFF)) {
+ DBG_FTL(("W: BRI use BAR[0] to get card serial number"))
+
+- confMem = (word *) a->resources.pci.addr[0];
++ confMem = (word *) DIVA_OS_MEM_ATTACH_RAM(&a->xdi_adapter);
+ serHi = (word) (READ_WORD(&confMem[0x11]) & 0x0FFF);
+ serLo = (word) (READ_WORD(&confMem[0x13]) & 0x0FFF);
+ serNo = (((dword) serHi) << 16) | ((dword) serLo);
++ DIVA_OS_MEM_DETACH_RAM(&a->xdi_adapter, confMem);
+ }
+
+ DBG_LOG(("Serial Number=%ld", serNo))
+@@ -342,9 +365,9 @@
+ int i;
+
+ for (i = 1; i < 3; i++) {
+- diva_os_register_io_port(0, a->resources.pci.bar[i],
++ diva_os_register_io_port(a, 0, a->resources.pci.bar[i],
+ a->resources.pci.length[i],
+- &a->port_name[0]);
++ &a->port_name[0], i);
+ a->resources.pci.addr[i] = 0;
+ }
+
+@@ -352,9 +375,9 @@
+ (long) a->xdi_adapter.serialNo);
+
+ for (i = 1; i < 3; i++) {
+- if (diva_os_register_io_port(1, a->resources.pci.bar[i],
++ if (diva_os_register_io_port(a, 1, a->resources.pci.bar[i],
+ a->resources.pci.length[i],
+- &a->port_name[0])) {
++ &a->port_name[0], i)) {
+ DBG_ERR(("A: failed to reregister BAR[%d]", i))
+ return (-1);
+ }
+@@ -493,6 +516,7 @@
+ {
+ byte *addrHi, *addrLo, *ioaddr;
+ dword i;
++ byte *Port;
+
+ if (!IoAdapter->port) {
+ return (-1);
+@@ -501,13 +525,13 @@
+ DBG_ERR(("A: A(%d) can't reset BRI adapter - please stop first",
+ IoAdapter->ANum)) return (-1);
+ }
+- addrHi =
+- IoAdapter->port +
+- ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
+- addrLo = IoAdapter->port + ADDR;
+- ioaddr = IoAdapter->port + DATA;
+ (*(IoAdapter->rstFnc)) (IoAdapter);
+ diva_os_wait(100);
++ Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
++ addrHi = Port +
++ ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
++ addrLo = Port + ADDR;
++ ioaddr = Port + DATA;
+ /*
+ recover
+ */
+@@ -540,6 +564,8 @@
+ outppw(addrLo, (word) 0);
+ outppw(ioaddr, (word) 0);
+
++ DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
++
+ /*
+ Forget all outstanding entities
+ */
+@@ -578,16 +604,17 @@
+ dword address, const byte * data, dword length)
+ {
+ byte *addrHi, *addrLo, *ioaddr;
++ byte *Port;
+
+ if (!IoAdapter->port) {
+ return (-1);
+ }
+
+- addrHi =
+- IoAdapter->port +
++ Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
++ addrHi = Port +
+ ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
+- addrLo = IoAdapter->port + ADDR;
+- ioaddr = IoAdapter->port + DATA;
++ addrLo = Port + ADDR;
++ ioaddr = Port + DATA;
+
+ while (length--) {
+ outpp(addrHi, (word) (address >> 16));
+@@ -596,6 +623,7 @@
+ address++;
+ }
+
++ DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
+ return (0);
+ }
+
+@@ -603,6 +631,7 @@
+ diva_bri_start_adapter(PISDN_ADAPTER IoAdapter,
+ dword start_address, dword features)
+ {
++ byte *Port;
+ dword i, test;
+ byte *addrHi, *addrLo, *ioaddr;
+ int started = 0;
+@@ -621,11 +650,11 @@
+ sprintf(IoAdapter->Name, "A(%d)", (int) IoAdapter->ANum);
+ DBG_LOG(("A(%d) start BRI", IoAdapter->ANum))
+
+- addrHi =
+- IoAdapter->port +
++ Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
++ addrHi = Port +
+ ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
+- addrLo = IoAdapter->port + ADDR;
+- ioaddr = IoAdapter->port + DATA;
++ addrLo = Port + ADDR;
++ ioaddr = Port + DATA;
+
+ outpp(addrHi,
+ (byte) (
+@@ -633,12 +662,20 @@
+ BRI_SHARED_RAM_SIZE) >> 16));
+ outppw(addrLo, 0x1e);
+ outppw(ioaddr, 0x00);
++ DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
+
+ /*
+ start the protocol code
+ */
+- outpp(IoAdapter->ctlReg, 0x08);
++ Port = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
++ outpp(Port, 0x08);
++ DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, Port);
+
++ Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
++ addrHi = Port +
++ ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
++ addrLo = Port + ADDR;
++ ioaddr = Port + DATA;
+ /*
+ wait for signature (max. 3 seconds)
+ */
+@@ -659,6 +696,7 @@
+ break;
+ }
+ }
++ DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
+
+ if (!started) {
+ DBG_FTL(("A: A(%d) %s: Adapter selftest failed 0x%04X",
+@@ -677,7 +715,9 @@
+ a->ReadyInt = 1;
+
+ if (IoAdapter->reset) {
+- outpp(IoAdapter->reset, 0x41);
++ Port = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
++ outpp(Port, 0x41);
++ DIVA_OS_MEM_DETACH_RESET(IoAdapter, Port);
+ }
+
+ a->ram_out(a, &PR_RAM->ReadyInt, 1);
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/os_pri.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/os_pri.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/os_pri.c 2003-09-27 11:38:21.763219872 +0800
+@@ -1,4 +1,4 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
+
+ #include "platform.h"
+ #include "debuglib.h"
+@@ -57,6 +57,34 @@
+ return (0);
+ }
+
++static void diva_pri_set_addresses(diva_os_xdi_adapter_t * a)
++{
++ a->resources.pci.mem_type_id[MEM_TYPE_ADDRESS] = 0;
++ a->resources.pci.mem_type_id[MEM_TYPE_CONTROL] = 2;
++ a->resources.pci.mem_type_id[MEM_TYPE_CONFIG] = 4;
++ a->resources.pci.mem_type_id[MEM_TYPE_RAM] = 0;
++ a->resources.pci.mem_type_id[MEM_TYPE_RESET] = 2;
++ a->resources.pci.mem_type_id[MEM_TYPE_CFG] = 4;
++ a->resources.pci.mem_type_id[MEM_TYPE_PROM] = 3;
++
++ a->xdi_adapter.Address = a->resources.pci.addr[0];
++ a->xdi_adapter.Control = a->resources.pci.addr[2];
++ a->xdi_adapter.Config = a->resources.pci.addr[4];
++
++ a->xdi_adapter.ram = a->resources.pci.addr[0];
++ a->xdi_adapter.ram += MP_SHARED_RAM_OFFSET;
++
++ a->xdi_adapter.reset = a->resources.pci.addr[2];
++ a->xdi_adapter.reset += MP_RESET;
++
++ a->xdi_adapter.cfg = a->resources.pci.addr[4];
++ a->xdi_adapter.cfg += MP_IRQ_RESET;
++
++ a->xdi_adapter.sdram_bar = a->resources.pci.bar[0];
++
++ a->xdi_adapter.prom = a->resources.pci.addr[3];
++}
++
+ /*
+ ** BAR0 - SDRAM, MP_MEMORY_SIZE, MP2_MEMORY_SIZE by Rev.2
+ ** BAR1 - DEVICES, 0x1000
+@@ -117,7 +145,7 @@
+ */
+ for (bar = 0; bar < 5; bar++) {
+ a->resources.pci.addr[bar] =
+- divasa_remap_pci_bar(a->resources.pci.bar[bar],
++ divasa_remap_pci_bar(a, bar, a->resources.pci.bar[bar],
+ bar_length[bar]);
+ if (!a->resources.pci.addr[bar]) {
+ DBG_ERR(("A: A(%d), can't map bar[%d]",
+@@ -128,6 +156,11 @@
+ }
+
+ /*
++ Set all memory areas
++ */
++ diva_pri_set_addresses(a);
++
++ /*
+ Get Serial Number of this adapter
+ */
+ if (pri_get_serial_number(a)) {
+@@ -194,23 +227,6 @@
+ prepare_pri_functions(&a->xdi_adapter);
+ }
+
+- /*
+- Set all memory areas
+- */
+- a->xdi_adapter.Address = a->resources.pci.addr[0];
+- a->xdi_adapter.sdram_bar = a->resources.pci.bar[0];
+- a->xdi_adapter.ram = a->resources.pci.addr[0];
+- a->xdi_adapter.ram += MP_SHARED_RAM_OFFSET;
+-
+- a->xdi_adapter.reset = a->resources.pci.addr[2];
+- a->xdi_adapter.reset += MP_RESET;
+-
+- a->xdi_adapter.prom =
+- (byte *) (unsigned long) a->resources.pci.bar[3];
+-
+- a->xdi_adapter.cfg = a->resources.pci.addr[4];
+- a->xdi_adapter.cfg += MP_IRQ_RESET;
+-
+ a->dsp_mask = diva_pri_detect_dsps(a);
+
+ /*
+@@ -317,7 +333,7 @@
+ static int diva_pri_reset_adapter(PISDN_ADAPTER IoAdapter)
+ {
+ dword i;
+- struct mp_load *boot = (struct mp_load *) IoAdapter->Address;
++ struct mp_load *boot;
+
+ if (!IoAdapter->Address || !IoAdapter->reset) {
+ return (-1);
+@@ -328,12 +344,20 @@
+ return (-1);
+ }
+
++ boot = (struct mp_load *) DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
+ WRITE_DWORD(&boot->err, 0);
++ DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
++
+ IoAdapter->rstFnc(IoAdapter);
++
+ diva_os_wait(10);
++
++ boot = (struct mp_load *) DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
+ i = READ_DWORD(&boot->live);
++
+ diva_os_wait(10);
+ if (i == READ_DWORD(&boot->live)) {
++ DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
+ DBG_ERR(("A: A(%d) CPU on PRI %ld is not alive!",
+ IoAdapter->ANum, IoAdapter->serialNo))
+ return (-1);
+@@ -342,8 +366,10 @@
+ DBG_ERR(("A: A(%d) PRI %ld Board Selftest failed, error=%08lx",
+ IoAdapter->ANum, IoAdapter->serialNo,
+ READ_DWORD(&boot->err)))
++ DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
+ return (-1);
+ }
++ DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
+
+ /*
+ Forget all outstanding entities
+@@ -383,9 +409,11 @@
+ dword address,
+ const byte * data, dword length, dword limit)
+ {
+- byte *mem = IoAdapter->Address;
++ byte *p = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
++ byte *mem = p;
+
+ if (((address + length) >= limit) || !mem) {
++ DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
+ DBG_ERR(("A: A(%d) write PRI address=0x%08lx",
+ IoAdapter->ANum, address + length))
+ return (-1);
+@@ -396,6 +424,7 @@
+ *mem++ = *data++;
+ }
+
++ DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
+ return (0);
+ }
+
+@@ -405,15 +434,18 @@
+ {
+ dword i;
+ int started = 0;
+- struct mp_load *boot = (struct mp_load *) IoAdapter->Address;
++ byte *p;
++ struct mp_load *boot = (struct mp_load *) DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
+ ADAPTER *a = &IoAdapter->a;
+
+ if (IoAdapter->Initialized) {
++ DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
+ DBG_ERR(("A: A(%d) pri_start_adapter, adapter already running",
+ IoAdapter->ANum))
+ return (-1);
+ }
+ if (!boot) {
++ DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
+ DBG_ERR(("A: PRI %ld can't start, adapter not mapped",
+ IoAdapter->serialNo))
+ return (-1);
+@@ -437,17 +469,22 @@
+ }
+
+ if (!started) {
+- dword TrapId = READ_DWORD(&IoAdapter->Address[0x80]);
+- dword debug = READ_DWORD(&IoAdapter->Address[0x1c]);
++ byte *p = (byte *)boot;
++ dword TrapId;
++ dword debug;
++ TrapId = READ_DWORD(&p[0x80]);
++ debug = READ_DWORD(&p[0x1c]);
+ DBG_ERR(("A(%d) Adapter start failed 0x%08lx, TrapId=%08lx, debug=%08lx",
+ IoAdapter->ANum, READ_DWORD(&boot->signature),
+ TrapId, debug))
++ DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
+ if (IoAdapter->trapFnc) {
+ (*(IoAdapter->trapFnc)) (IoAdapter);
+ }
+ IoAdapter->stop(IoAdapter);
+ return (-1);
+ }
++ DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
+
+ IoAdapter->Initialized = TRUE;
+
+@@ -455,8 +492,9 @@
+ Check Interrupt
+ */
+ IoAdapter->IrqCount = 0;
+- WRITE_DWORD(((dword volatile *) IoAdapter->cfg),
+- (dword) ~ 0x03E00000);
++ p = DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
++ WRITE_DWORD(((dword volatile *) p), (dword) ~ 0x03E00000);
++ DIVA_OS_MEM_DETACH_CFG(IoAdapter, p);
+ a->ReadyInt = 1;
+ a->ram_out(a, &PR_RAM->ReadyInt, 1);
+
+@@ -658,7 +696,8 @@
+ diva_os_malloc(0, a->xdi_mbox.data_length);
+ if (a->xdi_mbox.data) {
+ dword *data = (dword *) a->xdi_mbox.data;
+- if (!a->xdi_adapter.ram || !a->xdi_adapter.reset ||
++ if (!a->xdi_adapter.ram ||
++ !a->xdi_adapter.reset ||
+ !a->xdi_adapter.cfg) {
+ *data = 3;
+ } else if (a->xdi_adapter.trapped) {
+@@ -691,23 +730,18 @@
+ a->xdi_mbox.
+ data_length);
+ if (a->xdi_mbox.data) {
+- byte *src =
+- a->xdi_adapter.Address;
+- byte *dst =
+- a->xdi_mbox.data;
+- dword len =
+- a->xdi_mbox.
+- data_length;
+-
+- src +=
+- cmd->command_data.
+- read_sdram.offset;
++ byte *p = DIVA_OS_MEM_ATTACH_ADDRESS(&a->xdi_adapter);
++ byte *src = p;
++ byte *dst = a->xdi_mbox.data;
++ dword len = a->xdi_mbox.data_length;
++
++ src += cmd->command_data.read_sdram.offset;
+
+ while (len--) {
+ *dst++ = *src++;
+ }
+- a->xdi_mbox.status =
+- DIVA_XDI_MBOX_BUSY;
++ a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
++ DIVA_OS_MEM_DETACH_ADDRESS(&a->xdi_adapter, p);
+ ret = 0;
+ }
+ }
+@@ -731,27 +765,33 @@
+ byte data[64];
+ int i;
+ dword len = sizeof(data);
+- volatile byte *config = (byte *) a->resources.pci.addr[4];
+- volatile byte *flash = (byte *) a->resources.pci.addr[3];
++ volatile byte *config;
++ volatile byte *flash;
+
+ /*
+ * First set some GT6401x config registers before accessing the BOOT-ROM
+ */
++ config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
+ if (!(config[0xc3c] & 0x08)) {
+ config[0xc3c] |= 0x08; /* Base Address enable register */
+ }
+ config[LOW_BOOTCS_DREG] = 0x00;
+ config[HI_BOOTCS_DREG] = 0xFF;
++ DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
+ /*
+ * Read only the last 64 bytes of manufacturing data
+ */
+ memset(data, '\0', len);
++ flash = DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter);
+ for (i = 0; i < len; i++) {
+ data[i] = flash[0x8000 - len + i];
+ }
++ DIVA_OS_MEM_DETACH_PROM(&a->xdi_adapter, flash);
+
++ config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
+ config[LOW_BOOTCS_DREG] = 0xFC; /* Disable FLASH EPROM access */
+ config[HI_BOOTCS_DREG] = 0xFF;
++ DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
+
+ if (memcmp(&data[48], "DIVAserverPR", 12)) {
+ #if !defined(DIVA_PRI_NO_PCI_BIOS_WORKAROUND) /* { */
+@@ -791,22 +831,26 @@
+ /*
+ Try to read Flash again
+ */
+- config = (byte *) a->resources.pci.addr[4];
+- flash = (byte *) a->resources.pci.addr[3];
+ len = sizeof(data);
+
++ config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
+ if (!(config[0xc3c] & 0x08)) {
+ config[0xc3c] |= 0x08; /* Base Address enable register */
+ }
+ config[LOW_BOOTCS_DREG] = 0x00;
+ config[HI_BOOTCS_DREG] = 0xFF;
++ DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
+
+ memset(data, '\0', len);
++ flash = DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter);
+ for (i = 0; i < len; i++) {
+ data[i] = flash[0x8000 - len + i];
+ }
++ DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter, flash);
++ config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
+ config[LOW_BOOTCS_DREG] = 0xFC;
+ config[HI_BOOTCS_DREG] = 0xFF;
++ DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
+
+ if (memcmp(&data[48], "DIVAserverPR", 12)) {
+ DBG_ERR(("A: failed to read serial number"))
+@@ -907,7 +951,8 @@
+ */
+ static dword diva_pri_detect_dsps(diva_os_xdi_adapter_t * a)
+ {
+- byte *base = a->resources.pci.addr[2];
++ byte *base;
++ byte *p;
+ dword ret = 0;
+ dword row_offset[7] = {
+ 0x00000000,
+@@ -921,14 +966,17 @@
+ byte *dsp_addr_port, *dsp_data_port, row_state;
+ int dsp_row = 0, dsp_index, dsp_num;
+
+- if (!base || !a->xdi_adapter.reset) {
++ if (!a->xdi_adapter.Control || !a->xdi_adapter.reset) {
+ return (0);
+ }
+
+- *(volatile byte *) (a->xdi_adapter.reset) =
+- _MP_RISC_RESET | _MP_DSP_RESET;
++ p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
++ *(volatile byte *) p = _MP_RISC_RESET | _MP_DSP_RESET;
++ DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
+ diva_os_wait(5);
+
++ base = DIVA_OS_MEM_ATTACH_CONTROL(&a->xdi_adapter);
++
+ for (dsp_num = 0; dsp_num < 30; dsp_num++) {
+ dsp_row = dsp_num / 7 + 1;
+ dsp_index = dsp_num % 7;
+@@ -947,9 +995,11 @@
+ ret |= (1 << dsp_num);
+ }
+ }
++ DIVA_OS_MEM_DETACH_CONTROL(&a->xdi_adapter, base);
+
+- *(volatile byte *) (a->xdi_adapter.reset) =
+- _MP_RISC_RESET | _MP_LED1 | _MP_LED2;
++ p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
++ *(volatile byte *) p = _MP_RISC_RESET | _MP_LED1 | _MP_LED2;
++ DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
+ diva_os_wait(5);
+
+ /*
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/platform.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/platform.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/platform.h 2003-09-27 11:38:21.770218808 +0800
+@@ -1,9 +1,9 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
+ *
+ * platform.h
+ *
+ *
+- * Copyright 2000-2002 by Armin Schindler (mac@melware.de)
++ * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
+ * Copyright 2000 Eicon Networks
+ *
+ * This software may be used and distributed according to the terms
+@@ -23,20 +23,27 @@
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
++#include <linux/sched.h>
+ #include <linux/skbuff.h>
++#include <linux/vmalloc.h>
+ #include <linux/proc_fs.h>
+ #include <linux/interrupt.h>
+ #include <linux/smp_lock.h>
++#include <linux/delay.h>
+ #include <asm/types.h>
+ #include <asm/io.h>
+
+ #include "cardtype.h"
+
++/* activate debuglib for modules only */
++#ifndef MODULE
++#define DIVA_NO_DEBUGLIB
++#endif
++
+ #define DIVA_INIT_FUNCTION __init
+ #define DIVA_EXIT_FUNCTION __exit
+
+ #define DIVA_USER_MODE_CARD_CONFIG 1
+-#define XDI_USE_XLOG 1
+ #define USE_EXTENDED_DEBUGS 1
+
+ #define MAX_ADAPTER 32
+@@ -46,11 +53,6 @@
+ #define MEMORY_SPACE_TYPE 0
+ #define PORT_SPACE_TYPE 1
+
+-#include "debuglib.h"
+-
+-#define dtrc(p) DBG_PRV0(p)
+-#define dbug(a,p) DBG_PRV1(p)
+-
+
+ #include <linux/string.h>
+
+@@ -106,6 +108,36 @@
+ #define _cdecl
+ #endif
+
++#define MEM_TYPE_RAM 0
++#define MEM_TYPE_PORT 1
++#define MEM_TYPE_PROM 2
++#define MEM_TYPE_CTLREG 3
++#define MEM_TYPE_RESET 4
++#define MEM_TYPE_CFG 5
++#define MEM_TYPE_ADDRESS 6
++#define MEM_TYPE_CONFIG 7
++#define MEM_TYPE_CONTROL 8
++
++#define DIVA_OS_MEM_ATTACH_RAM(a) ((a)->ram)
++#define DIVA_OS_MEM_ATTACH_PORT(a) ((a)->port)
++#define DIVA_OS_MEM_ATTACH_PROM(a) ((a)->prom)
++#define DIVA_OS_MEM_ATTACH_CTLREG(a) ((a)->ctlReg)
++#define DIVA_OS_MEM_ATTACH_RESET(a) ((a)->reset)
++#define DIVA_OS_MEM_ATTACH_CFG(a) ((a)->cfg)
++#define DIVA_OS_MEM_ATTACH_ADDRESS(a) ((a)->Address)
++#define DIVA_OS_MEM_ATTACH_CONFIG(a) ((a)->Config)
++#define DIVA_OS_MEM_ATTACH_CONTROL(a) ((a)->Control)
++
++#define DIVA_OS_MEM_DETACH_RAM(a, x) do { } while(0)
++#define DIVA_OS_MEM_DETACH_PORT(a, x) do { } while(0)
++#define DIVA_OS_MEM_DETACH_PROM(a, x) do { } while(0)
++#define DIVA_OS_MEM_DETACH_CTLREG(a, x) do { } while(0)
++#define DIVA_OS_MEM_DETACH_RESET(a, x) do { } while(0)
++#define DIVA_OS_MEM_DETACH_CFG(a, x) do { } while(0)
++#define DIVA_OS_MEM_DETACH_ADDRESS(a, x) do { } while(0)
++#define DIVA_OS_MEM_DETACH_CONFIG(a, x) do { } while(0)
++#define DIVA_OS_MEM_DETACH_CONTROL(a, x) do { } while(0)
++
+ #if !defined(DIM)
+ #define DIM(array) (sizeof (array)/sizeof ((array)[0]))
+ #endif
+@@ -124,7 +156,11 @@
+ typedef struct _ISDN_ADAPTER* PISDN_ADAPTER;
+
+ typedef void (* DIVA_DI_PRINTF) (unsigned char *, ...);
+-extern DIVA_DI_PRINTF dprintf;
++#include "debuglib.h"
++
++#define dtrc(p) DBG_PRV0(p)
++#define dbug(a,p) DBG_PRV1(p)
++
+
+ typedef struct e_info_s E_INFO ;
+
+@@ -146,8 +182,21 @@
+ /*
+ ** memory allocation
+ */
+-void* diva_os_malloc (unsigned long flags, unsigned long size);
+-void diva_os_free (unsigned long flags, void* ptr);
++static __inline__ void* diva_os_malloc (unsigned long flags, unsigned long size)
++{
++ void *ret = NULL;
++
++ if (size) {
++ ret = (void *) vmalloc((unsigned int) size);
++ }
++ return (ret);
++}
++static __inline__ void diva_os_free (unsigned long flags, void* ptr)
++{
++ if (ptr) {
++ vfree(ptr);
++ }
++}
+
+ /*
+ ** use skbuffs for message buffer
+@@ -161,8 +210,17 @@
+ /*
+ ** mSeconds waiting
+ */
+-void diva_os_sleep(dword mSec);
+-void diva_os_wait(dword mSec);
++static __inline__ void diva_os_sleep(dword mSec)
++{
++ unsigned long timeout = HZ * mSec / 1000 + 1;
++
++ set_current_state(TASK_UNINTERRUPTIBLE);
++ schedule_timeout(timeout);
++}
++static __inline__ void diva_os_wait(dword mSec)
++{
++ mdelay(mSec);
++}
+
+ /*
+ ** PCI Configuration space access
+@@ -173,8 +231,8 @@
+ /*
+ ** I/O Port utilities
+ */
+-int diva_os_register_io_port (int register, unsigned long port, unsigned long length, const char* name);
+-
++int diva_os_register_io_port (void *adapter, int register, unsigned long port,
++ unsigned long length, const char* name, int id);
+ /*
+ ** I/O port access abstraction
+ */
+@@ -199,14 +257,6 @@
+ #define diva_os_in_irq() in_irq()
+
+ /*
+-** module locking
+-*/
+-/*
+-#define DIVA_LOCK_MODULE MOD_INC_USE_COUNT
+-#define DIVA_UNLOCK_MODULE MOD_DEC_USE_COUNT
+-*/
+-
+-/*
+ ** Spin Lock framework
+ */
+ typedef long diva_os_spin_lock_magic_t;
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/s_4bri.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/s_4bri.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/s_4bri.c 2003-09-27 11:38:21.779217440 +0800
+@@ -55,8 +55,8 @@
+ * check for trapped MIPS 46xx CPU, dump exception frame
+ */
+
++ base = DIVA_OS_MEM_ATTACH_CONTROL(IoAdapter);
+ offset = IoAdapter->ControllerNumber * (IoAdapter->MemorySize >> factor) ;
+- base = IoAdapter->ram - offset - ((IoAdapter->MemorySize >> factor) - MQ_SHARED_RAM_SIZE) ;
+
+ TrapID = READ_DWORD(&base[0x80]) ;
+
+@@ -75,8 +75,10 @@
+ if ( (regs[0] >= offset)
+ && (regs[0] < offset + (IoAdapter->MemorySize >> factor) - 1) )
+ {
+- if ( !(Xlog = (word *)diva_os_malloc (0, MAX_XLOG_SIZE)) )
++ if ( !(Xlog = (word *)diva_os_malloc (0, MAX_XLOG_SIZE)) ) {
++ DIVA_OS_MEM_DETACH_CONTROL(IoAdapter, base);
+ return ;
++ }
+
+ size = offset + (IoAdapter->MemorySize >> factor) - regs[0] ;
+ if ( size > MAX_XLOG_SIZE )
+@@ -89,7 +91,7 @@
+ diva_os_free (0, Xlog) ;
+ IoAdapter->trapped = 2 ;
+ }
+-
++ DIVA_OS_MEM_DETACH_CONTROL(IoAdapter, base);
+ }
+
+ /* --------------------------------------------------------------------------
+@@ -97,10 +99,10 @@
+ -------------------------------------------------------------------------- */
+ static void reset_qBri_hardware (PISDN_ADAPTER IoAdapter) {
+ word volatile *qBriReset ;
+- dword volatile *qBriCntrl ;
++ byte volatile *qBriCntrl ;
++ byte volatile *p ;
+
+- qBriReset = (word volatile *)IoAdapter->prom ;
+- qBriCntrl = (dword volatile *)(&IoAdapter->ctlReg[DIVA_4BRI_REVISION(IoAdapter) ? (MQ2_BREG_RISC) : (MQ_BREG_RISC)]);
++ qBriReset = (word volatile *)DIVA_OS_MEM_ATTACH_PROM(IoAdapter);
+ WRITE_WORD(qBriReset, READ_WORD(qBriReset) | PLX9054_SOFT_RESET) ;
+ diva_os_wait (1) ;
+ WRITE_WORD(qBriReset, READ_WORD(qBriReset) & ~PLX9054_SOFT_RESET) ;
+@@ -109,34 +111,40 @@
+ diva_os_wait (1) ;
+ WRITE_WORD(qBriReset, READ_WORD(qBriReset) & ~PLX9054_RELOAD_EEPROM) ;
+ diva_os_wait (1);
++ DIVA_OS_MEM_DETACH_PROM(IoAdapter, qBriReset);
+
+- WRITE_DWORD(qBriCntrl, 0) ;
++ qBriCntrl = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
++ p = &qBriCntrl[DIVA_4BRI_REVISION(IoAdapter) ? (MQ2_BREG_RISC) : (MQ_BREG_RISC)];
++ WRITE_DWORD(p, 0) ;
++ DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, qBriCntrl);
+
+ DBG_TRC(("resetted board @ reset addr 0x%08lx", qBriReset))
+- DBG_TRC(("resetted board @ cntrl addr 0x%08lx", qBriCntrl))
+-
++ DBG_TRC(("resetted board @ cntrl addr 0x%08lx", p))
+ }
+
+ /* --------------------------------------------------------------------------
+ Start Card CPU
+ -------------------------------------------------------------------------- */
+ void start_qBri_hardware (PISDN_ADAPTER IoAdapter) {
+- dword volatile *qBriReset ;
++ byte volatile *qBriReset ;
++ byte volatile *p ;
+
+- qBriReset = (dword volatile *)(&IoAdapter->ctlReg[DIVA_4BRI_REVISION(IoAdapter) ? (MQ2_BREG_RISC) : (MQ_BREG_RISC)]);
++ p = (byte volatile *)DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
++ qBriReset = &p[(DIVA_4BRI_REVISION(IoAdapter)) ? (MQ2_BREG_RISC) : (MQ_BREG_RISC)];
+ WRITE_DWORD(qBriReset, MQ_RISC_COLD_RESET_MASK) ;
+ diva_os_wait (2) ;
+ WRITE_DWORD(qBriReset, MQ_RISC_WARM_RESET_MASK | MQ_RISC_COLD_RESET_MASK) ;
+ diva_os_wait (10) ;
++ DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
+
+ DBG_TRC(("started processor @ addr 0x%08lx", qBriReset))
+-
+ }
+
+ /* --------------------------------------------------------------------------
+ Stop Card CPU
+ -------------------------------------------------------------------------- */
+ static void stop_qBri_hardware (PISDN_ADAPTER IoAdapter) {
++ byte volatile *p ;
+ dword volatile *qBriReset ;
+ dword volatile *qBriIrq ;
+ dword volatile *qBriIsacDspReset ;
+@@ -147,16 +155,24 @@
+
+ if ( IoAdapter->ControllerNumber > 0 )
+ return ;
+- qBriReset = (dword volatile *)(&IoAdapter->ctlReg[reset_offset]) ;
+- qBriIrq = (dword volatile *)(&IoAdapter->ctlReg[irq_offset]) ;
+- qBriIsacDspReset = (dword volatile *)(&IoAdapter->ctlReg[hw_offset]);
++ p = (byte volatile *)DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
++ qBriReset = (dword volatile *)&p[reset_offset];
++ qBriIsacDspReset = (dword volatile *)&p[hw_offset];
+ /*
+ * clear interrupt line (reset Local Interrupt Test Register)
+ */
+ WRITE_DWORD(qBriReset, 0) ;
+ WRITE_DWORD(qBriIsacDspReset, 0) ;
+- IoAdapter->reset[PLX9054_INTCSR] = 0x00 ; /* disable PCI interrupts */
++ DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
++
++ p = (byte volatile *)DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
++ p[PLX9054_INTCSR] = 0x00 ; /* disable PCI interrupts */
++ DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
++
++ p = (byte volatile *)DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
++ qBriIrq = (dword volatile *)&p[irq_offset];
+ WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF) ;
++ DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
+
+ DBG_TRC(("stopped processor @ addr 0x%08lx", qBriReset))
+
+@@ -260,7 +276,7 @@
+ int bit ;
+ byte *File ;
+ dword code, FileLength ;
+- word volatile *addr = (word volatile *)IoAdapter->prom ;
++ word volatile *addr = (word volatile *)DIVA_OS_MEM_ATTACH_PROM(IoAdapter);
+ word val, baseval = FPGA_CS | FPGA_PROG ;
+
+
+@@ -291,8 +307,10 @@
+ File = qBri_check_FPGAsrc (IoAdapter, "ds4bri.bit",
+ &FileLength, &code) ;
+ }
+- if ( !File )
++ if ( !File ) {
++ DIVA_OS_MEM_DETACH_PROM(IoAdapter, addr);
+ return (0) ;
++ }
+ /*
+ * prepare download, pulse PROGRAM pin down.
+ */
+@@ -306,6 +324,7 @@
+ {
+ DBG_FTL(("FPGA download: acknowledge for FPGA memory clear missing"))
+ xdiFreeFile (File) ;
++ DIVA_OS_MEM_DETACH_PROM(IoAdapter, addr);
+ return (0) ;
+ }
+ /*
+@@ -329,6 +348,8 @@
+ diva_os_wait (100) ;
+ val = READ_WORD(addr) ;
+
++ DIVA_OS_MEM_DETACH_PROM(IoAdapter, addr);
++
+ if ( !(val & FPGA_BUSY) )
+ {
+ DBG_FTL(("FPGA download: chip remains in busy state (0x%04x)", val))
+@@ -343,12 +364,10 @@
+ Download protocol code to the adapter
+ -------------------------------------------------------------------------- */
+
+-#define DOWNLOAD_ADDR(IoAdapter) (&IoAdapter->ram[IoAdapter->downloadAddr & (IoAdapter->MemorySize - 1)])
+-
+-
+ static int qBri_protocol_load (PISDN_ADAPTER BaseIoAdapter, PISDN_ADAPTER IoAdapter) {
+ PISDN_ADAPTER HighIoAdapter;
+
++ byte *p;
+ dword FileLength ;
+ dword *sharedRam, *File;
+ dword Addr, ProtOffset, SharedRamOffset, i;
+@@ -436,7 +455,8 @@
+ return (0) ;
+ }
+ IoAdapter->downloadAddr = 0 ;
+- sharedRam = (dword *)DOWNLOAD_ADDR(IoAdapter) ;
++ p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
++ sharedRam = (dword *)&p[IoAdapter->downloadAddr & (IoAdapter->MemorySize - 1)];
+ memcpy (sharedRam, File, FileLength) ;
+
+ DBG_TRC(("Download addr 0x%08x len %ld - virtual 0x%08x",
+@@ -449,10 +469,12 @@
+ DBG_FTL(("File=0x%x, sharedRam=0x%x", File, sharedRam))
+ DBG_BLK(( (char *)File, 256))
+ DBG_BLK(( (char *)sharedRam, 256))
++ DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
+
+ xdiFreeFile (File) ;
+ return (0) ;
+ }
++ DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
+ xdiFreeFile (File) ;
+
+ return (1) ;
+@@ -466,6 +488,7 @@
+ PISDN_ADAPTER IoAdapter;
+ word i ;
+ dword *sharedRam ;
++ byte *p;
+
+ i = 0 ;
+
+@@ -485,12 +508,14 @@
+ IoAdapter->downloadAddr + length))
+ return (-1) ;
+ }
+- sharedRam = (dword*)(&BaseIoAdapter->ram[IoAdapter->downloadAddr &
+- (IoAdapter->MemorySize - 1)]) ;
+-
++ p = DIVA_OS_MEM_ATTACH_RAM(BaseIoAdapter);
++ sharedRam = (dword*)&p[IoAdapter->downloadAddr & (IoAdapter->MemorySize - 1)];
+
+- if ( fp->sysFileRead (fp, sharedRam, length) != length )
++ if ( fp->sysFileRead (fp, sharedRam, length) != length ) {
++ DIVA_OS_MEM_DETACH_RAM(BaseIoAdapter, p);
+ return (-1) ;
++ }
++ DIVA_OS_MEM_DETACH_RAM(BaseIoAdapter, p);
+
+ IoAdapter->downloadAddr += length ;
+ IoAdapter->downloadAddr = (IoAdapter->downloadAddr + 3) & (~3) ;
+@@ -509,6 +534,7 @@
+ word download_count, i ;
+ dword *sharedRam ;
+ dword FileLength ;
++ byte *p;
+
+ if ( !(fp = OsOpenFile (DSP_TELINDUS_FILE)) ) {
+ DBG_FTL(("qBri_telindus_load: %s not found!", DSP_TELINDUS_FILE))
+@@ -553,8 +579,8 @@
+ * store # of download files extracted from the archive and download table
+ */
+ HighIoAdapter->downloadAddr = HighIoAdapter->DspCodeBaseAddr ;
+- sharedRam = (dword *)(&BaseIoAdapter->ram[HighIoAdapter->downloadAddr &
+- (IoAdapter->MemorySize - 1)]) ;
++ p = DIVA_OS_MEM_ATTACH_RAM(BaseIoAdapter);
++ sharedRam = (dword *)&p[HighIoAdapter->downloadAddr & (IoAdapter->MemorySize - 1)];
+ WRITE_DWORD(&(sharedRam[0]), (dword)download_count);
+ memcpy (&sharedRam[1], &download_table[0], sizeof(download_table)) ;
+
+@@ -563,6 +589,7 @@
+ if ( memcmp (&sharedRam[1], &download_table, download_count) ) {
+ DBG_FTL(("%s: Dsp Memory test failed!", IoAdapter->Properties.Name))
+ }
++ DIVA_OS_MEM_DETACH_RAM(BaseIoAdapter, p);
+
+ return (FileLength) ;
+ }
+@@ -588,6 +615,7 @@
+ dword phys_start_addr;
+ dword end_addr;
+ byte* sharedRam = 0;
++ byte *p;
+
+ if (task) {
+ if (!(fp = OsOpenFile (task))) {
+@@ -657,18 +685,22 @@
+ }
+
+ fp->sysFileSeek (fp, 0, OS_SEEK_SET);
+- sharedRam = &BaseIoAdapter->ram[phys_start_addr];
++ p = DIVA_OS_MEM_ATTACH_RAM(BaseIoAdapter);
++ sharedRam = &p[phys_start_addr];
+ if ((dword)fp->sysFileRead (fp, sharedRam, FileLength) != FileLength) {
++ DIVA_OS_MEM_DETACH_RAM(BaseIoAdapter, p);
+ OsCloseFile (fp) ;
+ DBG_ERR(("Can't read image [%s]", task))
+ return (0);
+ }
++ DIVA_OS_MEM_DETACH_RAM(BaseIoAdapter, p);
+
+ OsCloseFile (fp) ;
+ }
+
++ p = DIVA_OS_MEM_ATTACH_RAM(BaseIoAdapter);
+ if (!link_addr) {
+- link_addr = &BaseIoAdapter->ram[OFFS_DSP_CODE_BASE_ADDR];
++ link_addr = &p[OFFS_DSP_CODE_BASE_ADDR];
+ }
+
+ DBG_TRC(("Write task [%s] link %08lx at %08lx",
+@@ -681,6 +713,8 @@
+ link_addr[2] = (byte)((start_addr >> 16) & 0xff);
+ link_addr[3] = (byte)((start_addr >> 24) & 0xff);
+
++ DIVA_OS_MEM_DETACH_RAM(BaseIoAdapter, p);
++
+ return (task ? &sharedRam[DIVA_MIPS_TASK_IMAGE_LINK_OFFS] : 0);
+ }
+
+@@ -691,6 +725,7 @@
+ dword i, offset, controller ;
+ word *signature ;
+ int factor = (IoAdapter->tasks == 1) ? 1 : 2;
++ byte *p;
+
+ PISDN_ADAPTER Slave ;
+
+@@ -751,7 +786,8 @@
+ Slave->reset = IoAdapter->reset ;
+ Slave->ctlReg = IoAdapter->ctlReg ;
+ Slave->prom = IoAdapter->prom ;
+- Slave->reset = IoAdapter->reset ;
++ Slave->Config = IoAdapter->Config ;
++ Slave->Control = IoAdapter->Control ;
+
+ if ( !qBri_protocol_load (IoAdapter, Slave) )
+ return (0) ;
+@@ -782,9 +818,11 @@
+ {
+ Slave = IoAdapter->QuadroList->QuadroAdapter[i] ;
+ Slave->ram += (IoAdapter->MemorySize >> factor) - MQ_SHARED_RAM_SIZE ;
++ p = DIVA_OS_MEM_ATTACH_RAM(Slave);
+ DBG_TRC(("Configure instance %d shared memory @ 0x%08lx",
+- Slave->ControllerNumber, Slave->ram))
+- memset (Slave->ram, '\0', 256) ;
++ Slave->ControllerNumber, p))
++ memset (p, '\0', 256) ;
++ DIVA_OS_MEM_DETACH_RAM(Slave, p);
+ diva_configure_protocol (Slave);
+ }
+
+@@ -792,7 +830,8 @@
+ * start adapter
+ */
+ start_qBri_hardware (IoAdapter) ;
+- signature = (word *)(&IoAdapter->ram[0x1E]) ;
++ p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
++ signature = (word *)(&p[0x1E]) ;
+ /*
+ * wait for signature in shared memory (max. 3 seconds)
+ */
+@@ -802,12 +841,14 @@
+
+ if ( signature[0] == 0x4447 )
+ {
++ DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
+ DBG_TRC(("Protocol startup time %d.%02d seconds",
+ (i / 100), (i % 100) ))
+
+ return (1) ;
+ }
+ }
++ DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
+ DBG_FTL(("%s: Adapter selftest failed (0x%04X)!",
+ IoAdapter->Properties.Name, signature[0] >> 16))
+ qBri_cpu_trapped (IoAdapter) ;
+@@ -829,16 +870,23 @@
+
+ word i ;
+ int serviced = 0 ;
++ byte *p;
+
++ p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
+
+- if ( !(IoAdapter->reset[PLX9054_INTCSR] & 0x80) )
++ if ( !(p[PLX9054_INTCSR] & 0x80) ) {
++ DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
+ return (0) ;
++ }
++ DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
+
+ /*
+ * clear interrupt line (reset Local Interrupt Test Register)
+ */
+- qBriIrq = (dword volatile *)(&IoAdapter->ctlReg[DIVA_4BRI_REVISION(IoAdapter) ? (MQ2_BREG_IRQ_TEST) : (MQ_BREG_IRQ_TEST)]);
++ p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
++ qBriIrq = (dword volatile *)(&p[DIVA_4BRI_REVISION(IoAdapter) ? (MQ2_BREG_IRQ_TEST) : (MQ_BREG_IRQ_TEST)]);
+ WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF) ;
++ DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
+
+ for ( i = 0 ; i < IoAdapter->tasks; ++i )
+ {
+@@ -861,15 +909,21 @@
+ -------------------------------------------------------------------------- */
+ static void disable_qBri_interrupt (PISDN_ADAPTER IoAdapter) {
+ dword volatile *qBriIrq ;
++ byte *p;
+
+ if ( IoAdapter->ControllerNumber > 0 )
+ return ;
+- qBriIrq = (dword volatile *)(&IoAdapter->ctlReg[DIVA_4BRI_REVISION(IoAdapter) ? (MQ2_BREG_IRQ_TEST) : (MQ_BREG_IRQ_TEST)]);
+ /*
+ * clear interrupt line (reset Local Interrupt Test Register)
+ */
+- IoAdapter->reset[PLX9054_INTCSR] = 0x00 ; /* disable PCI interrupts */
++ p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
++ p[PLX9054_INTCSR] = 0x00 ; /* disable PCI interrupts */
++ DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
++
++ p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
++ qBriIrq = (dword volatile *)(&p[DIVA_4BRI_REVISION(IoAdapter) ? (MQ2_BREG_IRQ_TEST) : (MQ_BREG_IRQ_TEST)]);
+ WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF) ;
++ DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
+ }
+
+ /* --------------------------------------------------------------------------
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/s_bri.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/s_bri.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/s_bri.c 2003-09-27 11:38:21.785216528 +0800
+@@ -45,15 +45,16 @@
+ word *Xlog ;
+ dword regs[4], i, size ;
+ Xdesc xlogDesc ;
++ byte *Port;
+ /*
+ * first read pointers and trap frame
+ */
+ if ( !(Xlog = (word *)diva_os_malloc (0, MAX_XLOG_SIZE)) )
+ return ;
+- addrHi = IoAdapter->port
+- + ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH) ;
+- addrLo = IoAdapter->port + ADDR ;
+- ioaddr = IoAdapter->port + DATA ;
++ Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
++ addrHi = Port + ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH) ;
++ addrLo = Port + ADDR ;
++ ioaddr = Port + DATA ;
+ outpp (addrHi, 0) ;
+ outppw (addrLo, 0) ;
+ for ( i = 0 ; i < 0x100 ; Xlog[i++] = inppw(ioaddr) ) ;
+@@ -95,21 +96,28 @@
+ outpp (addrHi, (byte)((BRI_UNCACHED_ADDR (IoAdapter->MemoryBase + IoAdapter->MemorySize -
+ BRI_SHARED_RAM_SIZE)) >> 16)) ;
+ outppw (addrLo, 0x00) ;
++ DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
+ }
+ /* ---------------------------------------------------------------------
+ Reset hardware
+ --------------------------------------------------------------------- */
+ static void reset_bri_hardware (PISDN_ADAPTER IoAdapter) {
+- outpp (IoAdapter->ctlReg, 0x00) ;
++ byte *p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
++ outpp (p, 0x00) ;
++ DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
+ }
+ /* ---------------------------------------------------------------------
+ Halt system
+ --------------------------------------------------------------------- */
+ static void stop_bri_hardware (PISDN_ADAPTER IoAdapter) {
+- if (IoAdapter->reset) {
+- outpp (IoAdapter->reset, 0x00) ; /* disable interrupts ! */
+- }
+- outpp (IoAdapter->ctlReg, 0x00) ; /* clear int, halt cpu */
++ byte *p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
++ if (p) {
++ outpp (p, 0x00) ; /* disable interrupts ! */
++ }
++ DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
++ p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
++ outpp (p, 0x00) ; /* clear int, halt cpu */
++ DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
+ }
+ #if !defined(DIVA_USER_MODE_CARD_CONFIG) /* { */
+ /* ---------------------------------------------------------------------
+@@ -121,6 +129,7 @@
+ byte* addrHi, *addrLo, *ioaddr ;
+ char *FileName = &IoAdapter->Protocol[0] ;
+ dword Addr, i ;
++ byte *Port;
+ /* -------------------------------------------------------------------
+ Try to load protocol code. 'File' points to memory location
+ that does contain entire protocol code
+@@ -173,10 +182,10 @@
+ DBG_FTL(("Protocol code '%s' too big (%ld)", FileName, FileLength))
+ return (0) ;
+ }
+- addrHi = IoAdapter->port
+- + ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH) ;
+- addrLo = IoAdapter->port + ADDR ;
+- ioaddr = IoAdapter->port + DATA ;
++ Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
++ addrHi = Port + ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH) ;
++ addrLo = Port + ADDR ;
++ ioaddr = Port + DATA ;
+ /*
+ * set start address for download (use autoincrement mode !)
+ */
+@@ -204,12 +213,14 @@
+ test = inppw (ioaddr) ;
+ if ( test != File[i/2] )
+ {
++ DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
+ DBG_FTL(("%s: Memory test failed! (%d - 0x%04X/0x%04X)",
+ IoAdapter->Properties.Name, i, test, File[i/2]))
+ xdiFreeFile (File);
+ return (0) ;
+ }
+ }
++ DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
+ xdiFreeFile (File);
+ return (FileLength) ;
+ }
+@@ -290,6 +301,7 @@
+ t_dsp_portable_desc download_table[DSP_MAX_DOWNLOAD_COUNT] ;
+ word download_count ;
+ dword FileLength ;
++ byte *Port;
+ if (!pinfo) {
+ DBG_ERR (("A: out of memory s_bri at %d", __LINE__))
+ return (0);
+@@ -299,11 +311,11 @@
+ return (0) ;
+ }
+ FileLength = fp->sysFileSize ;
++ Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
+ pinfo->IoAdapter = IoAdapter ;
+- pinfo->AddrLo = IoAdapter->port + ADDR ;
+- pinfo->AddrHi = IoAdapter->port +\
+- (IoAdapter->Properties.Bus == BUS_PCI ? M_PCI_ADDRH : ADDRH);
+- pinfo->Data = (word*)(IoAdapter->port + DATA) ;
++ pinfo->AddrLo = Port + ADDR ;
++ pinfo->AddrHi = Port + (IoAdapter->Properties.Bus == BUS_PCI ? M_PCI_ADDRH : ADDRH);
++ pinfo->Data = (word*)(Port + DATA) ;
+ pinfo->DownloadPos = (IoAdapter->DspCodeBaseAddr +\
+ sizeof(dword) + sizeof(download_table) + 3) & (~3) ;
+ fp->sysLoadDesc = (void *)pinfo;
+@@ -317,6 +329,7 @@
+ &download_count, NULL, &download_table[0]) ;
+ if ( error )
+ {
++ DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
+ DBG_FTL(("download file error: %s", error))
+ OsCloseFile (fp) ;
+ diva_os_free (0, pinfo);
+@@ -335,23 +348,25 @@
+ * copy download table to board
+ */
+ outppw_buffer (pinfo->Data, &download_table[0], sizeof(download_table)) ;
++ DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
+ diva_os_free (0, pinfo);
+ return (FileLength) ;
+ }
+ /******************************************************************************/
+ static int load_bri_hardware (PISDN_ADAPTER IoAdapter) {
+ dword i ;
+- byte* addrHi, *addrLo, *ioaddr ;
++ byte* addrHi, *addrLo, *ioaddr, *p ;
+ dword test ;
++ byte *Port;
+ if ( IoAdapter->Properties.Card != CARD_MAE )
+ {
+ return (FALSE) ;
+ }
+- addrHi = IoAdapter->port \
+- + ((IoAdapter->Properties.Bus==BUS_PCI) ? M_PCI_ADDRH : ADDRH);
+- addrLo = IoAdapter->port + ADDR ;
+- ioaddr = IoAdapter->port + DATA ;
+ reset_bri_hardware (IoAdapter) ;
++ Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
++ addrHi = Port + ((IoAdapter->Properties.Bus==BUS_PCI) ? M_PCI_ADDRH : ADDRH);
++ addrLo = Port + ADDR ;
++ ioaddr = Port + DATA ;
+ diva_os_wait (100);
+ /*
+ * recover
+@@ -366,6 +381,7 @@
+ IoAdapter->MemorySize - BRI_SHARED_RAM_SIZE)) >> 16)) ;
+ outppw (addrLo, 0) ;
+ for ( i = 0 ; i < 0x8000 ; outppw (ioaddr, 0), ++i ) ;
++ DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
+ diva_os_wait (100) ;
+ /*
+ * download protocol and dsp files
+@@ -396,6 +412,11 @@
+ return (FALSE) ;
+ break ;
+ }
++
++ Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
++ addrHi = Port + ((IoAdapter->Properties.Bus==BUS_PCI) ? M_PCI_ADDRH : ADDRH);
++ addrLo = Port + ADDR ;
++ ioaddr = Port + DATA ;
+ /*
+ * clear signature
+ */
+@@ -408,13 +429,20 @@
+ * copy parameters
+ */
+ diva_configure_protocol (IoAdapter);
++ DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
+ /*
+ * start the protocol code
+ */
+- outpp (IoAdapter->ctlReg, 0x08) ;
++ p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
++ outpp (p, 0x08) ;
++ DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
+ /*
+ * wait for signature (max. 3 seconds)
+ */
++ Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
++ addrHi = Port + ((IoAdapter->Properties.Bus==BUS_PCI) ? M_PCI_ADDRH : ADDRH);
++ addrLo = Port + ADDR ;
++ ioaddr = Port + DATA ;
+ for ( i = 0 ; i < 300 ; ++i )
+ {
+ diva_os_wait (10) ;
+@@ -424,11 +452,13 @@
+ test = (dword)inppw (ioaddr) ;
+ if ( test == 0x4447 )
+ {
++ DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
+ DBG_TRC(("Protocol startup time %d.%02d seconds",
+ (i / 100), (i % 100) ))
+ return (TRUE) ;
+ }
+ }
++ DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
+ DBG_FTL(("%s: Adapter selftest failed (0x%04X)!",
+ IoAdapter->Properties.Name, test))
+ bri_cpu_trapped (IoAdapter) ;
+@@ -441,12 +471,18 @@
+ #endif /* } */
+ /******************************************************************************/
+ static int bri_ISR (struct _ISDN_ADAPTER* IoAdapter) {
+- if ( !(inpp (IoAdapter->ctlReg) & 0x01) )
++ byte *p;
++
++ p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
++ if ( !(inpp (p) & 0x01) ) {
++ DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
+ return (0) ;
++ }
+ /*
+ clear interrupt line
+ */
+- outpp (IoAdapter->ctlReg, 0x08) ;
++ outpp (p, 0x08) ;
++ DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
+ IoAdapter->IrqCount++ ;
+ if ( IoAdapter->Initialized ) {
+ diva_os_schedule_soft_isr (&IoAdapter->isr_soft_isr);
+@@ -457,11 +493,16 @@
+ Disable IRQ in the card hardware
+ -------------------------------------------------------------------------- */
+ static void disable_bri_interrupt (PISDN_ADAPTER IoAdapter) {
+- if ( IoAdapter->reset )
+- {
+- outpp (IoAdapter->reset, 0x00) ; /* disable interrupts ! */
+- }
+- outpp (IoAdapter->ctlReg, 0x00) ; /* clear int, halt cpu */
++ byte *p;
++ p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
++ if ( p )
++ {
++ outpp (p, 0x00) ; /* disable interrupts ! */
++ }
++ DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
++ p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
++ outpp (p, 0x00) ; /* clear int, halt cpu */
++ DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
+ }
+ /* -------------------------------------------------------------------------
+ Fill card entry points
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/s_pri.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/s_pri.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/s_pri.c 2003-09-27 11:38:21.791215616 +0800
+@@ -54,7 +54,7 @@
+ /*
+ * check for trapped MIPS 46xx CPU, dump exception frame
+ */
+- base = IoAdapter->ram - MP_SHARED_RAM_OFFSET ;
++ base = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
+ TrapID = READ_DWORD(&base[0x80]) ;
+ if ( (TrapID == 0x99999999) || (TrapID == 0x99999901) )
+ {
+@@ -68,8 +68,10 @@
+ regs[0] &= IoAdapter->MemorySize - 1 ;
+ if ( (regs[0] < IoAdapter->MemorySize - 1) )
+ {
+- if ( !(Xlog = (word *)diva_os_malloc (0, MAX_XLOG_SIZE)) )
++ if ( !(Xlog = (word *)diva_os_malloc (0, MAX_XLOG_SIZE)) ) {
++ DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, base);
+ return ;
++ }
+ size = IoAdapter->MemorySize - regs[0] ;
+ if ( size > MAX_XLOG_SIZE )
+ size = MAX_XLOG_SIZE ;
+@@ -81,24 +83,29 @@
+ diva_os_free (0, Xlog) ;
+ IoAdapter->trapped = 2 ;
+ }
++ DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, base);
+ }
+ /* -------------------------------------------------------------------------
+ Hardware reset of PRI card
+ ------------------------------------------------------------------------- */
+ static void reset_pri_hardware (PISDN_ADAPTER IoAdapter) {
+- *IoAdapter->reset = _MP_RISC_RESET | _MP_LED1 | _MP_LED2 ;
++ byte *p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
++ *p = _MP_RISC_RESET | _MP_LED1 | _MP_LED2 ;
+ diva_os_wait (50) ;
+- *IoAdapter->reset = 0x00 ;
++ *p = 0x00 ;
+ diva_os_wait (50) ;
++ DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
+ }
+ /* -------------------------------------------------------------------------
+ Stop Card Hardware
+ ------------------------------------------------------------------------- */
+ static void stop_pri_hardware (PISDN_ADAPTER IoAdapter) {
+ dword i;
+- dword volatile *cfgReg = (dword volatile *)IoAdapter->cfg ;
++ byte *p;
++ dword volatile *cfgReg = (dword volatile *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
+ cfgReg[3] = 0x00000000 ;
+ cfgReg[1] = 0x00000000 ;
++ DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg);
+ IoAdapter->a.ram_out (&IoAdapter->a, &RAM->SWReg, SWREG_HALT_CPU) ;
+ i = 0 ;
+ while ( (i < 100) && (IoAdapter->a.ram_in (&IoAdapter->a, &RAM->SWReg) != 0) )
+@@ -107,21 +114,25 @@
+ i++ ;
+ }
+ DBG_TRC(("%s: PRI stopped (%d)", IoAdapter->Name, i))
++ cfgReg = (dword volatile *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
+ WRITE_DWORD(&cfgReg[0],((dword)(~0x03E00000)));
++ DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg);
+ diva_os_wait (1) ;
+- *IoAdapter->reset = _MP_RISC_RESET | _MP_LED1 | _MP_LED2 ;
++ p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
++ *p = _MP_RISC_RESET | _MP_LED1 | _MP_LED2 ;
++ DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
+ }
+ #if !defined(DIVA_USER_MODE_CARD_CONFIG) /* { */
+ /* -------------------------------------------------------------------------
+ Load protocol code to the PRI Card
+ ------------------------------------------------------------------------- */
+-#define DOWNLOAD_ADDR(IoAdapter) \
+- (&IoAdapter->ram[IoAdapter->downloadAddr & (IoAdapter->MemorySize - 1)])
++#define DOWNLOAD_ADDR(IoAdapter) (IoAdapter->downloadAddr & (IoAdapter->MemorySize - 1))
+ static int pri_protocol_load (PISDN_ADAPTER IoAdapter) {
+ dword FileLength ;
+ dword *File ;
+ dword *sharedRam ;
+ dword Addr ;
++ byte *p;
+ if (!(File = (dword *)xdiLoadArchive (IoAdapter, &FileLength, 0))) {
+ return (0) ;
+ }
+@@ -172,14 +183,17 @@
+ return (0) ;
+ }
+ IoAdapter->downloadAddr = MP_UNCACHED_ADDR (MP_PROTOCOL_OFFSET) ;
+- sharedRam = (dword *)DOWNLOAD_ADDR(IoAdapter) ;
++ p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
++ sharedRam = (dword *)(&p[DOWNLOAD_ADDR(IoAdapter)]);
+ memcpy (sharedRam, File, FileLength) ;
+ if ( memcmp (sharedRam, File, FileLength) )
+ {
++ DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
+ DBG_FTL(("%s: Memory test failed!", IoAdapter->Properties.Name))
+ xdiFreeFile (File);
+ return (0) ;
+ }
++ DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
+ xdiFreeFile (File);
+ return (1) ;
+ }
+@@ -228,8 +242,8 @@
+ static dword
+ diva_pri_detect_dsps (PISDN_ADAPTER IoAdapter)
+ {
+- /* byte* base = a->resources.pci.addr[2]; */
+- byte* base = IoAdapter->reset - MP_RESET ;
++ byte* base;
++ byte* p;
+ dword ret = 0, DspCount = 0 ;
+ dword row_offset[] = {
+ 0x00000000,
+@@ -242,14 +256,18 @@
+ byte *dsp_addr_port, *dsp_data_port, row_state;
+ int dsp_row = 0, dsp_index, dsp_num;
+ IoAdapter->InitialDspInfo &= 0xffff ;
+- /* if (!base || !a->xdi_adapter.reset) */
+- if (!base || !IoAdapter->reset)
++ p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
++ if (!p)
+ {
++ DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
+ return (0);
+ }
+- /* *(volatile byte*)(a->xdi_adapter.reset) = _MP_RISC_RESET | _MP_DSP_RESET; */
+- *(volatile byte*)(IoAdapter->reset) = _MP_RISC_RESET | _MP_DSP_RESET;
++ *(volatile byte*)(p) = _MP_RISC_RESET | _MP_DSP_RESET;
++ DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
+ diva_os_wait (5) ;
++
++ base = DIVA_OS_MEM_ATTACH_CONTROL(IoAdapter);
++
+ for (dsp_num = 0; dsp_num < 30; dsp_num++) {
+ dsp_row = dsp_num / 7 + 1;
+ dsp_index = dsp_num % 7;
+@@ -264,8 +282,10 @@
+ DspCount++ ;
+ }
+ }
+- /* *(volatile byte*)(a->xdi_adapter.reset) = _MP_RISC_RESET | _MP_LED1 | _MP_LED2; */
+- *(volatile byte*)(IoAdapter->reset) = _MP_RISC_RESET | _MP_LED1 | _MP_LED2;
++ DIVA_OS_MEM_DETACH_CONTROL(IoAdapter, base);
++
++ p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
++ *(volatile byte*)(p) = _MP_RISC_RESET | _MP_LED1 | _MP_LED2;
+ diva_os_wait (50) ;
+ /*
+ Verify modules
+@@ -301,7 +321,8 @@
+ ((ret >> (3*7)) & 0x7F) ? "Y" : "N"))
+ DBG_LOG(("+-----------------------+"))
+ DBG_LOG(("DSP's(present-absent):%08x-%08x", ret, ~ret & 0x3fffffff))
+- *(volatile byte*)(IoAdapter->reset) = 0 ;
++ *(volatile byte*)(p) = 0 ;
++ DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
+ diva_os_wait (50) ;
+ IoAdapter->InitialDspInfo |= DspCount << 16 ;
+ return (ret);
+@@ -312,6 +333,7 @@
+ static long pri_download_buffer (OsFileHandle *fp, long length, void **addr) {
+ PISDN_ADAPTER IoAdapter = (PISDN_ADAPTER)fp->sysLoadDesc ;
+ dword *sharedRam ;
++ byte *p;
+ *addr = (void *)IoAdapter->downloadAddr ;
+ if ( ((dword) length) > IoAdapter->DspCodeBaseAddr +
+ IoAdapter->MaxDspCodeSize - IoAdapter->downloadAddr )
+@@ -321,11 +343,15 @@
+ IoAdapter->downloadAddr + length))
+ return (-1) ;
+ }
+- sharedRam = (dword *)DOWNLOAD_ADDR(IoAdapter) ;
+- if ( fp->sysFileRead (fp, sharedRam, length) != length )
++ p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
++ sharedRam = (dword *)(&p[DOWNLOAD_ADDR(IoAdapter)]);
++ if ( fp->sysFileRead (fp, sharedRam, length) != length ) {
++ DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
+ return (-1) ;
++ }
+ IoAdapter->downloadAddr += length ;
+ IoAdapter->downloadAddr = (IoAdapter->downloadAddr + 3) & (~3) ;
++ DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
+ return (0) ;
+ }
+ /* -------------------------------------------------------------------------
+@@ -338,6 +364,7 @@
+ word download_count ;
+ dword *sharedRam ;
+ dword FileLength ;
++ byte *p;
+ if ( !(fp = OsOpenFile (DSP_TELINDUS_FILE)) )
+ return (0) ;
+ IoAdapter->downloadAddr = (IoAdapter->DspCodeBaseAddr
+@@ -363,9 +390,11 @@
+ * store # of separate download files extracted from archive
+ */
+ IoAdapter->downloadAddr = IoAdapter->DspCodeBaseAddr ;
+- sharedRam = (dword *)DOWNLOAD_ADDR(IoAdapter) ;
++ p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
++ sharedRam = (dword *)(&p[DOWNLOAD_ADDR(IoAdapter)]);
+ WRITE_DWORD(&(sharedRam[0]), (dword)download_count);
+ memcpy (&sharedRam[1], &download_table[0], sizeof(download_table)) ;
++ DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
+ return (FileLength) ;
+ }
+ /* -------------------------------------------------------------------------
+@@ -374,14 +403,17 @@
+ #define MIN_DSPS 0x30000000
+ static int load_pri_hardware (PISDN_ADAPTER IoAdapter) {
+ dword i ;
+- struct mp_load *boot = (struct mp_load *)IoAdapter->ram ;
+- if ( IoAdapter->Properties.Card != CARD_MAEP )
++ struct mp_load *boot = (struct mp_load *)DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
++ if ( IoAdapter->Properties.Card != CARD_MAEP ) {
++ DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
+ return (0) ;
++ }
+ boot->err = 0 ;
+ #if 0
+ IoAdapter->rstFnc (IoAdapter) ;
+ #else
+ if ( MIN_DSPS != (MIN_DSPS & diva_pri_detect_dsps(IoAdapter)) ) { /* makes reset */
++ DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
+ DBG_FTL(("%s: DSP error!", IoAdapter->Properties.Name))
+ return (0) ;
+ }
+@@ -394,28 +426,36 @@
+ diva_os_wait (10) ;
+ if ( i == boot->live )
+ {
++ DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
+ DBG_FTL(("%s: CPU is not alive!", IoAdapter->Properties.Name))
+ return (0) ;
+ }
+ if ( boot->err )
+ {
++ DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
+ DBG_FTL(("%s: Board Selftest failed!", IoAdapter->Properties.Name))
+ return (0) ;
+ }
+ /*
+ * download protocol and dsp files
+ */
+- if ( !xdiSetProtocol (IoAdapter, IoAdapter->ProtocolSuffix) )
++ if ( !xdiSetProtocol (IoAdapter, IoAdapter->ProtocolSuffix) ) {
++ DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
+ return (0) ;
+- if ( !pri_protocol_load (IoAdapter) )
++ }
++ if ( !pri_protocol_load (IoAdapter) ) {
++ DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
+ return (0) ;
+- if ( !pri_telindus_load (IoAdapter) )
++ }
++ if ( !pri_telindus_load (IoAdapter) ) {
++ DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
+ return (0) ;
++ }
+ /*
+ * copy configuration parameters
+ */
+ IoAdapter->ram += MP_SHARED_RAM_OFFSET ;
+- memset (IoAdapter->ram, '\0', 256) ;
++ memset (boot + MP_SHARED_RAM_OFFSET, '\0', 256) ;
+ diva_configure_protocol (IoAdapter);
+ /*
+ * start adapter
+@@ -430,11 +470,13 @@
+ diva_os_wait (10) ;
+ if ( (boot->signature >> 16) == 0x4447 )
+ {
++ DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
+ DBG_TRC(("Protocol startup time %d.%02d seconds",
+ (i / 100), (i % 100) ))
+ return (1) ;
+ }
+ }
++ DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
+ DBG_FTL(("%s: Adapter selftest failed (0x%04X)!",
+ IoAdapter->Properties.Name, boot->signature >> 16))
+ pri_cpu_trapped (IoAdapter) ;
+@@ -449,12 +491,16 @@
+ PRI Adapter interrupt Service Routine
+ -------------------------------------------------------------------------- */
+ static int pri_ISR (struct _ISDN_ADAPTER* IoAdapter) {
+- if ( !((READ_DWORD((dword *)IoAdapter->cfg)) & 0x80000000) )
++ byte *cfg = DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
++ if ( !((READ_DWORD((dword *)cfg)) & 0x80000000) ) {
++ DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfg);
+ return (0) ;
++ }
+ /*
+ clear interrupt line
+ */
+- WRITE_DWORD(((dword *)IoAdapter->cfg), (dword)~0x03E00000) ;
++ WRITE_DWORD(((dword *)cfg), (dword)~0x03E00000) ;
++ DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfg);
+ IoAdapter->IrqCount++ ;
+ if ( IoAdapter->Initialized )
+ {
+@@ -466,10 +512,11 @@
+ Disable interrupt in the card hardware
+ ------------------------------------------------------------------------- */
+ static void disable_pri_interrupt (PISDN_ADAPTER IoAdapter) {
+- dword volatile *cfgReg = (dword volatile *)IoAdapter->cfg ;
++ dword volatile *cfgReg = (dword volatile *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter) ;
+ cfgReg[3] = 0x00000000 ;
+ cfgReg[1] = 0x00000000 ;
+ WRITE_DWORD(&cfgReg[0], (dword)(~0x03E00000)) ;
++ DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg);
+ }
+ /* -------------------------------------------------------------------------
+ Install entry points for PRI Adapter
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/um_idi.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/um_idi.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/um_idi.c 2003-09-27 11:38:21.799214400 +0800
+@@ -1,4 +1,4 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
+
+ #include "platform.h"
+ #include "di_defs.h"
+@@ -37,6 +37,11 @@
+ static int process_idi_ind(divas_um_idi_entity_t * e, byte ind);
+ static int write_return_code(divas_um_idi_entity_t * e, byte rc);
+
++/*
++ * include queue functions
++ */
++#include "dlist.c"
++
+ /* --------------------------------------------------------------------------
+ MAIN
+ -------------------------------------------------------------------------- */
+@@ -171,7 +176,15 @@
+ ------------------------------------------------------------------------ */
+ int diva_um_idi_nr_of_adapters(void)
+ {
+- return (diva_q_get_nr_of_entries(&adapter_q));
++ int i = 0;
++ const diva_entity_queue_t * q = &adapter_q;
++ const diva_entity_link_t *diva_current = q->head;
++
++ while (diva_current) {
++ i++;
++ diva_current = diva_current->next;
++ }
++ return(i);
+ }
+
+ /* ------------------------------------------------------------------------
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/xdi_adapter.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/xdi_adapter.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/xdi_adapter.h 2003-09-27 11:38:21.800214248 +0800
+@@ -1,4 +1,4 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
+
+ #ifndef __DIVA_OS_XDI_ADAPTER_H__
+ #define __DIVA_OS_XDI_ADAPTER_H__
+@@ -14,7 +14,8 @@
+ dword bar[8]; /* contains context of appropriate BAR Register */
+ void *addr[8]; /* same bar, but mapped into memory */
+ dword length[8]; /* bar length */
+-
++ int mem_type_id[10];
++ unsigned int qoffset;
+ byte irq;
+ } divas_pci_card_resources_t;
+
+Index: linux-2.6.0-test5/drivers/isdn/hisax/avma1_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hisax/avma1_cs.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hisax/avma1_cs.c 2003-09-27 11:38:21.804213640 +0800
+@@ -438,17 +438,6 @@
+
+ DEBUG(0, "avma1cs_release(0x%p)\n", link);
+
+- /*
+- If the device is currently in use, we won't release until it
+- is actually closed.
+- */
+- if (link->open) {
+- DEBUG(1, "avma1_cs: release postponed, '%s' still open\n",
+- link->dev->dev_name);
+- link->state |= DEV_STALE_CONFIG;
+- return;
+- }
+-
+ /* no unregister function with hisax */
+ HiSax_closecard(local->node.minor);
+
+@@ -463,7 +452,6 @@
+
+ if (link->state & DEV_STALE_LINK)
+ avma1cs_detach(link);
+-
+ } /* avma1cs_release */
+
+ /*======================================================================
+Index: linux-2.6.0-test5/drivers/isdn/hisax/config.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hisax/config.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hisax/config.c 2003-09-27 11:38:21.818211512 +0800
+@@ -2113,7 +2113,7 @@
+
+ #include <linux/pci.h>
+
+-static struct pci_device_id hisax_pci_tbl[] __initdata = {
++static struct pci_device_id hisax_pci_tbl[] = {
+ #ifdef CONFIG_HISAX_FRITZPCI
+ {PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1, PCI_ANY_ID, PCI_ANY_ID},
+ #endif
+Index: linux-2.6.0-test5/drivers/isdn/hisax/elsa_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hisax/elsa_cs.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hisax/elsa_cs.c 2003-09-27 11:38:21.824210600 +0800
+@@ -442,18 +442,6 @@
+
+ DEBUG(0, "elsa_cs_release(0x%p)\n", link);
+
+- /*
+- If the device is currently in use, we won't release until it
+- is actually closed, because until then, we can't be sure that
+- no one will try to access the device or its data structures.
+- */
+- if (link->open) {
+- DEBUG(1, "elsa_cs: release postponed, '%s' "
+- "still open\n", link->dev->dev_name);
+- link->state |= DEV_STALE_CONFIG;
+- return;
+- }
+-
+ /* Unlink the device chain */
+ link->dev = NULL;
+
+Index: linux-2.6.0-test5/drivers/isdn/hisax/sedlbauer_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hisax/sedlbauer_cs.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hisax/sedlbauer_cs.c 2003-09-27 11:38:21.830209688 +0800
+@@ -535,18 +535,6 @@
+ {
+ DEBUG(0, "sedlbauer_release(0x%p)\n", link);
+
+- /*
+- If the device is currently in use, we won't release until it
+- is actually closed, because until then, we can't be sure that
+- no one will try to access the device or its data structures.
+- */
+- if (link->open) {
+- DEBUG(1, "sedlbauer_cs: release postponed, '%s' still open\n",
+- link->dev->dev_name);
+- link->state |= DEV_STALE_CONFIG;
+- return;
+- }
+-
+ /* Unlink the device chain */
+ link->dev = NULL;
+
+Index: linux-2.6.0-test5/drivers/isdn/hysdn/hysdn_init.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hysdn/hysdn_init.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hysdn/hysdn_init.c 2003-09-27 11:38:21.834209080 +0800
+@@ -21,7 +21,7 @@
+
+ #include "hysdn_defs.h"
+
+-static struct pci_device_id hysdn_pci_tbl[] __initdata = {
++static struct pci_device_id hysdn_pci_tbl[] = {
+ {PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_METRO},
+ {PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2},
+ {PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_ERGO},
+Index: linux-2.6.0-test5/drivers/isdn/i4l/isdn_tty.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/i4l/isdn_tty.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/i4l/isdn_tty.c 2003-09-27 11:38:21.858205432 +0800
+@@ -1989,7 +1989,8 @@
+ memcpy(m->pmsn, m->msn, ISDN_MSNLEN);
+ memcpy(m->plmsn, m->lmsn, ISDN_LMSNLEN);
+ if ((get_isdn_dev())->profd)
+- kill_pg_info(SIGIO, SEND_SIG_PRIV, (get_isdn_dev())->profd->pgrp);
++ kill_pg_info(SIGIO, SEND_SIG_PRIV,
++ process_group((get_isdn_dev())->profd));
+ }
+
+ static struct tty_operations modem_ops = {
+Index: linux-2.6.0-test5/drivers/macintosh/adb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/macintosh/adb.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/macintosh/adb.c 2003-09-27 11:38:21.864204520 +0800
+@@ -266,8 +266,7 @@
+ static void
+ __adb_probe_task(void *data)
+ {
+- adb_probe_task_pid = kernel_thread(adb_probe_task, NULL,
+- SIGCHLD | CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++ adb_probe_task_pid = kernel_thread(adb_probe_task, NULL, SIGCHLD | CLONE_KERNEL);
+ }
+
+ static DECLARE_WORK(adb_reset_work, __adb_probe_task, NULL);
+Index: linux-2.6.0-test5/drivers/macintosh/mediabay.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/macintosh/mediabay.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/macintosh/mediabay.c 2003-09-27 11:38:21.871203456 +0800
+@@ -694,8 +694,7 @@
+
+ /* Startup kernel thread */
+ if (i == 0)
+- kernel_thread(media_bay_task, NULL,
+- CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++ kernel_thread(media_bay_task, NULL, CLONE_KERNEL);
+
+ return 0;
+
+Index: linux-2.6.0-test5/drivers/md/dm.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/md/dm.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/md/dm.c 2003-09-27 11:38:21.876202696 +0800
+@@ -79,7 +79,7 @@
+ int r;
+
+ /* allocate a slab for the dm_ios */
+- _io_cache = kmem_cache_create("dm io",
++ _io_cache = kmem_cache_create("dm_io",
+ sizeof(struct dm_io), 0, 0, NULL, NULL);
+ if (!_io_cache)
+ return -ENOMEM;
+Index: linux-2.6.0-test5/drivers/md/dm-ioctl-v1.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/md/dm-ioctl-v1.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/md/dm-ioctl-v1.c 2003-09-27 11:38:21.882201784 +0800
+@@ -459,7 +459,7 @@
+ if (!bdev)
+ return -ENXIO;
+
+- param->dev = bdev->bd_dev;
++ param->dev = old_encode_dev(bdev->bd_dev);
+ param->open_count = bdev->bd_openers;
+ bdput(bdev);
+
+@@ -577,7 +577,7 @@
+ }
+
+ if (param->flags & DM_PERSISTENT_DEV_FLAG)
+- r = dm_create_with_minor(MINOR(param->dev), &md);
++ r = dm_create_with_minor(MINOR(old_decode_dev(param->dev)), &md);
+ else
+ r = dm_create(&md);
+
+@@ -816,7 +816,7 @@
+ count = 0;
+ list_for_each(tmp, dm_table_get_devices(table)) {
+ struct dm_dev *dd = list_entry(tmp, struct dm_dev, list);
+- deps->dev[count++] = dd->bdev->bd_dev;
++ deps->dev[count++] = old_encode_dev(dd->bdev->bd_dev);
+ }
+ dm_table_put(table);
+ dm_put(md);
+Index: linux-2.6.0-test5/drivers/md/dm-ioctl-v4.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/md/dm-ioctl-v4.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/md/dm-ioctl-v4.c 2003-09-27 11:38:21.890200568 +0800
+@@ -401,7 +401,7 @@
+ old_nl->next = (uint32_t) ((void *) nl -
+ (void *) old_nl);
+ disk = dm_disk(hc->md);
+- nl->dev = MKDEV(disk->major, disk->first_minor);
++ nl->dev = huge_encode_dev(MKDEV(disk->major, disk->first_minor));
+ nl->next = 0;
+ strcpy(nl->name, hc->name);
+
+@@ -445,7 +445,7 @@
+ if (!bdev)
+ return -ENXIO;
+
+- param->dev = MKDEV(disk->major, disk->first_minor);
++ param->dev = huge_encode_dev(MKDEV(disk->major, disk->first_minor));
+
+ /*
+ * Yes, this will be out of date by the time it gets back
+@@ -481,7 +481,7 @@
+ return r;
+
+ if (param->flags & DM_PERSISTENT_DEV_FLAG)
+- r = dm_create_with_minor(MINOR(param->dev), &md);
++ r = dm_create_with_minor(MINOR(huge_decode_dev(param->dev)), &md);
+ else
+ r = dm_create(&md);
+
+@@ -886,7 +886,7 @@
+ count = 0;
+ list_for_each(tmp, dm_table_get_devices(table)) {
+ struct dm_dev *dd = list_entry(tmp, struct dm_dev, list);
+- deps->dev[count++] = dd->bdev->bd_dev;
++ deps->dev[count++] = huge_encode_dev(dd->bdev->bd_dev);
+ }
+
+ param->data_size = param->data_start + needed;
+Index: linux-2.6.0-test5/drivers/md/dm-table.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/md/dm-table.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/md/dm-table.c 2003-09-27 11:38:21.895199808 +0800
+@@ -426,6 +426,8 @@
+ if (sscanf(path, "%u:%u", &major, &minor) == 2) {
+ /* Extract the major/minor numbers */
+ dev = MKDEV(major, minor);
++ if (MAJOR(dev) != major || MINOR(dev) != minor)
++ return -EOVERFLOW;
+ } else {
+ /* convert the path to a device */
+ if ((r = lookup_device(path, &dev)))
+Index: linux-2.6.0-test5/drivers/md/md.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/md/md.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/md/md.c 2003-09-27 11:38:21.917196464 +0800
+@@ -1450,7 +1450,7 @@
+ static struct kobject *md_probe(dev_t dev, int *part, void *data)
+ {
+ static DECLARE_MUTEX(disks_sem);
+- int unit = MINOR(dev);
++ int unit = *part;
+ mddev_t *mddev = mddev_find(unit);
+ struct gendisk *disk;
+
+@@ -1607,9 +1607,6 @@
+ mddev->pers = pers[pnum];
+ spin_unlock(&pers_lock);
+
+- blk_queue_make_request(mddev->queue, mddev->pers->make_request);
+- mddev->queue->queuedata = mddev;
+-
+ err = mddev->pers->run(mddev);
+ if (err) {
+ printk(KERN_ERR "md: pers->run() failed ...\n");
+@@ -1627,6 +1624,10 @@
+ set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+ md_wakeup_thread(mddev->thread);
+ set_capacity(disk, mddev->array_size<<1);
++
++ blk_queue_make_request(mddev->queue, mddev->pers->make_request);
++ mddev->queue->queuedata = mddev;
++
+ return 0;
+ }
+
+@@ -1698,12 +1699,8 @@
+ } else {
+ if (mddev->ro)
+ set_disk_ro(disk, 0);
+- if (mddev->pers->stop(mddev)) {
+- err = -EBUSY;
+- if (mddev->ro)
+- set_disk_ro(disk, 1);
+- goto out;
+- }
++ blk_queue_make_request(mddev->queue, md_fail_request);
++ mddev->pers->stop(mddev);
+ module_put(mddev->pers->owner);
+ mddev->pers = NULL;
+ if (mddev->ro)
+@@ -1877,16 +1874,15 @@
+ list_add(&start_rdev->same_set, &pending_raid_disks);
+
+ for (i = 0; i < MD_SB_DISKS; i++) {
+- mdp_disk_t *desc;
+- dev_t dev;
+-
+- desc = sb->disks + i;
+- dev = MKDEV(desc->major, desc->minor);
++ mdp_disk_t *desc = sb->disks + i;
++ dev_t dev = MKDEV(desc->major, desc->minor);
+
+ if (!dev)
+ continue;
+ if (dev == startdev)
+ continue;
++ if (MAJOR(dev) != desc->major || MINOR(dev) != desc->minor)
++ continue;
+ rdev = md_import_device(dev, 0, 0);
+ if (IS_ERR(rdev)) {
+ printk(KERN_WARNING "md: could not import %s,"
+@@ -2009,8 +2005,11 @@
+ {
+ char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE];
+ mdk_rdev_t *rdev;
+- dev_t dev;
+- dev = MKDEV(info->major,info->minor);
++ dev_t dev = MKDEV(info->major,info->minor);
++
++ if (info->major != MAJOR(dev) || info->minor != MINOR(dev))
++ return -EOVERFLOW;
++
+ if (!mddev->raid_disks) {
+ int err;
+ /* expecting a device which has a superblock */
+@@ -2136,7 +2135,7 @@
+
+ rdev = find_rdev(mddev, dev);
+ if (!rdev) {
+- MD_BUG();
++ /* MD_BUG(); */ /* like hell - it's not a driver bug */
+ return -ENXIO;
+ }
+
+@@ -2409,7 +2408,7 @@
+ /* START_ARRAY doesn't need to lock the array as autostart_array
+ * does the locking, and it could even be a different array
+ */
+- err = autostart_array(arg);
++ err = autostart_array(new_decode_dev(arg));
+ if (err) {
+ printk(KERN_WARNING "md: autostart %s failed!\n",
+ __bdevname(arg, b));
+@@ -2546,18 +2545,18 @@
+ goto done_unlock;
+ }
+ case HOT_GENERATE_ERROR:
+- err = hot_generate_error(mddev, arg);
++ err = hot_generate_error(mddev, new_decode_dev(arg));
+ goto done_unlock;
+ case HOT_REMOVE_DISK:
+- err = hot_remove_disk(mddev, arg);
++ err = hot_remove_disk(mddev, new_decode_dev(arg));
+ goto done_unlock;
+
+ case HOT_ADD_DISK:
+- err = hot_add_disk(mddev, arg);
++ err = hot_add_disk(mddev, new_decode_dev(arg));
+ goto done_unlock;
+
+ case SET_DISK_FAULTY:
+- err = set_disk_faulty(mddev, arg);
++ err = set_disk_faulty(mddev, new_decode_dev(arg));
+ goto done_unlock;
+
+ case RUN_ARRAY:
+Index: linux-2.6.0-test5/drivers/mtd/maps/sa1100-flash.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/mtd/maps/sa1100-flash.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/mtd/maps/sa1100-flash.c 2003-09-27 11:38:21.925195248 +0800
+@@ -654,28 +654,21 @@
+ }, {
+ .name = "SIMpad kernel",
+ .size = 0x00100000,
+- .offset = 0x00080000,
+- }, {
+-#ifdef CONFIG_JFFS2_FS
+- .name = "SIMpad root jffs2",
+- .size = MTDPART_SIZ_FULL,
+- .offset = 0x00180000,
+-#else
+- .name = "SIMpad initrd",
+- .size = 0x00300000,
+- .offset = 0x00180000,
++ .offset = MTDPART_OFS_APPEND,
+ }, {
++#ifdef CONFIG_ROOT_CRAMFS
+ .name = "SIMpad root cramfs",
+- .size = 0x00300000,
+- .offset = 0x00480000,
+- }, {
+- .name = "SIMpad usr cramfs",
+- .size = 0x005c0000,
+- .offset = 0x00780000,
++ .size =0x00D80000,
++ .offset = MTDPART_OFS_APPEND
++
+ }, {
+- .name = "SIMpad usr local",
++ .name = "SIMpad local jffs2",
++ .size = MTDPART_SIZ_FULL,
++ .offset = MTDPART_OFS_APPEND
++#else
++ .name = "SIMpad root jffs2",
+ .size = MTDPART_SIZ_FULL,
+- .offset = 0x00d40000,
++ .offset = MTDPART_OFS_APPEND
+ #endif
+ }
+ };
+@@ -1244,8 +1237,10 @@
+ }
+ if (machine_is_simpad()) {
+ info[0].base = SA1100_CS0_PHYS;
+- info[0].size = SZ_32M;
+- nr = 1;
++ info[0].size = SZ_16M;
++ info[1].base = SA1100_CS1_PHYS;
++ info[1].size = SZ_16M;
++ nr = 2;
+ }
+ if (machine_is_stork()) {
+ info[0].base = SA1100_CS0_PHYS;
+Index: linux-2.6.0-test5/drivers/mtd/mtd_blkdevs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/mtd/mtd_blkdevs.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/mtd/mtd_blkdevs.c 2003-09-27 11:38:21.929194640 +0800
+@@ -397,8 +397,7 @@
+
+ tr->blkcore_priv->rq->queuedata = tr;
+
+- ret = kernel_thread(mtd_blktrans_thread, tr,
+- CLONE_FS|CLONE_FILES|CLONE_SIGHAND);
++ ret = kernel_thread(mtd_blktrans_thread, tr, CLONE_KERNEL);
+ if (ret < 0) {
+ blk_cleanup_queue(tr->blkcore_priv->rq);
+ unregister_blkdev(tr->major, tr->name);
+Index: linux-2.6.0-test5/drivers/net/3c501.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/3c501.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/3c501.c 2003-09-27 11:38:21.936193576 +0800
+@@ -123,6 +123,7 @@
+ #include <linux/config.h> /* for CONFIG_IP_MULTICAST */
+ #include <linux/spinlock.h>
+ #include <linux/ethtool.h>
++#include <linux/delay.h>
+
+ #include <asm/uaccess.h>
+ #include <asm/bitops.h>
+@@ -241,7 +242,7 @@
+
+ if (dev->irq < 2)
+ {
+- unsigned long irq_mask, delay;
++ unsigned long irq_mask;
+
+ irq_mask = probe_irq_on();
+ inb(RX_STATUS); /* Clear pending interrupts. */
+@@ -250,8 +251,7 @@
+
+ outb(0x00, AX_CMD);
+
+- delay = jiffies + HZ/50;
+- while (time_before(jiffies, delay)) ;
++ mdelay(20);
+ autoirq = probe_irq_off(irq_mask);
+
+ if (autoirq == 0)
+Index: linux-2.6.0-test5/drivers/net/3c505.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/3c505.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/3c505.c 2003-09-27 11:38:21.950191448 +0800
+@@ -298,17 +298,13 @@
+ set_hsf(dev, HSF_PCB_NAK);
+ }
+ outb_control(adapter->hcr_val | ATTN | DIR, dev);
+- timeout = jiffies + 1*HZ/100;
+- while (time_before_eq(jiffies, timeout));
++ mdelay(10);
+ outb_control(adapter->hcr_val & ~ATTN, dev);
+- timeout = jiffies + 1*HZ/100;
+- while (time_before_eq(jiffies, timeout));
++ mdelay(10);
+ outb_control(adapter->hcr_val | FLSH, dev);
+- timeout = jiffies + 1*HZ/100;
+- while (time_before_eq(jiffies, timeout));
++ mdelay(10);
+ outb_control(adapter->hcr_val & ~FLSH, dev);
+- timeout = jiffies + 1*HZ/100;
+- while (time_before_eq(jiffies, timeout));
++ mdelay(10);
+
+ outb_control(orig_hcr, dev);
+ if (!start_receive(dev, &adapter->tx_pcb))
+Index: linux-2.6.0-test5/drivers/net/3c515.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/3c515.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/3c515.c 2003-09-27 11:38:21.970188408 +0800
+@@ -59,7 +59,6 @@
+
+ #include <linux/config.h>
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/isapnp.h>
+ #include <linux/kernel.h>
+ #include <linux/netdevice.h>
+Index: linux-2.6.0-test5/drivers/net/3c59x.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/3c59x.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/3c59x.c 2003-09-27 11:38:23.696925904 +0800
+@@ -1063,6 +1063,22 @@
+ return rc;
+ }
+
++#ifdef CONFIG_NET_POLL_CONTROLLER
++static void vortex_rx_poll(struct net_device *dev)
++{
++ disable_irq(dev->irq);
++ vortex_interrupt(dev->irq, (void *)dev, 0);
++ enable_irq(dev->irq);
++}
++
++static void boomerang_rx_poll(struct net_device *dev)
++{
++ disable_irq(dev->irq);
++ boomerang_interrupt(dev->irq, (void *)dev, 0);
++ enable_irq(dev->irq);
++}
++#endif
++
+ /*
+ * Start up the PCI/EISA device which is described by *gendev.
+ * Return 0 on success.
+@@ -1450,6 +1466,13 @@
+ dev->set_multicast_list = set_rx_mode;
+ dev->tx_timeout = vortex_tx_timeout;
+ dev->watchdog_timeo = (watchdog * HZ) / 1000;
++#ifdef CONFIG_NET_POLL_CONTROLLER
++ if (vp->full_bus_master_tx)
++ dev->poll_controller = boomerang_rx_poll;
++ else
++ dev->poll_controller = vortex_rx_poll;
++#endif
++
+ if (pdev) {
+ vp->pm_state_valid = 1;
+ pci_save_state(VORTEX_PCI(vp), vp->power_state);
+Index: linux-2.6.0-test5/drivers/net/ac3200.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/ac3200.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/ac3200.c 2003-09-27 11:38:23.896895504 +0800
+@@ -25,6 +25,7 @@
+ "ac3200.c:v1.01 7/1/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
+
+ #include <linux/module.h>
++#include <linux/eisa.h>
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+ #include <linux/string.h>
+Index: linux-2.6.0-test5/drivers/net/acenic.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/acenic.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/acenic.c 2003-09-27 11:38:24.038873920 +0800
+@@ -1757,7 +1757,8 @@
+ * Wait for the firmware to spin up - max 3 seconds.
+ */
+ myjif = jiffies + 3 * HZ;
+- while (time_before(jiffies, myjif) && !ap->fw_running);
++ while (time_before(jiffies, myjif) && !ap->fw_running)
++ cpu_relax();
+
+ if (!ap->fw_running) {
+ printk(KERN_ERR "%s: Firmware NOT running!\n", dev->name);
+Index: linux-2.6.0-test5/drivers/net/arm/ether00.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/arm/ether00.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/arm/ether00.c 2003-09-27 11:38:24.188851120 +0800
+@@ -19,7 +19,7 @@
+ */
+
+ /* includes */
+-
++#include <linux/config.h>
+ #include <linux/pci.h>
+ #include <linux/netdevice.h>
+ #include <linux/sched.h>
+Index: linux-2.6.0-test5/drivers/net/bonding/bond_3ad.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/bonding/bond_3ad.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/bonding/bond_3ad.c 2003-09-27 11:38:24.267839112 +0800
+@@ -37,6 +37,16 @@
+ * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
+ * - Renamed bond_3ad_link_status_changed() to
+ * bond_3ad_handle_link_change() for compatibility with TLB.
++ *
++ * 2003/05/20 - Amir Noam <amir.noam at intel dot com>
++ * - Fix long fail over time when releasing last slave of an active
++ * aggregator - send LACPDU on unbind of slave to tell partner this
++ * port is no longer aggregatable.
++ *
++ * 2003/06/25 - Tsippy Mendelson <tsippy.mendelson at intel dot com>
++ * - Send LACPDU as highest priority packet to further fix the above
++ * problem on very high Tx traffic load where packets may get dropped
++ * by the slave.
+ */
+
+ #include <linux/skbuff.h>
+@@ -45,6 +55,7 @@
+ #include <linux/spinlock.h>
+ #include <linux/ethtool.h>
+ #include <linux/if_bonding.h>
++#include <linux/pkt_sched.h>
+ #include "bonding.h"
+ #include "bond_3ad.h"
+
+@@ -905,6 +916,7 @@
+ skb->mac.raw = skb->data;
+ skb->nh.raw = skb->data + ETH_HLEN;
+ skb->protocol = PKT_TYPE_LACPDU;
++ skb->priority = TC_PRIO_CONTROL;
+
+ lacpdu_header = (struct lacpdu_header *)skb_put(skb, length);
+
+Index: linux-2.6.0-test5/drivers/net/bonding/bond_3ad.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/bonding/bond_3ad.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/bonding/bond_3ad.h 2003-09-27 11:38:24.334828928 +0800
+@@ -165,7 +165,7 @@
+ // = 0x02 (marker response information)
+ u8 marker_length; // = 0x16
+ u16 requester_port; // The number assigned to the port by the requester
+- struct mac_addr requester_system; // The requester\92s system id
++ struct mac_addr requester_system; // The requester's system id
+ u32 requester_transaction_id; // The transaction id allocated by the requester,
+ u16 pad; // = 0
+ u8 tlv_type_terminator; // = 0x00
+Index: linux-2.6.0-test5/drivers/net/bonding/bond_alb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/bonding/bond_alb.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/bonding/bond_alb.c 2003-09-27 11:38:24.397819352 +0800
+@@ -17,10 +17,22 @@
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
++ *
++ *
++ * Changes:
++ *
++ * 2003/06/25 - Shmulik Hen <shmulik.hen at intel dot com>
++ * - Fixed signed/unsigned calculation errors that caused load sharing
++ * to collapse to one slave under very heavy UDP Tx stress.
++ *
++ * 2003/08/06 - Amir Noam <amir.noam at intel dot com>
++ * - Add support for setting bond's MAC address with special
++ * handling required for ALB/TLB.
+ */
+
+ #include <linux/skbuff.h>
+ #include <linux/netdevice.h>
++#include <linux/etherdevice.h>
+ #include <linux/pkt_sched.h>
+ #include <linux/spinlock.h>
+ #include <linux/slab.h>
+@@ -246,7 +258,7 @@
+ {
+ struct slave *slave;
+ struct slave *least_loaded;
+- u32 curr_gap, max_gap;
++ s64 curr_gap, max_gap;
+
+ /* Find the first enabled slave */
+ slave = bond_get_first_slave(bond);
+@@ -262,15 +274,15 @@
+ }
+
+ least_loaded = slave;
+- max_gap = (slave->speed * 1000000) -
+- (SLAVE_TLB_INFO(slave).load * 8);
++ max_gap = (s64)(slave->speed * 1000000) -
++ (s64)(SLAVE_TLB_INFO(slave).load * 8);
+
+ /* Find the slave with the largest gap */
+ slave = bond_get_next_slave(bond, slave);
+ while (slave) {
+ if (SLAVE_IS_OK(slave)) {
+- curr_gap = (slave->speed * 1000000) -
+- (SLAVE_TLB_INFO(slave).load * 8);
++ curr_gap = (s64)(slave->speed * 1000000) -
++ (s64)(SLAVE_TLB_INFO(slave).load * 8);
+ if (max_gap < curr_gap) {
+ least_loaded = slave;
+ max_gap = curr_gap;
+@@ -936,10 +948,11 @@
+ }
+
+ /* hw is a boolean parameter that determines whether we should try and
+- * set the hw address of the hw as well as the hw address of the net_device
++ * set the hw address of the device as well as the hw address of the
++ * net_device
+ */
+ static int
+-alb_set_mac_addr(struct slave *slave, u8 addr[], int hw)
++alb_set_slave_mac_addr(struct slave *slave, u8 addr[], int hw)
+ {
+ struct net_device *dev = NULL;
+ struct sockaddr s_addr;
+@@ -947,16 +960,16 @@
+ dev = slave->dev;
+
+ if (!hw) {
+- memcpy(dev->dev_addr, addr, ETH_ALEN);
++ memcpy(dev->dev_addr, addr, dev->addr_len);
+ return 0;
+ }
+
+ /* for rlb each slave must have a unique hw mac addresses so that */
+ /* each slave will receive packets destined to a different mac */
+- memcpy(s_addr.sa_data, addr, ETH_ALEN);
++ memcpy(s_addr.sa_data, addr, dev->addr_len);
+ s_addr.sa_family = dev->type;
+ if (dev->set_mac_address(dev, &s_addr)) {
+- printk(KERN_DEBUG "bonding: Error: alb_set_mac_addr:"
++ printk(KERN_DEBUG "bonding: Error: alb_set_slave_mac_addr:"
+ " dev->set_mac_address of dev %s failed!"
+ " ALB mode requires that the base driver"
+ " support setting the hw address also when"
+@@ -980,8 +993,8 @@
+ slaves_state_differ = (SLAVE_IS_OK(slave1) != SLAVE_IS_OK(slave2));
+
+ memcpy(tmp_mac_addr, slave1->dev->dev_addr, ETH_ALEN);
+- alb_set_mac_addr(slave1, slave2->dev->dev_addr, bond->alb_info.rlb_enabled);
+- alb_set_mac_addr(slave2, tmp_mac_addr, bond->alb_info.rlb_enabled);
++ alb_set_slave_mac_addr(slave1, slave2->dev->dev_addr, bond->alb_info.rlb_enabled);
++ alb_set_slave_mac_addr(slave2, tmp_mac_addr, bond->alb_info.rlb_enabled);
+
+ /* fasten the change in the switch */
+ if (SLAVE_IS_OK(slave1)) {
+@@ -1146,8 +1159,8 @@
+ }
+
+ if (tmp_slave1) {
+- alb_set_mac_addr(slave, tmp_slave1->perm_hwaddr,
+- bond->alb_info.rlb_enabled);
++ alb_set_slave_mac_addr(slave, tmp_slave1->perm_hwaddr,
++ bond->alb_info.rlb_enabled);
+
+ printk(KERN_WARNING "bonding: Warning: the hw address "
+ "of slave %s is in use by the bond; "
+@@ -1165,6 +1178,67 @@
+ return 0;
+ }
+
++/**
++ * alb_set_mac_address
++ * @bond:
++ * @addr:
++ *
++ * In TLB mode all slaves are configured to the bond's hw address, but set
++ * their dev_addr field to different addresses (based on their permanent hw
++ * addresses).
++ *
++ * For each slave, this function sets the interface to the new address and then
++ * changes its dev_addr field to its previous value.
++ *
++ * Unwinding assumes bond's mac address has not yet changed.
++ */
++static inline int
++alb_set_mac_address(struct bonding *bond, void *addr)
++{
++ struct sockaddr sa;
++ struct slave *slave;
++ char tmp_addr[ETH_ALEN];
++ int error;
++
++ if (bond->alb_info.rlb_enabled) {
++ return 0;
++ }
++
++ slave = bond_get_first_slave(bond);
++ for (; slave; slave = bond_get_next_slave(bond, slave)) {
++ if (slave->dev->set_mac_address == NULL) {
++ error = -EOPNOTSUPP;
++ goto unwind;
++ }
++
++ /* save net_device's current hw address */
++ memcpy(tmp_addr, slave->dev->dev_addr, ETH_ALEN);
++
++ error = slave->dev->set_mac_address(slave->dev, addr);
++
++ /* restore net_device's hw address */
++ memcpy(slave->dev->dev_addr, tmp_addr, ETH_ALEN);
++
++ if (error) {
++ goto unwind;
++ }
++ }
++
++ return 0;
++
++unwind:
++ memcpy(sa.sa_data, bond->device->dev_addr, bond->device->addr_len);
++ sa.sa_family = bond->device->type;
++ slave = bond_get_first_slave(bond);
++ for (; slave; slave = bond_get_next_slave(bond, slave)) {
++ memcpy(tmp_addr, slave->dev->dev_addr, ETH_ALEN);
++ slave->dev->set_mac_address(slave->dev, &sa);
++ memcpy(slave->dev->dev_addr, tmp_addr, ETH_ALEN);
++ }
++
++ return error;
++}
++
+ /************************ exported alb funcions ************************/
+
+ int
+@@ -1255,16 +1329,15 @@
+ hash_size = 16;
+ break;
+
+-#ifdef FIXME
+ case ETH_P_IPX:
+- if (skb->nh.ipxh->ipx_checksum !=
++ if (ipx_hdr(skb)->ipx_checksum !=
+ __constant_htons(IPX_NO_CHECKSUM)) {
+ /* something is wrong with this packet */
+ do_tx_balance = 0;
+ break;
+ }
+
+- if (skb->nh.ipxh->ipx_type !=
++ if (ipx_hdr(skb)->ipx_type !=
+ __constant_htons(IPX_TYPE_NCP)) {
+ /* The only protocol worth balancing in
+ * this family since it has an "ARP" like
+@@ -1277,7 +1350,6 @@
+ hash_start = (char*)eth_data->h_dest;
+ hash_size = ETH_ALEN;
+ break;
+-#endif
+
+ case ETH_P_ARP:
+ do_tx_balance = 0;
+@@ -1437,8 +1509,8 @@
+ {
+ int err = 0;
+
+- err = alb_set_mac_addr(slave, slave->perm_hwaddr,
+- bond->alb_info.rlb_enabled);
++ err = alb_set_slave_mac_addr(slave, slave->perm_hwaddr,
++ bond->alb_info.rlb_enabled);
+ if (err) {
+ return err;
+ }
+@@ -1562,10 +1634,61 @@
+ alb_swap_mac_addr(bond, swap_slave, new_slave);
+ } else {
+ /* set the new_slave to the bond mac address */
+- alb_set_mac_addr(new_slave, bond->device->dev_addr,
+- bond->alb_info.rlb_enabled);
++ alb_set_slave_mac_addr(new_slave, bond->device->dev_addr,
++ bond->alb_info.rlb_enabled);
+ /* fasten bond mac on new current slave */
+ alb_send_learning_packets(new_slave, bond->device->dev_addr);
+ }
+ }
+
++int
++bond_alb_set_mac_address(struct net_device *dev, void *addr)
++{
++ struct bonding *bond = dev->priv;
++ struct sockaddr *sa = addr;
++ struct slave *swap_slave = NULL;
++ int error = 0;
++
++ if (!is_valid_ether_addr(sa->sa_data)) {
++ return -EADDRNOTAVAIL;
++ }
++
++ error = alb_set_mac_address(bond, addr);
++ if (error) {
++ return error;
++ }
++
++ memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
++
++ /* If there is no current_slave there is nothing else to do.
++ * Otherwise we'll need to pass the new address to it and handle
++ * duplications.
++ */
++ if (bond->current_slave == NULL) {
++ return 0;
++ }
++
++ swap_slave = bond_get_first_slave(bond);
++ while (swap_slave) {
++ if (!memcmp(swap_slave->dev->dev_addr, dev->dev_addr, ETH_ALEN)) {
++ break;
++ }
++ swap_slave = bond_get_next_slave(bond, swap_slave);
++ }
++
++ if (swap_slave) {
++ alb_swap_mac_addr(bond, swap_slave, bond->current_slave);
++ } else {
++ alb_set_slave_mac_addr(bond->current_slave, dev->dev_addr,
++ bond->alb_info.rlb_enabled);
++
++ alb_send_learning_packets(bond->current_slave, dev->dev_addr);
++ if (bond->alb_info.rlb_enabled) {
++ /* inform clients mac address has changed */
++ rlb_req_update_slave_clients(bond, bond->current_slave);
++ }
++ }
++
++ return 0;
++}
++
+Index: linux-2.6.0-test5/drivers/net/bonding/bond_alb.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/bonding/bond_alb.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/bonding/bond_alb.h 2003-09-27 11:38:24.460809776 +0800
+@@ -17,6 +17,13 @@
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
++ *
++ *
++ * Changes:
++ *
++ * 2003/08/06 - Amir Noam <amir.noam at intel dot com>
++ * - Add support for setting bond's MAC address with special
++ * handling required for ALB/TLB.
+ */
+
+ #ifndef __BOND_ALB_H__
+@@ -122,6 +129,7 @@
+ void bond_alb_assign_current_slave(struct bonding *bond, struct slave *new_slave);
+ int bond_alb_xmit(struct sk_buff *skb, struct net_device *dev);
+ void bond_alb_monitor(struct bonding *bond);
++int bond_alb_set_mac_address(struct net_device *dev, void *addr);
+
+ #endif /* __BOND_ALB_H__ */
+
+Index: linux-2.6.0-test5/drivers/net/bonding/bonding.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/bonding/bonding.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/bonding/bonding.h 2003-09-27 11:38:24.500803696 +0800
+@@ -99,10 +99,10 @@
+ rwlock_t ptrlock;
+ struct timer_list mii_timer;
+ struct timer_list arp_timer;
+- struct net_device_stats *stats;
++ struct net_device_stats stats;
+ #ifdef CONFIG_PROC_FS
+- struct proc_dir_entry *bond_proc_dir;
+- struct proc_dir_entry *bond_proc_info_file;
++ struct proc_dir_entry *bond_proc_file;
++ char procdir_name[IFNAMSIZ];
+ #endif /* CONFIG_PROC_FS */
+ struct list_head bond_list;
+ struct net_device *device;
+Index: linux-2.6.0-test5/drivers/net/bonding/bond_main.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/bonding/bond_main.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/bonding/bond_main.c 2003-09-27 11:38:24.626784544 +0800
+@@ -278,7 +278,7 @@
+ * bonding round-robin mode ignoring links after failover/recovery
+ *
+ * 2003/03/17 - Jay Vosburgh <fubar at us dot ibm dot com>
+- * - kmalloc fix (GPF_KERNEL to GPF_ATOMIC) reported by
++ * - kmalloc fix (GFP_KERNEL to GFP_ATOMIC) reported by
+ * Shmulik dot Hen at intel.com.
+ * - Based on discussion on mailing list, changed use of
+ * update_slave_cnt(), created wrapper functions for adding/removing
+@@ -323,22 +323,22 @@
+ * 2003/03/18 - Amir Noam <amir.noam at intel dot com>,
+ * Tsippy Mendelson <tsippy.mendelson at intel dot com> and
+ * Shmulik Hen <shmulik.hen at intel dot com>
+- * - Added support for IEEE 802.3ad Dynamic link aggregation mode.
++ * - Added support for IEEE 802.3ad Dynamic link aggregation mode.
+ *
+ * 2003/05/01 - Amir Noam <amir.noam at intel dot com>
+- * - Added ABI version control to restore compatibility between
+- * new/old ifenslave and new/old bonding.
++ * - Added ABI version control to restore compatibility between
++ * new/old ifenslave and new/old bonding.
+ *
+ * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
+- * - Fixed bug in bond_release_all(): save old value of current_slave
+- * before setting it to NULL.
+- * - Changed driver versioning scheme to include version number instead
+- * of release date (that is already in another field). There are 3
+- * fields X.Y.Z where:
+- * X - Major version - big behavior changes
+- * Y - Minor version - addition of features
+- * Z - Extra version - minor changes and bug fixes
+- * The current version is 1.0.0 as a base line.
++ * - Fixed bug in bond_release_all(): save old value of current_slave
++ * before setting it to NULL.
++ * - Changed driver versioning scheme to include version number instead
++ * of release date (that is already in another field). There are 3
++ * fields X.Y.Z where:
++ * X - Major version - big behavior changes
++ * Y - Minor version - addition of features
++ * Z - Extra version - minor changes and bug fixes
++ * The current version is 1.0.0 as a base line.
+ *
+ * 2003/05/01 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
+ * Amir Noam <amir.noam at intel dot com>
+@@ -371,6 +371,61 @@
+ * - Added support for Adaptive load balancing mode which is
+ * equivalent to Transmit load balancing + Receive load balancing.
+ * new version - 2.2.0
++ *
++ * 2003/05/15 - Jay Vosburgh <fubar at us dot ibm dot com>
++ * - Applied fix to activebackup_arp_monitor posted to bonding-devel
++ * by Tony Cureington <tony.cureington * hp_com>. Fixes ARP
++ * monitor endless failover bug. Version to 2.2.10
++ *
++ * 2003/05/20 - Amir Noam <amir.noam at intel dot com>
++ * - Fixed bug in ABI version control - Don't commit to a specific
++ * ABI version if receiving unsupported ioctl commands.
++ *
++ * 2003/05/22 - Jay Vosburgh <fubar at us dot ibm dot com>
++ * - Fix ifenslave -c causing bond to loose existing routes;
++ * added bond_set_mac_address() that doesn't require the
++ * bond to be down.
++ * - In conjunction with fix for ifenslave -c, in
++ * bond_change_active(), changing to the already active slave
++ * is no longer an error (it successfully does nothing).
++ *
++ * 2003/06/30 - Amir Noam <amir.noam at intel dot com>
++ * - Fixed bond_change_active() for ALB/TLB modes.
++ * Version to 2.2.14.
++ *
++ * 2003/07/29 - Amir Noam <amir.noam at intel dot com>
++ * - Fixed ARP monitoring bug.
++ * Version to 2.2.15.
++ *
++ * 2003/07/31 - Willy Tarreau <willy at ods dot org>
++ * - Fixed kernel panic when using ARP monitoring without
++ * setting bond's IP address.
++ * Version to 2.2.16.
++ *
++ * 2003/08/06 - Amir Noam <amir.noam at intel dot com>
++ * - Back port from 2.6: use alloc_netdev(); fix /proc handling;
++ * made stats a part of bond struct so no need to allocate
++ * and free it separately; use standard list operations instead
++ * of pre-allocated array of bonds.
++ * Version to 2.3.0.
++ *
++ * 2003/08/07 - Jay Vosburgh <fubar at us dot ibm dot com>,
++ * Amir Noam <amir.noam at intel dot com> and
++ * Shmulik Hen <shmulik.hen at intel dot com>
++ * - Propagating master's settings: Distinguish between modes that
++ * use a primary slave from those that don't, and propagate settings
++ * accordingly; Consolidate change_active opeartions and add
++ * reselect_active and find_best opeartions; Decouple promiscuous
++ * handling from the multicast mode setting; Add support for changing
++ * HW address and MTU with proper unwind; Consolidate procfs code,
++ * add CHANGENAME handler; Enhance netdev notification handling.
++ * Version to 2.4.0.
++ *
++ * 2003/09/15 - Stephen Hemminger <shemminger at osdl dot org>,
++ * Amir Noam <amir.noam at intel dot com>
++ * - Convert /proc to seq_file interface.
++ * Change /proc/net/bondX/info to /proc/net/bonding/bondX.
++ * Set version to 2.4.1.
+ */
+
+ #include <linux/config.h>
+@@ -404,6 +459,8 @@
+ #include <linux/skbuff.h>
+ #include <net/sock.h>
+ #include <linux/rtnetlink.h>
++#include <linux/proc_fs.h>
++#include <linux/seq_file.h>
+
+ #include <linux/if_bonding.h>
+ #include <linux/smp.h>
+@@ -415,10 +472,10 @@
+ #include "bond_3ad.h"
+ #include "bond_alb.h"
+
+-#define DRV_VERSION "2.2.0"
+-#define DRV_RELDATE "April 15, 2003"
+-#define DRV_NAME "bonding"
+-#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
++#define DRV_VERSION "2.4.1"
++#define DRV_RELDATE "September 15, 2003"
++#define DRV_NAME "bonding"
++#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
+
+ static const char *version =
+ DRV_NAME ".c:v" DRV_VERSION " (" DRV_RELDATE ")\n";
+@@ -436,6 +493,11 @@
+ #define MAX_ARP_IP_TARGETS 16
+ #endif
+
++#define USES_PRIMARY(mode) \
++ (((mode) == BOND_MODE_ACTIVEBACKUP) || \
++ ((mode) == BOND_MODE_TLB) || \
++ ((mode) == BOND_MODE_ALB))
++
+ struct bond_parm_tbl {
+ char *modename;
+ int mode;
+@@ -443,7 +505,7 @@
+
+ static int arp_interval = BOND_LINK_ARP_INTERV;
+ static char *arp_ip_target[MAX_ARP_IP_TARGETS] = { NULL, };
+-static unsigned long arp_target[MAX_ARP_IP_TARGETS] = { 0, } ;
++static u32 arp_target[MAX_ARP_IP_TARGETS] = { 0, } ;
+ static int arp_ip_count = 0;
+ static u32 my_ip = 0;
+ char *arp_target_hw_addr = NULL;
+@@ -474,8 +536,8 @@
+ { "balance-xor", BOND_MODE_XOR},
+ { "broadcast", BOND_MODE_BROADCAST},
+ { "802.3ad", BOND_MODE_8023AD},
+-{ "tlb", BOND_MODE_TLB},
+-{ "alb", BOND_MODE_ALB},
++{ "balance-tlb", BOND_MODE_TLB},
++{ "balance-alb", BOND_MODE_ALB},
+ { NULL, -1},
+ };
+
+@@ -499,13 +561,16 @@
+ };
+
+ static LIST_HEAD(bond_dev_list);
++#ifdef CONFIG_PROC_FS
++static struct proc_dir_entry *bond_proc_dir = NULL;
++#endif
+
+ MODULE_PARM(max_bonds, "i");
+ MODULE_PARM_DESC(max_bonds, "Max number of bonded devices");
+ MODULE_PARM(miimon, "i");
+ MODULE_PARM_DESC(miimon, "Link check interval in milliseconds");
+ MODULE_PARM(use_carrier, "i");
+-MODULE_PARM_DESC(use_carrier, "Use netif_carrier_ok (vs MII ioctls) in miimon; 09 for off, 1 for on (default)");
++MODULE_PARM_DESC(use_carrier, "Use netif_carrier_ok (vs MII ioctls) in miimon; 0 for off, 1 for on (default)");
+ MODULE_PARM(mode, "s");
+ MODULE_PARM_DESC(mode, "Mode of operation : 0 for round robin, 1 for active-backup, 2 for xor");
+ MODULE_PARM(arp_interval, "i");
+@@ -530,7 +595,6 @@
+ static void bond_mii_monitor(struct net_device *dev);
+ static void loadbalance_arp_monitor(struct net_device *dev);
+ static void activebackup_arp_monitor(struct net_device *dev);
+-static int bond_event(struct notifier_block *this, unsigned long event, void *ptr);
+ static void bond_mc_list_destroy(struct bonding *bond);
+ static void bond_mc_add(bonding_t *bond, void *addr, int alen);
+ static void bond_mc_delete(bonding_t *bond, void *addr, int alen);
+@@ -544,30 +608,17 @@
+ static int bond_release(struct net_device *master, struct net_device *slave);
+ static int bond_release_all(struct net_device *master);
+ static int bond_sethwaddr(struct net_device *master, struct net_device *slave);
++static void change_active_interface(struct bonding *bond, struct slave *new);
++static void reselect_active_interface(struct bonding *bond);
++static struct slave *find_best_interface(struct bonding *bond);
+
+-/*
+- * bond_get_info is the interface into the /proc filesystem. This is
+- * a different interface than the BOND_INFO_QUERY ioctl. That is done
+- * through the generic networking ioctl interface, and bond_info_query
+- * is the internal function which provides that information.
+- */
+-static int bond_get_info(char *buf, char **start, off_t offset, int length);
+-
+-/* Caller must hold bond->ptrlock for write */
+-static inline struct slave*
+-bond_assign_current_slave(struct bonding *bond,struct slave *newslave)
+-{
+- if ((bond_mode == BOND_MODE_TLB) ||
+- (bond_mode == BOND_MODE_ALB)) {
+- bond_alb_assign_current_slave(bond, newslave);
+- } else {
+- bond->current_slave = newslave;
+- }
+-
+- return bond->current_slave;
+-}
+
+ /* #define BONDING_DEBUG 1 */
++#ifdef BONDING_DEBUG
++#define dprintk(x...) printk(x...)
++#else /* BONDING_DEBUG */
++#define dprintk(x...) do {} while (0)
++#endif /* BONDING_DEBUG */
+
+ /* several macros */
+
+@@ -662,7 +713,7 @@
+ * belongs to <bond>. It returns <slave> in case it's needed.
+ * Nothing is freed on return, structures are just unchained.
+ * If the bond->current_slave pointer was pointing to <slave>,
+- * it's replaced with bond->next, or NULL if not applicable.
++ * it should be changed by the calling function.
+ *
+ * bond->lock held for writing by caller.
+ */
+@@ -696,17 +747,6 @@
+
+ update_slave_cnt(bond, -1);
+
+- /* no need to hold ptrlock since bond lock is
+- * already held for writing
+- */
+- if (slave == bond->current_slave) {
+- if ( bond->next != (slave_t *)bond) { /* found one slave */
+- bond_assign_current_slave(bond, bond->next);
+- } else {
+- bond_assign_current_slave(bond, NULL);
+- }
+- }
+-
+ return slave;
+ }
+
+@@ -1138,23 +1178,22 @@
+ }
+
+ /*
+- * Push the promiscuity flag down to all slaves
++ * Push the promiscuity flag down to appropriate slaves
+ */
+ static void bond_set_promiscuity(bonding_t *bond, int inc)
+ {
+ slave_t *slave;
+- switch (multicast_mode) {
+- case BOND_MULTICAST_ACTIVE :
+- /* write lock already acquired */
+- if (bond->current_slave != NULL)
++
++ if (USES_PRIMARY(bond_mode)) {
++ if (bond->current_slave) {
+ dev_set_promiscuity(bond->current_slave->dev, inc);
+- break;
+- case BOND_MULTICAST_ALL :
+- for (slave = bond->prev; slave != (slave_t*)bond; slave = slave->prev)
++ }
++
++ } else {
++ for (slave = bond->prev; slave != (slave_t*)bond;
++ slave = slave->prev) {
+ dev_set_promiscuity(slave->dev, inc);
+- break;
+- case BOND_MULTICAST_DISABLED :
+- break;
++ }
+ }
+ }
+
+@@ -1200,20 +1239,23 @@
+ bonding_t *bond = master->priv;
+ struct dev_mc_list *dmi;
+
+- if (multicast_mode == BOND_MULTICAST_DISABLED)
+- return;
+- /*
+- * Lock the private data for the master
+- */
+ write_lock_bh(&bond->lock);
+
+- /* set promiscuity flag to slaves */
++ /*
++ * Do promisc before checking multicast_mode
++ */
+ if ( (master->flags & IFF_PROMISC) && !(bond->flags & IFF_PROMISC) )
+ bond_set_promiscuity(bond, 1);
+
+ if ( !(master->flags & IFF_PROMISC) && (bond->flags & IFF_PROMISC) )
+ bond_set_promiscuity(bond, -1);
+
++ if (multicast_mode == BOND_MULTICAST_DISABLED) {
++ bond->flags = master->flags;
++ write_unlock_bh(&bond->lock);
++ return;
++ }
++
+ /* set allmulti flag to slaves */
+ if ( (master->flags & IFF_ALLMULTI) && !(bond->flags & IFF_ALLMULTI) )
+ bond_set_allmulti(bond, 1);
+@@ -1245,32 +1287,40 @@
+
+ /*
+ * Update the mc list and multicast-related flags for the new and
+- * old active slaves (if any) according to the multicast mode
++ * old active slaves (if any) according to the multicast mode, and
++ * promiscuous flags unconditionally.
+ */
+ static void bond_mc_update(bonding_t *bond, slave_t *new, slave_t *old)
+ {
+ struct dev_mc_list *dmi;
+
+- switch(multicast_mode) {
+- case BOND_MULTICAST_ACTIVE :
++ if (USES_PRIMARY(bond_mode)) {
+ if (bond->device->flags & IFF_PROMISC) {
+- if (old != NULL && new != old)
++ if (old)
+ dev_set_promiscuity(old->dev, -1);
+- dev_set_promiscuity(new->dev, 1);
++ if (new)
++ dev_set_promiscuity(new->dev, 1);
+ }
++ }
++
++ switch(multicast_mode) {
++ case BOND_MULTICAST_ACTIVE :
+ if (bond->device->flags & IFF_ALLMULTI) {
+- if (old != NULL && new != old)
++ if (old)
+ dev_set_allmulti(old->dev, -1);
+- dev_set_allmulti(new->dev, 1);
++ if (new)
++ dev_set_allmulti(new->dev, 1);
+ }
+ /* first remove all mc addresses from old slave if any,
+ and _then_ add them to new active slave */
+- if (old != NULL && new != old) {
++ if (old) {
+ for (dmi = bond->device->mc_list; dmi != NULL; dmi = dmi->next)
+ dev_mc_delete(old->dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
+ }
+- for (dmi = bond->device->mc_list; dmi != NULL; dmi = dmi->next)
+- dev_mc_add(new->dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
++ if (new) {
++ for (dmi = bond->device->mc_list; dmi != NULL; dmi = dmi->next)
++ dev_mc_add(new->dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
++ }
+ break;
+ case BOND_MULTICAST_ALL :
+ /* nothing to do: mc list is already up-to-date on all slaves */
+@@ -1386,7 +1436,7 @@
+ * The application already set the master's
+ * mac address to that of the first slave
+ */
+- memcpy(addr.sa_data, master_dev->dev_addr, ETH_ALEN);
++ memcpy(addr.sa_data, master_dev->dev_addr, master_dev->addr_len);
+ addr.sa_family = slave_dev->type;
+ err = slave_dev->set_mac_address(slave_dev, &addr);
+ if (err) {
+@@ -1432,11 +1482,19 @@
+ }
+ }
+
+- if (multicast_mode == BOND_MULTICAST_ALL) {
+- /* set promiscuity level to new slave */
+- if (master_dev->flags & IFF_PROMISC)
++ /* set promiscuity level to new slave */
++ if (master_dev->flags & IFF_PROMISC) {
++ /* If the mode USES_PRIMARY, then the new slave gets the
++ * master's promisc (and mc) settings only if it becomes the
++ * current_slave, and that is taken care of later when calling
++ * bond_change_active()
++ */
++ if (!USES_PRIMARY(bond_mode)) {
+ dev_set_promiscuity(slave_dev, 1);
++ }
++ }
+
++ if (multicast_mode == BOND_MULTICAST_ALL) {
+ /* set allmulti level to new slave */
+ if (master_dev->flags & IFF_ALLMULTI)
+ dev_set_allmulti(slave_dev, 1);
+@@ -1549,9 +1607,7 @@
+ #endif
+ /* first slave or no active slave yet, and this link
+ is OK, so make this interface the active one */
+- bond_assign_current_slave(bond, new_slave);
+- bond_set_slave_active_flags(new_slave);
+- bond_mc_update(bond, new_slave, NULL);
++ change_active_interface(bond, new_slave);
+ }
+ else {
+ #ifdef BONDING_DEBUG
+@@ -1559,11 +1615,14 @@
+ #endif
+ bond_set_slave_inactive_flags(new_slave);
+ }
+- read_lock_irqsave(&(((struct in_device *)slave_dev->ip_ptr)->lock), rflags);
+- ifap= &(((struct in_device *)slave_dev->ip_ptr)->ifa_list);
+- ifa = *ifap;
+- my_ip = ifa->ifa_address;
+- read_unlock_irqrestore(&(((struct in_device *)slave_dev->ip_ptr)->lock), rflags);
++ if (((struct in_device *)slave_dev->ip_ptr) != NULL) {
++ read_lock_irqsave(&(((struct in_device *)slave_dev->ip_ptr)->lock), rflags);
++ ifap= &(((struct in_device *)slave_dev->ip_ptr)->ifa_list);
++ ifa = *ifap;
++ if (ifa != NULL)
++ my_ip = ifa->ifa_address;
++ read_unlock_irqrestore(&(((struct in_device *)slave_dev->ip_ptr)->lock), rflags);
++ }
+
+ /* if there is a primary slave, remember it */
+ if (primary != NULL) {
+@@ -1598,7 +1657,7 @@
+ /* first slave or no active slave yet, and this link
+ * is OK, so make this interface the active one
+ */
+- bond_assign_current_slave(bond, new_slave);
++ change_active_interface(bond, new_slave);
+ }
+
+ /* if there is a primary slave, remember it */
+@@ -1613,8 +1672,13 @@
+ #endif
+ /* always active in trunk mode */
+ new_slave->state = BOND_STATE_ACTIVE;
++
++ /* In trunking mode there is little meaning to current_slave
++ * anyway (it holds no special properties of the bond device),
++ * so we can change it without calling change_active_interface()
++ */
+ if (bond->current_slave == NULL)
+- bond_assign_current_slave(bond, new_slave);
++ bond->current_slave = new_slave;
+ }
+
+ write_unlock_bh(&bond->lock);
+@@ -1705,6 +1769,13 @@
+ return -ENODEV;
+ }
+
++ /* Verify that master_dev is indeed the master of slave_dev */
++ if (!(slave_dev->flags & IFF_SLAVE) ||
++ (slave_dev->master != master_dev)) {
++
++ return -EINVAL;
++ }
++
+ bond = (struct bonding *) master_dev->priv;
+ write_lock_bh(&bond->lock);
+ slave = (slave_t *)bond;
+@@ -1717,67 +1788,46 @@
+ }
+ }
+
++ /*
++ * Changing to the current active: do nothing; return success.
++ */
++ if (newactive && (newactive == oldactive)) {
++ write_unlock_bh(&bond->lock);
++ return 0;
++ }
++
+ if ((newactive != NULL)&&
+ (oldactive != NULL)&&
+- (newactive != oldactive)&&
+ (newactive->link == BOND_LINK_UP)&&
+ IS_UP(newactive->dev)) {
+- bond_set_slave_inactive_flags(oldactive);
+- bond_set_slave_active_flags(newactive);
+- bond_mc_update(bond, newactive, oldactive);
+- bond_assign_current_slave(bond, newactive);
+- printk("%s : activate %s(old : %s)\n",
+- master_dev->name, newactive->dev->name,
+- oldactive->dev->name);
+- }
+- else {
++ change_active_interface(bond, newactive);
++ } else {
+ ret = -EINVAL;
+ }
+ write_unlock_bh(&bond->lock);
+ return ret;
+ }
+
+-/* Choose a new valid interface from the pool, set it active
+- * and make it the current slave. If no valid interface is
+- * found, the oldest slave in BACK state is choosen and
+- * activated. If none is found, it's considered as no
+- * interfaces left so the current slave is set to NULL.
+- * The result is a pointer to the current slave.
+- *
+- * Since this function sends messages tails through printk, the caller
+- * must have started something like `printk(KERN_INFO "xxxx ");'.
++/**
++ * find_best_interface - select the best available slave to be the active one
++ * @bond: our bonding struct
+ *
+ * Warning: Caller must hold ptrlock for writing.
+ */
+-slave_t *change_active_interface(bonding_t *bond)
++static struct slave *find_best_interface(struct bonding *bond)
+ {
+- slave_t *newslave, *oldslave;
+- slave_t *bestslave = NULL;
++ struct slave *newslave, *oldslave;
++ struct slave *bestslave = NULL;
+ int mintime;
+
+ newslave = oldslave = bond->current_slave;
+
+ if (newslave == NULL) { /* there were no active slaves left */
+ if (bond->next != (slave_t *)bond) { /* found one slave */
+- newslave = bond_assign_current_slave(bond, bond->next);
++ newslave = bond->next;
+ } else {
+-
+- printk (" but could not find any %s interface.\n",
+- (bond_mode == BOND_MODE_ACTIVEBACKUP) ? "backup":"other");
+- bond_assign_current_slave(bond, NULL);
+ return NULL; /* still no slave, return NULL */
+ }
+- } else if (bond_mode == BOND_MODE_ACTIVEBACKUP) {
+- /* make sure oldslave doesn't send arps - this could
+- * cause a ping-pong effect between interfaces since they
+- * would be able to tx arps - in active backup only one
+- * slave should be able to tx arps, and that should be
+- * the current_slave; the only exception is when all
+- * slaves have gone down, then only one non-current slave can
+- * send arps at a time; clearing oldslaves' mc list is handled
+- * later in this function.
+- */
+- bond_set_slave_inactive_flags(oldslave);
+ }
+
+ mintime = updelay;
+@@ -1792,22 +1842,12 @@
+ newslave = bond->primary_slave;
+ }
+
++ /* remember where to stop iterating over the slaves */
++ oldslave = newslave;
++
+ do {
+ if (IS_UP(newslave->dev)) {
+ if (newslave->link == BOND_LINK_UP) {
+- /* this one is immediately usable */
+- if (bond_mode == BOND_MODE_ACTIVEBACKUP) {
+- bond_set_slave_active_flags(newslave);
+- bond_mc_update(bond, newslave, oldslave);
+- printk (" and making interface %s the active one.\n",
+- newslave->dev->name);
+- }
+- else {
+- printk (" and setting pointer to interface %s.\n",
+- newslave->dev->name);
+- }
+-
+- bond_assign_current_slave(bond, newslave);
+ return newslave;
+ }
+ else if (newslave->link == BOND_LINK_BACK) {
+@@ -1820,46 +1860,105 @@
+ }
+ } while ((newslave = newslave->next) != oldslave);
+
+- /* no usable backup found, we'll see if we at least got a link that was
+- coming back for a long time, and could possibly already be usable.
+- */
+-
+- if (bestslave != NULL) {
+- /* early take-over. */
+- printk (" and making interface %s the active one %d ms earlier.\n",
+- bestslave->dev->name,
+- (updelay - bestslave->delay)*miimon);
+-
+- bestslave->delay = 0;
+- bestslave->link = BOND_LINK_UP;
+- bestslave->jiffies = jiffies;
+- bond_set_slave_active_flags(bestslave);
+- bond_mc_update(bond, bestslave, oldslave);
+- bond_assign_current_slave(bond, bestslave);
+- return bestslave;
+- }
+-
+- if ((bond_mode == BOND_MODE_ACTIVEBACKUP) &&
+- (multicast_mode == BOND_MULTICAST_ACTIVE) &&
+- (oldslave != NULL)) {
+- /* flush bonds (master's) mc_list from oldslave since it wasn't
+- * updated (and deleted) above
+- */
+- bond_mc_list_flush(oldslave->dev, bond->device);
+- if (bond->device->flags & IFF_PROMISC) {
+- dev_set_promiscuity(oldslave->dev, -1);
++ return bestslave;
++}
++
++/**
++ * change_active_interface - change the active slave into the specified one
++ * @bond: our bonding struct
++ * @new: the new slave to make the active one
++ *
++ * Set the new slave to the bond's settings and unset them on the old
++ * current_slave.
++ * Setting include flags, mc-list, promiscuity, allmulti, etc.
++ *
++ * If @new's link state is %BOND_LINK_BACK we'll set it to %BOND_LINK_UP,
++ * because it is apparently the best available slave we have, even though its
++ * updelay hasn't timed out yet.
++ *
++ * Warning: Caller must hold ptrlock for writing.
++ */
++static void change_active_interface(struct bonding *bond, struct slave *new)
++{
++ struct slave *old = bond->current_slave;
++
++ if (old == new) {
++ return;
++ }
++
++ if (new) {
++ if (new->link == BOND_LINK_BACK) {
++ if (USES_PRIMARY(bond_mode)) {
++ printk (KERN_INFO
++ "%s: making interface %s the new "
++ "active one %d ms earlier.\n",
++ bond->device->name, new->dev->name,
++ (updelay - new->delay) * miimon);
++ }
++
++ new->delay = 0;
++ new->link = BOND_LINK_UP;
++ new->jiffies = jiffies;
++
++ if (bond_mode == BOND_MODE_8023AD) {
++ bond_3ad_handle_link_change(new, BOND_LINK_UP);
++ }
++
++ if ((bond_mode == BOND_MODE_TLB) ||
++ (bond_mode == BOND_MODE_ALB)) {
++ bond_alb_handle_link_change(bond, new, BOND_LINK_UP);
++ }
++ } else {
++ if (USES_PRIMARY(bond_mode)) {
++ printk (KERN_INFO
++ "%s: making interface %s the new active one.\n",
++ bond->device->name, new->dev->name);
++ }
+ }
+- if (bond->device->flags & IFF_ALLMULTI) {
+- dev_set_allmulti(oldslave->dev, -1);
++ }
++
++ if (bond_mode == BOND_MODE_ACTIVEBACKUP) {
++ if (old) {
++ bond_set_slave_inactive_flags(old);
++ }
++
++ if (new) {
++ bond_set_slave_active_flags(new);
+ }
+ }
+
+- printk (" but could not find any %s interface.\n",
+- (bond_mode == BOND_MODE_ACTIVEBACKUP) ? "backup":"other");
+-
+- /* absolutely nothing found. let's return NULL */
+- bond_assign_current_slave(bond, NULL);
+- return NULL;
++ if (USES_PRIMARY(bond_mode)) {
++ bond_mc_update(bond, new, old);
++ }
++
++ if ((bond_mode == BOND_MODE_TLB) ||
++ (bond_mode == BOND_MODE_ALB)) {
++ bond_alb_assign_current_slave(bond, new);
++ } else {
++ bond->current_slave = new;
++ }
++}
++
++/**
++ * reselect_active_interface - select a new active slave, if needed
++ * @bond: our bonding struct
++ *
++ * This functions shoud be called when one of the following occurs:
++ * - The old current_slave has been released or lost its link.
++ * - The primary_slave has got its link back.
++ * - A slave has got its link back and there's no old current_slave.
++ *
++ * Warning: Caller must hold ptrlock for writing.
++ */
++static void reselect_active_interface(struct bonding *bond)
++{
++ struct slave *best_slave;
++
++ best_slave = find_best_interface(bond);
++
++ if (best_slave != bond->current_slave) {
++ change_active_interface(bond, best_slave);
++ }
+ }
+
+ /*
+@@ -1908,12 +2007,12 @@
+ "of %s to a different address "
+ "to avoid conflicts.\n",
+ slave->name,
+- slave->dev_addr[0],
+- slave->dev_addr[1],
+- slave->dev_addr[2],
+- slave->dev_addr[3],
+- slave->dev_addr[4],
+- slave->dev_addr[5],
++ our_slave->perm_hwaddr[0],
++ our_slave->perm_hwaddr[1],
++ our_slave->perm_hwaddr[2],
++ our_slave->perm_hwaddr[3],
++ our_slave->perm_hwaddr[4],
++ our_slave->perm_hwaddr[5],
+ bond->device->name,
+ slave->name);
+ }
+@@ -1926,31 +2025,29 @@
+ bond_3ad_unbind_slave(our_slave);
+ }
+
+- /* release the slave from its bond */
+- bond_detach_slave(bond, our_slave);
+-
+- printk (KERN_INFO "%s: releasing %s interface %s",
++ printk (KERN_INFO "%s: releasing %s interface %s\n",
+ master->name,
+ (our_slave->state == BOND_STATE_ACTIVE) ? "active" : "backup",
+ slave->name);
+
+- if (our_slave == old_current) {
+- /* find a new interface and be verbose */
+- change_active_interface(bond);
+- } else {
+- printk(".\n");
++ /* release the slave from its bond */
++ bond_detach_slave(bond, our_slave);
++
++ if (bond->primary_slave == our_slave) {
++ bond->primary_slave = NULL;
+ }
+-
++
++ if (bond->current_slave == our_slave) {
++ change_active_interface(bond, NULL);
++ reselect_active_interface(bond);
++ }
++
+ if (bond->current_slave == NULL) {
+ printk(KERN_INFO
+ "%s: now running without any active interface !\n",
+ master->name);
+ }
+
+- if (bond->primary_slave == our_slave) {
+- bond->primary_slave = NULL;
+- }
+-
+ if ((bond_mode == BOND_MODE_TLB) ||
+ (bond_mode == BOND_MODE_ALB)) {
+ /* must be called only after the slave has been
+@@ -1972,16 +2069,22 @@
+ return -EINVAL;
+ }
+
++ /* unset promiscuity level from slave */
++ if (master->flags & IFF_PROMISC) {
++ /* If the mode USES_PRIMARY, then we should only remove its
++ * promisc settings if it was the current_slave, but that was
++ * already taken care of above when we detached the slave
++ */
++ if (!USES_PRIMARY(bond_mode)) {
++ dev_set_promiscuity(slave, -1);
++ }
++ }
++
+ /* undo settings and restore original values */
+-
+ if (multicast_mode == BOND_MULTICAST_ALL) {
+ /* flush master's mc_list from slave */
+ bond_mc_list_flush (slave, master);
+
+- /* unset promiscuity level from slave */
+- if (master->flags & IFF_PROMISC)
+- dev_set_promiscuity(slave, -1);
+-
+ /* unset allmulti level from slave */
+ if (master->flags & IFF_ALLMULTI)
+ dev_set_allmulti(slave, -1);
+@@ -2048,7 +2151,7 @@
+ }
+
+ old_current = bond->current_slave;
+- bond_assign_current_slave(bond, NULL);
++ change_active_interface(bond, NULL);
+ bond->current_arp_slave = NULL;
+ bond->primary_slave = NULL;
+
+@@ -2077,17 +2180,17 @@
+ */
+ write_unlock_bh(&bond->lock);
+
+- if (multicast_mode == BOND_MULTICAST_ALL
+- || (multicast_mode == BOND_MULTICAST_ACTIVE
+- && old_current == our_slave)) {
++ /* unset promiscuity level from slave */
++ if (master->flags & IFF_PROMISC) {
++ if (!USES_PRIMARY(bond_mode)) {
++ dev_set_promiscuity(slave_dev, -1);
++ }
++ }
+
++ if (multicast_mode == BOND_MULTICAST_ALL) {
+ /* flush master's mc_list from slave */
+ bond_mc_list_flush (slave_dev, master);
+
+- /* unset promiscuity level from slave */
+- if (master->flags & IFF_PROMISC)
+- dev_set_promiscuity(slave_dev, -1);
+-
+ /* unset allmulti level from slave */
+ if (master->flags & IFF_ALLMULTI)
+ dev_set_allmulti(slave_dev, -1);
+@@ -2233,9 +2336,7 @@
+ write_lock(&bond->ptrlock);
+ if (slave == bond->current_slave) {
+ /* find a new interface and be verbose */
+- change_active_interface(bond);
+- } else {
+- printk(".\n");
++ reselect_active_interface(bond);
+ }
+ write_unlock(&bond->ptrlock);
+ slave_died = 1;
+@@ -2331,7 +2432,7 @@
+ write_lock(&bond->ptrlock);
+ if ( (bond->primary_slave != NULL)
+ && (slave == bond->primary_slave) )
+- change_active_interface(bond);
++ reselect_active_interface(bond);
+ write_unlock(&bond->ptrlock);
+ }
+ else
+@@ -2377,40 +2478,8 @@
+ /* no active interface at the moment or need to bring up the primary */
+ if (oldcurrent == NULL) { /* no active interface at the moment */
+ if (bestslave != NULL) { /* last chance to find one ? */
+- if (bestslave->link == BOND_LINK_UP) {
+- printk (KERN_INFO
+- "%s: making interface %s the new active one.\n",
+- master->name, bestslave->dev->name);
+- } else {
+- printk (KERN_INFO
+- "%s: making interface %s the new "
+- "active one %d ms earlier.\n",
+- master->name, bestslave->dev->name,
+- (updelay - bestslave->delay) * miimon);
+-
+- bestslave->delay = 0;
+- bestslave->link = BOND_LINK_UP;
+- bestslave->jiffies = jiffies;
+-
+- /* notify ad that the link status has changed */
+- if (bond_mode == BOND_MODE_8023AD) {
+- bond_3ad_handle_link_change(bestslave, BOND_LINK_UP);
+- }
+-
+- if ((bond_mode == BOND_MODE_TLB) ||
+- (bond_mode == BOND_MODE_ALB)) {
+- bond_alb_handle_link_change(bond, bestslave, BOND_LINK_UP);
+- }
+- }
+-
+- if (bond_mode == BOND_MODE_ACTIVEBACKUP) {
+- bond_set_slave_active_flags(bestslave);
+- bond_mc_update(bond, bestslave, NULL);
+- } else if (bond_mode != BOND_MODE_8023AD) {
+- bestslave->state = BOND_STATE_ACTIVE;
+- }
+ write_lock(&bond->ptrlock);
+- bond_assign_current_slave(bond, bestslave);
++ change_active_interface(bond, bestslave);
+ write_unlock(&bond->ptrlock);
+ } else if (slave_died) {
+ /* print this message only once a slave has just died */
+@@ -2494,7 +2563,7 @@
+ "for interface %s, ",
+ master->name,
+ slave->dev->name);
+- change_active_interface(bond);
++ reselect_active_interface(bond);
+ } else {
+ printk(KERN_INFO
+ "%s: interface %s is now up\n",
+@@ -2526,7 +2595,7 @@
+
+ write_lock(&bond->ptrlock);
+ if (slave == bond->current_slave) {
+- change_active_interface(bond);
++ reselect_active_interface(bond);
+ }
+ write_unlock(&bond->ptrlock);
+ }
+@@ -2604,9 +2673,7 @@
+ if ((bond->current_slave == NULL) &&
+ ((jiffies - slave->dev->trans_start) <=
+ the_delta_in_ticks)) {
+- bond_assign_current_slave(bond, slave);
+- bond_set_slave_active_flags(slave);
+- bond_mc_update(bond, slave, NULL);
++ change_active_interface(bond, slave);
+ bond->current_arp_slave = NULL;
+ } else if (bond->current_slave != slave) {
+ /* this slave has just come up but we
+@@ -2696,7 +2763,8 @@
+ master->name,
+ slave->dev->name);
+ write_lock(&bond->ptrlock);
+- slave = change_active_interface(bond);
++ reselect_active_interface(bond);
++ slave = bond->current_slave;
+ write_unlock(&bond->ptrlock);
+ bond->current_arp_slave = slave;
+ if (slave != NULL) {
+@@ -2715,13 +2783,10 @@
+ bond->primary_slave->dev->name);
+
+ /* primary is up so switch to it */
+- bond_set_slave_inactive_flags(slave);
+- bond_mc_update(bond, bond->primary_slave, slave);
+ write_lock(&bond->ptrlock);
+- bond_assign_current_slave(bond, bond->primary_slave);
++ change_active_interface(bond, bond->primary_slave);
+ write_unlock(&bond->ptrlock);
+ slave = bond->primary_slave;
+- bond_set_slave_active_flags(slave);
+ slave->jiffies = jiffies;
+ } else {
+ bond->current_arp_slave = NULL;
+@@ -2730,10 +2795,8 @@
+ /* the current slave must tx an arp to ensure backup slaves
+ * rx traffic
+ */
+- if ((slave != NULL) &&
+- (((jiffies - slave->dev->last_rx) >= the_delta_in_ticks) &&
+- (my_ip != 0))) {
+- arp_send_all(slave);
++ if ((slave != NULL) && (my_ip != 0)) {
++ arp_send_all(slave);
+ }
+ }
+
+@@ -2766,7 +2829,7 @@
+ /* if the link state is up at this point, we
+ * mark it down - this can happen if we have
+ * simultaneous link failures and
+- * change_active_interface doesn't make this
++ * reselect_active_interface doesn't make this
+ * one the current slave so it is still marked
+ * up when it is actually down
+ */
+@@ -2986,7 +3049,7 @@
+ } else if (orig_app_abi_ver != app_abi_ver) {
+ printk(KERN_ERR
+ "bonding: Error: already using ifenslave ABI "
+- "version %d; to upgrade ifenslave to version %d,"
++ "version %d; to upgrade ifenslave to version %d, "
+ "you must first reload bonding.\n",
+ orig_app_abi_ver, app_abi_ver);
+ return -EINVAL;
+@@ -3011,15 +3074,9 @@
+ case SIOCBONDRELEASE:
+ ret = bond_release(master_dev, slave_dev);
+ break;
+- case BOND_SETHWADDR_OLD:
+- case SIOCBONDSETHWADDR:
+- ret = bond_sethwaddr(master_dev, slave_dev);
+- break;
+ case BOND_CHANGE_ACTIVE_OLD:
+ case SIOCBONDCHANGEACTIVE:
+- if ((bond_mode == BOND_MODE_ACTIVEBACKUP) ||
+- (bond_mode == BOND_MODE_TLB) ||
+- (bond_mode == BOND_MODE_ALB)) {
++ if (USES_PRIMARY(bond_mode)) {
+ ret = bond_change_active(master_dev, slave_dev);
+ }
+ else {
+@@ -3141,7 +3198,7 @@
+ dev_queue_xmit(skb);
+
+ write_lock(&bond->ptrlock);
+- bond_assign_current_slave(bond, slave->next);
++ bond->current_slave = slave->next;
+ write_unlock(&bond->ptrlock);
+
+ read_unlock(&bond->lock);
+@@ -3285,10 +3342,10 @@
+ static struct net_device_stats *bond_get_stats(struct net_device *dev)
+ {
+ bonding_t *bond = dev->priv;
+- struct net_device_stats *stats = bond->stats, *sstats;
++ struct net_device_stats *stats = &(bond->stats), *sstats;
+ slave_t *slave;
+
+- memset(bond->stats, 0, sizeof(struct net_device_stats));
++ memset(stats, 0, sizeof(struct net_device_stats));
+
+ read_lock_bh(&bond->lock);
+
+@@ -3327,152 +3384,511 @@
+ return stats;
+ }
+
+-static int bond_get_info(char *buf, char **start, off_t offset, int length)
+-{
+- bonding_t *bond;
+- int len = 0;
+- off_t begin = 0;
+- u16 link;
+- slave_t *slave = NULL;
++#ifdef CONFIG_PROC_FS
++
++#define SEQ_START_TOKEN ((void *)1)
+
+- len += sprintf(buf + len, "%s\n", version);
++static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos)
++{
++ struct bonding *bond = seq->private;
++ loff_t off = 0;
++ struct slave *slave;
+
++ /* make sure the bond won't be taken away */
+ read_lock(&dev_base_lock);
+- list_for_each_entry(bond, &bond_dev_list, bond_list) {
+- /*
+- * This function locks the mutex, so we can't lock it until
+- * afterwards
+- */
+- link = bond_check_mii_link(bond);
++ read_lock_bh(&bond->lock);
+
+- len += sprintf(buf + len, "Bonding Mode: %s\n",
+- bond_mode_name());
++ if (*pos == 0) {
++ return SEQ_START_TOKEN;
++ }
+
+- if ((bond_mode == BOND_MODE_ACTIVEBACKUP) ||
+- (bond_mode == BOND_MODE_TLB) ||
+- (bond_mode == BOND_MODE_ALB)) {
+- read_lock_bh(&bond->lock);
+- read_lock(&bond->ptrlock);
+- if (bond->current_slave != NULL) {
+- len += sprintf(buf + len,
+- "Currently Active Slave: %s\n",
+- bond->current_slave->dev->name);
+- }
+- read_unlock(&bond->ptrlock);
+- read_unlock_bh(&bond->lock);
+- }
+-
+- len += sprintf(buf + len, "MII Status: ");
+- len += sprintf(buf + len,
+- link == BMSR_LSTATUS ? "up\n" : "down\n");
+- len += sprintf(buf + len, "MII Polling Interval (ms): %d\n",
+- miimon);
+- len += sprintf(buf + len, "Up Delay (ms): %d\n",
+- updelay * miimon);
+- len += sprintf(buf + len, "Down Delay (ms): %d\n",
+- downdelay * miimon);
+- len += sprintf(buf + len, "Multicast Mode: %s\n",
+- multicast_mode_name());
++ for (slave = bond->prev; slave != (slave_t *)bond;
++ slave = slave->prev) {
+
+- read_lock_bh(&bond->lock);
++ if (++off == *pos) {
++ return slave;
++ }
++ }
+
+- if (bond_mode == BOND_MODE_8023AD) {
+- struct ad_info ad_info;
++ return NULL;
++}
+
+- len += sprintf(buf + len, "\n802.3ad info\n");
++static void *bond_info_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++{
++ struct bonding *bond = seq->private;
++ struct slave *slave = v;
+
+- if (bond_3ad_get_active_agg_info(bond, &ad_info)) {
+- len += sprintf(buf + len, "bond %s has no active aggregator\n", bond->device->name);
+- } else {
+- len += sprintf(buf + len, "Active Aggregator Info:\n");
++ ++*pos;
++ if (v == SEQ_START_TOKEN) {
++ slave = bond->prev;
++ } else {
++ slave = slave->prev;
++ }
+
+- len += sprintf(buf + len, "\tAggregator ID: %d\n", ad_info.aggregator_id);
+- len += sprintf(buf + len, "\tNumber of ports: %d\n", ad_info.ports);
+- len += sprintf(buf + len, "\tActor Key: %d\n", ad_info.actor_key);
+- len += sprintf(buf + len, "\tPartner Key: %d\n", ad_info.partner_key);
+- len += sprintf(buf + len, "\tPartner Mac Address: %02x:%02x:%02x:%02x:%02x:%02x\n",
+- ad_info.partner_system[0],
+- ad_info.partner_system[1],
+- ad_info.partner_system[2],
+- ad_info.partner_system[3],
+- ad_info.partner_system[4],
+- ad_info.partner_system[5]);
+- }
++ return (slave == (struct slave *) bond) ? NULL : slave;
++}
++
++static void bond_info_seq_stop(struct seq_file *seq, void *v)
++{
++ struct bonding *bond = seq->private;
++
++ read_unlock_bh(&bond->lock);
++ read_unlock(&dev_base_lock);
++}
++
++static void bond_info_show_master(struct seq_file *seq, struct bonding *bond)
++{
++ struct slave *curr;
++
++ read_lock(&bond->ptrlock);
++ curr = bond->current_slave;
++ read_unlock(&bond->ptrlock);
++
++ seq_printf(seq, "Bonding Mode: %s\n", bond_mode_name());
++
++ if (USES_PRIMARY(bond_mode)) {
++ if (curr) {
++ seq_printf(seq,
++ "Currently Active Slave: %s\n",
++ curr->dev->name);
+ }
++ }
+
+- for (slave = bond->prev; slave != (slave_t *)bond;
+- slave = slave->prev) {
+- len += sprintf(buf + len, "\nSlave Interface: %s\n", slave->dev->name);
++ seq_printf(seq, "MII Status: %s\n", (curr) ? "up" : "down");
++ seq_printf(seq, "MII Polling Interval (ms): %d\n", miimon);
++ seq_printf(seq, "Up Delay (ms): %d\n", updelay * miimon);
++ seq_printf(seq, "Down Delay (ms): %d\n", downdelay * miimon);
++ seq_printf(seq, "Multicast Mode: %s\n", multicast_mode_name());
+
+- len += sprintf(buf + len, "MII Status: ");
++ if (bond_mode == BOND_MODE_8023AD) {
++ struct ad_info ad_info;
+
+- len += sprintf(buf + len,
+- slave->link == BOND_LINK_UP ?
+- "up\n" : "down\n");
+- len += sprintf(buf + len, "Link Failure Count: %d\n",
+- slave->link_failure_count);
+-
+- if (app_abi_ver >= 1) {
+- len += sprintf(buf + len,
+- "Permanent HW addr: %02x:%02x:%02x:%02x:%02x:%02x\n",
+- slave->perm_hwaddr[0],
+- slave->perm_hwaddr[1],
+- slave->perm_hwaddr[2],
+- slave->perm_hwaddr[3],
+- slave->perm_hwaddr[4],
+- slave->perm_hwaddr[5]);
+- }
++ seq_puts(seq, "\n802.3ad info\n");
+
+- if (bond_mode == BOND_MODE_8023AD) {
+- struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator;
++ if (bond_3ad_get_active_agg_info(bond, &ad_info)) {
++ seq_printf(seq, "bond %s has no active aggregator\n",
++ bond->device->name);
++ } else {
++ seq_printf(seq, "Active Aggregator Info:\n");
+
+- if (agg) {
+- len += sprintf(buf + len, "Aggregator ID: %d\n",
+- agg->aggregator_identifier);
+- } else {
+- len += sprintf(buf + len, "Aggregator ID: N/A\n");
+- }
+- }
++ seq_printf(seq, "\tAggregator ID: %d\n",
++ ad_info.aggregator_id);
++ seq_printf(seq, "\tNumber of ports: %d\n",
++ ad_info.ports);
++ seq_printf(seq, "\tActor Key: %d\n",
++ ad_info.actor_key);
++ seq_printf(seq, "\tPartner Key: %d\n",
++ ad_info.partner_key);
++ seq_printf(seq, "\tPartner Mac Address: %02x:%02x:%02x:%02x:%02x:%02x\n",
++ ad_info.partner_system[0],
++ ad_info.partner_system[1],
++ ad_info.partner_system[2],
++ ad_info.partner_system[3],
++ ad_info.partner_system[4],
++ ad_info.partner_system[5]);
+ }
+- read_unlock_bh(&bond->lock);
++ }
++}
+
+- /*
+- * Figure out the calcs for the /proc/net interface
+- */
+- *start = buf + (offset - begin);
+- len -= (offset - begin);
+- if (len > length) {
+- len = length;
++static void bond_info_show_slave(struct seq_file *seq, const struct slave *slave)
++{
++ seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name);
++ seq_printf(seq, "MII Status: %s\n",
++ (slave->link == BOND_LINK_UP) ? "up" : "down");
++ seq_printf(seq, "Link Failure Count: %d\n",
++ slave->link_failure_count);
++
++ if (app_abi_ver >= 1) {
++ seq_printf(seq,
++ "Permanent HW addr: %02x:%02x:%02x:%02x:%02x:%02x\n",
++ slave->perm_hwaddr[0],
++ slave->perm_hwaddr[1],
++ slave->perm_hwaddr[2],
++ slave->perm_hwaddr[3],
++ slave->perm_hwaddr[4],
++ slave->perm_hwaddr[5]);
++ }
++
++ if (bond_mode == BOND_MODE_8023AD) {
++ const struct aggregator *agg
++ = SLAVE_AD_INFO(slave).port.aggregator;
++
++ if (agg) {
++ seq_printf(seq, "Aggregator ID: %d\n",
++ agg->aggregator_identifier);
++ } else {
++ seq_puts(seq, "Aggregator ID: N/A\n");
+ }
+- if (len < 0) {
+- len = 0;
++ }
++}
++
++static int bond_info_seq_show(struct seq_file *seq, void *v)
++{
++ if (v == SEQ_START_TOKEN) {
++ seq_printf(seq, "%s\n", version);
++ bond_info_show_master(seq, seq->private);
++ } else {
++ bond_info_show_slave(seq, v);
++ }
++
++ return 0;
++}
++
++static struct seq_operations bond_info_seq_ops = {
++ .start = bond_info_seq_start,
++ .next = bond_info_seq_next,
++ .stop = bond_info_seq_stop,
++ .show = bond_info_seq_show,
++};
++
++static int bond_info_open(struct inode *inode, struct file *file)
++{
++ struct seq_file *seq;
++ struct proc_dir_entry *proc;
++ int rc;
++
++ rc = seq_open(file, &bond_info_seq_ops);
++ if (!rc) {
++ /* recover the pointer buried in proc_dir_entry data */
++ seq = file->private_data;
++ proc = PDE(inode);
++ seq->private = proc->data;
++ }
++ return rc;
++}
++
++static struct file_operations bond_info_fops = {
++ .owner = THIS_MODULE,
++ .open = bond_info_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = seq_release,
++};
++
++static int bond_create_proc_info(struct bonding *bond)
++{
++ struct net_device *dev = bond->device;
++
++ if (bond_proc_dir) {
++ bond->bond_proc_file = create_proc_entry(dev->name,
++ S_IRUGO,
++ bond_proc_dir);
++ if (bond->bond_proc_file == NULL) {
++ printk(KERN_WARNING
++ "%s: Cannot create /proc/net/bonding/%s\n",
++ dev->name, dev->name);
++ } else {
++ bond->bond_proc_file->data = bond;
++ bond->bond_proc_file->proc_fops = &bond_info_fops;
++ bond->bond_proc_file->owner = THIS_MODULE;
++ memcpy(bond->procdir_name, dev->name, IFNAMSIZ);
+ }
++ }
++
++ return 0;
++}
+
++static void bond_destroy_proc_info(struct bonding *bond)
++{
++ if (bond_proc_dir && bond->bond_proc_file) {
++ remove_proc_entry(bond->procdir_name, bond_proc_dir);
++ memset(bond->procdir_name, 0, IFNAMSIZ);
++ bond->bond_proc_file = NULL;
+ }
+- read_unlock(&dev_base_lock);
++}
++#endif /* CONFIG_PROC_FS */
++
++/*
++ * Change HW address
++ *
++ * Note that many devices must be down to change the HW address, and
++ * downing the master releases all slaves. We can make bonds full of
++ * bonding devices to test this, however.
++ */
++static inline int
++bond_set_mac_address(struct net_device *dev, void *addr)
++{
++ struct bonding *bond = dev->priv;
++ struct sockaddr *sa = addr, tmp_sa;
++ struct slave *slave;
++ int error;
++
++ dprintk(KERN_INFO "bond_set_mac_address %p %s\n", dev,
++ dev->name);
+
+- return len;
++ if (!is_valid_ether_addr(sa->sa_data)) {
++ return -EADDRNOTAVAIL;
++ }
++
++ for (slave = bond->prev; slave != (struct slave *)bond;
++ slave = slave->prev) {
++ dprintk(KERN_INFO "bond_set_mac: slave %p %s\n", slave,
++ slave->dev->name);
++ if (slave->dev->set_mac_address == NULL) {
++ error = -EOPNOTSUPP;
++ dprintk(KERN_INFO "bond_set_mac EOPNOTSUPP %s\n",
++ slave->dev->name);
++ goto unwind;
++ }
++
++ error = slave->dev->set_mac_address(slave->dev, addr);
++ if (error) {
++ /* TODO: consider downing the slave
++ * and retry ?
++ * User should expect communications
++ * breakage anyway until ARP finish
++ * updating, so...
++ */
++ dprintk(KERN_INFO "bond_set_mac err %d %s\n",
++ error, slave->dev->name);
++ goto unwind;
++ }
++ }
++
++ /* success */
++ memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
++ return 0;
++
++unwind:
++ memcpy(tmp_sa.sa_data, dev->dev_addr, dev->addr_len);
++ tmp_sa.sa_family = dev->type;
++
++ for (slave = slave->next; slave != bond->next;
++ slave = slave->next) {
++ int tmp_error;
++
++ tmp_error = slave->dev->set_mac_address(slave->dev, &tmp_sa);
++ if (tmp_error) {
++ dprintk(KERN_INFO "bond_set_mac_address: "
++ "unwind err %d dev %s\n",
++ tmp_error, slave->dev->name);
++ }
++ }
++
++ return error;
+ }
+
+-static int bond_event(struct notifier_block *this, unsigned long event,
+- void *ptr)
++/*
++ * Change the MTU of all of a master's slaves to match the master
++ */
++static inline int
++bond_change_mtu(struct net_device *dev, int newmtu)
++{
++ bonding_t *bond = dev->priv;
++ slave_t *slave;
++ int error;
++
++ dprintk(KERN_INFO "CM: b %p nm %d\n", bond, newmtu);
++ for (slave = bond->prev; slave != (slave_t *)bond;
++ slave = slave->prev) {
++ dprintk(KERN_INFO "CM: s %p s->p %p c_m %p\n", slave,
++ slave->prev, slave->dev->change_mtu);
++ if (slave->dev->change_mtu) {
++ error = slave->dev->change_mtu(slave->dev, newmtu);
++ } else {
++ slave->dev->mtu = newmtu;
++ error = 0;
++ }
++
++ if (error) {
++ /* If we failed to set the slave's mtu to the new value
++ * we must abort the operation even in ACTIVE_BACKUP
++ * mode, because if we allow the backup slaves to have
++ * different mtu values than the active slave we'll
++ * need to change their mtu when doing a failover. That
++ * means changing their mtu from timer context, which
++ * is probably not a good idea.
++ */
++ dprintk(KERN_INFO "bond_change_mtu err %d %s\n",
++ error, slave->dev->name);
++ goto unwind;
++ }
++ }
++
++ dev->mtu = newmtu;
++ return 0;
++
++
++unwind:
++ for (slave = slave->next; slave != bond->next;
++ slave = slave->next) {
++
++ if (slave->dev->change_mtu) {
++ slave->dev->change_mtu(slave->dev, dev->mtu);
++ } else {
++ slave->dev->mtu = dev->mtu;
++ }
++ }
++
++ return error;
++}
++
++/*
++ * Change device name
++ */
++static inline int bond_event_changename(struct bonding *bond)
++{
++#ifdef CONFIG_PROC_FS
++ bond_destroy_proc_info(bond);
++ bond_create_proc_info(bond);
++#endif
++
++ return NOTIFY_DONE;
++}
++
++static int bond_master_netdev_event(unsigned long event, struct net_device *event_dev)
++{
++ struct bonding *bond, *event_bond = NULL;
++
++ list_for_each_entry(bond, &bond_dev_list, bond_list) {
++ if (bond == event_dev->priv) {
++ event_bond = bond;
++ break;
++ }
++ }
++
++ if (event_bond == NULL) {
++ return NOTIFY_DONE;
++ }
++
++ switch (event) {
++ case NETDEV_CHANGENAME:
++ return bond_event_changename(event_bond);
++ case NETDEV_UNREGISTER:
++ /*
++ * TODO: remove a bond from the list?
++ */
++ break;
++ default:
++ break;
++ }
++
++ return NOTIFY_DONE;
++}
++
++static int bond_slave_netdev_event(unsigned long event, struct net_device *event_dev)
+ {
+- struct net_device *event_dev = (struct net_device *)ptr;
+ struct net_device *master = event_dev->master;
+
+- if (event == NETDEV_UNREGISTER && master != NULL)
+- bond_release(master, event_dev);
++ switch (event) {
++ case NETDEV_UNREGISTER:
++ if (master != NULL) {
++ bond_release(master, event_dev);
++ }
++ break;
++ case NETDEV_CHANGE:
++ /*
++ * TODO: is this what we get if somebody
++ * sets up a hierarchical bond, then rmmod's
++ * one of the slave bonding devices?
++ */
++ break;
++ case NETDEV_DOWN:
++ /*
++ * ... Or is it this?
++ */
++ break;
++ case NETDEV_CHANGEMTU:
++ /*
++ * TODO: Should slaves be allowed to
++ * independently alter their MTU? For
++ * an active-backup bond, slaves need
++ * not be the same type of device, so
++ * MTUs may vary. For other modes,
++ * slaves arguably should have the
++ * same MTUs. To do this, we'd need to
++ * take over the slave's change_mtu
++ * function for the duration of their
++ * servitude.
++ */
++ break;
++ case NETDEV_CHANGENAME:
++ /*
++ * TODO: handle changing the primary's name
++ */
++ break;
++ default:
++ break;
++ }
+
+ return NOTIFY_DONE;
+ }
+
++/*
++ * bond_netdev_event: handle netdev notifier chain events.
++ *
++ * This function receives events for the netdev chain. The caller (an
++ * ioctl handler calling notifier_call_chain) holds the necessary
++ * locks for us to safely manipulate the slave devices (RTNL lock,
++ * dev_probe_lock).
++ */
++static int bond_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
++{
++ struct net_device *event_dev = (struct net_device *)ptr;
++ unsigned short flags;
++ int res = NOTIFY_DONE;
++
++ dprintk(KERN_INFO "bond_netdev_event n_b %p ev %lx ptr %p\n",
++ this, event, ptr);
++
++ flags = event_dev->flags & (IFF_MASTER | IFF_SLAVE);
++ switch (flags) {
++ case IFF_MASTER:
++ res = bond_master_netdev_event(event, event_dev);
++ break;
++ case IFF_SLAVE:
++ res = bond_slave_netdev_event(event, event_dev);
++ break;
++ default:
++ /* A master that is also a slave ? */
++ break;
++ }
++
++ return res;
++}
++
+ static struct notifier_block bond_netdev_notifier = {
+- .notifier_call = bond_event,
++ .notifier_call = bond_netdev_event,
+ };
+
++static inline void bond_deinit(struct net_device *dev)
++{
++ struct bonding *bond = dev->priv;
++
++ list_del(&bond->bond_list);
++
++#ifdef CONFIG_PROC_FS
++ bond_destroy_proc_info(bond);
++#endif
++}
++
++static void bond_free_all(void)
++{
++ struct bonding *bond, *nxt;
++
++ list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) {
++ struct net_device *dev = bond->device;
++
++ unregister_netdev(dev);
++ bond_deinit(dev);
++ free_netdev(dev);
++ }
++
++#ifdef CONFIG_PROC_FS
++ if (bond_proc_dir) {
++ remove_proc_entry(DRV_NAME, proc_net);
++ bond_proc_dir = NULL;
++ }
++#endif
++}
++
++/*
++ * Does not allocate but creates a /proc entry.
++ * Allowed to fail.
++ */
+ static int __init bond_init(struct net_device *dev)
+ {
+- bonding_t *bond;
++ struct bonding *bond;
+ int count;
+
+ #ifdef BONDING_DEBUG
+@@ -3483,15 +3899,16 @@
+ /* initialize rwlocks */
+ rwlock_init(&bond->lock);
+ rwlock_init(&bond->ptrlock);
+-
+- /* space is reserved for stats in alloc_netdev call. */
+- bond->stats = (struct net_device_stats *)(bond + 1);
++
++ /* Initialize pointers */
+ bond->next = bond->prev = (slave_t *)bond;
+ bond->current_slave = NULL;
+ bond->current_arp_slave = NULL;
+ bond->device = dev;
+
+ /* Initialize the device structure. */
++ dev->set_mac_address = bond_set_mac_address;
++
+ switch (bond_mode) {
+ case BOND_MODE_ACTIVEBACKUP:
+ dev->hard_start_xmit = bond_xmit_activebackup;
+@@ -3511,6 +3928,7 @@
+ case BOND_MODE_TLB:
+ case BOND_MODE_ALB:
+ dev->hard_start_xmit = bond_alb_xmit;
++ dev->set_mac_address = bond_alb_set_mac_address;
+ break;
+ default:
+ printk(KERN_ERR "Unknown bonding mode %d\n", bond_mode);
+@@ -3522,7 +3940,7 @@
+ dev->stop = bond_close;
+ dev->set_multicast_list = set_multicast_list;
+ dev->do_ioctl = bond_ioctl;
+-
++ dev->change_mtu = bond_change_mtu;
+ dev->tx_queue_len = 0;
+ dev->flags |= IFF_MASTER|IFF_MULTICAST;
+ #ifdef CONFIG_NET_FASTROUTE
+@@ -3549,30 +3967,13 @@
+ } else {
+ printk("out ARP monitoring\n");
+ }
+-
++
+ #ifdef CONFIG_PROC_FS
+- bond->bond_proc_dir = proc_mkdir(dev->name, proc_net);
+- if (bond->bond_proc_dir == NULL) {
+- printk(KERN_ERR "%s: Cannot init /proc/net/%s/\n",
+- dev->name, dev->name);
+- return -ENOMEM;
+- }
+- bond->bond_proc_dir->owner = THIS_MODULE;
+-
+- bond->bond_proc_info_file =
+- create_proc_info_entry("info", 0, bond->bond_proc_dir,
+- bond_get_info);
+- if (bond->bond_proc_info_file == NULL) {
+- printk(KERN_ERR "%s: Cannot init /proc/net/%s/info\n",
+- dev->name, dev->name);
+- remove_proc_entry(dev->name, proc_net);
+- return -ENOMEM;
+- }
+- bond->bond_proc_info_file->owner = THIS_MODULE;
+-#endif /* CONFIG_PROC_FS */
+-
++ bond_create_proc_info(bond);
++#endif
+
+ list_add_tail(&bond->bond_list, &bond_dev_list);
++
+ return 0;
+ }
+
+@@ -3605,6 +4006,7 @@
+ return -1;
+ }
+
++
+ static int __init bonding_init(void)
+ {
+ int no;
+@@ -3625,6 +4027,12 @@
+ }
+ }
+
++ if (USES_PRIMARY(bond_mode)) {
++ multicast_mode = BOND_MULTICAST_ACTIVE;
++ } else {
++ multicast_mode = BOND_MULTICAST_ALL;
++ }
++
+ if (multicast) {
+ multicast_mode = bond_parse_parm(multicast, bond_mc_tbl);
+ if (multicast_mode == -1) {
+@@ -3811,7 +4219,7 @@
+ arp_interval = 0;
+ } else {
+ u32 ip = in_aton(arp_ip_target[arp_ip_count]);
+- *(u32 *)(arp_ip_target[arp_ip_count]) = ip;
++ arp_target[arp_ip_count] = ip;
+ }
+ }
+
+@@ -3837,9 +4245,7 @@
+ "link failures! see bonding.txt for details.\n");
+ }
+
+- if ((primary != NULL) && (bond_mode != BOND_MODE_ACTIVEBACKUP) &&
+- (bond_mode != BOND_MODE_TLB) &&
+- (bond_mode != BOND_MODE_ALB)){
++ if ((primary != NULL) && !USES_PRIMARY(bond_mode)) {
+ /* currently, using a primary only makes sense
+ * in active backup, TLB or ALB modes
+ */
+@@ -3850,50 +4256,72 @@
+ primary = NULL;
+ }
+
+- register_netdevice_notifier(&bond_netdev_notifier);
++#ifdef CONFIG_PROC_FS
++ bond_proc_dir = proc_mkdir(DRV_NAME, proc_net);
++ if (bond_proc_dir == NULL) {
++ printk(KERN_WARNING
++ "bonding_init(): can not create /proc/net/" DRV_NAME);
++ } else {
++ bond_proc_dir->owner = THIS_MODULE;
++ }
++#endif
++
++ rtnl_lock();
+
++ err = 0;
+ for (no = 0; no < max_bonds; no++) {
+ struct net_device *dev;
+- char name[IFNAMSIZ];
+
+- snprintf(name, IFNAMSIZ, "bond%d", no);
+-
+- dev = alloc_netdev(sizeof(bonding_t)
+- + sizeof(struct net_device_stats),
+- name, ether_setup);
+- if (!dev)
+- return -ENOMEM;
++ dev = alloc_netdev(sizeof(struct bonding), "", ether_setup);
++ if (!dev) {
++ err = -ENOMEM;
++ goto out_err;
++ }
++
++ err = dev_alloc_name(dev, "bond%d");
++ if (err < 0) {
++ free_netdev(dev);
++ goto out_err;
++ }
++
++ /* bond_init() must be called after dev_alloc_name() (for the
++ * /proc files), but before register_netdevice(), because we
++ * need to set function pointers.
++ */
++ err = bond_init(dev);
++ if (err < 0) {
++ free_netdev(dev);
++ goto out_err;
++ }
+
+- dev->init = bond_init;
+ SET_MODULE_OWNER(dev);
+
+- if ( (err = register_netdev(dev)) ) {
+-#ifdef BONDING_DEBUG
+- printk(KERN_INFO "%s: register_netdev failed %d\n",
+- dev->name, err);
+-#endif
+- kfree(dev);
+- return err;
+- }
++ err = register_netdevice(dev);
++ if (err < 0) {
++ bond_deinit(dev);
++ free_netdev(dev);
++ goto out_err;
++ }
+ }
++
++ rtnl_unlock();
++ register_netdevice_notifier(&bond_netdev_notifier);
++
+ return 0;
++
++out_err:
++ rtnl_unlock();
++
++ /* free and unregister all bonds that were successfully added */
++ bond_free_all();
++
++ return err;
+ }
+
+ static void __exit bonding_exit(void)
+ {
+- struct bonding *bond, *nxt;
+-
+ unregister_netdevice_notifier(&bond_netdev_notifier);
+-
+- list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) {
+- struct net_device *dev = bond->device;
+-#ifdef CONFIG_PROC_FS
+- remove_proc_entry("info", bond->bond_proc_dir);
+- remove_proc_entry(dev->name, proc_net);
+-#endif
+- unregister_netdev(dev);
+- free_netdev(dev);
+- }
++ bond_free_all();
+ }
+
+ module_init(bonding_init);
+Index: linux-2.6.0-test5/drivers/net/cs89x0.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/cs89x0.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/cs89x0.c 2003-09-27 11:38:24.648781200 +0800
+@@ -90,7 +90,6 @@
+ or override something. */
+ #include <linux/config.h>
+ #include <linux/module.h>
+-#include <linux/version.h>
+
+ /*
+ * Set this to zero to disable DMA code
+Index: linux-2.6.0-test5/drivers/net/depca.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/depca.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/depca.c 2003-09-27 11:38:24.701773144 +0800
+@@ -1,4 +1,4 @@
+-/* depca.c: A DIGITAL DEPCA & EtherWORKS ethernet driver for linux.
++/* depca.c: A DIGITAL DEPCA & EtherWORKS ethernet driver for linux.
+
+ Written 1994, 1995 by David C. Davies.
+
+@@ -253,7 +253,8 @@
+ #include <linux/types.h>
+ #include <linux/unistd.h>
+ #include <linux/ctype.h>
+-#include <linux/mca-legacy.h>
++#include <linux/moduleparam.h>
++#include <linux/device.h>
+
+ #include <asm/uaccess.h>
+ #include <asm/bitops.h>
+@@ -265,7 +266,6 @@
+ #endif
+
+ #ifdef CONFIG_EISA
+-#include <linux/device.h>
+ #include <linux/eisa.h>
+ #endif
+
+@@ -305,21 +305,21 @@
+ ** EISA bus defines
+ */
+ #define DEPCA_EISA_IO_PORTS 0x0c00 /* I/O port base address, slot 0 */
+-#define MAX_EISA_SLOTS 16
+-#define EISA_SLOT_INC 0x1000
+
+ /*
+ ** ISA Bus defines
+ */
+ #define DEPCA_RAM_BASE_ADDRESSES {0xc0000,0xd0000,0xe0000,0x00000}
+-#define DEPCA_IO_PORTS {0x300, 0x200, 0}
+ #define DEPCA_TOTAL_SIZE 0x10
+-static short mem_chkd;
+
+-/*
+-** Adapter ID for the MCA EtherWORKS DE210/212 adapter
+-*/
+-#define DE212_ID 0x6def
++static struct {
++ u_long iobase;
++ struct platform_device *device;
++} depca_io_ports[] = {
++ { 0x300, NULL },
++ { 0x200, NULL },
++ { 0 , NULL },
++};
+
+ /*
+ ** Name <-> Adapter mapping
+@@ -330,34 +330,86 @@
+ "DE210","DE212",\
+ "DE422",\
+ ""}
+-static enum {
++
++static char* __initdata depca_signature[] = DEPCA_SIGNATURE;
++
++enum depca_type {
+ DEPCA, de100, de101, de200, de201, de202, de210, de212, de422, unknown
+-} adapter;
++};
++
++static char depca_string[] = "depca";
++
++static int depca_device_remove (struct device *device);
+
+ #ifdef CONFIG_EISA
+ struct eisa_device_id depca_eisa_ids[] = {
+- { "DEC4220" },
++ { "DEC4220", de422 },
+ { "" }
+ };
+
+ static int depca_eisa_probe (struct device *device);
+-static int depca_eisa_remove (struct device *device);
+
+ struct eisa_driver depca_eisa_driver = {
+ .id_table = depca_eisa_ids,
+ .driver = {
+- .name = "depca",
++ .name = depca_string,
+ .probe = depca_eisa_probe,
+- .remove = __devexit_p (depca_eisa_remove)
++ .remove = __devexit_p (depca_device_remove)
+ }
+ };
+ #endif
+
++#ifdef CONFIG_MCA
++/*
++** Adapter ID for the MCA EtherWORKS DE210/212 adapter
++*/
++#define DE210_ID 0x628d
++#define DE212_ID 0x6def
++
++static short depca_mca_adapter_ids[] = {
++ DE210_ID,
++ DE212_ID,
++ 0x0000
++};
++
++static char *depca_mca_adapter_name[] = {
++ "DEC EtherWORKS MC Adapter (DE210)",
++ "DEC EtherWORKS MC Adapter (DE212)",
++ NULL
++};
++
++static enum depca_type depca_mca_adapter_type[] = {
++ de210,
++ de212,
++ 0
++};
++
++static int depca_mca_probe (struct device *);
++
++static struct mca_driver depca_mca_driver = {
++ .id_table = depca_mca_adapter_ids,
++ .driver = {
++ .name = depca_string,
++ .bus = &mca_bus_type,
++ .probe = depca_mca_probe,
++ .remove = __devexit_p(depca_device_remove),
++ },
++};
++#endif
++
++static int depca_isa_probe (struct device *);
++
++static struct device_driver depca_isa_driver = {
++ .name = depca_string,
++ .bus = &platform_bus_type,
++ .probe = depca_isa_probe,
++ .remove = __devexit_p(depca_device_remove),
++};
++
+ /*
+ ** Miscellaneous info...
+ */
+ #define DEPCA_STRLEN 16
+-#define MAX_NUM_DEPCAS 2
+
+ /*
+ ** Memory Alignment. Each descriptor is 4 longwords long. To force a
+@@ -402,10 +454,13 @@
+ #define DEPCA_PKT_BIN_SZ 128 /* Should be >=100 unless you
+ increase DEPCA_PKT_STAT_SZ */
+ struct depca_private {
+- char devname[DEPCA_STRLEN]; /* Device Product String */
+ char adapter_name[DEPCA_STRLEN]; /* /proc/ioports string */
+- char adapter; /* Adapter type */
+- char mca_slot; /* MCA slot, if MCA else -1 */
++ enum depca_type adapter; /* Adapter type */
++ enum {
++ DEPCA_BUS_MCA = 1,
++ DEPCA_BUS_ISA,
++ DEPCA_BUS_EISA,
++ } depca_bus; /* type of bus */
+ struct depca_init init_block; /* Shadow Initialization block */
+ /* CPU address space fields */
+ struct depca_rx_desc *rx_ring; /* Pointer to start of RX descriptor ring */
+@@ -467,45 +522,39 @@
+ /*
+ ** Private functions
+ */
+-static int depca_hw_init(struct net_device *dev, u_long ioaddr, int mca_slot);
+ static void depca_init_ring(struct net_device *dev);
+ static int depca_rx(struct net_device *dev);
+ static int depca_tx(struct net_device *dev);
+
+ static void LoadCSRs(struct net_device *dev);
+ static int InitRestartDepca(struct net_device *dev);
+-static void DepcaSignature(char *name, u_long paddr);
++static int DepcaSignature(char *name, u_long paddr);
+ static int DevicePresent(u_long ioaddr);
+ static int get_hw_addr(struct net_device *dev);
+ static void SetMulticastFilter(struct net_device *dev);
+-static void isa_probe(struct net_device *dev, u_long iobase);
+-#ifdef CONFIG_MCA
+-static void mca_probe(struct net_device *dev, u_long iobase);
+-#endif
+-static struct net_device *alloc_device(struct net_device *dev, u_long iobase);
+-static int depca_dev_index(char *s);
+-static struct net_device *insert_device(struct net_device *dev, u_long iobase, int (*init) (struct net_device *));
+ static int load_packet(struct net_device *dev, struct sk_buff *skb);
+ static void depca_dbg_open(struct net_device *dev);
+
+-#ifdef MODULE
+-static int autoprobed = 1, loading_module = 1;
+-# else
+ static u_char de1xx_irq[] __initdata = { 2, 3, 4, 5, 7, 9, 0 };
+ static u_char de2xx_irq[] __initdata = { 5, 9, 10, 11, 15, 0 };
+ static u_char de422_irq[] __initdata = { 5, 9, 10, 11, 0 };
+ static u_char *depca_irq;
+-static int autoprobed, loading_module;
+-#endif /* MODULE */
+
+-static char name[DEPCA_STRLEN];
+-static int num_depcas, num_eth;
++static int irq;
++static int io;
++static char *adapter_name;
+ static int mem; /* For loadable module assignment
+ use insmod mem=0x????? .... */
+-static char *adapter_name; /* = '\0'; If no PROM when loadable module
+- use insmod adapter_name=DE??? ...
+- bss initializes this to zero
+- */
++module_param (irq, int, 0);
++module_param (io, int, 0);
++module_param (adapter_name, charp, 0);
++module_param (mem, int, 0);
++MODULE_PARM_DESC(irq, "DEPCA IRQ number");
++MODULE_PARM_DESC(io, "DEPCA I/O base address");
++MODULE_PARM_DESC(adapter_name, "DEPCA adapter name");
++MODULE_PARM_DESC(mem, "DEPCA shared memory address");
++MODULE_LICENSE("GPL");
++
+ /*
+ ** Miscellaneous defines...
+ */
+@@ -513,52 +562,30 @@
+ outw(CSR0, DEPCA_ADDR);\
+ outw(STOP, DEPCA_DATA)
+
+-int __init depca_probe(struct net_device *dev)
+-{
+- int tmp = num_depcas, status = -ENODEV;
+- u_long iobase = dev->base_addr;
+-
+- SET_MODULE_OWNER(dev);
+-
+- if ((iobase == 0) && loading_module) {
+- printk("Autoprobing is not supported when loading a module based driver.\n");
+- status = -EIO;
+- } else {
+-#ifdef CONFIG_MCA
+- mca_probe(dev, iobase);
+-#endif
+- isa_probe(dev, iobase);
+-#ifdef CONFIG_EISA
+- eisa_driver_register (&depca_eisa_driver);
+-#endif
+-
+- if ((tmp == num_depcas) && (iobase != 0) && loading_module) {
+- printk("%s: depca_probe() cannot find device at 0x%04lx.\n", dev->name, iobase);
+- }
+-
+- /*
+- ** Walk the device list to check that at least one device
+- ** initialised OK
+- */
+- for (; (dev->priv == NULL) && (dev->next != NULL); dev = dev->next);
+-
+- if (dev->priv)
+- status = 0;
+- if (iobase == 0)
+- autoprobed = 1;
+- }
+-
+- return status;
+-}
+-
+-static int __init depca_hw_init(struct net_device *dev, u_long ioaddr, int mca_slot)
++static int __init depca_hw_init (struct net_device *dev, struct device *device)
+ {
+ struct depca_private *lp;
+ int i, j, offset, netRAM, mem_len, status = 0;
+ s16 nicsr;
+- u_long mem_start = 0, mem_base[] = DEPCA_RAM_BASE_ADDRESSES;
+- int is_eisa = ((ioaddr & 0x0fff) == DEPCA_EISA_IO_PORTS);
++ u_long ioaddr;
++ u_long mem_start;
++
++ /*
++ * We are now supposed to enter this function with the
++ * following fields filled with proper values :
++ *
++ * dev->base_addr
++ * lp->mem_start
++ * lp->depca_bus
++ * lp->adapter
++ *
++ * dev->irq can be set if known from device configuration (on
++ * MCA or EISA) or module option. Otherwise, it will be auto
++ * detected.
++ */
+
++ ioaddr = dev->base_addr;
++
+ STOP_DEPCA;
+
+ nicsr = inb(DEPCA_NICSR);
+@@ -569,24 +596,34 @@
+ return -ENXIO;
+ }
+
+- do {
+- strcpy(name, (adapter_name ? adapter_name : ""));
+- mem_start = (mem ? mem & 0xf0000 : mem_base[mem_chkd++]);
+- DepcaSignature(name, mem_start);
+- } while (!mem && mem_base[mem_chkd] && (adapter == unknown));
++ lp = (struct depca_private *) dev->priv;
++ mem_start = lp->mem_start;
+
+- if ((adapter == unknown) || !mem_start) { /* DEPCA device not found */
++ if (!mem_start || lp->adapter < DEPCA || lp->adapter >=unknown)
+ return -ENXIO;
+- }
+
+- dev->base_addr = ioaddr;
++ printk ("%s: %s at 0x%04lx",
++ device->bus_id, depca_signature[lp->adapter], ioaddr);
++
++ switch (lp->depca_bus) {
++#ifdef CONFIG_MCA
++ case DEPCA_BUS_MCA:
++ printk(" (MCA slot %d)", to_mca_device(device)->slot + 1);
++ break;
++#endif
++
++#ifdef CONFIG_EISA
++ case DEPCA_BUS_EISA:
++ printk(" (EISA slot %d)", to_eisa_device(device)->slot);
++ break;
++#endif
+
+- if (mca_slot != -1) {
+- printk("%s: %s at 0x%04lx (MCA slot %d)", dev->name, name, ioaddr, mca_slot);
+- } else if (is_eisa) { /* EISA slot address */
+- printk("%s: %s at 0x%04lx (EISA slot %d)", dev->name, name, ioaddr, (int) ((ioaddr >> 12) & 0x0f));
+- } else { /* ISA port address */
+- printk("%s: %s at 0x%04lx", dev->name, name, ioaddr);
++ case DEPCA_BUS_ISA:
++ break;
++
++ default:
++ printk("Unknown DEPCA bus %d\n", lp->depca_bus);
++ return -ENXIO;
+ }
+
+ printk(", h/w address ");
+@@ -601,18 +638,20 @@
+ printk("%2.2x", dev->dev_addr[i]);
+
+ /* Set up the maximum amount of network RAM(kB) */
+- netRAM = ((adapter != DEPCA) ? 64 : 48);
+- if ((nicsr & _128KB) && (adapter == de422))
++ netRAM = ((lp->adapter != DEPCA) ? 64 : 48);
++ if ((nicsr & _128KB) && (lp->adapter == de422))
+ netRAM = 128;
+- offset = 0x0000;
+
+ /* Shared Memory Base Address */
+ if (nicsr & BUF) {
+- offset = 0x8000; /* 32kbyte RAM offset */
+ nicsr &= ~BS; /* DEPCA RAM in top 32k */
+ netRAM -= 32;
++
++ /* Only EISA/ISA needs start address to be re-computed */
++ if (lp->depca_bus != DEPCA_BUS_MCA)
++ mem_start += 0x8000;
+ }
+- mem_start += offset; /* (E)ISA start address */
++
+ if ((mem_len = (NUM_RX_DESC * (sizeof(struct depca_rx_desc) + RX_BUFF_SZ) + NUM_TX_DESC * (sizeof(struct depca_tx_desc) + TX_BUFF_SZ) + sizeof(struct depca_init)))
+ > (netRAM << 10)) {
+ printk(",\n requests %dkB RAM: only %dkB is available!\n", (mem_len >> 10), netRAM);
+@@ -622,23 +661,14 @@
+ printk(",\n has %dkB RAM at 0x%.5lx", netRAM, mem_start);
+
+ /* Enable the shadow RAM. */
+- if (adapter != DEPCA) {
++ if (lp->adapter != DEPCA) {
+ nicsr |= SHE;
+ outb(nicsr, DEPCA_NICSR);
+ }
+
+- /* Define the device private memory */
+- if (!is_eisa) {
+- dev->priv = (void *) kmalloc(sizeof(struct depca_private), GFP_KERNEL);
+- if (dev->priv == NULL)
+- return -ENOMEM;
+- }
+- lp = (struct depca_private *) dev->priv;
+- memset((char *) dev->priv, 0, sizeof(struct depca_private));
+- lp->adapter = adapter;
+- lp->mca_slot = mca_slot;
+ lp->lock = SPIN_LOCK_UNLOCKED;
+- sprintf(lp->adapter_name, "%s (%s)", name, dev->name);
++ sprintf(lp->adapter_name, "%s (%s)",
++ depca_signature[lp->adapter], device->bus_id);
+ status = -EBUSY;
+
+ /* Initialisation Block */
+@@ -702,7 +732,6 @@
+ /* To auto-IRQ we enable the initialization-done and DMA err,
+ interrupts. For now we will always get a DMA error. */
+ if (dev->irq < 2) {
+-#ifndef MODULE
+ unsigned char irqnum;
+ unsigned long irq_mask, delay;
+
+@@ -725,6 +754,9 @@
+ case de422:
+ depca_irq = de422_irq;
+ break;
++
++ default:
++ break; /* Not reached */
+ }
+
+ /* Trigger an initialization just for the interrupt. */
+@@ -733,6 +765,7 @@
+ delay = jiffies + HZ/50;
+ while (time_before(jiffies, delay))
+ yield();
++
+ irqnum = probe_irq_off(irq_mask);
+
+ status = -ENXIO;
+@@ -746,13 +779,11 @@
+ printk(" and uses IRQ%d.\n", dev->irq);
+ }
+
+- status = -ENXIO;
+ if (!dev->irq) {
+ printk(" but incorrect IRQ line detected.\n");
+- goto out_priv;
++ return -ENXIO;
+ }
+ }
+-#endif /* MODULE */
+ } else {
+ printk(" and assigned IRQ%d.\n", dev->irq);
+ }
+@@ -773,17 +804,14 @@
+
+ dev->mem_start = 0;
+
+- /* Fill in the generic field of the device structure. */
+- if (!is_eisa)
+- ether_setup(dev);
++ device->driver_data = dev;
++ SET_NETDEV_DEV (dev, device);
++
++ register_netdev (dev);
+ return 0;
+- out_priv:
+- if (!is_eisa) {
+- kfree(dev->priv);
+- dev->priv = NULL;
+- } else {
+- unregister_netdev (dev);
+- }
++
++ out_priv:
++
+ return status;
+ }
+ \f
+@@ -1284,215 +1312,265 @@
+ return;
+ }
+
++static int __init depca_common_init (u_long ioaddr, struct net_device **devp)
++{
++ int status = 0;
++
++ if (!request_region (ioaddr, DEPCA_TOTAL_SIZE, depca_string)) {
++ status = -EBUSY;
++ goto out;
++ }
++
++ if (DevicePresent(ioaddr)) {
++ status = -ENODEV;
++ goto out_release;
++ }
++
++ if (!(*devp = alloc_etherdev (sizeof (struct depca_private)))) {
++ status = -ENOMEM;
++ goto out_release;
++ }
++
++ return 0;
++
++ out_release:
++ release_region (ioaddr, DEPCA_TOTAL_SIZE);
++ out:
++ return status;
++}
++
+ #ifdef CONFIG_MCA
+ /*
+ ** Microchannel bus I/O device probe
+ */
+-static void __init mca_probe(struct net_device *dev, u_long ioaddr)
++static int __init depca_mca_probe(struct device *device)
+ {
+ unsigned char pos[2];
+ unsigned char where;
+- unsigned long iobase;
+- int irq;
+- int slot = 0;
++ unsigned long iobase, mem_start;
++ int irq, err;
++ struct mca_device *mdev = to_mca_device (device);
++ struct net_device *dev;
++ struct depca_private *lp;
+
+ /*
+- ** See if we've been here before.
+- */
+- if ((!ioaddr && autoprobed) || (ioaddr && !loading_module))
+- return;
+-
+- if (MCA_bus) {
+- /*
+- ** Search for the adapter. If an address has been given, search
+- ** specifically for the card at that address. Otherwise find the
+- ** first card in the system.
+- */
+- while ((dev != NULL) && ((slot = mca_find_adapter(DE212_ID, slot)) != MCA_NOTFOUND)) {
+- pos[0] = mca_read_stored_pos(slot, 2);
+- pos[1] = mca_read_stored_pos(slot, 3);
+-
+- /*
+- ** IO of card is handled by bits 1 and 2 of pos0.
+- **
+- ** bit2 bit1 IO
+- ** 0 0 0x2c00
+- ** 0 1 0x2c10
+- ** 1 0 0x2c20
+- ** 1 1 0x2c30
+- */
+- where = (pos[0] & 6) >> 1;
+- iobase = 0x2c00 + (0x10 * where);
+-
+- if ((ioaddr) && (ioaddr != iobase)) {
+- /*
+- ** Card was found, but not at the right IO location. Continue
+- ** scanning from the next MCA slot up for another card.
+- */
+- slot++;
+- continue;
+- }
+-
+- /*
+- ** Found the adapter we were looking for. Now start setting it up.
+- **
+- ** First work on decoding the IRQ. It's stored in the lower 4 bits
+- ** of pos1. Bits are as follows (from the ADF file):
+- **
+- ** Bits
+- ** 3 2 1 0 IRQ
+- ** --------------------
+- ** 0 0 1 0 5
+- ** 0 0 0 1 9
+- ** 0 1 0 0 10
+- ** 1 0 0 0 11
+- * */
+- where = pos[1] & 0x0f;
+- switch (where) {
+- case 1:
+- irq = 9;
+- break;
+- case 2:
+- irq = 5;
+- break;
+- case 4:
+- irq = 10;
+- break;
+- case 8:
+- irq = 11;
+- break;
+- default:
+- printk("%s: mca_probe IRQ error. You should never get here (%d).\n", dev->name, where);
+- return;
+- }
+-
+- /*
+- ** Shared memory address of adapter is stored in bits 3-5 of pos0.
+- ** They are mapped as follows:
+- **
+- ** Bit
+- ** 5 4 3 Memory Addresses
+- ** 0 0 0 C0000-CFFFF (64K)
+- ** 1 0 0 C8000-CFFFF (32K)
+- ** 0 0 1 D0000-DFFFF (64K)
+- ** 1 0 1 D8000-DFFFF (32K)
+- ** 0 1 0 E0000-EFFFF (64K)
+- ** 1 1 0 E8000-EFFFF (32K)
+- */
+- where = (pos[0] & 0x18) >> 3;
+- mem = 0xc0000 + (where * 0x10000);
+- if (pos[0] & 0x20) {
+- mem += 0x8000;
+- }
++ ** Search for the adapter. If an address has been given, search
++ ** specifically for the card at that address. Otherwise find the
++ ** first card in the system.
++ */
++
++ pos[0] = mca_device_read_stored_pos(mdev, 2);
++ pos[1] = mca_device_read_stored_pos(mdev, 3);
+
+- /*
+- ** Get everything allocated and initialized... (almost just
+- ** like the ISA and EISA probes)
+- */
+- if (!request_region (iobase, DEPCA_TOTAL_SIZE, "depca")) {
+- if (autoprobed)
+- printk(KERN_WARNING "%s: region already allocated at 0x%04lx.\n", dev->name, iobase);
+- goto next;
+- }
+- if (DevicePresent(iobase) != 0) {
+- /*
+- ** If the MCA configuration says the card should be here,
+- ** it really should be here.
+- */
+- printk(KERN_ERR "%s: MCA reports card at 0x%lx but it is not responding.\n", dev->name, iobase);
+- goto release_next;
+- }
++ /*
++ ** IO of card is handled by bits 1 and 2 of pos0.
++ **
++ ** bit2 bit1 IO
++ ** 0 0 0x2c00
++ ** 0 1 0x2c10
++ ** 1 0 0x2c20
++ ** 1 1 0x2c30
++ */
++ where = (pos[0] & 6) >> 1;
++ iobase = 0x2c00 + (0x10 * where);
+
+- if (!(dev = alloc_device(dev, iobase)))
+- goto release_next;
++ /*
++ ** Found the adapter we were looking for. Now start setting it up.
++ **
++ ** First work on decoding the IRQ. It's stored in the lower 4 bits
++ ** of pos1. Bits are as follows (from the ADF file):
++ **
++ ** Bits
++ ** 3 2 1 0 IRQ
++ ** --------------------
++ ** 0 0 1 0 5
++ ** 0 0 0 1 9
++ ** 0 1 0 0 10
++ ** 1 0 0 0 11
++ */
++ where = pos[1] & 0x0f;
++ switch (where) {
++ case 1:
++ irq = 9;
++ break;
++ case 2:
++ irq = 5;
++ break;
++ case 4:
++ irq = 10;
++ break;
++ case 8:
++ irq = 11;
++ break;
++ default:
++ printk("%s: mca_probe IRQ error. You should never get here (%d).\n", dev->name, where);
++ return -EINVAL;
++ }
+
+- num_eth++;
+- dev->irq = irq;
+- if (depca_hw_init(dev, iobase, slot))
+- goto release_next;
++ /*
++ ** Shared memory address of adapter is stored in bits 3-5 of pos0.
++ ** They are mapped as follows:
++ **
++ ** Bit
++ ** 5 4 3 Memory Addresses
++ ** 0 0 0 C0000-CFFFF (64K)
++ ** 1 0 0 C8000-CFFFF (32K)
++ ** 0 0 1 D0000-DFFFF (64K)
++ ** 1 0 1 D8000-DFFFF (32K)
++ ** 0 1 0 E0000-EFFFF (64K)
++ ** 1 1 0 E8000-EFFFF (32K)
++ */
++ where = (pos[0] & 0x18) >> 3;
++ mem_start = 0xc0000 + (where * 0x10000);
++ if (pos[0] & 0x20) {
++ mem_start += 0x8000;
++ }
++
++ /* claim the slot */
++ strncpy(mdev->name, depca_mca_adapter_name[mdev->index],
++ sizeof(mdev->name));
++ mca_device_set_claim(mdev, 1);
++
++ /*
++ ** Get everything allocated and initialized... (almost just
++ ** like the ISA and EISA probes)
++ */
++ irq = mca_device_transform_irq(mdev, irq);
++ iobase = mca_device_transform_ioport(mdev, iobase);
++
++ if ((err = depca_common_init (iobase, &dev)))
++ goto out_unclaim;
++
++ dev->irq = irq;
++ dev->base_addr = iobase;
++ lp = dev->priv;
++ lp->depca_bus = DEPCA_BUS_MCA;
++ lp->adapter = depca_mca_adapter_type[mdev->index];
++ lp->mem_start = mem_start;
++
++ if ((err = depca_hw_init(dev, device)))
++ goto out_free;
+
+- /*
+- ** Adapter initialized correctly: Name it in
+- ** /proc/mca.
+- */
+- mca_set_adapter_name(slot, "DE210/212 Ethernet Adapter");
+- mca_mark_as_used(slot);
+- num_depcas++;
+-
+- /*
+- ** If this is a probe by a module, return after setting up the
+- ** given card.
+- */
+- if (ioaddr)
+- return;
+-
+- /*
+- ** Set up to check the next slot and loop.
+- */
+- slot++;
+- continue;
++ return 0;
+
+- release_next:
+- release_region (iobase, DEPCA_TOTAL_SIZE);
+- next:
+- slot++;
+- }
+- }
++ out_free:
++ free_netdev (dev);
++ release_region (iobase, DEPCA_TOTAL_SIZE);
++ out_unclaim:
++ mca_device_set_claim(mdev, 0);
+
+- return;
++ return err;;
+ }
+ #endif
+
+ /*
+ ** ISA bus I/O device probe
+ */
+-static void __init isa_probe(struct net_device *dev, u_long ioaddr)
++
++static void depca_platform_release (struct device *device)
+ {
+- int i = num_depcas, maxSlots;
+- s32 ports[] = DEPCA_IO_PORTS;
++ struct platform_device *pldev;
+
+- if (!ioaddr && autoprobed)
+- return; /* Been here before ! */
+- if (ioaddr > 0x400)
+- return; /* EISA Address */
+- if (i >= MAX_NUM_DEPCAS)
+- return; /* Too many ISA adapters */
+-
+- if (ioaddr == 0) { /* Autoprobing */
+- maxSlots = MAX_NUM_DEPCAS;
+- } else { /* Probe a specific location */
+- ports[i] = ioaddr;
+- maxSlots = i + 1;
+- }
+-
+- for (; (i < maxSlots) && (dev != NULL) && ports[i]; i++) {
+- if (!request_region (ports[i], DEPCA_TOTAL_SIZE, "depca")) {
+- if (autoprobed)
+- printk("%s: region already allocated at 0x%04x.\n", dev->name, ports[i]);
++ /* free device */
++ pldev = to_platform_device (device);
++ kfree (pldev);
++}
++
++static void __init depca_platform_probe (void)
++{
++ int i;
++ struct platform_device *pldev;
++
++ for (i = 0; depca_io_ports[i].iobase; i++) {
++ depca_io_ports[i].device = NULL;
++
++ /* if an address has been specified on the command
++ * line, use it (if valid) */
++ if (io && io != depca_io_ports[i].iobase)
++ continue;
++
++ if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL)))
+ continue;
+- }
+
+- if (DevicePresent(ports[i])) {
+- release_region (ports[i], DEPCA_TOTAL_SIZE);
++ memset (pldev, 0, sizeof (*pldev));
++ pldev->name = depca_string;
++ pldev->id = i;
++ pldev->dev.platform_data = (void *) depca_io_ports[i].iobase;
++ pldev->dev.release = depca_platform_release;
++ depca_io_ports[i].device = pldev;
++
++ if (platform_device_register (pldev)) {
++ kfree (pldev);
++ depca_io_ports[i].device = NULL;
+ continue;
+ }
+
+- if (!(dev = alloc_device(dev, ports[i]))) {
+- release_region (ports[i], DEPCA_TOTAL_SIZE);
+- continue;
++ if (!pldev->dev.driver) {
++ /* The driver was not bound to this device, there was
++ * no hardware at this address. Unregister it, as the
++ * release fuction will take care of freeing the
++ * allocated structure */
++
++ depca_io_ports[i].device = NULL;
++ platform_device_unregister (pldev);
+ }
++ }
++}
+
+- num_eth++;
++static enum depca_type __init depca_shmem_probe (ulong *mem_start)
++{
++ u_long mem_base[] = DEPCA_RAM_BASE_ADDRESSES;
++ enum depca_type adapter = unknown;
++ int i;
+
+- if (depca_hw_init(dev, ports[i], -1)) {
+- release_region (ports[i], DEPCA_TOTAL_SIZE);
+- continue;
+- }
++ for (i = 0; mem_base[i]; i++) {
++ *mem_start = mem ? mem : mem_base[i];
++ adapter = DepcaSignature (adapter_name, *mem_start);
++ if (adapter != unknown)
++ break;
++ }
++
++ return adapter;
++}
+
+- num_depcas++;
++static int __init depca_isa_probe (struct device *device)
++{
++ struct net_device *dev;
++ struct depca_private *lp;
++ u_long ioaddr, mem_start = 0;
++ enum depca_type adapter = unknown;
++ int status = 0;
++
++ ioaddr = (u_long) device->platform_data;
++
++ if ((status = depca_common_init (ioaddr, &dev)))
++ goto out;
++
++ adapter = depca_shmem_probe (&mem_start);
++
++ if (adapter == unknown) {
++ status = -ENODEV;
++ goto out_free;
+ }
+
+- return;
++ dev->base_addr = ioaddr;
++ dev->irq = irq; /* Use whatever value the user gave
++ * us, and 0 if he didn't. */
++ lp = dev->priv;
++ lp->depca_bus = DEPCA_BUS_ISA;
++ lp->adapter = adapter;
++ lp->mem_start = mem_start;
++
++ if ((status = depca_hw_init(dev, device)))
++ goto out_free;
++
++ return 0;
++
++ out_free:
++ free_netdev (dev);
++ release_region (ioaddr, DEPCA_TOTAL_SIZE);
++ out:
++ return status;
+ }
+
+ /*
+@@ -1504,202 +1582,120 @@
+ {
+ struct eisa_device *edev;
+ struct net_device *dev;
+- u_long iobase;
++ struct depca_private *lp;
++ u_long ioaddr, mem_start;
+ int status = 0;
+
+ edev = to_eisa_device (device);
+- iobase = edev->base_addr + DEPCA_EISA_IO_PORTS;
++ ioaddr = edev->base_addr + DEPCA_EISA_IO_PORTS;
+
+- if (!request_region (iobase, DEPCA_TOTAL_SIZE, "depca")) {
+- status = -EBUSY;
++ if ((status = depca_common_init (ioaddr, &dev)))
+ goto out;
+- }
+-
+- if (DevicePresent(iobase)) {
+- status = -ENODEV;
+- goto out_release;
+- }
+
+- if (!(dev = init_etherdev (NULL, sizeof (struct depca_private)))) {
+- status = -ENOMEM;
+- goto out_release;
+- }
+-
+- eisa_set_drvdata (edev, dev);
++ /* It would have been nice to get card configuration from the
++ * card. Unfortunately, this register is write-only (shares
++ * it's address with the ethernet prom)... As we don't parse
++ * the EISA configuration structures (yet... :-), just rely on
++ * the ISA probing to sort it out... */
++
++ depca_shmem_probe (&mem_start);
+
+- if ((status = depca_hw_init(dev, iobase, -1)))
++ dev->base_addr = ioaddr;
++ dev->irq = irq;
++ lp = dev->priv;
++ lp->depca_bus = DEPCA_BUS_EISA;
++ lp->adapter = edev->id.driver_data;
++ lp->mem_start = mem_start;
++
++ if ((status = depca_hw_init(dev, device)))
+ goto out_free;
+-
+- num_depcas++;
++
+ return 0;
+
+ out_free:
+- kfree (dev);
+- out_release:
+- release_region (iobase, DEPCA_TOTAL_SIZE);
++ free_netdev (dev);
++ release_region (ioaddr, DEPCA_TOTAL_SIZE);
+ out:
+ return status;
+ }
++#endif
+
+-static int __devexit depca_eisa_remove (struct device *device)
++static int __devexit depca_device_remove (struct device *device)
+ {
+ struct net_device *dev;
+- struct eisa_device *edev;
+ struct depca_private *lp;
++ int bus;
+
+- edev = to_eisa_device (device);
+- dev = eisa_get_drvdata (edev);
++ dev = device->driver_data;
+ lp = dev->priv;
+
+ unregister_netdev (dev);
+ iounmap (lp->sh_mem);
+ release_mem_region (lp->mem_start, lp->mem_len);
+ release_region (dev->base_addr, DEPCA_TOTAL_SIZE);
+- kfree (dev);
++ bus = lp->depca_bus;
++ free_netdev (dev);
+
+ return 0;
+ }
+-#endif
+-
+-/*
+-** Search the entire 'eth' device list for a fixed probe. If a match isn't
+-** found then check for an autoprobe or unused device location. If they
+-** are not available then insert a new device structure at the end of
+-** the current list.
+-*/
+-static struct net_device *__init alloc_device(struct net_device *dev, u_long iobase)
+-{
+- struct net_device *adev = NULL;
+- int fixed = 0, new_dev = 0;
+-
+- num_eth = depca_dev_index(dev->name);
+- if (loading_module)
+- return dev;
+-
+- while (1) {
+- if (((dev->base_addr == DEPCA_NDA) || (dev->base_addr == 0)) && !adev) {
+- adev = dev;
+- } else if ((dev->priv == NULL) && (dev->base_addr == iobase)) {
+- fixed = 1;
+- } else {
+- if (dev->next == NULL) {
+- new_dev = 1;
+- } else if (strncmp(dev->next->name, "eth", 3) != 0) {
+- new_dev = 1;
+- }
+- }
+- if ((dev->next == NULL) || new_dev || fixed)
+- break;
+- dev = dev->next;
+- num_eth++;
+- }
+- if (adev && !fixed) {
+- dev = adev;
+- num_eth = depca_dev_index(dev->name);
+- new_dev = 0;
+- }
+-
+- if (((dev->next == NULL) && ((dev->base_addr != DEPCA_NDA) && (dev->base_addr != 0)) && !fixed) || new_dev) {
+- num_eth++; /* New device */
+- dev = insert_device(dev, iobase, depca_probe);
+- }
+-
+- return dev;
+-}
+-
+-/*
+-** If at end of eth device list and can't use current entry, malloc
+-** one up. If memory could not be allocated, print an error message.
+-*/
+-static struct net_device *__init insert_device(struct net_device *dev, u_long iobase, int (*init) (struct net_device *))
+-{
+- struct net_device *new;
+-
+- new = (struct net_device *) kmalloc(sizeof(struct net_device), GFP_KERNEL);
+- if (new == NULL) {
+- printk("eth%d: Device not initialised, insufficient memory\n", num_eth);
+- return NULL;
+- } else {
+- new->next = dev->next;
+- dev->next = new;
+- dev = dev->next; /* point to the new device */
+- if (num_eth > 9999) {
+- sprintf(dev->name, "eth????"); /* New device name */
+- } else {
+- sprintf(dev->name, "eth%d", num_eth); /* New device name */
+- }
+- dev->base_addr = iobase; /* assign the io address */
+- dev->init = init; /* initialisation routine */
+- }
+-
+- return dev;
+-}
+-
+-static int __init depca_dev_index(char *s)
+-{
+- int i = 0, j = 0;
+-
+- for (; *s; s++) {
+- if (isdigit(*s)) {
+- j = 1;
+- i = (i * 10) + (*s - '0');
+- } else if (j)
+- break;
+- }
+-
+- return i;
+-}
+
+ /*
+ ** Look for a particular board name in the on-board Remote Diagnostics
+ ** and Boot (readb) ROM. This will also give us a clue to the network RAM
+ ** base address.
+ */
+-static void __init DepcaSignature(char *name, u_long paddr)
++static int __init DepcaSignature(char *name, u_long base_addr)
+ {
+ u_int i, j, k;
+- const char *signatures[] = DEPCA_SIGNATURE;
+ void *ptr;
+ char tmpstr[16];
++ u_long prom_addr = base_addr + 0xc000;
++ u_long mem_addr = base_addr + 0x8000; /* 32KB */
++
++ /* Can't reserve the prom region, it is already marked as
++ * used, at least on x86. Instead, reserve a memory region a
++ * board would certainly use. If it works, go ahead. If not,
++ * run like hell... */
++
++ if (!request_mem_region (mem_addr, 16, depca_string))
++ return unknown;
+
+ /* Copy the first 16 bytes of ROM */
+- ptr = ioremap(paddr + 0xc000, 16);
++
++ ptr = ioremap(prom_addr, 16);
+ if (ptr == NULL) {
+- printk(KERN_ERR "depca: I/O remap failed at %lx\n", paddr + 0xc000);
+- adapter = unknown;
+- return;
++ printk(KERN_ERR "depca: I/O remap failed at %lx\n", prom_addr);
++ return unknown;
+ }
+ for (i = 0; i < 16; i++) {
+ tmpstr[i] = readb(ptr + i);
+ }
+ iounmap(ptr);
+
++ release_mem_region (mem_addr, 16);
++
+ /* Check if PROM contains a valid string */
+- for (i = 0; *signatures[i] != '\0'; i++) {
+- for (j = 0, k = 0; j < 16 && k < strlen(signatures[i]); j++) {
+- if (signatures[i][k] == tmpstr[j]) { /* track signature */
++ for (i = 0; *depca_signature[i] != '\0'; i++) {
++ for (j = 0, k = 0; j < 16 && k < strlen(depca_signature[i]); j++) {
++ if (depca_signature[i][k] == tmpstr[j]) { /* track signature */
+ k++;
+ } else { /* lost signature; begin search again */
+ k = 0;
+ }
+ }
+- if (k == strlen(signatures[i]))
++ if (k == strlen(depca_signature[i]))
+ break;
+ }
+
+ /* Check if name string is valid, provided there's no PROM */
+- if (*name && (i == unknown)) {
+- for (i = 0; *signatures[i] != '\0'; i++) {
+- if (strcmp(name, signatures[i]) == 0)
++ if (name && *name && (i == unknown)) {
++ for (i = 0; *depca_signature[i] != '\0'; i++) {
++ if (strcmp(name, depca_signature[i]) == 0)
+ break;
+ }
+ }
+
+- /* Update search results */
+- strcpy(name, signatures[i]);
+- adapter = i;
+-
+- return;
++ return i;
+ }
+
+ /*
+@@ -1773,10 +1769,11 @@
+ static int __init get_hw_addr(struct net_device *dev)
+ {
+ u_long ioaddr = dev->base_addr;
++ struct depca_private *lp = dev->priv;
+ int i, k, tmp, status = 0;
+ u_short j, x, chksum;
+
+- x = (((adapter == de100) || (adapter == de101)) ? 1 : 0);
++ x = (((lp->adapter == de100) || (lp->adapter == de101)) ? 1 : 0);
+
+ for (i = 0, k = 0, j = 0; j < 3; j++) {
+ k <<= 1;
+@@ -2083,55 +2080,40 @@
+ return status;
+ }
+
+-#ifdef MODULE
+-static struct net_device thisDepca;
+-static int irq = 7; /* EDIT THESE LINE FOR YOUR CONFIGURATION */
+-static int io = 0x200; /* Or use the irq= io= options to insmod */
+-MODULE_PARM(irq, "i");
+-MODULE_PARM(io, "i");
+-MODULE_PARM_DESC(irq, "DEPCA IRQ number");
+-MODULE_PARM_DESC(io, "DEPCA I/O base address");
+-
+-/* See depca_probe() for autoprobe messages when a module */
+-int init_module(void)
++static int __init depca_module_init (void)
+ {
+- thisDepca.irq = irq;
+- thisDepca.base_addr = io;
+- thisDepca.init = depca_probe;
++ int err = 0;
+
+- if (register_netdev(&thisDepca) != 0)
+- return -EIO;
+-
+- return 0;
++#if CONFIG_MCA
++ err = mca_register_driver (&depca_mca_driver);
++#endif
++#ifdef CONFIG_EISA
++ err |= eisa_driver_register (&depca_eisa_driver);
++#endif
++ err |= driver_register (&depca_isa_driver);
++ depca_platform_probe ();
++
++ return err;
+ }
+
+-void cleanup_module(void)
++static void __exit depca_module_exit (void)
+ {
+- struct depca_private *lp = thisDepca.priv;
+-
+- unregister_netdev(&thisDepca);
+- if (lp) {
+- iounmap(lp->sh_mem);
+- release_mem_region (lp->mem_start, lp->mem_len);
+-#ifdef CONFIG_MCA
+- if (lp->mca_slot != -1)
+- mca_mark_as_unused(lp->mca_slot);
++ int i;
++#if CONFIG_MCA
++ mca_unregister_driver (&depca_mca_driver);
+ #endif
+- kfree(lp);
+- thisDepca.priv = NULL;
+- }
+- thisDepca.irq = 0;
++#ifdef CONFIG_EISA
++ eisa_driver_unregister (&depca_eisa_driver);
++#endif
++ driver_unregister (&depca_isa_driver);
+
+- release_region(thisDepca.base_addr, DEPCA_TOTAL_SIZE);
++ for (i = 0; depca_io_ports[i].iobase; i++) {
++ if (depca_io_ports[i].device) {
++ platform_device_unregister (depca_io_ports[i].device);
++ depca_io_ports[i].device = NULL;
++ }
++ }
+ }
+-#endif /* MODULE */
+-MODULE_LICENSE("GPL");
+-\f
+
+-/*
+- * Local variables:
+- * compile-command: "gcc -D__KERNEL__ -I/linux/include -Wall -Wstrict-prototypes -fomit-frame-pointer -fno-strength-reduce -malign-loops=2 -malign-jumps=2 -malign-functions=2 -O2 -m486 -c depca.c"
+- *
+- * compile-command: "gcc -D__KERNEL__ -DMODULE -I/linux/include -Wall -Wstrict-prototypes -fomit-frame-pointer -fno-strength-reduce -malign-loops=2 -malign-jumps=2 -malign-functions=2 -O2 -m486 -c depca.c"
+- * End:
+- */
++module_init (depca_module_init);
++module_exit (depca_module_exit);
+Index: linux-2.6.0-test5/drivers/net/dgrs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/dgrs.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/dgrs.c 2003-09-27 11:38:24.748766000 +0800
+@@ -84,6 +84,7 @@
+ */
+
+ #include <linux/module.h>
++#include <linux/eisa.h>
+ #include <linux/kernel.h>
+ #include <linux/string.h>
+ #include <linux/delay.h>
+@@ -120,7 +121,7 @@
+ #include "dgrs_asstruct.h"
+ #include "dgrs_bcomm.h"
+
+-static struct pci_device_id dgrs_pci_tbl[] __initdata = {
++static struct pci_device_id dgrs_pci_tbl[] = {
+ { SE6_PCI_VENDOR_ID, SE6_PCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, },
+ { } /* Terminating entry */
+ };
+Index: linux-2.6.0-test5/drivers/net/e1000/e1000_ethtool.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/e1000/e1000_ethtool.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/e1000/e1000_ethtool.c 2003-09-27 11:38:24.783760680 +0800
+@@ -190,6 +190,55 @@
+ return 0;
+ }
+
++static int
++e1000_ethtool_gpause(struct e1000_adapter *adapter,
++ struct ethtool_pauseparam *epause)
++{
++ struct e1000_hw *hw = &adapter->hw;
++
++ epause->autoneg =
++ (adapter->fc_autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE);
++
++ if(hw->fc == e1000_fc_rx_pause)
++ epause->rx_pause = 1;
++ else if(hw->fc == e1000_fc_tx_pause)
++ epause->tx_pause = 1;
++ else if(hw->fc == e1000_fc_full) {
++ epause->rx_pause = 1;
++ epause->tx_pause = 1;
++ }
++
++ return 0;
++}
++
++static int
++e1000_ethtool_spause(struct e1000_adapter *adapter,
++ struct ethtool_pauseparam *epause)
++{
++ struct e1000_hw *hw = &adapter->hw;
++
++ adapter->fc_autoneg = epause->autoneg;
++
++ if(epause->rx_pause && epause->tx_pause)
++ hw->fc = e1000_fc_full;
++ else if(epause->rx_pause && !epause->tx_pause)
++ hw->fc = e1000_fc_rx_pause;
++ else if(!epause->rx_pause && epause->tx_pause)
++ hw->fc = e1000_fc_tx_pause;
++ else if(!epause->rx_pause && !epause->tx_pause)
++ hw->fc = e1000_fc_none;
++
++ hw->original_fc = hw->fc;
++
++ if(netif_running(adapter->netdev)) {
++ e1000_down(adapter);
++ e1000_up(adapter);
++ } else
++ e1000_reset(adapter);
++
++ return 0;
++}
++
+ static void
+ e1000_ethtool_gdrvinfo(struct e1000_adapter *adapter,
+ struct ethtool_drvinfo *drvinfo)
+@@ -958,9 +1007,13 @@
+ case e1000_82544:
+ case e1000_82540:
+ case e1000_82545:
++ case e1000_82545_rev_3:
+ case e1000_82546:
++ case e1000_82546_rev_3:
+ case e1000_82541:
++ case e1000_82541_rev_2:
+ case e1000_82547:
++ case e1000_82547_rev_2:
+ return e1000_integrated_phy_loopback(adapter);
+ break;
+
+@@ -983,9 +1036,12 @@
+ {
+ uint32_t rctl;
+
+- if(adapter->hw.media_type == e1000_media_type_fiber) {
++ if(adapter->hw.media_type == e1000_media_type_fiber ||
++ adapter->hw.media_type == e1000_media_type_internal_serdes) {
+ if(adapter->hw.mac_type == e1000_82545 ||
+- adapter->hw.mac_type == e1000_82546)
++ adapter->hw.mac_type == e1000_82546 ||
++ adapter->hw.mac_type == e1000_82545_rev_3 ||
++ adapter->hw.mac_type == e1000_82546_rev_3)
+ return e1000_set_phy_loopback(adapter);
+ else {
+ rctl = E1000_READ_REG(&adapter->hw, RCTL);
+@@ -1010,9 +1066,12 @@
+ E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
+
+ if(adapter->hw.media_type == e1000_media_type_copper ||
+- (adapter->hw.media_type == e1000_media_type_fiber &&
++ ((adapter->hw.media_type == e1000_media_type_fiber ||
++ adapter->hw.media_type == e1000_media_type_internal_serdes) &&
+ (adapter->hw.mac_type == e1000_82545 ||
+- adapter->hw.mac_type == e1000_82546))) {
++ adapter->hw.mac_type == e1000_82546 ||
++ adapter->hw.mac_type == e1000_82545_rev_3 ||
++ adapter->hw.mac_type == e1000_82546_rev_3))) {
+ adapter->hw.autoneg = TRUE;
+ e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg);
+ if(phy_reg & MII_CR_LOOPBACK) {
+@@ -1114,7 +1173,7 @@
+ e1000_down(adapter);
+ else
+ e1000_reset(adapter);
+-
++
+ if(e1000_reg_test(adapter, &data[0]))
+ eth_test->flags |= ETH_TEST_FL_FAILED;
+
+@@ -1162,6 +1221,7 @@
+ return;
+
+ case E1000_DEV_ID_82546EB_FIBER:
++ case E1000_DEV_ID_82546GB_FIBER:
+ /* Wake events only supported on port A for dual fiber */
+ if(E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1) {
+ wol->supported = 0;
+@@ -1200,6 +1260,7 @@
+ return wol->wolopts ? -EOPNOTSUPP : 0;
+
+ case E1000_DEV_ID_82546EB_FIBER:
++ case E1000_DEV_ID_82546GB_FIBER:
+ /* Wake events only supported on port A for dual fiber */
+ if(E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)
+ return wol->wolopts ? -EOPNOTSUPP : 0;
+@@ -1437,6 +1498,19 @@
+ addr += offsetof(struct ethtool_eeprom, data);
+ return e1000_ethtool_seeprom(adapter, &eeprom, addr);
+ }
++ case ETHTOOL_GPAUSEPARAM: {
++ struct ethtool_pauseparam epause = {ETHTOOL_GPAUSEPARAM};
++ e1000_ethtool_gpause(adapter, &epause);
++ if(copy_to_user(addr, &epause, sizeof(epause)))
++ return -EFAULT;
++ return 0;
++ }
++ case ETHTOOL_SPAUSEPARAM: {
++ struct ethtool_pauseparam epause;
++ if(copy_from_user(&epause, addr, sizeof(epause)))
++ return -EFAULT;
++ return e1000_ethtool_spause(adapter, &epause);
++ }
+ case ETHTOOL_GSTATS: {
+ struct {
+ struct ethtool_stats eth_stats;
+Index: linux-2.6.0-test5/drivers/net/e1000/e1000.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/e1000/e1000.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/e1000/e1000.h 2003-09-27 11:38:24.870747456 +0800
+@@ -122,7 +122,12 @@
+ #define E1000_RX_BUFFER_WRITE 16 /* Must be power of 2 */
+
+ #define AUTO_ALL_MODES 0
+-#define E1000_EEPROM_APME 4
++#define E1000_EEPROM_APME 0x0400
++
++#ifndef E1000_MASTER_SLAVE
++/* Switch to override PHY master/slave setting */
++#define E1000_MASTER_SLAVE e1000_ms_hw_default
++#endif
+
+ /* only works for sizes that are powers of 2 */
+ #define E1000_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1)))
+@@ -180,6 +185,7 @@
+ spinlock_t stats_lock;
+ atomic_t irq_sem;
+ struct work_struct tx_timeout_task;
++ uint8_t fc_autoneg;
+
+ struct timer_list blink_timer;
+ unsigned long led_status;
+@@ -194,6 +200,7 @@
+ uint32_t tx_head_addr;
+ uint32_t tx_fifo_size;
+ atomic_t tx_fifo_stall;
++ boolean_t pcix_82544;
+
+ /* RX */
+ struct e1000_desc_ring rx_ring;
+Index: linux-2.6.0-test5/drivers/net/e1000/e1000_hw.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/e1000/e1000_hw.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/e1000/e1000_hw.c 2003-09-27 11:38:25.047720552 +0800
+@@ -34,14 +34,15 @@
+
+ static int32_t e1000_set_phy_type(struct e1000_hw *hw);
+ static void e1000_phy_init_script(struct e1000_hw *hw);
+-static int32_t e1000_setup_fiber_link(struct e1000_hw *hw);
+ static int32_t e1000_setup_copper_link(struct e1000_hw *hw);
++static int32_t e1000_setup_fiber_serdes_link(struct e1000_hw *hw);
++static int32_t e1000_adjust_serdes_amplitude(struct e1000_hw *hw);
+ static int32_t e1000_phy_force_speed_duplex(struct e1000_hw *hw);
+ static int32_t e1000_config_mac_to_phy(struct e1000_hw *hw);
+-static int32_t e1000_force_mac_fc(struct e1000_hw *hw);
+ static void e1000_raise_mdi_clk(struct e1000_hw *hw, uint32_t *ctrl);
+ static void e1000_lower_mdi_clk(struct e1000_hw *hw, uint32_t *ctrl);
+-static void e1000_shift_out_mdi_bits(struct e1000_hw *hw, uint32_t data, uint16_t count);
++static void e1000_shift_out_mdi_bits(struct e1000_hw *hw, uint32_t data,
++ uint16_t count);
+ static uint16_t e1000_shift_in_mdi_bits(struct e1000_hw *hw);
+ static int32_t e1000_phy_reset_dsp(struct e1000_hw *hw);
+ static int32_t e1000_write_eeprom_spi(struct e1000_hw *hw, uint16_t offset,
+@@ -52,13 +53,30 @@
+ static int32_t e1000_spi_eeprom_ready(struct e1000_hw *hw);
+ static void e1000_raise_ee_clk(struct e1000_hw *hw, uint32_t *eecd);
+ static void e1000_lower_ee_clk(struct e1000_hw *hw, uint32_t *eecd);
+-static void e1000_shift_out_ee_bits(struct e1000_hw *hw, uint16_t data, uint16_t count);
++static void e1000_shift_out_ee_bits(struct e1000_hw *hw, uint16_t data,
++ uint16_t count);
++static int32_t e1000_write_phy_reg_ex(struct e1000_hw *hw, uint32_t reg_addr,
++ uint16_t phy_data);
++static int32_t e1000_read_phy_reg_ex(struct e1000_hw *hw,uint32_t reg_addr,
++ uint16_t *phy_data);
+ static uint16_t e1000_shift_in_ee_bits(struct e1000_hw *hw, uint16_t count);
+ static int32_t e1000_acquire_eeprom(struct e1000_hw *hw);
+ static void e1000_release_eeprom(struct e1000_hw *hw);
+ static void e1000_standby_eeprom(struct e1000_hw *hw);
+ static int32_t e1000_id_led_init(struct e1000_hw * hw);
++static int32_t e1000_set_vco_speed(struct e1000_hw *hw);
+
++/* IGP cable length table */
++static const
++uint16_t e1000_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] =
++ { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
++ 5, 10, 10, 10, 10, 10, 10, 10, 20, 20, 20, 20, 20, 25, 25, 25,
++ 25, 25, 25, 25, 30, 30, 30, 30, 40, 40, 40, 40, 40, 40, 40, 40,
++ 40, 50, 50, 50, 50, 50, 50, 50, 60, 60, 60, 60, 60, 60, 60, 60,
++ 60, 70, 70, 70, 70, 70, 70, 80, 80, 80, 80, 80, 80, 90, 90, 90,
++ 90, 90, 90, 90, 90, 90, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
++ 100, 100, 100, 100, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
++ 110, 110, 110, 110, 110, 110, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120};
+
+
+ /******************************************************************************
+@@ -100,50 +118,41 @@
+ DEBUGFUNC("e1000_phy_init_script");
+
+ if(hw->phy_init_script) {
+- msec_delay(10);
++ msec_delay(20);
+
+- e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x0000);
+ e1000_write_phy_reg(hw,0x0000,0x0140);
+
+ msec_delay(5);
+- e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F95);
+- e1000_write_phy_reg(hw,0x0015,0x0001);
+
+- e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F71);
+- e1000_write_phy_reg(hw,0x0011,0xBD21);
++ if(hw->mac_type == e1000_82541 || hw->mac_type == e1000_82547) {
++ e1000_write_phy_reg(hw, 0x1F95, 0x0001);
++
++ e1000_write_phy_reg(hw, 0x1F71, 0xBD21);
+
+- e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F79);
+- e1000_write_phy_reg(hw,0x0019,0x0018);
++ e1000_write_phy_reg(hw, 0x1F79, 0x0018);
+
+- e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F30);
+- e1000_write_phy_reg(hw,0x0010,0x1600);
++ e1000_write_phy_reg(hw, 0x1F30, 0x1600);
+
+- e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F31);
+- e1000_write_phy_reg(hw,0x0011,0x0014);
++ e1000_write_phy_reg(hw, 0x1F31, 0x0014);
+
+- e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F32);
+- e1000_write_phy_reg(hw,0x0012,0x161C);
++ e1000_write_phy_reg(hw, 0x1F32, 0x161C);
+
+- e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F94);
+- e1000_write_phy_reg(hw,0x0014,0x0003);
++ e1000_write_phy_reg(hw, 0x1F94, 0x0003);
+
+- e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F96);
+- e1000_write_phy_reg(hw,0x0016,0x003F);
++ e1000_write_phy_reg(hw, 0x1F96, 0x003F);
+
+- e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x2010);
+- e1000_write_phy_reg(hw,0x0010,0x0008);
++ e1000_write_phy_reg(hw, 0x2010, 0x0008);
++ } else {
++ e1000_write_phy_reg(hw, 0x1F73, 0x0099);
++ }
+
+- e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x0000);
+- e1000_write_phy_reg(hw,0x0000,0x3300);
++ e1000_write_phy_reg(hw, 0x0000, 0x3300);
+
+
+ if(hw->mac_type == e1000_82547) {
+ uint16_t fused, fine, coarse;
+
+ /* Move to analog registers page */
+- e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT,
+- IGP01E1000_ANALOG_REGS_PAGE);
+-
+ e1000_read_phy_reg(hw, IGP01E1000_ANALOG_SPARE_FUSE_STATUS, &fused);
+
+ if(!(fused & IGP01E1000_ANALOG_SPARE_FUSE_ENABLED)) {
+@@ -158,17 +167,14 @@
+ } else if(coarse == IGP01E1000_ANALOG_FUSE_COARSE_THRESH)
+ fine -= IGP01E1000_ANALOG_FUSE_FINE_10;
+
+- fused = (fused & IGP01E1000_ANALOG_FUSE_POLY_MASK) |
+- (fine & IGP01E1000_ANALOG_FUSE_FINE_MASK) |
++ fused = (fused & IGP01E1000_ANALOG_FUSE_POLY_MASK) |
++ (fine & IGP01E1000_ANALOG_FUSE_FINE_MASK) |
+ (coarse & IGP01E1000_ANALOG_FUSE_COARSE_MASK);
+
+ e1000_write_phy_reg(hw, IGP01E1000_ANALOG_FUSE_CONTROL, fused);
+- e1000_write_phy_reg(hw, IGP01E1000_ANALOG_FUSE_BYPASS,
++ e1000_write_phy_reg(hw, IGP01E1000_ANALOG_FUSE_BYPASS,
+ IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL);
+ }
+- /* Return to first page of registers */
+- e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT,
+- IGP01E1000_IEEE_REGS_PAGE);
+ }
+ }
+ }
+@@ -218,32 +224,89 @@
+ case E1000_DEV_ID_82545EM_FIBER:
+ hw->mac_type = e1000_82545;
+ break;
++ case E1000_DEV_ID_82545GM_COPPER:
++ case E1000_DEV_ID_82545GM_FIBER:
++ case E1000_DEV_ID_82545GM_SERDES:
++ hw->mac_type = e1000_82545_rev_3;
++ break;
+ case E1000_DEV_ID_82546EB_COPPER:
+ case E1000_DEV_ID_82546EB_FIBER:
+ case E1000_DEV_ID_82546EB_QUAD_COPPER:
+ hw->mac_type = e1000_82546;
+ break;
++ case E1000_DEV_ID_82546GB_COPPER:
++ case E1000_DEV_ID_82546GB_FIBER:
++ case E1000_DEV_ID_82546GB_SERDES:
++ hw->mac_type = e1000_82546_rev_3;
++ break;
+ case E1000_DEV_ID_82541EI:
+- case E1000_DEV_ID_82541EP:
++ case E1000_DEV_ID_82541EI_MOBILE:
+ hw->mac_type = e1000_82541;
+ break;
++ case E1000_DEV_ID_82541ER:
++ case E1000_DEV_ID_82541GI:
++ case E1000_DEV_ID_82541GI_MOBILE:
++ hw->mac_type = e1000_82541_rev_2;
++ break;
+ case E1000_DEV_ID_82547EI:
+ hw->mac_type = e1000_82547;
+ break;
++ case E1000_DEV_ID_82547GI:
++ hw->mac_type = e1000_82547_rev_2;
++ break;
+ default:
+ /* Should never have loaded on this device */
+ return -E1000_ERR_MAC_TYPE;
+ }
+
+-
+ return E1000_SUCCESS;
+ }
++
++/*****************************************************************************
++ * Set media type and TBI compatibility.
++ *
++ * hw - Struct containing variables accessed by shared code
++ * **************************************************************************/
++void
++e1000_set_media_type(struct e1000_hw *hw)
++{
++ uint32_t status;
++
++ DEBUGFUNC("e1000_set_media_type");
++
++ if(hw->mac_type != e1000_82543) {
++ /* tbi_compatibility is only valid on 82543 */
++ hw->tbi_compatibility_en = FALSE;
++ }
++
++ switch (hw->device_id) {
++ case E1000_DEV_ID_82545GM_SERDES:
++ case E1000_DEV_ID_82546GB_SERDES:
++ hw->media_type = e1000_media_type_internal_serdes;
++ break;
++ default:
++ if(hw->mac_type >= e1000_82543) {
++ status = E1000_READ_REG(hw, STATUS);
++ if(status & E1000_STATUS_TBIMODE) {
++ hw->media_type = e1000_media_type_fiber;
++ /* tbi_compatibility not valid on fiber */
++ hw->tbi_compatibility_en = FALSE;
++ } else {
++ hw->media_type = e1000_media_type_copper;
++ }
++ } else {
++ /* This is an 82542 (fiber only) */
++ hw->media_type = e1000_media_type_fiber;
++ }
++ }
++}
++
+ /******************************************************************************
+ * Reset the transmit and receive units; mask and clear all interrupts.
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+-void
++int32_t
+ e1000_reset_hw(struct e1000_hw *hw)
+ {
+ uint32_t ctrl;
+@@ -280,49 +343,75 @@
+ */
+ msec_delay(10);
+
+- /* Issue a global reset to the MAC. This will reset the chip's
+- * transmit, receive, DMA, and link units. It will not effect
+- * the current PCI configuration. The global reset bit is self-
+- * clearing, and should clear within a microsecond.
+- */
+- DEBUGOUT("Issuing a global reset to MAC\n");
+ ctrl = E1000_READ_REG(hw, CTRL);
+
+ /* Must reset the PHY before resetting the MAC */
+ if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
+ E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_PHY_RST));
+- msec_delay(5);
++ msec_delay(5);
+ }
+
++ /* Issue a global reset to the MAC. This will reset the chip's
++ * transmit, receive, DMA, and link units. It will not effect
++ * the current PCI configuration. The global reset bit is self-
++ * clearing, and should clear within a microsecond.
++ */
++ DEBUGOUT("Issuing a global reset to MAC\n");
++
+ switch(hw->mac_type) {
+ case e1000_82544:
+ case e1000_82540:
+ case e1000_82545:
+ case e1000_82546:
+ case e1000_82541:
++ case e1000_82541_rev_2:
+ /* These controllers can't ack the 64-bit write when issuing the
+ * reset, so use IO-mapping as a workaround to issue the reset */
+ E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_RST));
+ break;
++ case e1000_82545_rev_3:
++ case e1000_82546_rev_3:
++ /* Reset is performed on a shadow of the control register */
++ E1000_WRITE_REG(hw, CTRL_DUP, (ctrl | E1000_CTRL_RST));
++ break;
+ default:
+ E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST));
+ break;
+ }
+
+- /* Force a reload from the EEPROM if necessary */
+- if(hw->mac_type < e1000_82540) {
+- /* Wait for reset to complete */
+- udelay(10);
+- ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+- ctrl_ext |= E1000_CTRL_EXT_EE_RST;
+- E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+- E1000_WRITE_FLUSH(hw);
+- /* Wait for EEPROM reload */
+- msec_delay(2);
+- } else {
+- /* Wait for EEPROM reload (it happens automatically) */
+- msec_delay(5);
+- /* Dissable HW ARPs on ASF enabled adapters */
++ /* After MAC reset, force reload of EEPROM to restore power-on settings to
++ * device. Later controllers reload the EEPROM automatically, so just wait
++ * for reload to complete.
++ */
++ switch(hw->mac_type) {
++ case e1000_82542_rev2_0:
++ case e1000_82542_rev2_1:
++ case e1000_82543:
++ case e1000_82544:
++ /* Wait for reset to complete */
++ udelay(10);
++ ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
++ ctrl_ext |= E1000_CTRL_EXT_EE_RST;
++ E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
++ E1000_WRITE_FLUSH(hw);
++ /* Wait for EEPROM reload */
++ msec_delay(2);
++ break;
++ case e1000_82541:
++ case e1000_82541_rev_2:
++ case e1000_82547:
++ case e1000_82547_rev_2:
++ /* Wait for EEPROM reload */
++ msec_delay(20);
++ break;
++ default:
++ /* Wait for EEPROM reload (it happens automatically) */
++ msec_delay(5);
++ break;
++ }
++
++ /* Disable HW ARPs on ASF enabled adapters */
++ if(hw->mac_type >= e1000_82540) {
+ manc = E1000_READ_REG(hw, MANC);
+ manc &= ~(E1000_MANC_ARP_EN);
+ E1000_WRITE_REG(hw, MANC, manc);
+@@ -350,6 +439,8 @@
+ if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
+ e1000_pci_set_mwi(hw);
+ }
++
++ return E1000_SUCCESS;
+ }
+
+ /******************************************************************************
+@@ -366,7 +457,7 @@
+ int32_t
+ e1000_init_hw(struct e1000_hw *hw)
+ {
+- uint32_t ctrl, status;
++ uint32_t ctrl;
+ uint32_t i;
+ int32_t ret_val;
+ uint16_t pcix_cmd_word;
+@@ -377,31 +468,13 @@
+ DEBUGFUNC("e1000_init_hw");
+
+ /* Initialize Identification LED */
+- ret_val = e1000_id_led_init(hw);
+- if(ret_val < 0) {
++ if((ret_val = e1000_id_led_init(hw))) {
+ DEBUGOUT("Error Initializing Identification LED\n");
+ return ret_val;
+ }
+
+- /* Set the Media Type and exit with error if it is not valid. */
+- if(hw->mac_type != e1000_82543) {
+- /* tbi_compatibility is only valid on 82543 */
+- hw->tbi_compatibility_en = FALSE;
+- }
+-
+- if(hw->mac_type >= e1000_82543) {
+- status = E1000_READ_REG(hw, STATUS);
+- if(status & E1000_STATUS_TBIMODE) {
+- hw->media_type = e1000_media_type_fiber;
+- /* tbi_compatibility not valid on fiber */
+- hw->tbi_compatibility_en = FALSE;
+- } else {
+- hw->media_type = e1000_media_type_copper;
+- }
+- } else {
+- /* This is an 82542 (fiber only) */
+- hw->media_type = e1000_media_type_fiber;
+- }
++ /* Set the media type and TBI compatibility */
++ e1000_set_media_type(hw);
+
+ /* Disabling VLAN filtering. */
+ DEBUGOUT("Initializing the IEEE VLAN\n");
+@@ -446,21 +519,30 @@
+ E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PRIOR);
+ }
+
+- /* Workaround for PCI-X problem when BIOS sets MMRBC incorrectly. */
+- if(hw->bus_type == e1000_bus_type_pcix) {
+- e1000_read_pci_cfg(hw, PCIX_COMMAND_REGISTER, &pcix_cmd_word);
+- e1000_read_pci_cfg(hw, PCIX_STATUS_REGISTER_HI, &pcix_stat_hi_word);
+- cmd_mmrbc = (pcix_cmd_word & PCIX_COMMAND_MMRBC_MASK) >>
+- PCIX_COMMAND_MMRBC_SHIFT;
+- stat_mmrbc = (pcix_stat_hi_word & PCIX_STATUS_HI_MMRBC_MASK) >>
+- PCIX_STATUS_HI_MMRBC_SHIFT;
+- if(stat_mmrbc == PCIX_STATUS_HI_MMRBC_4K)
+- stat_mmrbc = PCIX_STATUS_HI_MMRBC_2K;
+- if(cmd_mmrbc > stat_mmrbc) {
+- pcix_cmd_word &= ~PCIX_COMMAND_MMRBC_MASK;
+- pcix_cmd_word |= stat_mmrbc << PCIX_COMMAND_MMRBC_SHIFT;
+- e1000_write_pci_cfg(hw, PCIX_COMMAND_REGISTER, &pcix_cmd_word);
++ switch(hw->mac_type) {
++ case e1000_82545_rev_3:
++ case e1000_82546_rev_3:
++ break;
++ default:
++ /* Workaround for PCI-X problem when BIOS sets MMRBC incorrectly. */
++ if(hw->bus_type == e1000_bus_type_pcix) {
++ e1000_read_pci_cfg(hw, PCIX_COMMAND_REGISTER, &pcix_cmd_word);
++ e1000_read_pci_cfg(hw, PCIX_STATUS_REGISTER_HI,
++ &pcix_stat_hi_word);
++ cmd_mmrbc = (pcix_cmd_word & PCIX_COMMAND_MMRBC_MASK) >>
++ PCIX_COMMAND_MMRBC_SHIFT;
++ stat_mmrbc = (pcix_stat_hi_word & PCIX_STATUS_HI_MMRBC_MASK) >>
++ PCIX_STATUS_HI_MMRBC_SHIFT;
++ if(stat_mmrbc == PCIX_STATUS_HI_MMRBC_4K)
++ stat_mmrbc = PCIX_STATUS_HI_MMRBC_2K;
++ if(cmd_mmrbc > stat_mmrbc) {
++ pcix_cmd_word &= ~PCIX_COMMAND_MMRBC_MASK;
++ pcix_cmd_word |= stat_mmrbc << PCIX_COMMAND_MMRBC_SHIFT;
++ e1000_write_pci_cfg(hw, PCIX_COMMAND_REGISTER,
++ &pcix_cmd_word);
++ }
+ }
++ break;
+ }
+
+ /* Call a subroutine to configure the link and setup flow control. */
+@@ -484,6 +566,46 @@
+ }
+
+ /******************************************************************************
++ * Adjust SERDES output amplitude based on EEPROM setting.
++ *
++ * hw - Struct containing variables accessed by shared code.
++ *****************************************************************************/
++static int32_t
++e1000_adjust_serdes_amplitude(struct e1000_hw *hw)
++{
++ uint16_t eeprom_data;
++ int32_t ret_val;
++
++ DEBUGFUNC("e1000_adjust_serdes_amplitude");
++
++ if(hw->media_type != e1000_media_type_internal_serdes)
++ return E1000_SUCCESS;
++
++ switch(hw->mac_type) {
++ case e1000_82545_rev_3:
++ case e1000_82546_rev_3:
++ break;
++ default:
++ return E1000_SUCCESS;
++ }
++
++ if ((ret_val = e1000_read_eeprom(hw, EEPROM_SERDES_AMPLITUDE, 1,
++ &eeprom_data))) {
++ return ret_val;
++ }
++
++ if(eeprom_data != EEPROM_RESERVED_WORD) {
++ /* Adjust SERDES output amplitude only. */
++ eeprom_data &= EEPROM_SERDES_AMPLITUDE_MASK;
++ if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_EXT_CTRL,
++ eeprom_data)))
++ return ret_val;
++ }
++
++ return E1000_SUCCESS;
++}
++
++/******************************************************************************
+ * Configures flow control and link settings.
+ *
+ * hw - Struct containing variables accessed by shared code
+@@ -554,9 +676,9 @@
+ }
+
+ /* Call the necessary subroutine to configure the link. */
+- ret_val = (hw->media_type == e1000_media_type_fiber) ?
+- e1000_setup_fiber_link(hw) :
+- e1000_setup_copper_link(hw);
++ ret_val = (hw->media_type == e1000_media_type_copper) ?
++ e1000_setup_copper_link(hw) :
++ e1000_setup_fiber_serdes_link(hw);
+
+ /* Initialize the flow control address, type, and PAUSE timer
+ * registers to their default values. This is done even if flow
+@@ -595,7 +717,7 @@
+ }
+
+ /******************************************************************************
+- * Sets up link for a fiber based adapter
++ * Sets up link for a fiber based or serdes based adapter
+ *
+ * hw - Struct containing variables accessed by shared code
+ *
+@@ -604,28 +726,37 @@
+ * and receiver are not enabled.
+ *****************************************************************************/
+ static int32_t
+-e1000_setup_fiber_link(struct e1000_hw *hw)
++e1000_setup_fiber_serdes_link(struct e1000_hw *hw)
+ {
+ uint32_t ctrl;
+ uint32_t status;
+ uint32_t txcw = 0;
+ uint32_t i;
+- uint32_t signal;
++ uint32_t signal = 0;
+ int32_t ret_val;
+
+- DEBUGFUNC("e1000_setup_fiber_link");
++ DEBUGFUNC("e1000_setup_fiber_serdes_link");
+
+- /* On adapters with a MAC newer that 82544, SW Defineable pin 1 will be
++ /* On adapters with a MAC newer than 82544, SW Defineable pin 1 will be
+ * set when the optics detect a signal. On older adapters, it will be
+- * cleared when there is a signal
++ * cleared when there is a signal. This applies to fiber media only.
++ * If we're on serdes media, adjust the output amplitude to value set in
++ * the EEPROM.
+ */
+ ctrl = E1000_READ_REG(hw, CTRL);
+- if(hw->mac_type > e1000_82544) signal = E1000_CTRL_SWDPIN1;
+- else signal = 0;
++ if(hw->media_type == e1000_media_type_fiber)
++ signal = (hw->mac_type > e1000_82544) ? E1000_CTRL_SWDPIN1 : 0;
++
++ if((ret_val = e1000_adjust_serdes_amplitude(hw)))
++ return ret_val;
+
+ /* Take the link out of reset */
+ ctrl &= ~(E1000_CTRL_LRST);
+
++ /* Adjust VCO speed to improve BER performance */
++ if((ret_val = e1000_set_vco_speed(hw)))
++ return ret_val;
++
+ e1000_config_collision_dist(hw);
+
+ /* Check for a software override of the flow control settings, and setup
+@@ -692,8 +823,10 @@
+ * indication in the Device Status Register. Time-out if a link isn't
+ * seen in 500 milliseconds seconds (Auto-negotiation should complete in
+ * less than 500 milliseconds even if the other end is doing it in SW).
++ * For internal serdes, we just assume a signal is present, then poll.
+ */
+- if((E1000_READ_REG(hw, CTRL) & E1000_CTRL_SWDPIN1) == signal) {
++ if(hw->media_type == e1000_media_type_internal_serdes ||
++ (E1000_READ_REG(hw, CTRL) & E1000_CTRL_SWDPIN1) == signal) {
+ DEBUGOUT("Looking for Link\n");
+ for(i = 0; i < (LINK_UP_TIMEOUT / 10); i++) {
+ msec_delay(10);
+@@ -701,19 +834,20 @@
+ if(status & E1000_STATUS_LU) break;
+ }
+ if(i == (LINK_UP_TIMEOUT / 10)) {
+- /* AutoNeg failed to achieve a link, so we'll call
+- * e1000_check_for_link. This routine will force the link up if we
+- * detect a signal. This will allow us to communicate with
+- * non-autonegotiating link partners.
+- */
+ DEBUGOUT("Never got a valid link from auto-neg!!!\n");
+ hw->autoneg_failed = 1;
+- ret_val = e1000_check_for_link(hw);
+- if(ret_val < 0) {
+- DEBUGOUT("Error while checking for link\n");
+- return ret_val;
++ if(hw->media_type == e1000_media_type_fiber) {
++ /* AutoNeg failed to achieve a link, so we'll call
++ * e1000_check_for_link. This routine will force the link up if
++ * we detect a signal. This will allow us to communicate with
++ * non-autonegotiating link partners.
++ */
++ if((ret_val = e1000_check_for_link(hw))) {
++ DEBUGOUT("Error while checking for link\n");
++ return ret_val;
++ }
++ hw->autoneg_failed = 0;
+ }
+- hw->autoneg_failed = 0;
+ } else {
+ hw->autoneg_failed = 0;
+ DEBUGOUT("Valid Link Found\n");
+@@ -721,7 +855,7 @@
+ } else {
+ DEBUGOUT("No Signal Detected\n");
+ }
+- return 0;
++ return E1000_SUCCESS;
+ }
+
+ /******************************************************************************
+@@ -756,233 +890,281 @@
+ }
+
+ /* Make sure we have a valid PHY */
+- ret_val = e1000_detect_gig_phy(hw);
+- if(ret_val < 0) {
++ if((ret_val = e1000_detect_gig_phy(hw))) {
+ DEBUGOUT("Error, did not detect valid phy.\n");
+ return ret_val;
+ }
+ DEBUGOUT1("Phy ID = %x \n", hw->phy_id);
+
+- if (hw->phy_type == e1000_phy_igp) {
+-
+- ret_val = e1000_phy_reset(hw);
+- if(ret_val < 0) {
+- DEBUGOUT("Error Resetting the PHY\n");
+- return ret_val;
+- }
++ if(hw->mac_type <= e1000_82543 ||
++ hw->mac_type == e1000_82541 || hw->mac_type == e1000_82547 ||
++ hw->mac_type == e1000_82541_rev_2 || hw->mac_type == e1000_82547_rev_2)
++ hw->phy_reset_disable = FALSE;
+
+- /* Wait 10ms for MAC to configure PHY from eeprom settings */
+- msec_delay(15);
++ if(!hw->phy_reset_disable) {
++ if (hw->phy_type == e1000_phy_igp) {
+
+- if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 0x0000) < 0) {
+- DEBUGOUT("PHY Write Error\n");
+- return -E1000_ERR_PHY;
+- }
++ if((ret_val = e1000_phy_reset(hw))) {
++ DEBUGOUT("Error Resetting the PHY\n");
++ return ret_val;
++ }
+
+- /* Configure activity LED after PHY reset */
+- led_ctrl = E1000_READ_REG(hw, LEDCTL);
+- led_ctrl &= IGP_ACTIVITY_LED_MASK;
+- led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
+- E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
++ /* Wait 10ms for MAC to configure PHY from eeprom settings */
++ msec_delay(15);
+
+- if(hw->autoneg_advertised == ADVERTISE_1000_FULL) {
+- /* Disable SmartSpeed */
+- if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
+- &phy_data) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
+- }
+- phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
+- if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
+- phy_data) < 0) {
+- DEBUGOUT("PHY Write Error\n");
+- return -E1000_ERR_PHY;
+- }
+- /* Set auto Master/Slave resolution process */
+- if(e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
++ /* Configure activity LED after PHY reset */
++ led_ctrl = E1000_READ_REG(hw, LEDCTL);
++ led_ctrl &= IGP_ACTIVITY_LED_MASK;
++ led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
++ E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
++
++ /* disable lplu d3 during driver init */
++ if((ret_val = e1000_set_d3_lplu_state(hw, FALSE))) {
++ DEBUGOUT("Error Disabling LPLU D3\n");
++ return ret_val;
+ }
+- phy_data &= ~CR_1000T_MS_ENABLE;
+- if(e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data) < 0) {
+- DEBUGOUT("PHY Write Error\n");
+- return -E1000_ERR_PHY;
++
++ /* Configure mdi-mdix settings */
++ if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL,
++ &phy_data)))
++ return ret_val;
++
++ if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
++ hw->dsp_config_state = e1000_dsp_config_disabled;
++ /* Force MDI for IGP B-0 PHY */
++ phy_data &= ~(IGP01E1000_PSCR_AUTO_MDIX |
++ IGP01E1000_PSCR_FORCE_MDI_MDIX);
++ hw->mdix = 1;
++
++ } else {
++ hw->dsp_config_state = e1000_dsp_config_enabled;
++ phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
++
++ switch (hw->mdix) {
++ case 1:
++ phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
++ break;
++ case 2:
++ phy_data |= IGP01E1000_PSCR_FORCE_MDI_MDIX;
++ break;
++ case 0:
++ default:
++ phy_data |= IGP01E1000_PSCR_AUTO_MDIX;
++ break;
++ }
+ }
+- }
++ if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL,
++ phy_data)))
++ return ret_val;
+
+- if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
+- }
++ /* set auto-master slave resolution settings */
++ if(hw->autoneg) {
++ e1000_ms_type phy_ms_setting = hw->master_slave;
++
++ if(hw->ffe_config_state == e1000_ffe_config_active)
++ hw->ffe_config_state = e1000_ffe_config_enabled;
++
++ if(hw->dsp_config_state == e1000_dsp_config_activated)
++ hw->dsp_config_state = e1000_dsp_config_enabled;
++
++ /* when autonegotiation advertisment is only 1000Mbps then we
++ * should disable SmartSpeed and enable Auto MasterSlave
++ * resolution as hardware default. */
++ if(hw->autoneg_advertised == ADVERTISE_1000_FULL) {
++ /* Disable SmartSpeed */
++ if((ret_val = e1000_read_phy_reg(hw,
++ IGP01E1000_PHY_PORT_CONFIG,
++ &phy_data)))
++ return ret_val;
++ phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
++ if((ret_val = e1000_write_phy_reg(hw,
++ IGP01E1000_PHY_PORT_CONFIG,
++ phy_data)))
++ return ret_val;
++ /* Set auto Master/Slave resolution process */
++ if((ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL,
++ &phy_data)))
++ return ret_val;
++ phy_data &= ~CR_1000T_MS_ENABLE;
++ if((ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL,
++ phy_data)))
++ return ret_val;
++ }
+
+- /* Force MDI for IGP PHY */
+- phy_data &= ~(IGP01E1000_PSCR_AUTO_MDIX |
+- IGP01E1000_PSCR_FORCE_MDI_MDIX);
++ if((ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL,
++ &phy_data)))
++ return ret_val;
+
+- hw->mdix = 1;
++ /* load defaults for future use */
++ hw->original_master_slave = (phy_data & CR_1000T_MS_ENABLE) ?
++ ((phy_data & CR_1000T_MS_VALUE) ?
++ e1000_ms_force_master :
++ e1000_ms_force_slave) :
++ e1000_ms_auto;
++
++ switch (phy_ms_setting) {
++ case e1000_ms_force_master:
++ phy_data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE);
++ break;
++ case e1000_ms_force_slave:
++ phy_data |= CR_1000T_MS_ENABLE;
++ phy_data &= ~(CR_1000T_MS_VALUE);
++ break;
++ case e1000_ms_auto:
++ phy_data &= ~CR_1000T_MS_ENABLE;
++ default:
++ break;
++ }
++ if((ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL,
++ phy_data)))
++ return ret_val;
++ }
++ } else {
++ /* Enable CRS on TX. This must be set for half-duplex operation. */
++ if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
++ &phy_data)))
++ return ret_val;
+
+- if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data) < 0) {
+- DEBUGOUT("PHY Write Error\n");
+- return -E1000_ERR_PHY;
+- }
++ phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
+
+- } else {
+- /* Enable CRS on TX. This must be set for half-duplex operation. */
+- if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
+- }
+- phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
++ /* Options:
++ * MDI/MDI-X = 0 (default)
++ * 0 - Auto for all speeds
++ * 1 - MDI mode
++ * 2 - MDI-X mode
++ * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
++ */
++ phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
+
+- /* Options:
+- * MDI/MDI-X = 0 (default)
+- * 0 - Auto for all speeds
+- * 1 - MDI mode
+- * 2 - MDI-X mode
+- * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
+- */
+- phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
++ switch (hw->mdix) {
++ case 1:
++ phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
++ break;
++ case 2:
++ phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
++ break;
++ case 3:
++ phy_data |= M88E1000_PSCR_AUTO_X_1000T;
++ break;
++ case 0:
++ default:
++ phy_data |= M88E1000_PSCR_AUTO_X_MODE;
++ break;
++ }
+
+- switch (hw->mdix) {
+- case 1:
+- phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
+- break;
+- case 2:
+- phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
+- break;
+- case 3:
+- phy_data |= M88E1000_PSCR_AUTO_X_1000T;
+- break;
+- case 0:
+- default:
+- phy_data |= M88E1000_PSCR_AUTO_X_MODE;
+- break;
+- }
++ /* Options:
++ * disable_polarity_correction = 0 (default)
++ * Automatic Correction for Reversed Cable Polarity
++ * 0 - Disabled
++ * 1 - Enabled
++ */
++ phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
++ if(hw->disable_polarity_correction == 1)
++ phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
++ if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
++ phy_data)))
++ return ret_val;
+
+- /* Options:
+- * disable_polarity_correction = 0 (default)
+- * Automatic Correction for Reversed Cable Polarity
+- * 0 - Disabled
+- * 1 - Enabled
+- */
+- phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
+- if(hw->disable_polarity_correction == 1)
+- phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
+- if(e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data) < 0) {
+- DEBUGOUT("PHY Write Error\n");
+- return -E1000_ERR_PHY;
+- }
++ /* Force TX_CLK in the Extended PHY Specific Control Register
++ * to 25MHz clock.
++ */
++ if((ret_val = e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
++ &phy_data)))
++ return ret_val;
+
+- /* Force TX_CLK in the Extended PHY Specific Control Register
+- * to 25MHz clock.
+- */
+- if(e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
+- }
+- phy_data |= M88E1000_EPSCR_TX_CLK_25;
++ phy_data |= M88E1000_EPSCR_TX_CLK_25;
+
+- if (hw->phy_revision < M88E1011_I_REV_4) {
+- /* Configure Master and Slave downshift values */
+- phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
+- M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
+- phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
+- M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
+- if(e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
+- phy_data) < 0) {
+- DEBUGOUT("PHY Write Error\n");
+- return -E1000_ERR_PHY;
++ if (hw->phy_revision < M88E1011_I_REV_4) {
++ /* Configure Master and Slave downshift values */
++ phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
++ M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
++ phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
++ M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
++ if((ret_val = e1000_write_phy_reg(hw,
++ M88E1000_EXT_PHY_SPEC_CTRL,
++ phy_data)))
++ return ret_val;
+ }
+- }
+
+- /* SW Reset the PHY so all changes take effect */
+- ret_val = e1000_phy_reset(hw);
+- if(ret_val < 0) {
+- DEBUGOUT("Error Resetting the PHY\n");
+- return ret_val;
++ /* SW Reset the PHY so all changes take effect */
++ if((ret_val = e1000_phy_reset(hw))) {
++ DEBUGOUT("Error Resetting the PHY\n");
++ return ret_val;
++ }
+ }
+- }
+
+- /* Options:
+- * autoneg = 1 (default)
+- * PHY will advertise value(s) parsed from
+- * autoneg_advertised and fc
+- * autoneg = 0
+- * PHY will be set to 10H, 10F, 100H, or 100F
+- * depending on value parsed from forced_speed_duplex.
+- */
++ /* Options:
++ * autoneg = 1 (default)
++ * PHY will advertise value(s) parsed from
++ * autoneg_advertised and fc
++ * autoneg = 0
++ * PHY will be set to 10H, 10F, 100H, or 100F
++ * depending on value parsed from forced_speed_duplex.
++ */
++
++ /* Is autoneg enabled? This is enabled by default or by software
++ * override. If so, call e1000_phy_setup_autoneg routine to parse the
++ * autoneg_advertised and fc options. If autoneg is NOT enabled, then
++ * the user should have provided a speed/duplex override. If so, then
++ * call e1000_phy_force_speed_duplex to parse and set this up.
++ */
++ if(hw->autoneg) {
++ /* Perform some bounds checking on the hw->autoneg_advertised
++ * parameter. If this variable is zero, then set it to the default.
++ */
++ hw->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT;
+
+- /* Is autoneg enabled? This is enabled by default or by software override.
+- * If so, call e1000_phy_setup_autoneg routine to parse the
+- * autoneg_advertised and fc options. If autoneg is NOT enabled, then the
+- * user should have provided a speed/duplex override. If so, then call
+- * e1000_phy_force_speed_duplex to parse and set this up.
+- */
+- if(hw->autoneg) {
+- /* Perform some bounds checking on the hw->autoneg_advertised
+- * parameter. If this variable is zero, then set it to the default.
+- */
+- hw->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT;
++ /* If autoneg_advertised is zero, we assume it was not defaulted
++ * by the calling code so we set to advertise full capability.
++ */
++ if(hw->autoneg_advertised == 0)
++ hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT;
+
+- /* If autoneg_advertised is zero, we assume it was not defaulted
+- * by the calling code so we set to advertise full capability.
+- */
+- if(hw->autoneg_advertised == 0)
+- hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT;
++ DEBUGOUT("Reconfiguring auto-neg advertisement params\n");
++ if((ret_val = e1000_phy_setup_autoneg(hw))) {
++ DEBUGOUT("Error Setting up Auto-Negotiation\n");
++ return ret_val;
++ }
++ DEBUGOUT("Restarting Auto-Neg\n");
+
+- DEBUGOUT("Reconfiguring auto-neg advertisement params\n");
+- ret_val = e1000_phy_setup_autoneg(hw);
+- if(ret_val < 0) {
+- DEBUGOUT("Error Setting up Auto-Negotiation\n");
+- return ret_val;
+- }
+- DEBUGOUT("Restarting Auto-Neg\n");
++ /* Restart auto-negotiation by setting the Auto Neg Enable bit and
++ * the Auto Neg Restart bit in the PHY control register.
++ */
++ if((ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data)))
++ return ret_val;
+
+- /* Restart auto-negotiation by setting the Auto Neg Enable bit and
+- * the Auto Neg Restart bit in the PHY control register.
+- */
+- if(e1000_read_phy_reg(hw, PHY_CTRL, &phy_data) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
+- }
+- phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
+- if(e1000_write_phy_reg(hw, PHY_CTRL, phy_data) < 0) {
+- DEBUGOUT("PHY Write Error\n");
+- return -E1000_ERR_PHY;
+- }
++ phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
++ if((ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data)))
++ return ret_val;
+
+- /* Does the user want to wait for Auto-Neg to complete here, or
+- * check at a later time (for example, callback routine).
+- */
+- if(hw->wait_autoneg_complete) {
+- ret_val = e1000_wait_autoneg(hw);
+- if(ret_val < 0) {
+- DEBUGOUT("Error while waiting for autoneg to complete\n");
++ /* Does the user want to wait for Auto-Neg to complete here, or
++ * check at a later time (for example, callback routine).
++ */
++ if(hw->wait_autoneg_complete) {
++ if((ret_val = e1000_wait_autoneg(hw))) {
++ DEBUGOUT("Error while waiting for autoneg to complete\n");
++ return ret_val;
++ }
++ }
++ hw->get_link_status = TRUE;
++ } else {
++ DEBUGOUT("Forcing speed and duplex\n");
++ if((ret_val = e1000_phy_force_speed_duplex(hw))) {
++ DEBUGOUT("Error Forcing Speed and Duplex\n");
+ return ret_val;
+ }
+ }
+- hw->get_link_status = TRUE;
+- } else {
+- DEBUGOUT("Forcing speed and duplex\n");
+- ret_val = e1000_phy_force_speed_duplex(hw);
+- if(ret_val < 0) {
+- DEBUGOUT("Error Forcing Speed and Duplex\n");
+- return ret_val;
+- }
+- }
++ } /* !hw->phy_reset_disable */
+
+ /* Check link status. Wait up to 100 microseconds for link to become
+ * valid.
+ */
+ for(i = 0; i < 10; i++) {
+- if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
+- }
+- if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
+- }
++ if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
++ return ret_val;
++ if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
++ return ret_val;
++
+ if(phy_data & MII_SR_LINK_STATUS) {
+ /* We have link, so we need to finish the config process:
+ * 1) Set up the MAC to the current PHY speed/duplex
+@@ -995,25 +1177,31 @@
+ if(hw->mac_type >= e1000_82544) {
+ e1000_config_collision_dist(hw);
+ } else {
+- ret_val = e1000_config_mac_to_phy(hw);
+- if(ret_val < 0) {
++ if((ret_val = e1000_config_mac_to_phy(hw))) {
+ DEBUGOUT("Error configuring MAC to PHY settings\n");
+ return ret_val;
+- }
++ }
+ }
+- ret_val = e1000_config_fc_after_link_up(hw);
+- if(ret_val < 0) {
++ if((ret_val = e1000_config_fc_after_link_up(hw))) {
+ DEBUGOUT("Error Configuring Flow Control\n");
+ return ret_val;
+ }
+ DEBUGOUT("Valid link established!!!\n");
+- return 0;
++
++ if(hw->phy_type == e1000_phy_igp) {
++ if((ret_val = e1000_config_dsp_after_link_change(hw, TRUE))) {
++ DEBUGOUT("Error Configuring DSP after link up\n");
++ return ret_val;
++ }
++ }
++ DEBUGOUT("Valid link established!!!\n");
++ return E1000_SUCCESS;
+ }
+ udelay(10);
+ }
+
+ DEBUGOUT("Unable to establish link!!!\n");
+- return 0;
++ return E1000_SUCCESS;
+ }
+
+ /******************************************************************************
+@@ -1024,22 +1212,20 @@
+ int32_t
+ e1000_phy_setup_autoneg(struct e1000_hw *hw)
+ {
++ int32_t ret_val;
+ uint16_t mii_autoneg_adv_reg;
+ uint16_t mii_1000t_ctrl_reg;
+
+ DEBUGFUNC("e1000_phy_setup_autoneg");
+
+ /* Read the MII Auto-Neg Advertisement Register (Address 4). */
+- if(e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
+- }
++ if((ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV,
++ &mii_autoneg_adv_reg)))
++ return ret_val;
+
+ /* Read the MII 1000Base-T Control Register (Address 9). */
+- if(e1000_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
+- }
++ if((ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg)))
++ return ret_val;
+
+ /* Need to parse both autoneg_advertised and fc and set up
+ * the appropriate PHY registers. First we will parse for
+@@ -1145,18 +1331,16 @@
+ return -E1000_ERR_CONFIG;
+ }
+
+- if(e1000_write_phy_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg) < 0) {
+- DEBUGOUT("PHY Write Error\n");
+- return -E1000_ERR_PHY;
+- }
++ if((ret_val = e1000_write_phy_reg(hw, PHY_AUTONEG_ADV,
++ mii_autoneg_adv_reg)))
++ return ret_val;
+
+ DEBUGOUT1("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
+
+- if(e1000_write_phy_reg(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg) < 0) {
+- DEBUGOUT("PHY Write Error\n");
+- return -E1000_ERR_PHY;
+- }
+- return 0;
++ if((ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg)))
++ return ret_val;
++
++ return E1000_SUCCESS;
+ }
+
+ /******************************************************************************
+@@ -1192,10 +1376,8 @@
+ ctrl &= ~E1000_CTRL_ASDE;
+
+ /* Read the MII Control Register. */
+- if(e1000_read_phy_reg(hw, PHY_CTRL, &mii_ctrl_reg) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
+- }
++ if((ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &mii_ctrl_reg)))
++ return ret_val;
+
+ /* We need to disable autoneg in order to force link and duplex. */
+
+@@ -1241,19 +1423,18 @@
+ E1000_WRITE_REG(hw, CTRL, ctrl);
+
+ if (hw->phy_type == e1000_phy_m88) {
+- if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
+- }
++ if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
++ &phy_data)))
++ return ret_val;
+
+ /* Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI
+ * forced whenever speed are duplex are forced.
+ */
+ phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
+- if(e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data) < 0) {
+- DEBUGOUT("PHY Write Error\n");
+- return -E1000_ERR_PHY;
+- }
++ if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
++ phy_data)))
++ return ret_val;
++
+ DEBUGOUT1("M88E1000 PSCR: %x \n", phy_data);
+
+ /* Need to reset the PHY or these changes will be ignored */
+@@ -1262,26 +1443,23 @@
+ /* Clear Auto-Crossover to force MDI manually. IGP requires MDI
+ * forced whenever speed or duplex are forced.
+ */
+- if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
+- }
++ if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL,
++ &phy_data)))
++ return ret_val;
+
+ phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
+ phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
+
+- if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data) < 0) {
+- DEBUGOUT("PHY Write Error\n");
+- return -E1000_ERR_PHY;
+- }
++ if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL,
++ phy_data)))
++ return ret_val;
+ }
+
+ /* Write back the modified PHY MII control register. */
+- if(e1000_write_phy_reg(hw, PHY_CTRL, mii_ctrl_reg) < 0) {
+- DEBUGOUT("PHY Write Error\n");
+- return -E1000_ERR_PHY;
+- }
+ udelay(1);
++ if((ret_val = e1000_write_phy_reg(hw, PHY_CTRL, mii_ctrl_reg)))
++ return ret_val;
++
+
+ /* The wait_autoneg_complete flag may be a little misleading here.
+ * Since we are forcing speed and duplex, Auto-Neg is not enabled.
+@@ -1300,22 +1478,18 @@
+ /* Read the MII Status Register and wait for Auto-Neg Complete bit
+ * to be set.
+ */
+- if(e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
+- }
+- if(e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
+- }
++ if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg)))
++ return ret_val;
++
++ if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg)))
++ return ret_val;
++
+ if(mii_status_reg & MII_SR_LINK_STATUS) break;
+ msec_delay(100);
+ }
+ if(i == 0) { /* We didn't get link */
+ /* Reset the DSP and wait again for link. */
+-
+- ret_val = e1000_phy_reset_dsp(hw);
+- if(ret_val < 0) {
++ if((ret_val = e1000_phy_reset_dsp(hw))) {
+ DEBUGOUT("Error Resetting PHY DSP\n");
+ return ret_val;
+ }
+@@ -1327,14 +1501,11 @@
+ /* Read the MII Status Register and wait for Auto-Neg Complete bit
+ * to be set.
+ */
+- if(e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
+- }
+- if(e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
+- }
++ if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg)))
++ return ret_val;
++
++ if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg)))
++ return ret_val;
+ }
+ }
+
+@@ -1343,30 +1514,29 @@
+ * Extended PHY Specific Control Register to 25MHz clock. This value
+ * defaults back to a 2.5MHz clock when the PHY is reset.
+ */
+- if(e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
+- }
++ if((ret_val = e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
++ &phy_data)))
++ return ret_val;
++
+ phy_data |= M88E1000_EPSCR_TX_CLK_25;
+- if(e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data) < 0) {
+- DEBUGOUT("PHY Write Error\n");
+- return -E1000_ERR_PHY;
+- }
++ if((ret_val = e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
++ phy_data)))
++ return ret_val;
+
+ /* In addition, because of the s/w reset above, we need to enable CRS on
+ * TX. This must be set for both full and half duplex operation.
+ */
+- if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
+- }
++ if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
++ &phy_data)))
++ return ret_val;
++
+ phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
+- if(e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data) < 0) {
+- DEBUGOUT("PHY Write Error\n");
+- return -E1000_ERR_PHY;
+- }
++ if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
++ phy_data)))
++ return ret_val;
++
+ }
+- return 0;
++ return E1000_SUCCESS;
+ }
+
+ /******************************************************************************
+@@ -1406,6 +1576,7 @@
+ e1000_config_mac_to_phy(struct e1000_hw *hw)
+ {
+ uint32_t ctrl;
++ int32_t ret_val;
+ uint16_t phy_data;
+
+ DEBUGFUNC("e1000_config_mac_to_phy");
+@@ -1421,10 +1592,10 @@
+ * registers depending on negotiated values.
+ */
+ if (hw->phy_type == e1000_phy_igp) {
+- if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &phy_data) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
+- }
++ if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
++ &phy_data)))
++ return ret_val;
++
+ if(phy_data & IGP01E1000_PSSR_FULL_DUPLEX) ctrl |= E1000_CTRL_FD;
+ else ctrl &= ~E1000_CTRL_FD;
+
+@@ -1440,10 +1611,10 @@
+ IGP01E1000_PSSR_SPEED_100MBPS)
+ ctrl |= E1000_CTRL_SPD_100;
+ } else {
+- if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
+- }
++ if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
++ &phy_data)))
++ return ret_val;
++
+ if(phy_data & M88E1000_PSSR_DPLX) ctrl |= E1000_CTRL_FD;
+ else ctrl &= ~E1000_CTRL_FD;
+
+@@ -1459,7 +1630,7 @@
+ }
+ /* Write the configured values back to the Device Control Reg. */
+ E1000_WRITE_REG(hw, CTRL, ctrl);
+- return 0;
++ return E1000_SUCCESS;
+ }
+
+ /******************************************************************************
+@@ -1473,7 +1644,7 @@
+ * by the PHY rather than the MAC. Software must also configure these
+ * bits when link is forced on a fiber connection.
+ *****************************************************************************/
+-static int32_t
++int32_t
+ e1000_force_mac_fc(struct e1000_hw *hw)
+ {
+ uint32_t ctrl;
+@@ -1526,7 +1697,7 @@
+ ctrl &= (~E1000_CTRL_TFCE);
+
+ E1000_WRITE_REG(hw, CTRL, ctrl);
+- return 0;
++ return E1000_SUCCESS;
+ }
+
+ /******************************************************************************
+@@ -1557,9 +1728,9 @@
+ * configuration of the MAC to match the "fc" parameter.
+ */
+ if(((hw->media_type == e1000_media_type_fiber) && (hw->autoneg_failed)) ||
++ ((hw->media_type == e1000_media_type_internal_serdes) && (hw->autoneg_failed)) ||
+ ((hw->media_type == e1000_media_type_copper) && (!hw->autoneg))) {
+- ret_val = e1000_force_mac_fc(hw);
+- if(ret_val < 0) {
++ if((ret_val = e1000_force_mac_fc(hw))) {
+ DEBUGOUT("Error forcing flow control settings\n");
+ return ret_val;
+ }
+@@ -1575,14 +1746,10 @@
+ * has completed. We read this twice because this reg has
+ * some "sticky" (latched) bits.
+ */
+- if(e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) {
+- DEBUGOUT("PHY Read Error \n");
+- return -E1000_ERR_PHY;
+- }
+- if(e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) {
+- DEBUGOUT("PHY Read Error \n");
+- return -E1000_ERR_PHY;
+- }
++ if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg)))
++ return ret_val;
++ if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg)))
++ return ret_val;
+
+ if(mii_status_reg & MII_SR_AUTONEG_COMPLETE) {
+ /* The AutoNeg process has completed, so we now need to
+@@ -1591,14 +1758,12 @@
+ * Register (Address 5) to determine how flow control was
+ * negotiated.
+ */
+- if(e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_nway_adv_reg) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
+- }
+- if(e1000_read_phy_reg(hw, PHY_LP_ABILITY, &mii_nway_lp_ability_reg) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
+- }
++ if((ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV,
++ &mii_nway_adv_reg)))
++ return ret_val;
++ if((ret_val = e1000_read_phy_reg(hw, PHY_LP_ABILITY,
++ &mii_nway_lp_ability_reg)))
++ return ret_val;
+
+ /* Two bits in the Auto Negotiation Advertisement Register
+ * (Address 4) and two bits in the Auto Negotiation Base
+@@ -1704,7 +1869,7 @@
+ hw->original_fc == e1000_fc_tx_pause) {
+ hw->fc = e1000_fc_none;
+ DEBUGOUT("Flow Control = NONE.\r\n");
+- } else {
++ } else if(!hw->fc_strict_ieee) {
+ hw->fc = e1000_fc_rx_pause;
+ DEBUGOUT("Flow Control = RX PAUSE frames only.\r\n");
+ }
+@@ -1713,7 +1878,10 @@
+ * negotiated to HALF DUPLEX, flow control should not be
+ * enabled per IEEE 802.3 spec.
+ */
+- e1000_get_speed_and_duplex(hw, &speed, &duplex);
++ if((ret_val = e1000_get_speed_and_duplex(hw, &speed, &duplex))) {
++ DEBUGOUT("Error getting link speed and duplex\n");
++ return ret_val;
++ }
+
+ if(duplex == HALF_DUPLEX)
+ hw->fc = e1000_fc_none;
+@@ -1721,16 +1889,15 @@
+ /* Now we call a subroutine to actually force the MAC
+ * controller to use the correct flow control settings.
+ */
+- ret_val = e1000_force_mac_fc(hw);
+- if(ret_val < 0) {
++ if((ret_val = e1000_force_mac_fc(hw))) {
+ DEBUGOUT("Error forcing flow control settings\n");
+ return ret_val;
+- }
++ }
+ } else {
+ DEBUGOUT("Copper PHY and Auto Neg has not completed.\r\n");
+ }
+ }
+- return 0;
++ return E1000_SUCCESS;
+ }
+
+ /******************************************************************************
+@@ -1747,19 +1914,19 @@
+ uint32_t ctrl;
+ uint32_t status;
+ uint32_t rctl;
+- uint32_t signal;
++ uint32_t signal = 0;
+ int32_t ret_val;
+ uint16_t phy_data;
+ uint16_t lp_capability;
+
+ DEBUGFUNC("e1000_check_for_link");
+
+- /* On adapters with a MAC newer that 82544, SW Defineable pin 1 will be
++ /* On adapters with a MAC newer than 82544, SW Defineable pin 1 will be
+ * set when the optics detect a signal. On older adapters, it will be
+- * cleared when there is a signal
++ * cleared when there is a signal. This applies to fiber media only.
+ */
+- if(hw->mac_type > e1000_82544) signal = E1000_CTRL_SWDPIN1;
+- else signal = 0;
++ if(hw->media_type == e1000_media_type_fiber)
++ signal = (hw->mac_type > e1000_82544) ? E1000_CTRL_SWDPIN1 : 0;
+
+ ctrl = E1000_READ_REG(hw, CTRL);
+ status = E1000_READ_REG(hw, STATUS);
+@@ -1777,14 +1944,10 @@
+ * of the PHY.
+ * Read the register twice since the link bit is sticky.
+ */
+- if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
+- }
+- if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
+- }
++ if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
++ return ret_val;
++ if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
++ return ret_val;
+
+ if(phy_data & MII_SR_LINK_STATUS) {
+ hw->get_link_status = FALSE;
+@@ -1794,6 +1957,7 @@
+
+ } else {
+ /* No link detected */
++ e1000_config_dsp_after_link_change(hw, FALSE);
+ return 0;
+ }
+
+@@ -1802,6 +1966,9 @@
+ */
+ if(!hw->autoneg) return -E1000_ERR_CONFIG;
+
++ /* optimize the dsp settings for the igp phy */
++ e1000_config_dsp_after_link_change(hw, TRUE);
++
+ /* We have a M88E1000 PHY and Auto-Neg is enabled. If we
+ * have Si on board that is 82544 or newer, Auto
+ * Speed Detection takes care of MAC speed/duplex
+@@ -1813,8 +1980,7 @@
+ if(hw->mac_type >= e1000_82544)
+ e1000_config_collision_dist(hw);
+ else {
+- ret_val = e1000_config_mac_to_phy(hw);
+- if(ret_val < 0) {
++ if((ret_val = e1000_config_mac_to_phy(hw))) {
+ DEBUGOUT("Error configuring MAC to PHY settings\n");
+ return ret_val;
+ }
+@@ -1824,8 +1990,7 @@
+ * need to restore the desired flow control settings because we may
+ * have had to re-autoneg with a different link partner.
+ */
+- ret_val = e1000_config_fc_after_link_up(hw);
+- if(ret_val < 0) {
++ if((ret_val = e1000_config_fc_after_link_up(hw))) {
+ DEBUGOUT("Error configuring flow control\n");
+ return ret_val;
+ }
+@@ -1840,10 +2005,9 @@
+ * partner is TBI-based, and we turn on TBI Compatibility.
+ */
+ if(hw->tbi_compatibility_en) {
+- if(e1000_read_phy_reg(hw, PHY_LP_ABILITY, &lp_capability) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
+- }
++ if((ret_val = e1000_read_phy_reg(hw, PHY_LP_ABILITY,
++ &lp_capability)))
++ return ret_val;
+ if(lp_capability & (NWAY_LPAR_10T_HD_CAPS |
+ NWAY_LPAR_10T_FD_CAPS |
+ NWAY_LPAR_100TX_HD_CAPS |
+@@ -1900,8 +2064,7 @@
+ E1000_WRITE_REG(hw, CTRL, ctrl);
+
+ /* Configure Flow Control after forcing link up. */
+- ret_val = e1000_config_fc_after_link_up(hw);
+- if(ret_val < 0) {
++ if((ret_val = e1000_config_fc_after_link_up(hw))) {
+ DEBUGOUT("Error configuring flow control\n");
+ return ret_val;
+ }
+@@ -1918,7 +2081,7 @@
+ E1000_WRITE_REG(hw, TXCW, hw->txcw);
+ E1000_WRITE_REG(hw, CTRL, (ctrl & ~E1000_CTRL_SLU));
+ }
+- return 0;
++ return E1000_SUCCESS;
+ }
+
+ /******************************************************************************
+@@ -1928,12 +2091,14 @@
+ * speed - Speed of the connection
+ * duplex - Duplex setting of the connection
+ *****************************************************************************/
+-void
++int32_t
+ e1000_get_speed_and_duplex(struct e1000_hw *hw,
+ uint16_t *speed,
+ uint16_t *duplex)
+ {
+ uint32_t status;
++ int32_t ret_val;
++ uint16_t phy_data;
+
+ DEBUGFUNC("e1000_get_speed_and_duplex");
+
+@@ -1962,6 +2127,27 @@
+ *speed = SPEED_1000;
+ *duplex = FULL_DUPLEX;
+ }
++
++ /* IGP01 PHY may advertise full duplex operation after speed downgrade even
++ * if it is operating at half duplex. Here we set the duplex settings to
++ * match the duplex in the link partner's capabilities.
++ */
++ if(hw->phy_type == e1000_phy_igp && hw->speed_downgraded) {
++ if((ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_EXP, &phy_data)))
++ return ret_val;
++
++ if(!(phy_data & NWAY_ER_LP_NWAY_CAPS))
++ *duplex = HALF_DUPLEX;
++ else {
++ if((ret_val == e1000_read_phy_reg(hw, PHY_LP_ABILITY, &phy_data)))
++ return ret_val;
++ if((*speed == SPEED_100 && !(phy_data & NWAY_LPAR_100TX_FD_CAPS)) ||
++ (*speed == SPEED_10 && !(phy_data & NWAY_LPAR_10T_FD_CAPS)))
++ *duplex = HALF_DUPLEX;
++ }
++ }
++
++ return E1000_SUCCESS;
+ }
+
+ /******************************************************************************
+@@ -1972,6 +2158,7 @@
+ int32_t
+ e1000_wait_autoneg(struct e1000_hw *hw)
+ {
++ int32_t ret_val;
+ uint16_t i;
+ uint16_t phy_data;
+
+@@ -1983,20 +2170,16 @@
+ /* Read the MII Status Register and wait for Auto-Neg
+ * Complete bit to be set.
+ */
+- if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
+- }
+- if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
+- }
++ if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
++ return ret_val;
++ if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
++ return ret_val;
+ if(phy_data & MII_SR_AUTONEG_COMPLETE) {
+- return 0;
++ return E1000_SUCCESS;
+ }
+ msec_delay(100);
+ }
+- return 0;
++ return E1000_SUCCESS;
+ }
+
+ /******************************************************************************
+@@ -2010,11 +2193,11 @@
+ uint32_t *ctrl)
+ {
+ /* Raise the clock input to the Management Data Clock (by setting the MDC
+- * bit), and then delay 2 microseconds.
++ * bit), and then delay 10 microseconds.
+ */
+ E1000_WRITE_REG(hw, CTRL, (*ctrl | E1000_CTRL_MDC));
+ E1000_WRITE_FLUSH(hw);
+- udelay(2);
++ udelay(10);
+ }
+
+ /******************************************************************************
+@@ -2028,11 +2211,11 @@
+ uint32_t *ctrl)
+ {
+ /* Lower the clock input to the Management Data Clock (by clearing the MDC
+- * bit), and then delay 2 microseconds.
++ * bit), and then delay 10 microseconds.
+ */
+ E1000_WRITE_REG(hw, CTRL, (*ctrl & ~E1000_CTRL_MDC));
+ E1000_WRITE_FLUSH(hw);
+- udelay(2);
++ udelay(10);
+ }
+
+ /******************************************************************************
+@@ -2076,7 +2259,7 @@
+ E1000_WRITE_REG(hw, CTRL, ctrl);
+ E1000_WRITE_FLUSH(hw);
+
+- udelay(2);
++ udelay(10);
+
+ e1000_raise_mdi_clk(hw, &ctrl);
+ e1000_lower_mdi_clk(hw, &ctrl);
+@@ -2138,8 +2321,8 @@
+ }
+
+ /*****************************************************************************
+-* Reads the value from a PHY register
+-*
++* Reads the value from a PHY register, if the value is on a specific non zero
++* page, sets the page first.
+ * hw - Struct containing variables accessed by shared code
+ * reg_addr - address of the PHY register to read
+ ******************************************************************************/
+@@ -2148,11 +2331,33 @@
+ uint32_t reg_addr,
+ uint16_t *phy_data)
+ {
++ uint32_t ret_val;
++
++ DEBUGFUNC("e1000_read_phy_reg");
++
++ if(hw->phy_type == e1000_phy_igp &&
++ (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
++ if((ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
++ (uint16_t)reg_addr)))
++ return ret_val;
++ }
++
++ ret_val = e1000_read_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT & reg_addr,
++ phy_data);
++
++ return ret_val;
++}
++
++int32_t
++e1000_read_phy_reg_ex(struct e1000_hw *hw,
++ uint32_t reg_addr,
++ uint16_t *phy_data)
++{
+ uint32_t i;
+ uint32_t mdic = 0;
+ const uint32_t phy_addr = 1;
+
+- DEBUGFUNC("e1000_read_phy_reg");
++ DEBUGFUNC("e1000_read_phy_reg_ex");
+
+ if(reg_addr > MAX_PHY_REG_ADDRESS) {
+ DEBUGOUT1("PHY Address %d is out of range\n", reg_addr);
+@@ -2172,7 +2377,7 @@
+
+ /* Poll the ready bit to see if the MDI read completed */
+ for(i = 0; i < 64; i++) {
+- udelay(10);
++ udelay(50);
+ mdic = E1000_READ_REG(hw, MDIC);
+ if(mdic & E1000_MDIC_READY) break;
+ }
+@@ -2214,7 +2419,7 @@
+ */
+ *phy_data = e1000_shift_in_mdi_bits(hw);
+ }
+- return 0;
++ return E1000_SUCCESS;
+ }
+
+ /******************************************************************************
+@@ -2229,11 +2434,33 @@
+ uint32_t reg_addr,
+ uint16_t phy_data)
+ {
++ uint32_t ret_val;
++
++ DEBUGFUNC("e1000_write_phy_reg");
++
++ if(hw->phy_type == e1000_phy_igp &&
++ (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
++ if((ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
++ (uint16_t)reg_addr)))
++ return ret_val;
++ }
++
++ ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT & reg_addr,
++ phy_data);
++
++ return ret_val;
++}
++
++int32_t
++e1000_write_phy_reg_ex(struct e1000_hw *hw,
++ uint32_t reg_addr,
++ uint16_t phy_data)
++{
+ uint32_t i;
+ uint32_t mdic = 0;
+ const uint32_t phy_addr = 1;
+
+- DEBUGFUNC("e1000_write_phy_reg");
++ DEBUGFUNC("e1000_write_phy_reg_ex");
+
+ if(reg_addr > MAX_PHY_REG_ADDRESS) {
+ DEBUGOUT1("PHY Address %d is out of range\n", reg_addr);
+@@ -2254,7 +2481,7 @@
+
+ /* Poll the ready bit to see if the MDI read completed */
+ for(i = 0; i < 64; i++) {
+- udelay(10);
++ udelay(50);
+ mdic = E1000_READ_REG(hw, MDIC);
+ if(mdic & E1000_MDIC_READY) break;
+ }
+@@ -2284,7 +2511,7 @@
+ e1000_shift_out_mdi_bits(hw, mdic, 32);
+ }
+
+- return 0;
++ return E1000_SUCCESS;
+ }
+
+ /******************************************************************************
+@@ -2329,11 +2556,6 @@
+ udelay(150);
+
+ if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
+- if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 0x0000) < 0) {
+- DEBUGOUT("PHY Write Error\n");
+- return;
+- }
+-
+ /* Configure activity LED after PHY reset */
+ led_ctrl = E1000_READ_REG(hw, LEDCTL);
+ led_ctrl &= IGP_ACTIVITY_LED_MASK;
+@@ -2352,24 +2574,26 @@
+ int32_t
+ e1000_phy_reset(struct e1000_hw *hw)
+ {
++ int32_t ret_val;
+ uint16_t phy_data;
+
+ DEBUGFUNC("e1000_phy_reset");
+
+- if(e1000_read_phy_reg(hw, PHY_CTRL, &phy_data) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
+- }
+- phy_data |= MII_CR_RESET;
+- if(e1000_write_phy_reg(hw, PHY_CTRL, phy_data) < 0) {
+- DEBUGOUT("PHY Write Error\n");
+- return -E1000_ERR_PHY;
+- }
+- udelay(1);
+- if (hw->phy_type == e1000_phy_igp) {
++ if(hw->mac_type != e1000_82541_rev_2) {
++ if((ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data)))
++ return ret_val;
++
++ phy_data |= MII_CR_RESET;
++ if((ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data)))
++ return ret_val;
++
++ udelay(1);
++ } else e1000_phy_hw_reset(hw);
++
++ if(hw->phy_type == e1000_phy_igp)
+ e1000_phy_init_script(hw);
+- }
+- return 0;
++
++ return E1000_SUCCESS;
+ }
+
+ /******************************************************************************
+@@ -2380,23 +2604,21 @@
+ int32_t
+ e1000_detect_gig_phy(struct e1000_hw *hw)
+ {
++ int32_t phy_init_status, ret_val;
+ uint16_t phy_id_high, phy_id_low;
+ boolean_t match = FALSE;
+- int32_t phy_init_status;
+
+ DEBUGFUNC("e1000_detect_gig_phy");
+
+ /* Read the PHY ID Registers to identify which PHY is onboard. */
+- if(e1000_read_phy_reg(hw, PHY_ID1, &phy_id_high) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
+- }
++ if((ret_val = e1000_read_phy_reg(hw, PHY_ID1, &phy_id_high)))
++ return ret_val;
++
+ hw->phy_id = (uint32_t) (phy_id_high << 16);
+ udelay(20);
+- if(e1000_read_phy_reg(hw, PHY_ID2, &phy_id_low) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
+- }
++ if((ret_val = e1000_read_phy_reg(hw, PHY_ID2, &phy_id_low)))
++ return ret_val;
++
+ hw->phy_id |= (uint32_t) (phy_id_low & PHY_REVISION_MASK);
+ hw->phy_revision = (uint32_t) phy_id_low & ~PHY_REVISION_MASK;
+
+@@ -2409,11 +2631,15 @@
+ break;
+ case e1000_82540:
+ case e1000_82545:
++ case e1000_82545_rev_3:
+ case e1000_82546:
++ case e1000_82546_rev_3:
+ if(hw->phy_id == M88E1011_I_PHY_ID) match = TRUE;
+ break;
+ case e1000_82541:
++ case e1000_82541_rev_2:
+ case e1000_82547:
++ case e1000_82547_rev_2:
+ if(hw->phy_id == IGP01E1000_I_PHY_ID) match = TRUE;
+ break;
+ default:
+@@ -2424,7 +2650,7 @@
+
+ if ((match) && (phy_init_status == E1000_SUCCESS)) {
+ DEBUGOUT1("PHY ID 0x%X detected\n", hw->phy_id);
+- return 0;
++ return E1000_SUCCESS;
+ }
+ DEBUGOUT1("Invalid PHY ID 0x%X\n", hw->phy_id);
+ return -E1000_ERR_PHY;
+@@ -2438,17 +2664,16 @@
+ static int32_t
+ e1000_phy_reset_dsp(struct e1000_hw *hw)
+ {
+- int32_t ret_val = -E1000_ERR_PHY;
++ int32_t ret_val;
+ DEBUGFUNC("e1000_phy_reset_dsp");
+
+ do {
+- if(e1000_write_phy_reg(hw, 29, 0x001d) < 0) break;
+- if(e1000_write_phy_reg(hw, 30, 0x00c1) < 0) break;
+- if(e1000_write_phy_reg(hw, 30, 0x0000) < 0) break;
+- ret_val = 0;
++ if((ret_val = e1000_write_phy_reg(hw, 29, 0x001d))) break;
++ if((ret_val = e1000_write_phy_reg(hw, 30, 0x00c1))) break;
++ if((ret_val = e1000_write_phy_reg(hw, 30, 0x0000))) break;
++ ret_val = E1000_SUCCESS;
+ } while(0);
+
+- if(ret_val < 0) DEBUGOUT("PHY Write Error\n");
+ return ret_val;
+ }
+
+@@ -2459,8 +2684,10 @@
+ * phy_info - PHY information structure
+ ******************************************************************************/
+ int32_t
+-e1000_phy_igp_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info)
++e1000_phy_igp_get_info(struct e1000_hw *hw,
++ struct e1000_phy_info *phy_info)
+ {
++ int32_t ret_val;
+ uint16_t phy_data, polarity, min_length, max_length, average;
+
+ DEBUGFUNC("e1000_phy_igp_get_info");
+@@ -2476,13 +2703,14 @@
+ phy_info->polarity_correction = e1000_polarity_reversal_enabled;
+
+ /* Check polarity status */
+- if(e1000_check_polarity(hw, &polarity) < 0)
+- return -E1000_ERR_PHY;
++ if((ret_val = e1000_check_polarity(hw, &polarity)))
++ return ret_val;
+
+ phy_info->cable_polarity = polarity;
+
+- if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &phy_data) < 0)
+- return -E1000_ERR_PHY;
++ if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
++ &phy_data)))
++ return ret_val;
+
+ phy_info->mdix_mode = (phy_data & IGP01E1000_PSSR_MDIX) >>
+ IGP01E1000_PSSR_MDIX_SHIFT;
+@@ -2490,8 +2718,8 @@
+ if((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
+ IGP01E1000_PSSR_SPEED_1000MBPS) {
+ /* Local/Remote Receiver Information are only valid at 1000 Mbps */
+- if(e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data) < 0)
+- return -E1000_ERR_PHY;
++ if((ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data)))
++ return ret_val;
+
+ phy_info->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS) >>
+ SR_1000T_LOCAL_RX_STATUS_SHIFT;
+@@ -2499,8 +2727,8 @@
+ SR_1000T_REMOTE_RX_STATUS_SHIFT;
+
+ /* Get cable length */
+- if(e1000_get_cable_length(hw, &min_length, &max_length) < 0)
+- return -E1000_ERR_PHY;
++ if((ret_val = e1000_get_cable_length(hw, &min_length, &max_length)))
++ return ret_val;
+
+ /* transalte to old method */
+ average = (max_length + min_length) / 2;
+@@ -2527,8 +2755,10 @@
+ * phy_info - PHY information structure
+ ******************************************************************************/
+ int32_t
+-e1000_phy_m88_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info)
++e1000_phy_m88_get_info(struct e1000_hw *hw,
++ struct e1000_phy_info *phy_info)
+ {
++ int32_t ret_val;
+ uint16_t phy_data, polarity;
+
+ DEBUGFUNC("e1000_phy_m88_get_info");
+@@ -2537,8 +2767,8 @@
+ * and it stored in the hw->speed_downgraded parameter. */
+ phy_info->downshift = hw->speed_downgraded;
+
+- if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0)
+- return -E1000_ERR_PHY;
++ if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data)))
++ return ret_val;
+
+ phy_info->extended_10bt_distance =
+ (phy_data & M88E1000_PSCR_10BT_EXT_DIST_ENABLE) >>
+@@ -2548,13 +2778,13 @@
+ M88E1000_PSCR_POLARITY_REVERSAL_SHIFT;
+
+ /* Check polarity status */
+- if(e1000_check_polarity(hw, &polarity) < 0)
+- return -E1000_ERR_PHY;
++ if((ret_val = e1000_check_polarity(hw, &polarity)))
++ return ret_val;
+
+ phy_info->cable_polarity = polarity;
+
+- if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0)
+- return -E1000_ERR_PHY;
++ if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data)))
++ return ret_val;
+
+ phy_info->mdix_mode = (phy_data & M88E1000_PSSR_MDIX) >>
+ M88E1000_PSSR_MDIX_SHIFT;
+@@ -2566,8 +2796,8 @@
+ phy_info->cable_length = ((phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
+ M88E1000_PSSR_CABLE_LENGTH_SHIFT);
+
+- if(e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data) < 0)
+- return -E1000_ERR_PHY;
++ if((ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data)))
++ return ret_val;
+
+ phy_info->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS) >>
+ SR_1000T_LOCAL_RX_STATUS_SHIFT;
+@@ -2589,6 +2819,7 @@
+ e1000_phy_get_info(struct e1000_hw *hw,
+ struct e1000_phy_info *phy_info)
+ {
++ int32_t ret_val;
+ uint16_t phy_data;
+
+ DEBUGFUNC("e1000_phy_get_info");
+@@ -2607,20 +2838,18 @@
+ return -E1000_ERR_CONFIG;
+ }
+
+- if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
+- }
+- if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
+- }
++ if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
++ return ret_val;
++
++ if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
++ return ret_val;
++
+ if((phy_data & MII_SR_LINK_STATUS) != MII_SR_LINK_STATUS) {
+ DEBUGOUT("PHY info is only valid if link is up\n");
+ return -E1000_ERR_CONFIG;
+ }
+
+- if (hw->phy_type == e1000_phy_igp)
++ if(hw->phy_type == e1000_phy_igp)
+ return e1000_phy_igp_get_info(hw, phy_info);
+ else
+ return e1000_phy_m88_get_info(hw, phy_info);
+@@ -2636,7 +2865,7 @@
+ hw->mdix = 1;
+ return -E1000_ERR_CONFIG;
+ }
+- return 0;
++ return E1000_SUCCESS;
+ }
+
+
+@@ -2668,7 +2897,9 @@
+ break;
+ case e1000_82540:
+ case e1000_82545:
++ case e1000_82545_rev_3:
+ case e1000_82546:
++ case e1000_82546_rev_3:
+ eeprom->type = e1000_eeprom_microwire;
+ eeprom->opcode_bits = 3;
+ eeprom->delay_usec = 50;
+@@ -2681,8 +2912,9 @@
+ }
+ break;
+ case e1000_82541:
++ case e1000_82541_rev_2:
+ case e1000_82547:
+- default:
++ case e1000_82547_rev_2:
+ if (eecd & E1000_EECD_TYPE) {
+ eeprom->type = e1000_eeprom_spi;
+ eeprom->opcode_bits = 8;
+@@ -2707,6 +2939,18 @@
+ }
+ }
+ break;
++ default:
++ eeprom->type = e1000_eeprom_spi;
++ eeprom->opcode_bits = 8;
++ eeprom->delay_usec = 1;
++ if (eecd & E1000_EECD_ADDR_BITS) {
++ eeprom->page_size = 32;
++ eeprom->address_bits = 16;
++ } else {
++ eeprom->page_size = 8;
++ eeprom->address_bits = 8;
++ }
++ break;
+ }
+
+ if (eeprom->type == e1000_eeprom_spi) {
+@@ -2715,28 +2959,28 @@
+ eeprom_size &= EEPROM_SIZE_MASK;
+
+ switch (eeprom_size) {
+- case EEPROM_SIZE_16KB:
+- eeprom->word_size = 8192;
+- break;
+- case EEPROM_SIZE_8KB:
+- eeprom->word_size = 4096;
+- break;
+- case EEPROM_SIZE_4KB:
+- eeprom->word_size = 2048;
+- break;
+- case EEPROM_SIZE_2KB:
+- eeprom->word_size = 1024;
+- break;
+- case EEPROM_SIZE_1KB:
+- eeprom->word_size = 512;
+- break;
+- case EEPROM_SIZE_512B:
+- eeprom->word_size = 256;
+- break;
+- case EEPROM_SIZE_128B:
+- default:
+- eeprom->word_size = 64;
+- break;
++ case EEPROM_SIZE_16KB:
++ eeprom->word_size = 8192;
++ break;
++ case EEPROM_SIZE_8KB:
++ eeprom->word_size = 4096;
++ break;
++ case EEPROM_SIZE_4KB:
++ eeprom->word_size = 2048;
++ break;
++ case EEPROM_SIZE_2KB:
++ eeprom->word_size = 1024;
++ break;
++ case EEPROM_SIZE_1KB:
++ eeprom->word_size = 512;
++ break;
++ case EEPROM_SIZE_512B:
++ eeprom->word_size = 256;
++ break;
++ case EEPROM_SIZE_128B:
++ default:
++ eeprom->word_size = 64;
++ break;
+ }
+ }
+ }
+@@ -2841,7 +3085,8 @@
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+ static uint16_t
+-e1000_shift_in_ee_bits(struct e1000_hw *hw, uint16_t count)
++e1000_shift_in_ee_bits(struct e1000_hw *hw,
++ uint16_t count)
+ {
+ uint32_t eecd;
+ uint32_t i;
+@@ -3101,13 +3346,17 @@
+ }
+
+ /* Prepare the EEPROM for reading */
+- if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
++ if(e1000_acquire_eeprom(hw) != E1000_SUCCESS)
+ return -E1000_ERR_EEPROM;
+
+ if(eeprom->type == e1000_eeprom_spi) {
++ uint16_t word_in;
+ uint8_t read_opcode = EEPROM_READ_OPCODE_SPI;
+
+- if(e1000_spi_eeprom_ready(hw)) return -E1000_ERR_EEPROM;
++ if(e1000_spi_eeprom_ready(hw)) {
++ e1000_release_eeprom(hw);
++ return -E1000_ERR_EEPROM;
++ }
+
+ e1000_standby_eeprom(hw);
+
+@@ -3118,30 +3367,35 @@
+ /* Send the READ command (opcode + addr) */
+ e1000_shift_out_ee_bits(hw, read_opcode, eeprom->opcode_bits);
+ e1000_shift_out_ee_bits(hw, (uint16_t)(offset*2), eeprom->address_bits);
+- }
+- else if(eeprom->type == e1000_eeprom_microwire) {
+- /* Send the READ command (opcode + addr) */
+- e1000_shift_out_ee_bits(hw, EEPROM_READ_OPCODE_MICROWIRE,
+- eeprom->opcode_bits);
+- e1000_shift_out_ee_bits(hw, offset, eeprom->address_bits);
+- }
+
+- /* Read the data. The address of the eeprom internally increments with
+- * each word (microwire) or byte (spi) being read, saving on the overhead
+- * of eeprom setup and tear-down. The address counter will roll over if
+- * reading beyond the size of the eeprom, thus allowing the entire memory
+- * to be read starting from any offset. */
+- for (i = 0; i < words; i++) {
+- uint16_t word_in = e1000_shift_in_ee_bits(hw, 16);
+- if (eeprom->type == e1000_eeprom_spi)
+- word_in = (word_in >> 8) | (word_in << 8);
+- data[i] = word_in;
++ /* Read the data. The address of the eeprom internally increments with
++ * each byte (spi) being read, saving on the overhead of eeprom setup
++ * and tear-down. The address counter will roll over if reading beyond
++ * the size of the eeprom, thus allowing the entire memory to be read
++ * starting from any offset. */
++ for (i = 0; i < words; i++) {
++ word_in = e1000_shift_in_ee_bits(hw, 16);
++ data[i] = (word_in >> 8) | (word_in << 8);
++ }
++ } else if(eeprom->type == e1000_eeprom_microwire) {
++ for (i = 0; i < words; i++) {
++ /* Send the READ command (opcode + addr) */
++ e1000_shift_out_ee_bits(hw, EEPROM_READ_OPCODE_MICROWIRE,
++ eeprom->opcode_bits);
++ e1000_shift_out_ee_bits(hw, (uint16_t)(offset + i),
++ eeprom->address_bits);
++
++ /* Read the data. For microwire, each word requires the overhead
++ * of eeprom setup and tear-down. */
++ data[i] = e1000_shift_in_ee_bits(hw, 16);
++ e1000_standby_eeprom(hw);
++ }
+ }
+
+ /* End this read operation */
+ e1000_release_eeprom(hw);
+
+- return 0;
++ return E1000_SUCCESS;
+ }
+
+ /******************************************************************************
+@@ -3169,9 +3423,9 @@
+ checksum += eeprom_data;
+ }
+
+- if(checksum == (uint16_t) EEPROM_SUM) {
+- return 0;
+- } else {
++ if(checksum == (uint16_t) EEPROM_SUM)
++ return E1000_SUCCESS;
++ else {
+ DEBUGOUT("EEPROM Checksum Invalid\n");
+ return -E1000_ERR_EEPROM;
+ }
+@@ -3205,7 +3459,7 @@
+ DEBUGOUT("EEPROM Write Error\n");
+ return -E1000_ERR_EEPROM;
+ }
+- return 0;
++ return E1000_SUCCESS;
+ }
+
+ /******************************************************************************
+@@ -3403,7 +3657,7 @@
+
+ e1000_shift_out_ee_bits(hw, 0, (uint16_t)(eeprom->address_bits - 2));
+
+- return 0;
++ return E1000_SUCCESS;
+ }
+
+ /******************************************************************************
+@@ -3437,7 +3691,7 @@
+ /* Save word 1 in lower half of part_num */
+ *part_num |= eeprom_data;
+
+- return 0;
++ return E1000_SUCCESS;
+ }
+
+ /******************************************************************************
+@@ -3463,7 +3717,7 @@
+ hw->perm_mac_addr[i] = (uint8_t) (eeprom_data & 0x00FF);
+ hw->perm_mac_addr[i+1] = (uint8_t) (eeprom_data >> 8);
+ }
+- if((hw->mac_type == e1000_82546) &&
++ if(((hw->mac_type == e1000_82546) || (hw->mac_type == e1000_82546_rev_3)) &&
+ (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) {
+ if(hw->perm_mac_addr[5] & 0x01)
+ hw->perm_mac_addr[5] &= ~(0x01);
+@@ -3472,7 +3726,7 @@
+ }
+ for(i = 0; i < NODE_ADDRESS_SIZE; i++)
+ hw->mac_addr[i] = hw->perm_mac_addr[i];
+- return 0;
++ return E1000_SUCCESS;
+ }
+
+ /******************************************************************************
+@@ -3748,7 +4002,7 @@
+
+ if(hw->mac_type < e1000_82540) {
+ /* Nothing to do */
+- return 0;
++ return E1000_SUCCESS;
+ }
+
+ ledctl = E1000_READ_REG(hw, LEDCTL);
+@@ -3799,7 +4053,7 @@
+ break;
+ }
+ }
+- return 0;
++ return E1000_SUCCESS;
+ }
+
+ /******************************************************************************
+@@ -3811,49 +4065,48 @@
+ e1000_setup_led(struct e1000_hw *hw)
+ {
+ uint32_t ledctl;
++ int32_t ret_val = E1000_SUCCESS;
+
+ DEBUGFUNC("e1000_setup_led");
+
+- switch(hw->device_id) {
+- case E1000_DEV_ID_82542:
+- case E1000_DEV_ID_82543GC_FIBER:
+- case E1000_DEV_ID_82543GC_COPPER:
+- case E1000_DEV_ID_82544EI_COPPER:
+- case E1000_DEV_ID_82544EI_FIBER:
+- case E1000_DEV_ID_82544GC_COPPER:
+- case E1000_DEV_ID_82544GC_LOM:
++ switch(hw->mac_type) {
++ case e1000_82542_rev2_0:
++ case e1000_82542_rev2_1:
++ case e1000_82543:
++ case e1000_82544:
+ /* No setup necessary */
+ break;
+- case E1000_DEV_ID_82545EM_FIBER:
+- case E1000_DEV_ID_82546EB_FIBER:
+- ledctl = E1000_READ_REG(hw, LEDCTL);
+- /* Save current LEDCTL settings */
+- hw->ledctl_default = ledctl;
+- /* Turn off LED0 */
+- ledctl &= ~(E1000_LEDCTL_LED0_IVRT |
+- E1000_LEDCTL_LED0_BLINK |
+- E1000_LEDCTL_LED0_MODE_MASK);
+- ledctl |= (E1000_LEDCTL_MODE_LED_OFF << E1000_LEDCTL_LED0_MODE_SHIFT);
+- E1000_WRITE_REG(hw, LEDCTL, ledctl);
+- break;
+- case E1000_DEV_ID_82540EP:
+- case E1000_DEV_ID_82540EP_LOM:
+- case E1000_DEV_ID_82540EP_LP:
+- case E1000_DEV_ID_82540EM:
+- case E1000_DEV_ID_82540EM_LOM:
+- case E1000_DEV_ID_82545EM_COPPER:
+- case E1000_DEV_ID_82546EB_COPPER:
+- case E1000_DEV_ID_82546EB_QUAD_COPPER:
+- case E1000_DEV_ID_82541EI:
+- case E1000_DEV_ID_82541EP:
+- case E1000_DEV_ID_82547EI:
+- E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode1);
+- break;
++ case e1000_82541:
++ case e1000_82547:
++ case e1000_82541_rev_2:
++ case e1000_82547_rev_2:
++ /* Turn off PHY Smart Power Down (if enabled) */
++ if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO,
++ &hw->phy_spd_default)))
++ return ret_val;
++ if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
++ (uint16_t)(hw->phy_spd_default &
++ ~IGP01E1000_GMII_SPD))))
++ return ret_val;
++ /* Fall Through */
+ default:
+- DEBUGOUT("Invalid device ID\n");
+- return -E1000_ERR_CONFIG;
++ if(hw->media_type == e1000_media_type_fiber) {
++ ledctl = E1000_READ_REG(hw, LEDCTL);
++ /* Save current LEDCTL settings */
++ hw->ledctl_default = ledctl;
++ /* Turn off LED0 */
++ ledctl &= ~(E1000_LEDCTL_LED0_IVRT |
++ E1000_LEDCTL_LED0_BLINK |
++ E1000_LEDCTL_LED0_MODE_MASK);
++ ledctl |= (E1000_LEDCTL_MODE_LED_OFF <<
++ E1000_LEDCTL_LED0_MODE_SHIFT);
++ E1000_WRITE_REG(hw, LEDCTL, ledctl);
++ } else if(hw->media_type == e1000_media_type_copper)
++ E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode1);
++ break;
+ }
+- return 0;
++
++ return E1000_SUCCESS;
+ }
+
+ /******************************************************************************
+@@ -3864,39 +4117,33 @@
+ int32_t
+ e1000_cleanup_led(struct e1000_hw *hw)
+ {
++ int32_t ret_val = E1000_SUCCESS;
++
+ DEBUGFUNC("e1000_cleanup_led");
+
+- switch(hw->device_id) {
+- case E1000_DEV_ID_82542:
+- case E1000_DEV_ID_82543GC_FIBER:
+- case E1000_DEV_ID_82543GC_COPPER:
+- case E1000_DEV_ID_82544EI_COPPER:
+- case E1000_DEV_ID_82544EI_FIBER:
+- case E1000_DEV_ID_82544GC_COPPER:
+- case E1000_DEV_ID_82544GC_LOM:
++ switch(hw->mac_type) {
++ case e1000_82542_rev2_0:
++ case e1000_82542_rev2_1:
++ case e1000_82543:
++ case e1000_82544:
+ /* No cleanup necessary */
+ break;
+- case E1000_DEV_ID_82540EP:
+- case E1000_DEV_ID_82540EP_LOM:
+- case E1000_DEV_ID_82540EP_LP:
+- case E1000_DEV_ID_82540EM:
+- case E1000_DEV_ID_82540EM_LOM:
+- case E1000_DEV_ID_82545EM_COPPER:
+- case E1000_DEV_ID_82545EM_FIBER:
+- case E1000_DEV_ID_82546EB_COPPER:
+- case E1000_DEV_ID_82546EB_FIBER:
+- case E1000_DEV_ID_82546EB_QUAD_COPPER:
+- case E1000_DEV_ID_82541EI:
+- case E1000_DEV_ID_82541EP:
+- case E1000_DEV_ID_82547EI:
++ case e1000_82541:
++ case e1000_82547:
++ case e1000_82541_rev_2:
++ case e1000_82547_rev_2:
++ /* Turn on PHY Smart Power Down (if previously enabled) */
++ if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
++ hw->phy_spd_default)))
++ return ret_val;
++ /* Fall Through */
++ default:
+ /* Restore LEDCTL settings */
+ E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_default);
+ break;
+- default:
+- DEBUGOUT("Invalid device ID\n");
+- return -E1000_ERR_CONFIG;
+ }
+- return 0;
++
++ return E1000_SUCCESS;
+ }
+
+ /******************************************************************************
+@@ -3907,50 +4154,44 @@
+ int32_t
+ e1000_led_on(struct e1000_hw *hw)
+ {
+- uint32_t ctrl;
++ uint32_t ctrl = E1000_READ_REG(hw, CTRL);
+
+ DEBUGFUNC("e1000_led_on");
+
+- switch(hw->device_id) {
+- case E1000_DEV_ID_82542:
+- case E1000_DEV_ID_82543GC_FIBER:
+- case E1000_DEV_ID_82543GC_COPPER:
+- case E1000_DEV_ID_82544EI_FIBER:
+- ctrl = E1000_READ_REG(hw, CTRL);
++ switch(hw->mac_type) {
++ case e1000_82542_rev2_0:
++ case e1000_82542_rev2_1:
++ case e1000_82543:
+ /* Set SW Defineable Pin 0 to turn on the LED */
+ ctrl |= E1000_CTRL_SWDPIN0;
+ ctrl |= E1000_CTRL_SWDPIO0;
+- E1000_WRITE_REG(hw, CTRL, ctrl);
+ break;
+- case E1000_DEV_ID_82544EI_COPPER:
+- case E1000_DEV_ID_82544GC_COPPER:
+- case E1000_DEV_ID_82544GC_LOM:
+- case E1000_DEV_ID_82545EM_FIBER:
+- case E1000_DEV_ID_82546EB_FIBER:
+- ctrl = E1000_READ_REG(hw, CTRL);
+- /* Clear SW Defineable Pin 0 to turn on the LED */
+- ctrl &= ~E1000_CTRL_SWDPIN0;
+- ctrl |= E1000_CTRL_SWDPIO0;
+- E1000_WRITE_REG(hw, CTRL, ctrl);
+- break;
+- case E1000_DEV_ID_82540EP:
+- case E1000_DEV_ID_82540EP_LOM:
+- case E1000_DEV_ID_82540EP_LP:
+- case E1000_DEV_ID_82540EM:
+- case E1000_DEV_ID_82540EM_LOM:
+- case E1000_DEV_ID_82545EM_COPPER:
+- case E1000_DEV_ID_82546EB_COPPER:
+- case E1000_DEV_ID_82546EB_QUAD_COPPER:
+- case E1000_DEV_ID_82541EI:
+- case E1000_DEV_ID_82541EP:
+- case E1000_DEV_ID_82547EI:
+- E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode2);
++ case e1000_82544:
++ if(hw->media_type == e1000_media_type_fiber) {
++ /* Set SW Defineable Pin 0 to turn on the LED */
++ ctrl |= E1000_CTRL_SWDPIN0;
++ ctrl |= E1000_CTRL_SWDPIO0;
++ } else {
++ /* Clear SW Defineable Pin 0 to turn on the LED */
++ ctrl &= ~E1000_CTRL_SWDPIN0;
++ ctrl |= E1000_CTRL_SWDPIO0;
++ }
+ break;
+ default:
+- DEBUGOUT("Invalid device ID\n");
+- return -E1000_ERR_CONFIG;
++ if(hw->media_type == e1000_media_type_fiber) {
++ /* Clear SW Defineable Pin 0 to turn on the LED */
++ ctrl &= ~E1000_CTRL_SWDPIN0;
++ ctrl |= E1000_CTRL_SWDPIO0;
++ } else if(hw->media_type == e1000_media_type_copper) {
++ E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode2);
++ return E1000_SUCCESS;
++ }
++ break;
+ }
+- return 0;
++
++ E1000_WRITE_REG(hw, CTRL, ctrl);
++
++ return E1000_SUCCESS;
+ }
+
+ /******************************************************************************
+@@ -3961,50 +4202,44 @@
+ int32_t
+ e1000_led_off(struct e1000_hw *hw)
+ {
+- uint32_t ctrl;
++ uint32_t ctrl = E1000_READ_REG(hw, CTRL);
+
+ DEBUGFUNC("e1000_led_off");
+
+- switch(hw->device_id) {
+- case E1000_DEV_ID_82542:
+- case E1000_DEV_ID_82543GC_FIBER:
+- case E1000_DEV_ID_82543GC_COPPER:
+- case E1000_DEV_ID_82544EI_FIBER:
+- ctrl = E1000_READ_REG(hw, CTRL);
++ switch(hw->mac_type) {
++ case e1000_82542_rev2_0:
++ case e1000_82542_rev2_1:
++ case e1000_82543:
+ /* Clear SW Defineable Pin 0 to turn off the LED */
+ ctrl &= ~E1000_CTRL_SWDPIN0;
+ ctrl |= E1000_CTRL_SWDPIO0;
+- E1000_WRITE_REG(hw, CTRL, ctrl);
+ break;
+- case E1000_DEV_ID_82544EI_COPPER:
+- case E1000_DEV_ID_82544GC_COPPER:
+- case E1000_DEV_ID_82544GC_LOM:
+- case E1000_DEV_ID_82545EM_FIBER:
+- case E1000_DEV_ID_82546EB_FIBER:
+- ctrl = E1000_READ_REG(hw, CTRL);
+- /* Set SW Defineable Pin 0 to turn off the LED */
+- ctrl |= E1000_CTRL_SWDPIN0;
+- ctrl |= E1000_CTRL_SWDPIO0;
+- E1000_WRITE_REG(hw, CTRL, ctrl);
+- break;
+- case E1000_DEV_ID_82540EP:
+- case E1000_DEV_ID_82540EP_LOM:
+- case E1000_DEV_ID_82540EP_LP:
+- case E1000_DEV_ID_82540EM:
+- case E1000_DEV_ID_82540EM_LOM:
+- case E1000_DEV_ID_82545EM_COPPER:
+- case E1000_DEV_ID_82546EB_COPPER:
+- case E1000_DEV_ID_82546EB_QUAD_COPPER:
+- case E1000_DEV_ID_82541EI:
+- case E1000_DEV_ID_82541EP:
+- case E1000_DEV_ID_82547EI:
+- E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode1);
++ case e1000_82544:
++ if(hw->media_type == e1000_media_type_fiber) {
++ /* Clear SW Defineable Pin 0 to turn off the LED */
++ ctrl &= ~E1000_CTRL_SWDPIN0;
++ ctrl |= E1000_CTRL_SWDPIO0;
++ } else {
++ /* Set SW Defineable Pin 0 to turn off the LED */
++ ctrl |= E1000_CTRL_SWDPIN0;
++ ctrl |= E1000_CTRL_SWDPIO0;
++ }
+ break;
+ default:
+- DEBUGOUT("Invalid device ID\n");
+- return -E1000_ERR_CONFIG;
++ if(hw->media_type == e1000_media_type_fiber) {
++ /* Set SW Defineable Pin 0 to turn off the LED */
++ ctrl |= E1000_CTRL_SWDPIN0;
++ ctrl |= E1000_CTRL_SWDPIO0;
++ } else if(hw->media_type == e1000_media_type_copper) {
++ E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode1);
++ return E1000_SUCCESS;
++ }
++ break;
+ }
+- return 0;
++
++ E1000_WRITE_REG(hw, CTRL, ctrl);
++
++ return E1000_SUCCESS;
+ }
+
+ /******************************************************************************
+@@ -4127,8 +4362,7 @@
+ DEBUGFUNC("e1000_update_adaptive");
+
+ if(hw->adaptive_ifs) {
+- if((hw->collision_delta * hw->ifs_ratio) >
+- hw->tx_packet_delta) {
++ if((hw->collision_delta * hw->ifs_ratio) > hw->tx_packet_delta) {
+ if(hw->tx_packet_delta > MIN_NUM_XMITS) {
+ hw->in_ifs_mode = TRUE;
+ if(hw->current_ifs_val < hw->ifs_max_val) {
+@@ -4140,8 +4374,7 @@
+ }
+ }
+ } else {
+- if((hw->in_ifs_mode == TRUE) &&
+- (hw->tx_packet_delta <= MIN_NUM_XMITS)) {
++ if(hw->in_ifs_mode && (hw->tx_packet_delta <= MIN_NUM_XMITS)) {
+ hw->current_ifs_val = 0;
+ hw->in_ifs_mode = FALSE;
+ E1000_WRITE_REG(hw, AIT, 0);
+@@ -4324,7 +4557,8 @@
+ * min_length - The estimated minimum length
+ * max_length - The estimated maximum length
+ *
+- * returns: E1000_SUCCESS / -E1000_ERR_XXX
++ * returns: - E1000_ERR_XXX
++ * E1000_SUCCESS
+ *
+ * This function always returns a ranged length (minimum & maximum).
+ * So for M88 phy's, this function interprets the one value returned from the
+@@ -4332,9 +4566,11 @@
+ * For IGP phy's, the function calculates the range by the AGC registers.
+ *****************************************************************************/
+ int32_t
+-e1000_get_cable_length(struct e1000_hw *hw, uint16_t *min_length,
++e1000_get_cable_length(struct e1000_hw *hw,
++ uint16_t *min_length,
+ uint16_t *max_length)
+ {
++ int32_t ret_val;
+ uint16_t agc_value = 0;
+ uint16_t cur_agc, min_agc = IGP01E1000_AGC_LENGTH_TABLE_SIZE;
+ uint16_t i, phy_data;
+@@ -4345,8 +4581,9 @@
+
+ /* Use old method for Phy older than IGP */
+ if(hw->phy_type == e1000_phy_m88) {
+- if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0)
+- return -E1000_ERR_PHY;
++ if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
++ &phy_data)))
++ return ret_val;
+
+ /* Convert the enum value to ranged values */
+ switch((phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
+@@ -4376,19 +4613,16 @@
+ break;
+ }
+ } else if(hw->phy_type == e1000_phy_igp) { /* For IGP PHY */
+- uint16_t agc_reg_array[IGP01E1000_PHY_AGC_NUM] = {IGP01E1000_PHY_AGC_A,
++ uint16_t agc_reg_array[IGP01E1000_PHY_CHANNEL_NUM] =
++ {IGP01E1000_PHY_AGC_A,
+ IGP01E1000_PHY_AGC_B,
+ IGP01E1000_PHY_AGC_C,
+ IGP01E1000_PHY_AGC_D};
+ /* Read the AGC registers for all channels */
+- for(i = 0; i < IGP01E1000_PHY_AGC_NUM; i++) {
+- if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT,
+- agc_reg_array[i]) != E1000_SUCCESS)
+- return -E1000_ERR_PHY;
+- if(e1000_read_phy_reg(hw, agc_reg_array[i] &
+- IGP01E1000_PHY_PAGE_SELECT, &phy_data) !=
+- E1000_SUCCESS)
+- return -E1000_ERR_PHY;
++ for(i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
++
++ if((ret_val = e1000_read_phy_reg(hw, agc_reg_array[i], &phy_data)))
++ return ret_val;
+
+ cur_agc = phy_data >> IGP01E1000_AGC_LENGTH_SHIFT;
+
+@@ -4404,20 +4638,15 @@
+ min_agc = cur_agc;
+ }
+
+- /* Return to page 0 */
+- if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 0x0) !=
+- E1000_SUCCESS)
+- return -E1000_ERR_PHY;
+-
+ /* Remove the minimal AGC result for length < 50m */
+- if(agc_value < IGP01E1000_PHY_AGC_NUM * e1000_igp_cable_length_50) {
++ if(agc_value < IGP01E1000_PHY_CHANNEL_NUM * e1000_igp_cable_length_50) {
+ agc_value -= min_agc;
+
+ /* Get the average length of the remaining 3 channels */
+- agc_value /= (IGP01E1000_PHY_AGC_NUM - 1);
++ agc_value /= (IGP01E1000_PHY_CHANNEL_NUM - 1);
+ } else {
+ /* Get the average length of all the 4 channels. */
+- agc_value /= IGP01E1000_PHY_AGC_NUM;
++ agc_value /= IGP01E1000_PHY_CHANNEL_NUM;
+ }
+
+ /* Set the range of the calculated length. */
+@@ -4439,7 +4668,8 @@
+ * polarity - output parameter : 0 - Polarity is not reversed
+ * 1 - Polarity is reversed.
+ *
+- * returns: E1000_SUCCESS / -E1000_ERR_XXX
++ * returns: - E1000_ERR_XXX
++ * E1000_SUCCESS
+ *
+ * For phy's older then IGP, this function simply reads the polarity bit in the
+ * Phy Status register. For IGP phy's, this bit is valid only if link speed is
+@@ -4448,22 +4678,26 @@
+ * IGP01E1000_PHY_PCS_INIT_REG.
+ *****************************************************************************/
+ int32_t
+-e1000_check_polarity(struct e1000_hw *hw, uint16_t *polarity)
++e1000_check_polarity(struct e1000_hw *hw,
++ uint16_t *polarity)
+ {
++ int32_t ret_val;
+ uint16_t phy_data;
+
+ DEBUGFUNC("e1000_check_polarity");
+
+ if(hw->phy_type == e1000_phy_m88) {
+ /* return the Polarity bit in the Status register. */
+- if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0)
+- return -E1000_ERR_PHY;
++ if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
++ &phy_data)))
++ return ret_val;
+ *polarity = (phy_data & M88E1000_PSSR_REV_POLARITY) >>
+ M88E1000_PSSR_REV_POLARITY_SHIFT;
+ } else if(hw->phy_type == e1000_phy_igp) {
+ /* Read the Status register to check the speed */
+- if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &phy_data) < 0)
+- return -E1000_ERR_PHY;
++ if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
++ &phy_data)))
++ return ret_val;
+
+ /* If speed is 1000 Mbps, must read the IGP01E1000_PHY_PCS_INIT_REG to
+ * find the polarity status */
+@@ -4471,18 +4705,9 @@
+ IGP01E1000_PSSR_SPEED_1000MBPS) {
+
+ /* Read the GIG initialization PCS register (0x00B4) */
+- if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT,
+- IGP01E1000_PHY_PCS_INIT_REG) < 0)
+- return -E1000_ERR_PHY;
+-
+- if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PCS_INIT_REG &
+- IGP01E1000_PHY_PAGE_SELECT, &phy_data) < 0)
+- return -E1000_ERR_PHY;
+-
+- /* Return to page 0 */
+- if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 0x0) !=
+- E1000_SUCCESS)
+- return -E1000_ERR_PHY;
++ if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PCS_INIT_REG,
++ &phy_data)))
++ return ret_val;
+
+ /* Check the polarity bits */
+ *polarity = (phy_data & IGP01E1000_PHY_POLARITY_MASK) ? 1 : 0;
+@@ -4502,7 +4727,8 @@
+ * downshift - output parameter : 0 - No Downshift ocured.
+ * 1 - Downshift ocured.
+ *
+- * returns: E1000_SUCCESS / -E1000_ERR_XXX
++ * returns: - E1000_ERR_XXX
++ * E1000_SUCCESS
+ *
+ * For phy's older then IGP, this function reads the Downshift bit in the Phy
+ * Specific Status register. For IGP phy's, it reads the Downgrade bit in the
+@@ -4512,25 +4738,287 @@
+ int32_t
+ e1000_check_downshift(struct e1000_hw *hw)
+ {
++ int32_t ret_val;
+ uint16_t phy_data;
+
+ DEBUGFUNC("e1000_check_downshift");
+
+ if(hw->phy_type == e1000_phy_igp) {
+- if(e1000_read_phy_reg(hw, IGP01E1000_PHY_LINK_HEALTH, &phy_data) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
+- }
++ if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_LINK_HEALTH,
++ &phy_data)))
++ return ret_val;
++
+ hw->speed_downgraded = (phy_data & IGP01E1000_PLHR_SS_DOWNGRADE) ? 1 : 0;
+ }
+ else if(hw->phy_type == e1000_phy_m88) {
+- if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0) {
+- DEBUGOUT("PHY Read Error\n");
+- return -E1000_ERR_PHY;
+- }
++ if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
++ &phy_data)))
++ return ret_val;
++
+ hw->speed_downgraded = (phy_data & M88E1000_PSSR_DOWNSHIFT) >>
+- M88E1000_PSSR_DOWNSHIFT_SHIFT;
++ M88E1000_PSSR_DOWNSHIFT_SHIFT;
+ }
+ return E1000_SUCCESS;
+ }
+
++/*****************************************************************************
++ *
++ * 82541_rev_2 & 82547_rev_2 have the capability to configure the DSP when a
++ * gigabit link is achieved to improve link quality.
++ *
++ * hw: Struct containing variables accessed by shared code
++ *
++ * returns: - E1000_ERR_PHY if fail to read/write the PHY
++ * E1000_SUCCESS at any other case.
++ *
++ ****************************************************************************/
++
++int32_t
++e1000_config_dsp_after_link_change(struct e1000_hw *hw,
++ boolean_t link_up)
++{
++ int32_t ret_val;
++ uint16_t phy_data, speed, duplex, i;
++ uint16_t dsp_reg_array[IGP01E1000_PHY_CHANNEL_NUM] =
++ {IGP01E1000_PHY_AGC_PARAM_A,
++ IGP01E1000_PHY_AGC_PARAM_B,
++ IGP01E1000_PHY_AGC_PARAM_C,
++ IGP01E1000_PHY_AGC_PARAM_D};
++ uint16_t min_length, max_length;
++
++ DEBUGFUNC("e1000_config_dsp_after_link_change");
++
++ if(hw->phy_type != e1000_phy_igp)
++ return E1000_SUCCESS;
++
++ if(link_up) {
++ if((ret_val = e1000_get_speed_and_duplex(hw, &speed, &duplex))) {
++ DEBUGOUT("Error getting link speed and duplex\n");
++ return ret_val;
++ }
++
++ if(speed == SPEED_1000) {
++
++ e1000_get_cable_length(hw, &min_length, &max_length);
++
++ if((hw->dsp_config_state == e1000_dsp_config_enabled) &&
++ min_length >= e1000_igp_cable_length_50) {
++
++ for(i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
++ if((ret_val = e1000_read_phy_reg(hw, dsp_reg_array[i],
++ &phy_data)))
++ return ret_val;
++
++ phy_data &= ~IGP01E1000_PHY_EDAC_MU_INDEX;
++
++ if((ret_val = e1000_write_phy_reg(hw, dsp_reg_array[i],
++ phy_data)))
++ return ret_val;
++ }
++ hw->dsp_config_state = e1000_dsp_config_activated;
++ }
++
++ if((hw->ffe_config_state == e1000_ffe_config_enabled) &&
++ (min_length < e1000_igp_cable_length_50)) {
++
++ uint16_t ffe_idle_err_timeout = FFE_IDLE_ERR_COUNT_TIMEOUT_20;
++ uint32_t idle_errs = 0;
++
++ /* clear previous idle error counts */
++ if((ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS,
++ &phy_data)))
++ return ret_val;
++
++ for(i = 0; i < ffe_idle_err_timeout; i++) {
++ udelay(1000);
++ if((ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS,
++ &phy_data)))
++ return ret_val;
++
++ idle_errs += (phy_data & SR_1000T_IDLE_ERROR_CNT);
++ if(idle_errs > SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT) {
++ hw->ffe_config_state = e1000_ffe_config_active;
++
++ if((ret_val = e1000_write_phy_reg(hw,
++ IGP01E1000_PHY_DSP_FFE,
++ IGP01E1000_PHY_DSP_FFE_CM_CP)))
++ return ret_val;
++ break;
++ }
++
++ if(idle_errs)
++ ffe_idle_err_timeout = FFE_IDLE_ERR_COUNT_TIMEOUT_100;
++ }
++ }
++ }
++ } else {
++ if(hw->dsp_config_state == e1000_dsp_config_activated) {
++ if((ret_val = e1000_write_phy_reg(hw, 0x0000,
++ IGP01E1000_IEEE_FORCE_GIGA)))
++ return ret_val;
++ for(i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
++ if((ret_val = e1000_read_phy_reg(hw, dsp_reg_array[i],
++ &phy_data)))
++ return ret_val;
++
++ phy_data &= ~IGP01E1000_PHY_EDAC_MU_INDEX;
++ phy_data |= IGP01E1000_PHY_EDAC_SIGN_EXT_9_BITS;
++
++ if((ret_val = e1000_write_phy_reg(hw,dsp_reg_array[i],
++ phy_data)))
++ return ret_val;
++ }
++
++ if((ret_val = e1000_write_phy_reg(hw, 0x0000,
++ IGP01E1000_IEEE_RESTART_AUTONEG)))
++ return ret_val;
++
++ hw->dsp_config_state = e1000_dsp_config_enabled;
++ }
++
++ if(hw->ffe_config_state == e1000_ffe_config_active) {
++ if((ret_val = e1000_write_phy_reg(hw, 0x0000,
++ IGP01E1000_IEEE_FORCE_GIGA)))
++ return ret_val;
++ if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_DSP_FFE,
++ IGP01E1000_PHY_DSP_FFE_DEFAULT)))
++ return ret_val;
++
++ if((ret_val = e1000_write_phy_reg(hw, 0x0000,
++ IGP01E1000_IEEE_RESTART_AUTONEG)))
++ return ret_val;
++ hw->ffe_config_state = e1000_ffe_config_enabled;
++ }
++ }
++ return E1000_SUCCESS;
++}
++
++/*****************************************************************************
++ *
++ * This function sets the lplu state according to the active flag. When
++ * activating lplu this function also disables smart speed and vise versa.
++ * lplu will not be activated unless the device autonegotiation advertisment
++ * meets standards of either 10 or 10/100 or 10/100/1000 at all duplexes.
++ * hw: Struct containing variables accessed by shared code
++ * active - true to enable lplu false to disable lplu.
++ *
++ * returns: - E1000_ERR_PHY if fail to read/write the PHY
++ * E1000_SUCCESS at any other case.
++ *
++ ****************************************************************************/
++
++int32_t
++e1000_set_d3_lplu_state(struct e1000_hw *hw,
++ boolean_t active)
++{
++ int32_t ret_val;
++ uint16_t phy_data;
++ DEBUGFUNC("e1000_set_d3_lplu_state");
++
++ if(!((hw->mac_type == e1000_82541_rev_2) ||
++ (hw->mac_type == e1000_82547_rev_2)))
++ return E1000_SUCCESS;
++
++ /* During driver activity LPLU should not be used or it will attain link
++ * from the lowest speeds starting from 10Mbps. The capability is used for
++ * Dx transitions and states */
++ if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO, &phy_data)))
++ return ret_val;
++
++ if(!active) {
++ phy_data &= ~IGP01E1000_GMII_FLEX_SPD;
++ if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data)))
++ return ret_val;
++
++ /* LPLU and SmartSpeed are mutually exclusive. LPLU is used during
++ * Dx states where the power conservation is most important. During
++ * driver activity we should enable SmartSpeed, so performance is
++ * maintained. */
++ if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
++ &phy_data)))
++ return ret_val;
++
++ phy_data |= IGP01E1000_PSCFR_SMART_SPEED;
++ if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
++ phy_data)))
++ return ret_val;
++
++ } else if((hw->autoneg_advertised == AUTONEG_ADVERTISE_SPEED_DEFAULT) ||
++ (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_ALL ) ||
++ (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_100_ALL)) {
++
++ phy_data |= IGP01E1000_GMII_FLEX_SPD;
++ if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data)))
++ return ret_val;
++
++ /* When LPLU is enabled we should disable SmartSpeed */
++ if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
++ &phy_data)))
++ return ret_val;
++
++ phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
++ if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
++ phy_data)))
++ return ret_val;
++
++ }
++ return E1000_SUCCESS;
++}
++
++/******************************************************************************
++ * Change VCO speed register to improve Bit Error Rate performance of SERDES.
++ *
++ * hw - Struct containing variables accessed by shared code
++ *****************************************************************************/
++static int32_t
++e1000_set_vco_speed(struct e1000_hw *hw)
++{
++ int32_t ret_val;
++ uint16_t default_page = 0;
++ uint16_t phy_data;
++
++ DEBUGFUNC("e1000_set_vco_speed");
++
++ switch(hw->mac_type) {
++ case e1000_82545_rev_3:
++ case e1000_82546_rev_3:
++ break;
++ default:
++ return E1000_SUCCESS;
++ }
++
++ /* Set PHY register 30, page 5, bit 8 to 0 */
++
++ if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_PAGE_SELECT,
++ &default_page)))
++ return ret_val;
++
++ if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0005)))
++ return ret_val;
++
++ if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data)))
++ return ret_val;
++
++ phy_data &= ~M88E1000_PHY_VCO_REG_BIT8;
++ if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data)))
++ return ret_val;
++
++ /* Set PHY register 30, page 4, bit 11 to 1 */
++
++ if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0004)))
++ return ret_val;
++
++ if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data)))
++ return ret_val;
++
++ phy_data |= M88E1000_PHY_VCO_REG_BIT11;
++ if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data)))
++ return ret_val;
++
++ if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT,
++ default_page)))
++ return ret_val;
++
++ return E1000_SUCCESS;
++}
++
+Index: linux-2.6.0-test5/drivers/net/e1000/e1000_hw.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/e1000/e1000_hw.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/e1000/e1000_hw.h 2003-09-27 11:38:25.283684680 +0800
+@@ -33,9 +33,9 @@
+ #ifndef _E1000_HW_H_
+ #define _E1000_HW_H_
+
+-
+ #include "e1000_osdep.h"
+
++
+ /* Forward declarations of structures used by the shared code */
+ struct e1000_hw;
+ struct e1000_hw_stats;
+@@ -50,9 +50,13 @@
+ e1000_82544,
+ e1000_82540,
+ e1000_82545,
++ e1000_82545_rev_3,
+ e1000_82546,
++ e1000_82546_rev_3,
+ e1000_82541,
++ e1000_82541_rev_2,
+ e1000_82547,
++ e1000_82547_rev_2,
+ e1000_num_macs
+ } e1000_mac_type;
+
+@@ -67,6 +71,7 @@
+ typedef enum {
+ e1000_media_type_copper = 0,
+ e1000_media_type_fiber = 1,
++ e1000_media_type_internal_serdes = 2,
+ e1000_num_media_types
+ } e1000_media_type;
+
+@@ -90,7 +95,8 @@
+ typedef enum {
+ e1000_bus_type_unknown = 0,
+ e1000_bus_type_pci,
+- e1000_bus_type_pcix
++ e1000_bus_type_pcix,
++ e1000_bus_type_reserved
+ } e1000_bus_type;
+
+ /* PCI bus speeds */
+@@ -108,7 +114,8 @@
+ typedef enum {
+ e1000_bus_width_unknown = 0,
+ e1000_bus_width_32,
+- e1000_bus_width_64
++ e1000_bus_width_64,
++ e1000_bus_width_reserved
+ } e1000_bus_width;
+
+ /* PHY status info structure and supporting enums */
+@@ -186,6 +193,26 @@
+ e1000_phy_undefined = 0xFF
+ } e1000_phy_type;
+
++typedef enum {
++ e1000_ms_hw_default = 0,
++ e1000_ms_force_master,
++ e1000_ms_force_slave,
++ e1000_ms_auto
++} e1000_ms_type;
++
++typedef enum {
++ e1000_ffe_config_enabled = 0,
++ e1000_ffe_config_active,
++ e1000_ffe_config_blocked
++} e1000_ffe_config;
++
++typedef enum {
++ e1000_dsp_config_disabled = 0,
++ e1000_dsp_config_enabled,
++ e1000_dsp_config_activated,
++ e1000_dsp_config_undefined = 0xFF
++} e1000_dsp_config;
++
+ struct e1000_phy_info {
+ e1000_cable_length cable_length;
+ e1000_10bt_ext_dist_enable extended_10bt_distance;
+@@ -224,9 +251,10 @@
+
+ /* Function prototypes */
+ /* Initialization */
+-void e1000_reset_hw(struct e1000_hw *hw);
++int32_t e1000_reset_hw(struct e1000_hw *hw);
+ int32_t e1000_init_hw(struct e1000_hw *hw);
+ int32_t e1000_set_mac_type(struct e1000_hw *hw);
++void e1000_set_media_type(struct e1000_hw *hw);
+
+ /* Link Configuration */
+ int32_t e1000_setup_link(struct e1000_hw *hw);
+@@ -234,8 +262,9 @@
+ void e1000_config_collision_dist(struct e1000_hw *hw);
+ int32_t e1000_config_fc_after_link_up(struct e1000_hw *hw);
+ int32_t e1000_check_for_link(struct e1000_hw *hw);
+-void e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t * speed, uint16_t * duplex);
++int32_t e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t * speed, uint16_t * duplex);
+ int32_t e1000_wait_autoneg(struct e1000_hw *hw);
++int32_t e1000_force_mac_fc(struct e1000_hw *hw);
+
+ /* PHY */
+ int32_t e1000_read_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t *phy_data);
+@@ -292,6 +321,8 @@
+ uint32_t e1000_read_reg_io(struct e1000_hw *hw, uint32_t offset);
+ void e1000_io_write(struct e1000_hw *hw, uint32_t port, uint32_t value);
+ void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset, uint32_t value);
++int32_t e1000_config_dsp_after_link_change(struct e1000_hw *hw, boolean_t link_up);
++int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active);
+
+ #define E1000_READ_REG_IO(a, reg) \
+ e1000_read_reg_io((a), E1000_##reg)
+@@ -313,13 +344,22 @@
+ #define E1000_DEV_ID_82540EP_LP 0x101E
+ #define E1000_DEV_ID_82545EM_COPPER 0x100F
+ #define E1000_DEV_ID_82545EM_FIBER 0x1011
++#define E1000_DEV_ID_82545GM_COPPER 0x1026
++#define E1000_DEV_ID_82545GM_FIBER 0x1027
++#define E1000_DEV_ID_82545GM_SERDES 0x1028
+ #define E1000_DEV_ID_82546EB_COPPER 0x1010
+ #define E1000_DEV_ID_82546EB_FIBER 0x1012
+ #define E1000_DEV_ID_82546EB_QUAD_COPPER 0x101D
+ #define E1000_DEV_ID_82541EI 0x1013
+-#define E1000_DEV_ID_82541EP 0x1018
++#define E1000_DEV_ID_82541EI_MOBILE 0x1018
++#define E1000_DEV_ID_82541ER 0x1078
++#define E1000_DEV_ID_82547GI 0x1075
++#define E1000_DEV_ID_82541GI 0x1076
++#define E1000_DEV_ID_82541GI_MOBILE 0x1077
++#define E1000_DEV_ID_82546GB_COPPER 0x1079
++#define E1000_DEV_ID_82546GB_FIBER 0x107A
++#define E1000_DEV_ID_82546GB_SERDES 0x107B
+ #define E1000_DEV_ID_82547EI 0x1019
+-#define NUM_DEV_IDS 20
+
+ #define NODE_ADDRESS_SIZE 6
+ #define ETH_LENGTH_OF_ADDRESS 6
+@@ -385,7 +425,7 @@
+ E1000_IMS_RXSEQ | \
+ E1000_IMS_LSC)
+
+-/* The number of high/low register pairs in the RAR. The RAR (Receive Address
++/* Number of high/low register pairs in the RAR. The RAR (Receive Address
+ * Registers) holds the directed and multicast addresses that we monitor. We
+ * reserve one of these spots for our directed address, allowing us room for
+ * E1000_RAR_ENTRIES - 1 multicast addresses.
+@@ -539,7 +579,7 @@
+ volatile uint32_t high; /* receive address high */
+ };
+
+-/* The number of entries in the Multicast Table Array (MTA). */
++/* Number of entries in the Multicast Table Array (MTA). */
+ #define E1000_NUM_MTA_REGISTERS 128
+
+ /* IPv4 Address Table Entry */
+@@ -599,6 +639,7 @@
+ * A - register array
+ */
+ #define E1000_CTRL 0x00000 /* Device Control - RW */
++#define E1000_CTRL_DUP 0x00004 /* Device Control Duplicate (Shadow) - RW */
+ #define E1000_STATUS 0x00008 /* Device Status - RO */
+ #define E1000_EECD 0x00010 /* EEPROM/Flash Control - RW */
+ #define E1000_EERD 0x00014 /* EEPROM Read - RW */
+@@ -934,6 +975,9 @@
+ e1000_bus_width bus_width;
+ e1000_bus_type bus_type;
+ struct e1000_eeprom_info eeprom;
++ e1000_ms_type master_slave;
++ e1000_ms_type original_master_slave;
++ e1000_ffe_config ffe_config_state;
+ uint32_t io_base;
+ uint32_t phy_id;
+ uint32_t phy_revision;
+@@ -950,6 +994,8 @@
+ uint32_t ledctl_default;
+ uint32_t ledctl_mode1;
+ uint32_t ledctl_mode2;
++ uint16_t phy_spd_default;
++ uint16_t dsp_reset_counter;
+ uint16_t autoneg_advertised;
+ uint16_t pci_cmd_word;
+ uint16_t fc_high_water;
+@@ -974,10 +1020,13 @@
+ uint8_t perm_mac_addr[NODE_ADDRESS_SIZE];
+ boolean_t disable_polarity_correction;
+ boolean_t speed_downgraded;
++ e1000_dsp_config dsp_config_state;
+ boolean_t get_link_status;
+ boolean_t tbi_compatibility_en;
+ boolean_t tbi_compatibility_on;
++ boolean_t phy_reset_disable;
+ boolean_t fc_send_xon;
++ boolean_t fc_strict_ieee;
+ boolean_t report_tx_early;
+ boolean_t adaptive_ifs;
+ boolean_t ifs_params_forced;
+@@ -1059,7 +1108,7 @@
+ #define E1000_EECD_PRES 0x00000100 /* EEPROM Present */
+ #define E1000_EECD_SIZE 0x00000200 /* EEPROM Size (0=64 word 1=256 word) */
+ #define E1000_EECD_ADDR_BITS 0x00000400 /* EEPROM Addressing bits based on type
+- * (0-small, 1-large) */
++ * (0-small, 1-large) */
+ #define E1000_EECD_TYPE 0x00002000 /* EEPROM Type (1-SPI, 0-Microwire) */
+ #ifndef E1000_EEPROM_GRANT_ATTEMPTS
+ #define E1000_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM # attempts to gain grant */
+@@ -1121,22 +1170,22 @@
+ #define E1000_MDIC_ERROR 0x40000000
+
+ /* LED Control */
+-#define E1000_LEDCTL_LED0_MODE_MASK 0x0000000F
+-#define E1000_LEDCTL_LED0_MODE_SHIFT 0
+-#define E1000_LEDCTL_LED0_IVRT 0x00000040
+-#define E1000_LEDCTL_LED0_BLINK 0x00000080
+-#define E1000_LEDCTL_LED1_MODE_MASK 0x00000F00
+-#define E1000_LEDCTL_LED1_MODE_SHIFT 8
+-#define E1000_LEDCTL_LED1_IVRT 0x00004000
+-#define E1000_LEDCTL_LED1_BLINK 0x00008000
+-#define E1000_LEDCTL_LED2_MODE_MASK 0x000F0000
+-#define E1000_LEDCTL_LED2_MODE_SHIFT 16
+-#define E1000_LEDCTL_LED2_IVRT 0x00400000
+-#define E1000_LEDCTL_LED2_BLINK 0x00800000
+-#define E1000_LEDCTL_LED3_MODE_MASK 0x0F000000
+-#define E1000_LEDCTL_LED3_MODE_SHIFT 24
+-#define E1000_LEDCTL_LED3_IVRT 0x40000000
+-#define E1000_LEDCTL_LED3_BLINK 0x80000000
++#define E1000_LEDCTL_LED0_MODE_MASK 0x0000000F
++#define E1000_LEDCTL_LED0_MODE_SHIFT 0
++#define E1000_LEDCTL_LED0_IVRT 0x00000040
++#define E1000_LEDCTL_LED0_BLINK 0x00000080
++#define E1000_LEDCTL_LED1_MODE_MASK 0x00000F00
++#define E1000_LEDCTL_LED1_MODE_SHIFT 8
++#define E1000_LEDCTL_LED1_IVRT 0x00004000
++#define E1000_LEDCTL_LED1_BLINK 0x00008000
++#define E1000_LEDCTL_LED2_MODE_MASK 0x000F0000
++#define E1000_LEDCTL_LED2_MODE_SHIFT 16
++#define E1000_LEDCTL_LED2_IVRT 0x00400000
++#define E1000_LEDCTL_LED2_BLINK 0x00800000
++#define E1000_LEDCTL_LED3_MODE_MASK 0x0F000000
++#define E1000_LEDCTL_LED3_MODE_SHIFT 24
++#define E1000_LEDCTL_LED3_IVRT 0x40000000
++#define E1000_LEDCTL_LED3_BLINK 0x80000000
+
+ #define E1000_LEDCTL_MODE_LINK_10_1000 0x0
+ #define E1000_LEDCTL_MODE_LINK_100_1000 0x1
+@@ -1159,109 +1208,109 @@
+ #define E1000_RAH_AV 0x80000000 /* Receive descriptor valid */
+
+ /* Interrupt Cause Read */
+-#define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */
+-#define E1000_ICR_TXQE 0x00000002 /* Transmit Queue empty */
+-#define E1000_ICR_LSC 0x00000004 /* Link Status Change */
+-#define E1000_ICR_RXSEQ 0x00000008 /* rx sequence error */
+-#define E1000_ICR_RXDMT0 0x00000010 /* rx desc min. threshold (0) */
+-#define E1000_ICR_RXO 0x00000040 /* rx overrun */
+-#define E1000_ICR_RXT0 0x00000080 /* rx timer intr (ring 0) */
+-#define E1000_ICR_MDAC 0x00000200 /* MDIO access complete */
+-#define E1000_ICR_RXCFG 0x00000400 /* RX /c/ ordered set */
+-#define E1000_ICR_GPI_EN0 0x00000800 /* GP Int 0 */
+-#define E1000_ICR_GPI_EN1 0x00001000 /* GP Int 1 */
+-#define E1000_ICR_GPI_EN2 0x00002000 /* GP Int 2 */
+-#define E1000_ICR_GPI_EN3 0x00004000 /* GP Int 3 */
+-#define E1000_ICR_TXD_LOW 0x00008000
+-#define E1000_ICR_SRPD 0x00010000
++#define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */
++#define E1000_ICR_TXQE 0x00000002 /* Transmit Queue empty */
++#define E1000_ICR_LSC 0x00000004 /* Link Status Change */
++#define E1000_ICR_RXSEQ 0x00000008 /* rx sequence error */
++#define E1000_ICR_RXDMT0 0x00000010 /* rx desc min. threshold (0) */
++#define E1000_ICR_RXO 0x00000040 /* rx overrun */
++#define E1000_ICR_RXT0 0x00000080 /* rx timer intr (ring 0) */
++#define E1000_ICR_MDAC 0x00000200 /* MDIO access complete */
++#define E1000_ICR_RXCFG 0x00000400 /* RX /c/ ordered set */
++#define E1000_ICR_GPI_EN0 0x00000800 /* GP Int 0 */
++#define E1000_ICR_GPI_EN1 0x00001000 /* GP Int 1 */
++#define E1000_ICR_GPI_EN2 0x00002000 /* GP Int 2 */
++#define E1000_ICR_GPI_EN3 0x00004000 /* GP Int 3 */
++#define E1000_ICR_TXD_LOW 0x00008000
++#define E1000_ICR_SRPD 0x00010000
+
+ /* Interrupt Cause Set */
+-#define E1000_ICS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
+-#define E1000_ICS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */
+-#define E1000_ICS_LSC E1000_ICR_LSC /* Link Status Change */
+-#define E1000_ICS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
+-#define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
+-#define E1000_ICS_RXO E1000_ICR_RXO /* rx overrun */
+-#define E1000_ICS_RXT0 E1000_ICR_RXT0 /* rx timer intr */
+-#define E1000_ICS_MDAC E1000_ICR_MDAC /* MDIO access complete */
+-#define E1000_ICS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */
+-#define E1000_ICS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */
+-#define E1000_ICS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */
+-#define E1000_ICS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */
+-#define E1000_ICS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */
+-#define E1000_ICS_TXD_LOW E1000_ICR_TXD_LOW
+-#define E1000_ICS_SRPD E1000_ICR_SRPD
++#define E1000_ICS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
++#define E1000_ICS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */
++#define E1000_ICS_LSC E1000_ICR_LSC /* Link Status Change */
++#define E1000_ICS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
++#define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
++#define E1000_ICS_RXO E1000_ICR_RXO /* rx overrun */
++#define E1000_ICS_RXT0 E1000_ICR_RXT0 /* rx timer intr */
++#define E1000_ICS_MDAC E1000_ICR_MDAC /* MDIO access complete */
++#define E1000_ICS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */
++#define E1000_ICS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */
++#define E1000_ICS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */
++#define E1000_ICS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */
++#define E1000_ICS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */
++#define E1000_ICS_TXD_LOW E1000_ICR_TXD_LOW
++#define E1000_ICS_SRPD E1000_ICR_SRPD
+
+ /* Interrupt Mask Set */
+-#define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
+-#define E1000_IMS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */
+-#define E1000_IMS_LSC E1000_ICR_LSC /* Link Status Change */
+-#define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
+-#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
+-#define E1000_IMS_RXO E1000_ICR_RXO /* rx overrun */
+-#define E1000_IMS_RXT0 E1000_ICR_RXT0 /* rx timer intr */
+-#define E1000_IMS_MDAC E1000_ICR_MDAC /* MDIO access complete */
+-#define E1000_IMS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */
+-#define E1000_IMS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */
+-#define E1000_IMS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */
+-#define E1000_IMS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */
+-#define E1000_IMS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */
+-#define E1000_IMS_TXD_LOW E1000_ICR_TXD_LOW
+-#define E1000_IMS_SRPD E1000_ICR_SRPD
++#define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
++#define E1000_IMS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */
++#define E1000_IMS_LSC E1000_ICR_LSC /* Link Status Change */
++#define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
++#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
++#define E1000_IMS_RXO E1000_ICR_RXO /* rx overrun */
++#define E1000_IMS_RXT0 E1000_ICR_RXT0 /* rx timer intr */
++#define E1000_IMS_MDAC E1000_ICR_MDAC /* MDIO access complete */
++#define E1000_IMS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */
++#define E1000_IMS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */
++#define E1000_IMS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */
++#define E1000_IMS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */
++#define E1000_IMS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */
++#define E1000_IMS_TXD_LOW E1000_ICR_TXD_LOW
++#define E1000_IMS_SRPD E1000_ICR_SRPD
+
+ /* Interrupt Mask Clear */
+-#define E1000_IMC_TXDW E1000_ICR_TXDW /* Transmit desc written back */
+-#define E1000_IMC_TXQE E1000_ICR_TXQE /* Transmit Queue empty */
+-#define E1000_IMC_LSC E1000_ICR_LSC /* Link Status Change */
+-#define E1000_IMC_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
+-#define E1000_IMC_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
+-#define E1000_IMC_RXO E1000_ICR_RXO /* rx overrun */
+-#define E1000_IMC_RXT0 E1000_ICR_RXT0 /* rx timer intr */
+-#define E1000_IMC_MDAC E1000_ICR_MDAC /* MDIO access complete */
+-#define E1000_IMC_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */
+-#define E1000_IMC_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */
+-#define E1000_IMC_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */
+-#define E1000_IMC_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */
+-#define E1000_IMC_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */
+-#define E1000_IMC_TXD_LOW E1000_ICR_TXD_LOW
+-#define E1000_IMC_SRPD E1000_ICR_SRPD
++#define E1000_IMC_TXDW E1000_ICR_TXDW /* Transmit desc written back */
++#define E1000_IMC_TXQE E1000_ICR_TXQE /* Transmit Queue empty */
++#define E1000_IMC_LSC E1000_ICR_LSC /* Link Status Change */
++#define E1000_IMC_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
++#define E1000_IMC_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
++#define E1000_IMC_RXO E1000_ICR_RXO /* rx overrun */
++#define E1000_IMC_RXT0 E1000_ICR_RXT0 /* rx timer intr */
++#define E1000_IMC_MDAC E1000_ICR_MDAC /* MDIO access complete */
++#define E1000_IMC_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */
++#define E1000_IMC_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */
++#define E1000_IMC_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */
++#define E1000_IMC_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */
++#define E1000_IMC_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */
++#define E1000_IMC_TXD_LOW E1000_ICR_TXD_LOW
++#define E1000_IMC_SRPD E1000_ICR_SRPD
+
+ /* Receive Control */
+-#define E1000_RCTL_RST 0x00000001 /* Software reset */
+-#define E1000_RCTL_EN 0x00000002 /* enable */
+-#define E1000_RCTL_SBP 0x00000004 /* store bad packet */
+-#define E1000_RCTL_UPE 0x00000008 /* unicast promiscuous enable */
+-#define E1000_RCTL_MPE 0x00000010 /* multicast promiscuous enab */
+-#define E1000_RCTL_LPE 0x00000020 /* long packet enable */
+-#define E1000_RCTL_LBM_NO 0x00000000 /* no loopback mode */
+-#define E1000_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */
+-#define E1000_RCTL_LBM_SLP 0x00000080 /* serial link loopback mode */
+-#define E1000_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */
+-#define E1000_RCTL_RDMTS_HALF 0x00000000 /* rx desc min threshold size */
+-#define E1000_RCTL_RDMTS_QUAT 0x00000100 /* rx desc min threshold size */
+-#define E1000_RCTL_RDMTS_EIGTH 0x00000200 /* rx desc min threshold size */
+-#define E1000_RCTL_MO_SHIFT 12 /* multicast offset shift */
+-#define E1000_RCTL_MO_0 0x00000000 /* multicast offset 11:0 */
+-#define E1000_RCTL_MO_1 0x00001000 /* multicast offset 12:1 */
+-#define E1000_RCTL_MO_2 0x00002000 /* multicast offset 13:2 */
+-#define E1000_RCTL_MO_3 0x00003000 /* multicast offset 15:4 */
+-#define E1000_RCTL_MDR 0x00004000 /* multicast desc ring 0 */
+-#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */
++#define E1000_RCTL_RST 0x00000001 /* Software reset */
++#define E1000_RCTL_EN 0x00000002 /* enable */
++#define E1000_RCTL_SBP 0x00000004 /* store bad packet */
++#define E1000_RCTL_UPE 0x00000008 /* unicast promiscuous enable */
++#define E1000_RCTL_MPE 0x00000010 /* multicast promiscuous enab */
++#define E1000_RCTL_LPE 0x00000020 /* long packet enable */
++#define E1000_RCTL_LBM_NO 0x00000000 /* no loopback mode */
++#define E1000_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */
++#define E1000_RCTL_LBM_SLP 0x00000080 /* serial link loopback mode */
++#define E1000_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */
++#define E1000_RCTL_RDMTS_HALF 0x00000000 /* rx desc min threshold size */
++#define E1000_RCTL_RDMTS_QUAT 0x00000100 /* rx desc min threshold size */
++#define E1000_RCTL_RDMTS_EIGTH 0x00000200 /* rx desc min threshold size */
++#define E1000_RCTL_MO_SHIFT 12 /* multicast offset shift */
++#define E1000_RCTL_MO_0 0x00000000 /* multicast offset 11:0 */
++#define E1000_RCTL_MO_1 0x00001000 /* multicast offset 12:1 */
++#define E1000_RCTL_MO_2 0x00002000 /* multicast offset 13:2 */
++#define E1000_RCTL_MO_3 0x00003000 /* multicast offset 15:4 */
++#define E1000_RCTL_MDR 0x00004000 /* multicast desc ring 0 */
++#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */
+ /* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */
+-#define E1000_RCTL_SZ_2048 0x00000000 /* rx buffer size 2048 */
+-#define E1000_RCTL_SZ_1024 0x00010000 /* rx buffer size 1024 */
+-#define E1000_RCTL_SZ_512 0x00020000 /* rx buffer size 512 */
+-#define E1000_RCTL_SZ_256 0x00030000 /* rx buffer size 256 */
++#define E1000_RCTL_SZ_2048 0x00000000 /* rx buffer size 2048 */
++#define E1000_RCTL_SZ_1024 0x00010000 /* rx buffer size 1024 */
++#define E1000_RCTL_SZ_512 0x00020000 /* rx buffer size 512 */
++#define E1000_RCTL_SZ_256 0x00030000 /* rx buffer size 256 */
+ /* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */
+-#define E1000_RCTL_SZ_16384 0x00010000 /* rx buffer size 16384 */
+-#define E1000_RCTL_SZ_8192 0x00020000 /* rx buffer size 8192 */
+-#define E1000_RCTL_SZ_4096 0x00030000 /* rx buffer size 4096 */
+-#define E1000_RCTL_VFE 0x00040000 /* vlan filter enable */
+-#define E1000_RCTL_CFIEN 0x00080000 /* canonical form enable */
+-#define E1000_RCTL_CFI 0x00100000 /* canonical form indicator */
+-#define E1000_RCTL_DPF 0x00400000 /* discard pause frames */
+-#define E1000_RCTL_PMCF 0x00800000 /* pass MAC control frames */
+-#define E1000_RCTL_BSEX 0x02000000 /* Buffer size extension */
++#define E1000_RCTL_SZ_16384 0x00010000 /* rx buffer size 16384 */
++#define E1000_RCTL_SZ_8192 0x00020000 /* rx buffer size 8192 */
++#define E1000_RCTL_SZ_4096 0x00030000 /* rx buffer size 4096 */
++#define E1000_RCTL_VFE 0x00040000 /* vlan filter enable */
++#define E1000_RCTL_CFIEN 0x00080000 /* canonical form enable */
++#define E1000_RCTL_CFI 0x00100000 /* canonical form indicator */
++#define E1000_RCTL_DPF 0x00400000 /* discard pause frames */
++#define E1000_RCTL_PMCF 0x00800000 /* pass MAC control frames */
++#define E1000_RCTL_BSEX 0x02000000 /* Buffer size extension */
+
+ /* Receive Descriptor */
+ #define E1000_RDT_DELAY 0x0000ffff /* Delay timer (1=1024us) */
+@@ -1426,15 +1475,17 @@
+ #define EEPROM_SIZE_128B 0x0000
+ #define EEPROM_SIZE_MASK 0x1C00
+
+-
+ /* EEPROM Word Offsets */
+-#define EEPROM_COMPAT 0x0003
+-#define EEPROM_ID_LED_SETTINGS 0x0004
+-#define EEPROM_INIT_CONTROL1_REG 0x000A
+-#define EEPROM_INIT_CONTROL2_REG 0x000F
+-#define EEPROM_CFG 0x0012
+-#define EEPROM_FLASH_VERSION 0x0032
+-#define EEPROM_CHECKSUM_REG 0x003F
++#define EEPROM_COMPAT 0x0003
++#define EEPROM_ID_LED_SETTINGS 0x0004
++#define EEPROM_SERDES_AMPLITUDE 0x0006 /* For SERDES output amplitude adjustment. */
++#define EEPROM_INIT_CONTROL1_REG 0x000A
++#define EEPROM_INIT_CONTROL2_REG 0x000F
++#define EEPROM_INIT_CONTROL3_PORT_B 0x0014
++#define EEPROM_INIT_CONTROL3_PORT_A 0x0024
++#define EEPROM_CFG 0x0012
++#define EEPROM_FLASH_VERSION 0x0032
++#define EEPROM_CHECKSUM_REG 0x003F
+
+ /* Word definitions for ID LED Settings */
+ #define ID_LED_RESERVED_0000 0x0000
+@@ -1458,6 +1509,9 @@
+ #define IGP_LED3_MODE 0x07000000
+
+
++/* Mask bits for SERDES amplitude adjustment in Word 6 of the EEPROM */
++#define EEPROM_SERDES_AMPLITUDE_MASK 0x000F
++
+ /* Mask bits for fields in Word 0x0a of the EEPROM */
+ #define EEPROM_WORD0A_ILOS 0x0010
+ #define EEPROM_WORD0A_SWDPIO 0x01E0
+@@ -1479,6 +1533,8 @@
+ #define EEPROM_NODE_ADDRESS_BYTE_0 0
+ #define EEPROM_PBA_BYTE_1 8
+
++#define EEPROM_RESERVED_WORD 0xFFFF
++
+ /* EEPROM Map Sizes (Byte Counts) */
+ #define PBA_SIZE 4
+
+@@ -1490,7 +1546,7 @@
+ #define E1000_HDX_COLLISION_DISTANCE E1000_COLLISION_DISTANCE
+ #define E1000_COLD_SHIFT 12
+
+-/* The number of Transmit and Receive Descriptors must be a multiple of 8 */
++/* Number of Transmit and Receive Descriptors must be a multiple of 8 */
+ #define REQ_TX_DESCRIPTOR_MULTIPLE 8
+ #define REQ_RX_DESCRIPTOR_MULTIPLE 8
+
+@@ -1557,35 +1613,30 @@
+ #define PCIX_STATUS_HI_MMRBC_2K 0x2
+
+
+-/* The number of bits that we need to shift right to move the "pause"
+- * bits from the EEPROM (bits 13:12) to the "pause" (bits 8:7) field
+- * in the TXCW register
++/* Number of bits required to shift right the "pause" bits from the
++ * EEPROM (bits 13:12) to the "pause" (bits 8:7) field in the TXCW register.
+ */
+ #define PAUSE_SHIFT 5
+
+-/* The number of bits that we need to shift left to move the "SWDPIO"
+- * bits from the EEPROM (bits 8:5) to the "SWDPIO" (bits 25:22) field
+- * in the CTRL register
++/* Number of bits required to shift left the "SWDPIO" bits from the
++ * EEPROM (bits 8:5) to the "SWDPIO" (bits 25:22) field in the CTRL register.
+ */
+ #define SWDPIO_SHIFT 17
+
+-/* The number of bits that we need to shift left to move the "SWDPIO_EXT"
+- * bits from the EEPROM word F (bits 7:4) to the bits 11:8 of The
+- * Extended CTRL register.
+- * in the CTRL register
++/* Number of bits required to shift left the "SWDPIO_EXT" bits from the
++ * EEPROM word F (bits 7:4) to the bits 11:8 of The Extended CTRL register.
+ */
+ #define SWDPIO__EXT_SHIFT 4
+
+-/* The number of bits that we need to shift left to move the "ILOS"
+- * bit from the EEPROM (bit 4) to the "ILOS" (bit 7) field
+- * in the CTRL register
++/* Number of bits required to shift left the "ILOS" bit from the EEPROM
++ * (bit 4) to the "ILOS" (bit 7) field in the CTRL register.
+ */
+ #define ILOS_SHIFT 3
+
+
+ #define RECEIVE_BUFFER_ALIGN_SIZE (256)
+
+-/* The number of milliseconds we wait for auto-negotiation to complete */
++/* Number of milliseconds we wait for auto-negotiation to complete */
+ #define LINK_UP_TIMEOUT 500
+
+ #define E1000_TX_BUFFER_SIZE ((uint32_t)1514)
+@@ -1668,7 +1719,16 @@
+ #define M88E1000_EXT_PHY_SPEC_CTRL 0x14 /* Extended PHY Specific Control */
+ #define M88E1000_RX_ERR_CNTR 0x15 /* Receive Error Counter */
+
++#define M88E1000_PHY_EXT_CTRL 0x1A /* PHY extend control register */
++#define M88E1000_PHY_PAGE_SELECT 0x1D /* Reg 29 for page number setting */
++#define M88E1000_PHY_GEN_CONTROL 0x1E /* Its meaning depends on reg 29 */
++#define M88E1000_PHY_VCO_REG_BIT8 0x100 /* Bits 8 & 11 are adjusted for */
++#define M88E1000_PHY_VCO_REG_BIT11 0x800 /* improved BER performance */
++
+ #define IGP01E1000_IEEE_REGS_PAGE 0x0000
++#define IGP01E1000_IEEE_RESTART_AUTONEG 0x3300
++#define IGP01E1000_IEEE_FORCE_GIGA 0x0140
++
+ /* IGP01E1000 Specific Registers */
+ #define IGP01E1000_PHY_PORT_CONFIG 0x10 /* PHY Specific Port Config Register */
+ #define IGP01E1000_PHY_PORT_STATUS 0x11 /* PHY Specific Status Register */
+@@ -1684,17 +1744,35 @@
+ #define IGP01E1000_PHY_AGC_C 0x1472
+ #define IGP01E1000_PHY_AGC_D 0x1872
+
+-/* Number of AGC registers */
+-#define IGP01E1000_PHY_AGC_NUM 4
++/* IGP01E1000 DSP Reset Register */
++#define IGP01E1000_PHY_DSP_RESET 0x1F33
++#define IGP01E1000_PHY_DSP_SET 0x1F71
++#define IGP01E1000_PHY_DSP_FFE 0x1F35
++
++#define IGP01E1000_PHY_CHANNEL_NUM 4
++#define IGP01E1000_PHY_AGC_PARAM_A 0x1171
++#define IGP01E1000_PHY_AGC_PARAM_B 0x1271
++#define IGP01E1000_PHY_AGC_PARAM_C 0x1471
++#define IGP01E1000_PHY_AGC_PARAM_D 0x1871
++
++#define IGP01E1000_PHY_EDAC_MU_INDEX 0xC000
++#define IGP01E1000_PHY_EDAC_SIGN_EXT_9_BITS 0x8000
++
++#define IGP01E1000_PHY_ANALOG_TX_STATE 0x2890
++#define IGP01E1000_PHY_ANALOG_CLASS_A 0x2000
++#define IGP01E1000_PHY_FORCE_ANALOG_ENABLE 0x0004
++#define IGP01E1000_PHY_DSP_FFE_CM_CP 0x0069
+
++#define IGP01E1000_PHY_DSP_FFE_DEFAULT 0x002A
+ /* IGP01E1000 PCS Initialization register - stores the polarity status when
+ * speed = 1000 Mbps. */
+ #define IGP01E1000_PHY_PCS_INIT_REG 0x00B4
++#define IGP01E1000_PHY_PCS_CTRL_REG 0x00B5
+
+ #define IGP01E1000_ANALOG_REGS_PAGE 0x20C0
+
+ #define MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */
+-
++#define MAX_PHY_MULTI_PAGE_REG 0xF /*Registers that are equal on all pages*/
+ /* PHY Control Register */
+ #define MII_CR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */
+ #define MII_CR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */
+@@ -1808,8 +1886,11 @@
+ #define SR_1000T_LOCAL_RX_STATUS 0x2000 /* Local receiver OK */
+ #define SR_1000T_MS_CONFIG_RES 0x4000 /* 1=Local TX is Master, 0=Slave */
+ #define SR_1000T_MS_CONFIG_FAULT 0x8000 /* Master/Slave config fault */
+-#define SR_1000T_REMOTE_RX_STATUS_SHIFT 12
+-#define SR_1000T_LOCAL_RX_STATUS_SHIFT 13
++#define SR_1000T_REMOTE_RX_STATUS_SHIFT 12
++#define SR_1000T_LOCAL_RX_STATUS_SHIFT 13
++#define SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT 5
++#define FFE_IDLE_ERR_COUNT_TIMEOUT_20 20
++#define FFE_IDLE_ERR_COUNT_TIMEOUT_100 100
+
+ /* Extended Status Register */
+ #define IEEE_ESR_1000T_HD_CAPS 0x1000 /* 1000T HD capable */
+@@ -1901,7 +1982,6 @@
+ #define M88E1000_EPSCR_TX_CLK_25 0x0070 /* 25 MHz TX_CLK */
+ #define M88E1000_EPSCR_TX_CLK_0 0x0000 /* NO TX_CLK */
+
+-
+ /* IGP01E1000 Specific Port Config Register - R/W */
+ #define IGP01E1000_PSCFR_AUTO_MDIX_PAR_DETECT 0x0010
+ #define IGP01E1000_PSCFR_PRE_EN 0x0020
+@@ -1952,6 +2032,11 @@
+ #define IGP01E1000_MSE_CHANNEL_B 0x0F00
+ #define IGP01E1000_MSE_CHANNEL_A 0xF000
+
++/* IGP01E1000 DSP reset macros */
++#define DSP_RESET_ENABLE 0x0
++#define DSP_RESET_DISABLE 0x2
++#define E1000_MAX_DSP_RESETS 10
++
+ /* IGP01E1000 AGC Registers */
+
+ #define IGP01E1000_AGC_LENGTH_SHIFT 7 /* Coarse - 13:11, Fine - 10:7 */
+@@ -1962,18 +2047,6 @@
+ /* The precision of the length is +/- 10 meters */
+ #define IGP01E1000_AGC_RANGE 10
+
+-/* IGP cable length table */
+-static const
+-uint16_t e1000_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] =
+- { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+- 5, 10, 10, 10, 10, 10, 10, 10, 20, 20, 20, 20, 20, 25, 25, 25,
+- 25, 25, 25, 25, 30, 30, 30, 30, 40, 40, 40, 40, 40, 40, 40, 40,
+- 40, 50, 50, 50, 50, 50, 50, 50, 60, 60, 60, 60, 60, 60, 60, 60,
+- 60, 70, 70, 70, 70, 70, 70, 80, 80, 80, 80, 80, 80, 90, 90, 90,
+- 90, 90, 90, 90, 90, 90, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
+- 100, 100, 100, 100, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
+- 110, 110, 110, 110, 110, 110, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120};
+-
+ /* IGP01E1000 PCS Initialization register */
+ /* bits 3:6 in the PCS registers stores the channels polarity */
+ #define IGP01E1000_PHY_POLARITY_MASK 0x0078
+@@ -1982,11 +2055,12 @@
+ #define IGP01E1000_GMII_FLEX_SPD 0x10 /* Enable flexible speed
+ * on Link-Up */
+ #define IGP01E1000_GMII_SPD 0x20 /* Enable SPD */
++
+ /* IGP01E1000 Analog Register */
+-#define IGP01E1000_ANALOG_SPARE_FUSE_STATUS 0x0011
+-#define IGP01E1000_ANALOG_FUSE_STATUS 0x0010
+-#define IGP01E1000_ANALOG_FUSE_CONTROL 0x001C
+-#define IGP01E1000_ANALOG_FUSE_BYPASS 0x001E
++#define IGP01E1000_ANALOG_SPARE_FUSE_STATUS 0x20D1
++#define IGP01E1000_ANALOG_FUSE_STATUS 0x20D0
++#define IGP01E1000_ANALOG_FUSE_CONTROL 0x20DC
++#define IGP01E1000_ANALOG_FUSE_BYPASS 0x20DE
+
+ #define IGP01E1000_ANALOG_FUSE_POLY_MASK 0xF000
+ #define IGP01E1000_ANALOG_FUSE_FINE_MASK 0x0F80
+@@ -2032,5 +2106,8 @@
+ #define ADVERTISE_1000_HALF 0x0010
+ #define ADVERTISE_1000_FULL 0x0020
+ #define AUTONEG_ADVERTISE_SPEED_DEFAULT 0x002F /* Everything but 1000-Half */
++#define AUTONEG_ADVERTISE_10_100_ALL 0x000F /* All 10/100 speeds*/
++#define AUTONEG_ADVERTISE_10_ALL 0x0003 /* 10Mbps Full & Half speeds*/
++
+
+ #endif /* _E1000_HW_H_ */
+Index: linux-2.6.0-test5/drivers/net/e1000/e1000_main.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/e1000/e1000_main.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/e1000/e1000_main.c 2003-09-27 11:38:25.514649568 +0800
+@@ -30,6 +30,22 @@
+
+ /* Change Log
+ *
++ * 5.2.16 8/8/03
++ * o Added support for new controllers: 82545GM, 82546GB, 82541/7_B1
++ * o Bug fix: reset h/w before first EEPROM read because we don't know
++ * who may have been messing with the device before we got there.
++ * [Dave Johnson (ddj -a-t- cascv.brown.edu)]
++ * o Bug fix: read the correct work from EEPROM to detect programmed
++ * WoL settings.
++ * o Bug fix: TSO would hang if space left in FIFO was being miscalculated
++ * when mss dropped without a correspoding drop in the DMA buffer size.
++ * o ASF for Fiber nics isn't supported.
++ * o Bug fix: Workaround added for potential hang with 82544 running in
++ * PCI-X if send buffer terminates within an evenly-aligned dword.
++ * o Feature: Add support for ethtool flow control setting.
++ * o Feature: Add support for ethtool TSO setting.
++ * o Feature: Increase default Tx Descriptor count to 1024 for >= 82544.
++ *
+ * 5.1.13 5/28/03
+ * o Bug fix: request_irq() failure resulted in freeing resources twice!
+ * [Don Fry (brazilnut@us.ibm.com)]
+@@ -39,18 +55,11 @@
+ * o Cleanup: s/int/unsigned int/ for descriptor ring indexes.
+ *
+ * 5.1.11 5/6/03
+- * o Feature: Added support for 82546EB (Quad-port) hardware.
+- * o Feature: Added support for Diagnostics through Ethtool.
+- * o Cleanup: Removed /proc support.
+- * o Cleanup: Removed proprietary IDIAG interface.
+- * o Bug fix: TSO bug fixes.
+- *
+- * 5.0.42 3/5/03
+ */
+
+ char e1000_driver_name[] = "e1000";
+ char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
+-char e1000_driver_version[] = "5.1.13-k2";
++char e1000_driver_version[] = "5.2.16-k1";
+ char e1000_copyright[] = "Copyright (c) 1999-2003 Intel Corporation.";
+
+ /* e1000_pci_tbl - PCI Device ID Table
+@@ -71,15 +80,28 @@
+ {0x8086, 0x100D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x8086, 0x100E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x8086, 0x100F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+- {0x8086, 0x1011, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x8086, 0x1010, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++ {0x8086, 0x1011, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x8086, 0x1012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++ {0x8086, 0x1013, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++ {0x8086, 0x1014, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++ {0x8086, 0x1015, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x8086, 0x1016, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x8086, 0x1017, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+- {0x8086, 0x101E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+- {0x8086, 0x101D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+- {0x8086, 0x1013, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++ {0x8086, 0x1018, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x8086, 0x1019, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++ {0x8086, 0x101D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++ {0x8086, 0x101E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++ {0x8086, 0x1026, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++ {0x8086, 0x1027, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++ {0x8086, 0x1028, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++ {0x8086, 0x1075, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++ {0x8086, 0x1076, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++ {0x8086, 0x1077, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++ {0x8086, 0x1078, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++ {0x8086, 0x1079, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++ {0x8086, 0x107A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++ {0x8086, 0x107B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ /* required last entry */
+ {0,}
+ };
+@@ -426,6 +448,11 @@
+ if(pci_using_dac)
+ netdev->features |= NETIF_F_HIGHDMA;
+
++ /* before reading the EEPROM, reset the controller to
++ * put the device in a known good starting state */
++
++ e1000_reset_hw(&adapter->hw);
++
+ /* make sure the EEPROM is good */
+
+ if(e1000_validate_eeprom_checksum(&adapter->hw) < 0) {
+@@ -457,7 +484,7 @@
+ adapter->phy_info_timer.function = &e1000_update_phy_info;
+ adapter->phy_info_timer.data = (unsigned long) adapter;
+
+- INIT_WORK(&adapter->tx_timeout_task,
++ INIT_WORK(&adapter->tx_timeout_task,
+ (void (*)(void *))e1000_tx_timeout_task, netdev);
+
+ register_netdev(netdev);
+@@ -476,12 +503,28 @@
+ * enable the ACPI Magic Packet filter
+ */
+
+- e1000_read_eeprom(&adapter->hw, EEPROM_INIT_CONTROL2_REG,1, &eeprom_data);
+- if((adapter->hw.mac_type >= e1000_82544) &&
+- (eeprom_data & E1000_EEPROM_APME))
++ switch(adapter->hw.mac_type) {
++ case e1000_82542_rev2_0:
++ case e1000_82542_rev2_1:
++ case e1000_82543:
++ break;
++ case e1000_82546:
++ case e1000_82546_rev_3:
++ if((E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1)
++ && (adapter->hw.media_type == e1000_media_type_copper)) {
++ e1000_read_eeprom(&adapter->hw,
++ EEPROM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
++ break;
++ }
++ /* Fall Through */
++ default:
++ e1000_read_eeprom(&adapter->hw,
++ EEPROM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
++ break;
++ }
++ if(eeprom_data & E1000_EEPROM_APME)
+ adapter->wol |= E1000_WUFC_MAG;
+
+-
+ /* reset the hardware with the new settings */
+
+ e1000_reset(adapter);
+@@ -516,7 +559,8 @@
+ struct e1000_adapter *adapter = netdev->priv;
+ uint32_t manc;
+
+- if(adapter->hw.mac_type >= e1000_82540) {
++ if(adapter->hw.mac_type >= e1000_82540 &&
++ adapter->hw.media_type == e1000_media_type_copper) {
+ manc = E1000_READ_REG(&adapter->hw, MANC);
+ if(manc & E1000_MANC_SMBUS_EN) {
+ manc |= E1000_MANC_ARP_EN;
+@@ -584,21 +628,13 @@
+ hw->fc_pause_time = E1000_FC_PAUSE_TIME;
+ hw->fc_send_xon = 1;
+
+- if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547))
++ if((hw->mac_type == e1000_82541) ||
++ (hw->mac_type == e1000_82547) ||
++ (hw->mac_type == e1000_82541_rev_2) ||
++ (hw->mac_type == e1000_82547_rev_2))
+ hw->phy_init_script = 1;
+
+- /* Media type - copper or fiber */
+-
+- if(hw->mac_type >= e1000_82543) {
+- uint32_t status = E1000_READ_REG(hw, STATUS);
+-
+- if(status & E1000_STATUS_TBIMODE)
+- hw->media_type = e1000_media_type_fiber;
+- else
+- hw->media_type = e1000_media_type_copper;
+- } else {
+- hw->media_type = e1000_media_type_fiber;
+- }
++ e1000_set_media_type(hw);
+
+ if(hw->mac_type < e1000_82543)
+ hw->report_tx_early = 0;
+@@ -614,6 +650,7 @@
+ if(hw->media_type == e1000_media_type_copper) {
+ hw->mdix = AUTO_ALL_MODES;
+ hw->disable_polarity_correction = FALSE;
++ hw->master_slave = E1000_MASTER_SLAVE;
+ }
+
+ atomic_set(&adapter->irq_sem, 1);
+@@ -763,7 +800,8 @@
+ tipg |= DEFAULT_82542_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
+ break;
+ default:
+- if(adapter->hw.media_type == e1000_media_type_fiber)
++ if(adapter->hw.media_type == e1000_media_type_fiber ||
++ adapter->hw.media_type == e1000_media_type_internal_serdes)
+ tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
+ else
+ tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
+@@ -798,6 +836,12 @@
+ adapter->txd_cmd |= E1000_TXD_CMD_RS;
+ else
+ adapter->txd_cmd |= E1000_TXD_CMD_RPS;
++
++ /* Cache if we're 82544 running in PCI-X because we'll
++ * need this to apply a workaround later in the send path. */
++ if(adapter->hw.mac_type == e1000_82544 &&
++ adapter->hw.bus_type == e1000_bus_type_pcix)
++ adapter->pcix_82544 = 1;
+ }
+
+ /**
+@@ -1490,27 +1534,46 @@
+ {
+ struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
+ struct e1000_buffer *buffer_info;
+- int len = skb->len;
++ unsigned int len = skb->len, max_per_txd = E1000_MAX_DATA_PER_TXD;
+ unsigned int offset = 0, size, count = 0, i;
+-
+ #ifdef NETIF_F_TSO
+- unsigned int tso = skb_shinfo(skb)->tso_size;
++ unsigned int mss;
+ #endif
+- unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
++ unsigned int nr_frags;
+ unsigned int f;
++
++#ifdef NETIF_F_TSO
++ mss = skb_shinfo(skb)->tso_size;
++ /* The controller does a simple calculation to
++ * make sure there is enough room in the FIFO before
++ * initiating the DMA for each buffer. The calc is:
++ * 4 = ceil(buffer len/mss). To make sure we don't
++ * overrun the FIFO, adjust the max buffer len if mss
++ * drops. */
++ if (mss)
++ max_per_txd = min(mss << 2, max_per_txd);
++#endif
++ nr_frags = skb_shinfo(skb)->nr_frags;
+ len -= skb->data_len;
+
+ i = tx_ring->next_to_use;
+
+ while(len) {
+ buffer_info = &tx_ring->buffer_info[i];
+- size = min(len, E1000_MAX_DATA_PER_TXD);
++ size = min(len, max_per_txd);
+ #ifdef NETIF_F_TSO
+ /* Workaround for premature desc write-backs
+ * in TSO mode. Append 4-byte sentinel desc */
+- if(tso && !nr_frags && size == len && size > 4)
++ if(mss && !nr_frags && size == len && size > 8)
+ size -= 4;
+ #endif
++ /* Workaround for potential 82544 hang in PCI-X. Avoid
++ * terminating buffers within evenly-aligned dwords. */
++ if(adapter->pcix_82544 &&
++ !((unsigned long)(skb->data + offset + size - 1) & 4) &&
++ size > 4)
++ size -= 4;
++
+ buffer_info->length = size;
+ buffer_info->dma =
+ pci_map_single(adapter->pdev,
+@@ -1530,22 +1593,30 @@
+
+ frag = &skb_shinfo(skb)->frags[f];
+ len = frag->size;
+- offset = 0;
++ offset = frag->page_offset;
+
+ while(len) {
+ buffer_info = &tx_ring->buffer_info[i];
+- size = min(len, E1000_MAX_DATA_PER_TXD);
++ size = min(len, max_per_txd);
+ #ifdef NETIF_F_TSO
+ /* Workaround for premature desc write-backs
+ * in TSO mode. Append 4-byte sentinel desc */
+- if(tso && f == (nr_frags-1) && size == len && size > 4)
++ if(mss && f == (nr_frags-1) && size == len && size > 8)
+ size -= 4;
+ #endif
++ /* Workaround for potential 82544 hang in PCI-X.
++ * Avoid terminating buffers within evenly-aligned
++ * dwords. */
++ if(adapter->pcix_82544 &&
++ !((unsigned long)(frag->page+offset+size-1) & 4) &&
++ size > 4)
++ size -= 4;
++
+ buffer_info->length = size;
+ buffer_info->dma =
+ pci_map_page(adapter->pdev,
+ frag->page,
+- frag->page_offset + offset,
++ offset,
+ size,
+ PCI_DMA_TODEVICE);
+ buffer_info->time_stamp = jiffies;
+@@ -1556,6 +1627,31 @@
+ if(++i == tx_ring->count) i = 0;
+ }
+ }
++
++ if(E1000_DESC_UNUSED(&adapter->tx_ring) < count) {
++
++ /* There aren't enough descriptors available to queue up
++ * this send, so undo the mapping and abort the send.
++ * We could have done the check before we mapped the skb,
++ * but because of all the workarounds (above), it's too
++ * difficult to predict how many we're going to need.*/
++ i = first;
++
++ while(count--) {
++ buffer_info = &tx_ring->buffer_info[i];
++ if(buffer_info->dma) {
++ pci_unmap_page(adapter->pdev,
++ buffer_info->dma,
++ buffer_info->length,
++ PCI_DMA_TODEVICE);
++ buffer_info->dma = 0;
++ }
++ if(++i == tx_ring->count) i = 0;
++ }
++
++ return 0;
++ }
++
+ i = (i == 0) ? tx_ring->count - 1 : i - 1;
+ tx_ring->buffer_info[i].skb = skb;
+ tx_ring->buffer_info[first].next_to_watch = i;
+@@ -1650,29 +1746,19 @@
+ return 0;
+ }
+
+-/* Tx Descriptors needed, worst case */
+-#define TXD_USE_COUNT(S) (((S) >> E1000_MAX_TXD_PWR) + \
+- (((S) & (E1000_MAX_DATA_PER_TXD - 1)) ? 1 : 0))
+-#define DESC_NEEDED TXD_USE_COUNT(MAX_JUMBO_FRAME_SIZE) + \
+- MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1
+-
+ static int
+ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+ {
+ struct e1000_adapter *adapter = netdev->priv;
+ unsigned int first;
+ unsigned int tx_flags = 0;
++ int count;
+
+ if(skb->len <= 0) {
+ dev_kfree_skb_any(skb);
+ return 0;
+ }
+
+- if(E1000_DESC_UNUSED(&adapter->tx_ring) < DESC_NEEDED) {
+- netif_stop_queue(netdev);
+- return 1;
+- }
+-
+ if(adapter->hw.mac_type == e1000_82547) {
+ if(e1000_82547_fifo_workaround(adapter, skb)) {
+ netif_stop_queue(netdev);
+@@ -1693,7 +1779,12 @@
+ else if(e1000_tx_csum(adapter, skb))
+ tx_flags |= E1000_TX_FLAGS_CSUM;
+
+- e1000_tx_queue(adapter, e1000_tx_map(adapter, skb, first), tx_flags);
++ if((count = e1000_tx_map(adapter, skb, first)))
++ e1000_tx_queue(adapter, count, tx_flags);
++ else {
++ netif_stop_queue(netdev);
++ return 1;
++ }
+
+ netdev->trans_start = jiffies;
+
+@@ -2001,6 +2092,7 @@
+ !e1000_clean_tx_irq(adapter))
+ break;
+ #endif
++
+ return IRQ_HANDLED;
+ }
+
+@@ -2387,7 +2479,7 @@
+ uint16_t mii_reg;
+ uint16_t spddplx;
+
+- if(adapter->hw.media_type == e1000_media_type_fiber)
++ if(adapter->hw.media_type != e1000_media_type_copper)
+ return -EOPNOTSUPP;
+
+ switch (cmd) {
+@@ -2659,7 +2751,7 @@
+ case SYS_DOWN:
+ case SYS_HALT:
+ case SYS_POWER_OFF:
+- while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
++ while((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev))) {
+ if(pci_dev_driver(pdev) == &e1000_driver)
+ e1000_suspend(pdev, 3);
+ }
+@@ -2706,7 +2798,8 @@
+ E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
+ }
+
+- if(adapter->hw.media_type == e1000_media_type_fiber) {
++ if(adapter->hw.media_type == e1000_media_type_fiber ||
++ adapter->hw.media_type == e1000_media_type_internal_serdes) {
+ /* keep the laser running in D3 */
+ ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
+ ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA;
+@@ -2726,7 +2819,8 @@
+
+ pci_save_state(pdev, adapter->pci_state);
+
+- if(adapter->hw.mac_type >= e1000_82540) {
++ if(adapter->hw.mac_type >= e1000_82540 &&
++ adapter->hw.media_type == e1000_media_type_copper) {
+ manc = E1000_READ_REG(&adapter->hw, MANC);
+ if(manc & E1000_MANC_SMBUS_EN) {
+ manc |= E1000_MANC_ARP_EN;
+@@ -2764,7 +2858,8 @@
+
+ netif_device_attach(netdev);
+
+- if(adapter->hw.mac_type >= e1000_82540) {
++ if(adapter->hw.mac_type >= e1000_82540 &&
++ adapter->hw.media_type == e1000_media_type_copper) {
+ manc = E1000_READ_REG(&adapter->hw, MANC);
+ manc &= ~(E1000_MANC_ARP_EN);
+ E1000_WRITE_REG(&adapter->hw, MANC, manc);
+Index: linux-2.6.0-test5/drivers/net/e1000/e1000_osdep.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/e1000/e1000_osdep.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/e1000/e1000_osdep.h 2003-09-27 11:38:25.533646680 +0800
+@@ -55,10 +55,13 @@
+ #define CMD_MEM_WRT_INVALIDATE PCI_COMMAND_INVALIDATE
+
+ typedef enum {
++#undef FALSE
+ FALSE = 0,
++#undef TRUE
+ TRUE = 1
+ } boolean_t;
+
++#undef ASSERT
+ #define ASSERT(x) if(!(x)) BUG()
+ #define MSGOUT(S, A, B) printk(KERN_DEBUG S "\n", A, B)
+
+Index: linux-2.6.0-test5/drivers/net/e1000/e1000_param.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/e1000/e1000_param.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/e1000/e1000_param.c 2003-09-27 11:38:25.553643640 +0800
+@@ -140,7 +140,7 @@
+ * Valid Range: 0, 1
+ * - 0 - disables all checksum offload
+ * - 1 - enables receive IP/TCP/UDP checksum offload
+- * on 82543 based NICs
++ * on 82543 and newer -based NICs
+ *
+ * Default Value: 1
+ */
+@@ -458,6 +458,7 @@
+
+ switch(adapter->hw.media_type) {
+ case e1000_media_type_fiber:
++ case e1000_media_type_internal_serdes:
+ e1000_check_fiber_options(adapter);
+ break;
+ case e1000_media_type_copper:
+@@ -601,7 +602,7 @@
+
+ switch (speed + dplx) {
+ case 0:
+- adapter->hw.autoneg = 1;
++ adapter->hw.autoneg = adapter->fc_autoneg = 1;
+ if(Speed[bd] != OPTION_UNSET || Duplex[bd] != OPTION_UNSET)
+ printk(KERN_INFO
+ "Speed and duplex autonegotiation enabled\n");
+@@ -609,14 +610,14 @@
+ case HALF_DUPLEX:
+ printk(KERN_INFO "Half Duplex specified without Speed\n");
+ printk(KERN_INFO "Using Autonegotiation at Half Duplex only\n");
+- adapter->hw.autoneg = 1;
++ adapter->hw.autoneg = adapter->fc_autoneg = 1;
+ adapter->hw.autoneg_advertised = ADVERTISE_10_HALF |
+ ADVERTISE_100_HALF;
+ break;
+ case FULL_DUPLEX:
+ printk(KERN_INFO "Full Duplex specified without Speed\n");
+ printk(KERN_INFO "Using Autonegotiation at Full Duplex only\n");
+- adapter->hw.autoneg = 1;
++ adapter->hw.autoneg = adapter->fc_autoneg = 1;
+ adapter->hw.autoneg_advertised = ADVERTISE_10_FULL |
+ ADVERTISE_100_FULL |
+ ADVERTISE_1000_FULL;
+@@ -624,38 +625,38 @@
+ case SPEED_10:
+ printk(KERN_INFO "10 Mbps Speed specified without Duplex\n");
+ printk(KERN_INFO "Using Autonegotiation at 10 Mbps only\n");
+- adapter->hw.autoneg = 1;
++ adapter->hw.autoneg = adapter->fc_autoneg = 1;
+ adapter->hw.autoneg_advertised = ADVERTISE_10_HALF |
+ ADVERTISE_10_FULL;
+ break;
+ case SPEED_10 + HALF_DUPLEX:
+ printk(KERN_INFO "Forcing to 10 Mbps Half Duplex\n");
+- adapter->hw.autoneg = 0;
++ adapter->hw.autoneg = adapter->fc_autoneg = 0;
+ adapter->hw.forced_speed_duplex = e1000_10_half;
+ adapter->hw.autoneg_advertised = 0;
+ break;
+ case SPEED_10 + FULL_DUPLEX:
+ printk(KERN_INFO "Forcing to 10 Mbps Full Duplex\n");
+- adapter->hw.autoneg = 0;
++ adapter->hw.autoneg = adapter->fc_autoneg = 0;
+ adapter->hw.forced_speed_duplex = e1000_10_full;
+ adapter->hw.autoneg_advertised = 0;
+ break;
+ case SPEED_100:
+ printk(KERN_INFO "100 Mbps Speed specified without Duplex\n");
+ printk(KERN_INFO "Using Autonegotiation at 100 Mbps only\n");
+- adapter->hw.autoneg = 1;
++ adapter->hw.autoneg = adapter->fc_autoneg = 1;
+ adapter->hw.autoneg_advertised = ADVERTISE_100_HALF |
+ ADVERTISE_100_FULL;
+ break;
+ case SPEED_100 + HALF_DUPLEX:
+ printk(KERN_INFO "Forcing to 100 Mbps Half Duplex\n");
+- adapter->hw.autoneg = 0;
++ adapter->hw.autoneg = adapter->fc_autoneg = 0;
+ adapter->hw.forced_speed_duplex = e1000_100_half;
+ adapter->hw.autoneg_advertised = 0;
+ break;
+ case SPEED_100 + FULL_DUPLEX:
+ printk(KERN_INFO "Forcing to 100 Mbps Full Duplex\n");
+- adapter->hw.autoneg = 0;
++ adapter->hw.autoneg = adapter->fc_autoneg = 0;
+ adapter->hw.forced_speed_duplex = e1000_100_full;
+ adapter->hw.autoneg_advertised = 0;
+ break;
+@@ -663,20 +664,20 @@
+ printk(KERN_INFO "1000 Mbps Speed specified without Duplex\n");
+ printk(KERN_INFO
+ "Using Autonegotiation at 1000 Mbps Full Duplex only\n");
+- adapter->hw.autoneg = 1;
++ adapter->hw.autoneg = adapter->fc_autoneg = 1;
+ adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL;
+ break;
+ case SPEED_1000 + HALF_DUPLEX:
+ printk(KERN_INFO "Half Duplex is not supported at 1000 Mbps\n");
+ printk(KERN_INFO
+ "Using Autonegotiation at 1000 Mbps Full Duplex only\n");
+- adapter->hw.autoneg = 1;
++ adapter->hw.autoneg = adapter->fc_autoneg = 1;
+ adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL;
+ break;
+ case SPEED_1000 + FULL_DUPLEX:
+ printk(KERN_INFO
+ "Using Autonegotiation at 1000 Mbps Full Duplex only\n");
+- adapter->hw.autoneg = 1;
++ adapter->hw.autoneg = adapter->fc_autoneg = 1;
+ adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL;
+ break;
+ default:
+Index: linux-2.6.0-test5/drivers/net/e100/e100_main.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/e100/e100_main.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/e100/e100_main.c 2003-09-27 11:38:26.431510184 +0800
+@@ -551,6 +551,15 @@
+ readw(&(bdp->scb->scb_status)); /* flushes last write, read-safe */
+ }
+
++#ifdef CONFIG_NET_POLL_CONTROLLER
++static void e100_rx_poll(struct net_device *dev)
++{
++ disable_irq(dev->irq);
++ e100intr(dev->irq, (void *)dev, 0);
++ enable_irq(dev->irq);
++}
++#endif
++
+ static int __devinit
+ e100_found1(struct pci_dev *pcid, const struct pci_device_id *ent)
+ {
+@@ -643,7 +652,9 @@
+ dev->set_multicast_list = &e100_set_multi;
+ dev->set_mac_address = &e100_set_mac;
+ dev->do_ioctl = &e100_ioctl;
+-
++#ifdef CONFIG_NET_POLL_CONTROLLER
++ dev->poll_controller = e100_rx_poll;
++#endif
+ if (bdp->flags & USE_IPCB)
+ dev->features = NETIF_F_SG | NETIF_F_HW_CSUM |
+ NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+Index: linux-2.6.0-test5/drivers/net/eepro100.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/eepro100.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/eepro100.c 2003-09-27 11:38:26.452506992 +0800
+@@ -543,6 +543,7 @@
+ static int speedo_rx(struct net_device *dev);
+ static void speedo_tx_buffer_gc(struct net_device *dev);
+ static irqreturn_t speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
++static void poll_speedo (struct net_device *dev);
+ static int speedo_close(struct net_device *dev);
+ static struct net_device_stats *speedo_get_stats(struct net_device *dev);
+ static int speedo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+@@ -885,6 +886,9 @@
+ dev->get_stats = &speedo_get_stats;
+ dev->set_multicast_list = &set_rx_mode;
+ dev->do_ioctl = &speedo_ioctl;
++#ifdef CONFIG_NET_POLL_CONTROLLER
++ dev->poll_controller = &poll_speedo;
++#endif
+
+ if (register_netdevice(dev))
+ goto err_free_unlock;
+@@ -1675,6 +1679,22 @@
+ return IRQ_RETVAL(handled);
+ }
+
++#ifdef CONFIG_NET_POLL_CONTROLLER
++
++/*
++ * Polling 'interrupt' - used by things like netconsole to send skbs
++ * without having to re-enable interrupts. It's not called while
++ * the interrupt routine is executing.
++ */
++
++static void poll_speedo (struct net_device *dev)
++{
++ disable_irq(dev->irq);
++ speedo_interrupt (dev->irq, dev, NULL);
++ enable_irq(dev->irq);
++}
++#endif
++
+ static inline struct RxFD *speedo_rx_alloc(struct net_device *dev, int entry)
+ {
+ struct speedo_private *sp = (struct speedo_private *)dev->priv;
+Index: linux-2.6.0-test5/drivers/net/eepro.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/eepro.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/eepro.c 2003-09-27 11:38:26.466504864 +0800
+@@ -897,14 +897,12 @@
+ eepro_sw2bank0(ioaddr); /* Switch back to Bank 0 */
+
+ if (request_irq (*irqp, NULL, SA_SHIRQ, "bogus", dev) != EBUSY) {
+- unsigned long irq_mask, delay;
++ unsigned long irq_mask;
+ /* Twinkle the interrupt, and check if it's seen */
+ irq_mask = probe_irq_on();
+
+ eepro_diag(ioaddr); /* RESET the 82595 */
+-
+- delay = jiffies + HZ/50;
+- while (time_before(jiffies, delay)) ;
++ mdelay(20);
+
+ if (*irqp == probe_irq_off(irq_mask)) /* It's a good IRQ line */
+ break;
+Index: linux-2.6.0-test5/drivers/net/es3210.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/es3210.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/es3210.c 2003-09-27 11:38:26.470504256 +0800
+@@ -49,6 +49,7 @@
+ "es3210.c: Driver revision v0.03, 14/09/96\n";
+
+ #include <linux/module.h>
++#include <linux/eisa.h>
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+ #include <linux/string.h>
+Index: linux-2.6.0-test5/drivers/net/ewrk3.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/ewrk3.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/ewrk3.c 2003-09-27 11:38:26.493500760 +0800
+@@ -564,7 +564,7 @@
+ if (dev->irq < 2) {
+ #ifndef MODULE
+ u_char irqnum;
+- unsigned long irq_mask, delay;
++ unsigned long irq_mask;
+
+
+ irq_mask = probe_irq_on();
+@@ -578,8 +578,7 @@
+
+ irqnum = irq[((icr & IRQ_SEL) >> 4)];
+
+- delay = jiffies + HZ/50;
+- while (time_before(jiffies, delay)) ;
++ mdelay(20);
+ dev->irq = probe_irq_off(irq_mask);
+ if ((dev->irq) && (irqnum == dev->irq)) {
+ printk(" and uses IRQ%d.\n", dev->irq);
+Index: linux-2.6.0-test5/drivers/net/fc/iph5526.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/fc/iph5526.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/fc/iph5526.c 2003-09-27 11:38:26.530495136 +0800
+@@ -110,7 +110,7 @@
+ #define ALIGNED_ADDR(addr, len) ((((unsigned long)(addr) + (len - 1)) & ~(len - 1)) - (unsigned long)(addr))
+
+
+-static struct pci_device_id iph5526_pci_tbl[] __initdata = {
++static struct pci_device_id iph5526_pci_tbl[] = {
+ { PCI_VENDOR_ID_INTERPHASE, PCI_DEVICE_ID_INTERPHASE_5526, PCI_ANY_ID, PCI_ANY_ID, },
+ { PCI_VENDOR_ID_INTERPHASE, PCI_DEVICE_ID_INTERPHASE_55x6, PCI_ANY_ID, PCI_ANY_ID, },
+ { } /* Terminating entry */
+Index: linux-2.6.0-test5/drivers/net/hamachi.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/hamachi.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/hamachi.c 2003-09-27 11:38:26.548492400 +0800
+@@ -178,7 +178,7 @@
+ #include <asm/unaligned.h>
+ #include <asm/cache.h>
+
+-static char version[] __initdata =
++static char version[] __devinitdata =
+ KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " Written by Donald Becker\n"
+ KERN_INFO " Some modifications by Eric kasten <kasten@nscl.msu.edu>\n"
+ KERN_INFO " Further modifications by Keith Underwood <keithu@parl.clemson.edu>\n";
+@@ -569,7 +569,7 @@
+ static void set_rx_mode(struct net_device *dev);
+
+
+-static int __init hamachi_init_one (struct pci_dev *pdev,
++static int __devinit hamachi_init_one (struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+ {
+ struct hamachi_private *hmp;
+@@ -794,7 +794,7 @@
+ return ret;
+ }
+
+-static int __init read_eeprom(long ioaddr, int location)
++static int __devinit read_eeprom(long ioaddr, int location)
+ {
+ int bogus_cnt = 1000;
+
+Index: linux-2.6.0-test5/drivers/net/hamradio/baycom_par.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/hamradio/baycom_par.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/hamradio/baycom_par.c 2003-09-27 11:38:26.553491640 +0800
+@@ -68,7 +68,6 @@
+
+ /*****************************************************************************/
+
+-#include <linux/version.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+Index: linux-2.6.0-test5/drivers/net/hamradio/baycom_ser_fdx.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/hamradio/baycom_ser_fdx.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/hamradio/baycom_ser_fdx.c 2003-09-27 11:38:26.559490728 +0800
+@@ -71,7 +71,6 @@
+
+ /*****************************************************************************/
+
+-#include <linux/version.h>
+ #include <linux/module.h>
+ #include <linux/ioport.h>
+ #include <linux/string.h>
+Index: linux-2.6.0-test5/drivers/net/hamradio/baycom_ser_hdx.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/hamradio/baycom_ser_hdx.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/hamradio/baycom_ser_hdx.c 2003-09-27 11:38:26.571488904 +0800
+@@ -61,7 +61,6 @@
+
+ /*****************************************************************************/
+
+-#include <linux/version.h>
+ #include <linux/module.h>
+ #include <linux/ioport.h>
+ #include <linux/string.h>
+Index: linux-2.6.0-test5/drivers/net/hamradio/bpqether.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/hamradio/bpqether.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/hamradio/bpqether.c 2003-09-27 11:38:26.575488296 +0800
+@@ -389,8 +389,6 @@
+ return buf;
+ }
+
+-#define BPQ_PROC_START ((void *)1)
+-
+ static void *bpq_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+ int i = 1;
+@@ -399,7 +397,7 @@
+ rcu_read_lock();
+
+ if (*pos == 0)
+- return BPQ_PROC_START;
++ return SEQ_START_TOKEN;
+
+ list_for_each_entry(bpqdev, &bpq_devices, bpq_list) {
+ if (i == *pos)
+@@ -414,7 +412,7 @@
+
+ ++*pos;
+
+- if (v == BPQ_PROC_START)
++ if (v == SEQ_START_TOKEN)
+ p = bpq_devices.next;
+ else
+ p = ((struct bpqdev *)v)->bpq_list.next;
+@@ -431,7 +429,7 @@
+
+ static int bpq_seq_show(struct seq_file *seq, void *v)
+ {
+- if (v == BPQ_PROC_START)
++ if (v == SEQ_START_TOKEN)
+ seq_puts(seq,
+ "dev ether destination accept from\n");
+ else {
+Index: linux-2.6.0-test5/drivers/net/hamradio/hdlcdrv.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/hamradio/hdlcdrv.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/hamradio/hdlcdrv.c 2003-09-27 11:38:26.587486472 +0800
+@@ -43,7 +43,6 @@
+ /*****************************************************************************/
+
+ #include <linux/config.h>
+-#include <linux/version.h>
+ #include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/net.h>
+Index: linux-2.6.0-test5/drivers/net/hamradio/scc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/hamradio/scc.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/hamradio/scc.c 2003-09-27 11:38:26.603484040 +0800
+@@ -171,6 +171,7 @@
+ #include <linux/ctype.h>
+ #include <linux/kernel.h>
+ #include <linux/proc_fs.h>
++#include <linux/seq_file.h>
+
+ #include <net/ax25.h>
+
+@@ -202,8 +203,8 @@
+ static irqreturn_t scc_isr(int irq, void *dev_id, struct pt_regs *regs);
+ static void scc_init_timer(struct scc_channel *scc);
+
+-static int scc_net_setup(struct scc_channel *scc, unsigned char *name, int addev);
+-static int scc_net_init(struct net_device *dev);
++static int scc_net_alloc(const char *name, struct scc_channel *scc);
++static void scc_net_setup(struct net_device *dev);
+ static int scc_net_open(struct net_device *dev);
+ static int scc_net_close(struct net_device *dev);
+ static void scc_net_rx(struct scc_channel *scc, struct sk_buff *skb);
+@@ -235,7 +236,7 @@
+
+ /* These provide interrupt save 2-step access to the Z8530 registers */
+
+-static spinlock_t iolock; /* Guards paired accesses */
++static spinlock_t iolock = SPIN_LOCK_UNLOCKED; /* Guards paired accesses */
+
+ static inline unsigned char InReg(io_port port, unsigned char reg)
+ {
+@@ -1512,34 +1513,28 @@
+ * Allocate device structure, err, instance, and register driver
+ */
+
+-static int scc_net_setup(struct scc_channel *scc, unsigned char *name, int addev)
++static int scc_net_alloc(const char *name, struct scc_channel *scc)
+ {
++ int err;
+ struct net_device *dev;
+
+- if (dev_get(name))
+- {
+- printk(KERN_INFO "Z8530drv: device %s already exists.\n", name);
+- return -EEXIST;
+- }
+-
+- if ((scc->dev = (struct net_device *) kmalloc(sizeof(struct net_device), GFP_KERNEL)) == NULL)
++ dev = alloc_netdev(0, name, scc_net_setup);
++ if (!dev)
+ return -ENOMEM;
+
+- dev = scc->dev;
+- memset(dev, 0, sizeof(struct net_device));
+-
+- strcpy(dev->name, name);
+- dev->priv = (void *) scc;
+- dev->init = scc_net_init;
+-
++ dev->priv = scc;
++ scc->dev = dev;
+ spin_lock_init(&scc->lock);
+-
+- if ((addev? register_netdevice(dev) : register_netdev(dev)) != 0) {
+- kfree(dev);
+- return -EIO;
+- }
+
+- SET_MODULE_OWNER(dev);
++ err = register_netdev(dev);
++ if (err) {
++ printk(KERN_ERR "%s: can't register network device (%d)\n",
++ name, err);
++ free_netdev(dev);
++ scc->dev = NULL;
++ return err;
++ }
++
+ return 0;
+ }
+
+@@ -1556,8 +1551,9 @@
+
+ /* ----> Initialize device <----- */
+
+-static int scc_net_init(struct net_device *dev)
++static void scc_net_setup(struct net_device *dev)
+ {
++ SET_MODULE_OWNER(dev);
+ dev->tx_queue_len = 16; /* should be enough... */
+
+ dev->open = scc_net_open;
+@@ -1581,7 +1577,6 @@
+ dev->mtu = AX25_DEF_PACLEN;
+ dev->addr_len = AX25_ADDR_LEN;
+
+- return 0;
+ }
+
+ /* ----> open network device <---- */
+@@ -1719,10 +1714,10 @@
+ struct scc_mem_config memcfg;
+ struct scc_hw_config hwcfg;
+ struct scc_calibrate cal;
++ struct scc_channel *scc;
+ int chan;
+- unsigned char device_name[10];
++ unsigned char device_name[IFNAMSIZ];
+ void *arg;
+- struct scc_channel *scc;
+
+ scc = (struct scc_channel *) dev->priv;
+ arg = (void *) ifr->ifr_data;
+@@ -1828,8 +1823,10 @@
+ {
+ request_region(SCC_Info[2*Nchips+chan].ctrl, 1, "scc ctrl");
+ request_region(SCC_Info[2*Nchips+chan].data, 1, "scc data");
+- if (Nchips+chan != 0)
+- scc_net_setup(&SCC_Info[2*Nchips+chan], device_name, 1);
++ if (Nchips+chan != 0 &&
++ scc_net_alloc(device_name,
++ &SCC_Info[2*Nchips+chan]))
++ return -EINVAL;
+ }
+ }
+
+@@ -1978,39 +1975,58 @@
+ /* * dump statistics to /proc/net/z8530drv * */
+ /* ******************************************************************** */
+
++#ifdef CONFIG_PROC_FS
+
+-static int scc_net_get_info(char *buffer, char **start, off_t offset, int length)
++static inline struct scc_channel *scc_net_seq_idx(loff_t pos)
+ {
+- struct scc_channel *scc;
+- struct scc_kiss *kiss;
+- struct scc_stat *stat;
+- int len = 0;
+- off_t pos = 0;
+- off_t begin = 0;
+ int k;
+
+- len += sprintf(buffer, "z8530drv-"VERSION"\n");
+-
+- if (!Driver_Initialized)
+- {
+- len += sprintf(buffer+len, "not initialized\n");
+- goto done;
++ for (k = 0; k < Nchips*2; ++k) {
++ if (!SCC_Info[k].init)
++ continue;
++ if (pos-- == 0)
++ return &SCC_Info[k];
+ }
++ return NULL;
++}
+
+- if (!Nchips)
+- {
+- len += sprintf(buffer+len, "chips missing\n");
+- goto done;
++static void *scc_net_seq_start(struct seq_file *seq, loff_t *pos)
++{
++ return *pos ? scc_net_seq_idx(*pos - 1) : SEQ_START_TOKEN;
++
++}
++
++static void *scc_net_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++{
++ unsigned k;
++ struct scc_channel *scc = v;
++ ++*pos;
++
++ for (k = (v == SEQ_START_TOKEN) ? 0 : (scc - SCC_Info)+1;
++ k < Nchips*2; ++k) {
++ if (SCC_Info[k].init)
++ return &SCC_Info[k];
+ }
++ return NULL;
++}
+
+- for (k = 0; k < Nchips*2; k++)
+- {
+- scc = &SCC_Info[k];
+- stat = &scc->stat;
+- kiss = &scc->kiss;
++static void scc_net_seq_stop(struct seq_file *seq, void *v)
++{
++}
++
++static int scc_net_seq_show(struct seq_file *seq, void *v)
++{
++ if (v == SEQ_START_TOKEN) {
++ seq_puts(seq, "z8530drv-"VERSION"\n");
++ } else if (!Driver_Initialized) {
++ seq_puts(seq, "not initialized\n");
++ } else if (!Nchips) {
++ seq_puts(seq, "chips missing\n");
++ } else {
++ const struct scc_channel *scc = v;
++ const struct scc_stat *stat = &scc->stat;
++ const struct scc_kiss *kiss = &scc->kiss;
+
+- if (!scc->init)
+- continue;
+
+ /* dev data ctrl irq clock brand enh vector special option
+ * baud nrz clocksrc softdcd bufsize
+@@ -2021,24 +2037,24 @@
+ * R ## ## XX ## ## ## ## ## XX ## ## ## ## ## ## ##
+ */
+
+- len += sprintf(buffer+len, "%s\t%3.3lx %3.3lx %d %lu %2.2x %d %3.3lx %3.3lx %d\n",
++ seq_printf(seq, "%s\t%3.3lx %3.3lx %d %lu %2.2x %d %3.3lx %3.3lx %d\n",
+ scc->dev->name,
+ scc->data, scc->ctrl, scc->irq, scc->clock, scc->brand,
+ scc->enhanced, Vector_Latch, scc->special,
+ scc->option);
+- len += sprintf(buffer+len, "\t%lu %d %d %d %d\n",
++ seq_printf(seq, "\t%lu %d %d %d %d\n",
+ scc->modem.speed, scc->modem.nrz,
+ scc->modem.clocksrc, kiss->softdcd,
+ stat->bufsize);
+- len += sprintf(buffer+len, "\t%lu %lu %lu %lu\n",
++ seq_printf(seq, "\t%lu %lu %lu %lu\n",
+ stat->rxints, stat->txints, stat->exints, stat->spints);
+- len += sprintf(buffer+len, "\t%lu %lu %d / %lu %lu %d / %d %d\n",
++ seq_printf(seq, "\t%lu %lu %d / %lu %lu %d / %d %d\n",
+ stat->rxframes, stat->rxerrs, stat->rx_over,
+ stat->txframes, stat->txerrs, stat->tx_under,
+ stat->nospace, stat->tx_state);
+
+ #define K(x) kiss->x
+- len += sprintf(buffer+len, "\t%d %d %d %d %d %d %d %d %d %d %d %d\n",
++ seq_printf(seq, "\t%d %d %d %d %d %d %d %d %d %d %d %d\n",
+ K(txdelay), K(persist), K(slottime), K(tailtime),
+ K(fulldup), K(waittime), K(mintime), K(maxkeyup),
+ K(idletime), K(maxdefer), K(tx_inhibit), K(group));
+@@ -2047,43 +2063,49 @@
+ {
+ int reg;
+
+- len += sprintf(buffer+len, "\tW ");
++ seq_printf(seq, "\tW ");
+ for (reg = 0; reg < 16; reg++)
+- len += sprintf(buffer+len, "%2.2x ", scc->wreg[reg]);
+- len += sprintf(buffer+len, "\n");
++ seq_printf(seq, "%2.2x ", scc->wreg[reg]);
++ seq_printf(seq, "\n");
+
+- len += sprintf(buffer+len, "\tR %2.2x %2.2x XX ", InReg(scc->ctrl,R0), InReg(scc->ctrl,R1));
++ seq_printf(seq, "\tR %2.2x %2.2x XX ", InReg(scc->ctrl,R0), InReg(scc->ctrl,R1));
+ for (reg = 3; reg < 8; reg++)
+- len += sprintf(buffer+len, "%2.2x ", InReg(scc->ctrl, reg));
+- len += sprintf(buffer+len, "XX ");
++ seq_printf(seq, "%2.2x ", InReg(scc->ctrl, reg));
++ seq_printf(seq, "XX ");
+ for (reg = 9; reg < 16; reg++)
+- len += sprintf(buffer+len, "%2.2x ", InReg(scc->ctrl, reg));
+- len += sprintf(buffer+len, "\n");
++ seq_printf(seq, "%2.2x ", InReg(scc->ctrl, reg));
++ seq_printf(seq, "\n");
+ }
+ #endif
+- len += sprintf(buffer+len, "\n");
+-
+- pos = begin + len;
+-
+- if (pos < offset) {
+- len = 0;
+- begin = pos;
+- }
+-
+- if (pos > offset + length)
+- break;
++ seq_putc(seq, '\n');
+ }
+
+-done:
++ return 0;
++}
+
+- *start = buffer + (offset - begin);
+- len -= (offset - begin);
++static struct seq_operations scc_net_seq_ops = {
++ .start = scc_net_seq_start,
++ .next = scc_net_seq_next,
++ .stop = scc_net_seq_stop,
++ .show = scc_net_seq_show,
++};
+
+- if (len > length) len = length;
+
+- return len;
++static int scc_net_seq_open(struct inode *inode, struct file *file)
++{
++ return seq_open(file, &scc_net_seq_ops);
+ }
+
++static struct file_operations scc_net_seq_fops = {
++ .owner = THIS_MODULE,
++ .open = scc_net_seq_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = seq_release_private,
++};
++
++#endif /* CONFIG_PROC_FS */
++
+
+ /* ******************************************************************** */
+ /* * Init SCC driver * */
+@@ -2091,23 +2113,18 @@
+
+ static int __init scc_init_driver (void)
+ {
+- int result;
+- char devname[10];
++ char devname[IFNAMSIZ];
+
+ printk(banner);
+
+- spin_lock_init(&iolock);
+-
+ sprintf(devname,"%s0", SCC_DriverName);
+
+- result = scc_net_setup(SCC_Info, devname, 0);
+- if (result)
+- {
++ if (scc_net_alloc(devname, SCC_Info)) {
+ printk(KERN_ERR "z8530drv: cannot initialize module\n");
+- return result;
++ return -EIO;
+ }
+
+- proc_net_create("z8530drv", 0, scc_net_get_info);
++ proc_net_fops_create("z8530drv", 0, &scc_net_seq_fops);
+
+ return 0;
+ }
+@@ -2117,11 +2134,12 @@
+ io_port ctrl;
+ int k;
+ struct scc_channel *scc;
++ struct net_device *dev;
+
+- if (Nchips == 0)
++ if (Nchips == 0 && (dev = SCC_Info[0].dev))
+ {
+- unregister_netdev(SCC_Info[0].dev);
+- free_netdev(SCC_Info[0].dev);
++ unregister_netdev(dev);
++ free_netdev(dev);
+ }
+
+ /* Guard against chip prattle */
+Index: linux-2.6.0-test5/drivers/net/hamradio/yam.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/hamradio/yam.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/hamradio/yam.c 2003-09-27 11:38:26.618481760 +0800
+@@ -74,7 +74,6 @@
+ #include <linux/proc_fs.h>
+ #include <linux/seq_file.h>
+
+-#include <linux/version.h>
+ #include <asm/uaccess.h>
+ #include <linux/init.h>
+
+Index: linux-2.6.0-test5/drivers/net/hp100.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/hp100.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/hp100.c 2003-09-27 11:38:26.661475224 +0800
+@@ -104,6 +104,7 @@
+ #include <linux/ioport.h>
+ #include <linux/slab.h>
+ #include <linux/interrupt.h>
++#include <linux/eisa.h>
+ #include <linux/pci.h>
+ #include <linux/spinlock.h>
+ #include <linux/netdevice.h>
+@@ -284,7 +285,7 @@
+
+ #define HP100_PCI_IDS_SIZE (sizeof(hp100_pci_ids)/sizeof(struct hp100_pci_id))
+
+-static struct pci_device_id hp100_pci_tbl[] __initdata = {
++static struct pci_device_id hp100_pci_tbl[] = {
+ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585A, PCI_ANY_ID, PCI_ANY_ID,},
+ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585B, PCI_ANY_ID, PCI_ANY_ID,},
+ {PCI_VENDOR_ID_COMPEX, PCI_DEVICE_ID_COMPEX_ENET100VG4, PCI_ANY_ID, PCI_ANY_ID,},
+Index: linux-2.6.0-test5/drivers/net/ibmlana.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/ibmlana.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/ibmlana.c 2003-09-27 11:38:26.669474008 +0800
+@@ -74,7 +74,6 @@
+
+ *************************************************************************/
+
+-#include <linux/version.h>
+ #include <linux/kernel.h>
+ #include <linux/string.h>
+ #include <linux/errno.h>
+Index: linux-2.6.0-test5/drivers/net/irda/ali-ircc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/irda/ali-ircc.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/irda/ali-ircc.c 2003-09-27 11:38:26.685471576 +0800
+@@ -89,7 +89,6 @@
+
+ static int ali_ircc_setup(chipio_t *info);
+ static int ali_ircc_is_receiving(struct ali_ircc_cb *self);
+-static int ali_ircc_net_init(struct net_device *dev);
+ static int ali_ircc_net_open(struct net_device *dev);
+ static int ali_ircc_net_close(struct net_device *dev);
+ static int ali_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+@@ -255,14 +254,14 @@
+ if ((ali_ircc_setup(info)) == -1)
+ return -1;
+
+- /* Allocate new instance of the driver */
+- self = kmalloc(sizeof(struct ali_ircc_cb), GFP_KERNEL);
+- if (self == NULL)
+- {
++ dev = alloc_netdev(sizeof(*self), "irda%d", irda_device_setup);
++ if (dev == NULL) {
+ ERROR("%s(), can't allocate memory for control block!\n", __FUNCTION__);
+ return -ENOMEM;
+ }
+- memset(self, 0, sizeof(struct ali_ircc_cb));
++
++ self = dev->priv;
++ self->netdev = dev;
+ spin_lock_init(&self->lock);
+
+ /* Need to store self somewhere */
+@@ -282,9 +281,8 @@
+ if (!request_region(self->io.fir_base, self->io.fir_ext, driver_name)) {
+ WARNING("%s(), can't get iobase of 0x%03x\n", __FUNCTION__,
+ self->io.fir_base);
+- dev_self[i] = NULL;
+- kfree(self);
+- return -ENODEV;
++ err = -ENODEV;
++ goto err_out1;
+ }
+
+ /* Initialize QoS for this device */
+@@ -307,19 +305,17 @@
+ /* Allocate memory if needed */
+ self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize,
+ GFP_KERNEL |GFP_DMA);
+- if (self->rx_buff.head == NULL)
+- {
+- kfree(self);
+- return -ENOMEM;
++ if (self->rx_buff.head == NULL) {
++ err = -ENOMEM;
++ goto err_out2;
+ }
+ memset(self->rx_buff.head, 0, self->rx_buff.truesize);
+
+ self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize,
+ GFP_KERNEL|GFP_DMA);
+ if (self->tx_buff.head == NULL) {
+- kfree(self->rx_buff.head);
+- kfree(self);
+- return -ENOMEM;
++ err = -ENOMEM;
++ goto err_out3;
+ }
+ memset(self->tx_buff.head, 0, self->tx_buff.truesize);
+
+@@ -332,28 +328,21 @@
+ self->tx_fifo.len = self->tx_fifo.ptr = self->tx_fifo.free = 0;
+ self->tx_fifo.tail = self->tx_buff.head;
+
+- if (!(dev = dev_alloc("irda%d", &err))) {
+- ERROR("%s(), dev_alloc() failed!\n", __FUNCTION__);
+- return -ENOMEM;
+- }
+-
+- dev->priv = (void *) self;
+- self->netdev = dev;
+
++ /* Keep track of module usage */
++ SET_MODULE_OWNER(dev);
++
+ /* Override the network functions we need to use */
+- dev->init = ali_ircc_net_init;
+ dev->hard_start_xmit = ali_ircc_sir_hard_xmit;
+ dev->open = ali_ircc_net_open;
+ dev->stop = ali_ircc_net_close;
+ dev->do_ioctl = ali_ircc_net_ioctl;
+ dev->get_stats = ali_ircc_net_get_stats;
+
+- rtnl_lock();
+- err = register_netdevice(dev);
+- rtnl_unlock();
++ err = register_netdev(dev);
+ if (err) {
+ ERROR("%s(), register_netdev() failed!\n", __FUNCTION__);
+- return -1;
++ goto err_out4;
+ }
+ MESSAGE("IrDA: Registered device %s\n", dev->name);
+
+@@ -370,6 +359,17 @@
+ IRDA_DEBUG(2, "%s(), ----------------- End -----------------\n", __FUNCTION__);
+
+ return 0;
++
++ err_out4:
++ kfree(self->tx_buff.head);
++ err_out3:
++ kfree(self->rx_buff.head);
++ err_out2:
++ release_region(self->io.fir_base, self->io.fir_ext);
++ err_out1:
++ dev_self[i] = NULL;
++ free_netdev(dev);
++ return err;
+ }
+
+
+@@ -390,8 +390,7 @@
+ iobase = self->io.fir_base;
+
+ /* Remove netdevice */
+- if (self->netdev)
+- unregister_netdev(self->netdev);
++ unregister_netdev(self->netdev);
+
+ /* Release the PORT that this driver is using */
+ IRDA_DEBUG(4, "%s(), Releasing Region %03x\n", __FUNCTION__, self->io.fir_base);
+@@ -404,7 +403,7 @@
+ kfree(self->rx_buff.head);
+
+ dev_self[self->index] = NULL;
+- kfree(self);
++ free_netdev(self->netdev);
+
+ IRDA_DEBUG(2, "%s(), ----------------- End -----------------\n", __FUNCTION__);
+
+@@ -1291,29 +1290,6 @@
+ }
+
+ /*
+- * Function ali_ircc_net_init (dev)
+- *
+- * Initialize network device
+- *
+- */
+-static int ali_ircc_net_init(struct net_device *dev)
+-{
+- IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__ );
+-
+- /* Keep track of module usage */
+- SET_MODULE_OWNER(dev);
+-
+- /* Setup to be a normal IrDA network device driver */
+- irda_device_setup(dev);
+-
+- /* Insert overrides below this line! */
+-
+- IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__ );
+-
+- return 0;
+-}
+-
+-/*
+ * Function ali_ircc_net_open (dev)
+ *
+ * Start the device
+Index: linux-2.6.0-test5/drivers/net/irda/donauboe.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/irda/donauboe.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/irda/donauboe.c 2003-09-27 11:38:26.699469448 +0800
+@@ -1396,20 +1396,6 @@
+ return IRQ_HANDLED;
+ }
+
+-static int
+-toshoboe_net_init (struct net_device *dev)
+-{
+- IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
+-
+- /* Keep track of module usage */
+- SET_MODULE_OWNER(dev);
+-
+- /* Setup to be a normal IrDA network device driver */
+- irda_device_setup (dev);
+-
+- /* Insert overrides below this line! */
+- return 0;
+-}
+
+ static int
+ toshoboe_net_open (struct net_device *dev)
+@@ -1589,14 +1575,13 @@
+ self->rx_bufs[i] = NULL;
+ }
+
+- if (self->netdev)
+- unregister_netdev(self->netdev);
++ unregister_netdev(self->netdev);
+
+ kfree (self->ringbuf);
+ self->ringbuf = NULL;
+ self->ring = NULL;
+
+- return;
++ free_netdev(self->netdev);
+ }
+
+ static int
+@@ -1613,17 +1598,17 @@
+ if ((err=pci_enable_device(pci_dev)))
+ return err;
+
+- self = kmalloc (sizeof (struct toshoboe_cb), GFP_KERNEL);
+-
+- if (self == NULL)
++ dev = alloc_netdev(sizeof (struct toshoboe_cb), "irda%d",
++ irda_device_setup);
++ if (dev == NULL)
+ {
+ printk (KERN_ERR DRIVER_NAME ": can't allocate memory for "
+ "IrDA control block\n");
+ return -ENOMEM;
+ }
+
+- memset (self, 0, sizeof (struct toshoboe_cb));
+-
++ self = dev->priv;
++ self->netdev = dev;
+ self->pdev = pci_dev;
+ self->base = pci_resource_start(pci_dev,0);
+
+@@ -1732,33 +1717,20 @@
+ }
+ #endif
+
+- if (!(dev = dev_alloc ("irda%d", &err)))
+- {
+- printk (KERN_ERR DRIVER_NAME ": dev_alloc() failed\n");
+- err = -ENOMEM;
+- goto freebufs;
+- }
+-
+- dev->priv = (void *) self;
+- self->netdev = dev;
+-
+- printk (KERN_INFO "IrDA: Registered device %s\n", dev->name);
+-
+- dev->init = toshoboe_net_init;
++ SET_MODULE_OWNER(dev);
+ dev->hard_start_xmit = toshoboe_hard_xmit;
+ dev->open = toshoboe_net_open;
+ dev->stop = toshoboe_net_close;
+ dev->do_ioctl = toshoboe_net_ioctl;
+
+- rtnl_lock ();
+- err = register_netdevice (dev);
+- rtnl_unlock ();
++ err = register_netdev(dev);
+ if (err)
+ {
+ printk (KERN_ERR DRIVER_NAME ": register_netdev() failed\n");
+ err = -ENOMEM;
+ goto freebufs;
+ }
++ printk (KERN_INFO "IrDA: Registered device %s\n", dev->name);
+
+ pci_set_drvdata(pci_dev,self);
+
+@@ -1779,7 +1751,7 @@
+ release_region (self->io.fir_base, self->io.fir_ext);
+
+ freeself:
+- kfree (self);
++ free_netdev(dev);
+
+ return err;
+ }
+Index: linux-2.6.0-test5/drivers/net/irda/irda-usb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/irda/irda-usb.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/irda/irda-usb.c 2003-09-27 11:38:26.713467320 +0800
+@@ -112,7 +112,6 @@
+ static void speed_bulk_callback(struct urb *urb, struct pt_regs *regs);
+ static void write_bulk_callback(struct urb *urb, struct pt_regs *regs);
+ static void irda_usb_receive(struct urb *urb, struct pt_regs *regs);
+-static int irda_usb_net_init(struct net_device *dev);
+ static int irda_usb_net_open(struct net_device *dev);
+ static int irda_usb_net_close(struct net_device *dev);
+ static int irda_usb_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+@@ -901,24 +900,6 @@
+ * be dealt with below...
+ */
+
+-/*------------------------------------------------------------------*/
+-/*
+- * Callback when a new IrDA device is created.
+- */
+-static int irda_usb_net_init(struct net_device *dev)
+-{
+- IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
+-
+- /* Keep track of module usage */
+- SET_MODULE_OWNER(dev);
+-
+- /* Set up to be a normal IrDA network device driver */
+- irda_device_setup(dev);
+-
+- /* Insert overrides below this line! */
+-
+- return 0;
+-}
+
+ /*------------------------------------------------------------------*/
+ /*
+@@ -1195,15 +1176,18 @@
+ memset(self->speed_buff, 0, IRDA_USB_SPEED_MTU);
+
+ /* Create a network device for us */
+- if (!(netdev = dev_alloc("irda%d", &err))) {
+- ERROR("%s(), dev_alloc() failed!\n", __FUNCTION__);
+- return -1;
++ netdev = alloc_netdev(0, "irda%d", irda_device_setup);
++ if (!netdev) {
++ ERROR("%s(), alloc_net_dev() failed!\n", __FUNCTION__);
++ return -ENOMEM;
+ }
++
++ SET_MODULE_OWNER(dev);
++
+ self->netdev = netdev;
+ netdev->priv = (void *) self;
+
+ /* Override the network functions we need to use */
+- netdev->init = irda_usb_net_init;
+ netdev->hard_start_xmit = irda_usb_hard_xmit;
+ netdev->tx_timeout = irda_usb_net_timeout;
+ netdev->watchdog_timeo = 250*HZ/1000; /* 250 ms > USB timeout */
+@@ -1212,12 +1196,12 @@
+ netdev->get_stats = irda_usb_net_get_stats;
+ netdev->do_ioctl = irda_usb_net_ioctl;
+
+- rtnl_lock();
+- err = register_netdevice(netdev);
+- rtnl_unlock();
++ err = register_netdev(netdev);
+ if (err) {
+ ERROR("%s(), register_netdev() failed!\n", __FUNCTION__);
+- return -1;
++ self->netdev = NULL;
++ free_netdev(netdev);
++ return err;
+ }
+ MESSAGE("IrDA: Registered device %s\n", netdev->name);
+
+@@ -1236,9 +1220,11 @@
+ ASSERT(self != NULL, return -1;);
+
+ /* Remove netdevice */
+- if (self->netdev)
++ if (self->netdev) {
+ unregister_netdev(self->netdev);
+- self->netdev = NULL;
++ free_netdev(self->netdev);
++ self->netdev = NULL;
++ }
+
+ /* Remove the speed buffer */
+ if (self->speed_buff != NULL) {
+Index: linux-2.6.0-test5/drivers/net/irda/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/irda/Kconfig 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/irda/Kconfig 2003-09-27 11:38:26.717466712 +0800
+@@ -254,18 +254,6 @@
+ <file:Documentation/modules.txt>. The module will be called
+ w83977af_ir.
+
+-config TOSHIBA_OLD
+- tristate "Toshiba Type-O IR Port (old driver)"
+- depends on IRDA && BROKEN_ON_SMP
+- help
+- Say Y here if you want to build support for the Toshiba Type-O IR
+- chipset. This chipset is used by the Toshiba Libretto 100CT, and
+- many more laptops. This driver is obsolete, will no more be
+- maintained and will be removed in favor of the new driver.
+- If you want to compile it as a module, say M here and read
+- <file:Documentation/modules.txt>.
+- The module will be called toshoboe.
+-
+ config TOSHIBA_FIR
+ tristate "Toshiba Type-O IR Port"
+ depends on IRDA
+@@ -281,18 +269,6 @@
+ tristate "Alchemy Au1000 SIR/FIR"
+ depends on MIPS_AU1000 && IRDA
+
+-config SMC_IRCC_OLD
+- tristate "SMC IrCC (old driver) (EXPERIMENTAL)"
+- depends on EXPERIMENTAL && IRDA && ISA
+- help
+- Say Y here if you want to build support for the SMC Infrared
+- Communications Controller. It is used in the Fujitsu Lifebook 635t
+- and Sony PCG-505TX. This driver is obsolete, will no more be
+- maintained and will be removed in favor of the new driver.
+- If you want to compile it as a module, say M here and read
+- <file:Documentation/modules.txt>. The module will be
+- called smc-ircc.
+-
+ config SMC_IRCC_FIR
+ tristate "SMSC IrCC (EXPERIMENTAL)"
+ depends on EXPERIMENTAL && IRDA && ISA
+Index: linux-2.6.0-test5/drivers/net/irda/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/irda/Makefile 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/irda/Makefile 2003-09-27 11:38:26.719466408 +0800
+@@ -12,9 +12,7 @@
+ obj-$(CONFIG_NSC_FIR) += nsc-ircc.o
+ obj-$(CONFIG_WINBOND_FIR) += w83977af_ir.o
+ obj-$(CONFIG_SA1100_FIR) += sa1100_ir.o
+-obj-$(CONFIG_TOSHIBA_OLD) += toshoboe.o
+ obj-$(CONFIG_TOSHIBA_FIR) += donauboe.o
+-obj-$(CONFIG_SMC_IRCC_OLD) += smc-ircc.o irport.o
+ obj-$(CONFIG_SMC_IRCC_FIR) += smsc-ircc2.o
+ obj-$(CONFIG_ALI_FIR) += ali-ircc.o
+ obj-$(CONFIG_VLSI_FIR) += vlsi_ir.o
+Index: linux-2.6.0-test5/drivers/net/irda/nsc-ircc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/irda/nsc-ircc.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/irda/nsc-ircc.c 2003-09-27 11:38:26.734464128 +0800
+@@ -143,7 +143,6 @@
+ static int nsc_ircc_read_dongle_id (int iobase);
+ static void nsc_ircc_init_dongle_interface (int iobase, int dongle_id);
+
+-static int nsc_ircc_net_init(struct net_device *dev);
+ static int nsc_ircc_net_open(struct net_device *dev);
+ static int nsc_ircc_net_close(struct net_device *dev);
+ static int nsc_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+@@ -261,14 +260,16 @@
+
+ MESSAGE("%s, driver loaded (Dag Brattli)\n", driver_name);
+
+- /* Allocate new instance of the driver */
+- self = kmalloc(sizeof(struct nsc_ircc_cb), GFP_KERNEL);
+- if (self == NULL) {
++ dev = alloc_netdev(sizeof(struct nsc_ircc_cb), "irda%d",
++ irda_device_setup);
++ if (dev == NULL) {
+ ERROR("%s(), can't allocate memory for "
+ "control block!\n", __FUNCTION__);
+ return -ENOMEM;
+ }
+- memset(self, 0, sizeof(struct nsc_ircc_cb));
++
++ self = dev->priv;
++ self->netdev = dev;
+ spin_lock_init(&self->lock);
+
+ /* Need to store self somewhere */
+@@ -288,9 +289,8 @@
+ if (!ret) {
+ WARNING("%s(), can't get iobase of 0x%03x\n",
+ __FUNCTION__, self->io.fir_base);
+- dev_self[i] = NULL;
+- kfree(self);
+- return -ENODEV;
++ err = -ENODEV;
++ goto out1;
+ }
+
+ /* Initialize QoS for this device */
+@@ -313,17 +313,17 @@
+ self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize,
+ GFP_KERNEL|GFP_DMA);
+ if (self->rx_buff.head == NULL) {
+- kfree(self);
+- return -ENOMEM;
++ err = -ENOMEM;
++ goto out2;
++
+ }
+ memset(self->rx_buff.head, 0, self->rx_buff.truesize);
+
+ self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize,
+ GFP_KERNEL|GFP_DMA);
+ if (self->tx_buff.head == NULL) {
+- kfree(self->rx_buff.head);
+- kfree(self);
+- return -ENOMEM;
++ err = -ENOMEM;
++ goto out3;
+ }
+ memset(self->tx_buff.head, 0, self->tx_buff.truesize);
+
+@@ -336,28 +336,18 @@
+ self->tx_fifo.len = self->tx_fifo.ptr = self->tx_fifo.free = 0;
+ self->tx_fifo.tail = self->tx_buff.head;
+
+- if (!(dev = dev_alloc("irda%d", &err))) {
+- ERROR("%s(), dev_alloc() failed!\n", __FUNCTION__);
+- return -ENOMEM;
+- }
+-
+- dev->priv = (void *) self;
+- self->netdev = dev;
+-
+ /* Override the network functions we need to use */
+- dev->init = nsc_ircc_net_init;
++ SET_MODULE_OWNER(dev);
+ dev->hard_start_xmit = nsc_ircc_hard_xmit_sir;
+ dev->open = nsc_ircc_net_open;
+ dev->stop = nsc_ircc_net_close;
+ dev->do_ioctl = nsc_ircc_net_ioctl;
+ dev->get_stats = nsc_ircc_net_get_stats;
+
+- rtnl_lock();
+- err = register_netdevice(dev);
+- rtnl_unlock();
++ err = register_netdev(dev);
+ if (err) {
+ ERROR("%s(), register_netdev() failed!\n", __FUNCTION__);
+- return -1;
++ goto out4;
+ }
+ MESSAGE("IrDA: Registered device %s\n", dev->name);
+
+@@ -380,6 +370,16 @@
+ pmdev->data = self;
+
+ return 0;
++ out4:
++ kfree(self->tx_buff.head);
++ out3:
++ kfree(self->rx_buff.head);
++ out2:
++ release_region(self->io.fir_base, self->io.fir_ext);
++ out1:
++ free_netdev(dev);
++ dev_self[i] = NULL;
++ return err;
+ }
+
+ /*
+@@ -399,8 +399,7 @@
+ iobase = self->io.fir_base;
+
+ /* Remove netdevice */
+- if (self->netdev)
+- unregister_netdev(self->netdev);
++ unregister_netdev(self->netdev);
+
+ /* Release the PORT that this driver is using */
+ IRDA_DEBUG(4, "%s(), Releasing Region %03x\n",
+@@ -414,7 +413,7 @@
+ kfree(self->rx_buff.head);
+
+ dev_self[self->index] = NULL;
+- kfree(self);
++ free_netdev(self->netdev);
+
+ return 0;
+ }
+@@ -1991,27 +1990,6 @@
+ }
+
+ /*
+- * Function nsc_ircc_net_init (dev)
+- *
+- * Initialize network device
+- *
+- */
+-static int nsc_ircc_net_init(struct net_device *dev)
+-{
+- IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
+-
+- /* Keep track of module usage */
+- SET_MODULE_OWNER(dev);
+-
+- /* Setup to be a normal IrDA network device driver */
+- irda_device_setup(dev);
+-
+- /* Insert overrides below this line! */
+-
+- return 0;
+-}
+-
+-/*
+ * Function nsc_ircc_net_open (dev)
+ *
+ * Start the device
+Index: linux-2.6.0-test5/drivers/net/irda/sir_kthread.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/irda/sir_kthread.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/irda/sir_kthread.c 2003-09-27 11:38:26.738463520 +0800
+@@ -132,7 +132,7 @@
+ if (list_empty(&irda_rq_queue.request_list))
+ schedule();
+ else
+- set_task_state(current, TASK_RUNNING);
++ __set_task_state(current, TASK_RUNNING);
+ remove_wait_queue(&irda_rq_queue.kick, &wait);
+
+ /* make swsusp happy with our thread */
+@@ -165,7 +165,7 @@
+ if (atomic_read(&irda_rq_queue.num_pending))
+ schedule();
+ else
+- set_task_state(current, TASK_RUNNING);
++ __set_task_state(current, TASK_RUNNING);
+ remove_wait_queue(&irda_rq_queue.done, &wait);
+ }
+ }
+Index: linux-2.6.0-test5/drivers/net/irda/via-ircc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/irda/via-ircc.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/irda/via-ircc.c 2003-09-27 11:38:26.749461848 +0800
+@@ -94,7 +94,6 @@
+ static int via_ircc_is_receiving(struct via_ircc_cb *self);
+ static int via_ircc_read_dongle_id(int iobase);
+
+-static int via_ircc_net_init(struct net_device *dev);
+ static int via_ircc_net_open(struct net_device *dev);
+ static int via_ircc_net_close(struct net_device *dev);
+ static int via_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq,
+@@ -107,7 +106,7 @@
+ void hwreset(struct via_ircc_cb *self);
+ static int via_ircc_dma_xmit(struct via_ircc_cb *self, u16 iobase);
+ static int upload_rxdata(struct via_ircc_cb *self, int iobase);
+-static int __init via_init_one (struct pci_dev *pcidev, const struct pci_device_id *id);
++static int __devinit via_init_one (struct pci_dev *pcidev, const struct pci_device_id *id);
+ static void __exit via_remove_one (struct pci_dev *pdev);
+
+ /* Should use udelay() instead, even if we are x86 only - Jean II */
+@@ -121,7 +120,7 @@
+ }
+ }
+
+-static struct pci_device_id via_pci_tbl[] __initdata = {
++static struct pci_device_id via_pci_tbl[] = {
+ { PCI_VENDOR_ID_VIA, DeviceID1, PCI_ANY_ID, PCI_ANY_ID,0,0,0 },
+ { PCI_VENDOR_ID_VIA, DeviceID2, PCI_ANY_ID, PCI_ANY_ID,0,0,1 },
+ { PCI_VENDOR_ID_VIA, DeviceID3, PCI_ANY_ID, PCI_ANY_ID,0,0,2 },
+@@ -168,7 +167,7 @@
+
+ }
+
+-static int __init via_init_one (struct pci_dev *pcidev, const struct pci_device_id *id)
++static int __devinit via_init_one (struct pci_dev *pcidev, const struct pci_device_id *id)
+ {
+ int rc;
+ u8 temp,oldPCI_40,oldPCI_44,bTmp,bTmp1;
+@@ -326,22 +325,23 @@
+ * Open driver instance
+ *
+ */
+-static __init int via_ircc_open(int i, chipio_t * info, unsigned int id)
++static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id)
+ {
+ struct net_device *dev;
+ struct via_ircc_cb *self;
+- int ret;
+ int err;
+
+ if ((via_ircc_setup(info, id)) == -1)
+ return -1;
+
+ /* Allocate new instance of the driver */
+- self = kmalloc(sizeof(struct via_ircc_cb), GFP_KERNEL);
+- if (self == NULL) {
++ dev = alloc_netdev(sizeof(struct via_ircc_cb), "irda%d",
++ irda_device_setup);
++ if (dev == NULL)
+ return -ENOMEM;
+- }
+- memset(self, 0, sizeof(struct via_ircc_cb));
++
++ self = dev->priv;
++ self->netdev = dev;
+ spin_lock_init(&self->lock);
+
+ /* Need to store self somewhere */
+@@ -360,14 +360,12 @@
+ self->RxDataReady = 0;
+
+ /* Reserve the ioports that we need */
+- ret = check_region(self->io.fir_base, self->io.fir_ext);
+- if (ret < 0) {
++ if (!request_region(self->io.fir_base, self->io.fir_ext, driver_name)) {
+ // WARNING(__FUNCTION__ "(), can't get iobase of 0x%03x\n",self->io.fir_base);
+- dev_self[i] = NULL;
+- kfree(self);
+- return -ENODEV;
++ err = -ENODEV;
++ goto err_out1;
+ }
+- request_region(self->io.fir_base, self->io.fir_ext, driver_name);
++
+ /* Initialize QoS for this device */
+ irda_init_max_qos_capabilies(&self->qos);
+ /* The only value we must override it the baudrate */
+@@ -391,17 +389,16 @@
+ self->rx_buff.head =
+ (__u8 *) kmalloc(self->rx_buff.truesize, GFP_KERNEL | GFP_DMA);
+ if (self->rx_buff.head == NULL) {
+- kfree(self);
+- return -ENOMEM;
++ err = -ENOMEM;
++ goto err_out2;
+ }
+ memset(self->rx_buff.head, 0, self->rx_buff.truesize);
+
+ self->tx_buff.head =
+ (__u8 *) kmalloc(self->tx_buff.truesize, GFP_KERNEL | GFP_DMA);
+ if (self->tx_buff.head == NULL) {
+- kfree(self->rx_buff.head);
+- kfree(self);
+- return -ENOMEM;
++ err = -ENOMEM;
++ goto err_out3;
+ }
+ memset(self->tx_buff.head, 0, self->tx_buff.truesize);
+
+@@ -414,30 +411,20 @@
+ self->tx_fifo.len = self->tx_fifo.ptr = self->tx_fifo.free = 0;
+ self->tx_fifo.tail = self->tx_buff.head;
+
+- if (!(dev = dev_alloc("irda%d", &err))) {
+- kfree(self->tx_buff.head);
+- kfree(self->rx_buff.head);
+- kfree(self);
+- return -ENOMEM;
+- }
+-
+- dev->priv = (void *) self;
+- self->netdev = dev;
++ /* Keep track of module usage */
++ SET_MODULE_OWNER(dev);
+
+ /* Override the network functions we need to use */
+- dev->init = via_ircc_net_init;
+ dev->hard_start_xmit = via_ircc_hard_xmit_sir;
+ dev->open = via_ircc_net_open;
+ dev->stop = via_ircc_net_close;
+ dev->do_ioctl = via_ircc_net_ioctl;
+ dev->get_stats = via_ircc_net_get_stats;
+
+- rtnl_lock();
+- err = register_netdevice(dev);
+- rtnl_unlock();
+- if (err) {
+- return -1;
+- }
++ err = register_netdev(dev);
++ if (err)
++ goto err_out4;
++
+ MESSAGE("IrDA: Registered device %s\n", dev->name);
+
+ /* Check if user has supplied the dongle id or not */
+@@ -448,6 +435,16 @@
+ self->io.dongle_id);
+
+ return 0;
++ err_out4:
++ kfree(self->tx_buff.head);
++ err_out3:
++ kfree(self->rx_buff.head);
++ err_out2:
++ release_region(self->io.fir_base, self->io.fir_ext);
++ err_out1:
++ free_netdev(dev);
++ dev_self[i] = NULL;
++ return err;
+ }
+
+ /*
+@@ -468,11 +465,7 @@
+
+ ResetChip(iobase, 5); //hardware reset.
+ /* Remove netdevice */
+- if (self->netdev) {
+- rtnl_lock();
+- unregister_netdevice(self->netdev);
+- rtnl_unlock();
+- }
++ unregister_netdev(self->netdev);
+
+ /* Release the PORT that this driver is using */
+ IRDA_DEBUG(4, "%s(), Releasing Region %03x\n",
+@@ -483,7 +476,8 @@
+ if (self->rx_buff.head)
+ kfree(self->rx_buff.head);
+ dev_self[self->index] = NULL;
+- kfree(self);
++
++ free_netdev(self->netdev);
+
+ return 0;
+ }
+@@ -1456,26 +1450,6 @@
+ return status;
+ }
+
+-/*
+- * Function via_ircc_net_init (dev)
+- *
+- * Initialize network device
+- *
+- */
+-static int via_ircc_net_init(struct net_device *dev)
+-{
+- IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
+-
+- /* Keep track of module usage */
+- SET_MODULE_OWNER(dev);
+-
+- /* Setup to be a normal IrDA network device driver */
+- irda_device_setup(dev);
+-
+- /* Insert overrides below this line! */
+-
+- return 0;
+-}
+
+ /*
+ * Function via_ircc_net_open (dev)
+Index: linux-2.6.0-test5/drivers/net/irda/w83977af_ir.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/irda/w83977af_ir.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/irda/w83977af_ir.c 2003-09-27 11:38:26.758460480 +0800
+@@ -99,7 +99,6 @@
+ static void w83977af_change_speed(struct w83977af_ir *self, __u32 speed);
+ static int w83977af_is_receiving(struct w83977af_ir *self);
+
+-static int w83977af_net_init(struct net_device *dev);
+ static int w83977af_net_open(struct net_device *dev);
+ static int w83977af_net_close(struct net_device *dev);
+ static int w83977af_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+@@ -171,14 +170,16 @@
+ /*
+ * Allocate new instance of the driver
+ */
+- self = kmalloc(sizeof(struct w83977af_ir), GFP_KERNEL);
+- if (self == NULL) {
++ dev = alloc_netdev(sizeof(struct w83977af_ir), "irda%d",
++ irda_device_setup);
++ if (dev == NULL) {
+ printk( KERN_ERR "IrDA: Can't allocate memory for "
+ "IrDA control block!\n");
+ err = -ENOMEM;
+ goto err_out;
+ }
+- memset(self, 0, sizeof(struct w83977af_ir));
++
++ self = dev->priv;
+ spin_lock_init(&self->lock);
+
+
+@@ -230,29 +231,21 @@
+ self->rx_buff.state = OUTSIDE_FRAME;
+ self->tx_buff.data = self->tx_buff.head;
+ self->rx_buff.data = self->rx_buff.head;
+-
+- if (!(dev = dev_alloc("irda%d", &err))) {
+- ERROR("%s(), dev_alloc() failed!\n", __FUNCTION__);
+- err = -ENOMEM;
+- goto err_out3;
+- }
+- dev->priv = (void *) self;
+ self->netdev = dev;
+
++ /* Keep track of module usage */
++ SET_MODULE_OWNER(dev);
++
+ /* Override the network functions we need to use */
+- dev->init = w83977af_net_init;
+ dev->hard_start_xmit = w83977af_hard_xmit;
+ dev->open = w83977af_net_open;
+ dev->stop = w83977af_net_close;
+ dev->do_ioctl = w83977af_net_ioctl;
+ dev->get_stats = w83977af_net_get_stats;
+
+- rtnl_lock();
+- err = register_netdevice(dev);
+- rtnl_unlock();
++ err = register_netdev(dev);
+ if (err) {
+ ERROR("%s(), register_netdevice() failed!\n", __FUNCTION__);
+- err = -1;
+ goto err_out3;
+ }
+ MESSAGE("IrDA: Registered device %s\n", dev->name);
+@@ -266,7 +259,7 @@
+ err_out2:
+ kfree(self->rx_buff.head);
+ err_out1:
+- kfree(self);
++ free_netdev(dev);
+ err_out:
+ release_region(iobase, CHIP_IO_EXTENT);
+ return err;
+@@ -299,8 +292,7 @@
+ #endif /* CONFIG_USE_W977_PNP */
+
+ /* Remove netdevice */
+- if (self->netdev)
+- unregister_netdev(self->netdev);
++ unregister_netdev(self->netdev);
+
+ /* Release the PORT that this driver is using */
+ IRDA_DEBUG(0 , "%s(), Releasing Region %03x\n",
+@@ -313,7 +305,7 @@
+ if (self->rx_buff.head)
+ kfree(self->rx_buff.head);
+
+- kfree(self);
++ free_netdev(self->netdev);
+
+ return 0;
+ }
+@@ -1187,28 +1179,6 @@
+ }
+
+ /*
+- * Function w83977af_net_init (dev)
+- *
+- *
+- *
+- */
+-static int w83977af_net_init(struct net_device *dev)
+-{
+- IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
+-
+- /* Keep track of module usage */
+- SET_MODULE_OWNER(dev);
+-
+- /* Set up to be a normal IrDA network device driver */
+- irda_device_setup(dev);
+-
+- /* Insert overrides below this line! */
+-
+- return 0;
+-}
+-
+-
+-/*
+ * Function w83977af_net_open (dev)
+ *
+ * Start the device
+Index: linux-2.6.0-test5/drivers/net/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/Kconfig 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/Kconfig 2003-09-27 11:38:26.785456376 +0800
+@@ -2715,6 +2715,9 @@
+ module, say M here and read <file:Documentation/modules.txt>. If
+ unsure, say N.
+
++config NET_POLL_CONTROLLER
++ def_bool KGDB
++
+ source "drivers/net/wan/Kconfig"
+
+ source "drivers/net/pcmcia/Kconfig"
+Index: linux-2.6.0-test5/drivers/net/kgdb_eth.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/kgdb_eth.c 2003-09-27 11:38:18.455722688 +0800
++++ linux-2.6.0-test5/drivers/net/kgdb_eth.c 2003-09-27 11:38:26.787456072 +0800
+@@ -0,0 +1,517 @@
++/*
++ * Network interface GDB stub
++ *
++ * Written by San Mehat (nettwerk@biodome.org)
++ * Based upon 'gdbserial' by David Grothe (dave@gcom.com)
++ * and Scott Foehner (sfoehner@engr.sgi.com)
++ *
++ * Twiddled for 2.6 by Robert Walsh <rjwalsh@durables.org>
++ * and wangdi <wangdi@clusterfs.com>.
++ */
++
++#include <linux/module.h>
++#include <linux/errno.h>
++#include <linux/signal.h>
++#include <linux/sched.h>
++#include <linux/timer.h>
++#include <linux/interrupt.h>
++#include <linux/config.h>
++#include <linux/major.h>
++#include <linux/string.h>
++#include <linux/fcntl.h>
++#include <linux/termios.h>
++#include <asm/kgdb.h>
++#include <linux/if_ether.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/skbuff.h>
++#include <linux/delay.h>
++#include <net/tcp.h>
++#include <net/udp.h>
++
++#include <asm/system.h>
++#include <asm/io.h>
++#include <asm/segment.h>
++#include <asm/bitops.h>
++#include <asm/system.h>
++#include <asm/irq.h>
++#include <asm/atomic.h>
++
++#define GDB_BUF_SIZE 512 /* power of 2, please */
++
++static char kgdb_buf[GDB_BUF_SIZE] ;
++static int kgdb_buf_in_inx ;
++static atomic_t kgdb_buf_in_cnt ;
++static int kgdb_buf_out_inx ;
++
++extern void set_debug_traps(void) ; /* GDB routine */
++extern void breakpoint(void);
++
++unsigned int kgdb_remoteip = 0;
++unsigned short kgdb_listenport = 6443;
++unsigned short kgdb_sendport= 6442;
++int kgdb_eth = -1; /* Default tty mode */
++unsigned char kgdb_remotemac[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
++unsigned char kgdb_localmac[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
++volatile int kgdb_eth_is_initializing = 0;
++int kgdb_eth_need_breakpoint[NR_CPUS];
++
++struct net_device *kgdb_netdevice = NULL;
++
++/*
++ * Get a char if available, return -1 if nothing available.
++ * Empty the receive buffer first, then look at the interface hardware.
++ */
++static int
++read_char(void)
++{
++ /* intr routine has queued chars */
++ if (atomic_read(&kgdb_buf_in_cnt) != 0)
++ {
++ int chr;
++
++ chr = kgdb_buf[kgdb_buf_out_inx++] ;
++ kgdb_buf_out_inx &= (GDB_BUF_SIZE - 1) ;
++ atomic_dec(&kgdb_buf_in_cnt) ;
++ return chr;
++ }
++
++ return -1; /* no data */
++}
++
++/*
++ * Wait until the interface can accept a char, then write it.
++ */
++static void
++write_buffer(char *buf, int len)
++{
++ int total_len, eth_len, ip_len, udp_len;
++ struct in_device *in_dev;
++ struct sk_buff *skb;
++ struct udphdr *udph;
++ struct iphdr *iph;
++ struct ethhdr *eth;
++
++ if (!(in_dev = (struct in_device *) kgdb_netdevice->ip_ptr)) {
++ panic("No in_device available for interface!\n");
++ }
++
++ if (!(in_dev->ifa_list)) {
++ panic("No interface address set for interface!\n");
++ }
++
++ udp_len = len + sizeof(struct udphdr);
++ ip_len = eth_len = udp_len + sizeof(struct iphdr);
++ total_len = eth_len + ETH_HLEN;
++
++ if (!(skb = alloc_skb(total_len, GFP_ATOMIC))) {
++ return;
++ }
++
++ atomic_set(&skb->users, 1);
++ skb_reserve(skb, total_len - len);
++
++ memcpy(skb->data, (unsigned char *) buf, len);
++ skb->len += len;
++
++ udph = (struct udphdr *) skb_push(skb, sizeof(*udph));
++ udph->source = htons(kgdb_listenport);
++ udph->dest = htons(kgdb_sendport);
++ udph->len = htons(udp_len);
++ udph->check = 0;
++
++ iph = (struct iphdr *)skb_push(skb, sizeof(*iph));
++ iph->version = 4;
++ iph->ihl = 5;
++ iph->tos = 0;
++ iph->tot_len = htons(ip_len);
++ iph->id = 0;
++ iph->frag_off = 0;
++ iph->ttl = 64;
++ iph->protocol = IPPROTO_UDP;
++ iph->check = 0;
++ iph->saddr = in_dev->ifa_list->ifa_address;
++ iph->daddr = kgdb_remoteip;
++ iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
++
++ eth = (struct ethhdr *) skb_push(skb, ETH_HLEN);
++ eth->h_proto = htons(ETH_P_IP);
++ memcpy(eth->h_source, kgdb_localmac, kgdb_netdevice->addr_len);
++ memcpy(eth->h_dest, kgdb_remotemac, kgdb_netdevice->addr_len);
++
++repeat:
++ spin_lock(&kgdb_netdevice->xmit_lock);
++ kgdb_netdevice->xmit_lock_owner = smp_processor_id();
++
++ if (netif_queue_stopped(kgdb_netdevice)) {
++ kgdb_netdevice->xmit_lock_owner = -1;
++ spin_unlock(&kgdb_netdevice->xmit_lock);
++
++ kgdb_netdevice->poll_controller(kgdb_netdevice);
++ goto repeat;
++ }
++
++ kgdb_netdevice->hard_start_xmit(skb, kgdb_netdevice);
++ kgdb_netdevice->xmit_lock_owner = -1;
++ spin_unlock(&kgdb_netdevice->xmit_lock);
++}
++
++/*
++ * In the interrupt state the target machine will not respond to any
++ * arp requests, so handle them here.
++ */
++
++static struct sk_buff *send_skb = NULL;
++
++void
++kgdb_eth_reply_arp(void)
++{
++ if (send_skb) {
++ spin_lock(&kgdb_netdevice->xmit_lock);
++ kgdb_netdevice->xmit_lock_owner = smp_processor_id();
++ kgdb_netdevice->hard_start_xmit(send_skb, kgdb_netdevice);
++ kgdb_netdevice->xmit_lock_owner = -1;
++ spin_unlock(&kgdb_netdevice->xmit_lock);
++ send_skb = NULL;
++ }
++}
++
++static int
++make_arp_request(struct sk_buff *skb)
++{
++ struct arphdr *arp;
++ unsigned char *arp_ptr;
++ int type = ARPOP_REPLY;
++ int ptype = ETH_P_ARP;
++ u32 sip, tip;
++ unsigned char *sha, *tha;
++ struct in_device *in_dev = (struct in_device *) kgdb_netdevice->ip_ptr;
++
++ /* No arp on this interface */
++
++ if (kgdb_netdevice->flags & IFF_NOARP) {
++ return 0;
++ }
++
++ if (!pskb_may_pull(skb, (sizeof(struct arphdr) +
++ (2 * kgdb_netdevice->addr_len) +
++ (2 * sizeof(u32))))) {
++ return 0;
++ }
++
++ skb->h.raw = skb->nh.raw = skb->data;
++ arp = skb->nh.arph;
++
++ if ((arp->ar_hrd != htons(ARPHRD_ETHER) &&
++ arp->ar_hrd != htons(ARPHRD_IEEE802)) ||
++ arp->ar_pro != htons(ETH_P_IP)) {
++ return 0;
++ }
++
++ /* Understand only these message types */
++
++ if (arp->ar_op != htons(ARPOP_REQUEST)) {
++ return 0;
++ }
++
++ /* Extract fields */
++
++ arp_ptr= (unsigned char *)(arp+1);
++ sha = arp_ptr;
++ arp_ptr += kgdb_netdevice->addr_len;
++ memcpy(&sip, arp_ptr, 4);
++ arp_ptr += 4;
++ tha = arp_ptr;
++ arp_ptr += kgdb_netdevice->addr_len;
++ memcpy(&tip, arp_ptr, 4);
++
++ if (tip != in_dev->ifa_list->ifa_address) {
++ return 0;
++ }
++
++ if (kgdb_remoteip != sip) {
++ return 0;
++ }
++
++ /*
++ * Check for bad requests for 127.x.x.x and requests for multicast
++ * addresses. If this is one such, delete it.
++ */
++
++ if (LOOPBACK(tip) || MULTICAST(tip)) {
++ return 0;
++ }
++
++ /* reply to the ARP request */
++
++ send_skb = alloc_skb(sizeof(struct arphdr) + 2 * (kgdb_netdevice->addr_len + 4) + LL_RESERVED_SPACE(kgdb_netdevice), GFP_ATOMIC);
++
++ if (send_skb == NULL) {
++ return 0;
++ }
++
++ skb_reserve(send_skb, LL_RESERVED_SPACE(kgdb_netdevice));
++ send_skb->nh.raw = send_skb->data;
++ arp = (struct arphdr *) skb_put(send_skb, sizeof(struct arphdr) + 2 * (kgdb_netdevice->addr_len + 4));
++ send_skb->dev = kgdb_netdevice;
++ send_skb->protocol = htons(ETH_P_ARP);
++
++ /* Fill the device header for the ARP frame */
++
++ if (kgdb_netdevice->hard_header &&
++ kgdb_netdevice->hard_header(send_skb, kgdb_netdevice, ptype,
++ kgdb_remotemac, kgdb_localmac,
++ send_skb->len) < 0) {
++ kfree_skb(send_skb);
++ return 0;
++ }
++
++ /*
++ * Fill out the arp protocol part.
++ *
++ * we only support ethernet device type,
++ * which (according to RFC 1390) should always equal 1 (Ethernet).
++ */
++
++ arp->ar_hrd = htons(kgdb_netdevice->type);
++ arp->ar_pro = htons(ETH_P_IP);
++
++ arp->ar_hln = kgdb_netdevice->addr_len;
++ arp->ar_pln = 4;
++ arp->ar_op = htons(type);
++
++ arp_ptr=(unsigned char *)(arp + 1);
++
++ memcpy(arp_ptr, kgdb_netdevice->dev_addr, kgdb_netdevice->addr_len);
++ arp_ptr += kgdb_netdevice->addr_len;
++ memcpy(arp_ptr, &tip, 4);
++ arp_ptr += 4;
++ memcpy(arp_ptr, kgdb_localmac, kgdb_netdevice->addr_len);
++ arp_ptr += kgdb_netdevice->addr_len;
++ memcpy(arp_ptr, &sip, 4);
++ return 0;
++}
++
++
++/*
++ * Accept an skbuff from net_device layer and add the payload onto
++ * kgdb buffer
++ *
++ * When the kgdb stub routine getDebugChar() is called it draws characters
++ * out of the buffer until it is empty and then reads directly from the
++ * serial port.
++ *
++ * We do not attempt to write chars from the interrupt routine since
++ * the stubs do all of that via putDebugChar() which writes one byte
++ * after waiting for the interface to become ready.
++ *
++ * The debug stubs like to run with interrupts disabled since, after all,
++ * they run as a consequence of a breakpoint in the kernel.
++ *
++ * NOTE: Return value of 1 means it was for us and is an indication to
++ * the calling driver to destroy the sk_buff and not send it up the stack.
++ */
++int
++kgdb_net_interrupt(struct sk_buff *skb)
++{
++ unsigned char chr;
++ struct iphdr *iph = (struct iphdr*)skb->data;
++ struct udphdr *udph= (struct udphdr*)(skb->data+(iph->ihl<<2));
++ unsigned char *data = (unsigned char *) udph + sizeof(struct udphdr);
++ int len;
++ int i;
++
++ if ((kgdb_eth != -1) && (!kgdb_netdevice) &&
++ (iph->protocol == IPPROTO_UDP) &&
++ (be16_to_cpu(udph->dest) == kgdb_listenport)) {
++ kgdb_sendport = be16_to_cpu(udph->source);
++
++ while (kgdb_eth_is_initializing)
++ ;
++ if (!kgdb_netdevice)
++ kgdb_eth_hook();
++ if (!kgdb_netdevice) {
++ /* Lets not even try again. */
++ kgdb_eth = -1;
++ return 0;
++ }
++ }
++ if (!kgdb_netdevice) {
++ return 0;
++ }
++ if (skb->protocol == __constant_htons(ETH_P_ARP) && !send_skb) {
++ make_arp_request(skb);
++ return 0;
++ }
++ if (iph->protocol != IPPROTO_UDP) {
++ return 0;
++ }
++
++ if (be16_to_cpu(udph->dest) != kgdb_listenport) {
++ return 0;
++ }
++
++ len = (be16_to_cpu(iph->tot_len) -
++ (sizeof(struct udphdr) + sizeof(struct iphdr)));
++
++ for (i = 0; i < len; i++) {
++ chr = data[i];
++ if (chr == 3) {
++ kgdb_eth_need_breakpoint[smp_processor_id()] = 1;
++ continue;
++ }
++ if (atomic_read(&kgdb_buf_in_cnt) >= GDB_BUF_SIZE) {
++ /* buffer overflow, clear it */
++ kgdb_buf_in_inx = 0;
++ atomic_set(&kgdb_buf_in_cnt, 0);
++ kgdb_buf_out_inx = 0;
++ break;
++ }
++ kgdb_buf[kgdb_buf_in_inx++] = chr;
++ kgdb_buf_in_inx &= (GDB_BUF_SIZE - 1);
++ atomic_inc(&kgdb_buf_in_cnt);
++ }
++
++ if (!kgdb_netdevice->kgdb_is_trapped) {
++ /*
++ * If a new gdb instance is trying to attach, we need to
++ * break here.
++ */
++ if (!strncmp(data, "$Hc-1#09", 8))
++ kgdb_eth_need_breakpoint[smp_processor_id()] = 1;
++ }
++ return 1;
++}
++EXPORT_SYMBOL(kgdb_net_interrupt);
++
++int
++kgdb_eth_hook(void)
++{
++ char kgdb_netdev[16];
++ extern void kgdb_respond_ok(void);
++
++ if (kgdb_remotemac[0] == 0xff) {
++ panic("ERROR! 'gdbeth_remotemac' option not set!\n");
++ }
++ if (kgdb_localmac[0] == 0xff) {
++ panic("ERROR! 'gdbeth_localmac' option not set!\n");
++ }
++ if (kgdb_remoteip == 0) {
++ panic("ERROR! 'gdbeth_remoteip' option not set!\n");
++ }
++
++ sprintf(kgdb_netdev,"eth%d",kgdb_eth);
++
++#ifdef CONFIG_SMP
++ if (num_online_cpus() > CONFIG_NO_KGDB_CPUS) {
++ printk("kgdb: too manu cpus. Cannot enable debugger with more than %d cpus\n", CONFIG_NO_KGDB_CPUS);
++ return -1;
++ }
++#endif
++ for (kgdb_netdevice = dev_base;
++ kgdb_netdevice != NULL;
++ kgdb_netdevice = kgdb_netdevice->next) {
++ if (strncmp(kgdb_netdevice->name, kgdb_netdev, IFNAMSIZ) == 0) {
++ break;
++ }
++ }
++ if (!kgdb_netdevice) {
++ printk("KGDB NET : Unable to find interface %s\n",kgdb_netdev);
++ return -ENODEV;
++ }
++
++ /*
++ * Call GDB routine to setup the exception vectors for the debugger
++ */
++ set_debug_traps();
++
++ /*
++ * Call the breakpoint() routine in GDB to start the debugging
++ * session.
++ */
++ kgdb_eth_is_initializing = 1;
++ kgdb_eth_need_breakpoint[smp_processor_id()] = 1;
++ return 0;
++}
++
++/*
++ * getDebugChar
++ *
++ * This is a GDB stub routine. It waits for a character from the
++ * serial interface and then returns it. If there is no serial
++ * interface connection then it returns a bogus value which will
++ * almost certainly cause the system to hang.
++ */
++int
++eth_getDebugChar(void)
++{
++ volatile int chr;
++
++ while ((chr = read_char()) < 0) {
++ if (send_skb) {
++ kgdb_eth_reply_arp();
++ }
++ if (kgdb_netdevice->poll_controller) {
++ kgdb_netdevice->poll_controller(kgdb_netdevice);
++ } else {
++ printk("KGDB NET: Error - Device %s is not supported!\n", kgdb_netdevice->name);
++ panic("Please add support for kgdb net to this driver");
++ }
++ }
++ return chr;
++}
++
++#define ETH_QUEUE_SIZE 256
++static char eth_queue[ETH_QUEUE_SIZE];
++static int outgoing_queue;
++
++void
++eth_flushDebugChar(void)
++{
++ if(outgoing_queue) {
++ write_buffer(eth_queue, outgoing_queue);
++
++ outgoing_queue = 0;
++ }
++}
++
++static void
++put_char_on_queue(int chr)
++{
++ eth_queue[outgoing_queue++] = chr;
++ if(outgoing_queue == ETH_QUEUE_SIZE)
++ {
++ eth_flushDebugChar();
++ }
++}
++
++/*
++ * eth_putDebugChar
++ *
++ * This is a GDB stub routine. It waits until the interface is ready
++ * to transmit a char and then sends it.
++ */
++void
++eth_putDebugChar(int chr)
++{
++ put_char_on_queue(chr); /* this routine will wait */
++}
++
++void
++kgdb_eth_set_trapmode(int mode)
++{
++ if (!kgdb_netdevice) {
++ return;
++ }
++ kgdb_netdevice->kgdb_is_trapped = mode;
++}
++
++int
++kgdb_eth_is_trapped()
++{
++ if (!kgdb_netdevice) {
++ return 0;
++ }
++ return kgdb_netdevice->kgdb_is_trapped;
++}
++EXPORT_SYMBOL(kgdb_eth_is_trapped);
+Index: linux-2.6.0-test5/drivers/net/lance.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/lance.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/lance.c 2003-09-27 11:38:26.797454552 +0800
+@@ -543,7 +543,7 @@
+ if (dev->irq >= 2)
+ printk(" assigned IRQ %d", dev->irq);
+ else if (lance_version != 0) { /* 7990 boards need DMA detection first. */
+- unsigned long irq_mask, delay;
++ unsigned long irq_mask;
+
+ /* To auto-IRQ we enable the initialization-done and DMA error
+ interrupts. For ISA boards we get a DMA error, but VLB and PCI
+@@ -553,8 +553,7 @@
+ /* Trigger an initialization just for the interrupt. */
+ outw(0x0041, ioaddr+LANCE_DATA);
+
+- delay = jiffies + HZ/50;
+- while (time_before(jiffies, delay)) ;
++ mdelay(20);
+ dev->irq = probe_irq_off(irq_mask);
+ if (dev->irq)
+ printk(", probed IRQ %d", dev->irq);
+@@ -621,13 +620,12 @@
+ if (lance_version == 0 && dev->irq == 0) {
+ /* We may auto-IRQ now that we have a DMA channel. */
+ /* Trigger an initialization just for the interrupt. */
+- unsigned long irq_mask, delay;
++ unsigned long irq_mask;
+
+ irq_mask = probe_irq_on();
+ outw(0x0041, ioaddr+LANCE_DATA);
+
+- delay = jiffies + HZ/25;
+- while (time_before(jiffies, delay)) ;
++ mdelay(40);
+ dev->irq = probe_irq_off(irq_mask);
+ if (dev->irq == 0) {
+ printk(" Failed to detect the 7990 IRQ line.\n");
+Index: linux-2.6.0-test5/drivers/net/lne390.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/lne390.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/lne390.c 2003-09-27 11:38:26.812452272 +0800
+@@ -35,6 +35,7 @@
+ "lne390.c: Driver revision v0.99.1, 01/09/2000\n";
+
+ #include <linux/module.h>
++#include <linux/eisa.h>
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+ #include <linux/string.h>
+Index: linux-2.6.0-test5/drivers/net/mace.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/mace.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/mace.c 2003-09-27 11:38:26.819451208 +0800
+@@ -7,7 +7,6 @@
+
+ #include <linux/config.h>
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/kernel.h>
+ #include <linux/netdevice.h>
+ #include <linux/etherdevice.h>
+Index: linux-2.6.0-test5/drivers/net/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/Makefile 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/Makefile 2003-09-27 11:38:26.821450904 +0800
+@@ -32,6 +32,8 @@
+
+ obj-$(CONFIG_OAKNET) += oaknet.o 8390.o
+
++obj-$(CONFIG_KGDB) += kgdb_eth.o
++
+ obj-$(CONFIG_DGRS) += dgrs.o
+ obj-$(CONFIG_RCPCI) += rcpci.o
+ obj-$(CONFIG_VORTEX) += 3c59x.o
+Index: linux-2.6.0-test5/drivers/net/ne2.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/ne2.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/ne2.c 2003-09-27 11:38:26.828449840 +0800
+@@ -60,7 +60,6 @@
+ static const char *version = "ne2.c:v0.91 Nov 16 1998 Wim Dumon <wimpie@kotnet.org>\n";
+
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+ #include <linux/fcntl.h>
+Index: linux-2.6.0-test5/drivers/net/ne3210.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/ne3210.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/ne3210.c 2003-09-27 11:38:26.836448624 +0800
+@@ -29,6 +29,7 @@
+ "ne3210.c: Driver revision v0.03, 30/09/98\n";
+
+ #include <linux/module.h>
++#include <linux/eisa.h>
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+ #include <linux/string.h>
+Index: linux-2.6.0-test5/drivers/net/net_init.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/net_init.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/net_init.c 2003-09-27 11:38:26.841447864 +0800
+@@ -381,7 +381,7 @@
+ dev->hard_header_len = ETH_HLEN;
+ dev->mtu = 1500; /* eth_mtu */
+ dev->addr_len = ETH_ALEN;
+- dev->tx_queue_len = 100; /* Ethernet wants good queues */
++ dev->tx_queue_len = 1000; /* Ethernet wants good queues */
+
+ memset(dev->broadcast,0xFF, ETH_ALEN);
+
+Index: linux-2.6.0-test5/drivers/net/ni5010.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/ni5010.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/ni5010.c 2003-09-27 11:38:26.848446800 +0800
+@@ -255,14 +255,13 @@
+ if (dev->irq == 0xff)
+ ;
+ else if (dev->irq < 2) {
+- unsigned long irq_mask, delay;
++ unsigned long irq_mask;
+
+ PRINTK2((KERN_DEBUG "%s: I/O #5 passed!\n", dev->name));
+
+ irq_mask = probe_irq_on();
+ trigger_irq(ioaddr);
+- delay = jiffies + HZ/50;
+- while (time_before(jiffies, delay)) ;
++ mdelay(20);
+ dev->irq = probe_irq_off(irq_mask);
+
+ PRINTK2((KERN_DEBUG "%s: I/O #6 passed!\n", dev->name));
+Index: linux-2.6.0-test5/drivers/net/ni52.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/ni52.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/ni52.c 2003-09-27 11:38:26.858445280 +0800
+@@ -492,14 +492,13 @@
+
+ if(dev->irq < 2)
+ {
+- unsigned long irq_mask, delay;
++ unsigned long irq_mask;
+
+ irq_mask = probe_irq_on();
+ ni_reset586();
+ ni_attn586();
+
+- delay = jiffies + HZ/50;
+- while (time_before(jiffies, delay)) ;
++ mdelay(20);
+ dev->irq = probe_irq_off(irq_mask);
+ if(!dev->irq)
+ {
+Index: linux-2.6.0-test5/drivers/net/ni65.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/ni65.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/ni65.c 2003-09-27 11:38:26.866444064 +0800
+@@ -72,7 +72,6 @@
+ #include <linux/netdevice.h>
+ #include <linux/etherdevice.h>
+ #include <linux/skbuff.h>
+-#include <linux/version.h>
+ #include <linux/module.h>
+
+ #include <asm/bitops.h>
+Index: linux-2.6.0-test5/drivers/net/ns83820.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/ns83820.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/ns83820.c 2003-09-27 11:38:26.881441784 +0800
+@@ -1833,13 +1833,13 @@
+ if (err) {
+ printk(KERN_INFO "ns83820: unable to register irq %d\n",
+ pci_dev->irq);
+- goto out_unmap;
++ goto out_disable;
+ }
+
+ err = register_netdev(&dev->net_dev);
+ if (err) {
+ printk(KERN_INFO "ns83820: unable to register netdev: %d\n", err);
+- goto out_unmap;
++ goto out_free_irq;
+ }
+
+ printk("%s: ns83820.c: 0x22c: %08x, subsystem: %04x:%04x\n",
+@@ -2025,9 +2025,11 @@
+
+ return 0;
+
+-out_unmap:
+- iounmap(dev->base);
++out_free_irq:
++ free_irq(pci_dev->irq, dev);
+ out_disable:
++ if (dev->base)
++ iounmap(dev->base);
+ pci_free_consistent(pci_dev, 4 * DESC_SIZE * NR_TX_DESC, dev->tx_descs, dev->tx_phy_descs);
+ pci_free_consistent(pci_dev, 4 * DESC_SIZE * NR_RX_DESC, dev->rx_info.descs, dev->rx_info.phy_descs);
+ pci_disable_device(pci_dev);
+Index: linux-2.6.0-test5/drivers/net/pcmcia/3c574_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/pcmcia/3c574_cs.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/pcmcia/3c574_cs.c 2003-09-27 11:38:26.891440264 +0800
+@@ -263,16 +263,6 @@
+
+ static dev_link_t *dev_list;
+
+-static void flush_stale_links(void)
+-{
+- dev_link_t *link, *next;
+- for (link = dev_list; link; link = next) {
+- next = link->next;
+- if (link->state & DEV_STALE_LINK)
+- tc574_detach(link);
+- }
+-}
+-
+ /*
+ tc574_attach() creates an "instance" of the driver, allocating
+ local data structures for one device. The device is registered
+@@ -288,7 +278,6 @@
+ int i, ret;
+
+ DEBUG(0, "3c574_attach()\n");
+- flush_stale_links();
+
+ /* Create the PC card device object. */
+ dev = alloc_etherdev(sizeof(struct el3_private));
+@@ -375,10 +364,8 @@
+
+ if (link->state & DEV_CONFIG) {
+ tc574_release(link);
+- if (link->state & DEV_STALE_CONFIG) {
+- link->state |= DEV_STALE_LINK;
++ if (link->state & DEV_STALE_CONFIG)
+ return;
+- }
+ }
+
+ if (link->handle)
+@@ -583,7 +570,9 @@
+
+ link->state &= ~DEV_CONFIG;
+
+-} /* tc574_release */
++ if (link->state & DEV_STALE_CONFIG)
++ tc574_detach(link);
++}
+
+ /*
+ The card status event handler. Mostly, this schedules other
+Index: linux-2.6.0-test5/drivers/net/pcmcia/3c589_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/pcmcia/3c589_cs.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/pcmcia/3c589_cs.c 2003-09-27 11:38:26.900438896 +0800
+@@ -176,24 +176,6 @@
+
+ /*======================================================================
+
+- This bit of code is used to avoid unregistering network devices
+- at inappropriate times. 2.2 and later kernels are fairly picky
+- about when this can happen.
+-
+-======================================================================*/
+-
+-static void flush_stale_links(void)
+-{
+- dev_link_t *link, *next;
+- for (link = dev_list; link; link = next) {
+- next = link->next;
+- if (link->state & DEV_STALE_LINK)
+- tc589_detach(link);
+- }
+-}
+-
+-/*======================================================================
+-
+ tc589_attach() creates an "instance" of the driver, allocating
+ local data structures for one device. The device is registered
+ with Card Services.
+@@ -209,7 +191,6 @@
+ int i, ret;
+
+ DEBUG(0, "3c589_attach()\n");
+- flush_stale_links();
+
+ /* Create new ethernet device */
+ dev = alloc_etherdev(sizeof(struct el3_private));
+@@ -297,10 +278,8 @@
+
+ if (link->state & DEV_CONFIG) {
+ tc589_release(link);
+- if (link->state & DEV_STALE_CONFIG) {
+- link->state |= DEV_STALE_LINK;
++ if (link->state & DEV_STALE_CONFIG)
+ return;
+- }
+ }
+
+ if (link->handle)
+@@ -466,8 +445,10 @@
+ CardServices(ReleaseIRQ, link->handle, &link->irq);
+
+ link->state &= ~DEV_CONFIG;
+-
+-} /* tc589_release */
++
++ if (link->state & DEV_STALE_CONFIG)
++ tc589_detach(link);
++}
+
+ /*======================================================================
+
+Index: linux-2.6.0-test5/drivers/net/pcmcia/axnet_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/pcmcia/axnet_cs.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/pcmcia/axnet_cs.c 2003-09-27 11:38:26.916436464 +0800
+@@ -142,24 +142,6 @@
+
+ /*======================================================================
+
+- This bit of code is used to avoid unregistering network devices
+- at inappropriate times. 2.2 and later kernels are fairly picky
+- about when this can happen.
+-
+-======================================================================*/
+-
+-static void flush_stale_links(void)
+-{
+- dev_link_t *link, *next;
+- for (link = dev_list; link; link = next) {
+- next = link->next;
+- if (link->state & DEV_STALE_LINK)
+- axnet_detach(link);
+- }
+-}
+-
+-/*======================================================================
+-
+ We never need to do anything when a axnet device is "initialized"
+ by the net software, because we only register already-found cards.
+
+@@ -187,7 +169,6 @@
+ int i, ret;
+
+ DEBUG(0, "axnet_attach()\n");
+- flush_stale_links();
+
+ /* Create new ethernet device */
+ info = kmalloc(sizeof(*info), GFP_KERNEL);
+@@ -258,10 +239,8 @@
+
+ if (link->state & DEV_CONFIG) {
+ axnet_release(link);
+- if (link->state & DEV_STALE_CONFIG) {
+- link->state |= DEV_STALE_LINK;
++ if (link->state & DEV_STALE_CONFIG)
+ return;
+- }
+ }
+
+ if (link->handle)
+@@ -547,7 +526,9 @@
+
+ link->state &= ~DEV_CONFIG;
+
+-} /* axnet_release */
++ if (link->state & DEV_STALE_CONFIG)
++ axnet_detach(link);
++}
+
+ /*======================================================================
+
+Index: linux-2.6.0-test5/drivers/net/pcmcia/com20020_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/pcmcia/com20020_cs.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/pcmcia/com20020_cs.c 2003-09-27 11:38:26.921435704 +0800
+@@ -145,22 +145,18 @@
+ dev_node_t node;
+ } com20020_dev_t;
+
+-/*======================================================================
++static void com20020_setup(struct net_device *dev)
++{
++ struct arcnet_local *lp = dev->priv;
+
+- This bit of code is used to avoid unregistering network devices
+- at inappropriate times. 2.2 and later kernels are fairly picky
+- about when this can happen.
+-
+-======================================================================*/
++ lp->timeout = timeout;
++ lp->backplane = backplane;
++ lp->clockp = clockp;
++ lp->clockm = clockm & 3;
++ lp->hw.owner = THIS_MODULE;
+
+-static void flush_stale_links(void)
+-{
+- dev_link_t *link, *next;
+- for (link = dev_list; link; link = next) {
+- next = link->next;
+- if (link->state & DEV_STALE_LINK)
+- com20020_detach(link);
+- }
++ /* fill in our module parameters as defaults */
++ dev->dev_addr[0] = node;
+ }
+
+ /*======================================================================
+@@ -181,7 +177,6 @@
+ struct arcnet_local *lp;
+
+ DEBUG(0, "com20020_attach()\n");
+- flush_stale_links();
+
+ /* Create new network device */
+ link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
+@@ -192,18 +187,14 @@
+ if (!info)
+ goto fail_alloc_info;
+
+- lp = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);
+- if (!lp)
+- goto fail_alloc_lp;
+-
+- dev = dev_alloc("arc%d", &ret);
++ dev = alloc_netdev(sizeof(struct arcnet_local), "arc%d",
++ com20020_setup);
+ if (!dev)
+ goto fail_alloc_dev;
+
+ memset(info, 0, sizeof(struct com20020_dev_t));
+- memset(lp, 0, sizeof(struct arcnet_local));
+ memset(link, 0, sizeof(struct dev_link_t));
+- dev->priv = lp;
++ lp = dev->priv;
+
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ link->io.NumPorts1 = 16;
+@@ -220,13 +211,6 @@
+ link->conf.IntType = INT_MEMORY_AND_IO;
+ link->conf.Present = PRESENT_OPTION;
+
+- /* fill in our module parameters as defaults */
+- dev->dev_addr[0] = node;
+- lp->timeout = timeout;
+- lp->backplane = backplane;
+- lp->clockp = clockp;
+- lp->clockm = clockm & 3;
+- lp->hw.owner = THIS_MODULE;
+
+ link->irq.Instance = info->dev = dev;
+ link->priv = info;
+@@ -253,8 +237,6 @@
+ return link;
+
+ fail_alloc_dev:
+- kfree(lp);
+-fail_alloc_lp:
+ kfree(info);
+ fail_alloc_info:
+ kfree(link);
+@@ -290,10 +272,8 @@
+
+ if (link->state & DEV_CONFIG) {
+ com20020_release(link);
+- if (link->state & DEV_STALE_CONFIG) {
+- link->state |= DEV_STALE_LINK;
++ if (link->state & DEV_STALE_CONFIG)
+ return;
+- }
+ }
+
+ if (link->handle)
+@@ -324,11 +304,9 @@
+ /* ...but I/O ports are done automatically by card services */
+
+ unregister_netdev(dev);
+- MOD_DEC_USE_COUNT;
+ }
+
+ DEBUG(1,"kfree...\n");
+- kfree(dev->priv);
+ free_netdev(dev);
+ }
+ DEBUG(1,"kfree2...\n");
+@@ -382,7 +360,6 @@
+
+ /* Configure card */
+ link->state |= DEV_CONFIG;
+- strcpy(info->node.dev_name, dev->name);
+
+ DEBUG(1,"arcnet: baseport1 is %Xh\n", link->io.BasePort1);
+ i = !CS_SUCCESS;
+@@ -428,13 +405,11 @@
+ goto failed;
+ }
+
+- MOD_INC_USE_COUNT;
+-
+ lp = dev->priv;
+ lp->card_name = "PCMCIA COM20020";
+ lp->card_flags = ARC_CAN_10MBIT; /* pretend all of them can 10Mbit */
+
+- i = com20020_found(dev, 0);
++ i = com20020_found(dev, 0); /* calls register_netdev */
+
+ if (i != 0) {
+ DEBUG(1,KERN_NOTICE "com20020_cs: com20020_found() failed\n");
+@@ -442,6 +417,7 @@
+ }
+
+ info->dev_configured = 1;
++ strcpy(info->node.dev_name, dev->name);
+ link->dev = &info->node;
+ link->state &= ~DEV_CONFIG_PENDING;
+
+@@ -484,7 +460,9 @@
+
+ link->state &= ~(DEV_CONFIG | DEV_RELEASE_PENDING);
+
+-} /* com20020_release */
++ if (link->state & DEV_STALE_CONFIG)
++ com20020_detach(link);
++}
+
+ /*======================================================================
+
+Index: linux-2.6.0-test5/drivers/net/pcmcia/fmvj18x_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/pcmcia/fmvj18x_cs.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/pcmcia/fmvj18x_cs.c 2003-09-27 11:38:26.931434184 +0800
+@@ -242,24 +242,6 @@
+ #define BANK_1U 0x24 /* bank 1 (CONFIG_1) */
+ #define BANK_2U 0x28 /* bank 2 (CONFIG_1) */
+
+-/*======================================================================
+-
+- This bit of code is used to avoid unregistering network devices
+- at inappropriate times. 2.2 and later kernels are fairly picky
+- about when this can happen.
+-
+-======================================================================*/
+-
+-static void flush_stale_links(void)
+-{
+- dev_link_t *link, *next;
+- for (link = dev_list; link; link = next) {
+- next = link->next;
+- if (link->state & DEV_STALE_LINK)
+- fmvj18x_detach(link);
+- }
+-}
+-
+ static dev_link_t *fmvj18x_attach(void)
+ {
+ local_info_t *lp;
+@@ -269,7 +251,6 @@
+ int i, ret;
+
+ DEBUG(0, "fmvj18x_attach()\n");
+- flush_stale_links();
+
+ /* Make up a FMVJ18x specific data structure */
+ dev = alloc_etherdev(sizeof(local_info_t));
+@@ -353,10 +334,8 @@
+
+ if (link->state & DEV_CONFIG) {
+ fmvj18x_release(link);
+- if (link->state & DEV_STALE_CONFIG) {
+- link->state |= DEV_STALE_LINK;
++ if (link->state & DEV_STALE_CONFIG)
+ return;
+- }
+ }
+
+ /* Break the link with Card Services */
+@@ -762,8 +741,10 @@
+ CardServices(ReleaseIRQ, link->handle, &link->irq);
+
+ link->state &= ~DEV_CONFIG;
+-
+-} /* fmvj18x_release */
++
++ if (link->state & DEV_STALE_CONFIG)
++ fmvj18x_detach(link);
++}
+
+ /*====================================================================*/
+
+Index: linux-2.6.0-test5/drivers/net/pcmcia/ibmtr_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/pcmcia/ibmtr_cs.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/pcmcia/ibmtr_cs.c 2003-09-27 11:38:26.936433424 +0800
+@@ -139,24 +139,6 @@
+ struct tok_info ti;
+ } ibmtr_dev_t;
+
+-/*======================================================================
+-
+- This bit of code is used to avoid unregistering network devices
+- at inappropriate times. 2.2 and later kernels are fairly picky
+- about when this can happen.
+-
+-======================================================================*/
+-
+-static void flush_stale_links(void)
+-{
+- dev_link_t *link, *next;
+- for (link = dev_list; link; link = next) {
+- next = link->next;
+- if (link->state & DEV_STALE_LINK)
+- ibmtr_detach(link);
+- }
+-}
+-
+ static void netdev_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
+ {
+@@ -184,7 +166,6 @@
+ int i, ret;
+
+ DEBUG(0, "ibmtr_attach()\n");
+- flush_stale_links();
+
+ /* Create new token-ring device */
+ dev = alloc_trdev(sizeof(*info));
+@@ -273,10 +254,8 @@
+ }
+ if (link->state & DEV_CONFIG) {
+ ibmtr_release(link);
+- if (link->state & DEV_STALE_CONFIG) {
+- link->state |= DEV_STALE_LINK;
++ if (link->state & DEV_STALE_CONFIG)
+ return;
+- }
+ }
+
+ if (link->handle)
+@@ -446,7 +425,9 @@
+
+ link->state &= ~DEV_CONFIG;
+
+-} /* ibmtr_release */
++ if (link->state & DEV_STALE_CONFIG)
++ ibmtr_detach(link);
++}
+
+ /*======================================================================
+
+Index: linux-2.6.0-test5/drivers/net/pcmcia/nmclan_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/pcmcia/nmclan_cs.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/pcmcia/nmclan_cs.c 2003-09-27 11:38:26.950431296 +0800
+@@ -449,21 +449,6 @@
+ static void nmclan_detach(dev_link_t *);
+
+ /* ----------------------------------------------------------------------------
+-flush_stale_links
+- Clean up stale device structures
+----------------------------------------------------------------------------- */
+-
+-static void flush_stale_links(void)
+-{
+- dev_link_t *link, *next;
+- for (link = dev_list; link; link = next) {
+- next = link->next;
+- if (link->state & DEV_STALE_LINK)
+- nmclan_detach(link);
+- }
+-}
+-
+-/* ----------------------------------------------------------------------------
+ nmclan_attach
+ Creates an "instance" of the driver, allocating local data
+ structures for one device. The device is registered with Card
+@@ -480,7 +465,6 @@
+
+ DEBUG(0, "nmclan_attach()\n");
+ DEBUG(1, "%s\n", rcsid);
+- flush_stale_links();
+
+ /* Create new ethernet device */
+ dev = alloc_etherdev(sizeof(mace_private));
+@@ -569,10 +553,8 @@
+
+ if (link->state & DEV_CONFIG) {
+ nmclan_release(link);
+- if (link->state & DEV_STALE_CONFIG) {
+- link->state |= DEV_STALE_LINK;
++ if (link->state & DEV_STALE_CONFIG)
+ return;
+- }
+ }
+
+ if (link->handle)
+@@ -843,7 +825,9 @@
+
+ link->state &= ~DEV_CONFIG;
+
+-} /* nmclan_release */
++ if (link->state & DEV_STALE_CONFIG)
++ nmclan_detach(link);
++}
+
+ /* ----------------------------------------------------------------------------
+ nmclan_event
+Index: linux-2.6.0-test5/drivers/net/pcmcia/pcnet_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/pcmcia/pcnet_cs.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/pcmcia/pcnet_cs.c 2003-09-27 11:38:26.964429168 +0800
+@@ -239,24 +239,6 @@
+
+ /*======================================================================
+
+- This bit of code is used to avoid unregistering network devices
+- at inappropriate times. 2.2 and later kernels are fairly picky
+- about when this can happen.
+-
+-======================================================================*/
+-
+-static void flush_stale_links(void)
+-{
+- dev_link_t *link, *next;
+- for (link = dev_list; link; link = next) {
+- next = link->next;
+- if (link->state & DEV_STALE_LINK)
+- pcnet_detach(link);
+- }
+-}
+-
+-/*======================================================================
+-
+ We never need to do anything when a pcnet device is "initialized"
+ by the net software, because we only register already-found cards.
+
+@@ -284,7 +266,6 @@
+ int i, ret;
+
+ DEBUG(0, "pcnet_attach()\n");
+- flush_stale_links();
+
+ /* Create new ethernet device */
+ info = kmalloc(sizeof(*info), GFP_KERNEL);
+@@ -356,10 +337,8 @@
+
+ if (link->state & DEV_CONFIG) {
+ pcnet_release(link);
+- if (link->state & DEV_STALE_CONFIG) {
+- link->state |= DEV_STALE_LINK;
++ if (link->state & DEV_STALE_CONFIG)
+ return;
+- }
+ }
+
+ if (link->handle)
+@@ -821,7 +800,9 @@
+
+ link->state &= ~DEV_CONFIG;
+
+-} /* pcnet_release */
++ if (link->state & DEV_STALE_CONFIG)
++ pcnet_detach(link);
++}
+
+ /*======================================================================
+
+Index: linux-2.6.0-test5/drivers/net/pcmcia/smc91c92_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/pcmcia/smc91c92_cs.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/pcmcia/smc91c92_cs.c 2003-09-27 11:38:26.982426432 +0800
+@@ -307,24 +307,6 @@
+
+ /*======================================================================
+
+- This bit of code is used to avoid unregistering network devices
+- at inappropriate times. 2.2 and later kernels are fairly picky
+- about when this can happen.
+-
+-======================================================================*/
+-
+-static void flush_stale_links(void)
+-{
+- dev_link_t *link, *next;
+- for (link = dev_list; link; link = next) {
+- next = link->next;
+- if (link->state & DEV_STALE_LINK)
+- smc91c92_detach(link);
+- }
+-}
+-
+-/*======================================================================
+-
+ smc91c92_attach() creates an "instance" of the driver, allocating
+ local data structures for one device. The device is registered
+ with Card Services.
+@@ -340,7 +322,6 @@
+ int i, ret;
+
+ DEBUG(0, "smc91c92_attach()\n");
+- flush_stale_links();
+
+ /* Create new ethernet device */
+ dev = alloc_etherdev(sizeof(struct smc_private));
+@@ -432,10 +413,8 @@
+
+ if (link->state & DEV_CONFIG) {
+ smc91c92_release(link);
+- if (link->state & DEV_STALE_CONFIG) {
+- link->state |= DEV_STALE_LINK;
++ if (link->state & DEV_STALE_CONFIG)
+ return;
+- }
+ }
+
+ if (link->handle)
+@@ -1103,7 +1082,9 @@
+
+ link->state &= ~DEV_CONFIG;
+
+-} /* smc91c92_release */
++ if (link->state & DEV_STALE_CONFIG)
++ smc91c92_detach(link);
++}
+
+ /*======================================================================
+
+Index: linux-2.6.0-test5/drivers/net/pcmcia/xirc2ps_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/pcmcia/xirc2ps_cs.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/pcmcia/xirc2ps_cs.c 2003-09-27 11:38:26.999423848 +0800
+@@ -390,17 +390,6 @@
+ static int do_stop(struct net_device *dev);
+
+ /*=============== Helper functions =========================*/
+-static void
+-flush_stale_links(void)
+-{
+- dev_link_t *link, *next;
+- for (link = dev_list; link; link = next) {
+- next = link->next;
+- if (link->state & DEV_STALE_LINK)
+- xirc2ps_detach(link);
+- }
+-}
+-
+ static int
+ get_tuple_data(int fn, client_handle_t handle, tuple_t *tuple)
+ {
+@@ -602,7 +591,6 @@
+ int err;
+
+ DEBUG(0, "attach()\n");
+- flush_stale_links();
+
+ /* Allocate the device structure */
+ dev = alloc_etherdev(sizeof(local_info_t));
+@@ -687,13 +675,8 @@
+ * the release() function is called, that will trigger a proper
+ * detach().
+ */
+- if (link->state & DEV_CONFIG) {
++ if (link->state & DEV_CONFIG)
+ xirc2ps_release(link);
+- if (link->state & DEV_STALE_CONFIG) {
+- link->state |= DEV_STALE_LINK;
+- return;
+- }
+- }
+
+ /* Break the link with Card Services */
+ if (link->handle)
+@@ -1183,19 +1166,6 @@
+
+ DEBUG(0, "release(0x%p)\n", link);
+
+-#if 0
+- /*
+- * If the device is currently in use, we won't release until it
+- * is actually closed.
+- */
+- if (link->open) {
+- DEBUG(0, "release postponed, '%s' "
+- "still open\n", link->dev->dev_name);
+- link->state |= DEV_STALE_CONFIG;
+- return;
+- }
+-#endif
+-
+ if (link->win) {
+ struct net_device *dev = link->priv;
+ local_info_t *local = dev->priv;
+@@ -2030,9 +2000,6 @@
+ SelectPage(0);
+
+ link->open--;
+- if (link->state & DEV_STALE_CONFIG)
+- xirc2ps_release(link);
+-
+ return 0;
+ }
+
+Index: linux-2.6.0-test5/drivers/net/ppp_generic.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/ppp_generic.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/ppp_generic.c 2003-09-27 11:38:27.016421264 +0800
+@@ -792,7 +792,7 @@
+
+ /* Called at boot time if ppp is compiled into the kernel,
+ or at module load time (from init_module) if compiled as a module. */
+-int __init ppp_init(void)
++static int __init ppp_init(void)
+ {
+ int err;
+
+@@ -801,6 +801,8 @@
+ if (!err) {
+ err = devfs_mk_cdev(MKDEV(PPP_MAJOR, 0),
+ S_IFCHR|S_IRUSR|S_IWUSR, "ppp");
++ if (err)
++ unregister_chrdev(PPP_MAJOR, "ppp");
+ }
+
+ if (err)
+Index: linux-2.6.0-test5/drivers/net/pppoe.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/pppoe.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/pppoe.c 2003-09-27 11:38:27.023420200 +0800
+@@ -986,7 +986,7 @@
+ struct pppox_opt *po;
+ char *dev_name;
+
+- if (v == (void *)1) {
++ if (v == SEQ_START_TOKEN) {
+ seq_puts(seq, "Id Address Device\n");
+ goto out;
+ }
+@@ -1025,7 +1025,7 @@
+ loff_t l = *pos;
+
+ read_lock_bh(&pppoe_hash_lock);
+- return l ? pppoe_get_idx(--l) : (void *)1;
++ return l ? pppoe_get_idx(--l) : SEQ_START_TOKEN;
+ }
+
+ static void *pppoe_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -1033,7 +1033,7 @@
+ struct pppox_opt *po;
+
+ ++*pos;
+- if (v == (void *)1) {
++ if (v == SEQ_START_TOKEN) {
+ po = pppoe_get_idx(0);
+ goto out;
+ }
+Index: linux-2.6.0-test5/drivers/net/rcpci45.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/rcpci45.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/rcpci45.c 2003-09-27 11:38:27.030419136 +0800
+@@ -259,10 +259,12 @@
+ dev->set_config = &RCconfig;
+
+ if ((error = register_netdev(dev)))
+- goto err_out_free_region;
++ goto err_out_iounmap;
+
+ return 0; /* success */
+
++err_out_iounmap:
++ iounmap((void *) dev->base_addr);
+ err_out_free_region:
+ pci_release_regions (pdev);
+ err_out_free_msgbuf:
+Index: linux-2.6.0-test5/drivers/net/rrunner.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/rrunner.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/rrunner.c 2003-09-27 11:38:27.042417312 +0800
+@@ -30,7 +30,6 @@
+
+ #include <linux/config.h>
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/types.h>
+ #include <linux/errno.h>
+ #include <linux/ioport.h>
+@@ -124,7 +123,6 @@
+ rrpriv->pci_dev = pdev;
+
+ spin_lock_init(&rrpriv->lock);
+- sprintf(rrpriv->name, "RoadRunner serial HIPPI");
+
+ dev->irq = pdev->irq;
+ dev->open = &rr_open;
+@@ -228,7 +226,7 @@
+ pci_set_drvdata(pdev, NULL);
+ }
+ out2:
+- kfree(dev);
++ free_netdev(dev);
+ out3:
+ return ret;
+ }
+@@ -236,9 +234,10 @@
+ static void __devexit rr_remove_one (struct pci_dev *pdev)
+ {
+ struct net_device *dev = pci_get_drvdata(pdev);
+- struct rr_private *rr = (struct rr_private *)dev->priv;
+
+ if (dev) {
++ struct rr_private *rr = dev->priv;
++
+ if (!(readl(&rr->regs->HostCtrl) & NIC_HALTED)){
+ printk(KERN_ERR "%s: trying to unload running NIC\n",
+ dev->name);
+@@ -721,7 +720,8 @@
+ * Give the FirmWare time to chew on the `get running' command.
+ */
+ myjif = jiffies + 5 * HZ;
+- while (time_before(jiffies, myjif) && !rrpriv->fw_running);
++ while (time_before(jiffies, myjif) && !rrpriv->fw_running)
++ cpu_relax();
+
+ netif_start_queue(dev);
+
+@@ -1201,8 +1201,7 @@
+ readl(®s->HostCtrl);
+ spin_unlock_irqrestore(&rrpriv->lock, flags);
+
+- if (request_irq(dev->irq, rr_interrupt, SA_SHIRQ, rrpriv->name, dev))
+- {
++ if (request_irq(dev->irq, rr_interrupt, SA_SHIRQ, dev->name, dev)) {
+ printk(KERN_WARNING "%s: Requested IRQ %d is busy\n",
+ dev->name, dev->irq);
+ ecode = -EAGAIN;
+@@ -1222,7 +1221,6 @@
+
+ netif_start_queue(dev);
+
+- MOD_INC_USE_COUNT;
+ return ecode;
+
+ error:
+@@ -1414,7 +1412,6 @@
+ free_irq(dev->irq, dev);
+ spin_unlock_irqrestore(&rrpriv->lock, flags);
+
+- MOD_DEC_USE_COUNT;
+ return 0;
+ }
+
+@@ -1727,7 +1724,7 @@
+ .name = "rrunner",
+ .id_table = rr_pci_tbl,
+ .probe = rr_init_one,
+- .remove = rr_remove_one,
++ .remove = __devexit_p(rr_remove_one),
+ };
+
+ static int __init rr_init_module(void)
+Index: linux-2.6.0-test5/drivers/net/rrunner.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/rrunner.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/rrunner.h 2003-09-27 11:38:27.046416704 +0800
+@@ -820,7 +820,6 @@
+ u32 tx_full;
+ u32 fw_rev;
+ volatile short fw_running;
+- char name[24]; /* The assigned name */
+ struct net_device_stats stats;
+ struct pci_dev *pci_dev;
+ };
+Index: linux-2.6.0-test5/drivers/net/sb1000.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/sb1000.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/sb1000.c 2003-09-27 11:38:27.055415336 +0800
+@@ -35,7 +35,6 @@
+ static char version[] = "sb1000.c:v1.1.2 6/01/98 (fventuri@mediaone.net)\n";
+
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/kernel.h>
+ #include <linux/string.h>
+ #include <linux/interrupt.h>
+Index: linux-2.6.0-test5/drivers/net/sis900.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/sis900.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/sis900.c 2003-09-27 11:38:27.073412600 +0800
+@@ -47,7 +47,6 @@
+ */
+
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/kernel.h>
+ #include <linux/string.h>
+ #include <linux/timer.h>
+Index: linux-2.6.0-test5/drivers/net/sk98lin/h/skdrv1st.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/sk98lin/h/skdrv1st.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/sk98lin/h/skdrv1st.h 2003-09-27 11:38:27.075412296 +0800
+@@ -107,9 +107,6 @@
+ #ifndef __INC_SKDRV1ST_H
+ #define __INC_SKDRV1ST_H
+
+-/* Check kernel version */
+-#include <linux/version.h>
+-
+ typedef struct s_AC SK_AC;
+
+ /* Set card versions */
+@@ -135,7 +132,6 @@
+ #error You must compile this driver with "-O".
+ #endif
+
+-#include <linux/version.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/string.h>
+Index: linux-2.6.0-test5/drivers/net/sk98lin/skge.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/sk98lin/skge.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/sk98lin/skge.c 2003-09-27 11:38:27.378366240 +0800
+@@ -361,7 +361,6 @@
+ * <linux/module.h>
+ *
+ * "h/skdrv1st.h"
+- * <linux/version.h>
+ * <linux/types.h>
+ * <linux/kernel.h>
+ * <linux/string.h>
+Index: linux-2.6.0-test5/drivers/net/skfp/h/targetos.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/skfp/h/targetos.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/skfp/h/targetos.h 2003-09-27 11:38:27.479350888 +0800
+@@ -43,7 +43,6 @@
+
+ #undef ADDR
+
+-#include <linux/version.h>
+ #include <asm/io.h>
+ #include <linux/netdevice.h>
+ #include <linux/fddidevice.h>
+Index: linux-2.6.0-test5/drivers/net/skfp/skfddi.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/skfp/skfddi.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/skfp/skfddi.c 2003-09-27 11:38:27.569337208 +0800
+@@ -182,7 +182,7 @@
+ extern void enable_tx_irq(struct s_smc *smc, u_short queue);
+ extern void mac_drv_clear_txd(struct s_smc *smc);
+
+-static struct pci_device_id skfddi_pci_tbl[] __initdata = {
++static struct pci_device_id skfddi_pci_tbl[] = {
+ { PCI_VENDOR_ID_SK, PCI_DEVICE_ID_SK_FP, PCI_ANY_ID, PCI_ANY_ID, },
+ { } /* Terminating entry */
+ };
+Index: linux-2.6.0-test5/drivers/net/sk_mca.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/sk_mca.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/sk_mca.h 2003-09-27 11:38:27.916284464 +0800
+@@ -1,3 +1,5 @@
++#include <linux/version.h>
++
+ #ifndef _SK_MCA_INCLUDE_
+ #define _SK_MCA_INCLUDE_
+
+Index: linux-2.6.0-test5/drivers/net/slip.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/slip.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/slip.c 2003-09-27 11:38:27.925283096 +0800
+@@ -869,12 +869,12 @@
+
+ /* OK. Find a free SLIP channel to use. */
+ err = -ENFILE;
+- if ((sl = sl_alloc(tty->device)) == NULL)
++ if ((sl = sl_alloc(tty_devnum(tty))) == NULL)
+ goto err_exit;
+
+ sl->tty = tty;
+ tty->disc_data = sl;
+- sl->line = tty->device;
++ sl->line = tty_devnum(tty);
+ sl->pid = current->pid;
+ if (tty->driver->flush_buffer)
+ tty->driver->flush_buffer(tty);
+@@ -1389,9 +1389,8 @@
+ */
+ do {
+ if (busy) {
+- current->state = TASK_INTERRUPTIBLE;
++ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(HZ / 10);
+- current->state = TASK_RUNNING;
+ }
+
+ busy = 0;
+Index: linux-2.6.0-test5/drivers/net/smc9194.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/smc9194.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/smc9194.c 2003-09-27 11:38:27.936281424 +0800
+@@ -58,7 +58,6 @@
+ "smc9194.c:v0.14 12/15/00 by Erik Stahlman (erik@vt.edu)\n";
+
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+ #include <linux/fcntl.h>
+Index: linux-2.6.0-test5/drivers/net/smc-ultra32.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/smc-ultra32.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/smc-ultra32.c 2003-09-27 11:38:27.940280816 +0800
+@@ -47,6 +47,7 @@
+
+
+ #include <linux/module.h>
++#include <linux/eisa.h>
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+ #include <linux/string.h>
+Index: linux-2.6.0-test5/drivers/net/Space.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/Space.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/Space.c 2003-09-27 11:38:27.945280056 +0800
+@@ -58,7 +58,6 @@
+ extern int at1700_probe(struct net_device *);
+ extern int fmv18x_probe(struct net_device *);
+ extern int eth16i_probe(struct net_device *);
+-extern int depca_probe(struct net_device *);
+ extern int i82596_probe(struct net_device *);
+ extern int ewrk3_probe(struct net_device *);
+ extern int el1_probe(struct net_device *);
+@@ -97,7 +96,6 @@
+ extern int mac8390_probe(struct net_device *dev);
+ extern int mac89x0_probe(struct net_device *dev);
+ extern int mc32_probe(struct net_device *dev);
+-extern struct net_device *sdla_init(void);
+ extern struct net_device *cops_probe(int unit);
+ extern struct net_device *ltpc_probe(void);
+
+@@ -253,9 +251,6 @@
+ #ifdef CONFIG_EEXPRESS_PRO /* Intel EtherExpress Pro/10 */
+ {eepro_probe, 0},
+ #endif
+-#ifdef CONFIG_DEPCA /* DEC DEPCA */
+- {depca_probe, 0},
+-#endif
+ #ifdef CONFIG_EWRK3 /* DEC EtherWORKS 3 */
+ {ewrk3_probe, 0},
+ #endif
+@@ -470,10 +465,6 @@
+ #ifdef CONFIG_LTPC
+ ltpc_probe();
+ #endif
+-#ifdef CONFIG_SDLA
+- sdla_init();
+-#endif
+-
+ }
+
+ /*
+Index: linux-2.6.0-test5/drivers/net/sunhme.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/sunhme.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/sunhme.c 2003-09-27 11:38:27.976275344 +0800
+@@ -179,7 +179,7 @@
+ where it could be referenced at any time due to hot plugging,
+ the __initdata reference should be removed. */
+
+-struct pci_device_id happymeal_pci_ids[] __initdata = {
++struct pci_device_id happymeal_pci_ids[] = {
+ {
+ .vendor = PCI_VENDOR_ID_SUN,
+ .device = PCI_DEVICE_ID_SUN_HAPPYMEAL,
+Index: linux-2.6.0-test5/drivers/net/tc35815.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/tc35815.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/tc35815.c 2003-09-27 11:38:27.991273064 +0800
+@@ -448,7 +448,7 @@
+
+ /* Index to functions, as function prototypes. */
+
+-static int __init tc35815_probe1(struct pci_dev *pdev, unsigned int base_addr, unsigned int irq);
++static int __devinit tc35815_probe1(struct pci_dev *pdev, unsigned int base_addr, unsigned int irq);
+
+ static int tc35815_open(struct net_device *dev);
+ static int tc35815_send_packet(struct sk_buff *skb, struct net_device *dev);
+@@ -526,7 +526,7 @@
+ return -ENODEV;
+ }
+
+-static int __init tc35815_probe1(struct pci_dev *pdev, unsigned int base_addr, unsigned int irq)
++static int __devinit tc35815_probe1(struct pci_dev *pdev, unsigned int base_addr, unsigned int irq)
+ {
+ static unsigned version_printed = 0;
+ int i;
+Index: linux-2.6.0-test5/drivers/net/tg3.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/tg3.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/tg3.c 2003-09-27 11:42:33.530945360 +0800
+@@ -33,6 +33,7 @@
+ #include <asm/io.h>
+ #include <asm/byteorder.h>
+ #include <asm/uaccess.h>
++#include <asm/kgdb.h>
+
+ #ifdef CONFIG_SPARC64
+ #include <asm/idprom.h>
+@@ -2453,9 +2454,9 @@
+ tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
+ sblk->status &= ~SD_STATUS_UPDATED;
+
+- if (likely(tg3_has_work(dev, tp)))
++ if (likely(tg3_has_work(dev, tp))) {
+ netif_rx_schedule(dev); /* schedule NAPI poll */
+- else {
++ } else {
+ /* no work, shared interrupt perhaps? re-enable
+ * interrupts, and flush that PCI write
+ */
+Index: linux-2.6.0-test5/drivers/net/tlan.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/tlan.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/tlan.c 2003-09-27 11:38:28.078259840 +0800
+@@ -169,6 +169,7 @@
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/ioport.h>
++#include <linux/eisa.h>
+ #include <linux/pci.h>
+ #include <linux/netdevice.h>
+ #include <linux/etherdevice.h>
+@@ -296,6 +297,7 @@
+ static int TLan_probe1( struct pci_dev *pdev, long ioaddr, int irq, int rev, const struct pci_device_id *ent);
+ static void TLan_tx_timeout( struct net_device *dev);
+ static int tlan_init_one( struct pci_dev *pdev, const struct pci_device_id *ent);
++static void TLan_Poll(struct net_device *dev);
+
+ static u32 TLan_HandleInvalid( struct net_device *, u16 );
+ static u32 TLan_HandleTxEOF( struct net_device *, u16 );
+@@ -452,6 +454,25 @@
+ pci_set_drvdata( pdev, NULL );
+ }
+
++#ifdef CONFIG_NET_POLL_CONTROLLER
++
++/*
++ * Polling 'interrupt' - used by things like netconsole to send skbs
++ * without having to re-enable interrupts. It's not called while
++ * the interrupt routine is executing.
++ */
++
++static void TLan_Poll (struct net_device *dev)
++{
++ disable_irq(dev->irq);
++ TLan_HandleInterrupt(dev->irq, dev, NULL);
++ enable_irq(dev->irq);
++}
++
++#endif
++
++
++
+ static struct pci_driver tlan_driver = {
+ .name = "tlan",
+ .id_table = tlan_pci_tbl,
+@@ -892,6 +913,9 @@
+ dev->do_ioctl = &TLan_ioctl;
+ dev->tx_timeout = &TLan_tx_timeout;
+ dev->watchdog_timeo = TX_TIMEOUT;
++#ifdef CONFIG_NET_POLL_CONTROLLER
++ dev->poll_controller = &TLan_Poll;
++#endif
+
+ return 0;
+
+Index: linux-2.6.0-test5/drivers/net/tokenring/abyss.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/tokenring/abyss.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/tokenring/abyss.c 2003-09-27 11:38:28.082259232 +0800
+@@ -40,7 +40,7 @@
+ #include "tms380tr.h"
+ #include "abyss.h" /* Madge-specific constants */
+
+-static char version[] __initdata =
++static char version[] __devinitdata =
+ "abyss.c: v1.02 23/11/2000 by Adam Fritzler\n";
+
+ #define ABYSS_IO_EXTENT 64
+@@ -92,7 +92,7 @@
+ outw(val, dev->base_addr + reg);
+ }
+
+-static int __init abyss_attach(struct pci_dev *pdev, const struct pci_device_id *ent)
++static int __devinit abyss_attach(struct pci_dev *pdev, const struct pci_device_id *ent)
+ {
+ static int versionprinted;
+ struct net_device *dev;
+Index: linux-2.6.0-test5/drivers/net/tokenring/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/tokenring/Kconfig 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/tokenring/Kconfig 2003-09-27 11:38:28.085258776 +0800
+@@ -2,13 +2,14 @@
+ # Token Ring driver configuration
+ #
+
+-menu "Token Ring devices (depends on LLC=y)"
++menu "Token Ring devices"
+ depends on NETDEVICES
+
+ # So far, we only have PCI, ISA, and MCA token ring devices
+ config TR
+ bool "Token Ring driver support"
+- depends on (PCI || ISA || MCA || CCW) && LLC=y
++ depends on (PCI || ISA || MCA || CCW)
++ select LLC
+ help
+ Token Ring is IBM's way of communication on a local network; the
+ rest of the world uses Ethernet. To participate on a Token Ring
+Index: linux-2.6.0-test5/drivers/net/tokenring/lanstreamer.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/tokenring/lanstreamer.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/tokenring/lanstreamer.h 2003-09-27 11:38:28.088258320 +0800
+@@ -60,6 +60,8 @@
+ *
+ */
+
++#include <linux/version.h>
++
+ #if STREAMER_IOCTL && (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+ #include <asm/ioctl.h>
+ #define IOCTL_PRINT_RX_BUFS SIOCDEVPRIVATE
+Index: linux-2.6.0-test5/drivers/net/tokenring/olympic.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/tokenring/olympic.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/tokenring/olympic.c 2003-09-27 11:38:28.106255584 +0800
+@@ -210,14 +210,13 @@
+ pci_set_master(pdev);
+
+ if ((i = pci_request_regions(pdev,"olympic"))) {
+- return i ;
+- } ;
++ goto op_disable_dev;
++ }
+
+ dev = alloc_trdev(sizeof(struct olympic_private)) ;
+-
+ if (!dev) {
+- pci_release_regions(pdev) ;
+- return -ENOMEM ;
++ i = -ENOMEM;
++ goto op_free_dev;
+ }
+
+ olympic_priv = dev->priv ;
+@@ -231,10 +230,12 @@
+ dev->base_addr=pci_resource_start(pdev, 0);
+ dev->init=NULL; /* Must be NULL otherwise we get called twice */
+ olympic_priv->olympic_card_name = pci_name(pdev);
++ olympic_priv->pdev = pdev;
+ olympic_priv->olympic_mmio = ioremap(pci_resource_start(pdev,1),256);
+ olympic_priv->olympic_lap = ioremap(pci_resource_start(pdev,2),2048);
+-#warning check ioremap return value
+- olympic_priv->pdev = pdev ;
++ if (!olympic_priv->olympic_mmio || !olympic_priv->olympic_lap) {
++ goto op_free_iomap;
++ }
+
+ if ((pkt_buf_sz[card_no] < 100) || (pkt_buf_sz[card_no] > 18000) )
+ olympic_priv->pkt_buf_sz = PKT_BUF_SZ ;
+@@ -246,12 +247,8 @@
+ olympic_priv->olympic_message_level = message_level[card_no] ;
+ olympic_priv->olympic_network_monitor = network_monitor[card_no];
+
+- if((i = olympic_init(dev))) {
+- iounmap(olympic_priv->olympic_mmio) ;
+- iounmap(olympic_priv->olympic_lap) ;
+- kfree(dev) ;
+- pci_release_regions(pdev) ;
+- return i ;
++ if ((i = olympic_init(dev))) {
++ goto op_free_iomap;
+ }
+
+ dev->open=&olympic_open;
+@@ -275,6 +272,20 @@
+ printk("Olympic: Network Monitor information: /proc/%s\n",proc_name);
+ }
+ return 0 ;
++
++op_free_iomap:
++ if (olympic_priv->olympic_mmio)
++ iounmap(olympic_priv->olympic_mmio);
++ if (olympic_priv->olympic_lap)
++ iounmap(olympic_priv->olympic_lap);
++
++op_free_dev:
++ free_netdev(dev);
++ pci_release_regions(pdev);
++
++op_disable_dev:
++ pci_disable_device(pdev);
++ return i;
+ }
+
+ static int __devinit olympic_init(struct net_device *dev)
+Index: linux-2.6.0-test5/drivers/net/tokenring/proteon.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/tokenring/proteon.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/tokenring/proteon.c 2003-09-27 11:38:28.109255128 +0800
+@@ -410,7 +410,7 @@
+ }
+ } else {
+ for(i = 0; num < ISATR_MAX_ADAPTERS && portlist[i]; i++) {
+- if (setup_card(portlist[i], irq[i], dma[i]))
++ if (setup_card(portlist[i], irq[num], dma[num]) == 0)
+ num++;
+ }
+ }
+Index: linux-2.6.0-test5/drivers/net/tokenring/skisa.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/tokenring/skisa.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/tokenring/skisa.c 2003-09-27 11:38:28.113254520 +0800
+@@ -423,7 +423,7 @@
+ }
+ } else {
+ for(i = 0; num < ISATR_MAX_ADAPTERS && portlist[i]; i++) {
+- if (setup_card(portlist[i], irq[i], dma[i]))
++ if (setup_card(portlist[i], irq[num], dma[num]) == 0)
+ num++;
+ }
+ }
+Index: linux-2.6.0-test5/drivers/net/tokenring/smctr.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/tokenring/smctr.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/tokenring/smctr.c 2003-09-27 11:38:28.159247528 +0800
+@@ -29,7 +29,6 @@
+ */
+
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/config.h>
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+Index: linux-2.6.0-test5/drivers/net/tokenring/tms380tr.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/tokenring/tms380tr.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/tokenring/tms380tr.c 2003-09-27 11:38:28.177244792 +0800
+@@ -77,7 +77,6 @@
+ #endif
+
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+ #include <linux/fcntl.h>
+Index: linux-2.6.0-test5/drivers/net/tokenring/tmspci.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/tokenring/tmspci.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/tokenring/tmspci.c 2003-09-27 11:38:28.180244336 +0800
+@@ -40,7 +40,7 @@
+
+ #include "tms380tr.h"
+
+-static char version[] __initdata =
++static char version[] __devinitdata =
+ "tmspci.c: v1.02 23/11/2000 by Adam Fritzler\n";
+
+ #define TMS_PCI_IO_EXTENT 32
+@@ -91,7 +91,7 @@
+ outw(val, dev->base_addr + reg);
+ }
+
+-static int __init tms_pci_attach(struct pci_dev *pdev, const struct pci_device_id *ent)
++static int __devinit tms_pci_attach(struct pci_dev *pdev, const struct pci_device_id *ent)
+ {
+ static int versionprinted;
+ struct net_device *dev;
+Index: linux-2.6.0-test5/drivers/net/tulip/de2104x.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/tulip/de2104x.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/tulip/de2104x.c 2003-09-27 11:38:28.195242056 +0800
+@@ -50,7 +50,7 @@
+ #include <asm/unaligned.h>
+
+ /* These identify the driver base version and may not be removed. */
+-static char version[] __initdata =
++static char version[] =
+ KERN_INFO DRV_NAME " PCI Ethernet driver v" DRV_VERSION " (" DRV_RELDATE ")\n";
+
+ MODULE_AUTHOR("Jeff Garzik <jgarzik@pobox.com>");
+@@ -1932,7 +1932,7 @@
+ goto fill_defaults;
+ }
+
+-static int __init de_init_one (struct pci_dev *pdev,
++static int __devinit de_init_one (struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+ {
+ struct net_device *dev;
+Index: linux-2.6.0-test5/drivers/net/tulip/de4x5.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/tulip/de4x5.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/tulip/de4x5.c 2003-09-27 11:38:28.237235672 +0800
+@@ -480,7 +480,7 @@
+
+ #include "de4x5.h"
+
+-static char version[] __initdata = "de4x5.c:V0.546 2001/02/22 davies@maniac.ultranet.com\n";
++static char version[] __devinitdata = "de4x5.c:V0.546 2001/02/22 davies@maniac.ultranet.com\n";
+
+ #define c_char const char
+ #define TWIDDLE(a) (u_short)le16_to_cpu(get_unaligned((u_short *)(a)))
+@@ -1082,7 +1082,7 @@
+ }
+
+ \f
+-static int __init
++static int __devinit
+ de4x5_hw_init(struct net_device *dev, u_long iobase, struct device *gendev)
+ {
+ char name[DE4X5_NAME_LENGTH + 1];
+@@ -2132,7 +2132,7 @@
+ ** DECchips, we can find the base SROM irrespective of the BIOS scan direction.
+ ** For single port cards this is a time waster...
+ */
+-static void __init
++static void __devinit
+ srom_search(struct net_device *dev, struct pci_dev *pdev)
+ {
+ u_char pb;
+@@ -2213,7 +2213,7 @@
+ ** kernels use the V0.535[n] drivers.
+ */
+
+-static int __init de4x5_pci_probe (struct pci_dev *pdev,
++static int __devinit de4x5_pci_probe (struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+ {
+ u_char pb, pbus = 0, dev_num, dnum = 0, timer;
+Index: linux-2.6.0-test5/drivers/net/tulip/tulip_core.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/tulip/tulip_core.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/tulip/tulip_core.c 2003-09-27 11:38:28.252233392 +0800
+@@ -246,6 +246,7 @@
+ static struct net_device_stats *tulip_get_stats(struct net_device *dev);
+ static int private_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+ static void set_rx_mode(struct net_device *dev);
++static void poll_tulip(struct net_device *dev);
+
+
+
+@@ -1631,6 +1632,9 @@
+ dev->get_stats = tulip_get_stats;
+ dev->do_ioctl = private_ioctl;
+ dev->set_multicast_list = set_rx_mode;
++#ifdef CONFIG_NET_POLL_CONTROLLER
++ dev->poll_controller = &poll_tulip;
++#endif
+
+ if (register_netdev(dev))
+ goto err_out_free_ring;
+@@ -1788,6 +1792,24 @@
+ }
+
+
++#ifdef CONFIG_NET_POLL_CONTROLLER
++
++/*
++ * Polling 'interrupt' - used by things like netconsole to send skbs
++ * without having to re-enable interrupts. It's not called while
++ * the interrupt routine is executing.
++ */
++
++static void poll_tulip (struct net_device *dev)
++{
++ disable_irq(dev->irq);
++ tulip_interrupt (dev->irq, dev, NULL);
++ enable_irq(dev->irq);
++}
++
++#endif
++
++
+ static struct pci_driver tulip_driver = {
+ .name = DRV_NAME,
+ .id_table = tulip_pci_tbl,
+Index: linux-2.6.0-test5/drivers/net/wan/comx.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/comx.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/comx.c 2003-09-27 11:38:28.260232176 +0800
+@@ -55,7 +55,6 @@
+
+ #include <linux/config.h>
+ #include <linux/module.h>
+-#include <linux/version.h>
+
+ #include <linux/types.h>
+ #include <linux/jiffies.h>
+Index: linux-2.6.0-test5/drivers/net/wan/comx-hw-comx.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/comx-hw-comx.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/comx-hw-comx.c 2003-09-27 11:38:28.270230656 +0800
+@@ -51,7 +51,6 @@
+ #define VERSION "0.87"
+
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/types.h>
+ #include <linux/netdevice.h>
+ #include <linux/proc_fs.h>
+Index: linux-2.6.0-test5/drivers/net/wan/comx-hw-locomx.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/comx-hw-locomx.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/comx-hw-locomx.c 2003-09-27 11:38:28.273230200 +0800
+@@ -38,7 +38,6 @@
+
+ #include <linux/interrupt.h>
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/types.h>
+ #include <linux/netdevice.h>
+ #include <linux/proc_fs.h>
+Index: linux-2.6.0-test5/drivers/net/wan/comx-hw-mixcom.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/comx-hw-mixcom.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/comx-hw-mixcom.c 2003-09-27 11:38:28.280229136 +0800
+@@ -41,7 +41,6 @@
+
+ #include <linux/interrupt.h>
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/types.h>
+ #include <linux/netdevice.h>
+ #include <linux/proc_fs.h>
+Index: linux-2.6.0-test5/drivers/net/wan/comx-hw-munich.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/comx-hw-munich.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/comx-hw-munich.c 2003-09-27 11:38:28.303225640 +0800
+@@ -30,7 +30,6 @@
+ #include <linux/config.h>
+ #include <linux/ctype.h>
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/types.h>
+ #include <linux/netdevice.h>
+ #include <linux/proc_fs.h>
+Index: linux-2.6.0-test5/drivers/net/wan/comx-proto-fr.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/comx-proto-fr.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/comx-proto-fr.c 2003-09-27 11:38:28.311224424 +0800
+@@ -37,7 +37,6 @@
+ #define VERSION "0.73"
+
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/types.h>
+ #include <linux/jiffies.h>
+ #include <linux/netdevice.h>
+Index: linux-2.6.0-test5/drivers/net/wan/comx-proto-lapb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/comx-proto-lapb.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/comx-proto-lapb.c 2003-09-27 11:38:28.315223816 +0800
+@@ -24,7 +24,6 @@
+ #define VERSION "0.80"
+
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/types.h>
+ #include <linux/netdevice.h>
+ #include <linux/proc_fs.h>
+Index: linux-2.6.0-test5/drivers/net/wan/comx-proto-ppp.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/comx-proto-ppp.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/comx-proto-ppp.c 2003-09-27 11:38:28.318223360 +0800
+@@ -34,7 +34,6 @@
+ #define VERSION "0.23"
+
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/types.h>
+ #include <linux/jiffies.h>
+ #include <linux/netdevice.h>
+Index: linux-2.6.0-test5/drivers/net/wan/cosa.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/cosa.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/cosa.c 2003-09-27 11:38:28.334220928 +0800
+@@ -326,11 +326,11 @@
+ /* Ioctls */
+ static int cosa_start(struct cosa_data *cosa, int address);
+ static int cosa_reset(struct cosa_data *cosa);
+-static int cosa_download(struct cosa_data *cosa, struct cosa_download *d);
+-static int cosa_readmem(struct cosa_data *cosa, struct cosa_download *d);
++static int cosa_download(struct cosa_data *cosa, unsigned long a);
++static int cosa_readmem(struct cosa_data *cosa, unsigned long a);
+
+ /* COSA/SRP ROM monitor */
+-static int download(struct cosa_data *cosa, char *data, int addr, int len);
++static int download(struct cosa_data *cosa, const char *data, int addr, int len);
+ static int startmicrocode(struct cosa_data *cosa, int address);
+ static int readmem(struct cosa_data *cosa, char *data, int addr, int len);
+ static int cosa_reset_and_read_id(struct cosa_data *cosa, char *id);
+@@ -1033,11 +1033,10 @@
+ }
+
+ /* High-level function to download data into COSA memory. Calls download() */
+-static inline int cosa_download(struct cosa_data *cosa, struct cosa_download *d)
++static inline int cosa_download(struct cosa_data *cosa, unsigned long arg)
+ {
++ struct cosa_download d;
+ int i;
+- int addr, len;
+- char *code;
+
+ if (cosa->usage > 1)
+ printk(KERN_INFO "%s: WARNING: download of microcode requested with cosa->usage > 1 (%d). Odd things may happen.\n",
+@@ -1047,38 +1046,36 @@
+ cosa->name, cosa->firmware_status);
+ return -EPERM;
+ }
+-
+- if (verify_area(VERIFY_READ, d, sizeof(*d)) ||
+- __get_user(addr, &(d->addr)) ||
+- __get_user(len, &(d->len)) ||
+- __get_user(code, &(d->code)))
++
++ if (copy_from_user(&d, (void __user *) arg, sizeof(d)))
+ return -EFAULT;
+
+- if (addr < 0 || addr > COSA_MAX_FIRMWARE_SIZE)
++ if (d.addr < 0 || d.addr > COSA_MAX_FIRMWARE_SIZE)
+ return -EINVAL;
+- if (len < 0 || len > COSA_MAX_FIRMWARE_SIZE)
++ if (d.len < 0 || d.len > COSA_MAX_FIRMWARE_SIZE)
+ return -EINVAL;
+
++
+ /* If something fails, force the user to reset the card */
+ cosa->firmware_status &= ~(COSA_FW_RESET|COSA_FW_DOWNLOAD);
+
+- if ((i=download(cosa, code, len, addr)) < 0) {
++ i = download(cosa, d.code, d.len, d.addr);
++ if (i < 0) {
+ printk(KERN_NOTICE "cosa%d: microcode download failed: %d\n",
+ cosa->num, i);
+ return -EIO;
+ }
+ printk(KERN_INFO "cosa%d: downloading microcode - 0x%04x bytes at 0x%04x\n",
+- cosa->num, len, addr);
++ cosa->num, d.len, d.addr);
+ cosa->firmware_status |= COSA_FW_RESET|COSA_FW_DOWNLOAD;
+ return 0;
+ }
+
+ /* High-level function to read COSA memory. Calls readmem() */
+-static inline int cosa_readmem(struct cosa_data *cosa, struct cosa_download *d)
++static inline int cosa_readmem(struct cosa_data *cosa, unsigned long arg)
+ {
++ struct cosa_download d;
+ int i;
+- int addr, len;
+- char *code;
+
+ if (cosa->usage > 1)
+ printk(KERN_INFO "cosa%d: WARNING: readmem requested with "
+@@ -1090,22 +1087,20 @@
+ return -EPERM;
+ }
+
+- if (verify_area(VERIFY_READ, d, sizeof(*d)) ||
+- __get_user(addr, &(d->addr)) ||
+- __get_user(len, &(d->len)) ||
+- __get_user(code, &(d->code)))
++ if (copy_from_user(&d, (void __user *) arg, sizeof(d)))
+ return -EFAULT;
+
+ /* If something fails, force the user to reset the card */
+ cosa->firmware_status &= ~COSA_FW_RESET;
+
+- if ((i=readmem(cosa, code, len, addr)) < 0) {
++ i = readmem(cosa, d.code, d.len, d.addr);
++ if (i < 0) {
+ printk(KERN_NOTICE "cosa%d: reading memory failed: %d\n",
+ cosa->num, i);
+ return -EIO;
+ }
+ printk(KERN_INFO "cosa%d: reading card memory - 0x%04x bytes at 0x%04x\n",
+- cosa->num, len, addr);
++ cosa->num, d.len, d.addr);
+ cosa->firmware_status |= COSA_FW_RESET;
+ return 0;
+ }
+@@ -1171,11 +1166,12 @@
+ case COSAIODOWNLD: /* Download the firmware */
+ if (!capable(CAP_SYS_RAWIO))
+ return -EACCES;
+- return cosa_download(cosa, (struct cosa_download *)arg);
++
++ return cosa_download(cosa, arg);
+ case COSAIORMEM:
+ if (!capable(CAP_SYS_RAWIO))
+ return -EACCES;
+- return cosa_readmem(cosa, (struct cosa_download *)arg);
++ return cosa_readmem(cosa, arg);
+ case COSAIORTYPE:
+ return cosa_gettype(cosa, (char *)arg);
+ case COSAIORIDSTR:
+@@ -1405,7 +1401,7 @@
+ * by a single space. Monitor has to reply with a space. Now the download
+ * begins. After the download monitor replies with "\r\n." (CR LF dot).
+ */
+-static int download(struct cosa_data *cosa, char *microcode, int length, int address)
++static int download(struct cosa_data *cosa, const char *microcode, int length, int address)
+ {
+ int i;
+
+Index: linux-2.6.0-test5/drivers/net/wan/cosa.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/cosa.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/cosa.h 2003-09-27 11:38:28.335220776 +0800
+@@ -73,19 +73,19 @@
+ #define COSAIORSET _IO('C',0xf0)
+
+ /* Start microcode at given address */
+-#define COSAIOSTRT _IOW('C',0xf1,sizeof(int))
++#define COSAIOSTRT _IOW('C',0xf1, int)
+
+ /* Read the block from the device memory */
+-#define COSAIORMEM _IOR('C',0xf2,sizeof(struct cosa_download *))
++#define COSAIORMEM _IOWR('C',0xf2, struct cosa_download)
+
+ /* Write the block to the device memory (i.e. download the microcode) */
+-#define COSAIODOWNLD _IOW('C',0xf2,sizeof(struct cosa_download *))
++#define COSAIODOWNLD _IOW('C',0xf2, struct cosa_download)
+
+ /* Read the device type (one of "srp", "cosa", and "cosa8" for now) */
+-#define COSAIORTYPE _IOR('C',0xf3,sizeof(char *))
++#define COSAIORTYPE _IOR('C',0xf3, char *)
+
+ /* Read the device identification string */
+-#define COSAIORIDSTR _IOR('C',0xf4,sizeof(char *))
++#define COSAIORIDSTR _IOR('C',0xf4, char *)
+ /* Maximum length of the identification string. */
+ #define COSA_MAX_ID_STRING 128
+
+@@ -100,7 +100,7 @@
+ #define COSAIONRCHANS _IO('C',0xf8)
+
+ /* Set the driver for the bus-master operations */
+-#define COSAIOBMSET _IOW('C', 0xf9, sizeof(unsigned short))
++#define COSAIOBMSET _IOW('C', 0xf9, unsigned short)
+
+ #define COSA_BM_OFF 0 /* Bus-mastering off - use ISA DMA (default) */
+ #define COSA_BM_ON 1 /* Bus-mastering on - faster but untested */
+Index: linux-2.6.0-test5/drivers/net/wan/cycx_x25.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/cycx_x25.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/cycx_x25.c 2003-09-27 11:38:28.347218952 +0800
+@@ -78,7 +78,6 @@
+
+ #define CYCLOMX_X25_DEBUG 1
+
+-#include <linux/version.h>
+ #include <linux/errno.h> /* return codes */
+ #include <linux/if_arp.h> /* ARPHRD_HWX25 */
+ #include <linux/kernel.h> /* printk(), and other useful stuff */
+Index: linux-2.6.0-test5/drivers/net/wan/dlci.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/dlci.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/dlci.c 2003-09-27 11:38:28.351218344 +0800
+@@ -40,7 +40,6 @@
+ #include <linux/init.h>
+ #include <linux/slab.h>
+ #include <linux/string.h>
+-#include <linux/init.h>
+ #include <linux/errno.h>
+ #include <linux/netdevice.h>
+ #include <linux/skbuff.h>
+@@ -58,64 +57,9 @@
+ static const char version[] = "DLCI driver v0.35, 4 Jan 1997, mike.mclagan@linux.org";
+
+ static LIST_HEAD(dlci_devs);
+-static spinlock_t dlci_dev_lock = SPIN_LOCK_UNLOCKED;
+-static char *basename[16];
+
+ static void dlci_setup(struct net_device *);
+
+-/* allow FRAD's to register their name as a valid FRAD */
+-int register_frad(const char *name)
+-{
+- int i;
+-
+- if (!name)
+- return(-EINVAL);
+-
+- for (i=0;i<sizeof(basename) / sizeof(char *);i++)
+- {
+- if (!basename[i])
+- break;
+-
+- /* take care of multiple registrations */
+- if (strcmp(basename[i], name) == 0)
+- return(0);
+- }
+-
+- if (i == sizeof(basename) / sizeof(char *))
+- return(-EMLINK);
+-
+- basename[i] = kmalloc(strlen(name) + 1, GFP_KERNEL);
+- if (!basename[i])
+- return(-ENOMEM);
+-
+- strcpy(basename[i], name);
+-
+- return(0);
+-}
+-
+-EXPORT_SYMBOL(register_frad);
+-
+-int unregister_frad(const char *name)
+-{
+- int i;
+-
+- if (!name)
+- return(-EINVAL);
+-
+- for (i=0;i<sizeof(basename) / sizeof(char *);i++)
+- if (basename[i] && (strcmp(basename[i], name) == 0))
+- break;
+-
+- if (i == sizeof(basename) / sizeof(char *))
+- return(-EINVAL);
+-
+- kfree(basename[i]);
+- basename[i] = NULL;
+-
+- return(0);
+-}
+-EXPORT_SYMBOL(unregister_frad);
+-
+ /*
+ * these encapsulate the RFC 1490 requirements as well as
+ * deal with packet transmission and reception, working with
+@@ -414,46 +358,38 @@
+ struct net_device *master, *slave;
+ struct dlci_local *dlp;
+ struct frad_local *flp;
+- int err, i;
++ int err = -EINVAL;
+
+
+ /* validate slave device */
+ slave = dev_get_by_name(dlci->devname);
+ if (!slave)
+- return(-ENODEV);
+-
+- if (slave->type != ARPHRD_FRAD) {
+- dev_put(slave);
+- return(-EINVAL);
+- }
++ return -ENODEV;
+
+- /* check for registration */
+- for (i=0;i<sizeof(basename) / sizeof(char *); i++)
+- if ((basename[i]) &&
+- (strncmp(dlci->devname, basename[i], strlen(basename[i])) == 0) &&
+- (strlen(dlci->devname) > strlen(basename[i])))
+- break;
+-
+- if (i == sizeof(basename) / sizeof(char *)) {
+- dev_put(slave);
+- return(-EINVAL);
+- }
++ if (slave->type != ARPHRD_FRAD || slave->priv == NULL)
++ goto err1;
+
+ /* create device name */
+ master = alloc_netdev( sizeof(struct dlci_local), "dlci%d",
+ dlci_setup);
+ if (!master) {
+- dev_put(slave);
+- return(-ENOMEM);
++ err = -ENOMEM;
++ goto err1;
+ }
+
+- err = register_netdev(master);
+- if (err < 0) {
+- dev_put(slave);
+- kfree(master);
+- return(err);
++ /* make sure same slave not already registered */
++ rtnl_lock();
++ list_for_each_entry(dlp, &dlci_devs, list) {
++ if (dlp->slave == slave) {
++ err = -EBUSY;
++ goto err2;
++ }
+ }
+
++ err = dev_alloc_name(master, master->name);
++ if (err < 0)
++ goto err2;
++
+ *(short *)(master->dev_addr) = dlci->dlci;
+
+ dlp = (struct dlci_local *) master->priv;
+@@ -461,22 +397,27 @@
+ dlp->master = master;
+
+ flp = slave->priv;
+- err = flp ? (*flp->assoc)(slave, master) : -EINVAL;
++ err = (*flp->assoc)(slave, master);
+ if (err < 0)
+- {
+- unregister_netdev(master);
+- dev_put(slave);
+- free_netdev(master);
+- return(err);
+- }
++ goto err2;
++
++ err = register_netdevice(master);
++ if (err < 0)
++ goto err2;
+
+ strcpy(dlci->devname, master->name);
+
+- spin_lock_bh(&dlci_dev_lock);
+ list_add(&dlp->list, &dlci_devs);
+- spin_unlock_bh(&dlci_dev_lock);
++ rtnl_unlock();
+
+ return(0);
++
++ err2:
++ rtnl_unlock();
++ kfree(master);
++ err1:
++ dev_put(slave);
++ return(err);
+ }
+
+ static int dlci_del(struct dlci_add *dlci)
+@@ -499,21 +440,18 @@
+ slave = dlp->slave;
+ flp = slave->priv;
+
++ rtnl_lock();
+ err = (*flp->deassoc)(slave, master);
+- if (err)
+- return(err);
+-
++ if (!err) {
++ list_del(&dlp->list);
+
+- spin_lock_bh(&dlci_dev_lock);
+- list_del(&dlp->list);
+- spin_unlock_bh(&dlci_dev_lock);
++ unregister_netdevice(master);
+
+- unregister_netdev(master);
+-
+- dev_put(slave);
+- free_netdev(master);
++ dev_put(slave);
++ }
++ rtnl_unlock();
+
+- return(0);
++ return(err);
+ }
+
+ static int dlci_ioctl(unsigned int cmd, void *arg)
+@@ -560,6 +498,7 @@
+ dev->hard_header = dlci_header;
+ dev->get_stats = dlci_get_stats;
+ dev->change_mtu = dlci_change_mtu;
++ dev->destructor = free_netdev;
+
+ dlp->receive = dlci_receive;
+
+@@ -569,31 +508,54 @@
+
+ }
+
+-int __init init_dlci(void)
++/* if slave is unregistering, then cleanup master */
++static int dlci_dev_event(struct notifier_block *unused,
++ unsigned long event, void *ptr)
++{
++ struct net_device *dev = (struct net_device *) ptr;
++
++ if (event == NETDEV_UNREGISTER) {
++ struct dlci_local *dlp;
++
++ list_for_each_entry(dlp, &dlci_devs, list) {
++ if (dlp->slave == dev) {
++ list_del(&dlp->list);
++ unregister_netdevice(dlp->master);
++ dev_put(dlp->slave);
++ break;
++ }
++ }
++ }
++ return NOTIFY_DONE;
++}
++
++static struct notifier_block dlci_notifier = {
++ .notifier_call = dlci_dev_event,
++};
++
++static int __init init_dlci(void)
+ {
+- int i;
+ dlci_ioctl_set(dlci_ioctl);
++ register_netdevice_notifier(&dlci_notifier);
+
+ printk("%s.\n", version);
+
+- for(i=0;i<sizeof(basename) / sizeof(char *);i++)
+- basename[i] = NULL;
+-
+ return 0;
+ }
+
+-void __exit dlci_exit(void)
++static void __exit dlci_exit(void)
+ {
+ struct dlci_local *dlp, *nxt;
+
+ dlci_ioctl_set(NULL);
++ unregister_netdevice_notifier(&dlci_notifier);
+
++ rtnl_lock();
+ list_for_each_entry_safe(dlp, nxt, &dlci_devs, list) {
+- unregister_netdev(dlp->master);
++ unregister_netdevice(dlp->master);
+ dev_put(dlp->slave);
+- free_netdev(dlp->master);
+ }
+-
++ rtnl_unlock();
+ }
+
+ module_init(init_dlci);
+Index: linux-2.6.0-test5/drivers/net/wan/dscc4.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/dscc4.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/dscc4.c 2003-09-27 11:38:28.366216064 +0800
+@@ -80,7 +80,6 @@
+ * - misc crapectomy.
+ */
+
+-#include <linux/version.h>
+ #include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/errno.h>
+@@ -693,7 +692,7 @@
+ kfree(ppriv);
+ }
+
+-static int __init dscc4_init_one(struct pci_dev *pdev,
++static int __devinit dscc4_init_one(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+ {
+ struct dscc4_pci_priv *priv;
+Index: linux-2.6.0-test5/drivers/net/wan/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/Kconfig 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/Kconfig 2003-09-27 11:38:28.373215000 +0800
+@@ -342,6 +342,30 @@
+ comment "X.25/LAPB support is disabled"
+ depends on WAN && HDLC && (LAPB!=m || HDLC!=m) && LAPB!=y
+
++config WANXL
++ tristate "SBE Inc. wanXL support"
++ depends on HDLC && PCI
++ help
++ This driver is for wanXL PCI cards made by SBE Inc. If you have
++ such a card, say Y here and see <http://hq.pm.waw.pl/pub/hdlc/>.
++
++ 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),
++ say M here and read <file:Documentation/modules.txt>. The module
++ will be called wanxl.
++
++ If unsure, say N here.
++
++config WANXL_BUILD_FIRMWARE
++ bool "rebuild wanXL firmware"
++ depends on WANXL
++ help
++ This option allows you to rebuild firmware run by the QUICC
++ processor. It requires as68k, ld68k and hexdump programs.
++ You should never need this option.
++
++ If unsure, say N here.
++
+ config PC300
+ tristate "Cyclades-PC300 support (RS-232/V.35, X.21, T1/E1 boards)"
+ depends on HDLC && PCI
+Index: linux-2.6.0-test5/drivers/net/wan/lmc/lmc_ver.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/lmc/lmc_ver.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/lmc/lmc_ver.h 2003-09-27 11:38:28.375214696 +0800
+@@ -1,3 +1,5 @@
++#include <linux/version.h>
++
+ #ifndef _IF_LMC_LINUXVER_
+ #define _IF_LMC_LINUXVER_
+
+Index: linux-2.6.0-test5/drivers/net/wan/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/Makefile 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/Makefile 2003-09-27 11:38:28.376214544 +0800
+@@ -66,3 +66,25 @@
+ endif
+ obj-$(CONFIG_N2) += n2.o
+ obj-$(CONFIG_C101) += c101.o
++obj-$(CONFIG_WANXL) += wanxl.o
++
++ifeq ($(CONFIG_WANXL_BUILD_FIRMWARE),y)
++ifeq ($(ARCH),m68k)
++ AS68K = $(AS)
++ LD68K = $(LD)
++else
++ AS68K = as68k
++ LD68K = ld68k
++endif
++
++quiet_cmd_build_wanxlfw = BLD FW $@
++ cmd_build_wanxlfw = \
++ $(CPP) -Wp,-MD,$(depfile) -Iinclude $(obj)/wanxlfw.S | $(AS68K) -m68360 -o $(obj)/wanxlfw.o; \
++ $(LD68K) --oformat binary -Ttext 0x1000 $(obj)/wanxlfw.o -o $(obj)/wanxlfw.bin; \
++ hexdump -ve '"\n" 16/1 "0x%02X,"' $(obj)/wanxlfw.bin | sed 's/0x ,//g;1s/^/static u8 firmware[]={/;$$s/,$$/\n};\n/' >$(obj)/wanxlfw.inc; \
++ rm -f $(obj)/wanxlfw.bin $(obj)/wanxlfw.o
++
++$(obj)/wanxlfw.inc: $(obj)/wanxlfw.S
++ $(call if_changed_dep,build_wanxlfw)
++targets += wanxlfw.inc
++endif
+Index: linux-2.6.0-test5/drivers/net/wan/pc300_drv.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/pc300_drv.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/pc300_drv.c 2003-09-27 11:38:28.404210288 +0800
+@@ -227,7 +227,6 @@
+ #include <linux/netdevice.h>
+ #include <linux/spinlock.h>
+ #include <linux/if.h>
+-#include <linux/version.h>
+
+ #include <net/syncppp.h>
+ #include <net/arp.h>
+Index: linux-2.6.0-test5/drivers/net/wan/pc300_tty.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/pc300_tty.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/pc300_tty.c 2003-09-27 11:38:28.413208920 +0800
+@@ -37,7 +37,6 @@
+ */
+
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/kernel.h>
+ #include <linux/pci.h>
+ #include <linux/errno.h>
+Index: linux-2.6.0-test5/drivers/net/wan/sbni.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/sbni.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/sbni.c 2003-09-27 11:38:28.424207248 +0800
+@@ -53,6 +53,7 @@
+ #include <linux/skbuff.h>
+ #include <linux/timer.h>
+ #include <linux/init.h>
++#include <linux/delay.h>
+
+ #include <net/arp.h>
+
+@@ -337,13 +338,12 @@
+ outb( 0, ioaddr + CSR0 );
+
+ if( irq < 2 ) {
+- unsigned long irq_mask, delay;
++ unsigned long irq_mask;
+
+ irq_mask = probe_irq_on();
+ outb( EN_INT | TR_REQ, ioaddr + CSR0 );
+ outb( PR_RES, ioaddr + CSR1 );
+- delay = jiffies + HZ/20;
+- while (time_before(jiffies, delay)) ;
++ mdelay(50);
+ irq = probe_irq_off(irq_mask);
+ outb( 0, ioaddr + CSR0 );
+
+@@ -1562,13 +1562,13 @@
+ static u32
+ calc_crc32( u32 crc, u8 *p, u32 len )
+ {
+- register u32 _crc __asm ( "ax" );
++ register u32 _crc;
+ _crc = crc;
+
+ __asm __volatile (
+ "xorl %%ebx, %%ebx\n"
+- "movl %1, %%esi\n"
+- "movl %2, %%ecx\n"
++ "movl %2, %%esi\n"
++ "movl %3, %%ecx\n"
+ "movl $crc32tab, %%edi\n"
+ "shrl $2, %%ecx\n"
+ "jz 1f\n"
+@@ -1604,7 +1604,7 @@
+ "jnz 0b\n"
+
+ "1:\n"
+- "movl %2, %%ecx\n"
++ "movl %3, %%ecx\n"
+ "andl $3, %%ecx\n"
+ "jz 2f\n"
+
+@@ -1629,9 +1629,9 @@
+ "xorb 2(%%esi), %%bl\n"
+ "xorl (%%edi,%%ebx,4), %%eax\n"
+ "2:\n"
+- :
+- : "a" (_crc), "g" (p), "g" (len)
+- : "ax", "bx", "cx", "dx", "si", "di"
++ : "=a" (_crc)
++ : "0" (_crc), "g" (p), "g" (len)
++ : "bx", "cx", "dx", "si", "di"
+ );
+
+ return _crc;
+Index: linux-2.6.0-test5/drivers/net/wan/sdla.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/sdla.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/sdla.c 2003-09-27 11:38:28.434205728 +0800
+@@ -60,8 +60,6 @@
+
+ static const char* version = "SDLA driver v0.30, 12 Sep 1996, mike.mclagan@linux.org";
+
+-static const char* devname = "sdla";
+-
+ static unsigned int valid_port[] __initdata = { 0x250, 0x270, 0x280, 0x300, 0x350, 0x360, 0x380, 0x390};
+
+ static unsigned int valid_mem[] __initdata = {
+@@ -1626,41 +1624,16 @@
+
+ static void setup_sdla(struct net_device *dev)
+ {
++ struct frad_local *flp = dev->priv;
++
++ netdev_boot_setup_check(dev);
++
++ SET_MODULE_OWNER(dev);
+ dev->flags = 0;
+ dev->type = 0xFFFF;
+ dev->hard_header_len = 0;
+ dev->addr_len = 0;
+ dev->mtu = SDLA_MAX_MTU;
+-}
+-
+-static int frad_registered;
+-
+-struct net_device * __init sdla_init(void)
+-{
+- struct net_device *dev;
+- struct frad_local *flp;
+- int err = -ENOMEM;
+-
+- if (!frad_registered) {
+- err = register_frad(devname);
+- if (err) {
+- printk(KERN_ERR "%s: frad registration failed %d\n",
+- devname, err);
+- return ERR_PTR(err);
+- }
+- frad_registered = 1;
+- printk("%s.\n", version);
+- }
+-
+-
+- dev = alloc_netdev(sizeof(struct frad_local), "sdla0", setup_sdla);
+- if (!dev)
+- goto out;
+-
+- SET_MODULE_OWNER(dev);
+- netdev_boot_setup_check(dev);
+-
+- flp = dev->priv;
+
+ dev->open = sdla_open;
+ dev->stop = sdla_close;
+@@ -1680,48 +1653,41 @@
+ flp->timer.expires = 1;
+ flp->timer.data = (unsigned long) dev;
+ flp->timer.function = sdla_poll;
+-
+- err = register_netdev(dev);
+- if (err)
+- goto out1;
+- return dev;
+-out1:
+- kfree(dev);
+-out:
+- return ERR_PTR(err);
+ }
+
+-#ifdef MODULE
+-static struct net_device *sdla0;
++static struct net_device *sdla;
+
+ static int __init init_sdla(void)
+ {
+- int result = 0;
++ int err;
+
+- sdla0 = sdla_init();
+- if (IS_ERR(sdla0))
+- result = PTR_ERR(sdla0);
++ printk("%s.\n", version);
+
+- return result;
++ sdla = alloc_netdev(sizeof(struct frad_local), "sdla0", setup_sdla);
++ if (!sdla)
++ return -ENOMEM;
++
++ err = register_netdev(sdla);
++ if (err)
++ free_netdev(sdla);
++
++ return err;
+ }
+
+ static void __exit exit_sdla(void)
+ {
+ struct frad_local *flp;
+
+- unregister_netdev(sdla0);
+- if (sdla0->irq)
+- free_irq(sdla0->irq, sdla0);
++ unregister_netdev(sdla);
++ if (sdla->irq)
++ free_irq(sdla->irq, sdla);
+
+- flp = sdla0->priv;
++ flp = sdla->priv;
+ del_timer_sync(&flp->timer);
+- free_netdev(sdla0);
+-
+- unregister_frad(devname);
++ free_netdev(sdla);
+ }
+
+ MODULE_LICENSE("GPL");
+
+ module_init(init_sdla);
+ module_exit(exit_sdla);
+-#endif
+Index: linux-2.6.0-test5/drivers/net/wan/sdla_chdlc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/sdla_chdlc.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/sdla_chdlc.c 2003-09-27 11:38:28.465201016 +0800
+@@ -49,7 +49,6 @@
+ *****************************************************************************/
+
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/kernel.h> /* printk(), and other useful stuff */
+ #include <linux/stddef.h> /* offsetof(), etc. */
+ #include <linux/errno.h> /* return codes */
+@@ -560,8 +559,8 @@
+
+
+ if (chdlc_set_intr_mode(card, APP_INT_ON_TIMER)){
+- printk (KERN_INFO "%s:
+- Failed to set interrupt triggers!\n",
++ printk (KERN_INFO "%s: "
++ "Failed to set interrupt triggers!\n",
+ card->devname);
+ return -EIO;
+ }
+Index: linux-2.6.0-test5/drivers/net/wan/sdladrv.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/sdladrv.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/sdladrv.c 2003-09-27 11:38:28.482198432 +0800
+@@ -91,7 +91,6 @@
+ #if defined(_LINUX_) /****** Linux *******************************/
+
+ #include <linux/config.h>
+-#include <linux/version.h>
+ #include <linux/kernel.h> /* printk(), and other useful stuff */
+ #include <linux/stddef.h> /* offsetof(), etc. */
+ #include <linux/errno.h> /* return codes */
+@@ -201,7 +200,7 @@
+ * Note: All data must be explicitly initialized!!!
+ */
+
+-static struct pci_device_id sdladrv_pci_tbl[] __initdata = {
++static struct pci_device_id sdladrv_pci_tbl[] = {
+ { V3_VENDOR_ID, V3_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, },
+ { } /* Terminating entry */
+ };
+@@ -351,7 +350,7 @@
+ }
+
+ module_init(sdladrv_init);
+-module_cleanup(sdladrv_cleanup);
++module_exit(sdladrv_cleanup);
+ #endif
+
+ /******* Kernel APIs ********************************************************/
+Index: linux-2.6.0-test5/drivers/net/wan/sdla_fr.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/sdla_fr.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/sdla_fr.c 2003-09-27 11:38:28.517193112 +0800
+@@ -139,7 +139,6 @@
+ *****************************************************************************/
+
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/kernel.h> /* printk(), and other useful stuff */
+ #include <linux/stddef.h> /* offsetof(), etc. */
+ #include <linux/errno.h> /* return codes */
+@@ -147,6 +146,7 @@
+ #include <linux/slab.h> /* kmalloc(), kfree() */
+ #include <linux/wanrouter.h> /* WAN router definitions */
+ #include <linux/wanpipe.h> /* WANPIPE common user API definitions */
++#include <linux/workqueue.h>
+ #include <linux/if_arp.h> /* ARPHRD_* defines */
+ #include <asm/byteorder.h> /* htons(), etc. */
+ #include <asm/io.h> /* for inb(), outb(), etc. */
+@@ -247,7 +247,7 @@
+ /* Polling task queue. Each interface
+ * has its own task queue, which is used
+ * to defer events from the interrupt */
+- struct tq_struct fr_poll_task;
++ struct work_struct fr_poll_work;
+ struct timer_list fr_arp_timer;
+
+ u32 ip_local;
+@@ -987,9 +987,7 @@
+ * We need a poll routine for each network
+ * interface.
+ */
+- chan->fr_poll_task.sync = 0;
+- chan->fr_poll_task.routine = (void *)(void *)fr_poll;
+- chan->fr_poll_task.data = dev;
++ INIT_WORK(&chan->fr_poll_work, (void *)fr_poll, dev);
+
+ init_timer(&chan->fr_arp_timer);
+ chan->fr_arp_timer.data=(unsigned long)dev;
+@@ -1212,9 +1210,7 @@
+ /* Initialize the task queue */
+ chan->tq_working=0;
+
+- chan->common.wanpipe_task.sync = 0;
+- chan->common.wanpipe_task.routine = (void *)(void *)fr_bh;
+- chan->common.wanpipe_task.data = dev;
++ INIT_WORK(&chan->common.wanpipe_work, (void *)fr_bh, dev);
+
+ /* Allocate and initialize BH circular buffer */
+ chan->bh_head = kmalloc((sizeof(bh_data_t)*MAX_BH_BUFF),GFP_ATOMIC);
+@@ -2178,7 +2174,7 @@
+ }
+
+
+- /* Send a packed up the IP stack */
++ /* Send a packet up the IP stack */
+ skb->dev->last_rx = jiffies;
+ netif_rx(skb);
+ ++chan->drvstats_rx_intr.rx_intr_bfr_passed_to_stack;
+@@ -2216,8 +2212,8 @@
+ * dlci number.
+ * 2. Check that network interface is up and
+ * properly setup.
+- * 3. Check for a buffered packed.
+- * 4. Transmit the packed.
++ * 3. Check for a buffered packet.
++ * 4. Transmit the packet.
+ * 5. If we are in WANPIPE mode, mark the
+ * NET_BH handler.
+ * 6. If we are in API mode, kick
+@@ -4359,8 +4355,8 @@
+ * bh_enqueue
+ *
+ * Description:
+- * Insert a received packed into a circular
+- * rx queue. This packed will be picked up
++ * Insert a received packet into a circular
++ * rx queue. This packet will be picked up
+ * by fr_bh() and sent up the stack to the
+ * user.
+ *
+@@ -4411,8 +4407,7 @@
+ static void trigger_fr_bh (fr_channel_t *chan)
+ {
+ if (!test_and_set_bit(0,&chan->tq_working)){
+- wanpipe_queue_tq(&chan->common.wanpipe_task);
+- wanpipe_mark_bh();
++ wanpipe_queue_work(&chan->common.wanpipe_work);
+ }
+ }
+
+@@ -4435,10 +4430,10 @@
+ * card into an skb buffer, the skb buffer
+ * is appended to a circular BH buffer.
+ * Then the interrupt kicks fr_bh() to finish the
+- * job at a later time (no within the interrupt).
++ * job at a later time (not within the interrupt).
+ *
+ * Usage:
+- * Interrupts use this to defer a taks to
++ * Interrupts use this to defer a task to
+ * a polling routine.
+ *
+ */
+@@ -4527,7 +4522,7 @@
+ static void trigger_fr_poll(struct net_device *dev)
+ {
+ fr_channel_t* chan = dev->priv;
+- schedule_task(&chan->fr_poll_task);
++ schedule_work(&chan->fr_poll_work);
+ return;
+ }
+
+Index: linux-2.6.0-test5/drivers/net/wan/sdla_ft1.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/sdla_ft1.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/sdla_ft1.c 2003-09-27 11:38:28.521192504 +0800
+@@ -21,7 +21,6 @@
+ *****************************************************************************/
+
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/kernel.h> /* printk(), and other useful stuff */
+ #include <linux/stddef.h> /* offsetof(), etc. */
+ #include <linux/errno.h> /* return codes */
+Index: linux-2.6.0-test5/drivers/net/wan/sdlamain.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/sdlamain.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/sdlamain.c 2003-09-27 11:38:28.531190984 +0800
+@@ -46,7 +46,6 @@
+ * Jan 02, 1997 Gene Kozin Initial version.
+ *****************************************************************************/
+
+-#include <linux/version.h>
+ #include <linux/config.h> /* OS configuration options */
+ #include <linux/stddef.h> /* offsetof(), etc. */
+ #include <linux/errno.h> /* return codes */
+@@ -189,7 +188,6 @@
+ /* Miscellaneous functions */
+ STATIC irqreturn_t sdla_isr (int irq, void* dev_id, struct pt_regs *regs);
+ static void release_hw (sdla_t *card);
+-static void run_wanpipe_tq (unsigned long);
+
+ static int check_s508_conflicts (sdla_t* card,wandev_conf_t* conf, int*);
+ static int check_s514_conflicts (sdla_t* card,wandev_conf_t* conf, int*);
+@@ -203,29 +201,21 @@
+ static char drvname[] = "wanpipe";
+ static char fullname[] = "WANPIPE(tm) Multiprotocol Driver";
+ static char copyright[] = "(c) 1995-2000 Sangoma Technologies Inc.";
+-static int ncards = 0;
+-static sdla_t* card_array = NULL; /* adapter data space */
++static int ncards;
++static sdla_t* card_array; /* adapter data space */
+
+-/* Wanpipe's own task queue, used for all API's.
+- * All protocol specific tasks will be instered
+- * into "wanpipe_tq_custom" task_queue.
+-
+- * On each rx_interrupt, the whole task queue
+- * (wanpipe_tq_custom) will be queued into
+- * IMMEDIATE_BH via wanpipe_mark_bh() call.
+-
+- * The IMMEDIATE_BH will execute run_wanpipe_tq()
+- * function, which will execute all pending,
+- * tasks in wanpipe_tq_custom queue */
+-
+-DECLARE_TASK_QUEUE(wanpipe_tq_custom);
+-static struct tq_struct wanpipe_tq_task =
+-{
+- .routine = (void (*)(void *)) run_wanpipe_tq,
+- .data = &wanpipe_tq_custom
+-};
++/* Wanpipe's own workqueue, used for all API's.
++ * All protocol specific tasks will be inserted
++ * into the "wanpipe_wq" workqueue.
++
++ * The kernel workqueue mechanism will execute
++ * all pending tasks in the "wanpipe_wq" workqueue.
++ */
+
+-static int wanpipe_bh_critical=0;
++struct workqueue_struct *wanpipe_wq;
++DECLARE_WORK(wanpipe_work, NULL, NULL);
++
++static int wanpipe_bh_critical;
+
+ /******* Kernel Loadable Module Entry Points ********************************/
+
+@@ -249,6 +239,10 @@
+ printk(KERN_INFO "%s v%u.%u %s\n",
+ fullname, DRV_VERSION, DRV_RELEASE, copyright);
+
++ wanpipe_wq = create_workqueue("wanpipe_wq");
++ if (!wanpipe_wq)
++ return -ENOMEM;
++
+ /* Probe for wanpipe cards and return the number found */
+ printk(KERN_INFO "wanpipe: Probing for WANPIPE hardware.\n");
+ ncards = wanpipe_hw_probe();
+@@ -256,13 +250,16 @@
+ printk(KERN_INFO "wanpipe: Allocating maximum %i devices: wanpipe%i - wanpipe%i.\n",ncards,1,ncards);
+ }else{
+ printk(KERN_INFO "wanpipe: No S514/S508 cards found, unloading modules!\n");
++ destroy_workqueue(wanpipe_wq);
+ return -ENODEV;
+ }
+
+ /* Verify number of cards and allocate adapter data space */
+ card_array = kmalloc(sizeof(sdla_t) * ncards, GFP_KERNEL);
+- if (card_array == NULL)
++ if (card_array == NULL) {
++ destroy_workqueue(wanpipe_wq);
+ return -ENOMEM;
++ }
+
+ memset(card_array, 0, sizeof(sdla_t) * ncards);
+
+@@ -292,6 +289,7 @@
+ ncards = cnt; /* adjust actual number of cards */
+ }else {
+ kfree(card_array);
++ destroy_workqueue(wanpipe_wq);
+ printk(KERN_INFO "IN Init Module: NO Cards registered\n");
+ err = -ENODEV;
+ }
+@@ -316,6 +314,7 @@
+ sdla_t* card = &card_array[i];
+ unregister_wan_device(card->devname);
+ }
++ destroy_workqueue(wanpipe_wq);
+ kfree(card_array);
+
+ printk(KERN_INFO "\nwanpipe: WANPIPE Modules Unloaded.\n");
+@@ -673,15 +672,20 @@
+
+
+ /* Make sure I/O port region is available only if we are the
+- * master device. If we are running in piggibacking mode,
+- * we will use the resources of the master card */
+- if (check_region(conf->ioport, SDLA_MAXIORANGE) &&
+- !card->wandev.piggyback) {
+- printk(KERN_INFO
+- "%s: I/O region 0x%X - 0x%X is in use!\n",
+- card->wandev.name, conf->ioport,
+- conf->ioport + SDLA_MAXIORANGE);
+- return -EINVAL;
++ * master device. If we are running in piggybacking mode,
++ * we will use the resources of the master card. */
++ if (!card->wandev.piggyback) {
++ struct resource *rr =
++ request_region(conf->ioport, SDLA_MAXIORANGE, "sdlamain");
++ release_region(conf->ioport, SDLA_MAXIORANGE);
++
++ if (!rr) {
++ printk(KERN_INFO
++ "%s: I/O region 0x%X - 0x%X is in use!\n",
++ card->wandev.name, conf->ioport,
++ conf->ioport + SDLA_MAXIORANGE - 1);
++ return -EINVAL;
++ }
+ }
+
+ return 0;
+@@ -1029,7 +1033,6 @@
+ STATIC irqreturn_t sdla_isr (int irq, void* dev_id, struct pt_regs *regs)
+ {
+ #define card ((sdla_t*)dev_id)
+- int handled = 0;
+
+ if(card->hw.type == SDLA_S514) { /* handle interrrupt on S514 */
+ u32 int_status;
+@@ -1210,6 +1213,7 @@
+ }
+ return NULL;
+ }
++
+ sdla_t * wanpipe_find_card_num (int num)
+ {
+ if (num < 1 || num > ncards)
+@@ -1218,35 +1222,20 @@
+ return &card_array[num];
+ }
+
+-
+-static void run_wanpipe_tq (unsigned long data)
+-{
+- task_queue *tq_queue = (task_queue *)data;
+- if (test_and_set_bit(2,(void*)&wanpipe_bh_critical))
+- printk(KERN_INFO "CRITICAL IN RUNNING TASK QUEUE\n");
+- run_task_queue (tq_queue);
+- clear_bit(2,(void*)&wanpipe_bh_critical);
+-
+-}
+-
+-void wanpipe_queue_tq (struct tq_struct *bh_pointer)
++/*
++ * @work_pointer: work_struct to be done;
++ * should already have PREPARE_WORK() or
++ * INIT_WORK() done on it by caller;
++ */
++void wanpipe_queue_work (struct work_struct *work_pointer)
+ {
+- if (test_and_set_bit(1,(void*)&wanpipe_bh_critical))
+- printk(KERN_INFO "CRITICAL IN QUEUING TASK\n");
++ if (test_and_set_bit(1, (void*)&wanpipe_bh_critical))
++ printk(KERN_INFO "CRITICAL IN QUEUING WORK\n");
+
+- queue_task(bh_pointer,&wanpipe_tq_custom);
++ queue_work(wanpipe_wq, work_pointer);
+ clear_bit(1,(void*)&wanpipe_bh_critical);
+ }
+
+-void wanpipe_mark_bh (void)
+-{
+- if (!test_and_set_bit(0,(void*)&wanpipe_bh_critical)){
+- queue_task(&wanpipe_tq_task,&tq_immediate);
+- mark_bh(IMMEDIATE_BH);
+- clear_bit(0,(void*)&wanpipe_bh_critical);
+- }
+-}
+-
+ void wakeup_sk_bh(struct net_device *dev)
+ {
+ wanpipe_common_t *chan = dev->priv;
+Index: linux-2.6.0-test5/drivers/net/wan/sdla_ppp.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/sdla_ppp.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/sdla_ppp.c 2003-09-27 11:38:28.556187184 +0800
+@@ -91,7 +91,6 @@
+ *****************************************************************************/
+
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/kernel.h> /* printk(), and other useful stuff */
+ #include <linux/stddef.h> /* offsetof(), etc. */
+ #include <linux/errno.h> /* return codes */
+Index: linux-2.6.0-test5/drivers/net/wan/sdla_x25.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/sdla_x25.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/sdla_x25.c 2003-09-27 11:38:28.594181408 +0800
+@@ -82,7 +82,6 @@
+ *=====================================================*/
+
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/kernel.h> /* printk(), and other useful stuff */
+ #include <linux/stddef.h> /* offsetof(), etc. */
+ #include <linux/errno.h> /* return codes */
+@@ -91,6 +90,7 @@
+ #include <linux/slab.h> /* kmalloc(), kfree() */
+ #include <linux/wanrouter.h> /* WAN router definitions */
+ #include <linux/wanpipe.h> /* WANPIPE common user API definitions */
++#include <linux/workqueue.h>
+ #include <asm/byteorder.h> /* htons(), etc. */
+ #include <asm/atomic.h>
+ #include <linux/delay.h> /* Experimental delay */
+@@ -790,9 +790,7 @@
+
+ init_global_statistics(card);
+
+- card->u.x.x25_poll_task.sync=0;
+- card->u.x.x25_poll_task.routine = (void*)(void*)wpx_poll;
+- card->u.x.x25_poll_task.data = card;
++ INIT_WORK(&card->u.x.x25_poll_work, (void *)wpx_poll, card);
+
+ init_timer(&card->u.x.x25_timer);
+ card->u.x.x25_timer.data = (unsigned long)card;
+@@ -1175,7 +1173,7 @@
+ * Warnings: None
+ *
+ * Return: 0 Ok
+- * <0 Failur: Interface will not come up.
++ * <0 Failure: Interface will not come up.
+ */
+
+ static int if_open(struct net_device* dev)
+@@ -1190,10 +1188,8 @@
+
+ chan->tq_working = 0;
+
+- /* Initialize the task queue */
+- chan->common.wanpipe_task.sync = 0;
+- chan->common.wanpipe_task.routine = (void *)(void *)x25api_bh;
+- chan->common.wanpipe_task.data = dev;
++ /* Initialize the workqueue */
++ INIT_WORK(&chan->common.wanpipe_work, (void *)x25api_bh, dev);
+
+ /* Allocate and initialize BH circular buffer */
+ /* Add 1 to MAX_BH_BUFF so we don't have test with (MAX_BH_BUFF-1) */
+@@ -1732,8 +1728,7 @@
+
+ chan->rx_skb = NULL;
+ if (!test_and_set_bit(0, &chan->tq_working)){
+- wanpipe_queue_tq(&chan->common.wanpipe_task);
+- wanpipe_mark_bh();
++ wanpipe_queue_work(&chan->common.wanpipe_work);
+ }
+ return;
+ }
+@@ -2227,7 +2222,7 @@
+
+ /*====================================================================
+ * Main polling routine.
+- * This routine is repeatedly called by the WANPIPE 'thead' to allow for
++ * This routine is repeatedly called by the WANPIPE 'thread' to allow for
+ * time-dependent housekeeping work.
+ *
+ * Notes:
+@@ -2274,7 +2269,7 @@
+
+ static void trigger_x25_poll(sdla_t *card)
+ {
+- schedule_task(&card->u.x.x25_poll_task);
++ schedule_work(&card->u.x.x25_poll_work);
+ }
+
+ /*====================================================================
+Index: linux-2.6.0-test5/drivers/net/wan/sealevel.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/sealevel.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/sealevel.c 2003-09-27 11:38:28.598180800 +0800
+@@ -31,7 +31,6 @@
+
+ struct slvl_device
+ {
+- void *if_ptr; /* General purpose pointer (used by SPPP) */
+ struct z8530_channel *chan;
+ struct ppp_device netdev;
+ int channel;
+@@ -40,7 +39,7 @@
+
+ struct slvl_board
+ {
+- struct slvl_device dev[2];
++ struct slvl_device *dev[2];
+ struct z8530_dev board;
+ int iobase;
+ };
+@@ -119,7 +118,6 @@
+ * Go go go
+ */
+ netif_start_queue(d);
+- MOD_INC_USE_COUNT;
+ return 0;
+ }
+
+@@ -153,7 +151,6 @@
+ z8530_sync_close(d, slvl->chan);
+ break;
+ }
+- MOD_DEC_USE_COUNT;
+ return 0;
+ }
+
+@@ -202,48 +199,79 @@
+ return 0;
+ }
+
++
++static void slvl_setup(struct net_device *d)
++{
++ d->open = sealevel_open;
++ d->stop = sealevel_close;
++ d->hard_start_xmit = sealevel_queue_xmit;
++ d->get_stats = sealevel_get_stats;
++ d->set_multicast_list = NULL;
++ d->do_ioctl = sealevel_ioctl;
++ d->neigh_setup = sealevel_neigh_setup_dev;
++ d->set_mac_address = NULL;
++
++}
++
++static inline struct slvl_device *slvl_alloc(int iobase, int irq)
++{
++ struct net_device *d;
++ struct slvl_device *sv;
++
++ d = alloc_netdev(sizeof(struct slvl_device), "hdlc%d",
++ slvl_setup);
++
++ if (!d)
++ return NULL;
++
++ sv = d->priv;
++ sv->netdev.dev = d;
++ d->base_addr = iobase;
++ d->irq = irq;
++
++ sppp_attach(&sv->netdev);
++ return sv;
++}
++
++
+ /*
+- * Description block for a Comtrol Hostess SV11 card
++ * Allocate and setup Sealevel board.
+ */
+
+-static struct slvl_board *slvl_init(int iobase, int irq, int txdma, int rxdma, int slow)
++static __init struct slvl_board *slvl_init(int iobase, int irq,
++ int txdma, int rxdma, int slow)
+ {
+ struct z8530_dev *dev;
+- struct slvl_device *sv;
+ struct slvl_board *b;
+- int u;
+
+ /*
+ * Get the needed I/O space
+ */
+-
++
+ if(!request_region(iobase, 8, "Sealevel 4021"))
+ {
+ printk(KERN_WARNING "sealevel: I/O 0x%X already in use.\n", iobase);
+ return NULL;
+ }
+
+- b=(struct slvl_board *)kmalloc(sizeof(struct slvl_board), GFP_KERNEL);
++ b = kmalloc(sizeof(struct slvl_board), GFP_KERNEL);
+ if(!b)
+ goto fail3;
+-
+- memset(b, 0, sizeof(*sv));
+
+- b->dev[0].chan = &b->board.chanA;
+- b->dev[0].if_ptr = &b->dev[0].netdev;
+- b->dev[0].netdev.dev=(struct net_device *)
+- kmalloc(sizeof(struct net_device), GFP_KERNEL);
+- if(!b->dev[0].netdev.dev)
++ memset(b, 0, sizeof(*b));
++ if (!(b->dev[0]= slvl_alloc(iobase, irq)))
+ goto fail2;
+
+- b->dev[1].chan = &b->board.chanB;
+- b->dev[1].if_ptr = &b->dev[1].netdev;
+- b->dev[1].netdev.dev=(struct net_device *)
+- kmalloc(sizeof(struct net_device), GFP_KERNEL);
+- if(!b->dev[1].netdev.dev)
++ b->dev[0]->chan = &b->board.chanA;
++ b->dev[0]->channel = 0;
++
++ if (!(b->dev[1] = slvl_alloc(iobase, irq)))
+ goto fail1_0;
+
+- dev=&b->board;
++ b->dev[1]->chan = &b->board.chanB;
++ b->dev[1]->channel = 1;
++
++ dev = &b->board;
+
+ /*
+ * Stuff in the I/O addressing
+@@ -287,8 +315,8 @@
+ dev->irq=irq;
+ dev->chanA.private=&b->dev[0];
+ dev->chanB.private=&b->dev[1];
+- dev->chanA.netdevice=b->dev[0].netdev.dev;
+- dev->chanB.netdevice=b->dev[1].netdev.dev;
++ dev->chanA.netdevice=b->dev[0]->netdev.dev;
++ dev->chanB.netdevice=b->dev[1]->netdev.dev;
+ dev->chanA.dev=dev;
+ dev->chanB.dev=dev;
+
+@@ -329,55 +357,18 @@
+
+ enable_irq(irq);
+
+- for(u=0; u<2; u++)
+- {
+- sv=&b->dev[u];
+- sv->channel = u;
+-
+- if(dev_alloc_name(sv->chan->netdevice,"hdlc%d")>=0)
+- {
+- struct net_device *d=sv->chan->netdevice;
+-
+- /*
+- * Initialise the PPP components
+- */
+- sppp_attach(&sv->netdev);
+-
+- /*
+- * Local fields
+- */
+-
+- d->base_addr = iobase;
+- d->irq = irq;
+- d->priv = sv;
+- d->init = NULL;
+-
+- d->open = sealevel_open;
+- d->stop = sealevel_close;
+- d->hard_start_xmit = sealevel_queue_xmit;
+- d->get_stats = sealevel_get_stats;
+- d->set_multicast_list = NULL;
+- d->do_ioctl = sealevel_ioctl;
+- d->neigh_setup = sealevel_neigh_setup_dev;
+- d->set_mac_address = NULL;
++ if (register_netdev(b->dev[0]->netdev.dev))
++ goto dmafail2;
+
+- if(register_netdev(d)==-1)
+- {
+- printk(KERN_ERR "%s: unable to register device.\n",
+- d->name);
+- goto fail_unit;
+- }
++ if (register_netdev(b->dev[1]->netdev.dev))
++ goto fail_unit;
+
+- break;
+- }
+- }
+ z8530_describe(dev, "I/O", iobase);
+ dev->active=1;
+ return b;
+
+ fail_unit:
+- if(u==1)
+- unregister_netdev(b->dev[0].chan->netdevice);
++ unregister_netdev(b->dev[0]->netdev.dev);
+
+ dmafail2:
+ free_dma(dev->chanA.rxdma);
+@@ -386,9 +377,9 @@
+ fail:
+ free_irq(irq, dev);
+ fail1_1:
+- kfree(b->dev[1].netdev.dev);
++ free_netdev(b->dev[1]->netdev.dev);
+ fail1_0:
+- kfree(b->dev[0].netdev.dev);
++ free_netdev(b->dev[0]->netdev.dev);
+ fail2:
+ kfree(b);
+ fail3:
+@@ -396,7 +387,7 @@
+ return NULL;
+ }
+
+-static void slvl_shutdown(struct slvl_board *b)
++static void __exit slvl_shutdown(struct slvl_board *b)
+ {
+ int u;
+
+@@ -404,8 +395,11 @@
+
+ for(u=0; u<2; u++)
+ {
+- sppp_detach(b->dev[u].netdev.dev);
+- unregister_netdev(b->dev[u].netdev.dev);
++ struct net_device *d = b->dev[u]->netdev.dev;
++ sppp_detach(d);
++
++ unregister_netdev(d);
++ free_netdev(d);
+ }
+
+ free_irq(b->board.irq, &b->board);
+@@ -416,7 +410,6 @@
+ release_region(b->iobase, 8);
+ }
+
+-#ifdef MODULE
+
+ static int io=0x238;
+ static int txdma=1;
+@@ -441,20 +434,22 @@
+
+ static struct slvl_board *slvl_unit;
+
+-int init_module(void)
++static int __init slvl_init_module(void)
+ {
++#ifdef MODULE
+ printk(KERN_INFO "SeaLevel Z85230 Synchronous Driver v 0.02.\n");
+- printk(KERN_INFO "(c) Copyright 1998, Building Number Three Ltd.\n");
+- if((slvl_unit=slvl_init(io,irq, txdma, rxdma, slow))==NULL)
+- return -ENODEV;
+- return 0;
++ printk(KERN_INFO "(c) Copyright 1998, Building Number Three Ltd.\n");
++#endif
++ slvl_unit = slvl_init(io, irq, txdma, rxdma, slow);
++
++ return slvl_unit ? 0 : -ENODEV;
+ }
+
+-void cleanup_module(void)
++static void __exit slvl_cleanup_module(void)
+ {
+ if(slvl_unit)
+ slvl_shutdown(slvl_unit);
+ }
+
+-#endif
+-
++module_init(slvl_init_module);
++module_exit(slvl_cleanup_module);
+Index: linux-2.6.0-test5/drivers/net/wan/wanpipe_multppp.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/wanpipe_multppp.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/wanpipe_multppp.c 2003-09-27 11:38:28.616178064 +0800
+@@ -18,7 +18,6 @@
+ *****************************************************************************/
+
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/kernel.h> /* printk(), and other useful stuff */
+ #include <linux/stddef.h> /* offsetof(), etc. */
+ #include <linux/errno.h> /* return codes */
+Index: linux-2.6.0-test5/drivers/net/wan/wanxl.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/wanxl.c 2003-09-27 11:38:18.459722080 +0800
++++ linux-2.6.0-test5/drivers/net/wan/wanxl.c 2003-09-27 11:38:28.618177760 +0800
+@@ -0,0 +1,836 @@
++/*
++ * wanXL serial card driver for Linux
++ * host part
++ *
++ * Copyright (C) 2003 Krzysztof Halasa <khc@pm.waw.pl>
++ *
++ * 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.
++ *
++ * Status:
++ * - Only DTE (external clock) support with NRZ and NRZI encodings
++ * - wanXL100 will require minor driver modifications, no access to hw
++ */
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/slab.h>
++#include <linux/sched.h>
++#include <linux/types.h>
++#include <linux/fcntl.h>
++#include <linux/string.h>
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/ioport.h>
++#include <linux/netdevice.h>
++#include <linux/hdlc.h>
++#include <linux/pci.h>
++#include <asm/io.h>
++#include <asm/delay.h>
++
++#include "wanxl.h"
++
++static const char* version = "wanXL serial card driver version: 0.46";
++
++#define PLX_CTL_RESET 0x40000000 /* adapter reset */
++
++#undef DEBUG_PKT
++#define DEBUG_PCI
++
++/* MAILBOX #1 - PUTS COMMANDS */
++#define MBX1_CMD_ABORTJ 0x85000000 /* Abort and Jump */
++#ifdef __LITTLE_ENDIAN
++#define MBX1_CMD_BSWAP 0x8C000001 /* little-endian Byte Swap Mode */
++#else
++#define MBX1_CMD_BSWAP 0x8C000000 /* big-endian Byte Swap Mode */
++#endif
++
++/* MAILBOX #2 - DRAM SIZE */
++#define MBX2_MEMSZ_MASK 0xFFFF0000 /* PUTS Memory Size Register mask */
++
++
++typedef struct {
++ hdlc_device hdlc; /* HDLC device struct - must be first */
++ struct card_t *card;
++ spinlock_t lock; /* for wanxl_xmit */
++ int node; /* physical port #0 - 3 */
++ unsigned int clock_type;
++ int tx_in, tx_out;
++ struct sk_buff *tx_skbs[TX_BUFFERS];
++}port_t;
++
++
++typedef struct {
++ desc_t rx_descs[RX_QUEUE_LENGTH];
++ port_status_t port_status[4];
++}card_status_t;
++
++
++typedef struct card_t {
++ int n_ports; /* 1, 2 or 4 ports */
++ u8 irq;
++
++ u8 *plx; /* PLX PCI9060 virtual base address */
++ struct pci_dev *pdev; /* for pdev->slot_name */
++ port_t *ports[4];
++ int rx_in;
++ struct sk_buff *rx_skbs[RX_QUEUE_LENGTH];
++ card_status_t *status; /* shared between host and card */
++ dma_addr_t status_address;
++}card_t;
++
++
++
++static inline port_t* hdlc_to_port(hdlc_device *hdlc)
++{
++ return (port_t*)hdlc;
++}
++
++
++static inline port_t* dev_to_port(struct net_device *dev)
++{
++ return hdlc_to_port(dev_to_hdlc(dev));
++}
++
++
++static inline struct net_device *port_to_dev(port_t* port)
++{
++ return hdlc_to_dev(&port->hdlc);
++}
++
++
++static inline const char* port_name(port_t *port)
++{
++ return hdlc_to_name((hdlc_device*)port);
++}
++
++
++static inline const char* card_name(struct pci_dev *pdev)
++{
++ return pdev->slot_name;
++}
++
++
++static inline port_status_t* get_status(port_t *port)
++{
++ return &port->card->status->port_status[port->node];
++}
++
++
++#ifdef DEBUG_PCI
++static inline dma_addr_t pci_map_single_debug(struct pci_dev *pdev, void *ptr,
++ size_t size, int direction)
++{
++ dma_addr_t addr = pci_map_single(pdev, ptr, size, direction);
++ if (addr + size > 0x100000000LL)
++ printk(KERN_CRIT "wanXL %s: pci_map_single() returned memory"
++ " at 0x%X!\n", card_name(pdev), addr);
++ return addr;
++}
++
++#undef pci_map_single
++#define pci_map_single pci_map_single_debug
++#endif
++
++
++/* Cable and/or personality module change interrupt service */
++static inline void wanxl_cable_intr(port_t *port)
++{
++ u32 value = get_status(port)->cable;
++ int valid = 1;
++ const char *cable, *pm, *dte = "", *dsr = "", *dcd = "";
++
++ switch(value & 0x7) {
++ case STATUS_CABLE_V35: cable = "V.35"; break;
++ case STATUS_CABLE_X21: cable = "X.21"; break;
++ case STATUS_CABLE_V24: cable = "V.24"; break;
++ case STATUS_CABLE_EIA530: cable = "EIA530"; break;
++ case STATUS_CABLE_NONE: cable = "no"; break;
++ default: cable = "invalid";
++ }
++
++ switch((value >> STATUS_CABLE_PM_SHIFT) & 0x7) {
++ case STATUS_CABLE_V35: pm = "V.35"; break;
++ case STATUS_CABLE_X21: pm = "X.21"; break;
++ case STATUS_CABLE_V24: pm = "V.24"; break;
++ case STATUS_CABLE_EIA530: pm = "EIA530"; break;
++ case STATUS_CABLE_NONE: pm = "no personality"; valid = 0; break;
++ default: pm = "invalid personality"; valid = 0;
++ }
++
++ if (valid) {
++ if ((value & 7) == ((value >> STATUS_CABLE_PM_SHIFT) & 7)) {
++ dsr = (value & STATUS_CABLE_DSR) ? ", DSR ON" :
++ ", DSR off";
++ dcd = (value & STATUS_CABLE_DCD) ? ", carrier ON" :
++ ", carrier off";
++ }
++ dte = (value & STATUS_CABLE_DCE) ? " DCE" : " DTE";
++ }
++ printk(KERN_INFO "%s: %s%s module, %s cable%s%s\n",
++ port_name(port), pm, dte, cable, dsr, dcd);
++
++ hdlc_set_carrier(value & STATUS_CABLE_DCD, &port->hdlc);
++}
++
++
++
++/* Transmit complete interrupt service */
++static inline void wanxl_tx_intr(port_t *port)
++{
++ while (1) {
++ desc_t *desc;
++ desc = &get_status(port)->tx_descs[port->tx_in];
++ struct sk_buff *skb = port->tx_skbs[port->tx_in];
++
++ switch (desc->stat) {
++ case PACKET_FULL:
++ case PACKET_EMPTY:
++ netif_wake_queue(port_to_dev(port));
++ return;
++
++ case PACKET_UNDERRUN:
++ port->hdlc.stats.tx_errors++;
++ port->hdlc.stats.tx_fifo_errors++;
++ break;
++
++ default:
++ port->hdlc.stats.tx_packets++;
++ port->hdlc.stats.tx_bytes += skb->len;
++ }
++ desc->stat = PACKET_EMPTY; /* Free descriptor */
++ pci_unmap_single(port->card->pdev, desc->address, skb->len,
++ PCI_DMA_TODEVICE);
++ dev_kfree_skb_irq(skb);
++ port->tx_in = (port->tx_in + 1) % TX_BUFFERS;
++ }
++}
++
++
++
++/* Receive complete interrupt service */
++static inline void wanxl_rx_intr(card_t *card)
++{
++ desc_t *desc;
++ while(desc = &card->status->rx_descs[card->rx_in],
++ desc->stat != PACKET_EMPTY) {
++ struct sk_buff *skb = card->rx_skbs[card->rx_in];
++ port_t *port = card->ports[desc->stat & PACKET_PORT_MASK];
++ struct net_device *dev = port_to_dev(port);
++
++ if ((desc->stat & PACKET_PORT_MASK) > card->n_ports)
++ printk(KERN_CRIT "wanXL %s: received packet for"
++ " nonexistent port\n", card_name(card->pdev));
++
++ else if (!skb)
++ port->hdlc.stats.rx_dropped++;
++
++ else {
++ pci_unmap_single(card->pdev, desc->address,
++ BUFFER_LENGTH, PCI_DMA_FROMDEVICE);
++ skb_put(skb, desc->length);
++
++#ifdef DEBUG_PKT
++ printk(KERN_DEBUG "%s RX(%i):", port_name(port),
++ skb->len);
++ debug_frame(skb);
++#endif
++ port->hdlc.stats.rx_packets++;
++ port->hdlc.stats.rx_bytes += skb->len;
++ skb->mac.raw = skb->data;
++ skb->dev = dev;
++ dev->last_rx = jiffies;
++ skb->protocol = hdlc_type_trans(skb, dev);
++ netif_rx(skb);
++ skb = NULL;
++ }
++
++ if (!skb) {
++ skb = dev_alloc_skb(BUFFER_LENGTH);
++ desc->address = skb ?
++ pci_map_single(card->pdev, skb->data,
++ BUFFER_LENGTH,
++ PCI_DMA_FROMDEVICE) : 0;
++ card->rx_skbs[card->rx_in] = skb;
++ }
++ desc->stat = PACKET_EMPTY; /* Free descriptor */
++ card->rx_in = (card->rx_in + 1) % RX_QUEUE_LENGTH;
++ }
++}
++
++
++
++static irqreturn_t wanxl_intr(int irq, void* dev_id, struct pt_regs *regs)
++{
++ card_t *card = dev_id;
++ int i;
++ u32 stat;
++ int handled = 0;
++
++
++ while((stat = readl(card->plx + PLX_DOORBELL_FROM_CARD)) != 0) {
++ handled = 1;
++ writel(stat, card->plx + PLX_DOORBELL_FROM_CARD);
++
++ for (i = 0; i < card->n_ports; i++) {
++ if (stat & (1 << (DOORBELL_FROM_CARD_TX_0 + i)))
++ wanxl_tx_intr(card->ports[i]);
++ if (stat & (1 << (DOORBELL_FROM_CARD_CABLE_0 + i)))
++ wanxl_cable_intr(card->ports[i]);
++ }
++ if (stat & (1 << DOORBELL_FROM_CARD_RX))
++ wanxl_rx_intr(card);
++ }
++
++ return IRQ_RETVAL(handled);
++}
++
++
++
++static int wanxl_xmit(struct sk_buff *skb, struct net_device *dev)
++{
++ hdlc_device *hdlc = dev_to_hdlc(dev);
++ port_t *port = hdlc_to_port(hdlc);
++
++ spin_lock(&port->lock);
++
++ desc_t *desc = &get_status(port)->tx_descs[port->tx_out];
++ if (desc->stat != PACKET_EMPTY) {
++ /* should never happen - previous xmit should stop queue */
++#ifdef DEBUG_PKT
++ printk(KERN_DEBUG "%s: transmitter buffer full\n",
++ port_name(port));
++#endif
++ netif_stop_queue(dev);
++ spin_unlock_irq(&port->lock);
++ return 1; /* request packet to be queued */
++ }
++
++#ifdef DEBUG_PKT
++ printk(KERN_DEBUG "%s TX(%i):", port_name(port), skb->len);
++ debug_frame(skb);
++#endif
++
++ port->tx_skbs[port->tx_out] = skb;
++ desc->address = pci_map_single(port->card->pdev, skb->data, skb->len,
++ PCI_DMA_TODEVICE);
++ desc->length = skb->len;
++ desc->stat = PACKET_FULL;
++ writel(1 << (DOORBELL_TO_CARD_TX_0 + port->node),
++ port->card->plx + PLX_DOORBELL_TO_CARD);
++ dev->trans_start = jiffies;
++
++ port->tx_out = (port->tx_out + 1) % TX_BUFFERS;
++
++ if (get_status(port)->tx_descs[port->tx_out].stat != PACKET_EMPTY) {
++ netif_stop_queue(dev);
++#ifdef DEBUG_PKT
++ printk(KERN_DEBUG "%s: transmitter buffer full\n",
++ port_name(port));
++#endif
++ }
++
++ spin_unlock(&port->lock);
++ return 0;
++}
++
++
++
++static int wanxl_attach(hdlc_device *hdlc, unsigned short encoding,
++ unsigned short parity)
++{
++ port_t *port = hdlc_to_port(hdlc);
++
++ if (encoding != ENCODING_NRZ &&
++ encoding != ENCODING_NRZI)
++ return -EINVAL;
++
++ if (parity != PARITY_NONE &&
++ parity != PARITY_CRC32_PR1_CCITT &&
++ parity != PARITY_CRC16_PR1_CCITT &&
++ parity != PARITY_CRC32_PR0_CCITT &&
++ parity != PARITY_CRC16_PR0_CCITT)
++ return -EINVAL;
++
++ get_status(port)->encoding = encoding;
++ get_status(port)->parity = parity;
++ return 0;
++}
++
++
++
++static int wanxl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
++{
++ const size_t size = sizeof(sync_serial_settings);
++ sync_serial_settings line;
++ hdlc_device *hdlc = dev_to_hdlc(dev);
++ port_t *port = hdlc_to_port(hdlc);
++
++ if (cmd != SIOCWANDEV)
++ return hdlc_ioctl(dev, ifr, cmd);
++
++ switch (ifr->ifr_settings.type) {
++ case IF_GET_IFACE:
++ ifr->ifr_settings.type = IF_IFACE_SYNC_SERIAL;
++ if (ifr->ifr_settings.size < size) {
++ ifr->ifr_settings.size = size; /* data size wanted */
++ return -ENOBUFS;
++ }
++ line.clock_type = get_status(port)->clocking;
++ line.clock_rate = 0;
++ line.loopback = 0;
++
++ if (copy_to_user(ifr->ifr_settings.ifs_ifsu.sync, &line, size))
++ return -EFAULT;
++ return 0;
++
++ case IF_IFACE_SYNC_SERIAL:
++ if (!capable(CAP_NET_ADMIN))
++ return -EPERM;
++ if (dev->flags & IFF_UP)
++ return -EBUSY;
++
++ if (copy_from_user(&line, ifr->ifr_settings.ifs_ifsu.sync,
++ size))
++ return -EFAULT;
++
++ if (line.clock_type != CLOCK_EXT &&
++ line.clock_type != CLOCK_TXFROMRX)
++ return -EINVAL; /* No such clock setting */
++
++ if (line.loopback != 0)
++ return -EINVAL;
++
++ get_status(port)->clocking = line.clock_type;
++ return 0;
++
++ default:
++ return hdlc_ioctl(dev, ifr, cmd);
++ }
++}
++
++
++
++static int wanxl_open(struct net_device *dev)
++{
++ hdlc_device *hdlc = dev_to_hdlc(dev);
++ port_t *port = hdlc_to_port(hdlc);
++ u8 *dbr = port->card->plx + PLX_DOORBELL_TO_CARD;
++ unsigned long timeout;
++ int i;
++
++ if (get_status(port)->open) {
++ printk(KERN_ERR "%s: port already open\n", port_name(port));
++ return -EIO;
++ }
++ if ((i = hdlc_open(hdlc)) != 0)
++ return i;
++
++ port->tx_in = port->tx_out = 0;
++ for (i = 0; i < TX_BUFFERS; i++)
++ get_status(port)->tx_descs[i].stat = PACKET_EMPTY;
++ /* signal the card */
++ writel(1 << (DOORBELL_TO_CARD_OPEN_0 + port->node), dbr);
++
++ timeout = jiffies + HZ;
++ do
++ if (get_status(port)->open)
++ return 0;
++ while (time_after(timeout, jiffies));
++
++ printk(KERN_ERR "%s: unable to open port\n", port_name(port));
++ /* ask the card to close the port, should it be still alive */
++ writel(1 << (DOORBELL_TO_CARD_CLOSE_0 + port->node), dbr);
++ return -EFAULT;
++}
++
++
++
++static int wanxl_close(struct net_device *dev)
++{
++ hdlc_device *hdlc = dev_to_hdlc(dev);
++ port_t *port = hdlc_to_port(hdlc);
++ unsigned long timeout;
++ int i;
++
++ hdlc_close(hdlc);
++ /* signal the card */
++ writel(1 << (DOORBELL_TO_CARD_CLOSE_0 + port->node),
++ port->card->plx + PLX_DOORBELL_TO_CARD);
++
++ timeout = jiffies + HZ;
++ do
++ if (!get_status(port)->open)
++ break;
++ while (time_after(timeout, jiffies));
++
++ if (get_status(port)->open)
++ printk(KERN_ERR "%s: unable to close port\n", port_name(port));
++
++ for (i = 0; i < TX_BUFFERS; i++) {
++ desc_t *desc = &get_status(port)->tx_descs[i];
++
++ if (desc->stat != PACKET_EMPTY) {
++ desc->stat = PACKET_EMPTY;
++ pci_unmap_single(port->card->pdev, desc->address,
++ port->tx_skbs[i]->len,
++ PCI_DMA_TODEVICE);
++ dev_kfree_skb(port->tx_skbs[i]);
++ }
++ }
++ return 0;
++}
++
++
++
++static struct net_device_stats *wanxl_get_stats(struct net_device *dev)
++{
++ hdlc_device *hdlc = dev_to_hdlc(dev);
++ port_t *port = hdlc_to_port(hdlc);
++
++ hdlc->stats.rx_over_errors = get_status(port)->rx_overruns;
++ hdlc->stats.rx_frame_errors = get_status(port)->rx_frame_errors;
++ hdlc->stats.rx_errors = hdlc->stats.rx_over_errors +
++ hdlc->stats.rx_frame_errors;
++ return &hdlc->stats;
++}
++
++
++
++static int wanxl_puts_command(card_t *card, u32 cmd)
++{
++ unsigned long timeout = jiffies + 5 * HZ;
++
++ writel(cmd, card->plx + PLX_MAILBOX_1);
++ do {
++ if (readl(card->plx + PLX_MAILBOX_1) == 0)
++ return 0;
++
++ schedule();
++ }while (time_after(timeout, jiffies));
++
++ return -1;
++}
++
++
++
++static void wanxl_reset(card_t *card)
++{
++ u32 old_value = readl(card->plx + PLX_CONTROL) & ~PLX_CTL_RESET;
++
++ writel(0x80, card->plx + PLX_MAILBOX_0);
++ writel(old_value | PLX_CTL_RESET, card->plx + PLX_CONTROL);
++ readl(card->plx + PLX_CONTROL); /* wait for posted write */
++ udelay(1);
++ writel(old_value, card->plx + PLX_CONTROL);
++ readl(card->plx + PLX_CONTROL); /* wait for posted write */
++}
++
++
++
++static void wanxl_pci_remove_one(struct pci_dev *pdev)
++{
++ card_t *card = pci_get_drvdata(pdev);
++ int i;
++
++ /* unregister and free all host resources */
++ if (card->irq)
++ free_irq(card->irq, card);
++
++ for (i = 0; i < 4; i++)
++ if (card->ports[i])
++ unregister_hdlc_device(&card->ports[i]->hdlc);
++
++ wanxl_reset(card);
++
++ for (i = 0; i < RX_QUEUE_LENGTH; i++)
++ if (card->rx_skbs[i]) {
++ pci_unmap_single(card->pdev,
++ card->status->rx_descs[i].address,
++ BUFFER_LENGTH, PCI_DMA_FROMDEVICE);
++ dev_kfree_skb(card->rx_skbs[i]);
++ }
++
++ if (card->plx)
++ iounmap(card->plx);
++
++ if (card->status)
++ pci_free_consistent(pdev, sizeof(card_status_t),
++ card->status, card->status_address);
++
++ pci_set_drvdata(pdev, NULL);
++ kfree(card);
++ pci_release_regions(pdev);
++}
++
++
++#include "wanxlfw.inc"
++
++static int __devinit wanxl_pci_init_one(struct pci_dev *pdev,
++ const struct pci_device_id *ent)
++{
++ card_t *card;
++ u32 ramsize, stat;
++ unsigned long timeout;
++ u32 plx_phy; /* PLX PCI base address */
++ u32 mem_phy; /* memory PCI base addr */
++ u8 *mem; /* memory virtual base addr */
++ int i, ports, alloc_size;
++
++ i = pci_enable_device(pdev);
++ if (i)
++ return i;
++
++ /* QUICC can only access first 256 MB of host RAM directly,
++ but PLX9060 DMA does 32-bits for actual packet data transfers */
++
++ /* FIXME when PCI/DMA subsystems are fixed.
++ We set both dma_mask and consistent_dma_mask to 28 bits
++ and pray pci_alloc_consistent() will use this info. It should
++ work on most platforms */
++ if (pci_set_consistent_dma_mask(pdev, 0x0FFFFFFF) ||
++ pci_set_dma_mask(pdev, 0x0FFFFFFF)) {
++ printk(KERN_ERR "No usable DMA configuration\n");
++ return -EIO;
++ }
++
++ i = pci_request_regions(pdev, "wanXL");
++ if (i)
++ return i;
++
++ switch (pdev->device) {
++ case PCI_DEVICE_ID_SBE_WANXL100: ports = 1; break;
++ case PCI_DEVICE_ID_SBE_WANXL200: ports = 2; break;
++ default: ports = 4;
++ }
++
++ alloc_size = sizeof(card_t) + ports * sizeof(port_t);
++ card = kmalloc(alloc_size, GFP_KERNEL);
++ if (card == NULL) {
++ printk(KERN_ERR "wanXL %s: unable to allocate memory\n",
++ card_name(pdev));
++ pci_release_regions(pdev);
++ return -ENOBUFS;
++ }
++ memset(card, 0, alloc_size);
++
++ pci_set_drvdata(pdev, card);
++ card->pdev = pdev;
++ card->n_ports = ports;
++
++ card->status = pci_alloc_consistent(pdev, sizeof(card_status_t),
++ &card->status_address);
++ if (card->status == NULL) {
++ wanxl_pci_remove_one(pdev);
++ return -ENOBUFS;
++ }
++
++#ifdef DEBUG_PCI
++ printk(KERN_DEBUG "wanXL %s: pci_alloc_consistent() returned memory"
++ " at 0x%X\n", card_name(pdev), card->status_address);
++#endif
++
++ /* FIXME when PCI/DMA subsystems are fixed.
++ We set both dma_mask and consistent_dma_mask back to 32 bits
++ to indicate the card can do 32-bit DMA addressing */
++ if (pci_set_consistent_dma_mask(pdev, 0xFFFFFFFF) ||
++ pci_set_dma_mask(pdev, 0xFFFFFFFF)) {
++ printk(KERN_ERR "No usable DMA configuration\n");
++ wanxl_pci_remove_one(pdev);
++ return -EIO;
++ }
++
++ /* set up PLX mapping */
++ plx_phy = pci_resource_start(pdev, 0);
++ card->plx = ioremap_nocache(plx_phy, 0x70);
++
++#if RESET_WHILE_LOADING
++ wanxl_reset(card);
++#endif
++
++ timeout = jiffies + 20 * HZ;
++ while ((stat = readl(card->plx + PLX_MAILBOX_0)) != 0) {
++ if (time_before(timeout, jiffies)) {
++ printk(KERN_WARNING "wanXL %s: timeout waiting for"
++ " PUTS to complete\n", card_name(pdev));
++ wanxl_pci_remove_one(pdev);
++ return -ENODEV;
++ }
++
++ switch(stat & 0xC0) {
++ case 0x00: /* hmm - PUTS completed with non-zero code? */
++ case 0x80: /* PUTS still testing the hardware */
++ break;
++
++ default:
++ printk(KERN_WARNING "wanXL %s: PUTS test 0x%X"
++ " failed\n", card_name(pdev), stat & 0x30);
++ wanxl_pci_remove_one(pdev);
++ return -ENODEV;
++ }
++
++ schedule();
++ }
++
++ /* get on-board memory size (PUTS detects no more than 4 MB) */
++ ramsize = readl(card->plx + PLX_MAILBOX_2) & MBX2_MEMSZ_MASK;
++
++ /* set up on-board RAM mapping */
++ mem_phy = pci_resource_start(pdev, 2);
++
++
++ /* sanity check the board's reported memory size */
++ if (ramsize < BUFFERS_ADDR +
++ (TX_BUFFERS + RX_BUFFERS) * BUFFER_LENGTH * ports) {
++ printk(KERN_WARNING "wanXL %s: no enough on-board RAM"
++ " (%u bytes detected, %u bytes required)\n",
++ card_name(pdev), ramsize, BUFFERS_ADDR +
++ (TX_BUFFERS + RX_BUFFERS) * BUFFER_LENGTH * ports);
++ wanxl_pci_remove_one(pdev);
++ return -ENODEV;
++ }
++
++ if (wanxl_puts_command(card, MBX1_CMD_BSWAP)) {
++ printk(KERN_WARNING "wanXL %s: unable to Set Byte Swap"
++ " Mode\n", card_name(pdev));
++ wanxl_pci_remove_one(pdev);
++ return -ENODEV;
++ }
++
++ for (i = 0; i < ports; i++) {
++ port_t *port = (void *)card + sizeof(card_t) +
++ i * sizeof(port_t);
++ struct net_device *dev = hdlc_to_dev(&port->hdlc);
++ spin_lock_init(&port->lock);
++ SET_MODULE_OWNER(dev);
++ dev->tx_queue_len = 50;
++ dev->do_ioctl = wanxl_ioctl;
++ dev->open = wanxl_open;
++ dev->stop = wanxl_close;
++ port->hdlc.attach = wanxl_attach;
++ port->hdlc.xmit = wanxl_xmit;
++ if(register_hdlc_device(&port->hdlc)) {
++ printk(KERN_ERR "wanXL %s: unable to register hdlc"
++ " device\n", card_name(pdev));
++ wanxl_pci_remove_one(pdev);
++ return -ENOBUFS;
++ }
++ card->ports[i] = port;
++ dev->get_stats = wanxl_get_stats;
++ port->card = card;
++ port->node = i;
++ get_status(port)->clocking = CLOCK_EXT;
++ }
++
++ for (i = 0; i < RX_QUEUE_LENGTH; i++) {
++ struct sk_buff *skb = dev_alloc_skb(BUFFER_LENGTH);
++ card->rx_skbs[i] = skb;
++ if (skb)
++ card->status->rx_descs[i].address =
++ pci_map_single(card->pdev, skb->data,
++ BUFFER_LENGTH,
++ PCI_DMA_FROMDEVICE);
++ }
++
++ mem = ioremap_nocache(mem_phy, PDM_OFFSET + sizeof(firmware));
++ for (i = 0; i < sizeof(firmware); i += 4)
++ writel(htonl(*(u32*)(firmware + i)), mem + PDM_OFFSET + i);
++
++ for (i = 0; i < ports; i++)
++ writel(card->status_address +
++ (void *)&card->status->port_status[i] -
++ (void *)card->status, mem + PDM_OFFSET + 4 + i * 4);
++ writel(card->status_address, mem + PDM_OFFSET + 20);
++ writel(PDM_OFFSET, mem);
++ iounmap(mem);
++
++ writel(0, card->plx + PLX_MAILBOX_5);
++
++ if (wanxl_puts_command(card, MBX1_CMD_ABORTJ)) {
++ printk(KERN_WARNING "wanXL %s: unable to Abort and Jump\n",
++ card_name(pdev));
++ wanxl_pci_remove_one(pdev);
++ return -ENODEV;
++ }
++
++ stat = 0;
++ timeout = jiffies + 5 * HZ;
++ do {
++ if ((stat = readl(card->plx + PLX_MAILBOX_5)) != 0)
++ break;
++ schedule();
++ }while (time_after(timeout, jiffies));
++
++ if (!stat) {
++ printk(KERN_WARNING "wanXL %s: timeout while initializing card"
++ "firmware\n", card_name(pdev));
++ wanxl_pci_remove_one(pdev);
++ return -ENODEV;
++ }
++
++#if DETECT_RAM
++ ramsize = stat;
++#endif
++
++ printk(KERN_INFO "wanXL %s: at 0x%X, %u KB of RAM at 0x%X, irq"
++ " %u\n" KERN_INFO "wanXL %s: port", card_name(pdev),
++ plx_phy, ramsize / 1024, mem_phy, pdev->irq, card_name(pdev));
++
++ for (i = 0; i < ports; i++)
++ printk("%s #%i: %s", i ? "," : "", i,
++ port_name(card->ports[i]));
++ printk("\n");
++
++ /* Allocate IRQ */
++ if(request_irq(pdev->irq, wanxl_intr, SA_SHIRQ, "wanXL", card)) {
++ printk(KERN_WARNING "wanXL %s: could not allocate IRQ%i.\n",
++ card_name(pdev), pdev->irq);
++ wanxl_pci_remove_one(pdev);
++ return -EBUSY;
++ }
++ card->irq = pdev->irq;
++
++ return 0;
++}
++
++static struct pci_device_id wanxl_pci_tbl[] __devinitdata = {
++ { PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_SBE_WANXL100, PCI_ANY_ID,
++ PCI_ANY_ID, 0, 0, 0 },
++ { PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_SBE_WANXL200, PCI_ANY_ID,
++ PCI_ANY_ID, 0, 0, 0 },
++ { PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_SBE_WANXL400, PCI_ANY_ID,
++ PCI_ANY_ID, 0, 0, 0 },
++ { 0, }
++};
++
++
++static struct pci_driver wanxl_pci_driver = {
++ name: "wanXL",
++ id_table: wanxl_pci_tbl,
++ probe: wanxl_pci_init_one,
++ remove: wanxl_pci_remove_one,
++};
++
++
++static int __init wanxl_init_module(void)
++{
++#ifdef MODULE
++ printk(KERN_INFO "%s\n", version);
++#endif
++ return pci_module_init(&wanxl_pci_driver);
++}
++
++static void __exit wanxl_cleanup_module(void)
++{
++ pci_unregister_driver(&wanxl_pci_driver);
++}
++
++
++MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
++MODULE_DESCRIPTION("SBE Inc. wanXL serial port driver");
++MODULE_LICENSE("GPL v2");
++MODULE_DEVICE_TABLE(pci, wanxl_pci_tbl);
++
++module_init(wanxl_init_module);
++module_exit(wanxl_cleanup_module);
+Index: linux-2.6.0-test5/drivers/net/wan/wanxlfw.inc
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/wanxlfw.inc 2003-09-27 11:38:18.459722080 +0800
++++ linux-2.6.0-test5/drivers/net/wan/wanxlfw.inc 2003-09-27 11:38:28.619177608 +0800
+@@ -0,0 +1,158 @@
++static u8 firmware[]={
++0x60,0x00,0x00,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0xB9,0x40,0x00,0x00,0x00,0x00,0x00,
++0x10,0x14,0x42,0x80,0x4A,0xB0,0x09,0xB0,0x00,0x00,0x10,0x04,0x67,0x00,0x00,0x0E,
++0x06,0xB0,0x40,0x00,0x00,0x00,0x09,0xB0,0x00,0x00,0x10,0x04,0x58,0x80,0x0C,0x80,
++0x00,0x00,0x00,0x10,0x66,0x00,0xFF,0xDE,0x21,0xFC,0x00,0x00,0x16,0xBC,0x00,0x6C,
++0x21,0xFC,0x00,0x00,0x17,0x5E,0x01,0x00,0x21,0xFC,0x00,0x00,0x16,0xDE,0x01,0x78,
++0x21,0xFC,0x00,0x00,0x16,0xFE,0x01,0x74,0x21,0xFC,0x00,0x00,0x17,0x1E,0x01,0x70,
++0x21,0xFC,0x00,0x00,0x17,0x3E,0x01,0x6C,0x21,0xFC,0x00,0x00,0x18,0x4C,0x02,0x00,
++0x23,0xFC,0x78,0x00,0x00,0x00,0xFF,0xFC,0x15,0x48,0x33,0xFC,0x04,0x80,0xFF,0xFC,
++0x10,0x26,0x33,0xFC,0x01,0x10,0xFF,0xFC,0x10,0x2A,0x23,0xFC,0x00,0xD4,0x9F,0x40,
++0xFF,0xFC,0x15,0x40,0x23,0xFC,0x00,0x00,0x05,0x43,0xFF,0xF9,0x01,0x00,0x23,0xFC,
++0x00,0x00,0x05,0x43,0xFF,0xF9,0x01,0x14,0x23,0xFC,0x00,0x00,0x00,0x00,0xFF,0xF9,
++0x01,0x10,0x23,0xFC,0x00,0x00,0x00,0x08,0xFF,0xF9,0x01,0x24,0x23,0xFC,0x00,0x00,
++0x01,0x01,0xFF,0xF9,0x01,0x28,0x00,0xB9,0x00,0x0F,0x03,0x00,0xFF,0xF9,0x00,0xE8,
++0x23,0xFC,0x00,0x00,0x00,0x01,0xFF,0xF9,0x00,0xD4,0x61,0x00,0x06,0x74,0x33,0xFC,
++0xFF,0xFF,0xFF,0xFC,0x15,0x52,0x42,0x79,0xFF,0xFC,0x15,0x50,0x42,0x79,0xFF,0xFC,
++0x15,0x64,0x2E,0x3A,0x08,0x50,0x42,0xB9,0x00,0x00,0x19,0x54,0x4A,0x87,0x66,0x00,
++0x00,0x0E,0x4E,0x72,0x22,0x00,0x46,0xFC,0x27,0x00,0x60,0x00,0xFF,0xE6,0x42,0x80,
++0x42,0x86,0x08,0x07,0x00,0x04,0x67,0x00,0x00,0x0A,0x08,0x87,0x00,0x00,0x61,0x00,
++0x02,0xA0,0x08,0x07,0x00,0x00,0x67,0x00,0x00,0x06,0x61,0x00,0x00,0x36,0x08,0x07,
++0x00,0x08,0x67,0x00,0x00,0x06,0x61,0x00,0x02,0xB8,0x08,0x07,0x00,0x0C,0x67,0x00,
++0x00,0x0A,0x61,0x00,0x04,0x94,0x61,0x00,0x03,0x60,0xE2,0x8F,0x58,0x80,0x0C,0x80,
++0x00,0x00,0x00,0x10,0x66,0x00,0xFF,0xBC,0x23,0xC6,0xFF,0xF9,0x00,0xE4,0x60,0x00,
++0xFF,0x92,0x20,0x70,0x09,0xB0,0x00,0x00,0x10,0x04,0x4A,0xA8,0x00,0x00,0x66,0x00,
++0x02,0x4E,0x21,0x7C,0x00,0x00,0x00,0x01,0x00,0x00,0x42,0xB0,0x09,0xB0,0x00,0x00,
++0x19,0x58,0x42,0xB0,0x09,0xB0,0x00,0x00,0x19,0x68,0x42,0xB0,0x09,0xB0,0x00,0x00,
++0x19,0x78,0x42,0xB0,0x09,0xB0,0x00,0x00,0x19,0x88,0x22,0x39,0xFF,0xFC,0x16,0xEC,
++0xC2,0xB0,0x09,0xB0,0x00,0x00,0x18,0xF2,0x0C,0xA8,0x00,0x00,0x00,0x04,0x00,0x18,
++0x66,0x00,0x00,0x0E,0x82,0xB0,0x09,0xB0,0x00,0x00,0x18,0xE2,0x60,0x00,0x00,0x0A,
++0x82,0xB0,0x09,0xB0,0x00,0x00,0x18,0xD2,0x23,0xC1,0xFF,0xFC,0x16,0xEC,0x00,0x70,
++0x10,0x00,0x09,0xB0,0x00,0x00,0x19,0xAA,0x61,0x00,0x05,0x76,0x22,0x30,0x09,0xB0,
++0x00,0x00,0x18,0x92,0x22,0x70,0x09,0xB0,0x00,0x00,0x18,0x72,0x74,0x08,0x26,0x3C,
++0x18,0x00,0x00,0x00,0x0C,0xA8,0x00,0x00,0x00,0x01,0x00,0x10,0x67,0x00,0x00,0x06,
++0x08,0xC3,0x00,0x1A,0x22,0xC3,0x22,0xC1,0x06,0x81,0x00,0x00,0x05,0xFC,0x51,0xCA,
++0xFF,0xF4,0x08,0xC3,0x00,0x1D,0x22,0xC3,0x22,0xC1,0x74,0x1C,0x22,0xFC,0x90,0x00,
++0x00,0x00,0x22,0xC1,0x06,0x81,0x00,0x00,0x05,0xFC,0x51,0xCA,0xFF,0xF0,0x22,0xFC,
++0xB0,0x00,0x00,0x00,0x22,0xC1,0x22,0x70,0x09,0xB0,0x00,0x00,0x18,0x62,0x24,0x70,
++0x09,0xB0,0x00,0x00,0x18,0x52,0x25,0x7C,0x00,0x00,0xFF,0xFF,0x00,0x10,0x25,0x7C,
++0x00,0x00,0x00,0x00,0x00,0x14,0x22,0x30,0x09,0xB0,0x00,0x00,0x18,0x72,0x33,0x41,
++0x00,0x02,0x06,0x81,0x00,0x00,0x00,0x50,0x33,0x41,0x00,0x00,0x13,0x7C,0x00,0x08,
++0x00,0x04,0x13,0x7C,0x00,0x08,0x00,0x05,0x0C,0xA8,0x00,0x00,0x00,0x05,0x00,0x10,
++0x66,0x00,0x00,0x2A,0x42,0x6A,0x00,0x08,0x23,0x7C,0x00,0x00,0xF0,0xB8,0x00,0x34,
++0x23,0x7C,0x00,0x00,0xFF,0xFF,0x00,0x38,0x33,0x7C,0x05,0xFA,0x00,0x46,0x31,0xBC,
++0x00,0x02,0x09,0xB0,0x00,0x00,0x19,0x9C,0x60,0x00,0x00,0xBC,0x0C,0xA8,0x00,0x00,
++0x00,0x07,0x00,0x10,0x66,0x00,0x00,0x2C,0x35,0x7C,0x08,0x00,0x00,0x08,0x23,0x7C,
++0xDE,0xBB,0x20,0xE3,0x00,0x34,0x23,0x7C,0xFF,0xFF,0xFF,0xFF,0x00,0x38,0x33,0x7C,
++0x05,0xFC,0x00,0x46,0x31,0xBC,0x00,0x04,0x09,0xB0,0x00,0x00,0x19,0x9C,0x60,0x00,
++0x00,0x86,0x0C,0xA8,0x00,0x00,0x00,0x04,0x00,0x10,0x66,0x00,0x00,0x26,0x42,0x6A,
++0x00,0x08,0x23,0x7C,0x00,0x00,0xF0,0xB8,0x00,0x34,0x42,0xA9,0x00,0x38,0x33,0x7C,
++0x05,0xFA,0x00,0x46,0x31,0xBC,0x00,0x02,0x09,0xB0,0x00,0x00,0x19,0x9C,0x60,0x00,
++0x00,0x56,0x0C,0xA8,0x00,0x00,0x00,0x06,0x00,0x10,0x66,0x00,0x00,0x28,0x35,0x7C,
++0x08,0x00,0x00,0x08,0x23,0x7C,0xDE,0xBB,0x20,0xE3,0x00,0x34,0x42,0xA9,0x00,0x38,
++0x33,0x7C,0x05,0xFC,0x00,0x46,0x31,0xBC,0x00,0x04,0x09,0xB0,0x00,0x00,0x19,0x9C,
++0x60,0x00,0x00,0x24,0x42,0x6A,0x00,0x08,0x23,0x7C,0x00,0x00,0xF0,0xB8,0x00,0x34,
++0x23,0x7C,0x00,0x00,0xFF,0xFF,0x00,0x38,0x33,0x7C,0x05,0xF8,0x00,0x46,0x42,0x70,
++0x09,0xB0,0x00,0x00,0x19,0x9C,0x25,0x7C,0x00,0x00,0x00,0x03,0x00,0x04,0x0C,0xA8,
++0x00,0x00,0x00,0x02,0x00,0x14,0x66,0x00,0x00,0x0E,0x25,0x7C,0x10,0x04,0x09,0x00,
++0x00,0x00,0x60,0x00,0x00,0x0A,0x25,0x7C,0x10,0x04,0x00,0x00,0x00,0x00,0x33,0x7C,
++0x05,0xFC,0x00,0x06,0x22,0x00,0xE9,0x89,0x00,0x81,0x00,0x00,0x00,0x01,0x33,0xC1,
++0xFF,0xFC,0x15,0xC0,0x08,0x39,0x00,0x00,0xFF,0xFC,0x15,0xC0,0x66,0x00,0xFF,0xF6,
++0x35,0x7C,0x00,0x1F,0x00,0x14,0x00,0xAA,0x00,0x00,0x00,0x30,0x00,0x00,0x4E,0x75,
++0x20,0x70,0x09,0xB0,0x00,0x00,0x18,0x52,0x42,0x68,0x00,0x14,0x02,0xA8,0xFF,0xFF,
++0xFF,0xCF,0x00,0x00,0x02,0x70,0xEF,0xFF,0x09,0xB0,0x00,0x00,0x19,0xAA,0x61,0x00,
++0x03,0x70,0x22,0x30,0x09,0xB0,0x00,0x00,0x10,0x04,0x42,0xB0,0x19,0x90,0x4E,0x75,
++0x0C,0xB0,0x00,0x00,0x00,0x0A,0x09,0xB0,0x00,0x00,0x19,0x78,0x67,0x00,0x00,0xA8,
++0x22,0x30,0x09,0xB0,0x00,0x00,0x19,0x68,0x24,0x01,0x4C,0x3C,0x20,0x00,0x00,0x00,
++0x00,0x0C,0xD4,0xB0,0x09,0xB0,0x00,0x00,0x10,0x04,0x06,0x82,0x00,0x00,0x00,0x1C,
++0x0C,0xB0,0x00,0x00,0x00,0x10,0x29,0x90,0x66,0x00,0x00,0x7C,0x20,0x70,0x29,0xA0,
++0x00,0x04,0xE7,0x89,0xD2,0xB0,0x09,0xB0,0x00,0x00,0x18,0x72,0x22,0x70,0x19,0xA0,
++0x00,0x04,0x24,0x30,0x29,0xA0,0x00,0x08,0x31,0x82,0x19,0xA0,0x00,0x02,0x56,0x82,
++0x02,0x82,0xFF,0xFF,0xFF,0xFC,0x23,0xC8,0xFF,0xF9,0x01,0x04,0x23,0xC9,0xFF,0xF9,
++0x01,0x08,0x23,0xC2,0xFF,0xF9,0x01,0x0C,0x23,0xFC,0x00,0x00,0x01,0x03,0xFF,0xF9,
++0x01,0x28,0x61,0x00,0x01,0xF6,0x08,0xF0,0x00,0x1F,0x19,0x90,0x22,0x30,0x09,0xB0,
++0x00,0x00,0x19,0x68,0x52,0x81,0x0C,0x81,0x00,0x00,0x00,0x0A,0x66,0x00,0x00,0x04,
++0x42,0x81,0x21,0x81,0x09,0xB0,0x00,0x00,0x19,0x68,0x52,0xB0,0x09,0xB0,0x00,0x00,
++0x19,0x78,0x60,0x00,0xFF,0x4C,0x4E,0x75,0x22,0x30,0x09,0xB0,0x00,0x00,0x19,0x88,
++0xE7,0x89,0xD2,0xB0,0x09,0xB0,0x00,0x00,0x18,0x82,0x34,0x30,0x19,0x90,0x08,0x02,
++0x00,0x0F,0x66,0x00,0x01,0x12,0x08,0x02,0x00,0x01,0x66,0x00,0x00,0xE6,0x4A,0x70,
++0x09,0xB0,0x00,0x00,0x19,0x9C,0x66,0x00,0x00,0x06,0x08,0x82,0x00,0x02,0x02,0x42,
++0x0C,0xBC,0x0C,0x42,0x0C,0x00,0x66,0x00,0x00,0xDC,0x42,0x83,0x36,0x30,0x19,0xA0,
++0x00,0x02,0x96,0x70,0x09,0xB0,0x00,0x00,0x19,0x9C,0x0C,0x43,0x05,0xF8,0x6E,0x00,
++0x00,0xC4,0x24,0x3A,0x04,0x84,0x4C,0x3C,0x20,0x00,0x00,0x00,0x00,0x0C,0xD4,0xBA,
++0xFA,0xF4,0x0C,0xB0,0x00,0x00,0x00,0x00,0x29,0x90,0x66,0x00,0x00,0x96,0x21,0x83,
++0x29,0xA0,0x00,0x08,0x20,0x70,0x19,0xA0,0x00,0x04,0x22,0x70,0x29,0xA0,0x00,0x04,
++0x4A,0x89,0x67,0x00,0x00,0x2A,0x56,0x83,0x02,0x83,0xFF,0xFF,0xFF,0xFC,0x23,0xC8,
++0xFF,0xF9,0x01,0x1C,0x23,0xC9,0xFF,0xF9,0x01,0x18,0x23,0xC3,0xFF,0xF9,0x01,0x20,
++0x23,0xFC,0x00,0x00,0x03,0x01,0xFF,0xF9,0x01,0x28,0x61,0x00,0x01,0x2C,0x21,0xB0,
++0x09,0xB0,0x00,0x00,0x18,0xC2,0x29,0x90,0x08,0xC6,0x00,0x04,0x24,0x3A,0x04,0x1A,
++0x52,0x82,0x0C,0x82,0x00,0x00,0x00,0x28,0x66,0x00,0x00,0x04,0x42,0x82,0x23,0xC2,
++0x00,0x00,0x19,0x98,0x02,0x70,0xF0,0x00,0x19,0x90,0x08,0xF0,0x00,0x1F,0x19,0x90,
++0x22,0x30,0x09,0xB0,0x00,0x00,0x19,0x88,0x52,0x81,0x0C,0x81,0x00,0x00,0x00,0x1E,
++0x66,0x00,0x00,0x04,0x42,0x81,0x21,0x81,0x09,0xB0,0x00,0x00,0x19,0x88,0x60,0x00,
++0xFE,0xF8,0x24,0x30,0x09,0xB0,0x00,0x00,0x10,0x04,0x52,0xB0,0x29,0xA0,0x00,0x08,
++0x60,0x00,0xFF,0xC2,0x24,0x30,0x09,0xB0,0x00,0x00,0x10,0x04,0x52,0xB0,0x29,0xA0,
++0x00,0x0C,0x60,0x00,0xFF,0xB0,0x4E,0x75,0x4A,0xB0,0x09,0xB0,0x00,0x00,0x19,0x78,
++0x67,0x00,0x00,0x86,0x22,0x30,0x09,0xB0,0x00,0x00,0x19,0x58,0x24,0x01,0xE7,0x89,
++0xD2,0xB0,0x09,0xB0,0x00,0x00,0x18,0x72,0x36,0x30,0x19,0x90,0x08,0x03,0x00,0x0F,
++0x66,0x00,0x00,0x66,0x8C,0xB0,0x09,0xB0,0x00,0x00,0x18,0xA2,0x53,0xB0,0x09,0xB0,
++0x00,0x00,0x19,0x78,0x22,0x30,0x09,0xB0,0x00,0x00,0x19,0x58,0x52,0x81,0x0C,0x81,
++0x00,0x00,0x00,0x0A,0x66,0x00,0x00,0x04,0x42,0x81,0x21,0x81,0x09,0xB0,0x00,0x00,
++0x19,0x58,0x4C,0x3C,0x20,0x00,0x00,0x00,0x00,0x0C,0xD4,0xB0,0x09,0xB0,0x00,0x00,
++0x10,0x04,0x06,0x82,0x00,0x00,0x00,0x1C,0x08,0x03,0x00,0x01,0x66,0x00,0x00,0x0E,
++0x21,0xBC,0x00,0x00,0x00,0x20,0x29,0x90,0x60,0x00,0xFF,0x7E,0x21,0xBC,0x00,0x00,
++0x00,0x30,0x29,0x90,0x60,0x00,0xFF,0x72,0x4E,0x75,0x2F,0x00,0x40,0xE7,0x20,0x39,
++0xFF,0xF9,0x01,0x28,0x08,0x00,0x00,0x04,0x66,0x00,0x00,0x2C,0x4E,0x72,0x22,0x00,
++0x46,0xFC,0x27,0x00,0x60,0x00,0xFF,0xE8,0x2F,0x00,0x40,0xE7,0x20,0x39,0xFF,0xF9,
++0x01,0x28,0x08,0x00,0x00,0x0C,0x66,0x00,0x00,0x0E,0x4E,0x72,0x22,0x00,0x46,0xFC,
++0x27,0x00,0x60,0x00,0xFF,0xE8,0x46,0xDF,0x20,0x1F,0x4E,0x75,0x2F,0x00,0x20,0x39,
++0xFF,0xF9,0x00,0xE0,0x23,0xC0,0xFF,0xF9,0x00,0xE0,0x81,0xB9,0x00,0x00,0x19,0x54,
++0x23,0xFC,0x00,0x00,0x09,0x09,0xFF,0xF9,0x01,0x28,0x20,0x1F,0x4E,0x73,0x00,0xB9,
++0x00,0x00,0x00,0x00,0xFF,0xFC,0x16,0x10,0x00,0xB9,0x00,0x00,0x10,0x00,0x00,0x00,
++0x19,0x54,0x23,0xFC,0x40,0x00,0x00,0x00,0xFF,0xFC,0x15,0x4C,0x4E,0x73,0x00,0xB9,
++0x00,0x00,0x00,0x00,0xFF,0xFC,0x16,0x30,0x00,0xB9,0x00,0x00,0x20,0x00,0x00,0x00,
++0x19,0x54,0x23,0xFC,0x20,0x00,0x00,0x00,0xFF,0xFC,0x15,0x4C,0x4E,0x73,0x00,0xB9,
++0x00,0x00,0x00,0x00,0xFF,0xFC,0x16,0x50,0x00,0xB9,0x00,0x00,0x40,0x00,0x00,0x00,
++0x19,0x54,0x23,0xFC,0x10,0x00,0x00,0x00,0xFF,0xFC,0x15,0x4C,0x4E,0x73,0x00,0xB9,
++0x00,0x00,0x00,0x00,0xFF,0xFC,0x16,0x70,0x00,0xB9,0x00,0x00,0x80,0x00,0x00,0x00,
++0x19,0x54,0x23,0xFC,0x08,0x00,0x00,0x00,0xFF,0xFC,0x15,0x4C,0x4E,0x73,0x4E,0x73,
++0x2F,0x00,0x2F,0x01,0x2F,0x02,0x2F,0x08,0x2F,0x09,0x42,0x80,0x20,0x7C,0xFF,0xFB,
++0x00,0x00,0x32,0x10,0x02,0x81,0x00,0x00,0x00,0xE7,0x0C,0x41,0x00,0x42,0x66,0x00,
++0x00,0x0A,0x32,0x3C,0x0E,0x08,0x60,0x00,0x00,0x3E,0x0C,0x41,0x00,0x63,0x66,0x00,
++0x00,0x0A,0x32,0x3C,0x04,0x08,0x60,0x00,0x00,0x2E,0x0C,0x41,0x00,0x84,0x66,0x00,
++0x00,0x0A,0x32,0x3C,0x02,0x08,0x60,0x00,0x00,0x1E,0x0C,0x41,0x00,0xA5,0x66,0x00,
++0x00,0x0A,0x32,0x3C,0x0D,0x08,0x60,0x00,0x00,0x0E,0x32,0x3C,0x00,0x08,0x34,0x3C,
++0x80,0xE7,0x60,0x00,0x00,0x14,0x34,0x30,0x09,0xB0,0x00,0x00,0x19,0xAA,0x02,0x42,
++0x30,0x00,0x82,0x42,0x34,0x3C,0x80,0xFF,0xB2,0x70,0x09,0xB0,0x00,0x00,0x19,0xAC,
++0x67,0x00,0x00,0x0C,0x31,0x81,0x09,0xB0,0x00,0x00,0x19,0xAC,0x30,0x81,0x32,0x39,
++0xFF,0xFC,0x15,0x66,0xC2,0x70,0x09,0xB0,0x00,0x00,0x19,0x02,0x67,0x00,0x00,0x0C,
++0x32,0x10,0x02,0x41,0xFF,0xF7,0x60,0x00,0x00,0x08,0x32,0x10,0x00,0x41,0x00,0x08,
++0xC2,0x42,0x22,0x70,0x09,0xB0,0x00,0x00,0x10,0x04,0xB2,0xA9,0x00,0x04,0x67,0x00,
++0x00,0x12,0x23,0x41,0x00,0x04,0x23,0xF0,0x09,0xB0,0x00,0x00,0x18,0xB2,0xFF,0xF9,
++0x00,0xE4,0x54,0x88,0x58,0x80,0x0C,0x80,0x00,0x00,0x00,0x10,0x66,0x00,0xFF,0x34,
++0x22,0x5F,0x20,0x5F,0x24,0x1F,0x22,0x1F,0x20,0x1F,0x4E,0x75,0x61,0x00,0xFF,0x12,
++0x4E,0x73,0xFF,0xFC,0x16,0x00,0xFF,0xFC,0x16,0x20,0xFF,0xFC,0x16,0x40,0xFF,0xFC,
++0x16,0x60,0xFF,0xFC,0x0C,0x00,0xFF,0xFC,0x0D,0x00,0xFF,0xFC,0x0E,0x00,0xFF,0xFC,
++0x0F,0x00,0xFF,0xFC,0x00,0x00,0xFF,0xFC,0x01,0x40,0xFF,0xFC,0x02,0x80,0xFF,0xFC,
++0x03,0xC0,0xFF,0xFC,0x00,0x50,0xFF,0xFC,0x01,0x90,0xFF,0xFC,0x02,0xD0,0xFF,0xFC,
++0x04,0x10,0x00,0x00,0x40,0x00,0x00,0x01,0x2F,0x60,0x00,0x02,0x1E,0xC0,0x00,0x03,
++0x0E,0x20,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x04,0x00,0x00,
++0x00,0x08,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x80,0x00,0x00,
++0x01,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x11,0x00,0x00,0x00,0x12,0x00,0x00,
++0x00,0x13,0x00,0x00,0x00,0x2C,0x00,0x00,0x3E,0x00,0x00,0x2C,0x00,0x00,0x3E,0x00,
++0x00,0x00,0x00,0x00,0x00,0x2D,0x00,0x00,0x3F,0x00,0x00,0x2D,0x00,0x00,0x3F,0x00,
++0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,
++0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x80,0x00,0x00,0x02,0x00,0x00,0x00,0x08,0x00,
++0x77,0x61,0x6E,0x58,0x4C,0x20,0x66,0x69,0x72,0x6D,0x77,0x61,0x72,0x65,0x0A,0x43,
++0x6F,0x70,0x79,0x72,0x69,0x67,0x68,0x74,0x20,0x28,0x43,0x29,0x20,0x32,0x30,0x30,
++0x33,0x20,0x4B,0x72,0x7A,0x79,0x73,0x7A,0x74,0x6F,0x66,0x20,0x48,0x61,0x6C,0x61,
++0x73,0x61,0x20,0x3C,0x6B,0x68,0x63,0x40,0x70,0x6D,0x2E,0x77,0x61,0x77,0x2E,0x70,
++0x6C,0x3E,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++};
+Index: linux-2.6.0-test5/drivers/net/wan/wanxlfw.S
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/wanxlfw.S 2003-09-27 11:38:18.459722080 +0800
++++ linux-2.6.0-test5/drivers/net/wan/wanxlfw.S 2003-09-27 11:38:28.621177304 +0800
+@@ -0,0 +1,895 @@
++.psize 0
++/*
++ wanXL serial card driver for Linux
++ card firmware part
++
++ Copyright (C) 2003 Krzysztof Halasa <khc@pm.waw.pl>
++
++ 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.
++
++
++
++
++ DPRAM BDs:
++ 0x000 - 0x050 TX#0 0x050 - 0x140 RX#0
++ 0x140 - 0x190 TX#1 0x190 - 0x280 RX#1
++ 0x280 - 0x2D0 TX#2 0x2D0 - 0x3C0 RX#2
++ 0x3C0 - 0x410 TX#3 0x410 - 0x500 RX#3
++
++
++ 000 5FF 1536 Bytes Dual-Port RAM User Data / BDs
++ 600 6FF 256 Bytes Dual-Port RAM User Data / BDs
++ 700 7FF 256 Bytes Dual-Port RAM User Data / BDs
++ C00 CBF 192 Bytes Dual-Port RAM Parameter RAM Page 1
++ D00 DBF 192 Bytes Dual-Port RAM Parameter RAM Page 2
++ E00 EBF 192 Bytes Dual-Port RAM Parameter RAM Page 3
++ F00 FBF 192 Bytes Dual-Port RAM Parameter RAM Page 4
++
++ local interrupts level
++ NMI 7
++ PIT timer, CPM (RX/TX complete) 4
++ PCI9060 DMA and PCI doorbells 3
++ Cable - not used 1
++*/
++
++#include <linux/hdlc.h>
++#include "wanxl.h"
++
++/* memory addresses and offsets */
++
++MAX_RAM_SIZE = 16 * 1024 * 1024 // max RAM supported by hardware
++
++PCI9060_VECTOR = 0x0000006C
++CPM_IRQ_BASE = 0x40
++ERROR_VECTOR = CPM_IRQ_BASE * 4
++SCC1_VECTOR = (CPM_IRQ_BASE + 0x1E) * 4
++SCC2_VECTOR = (CPM_IRQ_BASE + 0x1D) * 4
++SCC3_VECTOR = (CPM_IRQ_BASE + 0x1C) * 4
++SCC4_VECTOR = (CPM_IRQ_BASE + 0x1B) * 4
++CPM_IRQ_LEVEL = 4
++TIMER_IRQ = 128
++TIMER_IRQ_LEVEL = 4
++PITR_CONST = 0x100 + 16 // 1 Hz timer
++
++MBAR = 0x0003FF00
++
++VALUE_WINDOW = 0x40000000
++ORDER_WINDOW = 0xC0000000
++
++PLX = 0xFFF90000
++
++CSRA = 0xFFFB0000
++CSRB = 0xFFFB0002
++CSRC = 0xFFFB0004
++CSRD = 0xFFFB0006
++STATUS_CABLE_LL = 0x2000
++STATUS_CABLE_DTR = 0x1000
++
++DPRBASE = 0xFFFC0000
++
++SCC1_BASE = DPRBASE + 0xC00
++MISC_BASE = DPRBASE + 0xCB0
++SCC2_BASE = DPRBASE + 0xD00
++SCC3_BASE = DPRBASE + 0xE00
++SCC4_BASE = DPRBASE + 0xF00
++
++// offset from SCCx_BASE
++// SCC_xBASE contain offsets from DPRBASE and must be divisible by 8
++SCC_RBASE = 0 // 16-bit RxBD base address
++SCC_TBASE = 2 // 16-bit TxBD base address
++SCC_RFCR = 4 // 8-bit Rx function code
++SCC_TFCR = 5 // 8-bit Tx function code
++SCC_MRBLR = 6 // 16-bit maximum Rx buffer length
++SCC_C_MASK = 0x34 // 32-bit CRC constant
++SCC_C_PRES = 0x38 // 32-bit CRC preset
++SCC_MFLR = 0x46 // 16-bit max Rx frame length (without flags)
++
++REGBASE = DPRBASE + 0x1000
++PICR = REGBASE + 0x026 // 16-bit periodic irq control
++PITR = REGBASE + 0x02A // 16-bit periodic irq timing
++OR1 = REGBASE + 0x064 // 32-bit RAM bank #1 options
++CICR = REGBASE + 0x540 // 32(24)-bit CP interrupt config
++CIMR = REGBASE + 0x548 // 32-bit CP interrupt mask
++CISR = REGBASE + 0x54C // 32-bit CP interrupts in-service
++PADIR = REGBASE + 0x550 // 16-bit PortA data direction bitmap
++PAPAR = REGBASE + 0x552 // 16-bit PortA pin assignment bitmap
++PAODR = REGBASE + 0x554 // 16-bit PortA open drain bitmap
++PADAT = REGBASE + 0x556 // 16-bit PortA data register
++
++PCDIR = REGBASE + 0x560 // 16-bit PortC data direction bitmap
++PCPAR = REGBASE + 0x562 // 16-bit PortC pin assignment bitmap
++PCSO = REGBASE + 0x564 // 16-bit PortC special options
++PCDAT = REGBASE + 0x566 // 16-bit PortC data register
++PCINT = REGBASE + 0x568 // 16-bit PortC interrupt control
++CR = REGBASE + 0x5C0 // 16-bit Command register
++
++SCC1_REGS = REGBASE + 0x600
++SCC2_REGS = REGBASE + 0x620
++SCC3_REGS = REGBASE + 0x640
++SCC4_REGS = REGBASE + 0x660
++SICR = REGBASE + 0x6EC // 32-bit SI clock route
++
++// offset from SCCx_REGS
++SCC_GSMR_L = 0x00 // 32 bits
++SCC_GSMR_H = 0x04 // 32 bits
++SCC_PSMR = 0x08 // 16 bits
++SCC_TODR = 0x0C // 16 bits
++SCC_DSR = 0x0E // 16 bits
++SCC_SCCE = 0x10 // 16 bits
++SCC_SCCM = 0x14 // 16 bits
++SCC_SCCS = 0x17 // 8 bits
++
++#if QUICC_MEMCPY_USES_PLX
++ .macro memcpy_from_pci src, dest, len // len must be < 8 MB
++ addl #3, \len
++ andl #0xFFFFFFFC, \len // always copy n * 4 bytes
++ movel \src, PLX_DMA_0_PCI
++ movel \dest, PLX_DMA_0_LOCAL
++ movel \len, PLX_DMA_0_LENGTH
++ movel #0x0103, PLX_DMA_CMD_STS // start channel 0 transfer
++ bsr memcpy_from_pci_run
++ .endm
++
++ .macro memcpy_to_pci src, dest, len
++ addl #3, \len
++ andl #0xFFFFFFFC, \len // always copy n * 4 bytes
++ movel \src, PLX_DMA_1_LOCAL
++ movel \dest, PLX_DMA_1_PCI
++ movel \len, PLX_DMA_1_LENGTH
++ movel #0x0301, PLX_DMA_CMD_STS // start channel 1 transfer
++ bsr memcpy_to_pci_run
++ .endm
++
++#else
++
++ .macro memcpy src, dest, len // len must be < 65536 bytes
++ movel %d7, -(%sp) // src and dest must be < 256 MB
++ movel \len, %d7 // bits 0 and 1
++ lsrl #2, \len
++ andl \len, \len
++ beq 99f // only 0 - 3 bytes
++ subl #1, \len // for dbf
++98: movel (\src)+, (\dest)+
++ dbfw \len, 98b
++99: movel %d7, \len
++ btstl #1, \len
++ beq 99f
++ movew (\src)+, (\dest)+
++99: btstl #0, \len
++ beq 99f
++ moveb (\src)+, (\dest)+
++99:
++ movel (%sp)+, %d7
++ .endm
++
++ .macro memcpy_from_pci src, dest, len
++ addl #VALUE_WINDOW, \src
++ memcpy \src, \dest, \len
++ .endm
++
++ .macro memcpy_to_pci src, dest, len
++ addl #VALUE_WINDOW, \dest
++ memcpy \src, \dest, \len
++ .endm
++#endif
++
++
++ .macro wait_for_command
++99: btstl #0, CR
++ bne 99b
++ .endm
++
++
++
++
++/****************************** card initialization *******************/
++ .text
++ .global _start
++_start: bra init
++
++ .org _start + 4
++ch_status_addr: .long 0, 0, 0, 0
++rx_descs_addr: .long 0
++
++init:
++#if DETECT_RAM
++ movel OR1, %d0
++ andl #0xF00007FF, %d0 // mask AMxx bits
++ orl #0xFFFF800 & ~(MAX_RAM_SIZE - 1), %d0 // update RAM bank size
++ movel %d0, OR1
++#endif
++
++ addl #VALUE_WINDOW, rx_descs_addr // PCI addresses of shared data
++ clrl %d0 // D0 = 4 * port
++init_1: tstl ch_status_addr(%d0)
++ beq init_2
++ addl #VALUE_WINDOW, ch_status_addr(%d0)
++init_2: addl #4, %d0
++ cmpl #4 * 4, %d0
++ bne init_1
++
++ movel #pci9060_interrupt, PCI9060_VECTOR
++ movel #error_interrupt, ERROR_VECTOR
++ movel #port_interrupt_1, SCC1_VECTOR
++ movel #port_interrupt_2, SCC2_VECTOR
++ movel #port_interrupt_3, SCC3_VECTOR
++ movel #port_interrupt_4, SCC4_VECTOR
++ movel #timer_interrupt, TIMER_IRQ * 4
++
++ movel #0x78000000, CIMR // only SCCx IRQs from CPM
++ movew #(TIMER_IRQ_LEVEL << 8) + TIMER_IRQ, PICR // interrupt from PIT
++ movew #PITR_CONST, PITR
++
++ // SCC1=SCCa SCC2=SCCb SCC3=SCCc SCC4=SCCd prio=4 HP=-1 IRQ=64-79
++ movel #0xD41F40 + (CPM_IRQ_LEVEL << 13), CICR
++ movel #0x543, PLX_DMA_0_MODE // 32-bit, Ready, Burst, IRQ
++ movel #0x543, PLX_DMA_1_MODE
++ movel #0x0, PLX_DMA_0_DESC // from PCI to local
++ movel #0x8, PLX_DMA_1_DESC // from local to PCI
++ movel #0x101, PLX_DMA_CMD_STS // enable both DMA channels
++ // enable local IRQ, DMA, doorbells and PCI IRQ
++ orl #0x000F0300, PLX_INTERRUPT_CS
++
++#if DETECT_RAM
++ bsr ram_test
++#else
++ movel #1, PLX_MAILBOX_5 // non-zero value = init complete
++#endif
++ bsr check_csr
++
++ movew #0xFFFF, PAPAR // all pins are clocks/data
++ clrw PADIR // first function
++ clrw PCSO // CD and CTS always active
++
++
++/****************************** main loop *****************************/
++
++main: movel channel_stats, %d7 // D7 = doorbell + irq status
++ clrl channel_stats
++
++ tstl %d7
++ bne main_1
++ // nothing to do - wait for next event
++ stop #0x2200 // supervisor + IRQ level 2
++ movew #0x2700, %sr // disable IRQs again
++ bra main
++
++main_1: clrl %d0 // D0 = 4 * port
++ clrl %d6 // D6 = doorbell to host value
++
++main_l: btstl #DOORBELL_TO_CARD_CLOSE_0, %d7
++ beq main_op
++ bclrl #DOORBELL_TO_CARD_OPEN_0, %d7 // in case both bits are set
++ bsr close_port
++main_op:
++ btstl #DOORBELL_TO_CARD_OPEN_0, %d7
++ beq main_cl
++ bsr open_port
++main_cl:
++ btstl #DOORBELL_TO_CARD_TX_0, %d7
++ beq main_txend
++ bsr tx
++main_txend:
++ btstl #TASK_SCC_0, %d7
++ beq main_next
++ bsr tx_end
++ bsr rx
++
++main_next:
++ lsrl #1, %d7 // port status for next port
++ addl #4, %d0 // D0 = 4 * next port
++ cmpl #4 * 4, %d0
++ bne main_l
++ movel %d6, PLX_DOORBELL_FROM_CARD // signal the host
++ bra main
++
++
++/****************************** open port *****************************/
++
++open_port: // D0 = 4 * port, D6 = doorbell to host
++ movel ch_status_addr(%d0), %a0 // A0 = port status address
++ tstl STATUS_OPEN(%a0)
++ bne open_port_ret // port already open
++ movel #1, STATUS_OPEN(%a0) // confirm the port is open
++// setup BDs
++ clrl tx_in(%d0)
++ clrl tx_out(%d0)
++ clrl tx_count(%d0)
++ clrl rx_in(%d0)
++
++ movel SICR, %d1 // D1 = clock settings in SICR
++ andl clocking_mask(%d0), %d1
++ cmpl #CLOCK_TXFROMRX, STATUS_CLOCKING(%a0)
++ bne open_port_clock_ext
++ orl clocking_txfromrx(%d0), %d1
++ bra open_port_set_clock
++
++open_port_clock_ext:
++ orl clocking_ext(%d0), %d1
++open_port_set_clock:
++ movel %d1, SICR // update clock settings in SICR
++
++ orw #STATUS_CABLE_DTR, csr_output(%d0) // DTR on
++ bsr check_csr // call with disabled timer interrupt
++
++// Setup TX descriptors
++ movel first_buffer(%d0), %d1 // D1 = starting buffer address
++ movel tx_first_bd(%d0), %a1 // A1 = starting TX BD address
++ movel #TX_BUFFERS - 2, %d2 // D2 = TX_BUFFERS - 1 counter
++ movel #0x18000000, %d3 // D3 = initial TX BD flags: Int + Last
++ cmpl #PARITY_NONE, STATUS_PARITY(%a0)
++ beq open_port_tx_loop
++ bsetl #26, %d3 // TX BD flag: Transmit CRC
++open_port_tx_loop:
++ movel %d3, (%a1)+ // TX flags + length
++ movel %d1, (%a1)+ // buffer address
++ addl #BUFFER_LENGTH, %d1
++ dbfw %d2, open_port_tx_loop
++
++ bsetl #29, %d3 // TX BD flag: Wrap (last BD)
++ movel %d3, (%a1)+ // Final TX flags + length
++ movel %d1, (%a1)+ // buffer address
++
++// Setup RX descriptors // A1 = starting RX BD address
++ movel #RX_BUFFERS - 2, %d2 // D2 = RX_BUFFERS - 1 counter
++open_port_rx_loop:
++ movel #0x90000000, (%a1)+ // RX flags + length
++ movel %d1, (%a1)+ // buffer address
++ addl #BUFFER_LENGTH, %d1
++ dbfw %d2, open_port_rx_loop
++
++ movel #0xB0000000, (%a1)+ // Final RX flags + length
++ movel %d1, (%a1)+ // buffer address
++
++// Setup port parameters
++ movel scc_base_addr(%d0), %a1 // A1 = SCC_BASE address
++ movel scc_reg_addr(%d0), %a2 // A2 = SCC_REGS address
++
++ movel #0xFFFF, SCC_SCCE(%a2) // clear status bits
++ movel #0x0000, SCC_SCCM(%a2) // interrupt mask
++
++ movel tx_first_bd(%d0), %d1
++ movew %d1, SCC_TBASE(%a1) // D1 = offset of first TxBD
++ addl #TX_BUFFERS * 8, %d1
++ movew %d1, SCC_RBASE(%a1) // D1 = offset of first RxBD
++ moveb #0x8, SCC_RFCR(%a1) // Intel mode, 1000
++ moveb #0x8, SCC_TFCR(%a1)
++
++// Parity settings
++ cmpl #PARITY_CRC16_PR1_CCITT, STATUS_PARITY(%a0)
++ bne open_port_parity_1
++ clrw SCC_PSMR(%a2) // CRC16-CCITT
++ movel #0xF0B8, SCC_C_MASK(%a1)
++ movel #0xFFFF, SCC_C_PRES(%a1)
++ movew #HDLC_MAX_MRU + 2, SCC_MFLR(%a1) // 2 bytes for CRC
++ movew #2, parity_bytes(%d0)
++ bra open_port_2
++
++open_port_parity_1:
++ cmpl #PARITY_CRC32_PR1_CCITT, STATUS_PARITY(%a0)
++ bne open_port_parity_2
++ movew #0x0800, SCC_PSMR(%a2) // CRC32-CCITT
++ movel #0xDEBB20E3, SCC_C_MASK(%a1)
++ movel #0xFFFFFFFF, SCC_C_PRES(%a1)
++ movew #HDLC_MAX_MRU + 4, SCC_MFLR(%a1) // 4 bytes for CRC
++ movew #4, parity_bytes(%d0)
++ bra open_port_2
++
++open_port_parity_2:
++ cmpl #PARITY_CRC16_PR0_CCITT, STATUS_PARITY(%a0)
++ bne open_port_parity_3
++ clrw SCC_PSMR(%a2) // CRC16-CCITT preset 0
++ movel #0xF0B8, SCC_C_MASK(%a1)
++ clrl SCC_C_PRES(%a1)
++ movew #HDLC_MAX_MRU + 2, SCC_MFLR(%a1) // 2 bytes for CRC
++ movew #2, parity_bytes(%d0)
++ bra open_port_2
++
++open_port_parity_3:
++ cmpl #PARITY_CRC32_PR0_CCITT, STATUS_PARITY(%a0)
++ bne open_port_parity_4
++ movew #0x0800, SCC_PSMR(%a2) // CRC32-CCITT preset 0
++ movel #0xDEBB20E3, SCC_C_MASK(%a1)
++ clrl SCC_C_PRES(%a1)
++ movew #HDLC_MAX_MRU + 4, SCC_MFLR(%a1) // 4 bytes for CRC
++ movew #4, parity_bytes(%d0)
++ bra open_port_2
++
++open_port_parity_4:
++ clrw SCC_PSMR(%a2) // no parity
++ movel #0xF0B8, SCC_C_MASK(%a1)
++ movel #0xFFFF, SCC_C_PRES(%a1)
++ movew #HDLC_MAX_MRU, SCC_MFLR(%a1) // 0 bytes for CRC
++ clrw parity_bytes(%d0)
++
++open_port_2:
++ movel #0x00000003, SCC_GSMR_H(%a2) // RTSM
++ cmpl #ENCODING_NRZI, STATUS_ENCODING(%a0)
++ bne open_port_nrz
++ movel #0x10040900, SCC_GSMR_L(%a2) // NRZI: TCI Tend RECN+TENC=1
++ bra open_port_3
++
++open_port_nrz:
++ movel #0x10040000, SCC_GSMR_L(%a2) // NRZ: TCI Tend RECN+TENC=0
++open_port_3:
++ movew #BUFFER_LENGTH, SCC_MRBLR(%a1)
++ movel %d0, %d1
++ lsll #4, %d1 // D1 bits 7 and 6 = port
++ orl #1, %d1
++ movew %d1, CR // Init SCC RX and TX params
++ wait_for_command
++
++ // TCI Tend ENR ENT
++ movew #0x001F, SCC_SCCM(%a2) // TXE RXF BSY TXB RXB interrupts
++ orl #0x00000030, SCC_GSMR_L(%a2) // enable SCC
++open_port_ret:
++ rts
++
++
++/****************************** close port ****************************/
++
++close_port: // D0 = 4 * port, D6 = doorbell to host
++ movel scc_reg_addr(%d0), %a0 // A0 = SCC_REGS address
++ clrw SCC_SCCM(%a0) // no SCC interrupts
++ andl #0xFFFFFFCF, SCC_GSMR_L(%a0) // Disable ENT and ENR
++
++ andw #~STATUS_CABLE_DTR, csr_output(%d0) // DTR off
++ bsr check_csr // call with disabled timer interrupt
++
++ movel ch_status_addr(%d0), %d1
++ clrl STATUS_OPEN(%d1) // confirm the port is closed
++ rts
++
++
++/****************************** transmit packet ***********************/
++// queue packets for transmission
++tx: // D0 = 4 * port, D6 = doorbell to host
++ cmpl #TX_BUFFERS, tx_count(%d0)
++ beq tx_ret // all DB's = descs in use
++
++ movel tx_out(%d0), %d1
++ movel %d1, %d2 // D1 = D2 = tx_out BD# = desc#
++ mulul #DESC_LENGTH, %d2 // D2 = TX desc offset
++ addl ch_status_addr(%d0), %d2
++ addl #STATUS_TX_DESCS, %d2 // D2 = TX desc address
++ cmpl #PACKET_FULL, (%d2) // desc status
++ bne tx_ret
++
++// queue it
++ movel 4(%d2), %a0 // PCI address
++ lsll #3, %d1 // BD is 8-bytes long
++ addl tx_first_bd(%d0), %d1 // D1 = current tx_out BD addr
++
++ movel 4(%d1), %a1 // A1 = dest address
++ movel 8(%d2), %d2 // D2 = length
++ movew %d2, 2(%d1) // length into BD
++ memcpy_from_pci %a0, %a1, %d2
++ bsetl #31, (%d1) // CP go ahead
++
++// update tx_out and tx_count
++ movel tx_out(%d0), %d1
++ addl #1, %d1
++ cmpl #TX_BUFFERS, %d1
++ bne tx_1
++ clrl %d1
++tx_1: movel %d1, tx_out(%d0)
++
++ addl #1, tx_count(%d0)
++ bra tx
++
++tx_ret: rts
++
++
++/****************************** packet received ***********************/
++
++// Service receive buffers // D0 = 4 * port, D6 = doorbell to host
++rx: movel rx_in(%d0), %d1 // D1 = rx_in BD#
++ lsll #3, %d1 // BD is 8-bytes long
++ addl rx_first_bd(%d0), %d1 // D1 = current rx_in BD address
++ movew (%d1), %d2 // D2 = RX BD flags
++ btstl #15, %d2
++ bne rx_ret // BD still empty
++
++ btstl #1, %d2
++ bne rx_overrun
++
++ tstw parity_bytes(%d0)
++ bne rx_parity
++ bclrl #2, %d2 // do not test for CRC errors
++rx_parity:
++ andw #0x0CBC, %d2 // mask status bits
++ cmpw #0x0C00, %d2 // correct frame
++ bne rx_bad_frame
++ clrl %d3
++ movew 2(%d1), %d3
++ subw parity_bytes(%d0), %d3 // D3 = packet length
++ cmpw #HDLC_MAX_MRU, %d3
++ bgt rx_bad_frame
++
++rx_good_frame:
++ movel rx_out, %d2
++ mulul #DESC_LENGTH, %d2
++ addl rx_descs_addr, %d2 // D2 = RX desc address
++ cmpl #PACKET_EMPTY, (%d2) // desc stat
++ bne rx_overrun
++
++ movel %d3, 8(%d2)
++ movel 4(%d1), %a0 // A0 = source address
++ movel 4(%d2), %a1
++ tstl %a1
++ beq rx_ignore_data
++ memcpy_to_pci %a0, %a1, %d3
++rx_ignore_data:
++ movel packet_full(%d0), (%d2) // update desc stat
++
++// update D6 and rx_out
++ bsetl #DOORBELL_FROM_CARD_RX, %d6 // signal host that RX completed
++ movel rx_out, %d2
++ addl #1, %d2
++ cmpl #RX_QUEUE_LENGTH, %d2
++ bne rx_1
++ clrl %d2
++rx_1: movel %d2, rx_out
++
++rx_free_bd:
++ andw #0xF000, (%d1) // clear CM and error bits
++ bsetl #31, (%d1) // free BD
++// update rx_in
++ movel rx_in(%d0), %d1
++ addl #1, %d1
++ cmpl #RX_BUFFERS, %d1
++ bne rx_2
++ clrl %d1
++rx_2: movel %d1, rx_in(%d0)
++ bra rx
++
++rx_overrun:
++ movel ch_status_addr(%d0), %d2
++ addl #1, STATUS_RX_OVERRUNS(%d2)
++ bra rx_free_bd
++
++rx_bad_frame:
++ movel ch_status_addr(%d0), %d2
++ addl #1, STATUS_RX_FRAME_ERRORS(%d2)
++ bra rx_free_bd
++
++rx_ret: rts
++
++
++/****************************** packet transmitted ********************/
++
++// Service transmit buffers // D0 = 4 * port, D6 = doorbell to host
++tx_end: tstl tx_count(%d0)
++ beq tx_end_ret // TX buffers already empty
++
++ movel tx_in(%d0), %d1
++ movel %d1, %d2 // D1 = D2 = tx_in BD# = desc#
++ lsll #3, %d1 // BD is 8-bytes long
++ addl tx_first_bd(%d0), %d1 // D1 = current tx_in BD address
++ movew (%d1), %d3 // D3 = TX BD flags
++ btstl #15, %d3
++ bne tx_end_ret // BD still being transmitted
++
++// update D6, tx_in and tx_count
++ orl bell_tx(%d0), %d6 // signal host that TX desc freed
++ subl #1, tx_count(%d0)
++ movel tx_in(%d0), %d1
++ addl #1, %d1
++ cmpl #TX_BUFFERS, %d1
++ bne tx_end_1
++ clrl %d1
++tx_end_1:
++ movel %d1, tx_in(%d0)
++
++// free host's descriptor
++ mulul #DESC_LENGTH, %d2 // D2 = TX desc offset
++ addl ch_status_addr(%d0), %d2
++ addl #STATUS_TX_DESCS, %d2 // D2 = TX desc address
++ btstl #1, %d3
++ bne tx_end_underrun
++ movel #PACKET_SENT, (%d2)
++ bra tx_end
++
++tx_end_underrun:
++ movel #PACKET_UNDERRUN, (%d2)
++ bra tx_end
++
++tx_end_ret: rts
++
++
++/****************************** PLX PCI9060 DMA memcpy ****************/
++
++#if QUICC_MEMCPY_USES_PLX
++// called with interrupts disabled
++memcpy_from_pci_run:
++ movel %d0, -(%sp)
++ movew %sr, -(%sp)
++memcpy_1:
++ movel PLX_DMA_CMD_STS, %d0 // do not btst PLX register directly
++ btstl #4, %d0 // transfer done?
++ bne memcpy_end
++ stop #0x2200 // enable PCI9060 interrupts
++ movew #0x2700, %sr // disable interrupts again
++ bra memcpy_1
++
++memcpy_to_pci_run:
++ movel %d0, -(%sp)
++ movew %sr, -(%sp)
++memcpy_2:
++ movel PLX_DMA_CMD_STS, %d0 // do not btst PLX register directly
++ btstl #12, %d0 // transfer done?
++ bne memcpy_end
++ stop #0x2200 // enable PCI9060 interrupts
++ movew #0x2700, %sr // disable interrupts again
++ bra memcpy_2
++
++memcpy_end:
++ movew (%sp)+, %sr
++ movel (%sp)+, %d0
++ rts
++#endif
++
++
++
++
++
++
++/****************************** PLX PCI9060 interrupt *****************/
++
++pci9060_interrupt:
++ movel %d0, -(%sp)
++
++ movel PLX_DOORBELL_TO_CARD, %d0
++ movel %d0, PLX_DOORBELL_TO_CARD // confirm all requests
++ orl %d0, channel_stats
++
++ movel #0x0909, PLX_DMA_CMD_STS // clear DMA ch #0 and #1 interrupts
++
++ movel (%sp)+, %d0
++ rte
++
++/****************************** SCC interrupts ************************/
++
++port_interrupt_1:
++ orl #0, SCC1_REGS + SCC_SCCE; // confirm SCC events
++ orl #1 << TASK_SCC_0, channel_stats
++ movel #0x40000000, CISR
++ rte
++
++port_interrupt_2:
++ orl #0, SCC2_REGS + SCC_SCCE; // confirm SCC events
++ orl #1 << TASK_SCC_1, channel_stats
++ movel #0x20000000, CISR
++ rte
++
++port_interrupt_3:
++ orl #0, SCC3_REGS + SCC_SCCE; // confirm SCC events
++ orl #1 << TASK_SCC_2, channel_stats
++ movel #0x10000000, CISR
++ rte
++
++port_interrupt_4:
++ orl #0, SCC4_REGS + SCC_SCCE; // confirm SCC events
++ orl #1 << TASK_SCC_3, channel_stats
++ movel #0x08000000, CISR
++ rte
++
++error_interrupt:
++ rte
++
++
++/****************************** cable and PM routine ******************/
++// modified registers: none
++check_csr:
++ movel %d0, -(%sp)
++ movel %d1, -(%sp)
++ movel %d2, -(%sp)
++ movel %a0, -(%sp)
++ movel %a1, -(%sp)
++
++ clrl %d0 // D0 = 4 * port
++ movel #CSRA, %a0 // A0 = CSR address
++
++check_csr_loop:
++ movew (%a0), %d1 // D1 = CSR input bits
++ andl #0xE7, %d1 // PM and cable sense bits (no DCE bit)
++ cmpw #STATUS_CABLE_V35 * (1 + 1 << STATUS_CABLE_PM_SHIFT), %d1
++ bne check_csr_1
++ movew #0x0E08, %d1
++ bra check_csr_valid
++
++check_csr_1:
++ cmpw #STATUS_CABLE_X21 * (1 + 1 << STATUS_CABLE_PM_SHIFT), %d1
++ bne check_csr_2
++ movew #0x0408, %d1
++ bra check_csr_valid
++
++check_csr_2:
++ cmpw #STATUS_CABLE_V24 * (1 + 1 << STATUS_CABLE_PM_SHIFT), %d1
++ bne check_csr_3
++ movew #0x0208, %d1
++ bra check_csr_valid
++
++check_csr_3:
++ cmpw #STATUS_CABLE_EIA530 * (1 + 1 << STATUS_CABLE_PM_SHIFT), %d1
++ bne check_csr_disable
++ movew #0x0D08, %d1
++ bra check_csr_valid
++
++check_csr_disable:
++ movew #0x0008, %d1 // D1 = disable everything
++ movew #0x80E7, %d2 // D2 = input mask: ignore DSR
++ bra check_csr_write
++
++check_csr_valid: // D1 = mode and IRQ bits
++ movew csr_output(%d0), %d2
++ andw #0x3000, %d2 // D2 = requested LL and DTR bits
++ orw %d2, %d1 // D1 = all requested output bits
++ movew #0x80FF, %d2 // D2 = input mask: include DSR
++
++check_csr_write:
++ cmpw old_csr_output(%d0), %d1
++ beq check_csr_input
++ movew %d1, old_csr_output(%d0)
++ movew %d1, (%a0) // Write CSR output bits
++
++check_csr_input:
++ movew (PCDAT), %d1
++ andw dcd_mask(%d0), %d1
++ beq check_csr_dcd_on // DCD and CTS signals are negated
++ movew (%a0), %d1 // D1 = CSR input bits
++ andw #~STATUS_CABLE_DCD, %d1 // DCD off
++ bra check_csr_previous
++
++check_csr_dcd_on:
++ movew (%a0), %d1 // D1 = CSR input bits
++ orw #STATUS_CABLE_DCD, %d1 // DCD on
++check_csr_previous:
++ andw %d2, %d1 // input mask
++ movel ch_status_addr(%d0), %a1
++ cmpl STATUS_CABLE(%a1), %d1 // check for change
++ beq check_csr_next
++ movel %d1, STATUS_CABLE(%a1) // update status
++ movel bell_cable(%d0), PLX_DOORBELL_FROM_CARD // signal the host
++
++check_csr_next:
++ addl #2, %a0 // next CSR register
++ addl #4, %d0 // D0 = 4 * next port
++ cmpl #4 * 4, %d0
++ bne check_csr_loop
++
++ movel (%sp)+, %a1
++ movel (%sp)+, %a0
++ movel (%sp)+, %d2
++ movel (%sp)+, %d1
++ movel (%sp)+, %d0
++ rts
++
++
++/****************************** timer interrupt ***********************/
++
++timer_interrupt:
++ bsr check_csr
++ rte
++
++
++/****************************** RAM sizing and test *******************/
++#if DETECT_RAM
++ram_test:
++ movel #0x12345678, %d1 // D1 = test value
++ movel %d1, (128 * 1024 - 4)
++ movel #128 * 1024, %d0 // D0 = RAM size tested
++ram_test_size:
++ cmpl #MAX_RAM_SIZE, %d0
++ beq ram_test_size_found
++ movel %d0, %a0
++ addl #128 * 1024 - 4, %a0
++ cmpl (%a0), %d1
++ beq ram_test_size_check
++ram_test_next_size:
++ lsll #1, %d0
++ bra ram_test_size
++
++ram_test_size_check:
++ eorl #0xFFFFFFFF, %d1
++ movel %d1, (128 * 1024 - 4)
++ cmpl (%a0), %d1
++ bne ram_test_next_size
++
++ram_test_size_found: // D0 = RAM size
++ movel %d0, %a0 // A0 = fill ptr
++ subl #firmware_end + 4, %d0
++ lsrl #2, %d0
++ movel %d0, %d1 // D1 = DBf counter
++ram_test_fill:
++ movel %a0, -(%a0)
++ dbfw %d1, ram_test_fill
++ subl #0x10000, %d1
++ cmpl #0xFFFFFFFF, %d1
++ bne ram_test_fill
++
++ram_test_loop: // D0 = DBf counter
++ cmpl (%a0)+, %a0
++ dbnew %d0, ram_test_loop
++ bne ram_test_found_bad
++ subl #0x10000, %d0
++ cmpl #0xFFFFFFFF, %d0
++ bne ram_test_loop
++ bra ram_test_all_ok
++
++ram_test_found_bad:
++ subl #4, %a0
++ram_test_all_ok:
++ movel %a0, PLX_MAILBOX_5
++ rts
++#endif
++
++
++/****************************** constants *****************************/
++
++scc_reg_addr:
++ .long SCC1_REGS, SCC2_REGS, SCC3_REGS, SCC4_REGS
++scc_base_addr:
++ .long SCC1_BASE, SCC2_BASE, SCC3_BASE, SCC4_BASE
++
++tx_first_bd:
++ .long DPRBASE
++ .long DPRBASE + (TX_BUFFERS + RX_BUFFERS) * 8
++ .long DPRBASE + (TX_BUFFERS + RX_BUFFERS) * 8 * 2
++ .long DPRBASE + (TX_BUFFERS + RX_BUFFERS) * 8 * 3
++
++rx_first_bd:
++ .long DPRBASE + TX_BUFFERS * 8
++ .long DPRBASE + TX_BUFFERS * 8 + (TX_BUFFERS + RX_BUFFERS) * 8
++ .long DPRBASE + TX_BUFFERS * 8 + (TX_BUFFERS + RX_BUFFERS) * 8 * 2
++ .long DPRBASE + TX_BUFFERS * 8 + (TX_BUFFERS + RX_BUFFERS) * 8 * 3
++
++first_buffer:
++ .long BUFFERS_ADDR
++ .long BUFFERS_ADDR + (TX_BUFFERS + RX_BUFFERS) * BUFFER_LENGTH
++ .long BUFFERS_ADDR + (TX_BUFFERS + RX_BUFFERS) * BUFFER_LENGTH * 2
++ .long BUFFERS_ADDR + (TX_BUFFERS + RX_BUFFERS) * BUFFER_LENGTH * 3
++
++bell_tx:
++ .long 1 << DOORBELL_FROM_CARD_TX_0, 1 << DOORBELL_FROM_CARD_TX_1
++ .long 1 << DOORBELL_FROM_CARD_TX_2, 1 << DOORBELL_FROM_CARD_TX_3
++
++bell_cable:
++ .long 1 << DOORBELL_FROM_CARD_CABLE_0, 1 << DOORBELL_FROM_CARD_CABLE_1
++ .long 1 << DOORBELL_FROM_CARD_CABLE_2, 1 << DOORBELL_FROM_CARD_CABLE_3
++
++packet_full:
++ .long PACKET_FULL, PACKET_FULL + 1, PACKET_FULL + 2, PACKET_FULL + 3
++
++clocking_ext:
++ .long 0x0000002C, 0x00003E00, 0x002C0000, 0x3E000000
++clocking_txfromrx:
++ .long 0x0000002D, 0x00003F00, 0x002D0000, 0x3F000000
++clocking_mask:
++ .long 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000
++dcd_mask:
++ .word 0x020, 0, 0x080, 0, 0x200, 0, 0x800
++
++ .ascii "wanXL firmware\n"
++ .asciz "Copyright (C) 2003 Krzysztof Halasa <khc@pm.waw.pl>\n"
++
++
++/****************************** variables *****************************/
++
++ .align 4
++channel_stats: .long 0
++
++tx_in: .long 0, 0, 0, 0 // transmitted
++tx_out: .long 0, 0, 0, 0 // received from host for transmission
++tx_count: .long 0, 0, 0, 0 // currently in transmit queue
++
++rx_in: .long 0, 0, 0, 0 // received from port
++rx_out: .long 0 // transmitted to host
++parity_bytes: .word 0, 0, 0, 0, 0, 0, 0 // only 4 words are used
++
++csr_output: .word 0
++old_csr_output: .word 0, 0, 0, 0, 0, 0, 0
++ .align 4
++firmware_end: // must be dword-aligned
+Index: linux-2.6.0-test5/drivers/net/wan/wanxl.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/wanxl.h 2003-09-27 11:38:18.459722080 +0800
++++ linux-2.6.0-test5/drivers/net/wan/wanxl.h 2003-09-27 11:38:28.622177152 +0800
+@@ -0,0 +1,152 @@
++/*
++ * wanXL serial card driver for Linux
++ * definitions common to host driver and card firmware
++ *
++ * Copyright (C) 2003 Krzysztof Halasa <khc@pm.waw.pl>
++ *
++ * 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.
++ */
++
++#define RESET_WHILE_LOADING 0
++
++/* you must rebuild the firmware if any of the following is changed */
++#define DETECT_RAM 0 /* needed for > 4MB RAM, 16 MB maximum */
++#define QUICC_MEMCPY_USES_PLX 1 /* must be used if the host has > 256 MB RAM */
++
++
++#define STATUS_CABLE_V35 2
++#define STATUS_CABLE_X21 3
++#define STATUS_CABLE_V24 4
++#define STATUS_CABLE_EIA530 5
++#define STATUS_CABLE_INVALID 6
++#define STATUS_CABLE_NONE 7
++
++#define STATUS_CABLE_DCE 0x8000
++#define STATUS_CABLE_DSR 0x0010
++#define STATUS_CABLE_DCD 0x0008
++#define STATUS_CABLE_PM_SHIFT 5
++
++#define PDM_OFFSET 0x1000
++
++#define TX_BUFFERS 10 /* per port */
++#define RX_BUFFERS 30
++#define RX_QUEUE_LENGTH 40 /* card->host queue length - per card */
++
++#define PACKET_EMPTY 0x00
++#define PACKET_FULL 0x10
++#define PACKET_SENT 0x20 /* TX only */
++#define PACKET_UNDERRUN 0x30 /* TX only */
++#define PACKET_PORT_MASK 0x03 /* RX only */
++
++/* bit numbers in PLX9060 doorbell registers */
++#define DOORBELL_FROM_CARD_TX_0 0 /* packet sent by the card */
++#define DOORBELL_FROM_CARD_TX_1 1
++#define DOORBELL_FROM_CARD_TX_2 2
++#define DOORBELL_FROM_CARD_TX_3 3
++#define DOORBELL_FROM_CARD_RX 4
++#define DOORBELL_FROM_CARD_CABLE_0 5 /* cable/PM/etc. changed */
++#define DOORBELL_FROM_CARD_CABLE_1 6
++#define DOORBELL_FROM_CARD_CABLE_2 7
++#define DOORBELL_FROM_CARD_CABLE_3 8
++
++#define DOORBELL_TO_CARD_OPEN_0 0
++#define DOORBELL_TO_CARD_OPEN_1 1
++#define DOORBELL_TO_CARD_OPEN_2 2
++#define DOORBELL_TO_CARD_OPEN_3 3
++#define DOORBELL_TO_CARD_CLOSE_0 4
++#define DOORBELL_TO_CARD_CLOSE_1 5
++#define DOORBELL_TO_CARD_CLOSE_2 6
++#define DOORBELL_TO_CARD_CLOSE_3 7
++#define DOORBELL_TO_CARD_TX_0 8 /* outbound packet queued */
++#define DOORBELL_TO_CARD_TX_1 9
++#define DOORBELL_TO_CARD_TX_2 10
++#define DOORBELL_TO_CARD_TX_3 11
++
++/* firmware-only status bits, starting from last DOORBELL_TO_CARD + 1 */
++#define TASK_SCC_0 12
++#define TASK_SCC_1 13
++#define TASK_SCC_2 14
++#define TASK_SCC_3 15
++
++#define ALIGN32(x) (((x) + 3) & 0xFFFFFFFC)
++#define BUFFER_LENGTH ALIGN32(HDLC_MAX_MRU + 4) /* 4 bytes for 32-bit CRC */
++
++/* Address of TX and RX buffers in 68360 address space */
++#define BUFFERS_ADDR 0x4000 /* 16 KB */
++
++#ifndef __ASSEMBLER__
++#define PLX_OFFSET 0
++#else
++#define PLX_OFFSET PLX + 0x80
++#endif
++
++#define PLX_MAILBOX_0 (PLX_OFFSET + 0x40)
++#define PLX_MAILBOX_1 (PLX_OFFSET + 0x44)
++#define PLX_MAILBOX_2 (PLX_OFFSET + 0x48)
++#define PLX_MAILBOX_3 (PLX_OFFSET + 0x4C)
++#define PLX_MAILBOX_4 (PLX_OFFSET + 0x50)
++#define PLX_MAILBOX_5 (PLX_OFFSET + 0x54)
++#define PLX_MAILBOX_6 (PLX_OFFSET + 0x58)
++#define PLX_MAILBOX_7 (PLX_OFFSET + 0x5C)
++#define PLX_DOORBELL_TO_CARD (PLX_OFFSET + 0x60)
++#define PLX_DOORBELL_FROM_CARD (PLX_OFFSET + 0x64)
++#define PLX_INTERRUPT_CS (PLX_OFFSET + 0x68)
++#define PLX_CONTROL (PLX_OFFSET + 0x6C)
++
++#ifdef __ASSEMBLER__
++#define PLX_DMA_0_MODE (PLX + 0x100)
++#define PLX_DMA_0_PCI (PLX + 0x104)
++#define PLX_DMA_0_LOCAL (PLX + 0x108)
++#define PLX_DMA_0_LENGTH (PLX + 0x10C)
++#define PLX_DMA_0_DESC (PLX + 0x110)
++#define PLX_DMA_1_MODE (PLX + 0x114)
++#define PLX_DMA_1_PCI (PLX + 0x118)
++#define PLX_DMA_1_LOCAL (PLX + 0x11C)
++#define PLX_DMA_1_LENGTH (PLX + 0x120)
++#define PLX_DMA_1_DESC (PLX + 0x124)
++#define PLX_DMA_CMD_STS (PLX + 0x128)
++#define PLX_DMA_ARBITR_0 (PLX + 0x12C)
++#define PLX_DMA_ARBITR_1 (PLX + 0x130)
++#endif
++
++#define DESC_LENGTH 12
++
++/* offsets from start of status_t */
++/* card to host */
++#define STATUS_OPEN 0
++#define STATUS_CABLE (STATUS_OPEN + 4)
++#define STATUS_RX_OVERRUNS (STATUS_CABLE + 4)
++#define STATUS_RX_FRAME_ERRORS (STATUS_RX_OVERRUNS + 4)
++
++/* host to card */
++#define STATUS_PARITY (STATUS_RX_FRAME_ERRORS + 4)
++#define STATUS_ENCODING (STATUS_PARITY + 4)
++#define STATUS_CLOCKING (STATUS_ENCODING + 4)
++#define STATUS_TX_DESCS (STATUS_CLOCKING + 4)
++
++#ifndef __ASSEMBLER__
++
++typedef struct {
++ volatile u32 stat;
++ u32 address; /* PCI address */
++ volatile u32 length;
++}desc_t;
++
++
++typedef struct {
++// Card to host
++ volatile u32 open;
++ volatile u32 cable;
++ volatile u32 rx_overruns;
++ volatile u32 rx_frame_errors;
++
++// Host to card
++ u32 parity;
++ u32 encoding;
++ u32 clocking;
++ desc_t tx_descs[TX_BUFFERS];
++}port_status_t;
++
++#endif /* __ASSEMBLER__ */
+Index: linux-2.6.0-test5/drivers/net/wd.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wd.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wd.c 2003-09-27 11:38:28.627176392 +0800
+@@ -235,7 +235,7 @@
+ int reg4 = inb(ioaddr+4);
+ if (ancient || reg1 == 0xff) { /* Ack!! No way to read the IRQ! */
+ short nic_addr = ioaddr+WD_NIC_OFFSET;
+- unsigned long irq_mask, delay;
++ unsigned long irq_mask;
+
+ /* We have an old-style ethercard that doesn't report its IRQ
+ line. Do autoirq to find the IRQ line. Note that this IS NOT
+@@ -248,8 +248,7 @@
+ outb_p(0x00, nic_addr + EN0_RCNTLO);
+ outb_p(0x00, nic_addr + EN0_RCNTHI);
+ outb(E8390_RREAD+E8390_START, nic_addr); /* Trigger it... */
+- delay = jiffies + HZ/50;
+- while (time_before(jiffies, delay)) ;
++ mdelay(20);
+ dev->irq = probe_irq_off(irq_mask);
+
+ outb_p(0x00, nic_addr+EN0_IMR); /* Mask all intrs. again. */
+Index: linux-2.6.0-test5/drivers/net/wireless/airo.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wireless/airo.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wireless/airo.c 2003-09-27 11:38:28.682168032 +0800
+@@ -18,7 +18,6 @@
+ ======================================================================*/
+
+ #include <linux/config.h>
+-#include <linux/version.h>
+ #include <linux/init.h>
+
+ #include <linux/kernel.h>
+@@ -42,7 +41,6 @@
+ #include <linux/skbuff.h>
+ #include <linux/if_arp.h>
+ #include <linux/ioport.h>
+-#include <linux/config.h>
+ #include <linux/pci.h>
+ #include <asm/uaccess.h>
+
+@@ -1435,7 +1433,7 @@
+
+ int i,j;
+ u32 counter;
+- u8 *cipher;
++ u8 *cipher, plain[16];
+ struct scatterlist sg[1];
+
+ crypto_cipher_setkey(tfm, pkey, 16);
+@@ -1446,8 +1444,9 @@
+ aes_counter[13] = (u8)(counter >> 16);
+ aes_counter[12] = (u8)(counter >> 24);
+ counter++;
+- sg[0].page = virt_to_page(aes_counter);
+- sg[0].offset = ((long) aes_counter & ~PAGE_MASK);
++ memcpy (plain, aes_counter, 16);
++ sg[0].page = virt_to_page(plain);
++ sg[0].offset = ((long) plain & ~PAGE_MASK);
+ sg[0].length = 16;
+ crypto_cipher_encrypt(tfm, sg, sg, 16);
+ cipher = kmap(sg[0].page) + sg[0].offset;
+@@ -4624,7 +4623,7 @@
+ return -ENODEV;
+
+ pci_set_drvdata(pdev, dev);
+- clear_bit (FLAG_PCI, &((struct airo_info *)dev->priv)->flags);
++ set_bit (FLAG_PCI, &((struct airo_info *)dev->priv)->flags);
+ return 0;
+ }
+
+Index: linux-2.6.0-test5/drivers/net/wireless/airo_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wireless/airo_cs.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wireless/airo_cs.c 2003-09-27 11:38:28.689166968 +0800
+@@ -163,24 +163,6 @@
+
+ /*======================================================================
+
+- This bit of code is used to avoid unregistering network devices
+- at inappropriate times. 2.2 and later kernels are fairly picky
+- about when this can happen.
+-
+- ======================================================================*/
+-
+-static void flush_stale_links(void)
+-{
+- dev_link_t *link, *next;
+- for (link = dev_list; link; link = next) {
+- next = link->next;
+- if (link->state & DEV_STALE_LINK)
+- airo_detach(link);
+- }
+-}
+-
+-/*======================================================================
+-
+ airo_attach() creates an "instance" of the driver, allocating
+ local data structures for one device. The device is registered
+ with Card Services.
+@@ -199,8 +181,7 @@
+ int ret, i;
+
+ DEBUG(0, "airo_attach()\n");
+- flush_stale_links();
+-
++
+ /* Initialize the dev_link_t structure */
+ link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
+ if (!link) {
+@@ -285,10 +266,8 @@
+
+ if (link->state & DEV_CONFIG) {
+ airo_release(link);
+- if (link->state & DEV_STALE_CONFIG) {
+- link->state |= DEV_STALE_LINK;
++ if (link->state & DEV_STALE_CONFIG)
+ return;
+- }
+ }
+
+ if ( ((local_info_t*)link->priv)->eth_dev ) {
+@@ -554,8 +533,10 @@
+ if (link->irq.AssignedIRQ)
+ CardServices(ReleaseIRQ, link->handle, &link->irq);
+ link->state &= ~DEV_CONFIG;
+-
+-} /* airo_release */
++
++ if (link->state & DEV_STALE_CONFIG)
++ airo_detach(link);
++}
+
+ /*======================================================================
+
+Index: linux-2.6.0-test5/drivers/net/wireless/arlan.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wireless/arlan.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wireless/arlan.c 2003-09-27 11:38:28.705164536 +0800
+@@ -5,6 +5,7 @@
+ * This module provides support for the Arlan 655 card made by Aironet
+ */
+
++#include <linux/version.h>
+ #include <linux/config.h>
+ #include "arlan.h"
+
+Index: linux-2.6.0-test5/drivers/net/wireless/arlan.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wireless/arlan.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wireless/arlan.h 2003-09-27 11:38:28.710163776 +0800
+@@ -3,7 +3,6 @@
+ * Copyright (C) 1998 Elmer.Joandi@ut.ee, +37-255-13500
+ * GNU General Public License applies
+ */
+-#include <linux/version.h>
+
+ #include <linux/module.h>
+ #include <linux/config.h>
+Index: linux-2.6.0-test5/drivers/net/wireless/arlan-proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wireless/arlan-proc.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wireless/arlan-proc.c 2003-09-27 11:38:28.718162560 +0800
+@@ -5,9 +5,6 @@
+
+ #ifdef CONFIG_PROC_FS
+
+-
+-#include <linux/version.h>
+-
+ /* void enableReceive(struct net_device* dev);
+ */
+
+Index: linux-2.6.0-test5/drivers/net/wireless/atmel_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wireless/atmel_cs.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wireless/atmel_cs.c 2003-09-27 11:38:28.736159824 +0800
+@@ -176,24 +176,6 @@
+
+ /*======================================================================
+
+- This bit of code is used to avoid unregistering network devices
+- at inappropriate times. 2.2 and later kernels are fairly picky
+- about when this can happen.
+-
+- ======================================================================*/
+-
+-static void flush_stale_links(void)
+-{
+- dev_link_t *link, *next;
+- for (link = dev_list; link; link = next) {
+- next = link->next;
+- if (link->state & DEV_STALE_LINK)
+- atmel_detach(link);
+- }
+-}
+-
+-/*======================================================================
+-
+ atmel_attach() creates an "instance" of the driver, allocating
+ local data structures for one device. The device is registered
+ with Card Services.
+@@ -212,8 +194,7 @@
+ int ret, i;
+
+ DEBUG(0, "atmel_attach()\n");
+- flush_stale_links();
+-
++
+ /* Initialize the dev_link_t structure */
+ link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
+ if (!link) {
+@@ -296,29 +277,19 @@
+ if (*linkp == NULL)
+ return;
+
+- if ( link->state & DEV_CONFIG ) {
++ if (link->state & DEV_CONFIG)
+ atmel_release(link);
+- if ( link->state & DEV_STALE_CONFIG ) {
+- link->state |= DEV_STALE_LINK;
+- return;
+- }
+- }
+-
+
+ /* Break the link with Card Services */
+ if (link->handle)
+ CardServices(DeregisterClient, link->handle);
+-
+-
+-
++
+ /* Unlink device structure, free pieces */
+ *linkp = link->next;
+- if (link->priv) {
++ if (link->priv)
+ kfree(link->priv);
+- }
+ kfree(link);
+-
+-} /* atmel_detach */
++}
+
+ /*======================================================================
+
+Index: linux-2.6.0-test5/drivers/net/wireless/netwave_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wireless/netwave_cs.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wireless/netwave_cs.c 2003-09-27 11:38:28.751157544 +0800
+@@ -211,7 +211,6 @@
+ insertion */
+ static dev_link_t *netwave_attach(void); /* Create instance */
+ static void netwave_detach(dev_link_t *); /* Destroy instance */
+-static void netwave_flush_stale_links(void); /* Destroy all staled instances */
+
+ /* Hardware configuration */
+ static void netwave_doreset(ioaddr_t iobase, u_char* ramBase);
+@@ -444,9 +443,6 @@
+
+ DEBUG(0, "netwave_attach()\n");
+
+- /* Perform some cleanup */
+- netwave_flush_stale_links();
+-
+ /* Initialize the dev_link_t structure */
+ dev = alloc_etherdev(sizeof(netwave_private));
+ if (!dev)
+@@ -553,7 +549,6 @@
+ if (link->state & DEV_STALE_CONFIG) {
+ DEBUG(1, "netwave_cs: detach postponed, '%s' still "
+ "locked\n", link->dev->dev_name);
+- link->state |= DEV_STALE_LINK;
+ return;
+ }
+ }
+@@ -581,31 +576,6 @@
+ } /* netwave_detach */
+
+ /*
+- * Function netwave_flush_stale_links (void)
+- *
+- * This deletes all driver "instances" that need to be deleted.
+- * Sometimes, netwave_detach can't be performed following a call from
+- * cardmgr (device still open) and the device is put in a STALE_LINK
+- * state.
+- * This function is in charge of making the cleanup...
+- */
+-static void netwave_flush_stale_links(void)
+-{
+- dev_link_t * link; /* Current node in linked list */
+- dev_link_t * next; /* Next node in linked list */
+-
+- DEBUG(1, "netwave_flush_stale_links(0x%p)\n", dev_list);
+-
+- /* Go through the list */
+- for (link = dev_list; link; link = next) {
+- next = link->next;
+- /* Check if in need of being removed */
+- if(link->state & DEV_STALE_LINK)
+- netwave_detach(link);
+- }
+-} /* netwave_flush_stale_links */
+-
+-/*
+ * Wireless Handler : get protocol name
+ */
+ static int netwave_get_name(struct net_device *dev,
+@@ -1181,9 +1151,11 @@
+ CardServices(ReleaseIO, link->handle, &link->io);
+ CardServices(ReleaseIRQ, link->handle, &link->irq);
+
+- link->state &= ~(DEV_CONFIG | DEV_STALE_CONFIG);
++ link->state &= ~DEV_CONFIG;
+
+-} /* netwave_release */
++ if (link->state & DEV_STALE_CONFIG)
++ netwave_detach(link);
++}
+
+ /*
+ * Function netwave_event (event, priority, args)
+@@ -1755,8 +1727,6 @@
+ {
+ pcmcia_unregister_driver(&netwave_driver);
+
+- /* Do some cleanup of the device list */
+- netwave_flush_stale_links();
+ if (dev_list != NULL) /* Critical situation */
+ printk("netwave_cs: devices remaining when removing module\n");
+ }
+Index: linux-2.6.0-test5/drivers/net/wireless/orinoco_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wireless/orinoco_cs.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wireless/orinoco_cs.c 2003-09-27 11:38:28.757156632 +0800
+@@ -153,24 +153,6 @@
+ CardServices(ReportError, handle, &err);
+ }
+
+-
+-/* Remove zombie instances (card removed, detach pending) */
+-static void
+-flush_stale_links(void)
+-{
+- dev_link_t *link, *next;
+-
+- TRACE_ENTER("");
+-
+- for (link = dev_list; link; link = next) {
+- next = link->next;
+- if (link->state & DEV_STALE_LINK) {
+- orinoco_cs_detach(link);
+- }
+- }
+- TRACE_EXIT("");
+-}
+-
+ /*
+ * This creates an "instance" of the driver, allocating local data
+ * structures for one device. The device is registered with Card
+@@ -189,9 +171,6 @@
+ client_reg_t client_reg;
+ int ret, i;
+
+- /* A bit of cleanup */
+- flush_stale_links();
+-
+ dev = alloc_orinocodev(sizeof(*card), orinoco_cs_hard_reset);
+ if (! dev)
+ return NULL;
+@@ -266,13 +245,8 @@
+ return;
+ }
+
+- if (link->state & DEV_CONFIG) {
++ if (link->state & DEV_CONFIG)
+ orinoco_cs_release(link);
+- if (link->state & DEV_CONFIG) {
+- link->state |= DEV_STALE_LINK;
+- return;
+- }
+- }
+
+ /* Break the link with Card Services */
+ if (link->handle)
+Index: linux-2.6.0-test5/drivers/net/wireless/ray_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wireless/ray_cs.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wireless/ray_cs.c 2003-09-27 11:38:28.783152680 +0800
+@@ -138,7 +138,7 @@
+ static void verify_dl_startup(u_long);
+
+ /* Prototypes for interrpt time functions **********************************/
+-static void ray_interrupt (int reg, void *dev_id, struct pt_regs *regs);
++static irqreturn_t ray_interrupt (int reg, void *dev_id, struct pt_regs *regs);
+ static void clear_interrupt(ray_dev_t *local);
+ static void rx_deauthenticate(ray_dev_t *local, struct rcs *prcs,
+ unsigned int pkt_addr, int rx_len);
+@@ -319,24 +319,6 @@
+
+ static char rcsid[] = "Raylink/WebGear wireless LAN - Corey <Thomas corey@world.std.com>";
+
+-/*======================================================================
+-
+- This bit of code is used to avoid unregistering network devices
+- at inappropriate times. 2.2 and later kernels are fairly picky
+- about when this can happen.
+-
+-======================================================================*/
+-
+-static void flush_stale_links(void)
+-{
+- dev_link_t *link, *next;
+- for (link = dev_list; link; link = next) {
+- next = link->next;
+- if (link->state & DEV_STALE_LINK)
+- ray_detach(link);
+- }
+-}
+-
+ /*=============================================================================
+ ray_attach() creates an "instance" of the driver, allocating
+ local data structures for one device. The device is registered
+@@ -354,7 +336,6 @@
+ struct net_device *dev;
+
+ DEBUG(1, "ray_attach()\n");
+- flush_stale_links();
+
+ /* Initialize the dev_link_t structure */
+ link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
+@@ -484,10 +465,8 @@
+ */
+ if (link->state & DEV_CONFIG) {
+ ray_release(link);
+- if(link->state & DEV_STALE_CONFIG) {
+- link->state |= DEV_STALE_LINK;
++ if(link->state & DEV_STALE_CONFIG)
+ return;
+- }
+ }
+
+ /* Break the link with Card Services */
+@@ -932,7 +911,11 @@
+ if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseIRQ ret = %x\n",i);
+
+ DEBUG(2,"ray_release ending\n");
+-} /* ray_release */
++
++ if (link->state & DEV_STALE_CONFIG)
++ ray_detach(link);
++}
++
+ /*=============================================================================
+ The card status event handler. Mostly, this schedules other
+ stuff to run after an event is received. A CARD_REMOVAL event
+@@ -2050,7 +2033,7 @@
+ /*=============================================================================
+ * All routines below here are run at interrupt time.
+ =============================================================================*/
+-static void ray_interrupt(int irq, void *dev_id, struct pt_regs * regs)
++static irqreturn_t ray_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+ {
+ struct net_device *dev = (struct net_device *)dev_id;
+ dev_link_t *link;
+@@ -2063,7 +2046,7 @@
+ UCHAR status;
+
+ if (dev == NULL) /* Note that we want interrupts with dev->start == 0 */
+- return;
++ return IRQ_NONE;
+
+ DEBUG(4,"ray_cs: interrupt for *dev=%p\n",dev);
+
+@@ -2071,7 +2054,7 @@
+ link = (dev_link_t *)local->finder;
+ if ( ! (link->state & DEV_PRESENT) || link->state & DEV_SUSPEND ) {
+ DEBUG(2,"ray_cs interrupt from device not present or suspended.\n");
+- return;
++ return IRQ_NONE;
+ }
+ rcsindex = readb(&((struct scb *)(local->sram))->rcs_index);
+
+@@ -2079,7 +2062,7 @@
+ {
+ DEBUG(1,"ray_cs interrupt bad rcsindex = 0x%x\n",rcsindex);
+ clear_interrupt(local);
+- return;
++ return IRQ_HANDLED;
+ }
+ if (rcsindex < NUMBER_OF_CCS) /* If it's a returned CCS */
+ {
+@@ -2235,6 +2218,7 @@
+ writeb(CCS_BUFFER_FREE, &prcs->buffer_status);
+ }
+ clear_interrupt(local);
++ return IRQ_HANDLED;
+ } /* ray_interrupt */
+ /*===========================================================================*/
+ static void ray_rx(struct net_device *dev, ray_dev_t *local, struct rcs *prcs)
+Index: linux-2.6.0-test5/drivers/net/wireless/strip.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wireless/strip.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wireless/strip.c 2003-09-27 11:38:28.805149336 +0800
+@@ -83,7 +83,6 @@
+
+ #include <linux/config.h>
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/init.h>
+ #include <asm/system.h>
+ #include <asm/uaccess.h>
+@@ -965,8 +964,6 @@
+ return (buffer);
+ }
+
+-#define STRIP_PROC_HEADER ((void *)1)
+-
+ /* get Nth element of the linked list */
+ static struct strip *strip_get_idx(loff_t pos)
+ {
+@@ -984,7 +981,7 @@
+ static void *strip_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+ rcu_read_lock();
+- return *pos ? strip_get_idx(*pos - 1) : STRIP_PROC_HEADER;
++ return *pos ? strip_get_idx(*pos - 1) : SEQ_START_TOKEN;
+ }
+
+ static void *strip_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -993,7 +990,7 @@
+ struct strip *s;
+
+ ++*pos;
+- if (v == STRIP_PROC_HEADER)
++ if (v == SEQ_START_TOKEN)
+ return strip_get_idx(1);
+
+ s = v;
+@@ -1149,7 +1146,7 @@
+ */
+ static int strip_seq_show(struct seq_file *seq, void *v)
+ {
+- if (v == STRIP_PROC_HEADER)
++ if (v == SEQ_START_TOKEN)
+ seq_printf(seq, "strip_version: %s\n", StripVersion);
+ else
+ strip_seq_status_info(seq, (const struct strip *)v);
+Index: linux-2.6.0-test5/drivers/net/wireless/wavelan_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wireless/wavelan_cs.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wireless/wavelan_cs.c 2003-09-27 11:38:28.841143864 +0800
+@@ -4175,50 +4175,14 @@
+ CardServices(ReleaseIO, link->handle, &link->io);
+ CardServices(ReleaseIRQ, link->handle, &link->irq);
+
+- link->state &= ~(DEV_CONFIG | DEV_STALE_CONFIG);
++ link->state &= ~DEV_CONFIG;
+
+ #ifdef DEBUG_CONFIG_TRACE
+ printk(KERN_DEBUG "%s: <- wv_pcmcia_release()\n", dev->name);
+ #endif
+-} /* wv_pcmcia_release */
+
+-/*------------------------------------------------------------------*/
+-/*
+- * Sometimes, wavelan_detach can't be performed following a call from
+- * cardmgr (device still open, pcmcia_release not done) and the device
+- * is put in a STALE_LINK state and remains in memory.
+- *
+- * This function run through our current list of device and attempt
+- * another time to remove them. We hope that since last time the
+- * device has properly been closed.
+- *
+- * (called by wavelan_attach() & cleanup_module())
+- */
+-static void
+-wv_flush_stale_links(void)
+-{
+- dev_link_t * link; /* Current node in linked list */
+- dev_link_t * next; /* Next node in linked list */
+-
+-#ifdef DEBUG_CONFIG_TRACE
+- printk(KERN_DEBUG "-> wv_flush_stale_links(0x%p)\n", dev_list);
+-#endif
+-
+- /* Go through the list */
+- for (link = dev_list; link; link = next)
+- {
+- next = link->next;
+-
+- /* Check if in need of being removed */
+- if((link->state & DEV_STALE_LINK) ||
+- (! (link->state & DEV_PRESENT)))
+- wavelan_detach(link);
+-
+- }
+-
+-#ifdef DEBUG_CONFIG_TRACE
+- printk(KERN_DEBUG "<- wv_flush_stale_links()\n");
+-#endif
++ if (link->state & DEV_STALE_CONFIG)
++ wavelan_detach(link);
+ }
+
+ /************************ INTERRUPT HANDLING ************************/
+@@ -4705,9 +4669,6 @@
+ printk(KERN_DEBUG "-> wavelan_attach()\n");
+ #endif
+
+- /* Perform some cleanup */
+- wv_flush_stale_links();
+-
+ /* Initialize the dev_link_t structure */
+ link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
+ if (!link) return NULL;
+@@ -4859,7 +4820,6 @@
+ printk(KERN_DEBUG "wavelan_detach: detach postponed,"
+ " '%s' still locked\n", link->dev->dev_name);
+ #endif
+- link->state |= DEV_STALE_LINK;
+ return;
+ }
+ }
+@@ -5039,9 +4999,6 @@
+ static void __exit
+ exit_wavelan_cs(void)
+ {
+- /* Do some cleanup of the device list */
+- wv_flush_stale_links();
+-
+ pcmcia_unregister_driver(&wavelan_driver);
+ }
+
+Index: linux-2.6.0-test5/drivers/net/wireless/wavelan_cs.p.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wireless/wavelan_cs.p.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wireless/wavelan_cs.p.h 2003-09-27 11:38:28.849142648 +0800
+@@ -761,8 +761,7 @@
+ static inline int
+ wv_pcmcia_config(dev_link_t *); /* Configure the pcmcia interface */
+ static void
+- wv_pcmcia_release(dev_link_t *),/* Remove a device */
+- wv_flush_stale_links(void); /* "detach" all possible devices */
++ wv_pcmcia_release(dev_link_t *);/* Remove a device */
+ /* ---------------------- INTERRUPT HANDLING ---------------------- */
+ static irqreturn_t
+ wavelan_interrupt(int, /* Interrupt handler */
+Index: linux-2.6.0-test5/drivers/net/wireless/wl3501_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wireless/wl3501_cs.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wireless/wl3501_cs.c 2003-09-27 11:38:28.867139912 +0800
+@@ -82,7 +82,7 @@
+ MODULE_PARM(pc_debug, "i");
+ #define dprintk(n, format, args...) \
+ { if (pc_debug > (n)) \
+- printk(KERN_INFO "%s: " format "\n", __FUNCTION__, ##args); }
++ printk(KERN_INFO "%s: " format "\n", __FUNCTION__ , ##args); }
+ #else
+ #define dprintk(n, format, args...)
+ #endif
+@@ -638,8 +638,10 @@
+ .sig_id = WL3501_SIG_JOIN_REQ,
+ .timeout = 10,
+ .ds_pset = {
+- .el.id = IW_MGMT_INFO_ELEMENT_DS_PARAMETER_SET,
+- .el.len = 1,
++ .el = {
++ .id = IW_MGMT_INFO_ELEMENT_DS_PARAMETER_SET,
++ .len = 1,
++ },
+ .chan = this->chan,
+ },
+ };
+@@ -655,13 +657,17 @@
+ .beacon_period = 400,
+ .dtim_period = 1,
+ .ds_pset = {
+- .el.id = IW_MGMT_INFO_ELEMENT_DS_PARAMETER_SET,
+- .el.len = 1,
++ .el = {
++ .id = IW_MGMT_INFO_ELEMENT_DS_PARAMETER_SET,
++ .len = 1,
++ },
+ .chan = this->chan,
+ },
+ .bss_basic_rset = {
+- .el.id = IW_MGMT_INFO_ELEMENT_SUPPORTED_RATES,
+- .el.len = 2,
++ .el = {
++ .id = IW_MGMT_INFO_ELEMENT_SUPPORTED_RATES,
++ .len = 2,
++ },
+ .data_rate_labels = {
+ [0] = IW_MGMT_RATE_LABEL_MANDATORY |
+ IW_MGMT_RATE_LABEL_1MBIT,
+@@ -670,8 +676,10 @@
+ },
+ },
+ .operational_rset = {
+- .el.id = IW_MGMT_INFO_ELEMENT_SUPPORTED_RATES,
+- .el.len = 2,
++ .el = {
++ .id = IW_MGMT_INFO_ELEMENT_SUPPORTED_RATES,
++ .len = 2,
++ },
+ .data_rate_labels = {
+ [0] = IW_MGMT_RATE_LABEL_MANDATORY |
+ IW_MGMT_RATE_LABEL_1MBIT,
+@@ -680,8 +688,10 @@
+ },
+ },
+ .ibss_pset = {
+- .el.id = IW_MGMT_INFO_ELEMENT_IBSS_PARAMETER_SET,
+- .el.len = 2,
++ .el = {
++ .id = IW_MGMT_INFO_ELEMENT_IBSS_PARAMETER_SET,
++ .len = 2,
++ },
+ .atim_window = 10,
+ },
+ .bss_type = wl3501_fw_bss_type(this),
+@@ -1571,7 +1581,6 @@
+ printk(KERN_DEBUG "wl3501_cs: detach postponed, '%s' "
+ "still locked\n", link->dev->dev_name);
+ #endif
+- link->state |= DEV_STALE_LINK;
+ goto out;
+ }
+
+@@ -1589,22 +1598,6 @@
+ return;
+ }
+
+-/**
+- * wl3501_flush_stale_links - Remove zombie instances
+- *
+- * Remove zombie instances (card removed, detach pending)
+- */
+-static void wl3501_flush_stale_links(void)
+-{
+- dev_link_t *link, *next;
+-
+- for (link = wl3501_dev_list; link; link = next) {
+- next = link->next;
+- if (link->state & DEV_STALE_LINK)
+- wl3501_detach(link);
+- }
+-}
+-
+ static int wl3501_get_name(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+ {
+@@ -2033,8 +2026,6 @@
+ struct net_device *dev;
+ int ret, i;
+
+- wl3501_flush_stale_links();
+-
+ /* Initialize the dev_link_t structure */
+ link = kmalloc(sizeof(*link), GFP_KERNEL);
+ if (!link)
+@@ -2263,7 +2254,7 @@
+ CardServices(ReleaseIRQ, link->handle, &link->irq);
+ link->state &= ~DEV_CONFIG;
+
+- if (link->state & DEV_STALE_LINK)
++ if (link->state & DEV_STALE_CONFIG)
+ wl3501_detach(link);
+ out:
+ return;
+Index: linux-2.6.0-test5/drivers/parisc/asp.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/parisc/asp.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/parisc/asp.c 2003-09-27 11:38:28.869139608 +0800
+@@ -76,8 +76,6 @@
+
+ printk(KERN_INFO "%s version %d at 0x%lx found.\n",
+ asp->name, asp->version, dev->hpa);
+- snprintf(dev->dev.name, sizeof(dev->dev.name), "%s version %d",
+- asp->name, asp->version);
+
+ /* the IRQ ASP should use */
+ ret = -EBUSY;
+Index: linux-2.6.0-test5/drivers/parisc/ccio-dma.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/parisc/ccio-dma.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/parisc/ccio-dma.c 2003-09-27 11:38:28.881137784 +0800
+@@ -129,6 +129,92 @@
+ volatile uint32_t io_io_high; /* Offset 15 */
+ };
+
++/*
++** IOA Registers
++** -------------
++**
++** Runway IO_CONTROL Register (+0x38)
++**
++** The Runway IO_CONTROL register controls the forwarding of transactions.
++**
++** | 0 ... 13 | 14 15 | 16 ... 21 | 22 | 23 24 | 25 ... 31 |
++** | HV | TLB | reserved | HV | mode | reserved |
++**
++** o mode field indicates the address translation of transactions
++** forwarded from Runway to GSC+:
++** Mode Name Value Definition
++** Off (default) 0 Opaque to matching addresses.
++** Include 1 Transparent for matching addresses.
++** Peek 3 Map matching addresses.
++**
++** + "Off" mode: Runway transactions which match the I/O range
++** specified by the IO_IO_LOW/IO_IO_HIGH registers will be ignored.
++** + "Include" mode: all addresses within the I/O range specified
++** by the IO_IO_LOW and IO_IO_HIGH registers are transparently
++** forwarded. This is the I/O Adapter's normal operating mode.
++** + "Peek" mode: used during system configuration to initialize the
++** GSC+ bus. Runway Write_Shorts in the address range specified by
++** IO_IO_LOW and IO_IO_HIGH are forwarded through the I/O Adapter
++** *AND* the GSC+ address is remapped to the Broadcast Physical
++** Address space by setting the 14 high order address bits of the
++** 32 bit GSC+ address to ones.
++**
++** o TLB field affects transactions which are forwarded from GSC+ to Runway.
++** "Real" mode is the poweron default.
++**
++** TLB Mode Value Description
++** Real 0 No TLB translation. Address is directly mapped and the
++** virtual address is composed of selected physical bits.
++** Error 1 Software fills the TLB manually.
++** Normal 2 IOA fetches IO TLB misses from IO PDIR (in host memory).
++**
++**
++** IO_IO_LOW_HV +0x60 (HV dependent)
++** IO_IO_HIGH_HV +0x64 (HV dependent)
++** IO_IO_LOW +0x78 (Architected register)
++** IO_IO_HIGH +0x7c (Architected register)
++**
++** IO_IO_LOW and IO_IO_HIGH set the lower and upper bounds of the
++** I/O Adapter address space, respectively.
++**
++** 0 ... 7 | 8 ... 15 | 16 ... 31 |
++** 11111111 | 11111111 | address |
++**
++** Each LOW/HIGH pair describes a disjoint address space region.
++** (2 per GSC+ port). Each incoming Runway transaction address is compared
++** with both sets of LOW/HIGH registers. If the address is in the range
++** greater than or equal to IO_IO_LOW and less than IO_IO_HIGH the transaction
++** for forwarded to the respective GSC+ bus.
++** Specify IO_IO_LOW equal to or greater than IO_IO_HIGH to avoid specifying
++** an address space region.
++**
++** In order for a Runway address to reside within GSC+ extended address space:
++** Runway Address [0:7] must identically compare to 8'b11111111
++** Runway Address [8:11] must be equal to IO_IO_LOW(_HV)[16:19]
++** Runway Address [12:23] must be greater than or equal to
++** IO_IO_LOW(_HV)[20:31] and less than IO_IO_HIGH(_HV)[20:31].
++** Runway Address [24:39] is not used in the comparison.
++**
++** When the Runway transaction is forwarded to GSC+, the GSC+ address is
++** as follows:
++** GSC+ Address[0:3] 4'b1111
++** GSC+ Address[4:29] Runway Address[12:37]
++** GSC+ Address[30:31] 2'b00
++**
++** All 4 Low/High registers must be initialized (by PDC) once the lower bus
++** is interrogated and address space is defined. The operating system will
++** modify the architectural IO_IO_LOW and IO_IO_HIGH registers following
++** the PDC initialization. However, the hardware version dependent IO_IO_LOW
++** and IO_IO_HIGH registers should not be subsequently altered by the OS.
++**
++** Writes to both sets of registers will take effect immediately, bypassing
++** the queues, which ensures that subsequent Runway transactions are checked
++** against the updated bounds values. However reads are queued, introducing
++** the possibility of a read being bypassed by a subsequent write to the same
++** register. This sequence can be avoided by having software wait for read
++** returns before issuing subsequent writes.
++*/
++
+ struct ioc {
+ struct ioa_registers *ioc_hpa; /* I/O MMU base address */
+ u8 *res_map; /* resource map, bit == pdir entry */
+@@ -1448,13 +1534,74 @@
+ (unsigned long)&ioc->ioc_hpa->io_io_low_hv);
+ }
+
+-static void expand_ioc_area(struct ioc *ioc, unsigned long size,
+- unsigned long min, unsigned long max, unsigned long align)
++static int expand_resource(struct resource *res, unsigned long size,
++ unsigned long align)
+ {
+-#ifdef NASTY_HACK_FOR_K_CLASS
+- __raw_writel(0xfffff600, (unsigned long)&(ioc->ioc_hpa->io_io_high));
+- ioc->mmio_region[0].end = 0xf5ffffff;
+-#endif
++ struct resource *temp_res;
++ unsigned long start = res->start;
++ unsigned long end ;
++
++ /* see if we can expand above */
++ end = (res->end + size + align - 1) & ~(align - 1);;
++
++ temp_res = __request_region(res->parent, res->end, end - res->end,
++ "expansion");
++ if(!temp_res) {
++ /* now try below */
++ start = ((res->start - size + align) & ~(align - 1)) - align;
++ end = res->end;
++ temp_res = __request_region(res->parent, start, size,
++ "expansion");
++ if(!temp_res) {
++ return -ENOMEM;
++ }
++ }
++ release_resource(temp_res);
++ temp_res = res->parent;
++ release_resource(res);
++ res->start = start;
++ res->end = end;
++
++ /* This could be caused by some sort of race. Basically, if
++ * this tripped something stole the region we just reserved
++ * and then released to check for expansion */
++ BUG_ON(request_resource(temp_res, res) != 0);
++
++ return 0;
++}
++
++static void expand_ioc_area(struct resource *parent, struct ioc *ioc,
++ unsigned long size, unsigned long min,
++ unsigned long max, unsigned long align)
++{
++ if(ioc == NULL)
++ /* no IOC, so nothing to expand */
++ return;
++
++ if (expand_resource(parent, size, align) != 0) {
++ printk(KERN_ERR "Unable to expand %s window by 0x%lx\n",
++ parent->name, size);
++ return;
++ }
++
++ /* OK, we have the memory, now expand the window */
++ if (parent == &ioc->mmio_region[0]) {
++ __raw_writel(((parent->start)>>16) | 0xffff0000,
++ (unsigned long)&(ioc->ioc_hpa->io_io_low));
++ __raw_writel(((parent->end)>>16) | 0xffff0000,
++ (unsigned long)&(ioc->ioc_hpa->io_io_high));
++ } else if (parent == &ioc->mmio_region[1]) {
++ __raw_writel(((parent->start)>>16) | 0xffff0000,
++ (unsigned long)&(ioc->ioc_hpa->io_io_low_hv));
++ __raw_writel(((parent->end)>>16) | 0xffff0000,
++ (unsigned long)&(ioc->ioc_hpa->io_io_high_hv));
++ } else {
++ /* This should be impossible. It means
++ * expand_ioc_area got called with a resource that
++ * didn't belong to the ioc
++ */
++ BUG();
++ }
+ }
+
+ static struct resource *ccio_get_resource(struct ioc* ioc,
+@@ -1488,7 +1635,7 @@
+ alignf_data))
+ return 0;
+
+- expand_ioc_area(ioc, size, min, max, align);
++ expand_ioc_area(parent, ioc, size, min, max, align);
+ return allocate_resource(parent, res, size, min, max, align, alignf,
+ alignf_data);
+ }
+@@ -1522,7 +1669,6 @@
+ memset(ioc, 0, sizeof(struct ioc));
+
+ ioc->name = dev->id.hversion == U2_IOA_RUNWAY ? "U2" : "UTurn";
+- strlcpy(dev->dev.name, ioc->name, sizeof(dev->dev.name));
+
+ printk(KERN_INFO "Found %s at 0x%lx\n", ioc->name, dev->hpa);
+
+Index: linux-2.6.0-test5/drivers/parisc/dino.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/parisc/dino.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/parisc/dino.c 2003-09-27 11:38:28.889136568 +0800
+@@ -401,23 +401,7 @@
+ {
+ int irq;
+
+- /*
+- * Perform a binary search on set bits.
+- * `Less than Fatal' and PS2 interrupts aren't supported.
+- */
+- if (mask & 0xf) {
+- if (mask & 0x3) {
+- irq = (mask & 0x1) ? 0 : 1; /* PCI INT A, B */
+- } else {
+- irq = (mask & 0x4) ? 2 : 3; /* PCI INT C, D */
+- }
+- } else {
+- if (mask & 0x30) {
+- irq = (mask & 0x10) ? 4 : 5; /* PCI INT E, F */
+- } else {
+- irq = (mask & 0x40) ? 6 : 10; /* GSC, RS232 */
+- }
+- }
++ irq = __ffs(mask);
+
+ mask &= ~(1<<irq);
+
+@@ -440,7 +424,7 @@
+ if (mask) {
+ if (--ilr_loop > 0)
+ goto ilr_again;
+- printk("Dino %lx: stuck interrupt %d\n", dino_dev->hba.base_addr, mask);
++ printk(KERN_ERR "Dino %lx: stuck interrupt %d\n", dino_dev->hba.base_addr, mask);
+ return IRQ_NONE;
+ }
+ return IRQ_HANDLED;
+@@ -479,15 +463,35 @@
+ int i;
+ struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->dev));
+ struct resource *res;
++ char name[128];
++ int size;
+
+ res = &dino_dev->hba.lmmio_space;
+ res->flags = IORESOURCE_MEM;
++ size = snprintf(name, sizeof(name), "Dino LMMIO (%s)", bus->dev->bus_id);
++ res->name = kmalloc(size+1, GFP_KERNEL);
++ if(res->name)
++ strcpy((char *)res->name, name);
++ else
++ res->name = dino_dev->hba.lmmio_space.name;
++
+
+ if (ccio_allocate_resource(dino_dev->hba.dev, res, _8MB,
+- (unsigned long) 0xfffffffff0000000UL | _8MB,
+- 0xffffffffffffffffUL &~ _8MB, _8MB,
++ F_EXTEND(0xf0000000UL) | _8MB,
++ F_EXTEND(0xffffffffUL) &~ _8MB, _8MB,
+ NULL, NULL) < 0) {
+- printk(KERN_WARNING "Dino: Failed to allocate memory region\n");
++ struct list_head *ln, *tmp_ln;
++
++ printk(KERN_ERR "Dino: cannot attach bus %s\n",
++ bus->dev->bus_id);
++ /* kill the bus, we can't do anything with it */
++ list_for_each_safe(ln, tmp_ln, &bus->devices) {
++ struct pci_dev *dev = pci_dev_b(ln);
++
++ list_del(&dev->global_list);
++ list_del(&dev->bus_list);
++ }
++
+ return;
+ }
+ bus->resource[1] = res;
+@@ -495,9 +499,11 @@
+
+ /* Now tell dino what range it has */
+ for (i = 1; i < 31; i++) {
+- if (res->start == (0xfffffffff0000000UL | i * _8MB))
++ if (res->start == F_EXTEND(0xf0000000UL | (i * _8MB)))
+ break;
+ }
++ DBG("DINO GSC WRITE i=%d, start=%lx, dino addr = %lx\n",
++ i, res->start, base_addr + DINO_IO_ADDR_EN);
+ gsc_writel(1 << i, base_addr + DINO_IO_ADDR_EN);
+
+ pci_bus_assign_resources(bus);
+@@ -521,7 +527,7 @@
+ ** Set Latency Timer to 0xff (not a shared bus)
+ ** Set CACHELINE_SIZE.
+ */
+- dino_cfg_write(dev->bus, dev->devfn, PCI_CACHE_LINE_SIZE, 16, 0xff00 | L1_CACHE_BYTES/4);
++ dino_cfg_write(dev->bus, dev->devfn, PCI_CACHE_LINE_SIZE, 2, 0xff00 | L1_CACHE_BYTES/4);
+
+ /*
+ ** Program INT_LINE for card-mode devices.
+@@ -532,13 +538,13 @@
+ ** "-1" converts INTA-D (1-4) to PCIINTA-D (0-3) range.
+ ** The additional "-1" adjusts for skewing the IRQ<->slot.
+ */
+- dino_cfg_read(dev->bus, dev->devfn, PCI_INTERRUPT_PIN, 8, &irq_pin);
++ dino_cfg_read(dev->bus, dev->devfn, PCI_INTERRUPT_PIN, 1, &irq_pin);
+ dev->irq = (irq_pin + PCI_SLOT(dev->devfn) - 1) % 4 ;
+
+ /* Shouldn't really need to do this but it's in case someone tries
+ ** to bypass PCI services and look at the card themselves.
+ */
+- dino_cfg_write(dev->bus, dev->devfn, PCI_INTERRUPT_LINE, 8, dev->irq);
++ dino_cfg_write(dev->bus, dev->devfn, PCI_INTERRUPT_LINE, 1, dev->irq);
+ }
+
+
+@@ -585,8 +591,8 @@
+ #ifdef __LP64__
+ /* Sign Extend MMIO addresses */
+ else if (res->flags & IORESOURCE_MEM) {
+- res->start |= 0xffffffff00000000UL;
+- res->end |= 0xffffffff00000000UL;
++ res->start |= F_EXTEND(0UL);
++ res->end |= F_EXTEND(0UL);
+ }
+ #endif
+ }
+@@ -789,8 +795,8 @@
+ return 0;
+ }
+
+-#define CUJO_RAVEN_ADDR 0xfffffffff1000000UL
+-#define CUJO_FIREHAWK_ADDR 0xfffffffff1604000UL
++#define CUJO_RAVEN_ADDR F_EXTEND(0xf1000000UL)
++#define CUJO_FIREHAWK_ADDR F_EXTEND(0xf1604000UL)
+ #define CUJO_RAVEN_BADPAGE 0x01003000UL
+ #define CUJO_FIREHAWK_BADPAGE 0x01607000UL
+
+@@ -818,9 +824,16 @@
+ {
+ struct dino_device *dino_dev; // Dino specific control struct
+ const char *version = "unknown";
+- const char *name = "Dino";
++ const int name_len = 32;
++ char *name;
+ int is_cujo = 0;
+
++ name = kmalloc(name_len, GFP_KERNEL);
++ if(name)
++ snprintf(name, name_len, "Dino %s", dev->dev.bus_id);
++ else
++ name = "Dino";
++
+ if (is_card_dino(&dev->id)) {
+ version = "3.x (card mode)";
+ } else {
+@@ -838,8 +851,6 @@
+ }
+
+ printk("%s version %s found at 0x%lx\n", name, version, dev->hpa);
+- snprintf(dev->dev.name, sizeof(dev->dev.name),
+- "%s version %s", name, version);
+
+ if (!request_mem_region(dev->hpa, PAGE_SIZE, name)) {
+ printk(KERN_ERR "DINO: Hey! Someone took my MMIO space (0x%ld)!\n",
+Index: linux-2.6.0-test5/drivers/parisc/eisa.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/parisc/eisa.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/parisc/eisa.c 2003-09-27 11:38:28.893135960 +0800
+@@ -327,14 +327,13 @@
+
+ printk(KERN_INFO "%s EISA Adapter found at 0x%08lx\n",
+ name, dev->hpa);
+- snprintf(dev->dev.name, sizeof(dev->dev.name), "%s EISA", name);
+
+ eisa_dev.hba.dev = dev;
+ eisa_dev.hba.iommu = ccio_get_iommu(dev);
+
+ eisa_dev.hba.lmmio_space.name = "EISA";
+- eisa_dev.hba.lmmio_space.start = (unsigned long) 0xfffffffffc000000;
+- eisa_dev.hba.lmmio_space.end = (unsigned long) 0xffffffffffbfffff;
++ eisa_dev.hba.lmmio_space.start = F_EXTEND(0xfc000000);
++ eisa_dev.hba.lmmio_space.end = F_EXTEND(0xffbfffff);
+ eisa_dev.hba.lmmio_space.flags = IORESOURCE_MEM;
+ result = ccio_request_resource(dev, &eisa_dev.hba.lmmio_space);
+ if (result < 0) {
+Index: linux-2.6.0-test5/drivers/parisc/hppb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/parisc/hppb.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/parisc/hppb.c 2003-09-27 11:38:28.895135656 +0800
+@@ -70,7 +70,6 @@
+ card = card->next;
+ }
+ printk(KERN_INFO "Found GeckoBoa at 0x%lx\n", dev->hpa);
+- snprintf(dev->dev.name, sizeof(dev->dev.name), "GeckoBoa");
+
+ card->hpa = dev->hpa;
+ card->mmio_region.name = "HP-PB Bus";
+Index: linux-2.6.0-test5/drivers/parisc/iosapic.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/parisc/iosapic.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/parisc/iosapic.c 2003-09-27 11:38:28.904134288 +0800
+@@ -643,7 +643,7 @@
+
+ if (NULL == isi) {
+ printk(KERN_WARNING MODULE_NAME ": hpa not registered for %s\n",
+- pcidev->dev.name);
++ pci_name(pcidev));
+ return(-1);
+ }
+
+Index: linux-2.6.0-test5/drivers/parisc/lasi.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/parisc/lasi.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/parisc/lasi.c 2003-09-27 11:38:28.906133984 +0800
+@@ -185,8 +185,6 @@
+ lasi->version = gsc_readl(lasi->hpa + LASI_VER) & 0xf;
+ printk(KERN_INFO "%s version %d at 0x%lx found.\n",
+ lasi->name, lasi->version, lasi->hpa);
+- snprintf(dev->dev.name, sizeof(dev->dev.name), "%s version %d",
+- lasi->name, lasi->version);
+
+ /* initialize the chassis LEDs really early */
+ lasi_led_init(lasi->hpa);
+Index: linux-2.6.0-test5/drivers/parisc/lba_pci.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/parisc/lba_pci.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/parisc/lba_pci.c 2003-09-27 11:38:28.917132312 +0800
+@@ -782,7 +782,7 @@
+ int i;
+ struct pci_dev *dev = pci_dev_b(ln);
+
+- DBG("lba_fixup_bus() %s\n", dev->name);
++ DBG("lba_fixup_bus() %s\n", pci_name(dev));
+
+ /* Virtualize Device/Bridge Resources. */
+ for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+@@ -1358,8 +1358,6 @@
+
+ printk(KERN_INFO "%s version %s (0x%x) found at 0x%lx\n",
+ MODULE_NAME, version, func_class & 0xf, dev->hpa);
+- snprintf(dev->dev.name, sizeof(dev->dev.name), "%s version %s",
+- MODULE_NAME, version);
+
+ /* Just in case we find some prototypes... */
+ if (func_class < 2) {
+Index: linux-2.6.0-test5/drivers/parisc/led.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/parisc/led.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/parisc/led.c 2003-09-27 11:38:28.923131400 +0800
+@@ -91,7 +91,7 @@
+
+
+ /* LCD_CMD and LCD_DATA for KittyHawk machines */
+-#define KITTYHAWK_LCD_CMD (0xfffffffff0190000UL) /* 64bit-ready */
++#define KITTYHAWK_LCD_CMD F_EXTEND(0xf0190000UL) /* 64bit-ready */
+ #define KITTYHAWK_LCD_DATA (KITTYHAWK_LCD_CMD+1)
+
+ /* lcd_info is pre-initialized to the values needed to program KittyHawk LCD's
+Index: linux-2.6.0-test5/drivers/parisc/sba_iommu.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/parisc/sba_iommu.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/parisc/sba_iommu.c 2003-09-27 11:38:28.938129120 +0800
+@@ -1978,8 +1978,6 @@
+
+ printk(KERN_INFO "%s found %s at 0x%lx\n",
+ MODULE_NAME, version, dev->hpa);
+- snprintf(dev->dev.name, sizeof(dev->dev.name), "%s version %s",
+- MODULE_NAME, version);
+
+ #ifdef DEBUG_SBA_INIT
+ sba_dump_tlb(dev->hpa);
+Index: linux-2.6.0-test5/drivers/parisc/wax.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/parisc/wax.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/parisc/wax.c 2003-09-27 11:38:28.940128816 +0800
+@@ -83,8 +83,6 @@
+
+ wax->version = 0; /* gsc_readb(wax->hpa+WAX_VER); */
+ printk(KERN_INFO "%s at 0x%lx found.\n", wax->name, wax->hpa);
+- snprintf(dev->dev.name, sizeof(dev->dev.name), "%s version %d",
+- wax->name, wax->version);
+
+ /* Stop wax hissing for a bit */
+ wax_init_irq(wax);
+Index: linux-2.6.0-test5/drivers/pci/hotplug/acpiphp_core.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/acpiphp_core.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/acpiphp_core.c 2003-09-27 11:38:28.944128208 +0800
+@@ -1,12 +1,12 @@
+ /*
+ * ACPI PCI Hot Plug Controller Driver
+ *
+- * Copyright (c) 1995,2001 Compaq Computer Corporation
+- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001 IBM Corp.
+- * Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
+- * Copyright (c) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
+- * Copyright (c) 2002,2003 NEC Corporation
++ * Copyright (C) 1995,2001 Compaq Computer Corporation
++ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001 IBM Corp.
++ * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
++ * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
++ * Copyright (C) 2002,2003 NEC Corporation
+ *
+ * All rights reserved.
+ *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/acpiphp_glue.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/acpiphp_glue.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/acpiphp_glue.c 2003-09-27 11:38:28.952126992 +0800
+@@ -1,9 +1,9 @@
+ /*
+ * ACPI PCI HotPlug glue functions to ACPI CA subsystem
+ *
+- * Copyright (c) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
+- * Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
+- * Copyright (c) 2002,2003 NEC Corporation
++ * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
++ * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
++ * Copyright (C) 2002,2003 NEC Corporation
+ *
+ * All rights reserved.
+ *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/acpiphp.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/acpiphp.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/acpiphp.h 2003-09-27 11:38:28.955126536 +0800
+@@ -1,12 +1,12 @@
+ /*
+ * ACPI PCI Hot Plug Controller Driver
+ *
+- * Copyright (c) 1995,2001 Compaq Computer Corporation
+- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001 IBM Corp.
+- * Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
+- * Copyright (c) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
+- * Copyright (c) 2002,2003 NEC Corporation
++ * Copyright (C) 1995,2001 Compaq Computer Corporation
++ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001 IBM Corp.
++ * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
++ * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
++ * Copyright (C) 2002,2003 NEC Corporation
+ *
+ * All rights reserved.
+ *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/acpiphp_pci.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/acpiphp_pci.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/acpiphp_pci.c 2003-09-27 11:38:28.959125928 +0800
+@@ -1,12 +1,12 @@
+ /*
+ * ACPI PCI HotPlug PCI configuration space management
+ *
+- * Copyright (c) 1995,2001 Compaq Computer Corporation
+- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001,2002 IBM Corp.
+- * Copyright (c) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
+- * Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
+- * Copyright (c) 2002 NEC Corporation
++ * Copyright (C) 1995,2001 Compaq Computer Corporation
++ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001,2002 IBM Corp.
++ * Copyright (C) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
++ * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
++ * Copyright (C) 2002 NEC Corporation
+ *
+ * All rights reserved.
+ *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/acpiphp_res.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/acpiphp_res.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/acpiphp_res.c 2003-09-27 11:38:28.965125016 +0800
+@@ -1,12 +1,12 @@
+ /*
+ * ACPI PCI HotPlug Utility functions
+ *
+- * Copyright (c) 1995,2001 Compaq Computer Corporation
+- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001 IBM Corp.
+- * Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
+- * Copyright (c) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
+- * Copyright (c) 2002 NEC Corporation
++ * Copyright (C) 1995,2001 Compaq Computer Corporation
++ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001 IBM Corp.
++ * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
++ * Copyright (C) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
++ * Copyright (C) 2002 NEC Corporation
+ *
+ * All rights reserved.
+ *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/cpci_hotplug_core.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/cpci_hotplug_core.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/cpci_hotplug_core.c 2003-09-27 11:38:28.971124104 +0800
+@@ -1,9 +1,9 @@
+ /*
+ * CompactPCI Hot Plug Driver
+ *
+- * Copyright (c) 2002 SOMA Networks, Inc.
+- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001 IBM Corp.
++ * Copyright (C) 2002 SOMA Networks, Inc.
++ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001 IBM Corp.
+ *
+ * All rights reserved.
+ *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/cpci_hotplug.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/cpci_hotplug.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/cpci_hotplug.h 2003-09-27 11:38:28.972123952 +0800
+@@ -1,9 +1,9 @@
+ /*
+ * CompactPCI Hot Plug Core Functions
+ *
+- * Copyright (c) 2002 SOMA Networks, Inc.
+- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001 IBM Corp.
++ * Copyright (C) 2002 SOMA Networks, Inc.
++ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001 IBM Corp.
+ *
+ * All rights reserved.
+ *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/cpci_hotplug_pci.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/cpci_hotplug_pci.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/cpci_hotplug_pci.c 2003-09-27 11:38:28.977123192 +0800
+@@ -1,7 +1,7 @@
+ /*
+ * CompactPCI Hot Plug Driver PCI functions
+ *
+- * Copyright (c) 2002 by SOMA Networks, Inc.
++ * Copyright (C) 2002 by SOMA Networks, Inc.
+ *
+ * All rights reserved.
+ *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/cpqphp_core.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/cpqphp_core.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/cpqphp_core.c 2003-09-27 11:38:28.987121672 +0800
+@@ -1,9 +1,9 @@
+ /*
+ * Compaq Hot Plug Controller Driver
+ *
+- * Copyright (c) 1995,2001 Compaq Computer Corporation
+- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001 IBM Corp.
++ * Copyright (C) 1995,2001 Compaq Computer Corporation
++ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001 IBM Corp.
+ *
+ * All rights reserved.
+ *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/cpqphp_ctrl.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/cpqphp_ctrl.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/cpqphp_ctrl.c 2003-09-27 11:38:29.007118632 +0800
+@@ -1,9 +1,9 @@
+ /*
+ * Compaq Hot Plug Controller Driver
+ *
+- * Copyright (c) 1995,2001 Compaq Computer Corporation
+- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001 IBM Corp.
++ * Copyright (C) 1995,2001 Compaq Computer Corporation
++ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001 IBM Corp.
+ *
+ * All rights reserved.
+ *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/cpqphp.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/cpqphp.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/cpqphp.h 2003-09-27 11:38:29.015117416 +0800
+@@ -1,9 +1,9 @@
+ /*
+ * Compaq Hot Plug Controller Driver
+ *
+- * Copyright (c) 1995,2001 Compaq Computer Corporation
+- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001 IBM
++ * Copyright (C) 1995,2001 Compaq Computer Corporation
++ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001 IBM
+ *
+ * All rights reserved.
+ *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/cpqphp_nvram.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/cpqphp_nvram.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/cpqphp_nvram.c 2003-09-27 11:38:29.019116808 +0800
+@@ -1,9 +1,9 @@
+ /*
+ * Compaq Hot Plug Controller Driver
+ *
+- * Copyright (c) 1995,2001 Compaq Computer Corporation
+- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001 IBM Corp.
++ * Copyright (C) 1995,2001 Compaq Computer Corporation
++ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001 IBM Corp.
+ *
+ * All rights reserved.
+ *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/cpqphp_nvram.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/cpqphp_nvram.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/cpqphp_nvram.h 2003-09-27 11:38:29.020116656 +0800
+@@ -1,8 +1,8 @@
+ /*
+ * Compaq Hot Plug Controller Driver
+ *
+- * Copyright (c) 1995,2001 Compaq Computer Corporation
+- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 1995,2001 Compaq Computer Corporation
++ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ *
+ * All rights reserved.
+ *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/cpqphp_pci.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/cpqphp_pci.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/cpqphp_pci.c 2003-09-27 11:38:29.031114984 +0800
+@@ -1,9 +1,9 @@
+ /*
+ * Compaq Hot Plug Controller Driver
+ *
+- * Copyright (c) 1995,2001 Compaq Computer Corporation
+- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001 IBM Corp.
++ * Copyright (C) 1995,2001 Compaq Computer Corporation
++ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001 IBM Corp.
+ *
+ * All rights reserved.
+ *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/cpqphp_sysfs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/cpqphp_sysfs.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/cpqphp_sysfs.c 2003-09-27 11:38:29.034114528 +0800
+@@ -1,9 +1,9 @@
+ /*
+ * Compaq Hot Plug Controller Driver
+ *
+- * Copyright (c) 1995,2001 Compaq Computer Corporation
+- * Copyright (c) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001 IBM Corp.
++ * Copyright (C) 1995,2001 Compaq Computer Corporation
++ * Copyright (C) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001 IBM Corp.
+ *
+ * All rights reserved.
+ *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/fakephp.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/fakephp.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/fakephp.c 2003-09-27 11:38:29.036114224 +0800
+@@ -1,9 +1,9 @@
+ /*
+ * Fake PCI Hot Plug Controller Driver
+ *
+- * Copyright (c) 2003 Greg Kroah-Hartman <greg@kroah.com>
+- * Copyright (c) 2003 IBM Corp.
+- * Copyright (c) 2003 Rolf Eike Beer <eike-kernel@sf-tec.de>
++ * Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com>
++ * Copyright (C) 2003 IBM Corp.
++ * Copyright (C) 2003 Rolf Eike Beer <eike-kernel@sf-tec.de>
+ *
+ * Based on ideas and code from:
+ * Vladimir Kondratiev <vladimir.kondratiev@intel.com>
+Index: linux-2.6.0-test5/drivers/pci/hotplug/ibmphp_core.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/ibmphp_core.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/ibmphp_core.c 2003-09-27 11:38:29.046112704 +0800
+@@ -3,8 +3,8 @@
+ *
+ * Written By: Chuck Cole, Jyoti Shah, Tong Yu, Irene Zubarev, IBM Corporation
+ *
+- * Copyright (c) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001-2003 IBM Corp.
++ * Copyright (C) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001-2003 IBM Corp.
+ *
+ * All rights reserved.
+ *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/ibmphp_ebda.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/ibmphp_ebda.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/ibmphp_ebda.c 2003-09-27 11:38:29.056111184 +0800
+@@ -3,8 +3,8 @@
+ *
+ * Written By: Tong Yu, IBM Corporation
+ *
+- * Copyright (c) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001-2003 IBM Corp.
++ * Copyright (C) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001-2003 IBM Corp.
+ *
+ * All rights reserved.
+ *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/ibmphp.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/ibmphp.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/ibmphp.h 2003-09-27 11:38:29.064109968 +0800
+@@ -6,8 +6,8 @@
+ *
+ * Written By: Jyoti Shah, Tong Yu, Irene Zubarev, IBM Corporation
+ *
+- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001-2003 IBM Corp.
++ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001-2003 IBM Corp.
+ *
+ * All rights reserved.
+ *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/ibmphp_hpc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/ibmphp_hpc.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/ibmphp_hpc.c 2003-09-27 11:38:29.073108600 +0800
+@@ -3,7 +3,7 @@
+ *
+ * Written By: Jyoti Shah, IBM Corporation
+ *
+- * Copyright (c) 2001-2003 IBM Corp.
++ * Copyright (C) 2001-2003 IBM Corp.
+ *
+ * All rights reserved.
+ *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/ibmphp_pci.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/ibmphp_pci.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/ibmphp_pci.c 2003-09-27 11:38:29.088106320 +0800
+@@ -3,8 +3,8 @@
+ *
+ * Written By: Irene Zubarev, IBM Corporation
+ *
+- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001,2002 IBM Corp.
++ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001,2002 IBM Corp.
+ *
+ * All rights reserved.
+ *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/ibmphp_res.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/ibmphp_res.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/ibmphp_res.c 2003-09-27 11:38:29.104103888 +0800
+@@ -3,8 +3,8 @@
+ *
+ * Written By: Irene Zubarev, IBM Corporation
+ *
+- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001,2002 IBM Corp.
++ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001,2002 IBM Corp.
+ *
+ * All rights reserved.
+ *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/pci_hotplug_core.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/pci_hotplug_core.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/pci_hotplug_core.c 2003-09-27 11:38:29.110102976 +0800
+@@ -1,8 +1,8 @@
+ /*
+ * PCI HotPlug Controller Core
+ *
+- * Copyright (c) 2001-2002 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001-2002 IBM Corp.
++ * Copyright (C) 2001-2002 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001-2002 IBM Corp.
+ *
+ * All rights reserved.
+ *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/pci_hotplug.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/pci_hotplug.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/pci_hotplug.h 2003-09-27 11:38:29.112102672 +0800
+@@ -1,9 +1,9 @@
+ /*
+ * PCI HotPlug Core Functions
+ *
+- * Copyright (c) 1995,2001 Compaq Computer Corporation
+- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001 IBM Corp.
++ * Copyright (C) 1995,2001 Compaq Computer Corporation
++ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001 IBM Corp.
+ *
+ * All rights reserved.
+ *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/pcihp_skeleton.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/pcihp_skeleton.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/pcihp_skeleton.c 2003-09-27 11:38:29.116102064 +0800
+@@ -1,8 +1,8 @@
+ /*
+ * PCI Hot Plug Controller Skeleton Driver - 0.2
+ *
+- * Copyright (c) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001,2003 IBM Corp.
++ * Copyright (C) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001,2003 IBM Corp.
+ *
+ * All rights reserved.
+ *
+Index: linux-2.6.0-test5/drivers/pci/pci-driver.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/pci-driver.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/pci-driver.c 2003-09-27 11:38:29.121101304 +0800
+@@ -35,6 +35,173 @@
+ return NULL;
+ }
+
++/*
++ * Dynamic device IDs are disabled for !CONFIG_HOTPLUG
++ */
++
++#ifdef CONFIG_HOTPLUG
++/**
++ * pci_device_probe_dynamic()
++ *
++ * Walk the dynamic ID list looking for a match.
++ * returns 0 and sets pci_dev->driver when drv claims pci_dev, else error.
++ */
++static int
++pci_device_probe_dynamic(struct pci_driver *drv, struct pci_dev *pci_dev)
++{
++ int error = -ENODEV;
++ struct list_head *pos;
++ struct dynid *dynid;
++
++ spin_lock(&drv->dynids.lock);
++ list_for_each(pos, &drv->dynids.list) {
++ dynid = list_entry(pos, struct dynid, node);
++ if (pci_match_one_device(&dynid->id, pci_dev)) {
++ spin_unlock(&drv->dynids.lock);
++ error = drv->probe(pci_dev, &dynid->id);
++ if (error >= 0) {
++ pci_dev->driver = drv;
++ return 0;
++ }
++ return error;
++ }
++ }
++ spin_unlock(&drv->dynids.lock);
++ return error;
++}
++
++static inline void
++dynid_init(struct dynid *dynid)
++{
++ memset(dynid, 0, sizeof(*dynid));
++ INIT_LIST_HEAD(&dynid->node);
++}
++
++/**
++ * store_new_id
++ *
++ * Adds a new dynamic pci device ID to this driver,
++ * and causes the driver to probe for all devices again.
++ */
++static inline ssize_t
++store_new_id(struct device_driver *driver, const char *buf, size_t count)
++{
++ struct dynid *dynid;
++ struct bus_type * bus;
++ struct pci_driver *pdrv = to_pci_driver(driver);
++ __u32 vendor=PCI_ANY_ID, device=PCI_ANY_ID, subvendor=PCI_ANY_ID,
++ subdevice=PCI_ANY_ID, class=0, class_mask=0;
++ unsigned long driver_data=0;
++ int fields=0;
++
++ fields = sscanf(buf, "%x %x %x %x %x %x %lux",
++ &vendor, &device, &subvendor, &subdevice,
++ &class, &class_mask, &driver_data);
++ if (fields < 0)
++ return -EINVAL;
++
++ dynid = kmalloc(sizeof(*dynid), GFP_KERNEL);
++ if (!dynid)
++ return -ENOMEM;
++ dynid_init(dynid);
++
++ dynid->id.vendor = vendor;
++ dynid->id.device = device;
++ dynid->id.subvendor = subvendor;
++ dynid->id.subdevice = subdevice;
++ dynid->id.class = class;
++ dynid->id.class_mask = class_mask;
++ dynid->id.driver_data = pdrv->dynids.use_driver_data ?
++ driver_data : 0UL;
++
++ spin_lock(&pdrv->dynids.lock);
++ list_add_tail(&pdrv->dynids.list, &dynid->node);
++ spin_unlock(&pdrv->dynids.lock);
++
++ bus = get_bus(pdrv->driver.bus);
++ if (bus) {
++ if (get_driver(&pdrv->driver)) {
++ down_write(&bus->subsys.rwsem);
++ driver_attach(&pdrv->driver);
++ up_write(&bus->subsys.rwsem);
++ put_driver(&pdrv->driver);
++ }
++ put_bus(bus);
++ }
++
++ return count;
++}
++
++static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id);
++static inline void
++pci_init_dynids(struct pci_dynids *dynids)
++{
++ memset(dynids, 0, sizeof(*dynids));
++ spin_lock_init(&dynids->lock);
++ INIT_LIST_HEAD(&dynids->list);
++}
++
++static void
++pci_free_dynids(struct pci_driver *drv)
++{
++ struct list_head *pos, *n;
++ struct dynid *dynid;
++
++ spin_lock(&drv->dynids.lock);
++ list_for_each_safe(pos, n, &drv->dynids.list) {
++ dynid = list_entry(pos, struct dynid, node);
++ list_del(&dynid->node);
++ kfree(dynid);
++ }
++ spin_unlock(&drv->dynids.lock);
++}
++
++static int
++pci_create_newid_file(struct pci_driver *drv)
++{
++ int error = 0;
++ if (drv->probe != NULL)
++ error = sysfs_create_file(&drv->driver.kobj,
++ &driver_attr_new_id.attr);
++ return error;
++}
++
++static int
++pci_bus_match_dynids(const struct pci_dev *pci_dev, struct pci_driver *pci_drv)
++{
++ struct list_head *pos;
++ struct dynid *dynid;
++
++ spin_lock(&pci_drv->dynids.lock);
++ list_for_each(pos, &pci_drv->dynids.list) {
++ dynid = list_entry(pos, struct dynid, node);
++ if (pci_match_one_device(&dynid->id, pci_dev)) {
++ spin_unlock(&pci_drv->dynids.lock);
++ return 1;
++ }
++ }
++ spin_unlock(&pci_drv->dynids.lock);
++ return 0;
++}
++
++#else /* !CONFIG_HOTPLUG */
++static inline int pci_device_probe_dynamic(struct pci_driver *drv, struct pci_dev *pci_dev)
++{
++ return -ENODEV;
++}
++static inline void dynid_init(struct dynid *dynid) {}
++static inline void pci_init_dynids(struct pci_dynids *dynids) {}
++static inline void pci_free_dynids(struct pci_driver *drv) {}
++static inline int pci_create_newid_file(struct pci_driver *drv)
++{
++ return 0;
++}
++static inline int pci_bus_match_dynids(const struct pci_dev *pci_dev, struct pci_driver *pci_drv)
++{
++ return 0;
++}
++#endif
++
+ /**
+ * pci_match_device - Tell if a PCI device structure has a matching
+ * PCI device id structure
+@@ -80,36 +247,6 @@
+ }
+
+ /**
+- * pci_device_probe_dynamic()
+- *
+- * Walk the dynamic ID list looking for a match.
+- * returns 0 and sets pci_dev->driver when drv claims pci_dev, else error.
+- */
+-static int
+-pci_device_probe_dynamic(struct pci_driver *drv, struct pci_dev *pci_dev)
+-{
+- int error = -ENODEV;
+- struct list_head *pos;
+- struct dynid *dynid;
+-
+- spin_lock(&drv->dynids.lock);
+- list_for_each(pos, &drv->dynids.list) {
+- dynid = list_entry(pos, struct dynid, node);
+- if (pci_match_one_device(&dynid->id, pci_dev)) {
+- spin_unlock(&drv->dynids.lock);
+- error = drv->probe(pci_dev, &dynid->id);
+- if (error >= 0) {
+- pci_dev->driver = drv;
+- return 0;
+- }
+- return error;
+- }
+- }
+- spin_unlock(&drv->dynids.lock);
+- return error;
+-}
+-
+-/**
+ * __pci_device_probe()
+ *
+ * returns 0 on success, else error.
+@@ -178,72 +315,6 @@
+ return 0;
+ }
+
+-static inline void
+-dynid_init(struct dynid *dynid)
+-{
+- memset(dynid, 0, sizeof(*dynid));
+- INIT_LIST_HEAD(&dynid->node);
+-}
+-
+-/**
+- * store_new_id
+- * @ pdrv
+- * @ buf
+- * @ count
+- *
+- * Adds a new dynamic pci device ID to this driver,
+- * and causes the driver to probe for all devices again.
+- */
+-static inline ssize_t
+-store_new_id(struct device_driver * driver, const char * buf, size_t count)
+-{
+- struct dynid *dynid;
+- struct bus_type * bus;
+- struct pci_driver *pdrv = to_pci_driver(driver);
+- __u32 vendor=PCI_ANY_ID, device=PCI_ANY_ID, subvendor=PCI_ANY_ID,
+- subdevice=PCI_ANY_ID, class=0, class_mask=0;
+- unsigned long driver_data=0;
+- int fields=0;
+-
+- fields = sscanf(buf, "%x %x %x %x %x %x %lux",
+- &vendor, &device, &subvendor, &subdevice,
+- &class, &class_mask, &driver_data);
+- if (fields < 0)
+- return -EINVAL;
+-
+- dynid = kmalloc(sizeof(*dynid), GFP_KERNEL);
+- if (!dynid)
+- return -ENOMEM;
+- dynid_init(dynid);
+-
+- dynid->id.vendor = vendor;
+- dynid->id.device = device;
+- dynid->id.subvendor = subvendor;
+- dynid->id.subdevice = subdevice;
+- dynid->id.class = class;
+- dynid->id.class_mask = class_mask;
+- dynid->id.driver_data = pdrv->dynids.use_driver_data ?
+- driver_data : 0UL;
+-
+- spin_lock(&pdrv->dynids.lock);
+- list_add_tail(&pdrv->dynids.list, &dynid->node);
+- spin_unlock(&pdrv->dynids.lock);
+-
+- bus = get_bus(pdrv->driver.bus);
+- if (bus) {
+- if (get_driver(&pdrv->driver)) {
+- down_write(&bus->subsys.rwsem);
+- driver_attach(&pdrv->driver);
+- up_write(&bus->subsys.rwsem);
+- put_driver(&pdrv->driver);
+- }
+- put_bus(bus);
+- }
+-
+- return count;
+-}
+-
+-static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id);
+
+ #define kobj_to_pci_driver(obj) container_of(obj, struct device_driver, kobj)
+ #define attr_to_driver_attribute(obj) container_of(obj, struct driver_attribute, attr)
+@@ -288,40 +359,11 @@
+ };
+
+ static int
+-pci_populate_driver_dir(struct pci_driver * drv)
+-{
+- int error = 0;
+-
+- if (drv->probe != NULL)
+- error = sysfs_create_file(&drv->driver.kobj,
+- &driver_attr_new_id.attr);
+- return error;
+-}
+-
+-static inline void
+-pci_init_dynids(struct pci_dynids *dynids)
+-{
+- memset(dynids, 0, sizeof(*dynids));
+- spin_lock_init(&dynids->lock);
+- INIT_LIST_HEAD(&dynids->list);
+-}
+-
+-static void
+-pci_free_dynids(struct pci_driver *drv)
++pci_populate_driver_dir(struct pci_driver *drv)
+ {
+- struct list_head *pos, *n;
+- struct dynid *dynid;
+-
+- spin_lock(&drv->dynids.lock);
+- list_for_each_safe(pos, n, &drv->dynids.list) {
+- dynid = list_entry(pos, struct dynid, node);
+- list_del(&dynid->node);
+- kfree(dynid);
+- }
+- spin_unlock(&drv->dynids.lock);
++ return pci_create_newid_file(drv);
+ }
+
+-
+ /**
+ * pci_register_driver - register a new pci driver
+ * @drv: the driver structure to register
+@@ -411,8 +453,6 @@
+ struct pci_driver * pci_drv = to_pci_driver(drv);
+ const struct pci_device_id * ids = pci_drv->id_table;
+ const struct pci_device_id *found_id;
+- struct list_head *pos;
+- struct dynid *dynid;
+
+ if (!ids)
+ return 0;
+@@ -421,17 +461,7 @@
+ if (found_id)
+ return 1;
+
+- spin_lock(&pci_drv->dynids.lock);
+- list_for_each(pos, &pci_drv->dynids.list) {
+- dynid = list_entry(pos, struct dynid, node);
+- if (pci_match_one_device(&dynid->id, pci_dev)) {
+- spin_unlock(&pci_drv->dynids.lock);
+- return 1;
+- }
+- }
+- spin_unlock(&pci_drv->dynids.lock);
+-
+- return 0;
++ return pci_bus_match_dynids(pci_dev, pci_drv);
+ }
+
+ /**
+Index: linux-2.6.0-test5/drivers/pci/probe.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/probe.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/probe.c 2003-09-27 11:38:29.126100544 +0800
+@@ -176,7 +176,7 @@
+ limit |= (io_limit_hi << 16);
+ }
+
+- if (base && base <= limit) {
++ if (base <= limit) {
+ res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO;
+ res->start = base;
+ res->end = limit + 0xfff;
+@@ -187,7 +187,7 @@
+ pci_read_config_word(dev, PCI_MEMORY_LIMIT, &mem_limit_lo);
+ base = (mem_base_lo & PCI_MEMORY_RANGE_MASK) << 16;
+ limit = (mem_limit_lo & PCI_MEMORY_RANGE_MASK) << 16;
+- if (base && base <= limit) {
++ if (base <= limit) {
+ res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM;
+ res->start = base;
+ res->end = limit + 0xfffff;
+@@ -213,7 +213,7 @@
+ }
+ #endif
+ }
+- if (base && base <= limit) {
++ if (base <= limit) {
+ res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM | IORESOURCE_PREFETCH;
+ res->start = base;
+ res->end = limit + 0xfffff;
+Index: linux-2.6.0-test5/drivers/pcmcia/cardbus.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pcmcia/cardbus.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pcmcia/cardbus.c 2003-09-27 11:38:29.128100240 +0800
+@@ -29,18 +29,11 @@
+ the provisions above, a recipient may use your version of this
+ file under either the MPL or the GPL.
+
+- These routines handle allocating resources for Cardbus cards, as
+- well as setting up and shutting down Cardbus sockets. They are
+- called from cs.c in response to Request/ReleaseConfiguration and
+- Request/ReleaseIO calls.
+-
+ ======================================================================*/
+
+ /*
+- * This file is going away. Cardbus handling has been re-written to be
+- * more of a PCI bridge thing, and the PCI code basically does all the
+- * resource handling. This has wrappers to make the rest of the PCMCIA
+- * subsystem not notice that it's not here any more.
++ * Cardbus handling has been re-written to be more of a PCI bridge thing,
++ * and the PCI code basically does all the resource handling.
+ *
+ * Linus, Jan 2000
+ */
+Index: linux-2.6.0-test5/drivers/pcmcia/cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pcmcia/cs.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pcmcia/cs.c 2003-09-27 11:38:29.148097200 +0800
+@@ -244,13 +244,10 @@
+ static int socket_resume(struct pcmcia_socket *skt);
+ static int socket_suspend(struct pcmcia_socket *skt);
+
+-int pcmcia_socket_dev_suspend(struct device *dev, u32 state, u32 level)
++int pcmcia_socket_dev_suspend(struct device *dev, u32 state)
+ {
+ struct pcmcia_socket *socket;
+
+- if (level != SUSPEND_SAVE_STATE)
+- return 0;
+-
+ down_read(&pcmcia_socket_list_rwsem);
+ list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
+ if (socket->dev.dev != dev)
+@@ -265,13 +262,10 @@
+ }
+ EXPORT_SYMBOL(pcmcia_socket_dev_suspend);
+
+-int pcmcia_socket_dev_resume(struct device *dev, u32 level)
++int pcmcia_socket_dev_resume(struct device *dev)
+ {
+ struct pcmcia_socket *socket;
+
+- if (level != RESUME_RESTORE_STATE)
+- return 0;
+-
+ down_read(&pcmcia_socket_list_rwsem);
+ list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
+ if (socket->dev.dev != dev)
+@@ -287,72 +281,29 @@
+ EXPORT_SYMBOL(pcmcia_socket_dev_resume);
+
+
+-static int pccardd(void *__skt);
+-#define to_class_data(dev) dev->class_data
+-
+-static int pcmcia_add_socket(struct class_device *class_dev)
+-{
+- struct pcmcia_socket *socket = class_get_devdata(class_dev);
+- int ret = 0;
+-
+- /* base address = 0, map = 0 */
+- socket->cis_mem.flags = 0;
+- socket->cis_mem.speed = cis_speed;
+- socket->erase_busy.next = socket->erase_busy.prev = &socket->erase_busy;
+- INIT_LIST_HEAD(&socket->cis_cache);
+- spin_lock_init(&socket->lock);
+-
+- init_completion(&socket->thread_done);
+- init_waitqueue_head(&socket->thread_wait);
+- init_MUTEX(&socket->skt_sem);
+- spin_lock_init(&socket->thread_lock);
+-
+- socket->socket = dead_socket;
+- socket->ops->init(socket);
+-
+- ret = kernel_thread(pccardd, socket, CLONE_KERNEL);
+- if (ret < 0)
+- return ret;
+-
+- wait_for_completion(&socket->thread_done);
+- BUG_ON(!socket->thread);
+- pcmcia_parse_events(socket, SS_DETECT);
+-
+- return 0;
+-}
+-
+-static void pcmcia_remove_socket(struct class_device *class_dev)
++static void pcmcia_release_socket(struct class_device *class_dev)
+ {
+ struct pcmcia_socket *socket = class_get_devdata(class_dev);
+ client_t *client;
+
+- if (socket->thread) {
+- init_completion(&socket->thread_done);
+- socket->thread = NULL;
+- wake_up(&socket->thread_wait);
+- wait_for_completion(&socket->thread_done);
+- }
+- release_cis_mem(socket);
+ while (socket->clients) {
+ client = socket->clients;
+ socket->clients = socket->clients->next;
+ kfree(client);
+ }
+- socket->ops = NULL;
+-}
+
+-static void pcmcia_release_socket(struct class_device *class_dev)
+-{
+- struct pcmcia_socket *socket = class_get_devdata(class_dev);
+ complete(&socket->socket_released);
+ }
+
++static int pccardd(void *__skt);
+
+ /**
+ * pcmcia_register_socket - add a new pcmcia socket device
+ */
+ int pcmcia_register_socket(struct pcmcia_socket *socket)
+ {
++ int ret;
++
+ if (!socket || !socket->ops || !socket->dev.dev)
+ return -EINVAL;
+
+@@ -387,15 +338,34 @@
+ socket->dev.class = &pcmcia_socket_class;
+ snprintf(socket->dev.class_id, BUS_ID_SIZE, "pcmcia_socket%u", socket->sock);
+
+- /* register with the device core */
+- if (class_device_register(&socket->dev)) {
+- down_write(&pcmcia_socket_list_rwsem);
+- list_del(&socket->socket_list);
+- up_write(&pcmcia_socket_list_rwsem);
+- return -EINVAL;
+- }
++ /* base address = 0, map = 0 */
++ socket->cis_mem.flags = 0;
++ socket->cis_mem.speed = cis_speed;
++ socket->erase_busy.next = socket->erase_busy.prev = &socket->erase_busy;
++ INIT_LIST_HEAD(&socket->cis_cache);
++ spin_lock_init(&socket->lock);
++
++ init_completion(&socket->socket_released);
++ init_completion(&socket->thread_done);
++ init_waitqueue_head(&socket->thread_wait);
++ init_MUTEX(&socket->skt_sem);
++ spin_lock_init(&socket->thread_lock);
++
++ ret = kernel_thread(pccardd, socket, CLONE_KERNEL);
++ if (ret < 0)
++ goto err;
++
++ wait_for_completion(&socket->thread_done);
++ BUG_ON(!socket->thread);
++ pcmcia_parse_events(socket, SS_DETECT);
+
+ return 0;
++
++ err:
++ down_write(&pcmcia_socket_list_rwsem);
++ list_del(&socket->socket_list);
++ up_write(&pcmcia_socket_list_rwsem);
++ return ret;
+ } /* pcmcia_register_socket */
+ EXPORT_SYMBOL(pcmcia_register_socket);
+
+@@ -410,10 +380,13 @@
+
+ DEBUG(0, "cs: pcmcia_unregister_socket(0x%p)\n", socket->ops);
+
+- init_completion(&socket->socket_released);
+-
+- /* remove from the device core */
+- class_device_unregister(&socket->dev);
++ if (socket->thread) {
++ init_completion(&socket->thread_done);
++ socket->thread = NULL;
++ wake_up(&socket->thread_wait);
++ wait_for_completion(&socket->thread_done);
++ }
++ release_cis_mem(socket);
+
+ /* remove from our own list */
+ down_write(&pcmcia_socket_list_rwsem);
+@@ -657,7 +630,7 @@
+ pcmcia_error(skt, "unsupported voltage key.\n");
+ return CS_BAD_TYPE;
+ }
+- skt->socket.flags = SS_DEBOUNCED;
++ skt->socket.flags = 0;
+ skt->ops->set_socket(skt, &skt->socket);
+
+ /*
+@@ -690,7 +663,6 @@
+ }
+ #endif
+ send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
+- skt->socket.flags &= ~SS_DEBOUNCED;
+ } else {
+ socket_shutdown(skt);
+ cs_socket_put(skt);
+@@ -739,7 +711,6 @@
+ } else {
+ send_event(skt, CS_EVENT_PM_RESUME, CS_EVENT_PRI_LOW);
+ }
+- skt->socket.flags &= ~SS_DEBOUNCED;
+ } else {
+ socket_shutdown(skt);
+ cs_socket_put(skt);
+@@ -791,11 +762,22 @@
+ {
+ struct pcmcia_socket *skt = __skt;
+ DECLARE_WAITQUEUE(wait, current);
++ int ret;
+
+ daemonize("pccardd");
+ skt->thread = current;
+ complete(&skt->thread_done);
+
++ skt->socket = dead_socket;
++ skt->ops->init(skt);
++
++ /* register with the device core */
++ ret = class_device_register(&skt->dev);
++ if (ret) {
++ printk(KERN_WARNING "PCMCIA: unable to register socket 0x%p\n",
++ skt);
++ }
++
+ add_wait_queue(&skt->thread_wait, &wait);
+ for (;;) {
+ unsigned long flags;
+@@ -831,6 +813,9 @@
+ }
+ remove_wait_queue(&skt->thread_wait, &wait);
+
++ /* remove from the device core */
++ class_device_unregister(&skt->dev);
++
+ complete_and_exit(&skt->thread_done, 0);
+ }
+
+@@ -2509,12 +2494,6 @@
+ };
+ EXPORT_SYMBOL(pcmcia_socket_class);
+
+-static struct class_interface pcmcia_socket = {
+- .class = &pcmcia_socket_class,
+- .add = &pcmcia_add_socket,
+- .remove = &pcmcia_remove_socket,
+-};
+-
+
+ static int __init init_pcmcia_cs(void)
+ {
+@@ -2522,7 +2501,6 @@
+ printk(KERN_INFO " %s\n", options);
+ DEBUG(0, "%s\n", version);
+ class_register(&pcmcia_socket_class);
+- class_interface_register(&pcmcia_socket);
+
+ return 0;
+ }
+@@ -2531,7 +2509,6 @@
+ {
+ printk(KERN_INFO "unloading Kernel Card Services\n");
+ release_resource_db();
+- class_interface_unregister(&pcmcia_socket);
+ class_unregister(&pcmcia_socket_class);
+ }
+
+Index: linux-2.6.0-test5/drivers/pcmcia/cs_internal.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pcmcia/cs_internal.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pcmcia/cs_internal.h 2003-09-27 11:38:29.150096896 +0800
+@@ -100,11 +100,8 @@
+ /* Flags in socket state */
+ #define SOCKET_PRESENT 0x0008
+ #define SOCKET_INUSE 0x0010
+-#define SOCKET_SHUTDOWN_PENDING 0x0020
+-#define SOCKET_RESET_PENDING 0x0040
+ #define SOCKET_SUSPEND 0x0080
+ #define SOCKET_WIN_REQ(i) (0x0100<<(i))
+-#define SOCKET_IO_REQ(i) (0x1000<<(i))
+ #define SOCKET_REGION_INFO 0x4000
+ #define SOCKET_CARDBUS 0x8000
+ #define SOCKET_CARDBUS_CONFIG 0x10000
+Index: linux-2.6.0-test5/drivers/pcmcia/hd64465_ss.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pcmcia/hd64465_ss.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pcmcia/hd64465_ss.c 2003-09-27 11:38:29.196089904 +0800
+@@ -867,19 +867,32 @@
+ local_irq_restore(flags);
+ }
+
++static int hd64465_suspend(struct device *dev, u32 state, u32 level)
++{
++ int ret = 0;
++ if (level == SUSPEND_SAVE_STATE)
++ ret = pcmcia_socket_dev_suspend(dev, state);
++ return ret;
++}
++
++static int hd64465_resume(struct device *dev, u32 level)
++{
++ int ret = 0;
++ if (level == RESUME_RESTORE_STATE)
++ ret = pcmcia_socket_dev_resume(dev);
++ return ret;
++}
++
+ static struct device_driver hd64465_driver = {
+ .name = "hd64465-pcmcia",
+ .bus = &platform_bus_type,
+- .suspend = pcmcia_socket_dev_suspend,
+- .resume = pcmcia_socket_dev_resume,
++ .suspend = hd64465_suspend,
++ .resume = hd64465_resume,
+ };
+
+ static struct platform_device hd64465_device = {
+ .name = "hd64465-pcmcia",
+ .id = 0,
+- .dev = {
+- .name = "hd64465-pcmcia",
+- },
+ };
+
+ static int __init init_hs(void)
+Index: linux-2.6.0-test5/drivers/pcmcia/i82092.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pcmcia/i82092.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pcmcia/i82092.c 2003-09-27 11:38:29.215087016 +0800
+@@ -44,12 +44,12 @@
+
+ static int i82092aa_socket_suspend (struct pci_dev *dev, u32 state)
+ {
+- return pcmcia_socket_dev_suspend(&dev->dev, state, SUSPEND_SAVE_STATE);
++ return pcmcia_socket_dev_suspend(&dev->dev, state);
+ }
+
+ static int i82092aa_socket_resume (struct pci_dev *dev)
+ {
+- return pcmcia_socket_dev_resume(&dev->dev, RESUME_RESTORE_STATE);
++ return pcmcia_socket_dev_resume(&dev->dev);
+ }
+
+ static struct pci_driver i82092aa_pci_drv = {
+@@ -92,7 +92,7 @@
+ static int socket_count; /* shortcut */
+
+
+-static int __init i82092aa_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
++static int __devinit i82092aa_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
+ {
+ unsigned char configbyte;
+ int i, ret;
+Index: linux-2.6.0-test5/drivers/pcmcia/i82365.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pcmcia/i82365.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pcmcia/i82365.c 2003-09-27 11:38:29.230084736 +0800
+@@ -1351,11 +1351,27 @@
+
+ /*====================================================================*/
+
++static int i82365_suspend(struct device *dev, u32 state, u32 level)
++{
++ int ret = 0;
++ if (level == SUSPEND_SAVE_STATE)
++ ret = pcmcia_socket_dev_suspend(dev, state);
++ return ret;
++}
++
++static int i82365_resume(struct device *dev, u32 level)
++{
++ int ret = 0;
++ if (level == RESUME_RESTORE_STATE)
++ ret = pcmcia_socket_dev_resume(dev);
++ return ret;
++}
++
+ static struct device_driver i82365_driver = {
+ .name = "i82365",
+ .bus = &platform_bus_type,
+- .suspend = pcmcia_socket_dev_suspend,
+- .resume = pcmcia_socket_dev_resume,
++ .suspend = i82365_suspend,
++ .resume = i82365_resume,
+ };
+
+ static struct platform_device i82365_device = {
+Index: linux-2.6.0-test5/drivers/pcmcia/ricoh.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pcmcia/ricoh.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pcmcia/ricoh.h 2003-09-27 11:38:29.241083064 +0800
+@@ -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
+Index: linux-2.6.0-test5/drivers/pcmcia/rsrc_mgr.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pcmcia/rsrc_mgr.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pcmcia/rsrc_mgr.c 2003-09-27 11:38:29.295074856 +0800
+@@ -491,7 +491,7 @@
+
+ void validate_mem(struct pcmcia_socket *s)
+ {
+- resource_map_t *m, *n;
++ resource_map_t *m, mm;
+ static u_char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
+ static int hi = 0, lo = 0;
+ u_long b, i, ok = 0;
+@@ -510,18 +510,18 @@
+ }
+ if (lo++)
+ goto out;
+- for (m = mem_db.next; m != &mem_db; m = n) {
+- n = m->next;
++ for (m = mem_db.next; m != &mem_db; m = mm.next) {
++ mm = *m;
+ /* Only probe < 1 MB */
+- if (m->base >= 0x100000) continue;
+- if ((m->base | m->num) & 0xffff) {
+- ok += do_mem_probe(m->base, m->num, s);
++ if (mm.base >= 0x100000) continue;
++ if ((mm.base | mm.num) & 0xffff) {
++ ok += do_mem_probe(mm.base, mm.num, s);
+ continue;
+ }
+ /* Special probe for 64K-aligned block */
+ for (i = 0; i < 4; i++) {
+ b = order[i] << 12;
+- if ((b >= m->base) && (b+0x10000 <= m->base+m->num)) {
++ if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) {
+ if (ok >= mem_limit)
+ sub_interval(&mem_db, b, 0x10000);
+ else
+@@ -537,14 +537,14 @@
+
+ void validate_mem(struct pcmcia_socket *s)
+ {
+- resource_map_t *m, *n;
++ resource_map_t *m, mm;
+ static int done = 0;
+
+ if (probe_mem && done++ == 0) {
+ down(&rsrc_sem);
+- for (m = mem_db.next; m != &mem_db; m = n) {
+- n = m->next;
+- if (do_mem_probe(m->base, m->num, s))
++ for (m = mem_db.next; m != &mem_db; m = mm.next) {
++ mm = *m;
++ if (do_mem_probe(mm.base, mm.num, s))
+ break;
+ }
+ up(&rsrc_sem);
+Index: linux-2.6.0-test5/drivers/pcmcia/sa1100_assabet.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pcmcia/sa1100_assabet.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pcmcia/sa1100_assabet.c 2003-09-27 11:38:29.318071360 +0800
+@@ -4,7 +4,6 @@
+ * PCMCIA implementation routines for Assabet
+ *
+ */
+-#include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+Index: linux-2.6.0-test5/drivers/pcmcia/sa1100_generic.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pcmcia/sa1100_generic.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pcmcia/sa1100_generic.c 2003-09-27 11:38:29.337068472 +0800
+@@ -100,13 +100,29 @@
+ return ret;
+ }
+
++static int sa11x0_drv_pcmcia_suspend(struct device *dev, u32 state, u32 level)
++{
++ int ret = 0;
++ if (level == SUSPEND_SAVE_STATE)
++ ret = pcmcia_socket_dev_suspend(dev, state);
++ return ret;
++}
++
++static int sa11x0_drv_pcmcia_resume(struct device *dev, u32 level)
++{
++ int ret = 0;
++ if (level == RESUME_RESTORE_STATE)
++ ret = pcmcia_socket_dev_resume(dev);
++ return ret;
++}
++
+ static struct device_driver sa11x0_pcmcia_driver = {
+ .probe = sa11x0_drv_pcmcia_probe,
+ .remove = sa11xx_drv_pcmcia_remove,
+ .name = "sa11x0-pcmcia",
+ .bus = &platform_bus_type,
+- .suspend = pcmcia_socket_dev_suspend,
+- .resume = pcmcia_socket_dev_resume,
++ .suspend = sa11x0_drv_pcmcia_suspend,
++ .resume = sa11x0_drv_pcmcia_resume,
+ };
+
+ /* sa11x0_pcmcia_init()
+Index: linux-2.6.0-test5/drivers/pcmcia/sa1100_simpad.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pcmcia/sa1100_simpad.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pcmcia/sa1100_simpad.c 2003-09-27 11:38:29.382061632 +0800
+@@ -13,6 +13,7 @@
+ #include <asm/hardware.h>
+ #include <asm/mach-types.h>
+ #include <asm/irq.h>
++#include <asm/arch/simpad.h>
+ #include "sa1100_generic.h"
+
+ extern long get_cs3_shadow(void);
+@@ -25,9 +26,6 @@
+
+ static int simpad_pcmcia_hw_init(struct sa1100_pcmcia_socket *skt)
+ {
+- set_cs3_bit(PCMCIA_RESET);
+- clear_cs3_bit(PCMCIA_BUFF_DIS);
+- clear_cs3_bit(PCMCIA_RESET);
+
+ clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
+
+@@ -71,7 +69,7 @@
+ simpad_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt,
+ const socket_state_t *state)
+ {
+- unsigned long value, flags;
++ unsigned long flags;
+
+ local_irq_save(flags);
+
+@@ -82,8 +80,8 @@
+ break;
+
+ case 33:
+- clear_cs3_bit(VCC_3V_EN|EN0);
+- set_cs3_bit(VCC_5V_EN|EN1);
++ clear_cs3_bit(VCC_3V_EN|EN1);
++ set_cs3_bit(VCC_5V_EN|EN0);
+ break;
+
+ case 50:
+@@ -99,7 +97,7 @@
+ return -1;
+ }
+
+- /* Silently ignore Vpp, output enable, speaker enable. */
++
+ local_irq_restore(flags);
+
+ return 0;
+@@ -113,6 +111,7 @@
+ static void simpad_pcmcia_socket_suspend(struct sa1100_pcmcia_socket *skt)
+ {
+ sa11xx_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
++ set_cs3_bit(PCMCIA_RESET);
+ }
+
+ static struct pcmcia_low_level simpad_pcmcia_ops = {
+Index: linux-2.6.0-test5/drivers/pcmcia/sa1111_generic.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pcmcia/sa1111_generic.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pcmcia/sa1111_generic.c 2003-09-27 11:38:29.438053120 +0800
+@@ -5,6 +5,7 @@
+ * basically means we handle everything except controlling the
+ * power. Power is machine specific...
+ */
++#include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/ioport.h>
+@@ -171,12 +172,12 @@
+
+ static int pcmcia_suspend(struct sa1111_dev *dev, u32 state)
+ {
+- return pcmcia_socket_dev_suspend(&dev->dev, state, SUSPEND_SAVE_STATE);
++ return pcmcia_socket_dev_suspend(&dev->dev, state);
+ }
+
+ static int pcmcia_resume(struct sa1111_dev *dev)
+ {
+- return pcmcia_socket_dev_resume(&dev->dev, RESUME_RESTORE_STATE);
++ return pcmcia_socket_dev_resume(&dev->dev);
+ }
+
+ static struct sa1111_driver pcmcia_driver = {
+Index: linux-2.6.0-test5/drivers/pcmcia/sa11xx_core.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pcmcia/sa11xx_core.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pcmcia/sa11xx_core.c 2003-09-27 11:38:29.468048560 +0800
+@@ -556,7 +556,6 @@
+ { SS_DMA_MODE, "SS_DMA_MODE" },
+ { SS_SPKR_ENA, "SS_SPKR_ENA" },
+ { SS_OUTPUT_ENA, "SS_OUTPUT_ENA" },
+- { SS_DEBOUNCED, "SS_DEBOUNCED" },
+ };
+
+ static void
+Index: linux-2.6.0-test5/drivers/pcmcia/tcic.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pcmcia/tcic.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pcmcia/tcic.c 2003-09-27 11:38:29.520040656 +0800
+@@ -362,11 +362,27 @@
+
+ /*====================================================================*/
+
++static int tcic_drv_suspend(struct device *dev, u32 state, u32 level)
++{
++ int ret = 0;
++ if (level == SUSPEND_SAVE_STATE)
++ ret = pcmcia_socket_dev_suspend(dev, state);
++ return ret;
++}
++
++static int tcic_drv_resume(struct device *dev, u32 level)
++{
++ int ret = 0;
++ if (level == RESUME_RESTORE_STATE)
++ ret = pcmcia_socket_dev_resume(dev);
++ return ret;
++}
++
+ static struct device_driver tcic_driver = {
+ .name = "tcic-pcmcia",
+ .bus = &platform_bus_type,
+- .suspend = pcmcia_socket_dev_suspend,
+- .resume = pcmcia_socket_dev_resume,
++ .suspend = tcic_drv_suspend,
++ .resume = tcic_drv_resume,
+ };
+
+ static struct platform_device tcic_device = {
+Index: linux-2.6.0-test5/drivers/pcmcia/yenta_socket.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pcmcia/yenta_socket.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pcmcia/yenta_socket.c 2003-09-27 11:38:29.564033968 +0800
+@@ -248,10 +248,6 @@
+ struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
+ u16 bridge;
+
+- if (state->flags & SS_DEBOUNCED) {
+- /* The insertion debounce period has ended. Clear any pending insertion events */
+- state->flags &= ~SS_DEBOUNCED; /* SS_DEBOUNCED is oneshot */
+- }
+ yenta_set_power(socket, state);
+ socket->io_irq = state->io_irq;
+ bridge = config_readw(socket, CB_BRIDGE_CONTROL) & ~(CB_BRIDGE_CRST | CB_BRIDGE_INTR);
+@@ -937,7 +933,7 @@
+ struct yenta_socket *socket = pci_get_drvdata(dev);
+ int ret;
+
+- ret = pcmcia_socket_dev_suspend(&dev->dev, state, SUSPEND_SAVE_STATE);
++ ret = pcmcia_socket_dev_suspend(&dev->dev, state);
+
+ if (socket) {
+ if (socket->type && socket->type->save_state)
+@@ -969,7 +965,7 @@
+ socket->type->restore_state(socket);
+ }
+
+- return pcmcia_socket_dev_resume(&dev->dev, RESUME_RESTORE_STATE);
++ return pcmcia_socket_dev_resume(&dev->dev);
+ }
+
+
+Index: linux-2.6.0-test5/drivers/pnp/card.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pnp/card.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pnp/card.c 2003-09-27 11:38:29.600028496 +0800
+@@ -62,8 +62,14 @@
+ if (drv->probe) {
+ if (drv->probe(clink, id)>=0)
+ return 1;
+- else
++ else {
++ struct pnp_dev * dev;
++ card_for_each_dev(card, dev) {
++ if (dev->card_link == clink)
++ pnp_release_card_device(dev);
++ }
+ kfree(clink);
++ }
+ } else
+ return 1;
+ }
+Index: linux-2.6.0-test5/drivers/pnp/isapnp/compat.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pnp/isapnp/compat.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pnp/isapnp/compat.c 2003-09-27 11:38:29.654020288 +0800
+@@ -9,7 +9,6 @@
+ /* TODO: see if more isapnp functions are needed here */
+
+ #include <linux/config.h>
+-#include <linux/version.h>
+ #include <linux/module.h>
+ #include <linux/isapnp.h>
+ #include <linux/string.h>
+Index: linux-2.6.0-test5/drivers/pnp/isapnp/core.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pnp/isapnp/core.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pnp/isapnp/core.c 2003-09-27 11:38:29.702012992 +0800
+@@ -35,7 +35,6 @@
+ */
+
+ #include <linux/config.h>
+-#include <linux/version.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+@@ -65,7 +64,6 @@
+ MODULE_PARM_DESC(isapnp_rdp, "ISA Plug & Play read data port");
+ MODULE_PARM(isapnp_reset, "i");
+ MODULE_PARM_DESC(isapnp_reset, "ISA Plug & Play reset all cards");
+-MODULE_PARM(isapnp_allow_dma0, "i");
+ MODULE_PARM(isapnp_verbose, "i");
+ MODULE_PARM_DESC(isapnp_verbose, "ISA Plug & Play verbose mode");
+ MODULE_LICENSE("GPL");
+Index: linux-2.6.0-test5/drivers/pnp/isapnp/proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pnp/isapnp/proc.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pnp/isapnp/proc.c 2003-09-27 11:38:29.754005088 +0800
+@@ -20,7 +20,6 @@
+ */
+
+ #include <linux/config.h>
+-#include <linux/version.h>
+ #include <linux/module.h>
+ #include <linux/isapnp.h>
+ #include <linux/proc_fs.h>
+Index: linux-2.6.0-test5/drivers/pnp/pnpbios/bioscalls.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pnp/pnpbios/bioscalls.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pnp/pnpbios/bioscalls.c 2003-09-27 11:38:29.792999160 +0800
+@@ -23,41 +23,7 @@
+ #include <asm/system.h>
+ #include <asm/byteorder.h>
+
+-
+-/* PnP BIOS signature: "$PnP" */
+-#define PNP_SIGNATURE (('$' << 0) + ('P' << 8) + ('n' << 16) + ('P' << 24))
+-
+-#pragma pack(1)
+-union pnp_bios_expansion_header {
+- struct {
+- u32 signature; /* "$PnP" */
+- u8 version; /* in BCD */
+- u8 length; /* length in bytes, currently 21h */
+- u16 control; /* system capabilities */
+- u8 checksum; /* all bytes must add up to 0 */
+-
+- u32 eventflag; /* phys. address of the event flag */
+- u16 rmoffset; /* real mode entry point */
+- u16 rmcseg;
+- u16 pm16offset; /* 16 bit protected mode entry */
+- u32 pm16cseg;
+- u32 deviceID; /* EISA encoded system ID or 0 */
+- u16 rmdseg; /* real mode data segment */
+- u32 pm16dseg; /* 16 bit pm data segment base */
+- } fields;
+- char chars[0x21]; /* To calculate the checksum */
+-};
+-#pragma pack()
+-
+-static union pnp_bios_expansion_header * pnp_bios_hdr = NULL;
+-
+-/*
+- * Call this only after init time
+- */
+-static int pnp_bios_present(void)
+-{
+- return (pnp_bios_hdr != NULL);
+-}
++#include "pnpbios.h"
+
+ static struct {
+ u16 offset;
+@@ -557,10 +523,10 @@
+
+
+ /*
+- * Probing and Initialization
++ * Initialization
+ */
+
+-static void pnpbios_prepare_bios_calls(union pnp_bios_expansion_header *header)
++void pnpbios_calls_init(union pnp_bios_install_struct *header)
+ {
+ int i;
+ spin_lock_init(&pnp_bios_lock);
+@@ -576,52 +542,3 @@
+ Q_SET_SEL(i, PNP_DS, header->fields.pm16dseg, 64 * 1024);
+ }
+ }
+-
+-int pnpbios_probe_installation(void)
+-{
+- union pnp_bios_expansion_header *check;
+- u8 sum;
+- int length, i;
+-
+- printk(KERN_INFO "PnPBIOS: Scanning system for PnP BIOS support...\n");
+-
+- /*
+- * Search the defined area (0xf0000-0xffff0) for a valid PnP BIOS
+- * structure and, if one is found, sets up the selectors and
+- * entry points
+- */
+- for (check = (union pnp_bios_expansion_header *) __va(0xf0000);
+- check < (union pnp_bios_expansion_header *) __va(0xffff0);
+- ((void *) (check)) += 16) {
+- if (check->fields.signature != PNP_SIGNATURE)
+- continue;
+- printk(KERN_INFO "PnPBIOS: Found PnP BIOS installation structure at 0x%p\n", check);
+- length = check->fields.length;
+- if (!length) {
+- printk(KERN_ERR "PnPBIOS: installation structure is invalid, skipping\n");
+- continue;
+- }
+- for (sum = 0, i = 0; i < length; i++)
+- sum += check->chars[i];
+- if (sum) {
+- printk(KERN_ERR "PnPBIOS: installation structure is corrupted, skipping\n");
+- continue;
+- }
+- if (check->fields.version < 0x10) {
+- printk(KERN_WARNING "PnPBIOS: PnP BIOS version %d.%d is not supported\n",
+- check->fields.version >> 4,
+- check->fields.version & 15);
+- continue;
+- }
+- printk(KERN_INFO "PnPBIOS: PnP BIOS version %d.%d, entry 0x%x:0x%x, dseg 0x%x\n",
+- check->fields.version >> 4, check->fields.version & 15,
+- check->fields.pm16cseg, check->fields.pm16offset,
+- check->fields.pm16dseg);
+- pnp_bios_hdr = check;
+- pnpbios_prepare_bios_calls(check);
+- return 1;
+- }
+-
+- printk(KERN_INFO "PnPBIOS: PnP BIOS support was not detected.\n");
+- return 0;
+-}
+Index: linux-2.6.0-test5/drivers/pnp/pnpbios/core.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pnp/pnpbios/core.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pnp/pnpbios/core.c 2003-09-27 11:38:29.835992624 +0800
+@@ -74,6 +74,13 @@
+ *
+ */
+
++static union pnp_bios_install_struct * pnp_bios_install = NULL;
++
++int pnp_bios_present(void)
++{
++ return (pnp_bios_install != NULL);
++}
++
+ struct pnp_dev_node_info node_info;
+
+ void *pnpbios_kmalloc(size_t size, int f)
+@@ -410,7 +417,56 @@
+ __setup("pnpbios=", pnpbios_setup);
+ #endif
+
+-subsys_initcall(pnpbios_init);
++/* PnP BIOS signature: "$PnP" */
++#define PNP_SIGNATURE (('$' << 0) + ('P' << 8) + ('n' << 16) + ('P' << 24))
++
++int __init pnpbios_probe_system(void)
++{
++ union pnp_bios_install_struct *check;
++ u8 sum;
++ int length, i;
++
++ printk(KERN_INFO "PnPBIOS: Scanning system for PnP BIOS support...\n");
++
++ /*
++ * Search the defined area (0xf0000-0xffff0) for a valid PnP BIOS
++ * structure and, if one is found, sets up the selectors and
++ * entry points
++ */
++ for (check = (union pnp_bios_install_struct *) __va(0xf0000);
++ check < (union pnp_bios_install_struct *) __va(0xffff0);
++ ((void *) (check)) += 16) {
++ if (check->fields.signature != PNP_SIGNATURE)
++ continue;
++ printk(KERN_INFO "PnPBIOS: Found PnP BIOS installation structure at 0x%p\n", check);
++ length = check->fields.length;
++ if (!length) {
++ printk(KERN_ERR "PnPBIOS: installation structure is invalid, skipping\n");
++ continue;
++ }
++ for (sum = 0, i = 0; i < length; i++)
++ sum += check->chars[i];
++ if (sum) {
++ printk(KERN_ERR "PnPBIOS: installation structure is corrupted, skipping\n");
++ continue;
++ }
++ if (check->fields.version < 0x10) {
++ printk(KERN_WARNING "PnPBIOS: PnP BIOS version %d.%d is not supported\n",
++ check->fields.version >> 4,
++ check->fields.version & 15);
++ continue;
++ }
++ printk(KERN_INFO "PnPBIOS: PnP BIOS version %d.%d, entry 0x%x:0x%x, dseg 0x%x\n",
++ check->fields.version >> 4, check->fields.version & 15,
++ check->fields.pm16cseg, check->fields.pm16offset,
++ check->fields.pm16dseg);
++ pnp_bios_install = check;
++ return 1;
++ }
++
++ printk(KERN_INFO "PnPBIOS: PnP BIOS support was not detected.\n");
++ return 0;
++}
+
+ int __init pnpbios_init(void)
+ {
+@@ -421,24 +477,30 @@
+ }
+
+ /* scan the system for pnpbios support */
+- if (!pnpbios_probe_installation())
++ if (!pnpbios_probe_system())
+ return -ENODEV;
+
++ /* make preparations for bios calls */
++ pnpbios_calls_init(pnp_bios_install);
++
+ /* read the node info */
+- if (pnp_bios_dev_node_info(&node_info)) {
++ ret = pnp_bios_dev_node_info(&node_info);
++ if (ret) {
+ printk(KERN_ERR "PnPBIOS: Unable to get node info. Aborting.\n");
+- return -EIO;
++ return ret;
+ }
+
+ /* register with the pnp layer */
+- pnp_register_protocol(&pnpbios_protocol);
++ ret = pnp_register_protocol(&pnpbios_protocol);
++ if (ret) {
++ printk(KERN_ERR "PnPBIOS: Unable to register driver. Aborting.\n");
++ return ret;
++ }
+
+-#ifdef CONFIG_PROC_FS
+ /* start the proc interface */
+ ret = pnpbios_proc_init();
+ if (ret)
+- return ret;
+-#endif
++ printk(KERN_ERR "PnPBIOS: Failed to create proc interface.\n");
+
+ /* scan for pnpbios devices */
+ build_devlist();
+@@ -446,6 +508,8 @@
+ return 0;
+ }
+
++subsys_initcall(pnpbios_init);
++
+ static int __init pnpbios_thread_init(void)
+ {
+ #ifdef CONFIG_HOTPLUG
+Index: linux-2.6.0-test5/drivers/pnp/pnpbios/pnpbios.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pnp/pnpbios/pnpbios.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pnp/pnpbios/pnpbios.h 2003-09-27 11:38:29.888984568 +0800
+@@ -1,11 +1,47 @@
+ /*
+- * pnpbios.h - contains definitions for functions used only locally.
++ * pnpbios.h - contains local definitions
+ */
+
++#pragma pack(1)
++union pnp_bios_install_struct {
++ struct {
++ u32 signature; /* "$PnP" */
++ u8 version; /* in BCD */
++ u8 length; /* length in bytes, currently 21h */
++ u16 control; /* system capabilities */
++ u8 checksum; /* all bytes must add up to 0 */
++
++ u32 eventflag; /* phys. address of the event flag */
++ u16 rmoffset; /* real mode entry point */
++ u16 rmcseg;
++ u16 pm16offset; /* 16 bit protected mode entry */
++ u32 pm16cseg;
++ u32 deviceID; /* EISA encoded system ID or 0 */
++ u16 rmdseg; /* real mode data segment */
++ u32 pm16dseg; /* 16 bit pm data segment base */
++ } fields;
++ char chars[0x21]; /* To calculate the checksum */
++};
++#pragma pack()
++
++extern int pnp_bios_present(void);
++extern int pnpbios_dont_use_current_config;
++extern void *pnpbios_kmalloc(size_t size, int f);
++
+ extern int pnpbios_parse_data_stream(struct pnp_dev *dev, struct pnp_bios_node * node);
+ extern int pnpbios_read_resources_from_node(struct pnp_resource_table *res, struct pnp_bios_node * node);
+ extern int pnpbios_write_resources_to_node(struct pnp_resource_table *res, struct pnp_bios_node * node);
+ extern void pnpid32_to_pnpid(u32 id, char *str);
+
+ extern void pnpbios_print_status(const char * module, u16 status);
+-extern int pnpbios_probe_installation(void);
++extern void pnpbios_calls_init(union pnp_bios_install_struct * header);
++
++#ifdef CONFIG_PROC_FS
++extern int pnpbios_interface_attach_device(struct pnp_bios_node * node);
++extern int pnpbios_proc_init (void);
++extern void pnpbios_proc_exit (void);
++#else
++static inline int pnpbios_interface_attach_device(struct pnp_bios_node * node) { return 0; }
++static inline int pnpbios_proc_init (void) { return 0; }
++static inline void pnpbios_proc_exit (void) { ; }
++#endif /* CONFIG_PROC */
+Index: linux-2.6.0-test5/drivers/pnp/pnpbios/proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pnp/pnpbios/proc.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pnp/pnpbios/proc.c 2003-09-27 11:38:29.927978640 +0800
+@@ -31,6 +31,8 @@
+
+ #include <asm/uaccess.h>
+
++#include "pnpbios.h"
++
+ static struct proc_dir_entry *proc_pnp = NULL;
+ static struct proc_dir_entry *proc_pnp_boot = NULL;
+
+@@ -213,6 +215,9 @@
+ struct proc_dir_entry *ent;
+
+ sprintf(name, "%02x", node->handle);
++
++ if (!proc_pnp)
++ return -EIO;
+ if ( !pnpbios_dont_use_current_config ) {
+ ent = create_proc_entry(name, 0, proc_pnp);
+ if (ent) {
+@@ -221,6 +226,9 @@
+ ent->data = (void *)(long)(node->handle);
+ }
+ }
++
++ if (!proc_pnp_boot)
++ return -EIO;
+ ent = create_proc_entry(name, 0, proc_pnp_boot);
+ if (ent) {
+ ent->read_proc = proc_read_node;
+@@ -228,6 +236,7 @@
+ ent->data = (void *)(long)(node->handle+0x100);
+ return 0;
+ }
++
+ return -EIO;
+ }
+
+@@ -257,8 +266,9 @@
+ {
+ int i;
+ char name[3];
+-
+- if (!proc_pnp) return;
++
++ if (!proc_pnp)
++ return;
+
+ for (i=0; i<0xff; i++) {
+ sprintf(name, "%02x", i);
+Index: linux-2.6.0-test5/drivers/pnp/quirks.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pnp/quirks.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pnp/quirks.c 2003-09-27 11:38:29.987969520 +0800
+@@ -111,28 +111,6 @@
+ return;
+ }
+
+-extern int pnp_allow_dma0;
+-static void quirk_opl3sax_resources(struct pnp_dev *dev)
+-{
+- /* This really isn't a device quirk but isapnp core code
+- * doesn't allow a DMA channel of 0, afflicted card is an
+- * OPL3Sax where x=4.
+- */
+- struct pnp_option *res;
+- int max;
+- res = dev->dependent;
+- max = 0;
+- for (; res; res = res->next) {
+- if (res->dma->map > max)
+- max = res->dma->map;
+- }
+- if (max == 1 && pnp_allow_dma0 == -1) {
+- printk(KERN_INFO "pnp: opl3sa4 quirk: Allowing dma 0.\n");
+- pnp_allow_dma0 = 1;
+- }
+- return;
+-}
+-
+ /*
+ * PnP Quirks
+ * Cards or devices that need some tweaking due to incomplete resource info
+@@ -153,7 +131,6 @@
+ { "CTL0043", quirk_sb16audio_resources },
+ { "CTL0044", quirk_sb16audio_resources },
+ { "CTL0045", quirk_sb16audio_resources },
+- { "YMH0021", quirk_opl3sax_resources },
+ { "" }
+ };
+
+@@ -170,4 +147,3 @@
+ i++;
+ }
+ }
+-
+Index: linux-2.6.0-test5/drivers/pnp/resource.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pnp/resource.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pnp/resource.c 2003-09-27 11:38:30.050959944 +0800
+@@ -21,8 +21,6 @@
+ #include <linux/pnp.h>
+ #include "base.h"
+
+-int pnp_allow_dma0 = -1; /* allow dma 0 during auto activation:
+- * -1=off (:default), 0=off (set by user), 1=on */
+ int pnp_skip_pci_scan; /* skip PCI resource scanning */
+ int pnp_reserve_irq[16] = { [0 ... 15] = -1 }; /* reserve (don't use) some IRQ */
+ int pnp_reserve_dma[8] = { [0 ... 7] = -1 }; /* reserve (don't use) some DMA */
+@@ -426,7 +424,7 @@
+
+ int pnp_check_dma(struct pnp_dev * dev, int idx)
+ {
+- int tmp, mindma = 1;
++ int tmp;
+ struct pnp_dev *tdev;
+ unsigned long * dma = &dev->res.dma_resource[idx].start;
+
+@@ -435,9 +433,7 @@
+ return 1;
+
+ /* check if the resource is valid */
+- if (pnp_allow_dma0 == 1)
+- mindma = 0;
+- if (*dma < mindma || *dma == 4 || *dma > 7)
++ if (*dma < 0 || *dma == 4 || *dma > 7)
+ return 0;
+
+ /* check if the resource is reserved */
+@@ -488,16 +484,6 @@
+ EXPORT_SYMBOL(pnp_register_mem_resource);
+
+
+-/* format is: allowdma0 */
+-
+-static int __init pnp_allowdma0(char *str)
+-{
+- pnp_allow_dma0 = 1;
+- return 1;
+-}
+-
+-__setup("allowdma0", pnp_allowdma0);
+-
+ /* format is: pnp_reserve_irq=irq1[,irq2] .... */
+
+ static int __init pnp_setup_reserve_irq(char *str)
+Index: linux-2.6.0-test5/drivers/s390/block/dasd_int.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/s390/block/dasd_int.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/s390/block/dasd_int.h 2003-09-27 11:38:30.068957208 +0800
+@@ -14,7 +14,8 @@
+
+ #ifdef __KERNEL__
+
+-#define DASD_PER_MAJOR ( 1U<<(MINORBITS-DASD_PARTN_BITS))
++/* we keep old device allocation scheme; IOW, minors are still in 0..255 */
++#define DASD_PER_MAJOR ( 1U<<(8-DASD_PARTN_BITS))
+ #define DASD_PARTN_MASK ((1 << DASD_PARTN_BITS) - 1)
+
+ /*
+Index: linux-2.6.0-test5/drivers/sbus/char/bpp.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/sbus/char/bpp.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/sbus/char/bpp.c 2003-09-27 11:38:30.124948696 +0800
+@@ -12,7 +12,6 @@
+
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/fs.h>
+ #include <linux/errno.h>
+ #include <linux/sched.h>
+Index: linux-2.6.0-test5/drivers/sbus/char/cpwatchdog.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/sbus/char/cpwatchdog.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/sbus/char/cpwatchdog.c 2003-09-27 11:38:30.134947176 +0800
+@@ -17,7 +17,6 @@
+
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/fs.h>
+ #include <linux/errno.h>
+ #include <linux/major.h>
+Index: linux-2.6.0-test5/drivers/sbus/char/display7seg.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/sbus/char/display7seg.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/sbus/char/display7seg.c 2003-09-27 11:38:30.180940184 +0800
+@@ -9,7 +9,6 @@
+
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/fs.h>
+ #include <linux/errno.h>
+ #include <linux/major.h>
+Index: linux-2.6.0-test5/drivers/scsi/aic7xxx/aicasm/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/scsi/aic7xxx/aicasm/Makefile 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/scsi/aic7xxx/aicasm/Makefile 2003-09-27 11:38:30.225933344 +0800
+@@ -49,14 +49,18 @@
+ clean:
+ rm -f $(clean-files)
+
+-aicasm_gram.c aicasm_gram.h: aicasm_gram.y
++aicasm_gram.c: aicasm_gram.h
++ mv $(<:.h=).tab.c $(<:.h=.c)
++
++aicasm_gram.h: aicasm_gram.y
+ $(YACC) $(YFLAGS) -b $(<:.y=) $<
+- mv $(<:.y=).tab.c $(<:.y=.c)
+ mv $(<:.y=).tab.h $(<:.y=.h)
+
+-aicasm_macro_gram.c aicasm_macro_gram.h: aicasm_macro_gram.y
++aicasm_macro_gram.c: aicasm_macro_gram.h
++ mv $(<:.h=).tab.c $(<:.h=.c)
++
++aicasm_macro_gram.h: aicasm_macro_gram.y
+ $(YACC) $(YFLAGS) -b $(<:.y=) -p mm $<
+- mv $(<:.y=).tab.c $(<:.y=.c)
+ mv $(<:.y=).tab.h $(<:.y=.h)
+
+ aicasm_scan.c: aicasm_scan.l
+Index: linux-2.6.0-test5/drivers/scsi/aic7xxx/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/scsi/aic7xxx/Makefile 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/scsi/aic7xxx/Makefile 2003-09-27 11:38:31.142793960 +0800
+@@ -58,7 +58,9 @@
+ -p $(obj)/aic7xxx_reg_print.c -i aic7xxx_osm.h
+
+ ifeq ($(CONFIG_AIC7XXX_BUILD_FIRMWARE),y)
+-$(aic7xxx-gen-y): $(src)/aic7xxx.seq $(src)/aic7xxx.reg $(obj)/aicasm/aicasm
++$(aic7xxx-gen-y): $(src)/aic7xxx.seq
++
++$(src)/aic7xxx.seq: $(obj)/aicasm/aicasm $(src)/aic7xxx.reg
+ $(obj)/aicasm/aicasm -I$(src) -r $(obj)/aic7xxx_reg.h \
+ $(aicasm-7xxx-opts-y) -o $(obj)/aic7xxx_seq.h \
+ $(src)/aic7xxx.seq
+@@ -72,7 +74,9 @@
+ -p $(obj)/aic79xx_reg_print.c -i aic79xx_osm.h
+
+ ifeq ($(CONFIG_AIC79XX_BUILD_FIRMWARE),y)
+-$(aic79xx-gen-y): $(src)/aic79xx.seq $(src)/aic79xx.reg $(obj)/aicasm/aicasm
++$(aic79xx-gen-y): $(src)/aic79xx.seq
++
++$(src)/aic79xx.seq: $(obj)/aicasm/aicasm $(src)/aic79xx.reg
+ $(obj)/aicasm/aicasm -I$(src) -r $(obj)/aic79xx_reg.h \
+ $(aicasm-79xx-opts-y) -o $(obj)/aic79xx_seq.h \
+ $(src)/aic79xx.seq
+Index: linux-2.6.0-test5/drivers/scsi/aic7xxx_old/aic7xxx_proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/scsi/aic7xxx_old/aic7xxx_proc.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/scsi/aic7xxx_old/aic7xxx_proc.c 2003-09-27 11:38:31.227781040 +0800
+@@ -92,7 +92,7 @@
+
+ HBAptr = NULL;
+
+- for(p=first_aic7xxx; p->host != HBAptr; p=p->next)
++ for(p=first_aic7xxx; p && p->host != HBAptr; p=p->next)
+ ;
+
+ if (!p)
+Index: linux-2.6.0-test5/drivers/scsi/gdth.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/scsi/gdth.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/scsi/gdth.c 2003-09-27 11:38:31.324766296 +0800
+@@ -2048,7 +2048,7 @@
+ for (j = 0; j < 12; ++j)
+ rtc[j] = CMOS_READ(j);
+ } while (rtc[0] != CMOS_READ(0));
+- spin_lock_irqrestore(&rtc_lock, flags);
++ spin_unlock_irqrestore(&rtc_lock, flags);
+ TRACE2(("gdth_search_drives(): RTC: %x/%x/%x\n",*(ulong32 *)&rtc[0],
+ *(ulong32 *)&rtc[4], *(ulong32 *)&rtc[8]));
+ /* 3. send to controller firmware */
+Index: linux-2.6.0-test5/drivers/scsi/imm.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/scsi/imm.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/scsi/imm.h 2003-09-27 11:38:31.375758544 +0800
+@@ -100,8 +100,9 @@
+ [IMM_NIBBLE] = "SPP",
+ [IMM_PS2] = "PS/2",
+ [IMM_EPP_8] = "EPP 8 bit",
+-#ifdef CONFIG_SCSI_IZIP_EPP16
+ [IMM_EPP_16] = "EPP 16 bit",
++#ifdef CONFIG_SCSI_IZIP_EPP16
++ [IMM_EPP_32] = "EPP 16 bit",
+ #else
+ [IMM_EPP_32] = "EPP 32 bit",
+ #endif
+Index: linux-2.6.0-test5/drivers/scsi/NCR5380.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/scsi/NCR5380.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/scsi/NCR5380.c 2003-09-27 11:38:31.519736656 +0800
+@@ -372,7 +372,7 @@
+ {
+ r = NCR5380_read(reg);
+ if((r & bit) == val)
+- return r;
++ return 0;
+ cpu_relax();
+ }
+
+@@ -381,7 +381,7 @@
+ {
+ r = NCR5380_read(reg);
+ if((r & bit) == val)
+- return r;
++ return 0;
+ if(!in_interrupt())
+ yield();
+ else
+Index: linux-2.6.0-test5/drivers/scsi/sym53c8xx_2/sym_glue.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/scsi/sym53c8xx_2/sym_glue.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/scsi/sym53c8xx_2/sym_glue.c 2003-09-27 11:38:31.628720088 +0800
+@@ -2287,8 +2287,7 @@
+ }
+
+ if (chip->features & FE_WRIE) {
+- if (pci_set_mwi(pdev))
+- return -1;
++ pci_set_mwi(pdev);
+ }
+
+ /*
+Index: linux-2.6.0-test5/drivers/scsi/sym53c8xx_2/sym_hipd.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/scsi/sym53c8xx_2/sym_hipd.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/scsi/sym53c8xx_2/sym_hipd.c 2003-09-27 11:38:31.747702000 +0800
+@@ -831,7 +831,8 @@
+ }
+ #endif
+
+- if (period <= 250) np->minsync = 10;
++ if (period == 250) np->minsync = 9;
++ else if (period <= 250) np->minsync = 10;
+ else if (period <= 303) np->minsync = 11;
+ else if (period <= 500) np->minsync = 12;
+ else np->minsync = (period + 40 - 1) / 40;
+Index: linux-2.6.0-test5/drivers/serial/8250.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/serial/8250.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/serial/8250.c 2003-09-27 11:38:31.841687712 +0800
+@@ -122,6 +122,7 @@
+ struct uart_port port;
+ struct timer_list timer; /* "no irq" timer */
+ struct list_head list; /* ports on this IRQ */
++ unsigned int capabilities; /* port capabilities */
+ unsigned short rev;
+ unsigned char acr;
+ unsigned char ier;
+@@ -683,6 +684,7 @@
+ serial_outp(up, UART_LCR, save_lcr);
+
+ up->port.fifosize = uart_config[up->port.type].dfl_xmit_fifo_size;
++ up->capabilities = uart_config[up->port.type].flags;
+
+ if (up->port.type == PORT_UNKNOWN)
+ goto out;
+@@ -823,7 +825,7 @@
+ if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
+ tty->flip.work.func((void *)tty);
+ if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+- return; // if TTY_DONT_FLIP is set
++ return; /* if TTY_DONT_FLIP is set */
+ }
+ ch = serial_inp(up, UART_RX);
+ *tty->flip.char_buf_ptr = ch;
+@@ -1184,12 +1186,23 @@
+ spin_unlock_irqrestore(&up->port.lock, flags);
+ }
+
++#ifdef CONFIG_KGDB
++static int kgdb_irq = -1;
++#endif
++
+ static int serial8250_startup(struct uart_port *port)
+ {
+ struct uart_8250_port *up = (struct uart_8250_port *)port;
+ unsigned long flags;
+ int retval;
+
++#ifdef CONFIG_KGDB
++ if (up->port.irq == kgdb_irq)
++ return -EBUSY;
++#endif
++
++ up->capabilities = uart_config[up->port.type].flags;
++
+ if (up->port.type == PORT_16C950) {
+ /* Wake up and initialize UART */
+ up->acr = 0;
+@@ -1215,7 +1228,7 @@
+ * Clear the FIFO buffers and disable them.
+ * (they will be reeanbled in set_termios())
+ */
+- if (uart_config[up->port.type].flags & UART_CLEAR_FIFO) {
++ if (up->capabilities & UART_CLEAR_FIFO) {
+ serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+ serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO |
+ UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
+@@ -1428,7 +1441,7 @@
+ up->rev == 0x5201)
+ quot ++;
+
+- if (uart_config[up->port.type].flags & UART_USE_FIFO) {
++ if (up->capabilities & UART_USE_FIFO) {
+ if (baud < 2400)
+ fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
+ #ifdef CONFIG_SERIAL_8250_RSA
+@@ -1489,13 +1502,13 @@
+
+ serial_out(up, UART_IER, up->ier);
+
+- if (uart_config[up->port.type].flags & UART_STARTECH) {
++ if (up->capabilities & UART_STARTECH) {
+ serial_outp(up, UART_LCR, 0xBF);
+ serial_outp(up, UART_EFR,
+ termios->c_cflag & CRTSCTS ? UART_EFR_CTS :0);
+ }
+
+- if (uart_config[up->port.type].flags & UART_NATSEMI) {
++ if (up->capabilities & UART_NATSEMI) {
+ /* Switch to bank 2 not bank 1, to avoid resetting EXCR2 */
+ serial_outp(up, UART_LCR, 0xe0);
+ } else {
+@@ -1524,7 +1537,7 @@
+ struct uart_8250_port *up = (struct uart_8250_port *)port;
+ if (state) {
+ /* sleep */
+- if (uart_config[up->port.type].flags & UART_STARTECH) {
++ if (up->capabilities & UART_STARTECH) {
+ /* Arrange to enter sleep mode */
+ serial_outp(up, UART_LCR, 0xBF);
+ serial_outp(up, UART_EFR, UART_EFR_ECB);
+@@ -1543,7 +1556,7 @@
+ up->pm(port, state, oldstate);
+ } else {
+ /* wake */
+- if (uart_config[up->port.type].flags & UART_STARTECH) {
++ if (up->capabilities & UART_STARTECH) {
+ /* Wake up UART */
+ serial_outp(up, UART_LCR, 0xBF);
+ serial_outp(up, UART_EFR, UART_EFR_ECB);
+@@ -1853,6 +1866,10 @@
+ for (i = 0; i < UART_NR; i++) {
+ struct uart_8250_port *up = &serial8250_ports[i];
+
++#ifdef CONFIG_KGDB
++ if (up->port.irq == kgdb_irq)
++ up->port.kgdb = 1;
++#endif
+ up->port.line = i;
+ up->port.ops = &serial8250_pops;
+ init_timer(&up->timer);
+@@ -2101,9 +2118,9 @@
+ *
+ * Suspend one serial port.
+ */
+-void serial8250_suspend_port(int line, u32 level)
++void serial8250_suspend_port(int line)
+ {
+- uart_suspend_port(&serial8250_reg, &serial8250_ports[line].port, level);
++ uart_suspend_port(&serial8250_reg, &serial8250_ports[line].port);
+ }
+
+ /**
+@@ -2112,10 +2129,35 @@
+ *
+ * Resume one serial port.
+ */
+-void serial8250_resume_port(int line, u32 level)
++void serial8250_resume_port(int line)
+ {
+- uart_resume_port(&serial8250_reg, &serial8250_ports[line].port, level);
++ uart_resume_port(&serial8250_reg, &serial8250_ports[line].port);
++}
++
++#ifdef CONFIG_KGDB
++/*
++ * Find all the ports using the given irq and shut them down.
++ * Result should be that the irq will be released.
++ */
++void shutdown_for_kgdb(struct async_struct * info)
++{
++ int irq = info->state->irq;
++ struct uart_8250_port *up;
++ int ttyS;
++
++ kgdb_irq = irq; /* save for later init */
++ for (ttyS = 0; ttyS < UART_NR; ttyS++){
++ up = &serial8250_ports[ttyS];
++ if (up->port.irq == irq && (irq_lists + irq)->head) {
++#ifdef CONFIG_DEBUG_SPINLOCK /* ugly business... */
++ if(up->port.lock.magic != SPINLOCK_MAGIC)
++ spin_lock_init(&up->port.lock);
++#endif
++ serial8250_shutdown(&up->port);
++ }
++ }
+ }
++#endif /* CONFIG_KGDB */
+
+ static int __init serial8250_init(void)
+ {
+Index: linux-2.6.0-test5/drivers/serial/8250.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/serial/8250.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/serial/8250.h 2003-09-27 11:38:31.879681936 +0800
+@@ -27,8 +27,8 @@
+ int serial8250_register_probe(struct serial8250_probe *probe);
+ void serial8250_unregister_probe(struct serial8250_probe *probe);
+ void serial8250_get_irq_map(unsigned int *map);
+-void serial8250_suspend_port(int line, u32 level);
+-void serial8250_resume_port(int line, u32 level);
++void serial8250_suspend_port(int line);
++void serial8250_resume_port(int line);
+
+ struct old_serial_port {
+ unsigned int uart;
+Index: linux-2.6.0-test5/drivers/serial/8250_pci.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/serial/8250_pci.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/serial/8250_pci.c 2003-09-27 11:38:31.968668408 +0800
+@@ -1600,19 +1600,6 @@
+ }
+ }
+
+-static int pciserial_save_state_one(struct pci_dev *dev, u32 state)
+-{
+- struct serial_private *priv = pci_get_drvdata(dev);
+-
+- if (priv) {
+- int i;
+-
+- for (i = 0; i < priv->nr; i++)
+- serial8250_suspend_port(priv->line[i], SUSPEND_SAVE_STATE);
+- }
+- return 0;
+-}
+-
+ static int pciserial_suspend_one(struct pci_dev *dev, u32 state)
+ {
+ struct serial_private *priv = pci_get_drvdata(dev);
+@@ -1621,7 +1608,7 @@
+ int i;
+
+ for (i = 0; i < priv->nr; i++)
+- serial8250_suspend_port(priv->line[i], SUSPEND_POWER_DOWN);
++ serial8250_suspend_port(priv->line[i]);
+ }
+ return 0;
+ }
+@@ -1639,10 +1626,8 @@
+ if (priv->quirk->init)
+ priv->quirk->init(dev);
+
+- for (i = 0; i < priv->nr; i++) {
+- serial8250_resume_port(priv->line[i], RESUME_POWER_ON);
+- serial8250_resume_port(priv->line[i], RESUME_RESTORE_STATE);
+- }
++ for (i = 0; i < priv->nr; i++)
++ serial8250_resume_port(priv->line[i]);
+ }
+ return 0;
+ }
+@@ -2040,7 +2025,6 @@
+ .name = "serial",
+ .probe = pciserial_init_one,
+ .remove = __devexit_p(pciserial_remove_one),
+- .save_state = pciserial_save_state_one,
+ .suspend = pciserial_suspend_one,
+ .resume = pciserial_resume_one,
+ .id_table = serial_pci_tbl,
+Index: linux-2.6.0-test5/drivers/serial/clps711x.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/serial/clps711x.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/serial/clps711x.c 2003-09-27 11:38:32.032658680 +0800
+@@ -104,7 +104,7 @@
+ {
+ }
+
+-static void clps711xuart_int_rx(int irq, void *dev_id, struct pt_regs *regs)
++static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id, struct pt_regs *regs)
+ {
+ struct uart_port *port = dev_id;
+ struct tty_struct *tty = port->info->tty;
+@@ -139,7 +139,7 @@
+ }
+ out:
+ tty_flip_buffer_push(tty);
+- return;
++ return IRQ_HANDLED;
+
+ handle_error:
+ if (ch & UARTDR_PARERR)
+@@ -180,7 +180,7 @@
+ goto error_return;
+ }
+
+-static void clps711xuart_int_tx(int irq, void *dev_id, struct pt_regs *regs)
++static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id, struct pt_regs *regs)
+ {
+ struct uart_port *port = dev_id;
+ struct circ_buf *xmit = &port->info->xmit;
+@@ -190,11 +190,11 @@
+ clps_writel(port->x_char, UARTDR(port));
+ port->icount.tx++;
+ port->x_char = 0;
+- return;
++ return IRQ_HANDLED;
+ }
+ if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
+ clps711xuart_stop_tx(port, 0);
+- return;
++ return IRQ_HANDLED;
+ }
+
+ count = port->fifosize >> 1;
+@@ -211,6 +211,8 @@
+
+ if (uart_circ_empty(xmit))
+ clps711xuart_stop_tx(port, 0);
++
++ return IRQ_HANDLED;
+ }
+
+ static unsigned int clps711xuart_tx_empty(struct uart_port *port)
+Index: linux-2.6.0-test5/drivers/serial/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/serial/Kconfig 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/serial/Kconfig 2003-09-27 11:38:32.089650016 +0800
+@@ -10,6 +10,7 @@
+ # The new 8250/16550 serial drivers
+ config SERIAL_8250
+ tristate "8250/16550 and compatible serial support"
++ select SERIAL_CORE
+ ---help---
+ This selects whether you want to include the driver for the standard
+ serial ports. The standard answer is Y. People who might say N
+@@ -41,6 +42,7 @@
+ config SERIAL_8250_CONSOLE
+ bool "Console on 8250/16550 and compatible serial port"
+ depends on SERIAL_8250=y
++ select SERIAL_CORE_CONSOLE
+ ---help---
+ If you say Y here, it will be possible to use a serial port as the
+ system console (the system console is the device which receives all
+@@ -167,12 +169,14 @@
+ config SERIAL_ANAKIN
+ bool "Anakin serial port support"
+ depends on ARM && ARCH_ANAKIN
++ select SERIAL_CORE
+ help
+ ::: To be written :::
+
+ config SERIAL_ANAKIN_CONSOLE
+ bool "Console on Anakin serial port"
+ depends on SERIAL_ANAKIN
++ select SERIAL_CORE_CONSOLE
+ help
+ Even if you say Y here, the currently visible virtual console
+ (/dev/tty0) will still be used as the system console by default, but
+@@ -190,7 +194,8 @@
+
+ config SERIAL_AMBA
+ tristate "ARM AMBA serial port support"
+- depends on ARM && ARCH_INTEGRATOR
++ depends on ARM_AMBA
++ select SERIAL_CORE
+ help
+ This selects the ARM(R) AMBA(R) PrimeCell UART. If you have an
+ Integrator platform, say Y or M here.
+@@ -200,6 +205,7 @@
+ config SERIAL_AMBA_CONSOLE
+ bool "Support for console on AMBA serial port"
+ depends on SERIAL_AMBA=y
++ select SERIAL_CORE_CONSOLE
+ ---help---
+ Say Y here if you wish to use an AMBA PrimeCell UART as the system
+ console (the system console is the device which receives all kernel
+@@ -214,18 +220,20 @@
+
+ config SERIAL_INTEGRATOR
+ bool
+- depends on SERIAL_AMBA=y
++ depends on SERIAL_AMBA && ARCH_INTEGRATOR
+ default y
+
+ config SERIAL_CLPS711X
+ tristate "CLPS711X serial port support"
+ depends on ARM && ARCH_CLPS711X
++ select SERIAL_CORE
+ help
+ ::: To be written :::
+
+ config SERIAL_CLPS711X_CONSOLE
+ bool "Support for console on CLPS711X serial port"
+ depends on SERIAL_CLPS711X=y
++ select SERIAL_CORE_CONSOLE
+ help
+ Even if you say Y here, the currently visible virtual console
+ (/dev/tty0) will still be used as the system console by default, but
+@@ -243,6 +251,7 @@
+ config SERIAL_21285
+ tristate "DC21285 serial port support"
+ depends on ARM && FOOTBRIDGE
++ select SERIAL_CORE
+ help
+ If you have a machine based on a 21285 (Footbridge) StrongARM(R)/
+ PCI bridge you can enable its onboard serial port by enabling this
+@@ -258,6 +267,7 @@
+ config SERIAL_21285_CONSOLE
+ bool "Console on DC21285 serial port"
+ depends on SERIAL_21285=y
++ select SERIAL_CORE_CONSOLE
+ help
+ If you have enabled the serial port on the 21285 footbridge you can
+ make it the console by answering Y to this option.
+@@ -272,6 +282,7 @@
+ config SERIAL_UART00
+ bool "Excalibur serial port (uart00) support"
+ depends on ARM && ARCH_CAMELOT
++ select SERIAL_CORE
+ help
+ Say Y here if you want to use the hard logic uart on Excalibur. This
+ driver also supports soft logic implentations of this uart core.
+@@ -279,6 +290,7 @@
+ config SERIAL_UART00_CONSOLE
+ bool "Support for console on Excalibur serial port"
+ depends on SERIAL_UART00
++ select SERIAL_CORE_CONSOLE
+ help
+ Say Y here if you want to support a serial console on an Excalibur
+ hard logic uart or uart00 IP core.
+@@ -293,6 +305,7 @@
+ config SERIAL_SA1100
+ bool "SA1100 serial port support"
+ depends on ARM && ARCH_SA1100
++ select SERIAL_CORE
+ help
+ If you have a machine based on a SA1100/SA1110 StrongARM(R) CPU you
+ can enable its onboard serial port by enabling this option.
+@@ -302,6 +315,7 @@
+ config SERIAL_SA1100_CONSOLE
+ bool "Console on SA1100 serial port"
+ depends on SERIAL_SA1100
++ select SERIAL_CORE_CONSOLE
+ help
+ If you have enabled the serial port on the SA1100/SA1110 StrongARM
+ CPU you can make it the console by answering Y to this option.
+@@ -316,6 +330,8 @@
+ config SERIAL_SUNCORE
+ bool
+ depends on SPARC32 || SPARC64
++ select SERIAL_CORE
++ select SERIAL_CORE_CONSOLE
+ default y
+
+ config SERIAL_SUNZILOG
+@@ -352,6 +368,7 @@
+ config SERIAL_MUX
+ tristate "Serial MUX support"
+ depends on PARISC
++ select SERIAL_CORE
+ default y
+ ---help---
+ Saying Y here will enable the hardware MUX serial driver for
+@@ -369,6 +386,7 @@
+ config SERIAL_MUX_CONSOLE
+ bool "Support for console on serial MUX"
+ depends on SERIAL_MUX
++ select SERIAL_CORE_CONSOLE
+ default y
+
+ config PDC_CONSOLE
+@@ -406,6 +424,7 @@
+ config V850E_UART
+ bool "NEC V850E on-chip UART support"
+ depends on V850E_MA1 || V850E_ME2 || V850E_TEG || V850E2_ANNA || V850E_AS85EP1
++ select SERIAL_CORE
+ default y
+
+ config V850E_UARTB
+@@ -416,10 +435,12 @@
+ config V850E_UART_CONSOLE
+ bool "Use NEC V850E on-chip UART for console"
+ depends on V850E_UART
++ select SERIAL_CORE_CONSOLE
+
+ config SERIAL98
+ tristate "PC-9800 8251-based primary serial port support"
+ depends on X86_PC9800
++ select SERIAL_CORE
+ help
+ If you want to use standard primary serial ports on PC-9800,
+ say Y. Otherwise, say N.
+@@ -427,16 +448,13 @@
+ config SERIAL98_CONSOLE
+ bool "Support for console on PC-9800 standard serial port"
+ depends on SERIAL98=y
++ select SERIAL_CORE_CONSOLE
+
+ config SERIAL_CORE
+ tristate
+- default m if SERIAL_AMBA!=y && SERIAL_CLPS711X!=y && SERIAL_21285!=y && !SERIAL_SA1100 && !SERIAL_ANAKIN && !SERIAL_UART00 && SERIAL_8250!=y && SERIAL_MUX!=y && !SERIAL_ROCKETPORT && !SERIAL_SUNCORE && !V850E_UART && SERIAL_PMACZILOG!=y && (SERIAL_AMBA=m || SERIAL_CLPS711X=m || SERIAL_21285=m || SERIAL_8250=m || SERIAL_MUX=m || SERIAL98=m || SERIAL_PMACZILOG=m)
+- default y if SERIAL_AMBA=y || SERIAL_CLPS711X=y || SERIAL_21285=y || SERIAL_SA1100 || SERIAL_ANAKIN || SERIAL_UART00 || SERIAL_8250=y || SERIAL_MUX=y || SERIAL_ROCKETPORT || SERIAL_SUNCORE || V850E_UART || SERIAL98=y || SERIAL_PMACZILOG=y
+
+ config SERIAL_CORE_CONSOLE
+ bool
+- depends on SERIAL_AMBA_CONSOLE || SERIAL_CLPS711X_CONSOLE || SERIAL_21285_CONSOLE || SERIAL_SA1100_CONSOLE || SERIAL_ANAKIN_CONSOLE || SERIAL_UART00_CONSOLE || SERIAL_8250_CONSOLE || SERIAL_MUX_CONSOLE || SERIAL_SUNZILOG_CONSOLE || SERIAL_SUNSU_CONSOLE || SERIAL_SUNSAB_CONSOLE || V850E_UART_CONSOLE || SERIAL98_CONSOLE || SERIAL_PMACZILOG_CONSOLE
+- default y
+
+ config SERIAL_68328
+ bool "68328 serial support"
+@@ -476,6 +494,7 @@
+ config SERIAL_PMACZILOG
+ tristate "PowerMac z85c30 ESCC support"
+ depends on PPC_OF
++ select SERIAL_CORE
+ help
+ This driver supports the Zilog z85C30 serial ports found on
+ PowerMac machines.
+@@ -484,6 +503,7 @@
+ config SERIAL_PMACZILOG_CONSOLE
+ bool "Console on PowerMac z85c30 serial port"
+ depends on SERIAL_PMACZILOG=y
++ select SERIAL_CORE_CONSOLE
+ help
+ If you would like to be able to use the z85c30 serial port
+ on your PowerMac as the console, you can do so by answering
+Index: linux-2.6.0-test5/drivers/serial/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/serial/Makefile 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/serial/Makefile 2003-09-27 11:38:32.113646368 +0800
+@@ -11,10 +11,10 @@
+ serial-8250-$(CONFIG_SERIAL_8250_HCDP) += 8250_hcdp.o
+ serial-8250-$(CONFIG_SERIAL_8250_ACPI) += 8250_acpi.o
+
+-obj-$(CONFIG_SERIAL_CORE) += core.o
++obj-$(CONFIG_SERIAL_CORE) += serial_core.o
+ obj-$(CONFIG_SERIAL_21285) += 21285.o
+ obj-$(CONFIG_SERIAL_8250) += 8250.o $(serial-8250-y)
+-obj-$(CONFIG_SERIAL_8250_CS) += 8250_cs.o
++obj-$(CONFIG_SERIAL_8250_CS) += serial_cs.o
+ obj-$(CONFIG_SERIAL_8250_ACORN) += 8250_acorn.o
+ obj-$(CONFIG_SERIAL_ANAKIN) += anakin.o
+ obj-$(CONFIG_SERIAL_AMBA) += amba.o
+Index: linux-2.6.0-test5/drivers/serial/sa1100.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/serial/sa1100.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/serial/sa1100.c 2003-09-27 11:38:32.166638312 +0800
+@@ -862,8 +862,8 @@
+ {
+ struct sa1100_port *sport = dev_get_drvdata(_dev);
+
+- if (sport)
+- uart_suspend_port(&sa1100_reg, &sport->port, level);
++ if (sport && level == SUSPEND_DISABLE)
++ uart_suspend_port(&sa1100_reg, &sport->port);
+
+ return 0;
+ }
+@@ -872,8 +872,8 @@
+ {
+ struct sa1100_port *sport = dev_get_drvdata(_dev);
+
+- if (sport)
+- uart_resume_port(&sa1100_reg, &sport->port, level);
++ if (sport && level == RESUME_ENABLE)
++ uart_resume_port(&sa1100_reg, &sport->port);
+
+ return 0;
+ }
+Index: linux-2.6.0-test5/drivers/serial/serial_core.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/serial/serial_core.c 2003-09-27 11:38:18.463721472 +0800
++++ linux-2.6.0-test5/drivers/serial/serial_core.c 2003-09-27 11:38:32.171637552 +0800
+@@ -0,0 +1,2425 @@
++/*
++ * linux/drivers/char/core.c
++ *
++ * Driver core for serial ports
++ *
++ * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
++ *
++ * Copyright 1999 ARM Limited
++ * Copyright (C) 2000-2001 Deep Blue Solutions Ltd.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/tty.h>
++#include <linux/slab.h>
++#include <linux/init.h>
++#include <linux/console.h>
++#include <linux/serial_core.h>
++#include <linux/smp_lock.h>
++#include <linux/device.h>
++#include <linux/serial.h> /* for serial_state and serial_icounter_struct */
++
++#include <asm/irq.h>
++#include <asm/uaccess.h>
++
++#undef DEBUG
++#ifdef DEBUG
++#define DPRINTK(x...) printk(x)
++#else
++#define DPRINTK(x...) do { } while (0)
++#endif
++
++/*
++ * This is used to lock changes in serial line configuration.
++ */
++static DECLARE_MUTEX(port_sem);
++
++#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
++
++#define uart_users(state) ((state)->count + ((state)->info ? (state)->info->blocked_open : 0))
++
++#ifdef CONFIG_SERIAL_CORE_CONSOLE
++#define uart_console(port) ((port)->cons && (port)->cons->index == (port)->line)
++#else
++#define uart_console(port) (0)
++#endif
++
++static void uart_change_speed(struct uart_state *state, struct termios *old_termios);
++static void uart_wait_until_sent(struct tty_struct *tty, int timeout);
++static void uart_change_pm(struct uart_state *state, int pm_state);
++
++/*
++ * This routine is used by the interrupt handler to schedule processing in
++ * the software interrupt portion of the driver.
++ */
++void uart_write_wakeup(struct uart_port *port)
++{
++ struct uart_info *info = port->info;
++ tasklet_schedule(&info->tlet);
++}
++
++static void uart_stop(struct tty_struct *tty)
++{
++ struct uart_state *state = tty->driver_data;
++ struct uart_port *port = state->port;
++ unsigned long flags;
++
++ spin_lock_irqsave(&port->lock, flags);
++ port->ops->stop_tx(port, 1);
++ spin_unlock_irqrestore(&port->lock, flags);
++}
++
++static void __uart_start(struct tty_struct *tty)
++{
++ struct uart_state *state = tty->driver_data;
++ struct uart_port *port = state->port;
++
++ if (!uart_circ_empty(&state->info->xmit) && state->info->xmit.buf &&
++ !tty->stopped && !tty->hw_stopped)
++ port->ops->start_tx(port, 1);
++}
++
++static void uart_start(struct tty_struct *tty)
++{
++ struct uart_state *state = tty->driver_data;
++ struct uart_port *port = state->port;
++ unsigned long flags;
++
++ spin_lock_irqsave(&port->lock, flags);
++ __uart_start(tty);
++ spin_unlock_irqrestore(&port->lock, flags);
++}
++
++static void uart_tasklet_action(unsigned long data)
++{
++ struct uart_state *state = (struct uart_state *)data;
++ struct tty_struct *tty;
++
++ tty = state->info->tty;
++ if (tty) {
++ if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
++ tty->ldisc.write_wakeup)
++ tty->ldisc.write_wakeup(tty);
++ wake_up_interruptible(&tty->write_wait);
++ }
++}
++
++static inline void
++uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear)
++{
++ unsigned long flags;
++ unsigned int old;
++
++ spin_lock_irqsave(&port->lock, flags);
++ old = port->mctrl;
++ port->mctrl = (old & ~clear) | set;
++ if (old != port->mctrl)
++ port->ops->set_mctrl(port, port->mctrl);
++ spin_unlock_irqrestore(&port->lock, flags);
++}
++
++#define uart_set_mctrl(port,set) uart_update_mctrl(port,set,0)
++#define uart_clear_mctrl(port,clear) uart_update_mctrl(port,0,clear)
++
++/*
++ * Startup the port. This will be called once per open. All calls
++ * will be serialised by the per-port semaphore.
++ */
++static int uart_startup(struct uart_state *state, int init_hw)
++{
++ struct uart_info *info = state->info;
++ struct uart_port *port = state->port;
++ unsigned long page;
++ int retval = 0;
++
++ if (info->flags & UIF_INITIALIZED)
++ return 0;
++
++ /*
++ * Set the TTY IO error marker - we will only clear this
++ * once we have successfully opened the port. Also set
++ * up the tty->alt_speed kludge
++ */
++ if (info->tty)
++ set_bit(TTY_IO_ERROR, &info->tty->flags);
++
++ if (port->type == PORT_UNKNOWN)
++ return 0;
++
++ /*
++ * Initialise and allocate the transmit and temporary
++ * buffer.
++ */
++ if (!info->xmit.buf) {
++ page = get_zeroed_page(GFP_KERNEL);
++ if (!page)
++ return -ENOMEM;
++
++ info->xmit.buf = (unsigned char *) page;
++ info->tmpbuf = info->xmit.buf + UART_XMIT_SIZE;
++ init_MUTEX(&info->tmpbuf_sem);
++ uart_circ_clear(&info->xmit);
++ }
++
++ port->mctrl = 0;
++
++ retval = port->ops->startup(port);
++ if (retval == 0) {
++ if (init_hw) {
++ /*
++ * Initialise the hardware port settings.
++ */
++ uart_change_speed(state, NULL);
++
++ /*
++ * Setup the RTS and DTR signals once the
++ * port is open and ready to respond.
++ */
++ if (info->tty->termios->c_cflag & CBAUD)
++ uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR);
++ }
++
++ info->flags |= UIF_INITIALIZED;
++
++ clear_bit(TTY_IO_ERROR, &info->tty->flags);
++ }
++
++ if (retval && capable(CAP_SYS_ADMIN))
++ retval = 0;
++
++ return retval;
++}
++
++/*
++ * This routine will shutdown a serial port; interrupts are disabled, and
++ * DTR is dropped if the hangup on close termio flag is on. Calls to
++ * uart_shutdown are serialised by the per-port semaphore.
++ */
++static void uart_shutdown(struct uart_state *state)
++{
++ struct uart_info *info = state->info;
++ struct uart_port *port = state->port;
++
++ if (!(info->flags & UIF_INITIALIZED))
++ return;
++
++ /*
++ * Turn off DTR and RTS early.
++ */
++ if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
++ uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
++
++ /*
++ * clear delta_msr_wait queue to avoid mem leaks: we may free
++ * the irq here so the queue might never be woken up. Note
++ * that we won't end up waiting on delta_msr_wait again since
++ * any outstanding file descriptors should be pointing at
++ * hung_up_tty_fops now.
++ */
++ wake_up_interruptible(&info->delta_msr_wait);
++
++ /*
++ * Free the IRQ and disable the port.
++ */
++ port->ops->shutdown(port);
++
++ /*
++ * Ensure that the IRQ handler isn't running on another CPU.
++ */
++ synchronize_irq(port->irq);
++
++ /*
++ * Free the transmit buffer page.
++ */
++ if (info->xmit.buf) {
++ free_page((unsigned long)info->xmit.buf);
++ info->xmit.buf = NULL;
++ info->tmpbuf = NULL;
++ }
++
++ /*
++ * kill off our tasklet
++ */
++ tasklet_kill(&info->tlet);
++ if (info->tty)
++ set_bit(TTY_IO_ERROR, &info->tty->flags);
++
++ info->flags &= ~UIF_INITIALIZED;
++}
++
++/**
++ * uart_update_timeout - update per-port FIFO timeout.
++ * @port: uart_port structure describing the port.
++ * @cflag: termios cflag value
++ * @quot: uart clock divisor quotient
++ *
++ * Set the port FIFO timeout value. The @cflag value should
++ * reflect the actual hardware settings.
++ */
++void
++uart_update_timeout(struct uart_port *port, unsigned int cflag,
++ unsigned int baud)
++{
++ unsigned int bits;
++
++ /* byte size and parity */
++ switch (cflag & CSIZE) {
++ case CS5:
++ bits = 7;
++ break;
++ case CS6:
++ bits = 8;
++ break;
++ case CS7:
++ bits = 9;
++ break;
++ default:
++ bits = 10;
++ break; // CS8
++ }
++
++ if (cflag & CSTOPB)
++ bits++;
++ if (cflag & PARENB)
++ bits++;
++
++ /*
++ * The total number of bits to be transmitted in the fifo.
++ */
++ bits = bits * port->fifosize;
++
++ /*
++ * Figure the timeout to send the above number of bits.
++ * Add .02 seconds of slop
++ */
++ port->timeout = (HZ * bits) / baud + HZ/50;
++}
++
++EXPORT_SYMBOL(uart_update_timeout);
++
++/**
++ * uart_get_baud_rate - return baud rate for a particular port
++ * @port: uart_port structure describing the port in question.
++ * @termios: desired termios settings.
++ * @old: old termios (or NULL)
++ * @min: minimum acceptable baud rate
++ * @max: maximum acceptable baud rate
++ *
++ * Decode the termios structure into a numeric baud rate,
++ * taking account of the magic 38400 baud rate (with spd_*
++ * flags), and mapping the %B0 rate to 9600 baud.
++ *
++ * If the new baud rate is invalid, try the old termios setting.
++ * If it's still invalid, we try 9600 baud.
++ *
++ * Update the @termios structure to reflect the baud rate
++ * we're actually going to be using.
++ */
++unsigned int
++uart_get_baud_rate(struct uart_port *port, struct termios *termios,
++ struct termios *old, unsigned int min, unsigned int max)
++{
++ unsigned int try, baud, altbaud = 38400;
++ unsigned int flags = port->flags & UPF_SPD_MASK;
++
++ if (flags == UPF_SPD_HI)
++ altbaud = 57600;
++ if (flags == UPF_SPD_VHI)
++ altbaud = 115200;
++ if (flags == UPF_SPD_SHI)
++ altbaud = 230400;
++ if (flags == UPF_SPD_WARP)
++ altbaud = 460800;
++
++ for (try = 0; try < 2; try++) {
++ baud = tty_termios_baud_rate(termios);
++
++ /*
++ * The spd_hi, spd_vhi, spd_shi, spd_warp kludge...
++ * Die! Die! Die!
++ */
++ if (baud == 38400)
++ baud = altbaud;
++
++ /*
++ * Special case: B0 rate.
++ */
++ if (baud == 0)
++ baud = 9600;
++
++ if (baud >= min && baud <= max)
++ return baud;
++
++ /*
++ * Oops, the quotient was zero. Try again with
++ * the old baud rate if possible.
++ */
++ termios->c_cflag &= ~CBAUD;
++ if (old) {
++ termios->c_cflag |= old->c_cflag & CBAUD;
++ old = NULL;
++ continue;
++ }
++
++ /*
++ * As a last resort, if the quotient is zero,
++ * default to 9600 bps
++ */
++ termios->c_cflag |= B9600;
++ }
++
++ return 0;
++}
++
++EXPORT_SYMBOL(uart_get_baud_rate);
++
++/**
++ * uart_get_divisor - return uart clock divisor
++ * @port: uart_port structure describing the port.
++ * @baud: desired baud rate
++ *
++ * Calculate the uart clock divisor for the port.
++ */
++unsigned int
++uart_get_divisor(struct uart_port *port, unsigned int baud)
++{
++ unsigned int quot;
++
++ /*
++ * Old custom speed handling.
++ */
++ if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST)
++ quot = port->custom_divisor;
++ else
++ quot = port->uartclk / (16 * baud);
++
++ return quot;
++}
++
++EXPORT_SYMBOL(uart_get_divisor);
++
++static void
++uart_change_speed(struct uart_state *state, struct termios *old_termios)
++{
++ struct tty_struct *tty = state->info->tty;
++ struct uart_port *port = state->port;
++ struct termios *termios;
++
++ /*
++ * If we have no tty, termios, or the port does not exist,
++ * then we can't set the parameters for this port.
++ */
++ if (!tty || !tty->termios || port->type == PORT_UNKNOWN)
++ return;
++
++ termios = tty->termios;
++
++ /*
++ * Set flags based on termios cflag
++ */
++ if (termios->c_cflag & CRTSCTS)
++ state->info->flags |= UIF_CTS_FLOW;
++ else
++ state->info->flags &= ~UIF_CTS_FLOW;
++
++ if (termios->c_cflag & CLOCAL)
++ state->info->flags &= ~UIF_CHECK_CD;
++ else
++ state->info->flags |= UIF_CHECK_CD;
++
++ port->ops->set_termios(port, termios, old_termios);
++}
++
++static inline void
++__uart_put_char(struct uart_port *port, struct circ_buf *circ, unsigned char c)
++{
++ unsigned long flags;
++
++ if (!circ->buf)
++ return;
++
++ spin_lock_irqsave(&port->lock, flags);
++ if (uart_circ_chars_free(circ) != 0) {
++ circ->buf[circ->head] = c;
++ circ->head = (circ->head + 1) & (UART_XMIT_SIZE - 1);
++ }
++ spin_unlock_irqrestore(&port->lock, flags);
++}
++
++static inline int
++__uart_user_write(struct uart_port *port, struct circ_buf *circ,
++ const unsigned char *buf, int count)
++{
++ unsigned long flags;
++ int c, ret = 0;
++
++ if (down_interruptible(&port->info->tmpbuf_sem))
++ return -EINTR;
++
++ while (1) {
++ int c1;
++ c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
++ if (count < c)
++ c = count;
++ if (c <= 0)
++ break;
++
++ c -= copy_from_user(port->info->tmpbuf, buf, c);
++ if (!c) {
++ if (!ret)
++ ret = -EFAULT;
++ break;
++ }
++ spin_lock_irqsave(&port->lock, flags);
++ c1 = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
++ if (c1 < c)
++ c = c1;
++ memcpy(circ->buf + circ->head, port->info->tmpbuf, c);
++ circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1);
++ spin_unlock_irqrestore(&port->lock, flags);
++ buf += c;
++ count -= c;
++ ret += c;
++ }
++ up(&port->info->tmpbuf_sem);
++
++ return ret;
++}
++
++static inline int
++__uart_kern_write(struct uart_port *port, struct circ_buf *circ,
++ const unsigned char *buf, int count)
++{
++ unsigned long flags;
++ int c, ret = 0;
++
++ spin_lock_irqsave(&port->lock, flags);
++ while (1) {
++ c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
++ if (count < c)
++ c = count;
++ if (c <= 0)
++ break;
++ memcpy(circ->buf + circ->head, buf, c);
++ circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1);
++ buf += c;
++ count -= c;
++ ret += c;
++ }
++ spin_unlock_irqrestore(&port->lock, flags);
++
++ return ret;
++}
++
++static void uart_put_char(struct tty_struct *tty, unsigned char ch)
++{
++ struct uart_state *state = tty->driver_data;
++
++ if (tty)
++ __uart_put_char(state->port, &state->info->xmit, ch);
++}
++
++static void uart_flush_chars(struct tty_struct *tty)
++{
++ uart_start(tty);
++}
++
++static int
++uart_write(struct tty_struct *tty, int from_user, const unsigned char * buf,
++ int count)
++{
++ struct uart_state *state = tty->driver_data;
++ int ret;
++
++ if (!tty || !state->info->xmit.buf)
++ return 0;
++
++ if (from_user)
++ ret = __uart_user_write(state->port, &state->info->xmit, buf, count);
++ else
++ ret = __uart_kern_write(state->port, &state->info->xmit, buf, count);
++
++ uart_start(tty);
++ return ret;
++}
++
++static int uart_write_room(struct tty_struct *tty)
++{
++ struct uart_state *state = tty->driver_data;
++
++ return uart_circ_chars_free(&state->info->xmit);
++}
++
++static int uart_chars_in_buffer(struct tty_struct *tty)
++{
++ struct uart_state *state = tty->driver_data;
++
++ return uart_circ_chars_pending(&state->info->xmit);
++}
++
++static void uart_flush_buffer(struct tty_struct *tty)
++{
++ struct uart_state *state = tty->driver_data;
++ struct uart_port *port = state->port;
++ unsigned long flags;
++
++ DPRINTK("uart_flush_buffer(%d) called\n", tty->index);
++
++ spin_lock_irqsave(&port->lock, flags);
++ uart_circ_clear(&state->info->xmit);
++ spin_unlock_irqrestore(&port->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);
++}
++
++/*
++ * This function is used to send a high-priority XON/XOFF character to
++ * the device
++ */
++static void uart_send_xchar(struct tty_struct *tty, char ch)
++{
++ struct uart_state *state = tty->driver_data;
++ struct uart_port *port = state->port;
++ unsigned long flags;
++
++ if (port->ops->send_xchar)
++ port->ops->send_xchar(port, ch);
++ else {
++ port->x_char = ch;
++ if (ch) {
++ spin_lock_irqsave(&port->lock, flags);
++ port->ops->start_tx(port, 0);
++ spin_unlock_irqrestore(&port->lock, flags);
++ }
++ }
++}
++
++static void uart_throttle(struct tty_struct *tty)
++{
++ struct uart_state *state = tty->driver_data;
++
++ if (I_IXOFF(tty))
++ uart_send_xchar(tty, STOP_CHAR(tty));
++
++ if (tty->termios->c_cflag & CRTSCTS)
++ uart_clear_mctrl(state->port, TIOCM_RTS);
++}
++
++static void uart_unthrottle(struct tty_struct *tty)
++{
++ struct uart_state *state = tty->driver_data;
++ struct uart_port *port = state->port;
++
++ if (I_IXOFF(tty)) {
++ if (port->x_char)
++ port->x_char = 0;
++ else
++ uart_send_xchar(tty, START_CHAR(tty));
++ }
++
++ if (tty->termios->c_cflag & CRTSCTS)
++ uart_set_mctrl(port, TIOCM_RTS);
++}
++
++static int uart_get_info(struct uart_state *state, struct serial_struct *retinfo)
++{
++ struct uart_port *port = state->port;
++ struct serial_struct tmp;
++
++ memset(&tmp, 0, sizeof(tmp));
++ tmp.type = port->type;
++ tmp.line = port->line;
++ tmp.port = port->iobase;
++ if (HIGH_BITS_OFFSET)
++ tmp.port_high = (long) port->iobase >> HIGH_BITS_OFFSET;
++ tmp.irq = port->irq;
++ tmp.flags = port->flags;
++ tmp.xmit_fifo_size = port->fifosize;
++ tmp.baud_base = port->uartclk / 16;
++ tmp.close_delay = state->close_delay;
++ tmp.closing_wait = state->closing_wait;
++ tmp.custom_divisor = port->custom_divisor;
++ tmp.hub6 = port->hub6;
++ tmp.io_type = port->iotype;
++ tmp.iomem_reg_shift = port->regshift;
++ tmp.iomem_base = (void *)port->mapbase;
++
++ if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
++ return -EFAULT;
++ return 0;
++}
++
++static int
++uart_set_info(struct uart_state *state, struct serial_struct *newinfo)
++{
++ struct serial_struct new_serial;
++ struct uart_port *port = state->port;
++ unsigned long new_port;
++ unsigned int change_irq, change_port, old_flags;
++ unsigned int old_custom_divisor;
++ int retval = 0;
++
++ if (copy_from_user(&new_serial, newinfo, sizeof(new_serial)))
++ return -EFAULT;
++
++ new_port = new_serial.port;
++ if (HIGH_BITS_OFFSET)
++ new_port += (unsigned long) new_serial.port_high << HIGH_BITS_OFFSET;
++
++ new_serial.irq = irq_canonicalize(new_serial.irq);
++
++ /*
++ * This semaphore protects state->count. It is also
++ * very useful to prevent opens. Also, take the
++ * port configuration semaphore to make sure that a
++ * module insertion/removal doesn't change anything
++ * under us.
++ */
++ down(&state->sem);
++
++ change_irq = new_serial.irq != port->irq;
++
++ /*
++ * Since changing the 'type' of the port changes its resource
++ * allocations, we should treat type changes the same as
++ * IO port changes.
++ */
++ change_port = new_port != port->iobase ||
++ (unsigned long)new_serial.iomem_base != port->mapbase ||
++ new_serial.hub6 != port->hub6 ||
++ new_serial.io_type != port->iotype ||
++ new_serial.iomem_reg_shift != port->regshift ||
++ new_serial.type != port->type;
++
++ old_flags = port->flags;
++ old_custom_divisor = port->custom_divisor;
++
++ if (!capable(CAP_SYS_ADMIN)) {
++ retval = -EPERM;
++ if (change_irq || change_port ||
++ (new_serial.baud_base != port->uartclk / 16) ||
++ (new_serial.close_delay != state->close_delay) ||
++ (new_serial.closing_wait != state->closing_wait) ||
++ (new_serial.xmit_fifo_size != port->fifosize) ||
++ (((new_serial.flags ^ old_flags) & ~UPF_USR_MASK) != 0))
++ goto exit;
++ port->flags = ((port->flags & ~UPF_USR_MASK) |
++ (new_serial.flags & UPF_USR_MASK));
++ port->custom_divisor = new_serial.custom_divisor;
++ goto check_and_exit;
++ }
++
++ /*
++ * Ask the low level driver to verify the settings.
++ */
++ if (port->ops->verify_port)
++ retval = port->ops->verify_port(port, &new_serial);
++
++ if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) ||
++ (new_serial.baud_base < 9600))
++ retval = -EINVAL;
++
++ if (retval)
++ goto exit;
++
++ if (change_port || change_irq) {
++ retval = -EBUSY;
++
++ /*
++ * Make sure that we are the sole user of this port.
++ */
++ if (uart_users(state) > 1)
++ goto exit;
++
++ /*
++ * We need to shutdown the serial port at the old
++ * port/type/irq combination.
++ */
++ uart_shutdown(state);
++ }
++
++ if (change_port) {
++ unsigned long old_iobase, old_mapbase;
++ unsigned int old_type, old_iotype, old_hub6, old_shift;
++
++ old_iobase = port->iobase;
++ old_mapbase = port->mapbase;
++ old_type = port->type;
++ old_hub6 = port->hub6;
++ old_iotype = port->iotype;
++ old_shift = port->regshift;
++
++ /*
++ * Free and release old regions
++ */
++ if (old_type != PORT_UNKNOWN)
++ port->ops->release_port(port);
++
++ port->iobase = new_port;
++ port->type = new_serial.type;
++ port->hub6 = new_serial.hub6;
++ port->iotype = new_serial.io_type;
++ port->regshift = new_serial.iomem_reg_shift;
++ port->mapbase = (unsigned long)new_serial.iomem_base;
++
++ /*
++ * Claim and map the new regions
++ */
++ if (port->type != PORT_UNKNOWN) {
++ retval = port->ops->request_port(port);
++ } else {
++ /* Always success - Jean II */
++ retval = 0;
++ }
++
++ /*
++ * If we fail to request resources for the
++ * new port, try to restore the old settings.
++ */
++ if (retval && old_type != PORT_UNKNOWN) {
++ port->iobase = old_iobase;
++ port->type = old_type;
++ port->hub6 = old_hub6;
++ port->iotype = old_iotype;
++ port->regshift = old_shift;
++ port->mapbase = old_mapbase;
++ retval = port->ops->request_port(port);
++ /*
++ * If we failed to restore the old settings,
++ * we fail like this.
++ */
++ if (retval)
++ port->type = PORT_UNKNOWN;
++
++ /*
++ * We failed anyway.
++ */
++ retval = -EBUSY;
++ }
++ }
++
++ port->irq = new_serial.irq;
++ port->uartclk = new_serial.baud_base * 16;
++ port->flags = (port->flags & ~UPF_CHANGE_MASK) |
++ (new_serial.flags & UPF_CHANGE_MASK);
++ port->custom_divisor = new_serial.custom_divisor;
++ state->close_delay = new_serial.close_delay * HZ / 100;
++ state->closing_wait = new_serial.closing_wait * HZ / 100;
++ port->fifosize = new_serial.xmit_fifo_size;
++ if (state->info->tty)
++ state->info->tty->low_latency =
++ (port->flags & UPF_LOW_LATENCY) ? 1 : 0;
++
++ check_and_exit:
++ retval = 0;
++ if (port->type == PORT_UNKNOWN)
++ goto exit;
++ if (state->info->flags & UIF_INITIALIZED) {
++ if (((old_flags ^ port->flags) & UPF_SPD_MASK) ||
++ old_custom_divisor != port->custom_divisor) {
++ /* If they're setting up a custom divisor or speed,
++ * instead of clearing it, then bitch about it. No
++ * need to rate-limit; it's CAP_SYS_ADMIN only. */
++ if (port->flags & UPF_SPD_MASK) {
++ printk(KERN_NOTICE "%s sets custom speed on %s%d. This is deprecated.\n",
++ current->comm, state->info->tty->driver->name,
++ state->port->line);
++ }
++ uart_change_speed(state, NULL);
++ }
++ } else
++ retval = uart_startup(state, 1);
++ exit:
++ up(&state->sem);
++ return retval;
++}
++
++
++/*
++ * uart_get_lsr_info - get line status register info.
++ * Note: uart_ioctl protects us against hangups.
++ */
++static int uart_get_lsr_info(struct uart_state *state, unsigned int *value)
++{
++ struct uart_port *port = state->port;
++ unsigned int result;
++
++ result = port->ops->tx_empty(port);
++
++ /*
++ * If we're about to load something into the transmit
++ * register, we'll pretend the transmitter isn't empty to
++ * avoid a race condition (depending on when the transmit
++ * interrupt happens).
++ */
++ if (port->x_char ||
++ ((uart_circ_chars_pending(&state->info->xmit) > 0) &&
++ !state->info->tty->stopped && !state->info->tty->hw_stopped))
++ result &= ~TIOCSER_TEMT;
++
++ return put_user(result, value);
++}
++
++static int uart_tiocmget(struct tty_struct *tty, struct file *file)
++{
++ struct uart_state *state = tty->driver_data;
++ struct uart_port *port = state->port;
++ int result = -EIO;
++
++ down(&state->sem);
++ if ((!file || !tty_hung_up_p(file)) &&
++ !(tty->flags & (1 << TTY_IO_ERROR))) {
++ result = port->mctrl;
++ result |= port->ops->get_mctrl(port);
++ }
++ up(&state->sem);
++
++ return result;
++}
++
++static int
++uart_tiocmset(struct tty_struct *tty, struct file *file,
++ unsigned int set, unsigned int clear)
++{
++ struct uart_state *state = tty->driver_data;
++ struct uart_port *port = state->port;
++ int ret = -EIO;
++
++ down(&state->sem);
++ if ((!file || !tty_hung_up_p(file)) &&
++ !(tty->flags & (1 << TTY_IO_ERROR))) {
++ uart_update_mctrl(port, set, clear);
++ ret = 0;
++ }
++ up(&state->sem);
++ return ret;
++}
++
++static void uart_break_ctl(struct tty_struct *tty, int break_state)
++{
++ struct uart_state *state = tty->driver_data;
++ struct uart_port *port = state->port;
++
++ BUG_ON(!kernel_locked());
++
++ down(&state->sem);
++
++ if (port->type != PORT_UNKNOWN)
++ port->ops->break_ctl(port, break_state);
++
++ up(&state->sem);
++}
++
++static int uart_do_autoconfig(struct uart_state *state)
++{
++ struct uart_port *port = state->port;
++ int flags, ret;
++
++ if (!capable(CAP_SYS_ADMIN))
++ return -EPERM;
++
++ /*
++ * Take the per-port semaphore. This prevents count from
++ * changing, and hence any extra opens of the port while
++ * we're auto-configuring.
++ */
++ if (down_interruptible(&state->sem))
++ return -ERESTARTSYS;
++
++ ret = -EBUSY;
++ if (uart_users(state) == 1) {
++ uart_shutdown(state);
++
++ /*
++ * If we already have a port type configured,
++ * we must release its resources.
++ */
++ if (port->type != PORT_UNKNOWN)
++ port->ops->release_port(port);
++
++ flags = UART_CONFIG_TYPE;
++ if (port->flags & UPF_AUTO_IRQ)
++ flags |= UART_CONFIG_IRQ;
++
++ /*
++ * This will claim the ports resources if
++ * a port is found.
++ */
++ port->ops->config_port(port, flags);
++
++ ret = uart_startup(state, 1);
++ }
++ up(&state->sem);
++ return ret;
++}
++
++/*
++ * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
++ * - mask passed in arg for lines of interest
++ * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
++ * Caller should use TIOCGICOUNT to see which one it was
++ */
++static int
++uart_wait_modem_status(struct uart_state *state, unsigned long arg)
++{
++ struct uart_port *port = state->port;
++ DECLARE_WAITQUEUE(wait, current);
++ struct uart_icount cprev, cnow;
++ int ret;
++
++ /*
++ * note the counters on entry
++ */
++ spin_lock_irq(&port->lock);
++ memcpy(&cprev, &port->icount, sizeof(struct uart_icount));
++
++ /*
++ * Force modem status interrupts on
++ */
++ port->ops->enable_ms(port);
++ spin_unlock_irq(&port->lock);
++
++ add_wait_queue(&state->info->delta_msr_wait, &wait);
++ for (;;) {
++ spin_lock_irq(&port->lock);
++ memcpy(&cnow, &port->icount, sizeof(struct uart_icount));
++ spin_unlock_irq(&port->lock);
++
++ set_current_state(TASK_INTERRUPTIBLE);
++
++ if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
++ ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
++ ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
++ ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) {
++ ret = 0;
++ break;
++ }
++
++ schedule();
++
++ /* see if a signal did it */
++ if (signal_pending(current)) {
++ ret = -ERESTARTSYS;
++ break;
++ }
++
++ cprev = cnow;
++ }
++
++ current->state = TASK_RUNNING;
++ remove_wait_queue(&state->info->delta_msr_wait, &wait);
++
++ return ret;
++}
++
++/*
++ * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
++ * Return: write counters to the user passed counter struct
++ * NB: both 1->0 and 0->1 transitions are counted except for
++ * RI where only 0->1 is counted.
++ */
++static int
++uart_get_count(struct uart_state *state, struct serial_icounter_struct *icnt)
++{
++ struct serial_icounter_struct icount;
++ struct uart_icount cnow;
++ struct uart_port *port = state->port;
++
++ spin_lock_irq(&port->lock);
++ memcpy(&cnow, &port->icount, sizeof(struct uart_icount));
++ spin_unlock_irq(&port->lock);
++
++ icount.cts = cnow.cts;
++ icount.dsr = cnow.dsr;
++ icount.rng = cnow.rng;
++ icount.dcd = cnow.dcd;
++ icount.rx = cnow.rx;
++ icount.tx = cnow.tx;
++ icount.frame = cnow.frame;
++ icount.overrun = cnow.overrun;
++ icount.parity = cnow.parity;
++ icount.brk = cnow.brk;
++ icount.buf_overrun = cnow.buf_overrun;
++
++ return copy_to_user(icnt, &icount, sizeof(icount)) ? -EFAULT : 0;
++}
++
++/*
++ * Called via sys_ioctl under the BKL. We can use spin_lock_irq() here.
++ */
++static int
++uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd,
++ unsigned long arg)
++{
++ struct uart_state *state = tty->driver_data;
++ int ret = -ENOIOCTLCMD;
++
++ BUG_ON(!kernel_locked());
++
++ /*
++ * These ioctls don't rely on the hardware to be present.
++ */
++ switch (cmd) {
++ case TIOCGSERIAL:
++ ret = uart_get_info(state, (struct serial_struct *)arg);
++ break;
++
++ case TIOCSSERIAL:
++ ret = uart_set_info(state, (struct serial_struct *)arg);
++ break;
++
++ case TIOCSERCONFIG:
++ ret = uart_do_autoconfig(state);
++ break;
++
++ case TIOCSERGWILD: /* obsolete */
++ case TIOCSERSWILD: /* obsolete */
++ ret = 0;
++ break;
++ }
++
++ if (ret != -ENOIOCTLCMD)
++ goto out;
++
++ if (tty->flags & (1 << TTY_IO_ERROR)) {
++ ret = -EIO;
++ goto out;
++ }
++
++ /*
++ * The following should only be used when hardware is present.
++ */
++ switch (cmd) {
++ case TIOCMIWAIT:
++ ret = uart_wait_modem_status(state, arg);
++ break;
++
++ case TIOCGICOUNT:
++ ret = uart_get_count(state, (struct serial_icounter_struct *)arg);
++ break;
++ }
++
++ if (ret != -ENOIOCTLCMD)
++ goto out;
++
++ down(&state->sem);
++
++ if (tty_hung_up_p(filp)) {
++ ret = -EIO;
++ goto out_up;
++ }
++
++ /*
++ * All these rely on hardware being present and need to be
++ * protected against the tty being hung up.
++ */
++ switch (cmd) {
++ case TIOCSERGETLSR: /* Get line status register */
++ ret = uart_get_lsr_info(state, (unsigned int *)arg);
++ break;
++
++ default: {
++ struct uart_port *port = state->port;
++ if (port->ops->ioctl)
++ ret = port->ops->ioctl(port, cmd, arg);
++ break;
++ }
++ }
++ out_up:
++ up(&state->sem);
++ out:
++ return ret;
++}
++
++static void uart_set_termios(struct tty_struct *tty, struct termios *old_termios)
++{
++ struct uart_state *state = tty->driver_data;
++ unsigned long flags;
++ unsigned int cflag = tty->termios->c_cflag;
++
++ BUG_ON(!kernel_locked());
++
++ /*
++ * These are the bits that are used to setup various
++ * flags in the low level driver.
++ */
++#define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
++
++ if ((cflag ^ old_termios->c_cflag) == 0 &&
++ RELEVANT_IFLAG(tty->termios->c_iflag ^ old_termios->c_iflag) == 0)
++ return;
++
++ uart_change_speed(state, old_termios);
++
++ /* Handle transition to B0 status */
++ if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD))
++ uart_clear_mctrl(state->port, TIOCM_RTS | TIOCM_DTR);
++
++ /* Handle transition away from B0 status */
++ if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) {
++ unsigned int mask = TIOCM_DTR;
++ if (!(cflag & CRTSCTS) ||
++ !test_bit(TTY_THROTTLED, &tty->flags))
++ mask |= TIOCM_RTS;
++ uart_set_mctrl(state->port, mask);
++ }
++
++ /* Handle turning off CRTSCTS */
++ if ((old_termios->c_cflag & CRTSCTS) && !(cflag & CRTSCTS)) {
++ spin_lock_irqsave(&state->port->lock, flags);
++ tty->hw_stopped = 0;
++ __uart_start(tty);
++ spin_unlock_irqrestore(&state->port->lock, flags);
++ }
++
++#if 0
++ /*
++ * No need to wake up processes in open wait, since they
++ * sample the CLOCAL flag once, and don't recheck it.
++ * XXX It's not clear whether the current behavior is correct
++ * or not. Hence, this may change.....
++ */
++ if (!(old_termios->c_cflag & CLOCAL) &&
++ (tty->termios->c_cflag & CLOCAL))
++ wake_up_interruptible(&state->info->open_wait);
++#endif
++}
++
++/*
++ * In 2.4.5, calls to this will be serialized via the BKL in
++ * linux/drivers/char/tty_io.c:tty_release()
++ * linux/drivers/char/tty_io.c:do_tty_handup()
++ */
++static void uart_close(struct tty_struct *tty, struct file *filp)
++{
++ struct uart_state *state = tty->driver_data;
++ struct uart_port *port = state->port;
++
++ BUG_ON(!kernel_locked());
++ DPRINTK("uart_close(%d) called\n", port->line);
++
++ down(&state->sem);
++
++ if (tty_hung_up_p(filp))
++ goto done;
++
++ if ((tty->count == 1) && (state->count != 1)) {
++ /*
++ * Uh, oh. tty->count is 1, which means that the tty
++ * structure will be freed. state->count should always
++ * be one in these conditions. If it's greater than
++ * one, we've got real problems, since it means the
++ * serial port won't be shutdown.
++ */
++ printk("uart_close: bad serial port count; tty->count is 1, "
++ "state->count is %d\n", state->count);
++ state->count = 1;
++ }
++ if (--state->count < 0) {
++ printk("rs_close: bad serial port count for %s: %d\n",
++ tty->name, state->count);
++ state->count = 0;
++ }
++ if (state->count)
++ goto done;
++
++ /*
++ * Now we wait for the transmit buffer to clear; and we notify
++ * the line discipline to only process XON/XOFF characters by
++ * setting tty->closing.
++ */
++ tty->closing = 1;
++
++ if (state->closing_wait != USF_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.
++ */
++ if (state->info->flags & UIF_INITIALIZED) {
++ unsigned long flags;
++ spin_lock_irqsave(&port->lock, flags);
++ port->ops->stop_rx(port);
++ spin_unlock_irqrestore(&port->lock, flags);
++ /*
++ * Before we drop DTR, make sure the UART transmitter
++ * has completely drained; this is especially
++ * important if there is a transmit FIFO!
++ */
++ uart_wait_until_sent(tty, port->timeout);
++ }
++
++ uart_shutdown(state);
++ uart_flush_buffer(tty);
++ if (tty->ldisc.flush_buffer)
++ tty->ldisc.flush_buffer(tty);
++ tty->closing = 0;
++ state->info->tty = NULL;
++
++ if (state->info->blocked_open) {
++ if (state->close_delay) {
++ set_current_state(TASK_INTERRUPTIBLE);
++ schedule_timeout(state->close_delay);
++ set_current_state(TASK_RUNNING);
++ }
++ } else if (!uart_console(port)) {
++ uart_change_pm(state, 3);
++ }
++
++ /*
++ * Wake up anyone trying to open this port.
++ */
++ state->info->flags &= ~UIF_NORMAL_ACTIVE;
++ wake_up_interruptible(&state->info->open_wait);
++
++ done:
++ up(&state->sem);
++}
++
++static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
++{
++ struct uart_state *state = tty->driver_data;
++ struct uart_port *port = state->port;
++ unsigned long char_time, expire;
++
++ BUG_ON(!kernel_locked());
++
++ if (port->type == PORT_UNKNOWN || port->fifosize == 0)
++ return;
++
++ /*
++ * Set the check interval to be 1/5 of the estimated time to
++ * send a single character, and make it at least 1. The check
++ * interval should also be less than the timeout.
++ *
++ * Note: we have to use pretty tight timings here to satisfy
++ * the NIST-PCTS.
++ */
++ char_time = (port->timeout - HZ/50) / port->fifosize;
++ char_time = char_time / 5;
++ if (char_time == 0)
++ char_time = 1;
++ if (timeout && timeout < char_time)
++ char_time = timeout;
++
++ /*
++ * If the transmitter hasn't cleared in twice the approximate
++ * amount of time to send the entire FIFO, it probably won't
++ * ever clear. This assumes the UART isn't doing flow
++ * control, which is currently the case. Hence, if it ever
++ * takes longer than port->timeout, this is probably due to a
++ * UART bug of some kind. So, we clamp the timeout parameter at
++ * 2*port->timeout.
++ */
++ if (timeout == 0 || timeout > 2 * port->timeout)
++ timeout = 2 * port->timeout;
++
++ expire = jiffies + timeout;
++
++ DPRINTK("uart_wait_until_sent(%d), jiffies=%lu, expire=%lu...\n",
++ port->line, jiffies, expire);
++
++ /*
++ * Check whether the transmitter is empty every 'char_time'.
++ * 'timeout' / 'expire' give us the maximum amount of time
++ * we wait.
++ */
++ while (!port->ops->tx_empty(port)) {
++ set_current_state(TASK_INTERRUPTIBLE);
++ schedule_timeout(char_time);
++ if (signal_pending(current))
++ break;
++ if (time_after(jiffies, expire))
++ break;
++ }
++ set_current_state(TASK_RUNNING); /* might not be needed */
++}
++
++/*
++ * This is called with the BKL held in
++ * linux/drivers/char/tty_io.c:do_tty_hangup()
++ * We're called from the eventd thread, so we can sleep for
++ * a _short_ time only.
++ */
++static void uart_hangup(struct tty_struct *tty)
++{
++ struct uart_state *state = tty->driver_data;
++
++ BUG_ON(!kernel_locked());
++ DPRINTK("uart_hangup(%d)\n", state->port->line);
++
++ down(&state->sem);
++ if (state->info && state->info->flags & UIF_NORMAL_ACTIVE) {
++ uart_flush_buffer(tty);
++ uart_shutdown(state);
++ state->count = 0;
++ state->info->flags &= ~UIF_NORMAL_ACTIVE;
++ state->info->tty = NULL;
++ wake_up_interruptible(&state->info->open_wait);
++ wake_up_interruptible(&state->info->delta_msr_wait);
++ }
++ up(&state->sem);
++}
++
++/*
++ * Copy across the serial console cflag setting into the termios settings
++ * for the initial open of the port. This allows continuity between the
++ * kernel settings, and the settings init adopts when it opens the port
++ * for the first time.
++ */
++static void uart_update_termios(struct uart_state *state)
++{
++ struct tty_struct *tty = state->info->tty;
++ struct uart_port *port = state->port;
++
++ if (uart_console(port) && port->cons->cflag) {
++ tty->termios->c_cflag = port->cons->cflag;
++ port->cons->cflag = 0;
++ }
++
++ /*
++ * If the device failed to grab its irq resources,
++ * or some other error occurred, don't try to talk
++ * to the port hardware.
++ */
++ if (!(tty->flags & (1 << TTY_IO_ERROR))) {
++ /*
++ * Make termios settings take effect.
++ */
++ uart_change_speed(state, NULL);
++
++ /*
++ * And finally enable the RTS and DTR signals.
++ */
++ if (tty->termios->c_cflag & CBAUD)
++ uart_set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
++ }
++}
++
++/*
++ * Block the open until the port is ready. We must be called with
++ * the per-port semaphore held.
++ */
++static int
++uart_block_til_ready(struct file *filp, struct uart_state *state)
++{
++ DECLARE_WAITQUEUE(wait, current);
++ struct uart_info *info = state->info;
++ struct uart_port *port = state->port;
++
++ info->blocked_open++;
++ state->count--;
++
++ add_wait_queue(&info->open_wait, &wait);
++ while (1) {
++ set_current_state(TASK_INTERRUPTIBLE);
++
++ /*
++ * If we have been hung up, tell userspace/restart open.
++ */
++ if (tty_hung_up_p(filp) || info->tty == NULL)
++ break;
++
++ /*
++ * If the port has been closed, tell userspace/restart open.
++ */
++ if (!(info->flags & UIF_INITIALIZED))
++ break;
++
++ /*
++ * If non-blocking mode is set, or CLOCAL mode is set,
++ * we don't want to wait for the modem status lines to
++ * indicate that the port is ready.
++ *
++ * Also, if the port is not enabled/configured, we want
++ * to allow the open to succeed here. Note that we will
++ * have set TTY_IO_ERROR for a non-existant port.
++ */
++ if ((filp->f_flags & O_NONBLOCK) ||
++ (info->tty->termios->c_cflag & CLOCAL) ||
++ (info->tty->flags & (1 << TTY_IO_ERROR))) {
++ break;
++ }
++
++ /*
++ * Set DTR to allow modem to know we're waiting. Do
++ * not set RTS here - we want to make sure we catch
++ * the data from the modem.
++ */
++ if (info->tty->termios->c_cflag & CBAUD)
++ uart_set_mctrl(port, TIOCM_DTR);
++
++ /*
++ * and wait for the carrier to indicate that the
++ * modem is ready for us.
++ */
++ if (port->ops->get_mctrl(port) & TIOCM_CAR)
++ break;
++
++ up(&state->sem);
++ schedule();
++ down(&state->sem);
++
++ if (signal_pending(current))
++ break;
++ }
++ set_current_state(TASK_RUNNING);
++ remove_wait_queue(&info->open_wait, &wait);
++
++ state->count++;
++ info->blocked_open--;
++
++ if (signal_pending(current))
++ return -ERESTARTSYS;
++
++ if (!info->tty || tty_hung_up_p(filp))
++ return -EAGAIN;
++
++ return 0;
++}
++
++static struct uart_state *uart_get(struct uart_driver *drv, int line)
++{
++ struct uart_state *state;
++
++ down(&port_sem);
++ state = drv->state + line;
++ if (down_interruptible(&state->sem)) {
++ state = ERR_PTR(-ERESTARTSYS);
++ goto out;
++ }
++
++ state->count++;
++ if (!state->port) {
++ state->count--;
++ up(&state->sem);
++ state = ERR_PTR(-ENXIO);
++ goto out;
++ }
++
++ if (!state->info) {
++ state->info = kmalloc(sizeof(struct uart_info), GFP_KERNEL);
++ if (state->info) {
++ memset(state->info, 0, sizeof(struct uart_info));
++ init_waitqueue_head(&state->info->open_wait);
++ init_waitqueue_head(&state->info->delta_msr_wait);
++
++ /*
++ * Link the info into the other structures.
++ */
++ state->port->info = state->info;
++
++ tasklet_init(&state->info->tlet, uart_tasklet_action,
++ (unsigned long)state);
++ } else {
++ state->count--;
++ up(&state->sem);
++ state = ERR_PTR(-ENOMEM);
++ }
++ }
++
++ out:
++ up(&port_sem);
++ return state;
++}
++
++/*
++ * In 2.4.5, calls to uart_open are serialised by the BKL in
++ * linux/fs/devices.c:chrdev_open()
++ * Note that if this fails, then uart_close() _will_ be called.
++ *
++ * In time, we want to scrap the "opening nonpresent ports"
++ * behaviour and implement an alternative way for setserial
++ * to set base addresses/ports/types. This will allow us to
++ * get rid of a certain amount of extra tests.
++ */
++static int uart_open(struct tty_struct *tty, struct file *filp)
++{
++ struct uart_driver *drv = (struct uart_driver *)tty->driver->driver_state;
++ struct uart_state *state;
++ int retval, line = tty->index;
++
++ BUG_ON(!kernel_locked());
++ DPRINTK("uart_open(%d) called\n", line);
++
++ /*
++ * tty->driver->num won't change, so we won't fail here with
++ * tty->driver_data set to something non-NULL (and therefore
++ * we won't get caught by uart_close()).
++ */
++ retval = -ENODEV;
++ if (line >= tty->driver->num)
++ goto fail;
++
++ /*
++ * We take the semaphore inside uart_get to guarantee that we won't
++ * be re-entered while allocating the info structure, or while we
++ * request any IRQs that the driver may need. This also has the nice
++ * side-effect that it delays the action of uart_hangup, so we can
++ * guarantee that info->tty will always contain something reasonable.
++ */
++ state = uart_get(drv, line);
++ if (IS_ERR(state)) {
++ retval = PTR_ERR(state);
++ goto fail;
++ }
++
++ /*
++ * Once we set tty->driver_data here, we are guaranteed that
++ * uart_close() will decrement the driver module use count.
++ * Any failures from here onwards should not touch the count.
++ */
++ tty->driver_data = state;
++ tty->low_latency = (state->port->flags & UPF_LOW_LATENCY) ? 1 : 0;
++ tty->alt_speed = 0;
++ state->info->tty = tty;
++
++ /*
++ * If the port is in the middle of closing, bail out now.
++ */
++ if (tty_hung_up_p(filp)) {
++ retval = -EAGAIN;
++ state->count--;
++ up(&state->sem);
++ goto fail;
++ }
++
++ /*
++ * Make sure the device is in D0 state.
++ */
++ if (state->count == 1)
++ uart_change_pm(state, 0);
++
++ /*
++ * Start up the serial port.
++ */
++ retval = uart_startup(state, 0);
++
++ /*
++ * If we succeeded, wait until the port is ready.
++ */
++ if (retval == 0)
++ retval = uart_block_til_ready(filp, state);
++ up(&state->sem);
++
++ /*
++ * If this is the first open to succeed, adjust things to suit.
++ */
++ if (retval == 0 && !(state->info->flags & UIF_NORMAL_ACTIVE)) {
++ state->info->flags |= UIF_NORMAL_ACTIVE;
++
++ uart_update_termios(state);
++ }
++
++ fail:
++ return retval;
++}
++
++static const char *uart_type(struct uart_port *port)
++{
++ const char *str = NULL;
++
++ if (port->ops->type)
++ str = port->ops->type(port);
++
++ if (!str)
++ str = "unknown";
++
++ return str;
++}
++
++#ifdef CONFIG_PROC_FS
++
++static int uart_line_info(char *buf, struct uart_driver *drv, int i)
++{
++ struct uart_state *state = drv->state + i;
++ struct uart_port *port = state->port;
++ char stat_buf[32];
++ unsigned int status;
++ int ret;
++
++ if (!port)
++ return 0;
++
++ ret = sprintf(buf, "%d: uart:%s port:%08X irq:%d",
++ port->line, uart_type(port),
++ port->iobase, port->irq);
++
++ if (port->type == PORT_UNKNOWN) {
++ strcat(buf, "\n");
++ return ret + 1;
++ }
++
++ if(capable(CAP_SYS_ADMIN))
++ {
++ status = port->ops->get_mctrl(port);
++
++ ret += sprintf(buf + ret, " tx:%d rx:%d",
++ port->icount.tx, port->icount.rx);
++ if (port->icount.frame)
++ ret += sprintf(buf + ret, " fe:%d",
++ port->icount.frame);
++ if (port->icount.parity)
++ ret += sprintf(buf + ret, " pe:%d",
++ port->icount.parity);
++ if (port->icount.brk)
++ ret += sprintf(buf + ret, " brk:%d",
++ port->icount.brk);
++ if (port->icount.overrun)
++ ret += sprintf(buf + ret, " oe:%d",
++ port->icount.overrun);
++
++#define INFOBIT(bit,str) \
++ if (port->mctrl & (bit)) \
++ strncat(stat_buf, (str), sizeof(stat_buf) - \
++ strlen(stat_buf) - 2)
++#define STATBIT(bit,str) \
++ if (status & (bit)) \
++ strncat(stat_buf, (str), sizeof(stat_buf) - \
++ strlen(stat_buf) - 2)
++
++ stat_buf[0] = '\0';
++ stat_buf[1] = '\0';
++ INFOBIT(TIOCM_RTS, "|RTS");
++ STATBIT(TIOCM_CTS, "|CTS");
++ INFOBIT(TIOCM_DTR, "|DTR");
++ STATBIT(TIOCM_DSR, "|DSR");
++ STATBIT(TIOCM_CAR, "|CD");
++ STATBIT(TIOCM_RNG, "|RI");
++ if (stat_buf[0])
++ stat_buf[0] = ' ';
++ strcat(stat_buf, "\n");
++
++ ret += sprintf(buf + ret, stat_buf);
++ }
++#undef STATBIT
++#undef INFOBIT
++ return ret;
++}
++
++static int uart_read_proc(char *page, char **start, off_t off,
++ int count, int *eof, void *data)
++{
++ struct tty_driver *ttydrv = data;
++ struct uart_driver *drv = ttydrv->driver_state;
++ int i, len = 0, l;
++ off_t begin = 0;
++
++ len += sprintf(page, "serinfo:1.0 driver%s%s revision:%s\n",
++ "", "", "");
++ for (i = 0; i < drv->nr && len < PAGE_SIZE - 96; i++) {
++ l = uart_line_info(page + len, drv, i);
++ len += l;
++ if (len + begin > off + count)
++ goto done;
++ if (len + begin < off) {
++ begin += len;
++ len = 0;
++ }
++ }
++ *eof = 1;
++ done:
++ if (off >= len + begin)
++ return 0;
++ *start = page + (off - begin);
++ return (count < begin + len - off) ? count : (begin + len - off);
++}
++#endif
++
++#ifdef CONFIG_SERIAL_CORE_CONSOLE
++/*
++ * Check whether an invalid uart number has been specified, and
++ * if so, search for the first available port that does have
++ * console support.
++ */
++struct uart_port * __init
++uart_get_console(struct uart_port *ports, int nr, struct console *co)
++{
++ int idx = co->index;
++
++ if (idx < 0 || idx >= nr || (ports[idx].iobase == 0 &&
++ ports[idx].membase == NULL))
++ for (idx = 0; idx < nr; idx++)
++ if (ports[idx].iobase != 0 ||
++ ports[idx].membase != NULL)
++ break;
++
++ co->index = idx;
++
++ return ports + idx;
++}
++
++/**
++ * uart_parse_options - Parse serial port baud/parity/bits/flow contro.
++ * @options: pointer to option string
++ * @baud: pointer to an 'int' variable for the baud rate.
++ * @parity: pointer to an 'int' variable for the parity.
++ * @bits: pointer to an 'int' variable for the number of data bits.
++ * @flow: pointer to an 'int' variable for the flow control character.
++ *
++ * uart_parse_options decodes a string containing the serial console
++ * options. The format of the string is <baud><parity><bits><flow>,
++ * eg: 115200n8r
++ */
++void __init
++uart_parse_options(char *options, int *baud, int *parity, int *bits, int *flow)
++{
++ char *s = options;
++
++ *baud = simple_strtoul(s, NULL, 10);
++ while (*s >= '0' && *s <= '9')
++ s++;
++ if (*s)
++ *parity = *s++;
++ if (*s)
++ *bits = *s++ - '0';
++ if (*s)
++ *flow = *s;
++}
++
++struct baud_rates {
++ unsigned int rate;
++ unsigned int cflag;
++};
++
++static struct baud_rates baud_rates[] = {
++ { 921600, B921600 },
++ { 460800, B460800 },
++ { 230400, B230400 },
++ { 115200, B115200 },
++ { 57600, B57600 },
++ { 38400, B38400 },
++ { 19200, B19200 },
++ { 9600, B9600 },
++ { 4800, B4800 },
++ { 2400, B2400 },
++ { 1200, B1200 },
++ { 0, B38400 }
++};
++
++/**
++ * uart_set_options - setup the serial console parameters
++ * @port: pointer to the serial ports uart_port structure
++ * @co: console pointer
++ * @baud: baud rate
++ * @parity: parity character - 'n' (none), 'o' (odd), 'e' (even)
++ * @bits: number of data bits
++ * @flow: flow control character - 'r' (rts)
++ */
++int __init
++uart_set_options(struct uart_port *port, struct console *co,
++ int baud, int parity, int bits, int flow)
++{
++ struct termios termios;
++ int i;
++
++ memset(&termios, 0, sizeof(struct termios));
++
++ termios.c_cflag = CREAD | HUPCL | CLOCAL;
++
++ /*
++ * Construct a cflag setting.
++ */
++ for (i = 0; baud_rates[i].rate; i++)
++ if (baud_rates[i].rate <= baud)
++ break;
++
++ termios.c_cflag |= baud_rates[i].cflag;
++
++ if (bits == 7)
++ termios.c_cflag |= CS7;
++ else
++ termios.c_cflag |= CS8;
++
++ switch (parity) {
++ case 'o': case 'O':
++ termios.c_cflag |= PARODD;
++ /*fall through*/
++ case 'e': case 'E':
++ termios.c_cflag |= PARENB;
++ break;
++ }
++
++ if (flow == 'r')
++ termios.c_cflag |= CRTSCTS;
++
++ port->ops->set_termios(port, &termios, NULL);
++ co->cflag = termios.c_cflag;
++
++ return 0;
++}
++#endif /* CONFIG_SERIAL_CORE_CONSOLE */
++
++static void uart_change_pm(struct uart_state *state, int pm_state)
++{
++ struct uart_port *port = state->port;
++ if (port->ops->pm)
++ port->ops->pm(port, pm_state, state->pm_state);
++ state->pm_state = pm_state;
++}
++
++int uart_suspend_port(struct uart_driver *drv, struct uart_port *port)
++{
++ struct uart_state *state = drv->state + port->line;
++
++ down(&state->sem);
++
++ if (state->info && state->info->flags & UIF_INITIALIZED) {
++ struct uart_ops *ops = port->ops;
++
++ spin_lock_irq(&port->lock);
++ ops->stop_tx(port, 0);
++ ops->set_mctrl(port, 0);
++ ops->stop_rx(port);
++ spin_unlock_irq(&port->lock);
++
++ /*
++ * Wait for the transmitter to empty.
++ */
++ while (!ops->tx_empty(port)) {
++ set_current_state(TASK_UNINTERRUPTIBLE);
++ schedule_timeout(10*HZ/1000);
++ }
++ set_current_state(TASK_RUNNING);
++
++ ops->shutdown(port);
++ }
++
++ /*
++ * Disable the console device before suspending.
++ */
++ if (uart_console(port))
++ port->cons->flags &= ~CON_ENABLED;
++
++ uart_change_pm(state, 3);
++
++ up(&state->sem);
++
++ return 0;
++}
++
++int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
++{
++ struct uart_state *state = drv->state + port->line;
++
++ down(&state->sem);
++
++ uart_change_pm(state, 0);
++
++ /*
++ * Re-enable the console device after suspending.
++ */
++ if (uart_console(port)) {
++ uart_change_speed(state, NULL);
++ port->cons->flags |= CON_ENABLED;
++ }
++
++ if (state->info && state->info->flags & UIF_INITIALIZED) {
++ struct uart_ops *ops = port->ops;
++
++ ops->set_mctrl(port, 0);
++ ops->startup(port);
++ uart_change_speed(state, NULL);
++ spin_lock_irq(&port->lock);
++ ops->set_mctrl(port, port->mctrl);
++ ops->start_tx(port, 0);
++ spin_unlock_irq(&port->lock);
++ }
++
++ up(&state->sem);
++
++ return 0;
++}
++
++static inline void
++uart_report_port(struct uart_driver *drv, struct uart_port *port)
++{
++ printk("%s%d", drv->dev_name, port->line);
++ printk(" at ");
++ switch (port->iotype) {
++ case UPIO_PORT:
++ printk("I/O 0x%x", port->iobase);
++ break;
++ case UPIO_HUB6:
++ printk("I/O 0x%x offset 0x%x", port->iobase, port->hub6);
++ break;
++ case UPIO_MEM:
++ printk("MMIO 0x%lx", port->mapbase);
++ break;
++ }
++ printk(" (irq = %d) is a %s\n", port->irq, uart_type(port));
++}
++
++static void
++uart_configure_port(struct uart_driver *drv, struct uart_state *state,
++ struct uart_port *port)
++{
++ unsigned int flags;
++
++#ifdef CONFIG_KGDB
++ if (port->kgdb)
++ return;
++#endif
++
++ /*
++ * If there isn't a port here, don't do anything further.
++ */
++ if (!port->iobase && !port->mapbase && !port->membase)
++ return;
++
++ /*
++ * Now do the auto configuration stuff. Note that config_port
++ * is expected to claim the resources and map the port for us.
++ */
++ flags = UART_CONFIG_TYPE;
++ if (port->flags & UPF_AUTO_IRQ)
++ flags |= UART_CONFIG_IRQ;
++ if (port->flags & UPF_BOOT_AUTOCONF) {
++ port->type = PORT_UNKNOWN;
++ port->ops->config_port(port, flags);
++ }
++
++ if (port->type != PORT_UNKNOWN) {
++ unsigned long flags;
++
++ uart_report_port(drv, port);
++
++ /*
++ * Ensure that the modem control lines are de-activated.
++ * We probably don't need a spinlock around this, but
++ */
++ spin_lock_irqsave(&port->lock, flags);
++ port->ops->set_mctrl(port, 0);
++ spin_unlock_irqrestore(&port->lock, flags);
++
++ /*
++ * Power down all ports by default, except the
++ * console if we have one.
++ */
++ if (!uart_console(port))
++ uart_change_pm(state, 3);
++ }
++}
++
++/*
++ * This reverses the effects of uart_configure_port, hanging up the
++ * port before removal.
++ */
++static void
++uart_unconfigure_port(struct uart_driver *drv, struct uart_state *state)
++{
++ struct uart_port *port = state->port;
++ struct uart_info *info = state->info;
++
++ if (info && info->tty)
++ tty_vhangup(info->tty);
++
++ down(&state->sem);
++
++ state->info = NULL;
++
++ /*
++ * Free the port IO and memory resources, if any.
++ */
++ if (port->type != PORT_UNKNOWN)
++ port->ops->release_port(port);
++
++ /*
++ * Indicate that there isn't a port here anymore.
++ */
++ port->type = PORT_UNKNOWN;
++
++ /*
++ * Kill the tasklet, and free resources.
++ */
++ if (info) {
++ tasklet_kill(&info->tlet);
++ kfree(info);
++ }
++
++ up(&state->sem);
++}
++
++static struct tty_operations uart_ops = {
++ .open = uart_open,
++ .close = uart_close,
++ .write = uart_write,
++ .put_char = uart_put_char,
++ .flush_chars = uart_flush_chars,
++ .write_room = uart_write_room,
++ .chars_in_buffer= uart_chars_in_buffer,
++ .flush_buffer = uart_flush_buffer,
++ .ioctl = uart_ioctl,
++ .throttle = uart_throttle,
++ .unthrottle = uart_unthrottle,
++ .send_xchar = uart_send_xchar,
++ .set_termios = uart_set_termios,
++ .stop = uart_stop,
++ .start = uart_start,
++ .hangup = uart_hangup,
++ .break_ctl = uart_break_ctl,
++ .wait_until_sent= uart_wait_until_sent,
++#ifdef CONFIG_PROC_FS
++ .read_proc = uart_read_proc,
++#endif
++ .tiocmget = uart_tiocmget,
++ .tiocmset = uart_tiocmset,
++};
++
++/**
++ * uart_register_driver - register a driver with the uart core layer
++ * @drv: low level driver structure
++ *
++ * Register a uart driver with the core driver. We in turn register
++ * with the tty layer, and initialise the core driver per-port state.
++ *
++ * We have a proc file in /proc/tty/driver which is named after the
++ * normal driver.
++ *
++ * drv->port should be NULL, and the per-port structures should be
++ * registered using uart_add_one_port after this call has succeeded.
++ */
++int uart_register_driver(struct uart_driver *drv)
++{
++ struct tty_driver *normal = NULL;
++ int i, retval;
++
++ BUG_ON(drv->state);
++
++ /*
++ * Maybe we should be using a slab cache for this, especially if
++ * we have a large number of ports to handle.
++ */
++ drv->state = kmalloc(sizeof(struct uart_state) * drv->nr, GFP_KERNEL);
++ retval = -ENOMEM;
++ if (!drv->state)
++ goto out;
++
++ memset(drv->state, 0, sizeof(struct uart_state) * drv->nr);
++
++ normal = alloc_tty_driver(drv->nr);
++ if (!normal)
++ goto out;
++
++ drv->tty_driver = normal;
++
++ normal->owner = drv->owner;
++ normal->driver_name = drv->driver_name;
++ normal->devfs_name = drv->devfs_name;
++ normal->name = drv->dev_name;
++ normal->major = drv->major;
++ normal->minor_start = drv->minor;
++ normal->type = TTY_DRIVER_TYPE_SERIAL;
++ normal->subtype = SERIAL_TYPE_NORMAL;
++ normal->init_termios = tty_std_termios;
++ normal->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
++ normal->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
++ normal->driver_state = drv;
++ tty_set_operations(normal, &uart_ops);
++
++ /*
++ * Initialise the UART state(s).
++ */
++ for (i = 0; i < drv->nr; i++) {
++ struct uart_state *state = drv->state + i;
++
++ state->close_delay = 5 * HZ / 10;
++ state->closing_wait = 30 * HZ;
++
++ init_MUTEX(&state->sem);
++ }
++
++ retval = tty_register_driver(normal);
++ out:
++ if (retval < 0) {
++ put_tty_driver(normal);
++ kfree(drv->state);
++ }
++ return retval;
++}
++
++/**
++ * uart_unregister_driver - remove a driver from the uart core layer
++ * @drv: low level driver structure
++ *
++ * Remove all references to a driver from the core driver. The low
++ * level driver must have removed all its ports via the
++ * uart_remove_one_port() if it registered them with uart_add_one_port().
++ * (ie, drv->port == NULL)
++ */
++void uart_unregister_driver(struct uart_driver *drv)
++{
++ struct tty_driver *p = drv->tty_driver;
++ tty_unregister_driver(p);
++ put_tty_driver(p);
++ kfree(drv->state);
++ drv->tty_driver = NULL;
++}
++
++struct tty_driver *uart_console_device(struct console *co, int *index)
++{
++ struct uart_driver *p = co->data;
++ *index = co->index;
++ return p->tty_driver;
++}
++
++/**
++ * uart_add_one_port - attach a driver-defined port structure
++ * @drv: pointer to the uart low level driver structure for this port
++ * @port: uart port structure to use for this port.
++ *
++ * This allows the driver to register its own uart_port structure
++ * with the core driver. The main purpose is to allow the low
++ * level uart drivers to expand uart_port, rather than having yet
++ * more levels of structures.
++ */
++int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
++{
++ struct uart_state *state;
++ int ret = 0;
++
++ BUG_ON(in_interrupt());
++
++ if (port->line >= drv->nr)
++ return -EINVAL;
++
++ state = drv->state + port->line;
++
++ down(&port_sem);
++ if (state->port) {
++ ret = -EINVAL;
++ goto out;
++ }
++
++ state->port = port;
++
++ spin_lock_init(&port->lock);
++ port->cons = drv->cons;
++ port->info = state->info;
++
++ uart_configure_port(drv, state, port);
++
++ /*
++ * Register the port whether it's detected or not. This allows
++ * setserial to be used to alter this ports parameters.
++ */
++ tty_register_device(drv->tty_driver, port->line, NULL);
++
++ out:
++ up(&port_sem);
++
++ return ret;
++}
++
++/**
++ * uart_remove_one_port - detach a driver defined port structure
++ * @drv: pointer to the uart low level driver structure for this port
++ * @port: uart port structure for this port
++ *
++ * This unhooks (and hangs up) the specified port structure from the
++ * core driver. No further calls will be made to the low-level code
++ * for this port.
++ */
++int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port)
++{
++ struct uart_state *state = drv->state + port->line;
++
++ BUG_ON(in_interrupt());
++
++ if (state->port != port)
++ printk(KERN_ALERT "Removing wrong port: %p != %p\n",
++ state->port, port);
++
++ down(&port_sem);
++
++ /*
++ * Remove the devices from devfs
++ */
++ tty_unregister_device(drv->tty_driver, port->line);
++
++ uart_unconfigure_port(drv, state);
++ state->port = NULL;
++ up(&port_sem);
++
++ return 0;
++}
++
++/*
++ * Are the two ports equivalent?
++ */
++static int uart_match_port(struct uart_port *port1, struct uart_port *port2)
++{
++ if (port1->iotype != port2->iotype)
++ return 0;
++
++ switch (port1->iotype) {
++ case UPIO_PORT:
++ return (port1->iobase == port2->iobase);
++ case UPIO_HUB6:
++ return (port1->iobase == port2->iobase) &&
++ (port1->hub6 == port2->hub6);
++ case UPIO_MEM:
++ return (port1->membase == port2->membase);
++ }
++ return 0;
++}
++
++/*
++ * Try to find an unused uart_state slot for a port.
++ */
++static struct uart_state *
++uart_find_match_or_unused(struct uart_driver *drv, struct uart_port *port)
++{
++ int i;
++
++ /*
++ * First, find a port entry which matches. Note: if we do
++ * find a matching entry, and it has a non-zero use count,
++ * then we can't register the port.
++ */
++ for (i = 0; i < drv->nr; i++)
++ if (uart_match_port(drv->state[i].port, port))
++ return &drv->state[i];
++
++ /*
++ * We didn't find a matching entry, so look for the first
++ * free entry. We look for one which hasn't been previously
++ * used (indicated by zero iobase).
++ */
++ for (i = 0; i < drv->nr; i++)
++ if (drv->state[i].port->type == PORT_UNKNOWN &&
++ drv->state[i].port->iobase == 0 &&
++ drv->state[i].count == 0)
++ return &drv->state[i];
++
++ /*
++ * That also failed. Last resort is to find any currently
++ * entry which doesn't have a real port associated with it.
++ */
++ for (i = 0; i < drv->nr; i++)
++ if (drv->state[i].port->type == PORT_UNKNOWN &&
++ drv->state[i].count == 0)
++ return &drv->state[i];
++
++ return NULL;
++}
++
++/**
++ * uart_register_port: register uart settings with a port
++ * @drv: pointer to the uart low level driver structure for this port
++ * @port: uart port structure describing the port
++ *
++ * Register UART settings with the specified low level driver. Detect
++ * the type of the port if UPF_BOOT_AUTOCONF is set, and detect the
++ * IRQ if UPF_AUTO_IRQ is set.
++ *
++ * We try to pick the same port for the same IO base address, so that
++ * when a modem is plugged in, unplugged and plugged back in, it gets
++ * allocated the same port.
++ *
++ * Returns negative error, or positive line number.
++ */
++int uart_register_port(struct uart_driver *drv, struct uart_port *port)
++{
++ struct uart_state *state;
++ int ret;
++
++ down(&port_sem);
++
++ state = uart_find_match_or_unused(drv, port);
++
++ if (state) {
++ /*
++ * Ok, we've found a line that we can use.
++ *
++ * If we find a port that matches this one, and it appears
++ * to be in-use (even if it doesn't have a type) we shouldn't
++ * alter it underneath itself - the port may be open and
++ * trying to do useful work.
++ */
++ if (uart_users(state) != 0) {
++ ret = -EBUSY;
++ goto out;
++ }
++
++ /*
++ * If the port is already initialised, don't touch it.
++ */
++ if (state->port->type == PORT_UNKNOWN) {
++ state->port->iobase = port->iobase;
++ state->port->membase = port->membase;
++ state->port->irq = port->irq;
++ state->port->uartclk = port->uartclk;
++ state->port->fifosize = port->fifosize;
++ state->port->regshift = port->regshift;
++ state->port->iotype = port->iotype;
++ state->port->flags = port->flags;
++ state->port->line = state - drv->state;
++ state->port->mapbase = port->mapbase;
++
++ uart_configure_port(drv, state, state->port);
++ }
++
++ ret = state->port->line;
++ } else
++ ret = -ENOSPC;
++ out:
++ up(&port_sem);
++ return ret;
++}
++
++/**
++ * uart_unregister_port - de-allocate a port
++ * @drv: pointer to the uart low level driver structure for this port
++ * @line: line index previously returned from uart_register_port()
++ *
++ * Hang up the specified line associated with the low level driver,
++ * and mark the port as unused.
++ */
++void uart_unregister_port(struct uart_driver *drv, int line)
++{
++ struct uart_state *state;
++
++ if (line < 0 || line >= drv->nr) {
++ printk(KERN_ERR "Attempt to unregister ");
++ printk("%s%d", drv->dev_name, line);
++ printk("\n");
++ return;
++ }
++
++ state = drv->state + line;
++
++ down(&port_sem);
++ uart_unconfigure_port(drv, state);
++ up(&port_sem);
++}
++
++EXPORT_SYMBOL(uart_write_wakeup);
++EXPORT_SYMBOL(uart_register_driver);
++EXPORT_SYMBOL(uart_unregister_driver);
++EXPORT_SYMBOL(uart_suspend_port);
++EXPORT_SYMBOL(uart_resume_port);
++EXPORT_SYMBOL(uart_register_port);
++EXPORT_SYMBOL(uart_unregister_port);
++EXPORT_SYMBOL(uart_add_one_port);
++EXPORT_SYMBOL(uart_remove_one_port);
++
++MODULE_DESCRIPTION("Serial driver core");
++MODULE_LICENSE("GPL");
+Index: linux-2.6.0-test5/drivers/serial/serial_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/serial/serial_cs.c 2003-09-27 11:38:18.463721472 +0800
++++ linux-2.6.0-test5/drivers/serial/serial_cs.c 2003-09-27 11:38:32.173637248 +0800
+@@ -0,0 +1,712 @@
++/*======================================================================
++
++ A driver for PCMCIA serial devices
++
++ serial_cs.c 1.134 2002/05/04 05:48:53
++
++ The contents of this file are subject to the Mozilla Public
++ License Version 1.1 (the "License"); you may not use this file
++ except in compliance with the License. You may obtain a copy of
++ the License at http://www.mozilla.org/MPL/
++
++ Software distributed under the License is distributed on an "AS
++ IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
++ implied. See the License for the specific language governing
++ rights and limitations under the License.
++
++ The initial developer of the original code is David A. Hinds
++ <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
++ are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
++
++ Alternatively, the contents of this file may be used under the
++ terms of the GNU General Public License version 2 (the "GPL"), in which
++ case the provisions of the GPL are applicable instead of the
++ above. If you wish to allow the use of your version of this file
++ only under the terms of the GPL and not to allow others to use
++ your version of this file under the MPL, indicate your decision
++ 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 MPL or the GPL.
++
++======================================================================*/
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/sched.h>
++#include <linux/ptrace.h>
++#include <linux/slab.h>
++#include <linux/string.h>
++#include <linux/timer.h>
++#include <linux/tty.h>
++#include <linux/serial.h>
++#include <linux/serial_core.h>
++#include <linux/major.h>
++#include <asm/io.h>
++#include <asm/system.h>
++
++#include <pcmcia/version.h>
++#include <pcmcia/cs_types.h>
++#include <pcmcia/cs.h>
++#include <pcmcia/cistpl.h>
++#include <pcmcia/ciscode.h>
++#include <pcmcia/ds.h>
++#include <pcmcia/cisreg.h>
++
++#ifdef PCMCIA_DEBUG
++static int pc_debug = PCMCIA_DEBUG;
++MODULE_PARM(pc_debug, "i");
++#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
++static char *version = "serial_cs.c 1.134 2002/05/04 05:48:53 (David Hinds)";
++#else
++#define DEBUG(n, args...)
++#endif
++
++/*====================================================================*/
++
++/* Parameters that can be set with 'insmod' */
++
++/* Bit map of interrupts to choose from */
++static u_int irq_mask = 0xdeb8;
++static int irq_list[4] = { -1 };
++
++/* Enable the speaker? */
++static int do_sound = 1;
++/* Skip strict UART tests? */
++static int buggy_uart;
++
++MODULE_PARM(irq_mask, "i");
++MODULE_PARM(irq_list, "1-4i");
++MODULE_PARM(do_sound, "i");
++MODULE_PARM(buggy_uart, "i");
++
++/*====================================================================*/
++
++/* Table of multi-port card ID's */
++
++struct multi_id {
++ u_short manfid;
++ u_short prodid;
++ int multi; /* 1 = multifunction, > 1 = # ports */
++};
++
++static struct multi_id multi_id[] = {
++ { MANFID_OMEGA, PRODID_OMEGA_QSP_100, 4 },
++ { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232, 2 },
++ { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232_D1, 2 },
++ { MANFID_QUATECH, PRODID_QUATECH_QUAD_RS232, 4 },
++ { MANFID_SOCKET, PRODID_SOCKET_DUAL_RS232, 2 },
++ { MANFID_INTEL, PRODID_INTEL_DUAL_RS232, 2 },
++ { MANFID_NATINST, PRODID_NATINST_QUAD_RS232, 4 }
++};
++#define MULTI_COUNT (sizeof(multi_id)/sizeof(struct multi_id))
++
++struct serial_info {
++ dev_link_t link;
++ int ndev;
++ int multi;
++ int slave;
++ int manfid;
++ dev_node_t node[4];
++ int line[4];
++};
++
++static void serial_config(dev_link_t * link);
++static int serial_event(event_t event, int priority,
++ event_callback_args_t * args);
++
++static dev_info_t dev_info = "serial_cs";
++
++static dev_link_t *serial_attach(void);
++static void serial_detach(dev_link_t *);
++
++static dev_link_t *dev_list = NULL;
++
++/*======================================================================
++
++ After a card is removed, serial_remove() will unregister
++ the serial device(s), and release the PCMCIA configuration.
++
++======================================================================*/
++
++static void serial_remove(dev_link_t *link)
++{
++ struct serial_info *info = link->priv;
++ int i;
++
++ link->state &= ~DEV_PRESENT;
++
++ DEBUG(0, "serial_release(0x%p)\n", link);
++
++ /*
++ * Recheck to see if the device is still configured.
++ */
++ if (info->link.state & DEV_CONFIG) {
++ for (i = 0; i < info->ndev; i++)
++ unregister_serial(info->line[i]);
++
++ info->link.dev = NULL;
++
++ if (!info->slave) {
++ CardServices(ReleaseConfiguration, info->link.handle);
++ CardServices(ReleaseIO, info->link.handle, &info->link.io);
++ CardServices(ReleaseIRQ, info->link.handle, &info->link.irq);
++ }
++
++ info->link.state &= ~DEV_CONFIG;
++ }
++}
++
++/*======================================================================
++
++ serial_attach() creates an "instance" of the driver, allocating
++ local data structures for one device. The device is registered
++ with Card Services.
++
++======================================================================*/
++
++static dev_link_t *serial_attach(void)
++{
++ struct serial_info *info;
++ client_reg_t client_reg;
++ dev_link_t *link;
++ int i, ret;
++
++ DEBUG(0, "serial_attach()\n");
++
++ /* Create new serial device */
++ info = kmalloc(sizeof (*info), GFP_KERNEL);
++ if (!info)
++ return NULL;
++ memset(info, 0, sizeof (*info));
++ link = &info->link;
++ link->priv = info;
++
++ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
++ link->io.NumPorts1 = 8;
++ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
++ link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
++ if (irq_list[0] == -1)
++ link->irq.IRQInfo2 = irq_mask;
++ else
++ for (i = 0; i < 4; i++)
++ link->irq.IRQInfo2 |= 1 << irq_list[i];
++ link->conf.Attributes = CONF_ENABLE_IRQ;
++ if (do_sound) {
++ link->conf.Attributes |= CONF_ENABLE_SPKR;
++ link->conf.Status = CCSR_AUDIO_ENA;
++ }
++ link->conf.IntType = INT_MEMORY_AND_IO;
++
++ /* Register with Card Services */
++ link->next = dev_list;
++ dev_list = link;
++ client_reg.dev_info = &dev_info;
++ client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
++ client_reg.EventMask =
++ CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
++ CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
++ CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
++ client_reg.event_handler = &serial_event;
++ client_reg.Version = 0x0210;
++ client_reg.event_callback_args.client_data = link;
++ ret = CardServices(RegisterClient, &link->handle, &client_reg);
++ if (ret != CS_SUCCESS) {
++ cs_error(link->handle, RegisterClient, ret);
++ serial_detach(link);
++ return NULL;
++ }
++
++ return link;
++}
++
++/*======================================================================
++
++ This deletes a driver "instance". The device is de-registered
++ with Card Services. If it has been released, all local data
++ structures are freed. Otherwise, the structures will be freed
++ when the device is released.
++
++======================================================================*/
++
++static void serial_detach(dev_link_t * link)
++{
++ struct serial_info *info = link->priv;
++ dev_link_t **linkp;
++ int ret;
++
++ DEBUG(0, "serial_detach(0x%p)\n", link);
++
++ /* Locate device structure */
++ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
++ if (*linkp == link)
++ break;
++ if (*linkp == NULL)
++ return;
++
++ /*
++ * Ensure any outstanding scheduled tasks are completed.
++ */
++ flush_scheduled_work();
++
++ /*
++ * Ensure that the ports have been released.
++ */
++ serial_remove(link);
++
++ if (link->handle) {
++ ret = CardServices(DeregisterClient, link->handle);
++ if (ret != CS_SUCCESS)
++ cs_error(link->handle, DeregisterClient, ret);
++ }
++
++ /* Unlink device structure, free bits */
++ *linkp = link->next;
++ kfree(info);
++}
++
++/*====================================================================*/
++
++static int setup_serial(struct serial_info * info, ioaddr_t port, int irq)
++{
++ struct serial_struct serial;
++ int line;
++
++ memset(&serial, 0, sizeof (serial));
++ serial.port = port;
++ serial.irq = irq;
++ serial.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ;
++ if (buggy_uart)
++ serial.flags |= UPF_BUGGY_UART;
++ line = register_serial(&serial);
++ if (line < 0) {
++ printk(KERN_NOTICE "serial_cs: register_serial() at 0x%04lx,"
++ " irq %d failed\n", (u_long) serial.port, serial.irq);
++ return -EINVAL;
++ }
++
++ info->line[info->ndev] = line;
++ sprintf(info->node[info->ndev].dev_name, "ttyS%d", line);
++ info->node[info->ndev].major = TTY_MAJOR;
++ info->node[info->ndev].minor = 0x40 + line;
++ if (info->ndev > 0)
++ info->node[info->ndev - 1].next = &info->node[info->ndev];
++ info->ndev++;
++
++ return 0;
++}
++
++/*====================================================================*/
++
++static int
++get_tuple(int fn, client_handle_t handle, tuple_t * tuple, cisparse_t * parse)
++{
++ int i;
++ i = CardServices(fn, handle, tuple);
++ if (i != CS_SUCCESS)
++ return CS_NO_MORE_ITEMS;
++ i = CardServices(GetTupleData, handle, tuple);
++ if (i != CS_SUCCESS)
++ return i;
++ return CardServices(ParseTuple, handle, tuple, parse);
++}
++
++#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
++#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
++
++/*====================================================================*/
++
++static int simple_config(dev_link_t * link)
++{
++ static ioaddr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
++ client_handle_t handle = link->handle;
++ struct serial_info *info = link->priv;
++ tuple_t tuple;
++ u_char buf[256];
++ cisparse_t parse;
++ cistpl_cftable_entry_t *cf = &parse.cftable_entry;
++ config_info_t config;
++ int i, j, try;
++
++ /* If the card is already configured, look up the port and irq */
++ i = CardServices(GetConfigurationInfo, handle, &config);
++ if ((i == CS_SUCCESS) && (config.Attributes & CONF_VALID_CLIENT)) {
++ ioaddr_t port = 0;
++ if ((config.BasePort2 != 0) && (config.NumPorts2 == 8)) {
++ port = config.BasePort2;
++ info->slave = 1;
++ } else if ((info->manfid == MANFID_OSITECH) &&
++ (config.NumPorts1 == 0x40)) {
++ port = config.BasePort1 + 0x28;
++ info->slave = 1;
++ }
++ if (info->slave)
++ return setup_serial(info, port, config.AssignedIRQ);
++ }
++ link->conf.Vcc = config.Vcc;
++
++ /* First pass: look for a config entry that looks normal. */
++ tuple.TupleData = (cisdata_t *) buf;
++ tuple.TupleOffset = 0;
++ tuple.TupleDataMax = 255;
++ tuple.Attributes = 0;
++ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
++ /* Two tries: without IO aliases, then with aliases */
++ for (try = 0; try < 2; try++) {
++ i = first_tuple(handle, &tuple, &parse);
++ while (i != CS_NO_MORE_ITEMS) {
++ if (i != CS_SUCCESS)
++ goto next_entry;
++ if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
++ link->conf.Vpp1 = link->conf.Vpp2 =
++ cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
++ if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) &&
++ (cf->io.win[0].base != 0)) {
++ link->conf.ConfigIndex = cf->index;
++ link->io.BasePort1 = cf->io.win[0].base;
++ link->io.IOAddrLines = (try == 0) ?
++ 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
++ i =
++ CardServices(RequestIO, link->handle,
++ &link->io);
++ if (i == CS_SUCCESS)
++ goto found_port;
++ }
++ next_entry:
++ i = next_tuple(handle, &tuple, &parse);
++ }
++ }
++
++ /* Second pass: try to find an entry that isn't picky about
++ its base address, then try to grab any standard serial port
++ address, and finally try to get any free port. */
++ i = first_tuple(handle, &tuple, &parse);
++ while (i != CS_NO_MORE_ITEMS) {
++ if ((i == CS_SUCCESS) && (cf->io.nwin > 0) &&
++ ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
++ link->conf.ConfigIndex = cf->index;
++ for (j = 0; j < 5; j++) {
++ link->io.BasePort1 = base[j];
++ link->io.IOAddrLines = base[j] ? 16 : 3;
++ i = CardServices(RequestIO, link->handle,
++ &link->io);
++ if (i == CS_SUCCESS)
++ goto found_port;
++ }
++ }
++ i = next_tuple(handle, &tuple, &parse);
++ }
++
++ found_port:
++ if (i != CS_SUCCESS) {
++ printk(KERN_NOTICE
++ "serial_cs: no usable port range found, giving up\n");
++ cs_error(link->handle, RequestIO, i);
++ return -1;
++ }
++
++ i = CardServices(RequestIRQ, link->handle, &link->irq);
++ if (i != CS_SUCCESS) {
++ cs_error(link->handle, RequestIRQ, i);
++ link->irq.AssignedIRQ = 0;
++ }
++ if (info->multi && (info->manfid == MANFID_3COM))
++ link->conf.ConfigIndex &= ~(0x08);
++ i = CardServices(RequestConfiguration, link->handle, &link->conf);
++ if (i != CS_SUCCESS) {
++ cs_error(link->handle, RequestConfiguration, i);
++ return -1;
++ }
++
++ return setup_serial(info, link->io.BasePort1, link->irq.AssignedIRQ);
++}
++
++static int multi_config(dev_link_t * link)
++{
++ client_handle_t handle = link->handle;
++ struct serial_info *info = link->priv;
++ tuple_t tuple;
++ u_char buf[256];
++ cisparse_t parse;
++ cistpl_cftable_entry_t *cf = &parse.cftable_entry;
++ config_info_t config;
++ int i, base2 = 0;
++
++ i = CardServices(GetConfigurationInfo, handle, &config);
++ if (i != CS_SUCCESS) {
++ cs_error(handle, GetConfigurationInfo, i);
++ return -1;
++ }
++ link->conf.Vcc = config.Vcc;
++
++ tuple.TupleData = (cisdata_t *) buf;
++ tuple.TupleOffset = 0;
++ tuple.TupleDataMax = 255;
++ tuple.Attributes = 0;
++ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
++
++ /* First, look for a generic full-sized window */
++ link->io.NumPorts1 = info->multi * 8;
++ i = first_tuple(handle, &tuple, &parse);
++ while (i != CS_NO_MORE_ITEMS) {
++ /* The quad port cards have bad CIS's, so just look for a
++ window larger than 8 ports and assume it will be right */
++ if ((i == CS_SUCCESS) && (cf->io.nwin == 1) &&
++ (cf->io.win[0].len > 8)) {
++ link->conf.ConfigIndex = cf->index;
++ link->io.BasePort1 = cf->io.win[0].base;
++ link->io.IOAddrLines =
++ cf->io.flags & CISTPL_IO_LINES_MASK;
++ i = CardServices(RequestIO, link->handle, &link->io);
++ base2 = link->io.BasePort1 + 8;
++ if (i == CS_SUCCESS)
++ break;
++ }
++ i = next_tuple(handle, &tuple, &parse);
++ }
++
++ /* If that didn't work, look for two windows */
++ if (i != CS_SUCCESS) {
++ link->io.NumPorts1 = link->io.NumPorts2 = 8;
++ info->multi = 2;
++ i = first_tuple(handle, &tuple, &parse);
++ while (i != CS_NO_MORE_ITEMS) {
++ if ((i == CS_SUCCESS) && (cf->io.nwin == 2)) {
++ link->conf.ConfigIndex = cf->index;
++ link->io.BasePort1 = cf->io.win[0].base;
++ link->io.BasePort2 = cf->io.win[1].base;
++ link->io.IOAddrLines =
++ cf->io.flags & CISTPL_IO_LINES_MASK;
++ i =
++ CardServices(RequestIO, link->handle,
++ &link->io);
++ base2 = link->io.BasePort2;
++ if (i == CS_SUCCESS)
++ break;
++ }
++ i = next_tuple(handle, &tuple, &parse);
++ }
++ }
++
++ if (i != CS_SUCCESS) {
++ cs_error(link->handle, RequestIO, i);
++ return -1;
++ }
++
++ i = CardServices(RequestIRQ, link->handle, &link->irq);
++ if (i != CS_SUCCESS) {
++ printk(KERN_NOTICE
++ "serial_cs: no usable port range found, giving up\n");
++ cs_error(link->handle, RequestIRQ, i);
++ link->irq.AssignedIRQ = 0;
++ }
++ /* Socket Dual IO: this enables irq's for second port */
++ if (info->multi && (info->manfid == MANFID_SOCKET)) {
++ link->conf.Present |= PRESENT_EXT_STATUS;
++ link->conf.ExtStatus = ESR_REQ_ATTN_ENA;
++ }
++ i = CardServices(RequestConfiguration, link->handle, &link->conf);
++ if (i != CS_SUCCESS) {
++ cs_error(link->handle, RequestConfiguration, i);
++ return -1;
++ }
++
++ /* The Oxford Semiconductor OXCF950 cards are in fact single-port:
++ 8 registers are for the UART, the others are extra registers */
++ if (info->manfid == MANFID_OXSEMI) {
++ if (cf->index == 1 || cf->index == 3) {
++ setup_serial(info, base2, link->irq.AssignedIRQ);
++ outb(12, link->io.BasePort1 + 1);
++ } else {
++ setup_serial(info, link->io.BasePort1, link->irq.AssignedIRQ);
++ outb(12, base2 + 1);
++ }
++ return 0;
++ }
++
++ setup_serial(info, link->io.BasePort1, link->irq.AssignedIRQ);
++ /* The Nokia cards are not really multiport cards */
++ if (info->manfid == MANFID_NOKIA)
++ return 0;
++ for (i = 0; i < info->multi - 1; i++)
++ setup_serial(info, base2 + (8 * i), link->irq.AssignedIRQ);
++
++ return 0;
++}
++
++/*======================================================================
++
++ serial_config() is scheduled to run after a CARD_INSERTION event
++ is received, to configure the PCMCIA socket, and to make the
++ serial device available to the system.
++
++======================================================================*/
++
++#define CS_CHECK(fn, args...) \
++while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
++
++void serial_config(dev_link_t * link)
++{
++ client_handle_t handle = link->handle;
++ struct serial_info *info = link->priv;
++ tuple_t tuple;
++ u_short buf[128];
++ cisparse_t parse;
++ cistpl_cftable_entry_t *cf = &parse.cftable_entry;
++ int i, last_ret, last_fn;
++
++ DEBUG(0, "serial_config(0x%p)\n", link);
++
++ tuple.TupleData = (cisdata_t *) buf;
++ tuple.TupleOffset = 0;
++ tuple.TupleDataMax = 255;
++ tuple.Attributes = 0;
++ /* Get configuration register information */
++ tuple.DesiredTuple = CISTPL_CONFIG;
++ last_ret = first_tuple(handle, &tuple, &parse);
++ if (last_ret != CS_SUCCESS) {
++ last_fn = ParseTuple;
++ goto cs_failed;
++ }
++ link->conf.ConfigBase = parse.config.base;
++ link->conf.Present = parse.config.rmask[0];
++
++ /* Configure card */
++ link->state |= DEV_CONFIG;
++
++ /* Is this a compliant multifunction card? */
++ tuple.DesiredTuple = CISTPL_LONGLINK_MFC;
++ tuple.Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK;
++ info->multi = (first_tuple(handle, &tuple, &parse) == CS_SUCCESS);
++
++ /* Is this a multiport card? */
++ tuple.DesiredTuple = CISTPL_MANFID;
++ if (first_tuple(handle, &tuple, &parse) == CS_SUCCESS) {
++ info->manfid = le16_to_cpu(buf[0]);
++ for (i = 0; i < MULTI_COUNT; i++)
++ if ((info->manfid == multi_id[i].manfid) &&
++ (le16_to_cpu(buf[1]) == multi_id[i].prodid))
++ break;
++ if (i < MULTI_COUNT)
++ info->multi = multi_id[i].multi;
++ }
++
++ /* Another check for dual-serial cards: look for either serial or
++ multifunction cards that ask for appropriate IO port ranges */
++ tuple.DesiredTuple = CISTPL_FUNCID;
++ if ((info->multi == 0) &&
++ ((first_tuple(handle, &tuple, &parse) != CS_SUCCESS) ||
++ (parse.funcid.func == CISTPL_FUNCID_MULTI) ||
++ (parse.funcid.func == CISTPL_FUNCID_SERIAL))) {
++ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
++ if (first_tuple(handle, &tuple, &parse) == CS_SUCCESS) {
++ if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0))
++ info->multi = cf->io.win[0].len >> 3;
++ if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) &&
++ (cf->io.win[1].len == 8))
++ info->multi = 2;
++ }
++ }
++
++ if (info->multi > 1)
++ multi_config(link);
++ else
++ simple_config(link);
++
++ if (info->ndev == 0)
++ goto failed;
++
++ if (info->manfid == MANFID_IBM) {
++ conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
++ CS_CHECK(AccessConfigurationRegister, link->handle, ®);
++ reg.Action = CS_WRITE;
++ reg.Value = reg.Value | 1;
++ CS_CHECK(AccessConfigurationRegister, link->handle, ®);
++ }
++
++ link->dev = &info->node[0];
++ link->state &= ~DEV_CONFIG_PENDING;
++ return;
++
++ cs_failed:
++ cs_error(link->handle, last_fn, last_ret);
++ failed:
++ serial_remove(link);
++ link->state &= ~DEV_CONFIG_PENDING;
++}
++
++/*======================================================================
++
++ The card status event handler. Mostly, this schedules other
++ stuff to run after an event is received. A CARD_REMOVAL event
++ also sets some flags to discourage the serial drivers from
++ talking to the ports.
++
++======================================================================*/
++
++static int
++serial_event(event_t event, int priority, event_callback_args_t * args)
++{
++ dev_link_t *link = args->client_data;
++ struct serial_info *info = link->priv;
++
++ DEBUG(1, "serial_event(0x%06x)\n", event);
++
++ switch (event) {
++ case CS_EVENT_CARD_REMOVAL:
++ serial_remove(link);
++ break;
++
++ case CS_EVENT_CARD_INSERTION:
++ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
++ serial_config(link);
++ break;
++
++ case CS_EVENT_PM_SUSPEND:
++ link->state |= DEV_SUSPEND;
++ /* Fall through... */
++ case CS_EVENT_RESET_PHYSICAL:
++ if ((link->state & DEV_CONFIG) && !info->slave)
++ CardServices(ReleaseConfiguration, link->handle);
++ break;
++
++ case CS_EVENT_PM_RESUME:
++ link->state &= ~DEV_SUSPEND;
++ /* Fall through... */
++ case CS_EVENT_CARD_RESET:
++ if (DEV_OK(link) && !info->slave)
++ CardServices(RequestConfiguration, link->handle,
++ &link->conf);
++ break;
++ }
++ return 0;
++}
++
++static struct pcmcia_driver serial_cs_driver = {
++ .owner = THIS_MODULE,
++ .drv = {
++ .name = "serial_cs",
++ },
++ .attach = serial_attach,
++ .detach = serial_detach,
++};
++
++static int __init init_serial_cs(void)
++{
++ return pcmcia_register_driver(&serial_cs_driver);
++}
++
++static void __exit exit_serial_cs(void)
++{
++ pcmcia_unregister_driver(&serial_cs_driver);
++
++ /* XXX: this really needs to move into generic code.. */
++ while (dev_list != NULL)
++ serial_detach(dev_list);
++}
++
++module_init(init_serial_cs);
++module_exit(exit_serial_cs);
++
++MODULE_LICENSE("GPL");
+Index: linux-2.6.0-test5/drivers/usb/class/usblp.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/class/usblp.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/class/usblp.c 2003-09-27 11:38:32.231628432 +0800
+@@ -159,7 +159,10 @@
+ dbg("usblp=0x%p", usblp);
+ dbg("dev=0x%p", usblp->dev);
+ dbg("present=%d", usblp->present);
+- dbg("buf=0x%p", usblp->buf);
++ dbg("readbuf=0x%p", usblp->readbuf);
++ dbg("writebuf=0x%p", usblp->writebuf);
++ dbg("readurb=0x%p", usblp->readurb);
++ dbg("writeurb=0x%p", usblp->writeurb);
+ dbg("readcount=%d", usblp->readcount);
+ dbg("ifnum=%d", usblp->ifnum);
+ for (p = USBLP_FIRST_PROTOCOL; p <= USBLP_LAST_PROTOCOL; p++) {
+Index: linux-2.6.0-test5/drivers/usb/core/config.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/core/config.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/core/config.c 2003-09-27 11:38:32.275621744 +0800
+@@ -10,364 +10,329 @@
+
+ /* these maximums are arbitrary */
+ #define USB_MAXCONFIG 8
+-#define USB_ALTSETTINGALLOC 4
+ #define USB_MAXINTERFACES 32
+
+ static int usb_parse_endpoint(struct usb_host_endpoint *endpoint, unsigned char *buffer, int size)
+ {
++ unsigned char *buffer0 = buffer;
+ struct usb_descriptor_header *header;
+ unsigned char *begin;
+- int parsed = 0, len, numskipped;
++ int numskipped;
+
+ header = (struct usb_descriptor_header *)buffer;
+-
+- /* Everything should be fine being passed into here, but we sanity */
+- /* check JIC */
+- if (header->bLength > size) {
+- err("ran out of descriptors parsing");
+- return -1;
+- }
+-
+ if (header->bDescriptorType != USB_DT_ENDPOINT) {
+ warn("unexpected descriptor 0x%X, expecting endpoint, 0x%X",
+ header->bDescriptorType, USB_DT_ENDPOINT);
+- return parsed;
++ return -EINVAL;
+ }
+
+- if (header->bLength == USB_DT_ENDPOINT_AUDIO_SIZE)
++ if (header->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE)
+ memcpy(&endpoint->desc, buffer, USB_DT_ENDPOINT_AUDIO_SIZE);
+- else
++ else if (header->bLength >= USB_DT_ENDPOINT_SIZE)
+ memcpy(&endpoint->desc, buffer, USB_DT_ENDPOINT_SIZE);
+-
++ else {
++ warn("invalid endpoint descriptor");
++ return -EINVAL;
++ }
++
++ if ((endpoint->desc.bEndpointAddress & ~USB_ENDPOINT_DIR_MASK) >= 16) {
++ warn("invalid endpoint address 0x%X",
++ endpoint->desc.bEndpointAddress);
++ return -EINVAL;
++ }
++
+ le16_to_cpus(&endpoint->desc.wMaxPacketSize);
+
+ buffer += header->bLength;
+ size -= header->bLength;
+- parsed += header->bLength;
+
+- /* Skip over the rest of the Class Specific or Vendor Specific */
+- /* descriptors */
++ /* Skip over any Class Specific or Vendor Specific descriptors */
+ begin = buffer;
+ numskipped = 0;
+ while (size >= sizeof(struct usb_descriptor_header)) {
+ header = (struct usb_descriptor_header *)buffer;
+
+- if (header->bLength < 2) {
+- err("invalid descriptor length of %d", header->bLength);
+- return -1;
+- }
+-
+ /* If we find another "proper" descriptor then we're done */
+ if ((header->bDescriptorType == USB_DT_ENDPOINT) ||
+- (header->bDescriptorType == USB_DT_INTERFACE) ||
+- (header->bDescriptorType == USB_DT_CONFIG) ||
+- (header->bDescriptorType == USB_DT_DEVICE))
++ (header->bDescriptorType == USB_DT_INTERFACE))
+ break;
+
+- dbg("skipping descriptor 0x%X",
+- header->bDescriptorType);
++ dbg("skipping descriptor 0x%X", header->bDescriptorType);
+ numskipped++;
+
+ buffer += header->bLength;
+ size -= header->bLength;
+- parsed += header->bLength;
+ }
+- if (numskipped)
++ if (numskipped) {
+ dbg("skipped %d class/vendor specific endpoint descriptors", numskipped);
+-
+- /* Copy any unknown descriptors into a storage area for drivers */
+- /* to later parse */
+- len = (int)(buffer - begin);
+- if (!len) {
+- endpoint->extra = NULL;
+- endpoint->extralen = 0;
+- return parsed;
+- }
+-
+- endpoint->extra = kmalloc(len, GFP_KERNEL);
+-
+- if (!endpoint->extra) {
+- err("couldn't allocate memory for endpoint extra descriptors");
+- endpoint->extralen = 0;
+- return parsed;
++ endpoint->extra = begin;
++ endpoint->extralen = buffer - begin;
+ }
+
+- memcpy(endpoint->extra, begin, len);
+- endpoint->extralen = len;
+-
+- return parsed;
++ return buffer - buffer0;
+ }
+
+ static void usb_release_intf(struct device *dev)
+ {
+ struct usb_interface *intf;
+ int j;
+- int k;
+
+ intf = to_usb_interface(dev);
+
+ if (intf->altsetting) {
+ for (j = 0; j < intf->num_altsetting; j++) {
+ struct usb_host_interface *as = &intf->altsetting[j];
+- if (as->extra)
+- kfree(as->extra);
+
+- if (as->endpoint) {
+- for (k = 0; k < as->desc.bNumEndpoints; k++)
+- if (as->endpoint[k].extra)
+- kfree(as->endpoint[k].extra);
+- kfree(as->endpoint);
+- }
++ kfree(as->endpoint);
+ }
+ kfree(intf->altsetting);
+ }
+ kfree(intf);
+ }
+
+-static int usb_parse_interface(struct usb_interface *interface, unsigned char *buffer, int size)
++static int usb_parse_interface(struct usb_host_config *config, unsigned char *buffer, int size)
+ {
+- int i, len, numskipped, retval, parsed = 0;
+- struct usb_descriptor_header *header;
++ unsigned char *buffer0 = buffer;
++ struct usb_interface_descriptor *d;
++ int inum, asnum;
++ struct usb_interface *interface;
+ struct usb_host_interface *ifp;
++ int len, numskipped;
++ struct usb_descriptor_header *header;
+ unsigned char *begin;
++ int i, retval;
+
+- interface->act_altsetting = 0;
+- interface->num_altsetting = 0;
+- interface->max_altsetting = USB_ALTSETTINGALLOC;
+- device_initialize(&interface->dev);
+- interface->dev.release = usb_release_intf;
+-
+- /* put happens in usb_destroy_configuration */
+- get_device(&interface->dev);
+-
+- interface->altsetting = kmalloc(sizeof(*interface->altsetting) * interface->max_altsetting,
+- GFP_KERNEL);
+-
+- if (!interface->altsetting) {
+- err("couldn't kmalloc interface->altsetting");
+- return -1;
+- }
+-
+- while (size > 0) {
+- struct usb_interface_descriptor *d;
+-
+- if (interface->num_altsetting >= interface->max_altsetting) {
+- struct usb_host_interface *ptr;
+- int oldmas;
+-
+- oldmas = interface->max_altsetting;
+- interface->max_altsetting += USB_ALTSETTINGALLOC;
+- if (interface->max_altsetting > USB_MAXALTSETTING) {
+- warn("too many alternate settings (incr %d max %d)\n",
+- USB_ALTSETTINGALLOC, USB_MAXALTSETTING);
+- return -1;
+- }
+-
+- ptr = kmalloc(sizeof(*ptr) * interface->max_altsetting, GFP_KERNEL);
+- if (ptr == NULL) {
+- err("couldn't kmalloc interface->altsetting");
+- return -1;
+- }
+- memcpy(ptr, interface->altsetting, sizeof(*interface->altsetting) * oldmas);
+- kfree(interface->altsetting);
+- interface->altsetting = ptr;
+- }
+-
+- ifp = interface->altsetting + interface->num_altsetting;
+- ifp->endpoint = NULL;
+- ifp->extra = NULL;
+- ifp->extralen = 0;
+- interface->num_altsetting++;
+-
+- memcpy(ifp, buffer, USB_DT_INTERFACE_SIZE);
+-
+- /* Skip over the interface */
+- buffer += ifp->desc.bLength;
+- parsed += ifp->desc.bLength;
+- size -= ifp->desc.bLength;
++ d = (struct usb_interface_descriptor *) buffer;
++ if (d->bDescriptorType != USB_DT_INTERFACE) {
++ warn("unexpected descriptor 0x%X, expecting interface, 0x%X",
++ d->bDescriptorType, USB_DT_INTERFACE);
++ return -EINVAL;
++ }
+
+- begin = buffer;
+- numskipped = 0;
++ inum = d->bInterfaceNumber;
++ if (inum >= config->desc.bNumInterfaces) {
+
+- /* Skip over any interface, class or vendor descriptors */
++ /* Skip to the next interface descriptor */
++ buffer += d->bLength;
++ size -= d->bLength;
+ while (size >= sizeof(struct usb_descriptor_header)) {
+- header = (struct usb_descriptor_header *)buffer;
++ header = (struct usb_descriptor_header *) buffer;
+
+- if (header->bLength < 2) {
+- err("invalid descriptor length of %d", header->bLength);
+- return -1;
+- }
+-
+- /* If we find another "proper" descriptor then we're done */
+- if ((header->bDescriptorType == USB_DT_INTERFACE) ||
+- (header->bDescriptorType == USB_DT_ENDPOINT) ||
+- (header->bDescriptorType == USB_DT_CONFIG) ||
+- (header->bDescriptorType == USB_DT_DEVICE))
++ if (header->bDescriptorType == USB_DT_INTERFACE)
+ break;
+-
+- numskipped++;
+-
+ buffer += header->bLength;
+- parsed += header->bLength;
+ size -= header->bLength;
+ }
++ return buffer - buffer0;
++ }
+
+- if (numskipped)
+- dbg("skipped %d class/vendor specific interface descriptors", numskipped);
++ interface = config->interface[inum];
++ asnum = d->bAlternateSetting;
++ if (asnum >= interface->num_altsetting) {
++ warn("invalid alternate setting %d for interface %d",
++ asnum, inum);
++ return -EINVAL;
++ }
+
+- /* Copy any unknown descriptors into a storage area for */
+- /* drivers to later parse */
+- len = (int)(buffer - begin);
+- if (len) {
+- ifp->extra = kmalloc(len, GFP_KERNEL);
+-
+- if (!ifp->extra) {
+- err("couldn't allocate memory for interface extra descriptors");
+- ifp->extralen = 0;
+- return -1;
+- }
+- memcpy(ifp->extra, begin, len);
+- ifp->extralen = len;
+- }
++ ifp = &interface->altsetting[asnum];
++ if (ifp->desc.bLength) {
++ warn("duplicate descriptor for interface %d altsetting %d",
++ inum, asnum);
++ return -EINVAL;
++ }
++ memcpy(&ifp->desc, buffer, USB_DT_INTERFACE_SIZE);
++
++ buffer += d->bLength;
++ size -= d->bLength;
+
+- /* Did we hit an unexpected descriptor? */
++ /* Skip over any Class Specific or Vendor Specific descriptors */
++ begin = buffer;
++ numskipped = 0;
++ while (size >= sizeof(struct usb_descriptor_header)) {
+ header = (struct usb_descriptor_header *)buffer;
+- if ((size >= sizeof(struct usb_descriptor_header)) &&
+- ((header->bDescriptorType == USB_DT_CONFIG) ||
+- (header->bDescriptorType == USB_DT_DEVICE)))
+- return parsed;
+-
+- if (ifp->desc.bNumEndpoints > USB_MAXENDPOINTS) {
+- warn("too many endpoints");
+- return -1;
+- }
+
+- ifp->endpoint = (struct usb_host_endpoint *)
+- kmalloc(ifp->desc.bNumEndpoints *
+- sizeof(struct usb_host_endpoint), GFP_KERNEL);
+- if (!ifp->endpoint) {
+- err("out of memory");
+- return -1;
+- }
++ /* If we find another "proper" descriptor then we're done */
++ if ((header->bDescriptorType == USB_DT_INTERFACE) ||
++ (header->bDescriptorType == USB_DT_ENDPOINT))
++ break;
+
+- memset(ifp->endpoint, 0, ifp->desc.bNumEndpoints *
+- sizeof(struct usb_host_endpoint));
+-
+- for (i = 0; i < ifp->desc.bNumEndpoints; i++) {
+- header = (struct usb_descriptor_header *)buffer;
+-
+- if (header->bLength > size) {
+- err("ran out of descriptors parsing");
+- return -1;
+- }
+-
+- retval = usb_parse_endpoint(ifp->endpoint + i, buffer, size);
+- if (retval < 0)
+- return retval;
++ dbg("skipping descriptor 0x%X", header->bDescriptorType);
++ numskipped++;
++
++ buffer += header->bLength;
++ size -= header->bLength;
++ }
++ if (numskipped) {
++ dbg("skipped %d class/vendor specific interface descriptors", numskipped);
++ ifp->extra = begin;
++ ifp->extralen = buffer - begin;
++ }
++
++ if (ifp->desc.bNumEndpoints > USB_MAXENDPOINTS) {
++ warn("too many endpoints for interface %d altsetting %d",
++ inum, asnum);
++ return -EINVAL;
++ }
++
++ len = ifp->desc.bNumEndpoints * sizeof(struct usb_host_endpoint);
++ ifp->endpoint = kmalloc(len, GFP_KERNEL);
++ if (!ifp->endpoint) {
++ err("out of memory");
++ return -ENOMEM;
++ }
++ memset(ifp->endpoint, 0, len);
+
+- buffer += retval;
+- parsed += retval;
+- size -= retval;
++ for (i = 0; i < ifp->desc.bNumEndpoints; i++) {
++ if (size < USB_DT_ENDPOINT_SIZE) {
++ warn("ran out of descriptors while parsing endpoints");
++ return -EINVAL;
+ }
+
+- /* We check to see if it's an alternate to this one */
+- d = (struct usb_interface_descriptor *)buffer;
+- if (size < USB_DT_INTERFACE_SIZE
+- || d->bDescriptorType != USB_DT_INTERFACE
+- || !d->bAlternateSetting)
+- return parsed;
++ retval = usb_parse_endpoint(ifp->endpoint + i, buffer, size);
++ if (retval < 0)
++ return retval;
++
++ buffer += retval;
++ size -= retval;
+ }
+
+- return parsed;
++ return buffer - buffer0;
+ }
+
+-int usb_parse_configuration(struct usb_host_config *config, char *buffer)
++int usb_parse_configuration(struct usb_host_config *config, char *buffer, int size)
+ {
+- int i, size;
+- int retval = -EINVAL;
++ int nintf, nintf_orig;
++ int i, j;
++ struct usb_interface *interface;
++ char *buffer2;
++ int size2;
+ struct usb_descriptor_header *header;
++ int numskipped, len;
++ char *begin;
++ int retval;
+
+ memcpy(&config->desc, buffer, USB_DT_CONFIG_SIZE);
+- le16_to_cpus(&config->desc.wTotalLength);
+- size = config->desc.wTotalLength;
++ if (config->desc.bDescriptorType != USB_DT_CONFIG ||
++ config->desc.bLength < USB_DT_CONFIG_SIZE) {
++ warn("invalid configuration descriptor");
++ return -EINVAL;
++ }
++ config->desc.wTotalLength = size;
+
+- for (i = 0; i < USB_MAXINTERFACES; ++i)
+- config->interface[i] = NULL;
++ nintf = nintf_orig = config->desc.bNumInterfaces;
++ if (nintf > USB_MAXINTERFACES) {
++ warn("too many interfaces (%d max %d)",
++ nintf, USB_MAXINTERFACES);
++ config->desc.bNumInterfaces = nintf = USB_MAXINTERFACES;
++ }
+
+- if (config->desc.bNumInterfaces > USB_MAXINTERFACES) {
+- warn("too many interfaces");
+- goto error;
++ for (i = 0; i < nintf; ++i) {
++ interface = config->interface[i] =
++ kmalloc(sizeof(struct usb_interface), GFP_KERNEL);
++ dbg("kmalloc IF %p, numif %i", interface, i);
++ if (!interface) {
++ err("out of memory");
++ return -ENOMEM;
++ }
++ memset(interface, 0, sizeof(struct usb_interface));
++ interface->dev.release = usb_release_intf;
++ device_initialize(&interface->dev);
++
++ /* put happens in usb_destroy_configuration */
++ get_device(&interface->dev);
++ }
++
++ /* Go through the descriptors, checking their length and counting the
++ * number of altsettings for each interface */
++ buffer2 = buffer;
++ size2 = size;
++ j = 0;
++ while (size2 >= sizeof(struct usb_descriptor_header)) {
++ header = (struct usb_descriptor_header *) buffer2;
++ if ((header->bLength > size2) || (header->bLength < 2)) {
++ warn("invalid descriptor of length %d", header->bLength);
++ return -EINVAL;
++ }
++
++ if (header->bDescriptorType == USB_DT_INTERFACE) {
++ struct usb_interface_descriptor *d;
++
++ if (header->bLength < USB_DT_INTERFACE_SIZE) {
++ warn("invalid interface descriptor");
++ return -EINVAL;
++ }
++ d = (struct usb_interface_descriptor *) header;
++ i = d->bInterfaceNumber;
++ if (i >= nintf_orig) {
++ warn("invalid interface number (%d/%d)",
++ i, nintf_orig);
++ return -EINVAL;
++ }
++ if (i < nintf)
++ ++config->interface[i]->num_altsetting;
++
++ } else if ((header->bDescriptorType == USB_DT_DEVICE ||
++ header->bDescriptorType == USB_DT_CONFIG) && j) {
++ warn("unexpected descriptor type 0x%X", header->bDescriptorType);
++ return -EINVAL;
++ }
++
++ j = 1;
++ buffer2 += header->bLength;
++ size2 -= header->bLength;
+ }
+
++ /* Allocate the altsetting arrays */
+ for (i = 0; i < config->desc.bNumInterfaces; ++i) {
+- config->interface[i] = kmalloc(sizeof(struct usb_interface), GFP_KERNEL);
+- dbg("kmalloc IF %p, numif %i", config->interface[i], i);
+- if (!config->interface[i]) {
+- err("out of memory");
+- retval = -ENOMEM;
+- goto error;
++ interface = config->interface[i];
++ if (interface->num_altsetting > USB_MAXALTSETTING) {
++ warn("too many alternate settings for interface %d (%d max %d)\n",
++ i, interface->num_altsetting, USB_MAXALTSETTING);
++ return -EINVAL;
++ }
++ if (interface->num_altsetting == 0) {
++ warn("no alternate settings for interface %d", i);
++ return -EINVAL;
++ }
++
++ len = sizeof(*interface->altsetting) * interface->num_altsetting;
++ interface->altsetting = kmalloc(len, GFP_KERNEL);
++ if (!interface->altsetting) {
++ err("couldn't kmalloc interface->altsetting");
++ return -ENOMEM;
+ }
+- memset(config->interface[i], 0x00, sizeof(struct usb_interface));
++ memset(interface->altsetting, 0, len);
+ }
+
+ buffer += config->desc.bLength;
+ size -= config->desc.bLength;
+-
+- config->extra = NULL;
+- config->extralen = 0;
+-
+- for (i = 0; i < config->desc.bNumInterfaces; i++) {
+- int numskipped, len;
+- char *begin;
+-
+- /* Skip over the rest of the Class Specific or Vendor */
+- /* Specific descriptors */
+- begin = buffer;
+- numskipped = 0;
+- while (size >= sizeof(struct usb_descriptor_header)) {
+- header = (struct usb_descriptor_header *)buffer;
+
+- if ((header->bLength > size) || (header->bLength < 2)) {
+- err("invalid descriptor length of %d", header->bLength);
+- return -1;
+- }
+-
+- /* If we find another "proper" descriptor then we're done */
+- if ((header->bDescriptorType == USB_DT_ENDPOINT) ||
+- (header->bDescriptorType == USB_DT_INTERFACE) ||
+- (header->bDescriptorType == USB_DT_CONFIG) ||
+- (header->bDescriptorType == USB_DT_DEVICE))
+- break;
+-
+- dbg("skipping descriptor 0x%X", header->bDescriptorType);
+- numskipped++;
++ /* Skip over any Class Specific or Vendor Specific descriptors */
++ begin = buffer;
++ numskipped = 0;
++ while (size >= sizeof(struct usb_descriptor_header)) {
++ header = (struct usb_descriptor_header *)buffer;
+
+- buffer += header->bLength;
+- size -= header->bLength;
+- }
+- if (numskipped)
+- dbg("skipped %d class/vendor specific endpoint descriptors", numskipped);
++ /* If we find another "proper" descriptor then we're done */
++ if ((header->bDescriptorType == USB_DT_ENDPOINT) ||
++ (header->bDescriptorType == USB_DT_INTERFACE))
++ break;
+
+- /* Copy any unknown descriptors into a storage area for */
+- /* drivers to later parse */
+- len = (int)(buffer - begin);
+- if (len) {
+- if (config->extralen) {
+- warn("extra config descriptor");
+- } else {
+- config->extra = kmalloc(len, GFP_KERNEL);
+- if (!config->extra) {
+- err("couldn't allocate memory for config extra descriptors");
+- config->extralen = 0;
+- return -1;
+- }
++ dbg("skipping descriptor 0x%X", header->bDescriptorType);
++ numskipped++;
+
+- memcpy(config->extra, begin, len);
+- config->extralen = len;
+- }
+- }
++ buffer += header->bLength;
++ size -= header->bLength;
++ }
++ if (numskipped) {
++ dbg("skipped %d class/vendor specific configuration descriptors", numskipped);
++ config->extra = begin;
++ config->extralen = buffer - begin;
++ }
+
+- retval = usb_parse_interface(config->interface[i], buffer, size);
++ /* Parse all the interface/altsetting descriptors */
++ while (size >= sizeof(struct usb_descriptor_header)) {
++ retval = usb_parse_interface(config, buffer, size);
+ if (retval < 0)
+ return retval;
+
+@@ -375,11 +340,18 @@
+ size -= retval;
+ }
+
++ /* Check for missing altsettings */
++ for (i = 0; i < nintf; ++i) {
++ interface = config->interface[i];
++ for (j = 0; j < interface->num_altsetting; ++j) {
++ if (!interface->altsetting[j].desc.bLength) {
++ warn("missing altsetting %d for interface %d", j, i);
++ return -EINVAL;
++ }
++ }
++ }
++
+ return size;
+-error:
+- for (i = 0; i < USB_MAXINTERFACES; ++i)
+- kfree(config->interface[i]);
+- return retval;
+ }
+
+ // hub-only!! ... and only exported for reset/reinit path.
+@@ -387,7 +359,7 @@
+ void usb_destroy_configuration(struct usb_device *dev)
+ {
+ int c, i;
+-
++
+ if (!dev->config)
+ return;
+
+@@ -401,12 +373,11 @@
+ for (c = 0; c < dev->descriptor.bNumConfigurations; c++) {
+ struct usb_host_config *cf = &dev->config[c];
+
+- if (!cf->interface)
+- break;
+-
+ for (i = 0; i < cf->desc.bNumInterfaces; i++) {
+ struct usb_interface *ifp = cf->interface[i];
+- put_device(&ifp->dev);
++
++ if (ifp)
++ put_device(&ifp->dev);
+ }
+ }
+ kfree(dev->config);
+@@ -417,38 +388,39 @@
+ // (used by real hubs and virtual root hubs)
+ int usb_get_configuration(struct usb_device *dev)
+ {
++ int ncfg = dev->descriptor.bNumConfigurations;
+ int result;
+ unsigned int cfgno, length;
+ unsigned char *buffer;
+ unsigned char *bigbuffer;
+ struct usb_config_descriptor *desc;
+
+- if (dev->descriptor.bNumConfigurations > USB_MAXCONFIG) {
+- warn("too many configurations");
+- return -EINVAL;
++ if (ncfg > USB_MAXCONFIG) {
++ warn("too many configurations (%d max %d)",
++ ncfg, USB_MAXCONFIG);
++ dev->descriptor.bNumConfigurations = ncfg = USB_MAXCONFIG;
+ }
+
+- if (dev->descriptor.bNumConfigurations < 1) {
+- warn("not enough configurations");
++ if (ncfg < 1) {
++ warn("no configurations");
+ return -EINVAL;
+ }
+
+- dev->config = (struct usb_host_config *)
+- kmalloc(dev->descriptor.bNumConfigurations *
+- sizeof(struct usb_host_config), GFP_KERNEL);
++ length = ncfg * sizeof(struct usb_host_config);
++ dev->config = kmalloc(length, GFP_KERNEL);
+ if (!dev->config) {
+ err("out of memory");
+- return -ENOMEM;
++ return -ENOMEM;
+ }
+- memset(dev->config, 0, dev->descriptor.bNumConfigurations *
+- sizeof(struct usb_host_config));
++ memset(dev->config, 0, length);
+
+- dev->rawdescriptors = (char **)kmalloc(sizeof(char *) *
+- dev->descriptor.bNumConfigurations, GFP_KERNEL);
++ length = ncfg * sizeof(char *);
++ dev->rawdescriptors = kmalloc(length, GFP_KERNEL);
+ if (!dev->rawdescriptors) {
+ err("out of memory");
+ return -ENOMEM;
+ }
++ memset(dev->rawdescriptors, 0, length);
+
+ buffer = kmalloc(8, GFP_KERNEL);
+ if (!buffer) {
+@@ -457,7 +429,7 @@
+ }
+ desc = (struct usb_config_descriptor *)buffer;
+
+- for (cfgno = 0; cfgno < dev->descriptor.bNumConfigurations; cfgno++) {
++ for (cfgno = 0; cfgno < ncfg; cfgno++) {
+ /* We grab the first 8 bytes so we know how long the whole */
+ /* configuration is */
+ result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, 8);
+@@ -465,14 +437,14 @@
+ if (result < 0)
+ err("unable to get descriptor");
+ else {
+- err("config descriptor too short (expected %i, got %i)", 8, result);
++ warn("config descriptor too short (expected %i, got %i)", 8, result);
+ result = -EINVAL;
+ }
+ goto err;
+ }
+
+ /* Get the full buffer */
+- length = le16_to_cpu(desc->wTotalLength);
++ length = max((int) le16_to_cpu(desc->wTotalLength), USB_DT_CONFIG_SIZE);
+
+ bigbuffer = kmalloc(length, GFP_KERNEL);
+ if (!bigbuffer) {
+@@ -487,8 +459,8 @@
+ err("couldn't get all of config descriptors");
+ kfree(bigbuffer);
+ goto err;
+- }
+-
++ }
++
+ if (result < length) {
+ err("config descriptor too short (expected %i, got %i)", length, result);
+ result = -EINVAL;
+@@ -498,11 +470,11 @@
+
+ dev->rawdescriptors[cfgno] = bigbuffer;
+
+- result = usb_parse_configuration(&dev->config[cfgno], bigbuffer);
++ result = usb_parse_configuration(&dev->config[cfgno], bigbuffer, length);
+ if (result > 0)
+ dbg("descriptor data left");
+ else if (result < 0) {
+- result = -EINVAL;
++ ++cfgno;
+ goto err;
+ }
+ }
+Index: linux-2.6.0-test5/drivers/usb/core/hub.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/core/hub.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/core/hub.c 2003-09-27 11:38:32.306617032 +0800
+@@ -859,8 +859,7 @@
+ }
+ }
+
+- /* XXX Replace this with dbg() when 2.6 is about to ship. */
+- dev_info (hubdev (hub),
++ dev_dbg (hubdev (hub),
+ "debounce: port %d: delay %dms stable %d status 0x%x\n",
+ port + 1, delay_time, stable_count, portstatus);
+
+@@ -1183,8 +1182,7 @@
+ return -1;
+ }
+
+- pid = kernel_thread(hub_thread, NULL,
+- CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++ pid = kernel_thread(hub_thread, NULL, CLONE_KERNEL);
+ if (pid >= 0) {
+ khubd_pid = pid;
+
+Index: linux-2.6.0-test5/drivers/usb/core/usb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/core/usb.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/core/usb.c 2003-09-27 11:38:32.335612624 +0800
+@@ -1424,14 +1424,15 @@
+ struct usb_interface *intf;
+ struct usb_driver *driver;
+
+- if ((dev->driver == &usb_generic_driver) ||
++ if ((dev->driver == NULL) ||
++ (dev->driver == &usb_generic_driver) ||
+ (dev->driver_data == &usb_generic_driver_data))
+ return 0;
+
+ intf = to_usb_interface(dev);
+ driver = to_usb_driver(dev->driver);
+
+- if (driver && driver->suspend)
++ if (driver->suspend)
+ return driver->suspend(intf, state);
+ return 0;
+ }
+@@ -1441,14 +1442,15 @@
+ struct usb_interface *intf;
+ struct usb_driver *driver;
+
+- if ((dev->driver == &usb_generic_driver) ||
++ if ((dev->driver == NULL) ||
++ (dev->driver == &usb_generic_driver) ||
+ (dev->driver_data == &usb_generic_driver_data))
+ return 0;
+
+ intf = to_usb_interface(dev);
+ driver = to_usb_driver(dev->driver);
+
+- if (driver && driver->resume)
++ if (driver->resume)
+ return driver->resume(intf);
+ return 0;
+ }
+Index: linux-2.6.0-test5/drivers/usb/gadget/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/gadget/inode.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/gadget/inode.c 2003-09-27 11:38:32.405601984 +0800
+@@ -28,7 +28,6 @@
+ #include <linux/fs.h>
+ #include <linux/pagemap.h>
+ #include <linux/uts.h>
+-#include <linux/version.h>
+ #include <linux/wait.h>
+ #include <linux/compiler.h>
+ #include <asm/uaccess.h>
+Index: linux-2.6.0-test5/drivers/usb/gadget/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/gadget/Kconfig 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/gadget/Kconfig 2003-09-27 11:38:32.450595144 +0800
+@@ -68,7 +68,7 @@
+
+ config USB_ZERO
+ tristate "Gadget Zero (DEVELOPMENT)"
+- depends on USB_GADGET && (USB_DUMMY_HCD || USB_NET2280 || USB_PXA250 || USB_SA1100)
++ depends on USB_GADGET && (USB_DUMMY_HCD || USB_NET2280 || USB_PXA2XX || USB_SA1100)
+ help
+ Gadget Zero is a two-configuration device. It either sinks and
+ sources bulk data; or it loops back a configurable number of
+@@ -97,9 +97,9 @@
+ depends on USB_ZERO && (USB_NET2280 || USB_DUMMY_HCD)
+ default y
+
+-config USB_ZERO_PXA250
++config USB_ZERO_PXA2XX
+ bool
+- depends on USB_ZERO && USB_PXA250
++ depends on USB_ZERO && USB_PXA2XX
+ default y
+
+ config USB_ZERO_SA1100
+@@ -110,22 +110,28 @@
+
+ config USB_ETH
+ tristate "Ethernet Gadget"
+- depends on USB_GADGET && (USB_DUMMY_HCD || USB_NET2280 || USB_PXA250 || USB_SA1100)
++ depends on USB_GADGET && (USB_DUMMY_HCD || USB_NET2280 || USB_PXA2XX || USB_SA1100)
+ help
+- This driver implements the "Communication Device Class" (CDC)
+- Ethernet Control Model. That protocol is often avoided with pure
+- Ethernet adapters, in favor of simpler vendor-specific hardware,
+- but is widely supported by firmware for smart network devices.
++ This driver implements Ethernet style communication, in either
++ of two ways:
++
++ - The "Communication Device Class" (CDC) Ethernet Control Model.
++ That protocol is often avoided with pure Ethernet adapters, in
++ favor of simpler vendor-specific hardware, but is widely
++ supported by firmware for smart network devices.
++
++ - On hardware can't implement that protocol, a simpler approach
++ is used, placing fewer demands on USB.
+
+ Within the USB device, this gadget driver exposes a network device
+ "usbX", where X depends on what other networking devices you have.
+ Treat it like a two-node Ethernet link: host, and gadget.
+
+ The Linux-USB host-side "usbnet" driver interoperates with this
+- driver, so that deep I/O queues can be supported. (On 2.4 kernels,
+- use "CDCEther" instead.) Deep queues are especially important with
+- high speed devices. It should also interoperate with standard CDC
+- Ethernet class drivers on other host operating systems.
++ driver, so that deep I/O queues can be supported. On 2.4 kernels,
++ use "CDCEther" instead, if you're using the CDC option. That CDC
++ mode should also interoperate with standard CDC Ethernet class
++ drivers on other host operating systems.
+
+ Say "y" to link the driver statically, or "m" to build a
+ dynamically linked module called "g_ether".
+@@ -137,9 +143,9 @@
+ depends on USB_ETH && (USB_NET2280 || USB_DUMMY_HCD)
+ default y
+
+-config USB_ETH_PXA250
++config USB_ETH_PXA2XX
+ bool
+- depends on USB_ETH && USB_PXA250
++ depends on USB_ETH && USB_PXA2XX
+ default y
+
+ config USB_ETH_SA1100
+Index: linux-2.6.0-test5/drivers/usb/input/hiddev.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/input/hiddev.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/input/hiddev.c 2003-09-27 11:38:32.505586784 +0800
+@@ -727,6 +727,7 @@
+ retval = usb_register_dev(&hiddev->intf, &hiddev_class);
+ if (retval) {
+ err("Not able to get a minor for this device.");
++ kfree(hiddev);
+ return -1;
+ }
+
+Index: linux-2.6.0-test5/drivers/usb/input/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/input/Kconfig 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/input/Kconfig 2003-09-27 11:38:32.535582224 +0800
+@@ -20,10 +20,8 @@
+
+ If unsure, say Y.
+
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called hid. If you want to compile it as a
+- module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called hid.
+
+ comment "Input core support is needed for USB HID input layer or HIDBP support"
+ depends on USB && INPUT=n
+@@ -104,10 +102,8 @@
+ This is almost certainly not what you want. This is mostly
+ useful for embedded applications or simple keyboards.
+
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called usbkbd. If you want to compile it as a
+- module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called usbkbd.
+
+ If even remotely unsure, say N.
+
+@@ -122,10 +118,8 @@
+ This is almost certainly not what you want. This is mostly
+ useful for embedded applications or simple mice.
+
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called usbmouse. If you want to compile it as
+- a module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called usbmouse.
+
+ If even remotely unsure, say N.
+
+@@ -140,10 +134,8 @@
+ (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
+ (CONFIG_INPUT_EVDEV) as well.
+
+- This driver is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called aiptek. If you want to compile it as a
+- module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called aiptek.
+
+ config USB_WACOM
+ tristate "Wacom Intuos/Graphire tablet support"
+@@ -154,10 +146,8 @@
+ (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
+ (CONFIG_INPUT_EVDEV) as well.
+
+- This driver is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called wacom. If you want to compile it as a
+- module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called wacom.
+
+ config USB_KBTAB
+ tristate "KB Gear JamStudio tablet support"
+@@ -168,10 +158,8 @@
+ (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
+ (CONFIG_INPUT_EVDEV) as well.
+
+- This driver is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called kbtab.o. If you want to compile it as a
+- module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called kbtab.
+
+ config USB_POWERMATE
+ tristate "Griffin PowerMate and Contour Jog support"
+@@ -184,10 +172,8 @@
+
+ You can download userspace tools from http://sowerbutts.com/powermate/
+
+- This driver is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called powermate. If you want to compile it as a
+- module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called powermate.
+
+ config USB_XPAD
+ tristate "X-Box gamepad support"
+@@ -200,8 +186,6 @@
+ For information about how to connect the X-Box pad to USB, see
+ Documentation/input/xpad.txt.
+
+- This driver is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called xpad. If you want to compile it as a
+- module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called xpad.
+
+Index: linux-2.6.0-test5/drivers/usb/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/Kconfig 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/Kconfig 2003-09-27 11:38:32.584574776 +0800
+@@ -33,10 +33,8 @@
+
+ It doesn't normally hurt to select them all if you are not certain.
+
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called usbcore. If you want to compile it as a
+- module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called usbcore.
+
+ source "drivers/usb/core/Kconfig"
+
+@@ -82,10 +80,8 @@
+ Say Y here if you own an USS-720 USB->Parport cable and intend to
+ connect anything other than a printer to it.
+
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called uss720. If you want to compile it as a
+- module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called uss720.
+
+ source "drivers/usb/serial/Kconfig"
+
+Index: linux-2.6.0-test5/drivers/usb/media/dabusb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/media/dabusb.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/media/dabusb.c 2003-09-27 11:38:32.628568088 +0800
+@@ -89,7 +89,6 @@
+ static void dump_urb (struct urb *urb)
+ {
+ dbg("urb :%p", urb);
+- dbg("next :%p", urb->next);
+ dbg("dev :%p", urb->dev);
+ dbg("pipe :%08X", urb->pipe);
+ dbg("status :%d", urb->status);
+@@ -728,7 +727,7 @@
+ pdabusb_t s;
+
+ dbg("dabusb: probe: vendor id 0x%x, device id 0x%x ifnum:%d",
+- usbdev->descriptor.idVendor, usbdev->descriptor.idProduct, ifnum);
++ usbdev->descriptor.idVendor, usbdev->descriptor.idProduct, intf->altsetting->desc.bInterfaceNumber);
+
+ /* We don't handle multiple configurations */
+ if (usbdev->descriptor.bNumConfigurations != 1)
+@@ -762,7 +761,7 @@
+ goto reject;
+ }
+ }
+- dbg("bound to interface: %d", ifnum);
++ dbg("bound to interface: %d", intf->altsetting->desc.bInterfaceNumber);
+ usb_set_intfdata (intf, s);
+ up (&s->mutex);
+
+Index: linux-2.6.0-test5/drivers/usb/media/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/media/Kconfig 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/media/Kconfig 2003-09-27 11:38:32.677560640 +0800
+@@ -14,10 +14,8 @@
+ isochronous transactions. URB's are explained in
+ <file:Documentation/usb/URB.txt>.
+
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called dabusb. If you want to compile it as a
+- module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called dabusb.
+
+ comment "Video4Linux support is needed for USB Multimedia device support"
+ depends on USB && VIDEO_DEV=n
+@@ -33,10 +31,8 @@
+ Information on this API and pointers to "v4l" programs may be found
+ on the WWW at <http://roadrunner.swansea.uk.linux.org/v4l.shtml>.
+
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called vicam. If you want to compile it as a
+- module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called vicam.
+
+ config USB_DSBR
+ tristate "D-Link USB FM radio support (EXPERIMENTAL)"
+@@ -53,10 +49,8 @@
+ "v4l" programs may be found on the WWW at
+ <http://roadrunner.swansea.uk.linux.org/v4l.shtml>.
+
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called dsbr100. If you want to compile it as a
+- module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called dsbr100.
+
+ config USB_IBMCAM
+ tristate "USB IBM (Xirlink) C-it Camera support"
+@@ -72,13 +66,12 @@
+ "v4l" programs may be found on the WWW at
+ <http://roadrunner.swansea.uk.linux.org/v4l.shtml>.
+
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called ibmcam. If you want to compile it as a
+- module, say M here and read <file:Documentation/modules.txt>. This
+- camera has several configuration options which can be specified when
+- you load the module. Read <file:Documentation/usb/ibmcam.txt> to
+- learn more.
++ To compile this driver as a module, say M here: the
++ module will be called ibmcam.
++
++ This camera has several configuration options which
++ can be specified when you load the module. Read
++ <file:Documentation/usb/ibmcam.txt> to learn more.
+
+ config USB_KONICAWC
+ tristate "USB Konica Webcam support"
+@@ -93,10 +86,8 @@
+ "v4l" programs may be found on the WWW at
+ <http://roadrunner.swansea.uk.linux.org/v4l.shtml>.
+
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called konicawc. If you want to compile it as
+- a module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called konicawc.
+
+ config USB_OV511
+ tristate "USB OV511 Camera support"
+@@ -111,10 +102,8 @@
+ Information on this API and pointers to "v4l" programs may be found
+ on the WWW at <http://roadrunner.swansea.uk.linux.org/v4l.shtml>.
+
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called ov511. If you want to compile it as a
+- module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called ov511.
+
+ config USB_PWC
+ tristate "USB Philips Cameras"
+@@ -152,10 +141,8 @@
+ Information on this API and pointers to "v4l" programs may be found
+ on the WWW at <http://roadrunner.swansea.uk.linux.org/v4l.shtml>.
+
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called pwc. If you want to compile it as a
+- module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called pwc.
+
+ config USB_SE401
+ tristate "USB SE401 Camera support"
+@@ -170,10 +157,8 @@
+ Information on this API and pointers to "v4l" programs may be found
+ on the WWW at <http://roadrunner.swansea.uk.linux.org/v4l.shtml>.
+
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called se401. If you want to compile it as a
+- module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called se401.
+
+ config USB_STV680
+ tristate "USB STV680 (Pencam) Camera support"
+@@ -189,8 +174,6 @@
+ Information on this API and pointers to "v4l" programs may be found
+ on the WWW at <http://roadrunner.swansea.uk.linux.org/v4l.shtml>.
+
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called stv680. If you want to compile it as a
+- module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called stv680.
+
+Index: linux-2.6.0-test5/drivers/usb/media/usbvideo.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/media/usbvideo.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/media/usbvideo.c 2003-09-27 11:38:32.796542552 +0800
+@@ -24,7 +24,6 @@
+ #include <linux/vmalloc.h>
+ #include <linux/init.h>
+ #include <linux/spinlock.h>
+-#include <linux/mm.h>
+
+ #include <asm/io.h>
+
+Index: linux-2.6.0-test5/drivers/usb/media/vicam.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/media/vicam.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/media/vicam.c 2003-09-27 11:38:32.853533888 +0800
+@@ -1292,7 +1292,7 @@
+ interface = &intf->altsetting[0];
+
+ DBG(KERN_DEBUG "Interface %d. has %u. endpoints!\n",
+- ifnum, (unsigned) (interface->desc.bNumEndpoints));
++ interface->desc.bInterfaceNumber, (unsigned) (interface->desc.bNumEndpoints));
+ endpoint = &interface->endpoint[0].desc;
+
+ if ((endpoint->bEndpointAddress & 0x80) &&
+Index: linux-2.6.0-test5/drivers/usb/misc/speedtch.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/misc/speedtch.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/misc/speedtch.c 2003-09-27 11:38:32.906525832 +0800
+@@ -21,7 +21,9 @@
+ ******************************************************************************/
+
+ /*
+- * Written by Johan Verrept, maintained by Duncan Sands (duncan.sands@wanadoo.fr)
++ * Written by Johan Verrept, maintained by Duncan Sands (duncan.sands@free.fr)
++ *
++ * 1.7+: - See the check-in logs
+ *
+ * 1.6: - No longer opens a connection if the firmware is not loaded
+ * - Added support for the speedtouch 330
+@@ -84,6 +86,11 @@
+
+ #include <linux/usb.h>
+
++#ifdef DEBUG
++#define DEBUG_ON(x) BUG_ON(x)
++#else
++#define DEBUG_ON(x) do { if (x); } while (0)
++#endif
+
+ #ifdef VERBOSE_DEBUG
+ static int udsl_print_packet (const unsigned char *data, int len);
+@@ -94,9 +101,9 @@
+ #define vdbg(arg...)
+ #endif
+
+-#define DRIVER_AUTHOR "Johan Verrept, Duncan Sands <duncan.sands@wanadoo.fr>"
++#define DRIVER_AUTHOR "Johan Verrept, Duncan Sands <duncan.sands@free.fr>"
+ #define DRIVER_DESC "Alcatel SpeedTouch USB driver"
+-#define DRIVER_VERSION "1.6"
++#define DRIVER_VERSION "1.7"
+
+ static const char udsl_driver_name [] = "speedtch";
+
+@@ -109,10 +116,10 @@
+ #define UDSL_MAX_SND_BUFS 8
+ #define UDSL_MAX_RCV_BUF_SIZE 1024 /* ATM cells */
+ #define UDSL_MAX_SND_BUF_SIZE 1024 /* ATM cells */
+-#define UDSL_DEFAULT_RCV_URBS 1
+-#define UDSL_DEFAULT_SND_URBS 1
+-#define UDSL_DEFAULT_RCV_BUFS 2
+-#define UDSL_DEFAULT_SND_BUFS 2
++#define UDSL_DEFAULT_RCV_URBS 2
++#define UDSL_DEFAULT_SND_URBS 2
++#define UDSL_DEFAULT_RCV_BUFS 4
++#define UDSL_DEFAULT_SND_BUFS 4
+ #define UDSL_DEFAULT_RCV_BUF_SIZE 64 /* ATM cells */
+ #define UDSL_DEFAULT_SND_BUF_SIZE 64 /* ATM cells */
+
+@@ -351,7 +358,7 @@
+ dbg ("udsl_extract_cells: buffer overrun (max_pdu: %u, skb->len %u, vcc: 0x%p)", vcc_data->max_pdu, skb->len, vcc);
+ /* discard cells already received */
+ skb_trim (skb, 0);
+- BUG_ON (vcc_data->max_pdu < ATM_CELL_PAYLOAD);
++ DEBUG_ON (vcc_data->max_pdu < ATM_CELL_PAYLOAD);
+ }
+
+ memcpy (skb->tail, source + ATM_CELL_HEADER, ATM_CELL_PAYLOAD);
+@@ -498,7 +505,7 @@
+ memset (target, 0, ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER);
+ target += ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER;
+
+- BUG_ON (--ctrl->num_cells);
++ DEBUG_ON (--ctrl->num_cells);
+ }
+
+ memcpy (target, ctrl->aal5_trailer, ATM_AAL5_TRAILER);
+@@ -535,7 +542,7 @@
+
+ vdbg ("udsl_complete_receive: urb 0x%p, status %d, actual_length %d, filled_cells %u, rcv 0x%p, buf 0x%p", urb, urb->status, urb->actual_length, buf->filled_cells, rcv, buf);
+
+- BUG_ON (buf->filled_cells > rcv_buf_size);
++ DEBUG_ON (buf->filled_cells > rcv_buf_size);
+
+ /* may not be in_interrupt() */
+ spin_lock_irqsave (&instance->receive_lock, flags);
+@@ -1216,8 +1223,7 @@
+ count = 0;
+ spin_lock_irq (&instance->receive_lock);
+ list_for_each (pos, &instance->spare_receivers)
+- if (++count > num_rcv_urbs)
+- panic (__FILE__ ": memory corruption detected at line %d!\n", __LINE__);
++ DEBUG_ON (++count > num_rcv_urbs);
+ spin_unlock_irq (&instance->receive_lock);
+
+ dbg ("udsl_usb_disconnect: found %u spare receivers", count);
+@@ -1253,8 +1259,7 @@
+ count = 0;
+ spin_lock_irq (&instance->send_lock);
+ list_for_each (pos, &instance->spare_senders)
+- if (++count > num_snd_urbs)
+- panic (__FILE__ ": memory corruption detected at line %d!\n", __LINE__);
++ DEBUG_ON (++count > num_snd_urbs);
+ spin_unlock_irq (&instance->send_lock);
+
+ dbg ("udsl_usb_disconnect: found %u spare senders", count);
+Index: linux-2.6.0-test5/drivers/usb/misc/usbtest.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/misc/usbtest.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/misc/usbtest.c 2003-09-27 11:38:32.968516408 +0800
+@@ -87,7 +87,7 @@
+ struct usb_host_endpoint *in, *out;
+ struct usb_device *udev;
+
+- for (tmp = 0; tmp < intf->max_altsetting; tmp++) {
++ for (tmp = 0; tmp < intf->num_altsetting; tmp++) {
+ unsigned ep;
+
+ in = out = 0;
+Index: linux-2.6.0-test5/drivers/usb/net/usbnet.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/net/usbnet.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/net/usbnet.c 2003-09-27 11:38:33.172485400 +0800
+@@ -252,6 +252,8 @@
+ /* for new devices, use the descriptor-reading code instead */
+ int in; /* rx endpoint */
+ int out; /* tx endpoint */
++
++ unsigned long data; /* Misc driver specific data */
+ };
+
+ // we record the state for each of our queued skbs
+@@ -298,6 +300,9 @@
+
+ /*-------------------------------------------------------------------------*/
+
++static struct ethtool_ops usbnet_ethtool_ops;
++static void usbnet_get_drvinfo (struct net_device *, struct ethtool_drvinfo *);
++
+ /* mostly for PDA style devices, which are always connected if present */
+ static int always_connected (struct usbnet *dev)
+ {
+@@ -312,7 +317,7 @@
+ struct usb_host_interface *alt;
+ struct usb_host_endpoint *in, *out;
+
+- for (tmp = 0; tmp < intf->max_altsetting; tmp++) {
++ for (tmp = 0; tmp < intf->num_altsetting; tmp++) {
+ unsigned ep;
+
+ in = out = 0;
+@@ -383,10 +388,10 @@
+
+ \f
+ #ifdef CONFIG_USB_AX8817X
+-#define NEED_MII
+ /* ASIX AX8817X based USB 2.0 Ethernet Devices */
+
+ #define HAVE_HARDWARE
++#define NEED_MII
+
+ #include <linux/crc32.h>
+
+@@ -394,6 +399,8 @@
+ #define AX_CMD_READ_MII_REG 0x07
+ #define AX_CMD_WRITE_MII_REG 0x08
+ #define AX_CMD_SET_HW_MII 0x0a
++#define AX_CMD_READ_EEPROM 0x0b
++#define AX_CMD_WRITE_EEPROM 0x0c
+ #define AX_CMD_WRITE_RX_CTL 0x10
+ #define AX_CMD_READ_IPG012 0x11
+ #define AX_CMD_WRITE_IPG0 0x12
+@@ -403,8 +410,15 @@
+ #define AX_CMD_READ_NODE_ID 0x17
+ #define AX_CMD_READ_PHY_ID 0x19
+ #define AX_CMD_WRITE_MEDIUM_MODE 0x1b
++#define AX_CMD_READ_MONITOR_MODE 0x1c
++#define AX_CMD_WRITE_MONITOR_MODE 0x1d
+ #define AX_CMD_WRITE_GPIOS 0x1f
+
++#define AX_MONITOR_MODE 0x01
++#define AX_MONITOR_LINK 0x02
++#define AX_MONITOR_MAGIC 0x04
++#define AX_MONITOR_HSFS 0x10
++
+ #define AX_MCAST_FILTER_SIZE 8
+ #define AX_MAX_MCAST 64
+
+@@ -441,11 +455,11 @@
+ static void ax8817x_async_cmd_callback(struct urb *urb, struct pt_regs *regs)
+ {
+ struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context;
+-
++
+ if (urb->status < 0)
+ printk(KERN_DEBUG "ax8817x_async_cmd_callback() failed with %d",
+ urb->status);
+-
++
+ kfree(req);
+ usb_free_urb(urb);
+ }
+@@ -456,12 +470,12 @@
+ struct usb_ctrlrequest *req;
+ int status;
+ struct urb *urb;
+-
++
+ if ((urb = usb_alloc_urb(0, GFP_ATOMIC)) == NULL) {
+ devdbg(dev, "Error allocating URB in write_cmd_async!");
+ return;
+ }
+-
++
+ if ((req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC)) == NULL) {
+ deverr(dev, "Failed to allocate memory for control request");
+ usb_free_urb(urb);
+@@ -496,34 +510,31 @@
+ } else if (net->mc_count == 0) {
+ /* just broadcast and directed */
+ } else {
++ /* We use the 20 byte dev->data
++ * for our 8 byte filter buffer
++ * to avoid allocating memory that
++ * is tricky to free later */
++ u8 *multi_filter = (u8 *)dev->data;
+ struct dev_mc_list *mc_list = net->mc_list;
+- u8 *multi_filter;
+ u32 crc_bits;
+ int i;
+
+- multi_filter = kmalloc(AX_MCAST_FILTER_SIZE, GFP_ATOMIC);
+- if (multi_filter == NULL) {
+- /* Oops, couldn't allocate a buffer for setting the multicast
+- filter. Try all multi mode. */
+- rx_ctl |= 0x02;
+- } else {
+- memset(multi_filter, 0, AX_MCAST_FILTER_SIZE);
+-
+- /* Build the multicast hash filter. */
+- for (i = 0; i < net->mc_count; i++) {
+- crc_bits =
+- ether_crc(ETH_ALEN,
+- mc_list->dmi_addr) >> 26;
+- multi_filter[crc_bits >> 3] |=
+- 1 << (crc_bits & 7);
+- mc_list = mc_list->next;
+- }
+-
+- ax8817x_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0,
+- AX_MCAST_FILTER_SIZE, multi_filter);
++ memset(multi_filter, 0, AX_MCAST_FILTER_SIZE);
+
+- rx_ctl |= 0x10;
++ /* Build the multicast hash filter. */
++ for (i = 0; i < net->mc_count; i++) {
++ crc_bits =
++ ether_crc(ETH_ALEN,
++ mc_list->dmi_addr) >> 26;
++ multi_filter[crc_bits >> 3] |=
++ 1 << (crc_bits & 7);
++ mc_list = mc_list->next;
+ }
++
++ ax8817x_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0,
++ AX_MCAST_FILTER_SIZE, multi_filter);
++
++ rx_ctl |= 0x10;
+ }
+
+ ax8817x_write_cmd_async(dev, AX_CMD_WRITE_RX_CTL, rx_ctl, 0, 0, NULL);
+@@ -533,7 +544,7 @@
+ {
+ struct usbnet *dev = netdev->priv;
+ u16 res;
+- u8 buf[4];
++ u8 buf[1];
+
+ ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, &buf);
+ ax8817x_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, (__u16)loc, 2, (u16 *)&res);
+@@ -546,23 +557,103 @@
+ {
+ struct usbnet *dev = netdev->priv;
+ u16 res = val;
+- u8 buf[4];
++ u8 buf[1];
+
+ ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, &buf);
+ ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, (u16 *)&res);
+ ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf);
+ }
+
++void ax8817x_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
++{
++ struct usbnet *dev = (struct usbnet *)net->priv;
++ u8 opt;
++
++ if (ax8817x_read_cmd(dev, AX_CMD_READ_MONITOR_MODE, 0, 0, 1, &opt) < 0) {
++ wolinfo->supported = 0;
++ wolinfo->wolopts = 0;
++ return;
++ }
++ wolinfo->supported = WAKE_PHY | WAKE_MAGIC;
++ wolinfo->wolopts = 0;
++ if (opt & AX_MONITOR_MODE) {
++ if (opt & AX_MONITOR_LINK)
++ wolinfo->wolopts |= WAKE_PHY;
++ if (opt & AX_MONITOR_MAGIC)
++ wolinfo->wolopts |= WAKE_MAGIC;
++ }
++}
++
++int ax8817x_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
++{
++ struct usbnet *dev = (struct usbnet *)net->priv;
++ u8 opt = 0;
++ u8 buf[1];
++
++ if (wolinfo->wolopts & WAKE_PHY)
++ opt |= AX_MONITOR_LINK;
++ if (wolinfo->wolopts & WAKE_MAGIC)
++ opt |= AX_MONITOR_MAGIC;
++ if (opt != 0)
++ opt |= AX_MONITOR_MODE;
++
++ if (ax8817x_write_cmd(dev, AX_CMD_WRITE_MONITOR_MODE,
++ opt, 0, 0, &buf) < 0)
++ return -EINVAL;
++
++ return 0;
++}
++
++int ax8817x_get_eeprom(struct net_device *net,
++ struct ethtool_eeprom *eeprom, u8 *data)
++{
++ struct usbnet *dev = (struct usbnet *)net->priv;
++ u16 *ebuf = (u16 *)data;
++ int i;
++
++ /* Crude hack to ensure that we don't overwrite memory
++ * if an odd length is supplied
++ */
++ if (eeprom->len % 2)
++ return -EINVAL;
++
++ /* ax8817x returns 2 bytes from eeprom on read */
++ for (i=0; i < eeprom->len / 2; i++) {
++ if (ax8817x_read_cmd(dev, AX_CMD_READ_EEPROM,
++ eeprom->offset + i, 0, 2, &ebuf[i]) < 0)
++ return -EINVAL;
++ }
++ return i * 2;
++}
++
++static void ax8817x_get_drvinfo (struct net_device *net,
++ struct ethtool_drvinfo *info)
++{
++ /* Inherit standard device info */
++ usbnet_get_drvinfo(net, info);
++ info->eedump_len = 0x3e;
++}
++
+ static int ax8817x_bind(struct usbnet *dev, struct usb_interface *intf)
+ {
+ int ret;
+ u8 buf[6];
+ u16 *buf16 = (u16 *) buf;
+ int i;
++ unsigned long gpio_bits = dev->driver_info->data;
+
+ dev->in = usb_rcvbulkpipe(dev->udev, 3);
+ dev->out = usb_sndbulkpipe(dev->udev, 2);
+
++ /* Toggle the GPIOs in a manufacturer/model specific way */
++ for (i = 2; i >= 0; i--) {
++ if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS,
++ (gpio_bits >> (i * 8)) & 0xff, 0, 0,
++ buf)) < 0)
++ return ret;
++ wait_ms(5);
++ }
++
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, 0x80, 0, 0, buf)) < 0) {
+ dbg("send AX_CMD_WRITE_RX_CTL failed: %d", ret);
+ return ret;
+@@ -640,6 +731,11 @@
+
+ dev->net->set_multicast_list = ax8817x_set_multicast;
+
++ usbnet_ethtool_ops.get_drvinfo = &ax8817x_get_drvinfo;
++ usbnet_ethtool_ops.get_wol = &ax8817x_get_wol;
++ usbnet_ethtool_ops.set_wol = &ax8817x_set_wol;
++ usbnet_ethtool_ops.get_eeprom = &ax8817x_get_eeprom;
++
+ return 0;
+ }
+
+@@ -647,7 +743,30 @@
+ .description = "ASIX AX8817x USB 2.0 Ethernet",
+ .bind = ax8817x_bind,
+ .flags = FLAG_ETHER,
++ .data = 0x00130103,
++};
++
++static const struct driver_info dlink_dub_e100_info = {
++ .description = "DLink DUB-E100 USB Ethernet",
++ .bind = ax8817x_bind,
++ .flags = FLAG_ETHER,
++ .data = 0x009f9d9f,
++};
++
++static const struct driver_info netgear_fa120_info = {
++ .description = "Netgear FA-120 USB Ethernet",
++ .bind = ax8817x_bind,
++ .flags = FLAG_ETHER,
++ .data = 0x00130103,
+ };
++
++static const struct driver_info hawking_uf200_info = {
++ .description = "Hawking UF200 USB Ethernet",
++ .bind = ax8817x_bind,
++ .flags = FLAG_ETHER,
++ .data = 0x001f1d1f,
++};
++
+ #endif /* CONFIG_USB_AX8817X */
+
+
+@@ -2415,72 +2534,45 @@
+
+ /*-------------------------------------------------------------------------*/
+
+-static inline int
+-usbnet_ethtool_ioctl (struct net_device *net, void __user *useraddr)
++static void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info)
+ {
+- struct usbnet *dev = (struct usbnet *) net->priv;
+- u32 cmd;
++ struct usbnet *dev = net->priv;
+
+- if (get_user (cmd, (u32 *)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, driver_name, sizeof info.driver);
+- strncpy (info.version, DRIVER_VERSION, sizeof info.version);
+- strncpy (info.fw_version, dev->driver_info->description,
+- sizeof info.fw_version);
+- usb_make_path (dev->udev, info.bus_info, sizeof info.bus_info);
+- if (copy_to_user (useraddr, &info, sizeof (info)))
+- return -EFAULT;
+- return 0;
+- }
++ strncpy (info->driver, driver_name, sizeof info->driver);
++ strncpy (info->version, DRIVER_VERSION, sizeof info->version);
++ strncpy (info->fw_version, dev->driver_info->description,
++ sizeof info->fw_version);
++ usb_make_path (dev->udev, info->bus_info, sizeof info->bus_info);
++}
+
+- case ETHTOOL_GLINK: /* get link status */
+- if (dev->driver_info->check_connect) {
+- struct ethtool_value edata = { ETHTOOL_GLINK };
+-
+- edata.data = dev->driver_info->check_connect (dev) == 0;
+- if (copy_to_user (useraddr, &edata, sizeof (edata)))
+- return -EFAULT;
+- return 0;
+- }
+- break;
++static u32 usbnet_get_link (struct net_device *net)
++{
++ struct usbnet *dev = net->priv;
+
+- case ETHTOOL_GMSGLVL: { /* get message-level */
+- struct ethtool_value edata = {ETHTOOL_GMSGLVL};
++ /* If a check_connect is defined, return it's results */
++ if (dev->driver_info->check_connect)
++ return dev->driver_info->check_connect (dev) == 0;
+
+- edata.data = dev->msg_level;
+- if (copy_to_user (useraddr, &edata, sizeof (edata)))
+- return -EFAULT;
+- return 0;
+- }
++ /* Otherwise, we're up to avoid breaking scripts */
++ return 1;
++}
+
+- case ETHTOOL_SMSGLVL: { /* set message-level */
+- struct ethtool_value edata;
++static u32 usbnet_get_msglevel (struct net_device *net)
++{
++ struct usbnet *dev = net->priv;
+
+- if (copy_from_user (&edata, useraddr, sizeof (edata)))
+- return -EFAULT;
+- dev->msg_level = edata.data;
+- return 0;
+- }
+-
+- /* could also map RINGPARAM to RX/TX QLEN */
++ return dev->msg_level;
++}
+
+- }
+- /* Note that the ethtool user space code requires EOPNOTSUPP */
+- return -EOPNOTSUPP;
++static void usbnet_set_msglevel (struct net_device *net, u32 level)
++{
++ struct usbnet *dev = net->priv;
++
++ dev->msg_level = level;
+ }
+
+ static int usbnet_ioctl (struct net_device *net, struct ifreq *rq, int cmd)
+ {
+- if (cmd == SIOCETHTOOL)
+- return usbnet_ethtool_ioctl (net, (void __user *)rq->ifr_data);
+-
+ #ifdef NEED_MII
+ {
+ struct usbnet *dev = (struct usbnet *)net->priv;
+@@ -2889,6 +2981,7 @@
+ net->watchdog_timeo = TX_TIMEOUT_JIFFIES;
+ net->tx_timeout = usbnet_tx_timeout;
+ net->do_ioctl = usbnet_ioctl;
++ net->ethtool_ops = &usbnet_ethtool_ops;
+
+ // allow device-specific bind/init procedures
+ // NOTE net->name still not usable ...
+@@ -2991,19 +3084,19 @@
+ }, {
+ // Netgear FA120
+ USB_DEVICE (0x0846, 0x1040),
+- .driver_info = (unsigned long) &ax8817x_info,
++ .driver_info = (unsigned long) &netgear_fa120_info,
+ }, {
+ // DLink DUB-E100
+ USB_DEVICE (0x2001, 0x1a00),
+- .driver_info = (unsigned long) &ax8817x_info,
++ .driver_info = (unsigned long) &dlink_dub_e100_info,
+ }, {
+ // Intellinet, ST Lab USB Ethernet
+ USB_DEVICE (0x0b95, 0x1720),
+- .driver_info = (unsigned long) &ax8817x_info,
++ .driver_info = (unsigned long) &ax8817x_info,
+ }, {
+ // Hawking UF200, TrendNet TU2-ET100
+ USB_DEVICE (0x07b8, 0x420a),
+- .driver_info = (unsigned long) &ax8817x_info,
++ .driver_info = (unsigned long) &hawking_uf200_info,
+ },
+ #endif
+
+@@ -3167,6 +3260,14 @@
+ .disconnect = usbnet_disconnect,
+ };
+
++/* Default ethtool_ops assigned. Devices can override in their bind() routine */
++static struct ethtool_ops usbnet_ethtool_ops = {
++ .get_drvinfo = usbnet_get_drvinfo,
++ .get_link = usbnet_get_link,
++ .get_msglevel = usbnet_get_msglevel,
++ .set_msglevel = usbnet_set_msglevel,
++};
++
+ /*-------------------------------------------------------------------------*/
+
+ static int __init usbnet_init (void)
+Index: linux-2.6.0-test5/drivers/usb/serial/ipaq.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/serial/ipaq.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/serial/ipaq.c 2003-09-27 11:38:33.183483728 +0800
+@@ -341,7 +341,7 @@
+ usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
+
+ tty = port->tty;
+- if (urb->actual_length) {
++ if (tty && urb->actual_length) {
+ for (i = 0; i < urb->actual_length ; ++i) {
+ /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */
+ if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
+Index: linux-2.6.0-test5/drivers/usb/serial/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/serial/Kconfig 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/serial/Kconfig 2003-09-27 11:38:33.216478712 +0800
+@@ -17,10 +17,8 @@
+ information on the specifics of the different devices that are
+ supported, and on how to use them.
+
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called usbserial. If you want to compile it
+- as a module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called usbserial.
+
+ config USB_SERIAL_DEBUG
+ bool "USB Serial Converter verbose debug"
+@@ -70,10 +68,8 @@
+ adaptor (F5U103 is one of the model numbers) or the Peracom single
+ port USB to serial adapter.
+
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called belkin_sa. If you want to compile it as
+- a module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called belkin_sa.
+
+ config USB_SERIAL_WHITEHEAT
+ tristate "USB ConnectTech WhiteHEAT Serial Driver"
+@@ -82,10 +78,8 @@
+ Say Y here if you want to use a ConnectTech WhiteHEAT 4 port
+ USB to serial converter device.
+
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called whiteheat. If you want to compile it as
+- a module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called whiteheat.
+
+ config USB_SERIAL_DIGI_ACCELEPORT
+ tristate "USB Digi International AccelePort USB Serial Driver"
+@@ -99,11 +93,8 @@
+ This driver works under SMP with the usb-uhci driver. It does not
+ work under SMP with the uhci driver.
+
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called digi_acceleport. If you want to compile
+- it as a module, say M here and read
+- <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called digi_acceleport.
+
+ config USB_SERIAL_EMPEG
+ tristate "USB Empeg empeg-car Mark I/II Driver"
+@@ -114,10 +105,8 @@
+ device node. See <file:Documentation/usb/usb-serial.txt> for more
+ tidbits of information.
+
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called empeg. If you want to compile it as a
+- module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called empeg.
+
+ config USB_SERIAL_FTDI_SIO
+ tristate "USB FTDI Single Port Serial Driver (EXPERIMENTAL)"
+@@ -130,10 +119,8 @@
+ See <http://ftdi-usb-sio.sourceforge.net/> for more
+ information on this driver and the device.
+
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called ftdi_sio. If you want to compile it as
+- a module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called ftdi_sio.
+
+ config USB_SERIAL_VISOR
+ tristate "USB Handspring Visor / Palm m50x / Sony Clie Driver"
+@@ -144,10 +131,8 @@
+ <http://usbvisor.sourceforge.net/> for more information on using this
+ driver.
+
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called visor. If you want to compile it as a
+- module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called visor.
+
+ config USB_SERIAL_IPAQ
+ tristate "USB PocketPC PDA Driver"
+@@ -158,10 +143,8 @@
+ using a USB cradle/cable. For information on using the driver,
+ read <file:Documentation/usb/usb-serial.txt>.
+
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called ipaq. If you want to compile it as a
+- module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called ipaq.
+
+ config USB_SERIAL_IR
+ tristate "USB IR Dongle Serial Driver (EXPERIMENTAL)"
+@@ -171,10 +154,8 @@
+ devices. This is useful if you do not want to use the full IrDA
+ stack.
+
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called ir-usb. If you want to compile it as a
+- module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called ir-usb.
+
+ config USB_SERIAL_EDGEPORT
+ tristate "USB Inside Out Edgeport Serial Driver"
+@@ -199,10 +180,8 @@
+ Edgeport/4 DIN
+ Edgeport/16 Dual
+
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called io_edgeport. If you want to compile it
+- as a module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called io_edgeport.
+
+ config USB_SERIAL_EDGEPORT_TI
+ tristate "USB Inside Out Edgeport Serial Driver (TI devices)"
+@@ -212,10 +191,8 @@
+ Networks (Digi) that are not supported by the io_edgeport driver.
+ This includes the Edgeport/1 device.
+
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called io_ti. If you want to compile it
+- as a module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called io_ti.
+
+ config USB_SERIAL_KEYSPAN_PDA
+ tristate "USB Keyspan PDA Single Port Serial Driver"
+@@ -225,10 +202,8 @@
+ serial converter device. This driver makes use of firmware
+ developed from scratch by Brian Warner.
+
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called keyspan_pda. If you want to compile it
+- as a module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called keyspan_pda.
+
+ config USB_SERIAL_KEYSPAN
+ tristate "USB Keyspan USA-xxx Serial Driver"
+@@ -241,10 +216,8 @@
+
+ See <http://misc.nu/hugh/keyspan.html> for more information.
+
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called keyspan. If you want to compile it as a
+- module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called keyspan.
+
+ config USB_SERIAL_KEYSPAN_MPR
+ bool "USB Keyspan MPR Firmware"
+@@ -337,10 +310,8 @@
+ Please read <file:Documentation/usb/usb-serial.txt> for more
+ information.
+
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called kl5kusb105. If you want to compile it as
+- a module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called kl5kusb105.
+
+ config USB_SERIAL_KOBIL_SCT
+ tristate "USB KOBIL chipcard reader (EXPERIMENTAL)"
+@@ -357,10 +328,8 @@
+ - KAAN Professional
+
+ Note that you need a current CT-API.
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called kobil_sct. If you want to compile it as
+- a module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called kobil_sct.
+
+ config USB_SERIAL_MCT_U232
+ tristate "USB MCT Single Port Serial Driver"
+@@ -372,10 +341,8 @@
+ This driver also works with Sitecom U232-P25 and D-Link DU-H3SP USB
+ BAY devices.
+
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called mct_u232. If you want to compile it as
+- a module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called mct_u232.
+
+ config USB_SERIAL_PL2303
+ tristate "USB Prolific 2303 Single Port Serial Driver"
+@@ -384,10 +351,8 @@
+ Say Y here if you want to use the PL2303 USB Serial single port
+ adapter from Prolific.
+
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called pl2303. If you want to compile it as
+- a module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called pl2303.
+
+ config USB_SERIAL_SAFE
+ tristate "USB Safe Serial (Encapsulated) Driver (EXPERIMENTAL)"
+@@ -405,10 +370,8 @@
+ reader. This is an interface to ISO 7816 compatible contactbased
+ chipcards, e.g. GSM SIMs.
+
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called cyberjack. If you want to compile it as
+- a module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called cyberjack.
+
+ If unsure, say N.
+
+@@ -420,10 +383,8 @@
+ serial converter device. This driver makes use of firmware
+ developed from scratch by Brian Warner.
+
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called keyspan_pda. If you want to compile it
+- as a module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called keyspan_pda.
+
+ config USB_SERIAL_OMNINET
+ tristate "USB ZyXEL omni.net LCD Plus Driver (EXPERIMENTAL)"
+@@ -431,10 +392,8 @@
+ help
+ Say Y here if you want to use a ZyXEL omni.net LCD ISDN TA.
+
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called omninet. If you want to compile it as a
+- module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called omninet.
+
+ config USB_EZUSB
+ bool
+Index: linux-2.6.0-test5/drivers/usb/serial/usb-serial.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/serial/usb-serial.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/serial/usb-serial.c 2003-09-27 11:38:33.250473544 +0800
+@@ -871,8 +871,10 @@
+
+ /* the ports are cleaned up and released in port_release() */
+ for (i = 0; i < serial->num_ports; ++i)
+- if (serial->port[i]->dev.parent != NULL)
++ if (serial->port[i]->dev.parent != NULL) {
+ device_unregister(&serial->port[i]->dev);
++ serial->port[i] = NULL;
++ }
+
+ /* If this is a "fake" port, we have to clean it up here, as it will
+ * not get cleaned up in port_release() as it was never registered with
+Index: linux-2.6.0-test5/drivers/usb/storage/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/storage/Kconfig 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/storage/Kconfig 2003-09-27 11:38:33.287467920 +0800
+@@ -15,10 +15,8 @@
+ similar devices. This driver may also be used for some cameras and
+ card readers.
+
+- This code is also available as a module ( = code which can be
+- inserted in and removed from the running kernel whenever you want).
+- The module will be called usb-storage. If you want to compile it
+- as a module, say M here and read <file:Documentation/modules.txt>.
++ To compile this driver as a module, say M here: the
++ module will be called usb-storage.
+
+ config USB_STORAGE_DEBUG
+ bool "USB Mass Storage verbose debug"
+Index: linux-2.6.0-test5/drivers/usb/storage/unusual_devs.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/storage/unusual_devs.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/storage/unusual_devs.h 2003-09-27 11:38:33.350458344 +0800
+@@ -289,7 +289,7 @@
+ UNUSUAL_DEV( 0x057b, 0x0000, 0x0000, 0x0299,
+ "Y-E Data",
+ "Flashbuster-U",
+- US_SC_UFI, US_PR_CB, NULL,
++ US_SC_DEVICE, US_PR_CB, NULL,
+ US_FL_SINGLE_LUN),
+
+ UNUSUAL_DEV( 0x057b, 0x0000, 0x0300, 0x9999,
+Index: linux-2.6.0-test5/drivers/video/asiliantfb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/asiliantfb.c 2003-09-27 11:38:18.464721320 +0800
++++ linux-2.6.0-test5/drivers/video/asiliantfb.c 2003-09-27 11:38:33.359456976 +0800
+@@ -0,0 +1,619 @@
++/*
++ * drivers/video/asiliantfb.c
++ * frame buffer driver for Asiliant 69000 chip
++ * Copyright (C) 2001-2003 Saito.K & Jeanne
++ *
++ * from driver/video/chipsfb.c and,
++ *
++ * drivers/video/asiliantfb.c -- frame buffer device for
++ * Asiliant 69030 chip (formerly Intel, formerly Chips & Technologies)
++ * Author: apc@agelectronics.co.uk
++ * Copyright (C) 2000 AG Electronics
++ * Note: the data sheets don't seem to be available from Asiliant.
++ * They are available by searching developer.intel.com, but are not otherwise
++ * linked to.
++ *
++ * This driver should be portable with minimal effort to the 69000 display
++ * chip, and to the twin-display mode of the 69030.
++ * Contains code from Thomas Hhenleitner <th@visuelle-maschinen.de> (thanks)
++ *
++ * Derived from the CT65550 driver chipsfb.c:
++ * Copyright (C) 1998 Paul Mackerras
++ * ...which was derived from the Powermac "chips" driver:
++ * Copyright (C) 1997 Fabio Riccardi.
++ * And from the frame buffer device for Open Firmware-initialized devices:
++ * Copyright (C) 1997 Geert Uytterhoeven.
++ *
++ * 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.
++ */
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/string.h>
++#include <linux/mm.h>
++#include <linux/tty.h>
++#include <linux/slab.h>
++#include <linux/vmalloc.h>
++#include <linux/delay.h>
++#include <linux/interrupt.h>
++#include <linux/fb.h>
++#include <linux/init.h>
++#include <linux/pci.h>
++#include <asm/io.h>
++
++static struct fb_info asiliantfb_info;
++
++/* Built in clock of the 69030 */
++const unsigned Fref = 14318180;
++
++static u32 pseudo_palette[17];
++
++#define mmio_base (p->screen_base + 0x400000)
++
++#define mm_write_ind(num, val, ap, dp) do { \
++ writeb((num), mmio_base + (ap)); writeb((val), mmio_base + (dp)); \
++} while (0)
++
++static void mm_write_xr(struct fb_info *p, u8 reg, u8 data)
++{
++ mm_write_ind(reg, data, 0x7ac, 0x7ad);
++}
++#define write_xr(num, val) mm_write_xr(p, num, val)
++
++static void mm_write_fr(struct fb_info *p, u8 reg, u8 data)
++{
++ mm_write_ind(reg, data, 0x7a0, 0x7a1);
++}
++#define write_fr(num, val) mm_write_fr(p, num, val)
++
++static void mm_write_cr(struct fb_info *p, u8 reg, u8 data)
++{
++ mm_write_ind(reg, data, 0x7a8, 0x7a9);
++}
++#define write_cr(num, val) mm_write_cr(p, num, val)
++
++static void mm_write_gr(struct fb_info *p, u8 reg, u8 data)
++{
++ mm_write_ind(reg, data, 0x79c, 0x79d);
++}
++#define write_gr(num, val) mm_write_gr(p, num, val)
++
++static void mm_write_sr(struct fb_info *p, u8 reg, u8 data)
++{
++ mm_write_ind(reg, data, 0x788, 0x789);
++}
++#define write_sr(num, val) mm_write_sr(p, num, val)
++
++static void mm_write_ar(struct fb_info *p, u8 reg, u8 data)
++{
++ readb(mmio_base + 0x7b4);
++ mm_write_ind(reg, data, 0x780, 0x780);
++}
++#define write_ar(num, val) mm_write_ar(p, num, val)
++
++/*
++ * Exported functions
++ */
++int asiliantfb_init(void);
++
++static int asiliantfb_pci_init(struct pci_dev *dp, const struct pci_device_id *);
++static int asiliantfb_check_var(struct fb_var_screeninfo *var,
++ struct fb_info *info);
++static int asiliantfb_set_par(struct fb_info *info);
++static int asiliantfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
++ u_int transp, struct fb_info *info);
++
++static struct fb_ops asiliantfb_ops = {
++ .owner = THIS_MODULE,
++ .fb_check_var = asiliantfb_check_var,
++ .fb_set_par = asiliantfb_set_par,
++ .fb_setcolreg = asiliantfb_setcolreg,
++ .fb_fillrect = cfb_fillrect,
++ .fb_copyarea = cfb_copyarea,
++ .fb_imageblit = cfb_imageblit,
++ .fb_cursor = soft_cursor,
++};
++
++/* Calculate the ratios for the dot clocks without using a single long long
++ * value */
++static void asiliant_calc_dclk2(u32 *ppixclock, u8 *dclk2_m, u8 *dclk2_n, u8 *dclk2_div)
++{
++ unsigned pixclock = *ppixclock;
++ unsigned Ftarget = 1000000 * (1000000 / pixclock);
++ unsigned n;
++ unsigned best_error = 0xffffffff;
++ unsigned best_m = 0xffffffff,
++ best_n = 0xffffffff;
++ unsigned ratio;
++ unsigned remainder;
++ unsigned char divisor = 0;
++
++ /* Calculate the frequency required. This is hard enough. */
++ ratio = 1000000 / pixclock;
++ remainder = 1000000 % pixclock;
++ Ftarget = 1000000 * ratio + (1000000 * remainder) / pixclock;
++
++ while (Ftarget < 100000000) {
++ divisor += 0x10;
++ Ftarget <<= 1;
++ }
++
++ ratio = Ftarget / Fref;
++ remainder = Ftarget % Fref;
++
++ /* This expresses the constraint that 150kHz <= Fref/n <= 5Mhz,
++ * together with 3 <= n <= 257. */
++ for (n = 3; n <= 257; n++) {
++ unsigned m = n * ratio + (n * remainder) / Fref;
++
++ /* 3 <= m <= 257 */
++ if (m >= 3 && m <= 257) {
++ unsigned new_error = ((Ftarget * n) - (Fref * m)) >= 0 ?
++ ((Ftarget * n) - (Fref * m)) : ((Fref * m) - (Ftarget * n));
++ if (new_error < best_error) {
++ best_n = n;
++ best_m = m;
++ best_error = new_error;
++ }
++ }
++ /* But if VLD = 4, then 4m <= 1028 */
++ else if (m <= 1028) {
++ /* remember there are still only 8-bits of precision in m, so
++ * avoid over-optimistic error calculations */
++ unsigned new_error = ((Ftarget * n) - (Fref * (m & ~3))) >= 0 ?
++ ((Ftarget * n) - (Fref * (m & ~3))) : ((Fref * (m & ~3)) - (Ftarget * n));
++ if (new_error < best_error) {
++ best_n = n;
++ best_m = m;
++ best_error = new_error;
++ }
++ }
++ }
++ if (best_m > 257)
++ best_m >>= 2; /* divide m by 4, and leave VCO loop divide at 4 */
++ else
++ divisor |= 4; /* or set VCO loop divide to 1 */
++ *dclk2_m = best_m - 2;
++ *dclk2_n = best_n - 2;
++ *dclk2_div = divisor;
++ *ppixclock = pixclock;
++ return;
++}
++
++static void asiliant_set_timing(struct fb_info *p)
++{
++ unsigned hd = p->var.xres / 8;
++ unsigned hs = (p->var.xres + p->var.right_margin) / 8;
++ unsigned he = (p->var.xres + p->var.right_margin + p->var.hsync_len) / 8;
++ unsigned ht = (p->var.left_margin + p->var.xres + p->var.right_margin + p->var.hsync_len) / 8;
++ unsigned vd = p->var.yres;
++ unsigned vs = p->var.yres + p->var.lower_margin;
++ unsigned ve = p->var.yres + p->var.lower_margin + p->var.vsync_len;
++ unsigned vt = p->var.upper_margin + p->var.yres + p->var.lower_margin + p->var.vsync_len;
++ unsigned wd = (p->var.xres_virtual * ((p->var.bits_per_pixel+7)/8)) / 8;
++
++ if ((p->var.xres == 640) && (p->var.yres == 480) && (p->var.pixclock == 39722)) {
++ write_fr(0x01, 0x02); /* LCD */
++ } else {
++ write_fr(0x01, 0x01); /* CRT */
++ }
++
++ write_cr(0x11, (ve - 1) & 0x0f);
++ write_cr(0x00, (ht - 5) & 0xff);
++ write_cr(0x01, hd - 1);
++ write_cr(0x02, hd);
++ write_cr(0x03, ((ht - 1) & 0x1f) | 0x80);
++ write_cr(0x04, hs);
++ write_cr(0x05, (((ht - 1) & 0x20) <<2) | (he & 0x1f));
++ write_cr(0x3c, (ht - 1) & 0xc0);
++ write_cr(0x06, (vt - 2) & 0xff);
++ write_cr(0x30, (vt - 2) >> 8);
++ write_cr(0x07, 0x00);
++ write_cr(0x08, 0x00);
++ write_cr(0x09, 0x00);
++ write_cr(0x10, (vs - 1) & 0xff);
++ write_cr(0x32, ((vs - 1) >> 8) & 0xf);
++ write_cr(0x11, ((ve - 1) & 0x0f) | 0x80);
++ write_cr(0x12, (vd - 1) & 0xff);
++ write_cr(0x31, ((vd - 1) & 0xf00) >> 8);
++ write_cr(0x13, wd & 0xff);
++ write_cr(0x41, (wd & 0xf00) >> 8);
++ write_cr(0x15, (vs - 1) & 0xff);
++ write_cr(0x33, ((vs - 1) >> 8) & 0xf);
++ write_cr(0x38, ((ht - 5) & 0x100) >> 8);
++ write_cr(0x16, (vt - 1) & 0xff);
++ write_cr(0x18, 0x00);
++
++ if (p->var.xres == 640) {
++ writeb(0xc7, mmio_base + 0x784); /* set misc output reg */
++ } else {
++ writeb(0x07, mmio_base + 0x784); /* set misc output reg */
++ }
++}
++
++static int asiliantfb_check_var(struct fb_var_screeninfo *var,
++ struct fb_info *p)
++{
++ unsigned long Ftarget, ratio, remainder;
++
++ ratio = 1000000 / var->pixclock;
++ remainder = 1000000 % var->pixclock;
++ Ftarget = 1000000 * ratio + (1000000 * remainder) / var->pixclock;
++
++ /* First check the constraint that the maximum post-VCO divisor is 32,
++ * and the maximum Fvco is 220MHz */
++ if (Ftarget > 220000000 || Ftarget < 3125000) {
++ printk(KERN_ERR "asiliantfb dotclock must be between 3.125 and 220MHz\n");
++ return -ENXIO;
++ }
++ var->xres_virtual = var->xres;
++ var->yres_virtual = var->yres;
++
++ if (var->bits_per_pixel == 24) {
++ var->red.offset = 16;
++ var->green.offset = 8;
++ var->blue.offset = 0;
++ var->red.length = var->blue.length = var->green.length = 8;
++ } else if (var->bits_per_pixel == 16) {
++ switch (var->red.offset) {
++ case 11:
++ var->green.length = 6;
++ break;
++ case 10:
++ var->green.length = 5;
++ break;
++ default:
++ return -EINVAL;
++ }
++ var->green.offset = 5;
++ var->blue.offset = 0;
++ var->red.length = var->blue.length = 5;
++ } else if (var->bits_per_pixel == 8) {
++ var->red.offset = var->green.offset = var->blue.offset = 0;
++ var->red.length = var->green.length = var->blue.length = 8;
++ }
++ return 0;
++}
++
++static int asiliantfb_set_par(struct fb_info *p)
++{
++ u8 dclk2_m; /* Holds m-2 value for register */
++ u8 dclk2_n; /* Holds n-2 value for register */
++ u8 dclk2_div; /* Holds divisor bitmask */
++
++ /* Set pixclock */
++ asiliant_calc_dclk2(&p->var.pixclock, &dclk2_m, &dclk2_n, &dclk2_div);
++
++ /* Set color depth */
++ if (p->var.bits_per_pixel == 24) {
++ write_xr(0x81, 0x16); /* 24 bit packed color mode */
++ write_xr(0x82, 0x00); /* Disable palettes */
++ write_xr(0x20, 0x20); /* 24 bit blitter mode */
++ } else if (p->var.bits_per_pixel == 16) {
++ if (p->var.red.offset == 11)
++ write_xr(0x81, 0x15); /* 16 bit color mode */
++ else
++ write_xr(0x81, 0x14); /* 15 bit color mode */
++ write_xr(0x82, 0x00); /* Disable palettes */
++ write_xr(0x20, 0x10); /* 16 bit blitter mode */
++ } else if (p->var.bits_per_pixel == 8) {
++ write_xr(0x0a, 0x02); /* Linear */
++ write_xr(0x81, 0x12); /* 8 bit color mode */
++ write_xr(0x82, 0x00); /* Graphics gamma enable */
++ write_xr(0x20, 0x00); /* 8 bit blitter mode */
++ }
++ p->fix.line_length = p->var.xres * (p->var.bits_per_pixel >> 3);
++ p->fix.visual = (p->var.bits_per_pixel == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
++ write_xr(0xc4, dclk2_m);
++ write_xr(0xc5, dclk2_n);
++ write_xr(0xc7, dclk2_div);
++ /* Set up the CR registers */
++ asiliant_set_timing(p);
++ return 0;
++}
++
++static int asiliantfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
++ u_int transp, struct fb_info *p)
++{
++ if (regno > 255)
++ return 1;
++ red >>= 8;
++ green >>= 8;
++ blue >>= 8;
++
++ /* Set hardware palete */
++ writeb(regno, mmio_base + 0x790);
++ udelay(1);
++ writeb(red, mmio_base + 0x791);
++ writeb(green, mmio_base + 0x791);
++ writeb(blue, mmio_base + 0x791);
++
++ switch(p->var.bits_per_pixel) {
++ case 15:
++ if (regno < 16) {
++ ((u32 *)(p->pseudo_palette))[regno] =
++ ((red & 0xf8) << 7) |
++ ((green & 0xf8) << 2) |
++ ((blue & 0xf8) >> 3);
++ }
++ break;
++ case 16:
++ if (regno < 16) {
++ ((u32 *)(p->pseudo_palette))[regno] =
++ ((red & 0xf8) << 8) |
++ ((green & 0xfc) << 3) |
++ ((blue & 0xf8) >> 3);
++ }
++ break;
++ case 24:
++ if (regno < 24) {
++ ((u32 *)(p->pseudo_palette))[regno] =
++ (red << 16) |
++ (green << 8) |
++ (blue);
++ }
++ break;
++ }
++ return 0;
++}
++
++struct chips_init_reg {
++ unsigned char addr;
++ unsigned char data;
++};
++
++#define N_ELTS(x) (sizeof(x) / sizeof(x[0]))
++
++static struct chips_init_reg chips_init_sr[] =
++{
++ {0x00, 0x03}, /* Reset register */
++ {0x01, 0x01}, /* Clocking mode */
++ {0x02, 0x0f}, /* Plane mask */
++ {0x04, 0x0e} /* Memory mode */
++};
++
++static struct chips_init_reg chips_init_gr[] =
++{
++ {0x03, 0x00}, /* Data rotate */
++ {0x05, 0x00}, /* Graphics mode */
++ {0x06, 0x01}, /* Miscellaneous */
++ {0x08, 0x00} /* Bit mask */
++};
++
++static struct chips_init_reg chips_init_ar[] =
++{
++ {0x10, 0x01}, /* Mode control */
++ {0x11, 0x00}, /* Overscan */
++ {0x12, 0x0f}, /* Memory plane enable */
++ {0x13, 0x00} /* Horizontal pixel panning */
++};
++
++static struct chips_init_reg chips_init_cr[] =
++{
++ {0x0c, 0x00}, /* Start address high */
++ {0x0d, 0x00}, /* Start address low */
++ {0x40, 0x00}, /* Extended Start Address */
++ {0x41, 0x00}, /* Extended Start Address */
++ {0x14, 0x00}, /* Underline location */
++ {0x17, 0xe3}, /* CRT mode control */
++ {0x70, 0x00} /* Interlace control */
++};
++
++
++static struct chips_init_reg chips_init_fr[] =
++{
++ {0x01, 0x02},
++ {0x03, 0x08},
++ {0x08, 0xcc},
++ {0x0a, 0x08},
++ {0x18, 0x00},
++ {0x1e, 0x80},
++ {0x40, 0x83},
++ {0x41, 0x00},
++ {0x48, 0x13},
++ {0x4d, 0x60},
++ {0x4e, 0x0f},
++
++ {0x0b, 0x01},
++
++ {0x21, 0x51},
++ {0x22, 0x1d},
++ {0x23, 0x5f},
++ {0x20, 0x4f},
++ {0x34, 0x00},
++ {0x24, 0x51},
++ {0x25, 0x00},
++ {0x27, 0x0b},
++ {0x26, 0x00},
++ {0x37, 0x80},
++ {0x33, 0x0b},
++ {0x35, 0x11},
++ {0x36, 0x02},
++ {0x31, 0xea},
++ {0x32, 0x0c},
++ {0x30, 0xdf},
++ {0x10, 0x0c},
++ {0x11, 0xe0},
++ {0x12, 0x50},
++ {0x13, 0x00},
++ {0x16, 0x03},
++ {0x17, 0xbd},
++ {0x1a, 0x00},
++};
++
++
++static struct chips_init_reg chips_init_xr[] =
++{
++ {0xce, 0x00}, /* set default memory clock */
++ {0xcc, 200 }, /* MCLK ratio M */
++ {0xcd, 18 }, /* MCLK ratio N */
++ {0xce, 0x90}, /* MCLK divisor = 2 */
++
++ {0xc4, 209 },
++ {0xc5, 118 },
++ {0xc7, 32 },
++ {0xcf, 0x06},
++ {0x09, 0x01}, /* IO Control - CRT controller extensions */
++ {0x0a, 0x02}, /* Frame buffer mapping */
++ {0x0b, 0x01}, /* PCI burst write */
++ {0x40, 0x03}, /* Memory access control */
++ {0x80, 0x82}, /* Pixel pipeline configuration 0 */
++ {0x81, 0x12}, /* Pixel pipeline configuration 1 */
++ {0x82, 0x08}, /* Pixel pipeline configuration 2 */
++
++ {0xd0, 0x0f},
++ {0xd1, 0x01},
++};
++
++static void __init chips_hw_init(struct fb_info *p)
++{
++ int i;
++
++ for (i = 0; i < N_ELTS(chips_init_xr); ++i)
++ write_xr(chips_init_xr[i].addr, chips_init_xr[i].data);
++ write_xr(0x81, 0x12);
++ write_xr(0x82, 0x08);
++ write_xr(0x20, 0x00);
++ for (i = 0; i < N_ELTS(chips_init_sr); ++i)
++ write_sr(chips_init_sr[i].addr, chips_init_sr[i].data);
++ for (i = 0; i < N_ELTS(chips_init_gr); ++i)
++ write_gr(chips_init_gr[i].addr, chips_init_gr[i].data);
++ for (i = 0; i < N_ELTS(chips_init_ar); ++i)
++ write_ar(chips_init_ar[i].addr, chips_init_ar[i].data);
++ /* Enable video output in attribute index register */
++ writeb(0x20, mmio_base + 0x780);
++ for (i = 0; i < N_ELTS(chips_init_cr); ++i)
++ write_cr(chips_init_cr[i].addr, chips_init_cr[i].data);
++ for (i = 0; i < N_ELTS(chips_init_fr); ++i)
++ write_fr(chips_init_fr[i].addr, chips_init_fr[i].data);
++}
++
++static struct fb_fix_screeninfo asiliantfb_fix __initdata = {
++ .id = "Asiliant 69000",
++ .type = FB_TYPE_PACKED_PIXELS,
++ .visual = FB_VISUAL_PSEUDOCOLOR,
++ .accel = FB_ACCEL_NONE,
++ .line_length = 640,
++ .smem_len = 0x200000, /* 2MB */
++};
++
++static struct fb_var_screeninfo asiliantfb_var __initdata = {
++ .xres = 640,
++ .yres = 480,
++ .xres_virtual = 640,
++ .yres_virtual = 480,
++ .bits_per_pixel = 8,
++ .red = { .length = 8 },
++ .green = { .length = 8 },
++ .blue = { .length = 8 },
++ .height = -1,
++ .width = -1,
++ .vmode = FB_VMODE_NONINTERLACED,
++ .pixclock = 39722,
++ .left_margin = 48,
++ .right_margin = 16,
++ .upper_margin = 33,
++ .lower_margin = 10,
++ .hsync_len = 96,
++ .vsync_len = 2,
++};
++
++static void __init init_asiliant(struct fb_info *p, unsigned long addr)
++{
++ p->fix = asiliantfb_fix;
++ p->fix.smem_start = addr;
++ p->var = asiliantfb_var;
++ p->fbops = &asiliantfb_ops;
++ p->pseudo_palette = pseudo_palette;
++ p->flags = FBINFO_FLAG_DEFAULT;
++
++ fb_alloc_cmap(&p->cmap, 256, 0);
++
++ if (register_framebuffer(p) < 0) {
++ printk(KERN_ERR "C&T 69000 framebuffer failed to register\n");
++ return;
++ }
++
++ printk(KERN_INFO "fb%d: Asiliant 69000 frame buffer (%dK RAM detected)\n",
++ p->node, p->fix.smem_len / 1024);
++
++ writeb(0xff, mmio_base + 0x78c);
++ chips_hw_init(p);
++}
++
++static int __devinit
++asiliantfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent)
++{
++ struct fb_info *p = &asiliantfb_info;
++ unsigned long addr, size;
++
++ if ((dp->resource[0].flags & IORESOURCE_MEM) == 0)
++ return -ENODEV;
++ addr = pci_resource_start(dp, 0);
++ size = pci_resource_len(dp, 0);
++ if (addr == 0)
++ return -ENODEV;
++ if (p->screen_base != 0)
++ return -EBUSY;
++ if (!request_mem_region(addr, size, "asiliantfb"))
++ return -EBUSY;
++
++ p->screen_base = ioremap(addr, 0x800000);
++ if (p->screen_base == NULL) {
++ release_mem_region(addr, size);
++ return -ENOMEM;
++ }
++
++ pci_write_config_dword(dp, 4, 0x02800083);
++ writeb(3, addr + 0x400784);
++
++ init_asiliant(p, addr);
++
++ /* Clear the entire framebuffer */
++ memset(p->screen_base, 0, 0x200000);
++
++ pci_set_drvdata(dp, p);
++ return 0;
++}
++
++static void __devexit asiliantfb_remove(struct pci_dev *dp)
++{
++ struct fb_info *p = pci_get_drvdata(dp);
++
++ if (p != &asiliantfb_info || p->screen_base == NULL)
++ return;
++ unregister_framebuffer(p);
++ iounmap(p->screen_base);
++ p->screen_base = NULL;
++ release_mem_region(pci_resource_start(dp, 0), pci_resource_len(dp, 0));
++}
++
++static struct pci_device_id asiliantfb_pci_tbl[] __devinitdata = {
++ { PCI_VENDOR_ID_CT, PCI_DEVICE_ID_CT_69000, PCI_ANY_ID, PCI_ANY_ID },
++ { 0 }
++};
++
++MODULE_DEVICE_TABLE(pci, asiliantfb_pci_tbl);
++
++static struct pci_driver asiliantfb_driver = {
++ .name = "asiliantfb",
++ .id_table = asiliantfb_pci_tbl,
++ .probe = asiliantfb_pci_init,
++ .remove = __devexit_p(asiliantfb_remove),
++};
++
++int __init asiliantfb_init(void)
++{
++ return pci_module_init(&asiliantfb_driver);
++}
++
++static void __exit asiliantfb_exit(void)
++{
++ pci_unregister_driver(&asiliantfb_driver);
++}
++
++MODULE_LICENSE("GPL");
+Index: linux-2.6.0-test5/drivers/video/aty/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/aty/Makefile 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/aty/Makefile 2003-09-27 11:38:33.401450592 +0800
+@@ -4,4 +4,3 @@
+ atyfb-y := atyfb_base.o mach64_accel.o
+ atyfb-$(CONFIG_FB_ATY_GX) += mach64_gx.o
+ atyfb-$(CONFIG_FB_ATY_CT) += mach64_ct.o mach64_cursor.o
+-atyfb-objs := $(atyfb-y)
+Index: linux-2.6.0-test5/drivers/video/chipsfb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/chipsfb.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/chipsfb.c 2003-09-27 11:38:33.451442992 +0800
+@@ -85,7 +85,7 @@
+ /*
+ * Exported functions
+ */
+-int chips_init(void);
++int chipsfb_init(void);
+
+ static int chipsfb_pci_init(struct pci_dev *dp, const struct pci_device_id *);
+ static int chipsfb_check_var(struct fb_var_screeninfo *var,
+@@ -460,7 +460,7 @@
+ .remove = __devexit_p(chipsfb_remove),
+ };
+
+-int __init chips_init(void)
++int __init chipsfb_init(void)
+ {
+ return pci_module_init(&chipsfb_driver);
+ }
+Index: linux-2.6.0-test5/drivers/video/console/fbcon.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/console/fbcon.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/console/fbcon.c 2003-09-27 11:38:33.528431288 +0800
+@@ -195,8 +195,7 @@
+ {
+ struct fb_info *info = (struct fb_info *) private;
+
+- /* Test to see if the cursor is erased but still on */
+- if (!info || (info->cursor.rop == ROP_COPY))
++ if (!info)
+ return;
+ info->cursor.enable ^= 1;
+ info->fbops->fb_cursor(info, &info->cursor);
+@@ -226,8 +225,7 @@
+ struct fb_info *info = (struct fb_info *) dev_addr;
+
+ schedule_work(&info->queue);
+- cursor_timer.expires = jiffies + HZ / 5;
+- add_timer(&cursor_timer);
++ mod_timer(&cursor_timer, jiffies + HZ/5);
+ }
+
+ int __init fb_console_setup(char *this_opt)
+@@ -308,97 +306,6 @@
+ }
+
+ /*
+- * drawing helpers
+- */
+-static void putcs_unaligned(struct vc_data *vc, struct fb_info *info,
+- struct fb_image *image, int count,
+- const unsigned short *s)
+-{
+- unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
+- unsigned int width = (vc->vc_font.width + 7) >> 3;
+- unsigned int cellsize = vc->vc_font.height * width;
+- unsigned int maxcnt = info->pixmap.size/cellsize;
+- unsigned int shift_low = 0, mod = vc->vc_font.width % 8;
+- unsigned int shift_high = 8, size, pitch, cnt, k;
+- unsigned int buf_align = info->pixmap.buf_align - 1;
+- unsigned int scan_align = info->pixmap.scan_align - 1;
+- unsigned int idx = vc->vc_font.width >> 3;
+- u8 mask, *src, *dst, *dst0;
+-
+- while (count) {
+- if (count > maxcnt)
+- cnt = k = maxcnt;
+- else
+- cnt = k = count;
+-
+- image->width = vc->vc_font.width * cnt;
+- pitch = ((image->width + 7) >> 3) + scan_align;
+- pitch &= ~scan_align;
+- size = pitch * vc->vc_font.height + buf_align;
+- size &= ~buf_align;
+- dst0 = info->pixmap.addr + fb_get_buffer_offset(info, size);
+- image->data = dst0;
+- while (k--) {
+- src = vc->vc_font.data + (scr_readw(s++) & charmask)*
+- cellsize;
+- dst = dst0;
+- mask = (u8) (0xfff << shift_high);
+- move_buf_unaligned(info, dst, src, pitch, image->height,
+- mask, shift_high, shift_low, mod, idx);
+- shift_low += mod;
+- dst0 += (shift_low >= 8) ? width : width - 1;
+- shift_low &= 7;
+- shift_high = 8 - shift_low;
+- }
+- info->fbops->fb_imageblit(info, image);
+- image->dx += cnt * vc->vc_font.width;
+- count -= cnt;
+- atomic_dec(&info->pixmap.count);
+- smp_mb__after_atomic_dec();
+- }
+-}
+-
+-static void putcs_aligned(struct vc_data *vc, struct fb_info *info,
+- struct fb_image *image, int count,
+- const unsigned short *s)
+-{
+- unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
+- unsigned int width = vc->vc_font.width >> 3;
+- unsigned int cellsize = vc->vc_font.height * width;
+- unsigned int maxcnt = info->pixmap.size/cellsize;
+- unsigned int scan_align = info->pixmap.scan_align - 1;
+- unsigned int buf_align = info->pixmap.buf_align - 1;
+- unsigned int pitch, cnt, size, k;
+- u8 *src, *dst, *dst0;
+-
+- while (count) {
+- if (count > maxcnt)
+- cnt = k = maxcnt;
+- else
+- cnt = k = count;
+-
+- pitch = width * cnt + scan_align;
+- pitch &= ~scan_align;
+- size = pitch * vc->vc_font.height + buf_align;
+- size &= ~buf_align;
+- image->width = vc->vc_font.width * cnt;
+- dst0 = info->pixmap.addr + fb_get_buffer_offset(info, size);
+- image->data = dst0;
+- while (k--) {
+- src = vc->vc_font.data + (scr_readw(s++)&charmask)*cellsize;
+- dst = dst0;
+- move_buf_aligned(info, dst, src, pitch, width, image->height);
+- dst0 += width;
+- }
+- info->fbops->fb_imageblit(info, image);
+- image->dx += cnt * vc->vc_font.width;
+- count -= cnt;
+- atomic_dec(&info->pixmap.count);
+- smp_mb__after_atomic_dec();
+- }
+-}
+-
+-/*
+ * Accelerated handlers.
+ */
+ void accel_bmove(struct vc_data *vc, struct fb_info *info, int sy,
+@@ -432,48 +339,21 @@
+ info->fbops->fb_fillrect(info, ®ion);
+ }
+
+-static void accel_putc(struct vc_data *vc, struct fb_info *info,
+- int c, int ypos, int xpos)
++void accel_putcs(struct vc_data *vc, struct fb_info *info,
++ const unsigned short *s, int count, int yy, int xx)
+ {
+ unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
+ unsigned int width = (vc->vc_font.width + 7) >> 3;
++ unsigned int cellsize = vc->vc_font.height * width;
++ unsigned int maxcnt = info->pixmap.size/cellsize;
+ unsigned int scan_align = info->pixmap.scan_align - 1;
+ unsigned int buf_align = info->pixmap.buf_align - 1;
++ unsigned int shift_low = 0, mod = vc->vc_font.width % 8;
++ unsigned int shift_high = 8, pitch, cnt, size, k;
+ int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
+ int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
+- unsigned int size, pitch;
+- struct fb_image image;
+- u8 *src, *dst;
+-
+- image.dx = xpos * vc->vc_font.width;
+- image.dy = ypos * vc->vc_font.height;
+- image.width = vc->vc_font.width;
+- image.height = vc->vc_font.height;
+- image.fg_color = attr_fgcol(fgshift, c);
+- image.bg_color = attr_bgcol(bgshift, c);
+- image.depth = 1;
+-
+- pitch = width + scan_align;
+- pitch &= ~scan_align;
+- size = pitch * vc->vc_font.height;
+- size += buf_align;
+- size &= ~buf_align;
+- dst = info->pixmap.addr + fb_get_buffer_offset(info, size);
+- image.data = dst;
+- src = vc->vc_font.data + (c & charmask) * vc->vc_font.height * width;
+-
+- move_buf_aligned(info, dst, src, pitch, width, image.height);
+-
+- info->fbops->fb_imageblit(info, &image);
+- atomic_dec(&info->pixmap.count);
+- smp_mb__after_atomic_dec();
+-}
+-
+-void accel_putcs(struct vc_data *vc, struct fb_info *info,
+- const unsigned short *s, int count, int yy, int xx)
+-{
+- int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
+- int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
++ unsigned int idx = vc->vc_font.width >> 3;
++ u8 *src, *dst, *dst0, mask;
+ struct fb_image image;
+ u16 c = scr_readw(s);
+
+@@ -484,10 +364,44 @@
+ image.height = vc->vc_font.height;
+ image.depth = 1;
+
+- if (!(vc->vc_font.width & 7))
+- putcs_aligned(vc, info, &image, count, s);
+- else
+- putcs_unaligned(vc, info, &image, count, s);
++ while (count) {
++ if (count > maxcnt)
++ cnt = k = maxcnt;
++ else
++ cnt = k = count;
++
++ image.width = vc->vc_font.width * cnt;
++ pitch = ((image.width + 7) >> 3) + scan_align;
++ pitch &= ~scan_align;
++ size = pitch * vc->vc_font.height + buf_align;
++ size &= ~buf_align;
++ dst0 = fb_get_buffer_offset(info, &info->pixmap, size);
++ image.data = dst0;
++ while (k--) {
++ src = vc->vc_font.data + (scr_readw(s++) & charmask)*cellsize;
++ dst = dst0;
++
++ if (mod) {
++ mask = (u8) (0xfff << shift_high);
++ move_buf_unaligned(info, &info->pixmap, dst, src, pitch,
++ image.height, mask, shift_high,
++ shift_low, mod, idx);
++ shift_low += mod;
++ dst0 += (shift_low >= 8) ? width : width - 1;
++ shift_low &= 7;
++ shift_high = 8 - shift_low;
++ } else {
++ move_buf_aligned(info, &info->pixmap, dst, src, pitch, idx,
++ image.height);
++ dst0 += width;
++ }
++ }
++ info->fbops->fb_imageblit(info, &image);
++ image.dx += cnt * vc->vc_font.width;
++ count -= cnt;
++ atomic_dec(&info->pixmap.count);
++ smp_mb__after_atomic_dec();
++ }
+ }
+
+ void accel_clear_margins(struct vc_data *vc, struct fb_info *info,
+@@ -676,7 +590,7 @@
+ if (!info->queue.func) {
+ INIT_WORK(&info->queue, fb_flashcursor, info);
+
+- cursor_timer.expires = jiffies + HZ / 50;
++ cursor_timer.expires = jiffies + HZ / 5;
+ cursor_timer.data = (unsigned long ) info;
+ add_timer(&cursor_timer);
+ }
+@@ -728,15 +642,13 @@
+ static void fbcon_set_display(struct vc_data *vc, int init, int logo)
+ {
+ struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
++ int nr_rows, nr_cols, old_rows, old_cols, i, charcnt = 256;
+ struct display *p = &fb_display[vc->vc_num];
+- int nr_rows, nr_cols;
+- int old_rows, old_cols;
+ unsigned short *save = NULL, *r, *q;
+- int i, charcnt = 256;
+ struct font_desc *font;
+
+ if (vc->vc_num != fg_console || (info->flags & FBINFO_FLAG_MODULE) ||
+- info->fix.type == FB_TYPE_TEXT)
++ (info->fix.type == FB_TYPE_TEXT))
+ logo = 0;
+
+ info->var.xoffset = info->var.yoffset = p->yscroll = 0; /* reset wrap/pan */
+@@ -960,11 +872,19 @@
+ accel_clear(vc, info, real_y(p, sy), sx, height, width);
+ }
+
+-
+ static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos)
+ {
+ struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
++ unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
++ unsigned int scan_align = info->pixmap.scan_align - 1;
++ unsigned int buf_align = info->pixmap.buf_align - 1;
++ unsigned int width = (vc->vc_font.width + 7) >> 3;
++ int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
++ int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
+ struct display *p = &fb_display[vc->vc_num];
++ unsigned int size, pitch;
++ struct fb_image image;
++ u8 *src, *dst;
+
+ if (!info->fbops->fb_blank && console_blanked)
+ return;
+@@ -972,7 +892,31 @@
+ if (vt_cons[vc->vc_num]->vc_mode != KD_TEXT)
+ return;
+
+- accel_putc(vc, info, c, real_y(p, ypos), xpos);
++ image.dx = xpos * vc->vc_font.width;
++ image.dy = real_y(p, ypos) * vc->vc_font.height;
++ image.width = vc->vc_font.width;
++ image.height = vc->vc_font.height;
++ image.fg_color = attr_fgcol(fgshift, c);
++ image.bg_color = attr_bgcol(bgshift, c);
++ image.depth = 1;
++
++ src = vc->vc_font.data + (c & charmask) * vc->vc_font.height * width;
++
++ pitch = width + scan_align;
++ pitch &= ~scan_align;
++ size = pitch * vc->vc_font.height;
++ size += buf_align;
++ size &= ~buf_align;
++
++ dst = fb_get_buffer_offset(info, &info->pixmap, size);
++ image.data = dst;
++
++ move_buf_aligned(info, &info->pixmap, dst, src, pitch, width,
++ image.height);
++
++ info->fbops->fb_imageblit(info, &image);
++ atomic_dec(&info->pixmap.count);
++ smp_mb__after_atomic_dec();
+ }
+
+ static void fbcon_putcs(struct vc_data *vc, const unsigned short *s,
+@@ -994,12 +938,16 @@
+ {
+ struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
+ unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
++ unsigned int scan_align = info->sprite.scan_align - 1;
++ unsigned int buf_align = info->sprite.buf_align - 1;
+ int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
+ int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
+ struct display *p = &fb_display[vc->vc_num];
+- int w = (vc->vc_font.width + 7) >> 3, c;
+- int y = real_y(p, vc->vc_y);
++ int y = real_y(p, vc->vc_y), d_pitch, dsize;
++ int s_pitch = (vc->vc_font.width + 7) >> 3;
++ int size = s_pitch * vc->vc_font.height, c;
+ struct fb_cursor cursor;
++ u8 *src, *dst;
+
+ if (mode & CM_SOFTBACK) {
+ mode &= ~CM_SOFTBACK;
+@@ -1012,28 +960,24 @@
+ } else if (softback_lines)
+ fbcon_set_origin(vc);
+
+- c = scr_readw((u16 *) vc->vc_pos);
++ del_timer(&cursor_timer);
++ if (info->cursor.enable) {
++ info->cursor.enable = 0;
++ info->fbops->fb_cursor(info, &info->cursor);
++ }
+
+- cursor.image.data = vc->vc_font.data + ((c & charmask) * (w * vc->vc_font.height));
+- cursor.set = FB_CUR_SETCUR;
+- cursor.image.depth = 1;
+-
+- switch (mode) {
+- case CM_ERASE:
+- if (info->cursor.rop == ROP_XOR) {
+- info->cursor.enable = 0;
+- info->cursor.rop = ROP_COPY;
+- info->fbops->fb_cursor(info, &cursor);
+- }
+- break;
+- case CM_MOVE:
+- case CM_DRAW:
++ if (mode != CM_ERASE) {
++ memset(&cursor, 0, sizeof(struct fb_cursor));
+ info->cursor.enable = 1;
+-
++
++ c = scr_readw((u16 *) vc->vc_pos);
++
++ src = vc->vc_font.data + ((c & charmask) * size);
+ if (info->cursor.image.fg_color != attr_fgcol(fgshift, c) ||
+ info->cursor.image.bg_color != attr_bgcol(bgshift, c)) {
+ cursor.image.fg_color = attr_fgcol(fgshift, c);
+ cursor.image.bg_color = attr_bgcol(bgshift, c);
++ cursor.image.depth = 1;
+ cursor.set |= FB_CUR_SETCMAP;
+ }
+
+@@ -1056,18 +1000,29 @@
+ cursor.set |= FB_CUR_SETHOT;
+ }
+
++ src = vc->vc_font.data + ((c & charmask) * size);
++
++ d_pitch = (s_pitch + scan_align) & ~scan_align;
++ dsize = d_pitch * vc->vc_font.height + buf_align;
++ dsize &= ~buf_align;
++ dst = fb_get_buffer_offset(info, &info->sprite, dsize);
++ move_buf_aligned(info, &info->sprite, dst, src, d_pitch, s_pitch, vc->vc_font.height);
++ info->cursor.image.data = dst;
++ cursor.set |= FB_CUR_SETSHAPE;
++
+ if ((cursor.set & FB_CUR_SETSIZE) || ((vc->vc_cursor_type & 0x0f) != p->cursor_shape)) {
+- char *mask = kmalloc(w*vc->vc_font.height, GFP_ATOMIC);
+- int cur_height, size, i = 0;
++ char *mask = kmalloc(dsize, GFP_ATOMIC);
++ int cur_height, i, j, k;
+
+ if (!mask) return;
+-
++
++ memset(mask, 0, dsize);
++
+ if (info->cursor.mask)
+ kfree(info->cursor.mask);
+ info->cursor.mask = mask;
+
+ p->cursor_shape = vc->vc_cursor_type & 0x0f;
+- cursor.set |= FB_CUR_SETSHAPE;
+
+ switch (vc->vc_cursor_type & 0x0f) {
+ case CUR_NONE:
+@@ -1090,17 +1045,19 @@
+ cur_height = vc->vc_font.height;
+ break;
+ }
+- size = (vc->vc_font.height - cur_height) * w;
+- while (size--)
+- mask[i++] = 0;
+- size = cur_height * w;
+- while (size--)
+- mask[i++] = 0xff;
++ i = (vc->vc_font.height - cur_height) * d_pitch;
++ for (j = 0; j < cur_height; j++) {
++ for (k = 0; k < s_pitch; k++)
++ mask[i++] = 0xff;
++ i += (d_pitch - s_pitch);
++ }
+ }
+ info->cursor.rop = ROP_XOR;
+ info->fbops->fb_cursor(info, &cursor);
++ atomic_dec(&info->sprite.count);
++ smp_mb__after_atomic_dec();
++ mod_timer(&cursor_timer, jiffies + HZ/5);
+ vbl_cursor_cnt = CURSOR_DRAW_DELAY;
+- break;
+ }
+ }
+
+@@ -1826,8 +1783,10 @@
+ vc->vc_font.height = h;
+ if (vc->vc_hi_font_mask && cnt == 256) {
+ vc->vc_hi_font_mask = 0;
+- if (vc->vc_can_do_color)
++ if (vc->vc_can_do_color) {
+ vc->vc_complement_mask >>= 1;
++ vc->vc_s_complement_mask >>= 1;
++ }
+
+ /* ++Edmund: reorder the attribute bits */
+ if (vc->vc_can_do_color) {
+@@ -1847,8 +1806,10 @@
+ }
+ } else if (!vc->vc_hi_font_mask && cnt == 512) {
+ vc->vc_hi_font_mask = 0x100;
+- if (vc->vc_can_do_color)
++ if (vc->vc_can_do_color) {
+ vc->vc_complement_mask <<= 1;
++ vc->vc_s_complement_mask <<= 1;
++ }
+
+ /* ++Edmund: reorder the attribute bits */
+ {
+Index: linux-2.6.0-test5/drivers/video/console/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/console/Makefile 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/console/Makefile 2003-09-27 11:38:33.536430072 +0800
+@@ -3,18 +3,16 @@
+ # Rewritten to use lists instead of if-statements.
+
+ # Font handling
+-font-objs := fonts.o
++font-y := fonts.o
+
+-font-objs-$(CONFIG_FONT_SUN8x16) += font_sun8x16.o
+-font-objs-$(CONFIG_FONT_SUN12x22) += font_sun12x22.o
+-font-objs-$(CONFIG_FONT_8x8) += font_8x8.o
+-font-objs-$(CONFIG_FONT_8x16) += font_8x16.o
+-font-objs-$(CONFIG_FONT_6x11) += font_6x11.o
+-font-objs-$(CONFIG_FONT_PEARL_8x8) += font_pearl_8x8.o
+-font-objs-$(CONFIG_FONT_ACORN_8x8) += font_acorn_8x8.o
+-font-objs-$(CONFIG_FONT_MINI_4x6) += font_mini_4x6.o
+-
+-font-objs += $(font-objs-y)
++font-$(CONFIG_FONT_SUN8x16) += font_sun8x16.o
++font-$(CONFIG_FONT_SUN12x22) += font_sun12x22.o
++font-$(CONFIG_FONT_8x8) += font_8x8.o
++font-$(CONFIG_FONT_8x16) += font_8x16.o
++font-$(CONFIG_FONT_6x11) += font_6x11.o
++font-$(CONFIG_FONT_PEARL_8x8) += font_pearl_8x8.o
++font-$(CONFIG_FONT_ACORN_8x8) += font_acorn_8x8.o
++font-$(CONFIG_FONT_MINI_4x6) += font_mini_4x6.o
+
+ # Each configuration option enables a list of files.
+
+@@ -31,8 +29,11 @@
+ # Files generated that shall be removed upon make clean
+ clean-files := promcon_tbl.c
+
+-$(obj)/promcon_tbl.c: $(src)/prom.uni
+- $(objtree)/scripts/conmakehash $< | \
++quiet_cmd_promtbl = GEN $@
++ cmd_promtbl = scripts/conmakehash $< | \
+ sed -e '/#include <[^>]*>/p' -e 's/types/init/' \
+ -e 's/dfont\(_uni.*\]\)/promfont\1 __initdata/' > $@
+
++$(obj)/promcon_tbl.c: $(src)/prom.uni
++ $(call cmd,promtbl)
++
+Index: linux-2.6.0-test5/drivers/video/controlfb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/controlfb.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/controlfb.c 2003-09-27 11:38:33.589422016 +0800
+@@ -136,8 +136,8 @@
+ /*
+ * inititialization
+ */
+-int control_init(void);
+-void control_setup(char *);
++int controlfb_init(void);
++void controlfb_setup(char *);
+
+ /******************** Prototypes for internal functions **********************/
+
+@@ -553,7 +553,7 @@
+ /*
+ * Called from fbmem.c for probing & initializing
+ */
+-int __init control_init(void)
++int __init controlfb_init(void)
+ {
+ struct device_node *dp;
+
+@@ -1057,7 +1057,7 @@
+ /*
+ * Parse user speficied options (`video=controlfb:')
+ */
+-void __init control_setup(char *options)
++void __init controlfb_setup(char *options)
+ {
+ char *this_opt;
+
+Index: linux-2.6.0-test5/drivers/video/epson1355fb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/epson1355fb.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/epson1355fb.c 2003-09-27 11:38:33.653412288 +0800
+@@ -1,541 +1,714 @@
+ /*
+- * linux/drivers/video/epson1355fb.c
+- * -- Support for the Epson SED1355 LCD/CRT controller
++ * linux/drivers/video/epson1355fb.c -- Epson S1D13505 frame buffer for 2.5.
+ *
+- * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
++ * Epson Research S1D13505 Embedded RAMDAC LCD/CRT Controller
++ * (previously known as SED1355)
+ *
+- * based on linux/drivers/video/skeletonfb.c, which was
++ * Cf. http://www.erd.epson.com/vdc/html/S1D13505.html
++ *
++ *
++ * Copyright (C) Hewlett-Packard Company. All rights reserved.
++ *
++ * Written by Christopher Hoover <ch@hpl.hp.com>
++ *
++ * Adapted from:
++ *
++ * linux/drivers/video/skeletonfb.c
++ * Modified to new api Jan 2001 by James Simmons (jsimmons@transvirtual.com)
+ * Created 28 Dec 1997 by Geert Uytterhoeven
+ *
++ * linux/drivers/video/epson1355fb.c (2.4 driver)
++ * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
++ *
+ * 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.
+- */
+-/* TODO (roughly in order of priority):
+- * 16 bpp support
+- * crt support
+- * hw cursor support
+- * SwivelView
++ * License. See the file COPYING in the main directory of this archive for
++ * more details.
++ *
++ *
++ * Noteworthy Issues
++ * -----------------
++ *
++ * This driver is complicated by the fact that this is a 16-bit chip
++ * and, on at least one platform (ceiva), we can only do 16-bit reads
++ * and writes to the framebuffer. We hide this from user space
++ * except in the case of mmap().
++ *
++ *
++ * To Do
++ * -----
++ *
++ * - Test 8-bit pseudocolor mode
++ * - Allow setting bpp, virtual resolution
++ * - Implement horizontal panning
++ * - (maybe) Implement hardware cursor
+ */
+
+-#include <asm/io.h>
+-#include <linux/config.h>
+-#include <linux/delay.h>
+-#include <linux/errno.h>
+-#include <linux/fb.h>
+-#include <linux/init.h>
+-#include <linux/kernel.h>
+-#include <linux/slab.h>
+-#include <linux/mm.h>
+ #include <linux/module.h>
+-#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
+ #include <linux/string.h>
++#include <linux/mm.h>
+ #include <linux/tty.h>
+-#include <video/fbcon-cfb8.h>
+-#include <video/fbcon-mfb.h>
+-#include <video/fbcon.h>
+-
+-/* Register defines. The docs don't seem to provide nice mnemonic names
+- * so I made them up myself ... */
+-
+-#define E1355_PANEL 0x02
+-#define E1355_DISPLAY 0x0D
+-#define E1355_MISC 0x1B
+-#define E1355_GPIO 0x20
+-#define E1355_LUT_INDEX 0x24
+-#define E1355_LUT_DATA 0x26
++#include <linux/slab.h>
++#include <linux/delay.h>
++#include <linux/fb.h>
++#include <linux/init.h>
++#include <linux/ioport.h>
++#include <asm/types.h>
++#include <asm/io.h>
++#include <asm/uaccess.h>
++
++#include <video/epson1355.h>
++
++static struct fb_info info;
++
++static struct epson1355fb_par {
++ unsigned long reg_addr;
++} par;
++
++static u32 pseudo_palette[16];
++
++/* ------------------------------------------------------------------------- */
+
+ #ifdef CONFIG_SUPERH
+-#define E1355_REG_BASE CONFIG_E1355_REG_BASE
+-#define E1355_FB_BASE CONFIG_E1355_FB_BASE
+
+-static inline u8 e1355_read_reg(int index)
++static inline u8 epson1355_read_reg(int index)
+ {
+- return ctrl_inb(E1355_REG_BASE + index);
++ return ctrl_inb(par.reg_addr + index);
+ }
+
+-static inline void e1355_write_reg(u8 data, int index)
++static inline void epson1355_write_reg(u8 data, int index)
+ {
+- ctrl_outb(data, E1355_REG_BASE + index);
++ ctrl_outb(data, par.reg_addr + index);
+ }
+
+-static inline u16 e1355_read_reg16(int index)
++#elif defined(CONFIG_ARM)
++
++# ifdef CONFIG_ARCH_CEIVA
++# include <asm/arch/hardware.h>
++# define EPSON1355FB_BASE_PHYS (CEIVA_PHYS_SED1355)
++# endif
++
++static inline u8 epson1355_read_reg(int index)
+ {
+- return e1355_read_reg(index) + (e1355_read_reg(index+1) << 8);
++ return __raw_readb(par.reg_addr + index);
+ }
+
+-static inline void e1355_write_reg16(u16 data, int index)
++static inline void epson1355_write_reg(u8 data, int index)
+ {
+- e1355_write_reg((data&0xff), index);
+- e1355_write_reg(((data>>8)&0xff), index + 1);
++ __raw_writeb(data, par.reg_addr + index);
+ }
++
+ #else
+-#error unknown architecture
++# error "no architecture-specific epson1355_{read,write}_reg"
+ #endif
+
+-struct e1355fb_info {
+- struct fb_info_gen gen;
+-};
+-
+-static int current_par_valid = 0;
+-static struct display disp;
++#ifndef EPSON1355FB_BASE_PHYS
++# error "EPSON1355FB_BASE_PHYS is not defined"
++#endif
+
+-static struct fb_var_screeninfo default_var;
++#define EPSON1355FB_REGS_OFS (0)
++#define EPSON1355FB_REGS_PHYS (EPSON1355FB_BASE_PHYS + EPSON1355FB_REGS_OFS)
++#define EPSON1355FB_REGS_LEN (64)
+
+-int e1355fb_init(void);
+-int e1355fb_setup(char*);
+-static int e1355_encode_var(struct fb_var_screeninfo *var, const void *par,
+- struct fb_info_gen *info);
+-/* ------------------- chipset specific functions -------------------------- */
++#define EPSON1355FB_FB_OFS (0x00200000)
++#define EPSON1355FB_FB_PHYS (EPSON1355FB_BASE_PHYS + EPSON1355FB_FB_OFS)
++#define EPSON1355FB_FB_LEN (2 * 1024 * 1024)
+
++/* ------------------------------------------------------------------------- */
+
+-static void disable_hw_cursor(void)
++static inline u16 epson1355_read_reg16(int index)
+ {
+- u8 curs;
++ u8 lo = epson1355_read_reg(index);
++ u8 hi = epson1355_read_reg(index + 1);
+
+- curs = e1355_read_reg(0x27);
+- curs &= ~0xc0;
+- e1355_write_reg(curs, 0x27);
++ return (hi << 8) | lo;
+ }
+
+-static void e1355_detect(void)
++static inline void epson1355_write_reg16(u16 data, int index)
+ {
+- u8 rev;
++ u8 lo = data & 0xff;
++ u8 hi = (data >> 8) & 0xff;
+
+- e1355_write_reg(0x00, E1355_MISC);
++ epson1355_write_reg(lo, index);
++ epson1355_write_reg(hi, index + 1);
++}
+
+- rev = e1355_read_reg(0x00);
++static inline u32 epson1355_read_reg20(int index)
++{
++ u8 b0 = epson1355_read_reg(index);
++ u8 b1 = epson1355_read_reg(index + 1);
++ u8 b2 = epson1355_read_reg(index + 2);
+
+- if ((rev & 0xfc) != 0x0c) {
+- printk(KERN_WARNING "Epson 1355 not detected\n");
+- }
++ return (b2 & 0x0f) << 16 | (b1 << 8) | b0;
++}
+
+- /* XXX */
+- disable_hw_cursor();
++static inline void epson1355_write_reg20(u32 data, int index)
++{
++ u8 b0 = data & 0xff;
++ u8 b1 = (data >> 8) & 0xff;
++ u8 b2 = (data >> 16) & 0x0f;
+
+- e1355_encode_var(&default_var, NULL, NULL);
++ epson1355_write_reg(b0, index);
++ epson1355_write_reg(b1, index + 1);
++ epson1355_write_reg(b2, index + 2);
+ }
+
+-struct e1355_par {
+- u32 xres;
+- u32 yres;
++/* ------------------------------------------------------------------------- */
+
+- int bpp;
+- int mem_bpp;
++static void set_lut(u8 index, u8 r, u8 g, u8 b)
++{
++ epson1355_write_reg(index, REG_LUT_ADDR);
++ epson1355_write_reg(r, REG_LUT_DATA);
++ epson1355_write_reg(g, REG_LUT_DATA);
++ epson1355_write_reg(b, REG_LUT_DATA);
++}
+
+- u32 panel_xres;
+- u32 panel_yres;
+-
+- int panel_width;
+- int panel_ymul;
+-};
+
+-static int e1355_encode_fix(struct fb_fix_screeninfo *fix,
+- const void *raw_par,
+- struct fb_info_gen *info)
+-{
+- const struct e1355_par *par = raw_par;
+-
+- memset(fix, 0, sizeof *fix);
+-
+- fix->type= FB_TYPE_PACKED_PIXELS;
++/**
++ * epson1355fb_setcolreg - sets a color register.
++ * @regno: Which register in the CLUT we are programming
++ * @red: The red value which can be up to 16 bits wide
++ * @green: The green value which can be up to 16 bits wide
++ * @blue: The blue value which can be up to 16 bits wide.
++ * @transp: If supported the alpha value which can be up to 16 bits wide.
++ * @info: frame buffer info structure
++ *
++ * Returns negative errno on error, or zero on success.
++ */
++static int epson1355fb_setcolreg(unsigned regno, unsigned r, unsigned g,
++ unsigned b, unsigned transp,
++ struct fb_info *info)
++{
++ if (info->var.grayscale)
++ r = g = b = (19595 * r + 38470 * g + 7471 * b) >> 16;
++
++ switch (info->fix.visual) {
++ case FB_VISUAL_TRUECOLOR:
++ if (regno >= 16)
++ return -EINVAL;
+
+- if (!par)
+- BUG();
++ ((u32 *) info->pseudo_palette)[regno] =
++ (r & 0xf800) | (g & 0xfc00) >> 5 | (b & 0xf800) >> 11;
+
+- if (par->bpp == 1) {
+- fix->visual = FB_VISUAL_MONO10;
+- } else if (par->bpp <= 8) {
+- fix->visual = FB_VISUAL_PSEUDOCOLOR;
+- } else {
+- fix->visual = FB_VISUAL_TRUECOLOR;
+- }
++ break;
++ case FB_VISUAL_PSEUDOCOLOR:
++ if (regno >= 256)
++ return -EINVAL;
+
+- return 0;
+-}
++ set_lut(regno, r >> 8, g >> 8, b >> 8);
+
+-static int e1355_set_bpp(struct e1355_par *par, int bpp)
+-{
+- int code;
+- u8 disp;
+- u16 bytes_per_line;
+-
+- switch(bpp) {
+- case 1:
+- code = 0; break;
+- case 2:
+- code = 1; break;
+- case 4:
+- code = 2; break;
+- case 8:
+- code = 3; break;
+- case 16:
+- code = 5; break;
++ break;
+ default:
+- return -EINVAL; break;
++ return -ENOSYS;
+ }
+-
+- disp = e1355_read_reg(E1355_DISPLAY);
+- disp &= ~0x1c;
+- disp |= code << 2;
+- e1355_write_reg(disp, E1355_DISPLAY);
+-
+- bytes_per_line = (par->xres * bpp) >> 3;
+-
+- e1355_write_reg16(bytes_per_line, 0x16);
+-
+- par->bpp = bpp;
+-
+ return 0;
+ }
+-
+-static int e1355_decode_var(const struct fb_var_screeninfo *var,
+- void *raw_par,
+- struct fb_info_gen *info)
++
++/* ------------------------------------------------------------------------- */
++
++/**
++ * epson1355fb_pan_display - Pans the display.
++ * @var: frame buffer variable screen structure
++ * @info: frame buffer structure that represents a single frame buffer
++ *
++ * Pan (or wrap, depending on the `vmode' field) the display using the
++ * `xoffset' and `yoffset' fields of the `var' structure.
++ * If the values don't fit, return -EINVAL.
++ *
++ * Returns negative errno on error, or zero on success.
++ */
++static int epson1355fb_pan_display(struct fb_var_screeninfo *var,
++ struct fb_info *info)
+ {
+- struct e1355_par *par = raw_par;
+- int ret;
++ u32 start;
+
+- if (!par)
+- BUG();
++ if (var->xoffset != 0) /* not yet ... */
++ return -EINVAL;
+
+- /*
+- * Don't allow setting any of these yet: xres and yres don't
+- * make sense for LCD panels; xres_virtual and yres_virtual
+- * should be supported fine by our hardware though.
+- */
+- if (var->xres != par->xres ||
+- var->yres != par->yres ||
+- var->xres != var->xres_virtual ||
+- var->yres != var->yres_virtual ||
+- var->xoffset != 0 ||
+- var->yoffset != 0)
++ if (var->yoffset + info->var.yres > info->var.yres_virtual)
+ return -EINVAL;
+
+- if(var->bits_per_pixel != par->bpp) {
+- ret = e1355_set_bpp(par, var->bits_per_pixel);
++ start = (info->fix.line_length >> 1) * var->yoffset;
+
+- if (ret)
+- goto out_err;
+- }
+-
+- return 0;
++ epson1355_write_reg20(start, REG_SCRN1_DISP_START_ADDR0);
+
+- out_err:
+- return ret;
++ return 0;
+ }
+
+-static void dump_panel_data(void)
++/* ------------------------------------------------------------------------- */
++
++static void lcd_enable(int enable)
+ {
+- u8 panel = e1355_read_reg(E1355_PANEL);
+- int width[2][4] = { { 4, 8, 16, -1 }, { 9, 12, 16, -1 } };
++ u8 mode = epson1355_read_reg(REG_DISPLAY_MODE);
+
+- printk("%s %s %s panel, width %d bits\n",
+- panel & 2 ? "dual" : "single",
+- panel & 4 ? "color" : "mono",
+- panel & 1 ? "TFT" : "passive",
+- width[panel&1][(panel>>4)&3]);
++ if (enable)
++ mode |= 1;
++ else
++ mode &= ~1;
+
+- printk("resolution %d x %d\n",
+- (e1355_read_reg(0x04) + 1) * 8,
+- ((e1355_read_reg16(0x08) + 1) * (1 + ((panel & 3) == 2))));
++ epson1355_write_reg(mode, REG_DISPLAY_MODE);
+ }
+
+-static int e1355_bpp_to_var(int bpp, struct fb_var_screeninfo *var)
++#if defined(CONFIG_ARCH_CEIVA)
++static void backlight_enable(int enable)
+ {
+- switch(bpp) {
+- case 1:
+- case 2:
+- case 4:
+- case 8:
+- var->bits_per_pixel = bpp;
+- var->red.offset = var->green.offset = var->blue.offset = 0;
+- var->red.length = var->green.length = var->blue.length = bpp;
++ /* ### this should be protected by a spinlock ... */
++ u8 pddr = clps_readb(PDDR);
++ if (enable)
++ pddr |= (1 << 5);
++ else
++ pddr &= ~(1 << 5);
++ clps_writeb(pddr, PDDR);
++}
++#else
++static void backlight_enable(int enable)
++{
++}
++#endif
++
++
++/**
++ * epson1355fb_blank - blanks the display.
++ * @blank_mode: the blank mode we want.
++ * @info: frame buffer structure that represents a single frame buffer
++ *
++ * Blank the screen if blank_mode != 0, else unblank. Return 0 if
++ * blanking succeeded, != 0 if un-/blanking failed due to e.g. a
++ * video mode which doesn't support it. Implements VESA suspend
++ * and powerdown modes on hardware that supports disabling hsync/vsync:
++ * blank_mode == 2: suspend vsync
++ * blank_mode == 3: suspend hsync
++ * blank_mode == 4: powerdown
++ *
++ * Returns negative errno on error, or zero on success.
++ *
++ */
++static int epson1355fb_blank(int blank_mode, struct fb_info *info)
++{
++ switch (blank_mode) {
++ case VESA_NO_BLANKING:
++ lcd_enable(1);
++ backlight_enable(1);
+ break;
+- case 16:
+- var->bits_per_pixel = 16;
+- var->red.offset = 11;
+- var->red.length = 5;
+- var->green.offset = 5;
+- var->green.length = 6;
+- var->blue.offset = 0;
+- var->blue.length = 5;
++ case VESA_VSYNC_SUSPEND:
++ case VESA_HSYNC_SUSPEND:
++ backlight_enable(0);
+ break;
++ case VESA_POWERDOWN:
++ backlight_enable(0);
++ lcd_enable(0);
++ break;
++ default:
++ return -EINVAL;
+ }
+-
+ return 0;
+ }
+
+-static int e1355_encode_var(struct fb_var_screeninfo *var, const void *raw_par,
+- struct fb_info_gen *info)
++/* ------------------------------------------------------------------------- */
++
++/*
++ * We can't use the cfb generic routines, as we have to limit
++ * ourselves to 16-bit or 8-bit loads and stores to this 16-bit
++ * chip.
++ */
++
++static inline void epson1355fb_fb_writel(unsigned long v, unsigned long *a)
+ {
+- u8 panel, display;
+- u32 xres, xres_virtual, yres;
+- static int width[2][4] = { { 4, 8, 16, -1 }, { 9, 12, 16, -1 } };
+- static int bpp_tab[8] = { 1, 2, 4, 8, 15, 16 };
+- int bpp, hw_bpp;
+- int is_color, is_dual, is_tft;
+- int lcd_enabled, crt_enabled;
++ u16 *p = (u16 *) a;
++ u16 l = v & 0xffff;
++ u16 h = v >> 16;
+
+- panel = e1355_read_reg(E1355_PANEL);
+- display = e1355_read_reg(E1355_DISPLAY);
++ fb_writew(l, p);
++ fb_writew(h, p + 1);
++}
+
+- is_color = (panel & 0x04) != 0;
+- is_dual = (panel & 0x02) != 0;
+- is_tft = (panel & 0x01) != 0;
++static inline unsigned long epson1355fb_fb_readl(const unsigned long *a)
++{
++ const u16 *p = (u16 *) a;
++ u16 l = fb_readw(p);
++ u16 h = fb_readw(p + 1);
+
+- bpp = bpp_tab[(display>>2)&7];
+- e1355_bpp_to_var(bpp, var);
++ return (h << 16) | l;
++}
+
+- crt_enabled = (display & 0x02) != 0;
+- lcd_enabled = (display & 0x02) != 0;
++#define FB_READL epson1355fb_fb_readl
++#define FB_WRITEL epson1355fb_fb_writel
+
+- hw_bpp = width[is_tft][(panel>>4)&3];
++/* ------------------------------------------------------------------------- */
+
+- xres = e1355_read_reg(0x04) + 1;
+- yres = e1355_read_reg16(0x08) + 1;
+-
+- xres *= 8;
+- /* talk about weird hardware .. */
+- yres *= (is_dual && !crt_enabled) ? 2 : 1;
+-
+- xres_virtual = e1355_read_reg16(0x16);
+- /* it's in 2-byte words initially */
+- xres_virtual *= 16;
+- xres_virtual /= var->bits_per_pixel;
++static inline unsigned long copy_from_user16(void *to, const void *from,
++ unsigned long n)
++{
++ u16 *dst = (u16 *) to;
++ u16 *src = (u16 *) from;
+
+- var->xres = xres;
+- var->yres = yres;
+- var->xres_virtual = xres_virtual;
+- var->yres_virtual = yres;
++ if (!access_ok(VERIFY_READ, from, n))
++ return n;
+
+- var->xoffset = var->yoffset = 0;
++ while (n > 1) {
++ u16 v;
++ if (__get_user(v, src))
++ return n;
+
+- var->grayscale = !is_color;
+-
+- return 0;
+-}
++ fb_writew(v, dst);
+
+-#define is_dual(panel) (((panel)&3)==2)
++ src++, dst++;
++ n -= 2;
++ }
+
+-static void get_panel_data(struct e1355_par *par)
+-{
+- u8 panel;
+- int width[2][4] = { { 4, 8, 16, -1 }, { 9, 12, 16, -1 } };
++ if (n) {
++ u8 v;
+
+- panel = e1355_read_reg(E1355_PANEL);
++ if (__get_user(v, ((u8 *) src)))
++ return n;
+
+- par->panel_width = width[panel&1][(panel>>4)&3];
+- par->panel_xres = (e1355_read_reg(0x04) + 1) * 8;
+- par->panel_ymul = is_dual(panel) ? 2 : 1;
+- par->panel_yres = ((e1355_read_reg16(0x08) + 1)
+- * par->panel_ymul);
++ fb_writeb(v, dst);
++ }
++ return 0;
+ }
+
+-static void e1355_get_par(void *raw_par, struct fb_info_gen *info)
++static inline unsigned long copy_to_user16(void *to, const void *from,
++ unsigned long n)
+ {
+- struct e1355_par *par = raw_par;
++ u16 *dst = (u16 *) to;
++ u16 *src = (u16 *) from;
+
+- get_panel_data(par);
+-}
++ if (!access_ok(VERIFY_WRITE, to, n))
++ return n;
+
+-static void e1355_set_par(const void *par, struct fb_info_gen *info)
+-{
+-}
++ while (n > 1) {
++ u16 v = fb_readw(src);
+
+-static int e1355_getcolreg(unsigned regno, unsigned *red, unsigned *green,
+- unsigned *blue, unsigned *transp,
+- struct fb_info *info)
+-{
+- u8 r, g, b;
++ if (__put_user(v, dst))
++ return n;
+
+- e1355_write_reg(regno, E1355_LUT_INDEX);
+- r = e1355_read_reg(E1355_LUT_DATA);
+- g = e1355_read_reg(E1355_LUT_DATA);
+- b = e1355_read_reg(E1355_LUT_DATA);
++ src++, dst++;
++ n -= 2;
++ }
+
+- *red = r << 8;
+- *green = g << 8;
+- *blue = b << 8;
++ if (n) {
++ u8 v = fb_readb(src);
+
++ if (__put_user(v, ((u8 *) dst)))
++ return n;
++ }
+ return 0;
+ }
+
+-static int e1355fb_setcolreg(unsigned regno, unsigned red, unsigned green,
+- unsigned blue, unsigned transp,
+- struct fb_info *info)
+-{
+- u8 r = (red >> 8) & 0xf0;
+- u8 g = (green>>8) & 0xf0;
+- u8 b = (blue>> 8) & 0xf0;
+-
+- e1355_write_reg(regno, E1355_LUT_INDEX);
+- e1355_write_reg(r, E1355_LUT_DATA);
+- e1355_write_reg(g, E1355_LUT_DATA);
+- e1355_write_reg(b, E1355_LUT_DATA);
+-
+- return 0;
+-}
+
+-static int e1355_pan_display(const struct fb_var_screeninfo *var,
+- struct fb_info_gen *info)
++static ssize_t
++epson1355fb_read(struct file *file, char *buf, size_t count, loff_t * ppos)
+ {
+- BUG();
+-
+- return -EINVAL;
++ unsigned long p = *ppos;
++
++ /* from fbmem.c except for our own copy_*_user */
++ if (p >= info.fix.smem_len)
++ return 0;
++ if (count >= info.fix.smem_len)
++ count = info.fix.smem_len;
++ if (count + p > info.fix.smem_len)
++ count = info.fix.smem_len - p;
++
++ if (count) {
++ char *base_addr;
++
++ base_addr = info.screen_base;
++ count -= copy_to_user16(buf, base_addr + p, count);
++ if (!count)
++ return -EFAULT;
++ *ppos += count;
++ }
++ return count;
+ }
+
+-/*
+- * The AERO_HACKS parts disable/enable the backlight on the Compaq Aero 8000.
+- * I'm not sure they aren't dangerous to the hardware, so be warned.
+- */
+-#undef AERO_HACKS
++static ssize_t
++epson1355fb_write(struct file *file, const char *buf,
++ size_t count, loff_t * ppos)
++{
++ unsigned long p = *ppos;
++ int err;
++
++ /* from fbmem.c except for our own copy_*_user */
++ if (p > info.fix.smem_len)
++ return -ENOSPC;
++ if (count >= info.fix.smem_len)
++ count = info.fix.smem_len;
++ err = 0;
++ if (count + p > info.fix.smem_len) {
++ count = info.fix.smem_len - p;
++ err = -ENOSPC;
++ }
+
+-static int e1355_blank(int blank_mode, struct fb_info_gen *info)
+-{
+- u8 disp;
++ if (count) {
++ char *base_addr;
+
+- switch (blank_mode) {
+- case VESA_NO_BLANKING:
+- disp = e1355_read_reg(E1355_DISPLAY);
+- disp |= 1;
+- e1355_write_reg(disp, E1355_DISPLAY);
+-
+-#ifdef AERO_HACKS
+- e1355_write_reg(0x6, 0x20);
+-#endif
+- break;
++ base_addr = info.screen_base;
++ count -= copy_from_user16(base_addr + p, buf, count);
++ *ppos += count;
++ err = -EFAULT;
++ }
++ if (count)
++ return count;
++ return err;
++}
++
++/* ------------------------------------------------------------------------- */
++
++static struct fb_ops epson1355fb_fbops = {
++ .owner = THIS_MODULE,
++ .fb_setcolreg = epson1355fb_setcolreg,
++ .fb_pan_display = epson1355fb_pan_display,
++ .fb_blank = epson1355fb_blank,
++ .fb_fillrect = cfb_fillrect,
++ .fb_copyarea = cfb_copyarea,
++ .fb_imageblit = cfb_imageblit,
++ .fb_read = epson1355fb_read,
++ .fb_write = epson1355fb_write,
++ .fb_cursor = soft_cursor,
++};
+
+- case VESA_VSYNC_SUSPEND:
+- case VESA_HSYNC_SUSPEND:
+- case VESA_POWERDOWN:
+- disp = e1355_read_reg(E1355_DISPLAY);
+- disp &= ~1;
+- e1355_write_reg(disp, E1355_DISPLAY);
++/* ------------------------------------------------------------------------- */
+
+-#ifdef AERO_HACKS
+- e1355_write_reg(0x0, 0x20);
+-#endif
+- break;
++static __init unsigned int get_fb_size(struct fb_info *info)
++{
++ unsigned int size = 2 * 1024 * 1024;
++ char *p = info->screen_base;
+
+- default:
+- return -EINVAL;
+- }
++ /* the 512k framebuffer is aliased at start + 0x80000 * n */
++ fb_writeb(1, p);
++ fb_writeb(0, p + 0x80000);
++ if (!fb_readb(p))
++ size = 512 * 1024;
+
+- return 0;
++ fb_writeb(0, p);
++
++ return size;
+ }
+
+-static struct display_switch e1355_dispsw;
++static int epson1355_width_tab[2][4] __initdata =
++ { {4, 8, 16, -1}, {9, 12, 16, -1} };
++static int epson1355_bpp_tab[8] __initdata = { 1, 2, 4, 8, 15, 16 };
+
+-static void e1355_set_disp(const void *unused, struct display *disp,
+- struct fb_info_gen *info)
++static void __init fetch_hw_state(struct fb_info *info)
+ {
+- struct display_switch *d;
++ struct fb_var_screeninfo *var = &info->var;
++ struct fb_fix_screeninfo *fix = &info->fix;
++ u8 panel, display;
++ u16 offset;
++ u32 xres, yres;
++ u32 xres_virtual, yres_virtual;
++ int bpp, lcd_bpp;
++ int is_color, is_dual, is_tft;
++ int lcd_enabled, crt_enabled;
++
++ fix->type = FB_TYPE_PACKED_PIXELS;
+
+- disp->dispsw = &e1355_dispsw;
+-
+- switch(disp->var.bits_per_pixel) {
+-#ifdef FBCON_HAS_MFB
+- case 1:
+- d = &fbcon_mfb; break;
+-#endif
+-#ifdef FBCON_HAS_CFB8
++ display = epson1355_read_reg(REG_DISPLAY_MODE);
++ bpp = epson1355_bpp_tab[(display >> 2) & 7];
++
++ switch (bpp) {
+ case 8:
+- d = &fbcon_cfb8; break;
+-#endif
++ fix->visual = FB_VISUAL_PSEUDOCOLOR;
++ var->bits_per_pixel = 8;
++ var->red.offset = var->green.offset = var->blue.offset = 0;
++ var->red.length = var->green.length = var->blue.length = 8;
++ break;
++ case 16:
++ /* 5-6-5 RGB */
++ fix->visual = FB_VISUAL_TRUECOLOR;
++ var->bits_per_pixel = 16;
++ var->red.offset = 11;
++ var->red.length = 5;
++ var->green.offset = 5;
++ var->green.length = 6;
++ var->blue.offset = 0;
++ var->blue.length = 5;
++ break;
+ default:
+- BUG(); break;
++ BUG();
+ }
+
+- memcpy(&e1355_dispsw, d, sizeof *d);
++ if (fix->visual == FB_VISUAL_TRUECOLOR) {
++ info->pseudo_palette = &pseudo_palette;
++ fb_alloc_cmap(&(info->cmap), 16, 0);
++ } else
++ fb_alloc_cmap(&(info->cmap), 1 << bpp, 0);
++
++ panel = epson1355_read_reg(REG_PANEL_TYPE);
++ is_color = (panel & 0x04) != 0;
++ is_dual = (panel & 0x02) != 0;
++ is_tft = (panel & 0x01) != 0;
++ crt_enabled = (display & 0x02) != 0;
++ lcd_enabled = (display & 0x01) != 0;
++ lcd_bpp = epson1355_width_tab[is_tft][(panel >> 4) & 3];
++
++ xres = (epson1355_read_reg(REG_HORZ_DISP_WIDTH) + 1) * 8;
++ yres = (epson1355_read_reg16(REG_VERT_DISP_HEIGHT0) + 1) *
++ ((is_dual && !crt_enabled) ? 2 : 1);
++ offset = epson1355_read_reg16(REG_MEM_ADDR_OFFSET0) & 0x7ff;
++ xres_virtual = offset * 16 / bpp;
++ yres_virtual = fix->smem_len / (offset * 2);
++
++ var->xres = xres;
++ var->yres = yres;
++ var->xres_virtual = xres_virtual;
++ var->yres_virtual = yres_virtual;
++ var->xoffset = var->yoffset = 0;
+
+- /* reading is terribly slow for us */
+-#if 0 /* XXX: need to work out why this doesn't work */
+- e1355_dispsw.bmove = fbcon_redraw_bmove;
++ fix->line_length = offset * 2;
++
++ fix->xpanstep = 0; /* no pan yet */
++ fix->ypanstep = 1;
++ fix->ywrapstep = 0;
++ fix->accel = FB_ACCEL_NONE;
++
++ var->grayscale = !is_color;
++
++#ifdef DEBUG
++ printk(KERN_INFO
++ "epson1355fb: xres=%d, yres=%d, "
++ "is_color=%d, is_dual=%d, is_tft=%d\n",
++ xres, yres, is_color, is_dual, is_tft);
++ printk(KERN_INFO
++ "epson1355fb: bpp=%d, lcd_bpp=%d, "
++ "crt_enabled=%d, lcd_enabled=%d\n",
++ bpp, lcd_bpp, crt_enabled, lcd_enabled);
+ #endif
+ }
+
+-/* ------------ Interfaces to hardware functions ------------ */
+
++static void clearfb16(struct fb_info *info)
++{
++ u16 *dst = (u16 *) info->screen_base;
++ unsigned long n = info->fix.smem_len;
+
+-struct fbgen_hwswitch e1355_switch = {
+- .detect = e1355_detect,
+- .encode_fix = e1355_encode_fix,
+- .decode_var = e1355_decode_var,
+- .encode_var = e1355_encode_var,
+- .get_par = e1355_get_par,
+- .set_par = e1355_set_par,
+- .getcolreg = e1355_getcolreg,
+- .pan_display = e1355_pan_display,
+- .blank = e1355_blank,
+- .set_disp = e1355_set_disp,
+-};
++ while (n > 1) {
++ fb_writew(0, dst);
++ dst++, n -= 2;
++ }
+
++ if (n)
++ fb_writeb(0, dst);
++}
+
+-/* ------------ Hardware Independent Functions ------------ */
++static void epson1355fb_deinit(void);
+
++int __init epson1355fb_init(void)
++{
++ u8 revision;
++ int rc = 0;
+
+-static struct fb_ops e1355fb_ops = {
+- .owner = THIS_MODULE,
+- .fb_get_fix = fbgen_get_fix,
+- .fb_get_var = fbgen_get_var,
+- .fb_set_var = fbgen_set_var,
+- .fb_get_cmap = fbgen_get_cmap,
+- .fb_set_cmap = gen_set_cmap,
+- .fb_setcolreg = e1355fb_setcolreg,
+- .fb_pan_display =fbgen_pan_display,
+- .fb_blank = fbgen_blank,
+-};
++ if (!request_mem_region
++ (EPSON1355FB_REGS_PHYS, EPSON1355FB_REGS_LEN,
++ "S1D13505 registers")) {
++ printk(KERN_ERR "epson1355fb: unable to reserve "
++ "registers at 0x%0x\n", EPSON1355FB_REGS_PHYS);
++ rc = -EBUSY;
++ goto bail;
++ }
+
+-static struct e1355fb_info fb_info;
++ if (!request_mem_region(EPSON1355FB_FB_PHYS, EPSON1355FB_FB_LEN,
++ "S1D13505 framebuffer")) {
++ printk(KERN_ERR "epson1355fb: unable to reserve "
++ "framebuffer at 0x%0x\n", EPSON1355FB_FB_PHYS);
++ rc = -EBUSY;
++ goto bail;
++ }
++
++ par.reg_addr = (unsigned long)
++ ioremap(EPSON1355FB_REGS_PHYS, EPSON1355FB_REGS_LEN);
++ if (!par.reg_addr) {
++ printk(KERN_ERR "epson1355fb: unable to map registers\n");
++ rc = -ENOMEM;
++ goto bail;
++ }
++
++ info.screen_base =
++ ioremap(EPSON1355FB_FB_PHYS, EPSON1355FB_FB_LEN);
++ if (!info.screen_base) {
++ printk(KERN_ERR
++ "epson1355fb: unable to map framebuffer\n");
++ rc = -ENOMEM;
++ goto bail;
++ }
++
++ revision = epson1355_read_reg(REG_REVISION_CODE);
++ if ((revision >> 2) != 3) {
++ printk(KERN_INFO "epson1355fb: epson1355 not found\n");
++ rc = -ENODEV;
++ goto bail;
++ }
++
++ info.fix.mmio_start = EPSON1355FB_REGS_PHYS;
++ info.fix.mmio_len = EPSON1355FB_REGS_LEN;
++ info.fix.smem_start = EPSON1355FB_FB_PHYS;
++ info.fix.smem_len = get_fb_size(&info);
++
++ printk(KERN_INFO
++ "epson1355fb: regs mapped at 0x%lx, fb %d KiB mapped at 0x%p\n",
++ par.reg_addr, info.fix.smem_len / 1024, info.screen_base);
++
++ strcpy(info.fix.id, "S1D13505");
++ info.par = ∥
++ info.node = NODEV;
++ info.fbops = &epson1355fb_fbops;
++ info.flags = FBINFO_FLAG_DEFAULT;
++
++ /* we expect the boot loader to have initialized the chip
++ with appropriate parameters from which we can determinte
++ the flavor of lcd panel attached */
++ fetch_hw_state(&info);
++
++ /* turn this puppy on ... */
++ clearfb16(&info);
++ backlight_enable(1);
++ lcd_enable(1);
++
++ if (register_framebuffer(&info) < 0) {
++ rc = -EINVAL;
++ goto bail;
++ }
++
++ printk(KERN_INFO "fb%d: %s frame buffer device\n",
++ minor(info.node), info.fix.id);
+
+-int __init e1355fb_setup(char *str)
+-{
+ return 0;
++
++ bail:
++ epson1355fb_deinit();
++ return rc;
+ }
+
+-int __init e1355fb_init(void)
++static void epson1355fb_deinit(void)
+ {
+- fb_info.gen.fbhw = &e1355_switch;
+- fb_info.gen.fbhw->detect();
+- strcpy(fb_info.gen.info.modename, "SED1355");
+- fb_info.gen.info.changevar = NULL;
+- fb_info.gen.info.fbops = &e1355fb_ops;
+- fb_info.gen.info.screen_base = (void *)E1355_FB_BASE;
+- fb_info.gen.currcon = -1;
+- fb_info.gen.info.disp = &disp;
+- fb_info.gen.parsize = sizeof(struct e1355_par);
+- fb_info.gen.info.switch_con = &fbgen_switch;
+- fb_info.gen.info.updatevar = &fbgen_update_var;
+- fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT;
+- /* This should give a reasonable default video mode */
+- fbgen_get_var(&disp.var, -1, &fb_info.gen.info);
+- fbgen_do_set_var(&disp.var, 1, &fb_info.gen);
+- fbgen_set_disp(-1, &fb_info.gen);
+- if (disp.var.bits_per_pixel > 1)
+- do_install_cmap(0, &fb_info.gen);
+- if (register_framebuffer(&fb_info.gen.info) < 0)
+- return -EINVAL;
+- printk(KERN_INFO "fb%d: %s frame buffer device\n", fb_info.gen.info.node,
+- fb_info.gen.info.modename);
++ fb_dealloc_cmap(&info.cmap);
+
+- return 0;
++ if (info.screen_base)
++ iounmap(info.screen_base);
++ if (par.reg_addr)
++ iounmap((void *) par.reg_addr);
++
++ release_mem_region(EPSON1355FB_FB_PHYS, EPSON1355FB_FB_LEN);
++ release_mem_region(EPSON1355FB_REGS_PHYS, EPSON1355FB_REGS_LEN);
+ }
+
++static void __exit epson1355fb_cleanup(void)
++{
++ backlight_enable(0);
++ lcd_enable(0);
+
+- /*
+- * Cleanup
+- */
+-
+-void e1355fb_cleanup(struct fb_info *info)
+-{
+- /*
+- * If your driver supports multiple boards, you should unregister and
+- * clean up all instances.
+- */
+-
+- unregister_framebuffer(info);
+- /* ... */
++ unregister_framebuffer(&info);
++ epson1355fb_deinit();
+ }
+
++/* ------------------------------------------------------------------------- */
++
++#ifdef MODULE
++module_init(epson1355fb_init);
++#endif
++module_exit(epson1355fb_cleanup);
++
++MODULE_AUTHOR("Christopher Hoover <ch@hpl.hp.com>");
++MODULE_DESCRIPTION("Framebuffer driver for Epson S1D13505");
+ MODULE_LICENSE("GPL");
+Index: linux-2.6.0-test5/drivers/video/fbmem.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/fbmem.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/fbmem.c 2003-09-27 11:38:33.721401952 +0800
+@@ -25,7 +25,6 @@
+ #include <linux/mman.h>
+ #include <linux/tty.h>
+ #include <linux/init.h>
+-#include <linux/linux_logo.h>
+ #include <linux/proc_fs.h>
+ #ifdef CONFIG_KMOD
+ #include <linux/kmod.h>
+@@ -102,13 +101,13 @@
+ extern int matroxfb_init(void);
+ extern int matroxfb_setup(char*);
+ extern int hpfb_init(void);
+-extern int control_init(void);
+-extern int control_setup(char*);
+-extern int platinum_init(void);
+-extern int platinum_setup(char*);
++extern int controlfb_init(void);
++extern int controlfb_setup(char*);
++extern int platinumfb_init(void);
++extern int platinumfb_setup(char*);
+ extern int valkyriefb_init(void);
+ extern int valkyriefb_setup(char*);
+-extern int chips_init(void);
++extern int chipsfb_init(void);
+ extern int g364fb_init(void);
+ extern int sa1100fb_init(void);
+ extern int fm2fb_init(void);
+@@ -135,14 +134,14 @@
+ extern int tx3912fb_setup(char*);
+ extern int radeonfb_init(void);
+ extern int radeonfb_setup(char*);
+-extern int e1355fb_init(void);
+-extern int e1355fb_setup(char*);
++extern int epson1355fb_init(void);
+ extern int pvr2fb_init(void);
+ extern int pvr2fb_setup(char*);
+ extern int sstfb_init(void);
+ extern int sstfb_setup(char*);
+ extern int i810fb_init(void);
+ extern int i810fb_setup(char*);
++extern int asiliantfb_init(void);
+ extern int ffb_init(void);
+ extern int ffb_setup(char*);
+ extern int cg6_init(void);
+@@ -221,16 +220,16 @@
+ { "radeonfb", radeonfb_init, radeonfb_setup },
+ #endif
+ #ifdef CONFIG_FB_CONTROL
+- { "controlfb", control_init, control_setup },
++ { "controlfb", controlfb_init, controlfb_setup },
+ #endif
+ #ifdef CONFIG_FB_PLATINUM
+- { "platinumfb", platinum_init, platinum_setup },
++ { "platinumfb", platinumfb_init, platinumfb_setup },
+ #endif
+ #ifdef CONFIG_FB_VALKYRIE
+ { "valkyriefb", valkyriefb_init, valkyriefb_setup },
+ #endif
+ #ifdef CONFIG_FB_CT65550
+- { "chipsfb", chips_init, NULL },
++ { "chipsfb", chipsfb_init, NULL },
+ #endif
+ #ifdef CONFIG_FB_IMSTT
+ { "imsttfb", imsttfb_init, imsttfb_setup },
+@@ -342,8 +341,8 @@
+ #ifdef CONFIG_FB_TX3912
+ { "tx3912fb", tx3912fb_init, tx3912fb_setup },
+ #endif
+-#ifdef CONFIG_FB_E1355
+- { "e1355fb", e1355fb_init, e1355fb_setup },
++#ifdef CONFIG_FB_EPSON1355
++ { "s1d1355fb", epson1355fb_init, NULL },
+ #endif
+ #ifdef CONFIG_FB_PVR2
+ { "pvr2fb", pvr2fb_init, pvr2fb_setup },
+@@ -360,6 +359,10 @@
+ #ifdef CONFIG_FB_VOODOO1
+ { "sstfb", sstfb_init, sstfb_setup },
+ #endif
++#ifdef CONFIG_FB_ASILIANT
++ { "asiliantfb", asiliantfb_init, NULL },
++#endif
++
+ /*
+ * Generic drivers that don't use resource management (yet)
+ */
+@@ -409,20 +412,20 @@
+ memcpy(dst, src, size);
+ }
+
+-void move_buf_aligned(struct fb_info *info, u8 *dst, u8 *src, u32 d_pitch,
+- u32 s_pitch, u32 height)
++void move_buf_aligned(struct fb_info *info, struct fb_pixmap *buf, u8 *dst, u8 *src,
++ u32 d_pitch, u32 s_pitch, u32 height)
+ {
+ int i;
+
+ for (i = height; i--; ) {
+- info->pixmap.outbuf(src, dst, s_pitch);
++ buf->outbuf(src, dst, s_pitch);
+ src += s_pitch;
+ dst += d_pitch;
+ }
+ }
+
+-void move_buf_unaligned(struct fb_info *info, u8 *dst, u8 *src, u32 d_pitch,
+- u32 height, u32 mask, u32 shift_high, u32 shift_low,
++void move_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf, u8 *dst, u8 *src,
++ u32 d_pitch, u32 height, u32 mask, u32 shift_high, u32 shift_low,
+ u32 mod, u32 idx)
+ {
+ int i, j;
+@@ -430,21 +433,21 @@
+
+ for (i = height; i--; ) {
+ for (j = 0; j < idx; j++) {
+- tmp = info->pixmap.inbuf(dst+j);
++ tmp = buf->inbuf(dst+j);
+ tmp &= mask;
+ tmp |= *src >> shift_low;
+- info->pixmap.outbuf(&tmp, dst+j, 1);
++ buf->outbuf(&tmp, dst+j, 1);
+ tmp = *src << shift_high;
+- info->pixmap.outbuf(&tmp, dst+j+1, 1);
++ buf->outbuf(&tmp, dst+j+1, 1);
+ src++;
+ }
+- tmp = info->pixmap.inbuf(dst+idx);
++ tmp = buf->inbuf(dst+idx);
+ tmp &= mask;
+ tmp |= *src >> shift_low;
+- info->pixmap.outbuf(&tmp, dst+idx, 1);
++ buf->outbuf(&tmp, dst+idx, 1);
+ if (shift_high < mod) {
+ tmp = *src << shift_high;
+- info->pixmap.outbuf(&tmp, dst+idx+1, 1);
++ buf->outbuf(&tmp, dst+idx+1, 1);
+ }
+ src++;
+ dst += d_pitch;
+@@ -455,26 +458,29 @@
+ * we need to lock this section since fb_cursor
+ * may use fb_imageblit()
+ */
+-u32 fb_get_buffer_offset(struct fb_info *info, u32 size)
++char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size)
+ {
+- u32 align = info->pixmap.buf_align - 1;
++ u32 align = buf->buf_align - 1;
+ u32 offset, count = 1000;
++ char *addr = buf->addr;
+
+- spin_lock(&info->pixmap.lock);
+- offset = info->pixmap.offset + align;
+- offset &= ~align;
+- if (offset + size > info->pixmap.size) {
+- while (atomic_read(&info->pixmap.count) && count--);
+- if (info->fbops->fb_sync &&
+- info->pixmap.flags & FB_PIXMAP_SYNC)
+- info->fbops->fb_sync(info);
+- offset = 0;
++ spin_lock(&buf->lock);
++ if (!(buf->flags & FB_PIXMAP_IO)) {
++ offset = buf->offset + align;
++ offset &= ~align;
++ if (offset + size > buf->size) {
++ while (atomic_read(&buf->count) && count--);
++ if (info->fbops->fb_sync && (buf->flags & FB_PIXMAP_SYNC))
++ info->fbops->fb_sync(info);
++ offset = 0;
++ }
++ buf->offset = offset + size;
++ addr += offset;
+ }
+- info->pixmap.offset = offset + size;
+- atomic_inc(&info->pixmap.count);
++ atomic_inc(&buf->count);
+ smp_mb__after_atomic_inc();
+- spin_unlock(&info->pixmap.lock);
+- return offset;
++ spin_unlock(&buf->lock);
++ return addr;
+ }
+
+ #ifdef CONFIG_LOGO
+@@ -656,7 +662,7 @@
+ }
+
+ /* Return if no suitable logo was found */
+- fb_logo.logo = fb_find_logo(info->var.bits_per_pixel);
++ fb_logo.logo = find_logo(info->var.bits_per_pixel);
+
+ if (!fb_logo.logo || fb_logo.logo->height > info->var.yres) {
+ fb_logo.logo = NULL;
+@@ -726,8 +732,6 @@
+ x <= info->var.xres-fb_logo.logo->width; x += (fb_logo.logo->width + 8)) {
+ image.dx = x;
+ info->fbops->fb_imageblit(info, &image);
+- //atomic_dec(&info->pixmap.count);
+- //smp_mb__after_atomic_dec();
+ }
+
+ if (palette != NULL)
+@@ -1238,6 +1242,22 @@
+ fb_info->pixmap.inbuf = sys_inbuf;
+ spin_lock_init(&fb_info->pixmap.lock);
+
++ if (fb_info->sprite.addr == NULL) {
++ fb_info->sprite.addr = kmalloc(FBPIXMAPSIZE, GFP_KERNEL);
++ if (fb_info->sprite.addr) {
++ fb_info->sprite.size = FBPIXMAPSIZE;
++ fb_info->sprite.buf_align = 1;
++ fb_info->sprite.scan_align = 1;
++ fb_info->sprite.flags = FB_PIXMAP_IO;
++ }
++ }
++ fb_info->sprite.offset = 0;
++ if (fb_info->sprite.outbuf == NULL)
++ fb_info->sprite.outbuf = sys_outbuf;
++ if (fb_info->sprite.inbuf == NULL)
++ fb_info->sprite.inbuf = sys_inbuf;
++ spin_lock_init(&fb_info->sprite.lock);
++
+ registered_fb[i] = fb_info;
+
+ devfs_mk_cdev(MKDEV(FB_MAJOR, i),
+@@ -1371,6 +1391,33 @@
+
+ __setup("video=", video_setup);
+
++static int fbdev_dummy(void)
++{
++ return 0;
++}
++
++#define FBDEV_EMPTY (void *)fbdev_dummy
++
++const struct fb_ops dummy_fbdev = {
++ .fb_open = FBDEV_EMPTY,
++ .fb_release = FBDEV_EMPTY,
++ .fb_read = FBDEV_EMPTY,
++ .fb_write = FBDEV_EMPTY,
++ .fb_check_var = FBDEV_EMPTY,
++ .fb_set_par = FBDEV_EMPTY,
++ .fb_setcolreg = FBDEV_EMPTY,
++ .fb_blank = FBDEV_EMPTY,
++ .fb_pan_display = FBDEV_EMPTY,
++ .fb_fillrect = FBDEV_EMPTY,
++ .fb_copyarea = FBDEV_EMPTY,
++ .fb_imageblit = FBDEV_EMPTY,
++ .fb_cursor = FBDEV_EMPTY,
++ .fb_rotate = FBDEV_EMPTY,
++ .fb_sync = FBDEV_EMPTY,
++ .fb_ioctl = FBDEV_EMPTY,
++ .fb_mmap = FBDEV_EMPTY,
++};
++
+ /*
+ * Visible symbols for modules
+ */
+Index: linux-2.6.0-test5/drivers/video/g364fb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/g364fb.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/g364fb.c 2003-09-27 11:38:33.764395416 +0800
+@@ -127,20 +127,55 @@
+
+ int g364fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
+ {
++
++ /* Turn the cursor off before we start changing it. */
++ *(unsigned int *) CTLA_REG |= CURS_TOGGLE;
++
++ if (cursor->set & FB_CUR_SETHOT)
++ info->cursor.hot = cursor->hot;
+
+- switch (cursor->enable) {
+- case CM_ERASE:
+- *(unsigned int *) CTLA_REG |= CURS_TOGGLE;
+- break;
++ if (cursor->set & FB_CUR_SETPOS) {
++ unsigned int tmp;
+
+- case CM_MOVE:
+- case CM_DRAW:
+- *(unsigned int *) CTLA_REG &= ~CURS_TOGGLE;
+- *(unsigned int *) CURS_POS_REG =
+- ((x * fontwidth(p)) << 12) | ((y * fontheight(p)) -
+- info->var.yoffset);
+- break;
++ info->cursor.image.dx = cursor->image.dx;
++ info->cursor.image.dy = cursor->image.dy;
++
++ tmp = cursor->image.dy - info->var.yoffset;
++ tmp |= (cursor->image.dx - info->var.xoffset) << 12;
++
++ *(unsigned int *) CURS_POS_REG = tmp;
++ }
++
++ if (cursor->set & FB_CUR_SETSIZE) {
++ info->cursor.image.height = cursor->image.height;
++ info->cursor.image.width = cursor->image.width;
++
++ /* set the whole cursor to transparent */
++ for (i = 0; i < 512; i++)
++ *(unsigned short *) (CURS_PAT_REG + i * 8) = 0;
+ }
++
++ if (cursor->set & FB_CUR_SETCMAP) {
++ volatile unsigned int *curs_pal_ptr =
++ (volatile unsigned int *) CURS_PAL_REG;
++
++ /* setup cursor */
++ curs_pal_ptr[0] |= 0x00ffffff;
++ curs_pal_ptr[2] |= 0x00ffffff;
++ curs_pal_ptr[4] |= 0x00ffffff;
++ }
++
++ if (cursor->set & FB_CUR_SETSHAPE) {
++ /*
++ * switch the last two lines to cursor palette 3
++ * we assume here, that FONTSIZE_X is 8
++ */
++ *(unsigned short *) (CURS_PAT_REG + 14 * 64) = 0xffff;
++ *(unsigned short *) (CURS_PAT_REG + 15 * 64) = 0xffff;
++ }
++
++ if (info->cursor.enable)
++ *(unsigned int *) CTLA_REG &= ~CURS_TOGGLE;
+ return 0;
+ }
+
+@@ -196,10 +231,6 @@
+ */
+ int __init g364fb_init(void)
+ {
+- volatile unsigned int *pal_ptr =
+- (volatile unsigned int *) CLR_PAL_REG;
+- volatile unsigned int *curs_pal_ptr =
+- (volatile unsigned int *) CURS_PAL_REG;
+ int mem, i, j;
+
+ /* TBD: G364 detection */
+@@ -212,23 +243,6 @@
+ (*((volatile unsigned int *) VDISPLAY_REG) & 0x00ffffff) / 2;
+ *(volatile unsigned int *) CTLA_REG |= ENABLE_VTG;
+
+- /* setup cursor */
+- curs_pal_ptr[0] |= 0x00ffffff;
+- curs_pal_ptr[2] |= 0x00ffffff;
+- curs_pal_ptr[4] |= 0x00ffffff;
+-
+- /*
+- * first set the whole cursor to transparent
+- */
+- for (i = 0; i < 512; i++)
+- *(unsigned short *) (CURS_PAT_REG + i * 8) = 0;
+-
+- /*
+- * switch the last two lines to cursor palette 3
+- * we assume here, that FONTSIZE_X is 8
+- */
+- *(unsigned short *) (CURS_PAT_REG + 14 * 64) = 0xffff;
+- *(unsigned short *) (CURS_PAT_REG + 15 * 64) = 0xffff;
+ fb_var.xres_virtual = fbvar.xres;
+ fb_fix.line_length = (xres / 8) * fb_var.bits_per_pixel;
+ fb_fix.smem_start = 0x40000000; /* physical address */
+Index: linux-2.6.0-test5/drivers/video/i810/i810_main.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/i810/i810_main.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/i810/i810_main.c 2003-09-27 11:38:33.913372768 +0800
+@@ -57,7 +57,7 @@
+ #include "i810_main.h"
+
+ /* PCI */
+-static const char *i810_pci_list[] __initdata = {
++static const char *i810_pci_list[] __devinitdata = {
+ "Intel(R) 810 Framebuffer Device" ,
+ "Intel(R) 810-DC100 Framebuffer Device" ,
+ "Intel(R) 810E Framebuffer Device" ,
+@@ -66,7 +66,7 @@
+ "Intel(R) 815 (Internal Graphics with AGP) Framebuffer Device"
+ };
+
+-static struct pci_device_id i810fb_pci_tbl[] __initdata = {
++static struct pci_device_id i810fb_pci_tbl[] = {
+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG1,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG3,
+@@ -1456,7 +1456,7 @@
+ return 0;
+ }
+
+-static struct fb_ops i810fb_ops __initdata = {
++static struct fb_ops i810fb_ops __devinitdata = {
+ .owner = THIS_MODULE,
+ .fb_open = i810fb_open,
+ .fb_release = i810fb_release,
+@@ -1538,7 +1538,7 @@
+ * AGP resource allocation *
+ ***********************************************************************/
+
+-static void __init i810_fix_pointers(struct i810fb_par *par)
++static void __devinit i810_fix_pointers(struct i810fb_par *par)
+ {
+ par->fb.physical = par->aperture.physical+(par->fb.offset << 12);
+ par->fb.virtual = par->aperture.virtual+(par->fb.offset << 12);
+@@ -1550,7 +1550,7 @@
+ (par->cursor_heap.offset << 12);
+ }
+
+-static void __init i810_fix_offsets(struct i810fb_par *par)
++static void __devinit i810_fix_offsets(struct i810fb_par *par)
+ {
+ if (vram + 1 > par->aperture.size >> 20)
+ vram = (par->aperture.size >> 20) - 1;
+@@ -1570,7 +1570,7 @@
+ par->cursor_heap.size = 4096;
+ }
+
+-static int __init i810_alloc_agp_mem(struct fb_info *info)
++static int __devinit i810_alloc_agp_mem(struct fb_info *info)
+ {
+ struct i810fb_par *par = (struct i810fb_par *) info->par;
+ int size;
+@@ -1635,7 +1635,7 @@
+ * Sets the the user monitor's horizontal and vertical
+ * frequency limits
+ */
+-static void __init i810_init_monspecs(struct fb_info *info)
++static void __devinit i810_init_monspecs(struct fb_info *info)
+ {
+ if (!hsync1)
+ hsync1 = HFMIN;
+@@ -1663,7 +1663,7 @@
+ * @par: pointer to i810fb_par structure
+ * @info: pointer to current fb_info structure
+ */
+-static void __init i810_init_defaults(struct i810fb_par *par,
++static void __devinit i810_init_defaults(struct i810fb_par *par,
+ struct fb_info *info)
+ {
+ if (voffset)
+@@ -1707,7 +1707,7 @@
+ * i810_init_device - initialize device
+ * @par: pointer to i810fb_par structure
+ */
+-static void __init i810_init_device(struct i810fb_par *par)
++static void __devinit i810_init_device(struct i810fb_par *par)
+ {
+ u8 reg, *mmio = par->mmio_start_virtual;
+
+@@ -1726,7 +1726,7 @@
+ par->mem_freq = (reg) ? 133 : 100;
+ }
+
+-static int __init
++static int __devinit
+ i810_allocate_pci_resource(struct i810fb_par *par,
+ const struct pci_device_id *entry)
+ {
+@@ -1831,7 +1831,7 @@
+ return 0;
+ }
+
+-static int __init i810fb_init_pci (struct pci_dev *dev,
++static int __devinit i810fb_init_pci (struct pci_dev *dev,
+ const struct pci_device_id *entry)
+ {
+ struct fb_info *info;
+Index: linux-2.6.0-test5/drivers/video/i810/i810_main.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/i810/i810_main.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/i810/i810_main.h 2003-09-27 11:38:33.994360456 +0800
+@@ -14,7 +14,7 @@
+ #ifndef __I810_MAIN_H__
+ #define __I810_MAIN_H__
+
+-static int __init i810fb_init_pci (struct pci_dev *dev,
++static int __devinit i810fb_init_pci (struct pci_dev *dev,
+ const struct pci_device_id *entry);
+ static void __exit i810fb_remove_pci(struct pci_dev *dev);
+ static int i810fb_resume(struct pci_dev *dev);
+@@ -95,7 +95,7 @@
+
+ #ifdef CONFIG_MTRR
+ #define KERNEL_HAS_MTRR 1
+-static inline void __init set_mtrr(struct i810fb_par *par)
++static inline void __devinit set_mtrr(struct i810fb_par *par)
+ {
+ par->mtrr_reg = mtrr_add((u32) par->aperture.physical,
+ par->aperture.size, MTRR_TYPE_WRCOMB, 1);
+Index: linux-2.6.0-test5/drivers/video/i810/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/i810/Makefile 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/i810/Makefile 2003-09-27 11:38:34.010358024 +0800
+@@ -1,16 +1,9 @@
+ #
+ # Makefile for the Intel 810/815 framebuffer driver
+ #
+-# 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).
+-#
+-# Note 2! The CFLAGS definitions are now in the main makefile...
+-
+
+ obj-$(CONFIG_FB_I810) += i810fb.o
+
+-
+ i810fb-objs := i810_main.o i810_accel.o
+
+ ifdef CONFIG_FB_I810_GTF
+Index: linux-2.6.0-test5/drivers/video/imsttfb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/imsttfb.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/imsttfb.c 2003-09-27 11:38:34.121341152 +0800
+@@ -1495,6 +1495,8 @@
+ default:
+ printk(KERN_INFO "imsttfb: Device 0x%x unknown, "
+ "contact maintainer.\n", pdev->device);
++ release_mem_region(addr, size);
++ kfree(info);
+ return -ENODEV;
+ }
+
+Index: linux-2.6.0-test5/drivers/video/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/Kconfig 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/Kconfig 2003-09-27 11:38:34.169333856 +0800
+@@ -268,6 +268,10 @@
+ This is the frame buffer device driver for the Chips & Technologies
+ 65550 graphics chip in PowerBooks.
+
++config FB_ASILIANT
++ bool "Chips 69000 display support"
++ depends on FB && PCI
++
+ config FB_IMSTT
+ bool "IMS Twin Turbo display support"
+ depends on FB && PCI
+@@ -423,35 +427,15 @@
+ messages. Most people will want to say N here. If unsure, you will
+ also want to say N.
+
+-config FB_E1355
++config FB_EPSON1355
+ bool "Epson 1355 framebuffer support"
+- depends on FB && SUPERH
++ depends on FB && (SUPERH || ARCH_CEIVA)
+ help
+ Build in support for the SED1355 Epson Research Embedded RAMDAC
+ LCD/CRT Controller (since redesignated as the S1D13505) as a
+ framebuffer. Product specs at
+ <http://www.erd.epson.com/vdc/html/products.htm>.
+
+-config E1355_REG_BASE
+- hex "Register Base Address"
+- depends on FB_E1355
+- default "a8000000"
+- help
+- Epson SED1355/S1D13505 LCD/CRT controller register base address.
+- See the manuals at
+- <http://www.erd.epson.com/vdc/html/contents/S1D13505.htm> for
+- discussion.
+-
+-config E1355_FB_BASE
+- hex "Framebuffer Base Address"
+- depends on FB_E1355
+- default "a8200000"
+- help
+- Epson SED1355/S1D13505 LCD/CRT controller memory base address. See
+- the manuals at
+- <http://www.erd.epson.com/vdc/html/contents/S1D13505.htm> for
+- discussion.
+-
+ config FB_RIVA
+ tristate "nVidia Riva support"
+ depends on FB && PCI
+@@ -722,26 +706,40 @@
+ Say Y here to support booting a Rage XL without BIOS support.
+
+ config FB_SIS
+- tristate "SIS acceleration"
++ tristate "SiS acceleration"
+ depends on FB && PCI
+ help
+- This is the frame buffer device driver for the SiS 630 and 640 Super
+- Socket 7 UMA cards. Specs available at <http://www.sis.com.tw/>.
++ This is the frame buffer device driver for the SiS 300, 315 and Xabre
++ series VGA controller.
++
++ Specs available at <http://www.sis.com.tw/>.
++
++ See <http://www.winischhofer.net/linuxsisvga.shtml> for
++ documentation and updates.
++
++ The driver is also available as a module ( = code which can be
++ inserted and removed from the running kernel whenever you want). The
++ module will be called sisfb. If you want to compile it as a
++ module, say M here and read Documentation/modules.txt.
+
+ config FB_SIS_300
+- bool "SIS 630/540/730 support"
++ bool "SIS 300 series support"
+ depends on FB_SIS
+ help
+- This is the frame buffer device driver for the SiS 630 and related
+- Super Socket 7 UMA cards. Specs available at
+- <http://www.sis.com.tw/>.
++ This is the frame buffer device driver for the SiS 300 series VGA
++ controllers. This includes the 300, 540, 630, 730.
++ Documentation and updates available at
++ http://www.winischhofer.net/linuxsisvga.shtml
+
+ config FB_SIS_315
+- bool "SIS 315H/315 support"
++ bool "SIS 315/Xabre support"
+ depends on FB_SIS
+ help
+- This is the frame buffer device driver for the SiS 315 graphics
+- card. Specs available at <http://www.sis.com.tw/>.
++ This is the frame buffer device driver for the SiS 315 and Xabre
++ series VGA controllers. This includes the 315, 315H, 315PRO, 650,
++ 651, M650, 652, M652, 740, 330 (Xabre), 660, M660, 760, M760.
++ Documentation and updates available at
++ http://www.winischhofer.net/linuxsisvga.shtml
+
+ config FB_NEOMAGIC
+ tristate "NeoMagic display support"
+Index: linux-2.6.0-test5/drivers/video/logo/logo.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/logo/logo.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/logo/logo.c 2003-09-27 11:38:34.213327168 +0800
+@@ -32,8 +32,7 @@
+ extern const struct linux_logo logo_superh_vga16;
+ extern const struct linux_logo logo_superh_clut224;
+
+-
+-const struct linux_logo *fb_find_logo(int depth)
++const struct linux_logo *find_logo(int depth)
+ {
+ const struct linux_logo *logo = 0;
+
+Index: linux-2.6.0-test5/drivers/video/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/Makefile 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/Makefile 2003-09-27 11:38:34.273318048 +0800
+@@ -22,7 +22,7 @@
+ obj-$(CONFIG_FB_ATARI) += atafb.o
+ obj-$(CONFIG_FB_68328) += 68328fb.o
+ obj-$(CONFIG_FB_RADEON) += radeonfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+-obj-$(CONFIG_FB_NEOMAGIC) += neofb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
++obj-$(CONFIG_FB_NEOMAGIC) += neofb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o vgastate.o
+ obj-$(CONFIG_FB_IGA) += igafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+ obj-$(CONFIG_FB_CONTROL) += controlfb.o macmodes.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+ obj-$(CONFIG_FB_PLATINUM) += platinumfb.o macmodes.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+@@ -68,9 +68,10 @@
+ obj-$(CONFIG_FB_SA1100) += sa1100fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+ obj-$(CONFIG_FB_VIRTUAL) += vfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+ obj-$(CONFIG_FB_HIT) += hitfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+-obj-$(CONFIG_FB_E1355) += epson1355fb.o
+-obj-$(CONFIG_FB_PVR2) += pvr2fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
++obj-$(CONFIG_FB_EPSON1355) += epson1355fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
++obj-$(CONFIG_FB_PVR2) += pvr2fb.o cfbcillrect.o cfbcopyarea.o cfbimgblt.o
+ obj-$(CONFIG_FB_VOODOO1) += sstfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
++obj-$(CONFIG_FB_ASILIANT) += asiliantfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+
+ obj-$(CONFIG_FB_FFB) += ffb.o sbuslib.o cfbimgblt.o cfbcopyarea.o
+ obj-$(CONFIG_FB_CG6) += cg6.o sbuslib.o cfbimgblt.o cfbcopyarea.o
+Index: linux-2.6.0-test5/drivers/video/neofb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/neofb.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/neofb.c 2003-09-27 11:38:34.464289016 +0800
+@@ -81,9 +81,10 @@
+ #include <asm/mtrr.h>
+ #endif
+
++#include <video/vga.h>
+ #include <video/neomagic.h>
+
+-#define NEOFB_VERSION "0.4.1"
++#define NEOFB_VERSION "0.4.2"
+
+ /* --------------------------------------------------------------------- */
+
+@@ -152,6 +153,16 @@
+ };
+ #endif
+
++static inline u32 read_le32(int regindex, const struct neofb_par *par)
++{
++ return readl(par->neo2200 + par->cursorOff + regindex);
++}
++
++static inline void write_le32(int regindex, u32 val, const struct neofb_par *par)
++{
++ writel(val, par->neo2200 + par->cursorOff + regindex);
++}
++
+ static int neoFindMode(int xres, int yres, int depth)
+ {
+ int xres_s;
+@@ -363,44 +374,61 @@
+ par->Attribute[18] = 0x0F;
+ par->Attribute[19] = 0x00;
+ par->Attribute[20] = 0x00;
+-
+ return 0;
+ }
+
+-static void vgaHWLock(void)
++static void vgaHWLock(struct vgastate *state)
+ {
+ /* Protect CRTC[0-7] */
+- VGAwCR(0x11, VGArCR(0x11) | 0x80);
++ vga_wcrt(state->vgabase, 0x11, vga_rcrt(state->vgabase, 0x11) | 0x80);
+ }
+
+ static void vgaHWUnlock(void)
+ {
+ /* Unprotect CRTC[0-7] */
+- VGAwCR(0x11, VGArCR(0x11) & ~0x80);
++ vga_wcrt(NULL, 0x11, vga_rcrt(NULL, 0x11) & ~0x80);
+ }
+
+-static void neoLock(void)
++static void neoLock(struct vgastate *state)
+ {
+- VGAwGR(0x09, 0x00);
+- vgaHWLock();
++ vga_wgfx(state->vgabase, 0x09, 0x00);
++ vgaHWLock(state);
+ }
+
+ static void neoUnlock(void)
+ {
+ vgaHWUnlock();
+- VGAwGR(0x09, 0x26);
++ vga_wgfx(NULL, 0x09, 0x26);
+ }
+
+ /*
+- * vgaHWSeqReset
+- * perform a sequencer reset.
++ * VGA Palette management
+ */
+-void vgaHWSeqReset(int start)
++static int paletteEnabled = 0;
++
++inline void VGAenablePalette(void)
+ {
+- if (start)
+- VGAwSEQ(0x00, 0x01); /* Synchronous Reset */
++ vga_r(NULL, VGA_IS1_RC);
++ vga_w(NULL, VGA_ATT_W, 0x00);
++ paletteEnabled = 1;
++}
++
++inline void VGAdisablePalette(void)
++{
++ vga_r(NULL, VGA_IS1_RC);
++ vga_w(NULL, VGA_ATT_W, 0x20);
++ paletteEnabled = 0;
++}
++
++inline void VGAwATTR(u8 index, u8 value)
++{
++ if (paletteEnabled)
++ index &= ~0x20;
+ else
+- VGAwSEQ(0x00, 0x03); /* End Reset */
++ index |= 0x20;
++
++ vga_r(NULL, VGA_IS1_RC);
++ vga_wattr(NULL, index, value);
+ }
+
+ void vgaHWProtect(int on)
+@@ -411,21 +439,18 @@
+ /*
+ * Turn off screen and disable sequencer.
+ */
+- tmp = VGArSEQ(0x01);
+-
+- vgaHWSeqReset(1); /* start synchronous reset */
+- VGAwSEQ(0x01, tmp | 0x20); /* disable the display */
++ tmp = vga_rseq(NULL, 0x01);
++ vga_wseq(NULL, 0x00, 0x01); /* Synchronous Reset */
++ vga_wseq(NULL, 0x01, tmp | 0x20); /* disable the display */
+
+ VGAenablePalette();
+ } else {
+ /*
+ * Reenable sequencer, then turn on screen.
+ */
+-
+- tmp = VGArSEQ(0x01);
+-
+- VGAwSEQ(0x01, tmp & ~0x20); /* reenable display */
+- vgaHWSeqReset(0); /* clear synchronousreset */
++ tmp = vga_rseq(NULL, 0x01);
++ vga_wseq(NULL, 0x01, tmp & ~0x20); /* reenable display */
++ vga_wseq(NULL, 0x00, 0x03); /* clear synchronousreset */
+
+ VGAdisablePalette();
+ }
+@@ -436,19 +461,19 @@
+ {
+ int i;
+
+- VGAwMISC(par->MiscOutReg);
++ vga_w(NULL, VGA_MIS_W, par->MiscOutReg);
+
+ for (i = 1; i < 5; i++)
+- VGAwSEQ(i, par->Sequencer[i]);
++ vga_wseq(NULL, i, par->Sequencer[i]);
+
+ /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 or CRTC[17] */
+- VGAwCR(17, par->CRTC[17] & ~0x80);
++ vga_wcrt(NULL, 17, par->CRTC[17] & ~0x80);
+
+ for (i = 0; i < 25; i++)
+- VGAwCR(i, par->CRTC[i]);
++ vga_wcrt(NULL, i, par->CRTC[i]);
+
+ for (i = 0; i < 9; i++)
+- VGAwGR(i, par->Graphics[i]);
++ vga_wgfx(NULL, i, par->Graphics[i]);
+
+ VGAenablePalette();
+
+@@ -535,6 +560,36 @@
+ /* --------------------------------------------------------------------- */
+
+ static int
++neofb_open(struct fb_info *info, int user)
++{
++ struct neofb_par *par = (struct neofb_par *) info->par;
++ int cnt = atomic_read(&par->ref_count);
++
++ if (cnt) {
++ memset(&par->state, 0, sizeof(struct vgastate));
++ par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS;
++ save_vga(&par->state);
++ }
++ atomic_inc(&par->ref_count);
++ return 0;
++}
++
++static int
++neofb_release(struct fb_info *info, int user)
++{
++ struct neofb_par *par = (struct neofb_par *) info->par;
++ int cnt = atomic_read(&par->ref_count);
++
++ if (!cnt)
++ return -EINVAL;
++ if (cnt == 1) {
++ restore_vga(&par->state);
++ }
++ atomic_dec(&par->ref_count);
++ return 0;
++}
++
++static int
+ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+ {
+ struct neofb_par *par = (struct neofb_par *) info->par;
+@@ -981,13 +1036,13 @@
+ }
+
+ /* alread unlocked above */
+- /* BOGUS VGAwGR (0x09, 0x26); */
++ /* BOGUS vga_wgfx(NULL, 0x09, 0x26); */
+
+ /* don't know what this is, but it's 0 from bootup anyway */
+- VGAwGR(0x15, 0x00);
++ vga_wgfx(NULL, 0x15, 0x00);
+
+ /* was set to 0x01 by my bios in text and vesa modes */
+- VGAwGR(0x0A, par->GeneralLockReg);
++ vga_wgfx(NULL, 0x0A, par->GeneralLockReg);
+
+ /*
+ * The color mode needs to be set before calling vgaHWRestore
+@@ -996,7 +1051,7 @@
+ * NOTE: Make sure we don't change bits make sure we don't change
+ * any reserved bits.
+ */
+- temp = VGArGR(0x90);
++ temp = vga_rgfx(NULL, 0x90);
+ switch (info->fix.accel) {
+ case FB_ACCEL_NEOMAGIC_NM2070:
+ temp &= 0xF0; /* Save bits 7:4 */
+@@ -1015,7 +1070,7 @@
+ break;
+ }
+
+- VGAwGR(0x90, temp);
++ vga_wgfx(NULL, 0x90, temp);
+
+ /*
+ * In some rare cases a lockup might occur if we don't delay
+@@ -1027,9 +1082,9 @@
+ * Disable horizontal and vertical graphics and text expansions so
+ * that vgaHWRestore works properly.
+ */
+- temp = VGArGR(0x25);
++ temp = vga_rgfx(NULL, 0x25);
+ temp &= 0x39;
+- VGAwGR(0x25, temp);
++ vga_wgfx(NULL, 0x25, temp);
+
+ /*
+ * Sleep for 200ms to make sure that the two operations above have
+@@ -1041,19 +1096,18 @@
+ * This function handles restoring the generic VGA registers. */
+ vgaHWRestore(info, par);
+
+-
+- VGAwGR(0x0E, par->ExtCRTDispAddr);
+- VGAwGR(0x0F, par->ExtCRTOffset);
+- temp = VGArGR(0x10);
++ vga_wgfx(NULL, 0x0E, par->ExtCRTDispAddr);
++ vga_wgfx(NULL, 0x0F, par->ExtCRTOffset);
++ temp = vga_rgfx(NULL, 0x10);
+ temp &= 0x0F; /* Save bits 3:0 */
+ temp |= (par->SysIfaceCntl1 & ~0x0F); /* VESA Bios sets bit 1! */
+- VGAwGR(0x10, temp);
++ vga_wgfx(NULL, 0x10, temp);
+
+- VGAwGR(0x11, par->SysIfaceCntl2);
+- VGAwGR(0x15, 0 /*par->SingleAddrPage */ );
+- VGAwGR(0x16, 0 /*par->DualAddrPage */ );
++ vga_wgfx(NULL, 0x11, par->SysIfaceCntl2);
++ vga_wgfx(NULL, 0x15, 0 /*par->SingleAddrPage */ );
++ vga_wgfx(NULL, 0x16, 0 /*par->DualAddrPage */ );
+
+- temp = VGArGR(0x20);
++ temp = vga_rgfx(NULL, 0x20);
+ switch (info->fix.accel) {
+ case FB_ACCEL_NEOMAGIC_NM2070:
+ temp &= 0xFC; /* Save bits 7:2 */
+@@ -1074,79 +1128,78 @@
+ temp |= (par->PanelDispCntlReg1 & ~0x98);
+ break;
+ }
+- VGAwGR(0x20, temp);
++ vga_wgfx(NULL, 0x20, temp);
+
+- temp = VGArGR(0x25);
++ temp = vga_rgfx(NULL, 0x25);
+ temp &= 0x38; /* Save bits 5:3 */
+ temp |= (par->PanelDispCntlReg2 & ~0x38);
+- VGAwGR(0x25, temp);
++ vga_wgfx(NULL, 0x25, temp);
+
+ if (info->fix.accel != FB_ACCEL_NEOMAGIC_NM2070) {
+- temp = VGArGR(0x30);
++ temp = vga_rgfx(NULL, 0x30);
+ temp &= 0xEF; /* Save bits 7:5 and bits 3:0 */
+ temp |= (par->PanelDispCntlReg3 & ~0xEF);
+- VGAwGR(0x30, temp);
++ vga_wgfx(NULL, 0x30, temp);
+ }
+
+- VGAwGR(0x28, par->PanelVertCenterReg1);
+- VGAwGR(0x29, par->PanelVertCenterReg2);
+- VGAwGR(0x2a, par->PanelVertCenterReg3);
++ vga_wgfx(NULL, 0x28, par->PanelVertCenterReg1);
++ vga_wgfx(NULL, 0x29, par->PanelVertCenterReg2);
++ vga_wgfx(NULL, 0x2a, par->PanelVertCenterReg3);
+
+ if (info->fix.accel != FB_ACCEL_NEOMAGIC_NM2070) {
+- VGAwGR(0x32, par->PanelVertCenterReg4);
+- VGAwGR(0x33, par->PanelHorizCenterReg1);
+- VGAwGR(0x34, par->PanelHorizCenterReg2);
+- VGAwGR(0x35, par->PanelHorizCenterReg3);
++ vga_wgfx(NULL, 0x32, par->PanelVertCenterReg4);
++ vga_wgfx(NULL, 0x33, par->PanelHorizCenterReg1);
++ vga_wgfx(NULL, 0x34, par->PanelHorizCenterReg2);
++ vga_wgfx(NULL, 0x35, par->PanelHorizCenterReg3);
+ }
+
+ if (info->fix.accel == FB_ACCEL_NEOMAGIC_NM2160)
+- VGAwGR(0x36, par->PanelHorizCenterReg4);
++ vga_wgfx(NULL, 0x36, par->PanelHorizCenterReg4);
+
+ if (info->fix.accel == FB_ACCEL_NEOMAGIC_NM2200 ||
+ info->fix.accel == FB_ACCEL_NEOMAGIC_NM2230 ||
+ info->fix.accel == FB_ACCEL_NEOMAGIC_NM2360 ||
+ info->fix.accel == FB_ACCEL_NEOMAGIC_NM2380) {
+- VGAwGR(0x36, par->PanelHorizCenterReg4);
+- VGAwGR(0x37, par->PanelVertCenterReg5);
+- VGAwGR(0x38, par->PanelHorizCenterReg5);
++ vga_wgfx(NULL, 0x36, par->PanelHorizCenterReg4);
++ vga_wgfx(NULL, 0x37, par->PanelVertCenterReg5);
++ vga_wgfx(NULL, 0x38, par->PanelHorizCenterReg5);
+
+ clock_hi = 1;
+ }
+
+ /* Program VCLK3 if needed. */
+- if (par->ProgramVCLK && ((VGArGR(0x9B) != par->VCLK3NumeratorLow)
+- || (VGArGR(0x9F) != par->VCLK3Denominator)
+- || (clock_hi && ((VGArGR(0x8F) & ~0x0f)
+- != (par->
+- VCLK3NumeratorHigh &
++ if (par->ProgramVCLK && ((vga_rgfx(NULL, 0x9B) != par->VCLK3NumeratorLow)
++ || (vga_rgfx(NULL, 0x9F) != par->VCLK3Denominator)
++ || (clock_hi && ((vga_rgfx(NULL, 0x8F) & ~0x0f)
++ != (par->VCLK3NumeratorHigh &
+ ~0x0F))))) {
+- VGAwGR(0x9B, par->VCLK3NumeratorLow);
++ vga_wgfx(NULL, 0x9B, par->VCLK3NumeratorLow);
+ if (clock_hi) {
+- temp = VGArGR(0x8F);
++ temp = vga_rgfx(NULL, 0x8F);
+ temp &= 0x0F; /* Save bits 3:0 */
+ temp |= (par->VCLK3NumeratorHigh & ~0x0F);
+- VGAwGR(0x8F, temp);
++ vga_wgfx(NULL, 0x8F, temp);
+ }
+- VGAwGR(0x9F, par->VCLK3Denominator);
++ vga_wgfx(NULL, 0x9F, par->VCLK3Denominator);
+ }
+
+ if (par->biosMode)
+- VGAwCR(0x23, par->biosMode);
++ vga_wcrt(NULL, 0x23, par->biosMode);
+
+- VGAwGR(0x93, 0xc0); /* Gives 5x faster framebuffer writes !!! */
++ vga_wgfx(NULL, 0x93, 0xc0); /* Gives 5x faster framebuffer writes !!! */
+
+ /* Program vertical extension register */
+ if (info->fix.accel == FB_ACCEL_NEOMAGIC_NM2200 ||
+ info->fix.accel == FB_ACCEL_NEOMAGIC_NM2230 ||
+ info->fix.accel == FB_ACCEL_NEOMAGIC_NM2360 ||
+ info->fix.accel == FB_ACCEL_NEOMAGIC_NM2380) {
+- VGAwCR(0x70, par->VerticalExt);
++ vga_wcrt(NULL, 0x70, par->VerticalExt);
+ }
+
+ vgaHWProtect(0); /* Turn on screen */
+
+ /* Calling this also locks offset registers required in update_start */
+- neoLock();
++ neoLock(&par->state);
+
+ info->fix.line_length =
+ info->var.xres_virtual * (info->var.bits_per_pixel >> 3);
+@@ -1167,6 +1220,8 @@
+ static void neofb_update_start(struct fb_info *info,
+ struct fb_var_screeninfo *var)
+ {
++ struct neofb_par *par = (struct neofb_par *) info->par;
++ struct vgastate *state = &par->state;
+ int oldExtCRTDispAddr;
+ int Base;
+
+@@ -1180,18 +1235,18 @@
+ /*
+ * These are the generic starting address registers.
+ */
+- VGAwCR(0x0C, (Base & 0x00FF00) >> 8);
+- VGAwCR(0x0D, (Base & 0x00FF));
++ vga_wcrt(state->vgabase, 0x0C, (Base & 0x00FF00) >> 8);
++ vga_wcrt(state->vgabase, 0x0D, (Base & 0x00FF));
+
+ /*
+ * Make sure we don't clobber some other bits that might already
+ * have been set. NOTE: NM2200 has a writable bit 3, but it shouldn't
+ * be needed.
+ */
+- oldExtCRTDispAddr = VGArGR(0x0E);
+- VGAwGR(0x0E, (((Base >> 16) & 0x0f) | (oldExtCRTDispAddr & 0xf0)));
++ oldExtCRTDispAddr = vga_rgfx(NULL, 0x0E);
++ vga_wgfx(state->vgabase, 0x0E, (((Base >> 16) & 0x0f) | (oldExtCRTDispAddr & 0xf0)));
+
+- neoLock();
++ neoLock(state);
+ }
+
+ /*
+@@ -1353,7 +1408,7 @@
+ }
+
+ par->neo2200->dstStart =
+- dst * ((info->var.bits_per_pixel + 7) / 8);
++ dst * ((info->var.bits_per_pixel + 7) >> 3);
+ par->neo2200->xyExt =
+ (rect->height << 16) | (rect->width & 0xffff);
+ }
+@@ -1361,24 +1416,20 @@
+ static void
+ neo2200_copyarea(struct fb_info *info, const struct fb_copyarea *area)
+ {
+- struct neofb_par *par = (struct neofb_par *) info->par;
+ u32 sx = area->sx, sy = area->sy, dx = area->dx, dy = area->dy;
++ struct neofb_par *par = (struct neofb_par *) info->par;
+ u_long src, dst, bltCntl;
+
+ bltCntl = NEO_BC3_FIFO_EN | NEO_BC3_SKIP_MAPPING | 0x0C0000;
+
+- if (sy < dy) {
++ if ((dy > sy) || ((dy == sy) && (dx > sx))) {
++ /* Start with the lower right corner */
+ sy += (area->height - 1);
+ dy += (area->height - 1);
+-
+- bltCntl |= NEO_BC0_DST_Y_DEC | NEO_BC0_SRC_Y_DEC;
+- }
+-
+- if (area->sx < area->dx) {
+ sx += (area->width - 1);
+ dx += (area->width - 1);
+
+- bltCntl |= NEO_BC0_X_DEC;
++ bltCntl |= NEO_BC0_X_DEC | NEO_BC0_DST_Y_DEC | NEO_BC0_SRC_Y_DEC;
+ }
+
+ src = sx * (info->var.bits_per_pixel >> 3) + sy*info->fix.line_length;
+@@ -1496,8 +1547,60 @@
+ return 0;
+ }
+
++static int
++neofb_cursor(struct fb_info *info, struct fb_cursor *cursor)
++{
++ struct neofb_par *par = (struct neofb_par *) info->par;
++
++ /* Disable cursor */
++ write_le32(NEOREG_CURSCNTL, ~NEO_CURS_ENABLE, par);
++
++ if (cursor->set & FB_CUR_SETPOS) {
++ u32 x = cursor->image.dx;
++ u32 y = cursor->image.dy;
++
++ info->cursor.image.dx = x;
++ info->cursor.image.dy = y;
++ write_le32(NEOREG_CURSX, x, par);
++ write_le32(NEOREG_CURSY, y, par);
++ }
++
++ if (cursor->set & FB_CUR_SETSIZE) {
++ }
++
++ if (cursor->set & FB_CUR_SETCMAP) {
++ if (cursor->image.depth == 1) {
++ u32 fg = cursor->image.fg_color;
++ u32 bg = cursor->image.bg_color;
++
++ info->cursor.image.fg_color = fg;
++ info->cursor.image.bg_color = bg;
++
++ fg = ((fg & 0xff0000) >> 16) | ((fg & 0xff) << 16) | (fg & 0xff00);
++ bg = ((bg & 0xff0000) >> 16) | ((bg & 0xff) << 16) | (bg & 0xff00);
++ write_le32(NEOREG_CURSFGCOLOR, fg, par);
++ write_le32(NEOREG_CURSBGCOLOR, bg, par);
++ }
++ }
++
++ if (cursor->set & FB_CUR_SETSHAPE) {
++ unsigned long dest = (unsigned long) par->cursorPad;
++ int i, j;
++
++ //memset_io(par->cursorPad, 0xff, 1);
++ //write_le32(NEOREG_CURSMEMPOS, ((0x000f & (dest >> 10)) << 8) |
++ // ((0x0ff0 & (dest >> 10)) >> 4), par);
++ }
++
++ if (info->cursor.enable)
++ write_le32(NEOREG_CURSCNTL, NEO_CURS_ENABLE, par);
++ return 0;
++}
++
+ static struct fb_ops neofb_ops = {
+ .owner = THIS_MODULE,
++ .fb_open = neofb_open,
++ .fb_release = neofb_release,
+ .fb_check_var = neofb_check_var,
+ .fb_set_par = neofb_set_par,
+ .fb_setcolreg = neofb_setcolreg,
+@@ -1507,7 +1610,7 @@
+ .fb_fillrect = neofb_fillrect,
+ .fb_copyarea = neofb_copyarea,
+ .fb_imageblit = neofb_imageblit,
+- .fb_cursor = soft_cursor,
++ .fb_cursor = neofb_cursor,
+ };
+
+ /* --------------------------------------------------------------------- */
+@@ -1650,6 +1753,7 @@
+ struct pci_dev *dev, int video_len)
+ {
+ struct neofb_par *par = (struct neofb_par *) info->par;
++ unsigned long addr;
+
+ DBG("neo_map_video");
+
+@@ -1681,6 +1785,10 @@
+
+ /* Clear framebuffer, it's all white in memory after boot */
+ memset(info->screen_base, 0, info->fix.smem_len);
++
++ /* Allocate Cursor drawing pad. */
++ addr = info->fix.smem_start + info->fix.smem_len;
++ par->cursorPad = (u8 *) ioremap(addr, info->sprite.size);
+ return 0;
+ }
+
+@@ -1725,16 +1833,16 @@
+ printk(KERN_DEBUG "--- Neo extended register dump ---\n");
+ for (w = 0; w < 0x85; w++)
+ printk(KERN_DEBUG "CR %p: %p\n", (void *) w,
+- (void *) VGArCR(w));
++ (void *) vga_rcrt(NULL, w);
+ for (w = 0; w < 0xC7; w++)
+ printk(KERN_DEBUG "GR %p: %p\n", (void *) w,
+- (void *) VGArGR(w));
++ (void *) vga_rgfx(NULL, w));
+ #endif
+
+ /* Determine the panel type */
+- VGAwGR(0x09, 0x26);
+- type = VGArGR(0x21);
+- display = VGArGR(0x20);
++ vga_wgfx(NULL, 0x09, 0x26);
++ type = vga_rgfx(NULL, 0x21);
++ display = vga_rgfx(NULL, 0x20);
+ if (!par->internal_display && !par->external_display) {
+ par->internal_display = display & 2 || !(display & 3) ? 1 : 0;
+ par->external_display = display & 1;
+@@ -1744,8 +1852,8 @@
+ }
+
+ /* Determine panel width -- used in NeoValidMode. */
+- w = VGArGR(0x20);
+- VGAwGR(0x09, 0x00);
++ w = vga_rgfx(NULL, 0x20);
++ vga_wgfx(NULL, 0x09, 0x00);
+ switch ((w & 0x18) >> 3) {
+ case 0x00:
+ par->NeoPanelWidth = 640;
+@@ -1870,10 +1978,20 @@
+ par->neo2200 = (Neo2200 *) par->mmio_vbase;
+ break;
+ }
+-
++ info->sprite.size = CursorMem;
++ info->sprite.addr = kmalloc(CursorMem, GFP_KERNEL);
++ info->sprite.scan_align = 1;
++ info->sprite.buf_align = 1;
++ info->sprite.flags = FB_PIXMAP_IO;
+ par->maxClock = maxClock;
+-
+- return videoRam * 1024;
++ par->cursorOff = CursorOff;
++ /*
++ * We decrease the size of the framebuffer by a page
++ * instead of the size of the cursor pad to avoid
++ * userland being able to page fault the cursor
++ * region and start drawing in it.
++ */
++ return ((videoRam * 1024) - PAGE_SIZE);
+ }
+
+
+Index: linux-2.6.0-test5/drivers/video/platinumfb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/platinumfb.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/platinumfb.c 2003-09-27 11:38:34.488285368 +0800
+@@ -104,9 +104,6 @@
+ * Interface used by the world
+ */
+
+-int platinum_init(void);
+-int platinum_setup(char*);
+-
+ static struct fb_ops platinumfb_ops = {
+ .owner = THIS_MODULE,
+ .fb_check_var = platinumfb_check_var,
+@@ -492,7 +489,7 @@
+ /*
+ * Parse user speficied options (`video=platinumfb:')
+ */
+-int __init platinum_setup(char *options)
++int __init platinumfb_setup(char *options)
+ {
+ char *this_opt;
+
+@@ -672,7 +669,7 @@
+ .remove = platinumfb_remove,
+ };
+
+-int __init platinum_init(void)
++int __init platinumfb_init(void)
+ {
+ of_register_driver(&platinum_driver);
+
+Index: linux-2.6.0-test5/drivers/video/pvr2fb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/pvr2fb.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/pvr2fb.c 2003-09-27 11:38:34.532278680 +0800
+@@ -166,6 +166,11 @@
+ static int cable_type = -1;
+ static int video_output = -1;
+
++#ifdef CONFIG_MTRR
++static int enable_mtrr = 1;
++static int mtrr_handle;
++#endif
++
+ static int nopan = 0;
+ static int nowrap = 1;
+
+@@ -385,6 +390,7 @@
+
+ static int pvr2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+ {
++ struct pvr2fb_par *par = (struct pvr2fb_par *)info->par;
+ u_short vtotal, hsync_total;
+ u_long line_length;
+
+@@ -413,7 +419,7 @@
+
+ if (var->vmode & FB_VMODE_YWRAP) {
+ if (var->xoffset || var->yoffset < 0 ||
+- var->yoffset >= var->yres_virtual) {
++ var->yoffset >= var->yres_virtual)
+ var->xoffset = var->yoffset = 0;
+ } else {
+ if (var->xoffset > var->xres_virtual - var->xres ||
+@@ -421,9 +427,8 @@
+ var->xoffset < 0 || var->yoffset < 0)
+ var->xoffset = var->yoffset = 0;
+ }
+- } else {
++ } else
+ var->xoffset = var->yoffset = 0;
+- }
+
+ /*
+ * XXX: Need to be more creative with this (i.e. allow doublecan for
+@@ -456,7 +461,6 @@
+ DPRINTK("invalid hsync total for NTSC\n");
+ return -EINVAL;
+ }
+- }
+ }
+ /* Check memory sizes */
+ line_length = get_line_length(var->xres_virtual, var->bits_per_pixel);
+@@ -599,10 +603,10 @@
+
+ int __init pvr2fb_init(void)
+ {
++ struct fb_var_screeninfo var;
+ u_long modememused;
+- int err = -EINVAL;
+
+- if (!mach_is_dreamcast())
++ if (!MACH_DREAMCAST)
+ return -ENXIO;
+
+ fb_info = kmalloc(sizeof(struct fb_info) + sizeof(struct pvr2fb_par) +
+@@ -650,8 +654,8 @@
+
+ if (!fb_info->screen_base) {
+ printk("Failed to remap MMIO space\n");
+- err = -ENXIO;
+- goto out_err;
++ kfree(fb_info);
++ return -ENXIO;
+ }
+
+ memset_io((unsigned long)fb_info->screen_base, 0, pvr2_fix.smem_len);
+@@ -665,6 +669,8 @@
+ fb_info->pseudo_palette = (void *)(fb_info->par + 1);
+ fb_info->flags = FBINFO_FLAG_DEFAULT;
+
++ memset(&var, 0, sizeof(var));
++
+ if (video_output == VO_VGA)
+ defmode = DEFMODE_VGA;
+
+@@ -677,41 +683,46 @@
+
+ if (request_irq(HW_EVENT_VSYNC, pvr2fb_interrupt, 0,
+ "pvr2 VBL handler", fb_info)) {
+- err = -EBUSY;
+- goto out_err;
++ DPRINTK("couldn't register VBL int\n");
++ kfree(fb_info);
++ return -EBUSY;
+ }
+
+- if (register_framebuffer(fb_info) < 0)
+- goto reg_failed;
++#ifdef CONFIG_MTRR
++ if (enable_mtrr) {
++ mtrr_handle = mtrr_add(videomemory, videomemorysize, MTRR_TYPE_WRCOMB, 1);
++ printk("pvr2fb: MTRR turned on\n");
++ }
++#endif
+
+- modememused = get_line_length(fb_info->var.xres_virtual,
+- fb_info->var.bits_per_pixel);
+- modememused *= fb_info->var.yres_virtual;
++ if (register_framebuffer(fb_info) < 0) {
++ kfree(fb_info);
++ return -EINVAL;
++ }
+
++ modememused = get_line_length(var.xres_virtual, var.bits_per_pixel);
++ modememused *= var.yres_virtual;
+ printk("fb%d: %s frame buffer device, using %ldk/%ldk of video memory\n",
+ fb_info->node, fb_info->fix.id, modememused>>10,
+ videomemorysize>>10);
+ printk("fb%d: Mode %dx%d-%d pitch = %ld cable: %s video output: %s\n",
+- fb_info->node, fb_info->var.xres, fb_info->var.yres,
+- fb_info->var.bits_per_pixel,
+- get_line_length(fb_info->var.xres, fb_info->var.bits_per_pixel),
++ fb_info->node, var.xres, var.yres, var.bits_per_pixel,
++ get_line_length(var.xres, var.bits_per_pixel),
+ (char *)pvr2_get_param(cables, NULL, cable_type, 3),
+ (char *)pvr2_get_param(outputs, NULL, video_output, 3));
+
+ return 0;
+-
+-reg_failed:
+- free_irq(HW_EVENT_VSYNC, 0);
+-out_err:
+- kfree(fb_info);
+-
+- return err;
+ }
+
+ static void __exit pvr2fb_exit(void)
+ {
++#ifdef CONFIG_MTRR
++ if (enable_mtrr) {
++ mtrr_del(mtrr_handle, videomemory, videomemorysize);
++ printk("pvr2fb: MTRR turned off\n");
++ }
++#endif
+ unregister_framebuffer(fb_info);
+- free_irq(HW_EVENT_VSYNC, 0);
+ kfree(fb_info);
+ }
+
+@@ -767,6 +778,10 @@
+ nopan = 1;
+ } else if (!strncmp(this_opt, "nowrap", 6)) {
+ nowrap = 1;
++#ifdef CONFIG_MTRR
++ } else if (!strncmp(this_opt, "nomtrr", 6)) {
++ enable_mtrr = 0;
++#endif
+ } else {
+ mode_option = this_opt;
+ }
+Index: linux-2.6.0-test5/drivers/video/riva/fbdev.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/riva/fbdev.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/riva/fbdev.c 2003-09-27 11:38:34.667258160 +0800
+@@ -143,7 +143,17 @@
+ CH_GEFORCE4_TI_4200,
+ CH_QUADRO4_900XGL,
+ CH_QUADRO4_750XGL,
+- CH_QUADRO4_700XGL
++ CH_QUADRO4_700XGL,
++ CH_GEFORCE4_TI_4800,
++ CH_GEFORCE4_TI_4280,
++ CH_GEFORCE4_TI_4800SE,
++ CH_GEFORCE4_4200_GO,
++ CH_GEFORCE_FX_5800_U,
++ CH_GEFORCE_FX_5800,
++ CH_GEFORCE_FX_5600_U,
++ CH_GEFORCE_FX_5600,
++ CH_GEFORCE_FX_5200_U,
++ CH_GEFORCE_FX_5200
+ };
+
+ /* directly indexed by riva_chips enum, above */
+@@ -190,7 +200,17 @@
+ { "GeForce4 Ti 4200", NV_ARCH_20 },
+ { "Quadro4-900-XGL", NV_ARCH_20 },
+ { "Quadro4-750-XGL", NV_ARCH_20 },
+- { "Quadro4-700-XGL", NV_ARCH_20 }
++ { "Quadro4-700-XGL", NV_ARCH_20 },
++ { "GeForce4 Ti 4800", NV_ARCH_20 },
++ { "GeForce4 Ti 4280", NV_ARCH_20},
++ { "GeForce4 Ti 4800 SE", NV_ARCH_20},
++ { "GeForce4 4200 GO", NV_ARCH_20},
++ { "GeForce FX 5800 ULTRA", NV_ARCH_20},
++ { "GeForce FX 5800", NV_ARCH_20},
++ { "GeForce FX 5600 ULTRA", NV_ARCH_20},
++ { "GeForce FX 5600", NV_ARCH_20},
++ { "GeForce FX 5200 ULTRA", NV_ARCH_20},
++ { "GeForce FX 5200", NV_ARCH_20}
+ };
+
+ static struct pci_device_id rivafb_pci_tbl[] = {
+@@ -274,6 +294,26 @@
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO4_750XGL },
+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO4_700XGL },
++ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800,
++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE4_TI_4800 },
++ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4280,
++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE4_TI_4280 },
++ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800_SE,
++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE4_TI_4800SE },
++ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_4200_GO,
++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE4_4200_GO },
++ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800_U,
++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE_FX_5800_U },
++ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800,
++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE_FX_5800 },
++ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600_U,
++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE_FX_5600_U },
++ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600,
++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE_FX_5600 },
++ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200_U,
++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE_FX_5200_U },
++ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200,
++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE_FX_5200 },
+ { 0, } /* terminate list */
+ };
+ MODULE_DEVICE_TABLE(pci, rivafb_pci_tbl);
+@@ -1469,8 +1509,6 @@
+ static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
+ {
+ struct riva_par *par = (struct riva_par *) info->par;
+- u8 data[MAX_CURS * MAX_CURS/8];
+- u8 mask[MAX_CURS * MAX_CURS/8];
+ u16 fg, bg;
+ int i;
+
+@@ -1492,7 +1530,6 @@
+ if (cursor->set & FB_CUR_SETSIZE) {
+ info->cursor.image.height = cursor->image.height;
+ info->cursor.image.width = cursor->image.width;
+- memset_io(par->riva.CURSOR, 0, MAX_CURS * MAX_CURS * 2);
+ }
+
+ if (cursor->set & FB_CUR_SETCMAP) {
+@@ -1503,29 +1540,22 @@
+ if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP)) {
+ u32 bg_idx = info->cursor.image.bg_color;
+ u32 fg_idx = info->cursor.image.fg_color;
+- u32 s_pitch = (info->cursor.image.width+7) >> 3;
+- u32 d_pitch = MAX_CURS/8;
+- u8 *dat = (u8 *) cursor->image.data;
++ u8 *dat = (u8 *) info->cursor.image.data;
+ u8 *msk = (u8 *) info->cursor.mask;
+ u8 src[64];
+
+ switch (info->cursor.rop) {
+ case ROP_XOR:
+- for (i = 0; i < s_pitch * info->cursor.image.height; i++)
++ for (i = 0; i < info->sprite.size; i++)
+ src[i] = dat[i] ^ msk[i];
+ break;
+ case ROP_COPY:
+ default:
+- for (i = 0; i < s_pitch * info->cursor.image.height; i++)
+-
++ for (i = 0; i < info->sprite.size; i++)
+ src[i] = dat[i] & msk[i];
+ break;
+ }
+
+- move_buf_aligned(info, data, src, d_pitch, s_pitch, info->cursor.image.height);
+-
+- move_buf_aligned(info, mask, msk, d_pitch, s_pitch, info->cursor.image.height);
+-
+ bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |
+ ((info->cmap.green[bg_idx] & 0xf8) << 2) |
+ ((info->cmap.blue[bg_idx] & 0xf8) >> 3);
+@@ -1536,7 +1566,7 @@
+
+ par->riva.LockUnlock(&par->riva, 0);
+
+- rivafb_load_cursor_image(par, data, mask, bg, fg,
++ rivafb_load_cursor_image(par, dat, msk, bg, fg,
+ info->cursor.image.width,
+ info->cursor.image.height);
+ }
+@@ -1572,11 +1602,11 @@
+ .fb_fillrect = rivafb_fillrect,
+ .fb_copyarea = rivafb_copyarea,
+ .fb_imageblit = rivafb_imageblit,
+- .fb_cursor = rivafb_cursor,
++ .fb_cursor = soft_cursor,
+ .fb_sync = rivafb_sync,
+ };
+
+-static int __init riva_set_fbinfo(struct fb_info *info)
++static int __devinit riva_set_fbinfo(struct fb_info *info)
+ {
+ struct riva_par *par = (struct riva_par *) info->par;
+ unsigned int cmap_len;
+@@ -1603,6 +1633,15 @@
+ info->pixmap.buf_align = 4;
+ info->pixmap.scan_align = 4;
+ info->pixmap.flags = FB_PIXMAP_SYSTEM;
++/*
++ info->sprite.addr = (char *) par->riva.CURSOR;
++ info->sprite.size = MAX_CURS * MAX_CURS * 2;
++ info->sprite.buf_align = info->sprite.size;
++ info->sprite.scan_align = MAX_CURS >> 3;
++ info->sprite.access_align = 2;
++ info->sprite.flags = FB_PIXMAP_IO;
++ memset_io(par->riva.CURSOR, 0, MAX_CURS * MAX_CURS * 2);
++*/
+ return 0;
+ }
+
+@@ -1726,7 +1765,7 @@
+ *
+ * ------------------------------------------------------------------------- */
+
+-static int __init rivafb_probe(struct pci_dev *pd,
++static int __devinit rivafb_probe(struct pci_dev *pd,
+ const struct pci_device_id *ent)
+ {
+ struct riva_chip_info *rci = &riva_chip_info[ent->driver_data];
+Index: linux-2.6.0-test5/drivers/video/riva/nv_type.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/riva/nv_type.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/riva/nv_type.h 2003-09-27 11:38:34.708251928 +0800
+@@ -50,8 +50,16 @@
+ #define NV_CHIP_QUADRO4_900XGL ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL)
+ #define NV_CHIP_QUADRO4_750XGL ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL)
+ #define NV_CHIP_QUADRO4_700XGL ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL)
+-#define NV_CHIP_0x0280 ((PCI_VENDOR_ID_NVIDIA << 16) | 0x0280)
+-#define NV_CHIP_0x0281 ((PCI_VENDOR_ID_NVIDIA << 16) | 0x0281)
++#define NV_CHIP_GEFORCE4_TI_4800 ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800)
++#define NV_CHIP_GEFORCE4_TI_4280 ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4280)
++#define NV_CHIP_GEFORCE4_TI_4800SE ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800_SE)
++#define NV_CHIP_GEFORCE4_4200_GO ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE4_4200_GO)
++#define NV_CHIP_GEFORCE_FX_5800_U ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800_U)
++#define NV_CHIP_GEFORCE_FX_5800 ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800)
++#define NV_CHIP_GEFORCE_FX_5600_U ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600_U)
++#define NV_CHIP_GEFORCE_FX_5600 ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600)
++#define NV_CHIP_GEFORCE_FX_5200_U ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200_U)
++#define NV_CHIP_GEFORCE_FX_5200 ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200)
+ #define NV_CHIP_0x0288 ((PCI_VENDOR_ID_NVIDIA << 16) | 0x0288)
+ #define NV_CHIP_0x0289 ((PCI_VENDOR_ID_NVIDIA << 16) | 0x0289)
+
+Index: linux-2.6.0-test5/drivers/video/sis/300vtbl.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/sis/300vtbl.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/sis/300vtbl.h 2003-09-27 11:38:34.786240072 +0800
+@@ -1,7 +1,37 @@
+-
+-
+-/* Register settings for SiS 300 series */
+-
++/* $XFree86$ */
++/*
++ * Register settings for SiS 300 series
++ *
++ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
++ *
++ * If distributed as part of the linux kernel, the contents of this file
++ * is entirely covered by the GPL.
++ *
++ * Otherwise, the following terms apply:
++ *
++ * Permission to use, copy, modify, distribute, and sell this software and its
++ * documentation for any purpose is hereby granted without fee, provided that
++ * the above copyright notice appear in all copies and that both that
++ * copyright notice and this permission notice appear in supporting
++ * documentation, and that the name of the copyright holder not be used in
++ * advertising or publicity pertaining to distribution of the software without
++ * specific, written prior permission. The copyright holder makes no representations
++ * about the suitability of this software for any purpose. It is provided
++ * "as is" without express or implied warranty.
++ *
++ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
++ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
++ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
++ * PERFORMANCE OF THIS SOFTWARE.
++ *
++ * Author: Thomas Winischhofer <thomas@winischhofer.net>
++ *
++ * Based on code by Silicon Intergrated Systems
++ *
++ */
+
+ typedef struct _SiS300_StStruct
+ {
+@@ -39,470 +69,109 @@
+ {0xff, 0, 0, 0, 0, 0, 0, 0}
+ };
+
+-typedef struct _SiS300_StandTableStruct
+-{
+- UCHAR CRT_COLS;
+- UCHAR ROWS;
+- UCHAR CHAR_HEIGHT;
+- USHORT CRT_LEN;
+- UCHAR SR[4];
+- UCHAR MISC;
+- UCHAR CRTC[0x19];
+- UCHAR ATTR[0x14];
+- UCHAR GRC[9];
+-} SiS300_StandTableStruct;
+-
+-static const SiS300_StandTableStruct SiS300_StandTable[] =
+-{
+- {0x28,0x18,0x08,0x0800, /* 0x00 */
+- {0x09,0x03,0x00,0x02},
+- 0x63,
+- {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+- 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+- 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
+- 0xff},
+- {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+- 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+- 0x08,0x00,0x0f,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+- 0xff} },
+- {0x28,0x18,0x08,0x0800, /* 0x01 */
+- {0x09,0x03,0x00,0x02},
+- 0x63,
+- {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+- 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+- 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
+- 0xff},
+- {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+- 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+- 0x08,0x00,0x0f,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+- 0xff} },
+- {0x50,0x18,0x08,0x1000, /* 0x02 */
+- {0x01,0x03,0x00,0x02},
+- 0x63,
+- {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+- 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+- 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+- 0xff},
+- {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+- 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+- 0x08,0x00,0x0f,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+- 0xff} },
+- {0x50,0x18,0x08,0x1000, /* 0x03 */
+- {0x01,0x03,0x00,0x02},
+- 0x63,
+- {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+- 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+- 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+- 0xff},
+- {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+- 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+- 0x08,0x00,0x0f,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+- 0xff} },
+- {0x28,0x18,0x08,0x4000, /* 0x04 */
+- {0x09,0x03,0x00,0x02},
+- 0x63,
+- {0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f,
+- 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
+- 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
+- 0xff},
+- {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
+- 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+- 0x01,0x00,0x03,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
+- 0xff} },
+- {0x28,0x18,0x08,0x4000, /* 0x05 */
+- {0x09,0x03,0x00,0x02},
+- 0x63,
+- {0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f,
+- 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
+- 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
+- 0xff},
+- {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
+- 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+- 0x01,0x00,0x03,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
+- 0xff} },
+- {0x50,0x18,0x08,0x4000, /* 0x06 */
+- {0x01,0x01,0x00,0x06},
+- 0x63,
+- {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
+- 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
+- 0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xc2,
+- 0xff},
+- {0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+- 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+- 0x01,0x00,0x01,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00,
+- 0xff} },
+- {0x50,0x18,0x0e,0x1000, /* 0x07 */
+- {0x00,0x03,0x00,0x03},
+- 0xa6,
+- {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+- 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+- 0x83,0x85,0x5d,0x28,0x0d,0x63,0xba,0xa3,
+- 0xff},
+- {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+- 0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+- 0x0e,0x00,0x0f,0x08},
+- {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
+- 0xff} },
+-/* MDA_DAC*/
+- {0x00,0x00,0x00,0x0000, /* 0x08 */
+- {0x00,0x00,0x00,0x15},
+- 0x15,
+- {0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+- 0x15,0x15,0x15,0x15,0x15,0x15,0x3f,0x3f,
+- 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00,
+- 0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x15,0x15,0x15,
+- 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+- 0x15,0x15,0x15,0x15},
+- {0x15,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+- 0x3f} },
+-/* CGA_DAC*/
+- {0x00,0x10,0x04,0x0114, /* 0x09 */
+- {0x11,0x09,0x15,0x00},
+- 0x10,
+- {0x04,0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,
+- 0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x2a,0x3a,
+- 0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x10,
+- 0x04},
+- {0x14,0x01,0x11,0x09,0x15,0x00,0x10,0x04,
+- 0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,0x2e,
+- 0x3e,0x2b,0x3b,0x2f},
+- {0x3f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
+- 0x3f} },
+-/* EGA_DAC*/
+- {0x00,0x10,0x04,0x0114, /* 0x0a */
+- {0x11,0x05,0x15,0x20},
+- 0x30,
+- {0x24,0x34,0x21,0x31,0x25,0x35,0x08,0x18,
+- 0x0c,0x1c,0x09,0x19,0x0d,0x1d,0x28,0x38,
+- 0x2c,0x3c,0x29,0x39,0x2d,0x3d,0x02,0x12,
+- 0x06},
+- {0x16,0x03,0x13,0x07,0x17,0x22,0x32,0x26,
+- 0x36,0x23,0x33,0x27,0x37,0x0a,0x1a,0x0e,
+- 0x1e,0x0b,0x1b,0x0f},
+- {0x1f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
+- 0x3f} },
+-/* VGA_DAC*/
+- {0x00,0x10,0x04,0x0114, /* 0x0b */
+- {0x11,0x09,0x15,0x2a},
+- 0x3a,
+- {0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x05,
+- 0x08,0x0b,0x0e,0x11,0x14,0x18,0x1c,0x20,
+- 0x24,0x28,0x2d,0x32,0x38,0x3f,0x00,0x10,
+- 0x1f},
+- {0x2f,0x3f,0x1f,0x27,0x2f,0x37,0x3f,0x2d,
+- 0x31,0x36,0x3a,0x3f,0x00,0x07,0x0e,0x15,
+- 0x1c,0x0e,0x11,0x15},
+- {0x18,0x1c,0x14,0x16,0x18,0x1a,0x1c,0x00,
+- 0x04} },
+- {0x08,0x0c,0x10,0x0a08, /* 0x0c */
+- {0x0c,0x0e,0x10,0x0b},
+- 0x0c,
+- {0x0d,0x0f,0x10,0x10,0x01,0x08,0x00,0x00,
+- 0x00,0x00,0x01,0x00,0x02,0x02,0x01,0x00,
+- 0x04,0x04,0x01,0x00,0x05,0x02,0x05,0x00,
+- 0x06},
+- {0x01,0x06,0x05,0x06,0x00,0x08,0x01,0x08,
+- 0x00,0x07,0x02,0x07,0x06,0x07,0x00,0x00,
+- 0x00,0x00,0x00,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+- 0x00} },
+- {0x28,0x18,0x08,0x2000, /* 0x0d */
+- {0x09,0x0f,0x00,0x06},
+- 0x63,
+- {0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f,
+- 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+- 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xe3,
+- 0xff},
+- {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+- 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+- 0x01,0x00,0x0f,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+- 0xff} },
+- {0x50,0x18,0x08,0x4000, /* 0x0e */
+- {0x01,0x0f,0x00,0x06},
+- 0x63,
+- {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
+- 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+- 0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xe3,
+- 0xff},
+- {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+- 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+- 0x01,0x00,0x0f,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+- 0xff} },
+- {0x00,0x00,0x00,0x0000, /* 0x0f */ /* TW: Standtable for VGA modes */
+- {0x01,0x0f,0x00,0x0e},
+- 0x23,
+- {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
+- 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+- 0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3,
+- 0xff},
+- {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+- 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+- 0x01,0x00,0x00,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
+- 0xff} },
+- {0x4a,0x36,0x00,0x00c0, /* 0x10 */
+- {0x00,0x00,0x00,0x00},
+- 0x00,
+- {0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x3a,
+- 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+- 0x00,0x00,0x1a,0x00,0x57,0x39,0x00,0xc0,
+- 0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+- 0x00,0x00,0x00,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+- 0x00} },
+- {0x50,0x18,0x0e,0x8000, /* 0x11 */
+- {0x01,0x0f,0x00,0x06},
+- 0xa2,
+- {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
+- 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+- 0x83,0x85,0x5d,0x28,0x0f,0x63,0xba,0xe3,
+- 0xff},
+- {0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00,
+- 0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00,
+- 0x0b,0x00,0x05,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x05,
+- 0xff} },
+- {0x50,0x18,0x0e,0x8000, /* 0x12 */
+- {0x01,0x0f,0x00,0x06},
+- 0xa3,
+- {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
+- 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+- 0x83,0x85,0x5d,0x28,0x0f,0x63,0xba,0xe3,
+- 0xff},
+- {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+- 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+- 0x01,0x00,0x0f,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+- 0xff} },
+- {0x28,0x18,0x0e,0x0800, /* 0x13 */
+- {0x09,0x03,0x00,0x02},
+- 0xa3,
+- {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+- 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+- 0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
+- 0xff},
+- {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+- 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+- 0x08,0x00,0x0f,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+- 0xff} },
+- {0x28,0x18,0x0e,0x0800, /* 0x14 */
+- {0x09,0x03,0x00,0x02},
+- 0xa3,
+- {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+- 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+- 0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
+- 0xff},
+- {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+- 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+- 0x08,0x00,0x0f,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+- 0xff} },
+- {0x50,0x18,0x0e,0x1000, /* 0x15 */
+- {0x01,0x03,0x00,0x02},
+- 0xa3,
+- {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+- 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+- 0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
+- 0xff},
+- {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+- 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+- 0x08,0x00,0x0f,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+- 0xff} },
+- {0x50,0x18,0x0e,0x1000, /* 0x16 */
+- {0x01,0x03,0x00,0x02},
+- 0xa3,
+- {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+- 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+- 0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
+- 0xff},
+- {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+- 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+- 0x08,0x00,0x0f,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+- 0xff} },
+- {0x28,0x18,0x10,0x0800, /* 0x17 */
+- {0x08,0x03,0x00,0x02},
+- 0x67,
+- {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+- 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
+- 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
+- 0xff},
+- {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+- 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+- 0x0c,0x00,0x0f,0x08},
+- {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+- 0xff} },
+- {0x50,0x18,0x10,0x1000, /* 0x18 */
+- {0x00,0x03,0x00,0x02},
+- 0x67,
+- {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+- 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
+- 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+- 0xff},
+- {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+- 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+- 0x0c,0x00,0x0f,0x08},
+- {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+- 0xff} },
+- {0x50,0x18,0x10,0x1000, /* 0x19 */
+- {0x00,0x03,0x00,0x02},
+- 0x66,
+- {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+- 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
+- 0x9c,0x8e,0x8f,0x28,0x0f,0x96,0xb9,0xa3,
+- 0xff},
+- {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+- 0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+- 0x0e,0x00,0x0f,0x08},
+- {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
+- 0xff} },
+- {0x50,0x1d,0x10,0xa000, /* 0x1a */
+- {0x01,0x0f,0x00,0x06},
+- 0xe3,
+- {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
+- 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+- 0xea,0x8c,0xdf,0x28,0x00,0xe7,0x04,0xc3,
+- 0xff},
+- {0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+- 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+- 0x01,0x00,0x0f,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01,
+- 0xff} },
+- {0x50,0x1d,0x10,0xa000, /* 0x1b */
+- {0x01,0x0f,0x00,0x06},
+- 0xe3,
+- {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
+- 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+- 0xea,0x8c,0xdf,0x28,0x00,0xe7,0x04,0xe3,
+- 0xff},
+- {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+- 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+- 0x01,0x00,0x0f,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+- 0xff} },
+- {0x28,0x18,0x08,0x2000, /* 0x1c */
+- {0x01,0x0f,0x00,0x0e},
+- 0x63,
+- {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
+- 0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
+- 0x9c,0x8e,0x8f,0x28,0x40,0x96,0xb9,0xa3,
+- 0xff},
+- {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+- 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+- 0x41,0x00,0x0f,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
+- 0xff} }
+-};
+-
+ typedef struct _SiS300_ExtStruct
+ {
+- UCHAR Ext_ModeID;
++ UCHAR Ext_ModeID;
+ USHORT Ext_ModeFlag;
+ USHORT Ext_ModeInfo;
+- USHORT Ext_Point;
+ USHORT Ext_VESAID;
+- UCHAR Ext_VESAMEMSize;
+- UCHAR Ext_RESINFO;
+- UCHAR VB_ExtTVFlickerIndex;
+- UCHAR VB_ExtTVEdgeIndex;
+- UCHAR VB_ExtTVYFilterIndex;
+- UCHAR REFindex;
++ UCHAR Ext_RESINFO;
++ UCHAR VB_ExtTVFlickerIndex;
++ UCHAR VB_ExtTVEdgeIndex;
++ UCHAR VB_ExtTVYFilterIndex;
++ UCHAR REFindex;
+ } SiS300_ExtStruct;
+
+ static const SiS300_ExtStruct SiS300_EModeIDTable[] =
+ {
+- {0x6a,0x2212,0x47,0x3563,0x0102,0x08,0x07,0x00,0x00,0x00,0x00}, /* 800x600x? */
+- {0x2e,0x0a1b,0x36,0x3539,0x0101,0x08,0x06,0x00,0x00,0x00,0x08},
+- {0x2f,0x021b,0x35,0x3532,0x0100,0x08,0x05,0x00,0x00,0x00,0x10}, /* 640x400x8 */
+- {0x30,0x2a1b,0x47,0x3563,0x0103,0x08,0x07,0x00,0x00,0x00,0x00},
+- {0x31,0x0a1b,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11}, /* 720x480x8 */
+- {0x32,0x2a1b,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12}, /* 720x576x8 */
+- {0x33,0x0a1d,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11}, /* 720x480x16 */
+- {0x34,0x2a1d,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12}, /* 720x576x16 */
+- {0x35,0x0a1f,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11}, /* 720x480x32 */
+- {0x36,0x2a1f,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12}, /* 720x576x32 */
+- {0x37,0x0212,0x58,0x358d,0x0104,0x08,0x08,0x00,0x00,0x00,0x13}, /* 1024x768x? */
+- {0x38,0x0a1b,0x58,0x358d,0x0105,0x08,0x08,0x00,0x00,0x00,0x13}, /* 1024x768x8 */
+- {0x3a,0x0e3b,0x69,0x35be,0x0107,0x08,0x09,0x00,0x00,0x00,0x1a}, /* 1280x1024x8 */
+- {0x3c,0x063b,0x7a,0x35d4,0x0130,0x08,0x0a,0x00,0x00,0x00,0x1e},
+- {0x3d,0x067d,0x7a,0x35d4,0x0131,0x08,0x0a,0x00,0x00,0x00,0x1e},
+- {0x40,0x921c,0x00,0x3516,0x010d,0x08,0x00,0x00,0x00,0x00,0x23},
+- {0x41,0x921d,0x00,0x3516,0x010e,0x08,0x00,0x00,0x00,0x00,0x23},
+- {0x43,0x0a1c,0x36,0x3539,0x0110,0x08,0x06,0x00,0x00,0x00,0x08},
+- {0x44,0x0a1d,0x36,0x3539,0x0111,0x08,0x06,0x00,0x00,0x00,0x08},
+- {0x46,0x2a1c,0x47,0x3563,0x0113,0x08,0x07,0x00,0x00,0x00,0x00}, /* 800x600 */
+- {0x47,0x2a1d,0x47,0x3563,0x0114,0x08,0x07,0x00,0x00,0x00,0x00}, /* 800x600 */
+- {0x49,0x0a3c,0x58,0x358d,0x0116,0x08,0x08,0x00,0x00,0x00,0x13},
+- {0x4a,0x0a3d,0x58,0x358d,0x0117,0x08,0x08,0x00,0x00,0x00,0x13},
+- {0x4c,0x0e7c,0x69,0x35be,0x0119,0x08,0x09,0x00,0x00,0x00,0x1a},
+- {0x4d,0x0e7d,0x69,0x35be,0x011a,0x08,0x09,0x00,0x00,0x00,0x1a},
+- {0x50,0x921b,0x01,0x351d,0x0132,0x08,0x01,0x00,0x00,0x00,0x24},
+- {0x51,0xb21b,0x13,0x3524,0x0133,0x08,0x03,0x00,0x00,0x00,0x25}, /* 400x300 */
+- {0x52,0x921b,0x24,0x352b,0x0134,0x08,0x04,0x00,0x00,0x00,0x26},
+- {0x56,0x921d,0x01,0x351d,0x0135,0x08,0x01,0x00,0x00,0x00,0x24},
+- {0x57,0xb21d,0x13,0x3524,0x0136,0x08,0x03,0x00,0x00,0x00,0x25}, /* 400x300 */
+- {0x58,0x921d,0x24,0x352b,0x0137,0x08,0x04,0x00,0x00,0x00,0x26},
+- {0x59,0x921b,0x00,0x3516,0x0138,0x08,0x00,0x00,0x00,0x00,0x23},
+- {0x5c,0x921f,0x24,0x352b,0x0000,0x08,0x04,0x00,0x00,0x00,0x26}, /* TW: inserted 512x384x32 */
+- {0x5d,0x021d,0x35,0x3532,0x0139,0x08,0x05,0x00,0x00,0x00,0x10}, /* 640x400x16 */
+- {0x5e,0x021f,0x35,0x3532,0x0000,0x08,0x05,0x00,0x00,0x00,0x10}, /* TW: inserted 640x400x32 */
+- {0x62,0x0a3f,0x36,0x3539,0x013a,0x08,0x06,0x00,0x00,0x00,0x08},
+- {0x63,0x2a3f,0x47,0x3563,0x013b,0x08,0x07,0x00,0x00,0x00,0x00}, /* 800x600 */
+- {0x64,0x0a7f,0x58,0x358d,0x013c,0x08,0x08,0x00,0x00,0x00,0x13},
+- {0x65,0x0eff,0x69,0x35be,0x013d,0x08,0x09,0x00,0x00,0x00,0x1a},
+- {0x66,0x06ff,0x7a,0x35d4,0x013e,0x08,0x0a,0x00,0x00,0x00,0x1e},
+- {0x68,0x067b,0x8b,0x35ef,0x013f,0x08,0x0b,0x00,0x00,0x00,0x27},
+- {0x69,0x06fd,0x8b,0x35ef,0x0140,0x08,0x0b,0x00,0x00,0x00,0x27},
+- {0x6b,0x07ff,0x8b,0x35ef,0x0000,0x10,0x0b,0x00,0x00,0x00,0x27},
+- {0x6c,0x067b,0x9c,0x35f6,0x0000,0x08,0x11,0x00,0x00,0x00,0x28}, /* TW: 2048x1536x8 - not in BIOS! */
+- {0x6d,0x06fd,0x9c,0x35f6,0x0000,0x10,0x11,0x00,0x00,0x00,0x28}, /* TW: 2048x1536x16 - not in BIOS! */
+- {0x6e,0x0a3b,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29}, /* 1280x960x8 */
+- {0x6f,0x0a7d,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29}, /* 1280x960x16 */
+- /* TW: 16:9 modes copied from 310/325 series - not in ANY BIOS */
+- {0x70,0x2a1b,0x40,0x3b52,0x0000,0x08,0x12,0x00,0x00,0x07,0x2d}, /* 800x480x8 */
+- {0x71,0x0a1b,0x51,0x3b63,0x0000,0x08,0x13,0x00,0x00,0x00,0x30}, /* 1024x576x8 */
+- {0x74,0x0a1d,0x51,0x3b63,0x0000,0x08,0x13,0x00,0x00,0x00,0x30}, /* 1024x576x16 */
+- {0x75,0x0e3d,0x62,0x3b74,0x0000,0x08,0x14,0x00,0x00,0x00,0x33}, /* 1280x720x16 */
+- {0x76,0x2a1f,0x40,0x3b52,0x0000,0x08,0x12,0x00,0x00,0x07,0x2d}, /* 800x480x32 */
+- {0x77,0x0a3f,0x51,0x3b63,0x0000,0x08,0x13,0x00,0x00,0x00,0x30}, /* 1024x576x32 */
+- {0x78,0x0eff,0x62,0x3b74,0x0000,0x08,0x14,0x00,0x00,0x00,0x33}, /* 1280x720x32 */
+- {0x79,0x0e3b,0x62,0x3b74,0x0000,0x08,0x14,0x00,0x00,0x00,0x33}, /* 1280x720x8 */
+- {0x7a,0x2a1d,0x40,0x3b52,0x0000,0x08,0x12,0x00,0x00,0x07,0x2d}, /* 800x480x16 */
+- /* TW: End of new 16:9 modes */
+- {0x7b,0x0aff,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29}, /* 1280x960x32 */
+- {0x20,0x0a1b,0x54,0x0000,0x0000,0x08,0x0f,0x00,0x00,0x00,0x2b}, /* 1024x600 */
+- {0x21,0x0a3d,0x54,0x0000,0x0000,0x08,0x0f,0x00,0x00,0x00,0x2b},
+- {0x22,0x0a7f,0x54,0x0000,0x0000,0x08,0x0f,0x00,0x00,0x00,0x2b},
+- {0x23,0x0a1b,0xc5,0x0000,0x0000,0x08,0x10,0x00,0x00,0x00,0x2c}, /* 1152x768 */
+- {0x24,0x0a3d,0xc5,0x431d,0x0000,0x08,0x10,0x00,0x00,0x00,0x2c},
+- {0x25,0x0a7f,0xc5,0x431d,0x0000,0x08,0x10,0x00,0x00,0x00,0x2c},
+- {0x29,0x0e1b,0xc5,0x0000,0x0000,0x08,0x15,0x00,0x00,0x00,0x36}, /* TW: NEW 1152x864 - not in BIOS */
+- {0x2a,0x0e3d,0xc5,0x0000,0x0000,0x08,0x15,0x00,0x00,0x00,0x36},
+- {0x2b,0x0e7f,0xc5,0x0000,0x0000,0x08,0x15,0x00,0x00,0x00,0x36},
+- {0x39,0x2a1b,0xd6,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x38}, /* TW: NEW 848x480 - not in BIOS */
+- {0x3b,0x2a3d,0xd6,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x38},
+- {0x3e,0x2a7f,0xd6,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x38},
+- {0x3f,0x2a1b,0xd7,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x3a}, /* TW: NEW 856x480 - not in BIOS */
+- {0x42,0x2a3d,0xd7,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x3a},
+- {0x45,0x2a7f,0xd7,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x3a},
+- {0x48,0x223b,0xe8,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x3c}, /* TW: NEW 1360x768 - not in BIOS */
+- {0x4b,0x227d,0xe8,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x3c},
+- {0x4e,0x22ff,0xe8,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x3c},
+- {0xff,0x0000,0x00,0x0000,0xffff,0x00,0x00,0x00,0x00,0x00,0x00}
++ {0x6a,0x2212,0x0407,0x0102,SIS_RI_800x600, 0x00,0x00,0x00,0x00}, /* 800x600x? */
++ {0x2e,0x0a1b,0x0306,0x0101,SIS_RI_640x480, 0x00,0x00,0x00,0x08},
++ {0x2f,0x021b,0x0305,0x0100,SIS_RI_640x400, 0x00,0x00,0x00,0x10}, /* 640x400x8 */
++ {0x30,0x2a1b,0x0407,0x0103,SIS_RI_800x600, 0x00,0x00,0x00,0x00},
++ {0x31,0x0a1b,0x0a0d,0x0000,SIS_RI_720x480, 0x00,0x00,0x00,0x11}, /* 720x480x8 */
++ {0x32,0x2a1b,0x0a0e,0x0000,SIS_RI_720x576, 0x00,0x00,0x00,0x12}, /* 720x576x8 */
++ {0x33,0x0a1d,0x0a0d,0x0000,SIS_RI_720x480, 0x00,0x00,0x00,0x11}, /* 720x480x16 */
++ {0x34,0x2a1d,0x0a0e,0x0000,SIS_RI_720x576, 0x00,0x00,0x00,0x12}, /* 720x576x16 */
++ {0x35,0x0a1f,0x0a0d,0x0000,SIS_RI_720x480, 0x00,0x00,0x00,0x11}, /* 720x480x32 */
++ {0x36,0x2a1f,0x0a0e,0x0000,SIS_RI_720x576, 0x00,0x00,0x00,0x12}, /* 720x576x32 */
++ {0x37,0x0212,0x0508,0x0104,SIS_RI_1024x768, 0x00,0x00,0x00,0x13}, /* 1024x768x? */
++ {0x38,0x0a1b,0x0508,0x0105,SIS_RI_1024x768, 0x00,0x00,0x00,0x13}, /* 1024x768x8 */
++ {0x3a,0x0e3b,0x0609,0x0107,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a}, /* 1280x1024x8 */
++ {0x3c,0x063b,0x070a,0x0130,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e},
++ {0x3d,0x067d,0x070a,0x0131,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e},
++ {0x40,0x921c,0x0000,0x010d,SIS_RI_320x200, 0x00,0x00,0x00,0x23}, /* 320x200x15 */
++ {0x41,0x921d,0x0000,0x010e,SIS_RI_320x200, 0x00,0x00,0x00,0x23}, /* 320x200x16 */
++ {0x43,0x0a1c,0x0306,0x0110,SIS_RI_640x480, 0x00,0x00,0x00,0x08},
++ {0x44,0x0a1d,0x0306,0x0111,SIS_RI_640x480, 0x00,0x00,0x00,0x08},
++ {0x46,0x2a1c,0x0407,0x0113,SIS_RI_800x600, 0x00,0x00,0x00,0x00}, /* 800x600x15 */
++ {0x47,0x2a1d,0x0407,0x0114,SIS_RI_800x600, 0x00,0x00,0x00,0x00}, /* 800x600x16 */
++ {0x49,0x0a3c,0x0508,0x0116,SIS_RI_1024x768, 0x00,0x00,0x00,0x13},
++ {0x4a,0x0a3d,0x0508,0x0117,SIS_RI_1024x768, 0x00,0x00,0x00,0x13},
++ {0x4c,0x0e7c,0x0609,0x0119,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a},
++ {0x4d,0x0e7d,0x0609,0x011a,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a},
++ {0x50,0x921b,0x0001,0x0132,SIS_RI_320x240, 0x00,0x00,0x00,0x24}, /* 320x240x8 */
++ {0x51,0xb21b,0x0103,0x0133,SIS_RI_400x300, 0x00,0x00,0x00,0x25}, /* 400x300x8 */
++ {0x52,0x921b,0x0204,0x0134,SIS_RI_512x384, 0x00,0x00,0x00,0x26}, /* 512x384x8 */
++ {0x56,0x921d,0x0001,0x0135,SIS_RI_320x240, 0x00,0x00,0x00,0x24}, /* 320x240x16 */
++ {0x57,0xb21d,0x0103,0x0136,SIS_RI_400x300, 0x00,0x00,0x00,0x25}, /* 400x300x16 */
++ {0x58,0x921d,0x0204,0x0137,SIS_RI_512x384, 0x00,0x00,0x00,0x26}, /* 512x384x16 */
++ {0x59,0x921b,0x0000,0x0138,SIS_RI_320x200, 0x00,0x00,0x00,0x23}, /* 320x200x8 */
++ {0x5c,0x921f,0x0204,0x0000,SIS_RI_512x384, 0x00,0x00,0x00,0x26}, /* 512x384x32 */
++ {0x5d,0x021d,0x0305,0x0139,SIS_RI_640x400, 0x00,0x00,0x00,0x10}, /* 640x400x16 */
++ {0x5e,0x021f,0x0305,0x0000,SIS_RI_640x400, 0x00,0x00,0x00,0x10}, /* 640x400x32 */
++ {0x62,0x0a3f,0x0306,0x013a,SIS_RI_640x480, 0x00,0x00,0x00,0x08},
++ {0x63,0x2a3f,0x0407,0x013b,SIS_RI_800x600, 0x00,0x00,0x00,0x00}, /* 800x600x32 */
++ {0x64,0x0a7f,0x0508,0x013c,SIS_RI_1024x768, 0x00,0x00,0x00,0x13},
++ {0x65,0x0eff,0x0609,0x013d,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a},
++ {0x66,0x06ff,0x070a,0x013e,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e},
++ {0x68,0x067b,0x080b,0x013f,SIS_RI_1920x1440,0x00,0x00,0x00,0x27},
++ {0x69,0x06fd,0x080b,0x0140,SIS_RI_1920x1440,0x00,0x00,0x00,0x27},
++ {0x6b,0x07ff,0x080b,0x0000,SIS_RI_1920x1440,0x00,0x00,0x00,0x27},
++ {0x6c,0x067b,0x090c,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x28}, /* 2048x1536x8 - not in BIOS! */
++ {0x6d,0x06fd,0x090c,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x28}, /* 2048x1536x16 - not in BIOS! */
++ {0x70,0x2a1b,0x0400,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x2d}, /* 800x480x8 */
++ {0x71,0x0a1b,0x0501,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x30}, /* 1024x576x8 */
++ {0x74,0x0a1d,0x0501,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x30}, /* 1024x576x16 */
++ {0x75,0x0e3d,0x0602,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x33}, /* 1280x720x16 */
++ {0x76,0x2a1f,0x0400,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x2d}, /* 800x480x32 */
++ {0x77,0x0a3f,0x0501,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x30}, /* 1024x576x32 */
++ {0x78,0x0eff,0x0602,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x33}, /* 1280x720x32 */
++ {0x79,0x0e3b,0x0602,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x33}, /* 1280x720x8 */
++ {0x7a,0x2a1d,0x0400,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x2d}, /* 800x480x16 */
++ {0x7c,0x0a3b,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x29}, /* 1280x960x8 */
++ {0x7d,0x0a7d,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x29}, /* 1280x960x16 */
++ {0x7e,0x0aff,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x29}, /* 1280x960x32 */
++ {0x20,0x0a1b,0x0504,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x2b}, /* 1024x600 */
++ {0x21,0x0a3d,0x0504,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x2b},
++ {0x22,0x0a7f,0x0504,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x2b},
++ {0x23,0x0a1b,0x0c05,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x2c}, /* 1152x768 */
++ {0x24,0x0a3d,0x0c05,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x2c},
++ {0x25,0x0a7f,0x0c05,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x2c},
++ {0x29,0x0e1b,0x0c05,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x36}, /* 1152x864 */
++ {0x2a,0x0e3d,0x0c05,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x36},
++ {0x2b,0x0e7f,0x0c05,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x36},
++ {0x39,0x2a1b,0x0d06,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x38}, /* 848x480 */
++ {0x3b,0x2a3d,0x0d06,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x38},
++ {0x3e,0x2a7f,0x0d06,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x38},
++ {0x3f,0x2a1b,0x0d07,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x3a}, /* 856x480 */
++ {0x42,0x2a3d,0x0d07,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x3a},
++ {0x45,0x2a7f,0x0d07,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x3a},
++ {0x48,0x223b,0x0e08,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x3c}, /* 1360x768 */
++ {0x4b,0x227d,0x0e08,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x3c},
++ {0x4e,0x22ff,0x0e08,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x3c},
++ {0x4f,0x921f,0x0000,0x0000,SIS_RI_320x200, 0x00,0x00,0x00,0x23}, /* 320x200x32 */
++ {0x53,0x921f,0x0001,0x0000,SIS_RI_320x240, 0x00,0x00,0x00,0x24}, /* 320x240x32 */
++ {0x54,0xb21f,0x0103,0x0000,SIS_RI_400x300, 0x00,0x00,0x00,0x25}, /* 400x300x32 */
++ {0x55,0x2e3b,0x0609,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x3d}, /* 1280x768 */
++ {0x5a,0x2e7d,0x0609,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x3d},
++ {0x5b,0x2eff,0x0609,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x3d},
++ {0x5f,0x2a1b,0x0f0e,0x0000,SIS_RI_768x576, 0x00,0x00,0x00,0x3e}, /* 768x576x8 */
++ {0x60,0x2a1d,0x0f0e,0x0000,SIS_RI_768x576, 0x00,0x00,0x00,0x3e}, /* 768x576x16 */
++ {0x61,0x2a1f,0x0f0e,0x0000,SIS_RI_768x576, 0x00,0x00,0x00,0x3e}, /* 768x576x32 */
++ {0x67,0x2e3b,0x0e08,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x3f}, /* 1360x1024x8 (BARCO) */
++ {0x6f,0x2e7d,0x0e08,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x3f}, /* 1360x1024x16 (BARCO) */
++ {0x72,0x2eff,0x0e08,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x3f}, /* 1360x1024x32 (BARCO) */
++ {0xff,0x0000,0x0000,0xffff,0x00, 0x00,0x00,0x00,0x00}
+ };
+
+ typedef struct _SiS300_Ext2Struct
+@@ -514,76 +183,77 @@
+ UCHAR ModeID;
+ USHORT XRes;
+ USHORT YRes;
+- USHORT ROM_OFFSET;
+ } SiS300_Ext2Struct;
+
+ static const SiS300_Ext2Struct SiS300_RefIndex[] =
+ { /* TW: Don't ever insert anything here, table is indexed */
+- {0x085f,0x0d,0x03,0x05,0x6a, 800, 600,0x3563}, /* 00 */
+- {0x0467,0x0e,0x44,0x05,0x6a, 800, 600,0x3568}, /* 01 */
+- {0x0067,0x0f,0x07,0x48,0x6a, 800, 600,0x356d}, /* 02 - CRT1CRTC was 0x4f */
+- {0x0067,0x10,0x06,0x8b,0x6a, 800, 600,0x3572}, /* 03 */
+- {0x0147,0x11,0x08,0x00,0x6a, 800, 600,0x3577}, /* 04 */
+- {0x0147,0x12,0x0c,0x00,0x6a, 800, 600,0x357c}, /* 05 */
+- {0x0047,0x11,0x4e,0x00,0x6a, 800, 600,0x3581}, /* 06 - CRT1CRTC was 0x51 */
+- {0x0047,0x11,0x13,0x00,0x6a, 800, 600,0x3586}, /* 07 */
+- {0xc85f,0x05,0x00,0x04,0x2e, 640, 480,0x3539}, /* 08 */
+- {0xc067,0x06,0x02,0x04,0x2e, 640, 480,0x353e}, /* 09 */
+- {0xc067,0x07,0x02,0x47,0x2e, 640, 480,0x3543}, /* 0a */
+- {0xc067,0x08,0x03,0x8a,0x2e, 640, 480,0x3548}, /* 0b */
+- {0xc047,0x09,0x05,0x00,0x2e, 640, 480,0x354d}, /* 0c */
+- {0xc047,0x0a,0x08,0x00,0x2e, 640, 480,0x3552}, /* 0d */
+- {0xc047,0x0b,0x0a,0x00,0x2e, 640, 480,0x3557}, /* 0e */
+- {0xc047,0x0c,0x10,0x00,0x2e, 640, 480,0x355c}, /* 0f */
+- {0x487f,0x04,0x00,0x00,0x2f, 640, 400,0x3532}, /* 10 */
+- {0xc00f,0x31,0x01,0x06,0x31, 720, 480,0x3630}, /* 11 */
+- {0x000f,0x32,0x03,0x06,0x32, 720, 576,0x3637}, /* 12 */
+- {0x0187,0x15,0x05,0x00,0x37,1024, 768,0x358d}, /* 13 */
+- {0xc877,0x16,0x09,0x06,0x37,1024, 768,0x3592}, /* 14 */
+- {0xc067,0x17,0x0b,0x49,0x37,1024, 768,0x3597}, /* 15 - CRT1CRTC was 0x97 */
+- {0x0267,0x18,0x0d,0x00,0x37,1024, 768,0x359c}, /* 16 */
+- {0x0047,0x19,0x11,0x8c,0x37,1024, 768,0x35a1}, /* 17 - CRT1CRTC was 0x59 */
+- {0x0047,0x1a,0x52,0x00,0x37,1024, 768,0x35a6}, /* 18 */
+- {0x0007,0x1b,0x16,0x00,0x37,1024, 768,0x35ab}, /* 19 - CRT1CRTC was 0x5b */
+- {0x0387,0x1c,0x4d,0x00,0x3a,1280,1024,0x35be}, /* 1a - CRT1CRTC was 0x5c */
+- {0x0077,0x1d,0x14,0x07,0x3a,1280,1024,0x35c3}, /* 1b */
+- {0x0047,0x1e,0x17,0x00,0x3a,1280,1024,0x35c8}, /* 1c */
+- {0x0007,0x1f,0x98,0x00,0x3a,1280,1024,0x35cd}, /* 1d */
+- {0x0007,0x20,0x59,0x00,0x3c,1600,1200,0x35d4}, /* 1e - CRT1CRTC was 0x60 */
+- {0x0007,0x21,0x5a,0x00,0x3c,1600,1200,0x35d9}, /* 1f */
+- {0x0007,0x22,0x1b,0x00,0x3c,1600,1200,0x35de}, /* 20 */
+- {0x0007,0x23,0x1d,0x00,0x3c,1600,1200,0x35e3}, /* 21 - CRT1CRTC was 0x63 */
+- {0x0007,0x24,0x1e,0x00,0x3c,1600,1200,0x35e8}, /* 22 */
+- {0x407f,0x00,0x00,0x00,0x40, 320, 200,0x3516}, /* 23 */
+- {0xc07f,0x01,0x00,0x04,0x50, 320, 240,0x351d}, /* 24 */
+- {0x0077,0x02,0x04,0x05,0x51, 400, 300,0x3524}, /* 25 */
+- {0xc877,0x03,0x09,0x06,0x52, 512, 384,0x352b}, /* 26 */ /* was c077 */
+- {0x8207,0x25,0x1f,0x00,0x68,1920,1440,0x35ef}, /* 27 */
+- {0x0007,0x26,0x20,0x00,0x6c,2048,1536,0x35f6}, /* 28 */
+- {0x0067,0x27,0x14,0x08,0x6e,1280, 960,0x35b7}, /* 29 - TW: 1280x960-60 */
+- {0x0027,0x45,0x3c,0x08,0x6e,1280, 960,0x35b7}, /* 2a - TW: 1280x960-85 */
+- {0xc077,0x33,0x09,0x06,0x20,1024, 600,0x0000}, /* 2b */
+- {0xc077,0x34,0x0b,0x06,0x23,1152, 768,0x0000}, /* 2c */ /* VCLK 0x09 */
+- {0x0057,0x35,0x27,0x08,0x70, 800, 480,0x3b52}, /* 2d - TW: 16:9 modes */
+- {0x0047,0x36,0x37,0x08,0x70, 800, 480,0x3b57}, /* 2e */
+- {0x0047,0x37,0x08,0x08,0x70, 800, 480,0x3b5c}, /* 2f */
+- {0x0057,0x38,0x09,0x09,0x71,1024, 576,0x3b63}, /* 30 */
+- {0x0047,0x39,0x38,0x09,0x71,1024, 576,0x3b68}, /* 31 */
+- {0x0047,0x3a,0x11,0x09,0x71,1024, 576,0x3b6d}, /* 32 */
+- {0x0057,0x3b,0x39,0x0a,0x75,1280, 720,0x3b74}, /* 33 */
+- {0x0047,0x3c,0x3a,0x0a,0x75,1280, 720,0x3b79}, /* 34 */
+- {0x0007,0x3d,0x3b,0x0a,0x75,1280, 720,0x3b7e}, /* 35 - TW: END of 16:9 modes */
+- {0x0047,0x3e,0x34,0x06,0x29,1152, 864,0x0000}, /* 36 TW: 1152x864-75Hz - Non-BIOS, new */
+- {0x0047,0x44,0x3a,0x06,0x29,1152, 864,0x0000}, /* 37 TW: 1152x864-85Hz - Non-BIOS, new */
+- {0x00c7,0x3f,0x28,0x00,0x39, 848, 480,0x0000}, /* 38 TW: 848x480-38Hzi - Non-BIOS, new */
+- {0xc047,0x40,0x3d,0x00,0x39, 848, 480,0x0000}, /* 39 TW: 848x480-60Hz - Non-BIOS, new */
+- {0x00c7,0x41,0x28,0x00,0x3f, 856, 480,0x0000}, /* 3a TW: 856x480-38Hzi - Non-BIOS, new */
+- {0xc047,0x42,0x28,0x00,0x3f, 856, 480,0x0000}, /* 3b TW: 856x480-60Hz - Non-BIOS, new */
+- {0x0047,0x43,0x3e,0x00,0x48,1360, 768,0x0000}, /* 3c TW: 1360x768-60Hz - Non-BIOS, new */
+- {0xffff,0,0,0,0,0,0,0}
++ {0x085f,0x0d,0x03,0x05,0x6a, 800, 600}, /* 00 */
++ {0x0467,0x0e,0x44,0x05,0x6a, 800, 600}, /* 01 */
++ {0x0067,0x0f,0x07,0x48,0x6a, 800, 600}, /* 02 - CRT1CRTC was 0x4f */
++ {0x0067,0x10,0x06,0x8b,0x6a, 800, 600}, /* 03 */
++ {0x0147,0x11,0x08,0x00,0x6a, 800, 600}, /* 04 */
++ {0x0147,0x12,0x0c,0x00,0x6a, 800, 600}, /* 05 */
++ {0x0047,0x11,0x4e,0x00,0x6a, 800, 600}, /* 06 - CRT1CRTC was 0x51 */
++ {0x0047,0x11,0x13,0x00,0x6a, 800, 600}, /* 07 */
++ {0xc85f,0x05,0x00,0x04,0x2e, 640, 480}, /* 08 */
++ {0xc067,0x06,0x02,0x04,0x2e, 640, 480}, /* 09 */
++ {0xc067,0x07,0x02,0x47,0x2e, 640, 480}, /* 0a */
++ {0xc067,0x08,0x03,0x8a,0x2e, 640, 480}, /* 0b */
++ {0xc047,0x09,0x05,0x00,0x2e, 640, 480}, /* 0c */
++ {0xc047,0x0a,0x08,0x00,0x2e, 640, 480}, /* 0d */
++ {0xc047,0x0b,0x0a,0x00,0x2e, 640, 480}, /* 0e */
++ {0xc047,0x0c,0x10,0x00,0x2e, 640, 480}, /* 0f */
++ {0x487f,0x04,0x00,0x00,0x2f, 640, 400}, /* 10 */
++ {0xc00f,0x31,0x01,0x06,0x31, 720, 480}, /* 11 */
++ {0x000f,0x32,0x03,0x06,0x32, 720, 576}, /* 12 */
++ {0x0187,0x15,0x05,0x00,0x37,1024, 768}, /* 13 */
++ {0xc877,0x16,0x09,0x06,0x37,1024, 768}, /* 14 */
++ {0xc067,0x17,0x0b,0x49,0x37,1024, 768}, /* 15 - CRT1CRTC was 0x97 */
++ {0x0267,0x18,0x0d,0x00,0x37,1024, 768}, /* 16 */
++ {0x0047,0x19,0x11,0x8c,0x37,1024, 768}, /* 17 - CRT1CRTC was 0x59 */
++ {0x0047,0x1a,0x52,0x00,0x37,1024, 768}, /* 18 */
++ {0x0007,0x1b,0x16,0x00,0x37,1024, 768}, /* 19 - CRT1CRTC was 0x5b */
++ {0x0387,0x1c,0x4d,0x00,0x3a,1280,1024}, /* 1a - CRT1CRTC was 0x5c */
++ {0x0077,0x1d,0x14,0x07,0x3a,1280,1024}, /* 1b */
++ {0x0047,0x1e,0x17,0x00,0x3a,1280,1024}, /* 1c */
++ {0x0007,0x1f,0x98,0x00,0x3a,1280,1024}, /* 1d */
++ {0x0007,0x20,0x59,0x00,0x3c,1600,1200}, /* 1e - CRT1CRTC was 0x60 */
++ {0x0007,0x21,0x5a,0x00,0x3c,1600,1200}, /* 1f */
++ {0x0007,0x22,0x1b,0x00,0x3c,1600,1200}, /* 20 */
++ {0x0007,0x23,0x1d,0x00,0x3c,1600,1200}, /* 21 - CRT1CRTC was 0x63 */
++ {0x0007,0x24,0x1e,0x00,0x3c,1600,1200}, /* 22 */
++ {0x407f,0x00,0x00,0x00,0x40, 320, 200}, /* 23 */
++ {0xc07f,0x01,0x00,0x04,0x50, 320, 240}, /* 24 */
++ {0x0077,0x02,0x04,0x05,0x51, 400, 300}, /* 25 */
++ {0xc877,0x03,0x09,0x06,0x52, 512, 384}, /* 26 */ /* was c077 */
++ {0x8207,0x25,0x1f,0x00,0x68,1920,1440}, /* 27 */
++ {0x0007,0x26,0x20,0x00,0x6c,2048,1536}, /* 28 */
++ {0x0067,0x27,0x14,0x08,0x6e,1280, 960}, /* 29 - TW: 1280x960-60 */
++ {0x0027,0x45,0x3c,0x08,0x6e,1280, 960}, /* 2a - TW: 1280x960-85 */
++ {0xc077,0x33,0x09,0x06,0x20,1024, 600}, /* 2b */
++ {0xc077,0x34,0x0b,0x06,0x23,1152, 768}, /* 2c */ /* VCLK 0x09 */
++ {0x0057,0x35,0x27,0x08,0x70, 800, 480}, /* 2d */
++ {0x0047,0x36,0x37,0x08,0x70, 800, 480}, /* 2e */
++ {0x0047,0x37,0x08,0x08,0x70, 800, 480}, /* 2f */
++ {0x0057,0x38,0x09,0x09,0x71,1024, 576}, /* 30 */
++ {0x0047,0x39,0x38,0x09,0x71,1024, 576}, /* 31 */
++ {0x0047,0x3a,0x11,0x09,0x71,1024, 576}, /* 32 */
++ {0x0057,0x3b,0x39,0x0a,0x75,1280, 720}, /* 33 */
++ {0x0047,0x3c,0x3a,0x0a,0x75,1280, 720}, /* 34 */
++ {0x0007,0x3d,0x3b,0x0a,0x75,1280, 720}, /* 35 */
++ {0x0047,0x3e,0x34,0x06,0x29,1152, 864}, /* 36 1152x864-75Hz */
++ {0x0047,0x44,0x3a,0x06,0x29,1152, 864}, /* 37 1152x864-85Hz */
++ {0x00c7,0x3f,0x28,0x00,0x39, 848, 480}, /* 38 848x480-38Hzi */
++ {0xc067,0x40,0x3d,0x0b,0x39, 848, 480}, /* 39 848x480-60Hz */
++ {0x00c7,0x41,0x28,0x00,0x3f, 856, 480}, /* 3a 856x480-38Hzi */
++ {0xc047,0x42,0x28,0x00,0x3f, 856, 480}, /* 3b 856x480-60Hz */
++ {0x0067,0x43,0x3e,0x0c,0x48,1360, 768}, /* 3c 1360x768-60Hz */
++ {0x0077,0x46,0x3f,0x08,0x55,1280, 768}, /* 3d 1280x768-60Hz */
++ {0x000f,0x47,0x03,0x06,0x5f, 768, 576}, /* 3e 768x576 */
++ {0x0027,0x48,0x13,0x08,0x67,1360,1024}, /* 3f 1360x1024-59Hz (BARCO1366 only) */
++ {0xffff, 0, 0, 0, 0, 0, 0}
+ };
+
+-/*add for 300 oem util*/
+ typedef struct _SiS_VBModeIDTableStruct
+ {
+ UCHAR ModeID;
+@@ -649,9 +319,8 @@
+ {0x6e,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
+ {0x6f,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
+ {0x7b,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
+- {0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00} /* TW: added! */
++ {0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
+ };
+-/*end*/
+
+ typedef struct _SiS300_CRT1TableStruct
+ {
+@@ -660,15 +329,32 @@
+
+ static const SiS300_CRT1TableStruct SiS300_CRT1Table[] =
+ {
+- {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f, /* 0x00 */
+- 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00,
++#if 1
++ {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f, /* 0x00 - 320x200 */
++ 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00, /* HRE [4],[15] is invalid - but correcting it does not work */
++ 0x00}},
++#endif
++#if 0
++ {{0x2d,0x27,0x27,0x91,0x2c,0x92,0xbf,0x1f, /* 0x00 - corrected 320x200-72 - does not work */
++ 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x04,
+ 0x00}},
+- {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e,
+- 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,
++#endif
++ {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e, /* 0x01 */
++ 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00, /* HRE [4],[15] is invalid - but correcting it does not work */
+ 0x00}},
+- {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0,
++#if 0
++ {{0x2d,0x27,0x27,0x91,0x2c,0x92,0x0b,0x3e, /* 0x01 - corrected 320x240-60 - does not work */
++ 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x04,
++ 0x00}},
++#endif
++ {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0, /* 0x02 */
++ 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
++ 0x01}},
++#if 0
++ {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0, /* 0x02 - corrected 400x300-60 */
+ 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
+ 0x01}},
++#endif
+ {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+ 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01,
+ 0x01}},
+@@ -683,7 +369,7 @@
+ {{0x5f,0x4f,0x4f,0x83,0x55,0x81,0x0b,0x3e, /* 0x05 - corrected 640x480-60 */
+ 0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x05,
+ 0x00}},
+- #if 0
++#if 0
+ {{0x63,0x4f,0x50,0x86,0x56,0x9b,0x06,0x3e, /* 0x06 */
+ 0xe8,0x8b,0xdf,0xe7,0xff,0x10,0x00,0x01,
+ 0x00}},
+@@ -841,15 +527,10 @@
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1, /* 0x33 - 1024x600 */
+ 0xae,0x85,0x57,0x57,0x1f,0x30,0x00,0x02,
+ 0x01}},
+-#if 0
+- {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5, /* 0x34 - 1152x768 */
+- 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+- 0x01}},
+-#endif
+- {{0xa3,0x8f,0x8f,0x97,0x96,0x97,0x24,0xf5, /* 0x34 - 1152x768 - TW: corrected */
++ {{0xa3,0x8f,0x8f,0x97,0x96,0x97,0x24,0xf5, /* 0x34 - 1152x768 - corrected */
+ 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+ 0x01}},
+- {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba, /* 0x35 - NEW 16:9 modes, not in BIOS ------ */
++ {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba, /* 0x35 */
+ 0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06,
+ 0x01}}, /* 0x35 */
+ {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xba,
+@@ -864,7 +545,7 @@
+ {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1,
+ 0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02,
+ 0x01}}, /* 0x39 */
+- {{0xa7,0x7f,0x7f,0x88,0x89,0x95,0x26,0xf1, /* TW: 95 was 15 - illegal HBE! */
++ {{0xa7,0x7f,0x7f,0x88,0x89,0x95,0x26,0xf1, /* 95 was 15 - illegal HBE! */
+ 0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02,
+ 0x01}}, /* 0x3a */
+ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4,
+@@ -875,36 +556,40 @@
+ 0x01}}, /* 0x3c */
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xd4,
+ 0x7d,0x81,0xcf,0xcf,0x2f,0x21,0x00,0x07,
+- 0x01}}, /* 0x3d */ /* TW: End of 16:9 modes --------------- */
+- {{0xc3,0x8f,0x8f,0x87,0x9b,0x0b,0x82,0xef, /* TW: New, 1152x864-75 (not in any BIOS) */
++ 0x01}}, /* 0x3d */
++ {{0xc3,0x8f,0x8f,0x87,0x9b,0x0b,0x82,0xef, /* 1152x864-75 */
+ 0x60,0x83,0x5f,0x5f,0x83,0x10,0x00,0x07,
+ 0x01}}, /* 0x3e */
+- {{0x86,0x69,0x69,0x8A,0x74,0x06,0x8C,0x15, /* TW: New, 848x480-38i, not in BIOS */
++ {{0x86,0x69,0x69,0x8A,0x74,0x06,0x8C,0x15, /* 848x480-38i */
+ 0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
+ 0x00}}, /* 0x3f */
+-#if 0
+- {{0x81,0x69,0x69,0x85,0x70,0x00,0x0F,0x3E, /* TW: New, 848x480-60, not in BIOS - incorrect for Philips panel */
+- 0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02,
+- 0x00}}, /* 0x40 */
+-#endif
+- {{0x83,0x69,0x69,0x87,0x6f,0x1d,0x03,0x3E, /* TW: New, 848x480-60, not in BIOS */
++ {{0x83,0x69,0x69,0x87,0x6f,0x1d,0x03,0x3E, /* 848x480-60 */
+ 0xE5,0x8d,0xDF,0xe4,0x04,0x00,0x00,0x06,
+ 0x00}}, /* 0x40 */
+- {{0x86,0x6A,0x6A,0x8A,0x74,0x06,0x8C,0x15, /* TW: New, 856x480-38i, not in BIOS */
++ {{0x86,0x6A,0x6A,0x8A,0x74,0x06,0x8C,0x15, /* 856x480-38i */
+ 0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
+ 0x00}}, /* 0x41 */
+- {{0x81,0x6A,0x6A,0x85,0x70,0x00,0x0F,0x3E, /* TW: New, 856x480-60, not in BIOS */
++ {{0x81,0x6A,0x6A,0x85,0x70,0x00,0x0F,0x3E, /* 856x480-60 */
+ 0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02,
+ 0x00}}, /* 0x42 */
+- {{0xdd,0xa9,0xa9,0x81,0xb4,0x97,0x26,0xfd, /* TW: New, 1360x768-60, not in BIOS */
++ {{0xdd,0xa9,0xa9,0x81,0xb4,0x97,0x26,0xfd, /* 1360x768-60 */
+ 0x01,0x8d,0xff,0x00,0x27,0x10,0x00,0x03,
+ 0x01}}, /* 0x43 */
+- {{0xd9,0x8f,0x8f,0x9d,0xba,0x0a,0x8a,0xff, /* TW: New, 1152x864-84 (not in any BIOS) */
++ {{0xd9,0x8f,0x8f,0x9d,0xba,0x0a,0x8a,0xff, /* 1152x864-84 */
+ 0x60,0x8b,0x5f,0x5f,0x8b,0x10,0x00,0x03,
+- 0x01}}, /* 0x44 */
+- {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff, /* TW: New, 1280x960-85 (not in any BIOS) */
++ 0x01}}, /* 0x44 */
++ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff, /* 1280x960-85 */
+ 0xc0,0x83,0xbf,0xbf,0xf2,0x10,0x00,0x07,
+- 0x01}} /* 0x45 */
++ 0x01}}, /* 0x45 */
++ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x20,0xf5, /* 1280x768-60 */
++ 0x03,0x88,0xff,0xff,0x21,0x10,0x00,0x07,
++ 0x01}}, /* 0x46 */
++ {{0x7b,0x5f,0x63,0x9f,0x6a,0x93,0x6f,0xf0, /* 768x576 */
++ 0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05,
++ 0x01}}, /* 0x47 */
++ {{0xce,0xa9,0xa9,0x92,0xb1,0x07,0x28,0x52, /* 1360x1024 (Barco iQ Pro R300) */
++ 0x02,0x8e,0xff,0x00,0x29,0x0d,0x00,0x03,
++ 0x00}} /* 0x48 */
+ };
+
+ typedef struct _SiS300_MCLKDataStruct
+@@ -913,8 +598,8 @@
+ USHORT CLOCK;
+ } SiS300_MCLKDataStruct;
+
+-static const SiS300_MCLKDataStruct SiS300_MCLKData_630[] = /* 630 */
+-{ /* TW: at 0x54 in BIOS */
++static const SiS300_MCLKDataStruct SiS300_MCLKData_630[] =
++{
+ { 0x5a,0x64,0x80, 66},
+ { 0xb3,0x45,0x80, 83},
+ { 0x37,0x61,0x80,100},
+@@ -925,8 +610,8 @@
+ { 0x37,0x61,0x80,100}
+ };
+
+-static const SiS300_MCLKDataStruct SiS300_MCLKData_300[] = /* 300 */
+-{ /* TW: at 0x54 in BIOS */
++static const SiS300_MCLKDataStruct SiS300_MCLKData_300[] =
++{
+ { 0x68,0x43,0x80,125},
+ { 0x68,0x43,0x80,125},
+ { 0x68,0x43,0x80,125},
+@@ -937,6 +622,7 @@
+ { 0x37,0x61,0x80,100}
+ };
+
++#ifdef LINUXBIOS
+ typedef struct _SiS300_ECLKDataStruct
+ {
+ UCHAR SR2E,SR2F,SR30;
+@@ -954,6 +640,7 @@
+ { 0x54,0x43,0x80,100},
+ { 0x54,0x43,0x80,100}
+ };
++#endif
+
+ typedef struct _SiS300_VCLKDataStruct
+ {
+@@ -964,71 +651,77 @@
+ static const SiS300_VCLKDataStruct SiS300_VCLKData[] =
+ {
+ { 0x1b,0xe1, 25}, /* 0x00 */
+- { 0x4e,0xe4, 28},
++ { 0x4e,0xe4, 28}, /* 0x01 */
+ { 0x57,0xe4, 32}, /* 0x02 */
+- { 0xc3,0xc8, 36},
++ { 0xc3,0xc8, 36}, /* 0x03 */
+ { 0x42,0xc3, 40}, /* 0x04 */
+- { 0x5d,0xc4, 45},
++ { 0x5d,0xc4, 45}, /* 0x05 */
+ { 0x52,0x65, 50}, /* 0x06 */
+- { 0x53,0x65, 50},
++ { 0x53,0x65, 50}, /* 0x07 */
+ { 0x6d,0x66, 56}, /* 0x08 */
+- { 0x5a,0x64, 65},
++ { 0x5a,0x64, 65}, /* 0x09 */
+ { 0x46,0x44, 68}, /* 0x0a */
+- { 0x3e,0x43, 75},
+- { 0x6d,0x46, 76}, /* 0x0c: 800x600 | LVDS_2(CH), MITAC(CH); - 730, A901(301B): 0xb1,0x46, 76 */
+- { 0x41,0x43, 79},
++ { 0x3e,0x43, 75}, /* 0x0b */
++ { 0x6d,0x46, 76}, /* 0x0c */ /* 800x600 | LVDS_2(CH), MITAC(CH); - 730, A901(301B): 0xb1,0x46, 76 */
++ { 0x41,0x43, 79}, /* 0x0d */
+ { 0x31,0x42, 79}, /* 0x0e */
+- { 0x46,0x25, 85},
++ { 0x46,0x25, 85}, /* 0x0f */
+ { 0x78,0x29, 87}, /* 0x10 */
+- { 0x62,0x44, 95},
++ { 0x62,0x44, 95}, /* 0x11 */
+ { 0x2b,0x22,105}, /* 0x12 */
+- { 0x49,0x24,106},
++ { 0x49,0x24,106}, /* 0x13 */
+ { 0xc3,0x28,108}, /* 0x14 */
+- { 0x3c,0x23,109},
++ { 0x3c,0x23,109}, /* 0x15 */
+ { 0xf7,0x2c,132}, /* 0x16 */
+- { 0xd4,0x28,136},
++ { 0xd4,0x28,136}, /* 0x17 */
+ { 0x41,0x05,158}, /* 0x18 */
+- { 0x43,0x05,162},
++ { 0x43,0x05,162}, /* 0x19 */
+ { 0xe1,0x0f,175}, /* 0x1a */
+ { 0xfc,0x12,189}, /* 0x1b */
+ { 0xde,0x26,194}, /* 0x1c */
+- { 0x54,0x05,203},
++ { 0x54,0x05,203}, /* 0x1d */
+ { 0x3f,0x03,230}, /* 0x1e */
+- { 0x30,0x02,234},
++ { 0x30,0x02,234}, /* 0x1f */
+ { 0x24,0x01,266}, /* 0x20 */
+- { 0x52,0x2a, 54}, /* 301 TV */
+- { 0x52,0x6a, 27}, /* 301 TV */
+- { 0x62,0x24, 70}, /* 301 TV */
+- { 0x62,0x64, 70}, /* 301 TV */
+- { 0xa8,0x4c, 30}, /* 301 TV */
+- { 0x20,0x26, 33}, /* 301 TV */
+- { 0x31,0xc2, 39},
+- { 0xbf,0xc8, 35}, /* 0x28 - 856x480 */
+- { 0x60,0x36, 30}, /* 0x29 CH/UNTSC TEXT | LVDS_2(CH) - 730, A901(301B), Mitac(CH): 0xe0, 0xb6, 30 */
+- { 0x40,0x4a, 28},
+- { 0x9f,0x46, 44},
+- { 0x97,0x2c, 26},
+- { 0x44,0xe4, 25},
+- { 0x7e,0x32, 47},
+- { 0x8a,0x24, 31}, /* 0x2f CH/PAL TEXT | LVDS_2(CH), Mitac(CH) - 730, A901(301B): 0x57, 0xe4, 31 */
+- { 0x97,0x2c, 26},
+- { 0xce,0x3c, 39},
+- { 0x52,0x4a, 36}, /* 0x32 CH/PAL 800x600 5/6 */
+- { 0x34,0x61, 95},
+- { 0x78,0x27,108},
+- { 0xce,0x25,189}, /* 0x35 */
+- { 0x45,0x6b, 21}, /* 0x36 */ /* TW: Added from Mitac */
+- { 0x52,0xe2, 49}, /* 0x37 - added for 16:9 modes (not in any BIOS) */
+- { 0x2b,0x61, 78}, /* 0x38 - added for 16:9 modes (not in any BIOS) */
+- { 0x70,0x44,108}, /* 0x39 - added for 16:9 modes (not in any BIOS) */
+- { 0x54,0x42,135}, /* 0x3a - added for 16:9 modes (not in any BIOS) */
+- { 0x41,0x22,157}, /* 0x3b - added for 16:9 modes (not in any BIOS) */
+- { 0x52,0x07,149}, /* 0x3c - added for 1280x960-85 (not in any BIOS)*/
+- { 0x62,0xc6, 34}, /* 0x3d - added for 848x480-60 (not in any BIOS) */
+- { 0x30,0x23, 88}, /* 0x3e - added for 1360x768-60 (not in any BIOS)*/
+- { 0x3f,0x64, 46}, /* 0x3f - added for 640x480-100 (not in any BIOS)*/
+- { 0x72,0x2a, 76}, /* 0x40 - test for SiS730 */
+- { 0x15,0x21, 79}, /* 0x41 - test for SiS730 */
++ { 0x52,0x2a, 54}, /* 0x21 */ /* 301 TV */
++ { 0x52,0x6a, 27}, /* 0x22 */ /* 301 TV */
++ { 0x62,0x24, 70}, /* 0x23 */ /* 301 TV */
++ { 0x62,0x64, 70}, /* 0x24 */ /* 301 TV */
++ { 0xa8,0x4c, 30}, /* 0x25 */ /* 301 TV */
++ { 0x20,0x26, 33}, /* 0x26 */ /* 301 TV */
++ { 0x31,0xc2, 39}, /* 0x27 */
++ { 0xbf,0xc8, 35}, /* 0x28 */ /* 856x480 */
++ { 0x60,0x36, 30}, /* 0x29 */ /* CH/UNTSC TEXT | LVDS_2(CH) - 730, A901(301B), Mitac(CH): 0xe0, 0xb6, 30 */
++ { 0x40,0x4a, 28}, /* 0x2a */
++ { 0x9f,0x46, 44}, /* 0x2b */
++ { 0x97,0x2c, 26}, /* 0x2c */
++ { 0x44,0xe4, 25}, /* 0x2d */
++ { 0x7e,0x32, 47}, /* 0x2e */
++ { 0x8a,0x24, 31}, /* 0x2f */ /* CH/PAL TEXT | LVDS_2(CH), Mitac(CH) - 730, A901(301B): 0x57, 0xe4, 31 */
++ { 0x97,0x2c, 26}, /* 0x30 */
++ { 0xce,0x3c, 39}, /* 0x31 */
++ { 0x52,0x4a, 36}, /* 0x32 */ /* CH/PAL 800x600 5/6 */
++ { 0x34,0x61, 95}, /* 0x33 */
++ { 0x78,0x27,108}, /* 0x34 */ /* Replacement for index 0x14 for 630 (?) */
++ { 0xce,0x25,189}, /* 0x35 */ /* Replacement for index 0x1b for 730 (and 540?) */
++ { 0x45,0x6b, 21}, /* 0x36 */
++ { 0x52,0xe2, 49}, /* 0x37 */ /* 16:9 modes */
++ { 0x2b,0x61, 78}, /* 0x38 */ /* 16:9 modes */
++ { 0x70,0x44,108}, /* 0x39 */ /* 16:9 modes */
++ { 0x54,0x42,135}, /* 0x3a */ /* 16:9 modes */
++ { 0x41,0x22,157}, /* 0x3b */ /* 16:9 modes */
++ { 0x52,0x07,149}, /* 0x3c */ /* 1280x960-85 */
++ { 0x62,0xc6, 34}, /* 0x3d */ /* 848x480-60 */
++ { 0x30,0x23, 88}, /* 0x3e */ /* 1360x768-60 */
++#if 0
++ { 0x3f,0x64, 46}, /* 0x3f */ /* 640x480-100 */
++#endif
++ { 0x70,0x29, 81}, /* 0x3f */ /* 1280x768-60 */
++ { 0x72,0x2a, 76}, /* 0x40 */ /* test for SiS730 */
++ { 0x15,0x21, 79}, /* 0x41 */ /* test for SiS730 */
++ { 0xa1,0x42,108}, /* 0x42 */ /* 1280x960 LCD */
++ { 0x37,0x61,100}, /* 0x43 */ /* 1280x960 LCD */
++ { 0xe3,0x9a,106}, /* 0x44 */ /* 1360x1024 - special for Barco iQ R300 */
+ { 0xff,0x00, 0}
+ };
+
+@@ -1089,66 +782,10 @@
+ static const UCHAR SiS300_ScreenOffset[] =
+ {
+ 0x14,0x19,0x20,0x28,0x32,0x40,0x50,
+- 0x64,0x78,0x80,0x2d,0x35,0x48,0x35, /* 0x35 for 848 and 856 */
+- 0x55,0xff /* 0x55 for 1360 */
++ 0x64,0x78,0x80,0x2d,0x35,0x48,0x35,
++ 0x55,0x30,0xff
+ };
+
+-typedef struct _SiS300_StResInfoStruct
+-{
+- USHORT HTotal;
+- USHORT VTotal;
+-} SiS300_StResInfoStruct;
+-
+-static const SiS300_StResInfoStruct SiS300_StResInfo[] =
+-{
+- { 640,400},
+- { 640,350},
+- { 720,400},
+- { 720,350},
+- { 640,480}
+-};
+-
+-typedef struct _SiS300_ModeResInfoStruct
+-{
+- USHORT HTotal;
+- USHORT VTotal;
+- UCHAR XChar;
+- UCHAR YChar;
+-} SiS300_ModeResInfoStruct;
+-
+-static const SiS300_ModeResInfoStruct SiS300_ModeResInfo[] =
+-{
+- { 320, 200, 8, 8}, /* 0x00 */
+- { 320, 240, 8, 8}, /* 0x01 */
+- { 320, 400, 8, 8}, /* 0x02 */
+- { 400, 300, 8, 8}, /* 0x03 */
+- { 512, 384, 8, 8}, /* 0x04 */
+- { 640, 400, 8,16}, /* 0x05 */
+- { 640, 480, 8,16}, /* 0x06 */
+- { 800, 600, 8,16}, /* 0x07 */
+- { 1024, 768, 8,16}, /* 0x08 */
+- { 1280,1024, 8,16}, /* 0x09 */
+- { 1600,1200, 8,16}, /* 0x0a */
+- { 1920,1440, 8,16}, /* 0x0b */
+- { 720, 480, 8,16}, /* 0x0c */
+- { 720, 576, 8,16}, /* 0x0d */
+- { 1280, 960, 8,16}, /* 0x0e */
+- { 1024, 600, 8,16}, /* 0x0f */
+- { 1152, 768, 8,16}, /* 0x10 */
+- { 2048,1536, 8,16}, /* 0x11 - TW: Not in BIOS! */
+- { 800, 480, 8,16}, /* 0x12 - TW: New, not in any BIOS */
+- { 1024, 576, 8,16}, /* 0x13 - TW: New, not in any BIOS */
+- { 1280, 720, 8,16}, /* 0x14 - TW: New, not in any BIOS */
+- { 1152, 864, 8,16}, /* 0x15 - TW: New, not in any BIOS */
+- { 848, 480, 8,16}, /* 0x16 - TW: New, not in any BIOS */
+- { 856, 480, 8,16}, /* 0x17 - TW: New, not in any BIOS */
+- { 1360, 768, 8,16} /* 0x18 - TW: New, not in any BIOS */
+-};
+-
+-static const UCHAR SiS300_OutputSelect = 0x40;
+-
+-static const UCHAR SiS300_SoftSetting = 0x30;
+-
+ #ifndef LINUX_XF86
+ static UCHAR SiS300_SR07 = 0x10;
+ #endif
+@@ -1183,7 +820,7 @@
+ static const USHORT SiS300_RGBSenseData = 0xd1;
+ static const USHORT SiS300_VideoSenseData = 0xb3;
+ static const USHORT SiS300_YCSenseData = 0xb9;
+-static const USHORT SiS300_RGBSenseData2 = 0x0190; /*301b*/
++static const USHORT SiS300_RGBSenseData2 = 0x0190;
+ static const USHORT SiS300_VideoSenseData2 = 0x0174;
+ static const USHORT SiS300_YCSenseData2 = 0x016b;
+
+@@ -1192,15 +829,6 @@
+ static UCHAR SiS300_CR49[2];
+ #endif
+
+-static const UCHAR SiS300_NTSCPhase[] = {0x21,0xed,0xba,0x08}; /* TW: Was {0x21,0xed,0x8a,0x08}; */
+-static const UCHAR SiS300_PALPhase[] = {0x2a,0x05,0xe3,0x00}; /* TW: Was {0x2a,0x05,0xd3,0x00}; */
+-static const UCHAR SiS300_PALMPhase[] = {0x21,0xE4,0x2E,0x9B}; /* palmn */
+-static const UCHAR SiS300_PALNPhase[] = {0x21,0xF4,0x3E,0xBA};
+-static const UCHAR SiS300_NTSCPhase2[] = {0x21,0xF0,0x7B,0xD6}; /* 301b */
+-static const UCHAR SiS300_PALPhase2[] = {0x2a,0x09,0x86,0xe9}; /* 301b */
+-static const UCHAR SiS300_PALMPhase2[] = {0x21,0xE6,0xEF,0xA4}; /* TW: palm 301b*/
+-static const UCHAR SiS300_PALNPhase2[] = {0x21,0xF6,0x94,0x46}; /* TW: paln 301b*/
+-
+ typedef struct _SiS300_PanelDelayTblStruct
+ {
+ UCHAR timer[2];
+@@ -1208,7 +836,7 @@
+
+ static const SiS300_PanelDelayTblStruct SiS300_PanelDelayTbl[] =
+ {
+- {{0x05,0xaa}}, /* TW: From 2.04.5a */
++ {{0x05,0xaa}},
+ {{0x05,0x14}},
+ {{0x05,0x36}},
+ {{0x05,0x14}},
+@@ -1355,309 +983,6 @@
+ { 1, 1,1688,1066,1688,1066}
+ };
+
+-static const SiS300_LCDDataStruct SiS300_LCD1280x960Data[] =
+-{
+- { 9, 2, 800, 500,1800,1000},
+- { 9, 2, 800, 500,1800,1000},
+- { 4, 1, 900, 500,1800,1000},
+- { 4, 1, 900, 500,1800,1000},
+- { 9, 2, 800, 500,1800,1000},
+- { 30, 11,1056, 625,1800,1000},
+- { 5, 3,1350, 800,1800,1000},
+- { 1, 1,1576,1050,1576,1050},
+- { 1, 1,1800,1000,1800,1000}
+-};
+-
+-static const SiS300_LCDDataStruct SiS300_ExtLCD1400x1050Data[] = /* TW: New */
+-{
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0}
+-};
+-
+-static const SiS300_LCDDataStruct SiS300_ExtLCD1600x1200Data[] = /* TW: New */
+-{
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0}
+-};
+-
+-static const SiS300_LCDDataStruct SiS300_StLCD1400x1050Data[] = /* TW: New */
+-{
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0}
+-};
+-
+-static const SiS300_LCDDataStruct SiS300_StLCD1600x1200Data[] = /* TW: New */
+-{
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0}
+-};
+-
+-static const SiS300_LCDDataStruct SiS300_NoScaleData1400x1050[] = /* TW: New */
+-{
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0}
+-};
+-
+-static const SiS300_LCDDataStruct SiS300_NoScaleData1600x1200[] = /* TW: New */
+-{
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0},
+- { 0, 0, 0, 0, 0, 0}
+-};
+-
+-
+-typedef struct _SiS300_TVDataStruct
+-{
+- USHORT RVBHCMAX;
+- USHORT RVBHCFACT;
+- USHORT VGAHT;
+- USHORT VGAVT;
+- USHORT TVHDE;
+- USHORT TVVDE;
+- USHORT RVBHRS;
+- UCHAR FlickerMode;
+- USHORT HALFRVBHRS;
+- UCHAR RY1COE;
+- UCHAR RY2COE;
+- UCHAR RY3COE;
+- UCHAR RY4COE;
+-} SiS300_TVDataStruct;
+-
+-static const SiS300_TVDataStruct SiS300_StPALData[] =
+-{
+- { 1, 1, 864, 525,1270, 400, 100, 0, 760,0xf4,0xff,0x1c,0x22},
+- { 1, 1, 864, 525,1270, 350, 100, 0, 760,0xf4,0xff,0x1c,0x22},
+- { 1, 1, 864, 525,1270, 400, 0, 0, 720,0xf1,0x04,0x1f,0x18},
+- { 1, 1, 864, 525,1270, 350, 0, 0, 720,0xf4,0x0b,0x1c,0x0a},
+- { 1, 1, 864, 525,1270, 480, 50, 0, 760,0xf4,0xff,0x1c,0x22},
+- { 1, 1, 864, 525,1270, 600, 50, 0, 0,0xf4,0xff,0x1c,0x22}
+-};
+-
+-static const SiS300_TVDataStruct SiS300_ExtPALData[] =
+-{
+- { 27, 10, 848, 448,1270, 530, 50, 0, 50,0xf4,0xff,0x1c,0x22},
+- { 108, 35, 848, 398,1270, 530, 50, 0, 50,0xf4,0xff,0x1c,0x22},
+- { 12, 5, 954, 448,1270, 530, 50, 0, 50,0xf1,0x04,0x1f,0x18},
+- { 9, 4, 960, 463,1644, 438, 50, 0, 50,0xf4,0x0b,0x1c,0x0a},
+- { 9, 4, 848, 528,1270, 530, 0, 0, 50,0xf5,0xfb,0x1b,0x2a},
+- { 36, 25,1060, 648,1316, 530, 438, 0, 438,0xeb,0x05,0x25,0x16},
+- { 3, 2,1080, 619,1270, 540, 438, 0, 438,0xf3,0x00,0x1d,0x20},
+- { 1, 1,1170, 821,1270, 520, 686, 0, 686,0xF3,0x00,0x1D,0x20}
+-
+-};
+-
+-static const SiS300_TVDataStruct SiS300_StNTSCData[] =
+-{
+- { 1, 1, 858, 525,1270, 400, 50, 0, 760,0xf1,0x04,0x1f,0x18},
+- { 1, 1, 858, 525,1270, 350, 50, 0, 640,0xf1,0x04,0x1f,0x18},
+- { 1, 1, 858, 525,1270, 400, 0, 0, 720,0xf1,0x04,0x1f,0x18},
+- { 1, 1, 858, 525,1270, 350, 0, 0, 720,0xf4,0x0b,0x1c,0x0a},
+- { 1, 1, 858, 525,1270, 480, 0, 0, 760,0xf1,0x04,0x1f,0x18}
+-};
+-
+-static const SiS300_TVDataStruct SiS300_ExtNTSCData[] =
+-{
+- { 143, 65, 858, 443,1270, 440, 171, 0, 171,0xf1,0x04,0x1f,0x18},
+- { 88, 35, 858, 393,1270, 440, 171, 0, 171,0xf1,0x04,0x1f,0x18},
+- { 143, 70, 924, 443,1270, 440, 92, 0, 92,0xf1,0x04,0x1f,0x18},
+- { 143, 70, 924, 393,1270, 440, 92, 0, 92,0xf4,0x0b,0x1c,0x0a},
+- { 143, 76, 836, 523,1270, 440, 224, 0, 0,0xf1,0x05,0x1f,0x16},
+- { 143, 120,1056, 643,1270, 440, 0, 128, 0,0xf4,0x10,0x1c,0x00},
+- { 143, 76, 836, 523,1270, 440, 0, 128, 0,0xee,0x0c,0x22,0x08},
+- { 65, 64,1056, 791,1270, 480, 638, 0, 0,0xf1,0x04,0x1f,0x18}
+-};
+-
+-#if 0
+-static const SiS300_TVDataStruct SiS300_St1HiTVData[]=
+-{
+-
+-};
+-#endif
+-
+-static const SiS300_TVDataStruct SiS300_St2HiTVData[]=
+-{
+- { 3, 1, 0x348,0x1e3,0x670,0x3c0,0x032, 0, 0, 0x00,0x00,0x00,0x00},
+- { 1, 1, 0x37c,0x233,0x2b2,0x2bc, 0, 0, 0, 0x00,0x00,0x00,0x00},
+- { 3, 1, 0x348,0x1e3,0x670,0x3c0,0x032, 0, 0, 0x00,0x00,0x00,0x00},
+- { 1, 1, 0x3e8,0x233,0x311,0x2bc, 0, 0, 0, 0x00,0x00,0x00,0x00},
+- { 5, 2, 0x348,0x233,0x670,0x3c0,0x08d,128, 0, 0x00,0x00,0x00,0x00},
+- { 8, 5, 0x41a,0x2ab,0x670,0x3c0,0x17c,128, 0, 0x00,0x00,0x00,0x00}
+-};
+-
+-static const SiS300_TVDataStruct SiS300_ExtHiTVData[]=
+-{
+- { 6, 1, 0x348,0x233,0x660,0x3c0, 0, 0, 0, 0x00,0x00,0x00,0x00},
+- { 3, 1, 0x3c0,0x233,0x660,0x3c0, 0, 0, 0, 0x00,0x00,0x00,0x00},
+- { 3, 1, 0x348,0x1e3,0x660,0x3c0, 0, 0, 0, 0x00,0x00,0x00,0x00},
+- { 3, 1, 0x3c0,0x233,0x660,0x3c0, 0, 0, 0, 0x00,0x00,0x00,0x00},
+- { 5, 1, 0x348,0x233,0x670,0x3c0,0x166,128, 0, 0x00,0x00,0x00,0x00},
+- { 16, 5, 0x41a,0x2ab,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},
+- { 25, 12, 0x4ec,0x353,0x670,0x3c0,0x032, 0, 0, 0x00,0x00,0x00,0x00},
+- { 5, 4, 0x627,0x464,0x670,0x3c0,0x128, 0, 0, 0x00,0x00,0x00,0x00},
+- { 4, 1, 0x41a,0x233,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},
+- { 5, 2, 0x578,0x293,0x670,0x3c0,0x032, 0, 0, 0x00,0x00,0x00,0x00},
+- { 8, 5, 0x6d6,0x323,0x670,0x3c0,0x128, 0, 0, 0x00,0x00,0x00,0x00}
+-};
+-
+-static const UCHAR SiS300_NTSCTiming[] =
+-{
+- 0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
+- 0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
+- 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
+- 0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17, /* (in 2.06.50) */
+-/* 0x0c,0x50,0x00,0x99,0x00,0xec,0x4a,0x17, (in 2.04.5a) */
+- 0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02, /* (in 2.06.50) */
+-/* 0x88,0x00,0x4b,0x00,0x00,0xe2,0x00,0x02, (in 2.04.5a) */
+- 0x03,0x0a,0x65,0x9d,0x08,0x92,0x8f,0x40,
+- 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x50,
+- 0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
+-};
+-
+-static const UCHAR SiS300_PALTiming[] =
+-{
+- 0x19,0x52,0x35,0x6e,0x04,0x38,0x3d,0x70,
+- 0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d,
+- 0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b,
+- 0x70,0x50,0x00,0x9b,0x00,0xd9,0x5d,0x17, /* (in 2.06.50) */
+-/* 0x70,0x50,0x00,0x97,0x00,0xd7,0x5d,0x17, (in 2.04.5a) */
+- 0x7d,0x05,0x45,0x00,0x00,0xe8,0x00,0x02, /* (in 2.06.50) */
+-/* 0x88,0x00,0x45,0x00,0x00,0xe8,0x00,0x02, (in 2.04.5a) */
+- 0x0d,0x00,0x68,0xb0,0x0b,0x92,0x8f,0x40,
+- 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x63,
+- 0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00
+-};
+-
+-static const UCHAR SiS300_HiTVExtTiming[] = /* TW: New */
+-{
+- 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
+- 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+- 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+- 0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
+- 0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
+- 0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
+- 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
+- 0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
+-};
+-
+-static const UCHAR SiS300_HiTVSt1Timing[] = /* TW: New */
+-{
+- 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
+- 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+- 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+- 0x65,0x90,0x7b,0xa8,0x03,0xf0,0x87,0x03,
+- 0x11,0x15,0x11,0xcf,0x10,0x11,0xcf,0x10,
+- 0x35,0x35,0x3b,0x69,0x1d,0x92,0x0f,0x40,
+- 0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x86,
+- 0xaf,0x5d,0x0e,0x00,0xfc,0xff,0x2d,0x00
+-};
+-
+-static const UCHAR SiS300_HiTVSt2Timing[] = /* TW: New */
+-{
+- 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
+- 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+- 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+- 0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
+- 0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
+- 0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
+- 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
+- 0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
+-};
+-
+-static const UCHAR SiS300_HiTVTextTiming[] = /* TW: New */
+-{
+- 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
+- 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+- 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+- 0x65,0x90,0xe7,0xbc,0x03,0x0c,0x97,0x03,
+- 0x14,0x78,0x14,0x08,0x20,0x14,0x08,0x20,
+- 0xc8,0xc8,0x3b,0xd2,0x26,0x92,0x0f,0x40,
+- 0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x96,
+- 0x72,0x5c,0x11,0x00,0xfc,0xff,0x32,0x00
+-};
+-
+-static const UCHAR SiS300_HiTVGroup3Data[] = /* TW: New */
+-{
+- 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x5f,
+- 0x05,0x21,0xb2,0xb2,0x55,0x77,0x2a,0xa6,
+- 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
+- 0x8c,0x6e,0x60,0x2e,0x58,0x48,0x72,0x44,
+- 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
+- 0x4f,0x7f,0x03,0xa8,0x7d,0x20,0x1a,0xa9,
+- 0x14,0x05,0x03,0x7e,0x64,0x31,0x14,0x75,
+- 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
+-};
+-
+-static const UCHAR SiS300_HiTVGroup3Simu[] = /* TW: New */
+-{
+- 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x95,
+- 0xdb,0x20,0xb8,0xb8,0x55,0x47,0x2a,0xa6,
+- 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
+- 0x8c,0x6e,0x60,0x15,0x26,0xd3,0xe4,0x11,
+- 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
+- 0x67,0x36,0x01,0x47,0x0e,0x10,0xbe,0xb4,
+- 0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
+- 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
+-};
+-
+-static const UCHAR SiS300_HiTVGroup3Text[] = /* TW: New */
+-{
+- 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0xa7,
+- 0xf5,0x20,0xce,0xce,0x55,0x47,0x2a,0xa6,
+- 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
+- 0x8c,0x6e,0x60,0x18,0x2c,0x0c,0x20,0x22,
+- 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
+- 0x93,0x3c,0x01,0x50,0x2f,0x10,0xf4,0xca,
+- 0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
+- 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
+-};
+-
+ typedef struct _SiS300_LVDSDataStruct
+ {
+ USHORT VGAHT;
+@@ -1666,366 +991,14 @@
+ USHORT LCDVT;
+ } SiS300_LVDSDataStruct;
+
+-static const SiS300_LVDSDataStruct SiS300_LVDS320x480Data_1[] =
+-{
+- {848, 433,400, 525},
+- {848, 389,400, 525},
+- {848, 433,400, 525},
+- {848, 389,400, 525},
+- {848, 518,400, 525},
+- {1056,628,400, 525},
+- {400, 525,400, 525},
+- {800, 449,1000, 644},
+- {800, 525,1000, 635}
+-};
+-
+-static const SiS300_LVDSDataStruct SiS300_LVDS800x600Data_1[] =
+-{
+- {848, 433,1060, 629},
+- {848, 389,1060, 629},
+- {848, 433,1060, 629},
+- {848, 389,1060, 629},
+- {848, 518,1060, 629},
+- {1056, 628,1056, 628},
+- {1056, 628,1056, 628},
+- {800, 449,1000, 644},
+- {800, 525,1000, 635}
+-};
+-
+-static const SiS300_LVDSDataStruct SiS300_LVDS800x600Data_2[] =
+-{
+- {1056, 628,1056, 628},
+- {1056, 628,1056, 628},
+- {1056, 628,1056, 628},
+- {1056, 628,1056, 628},
+- {1056, 628,1056, 628},
+- {1056, 628,1056, 628},
+- {1056, 628,1056, 628},
+- {800, 449,1000, 644},
+- {800, 525,1000, 635}
+-};
+-
+-static const SiS300_LVDSDataStruct SiS300_LVDS1024x768Data_1[] =
+-{
+- {840, 438,1344, 806},
+- {840, 409,1344, 806},
+- {840, 438,1344, 806},
+- {840, 409,1344, 806},
+- {840, 518,1344, 806},
+- {1050, 638,1344, 806},
+- {1344, 806,1344, 806},
+- {800, 449,1280, 801},
+- {800, 525,1280, 813}
+-};
+-
+-static const SiS300_LVDSDataStruct SiS300_LVDS1024x768Data_2[] =
+-{
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {800, 449,1280, 801},
+- {800, 525,1280, 813}
+-};
+-
+-static const SiS300_LVDSDataStruct SiS300_LVDS1280x1024Data_1[]=
+-{
+- {1048, 442,1688,1066},
+- {1048, 392,1688,1066},
+- {1048, 442,1688,1066},
+- {1048, 392,1688,1066},
+- {1048, 522,1688,1066},
+- {1208, 642,1688,1066},
+- {1432, 810,1688,1066},
+- {1688,1066,1688,1066}
+-};
+-
+-static const SiS300_LVDSDataStruct SiS300_LVDS1280x1024Data_2[]=
+-{
+- {1688,1066,1688,1066},
+- {1688,1066,1688,1066},
+- {1688,1066,1688,1066},
+- {1688,1066,1688,1066},
+- {1688,1066,1688,1066},
+- {1688,1066,1688,1066},
+- {1688,1066,1688,1066},
+- {1688,1066,1688,1066}
+-};
+-
+-static const SiS300_LVDSDataStruct SiS300_LVDS1400x1050Data_1[] =
+-{
+- {928, 416, 1688, 1066},
+- {928, 366, 1688, 1066},
+- {928, 416, 1688, 1066},
+- {928, 366, 1688, 1066},
+- {928, 496, 1688, 1066},
+- {1088, 616, 1688, 1066},
+- {1312, 784, 1688, 1066},
+- {1568, 1040, 1688, 1066},
+- {1688, 1066, 1688, 1066}
+-};
+-
+-static const SiS300_LVDSDataStruct SiS300_LVDS1400x1050Data_2[] =
+-{
+- {1688,1066, 1688,1066},
+- {1688,1066, 1688,1066},
+- {1688,1066, 1688,1066},
+- {1688,1066, 1688,1066},
+- {1688,1066, 1688,1066},
+- {1688,1066, 1688,1066},
+- {1688,1066, 1688,1066},
+- {1688,1066, 1688,1066},
+- {1688,1066, 1688,1066},
+-};
+-
+-static const SiS300_LVDSDataStruct SiS300_LVDS1600x1200Data_1[]=
+-{
+- {1088, 450, 2048,1250},
+- {1088, 400, 2048,1250},
+- {1088, 450, 2048,1250},
+- {1088, 400, 2048,1250},
+- {1088, 530, 2048,1250},
+- {1248, 650, 2048,1250},
+- {1472, 818, 2048,1250},
+- {1728,1066, 2048,1250},
+- {1848,1066, 2048,1250},
+- {2048,1250, 2048,1250}
+-};
+-
+-static const SiS300_LVDSDataStruct SiS300_LVDS1600x1200Data_2[]=
+-{
+- {2048,1250, 2048,1250},
+- {2048,1250, 2048,1250},
+- {2048,1250, 2048,1250},
+- {2048,1250, 2048,1250},
+- {2048,1250, 2048,1250},
+- {2048,1250, 2048,1250},
+- {2048,1250, 2048,1250},
+- {2048,1250, 2048,1250},
+- {2048,1250, 2048,1250},
+- {2048,1250, 2048,1250}
+-};
+-
+-static const SiS300_LVDSDataStruct SiS300_LVDS1280x768Data_1[]=
+-{
+- { 768, 438, 1408, 806},
+- { 768, 388, 1408, 806},
+- { 768, 438, 1408, 806},
+- { 768, 388, 1408, 806},
+- { 768, 518, 1408, 806},
+- { 928, 638, 1408, 806},
+- {1152, 806, 1408, 806},
+- {1408, 806, 1408, 806},
+- {1408, 806, 1408, 806}
+-};
+-
+-static const SiS300_LVDSDataStruct SiS300_LVDS1280x768Data_2[]=
+-{
+- {1408, 806, 1408, 806},
+- {1408, 806, 1408, 806},
+- {1408, 806, 1408, 806},
+- {1408, 806, 1408, 806},
+- {1408, 806, 1408, 806},
+- {1408, 806, 1408, 806},
+- {1408, 806, 1408, 806},
+- {1408, 806, 1408, 806},
+- {1408, 806, 1408, 806}
+-};
+-
+-static const SiS300_LVDSDataStruct SiS300_LVDS1024x600Data_1[] =
+-{
+- {840, 604,1344, 800},
+- {840, 560,1344, 800},
+- {840, 604,1344, 800},
+- {840, 560,1344, 800},
+- {840, 689,1344, 800},
+- {1050, 800,1344, 800},
+- {1344, 800,1344, 800},
+- {800, 449,1280, 789},
+- {800, 525,1280, 785}
+-};
+-
+-static const SiS300_LVDSDataStruct SiS300_LVDS1024x600Data_2[] =
+-{
+- {1344, 800,1344, 800},
+- {1344, 800,1344, 800},
+- {1344, 800,1344, 800},
+- {1344, 800,1344, 800},
+- {1344, 800,1344, 800},
+- {1344, 800,1344, 800},
+- {1344, 800,1344, 800},
+- {800, 449,1280, 801},
+- {800, 525,1280, 813}
+-};
+-
+-static const SiS300_LVDSDataStruct SiS300_LVDS1152x768Data_1[] =
+-{
+- {840, 438,1344, 806},
+- {840, 409,1344, 806},
+- {840, 438,1344, 806},
+- {840, 409,1344, 806},
+- {840, 518,1344, 806},
+- {1050, 638,1344, 806},
+- {1344, 806,1344, 806},
+- {800, 449,1280, 801},
+- {800, 525,1280, 813}
+-};
+-
+-static const SiS300_LVDSDataStruct SiS300_LVDS1152x768Data_2[] =
+-{
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {800, 449,1280, 801},
+- {800, 525,1280, 813}
+-};
+-
+-/* TW: pass 1:1 data */
+-static const SiS300_LVDSDataStruct SiS300_LVDSXXXxXXXData_1[]=
+-{
+- { 800, 449, 800, 449},
+- { 800, 449, 800, 449},
+- { 900, 449, 900, 449},
+- { 900, 449, 900, 449},
+- { 800, 525, 800, 525}, /* 640x480 */
+- {1056, 628, 1056, 628}, /* 800x600 */
+- {1344, 806, 1344, 806}, /* 1024x768 */
+- {1344,1066, 1344,1066}, /* 1280x1024 */ /* INSERTED ! */
+- {1688, 806, 1688, 806}, /* 1280x768 ! */
+- /* No other panels ! */
+-};
+-
+-static const SiS300_LVDSDataStruct SiS300_LVDS640x480Data_1[] =
+-{
+- {800, 449, 800, 449},
+- {800, 449, 800, 449},
+- {800, 449, 800, 449},
+- {800, 449, 800, 449},
+- {800, 525, 800, 525},
+- {1056, 628,1056, 628},
+- {1056, 628,1056, 628},
+- {1056, 628,1056, 628},
+- {1056, 628,1056, 628}
+-};
+-
+-static const SiS300_LVDSDataStruct SiS300_LVDS1280x960Data_1[] = /* TW: New */
+-{
+- {840, 438,1344, 806},
+- {840, 409,1344, 806},
+- {840, 438,1344, 806},
+- {840, 409,1344, 806},
+- {840, 518,1344, 806},
+- {1050, 638,1344, 806},
+- {1344, 806,1344, 806},
+- {800, 449,1280, 801},
+- {800, 525,1280, 813}
+-};
+-
+-static const SiS300_LVDSDataStruct SiS300_LVDS1280x960Data_2[] = /* TW: New */
+-{
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {800, 449,1280, 801},
+- {800, 525,1280, 813}
+-};
+-
+-static const SiS300_LVDSDataStruct SiS300_LCDA1400x1050Data_1[] = /* TW: New */
+-{ /* TW: Might be temporary (invalid) data */
+- {928, 416, 1688, 1066},
+- {928, 366, 1688, 1066},
+- {1008, 416, 1688, 1066},
+- {1008, 366, 1688, 1066},
+- {1200, 530, 1688, 1066},
+- {1088, 616, 1688, 1066},
+- {1312, 784, 1688, 1066},
+- {1568, 1040, 1688, 1066},
+- {1688, 1066, 1688, 1066}
+-};
+-
+-static const SiS300_LVDSDataStruct SiS300_LCDA1400x1050Data_2[] = /* TW: New */
+-{ /* TW: Temporary data. Not valid */
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {800, 449,1280, 801},
+- {800, 525,1280, 813}
+-};
+-
+-static const SiS300_LVDSDataStruct SiS300_LCDA1600x1200Data_1[] = /* TW: New */
+-{ /* TW: Temporary data. Not valid */
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {800, 449,1280, 801},
+- {800, 525,1280, 813}
+-};
+-
+-static const SiS300_LVDSDataStruct SiS300_LCDA1600x1200Data_2[] = /* TW: New */
+-{ /* TW: Temporary data. Not valid */
+- {0, 0, 0, 0},
+- {0, 0, 0, 0},
+- {0, 0, 0, 0},
+- {0, 0, 0, 0},
+- {0, 0, 0, 0},
+- {0, 0, 0, 0},
+- {0, 0, 0, 0},
+- {0, 0, 0, 0},
+- {0, 0, 0, 0},
+- {0, 0, 0, 0},
+- {0, 0, 0, 0},
+- {0, 0, 0, 0}
+-};
+-
+-
+-/* TW: New: */
+-static const SiS300_LVDSDataStruct SiS300_CHTVUNTSCData[] =
+-{
+- {840, 600, 840, 600},
+- {840, 600, 840, 600},
+- {840, 600, 840, 600},
+- {840, 600, 840, 600},
+- {784, 600, 784, 600},
+- {1064, 750,1064, 750}
+-};
+-
+-static const SiS300_LVDSDataStruct SiS300_CHTVONTSCData[] =
+-{
+- {840, 525, 840, 525},
+- {840, 525, 840, 525},
+- {840, 525, 840, 525},
+- {840, 525, 840, 525},
+- {784, 525, 784, 525},
+- {1040, 700,1040, 700}
+-};
+-
+ static const SiS300_LVDSDataStruct SiS300_CHTVUPALData[] =
+ {
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+- {840, 750, 840, 750},
+- {936, 836, 936, 836}
++ { 840, 750, 840, 750},
++ { 936, 836, 936, 836}
+ };
+
+ static const SiS300_LVDSDataStruct SiS300_CHTVOPALData[] =
+@@ -2034,8 +1007,8 @@
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+- {840, 625, 840, 625},
+- {960, 750, 960, 750}
++ { 840, 625, 840, 625},
++ { 960, 750, 960, 750}
+ };
+
+ static const SiS300_LVDSDataStruct SiS300_CHTVSOPALData[] =
+@@ -2044,12 +1017,10 @@
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+- {840, 500, 840, 500},
+- {944, 625, 944, 625}
++ { 840, 500, 840, 500},
++ { 944, 625, 944, 625}
+ };
+
+-/* TW: new end */
+-
+ typedef struct _SiS300_LVDSDesStruct
+ {
+ USHORT LCDHDES;
+@@ -2058,57 +1029,90 @@
+
+ static const SiS300_LVDSDesStruct SiS300_PanelType00_1[] =
+ {
++ { 1059, 626 }, /* 2.08 */
++ { 1059, 624 },
++ { 1059, 626 },
++ { 1059, 624 },
++ { 1059, 624 },
++ { 0, 627 },
++ { 0, 627 },
++ { 0, 0 },
++ { 0, 0 }
++#if 0
+ {0, 626},
+ {0, 624},
+ {0, 626},
+ {0, 624},
+ {0, 624},
+- { 0, 627},
+- { 0, 627},
+- { 0, 0},
+- { 0, 0}
++ {0, 627},
++ {0, 627},
++ {0, 0},
++ {0, 0}
++#endif
+ };
+
+ static const SiS300_LVDSDesStruct SiS300_PanelType01_1[] =
+ {
++ { 0, 0 }, /* 2.08 */
++ { 0, 0 },
++ { 0, 0 },
++ { 0, 0 },
++ { 0, 0 },
++ { 0, 0 },
++ { 0, 0 },
++ { 0, 0 },
++ { 0, 0 }
++#if 0
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343, 0},
+ {1343, 0},
+- { 0, 805},
+- { 0, 794},
+- { 0, 0}
++ { 0, 805},
++ { 0, 794},
++ { 0, 0}
++#endif
+ };
+
+ static const SiS300_LVDSDesStruct SiS300_PanelType02_1[] =
+ {
++ { 1059, 626 }, /* 2.08 */
++ { 1059, 624 },
++ { 1059, 626 },
++ { 1059, 624 },
++ { 1059, 624 },
++ { 0, 627 },
++ { 0, 627 },
++ { 0, 0 },
++ { 0, 0 }
++#if 0
+ {0, 626},
+ {0, 624},
+ {0, 626},
+ {0, 624},
+ {0, 624},
+- { 0, 627},
+- { 0, 627},
+- { 0, 0},
+- { 0, 0}
++ {0, 627},
++ {0, 627},
++ {0, 0},
++ {0, 0}
++#endif
+ };
+
+ static const SiS300_LVDSDesStruct SiS300_PanelType03_1[] =
+ {
+- { 8, 436},
+- { 8, 440},
+- { 8, 436},
+- { 8, 440},
+- { 8, 512},
++ { 8, 436},
++ { 8, 440},
++ { 8, 436},
++ { 8, 440},
++ { 8, 512},
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794}
+ };
+
+-static const SiS300_LVDSDesStruct SiS300_PanelType04_1[] =
++static const SiS300_LVDSDesStruct SiS300_PanelType04_1[] = /* 1280x1024 */
+ {
+ {1343, 798},
+ {1343, 794},
+@@ -2116,9 +1120,9 @@
+ {1343, 794},
+ {1343, 0},
+ {1343, 0},
+- { 0, 805},
+- { 0, 794},
+- { 0, 0}
++ { 0, 805},
++ { 0, 794},
++ { 0, 0}
+ };
+
+ static const SiS300_LVDSDesStruct SiS300_PanelType05_1[] =
+@@ -2129,9 +1133,9 @@
+ {1343, 794},
+ {1343, 0},
+ {1343, 0},
+- { 0, 805},
+- { 0, 794},
+- { 0, 0}
++ { 0, 805},
++ { 0, 794},
++ { 0, 0}
+ };
+
+ static const SiS300_LVDSDesStruct SiS300_PanelType06_1[] =
+@@ -2142,9 +1146,9 @@
+ {1343, 794},
+ {1343, 0},
+ {1343, 0},
+- { 0, 805},
+- { 0, 794},
+- { 0, 0}
++ { 0, 805},
++ { 0, 794},
++ { 0, 0}
+ };
+
+ static const SiS300_LVDSDesStruct SiS300_PanelType07_1[] =
+@@ -2155,9 +1159,9 @@
+ {1343, 794},
+ {1343, 0},
+ {1343, 0},
+- { 0, 805},
+- { 0, 794},
+- { 0, 0}
++ { 0, 805},
++ { 0, 794},
++ { 0, 0}
+ };
+
+ static const SiS300_LVDSDesStruct SiS300_PanelType08_1[] =
+@@ -2167,10 +1171,10 @@
+ {1059, 626},
+ {1059, 624},
+ {1059, 624},
+- { 0, 627},
+- { 0, 627},
+- { 0, 0},
+- { 0, 0}
++ { 0, 627},
++ { 0, 627},
++ { 0, 0},
++ { 0, 0}
+ };
+
+ static const SiS300_LVDSDesStruct SiS300_PanelType09_1[] =
+@@ -2181,9 +1185,9 @@
+ {1343, 794},
+ {1343, 0},
+ {1343, 0},
+- { 0, 805},
+- { 0, 794},
+- { 0, 0}
++ { 0, 805},
++ { 0, 794},
++ { 0, 0}
+ };
+
+ static const SiS300_LVDSDesStruct SiS300_PanelType0a_1[] =
+@@ -2193,23 +1197,23 @@
+ {1059, 626},
+ {1059, 624},
+ {1059, 624},
+- { 0, 627},
+- { 0, 627},
+- { 0, 0},
+- { 0, 0}
++ { 0, 627},
++ { 0, 627},
++ { 0, 0},
++ { 0, 0}
+ };
+
+ static const SiS300_LVDSDesStruct SiS300_PanelType0b_1[] =
+ {
+- {1343, 0},
+- {1343, 0},
+- {1343, 0},
+- {1343, 0},
+- {1343, 0}, /* 640x480 - BIOS 1343, 0 */
+- {1343, 0},
+- { 0, 799},
+- { 0, 0},
+- { 0, 0}
++ {1343, 0},
++ {1343, 0},
++ {1343, 0},
++ {1343, 0},
++ {1343, 0},
++ {1343, 0},
++ { 0, 799},
++ { 0, 0},
++ { 0, 0}
+ };
+
+ static const SiS300_LVDSDesStruct SiS300_PanelType0c_1[] =
+@@ -2220,9 +1224,9 @@
+ {1343, 794},
+ {1343, 0},
+ {1343, 0},
+- { 0, 805},
+- { 0, 794},
+- { 0, 0}
++ { 0, 805},
++ { 0, 794},
++ { 0, 0}
+ };
+
+ static const SiS300_LVDSDesStruct SiS300_PanelType0d_1[] =
+@@ -2233,9 +1237,9 @@
+ {1343, 794},
+ {1343, 0},
+ {1343, 0},
+- { 0, 805},
+- { 0, 794},
+- { 0, 0}
++ { 0, 805},
++ { 0, 794},
++ { 0, 0}
+ };
+
+ static const SiS300_LVDSDesStruct SiS300_PanelType0e_1[] =
+@@ -2244,11 +1248,11 @@
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+- {1343, 0}, /* 640x480 */
+- {1343, 0}, /* 800x600 */
+- { 0, 805}, /* 1024x768 */
+- { 0, 794}, /* 1280x1024 */
+- { 0, 0} /* 1280x960 - not applicable */
++ {1343, 0}, /* 640x480 */
++ {1343, 0}, /* 800x600 */
++ { 0, 805}, /* 1024x768 */
++ { 0, 794}, /* 1280x1024 */
++ { 0, 0} /* 1280x960 - not applicable */
+ };
+
+ static const SiS300_LVDSDesStruct SiS300_PanelType0f_1[] =
+@@ -2259,9 +1263,9 @@
+ {1343, 794},
+ {1343, 0},
+ {1343, 0},
+- { 0, 805},
+- { 0, 794},
+- { 0, 0}
++ { 0, 805},
++ { 0, 794},
++ { 0, 0}
+ };
+
+ static const SiS300_LVDSDesStruct SiS300_PanelType00_2[] =
+@@ -2271,10 +1275,10 @@
+ {976, 527},
+ {976, 502},
+ {976, 567},
+- { 0, 627},
+- { 0, 627},
+- { 0, 0},
+- { 0, 0}
++ { 0, 627},
++ { 0, 627},
++ { 0, 0},
++ { 0, 0}
+ };
+
+ static const SiS300_LVDSDesStruct SiS300_PanelType01_2[] =
+@@ -2285,9 +1289,9 @@
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+- { 0, 805},
+- { 0, 794},
+- { 0, 0}
++ { 0, 805},
++ { 0, 794},
++ { 0, 0}
+ };
+
+ static const SiS300_LVDSDesStruct SiS300_PanelType02_2[] =
+@@ -2297,10 +1301,10 @@
+ {976, 527},
+ {976, 502},
+ {976, 567},
+- { 0, 627},
+- { 0, 627},
+- { 0, 0},
+- { 0, 0}
++ { 0, 627},
++ { 0, 627},
++ { 0, 0},
++ { 0, 0}
+ };
+
+ static const SiS300_LVDSDesStruct SiS300_PanelType03_2[] =
+@@ -2472,156 +1476,57 @@
+ { 0, 0}
+ };
+
+-static const SiS300_LVDSDesStruct SiS300_PanelTypeNS_1[]=
++/* Custom data for Barco iQ R200/300/400 (BIOS 2.00.07) */
++static const SiS300_LVDSDesStruct SiS300_PanelType04_1a[] = /* 1280x1024 (1366x1024) */
+ {
+- { 8, 0},
+- { 8, 0},
+- { 8, 0},
+- { 8, 0},
+- { 8, 0},
+- { 0, 0},
+- { 0, 0},
+- { 0, 0},
+- { 0, 806},
+- { 0, 0 }
+-};
+-
+-static const SiS300_LVDSDesStruct SiS300_PanelTypeNS_2[] =
+-{
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0}
+-};
+-
+-static const SiS300_LVDSDesStruct SiS300_PanelType1076_1[] = /* TW: New */
+-{
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0}
+-};
+-
+-static const SiS300_LVDSDesStruct SiS300_PanelType1076_2[] = /* TW: New */
+-{
+- { 1152, 622 },
+- { 1152, 597 },
+- { 1152, 622 },
+- { 1152, 597 },
+- { 1152, 622 },
+- { 1232, 722 },
+- { 0, 0 },
+- { 0, 794 },
+- { 0, 0 }
+-};
+-
+-static const SiS300_LVDSDesStruct SiS300_PanelType1210_1[] = /* TW: New */
+-{
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0}
+-};
+-
+-static const SiS300_LVDSDesStruct SiS300_PanelType1210_2[] = /* TW: New */
+-{
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0}
+-};
+-
+-static const SiS300_LVDSDesStruct SiS300_PanelType1296_1[] = /* TW: New */
+-{
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0}
+-};
+-
+-static const SiS300_LVDSDesStruct SiS300_PanelType1296_2[] = /* TW: New */
+-{
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0}
+-};
+-
+-
+-/* TW: New */
+-static const SiS300_LVDSDesStruct SiS300_CHTVUNTSCDesData[] =
+-{
+- { 0, 0},
+- { 0, 0},
+- { 0, 0},
+- { 0, 0},
+- { 0, 0},
+- { 0, 0}
+-};
+-
+-static const SiS300_LVDSDesStruct SiS300_CHTVONTSCDesData[] =
+-{
+- { 0, 0},
+- { 0, 0},
+- { 0, 0},
+- { 0, 0},
+- { 0, 0},
+- { 0, 0}
+-};
+-
+-static const SiS300_LVDSDesStruct SiS300_CHTVUPALDesData[] =
+-{
+- {256, 0},
+- {256, 0},
+- {256, 0},
+- {256, 0},
+- { 0, 0},
+- { 0, 0}
++ {1330, 798}, /* 320x200 */
++ {1330, 794},
++ {1330, 798},
++ {1330, 794},
++ {1330, 0}, /* 640x480 / 320x240 */
++ {1343, 0}, /* 800x600 / 400x300 */
++ { 0, 805}, /* 1024x768 / 512x384 */
++ {1688,1066}, /* 1280x1024 */
++ { 0, 0} /* 1360x1024 */
+ };
+
+-static const SiS300_LVDSDesStruct SiS300_CHTVOPALDesData[] =
++static const SiS300_LVDSDesStruct SiS300_PanelType04_2a[] =
+ {
+- {256, 0},
+- {256, 0},
+- {256, 0},
+- {256, 0},
+- { 0, 0},
+- { 0, 0}
++ {1152, 622},
++ {1152, 597},
++ {1152, 622},
++ {1152, 597},
++ {1152, 662},
++ {1232, 722},
++ { 0, 805},
++ {1688,1066},
++ { 0, 0}
++};
++
++/* Custom data for Barco iQ G200/300/400 (BIOS 2.00.07) */
++static const SiS300_LVDSDesStruct SiS300_PanelType04_1b[] = /* 1024x768 */
++{
++ {1330, 798}, /* 320x200 */
++ {1330, 794},
++ {1330, 798},
++ {1330, 794},
++ {1330, 0}, /* 640x480 / 320x240 */
++ {1343, 0}, /* 800x600 / 400x300 */
++ { 0, 805} /* 1024x768 / 512x384 */
++};
++
++static const SiS300_LVDSDesStruct SiS300_PanelType04_2b[] =
++{
++ {1152, 622},
++ {1152, 597},
++ {1152, 622},
++ {1152, 597},
++ {1152, 662},
++ {1232, 722},
++ { 0, 805}
+ };
+-/* TW: New end */
+
+-/* TW: New for SiS300+301LV */
++
+ typedef struct _SiS300_Part2PortTblStruct
+ {
+ UCHAR CR[12];
+@@ -2726,6 +1631,28 @@
+ 0x01 }}
+ };
+
++static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_1_H[] =
++{
++ {{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
++ 0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
++ 0x00 }},
++ {{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
++ 0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
++ 0x00 }},
++ {{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
++ 0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
++ 0x00 }},
++ {{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
++ 0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
++ 0x00 }},
++ {{0x30,0x27,0x94,0x2c,0x92,0x04,0x3e,
++ 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x04,
++ 0x00 }},
++ {{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
++ 0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
++ 0x01 }}
++};
++
+ static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_1[] =
+ {
+ {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
+@@ -2751,55 +1678,31 @@
+ 0x01}}
+ };
+
+-static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_1[] =
+-{
+- {{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
+- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+- 0x00 }},
+- {{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
+- 0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+- 0x00 }},
+- {{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
+- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+- 0x00 }},
+- {{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
+- 0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+- 0x00 }},
+- {{0x63,0x4f,0x87,0x54,0x9f,0x04,0x3e,
+- 0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
+- 0x00 }},
+- {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
+- 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
+- 0x01 }},
+- {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+- 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+- 0x01 }}
+-};
+-
+-static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_1_H[] =
++static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_1_H[] =
+ {
+- {{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
+- 0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
+- 0x00 }},
+- {{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
+- 0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
+- 0x00 }},
+- {{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
+- 0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
+- 0x00 }},
+- {{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
+- 0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
+- 0x00 }},
+- {{0x30,0x27,0x94,0x2c,0x92,0x04,0x3e,
+- 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x04,
++ {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
++ 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+ 0x00 }},
+- {{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
+- 0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
++ {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
++ 0x60,0x87,0x5D,0x83,0x10,0x00,0x44,
++ 0x00}},
++ {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
++ 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
++ 0x00}},
++ {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
++ 0x60,0x87,0x5D,0x83,0x10,0x00,0x44,
++ 0x00}},
++ {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
++ 0xE2,0x89,0xdf,0x05,0x00,0x00,0x44,
++ 0x00}},
++ {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
++ 0x5A,0x8F,0x57,0x7D,0x20,0x00,0x55,
++ 0x01}},
++ {{0x4f,0x3F,0x93,0x45,0x0D,0x24,0xf5,
++ 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+ 0x01 }}
+-};
+
+-static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_1_H[] =
+-{
++#if 0
+ {{0x37,0x27,0x9B,0x2b,0x94,0xc4,0x1f,
+ 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+ 0x00 }},
+@@ -2821,6 +1724,32 @@
+ {{0x4f,0x3F,0x93,0x45,0x0D,0x24,0xf5,
+ 0x02,0x88,0xFf,0x25,0x10,0x00,0x01,
+ 0x01 }}
++#endif
++};
++
++static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_1[] =
++{
++ {{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
++ 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
++ 0x00 }},
++ {{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
++ 0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
++ 0x00 }},
++ {{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
++ 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
++ 0x00 }},
++ {{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
++ 0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
++ 0x00 }},
++ {{0x63,0x4f,0x87,0x54,0x9f,0x04,0x3e,
++ 0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
++ 0x00 }},
++ {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
++ 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
++ 0x01 }},
++ {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
++ 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
++ 0x01 }}
+ };
+
+ static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_1_H[] =
+@@ -2870,32 +1799,29 @@
+ 0x01 }}
+ };
+
+-static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_2[] =
++static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_2_H[] =
+ {
+- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+- 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
++ {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
++ 0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
+ 0x00 }},
+- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+- 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
++ {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
++ 0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
+ 0x00 }},
+- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+- 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
++ {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
++ 0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
+ 0x00 }},
+- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+- 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
++ {{0x3d,0x27,0x81,0x3a,0x1a,0x72,0x3e,
++ 0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
+ 0x00 }},
+- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+- 0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
++ {{0x3d,0x27,0x81,0x32,0x1a,0x72,0xba,
++ 0x1c,0x80,0xdf,0x73,0x00,0x00,0x05,
+ 0x00 }},
+- {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
+- 0xae,0x84,0x57,0x25,0x30,0x00,0x02,
+- 0x01 }},
+- {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+- 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
++ {{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
++ 0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
+ 0x01 }}
+ };
+
+-static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_2[] =
++static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_2[] =
+ {
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+@@ -2920,28 +1846,6 @@
+ 0x01 }}
+ };
+
+-static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_2_H[] =
+-{
+- {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
+- 0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
+- 0x00 }},
+- {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
+- 0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
+- 0x00 }},
+- {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
+- 0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
+- 0x00 }},
+- {{0x3d,0x27,0x81,0x3a,0x1a,0x72,0x3e,
+- 0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
+- 0x00 }},
+- {{0x3d,0x27,0x81,0x32,0x1a,0x72,0xba,
+- 0x1c,0x80,0xdf,0x73,0x00,0x00,0x05,
+- 0x00 }},
+- {{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
+- 0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
+- 0x01 }}
+-};
+-
+ static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_2_H[] =
+ {
+ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+@@ -2967,6 +1871,31 @@
+ 0x01 }}
+ };
+
++static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_2[] =
++{
++ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
++ 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
++ 0x00 }},
++ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
++ 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
++ 0x00 }},
++ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
++ 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
++ 0x00 }},
++ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
++ 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
++ 0x00 }},
++ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
++ 0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
++ 0x00 }},
++ {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
++ 0xae,0x84,0x57,0x25,0x30,0x00,0x02,
++ 0x01 }},
++ {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
++ 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
++ 0x01 }}
++};
++
+ static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_2_H[] =
+ {
+ {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+@@ -2992,207 +1921,6 @@
+ 0x01}}
+ };
+
+-static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x600_1[] =
+-{
+- {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
+- 0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
+- 0x00}},
+- {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
+- 0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
+- 0x00}},
+- {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
+- 0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
+- 0x00}},
+- {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
+- 0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
+- 0x00}},
+- {{0x64,0x4f,0x88,0x54,0x9f,0xaf,0xba,
+- 0x3b,0x82,0xdf,0xb0,0x00,0x00,0x01,
+- 0x00}},
+- {{0x7e,0x63,0x82,0x68,0x15,0x1e,0xf1,
+- 0xae,0x85,0x57,0x1f,0x30,0x00,0x26,
+- 0x01}},
+- {{0xa3,0x7f,0x87,0x86,0x97,0x1e,0xf1,
+- 0xae,0x85,0x57,0x1f,0x30,0x00,0x02,
+- 0x01}}
+-};
+-
+-static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x600_1_H[] =
+-{
+- {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+- 0x00}},
+- {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+- 0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
+- 0x00}},
+- {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+- 0x00}},
+- {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+- 0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
+- 0x00}},
+- {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
+- 0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
+- 0x00}},
+- {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
+- 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
+- 0x01}},
+- {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+- 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+- 0x01}}
+-};
+-
+-static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x600_2[] =
+-{
+- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+- 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+- 0x00}},
+- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+- 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+- 0x00}},
+- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+- 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+- 0x00}},
+- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+- 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+- 0x00}},
+- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+- 0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
+- 0x00}},
+- {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
+- 0xae,0x84,0x57,0x25,0x30,0x00,0x02,
+- 0x01}},
+- {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+- 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+- 0x01}}
+-};
+-
+-static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x600_2_H[] =
+-{
+- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+- 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+- 0x00}},
+- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+- 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+- 0x00}},
+- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+- 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+- 0x00}},
+- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+- 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+- 0x00}},
+- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+- 0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
+- 0x00}},
+- {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
+- 0xae,0x84,0x57,0x25,0x30,0x00,0x01,
+- 0x01}},
+- {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+- 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+- 0x01}}
+-};
+-
+-static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11152x768_1[] =
+-{
+- {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
+- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+- 0x00}},
+- {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
+- 0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+- 0x00}},
+- {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
+- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+- 0x00}},
+- {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
+- 0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+- 0x00}},
+- {{0x64,0x4f,0x88,0x54,0x9f,0x04,0x3e,
+- 0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
+- 0x00}},
+- {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
+- 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
+- 0x01}},
+- {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+- 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+- 0x01}}
+-};
+-
+-static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11152x768_1_H[] =
+-{
+- {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+- 0x00}},
+- {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+- 0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
+- 0x00}},
+- {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+- 0x00}},
+- {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+- 0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
+- 0x00}},
+- {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
+- 0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
+- 0x00}},
+- {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
+- 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
+- 0x01}},
+- {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+- 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+- 0x01}}
+-};
+-
+-static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11152x768_2[] =
+-{
+- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+- 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+- 0x00}},
+- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+- 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+- 0x00}},
+- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+- 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+- 0x00}},
+- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+- 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+- 0x00}},
+- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+- 0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
+- 0x00}},
+- {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
+- 0xae,0x84,0x57,0x25,0x30,0x00,0x02,
+- 0x01}},
+- {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+- 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+- 0x01}}
+-};
+-
+-static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11152x768_2_H[] =
+-{
+- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+- 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+- 0x00}},
+- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+- 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+- 0x00}},
+- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+- 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+- 0x00}},
+- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+- 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+- 0x00}},
+- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+- 0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
+- 0x00}},
+- {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
+- 0xae,0x84,0x57,0x25,0x30,0x00,0x01,
+- 0x01}},
+- {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+- 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+- 0x01}}
+-};
+-
+-/* TW: New */
+ static const SiS300_LVDSCRT1DataStruct SiS300_CHTVCRT1UNTSC[] =
+ {
+ {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+@@ -3302,9 +2030,7 @@
+ 0x90,0x8c,0x57,0xed,0x20,0x00,0x05,
+ 0x01 }}
+ };
+-/* TW: New end */
+
+-/* TW: New */
+ typedef struct _SiS300_CHTVRegDataStruct
+ {
+ UCHAR Reg[16];
+@@ -3361,9 +2087,7 @@
+ {{0x60,0x30,0x00,0x10,0x00,0,0,0,0,0,0,0,0,0,0,0}}, /* TW: Mode 13: 640x480 PAL 5/4 */
+ {{0x81,0x50,0x00,0x1b,0x00,0,0,0,0,0,0,0,0,0,0,0}} /* TW: Mode 19: 800x600 PAL 1/1 */
+ };
+-/* TW: New end */
+
+-/* TW: New */
+ static const UCHAR SiS300_CHTVVCLKUNTSC[] = {0x29,0x29,0x29,0x29,0x2a,0x2e};
+
+ static const UCHAR SiS300_CHTVVCLKONTSC[] = {0x2c,0x2c,0x2c,0x2c,0x2d,0x2b};
+@@ -3375,6 +2099,5 @@
+ static const UCHAR SiS300_CHTVVCLKOPAL[] = {0x2f,0x2f,0x2f,0x2f,0x30,0x32};
+
+ static const UCHAR SiS300_CHTVVCLKSOPAL[] = {0x2f,0x2f,0x2f,0x2f,0x36,0x29};
+-/* TW: New end */
+
+
+Index: linux-2.6.0-test5/drivers/video/sis/310vtbl.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/sis/310vtbl.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/sis/310vtbl.h 2003-09-27 11:38:34.911221072 +0800
+@@ -1,7 +1,37 @@
+-
+-
+-/* Register settings for SiS 310/325/330 series */
+-
++/* $XFree86$ */
++/*
++ * Register settings for SiS 315/330 series
++ *
++ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
++ *
++ * If distributed as part of the linux kernel, the contents of this file
++ * is entirely covered by the GPL.
++ *
++ * Otherwise, the following terms apply:
++ *
++ * Permission to use, copy, modify, distribute, and sell this software and its
++ * documentation for any purpose is hereby granted without fee, provided that
++ * the above copyright notice appear in all copies and that both that
++ * copyright notice and this permission notice appear in supporting
++ * documentation, and that the name of the copyright holder not be used in
++ * advertising or publicity pertaining to distribution of the software without
++ * specific, written prior permission. The copyright holder makes no representations
++ * about the suitability of this software for any purpose. It is provided
++ * "as is" without express or implied warranty.
++ *
++ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
++ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
++ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
++ * PERFORMANCE OF THIS SOFTWARE.
++ *
++ * Author: Thomas Winischhofer <thomas@winischhofer.net>
++ *
++ * Based on code by Silicon Intergrated Systems
++ *
++ */
+
+ typedef struct _SiS310_StStruct
+ {
+@@ -39,466 +69,12 @@
+ {0xff,0x0000,0x00,0x00,0x00,0x00,0x00,0x00}
+ };
+
+-typedef struct _SiS310_StandTableStruct
+-{
+- UCHAR CRT_COLS;
+- UCHAR ROWS;
+- UCHAR CHAR_HEIGHT;
+- USHORT CRT_LEN;
+- UCHAR SR[4];
+- UCHAR MISC;
+- UCHAR CRTC[0x19];
+- UCHAR ATTR[0x14];
+- UCHAR GRC[9];
+-} SiS310_StandTableStruct;
+-
+-static const SiS310_StandTableStruct SiS310_StandTable[]=
+-{
+-/* 0x00: MD_0_200 */
+- {
+- 0x28,0x18,0x08,0x0800,
+- {0x09,0x03,0x00,0x02},
+- 0x63,
+- {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+- 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+- 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
+- 0xff},
+- {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+- 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+- 0x08,0x00,0x0f,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+- 0xff}
+- },
+-/* 0x01: MD_1_200 */
+- {
+- 0x28,0x18,0x08,0x0800,
+- {0x09,0x03,0x00,0x02},
+- 0x63,
+- {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+- 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+- 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
+- 0xff},
+- {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+- 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+- 0x08,0x00,0x0f,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+- 0xff}
+- },
+-/* 0x02: MD_2_200 */
+- {
+- 0x50,0x18,0x08,0x1000,
+- {0x01,0x03,0x00,0x02},
+- 0x63,
+- {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+- 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+- 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+- 0xff},
+- {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+- 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+- 0x08,0x00,0x0f,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+- 0xff}
+- },
+-/* 0x03: MD_3_200 - mode 0x03 - 0 */
+- {
+- 0x50,0x18,0x08,0x1000,
+- {0x01,0x03,0x00,0x02},
+- 0x63,
+- {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+- 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+- 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+- 0xff},
+- {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+- 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+- 0x08,0x00,0x0f,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+- 0xff}
+- },
+-/* 0x04: MD_4 */
+- {
+- 0x28,0x18,0x08,0x4000,
+- {0x09,0x03,0x00,0x02},
+- 0x63,
+- {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
+- 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
+- 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
+- 0xff},
+- {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
+- 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+- 0x01,0x00,0x03,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
+- 0xff}
+- },
+-/* 0x05: MD_5 */
+- {
+- 0x28,0x18,0x08,0x4000,
+- {0x09,0x03,0x00,0x02},
+- 0x63,
+- {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
+- 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
+- 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
+- 0xff},
+- {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
+- 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+- 0x01,0x00,0x03,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
+- 0xff}
+- },
+-/* 0x06: MD_6 */
+- {
+- 0x50,0x18,0x08,0x4000,
+- {0x01,0x01,0x00,0x06},
+- 0x63,
+- {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+- 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
+- 0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xc2,
+- 0xff},
+- {0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+- 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+- 0x01,0x00,0x01,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00,
+- 0xff}
+- },
+-/* 0x07: MD_7 */
+- {
+- 0x50,0x18,0x0e,0x1000,
+- {0x00,0x03,0x00,0x03},
+- 0xa6,
+- {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+- 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+- 0x83,0x85,0x5d,0x28,0x0d,0x63,0xba,0xa3,
+- 0xff},
+- {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+- 0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+- 0x0e,0x00,0x0f,0x08},
+- {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
+- 0xff}
+- },
+-/* 0x08: MDA_DAC */
+- {
+- 0x00,0x00,0x00,0x0000,
+- {0x00,0x00,0x00,0x15},
+- 0x15,
+- {0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+- 0x15,0x15,0x15,0x15,0x15,0x15,0x3f,0x3f,
+- 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00,
+- 0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x15,0x15,0x15,
+- 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+- 0x15,0x15,0x15,0x15},
+- {0x15,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+- 0x3f}
+- },
+-/* 0x09: CGA_DAC */
+- {
+- 0x00,0x10,0x04,0x0114,
+- {0x11,0x09,0x15,0x00},
+- 0x10,
+- {0x04,0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,
+- 0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x2a,0x3a,
+- 0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x10,
+- 0x04},
+- {0x14,0x01,0x11,0x09,0x15,0x00,0x10,0x04,
+- 0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,0x2e,
+- 0x3e,0x2b,0x3b,0x2f},
+- {0x3f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
+- 0x3f}
+- },
+-/* 0x0a: EGA_DAC */
+- {
+- 0x00,0x10,0x04,0x0114,
+- {0x11,0x05,0x15,0x20},
+- 0x30,
+- {0x24,0x34,0x21,0x31,0x25,0x35,0x08,0x18,
+- 0x0c,0x1c,0x09,0x19,0x0d,0x1d,0x28,0x38,
+- 0x2c,0x3c,0x29,0x39,0x2d,0x3d,0x02,0x12,
+- 0x06},
+- {0x16,0x03,0x13,0x07,0x17,0x22,0x32,0x26,
+- 0x36,0x23,0x33,0x27,0x37,0x0a,0x1a,0x0e,
+- 0x1e,0x0b,0x1b,0x0f},
+- {0x1f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
+- 0x3f}
+- },
+-/* 0x0b: VGA_DAC */
+- {
+- 0x00,0x10,0x04,0x0114,
+- {0x11,0x09,0x15,0x2a},
+- 0x3a,
+- {0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x05,
+- 0x08,0x0b,0x0e,0x11,0x14,0x18,0x1c,0x20,
+- 0x24,0x28,0x2d,0x32,0x38,0x3f,0x00,0x10,
+- 0x1f},
+- {0x2f,0x3f,0x1f,0x27,0x2f,0x37,0x3f,0x2d,
+- 0x31,0x36,0x3a,0x3f,0x00,0x07,0x0e,0x15,
+- 0x1c,0x0e,0x11,0x15},
+- {0x18,0x1c,0x14,0x16,0x18,0x1a,0x1c,0x00,
+- 0x04}
+- },
+-/* 0x0c */
+- {
+- 0x08,0x0c,0x10,0x0a08,
+- {0x0c,0x0e,0x10,0x0b},
+- 0x0c,
+- {0x0d,0x0f,0x10,0x10,0x01,0x08,0x00,0x00,
+- 0x00,0x00,0x01,0x00,0x02,0x02,0x01,0x00,
+- 0x04,0x04,0x01,0x00,0x05,0x02,0x05,0x00,
+- 0x06},
+- {0x01,0x06,0x05,0x06,0x00,0x08,0x01,0x08,
+- 0x00,0x07,0x02,0x07,0x06,0x07,0x00,0x00,
+- 0x00,0x00,0x00,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+- 0x00}
+- },
+-/* 0x0d: MD_D */
+- {
+- 0x28,0x18,0x08,0x2000,
+- {0x09,0x0f,0x00,0x06},
+- 0x63,
+- {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
+- 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+- 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xe3,
+- 0xff},
+- {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+- 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+- 0x01,0x00,0x0f,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+- 0xff}
+- },
+-/* 0x0e: MD_E */
+- {
+- 0x50,0x18,0x08,0x4000,
+- {0x01,0x0f,0x00,0x06},
+- 0x63,
+- {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+- 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+- 0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xe3,
+- 0xff},
+- {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+- 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+- 0x01,0x00,0x0f,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+- 0xff}
+- },
+-/* 0x0f: ExtVGATable - modes > 0x13 */
+- {
+- 0x00,0x00,0x00,0x0000,
+- {0x01,0x0f,0x00,0x0e},
+- 0x23,
+- {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
+- 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+- 0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3,
+- 0xff},
+- {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+- 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+- 0x01,0x00,0x00,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
+- 0xff}
+- },
+-/* 0x10: ROM_SAVEPTR */
+- {
+- 0x9f,0x3b,0x00,0x00c0,
+- {0x00,0x00,0x00,0x00},
+- 0x00,
+- {0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x3f,
+- 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+- 0x00,0x00,0x1a,0x00,0xac,0x3e,0x00,0xc0,
+- 0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+- 0x00,0x00,0x00,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+- 0x00}
+- },
+-/* 0x11: MD_F */
+- {
+- 0x50,0x18,0x0e,0x8000,
+- {0x01,0x0f,0x00,0x06},
+- 0xa2,
+- {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+- 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+- 0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3,
+- 0xff},
+- {0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00,
+- 0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00,
+- 0x0b,0x00,0x05,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x05,
+- 0xff}
+- },
+-/* 0x12: MD_10 */
+- {
+- 0x50,0x18,0x0e,0x8000,
+- {0x01,0x0f,0x00,0x06},
+- 0xa3,
+- {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+- 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+- 0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3,
+- 0xff},
+- {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+- 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+- 0x01,0x00,0x0f,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+- 0xff}
+- },
+-/* 0x13: MD_0_350 */
+- {
+- 0x28,0x18,0x0e,0x0800,
+- {0x09,0x03,0x00,0x02},
+- 0xa3,
+- {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f,
+- 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+- 0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
+- 0xff},
+- {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+- 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+- 0x08,0x00,0x0f,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+- 0xff}
+- },
+-/* 0x14: MD_1_350 */
+- {
+- 0x28,0x18,0x0e,0x0800,
+- {0x09,0x03,0x00,0x02},
+- 0xa3,
+- {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+- 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+- 0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
+- 0xff},
+- {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+- 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+- 0x08,0x00,0x0f,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+- 0xff}
+- },
+-/* 0x15: MD_2_350 */
+- {
+- 0x50,0x18,0x0e,0x1000,
+- {0x01,0x03,0x00,0x02},
+- 0xa3,
+- {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+- 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+- 0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
+- 0xff},
+- {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+- 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+- 0x08,0x00,0x0f,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+- 0xff}
+- },
+-/* 0x16: MD_3_350 - mode 0x03 - 1 */
+- {
+- 0x50,0x18,0x0e,0x1000,
+- {0x01,0x03,0x00,0x02},
+- 0xa3,
+- {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+- 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+- 0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
+- 0xff},
+- {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+- 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+- 0x08,0x00,0x0f,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+- 0xff}
+- },
+-/* 0x17: MD_0_1_400 */
+- {
+- 0x28,0x18,0x10,0x0800,
+- {0x08,0x03,0x00,0x02},
+- 0x67,
+- {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f,
+- 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
+- 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
+- 0xff},
+- {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+- 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+- 0x0c,0x00,0x0f,0x08},
+- {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+- 0xff}
+- },
+-/* 0x18: MD_2_3_400 - mode 0x03 - 2 */
+- {
+- 0x50,0x18,0x10,0x1000,
+- {0x00,0x03,0x00,0x02},
+- 0x67,
+- {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+- 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
+- 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+- 0xff},
+- {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+- 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+- 0x0c,0x00,0x0f,0x08},
+- {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+- 0xff}
+- },
+-/* 0x19: MD_7_400 */
+- {
+- 0x50,0x18,0x10,0x1000,
+- {0x00,0x03,0x00,0x02},
+- 0x66,
+- {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+- 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
+- 0x9c,0x8e,0x8f,0x28,0x0f,0x96,0xb9,0xa3,
+- 0xff},
+- {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+- 0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+- 0x0e,0x00,0x0f,0x08},
+- {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
+- 0xff}
+- },
+-/* 0x1a: MD_11 */
+- {
+- 0x50,0x1d,0x10,0xa000,
+- {0x01,0x0f,0x00,0x06},
+- 0xe3,
+- {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
+- 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+- 0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xc3,
+- 0xff},
+- {0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+- 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+- 0x01,0x00,0x0f,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01,
+- 0xff}
+- },
+-/* 0x1b: ExtEGATable - Modes <= 0x02 */
+- {
+- 0x50,0x1d,0x10,0xa000,
+- {0x01,0x0f,0x00,0x06},
+- 0xe3,
+- {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
+- 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+- 0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xe3,
+- 0xff},
+- {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+- 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+- 0x01,0x00,0x0f,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+- 0xff}
+- },
+-/* 0x1c: MD_13 */
+- {
+- 0x28,0x18,0x08,0x2000,
+- {0x01,0x0f,0x00,0x0e},
+- 0x63,
+- {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+- 0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
+- 0x9c,0x8e,0x8f,0x28,0x40,0x96,0xb9,0xa3,
+- 0xff},
+- {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+- 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+- 0x41,0x00,0x0f,0x00},
+- {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
+- 0xff}
+- }
+-};
+-
+ typedef struct _SiS310_ExtStruct
+ {
+ UCHAR Ext_ModeID;
+ USHORT Ext_ModeFlag;
+ USHORT Ext_ModeInfo;
+- USHORT Ext_Point; /* TW: Address of table entry in (older) BIOS image */
+ USHORT Ext_VESAID;
+- UCHAR Ext_VESAMEMSize;
+ UCHAR Ext_RESINFO;
+ UCHAR VB_ExtTVFlickerIndex;
+ UCHAR VB_ExtTVEdgeIndex;
+@@ -506,93 +82,93 @@
+ UCHAR REFindex;
+ } SiS310_ExtStruct;
+
+-/* TW: Checked with 650/LVDS and 650/301LVx 1.10.6s */
+ static const SiS310_ExtStruct SiS310_EModeIDTable[]=
+ {
+- {0x6a,0x2212,0x0407,0x3a81,0x0102,0x08,0x07,0x00,0x00,0x07,0x00}, /* 800x600x? */
+- {0x2e,0x0a1b,0x0306,0x3a57,0x0101,0x08,0x06,0x00,0x00,0x05,0x08}, /* 640x480x8 */
+-/* {0x2e,0x021b,0x0306,0x3a57,0x0101,0x08,0x06,0x00,0x00,0x05,0x08}, */ /* 640x480x8 - 650/LVDS BIOS (no CRt2Mode) */
+- {0x2f,0x0a1b,0x0305,0x3a50,0x0100,0x08,0x05,0x00,0x00,0x05,0x10}, /* 640x400x8 */
+-/* {0x2f,0x021b,0x0305,0x3a50,0x0100,0x08,0x05,0x00,0x00,0x05,0x10}, */ /* 640x400x8 - 650/LVDS BIOS (no CRt2Mode) */
+- {0x30,0x2a1b,0x0407,0x3a81,0x0103,0x08,0x07,0x00,0x00,0x07,0x00}, /* 800x600x8 */
+-/* {0x30,0x221b,0x0407,0x3a81,0x0103,0x08,0x07,0x00,0x00,0x07,0x00}, */ /* 800x600x8 - 650/LVDS BIOS (no CRt2Mode) */
+-/* {0x31,0x0a1b,0x030d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11}, */ /* 720x480x8 */
+- {0x31,0x0a1b,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11}, /* 720x480x8 BIOS (301/LVDS) */
+- {0x32,0x0a1b,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12}, /* 720x576x8 */
+- {0x33,0x0a1d,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11}, /* 720x480x16 */
+- {0x34,0x2a1d,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12}, /* 720x576x16 */
+- {0x35,0x0a1f,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11}, /* 720x480x32 */
+- {0x36,0x2a1f,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12}, /* 720x576x32 */
+- {0x37,0x0212,0x0508,0x3aab,0x0104,0x08,0x08,0x00,0x00,0x08,0x13}, /* 1024x768x? */
+- {0x38,0x0a1b,0x0508,0x3aab,0x0105,0x08,0x08,0x00,0x00,0x08,0x13}, /* 1024x768x8 */
+- {0x3a,0x0e3b,0x0609,0x3adc,0x0107,0x08,0x09,0x00,0x00,0x00,0x1a}, /* 1280x1024x8 */
+- {0x3c,0x0e3b,0x070a,0x3af2,0x0130,0x08,0x0a,0x00,0x00,0x00,0x1e}, /* 1600x1200x8 */
+- {0x3d,0x0e7d,0x070a,0x3af2,0x0131,0x08,0x0a,0x00,0x00,0x00,0x1e}, /* 1600x1200x16 - 650/301LVx - no CRT2Mode? */
+- {0x40,0x9a1c,0x0000,0x3a34,0x010d,0x08,0x00,0x00,0x00,0x04,0x25},
+- {0x41,0x9a1d,0x0000,0x3a34,0x010e,0x08,0x00,0x00,0x00,0x04,0x25},
+- {0x43,0x0a1c,0x0306,0x3a57,0x0110,0x08,0x06,0x00,0x00,0x05,0x08},
+- {0x44,0x0a1d,0x0306,0x3a57,0x0111,0x08,0x06,0x00,0x00,0x05,0x08}, /* 640x480x16 */
+- {0x46,0x2a1c,0x0407,0x3a81,0x0113,0x08,0x07,0x00,0x00,0x07,0x00},
+- {0x47,0x2a1d,0x0407,0x3a81,0x0114,0x08,0x07,0x00,0x00,0x07,0x00}, /* 800x600x16 */
+- {0x49,0x0a3c,0x0508,0x3aab,0x0116,0x08,0x08,0x00,0x00,0x00,0x13},
+- {0x4a,0x0a3d,0x0508,0x3aab,0x0117,0x08,0x08,0x00,0x00,0x08,0x13}, /* 1024x768x16 */
+- {0x4c,0x0e7c,0x0609,0x3adc,0x0119,0x08,0x09,0x00,0x00,0x00,0x1a},
+- {0x4d,0x0e7d,0x0609,0x3adc,0x011a,0x08,0x09,0x00,0x00,0x00,0x1a}, /* 1280x1024x16 */
+- {0x50,0x9a1b,0x0001,0x3a3b,0x0132,0x08,0x01,0x00,0x00,0x04,0x26}, /* 320x240 */
+- {0x51,0xba1b,0x0103,0x3a42,0x0133,0x08,0x03,0x00,0x00,0x07,0x27},
+- {0x52,0xba1b,0x0204,0x3a49,0x0134,0x08,0x04,0x00,0x00,0x00,0x28}, /* 650/301 BIOS */
+- {0x56,0x9a1d,0x0001,0x3a3b,0x0135,0x08,0x01,0x00,0x00,0x04,0x26},
+- {0x57,0xba1d,0x0103,0x3a42,0x0136,0x08,0x03,0x00,0x00,0x07,0x27},
+- {0x58,0xba1d,0x0204,0x3a49,0x0137,0x08,0x04,0x00,0x00,0x00,0x28}, /* BIOS (301+LVDS) */
+- {0x59,0x9a1b,0x0000,0x3a34,0x0138,0x08,0x00,0x00,0x00,0x04,0x25}, /* 320x200 */
+- {0x5A,0x021b,0x0014,0x3b83,0x0138,0x08,0x01,0x00,0x00,0x04,0x3f}, /* 320x480x8 fstn add new mode*/
+- {0x5B,0x0a1d,0x0014,0x3b83,0x0135,0x08,0x01,0x00,0x00,0x04,0x3f}, /* 320x480x16 fstn add new mode*/
+- {0x5c,0xba1f,0x0204,0x3a49,0x0000,0x08,0x04,0x00,0x00,0x00,0x28}, /* TW: inserted 512x384x32 */
+- {0x5d,0x0a1d,0x0305,0x3a50,0x0139,0x08,0x05,0x00,0x00,0x07,0x10},
+- {0x5e,0x0a1f,0x0305,0x3a50,0x0000,0x08,0x05,0x00,0x00,0x07,0x10}, /* TW: Inserted 640x400x32 */
+- {0x62,0x0a3f,0x0306,0x3a57,0x013a,0x08,0x06,0x00,0x00,0x05,0x08}, /* 640x480x32 */
+- {0x63,0x2a3f,0x0407,0x3a81,0x013b,0x08,0x07,0x00,0x00,0x07,0x00}, /* 800x600x32 */
+- {0x64,0x0a7f,0x0508,0x3aab,0x013c,0x08,0x08,0x00,0x00,0x08,0x13}, /* 1024x768x32 */
+- {0x65,0x0eff,0x0609,0x3adc,0x013d,0x08,0x09,0x00,0x00,0x00,0x1a}, /* 1280x1024x32 */
+- {0x66,0x0eff,0x070a,0x3af2,0x013e,0x08,0x0a,0x00,0x00,0x00,0x1e}, /* 1600x1200x32 */
+- {0x68,0x067b,0x080b,0x3b17,0x013f,0x08,0x0b,0x00,0x00,0x00,0x29}, /* 1920x1440x8 */
+- {0x69,0x06fd,0x080b,0x3b17,0x0140,0x08,0x0b,0x00,0x00,0x00,0x29}, /* 1920x1440x16 */
+- {0x6b,0x07ff,0x080b,0x3b17,0x0141,0x10,0x0b,0x00,0x00,0x00,0x29}, /* 1920x1440x32 */
+- {0x6c,0x067b,0x090c,0x3b37,0x0000,0x08,0x0c,0x00,0x00,0x00,0x2f}, /* 2048x1536x8 */
+- {0x6d,0x06fd,0x090c,0x3b37,0x0000,0x10,0x0c,0x00,0x00,0x00,0x2f}, /* 2048x1536x16 */
+- {0x6e,0x07ff,0x090c,0x3b37,0x0000,0x10,0x0c,0x00,0x00,0x00,0x2f}, /* 2048x1536x32 */
+- {0x70,0x2a1b,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34}, /* 800x480x8 */
+- {0x71,0x0a1b,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37}, /* 1024x576x8 */
+- {0x74,0x0a1d,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37}, /* 1024x576x16 */
+- {0x75,0x0a3d,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a}, /* 1280x720x16 */
+- {0x76,0x2a1f,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34}, /* 800x480x32 */
+- {0x77,0x0a1f,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37}, /* 1024x576x32 */
+- {0x78,0x0a3f,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a}, /* 1280x720x32 */
+- {0x79,0x0a3b,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a}, /* 1280x720x8 */
+- {0x7a,0x2a1d,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34}, /* 800x480x16 */
+- {0x7c,0x0e3b,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d}, /* 1280x960x8 - TW */
+- {0x7d,0x0e7d,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d}, /* 1280x960x16 - TW */
+- {0x7e,0x0eff,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d}, /* 1280x960x32 - TW */
+- /* TW: 650/LVDS BIOS new modes */
+- {0x23,0x0e3b,0x0614,0x36f7,0x0000,0x08,0x14,0x00,0x00,0x00,0x40}, /* 1280x768x8 */
+- {0x24,0x0e7d,0x0614,0x36f7,0x0000,0x08,0x14,0x00,0x00,0x00,0x40}, /* 1280x768x16 */
+- {0x25,0x0eff,0x0614,0x36f7,0x0000,0x08,0x14,0x00,0x00,0x00,0x40}, /* 1280x768x32 */
+- {0x26,0x0e3b,0x0c15,0x36fe,0x0000,0x08,0x15,0x00,0x00,0x00,0x41}, /* 1400x1050x8 */
+- {0x27,0x0e7d,0x0c15,0x36fe,0x0000,0x08,0x15,0x00,0x00,0x00,0x41}, /* 1400x1050x16 */
+- {0x28,0x0eff,0x0c15,0x36fe,0x0000,0x08,0x15,0x00,0x00,0x00,0x41}, /* 1400x1050x32*/
+- {0x29,0x0e1b,0x0d16,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x43}, /* TW: NEW 1152x864 - not in BIOS */
+- {0x2a,0x0e3d,0x0d16,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x43},
+- {0x2b,0x0e7f,0x0d16,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x43},
+- {0x39,0x2a1b,0x0b17,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x45}, /* TW: NEW 848x480 - not in BIOS */
+- {0x3b,0x2a3d,0x0b17,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x45},
+- {0x3e,0x2a7f,0x0b17,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x45},
+- {0x3f,0x2a1b,0x0b13,0x0000,0x0000,0x08,0x13,0x00,0x00,0x00,0x47}, /* TW: NEW 856x480 - not in BIOS */
+- {0x42,0x2a3d,0x0b13,0x0000,0x0000,0x08,0x13,0x00,0x00,0x00,0x47},
+- {0x45,0x2a7f,0x0b13,0x0000,0x0000,0x08,0x13,0x00,0x00,0x00,0x47},
+- {0x48,0x2a1b,0x0e18,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x49}, /* TW: NEW 1360x768 - not in BIOS */
+- {0x4b,0x2a3d,0x0e18,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x49},
+- {0x4e,0x2a7f,0x0e18,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x49},
+- {0xff,0x0000,0x0000,0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00}
++ {0x6a,0x2212,0x0407,0x0102,SIS_RI_800x600, 0x00,0x00,0x07,0x00}, /* 800x600x? */
++ {0x2e,0x0a1b,0x0306,0x0101,SIS_RI_640x480, 0x00,0x00,0x05,0x08}, /* 640x480x8 */
++ {0x2f,0x0a1b,0x0305,0x0100,SIS_RI_640x400, 0x00,0x00,0x05,0x10}, /* 640x400x8 */
++ {0x30,0x2a1b,0x0407,0x0103,SIS_RI_800x600, 0x00,0x00,0x07,0x00}, /* 800x600x8 */
++ {0x31,0x0a1b,0x0a0d,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x11}, /* 720x480x8 */
++ {0x32,0x0a1b,0x0a0e,0x0000,SIS_RI_720x576, 0x00,0x00,0x06,0x12}, /* 720x576x8 */
++ {0x33,0x0a1d,0x0a0d,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x11}, /* 720x480x16 */
++ {0x34,0x2a1d,0x0a0e,0x0000,SIS_RI_720x576, 0x00,0x00,0x06,0x12}, /* 720x576x16 */
++ {0x35,0x0a1f,0x0a0d,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x11}, /* 720x480x32 */
++ {0x36,0x2a1f,0x0a0e,0x0000,SIS_RI_720x576, 0x00,0x00,0x06,0x12}, /* 720x576x32 */
++ {0x37,0x0212,0x0508,0x0104,SIS_RI_1024x768, 0x00,0x00,0x08,0x13}, /* 1024x768x? */
++ {0x38,0x0a1b,0x0508,0x0105,SIS_RI_1024x768, 0x00,0x00,0x08,0x13}, /* 1024x768x8 */
++ {0x3a,0x0e3b,0x0609,0x0107,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a}, /* 1280x1024x8 */
++ {0x3c,0x0e3b,0x070a,0x0130,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e}, /* 1600x1200x8 */
++ {0x3d,0x0e7d,0x070a,0x0131,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e}, /* 1600x1200x16 */
++ {0x40,0x9a1c,0x0000,0x010d,SIS_RI_320x200, 0x00,0x00,0x04,0x25}, /* 320x200x15 */
++ {0x41,0x9a1d,0x0000,0x010e,SIS_RI_320x200, 0x00,0x00,0x04,0x25}, /* 320x200x16 */
++ {0x43,0x0a1c,0x0306,0x0110,SIS_RI_640x480, 0x00,0x00,0x05,0x08},
++ {0x44,0x0a1d,0x0306,0x0111,SIS_RI_640x480, 0x00,0x00,0x05,0x08}, /* 640x480x16 */
++ {0x46,0x2a1c,0x0407,0x0113,SIS_RI_800x600, 0x00,0x00,0x07,0x00},
++ {0x47,0x2a1d,0x0407,0x0114,SIS_RI_800x600, 0x00,0x00,0x07,0x00}, /* 800x600x16 */
++ {0x49,0x0a3c,0x0508,0x0116,SIS_RI_1024x768, 0x00,0x00,0x00,0x13},
++ {0x4a,0x0a3d,0x0508,0x0117,SIS_RI_1024x768, 0x00,0x00,0x08,0x13}, /* 1024x768x16 */
++ {0x4c,0x0e7c,0x0609,0x0119,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a},
++ {0x4d,0x0e7d,0x0609,0x011a,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a}, /* 1280x1024x16 */
++ {0x50,0x9a1b,0x0001,0x0132,SIS_RI_320x240, 0x00,0x00,0x04,0x26}, /* 320x240x8 */
++ {0x51,0xba1b,0x0103,0x0133,SIS_RI_400x300, 0x00,0x00,0x07,0x27}, /* 400x300x8 */
++ {0x52,0xba1b,0x0204,0x0134,SIS_RI_512x384, 0x00,0x00,0x00,0x28}, /* 512x384x8 */
++ {0x56,0x9a1d,0x0001,0x0135,SIS_RI_320x240, 0x00,0x00,0x04,0x26}, /* 320x240x16 */
++ {0x57,0xba1d,0x0103,0x0136,SIS_RI_400x300, 0x00,0x00,0x07,0x27}, /* 400x300x16 */
++ {0x58,0xba1d,0x0204,0x0137,SIS_RI_512x384, 0x00,0x00,0x00,0x28}, /* 512x384x16 */
++ {0x59,0x9a1b,0x0000,0x0138,SIS_RI_320x200, 0x00,0x00,0x04,0x25}, /* 320x200x8 */
++ {0x5a,0x021b,0x0014,0x0138,SIS_RI_320x240, 0x00,0x00,0x04,0x3f}, /* 320x240x8 fstn */
++ {0x5b,0x0a1d,0x0014,0x0135,SIS_RI_320x240, 0x00,0x00,0x04,0x3f}, /* 320x240x16 fstn */
++ {0x5c,0xba1f,0x0204,0x0000,SIS_RI_512x384, 0x00,0x00,0x00,0x28}, /* 512x384x32 */
++ {0x5d,0x0a1d,0x0305,0x0139,SIS_RI_640x400, 0x00,0x00,0x07,0x10},
++ {0x5e,0x0a1f,0x0305,0x0000,SIS_RI_640x400, 0x00,0x00,0x07,0x10}, /* 640x400x32 */
++ {0x62,0x0a3f,0x0306,0x013a,SIS_RI_640x480, 0x00,0x00,0x05,0x08}, /* 640x480x32 */
++ {0x63,0x2a3f,0x0407,0x013b,SIS_RI_800x600, 0x00,0x00,0x07,0x00}, /* 800x600x32 */
++ {0x64,0x0a7f,0x0508,0x013c,SIS_RI_1024x768, 0x00,0x00,0x08,0x13}, /* 1024x768x32 */
++ {0x65,0x0eff,0x0609,0x013d,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a}, /* 1280x1024x32 */
++ {0x66,0x0eff,0x070a,0x013e,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e}, /* 1600x1200x32 */
++ {0x68,0x067b,0x080b,0x013f,SIS_RI_1920x1440,0x00,0x00,0x00,0x29}, /* 1920x1440x8 */
++ {0x69,0x06fd,0x080b,0x0140,SIS_RI_1920x1440,0x00,0x00,0x00,0x29}, /* 1920x1440x16 */
++ {0x6b,0x07ff,0x080b,0x0141,SIS_RI_1920x1440,0x00,0x00,0x00,0x29}, /* 1920x1440x32 */
++ {0x6c,0x067b,0x090c,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x2f}, /* 2048x1536x8 */
++ {0x6d,0x06fd,0x090c,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x2f}, /* 2048x1536x16 */
++ {0x6e,0x07ff,0x090c,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x2f}, /* 2048x1536x32 */
++ {0x70,0x2a1b,0x0410,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x34}, /* 800x480x8 */
++ {0x71,0x0a1b,0x0511,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x37}, /* 1024x576x8 */
++ {0x74,0x0a1d,0x0511,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x37}, /* 1024x576x16 */
++ {0x75,0x0a3d,0x0612,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x3a}, /* 1280x720x16 */
++ {0x76,0x2a1f,0x0410,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x34}, /* 800x480x32 */
++ {0x77,0x0a1f,0x0511,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x37}, /* 1024x576x32 */
++ {0x78,0x0a3f,0x0612,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x3a}, /* 1280x720x32 */
++ {0x79,0x0a3b,0x0612,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x3a}, /* 1280x720x8 */
++ {0x7a,0x2a1d,0x0410,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x34}, /* 800x480x16 */
++ {0x7c,0x0e3b,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x3d}, /* 1280x960x8 */
++ {0x7d,0x0e7d,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x3d}, /* 1280x960x16 */
++ {0x7e,0x0eff,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x3d}, /* 1280x960x32 */
++ {0x23,0x0e3b,0x0614,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x40}, /* 1280x768x8 */
++ {0x24,0x0e7d,0x0614,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x40}, /* 1280x768x16 */
++ {0x25,0x0eff,0x0614,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x40}, /* 1280x768x32 */
++ {0x26,0x0e3b,0x0c15,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x41}, /* 1400x1050x8 */
++ {0x27,0x0e7d,0x0c15,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x41}, /* 1400x1050x16 */
++ {0x28,0x0eff,0x0c15,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x41}, /* 1400x1050x32*/
++ {0x29,0x0e1b,0x0d16,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x43}, /* 1152x864 */
++ {0x2a,0x0e3d,0x0d16,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x43},
++ {0x2b,0x0e7f,0x0d16,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x43},
++ {0x39,0x2a1b,0x0b17,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x45}, /* 848x480 */
++ {0x3b,0x2a3d,0x0b17,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x45},
++ {0x3e,0x2a7f,0x0b17,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x45},
++ {0x3f,0x2a1b,0x0b13,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x47}, /* 856x480 */
++ {0x42,0x2a3d,0x0b13,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x47},
++ {0x45,0x2a7f,0x0b13,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x47},
++ {0x48,0x2a1b,0x0e18,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x49}, /* 1360x768 */
++ {0x4b,0x2a3d,0x0e18,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x49},
++ {0x4e,0x2a7f,0x0e18,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x49},
++ {0x4f,0x9a1f,0x0000,0x0000,SIS_RI_320x200, 0x00,0x00,0x04,0x25}, /* 320x200x32 */
++ {0x53,0x9a1f,0x0001,0x0000,SIS_RI_320x240, 0x00,0x00,0x04,0x26}, /* 320x240x32 */
++ {0x54,0xba1f,0x0103,0x0000,SIS_RI_400x300, 0x00,0x00,0x07,0x27}, /* 400x300x32 */
++ {0x5f,0x2a1b,0x0f0e,0x0000,SIS_RI_768x576, 0x00,0x00,0x00,0x4a}, /* 768x576x8 */
++ {0x60,0x2a1d,0x0f0e,0x0000,SIS_RI_768x576, 0x00,0x00,0x00,0x4a}, /* 768x576x16 */
++ {0x61,0x2a1f,0x0f0e,0x0000,SIS_RI_768x576, 0x00,0x00,0x00,0x4a}, /* 768x576x32 */
++ {0xff,0x0000,0x0000,0x0000,0x00, 0x00,0x00,0x00,0x00}
+ };
+
+ typedef struct _SiS310_Ext2Struct
+@@ -604,89 +180,87 @@
+ UCHAR ModeID;
+ USHORT XRes;
+ USHORT YRes;
+- USHORT ROM_OFFSET;
+ } SiS310_Ext2Struct;
+
+ static const SiS310_Ext2Struct SiS310_RefIndex[]=
+ {
+-/* {0x005f,0x0d,0x03,0x05,0x6a, 800, 600,0x3a81}, 0x0 - TW: Patch for Chrontel 7019 */
+- {0x085f,0x0d,0x03,0x05,0x6a, 800, 600,0x3a81}, /* 0x0 */
+- {0x0467,0x0e,0x04,0x05,0x6a, 800, 600,0x3a86}, /* 0x1 */
+- {0x0067,0x0f,0x08,0x48,0x6a, 800, 600,0x3a8b}, /* 0x2 */
+- {0x0067,0x10,0x07,0x8b,0x6a, 800, 600,0x3a90}, /* 0x3 */
+- {0x0147,0x11,0x0a,0x00,0x6a, 800, 600,0x3a95}, /* 0x4 */
+- {0x0147,0x12,0x0d,0x00,0x6a, 800, 600,0x3a9a}, /* 0x5 - 4147 TW: Test sync change */
+- {0x0047,0x13,0x13,0x00,0x6a, 800, 600,0x3a9f}, /* 0x6 - 4047 */
+- {0x0047,0x14,0x1c,0x00,0x6a, 800, 600,0x3aa4}, /* 0x7 - 4047 */
+-/* {0xc05f,0x05,0x00,0x04,0x2e, 640, 480,0x3a57}, 0x8 - TW: Patch for Chrontel 7019 */
+- {0xc85f,0x05,0x00,0x04,0x2e, 640, 480,0x3a57}, /* 0x8 */
+- {0xc067,0x06,0x02,0x04,0x2e, 640, 480,0x3a5c}, /* 0x9 */
+- {0xc067,0x07,0x02,0x47,0x2e, 640, 480,0x3a61}, /* 0xa */
+- {0xc067,0x08,0x03,0x8a,0x2e, 640, 480,0x3a66}, /* 0xb */
+- {0xc047,0x09,0x05,0x00,0x2e, 640, 480,0x3a6b}, /* 0xc - 4047 */
+- {0xc047,0x0a,0x09,0x00,0x2e, 640, 480,0x3a70}, /* 0xd - 4047 */
+- {0xc047,0x0b,0x0e,0x00,0x2e, 640, 480,0x3a75}, /* 0xe - 4047 */
+- {0xc047,0x0c,0x15,0x00,0x2e, 640, 480,0x3a7a}, /* 0xf */
+- {0x407f,0x04,0x00,0x00,0x2f, 640, 400,0x3a50}, /* 0x10 */
+- {0xc00f,0x3c,0x01,0x06,0x31, 720, 480,0x3b85}, /* 0x11 */
+- {0x000f,0x3d,0x03,0x06,0x32, 720, 576,0x3b8c}, /* 0x12 */
+- {0x0187,0x15,0x06,0x00,0x37,1024, 768,0x3aab}, /* 0x13 */
+- {0xc877,0x16,0x0b,0x06,0x37,1024, 768,0x3ab0}, /* 0x14 */
+- {0xc067,0x17,0x0f,0x49,0x37,1024, 768,0x3ab5}, /* 0x15 */
+- {0x0267,0x18,0x11,0x00,0x37,1024, 768,0x3aba}, /* 0x16 */
+- {0x0047,0x19,0x16,0x8c,0x37,1024, 768,0x3abf}, /* 0x17 */
+- {0x0047,0x1a,0x1b,0x00,0x37,1024, 768,0x3ac4}, /* 0x18 - 4047 */
+- {0x0007,0x1b,0x1f,0x00,0x37,1024, 768,0x3ac9}, /* 0x19 - 4047 */
+- {0x0387,0x1c,0x11,0x00,0x3a,1280,1024,0x3adc}, /* 0x1a */
+- {0x0077,0x1d,0x19,0x07,0x3a,1280,1024,0x3ae1}, /* 0x1b */
+- {0x0047,0x1e,0x1e,0x00,0x3a,1280,1024,0x3ae6}, /* 0x1c */
+- {0x0007,0x1f,0x20,0x00,0x3a,1280,1024,0x3aeb}, /* 0x1d */
+- {0x0027,0x20,0x21,0x09,0x3c,1600,1200,0x3af2}, /* 0x1e */
+- {0x0007,0x21,0x22,0x00,0x3c,1600,1200,0x3af7}, /* 0x1f */
+- {0x0007,0x22,0x23,0x00,0x3c,1600,1200,0x3afc}, /* 0x20 */
+- {0x0007,0x23,0x25,0x00,0x3c,1600,1200,0x3b01}, /* 0x21 */
+- {0x0007,0x24,0x26,0x00,0x3c,1600,1200,0x3b06}, /* 0x22 */
+- {0x0007,0x25,0x2c,0x00,0x3c,1600,1200,0x3b0b}, /* 0x23 */
+- {0x0007,0x26,0x34,0x00,0x3c,1600,1200,0x3b10}, /* 0x24 */
+- {0x407f,0x00,0x00,0x00,0x40, 320, 200,0x3a34}, /* 0x25 */
+- {0xc07f,0x01,0x00,0x04,0x50, 320, 240,0x3a3b}, /* 0x26 */
+- {0x007f,0x02,0x04,0x05,0x51, 400, 300,0x3a42}, /* 0x27 */
+- {0xc077,0x03,0x0b,0x06,0x52, 512, 384,0x3a49}, /* 0x28 */
+- {0x8007,0x27,0x27,0x00,0x68,1920,1440,0x3b17}, /* 0x29 */
+- {0x4007,0x28,0x29,0x00,0x68,1920,1440,0x3b1c}, /* 0x2a */
+- {0x4007,0x29,0x2e,0x00,0x68,1920,1440,0x3b21}, /* 0x2b */
+- {0x4007,0x2a,0x30,0x00,0x68,1920,1440,0x3b26}, /* 0x2c */
+- {0x4007,0x2b,0x35,0x00,0x68,1920,1440,0x3b2b}, /* 0x2d */
+- {0x4005,0x2c,0x39,0x00,0x68,1920,1440,0x3b30}, /* 0x2e */
+- {0x4007,0x2d,0x2b,0x00,0x6c,2048,1536,0x3b37}, /* 0x2f */
+- {0x4007,0x2e,0x31,0x00,0x6c,2048,1536,0x3b3c}, /* 0x30 */
+- {0x4007,0x2f,0x33,0x00,0x6c,2048,1536,0x3b41}, /* 0x31 */
+- {0x4007,0x30,0x37,0x00,0x6c,2048,1536,0x3b46}, /* 0x32 */
+- {0x4005,0x31,0x38,0x00,0x6c,2048,1536,0x3b4b}, /* 0x33 */
+- {0x0057,0x32,0x40,0x08,0x70, 800, 480,0x3b52}, /* 0x34 */
+- {0x0047,0x33,0x07,0x08,0x70, 800, 480,0x3b57}, /* 0x35 */
+- {0x0047,0x34,0x0a,0x08,0x70, 800, 480,0x3b5c}, /* 0x36 */
+- {0x0057,0x35,0x0b,0x09,0x71,1024, 576,0x3b63}, /* 0x37 */
+- {0x0047,0x36,0x11,0x09,0x71,1024, 576,0x3b68}, /* 0x38 */
+- {0x0047,0x37,0x16,0x09,0x71,1024, 576,0x3b6d}, /* 0x39 */
+- {0x0057,0x38,0x19,0x0a,0x75,1280, 720,0x3b74}, /* 0x3a */
+- {0x0047,0x39,0x1e,0x0a,0x75,1280, 720,0x3b79}, /* 0x3b */
+- {0x0007,0x3a,0x20,0x0a,0x75,1280, 720,0x3b7e}, /* 0x3c */
+- {0x0067,0x3b,0x19,0x08,0x7c,1280, 960,0x3ad0}, /* 0x3d */
+- {0x0027,0x4c,0x59,0x08,0x7c,1280, 960,0x3ad0}, /* 0x3e */
+- {0xc07f,0x01,0x00,0x06,0x5a, 320, 480,0x3b83}, /* 0x3f */ /* FSTN mode */
+- {0x0077,0x42,0x12,0x08,0x23,1280, 768,0x0000}, /* 0x40 */
+- {0x0067,0x43,0x4d,0x08,0x26,1400,1050,0x0000}, /* 0x41 */
+- {0x0007,0x4b,0x5a,0x08,0x26,1400,1050,0x0000}, /* 0x42 */ /* TW: new, not in any BIOS */
+- {0x0047,0x44,0x19,0x00,0x29,1152, 864,0x0000}, /* 0x43 TW: Non-BIOS, new */
+- {0x0047,0x4a,0x1e,0x00,0x29,1152, 864,0x0000}, /* 0x44 TW: Non-BIOS, new */
+- {0x00c7,0x45,0x57,0x00,0x39, 848, 480,0x0000}, /* 0x45 TW: 848x480-38Hzi - Non-BIOS, new */
+- {0xc047,0x46,0x55,0x00,0x39, 848, 480,0x0000}, /* 0x46 TW: 848x480-60Hz - Non-BIOS, new */
+- {0x00c7,0x47,0x57,0x00,0x3f, 856, 480,0x0000}, /* 0x47 TW: 856x480-38Hzi - Non-BIOS, new */
+- {0xc047,0x48,0x57,0x00,0x3f, 856, 480,0x0000}, /* 0x48 TW: 856x480-60Hz - Non-BIOS, new */
+- {0x0047,0x49,0x58,0x00,0x48,1360, 768,0x0000}, /* 0x49 TW: 1360x768-60Hz - Non-BIOS, new */
+- {0xffff,0x00,0x00,0x00,0x00, 0, 0,0x0000}
+-};
++ {0x085f,0x0d,0x03,0x05,0x6a, 800, 600}, /* 0x0 */
++ {0x0467,0x0e,0x04,0x05,0x6a, 800, 600}, /* 0x1 */
++ {0x0067,0x0f,0x08,0x48,0x6a, 800, 600}, /* 0x2 */
++ {0x0067,0x10,0x07,0x8b,0x6a, 800, 600}, /* 0x3 */
++ {0x0147,0x11,0x0a,0x00,0x6a, 800, 600}, /* 0x4 */
++ {0x0147,0x12,0x0d,0x00,0x6a, 800, 600}, /* 0x5 - TW: Test sync change */
++ {0x0047,0x13,0x13,0x00,0x6a, 800, 600}, /* 0x6 */
++ {0x0047,0x14,0x1c,0x00,0x6a, 800, 600}, /* 0x7 */
++ {0xc85f,0x05,0x00,0x04,0x2e, 640, 480}, /* 0x8 */
++ {0xc067,0x06,0x02,0x04,0x2e, 640, 480}, /* 0x9 */
++ {0xc067,0x07,0x02,0x47,0x2e, 640, 480}, /* 0xa */
++ {0xc067,0x08,0x03,0x8a,0x2e, 640, 480}, /* 0xb */
++ {0xc047,0x09,0x05,0x00,0x2e, 640, 480}, /* 0xc */
++ {0xc047,0x0a,0x09,0x00,0x2e, 640, 480}, /* 0xd */
++ {0xc047,0x0b,0x0e,0x00,0x2e, 640, 480}, /* 0xe */
++ {0xc047,0x0c,0x15,0x00,0x2e, 640, 480}, /* 0xf */
++ {0x407f,0x04,0x00,0x00,0x2f, 640, 400}, /* 0x10 */
++ {0xc00f,0x3c,0x01,0x06,0x31, 720, 480}, /* 0x11 */
++ {0x000f,0x3d,0x03,0x06,0x32, 720, 576}, /* 0x12 */
++ {0x0187,0x15,0x06,0x00,0x37,1024, 768}, /* 0x13 */
++ {0xc877,0x16,0x0b,0x06,0x37,1024, 768}, /* 0x14 */
++ {0xc067,0x17,0x0f,0x49,0x37,1024, 768}, /* 0x15 */
++ {0x0267,0x18,0x11,0x00,0x37,1024, 768}, /* 0x16 */
++ {0x0047,0x19,0x16,0x8c,0x37,1024, 768}, /* 0x17 */
++ {0x0047,0x1a,0x1b,0x00,0x37,1024, 768}, /* 0x18 */
++ {0x0007,0x1b,0x1f,0x00,0x37,1024, 768}, /* 0x19 */
++ {0x0387,0x1c,0x11,0x00,0x3a,1280,1024}, /* 0x1a */
++ {0x0077,0x1d,0x19,0x07,0x3a,1280,1024}, /* 0x1b */
++ {0x0047,0x1e,0x1e,0x00,0x3a,1280,1024}, /* 0x1c */
++ {0x0007,0x1f,0x20,0x00,0x3a,1280,1024}, /* 0x1d */
++ {0x0867,0x20,0x21,0x09,0x3c,1600,1200}, /* 0x1e */
++ {0x0007,0x21,0x22,0x00,0x3c,1600,1200}, /* 0x1f */
++ {0x0007,0x22,0x23,0x00,0x3c,1600,1200}, /* 0x20 */
++ {0x0007,0x23,0x25,0x00,0x3c,1600,1200}, /* 0x21 */
++ {0x0007,0x24,0x26,0x00,0x3c,1600,1200}, /* 0x22 */
++ {0x0007,0x25,0x2c,0x00,0x3c,1600,1200}, /* 0x23 */
++ {0x0007,0x26,0x34,0x00,0x3c,1600,1200}, /* 0x24 */
++ {0x407f,0x00,0x00,0x00,0x40, 320, 200}, /* 0x25 */
++ {0xc07f,0x01,0x00,0x04,0x50, 320, 240}, /* 0x26 */
++ {0x007f,0x02,0x04,0x05,0x51, 400, 300}, /* 0x27 */
++ {0xc077,0x03,0x0b,0x06,0x52, 512, 384}, /* 0x28 */
++ {0x8007,0x27,0x27,0x00,0x68,1920,1440}, /* 0x29 */
++ {0x4007,0x28,0x29,0x00,0x68,1920,1440}, /* 0x2a */
++ {0x4007,0x29,0x2e,0x00,0x68,1920,1440}, /* 0x2b */
++ {0x4007,0x2a,0x30,0x00,0x68,1920,1440}, /* 0x2c */
++ {0x4007,0x2b,0x35,0x00,0x68,1920,1440}, /* 0x2d */
++ {0x4005,0x2c,0x39,0x00,0x68,1920,1440}, /* 0x2e */
++ {0x4007,0x2d,0x2b,0x00,0x6c,2048,1536}, /* 0x2f */
++ {0x4007,0x2e,0x31,0x00,0x6c,2048,1536}, /* 0x30 */
++ {0x4007,0x2f,0x33,0x00,0x6c,2048,1536}, /* 0x31 */
++ {0x4007,0x30,0x37,0x00,0x6c,2048,1536}, /* 0x32 */
++ {0x4005,0x31,0x38,0x00,0x6c,2048,1536}, /* 0x33 */
++ {0x0057,0x32,0x40,0x08,0x70, 800, 480}, /* 0x34 */
++ {0x0047,0x33,0x07,0x08,0x70, 800, 480}, /* 0x35 */
++ {0x0047,0x34,0x0a,0x08,0x70, 800, 480}, /* 0x36 */
++ {0x0057,0x35,0x0b,0x09,0x71,1024, 576}, /* 0x37 */
++ {0x0047,0x36,0x11,0x09,0x71,1024, 576}, /* 0x38 */
++ {0x0047,0x37,0x16,0x09,0x71,1024, 576}, /* 0x39 */
++ {0x0057,0x38,0x19,0x0a,0x75,1280, 720}, /* 0x3a */
++ {0x0047,0x39,0x1e,0x0a,0x75,1280, 720}, /* 0x3b */
++ {0x0007,0x3a,0x20,0x0a,0x75,1280, 720}, /* 0x3c */
++ {0x0067,0x3b,0x19,0x08,0x7c,1280, 960}, /* 0x3d */
++ {0x0027,0x4c,0x59,0x08,0x7c,1280, 960}, /* 0x3e */
++ {0xc07f,0x4e,0x00,0x06,0x5a, 320, 240}, /* 0x3f */ /* FSTN 320x240 */
++ {0x0077,0x42,0x5b,0x08,0x23,1280, 768}, /* 0x40 */ /* TW: 0x5b was 0x12 */
++ {0x0067,0x43,0x4d,0x08,0x26,1400,1050}, /* 0x41 */
++ {0x0007,0x4b,0x5a,0x08,0x26,1400,1050}, /* 0x42 TW: not in any BIOS */
++ {0x0047,0x44,0x19,0x00,0x29,1152, 864}, /* 0x43 TW: Non-BIOS, new */
++ {0x0047,0x4a,0x1e,0x00,0x29,1152, 864}, /* 0x44 TW: Non-BIOS, new */
++ {0x00c7,0x45,0x57,0x00,0x39, 848, 480}, /* 0x45 TW: 848x480-38Hzi - Non-BIOS, new */
++ {0xc067,0x46,0x55,0x0b,0x39, 848, 480}, /* 0x46 TW: 848x480-60Hz - Non-BIOS, new */
++ {0x00c7,0x47,0x57,0x00,0x3f, 856, 480}, /* 0x47 TW: 856x480-38Hzi - Non-BIOS, new */
++ {0xc047,0x48,0x57,0x00,0x3f, 856, 480}, /* 0x48 TW: 856x480-60Hz - Non-BIOS, new */
++ {0x0067,0x49,0x58,0x0c,0x48,1360, 768}, /* 0x49 TW: 1360x768-60Hz - Non-BIOS, new */
++ {0x000f,0x4d,0x03,0x06,0x5f, 768, 576}, /* 0x4a TW: 768x576 */
++ {0xffff,0x00,0x00,0x00,0x00, 0, 0}
++};
+
+ typedef struct _SiS310_CRT1TableStruct
+ {
+@@ -710,7 +284,7 @@
+ {{0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+ 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x05,
+ 0x00}}, /* 0x4 */
+-#if 0
++#if 0
+ {{0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
+ 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
+ 0x00}}, /* 0x5 */
+@@ -940,19 +514,25 @@
+ 0x00}}, /* 0x4b */
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff, /* TW: New, 1280x960-85, not in any BIOS */
+ 0xc0,0x83,0xbf,0xbf,0xf2,0x10,0x00,0x07,
+- 0x01}} /* 0x4c */
++ 0x01}}, /* 0x4c */
++ {{0x7b,0x5f,0x63,0x9f,0x6a,0x93,0x6f,0xf0, /* 768x576 */
++ 0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05,
++ 0x01}}, /* 0x4d */
++ {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e, /* FSTN 320x480, TEMP - possibly invalid */
++ 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,
++ 0x00}} /* 0x4e */
+ };
+
+-
+ typedef struct _SiS310_MCLKDataStruct
+ {
+ UCHAR SR28,SR29,SR2A;
+ USHORT CLOCK;
+ } SiS310_MCLKDataStruct;
+
++#ifdef LINUXBIOS
+ static const SiS310_MCLKDataStruct SiS310_MCLKData_0_315[] =
+ {
+- { 0x3b,0x22,0x01,143}, /* TW: Was { 0x5c,0x23,0x01,166}, */
++ { 0x3b,0x22,0x01,143},
+ { 0x5c,0x23,0x01,166},
+ { 0x5c,0x23,0x01,166},
+ { 0x5c,0x23,0x01,166},
+@@ -962,7 +542,7 @@
+ { 0x5c,0x23,0x01,166}
+ };
+
+-static const SiS310_MCLKDataStruct SiS310_MCLKData_0_650[] = /* @ 0x54 */
++static const SiS310_MCLKDataStruct SiS310_MCLKData_0_650[] =
+ {
+ { 0x5a,0x64,0x82, 66},
+ { 0xb3,0x45,0x82, 83},
+@@ -973,8 +553,22 @@
+ { 0x37,0x22,0x82,133},
+ { 0x37,0x22,0x82,133}
+ };
++#endif
++
++static const SiS310_MCLKDataStruct SiS310_MCLKData_0_330[] =
++{
++ { 0x5c,0x23,0x01,166},
++ { 0x5c,0x23,0x01,166},
++ { 0x7c,0x08,0x01,200},
++ { 0x79,0x06,0x01,250},
++ { 0x7c,0x08,0x01,200},
++ { 0x7c,0x08,0x01,200},
++ { 0x7c,0x08,0x01,200},
++ { 0x79,0x06,0x01,250}
++};
+
+-static const SiS310_MCLKDataStruct SiS310_MCLKData_0_330[] = /* @ 0x54 */
++#ifdef LINUXBIOS
++static const SiS310_MCLKDataStruct SiS310_MCLKData_0_660[] = /* TODO */
+ {
+ { 0x5c,0x23,0x01,166},
+ { 0x5c,0x23,0x01,166},
+@@ -985,8 +579,9 @@
+ { 0x7c,0x08,0x01,200},
+ { 0x79,0x06,0x01,250}
+ };
++#endif
+
+-static const SiS310_MCLKDataStruct SiS310_MCLKData_1[] = /* @ 0x155 */
++static const SiS310_MCLKDataStruct SiS310_MCLKData_1[] =
+ {
+ { 0x29,0x21,0x82,150},
+ { 0x5c,0x23,0x82,166},
+@@ -998,6 +593,7 @@
+ { 0x37,0x22,0x82,133}
+ };
+
++#ifdef LINUXBIOS
+ typedef struct _SiS310_ECLKDataStruct
+ {
+ UCHAR SR2E,SR2F,SR30;
+@@ -1011,6 +607,7 @@
+ { 0x5c,0x23,0x01,166},
+ { 0x5c,0x23,0x01,166}
+ };
++#endif
+
+ typedef struct _SiS310_VCLKDataStruct
+ {
+@@ -1020,22 +617,22 @@
+
+ static const SiS310_VCLKDataStruct SiS310_VCLKData[]=
+ {
+- { 0x1b,0xe1, 25}, /* 0x0 */ /* 650/LVDS BIOS: @ 0x5647 */
+- { 0x4e,0xe4, 28}, /* 0x1 */
+- { 0x57,0xe4, 31}, /* 0x2 */
+- { 0xc3,0xc8, 36}, /* 0x3 */
+- { 0x42,0xe2, 40}, /* 0x4 */
+- { 0xfe,0xcd, 43}, /* 0x5 */
+- { 0x5d,0xc4, 44}, /* 0x6 */
+- { 0x52,0xe2, 49}, /* 0x7 */
+- { 0x53,0xe2, 50}, /* 0x8 */
+- { 0x74,0x67, 52}, /* 0x9 */
+- { 0x6d,0x66, 56}, /* 0xa */
+- { 0x5a,0x64, 65}, /* 0xb */ /* TW: was 6c c3 - WRONG */
+- { 0x46,0x44, 67}, /* 0xc */
+- { 0xb1,0x46, 68}, /* 0xd */
+- { 0xd3,0x4a, 72}, /* 0xe */
+- { 0x29,0x61, 75}, /* 0xf */
++ { 0x1b,0xe1, 25}, /* 0x00 */
++ { 0x4e,0xe4, 28}, /* 0x01 */
++ { 0x57,0xe4, 31}, /* 0x02 */
++ { 0xc3,0xc8, 36}, /* 0x03 */
++ { 0x42,0xe2, 40}, /* 0x04 */
++ { 0xfe,0xcd, 43}, /* 0x05 */
++ { 0x5d,0xc4, 44}, /* 0x06 */
++ { 0x52,0xe2, 49}, /* 0x07 */
++ { 0x53,0xe2, 50}, /* 0x08 */
++ { 0x74,0x67, 52}, /* 0x09 */
++ { 0x6d,0x66, 56}, /* 0x0a */
++ { 0x5a,0x64, 65}, /* 0x0b */ /* TW: was 6c c3 - WRONG */
++ { 0x46,0x44, 67}, /* 0x0c */
++ { 0xb1,0x46, 68}, /* 0x0d */
++ { 0xd3,0x4a, 72}, /* 0x0e */
++ { 0x29,0x61, 75}, /* 0x0f */
+ { 0x6e,0x46, 76}, /* 0x10 */
+ { 0x2b,0x61, 78}, /* 0x11 */
+ { 0x31,0x42, 79}, /* 0x12 */
+@@ -1045,7 +642,7 @@
+ { 0x62,0x44, 94}, /* 0x16 */
+ { 0x2b,0x41,104}, /* 0x17 */
+ { 0x3a,0x23,105}, /* 0x18 */
+- { 0x70,0x44,108}, /* 0x19 */
++ { 0x70,0x44,108}, /* 0x19 */ /* 1400x1050 LCD */
+ { 0x3c,0x23,109}, /* 0x1a */
+ { 0x5e,0x43,113}, /* 0x1b */
+ { 0xbc,0x44,116}, /* 0x1c */
+@@ -1078,12 +675,12 @@
+ { 0xea,0x08,340}, /* 0x37 */
+ { 0xe8,0x07,376}, /* 0x38 */
+ { 0xde,0x06,389}, /* 0x39 */
+- { 0x52,0x2a, 54}, /* 0x3a */
+- { 0x52,0x6a, 27}, /* 0x3b */
+- { 0x62,0x24, 70}, /* 0x3c */
+- { 0x62,0x64, 70}, /* 0x3d */
+- { 0xa8,0x4c, 30}, /* 0x3e */
+- { 0x20,0x26, 33}, /* 0x3f */
++ { 0x52,0x2a, 54}, /* 0x3a */ /* 301 TV */
++ { 0x52,0x6a, 27}, /* 0x3b */ /* 301 TV */
++ { 0x62,0x24, 70}, /* 0x3c */ /* 301 TV */
++ { 0x62,0x64, 70}, /* 0x3d */ /* 301 TV */
++ { 0xa8,0x4c, 30}, /* 0x3e */ /* 301 TV */
++ { 0x20,0x26, 33}, /* 0x3f */ /* 301 TV */
+ { 0x31,0xc2, 39}, /* 0x40 */
+ { 0x60,0x36, 30}, /* 0x41 */ /* Chrontel */
+ { 0x40,0x4a, 28}, /* 0x42 */ /* Chrontel */
+@@ -1096,7 +693,7 @@
+ { 0xce,0x3c, 39}, /* 0x49 */
+ { 0x52,0x4a, 36}, /* 0x4a */ /* Chrontel */
+ { 0x34,0x61, 95}, /* 0x4b */
+- { 0x78,0x27,108}, /* 0x4c - was 102 */ /* TW: Last entry in 650/301 BIOS */
++ { 0x78,0x27,108}, /* 0x4c - was 102 */
+ { 0x66,0x43,123}, /* 0x4d */ /* Modes 0x26-0x28 (1400x1050) */
+ { 0x41,0x4e, 21}, /* 0x4e */
+ { 0xa1,0x4a, 29}, /* 0x4f */ /* Chrontel */
+@@ -1110,7 +707,8 @@
+ { 0xbf,0xc8, 35}, /* 0x57 - added for 856x480-38i,60 (not in any BIOS) */
+ { 0x30,0x23, 88}, /* 0x58 - added for 1360x768-62 (is 60Hz!) (not in any BIOS) */
+ { 0x52,0x07,149}, /* 0x59 - added for 1280x960-85 (Not in any BIOS) */
+- { 0x56,0x07,156} /* 0x5a - added for 1400x1050-75 */
++ { 0x56,0x07,156}, /* 0x5a - added for 1400x1050-75 */
++ { 0x70,0x29, 81} /* 0x5b */ /* 1280x768 LCD */
+ };
+
+ typedef struct _SiS310_VBVCLKDataStruct
+@@ -1121,22 +719,22 @@
+
+ static const SiS310_VBVCLKDataStruct SiS310_VBVCLKData[]=
+ {
+- { 0x1b,0xe1, 25}, /* 0x0 */ /* 650/LVDS BIOS: @ 0x579c */
+- { 0x4e,0xe4, 28}, /* 0x1 */
+- { 0x57,0xe4, 31}, /* 0x2 */
+- { 0xc3,0xc8, 36}, /* 0x3 */
+- { 0x42,0x47, 40}, /* 0x4 */
+- { 0xfe,0xcd, 43}, /* 0x5 */
+- { 0x5d,0xc4, 44}, /* 0x6 */
+- { 0x52,0x47, 49}, /* 0x7 */
+- { 0x53,0x47, 50}, /* 0x8 */
+- { 0x74,0x67, 52}, /* 0x9 */
+- { 0x6d,0x66, 56}, /* 0xa */
+- { 0x35,0x62, 65}, /* 0xb */ /* Was 0x5a,0x64 - 650/LVDS+301 bios: 35,62 */
+- { 0x46,0x44, 67}, /* 0xc */
+- { 0xb1,0x46, 68}, /* 0xd */
+- { 0xd3,0x4a, 72}, /* 0xe */
+- { 0x29,0x61, 75}, /* 0xf */
++ { 0x1b,0xe1, 25}, /* 0x00 */
++ { 0x4e,0xe4, 28}, /* 0x01 */
++ { 0x57,0xe4, 31}, /* 0x02 */
++ { 0xc3,0xc8, 36}, /* 0x03 */
++ { 0x42,0x47, 40}, /* 0x04 */
++ { 0xfe,0xcd, 43}, /* 0x05 */
++ { 0x5d,0xc4, 44}, /* 0x06 */
++ { 0x52,0x47, 49}, /* 0x07 */
++ { 0x53,0x47, 50}, /* 0x08 */
++ { 0x74,0x67, 52}, /* 0x09 */
++ { 0x6d,0x66, 56}, /* 0x0a */
++ { 0x35,0x62, 65}, /* 0x0b */ /* Was 0x5a,0x64 - 650/LVDS+301 bios: 35,62 */
++ { 0x46,0x44, 67}, /* 0x0c */
++ { 0xb1,0x46, 68}, /* 0x0d */
++ { 0xd3,0x4a, 72}, /* 0x0e */
++ { 0x29,0x61, 75}, /* 0x0f */
+ { 0x6d,0x46, 75}, /* 0x10 */
+ { 0x41,0x43, 78}, /* 0x11 */
+ { 0x31,0x42, 79}, /* 0x12 */
+@@ -1146,7 +744,7 @@
+ { 0x62,0x44, 94}, /* 0x16 */
+ { 0x2b,0x22,104}, /* 0x17 */
+ { 0x49,0x24,105}, /* 0x18 */
+- { 0xf8,0x2f,108}, /* 0x19 */
++ { 0xf8,0x2f,108}, /* 0x19 */ /* 1400x1050 LCD */
+ { 0x3c,0x23,109}, /* 0x1a */
+ { 0x5e,0x43,113}, /* 0x1b */
+ { 0xbc,0x44,116}, /* 0x1c */
+@@ -1179,19 +777,19 @@
+ { 0xea,0x08,340}, /* 0x37 */
+ { 0xe8,0x07,376}, /* 0x38 */
+ { 0xde,0x06,389}, /* 0x39 */
+- { 0x52,0x2a, 54}, /* 0x3a */
+- { 0x52,0x6a, 27}, /* 0x3b */
+- { 0x62,0x24, 70}, /* 0x3c */
+- { 0x62,0x64, 70}, /* 0x3d */
+- { 0xa8,0x4c, 30}, /* 0x3e */
+- { 0x20,0x26, 33}, /* 0x3f */
++ { 0x52,0x2a, 54}, /* 0x3a */ /* 301 TV */
++ { 0x52,0x6a, 27}, /* 0x3b */ /* 301 TV */
++ { 0x62,0x24, 70}, /* 0x3c */ /* 301 TV */
++ { 0x62,0x64, 70}, /* 0x3d */ /* 301 TV */
++ { 0xa8,0x4c, 30}, /* 0x3e */ /* 301 TV */
++ { 0x20,0x26, 33}, /* 0x3f */ /* 301 TV */
+ { 0x31,0xc2, 39}, /* 0x40 */
+- { 0x2e,0x48, 25}, /* 0x41 */
+- { 0x24,0x46, 25}, /* 0x42 */
+- { 0x26,0x64, 28}, /* 0x43 */
+- { 0x37,0x64, 40}, /* 0x44 */
+- { 0xa1,0x42,108}, /* 0x45 */
+- { 0x37,0x61,100}, /* 0x46 */
++ { 0x2e,0x48, 25}, /* 0x41 */ /* Replacement for LCD on 315 for index 0 */
++ { 0x24,0x46, 25}, /* 0x42 */ /* Replacement for LCD on 315 for modes 0x01, 0x03, 0x0f, 0x10, 0x12 */
++ { 0x26,0x64, 28}, /* 0x43 */ /* Replacement for LCD on 315 for index 1 */
++ { 0x37,0x64, 40}, /* 0x44 */ /* Replacement for LCD on 315 for index 4 */
++ { 0xa1,0x42,108}, /* 0x45 */ /* 1280x960 LCD */
++ { 0x37,0x61,100}, /* 0x46 */ /* 1280x960 LCD */
+ { 0x78,0x27,108}, /* 0x47 */
+ { 0x97,0x2c, 26}, /* 0x48 */ /* UNUSED - Entries from here new, not in any BIOS */
+ { 0xce,0x3c, 39}, /* 0x49 */ /* UNUSED */
+@@ -1211,72 +809,17 @@
+ { 0xbf,0xc8, 35}, /* 0x57 */ /* 856x480-38i,60 */
+ { 0x30,0x23, 88}, /* 0x58 */ /* 1360x768-62 (is 60Hz!) TEMP, UNUSED */
+ { 0x52,0x07,149}, /* 0x59 */ /* 1280x960-85 - UNUSED */
+- { 0x56,0x07,156} /* 0x5a */ /* 1400x1050-75 - UNUSED */
++ { 0x56,0x07,156}, /* 0x5a */ /* 1400x1050-75 - UNUSED */
++ { 0x70,0x29, 81} /* 0x5b */ /* 1280x768 LCD */
+ };
+
+ static const UCHAR SiS310_ScreenOffset[] =
+ {
+ 0x14,0x19,0x20,0x28,0x32,0x40,0x50,0x64,
+- 0x78,0x80,0x2d,0x35,0x57,0x48,0x55,
++ 0x78,0x80,0x2d,0x35,0x57,0x48,0x55,0x30,
+ 0xff
+-}; /* TW: Added 1400x1050, 1152x864, 848/856x480, 1360x768 */
+-
+-typedef struct _SiS310_StResInfoStruct
+-{
+- USHORT HTotal;
+- USHORT VTotal;
+-} SiS310_StResInfoStruct;
+-
+-static const SiS310_StResInfoStruct SiS310_StResInfo[]=
+-{
+- { 640,400},
+- { 640,350},
+- { 720,400},
+- { 720,350},
+- { 640,480}
+-};
+-
+-typedef struct _SiS310_ModeResInfoStruct
+-{
+- USHORT HTotal;
+- USHORT VTotal;
+- UCHAR XChar;
+- UCHAR YChar;
+-} SiS310_ModeResInfoStruct;
+-
+-static const SiS310_ModeResInfoStruct SiS310_ModeResInfo[] =
+-{
+- { 320, 200, 8, 8}, /* 0x00 */
+- { 320, 240, 8, 8}, /* 0x01 */
+- { 320, 400, 8, 8}, /* 0x02 */
+- { 400, 300, 8, 8}, /* 0x03 */
+- { 512, 384, 8, 8}, /* 0x04 */
+- { 640, 400, 8,16}, /* 0x05 */
+- { 640, 480, 8,16}, /* 0x06 */
+- { 800, 600, 8,16}, /* 0x07 */
+- { 1024, 768, 8,16}, /* 0x08 */
+- { 1280,1024, 8,16}, /* 0x09 */
+- { 1600,1200, 8,16}, /* 0x0a */
+- { 1920,1440, 8,16}, /* 0x0b */
+- { 2048,1536, 8,16}, /* 0x0c */
+- { 720, 480, 8,16}, /* 0x0d */
+- { 720, 576, 8,16}, /* 0x0e */
+- { 1280, 960, 8,16}, /* 0x0f */
+- { 800, 480, 8,16}, /* 0x10 */
+- { 1024, 576, 8,16}, /* 0x11 */
+- { 1280, 720, 8,16}, /* 0x12 */
+- { 856, 480, 8,16}, /* 0x13 - TW: New, not in any BIOS */
+- { 1280, 768, 8,16}, /* 0x14 20; TW: New */
+- { 1400,1050, 8,16}, /* 0x15 21; TW: New */
+- { 1152, 864, 8,16}, /* 0x16 - TW: New, not in any BIOS */
+- { 848, 480, 8,16}, /* 0x17 - TW: New, not in any BIOS */
+- { 1360, 768, 8,16} /* 0x18 - TW: New, not in any BIOS */
+ };
+
+-static const UCHAR SiS310_OutputSelect = 0x40;
+-
+-static const UCHAR SiS310_SoftSetting = 0x30; /* TW: RAM setting */
+-
+ static const UCHAR SiS310_SR15[8][4]={
+ {0x00,0x04,0x60,0x60},
+ {0x0f,0x0f,0x0f,0x0f},
+@@ -1322,16 +865,6 @@
+ static const USHORT SiS310_YCSenseData2 = 0x016b;
+ #endif
+
+-static const UCHAR SiS310_NTSCPhase[] = {0x21,0xed,0xba,0x08}; /* TW: Was {0x21,0xed,0x8a,0x08}; */
+-static const UCHAR SiS310_PALPhase[] = {0x2a,0x05,0xe3,0x00}; /* TW: Was {0x2a,0x05,0xd3,0x00}; */
+-static const UCHAR SiS310_PALMPhase[] = {0x21,0xE4,0x2E,0x9B}; /* TW: palm*/
+-static const UCHAR SiS310_PALNPhase[] = {0x21,0xF4,0x3E,0xBA}; /* TW: paln*/
+-static const UCHAR SiS310_NTSCPhase2[] = {0x21,0xF0,0x7B,0xD6};
+-static const UCHAR SiS310_PALPhase2[] = {0x2a,0x09,0x86,0xe9};
+-static const UCHAR SiS310_PALMPhase2[] = {0x21,0xE6,0xEF,0xA4}; /* TW: palm 301b*/
+-static const UCHAR SiS310_PALNPhase2[] = {0x21,0xF6,0x94,0x46}; /* TW: paln 301b*/
+-static const UCHAR SiS310_SpecialPhase[] = {0x1e,0x8c,0x5c,0x7a};
+-
+ typedef struct _SiS310_LCDDataStruct
+ {
+ USHORT RVBHCMAX;
+@@ -1353,25 +886,6 @@
+ { 1, 1,1344, 806,1344, 806}
+ };
+
+-#if 0 /* Seems out-dated, all BIOSes since 03/27/2002 have the other version */
+-static const SiS310_LCDDataStruct SiS310_ExtLCD1024x768Data[] =
+-{
+- { 12, 5, 896, 512,1344, 806},
+- { 12, 5, 896, 510,1344, 806},
+- { 32, 15,1008, 505,1344, 806},
+- { 32, 15,1008, 514,1344, 806},
+- { 12, 5, 896, 500,1344, 806},
+- { 42, 25,1024, 625,1344, 806},
+- { 1, 1,1344, 806,1344, 806},
+- { 12, 5, 896, 500,1344, 806},
+- { 42, 25,1024, 625,1344, 806},
+- { 1, 1,1344, 806,1344, 806},
+- { 12, 5, 896, 500,1344, 806},
+- { 42, 25,1024, 625,1344, 806},
+- { 1, 1,1344, 806,1344, 806}
+-};
+-#endif
+-
+ static const SiS310_LCDDataStruct SiS310_ExtLCD1024x768Data[] =
+ {
+ { 42, 25,1536, 419,1344, 806},
+@@ -1413,7 +927,7 @@
+ { 1, 1,1688,1066,1688,1066}
+ };
+
+-static const SiS310_LCDDataStruct SiS310_ExtLCD1280x1024Data[] =
++static const SiS310_LCDDataStruct SiS310_ExtLCD1280x1024Data[] =
+ {
+ { 211, 60,1024, 501,1688,1066},
+ { 211, 60,1024, 508,1688,1066},
+@@ -1450,7 +964,7 @@
+ { 1, 1,1344, 806,1344, 806}
+ };
+
+-static const SiS310_LCDDataStruct SiS310_NoScaleData1280x1024[] =
++static const SiS310_LCDDataStruct SiS310_NoScaleData1280x1024[] =
+ {
+ { 1, 1,1688,1066,1688,1066},
+ { 1, 1,1688,1066,1688,1066},
+@@ -1463,272 +977,15 @@
+ { 1, 1,1688,1066,1688,1066}
+ };
+
+-static const SiS310_LCDDataStruct SiS310_LCD1280x960Data[] =
+-{
+- { 9, 2, 800, 500,1800,1000},
+- { 9, 2, 800, 500,1800,1000},
+- { 4, 1, 900, 500,1800,1000},
+- { 4, 1, 900, 500,1800,1000},
+- { 9, 2, 800, 500,1800,1000},
+- { 30, 11,1056, 625,1800,1000},
+- { 5, 3,1350, 800,1800,1000},
+- { 1, 1,1576,1050,1576,1050},
+- { 1, 1,1800,1000,1800,1000}
+-};
+-
+-static const SiS310_LCDDataStruct SiS310_StLCD1400x1050Data[] =
+-{ /* TW: New from 1.11.6s */
+- { 211, 100, 2100, 408, 1688, 1066 },
+- { 211, 64, 1536, 358, 1688, 1066 },
+- { 211, 100, 2100, 408, 1688, 1066 },
+- { 211, 64, 1536, 358, 1688, 1066 },
+- { 211, 48, 840, 488, 1688, 1066 },
+- { 211, 72, 1008, 609, 1688, 1066 },
+- { 211, 128, 1400, 776, 1688, 1066 },
+- { 211, 205, 1680, 1041, 1688, 1066 },
+- { 1, 1, 1688, 1066, 1688, 1066 }
+-};
+-
+-static const SiS310_LCDDataStruct SiS310_ExtLCD1400x1050Data[] =
+-{ /* TW: New from 1.11.6s */
+- { 211, 100, 2100, 408, 1688, 1066 },
+- { 211, 64, 1536, 358, 1688, 1066 },
+- { 211, 100, 2100, 408, 1688, 1066 },
+- { 211, 64, 1536, 358, 1688, 1066 },
+- { 211, 48, 840, 488, 1688, 1066 },
+- { 211, 72, 1008, 609, 1688, 1066 },
+- { 211, 128, 1400, 776, 1688, 1066 },
+- { 211, 205, 1680, 1041, 1688, 1066 },
+- { 1, 1, 1688, 1066, 1688, 1066 }
+-};
+-
+-static const SiS310_LCDDataStruct SiS310_NoScaleData1400x1050[] =
+-{ /* TW: To be checked (BIOS uses 1280x1024 data, one line too short) */
+- { 1, 1, 1688, 1066, 1688, 1066 },
+- { 1, 1, 1688, 1066, 1688, 1066 },
+- { 1, 1, 1688, 1066, 1688, 1066 },
+- { 1, 1, 1688, 1066, 1688, 1066 },
+- { 1, 1, 1688, 1066, 1688, 1066 },
+- { 1, 1, 1688, 1066, 1688, 1066 },
+- { 1, 1, 1688, 1066, 1688, 1066 },
+- { 1, 1, 1688, 1066, 1688, 1066 },
+- { 1, 1, 1688, 1066, 1688, 1066 }
+-};
+-
+-static const SiS310_LCDDataStruct SiS310_StLCD1600x1200Data[] =
+-{ /* TODO */
+- { 0, 0, 0, 0, 0, 0}
+-};
+-
+-static const SiS310_LCDDataStruct SiS310_ExtLCD1600x1200Data[] =
+-{ /* TODO */
+- { 0, 0, 0, 0, 0, 0}
+-};
+-
+-static const SiS310_LCDDataStruct SiS310_NoScaleData1600x1200[] =
+-{ /* TODO */
+- { 0, 0, 0, 0, 0, 0}
+-};
+-
+-typedef struct _SiS310_TVDataStruct
+-{
+- USHORT RVBHCMAX;
+- USHORT RVBHCFACT;
+- USHORT VGAHT;
+- USHORT VGAVT;
+- USHORT TVHDE;
+- USHORT TVVDE;
+- USHORT RVBHRS;
+- UCHAR FlickerMode;
+- USHORT HALFRVBHRS;
+- UCHAR RY1COE;
+- UCHAR RY2COE;
+- UCHAR RY3COE;
+- UCHAR RY4COE;
+-} SiS310_TVDataStruct;
+-
+-static const SiS310_TVDataStruct SiS310_StPALData[]=
+-{
+- { 1, 1, 864, 525,1270, 400, 100, 0, 760,0xf4,0xff,0x1c,0x22},
+- { 1, 1, 864, 525,1270, 350, 100, 0, 760,0xf4,0xff,0x1c,0x22},
+- { 1, 1, 864, 525,1270, 400, 0, 0, 720,0xf1,0x04,0x1f,0x18},
+- { 1, 1, 864, 525,1270, 350, 0, 0, 720,0xf4,0x0b,0x1c,0x0a},
+- { 1, 1, 864, 525,1270, 480, 50, 0, 760,0xf4,0xff,0x1c,0x22},
+- { 1, 1, 864, 525,1270, 600, 50, 0, 0,0xf4,0xff,0x1c,0x22}
+-};
+-
+-static const SiS310_TVDataStruct SiS310_ExtPALData[] =
+-{
+- { 27, 10, 848, 448,1270, 530, 50, 0, 50,0xf4,0xff,0x1c,0x22},
+- { 108, 35, 848, 398,1270, 530, 50, 0, 50,0xf4,0xff,0x1c,0x22},
+- { 12, 5, 954, 448,1270, 530, 50, 0, 50,0xf1,0x04,0x1f,0x18},
+- { 9, 4, 960, 463,1644, 438, 50, 0, 50,0xf4,0x0b,0x1c,0x0a},
+- { 9, 4, 848, 528,1270, 530, 0, 0, 50,0xf5,0xfb,0x1b,0x2a}, /* 640x480 */
+- { 36, 25,1060, 648,1316, 530, 438, 0, 438,0xeb,0x05,0x25,0x16}, /* 800x600 */
+- { 3, 2,1080, 619,1270, 540, 438, 0, 438,0xf3,0x00,0x1d,0x20}, /* 720x480/576 */
+- { 1, 1,1170, 821,1270, 520, 686, 0, 686,0xF3,0x00,0x1D,0x20} /* 1024x768 */
+-};
+-
+-static const SiS310_TVDataStruct SiS310_StNTSCData[]=
+-{
+- { 1, 1, 858, 525,1270, 400, 50, 0, 760,0xf1,0x04,0x1f,0x18},
+- { 1, 1, 858, 525,1270, 350, 50, 0, 640,0xf1,0x04,0x1f,0x18},
+- { 1, 1, 858, 525,1270, 400, 0, 0, 720,0xf1,0x04,0x1f,0x18},
+- { 1, 1, 858, 525,1270, 350, 0, 0, 720,0xf4,0x0b,0x1c,0x0a},
+- { 1, 1, 858, 525,1270, 480, 0, 0, 760,0xf1,0x04,0x1f,0x18}
+-};
+-
+-static const SiS310_TVDataStruct SiS310_ExtNTSCData[]=
+-{
+- { 143, 65, 858, 443,1270, 440, 171, 0, 171,0xf1,0x04,0x1f,0x18},
+- { 88, 35, 858, 393,1270, 440, 171, 0, 171,0xf1,0x04,0x1f,0x18},
+- { 143, 70, 924, 443,1270, 440, 92, 0, 92,0xf1,0x04,0x1f,0x18},
+- { 143, 70, 924, 393,1270, 440, 92, 0, 92,0xf4,0x0b,0x1c,0x0a},
+- { 143, 76, 836, 523,1270, 440, 224, 0, 0,0xf1,0x05,0x1f,0x16}, /* 640x480 */
+- { 143, 120,1056, 643,1270, 440, 0, 128, 0,0xf4,0x10,0x1c,0x00}, /* 800x600 */
+- { 2, 1, 858, 503,1270, 480, 0, 128, 0,0xee,0x0c,0x22,0x08}, /* 720x480/576 */
+- { 65, 64,1056, 791,1270, 480, 638, 0, 0,0xEE,0x0C,0x22,0x08} /* 1024x768 */
+-};
+-
+-#if 0
+-static const SiS310_TVDataStruct SiS310_St1HiTVData[]=
+-{
+-
+-};
+-#endif
+-
+-static const SiS310_TVDataStruct SiS310_St2HiTVData[]=
+-{
+- { 3, 1, 0x348,0x1e3,0x670,0x3c0,0x032, 0, 0, 0x00,0x00,0x00,0x00},
+- { 1, 1, 0x37c,0x233,0x2b2,0x2bc, 0, 0, 0, 0x00,0x00,0x00,0x00},
+- { 3, 1, 0x348,0x1e3,0x670,0x3c0,0x032, 0, 0, 0x00,0x00,0x00,0x00},
+- { 1, 1, 0x3e8,0x233,0x311,0x2bc, 0, 0, 0, 0x00,0x00,0x00,0x00},
+- { 5, 2, 0x348,0x233,0x670,0x3c0,0x08d,128, 0, 0x00,0x00,0x00,0x00},
+- { 8, 5, 0x41a,0x2ab,0x670,0x3c0,0x17c,128, 0, 0x00,0x00,0x00,0x00}
+-};
+-
+-static const SiS310_TVDataStruct SiS310_ExtHiTVData[]=
+-{
+- { 6, 1, 0x348,0x233,0x660,0x3c0, 0, 0, 0, 0x00,0x00,0x00,0x00},
+- { 3, 1, 0x3c0,0x233,0x660,0x3c0, 0, 0, 0, 0x00,0x00,0x00,0x00},
+- { 3, 1, 0x348,0x1e3,0x660,0x3c0, 0, 0, 0, 0x00,0x00,0x00,0x00},
+- { 3, 1, 0x3c0,0x233,0x660,0x3c0, 0, 0, 0, 0x00,0x00,0x00,0x00},
+- { 5, 1, 0x348,0x233,0x670,0x3c0,0x166,128, 0, 0x00,0x00,0x00,0x00},
+- { 16, 5, 0x41a,0x2ab,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},
+- { 25, 12, 0x4ec,0x353,0x670,0x3c0,0x032, 0, 0, 0x00,0x00,0x00,0x00},
+- { 5, 4, 0x627,0x464,0x670,0x3c0,0x128, 0, 0, 0x00,0x00,0x00,0x00},
+- { 4, 1, 0x41a,0x233,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},
+- { 5, 2, 0x578,0x293,0x670,0x3c0,0x032, 0, 0, 0x00,0x00,0x00,0x00},
+- { 8, 5, 0x6d6,0x323,0x670,0x3c0,0x128, 0, 0, 0x00,0x00,0x00,0x00}
+-};
+-
+-static const UCHAR SiS310_NTSCTiming[] = {
+- 0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
+- 0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
+- 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
+- 0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17,
+- 0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02,
+- 0x03,0x0a,0x65,0x9d,0x08,0x92,0x8f,0x40,
+- 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x50,
+- 0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
+-};
+-
+-static const UCHAR SiS310_PALTiming[] = {
+- 0x19,0x52,0x35,0x6e,0x04,0x38,0x3d,0x70,
+- 0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d,
+- 0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b,
+- 0x70,0x50,0x00,0x9b,0x00,0xd9,0x5d,0x17,
+- 0x7d,0x05,0x45,0x00,0x00,0xe8,0x00,0x02,
+- 0x0d,0x00,0x68,0xb0,0x0b,0x92,0x8f,0x40,
+- 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x63,
+- 0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00
+-};
+-
+-static const UCHAR SiS310_HiTVExtTiming[] = {
+- 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
+- 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+- 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+- 0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
+- 0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
+- 0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
+- 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
+- 0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
+-};
+-
+-static const UCHAR SiS310_HiTVSt1Timing[] = {
+- 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
+- 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+- 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+- 0x65,0x90,0x7b,0xa8,0x03,0xf0,0x87,0x03,
+- 0x11,0x15,0x11,0xcf,0x10,0x11,0xcf,0x10,
+- 0x35,0x35,0x3b,0x69,0x1d,0x92,0x0f,0x40,
+- 0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x86,
+- 0xaf,0x5d,0x0e,0x00,0xfc,0xff,0x2d,0x00
+-};
+-
+-static const UCHAR SiS310_HiTVSt2Timing[] = {
+- 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
+- 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+- 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+- 0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
+- 0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
+- 0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
+- 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
+- 0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
+-};
+-
+-static const UCHAR SiS310_HiTVTextTiming[] = {
+- 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
+- 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+- 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+- 0x65,0x90,0xe7,0xbc,0x03,0x0c,0x97,0x03,
+- 0x14,0x78,0x14,0x08,0x20,0x14,0x08,0x20,
+- 0xc8,0xc8,0x3b,0xd2,0x26,0x92,0x0f,0x40,
+- 0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x96,
+- 0x72,0x5c,0x11,0x00,0xfc,0xff,0x32,0x00
+-};
+-
+-static const UCHAR SiS310_HiTVGroup3Data[] = {
+- 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x5f,
+- 0x05,0x21,0xb2,0xb2,0x55,0x77,0x2a,0xa6,
+- 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
+- 0x8c,0x6e,0x60,0x2e,0x58,0x48,0x72,0x44,
+- 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
+- 0x4f,0x7f,0x03,0xa8,0x7d,0x20,0x1a,0xa9,
+- 0x14,0x05,0x03,0x7e,0x64,0x31,0x14,0x75,
+- 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
+-};
+-
+-static const UCHAR SiS310_HiTVGroup3Simu[] = {
+- 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x95,
+- 0xdb,0x20,0xb8,0xb8,0x55,0x47,0x2a,0xa6,
+- 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
+- 0x8c,0x6e,0x60,0x15,0x26,0xd3,0xe4,0x11,
+- 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
+- 0x67,0x36,0x01,0x47,0x0e,0x10,0xbe,0xb4,
+- 0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
+- 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
+-};
+-
+-static const UCHAR SiS310_HiTVGroup3Text[] = {
+- 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0xa7,
+- 0xf5,0x20,0xce,0xce,0x55,0x47,0x2a,0xa6,
+- 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
+- 0x8c,0x6e,0x60,0x18,0x2c,0x0c,0x20,0x22,
+- 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
+- 0x93,0x3c,0x01,0x50,0x2f,0x10,0xf4,0xca,
+- 0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
+- 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
+-};
+
+ typedef struct _SiS310_PanelDelayTblStruct
+ {
+ UCHAR timer[2];
+ } SiS310_PanelDelayTblStruct;
+
+-static const SiS310_PanelDelayTblStruct SiS310_PanelDelayTbl[]=
++static const SiS310_PanelDelayTblStruct SiS310_PanelDelayTbl[]=
+ {
+- {{0x10,0x40}}, /* TW: from 650/301LVx 1.10.6s BIOS */
++ {{0x10,0x40}},
+ {{0x10,0x40}},
+ {{0x10,0x40}},
+ {{0x10,0x40}},
+@@ -1744,24 +1001,6 @@
+ {{0x10,0x40}},
+ {{0x10,0x40}},
+ {{0x10,0x40}}
+-#if 0
+- {{0x28,0xc8}}, /* TW: from 650/301LV BIOS */
+- {{0x28,0xc8}},
+- {{0x28,0xc8}},
+- {{0x28,0xc8}},
+- {{0x28,0xc8}},
+- {{0x28,0xc8}},
+- {{0x28,0xc8}},
+- {{0x28,0xc8}},
+- {{0x28,0xc8}},
+- {{0x28,0xc8}},
+- {{0x28,0xc8}},
+- {{0x28,0xc8}},
+- {{0x28,0xc8}},
+- {{0x28,0xc8}},
+- {{0x28,0xc8}},
+- {{0x28,0xc8}}
+-#endif
+ };
+
+ static const SiS310_PanelDelayTblStruct SiS310_PanelDelayTblLVDS[]=
+@@ -1792,363 +1031,7 @@
+ USHORT LCDVT;
+ } SiS310_LVDSDataStruct;
+
+-static const SiS310_LVDSDataStruct SiS310_LVDS320x480Data_1[]=
+-{
+- { 848, 433, 400, 525},
+- { 848, 389, 400, 525},
+- { 848, 433, 400, 525},
+- { 848, 389, 400, 525},
+- { 848, 518, 400, 525},
+- {1056, 628, 400, 525},
+- { 400, 525, 400, 525},
+- { 800, 449,1000, 644},
+- { 800, 525,1000, 635}
+-};
+-
+-static const SiS310_LVDSDataStruct SiS310_LVDS800x600Data_1[]=
+-{
+- { 848, 433,1060, 629},
+- { 848, 389,1060, 629},
+- { 848, 433,1060, 629},
+- { 848, 389,1060, 629},
+- { 848, 518,1060, 629},
+- {1056, 628,1056, 628},
+- {1056, 628,1056, 628},
+- { 800, 449,1000, 644},
+- { 800, 525,1000, 635}
+-};
+-
+-static const SiS310_LVDSDataStruct SiS310_LVDS800x600Data_2[]=
+-{
+- {1056, 628,1056, 628},
+- {1056, 628,1056, 628},
+- {1056, 628,1056, 628},
+- {1056, 628,1056, 628},
+- {1056, 628,1056, 628},
+- {1056, 628,1056, 628},
+- {1056, 628,1056, 628},
+- { 800, 449,1000, 644},
+- { 800, 525,1000, 635}
+-};
+-
+-static const SiS310_LVDSDataStruct SiS310_LVDS1024x768Data_1[]=
+-{
+- { 840, 438,1344, 806},
+- { 840, 409,1344, 806},
+- { 840, 438,1344, 806},
+- { 840, 409,1344, 806},
+- { 840, 518,1344, 806}, /* 640x480 */
+- {1050, 638,1344, 806}, /* 800x600 */
+- {1344, 806,1344, 806}, /* 1024x768 */
+- { 800, 449,1280, 801},
+- { 800, 525,1280, 813}
+-};
+-
+-static const SiS310_LVDSDataStruct SiS310_LVDS1024x768Data_2[]=
+-{
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- { 800, 449,1280, 801},
+- { 800, 525,1280, 813}
+-};
+-
+-static const SiS310_LVDSDataStruct SiS310_LVDS1280x1024Data_1[]=
+-{
+- {1048, 442,1688,1066},
+- {1048, 392,1688,1066},
+- {1048, 442,1688,1066},
+- {1048, 392,1688,1066},
+- {1048, 522,1688,1066},
+- {1208, 642,1688,1066},
+- {1432, 810,1688,1066},
+- {1688,1066,1688,1066}
+-};
+-
+-static const SiS310_LVDSDataStruct SiS310_LVDS1280x1024Data_2[]=
+-{
+- {1688,1066,1688,1066},
+- {1688,1066,1688,1066},
+- {1688,1066,1688,1066},
+- {1688,1066,1688,1066},
+- {1688,1066,1688,1066},
+- {1688,1066,1688,1066},
+- {1688,1066,1688,1066},
+- {1688,1066,1688,1066}
+-};
+-
+-static const SiS310_LVDSDataStruct SiS310_LVDS1400x1050Data_1[]=
+-{
+- { 928, 416, 1688,1066},
+- { 928, 366, 1688,1066},
+- { 928, 416, 1688,1066},
+- { 928, 366, 1688,1066},
+- { 928, 496, 1688,1066},
+- {1088, 616, 1688,1066},
+- {1312, 784, 1688,1066},
+- {1568,1040, 1688,1066},
+- {1688,1066, 1688,1066}
+-};
+-
+-static const SiS310_LVDSDataStruct SiS310_LVDS1400x1050Data_2[]=
+-{
+- {1688,1066, 1688,1066},
+- {1688,1066, 1688,1066},
+- {1688,1066, 1688,1066},
+- {1688,1066, 1688,1066},
+- {1688,1066, 1688,1066},
+- {1688,1066, 1688,1066},
+- {1688,1066, 1688,1066},
+- {1688,1066, 1688,1066},
+- {1688,1066, 1688,1066},
+-};
+-
+-static const SiS310_LVDSDataStruct SiS310_LVDS1600x1200Data_1[]=
+-{
+- {1088, 450, 2048,1250},
+- {1088, 400, 2048,1250},
+- {1088, 450, 2048,1250},
+- {1088, 400, 2048,1250},
+- {1088, 530, 2048,1250},
+- {1248, 650, 2048,1250},
+- {1472, 818, 2048,1250},
+- {1728,1066, 2048,1250},
+- {1848,1066, 2048,1250},
+- {2048,1250, 2048,1250}
+-};
+-
+-static const SiS310_LVDSDataStruct SiS310_LVDS1600x1200Data_2[]=
+-{
+- {2048,1250, 2048,1250},
+- {2048,1250, 2048,1250},
+- {2048,1250, 2048,1250},
+- {2048,1250, 2048,1250},
+- {2048,1250, 2048,1250},
+- {2048,1250, 2048,1250},
+- {2048,1250, 2048,1250},
+- {2048,1250, 2048,1250},
+- {2048,1250, 2048,1250},
+- {2048,1250, 2048,1250}
+-};
+-
+-static const SiS310_LVDSDataStruct SiS310_LVDS1280x768Data_1[]=
+-{
+- { 768, 438, 1408, 806},
+- { 768, 388, 1408, 806},
+- { 768, 438, 1408, 806},
+- { 768, 388, 1408, 806},
+- { 768, 518, 1408, 806},
+- { 928, 638, 1408, 806},
+- {1152, 806, 1408, 806},
+- {1408, 806, 1408, 806},
+- {1408, 806, 1408, 806}
+-};
+-
+-static const SiS310_LVDSDataStruct SiS310_LVDS1280x768Data_2[]=
+-{
+- {1408, 806, 1408, 806},
+- {1408, 806, 1408, 806},
+- {1408, 806, 1408, 806},
+- {1408, 806, 1408, 806},
+- {1408, 806, 1408, 806},
+- {1408, 806, 1408, 806},
+- {1408, 806, 1408, 806},
+- {1408, 806, 1408, 806},
+- {1408, 806, 1408, 806}
+-};
+-
+-static const SiS310_LVDSDataStruct SiS310_LVDS1024x600Data_1[]=
+-{
+- { 840, 604, 1344, 800},
+- { 840, 560, 1344, 800},
+- { 840, 604, 1344, 800},
+- { 840, 560, 1344, 800},
+- { 840, 689, 1344, 800},
+- {1050, 800, 1344, 800},
+- {1344, 800, 1344, 800},
+- { 800, 449, 1280, 801},
+- { 800, 525, 1280, 813}
+-};
+-
+-static const SiS310_LVDSDataStruct SiS310_LVDS1024x600Data_2[]=
+-{
+- {1344, 800, 1344, 800},
+- {1344, 800, 1344, 800},
+- {1344, 800, 1344, 800},
+- {1344, 800, 1344, 800},
+- {1344, 800, 1344, 800},
+- {1344, 800, 1344, 800},
+- {1344, 800, 1344, 800},
+- { 800, 449, 1280, 801},
+- { 800, 525, 1280, 813}
+-};
+-
+-static const SiS310_LVDSDataStruct SiS310_LVDS1152x768Data_1[]=
+-{
+- { 840, 438, 1344, 806},
+- { 840, 409, 1344, 806},
+- { 840, 438, 1344, 806},
+- { 840, 409, 1344, 806},
+- { 840, 518, 1344, 806},
+- {1050, 638, 1344, 806},
+- {1344, 806, 1344, 806},
+- { 800, 449, 1280, 801},
+- { 800, 525, 1280, 813}
+-};
+-
+-static const SiS310_LVDSDataStruct SiS310_LVDS1152x768Data_2[]=
+-{
+- {1344, 806, 1344, 806},
+- {1344, 806, 1344, 806},
+- {1344, 806, 1344, 806},
+- {1344, 806, 1344, 806},
+- {1344, 806, 1344, 806},
+- {1344, 806, 1344, 806},
+- {1344, 806, 1344, 806},
+- { 800, 449, 1280, 801},
+- { 800, 525, 1280, 813}
+-};
+-
+-/* TW: Pass 1:1 data */
+-static const SiS310_LVDSDataStruct SiS310_LVDSXXXxXXXData_1[]=
+-{
+- { 800, 449, 800, 449},
+- { 800, 449, 800, 449},
+- { 900, 449, 900, 449},
+- { 900, 449, 900, 449},
+- { 800, 525, 800, 525}, /* 640x480 */
+- {1056, 628, 1056, 628}, /* 800x600 */
+- {1344, 806, 1344, 806}, /* 1024x768 */
+- {1344,1066, 1344,1066}, /* 1280x1024 */ /* INSERTED ! */
+- {1688, 806, 1688, 806}, /* 1280x768 ! */
+- /* No other panels ! */
+-};
+-
+-static const SiS310_LVDSDataStruct SiS310_LVDS640x480Data_1[]=
+-{
+- { 800, 449, 800, 449},
+- { 800, 449, 800, 449},
+- { 800, 449, 800, 449},
+- { 800, 449, 800, 449},
+- { 800, 525, 800, 525},
+- {1056, 628,1056, 628},
+- {1056, 628,1056, 628},
+- {1056, 628,1056, 628},
+- {1056, 628,1056, 628}
+-};
+-
+-static const SiS310_LVDSDataStruct SiS310_LVDS1280x960Data_1[]=
+-{
+- { 840, 438,1344, 806},
+- { 840, 409,1344, 806},
+- { 840, 438,1344, 806},
+- { 840, 409,1344, 806},
+- { 840, 518,1344, 806},
+- {1050, 638,1344, 806},
+- {1344, 806,1344, 806},
+- { 800, 449,1280, 801},
+- { 800, 525,1280, 813}
+-};
+-
+-static const SiS310_LVDSDataStruct SiS310_LVDS1280x960Data_2[]=
+-{
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- { 800, 449,1280, 801},
+- { 800, 525,1280, 813}
+-};
+-
+-/* LCDA */
+-
+-static const SiS310_LVDSDataStruct SiS310_LCDA1400x1050Data_1[]=
+-{ /* TW: Might be temporary (invalid) data */
+- { 928, 416, 1688,1066},
+- { 928, 366, 1688,1066},
+- {1008, 416, 1688,1066},
+- {1008, 366, 1688,1066},
+- {1200, 530, 1688,1066},
+- {1088, 616, 1688,1066},
+- {1312, 784, 1688,1066},
+- {1568,1040, 1688,1066},
+- {1688,1066, 1688,1066}
+-};
+-
+-static const SiS310_LVDSDataStruct SiS310_LCDA1400x1050Data_2[]=
+-{ /* TW: Temporary data. Not valid */
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- { 800, 449,1280, 801},
+- { 800, 525,1280, 813}
+-};
+-
+-static const SiS310_LVDSDataStruct SiS310_LCDA1600x1200Data_1[]=
+-{ /* TW: Temporary data. Not valid */
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- {1344, 806,1344, 806},
+- { 800, 449,1280, 801},
+- { 800, 525,1280, 813}
+-};
+-
+-static const SiS310_LVDSDataStruct SiS310_LCDA1600x1200Data_2[]=
+-{ /* TW: Temporary data. Not valid */
+- {0, 0, 0, 0},
+- {0, 0, 0, 0},
+- {0, 0, 0, 0},
+- {0, 0, 0, 0},
+- {0, 0, 0, 0},
+- {0, 0, 0, 0},
+- {0, 0, 0, 0},
+- {0, 0, 0, 0},
+- {0, 0, 0, 0},
+- {0, 0, 0, 0},
+- {0, 0, 0, 0},
+- {0, 0, 0, 0}
+-};
+-
+-/* Chrontel TV */
+-
+-static const SiS310_LVDSDataStruct SiS310_CHTVUNTSCData[]=
+-{
+- { 840, 600, 840, 600},
+- { 840, 600, 840, 600},
+- { 840, 600, 840, 600},
+- { 840, 600, 840, 600},
+- { 784, 600, 784, 600},
+- {1064, 750,1064, 750},
+- {1160, 945,1160, 945} /* TW: For Ch7019 1024 */
+-};
+-
+-static const SiS310_LVDSDataStruct SiS310_CHTVONTSCData[]=
+-{
+- { 840, 525, 840, 525},
+- { 840, 525, 840, 525},
+- { 840, 525, 840, 525},
+- { 840, 525, 840, 525},
+- { 784, 525, 784, 525},
+- {1040, 700,1040, 700},
+- {1160, 840,1160, 840} /* TW: For Ch7019 1024 */
+-};
+-
+-static const SiS310_LVDSDataStruct SiS310_CHTVUPALData[]=
++static const SiS310_LVDSDataStruct SiS310_CHTVUPALData[]=
+ {
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+@@ -2156,7 +1039,7 @@
+ {1008, 625,1008, 625},
+ { 840, 625, 840, 625},
+ { 960, 750, 960, 750},
+- {1400,1000,1400,1000} /* TW: For Ch7019 1024 */
++ {1400,1000,1400,1000}
+ };
+
+ static const SiS310_LVDSDataStruct SiS310_CHTVOPALData[]=
+@@ -2167,7 +1050,7 @@
+ {1008, 625,1008, 625},
+ { 840, 625, 840, 625},
+ { 944, 625, 944, 625},
+- {1400, 875,1400, 875} /* TW: For Ch7019 1024 */
++ {1400, 875,1400, 875}
+ };
+
+ static const SiS310_LVDSDataStruct SiS310_CHTVUPALMData[]=
+@@ -2178,7 +1061,7 @@
+ { 840, 600, 840, 600},
+ { 784, 600, 784, 600},
+ {1064, 750,1064, 750},
+- {1160, 945,1160, 945} /* TW: For Ch7019 1024 */
++ {1160, 945,1160, 945}
+ };
+
+ static const SiS310_LVDSDataStruct SiS310_CHTVOPALMData[]=
+@@ -2189,7 +1072,7 @@
+ { 840, 525, 840, 525},
+ { 784, 525, 784, 525},
+ {1040, 700,1040, 700},
+- {1160, 840,1160, 840} /* TW: For Ch7019 1024 */
++ {1160, 840,1160, 840}
+ };
+
+ static const SiS310_LVDSDataStruct SiS310_CHTVUPALNData[]=
+@@ -2200,7 +1083,7 @@
+ {1008, 625,1008, 625},
+ { 840, 625, 840, 625},
+ { 960, 750, 960, 750},
+- {1400,1000,1400,1000} /* TW: For Ch7019 1024 */
++ {1400,1000,1400,1000}
+ };
+
+ static const SiS310_LVDSDataStruct SiS310_CHTVOPALNData[]=
+@@ -2211,7 +1094,7 @@
+ {1008, 625,1008, 625},
+ { 840, 625, 840, 625},
+ { 944, 625, 944, 625},
+- {1400, 875,1400, 875} /* TW: For Ch7019 1024 */
++ {1400, 875,1400, 875}
+ };
+
+ static const SiS310_LVDSDataStruct SiS310_CHTVSOPALData[]= /* TW: (super overscan - no effect on 7019) */
+@@ -2231,7 +1114,7 @@
+ USHORT LCDVDES;
+ } SiS310_LVDSDesStruct;
+
+-static const SiS310_LVDSDesStruct SiS310_PanelType00_1[]=
++static const SiS310_LVDSDesStruct SiS310_PanelType00_1[]= /* 800x600 */
+ {
+ { 0, 0},
+ { 0, 0},
+@@ -2244,7 +1127,7 @@
+ { 0, 0}
+ };
+
+-static const SiS310_LVDSDesStruct SiS310_PanelType01_1[]=
++static const SiS310_LVDSDesStruct SiS310_PanelType01_1[]= /* 1024x768 */
+ {
+ { 0, 0},
+ { 0, 0},
+@@ -2257,7 +1140,7 @@
+ { 0, 0}
+ };
+
+-static const SiS310_LVDSDesStruct SiS310_PanelType02_1[]=
++static const SiS310_LVDSDesStruct SiS310_PanelType02_1[]= /* 1280x1024 */
+ {
+ { 0, 0},
+ { 0, 0},
+@@ -2382,33 +1265,31 @@
+ { 0, 0}
+ };
+
+-static const SiS310_LVDSDesStruct SiS310_PanelType0b_1[]=
+-{
+- {1343, 798},
+- {1343, 794},
+- {1343, 798},
+- {1343, 794},
+- {1343, 0},
+- {1343, 0},
+- { 0, 805},
+- { 0, 794},
+- { 0, 0}
+-};
+-
+-static const SiS310_LVDSDesStruct SiS310_PanelType0c_1[]=
++static const SiS310_LVDSDesStruct SiS310_PanelType0b_1[]= /* 640x480_2 */
+ {
+- {1343, 798},
+- {1343, 794},
+- {1343, 798},
+- {1343, 794},
+- {1343, 0},
+- {1343, 0},
+- { 0, 805},
+- { 0, 794},
+- { 0, 0}
++ { 0, 524},
++ { 0, 524},
++ { 0, 524},
++ { 0, 524},
++ { 0, 524},
++ { 0, 524},
++ { 8, 524},
++ { 0, 524}
++};
++
++static const SiS310_LVDSDesStruct SiS310_PanelType0c_1[]= /* 640x480_3 */
++{
++ { 0, 524},
++ { 0, 524},
++ { 0, 524},
++ { 0, 524},
++ { 0, 524},
++ { 0, 524},
++ { 8, 524},
++ { 0, 524}
+ };
+
+-static const SiS310_LVDSDesStruct SiS310_PanelType0d_1[]=
++static const SiS310_LVDSDesStruct SiS310_PanelType0d_1[]=
+ {
+ {1343, 798},
+ {1343, 794},
+@@ -2604,7 +1485,7 @@
+ { 0, 0}
+ };
+
+-static const SiS310_LVDSDesStruct SiS310_PanelType0b_2[]=
++static const SiS310_LVDSDesStruct SiS310_PanelType0b_2[]= /* 640x480_2 */
+ {
+ {1152, 622},
+ {1152, 597},
+@@ -2617,7 +1498,7 @@
+ { 0, 0}
+ };
+
+-static const SiS310_LVDSDesStruct SiS310_PanelType0c_2[]=
++static const SiS310_LVDSDesStruct SiS310_PanelType0c_2[]= /* 640x480_3 */
+ {
+ {1152, 622},
+ {1152, 597},
+@@ -2669,184 +1550,6 @@
+ { 0, 0}
+ };
+
+-static const SiS310_LVDSDesStruct SiS310_PanelTypeNS_1[]=
+-{
+- { 8, 0},
+- { 8, 0},
+- { 8, 0},
+- { 8, 0},
+- { 8, 0},
+- { 0, 0},
+- { 0, 0},
+- { 0, 0},
+- { 0, 806},
+- { 0, 0 }
+-};
+-
+-static const SiS310_LVDSDesStruct SiS310_PanelTypeNS_2[] =
+-{
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0}
+-};
+-
+-static const SiS310_LVDSDesStruct SiS310_PanelType1076_1[]=
+-{ /* 1024x768 - Checked (1.10.6s) */
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0}
+-};
+-
+-static const SiS310_LVDSDesStruct SiS310_PanelType1076_2[]=
+-{ /* 1024x768 - Checked (1.10.6s) */
+- { 1184, 622 },
+- { 1184, 597 },
+- { 1184, 622 },
+- { 1184, 597 },
+- { 1152, 622 },
+- { 1232, 722 },
+- { 0, 0 },
+- { 0, 794 },
+- { 0, 0 }
+-};
+-
+-static const SiS310_LVDSDesStruct SiS310_PanelType1210_1[]=
+-{ /* 1280x1024 - Checked (1.10.6s) */
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0}
+-};
+-
+-static const SiS310_LVDSDesStruct SiS310_PanelType1210_2[]=
+-{ /* 1280x1024 - Checked (1.10.6s) */
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0}
+-};
+-
+-static const SiS310_LVDSDesStruct SiS310_PanelType1296_1[]=
+-{ /* 1400x1050 - Checked (1.10.6s) */
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0}
+-};
+-
+-static const SiS310_LVDSDesStruct SiS310_PanelType1296_2[]=
+-{ /* 1400x1050 - Checked (1.10.6s) - looks heavily invalid */
+- { 808 , 740},
+- { 0 , 715},
+- { 632 , 740},
+- { 632 , 715},
+- { 1307, 780},
+- { 1387,1157},
+- { 1499, 924},
+- { 1627,1052},
+- { 0 , 0}
+-};
+-
+-static const SiS310_LVDSDesStruct SiS310_PanelType1600_1[]=
+-{ /* 1600x1200 - Checked (1.10.6s) */
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0}
+-};
+-
+-static const SiS310_LVDSDesStruct SiS310_PanelType1600_2[]=
+-{ /* 1600x1200 - Checked (1.10.6s) - looks heavily invalid, not copied */
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0},
+- { 0 , 0}
+-};
+-
+-static const SiS310_LVDSDesStruct SiS310_CHTVUNTSCDesData[]=
+-{
+- { 0, 0},
+- { 0, 0},
+- { 0, 0},
+- { 0, 0},
+- { 0, 0},
+- { 0, 0},
+- { 0, 0}
+-};
+-
+-static const SiS310_LVDSDesStruct SiS310_CHTVONTSCDesData[]=
+-{
+- { 0, 0},
+- { 0, 0},
+- { 0, 0},
+- { 0, 0},
+- { 0, 0},
+- { 0, 0},
+- { 0, 0}
+-};
+-
+-static const SiS310_LVDSDesStruct SiS310_CHTVUPALDesData[]=
+-{
+- {256, 0},
+- {256, 0},
+- {256, 0},
+- {256, 0},
+- { 0, 0},
+- { 0, 0},
+- { 0, 0}
+-};
+-
+-static const SiS310_LVDSDesStruct SiS310_CHTVOPALDesData[]=
+-{
+- {256, 0},
+- {256, 0},
+- {256, 0},
+- {256, 0},
+- { 0, 0},
+- { 0, 0},
+- { 0, 0}
+-};
+-
+ typedef struct _SiS310_Part2PortTblStruct
+ {
+ UCHAR CR[12];
+@@ -2866,16 +1569,15 @@
+ };
+
+ static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_1[] =
+-{ /* TW: Temporary data, invalid */
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}
++{ /* TW: BIOS data invalid, last row taken from _3 */
++ {{0x25,0x12,0x51,0x6E,0x48,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
++ {{0x2C,0x12,0x38,0x55,0x2F,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
++ {{0x25,0x12,0x51,0x6E,0x48,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
++ {{0x2C,0x12,0x38,0x55,0x2F,0xC1,0x35,0xB1,0x47,0xE9,0x71,0x33}},
++ {{0x2D,0x12,0x79,0x96,0x70,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
++ {{0x29,0x12,0xB5,0xD2,0xAC,0xE9,0x35,0xD9,0x47,0x11,0x99,0x33}},
++ {{0x36,0x13,0x02,0x25,0xFF,0x03,0x45,0x09,0x07,0xF9,0x00,0x24}},
++ {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}}
+ };
+
+ static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_1[] =
+@@ -2892,16 +1594,17 @@
+ };
+
+ static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_1[] =
+-{ /* TW: Temporary data, invalid */
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}
++{
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}}
+ };
+
+ static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_2[] =
+@@ -2912,7 +1615,8 @@
+ {{0x2c,0x12,0x38,0x55,0x2f,0xc1,0x35,0xb1,0x47,0xe9,0x71,0x33}},
+ {{0x2d,0x12,0x79,0x96,0x70,0x99,0x35,0x89,0x47,0xc1,0x49,0x33}},
+ {{0x29,0x12,0xb5,0xd2,0xac,0xe9,0x35,0xd9,0x47,0x11,0x99,0x33}},
+- {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
++ {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, /* old */
++/* 0x36,0x13,0x02,0x25,0xff,0x03,0x45,0x09,0x07,0xf9,0x00,0x24 new? */
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+ };
+@@ -2944,21 +1648,23 @@
+ };
+
+ static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_2[] =
+-{ /* TW: Temporary data, invalid */
+- {{0x2b,0x12,0xd9,0xe5,0xd5,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
+- {{0x22,0x12,0xc0,0xcc,0xbc,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
+- {{0x2b,0x12,0xd9,0xe5,0xd5,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
+- {{0x22,0x12,0xc0,0xcc,0xbc,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
+- {{0x33,0x13,0x01,0x0d,0xfd,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
+- {{0x3f,0x1b,0x3d,0x49,0x39,0x54,0x23,0xc0,0x27,0x66,0x30,0x42}},
+- {{0x33,0x1b,0x91,0x9d,0x8d,0x8c,0x23,0xf8,0x27,0x9e,0x68,0x42}},
+- {{0x43,0x24,0x11,0x1d,0x0d,0xcc,0x23,0x38,0x37,0xde,0xa8,0x42}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}
++{
++ {{0x32,0x1B,0x2C,0x52,0x20,0x80,0x20,0x52,0x30,0xA3,0x3A,0x02}},
++ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
++ {{0x32,0x1B,0x2C,0x52,0x20,0x80,0x20,0x52,0x30,0xA3,0x3A,0x02}},
++ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
++ {{0x3A,0x1B,0x54,0x7A,0x48,0x80,0x24,0x52,0x30,0xA3,0x3A,0x02}},
++ {{0x36,0x1B,0x90,0xB6,0x84,0xA8,0x24,0x7A,0x30,0xCB,0x62,0x02}},
++ {{0x3A,0x1C,0xE4,0x0A,0xD8,0xE0,0x24,0xB2,0x30,0x03,0x9A,0x02}},
++ {{0x4A,0x24,0x64,0x8A,0x58,0x20,0x34,0xF2,0x30,0x43,0xDA,0x52}},
++ {{0x47,0x24,0x71,0x97,0x65,0x3E,0x34,0x10,0x40,0x61,0xF8,0x02}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}}
+ };
+
+
+ static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_3[] =
+ { /* TW: Data from 650/301LVx 1.10.6s */
++#if 0
+ {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x2c,0x13,0x9a,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x25,0x13,0xc9,0x24,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+@@ -2968,56 +1674,56 @@
+ {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x25,0x13,0xc9,0x25,0xff,0xf9,0x45,0x09,0x07,0xf9,0x09,0x24}}
+-#if 0 /* TW: Data from 650/301LV */
+- {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+- {{0x2c,0x12,0x9a,0xae,0x88,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+- {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+- {{0x38,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+- {{0x38,0x18,0x16,0x00,0x00,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+- {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+-#endif
++#endif /* Data from my 301LV */
++ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}}, /* @@@@@ TEST */
++ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
++ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
++ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
++ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
++ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
++ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
++ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
++ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}}
+ };
+
+ /* 1 2 4 5 6 1c 1d 1f 20 21 23 25 */
+ static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_3[] =
+-{ /* TW: Temporary data, invalid */
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}
++{
++ {{0x31,0x1B,0xC4,0xDA,0xB0,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
++ {{0x34,0x1B,0x9F,0xC0,0x80,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
++ {{0x3E,0x1B,0xCF,0xF0,0xB0,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
++ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
++ {{0x48,0x1C,0x15,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
++ {{0x48,0x1C,0x15,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
++ {{0x48,0x1C,0x15,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
++ {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}}
+ };
+
+ static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_3[] =
+ {
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}
++ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
++ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
++ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
++ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
++ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
++ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
++ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
++ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
++ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}
+ };
+
+ static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_3[] =
+-{ /* TW: Temporary data, invalid */
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}
++{
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}}
+ };
+
+ typedef struct _SiS310_LCDACRT1DataStruct
+@@ -3054,7 +1760,7 @@
+ };
+
+ static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11024x768_1[]=
+-{ /* TW: Checked (1.10.6s) */
++{
+ {{0x73,0x4f,0x4f,0x97,0x55,0x86,0xc4,0x1f,
+ 0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
+ 0x00}},
+@@ -3079,7 +1785,7 @@
+ };
+
+ static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11280x1024_1[]=
+-{ /* Checked (1.10.6s) */
++{
+ {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0xb8,0x1f,
+ 0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x06,
+ 0x00}},
+@@ -3107,7 +1813,7 @@
+ };
+
+ static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11400x1050_1[]=
+-{ /* Checked (1.10.6s) */
++{
+ {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
+ 0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
+ 0x00}},
+@@ -3200,7 +1906,7 @@
+ };
+
+ static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11024x768_1_H[]=
+-{ /* TW: Checked (1.10.6s) */
++{
+ {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0xc4,0x1f,
+ 0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x44,
+ 0x00}},
+@@ -3225,7 +1931,7 @@
+ };
+
+ static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11280x1024_1_H[]=
+-{ /* Checked (1.10.6s) */
++{
+ {{0x56,0x27,0x27,0x9a,0x30,0x1e,0xb8,0x1f,
+ 0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x05,
+ 0x00}},
+@@ -3250,7 +1956,7 @@
+ };
+
+ static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11400x1050_1_H[]=
+-{ /* Checked (1.10.6s) */
++{
+ {{0x47,0x27,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
+ 0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
+ 0x00}},
+@@ -3343,7 +2049,7 @@
+ };
+
+ static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11024x768_2[]=
+-{ /* Checked (1.10.6s) */
++{
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
+ 0x00}},
+@@ -3368,7 +2074,7 @@
+ };
+
+ static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11280x1024_2[]=
+-{ /* Checked (1.10.6s) */
++{
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
+ 0x00}},
+@@ -3393,7 +2099,7 @@
+ };
+
+ static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11400x1050_2[]=
+-{ /* Checked (1.10.6s) */
++{
+ {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
+ 0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x03,
+ 0x00}},
+@@ -3486,7 +2192,7 @@
+ };
+
+ static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11024x768_2_H[]=
+-{ /* Checked (1.10.6s) */
++{
+ {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb,
+ 0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01,
+ 0x00 }},
+@@ -3511,7 +2217,7 @@
+ };
+
+ static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11280x1024_2_H[]=
+-{ /* Checked (1.10.6s) */
++{
+ {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
+ 0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01,
+ 0x00 }},
+@@ -3536,7 +2242,7 @@
+ };
+
+ static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11400x1050_2_H[]=
+-{ /* Checked (1.10.6s) */
++{
+ {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9a,
+ 0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x06,
+ 0x00}},
+@@ -3605,32 +2311,7 @@
+ UCHAR CR[15];
+ } SiS310_LVDSCRT1DataStruct;
+
+-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1320x480_1[] =
+-{
+- {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
+- 0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
+- 0x00 }},
+- {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
+- 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+- 0x00 }},
+- {{0x65,0x4f,0x89,0x54,0x9f,0xc4,0x1f,
+- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+- 0x00 }},
+- {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
+- 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+- 0x00 }},
+- {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
+- 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
+- 0x00 }},
+- {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+- 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+- 0x01 }},
+- {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
+- 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
+- 0x00 }}
+-};
+-
+-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_1[] =
++static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_1[] =
+ {
+ {{0x6b,0x4f,0x8f,0x55,0x85,0xaa,0x1f,
+ 0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
+@@ -3924,63 +2605,7 @@
+ 0x01}}
+ };
+
+-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1XXXxXXX_1[] =
+-{
+- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
+- 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
+- 0x00}},
+- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
+- 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
+- 0x00}},
+- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
+- 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
+- 0x00}},
+- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
+- 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
+- 0x00}},
+- {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+- 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x05,
+- 0x00}},
+- {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+- 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+- 0x01}},
+- {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+- 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+- 0x01}},
+- {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
+- 0x00,0x84,0xff,0x29,0x09,0x00,0x07,
+- 0x01}},
+- {{0xce,0x9f,0x92,0xa9,0x17,0x24,0xf5,
+- 0x02,0x88,0xff,0x25,0x10,0x00,0x07,
+- 0x01}}
+-};
+-
+-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1XXXxXXX_1_H[] =
+-{
+- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+- 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+- 0x00}},
+- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+- 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+- 0x00}},
+- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+- 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+- 0x00}},
+- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+- 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+- 0x00}},
+- {{0x38,0x27,0x9c,0x2c,0x80,0x0b,0x3e,
+- 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
+- 0x00}},
+- {{0x4d,0x31,0x91,0x3b,0x03,0x72,0xf0,
+- 0x58,0x8c,0x57,0x73,0x20,0x00,0x01,
+- 0x01}},
+- {{0x63,0x3f,0x87,0x4a,0x92,0x24,0xf5,
+- 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+- 0x01}}
+-};
+-
+-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_1[] =
++static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_1[] =
+ {
+ {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
+ 0x8f,0x81,0x8f,0x9f,0x30,0x00,0x05,
+@@ -4220,332 +2845,8 @@
+ #endif
+ };
+
+-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x768_1[] =
+-{
+- {{0x5b,0x4f,0x9f,0x55,0x19,0xb4,0x1f,
+- 0x9c,0x8e,0x8f,0xb5,0x10,0x00,0x01,
+- 0x00}},
+- {{0x5b,0x4f,0x9f,0x55,0x19,0x82,0x1f,
+- 0x6a,0x8c,0x5d,0x83,0x30,0x00,0x01,
+- 0x00}},
+- {{0x5b,0x4f,0x9f,0x55,0x19,0xb4,0x1f,
+- 0x9c,0x8e,0x8f,0xb5,0x10,0x00,0x01,
+- 0x00}},
+- {{0x5b,0x4f,0x9f,0x55,0x19,0x82,0x1f,
+- 0x6a,0x8c,0x5d,0x83,0x30,0x00,0x01,
+- 0x00}},
+- {{0x5b,0x4f,0x9f,0x55,0x19,0x04,0x3e,
+- 0xec,0x8e,0xdf,0x05,0x20,0x00,0x01,
+- 0x00}},
+- {{0x6f,0x63,0x93,0x69,0x8d,0x7c,0xf0,
+- 0x64,0x86,0x57,0x7d,0x20,0x00,0x05,
+- 0x01}},
+- {{0x8b,0x7f,0x8f,0x85,0x09,0x24,0xf5,
+- 0x0c,0x8e,0xff,0x25,0x30,0x00,0x02,
+- 0x01}},
+- {{0xab,0x9f,0x8f,0xa5,0x89,0x24,0xf5,
+- 0x0c,0x8e,0xff,0x25,0x30,0x00,0x06,
+- 0x01}},
+- {{0xab,0x9f,0x8f,0xa5,0x89,0x24,0xf5,
+- 0x0c,0x8e,0xff,0x25,0x30,0x00,0x06,
+- 0x01}}
+-};
+-
+-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x768_1_H[] =
+-{
+- {{0x47,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
+- 0x93,0x86,0x8f,0x9f,0x30,0x00,0x05,
+- 0x00}},
+- {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
+- 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
+- 0x00}},
+- {{0x47,0x27,0x8b,0x30,0x1e,0x9e,0x1f,
+- 0x92,0x86,0x8f,0x9f,0x30,0x00,0x05,
+- 0x00}},
+- {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
+- 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
+- 0x00}},
+- {{0x47,0x27,0x8b,0x2c,0x1a,0xee,0x1f,
+- 0xe2,0x86,0xdf,0xef,0x10,0x00,0x05,
+- 0x00}},
+- {{0x51,0x31,0x95,0x36,0x04,0x66,0xf0,
+- 0x5a,0x8e,0x57,0x67,0x20,0x00,0x01,
+- 0x01}},
+- {{0x5f,0x3f,0x83,0x44,0x92,0x0e,0xf5,
+- 0x02,0x86,0xff,0x0f,0x10,0x00,0x01,
+- 0x01}},
+- {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
+- 0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
+- 0x01}},
+- {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
+- 0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
+- 0x01}}
+-};
+-
+-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x768_2[] =
++static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_1[] =
+ {
+- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
+- 0x54,0x86,0xdb,0xda,0x00,0x00,0x02,
+- 0x00}},
+- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
+- 0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x02,
+- 0x00}},
+- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
+- 0x54,0x86,0xdb,0xda,0x00,0x00,0x02,
+- 0x00}},
+- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
+- 0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x02,
+- 0x00}},
+- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xb3,
+- 0x7c,0x8e,0x03,0x02,0x10,0x00,0x02,
+- 0x01}},
+- {{0xab,0x63,0x8f,0x8a,0x8e,0x24,0xf1,
+- 0xb6,0x88,0x57,0x25,0x10,0x00,0x02,
+- 0x01}},
+- {{0xab,0x7f,0x8f,0x98,0x9c,0x24,0xf5,
+- 0x0a,0x8c,0xff,0x25,0x30,0x00,0x02,
+- 0x01}},
+- {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
+- 0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
+- 0x01}},
+- {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
+- 0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
+- 0x01}}
+-};
+-
+-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x768_2_H[] =
+-{
+- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
+- 0x54,0x86,0xdb,0xda,0x00,0x00,0x01,
+- 0x00}},
+- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
+- 0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x01,
+- 0x00}},
+- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
+- 0x54,0x86,0xdb,0xda,0x00,0x00,0x01,
+- 0x00}},
+- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
+- 0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x01,
+- 0x00}},
+- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xb3,
+- 0x7c,0x8e,0x03,0x02,0x10,0x00,0x01,
+- 0x01}},
+- {{0x79,0x31,0x9d,0x58,0x9c,0x24,0xf1,
+- 0xb6,0x88,0x57,0x25,0x10,0x00,0x01,
+- 0x01}},
+- {{0x6b,0x3f,0x8f,0x58,0x9c,0x24,0xf5,
+- 0x0a,0x8c,0xff,0x25,0x30,0x00,0x01,
+- 0x01}},
+- {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
+- 0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
+- 0x01}},
+- {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
+- 0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
+- 0x01}}
+-};
+-
+-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x600_1[] =
+-{
+- {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
+- 0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
+- 0x00}},
+- {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
+- 0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
+- 0x00}},
+- {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
+- 0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
+- 0x00}},
+- {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
+- 0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
+- 0x00}},
+- {{0x64,0x4f,0x88,0x54,0x9f,0xaf,0xba,
+- 0x3b,0x82,0xdf,0xb0,0x00,0x00,0x01,
+- 0x00}},
+- {{0x7e,0x63,0x82,0x68,0x15,0x1e,0xf1,
+- 0xae,0x85,0x57,0x1f,0x30,0x00,0x26,
+- 0x01}},
+- {{0xa3,0x7f,0x87,0x86,0x97,0x1e,0xf1,
+- 0xae,0x85,0x57,0x1f,0x30,0x00,0x02,
+- 0x01}}
+-};
+-
+-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x600_1_H[] =
+-{
+- {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+- 0x00}},
+- {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+- 0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
+- 0x00}},
+- {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+- 0x00}},
+- {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+- 0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
+- 0x00}},
+- {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
+- 0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
+- 0x00}},
+- {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
+- 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
+- 0x01}},
+- {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+- 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+- 0x01}}
+-};
+-
+-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x600_2[] =
+-{
+- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+- 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+- 0x00}},
+- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+- 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+- 0x00}},
+- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+- 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+- 0x00}},
+- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+- 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+- 0x00}},
+- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+- 0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
+- 0x00}},
+- {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
+- 0xae,0x84,0x57,0x25,0x30,0x00,0x02,
+- 0x01}},
+- {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+- 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+- 0x01}}
+-};
+-
+-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x600_2_H[] =
+-{
+- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+- 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+- 0x00}},
+- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+- 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+- 0x00}},
+- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+- 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+- 0x00}},
+- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+- 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+- 0x00}},
+- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+- 0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
+- 0x00}},
+- {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
+- 0xae,0x84,0x57,0x25,0x30,0x00,0x01,
+- 0x01}},
+- {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+- 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+- 0x01}}
+-};
+-
+-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11152x768_1[] =
+-{
+- {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
+- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+- 0x00}},
+- {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
+- 0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+- 0x00}},
+- {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
+- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+- 0x00}},
+- {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
+- 0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+- 0x00}},
+- {{0x64,0x4f,0x88,0x54,0x9f,0x04,0x3e,
+- 0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
+- 0x00}},
+- {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
+- 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
+- 0x01}},
+- {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+- 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+- 0x01}}
+-};
+-
+-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11152x768_1_H[] =
+-{
+- {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+- 0x00}},
+- {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+- 0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
+- 0x00}},
+- {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+- 0x00}},
+- {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+- 0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
+- 0x00}},
+- {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
+- 0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
+- 0x00}},
+- {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
+- 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
+- 0x01}},
+- {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+- 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+- 0x01}}
+-};
+-
+-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11152x768_2[] =
+-{
+- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+- 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+- 0x00}},
+- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+- 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+- 0x00}},
+- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+- 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+- 0x00}},
+- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+- 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+- 0x00}},
+- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+- 0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
+- 0x00}},
+- {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
+- 0xae,0x84,0x57,0x25,0x30,0x00,0x02,
+- 0x01}},
+- {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+- 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+- 0x01}}
+-};
+-
+-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11152x768_2_H[] =
+-{
+- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+- 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+- 0x00}},
+- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+- 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+- 0x00}},
+- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+- 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+- 0x00}},
+- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+- 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+- 0x00}},
+- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+- 0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
+- 0x00}},
+- {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
+- 0xae,0x84,0x57,0x25,0x30,0x00,0x01,
+- 0x01}},
+- {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+- 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+- 0x01}}
+-};
+-
+-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_1[] =
+-{
+ {{0x83,0x4f,0x87,0x51,0x09,0xc0,0x1f,
+ 0x90,0x84,0x8f,0xc1,0x30,0x00,0x06,
+ 0x00}},
+@@ -4701,7 +3002,7 @@
+ {{0x80,0x63,0x84,0x6d,0x0f,0xec,0xf0,
+ 0x7a,0x8f,0x57,0xed,0x20,0x00,0x06,
+ 0x01 }},
+- {{0x8c,0x7f,0x90,0x86,0x09,0xaf,0xf5, /* TW: 1024x768 */
++ {{0x8c,0x7f,0x90,0x86,0x09,0xaf,0xf5,
+ 0x36,0x88,0xff,0xb0,0x10,0x00,0x02,
+ 0x01}}
+ };
+@@ -4726,7 +3027,7 @@
+ {{0x7d,0x63,0x81,0x68,0x0e,0xba,0xf0,
+ 0x78,0x8a,0x57,0xbb,0x20,0x00,0x06,
+ 0x01 }},
+- {{0x8c,0x7f,0x90,0x82,0x06,0x46,0xf5, /* TW: 1024x768 */
++ {{0x8c,0x7f,0x90,0x82,0x06,0x46,0xf5,
+ 0x15,0x88,0xff,0x47,0x70,0x00,0x02,
+ 0x01 }}
+ };
+@@ -4751,7 +3052,7 @@
+ {{0x73,0x63,0x97,0x69,0x8b,0xec,0xf0,
+ 0x90,0x8c,0x57,0xed,0x20,0x00,0x05,
+ 0x01 }},
+- {{0xaa,0x7f,0x8e,0x8e,0x96,0xe6,0xf5, /* TW: 1024x768 */
++ {{0xaa,0x7f,0x8e,0x8e,0x96,0xe6,0xf5,
+ 0x50,0x88,0xff,0xe7,0x10,0x00,0x02,
+ 0x01}}
+ };
+@@ -4776,7 +3077,7 @@
+ {{0x71,0x63,0x95,0x69,0x8c,0x6f,0xf0,
+ 0x5a,0x8b,0x57,0x70,0x20,0x00,0x05,
+ 0x01 }},
+- {{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5, /* TW: 1024x768 */
++ {{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5,
+ 0x28,0x88,0xff,0x6a,0x10,0x00,0x02,
+ 0x01 }}
+ };
+@@ -4801,12 +3102,11 @@
+ {{0x71,0x63,0x95,0x69,0x8c,0x6f,0xf0,
+ 0x5a,0x8b,0x57,0x70,0x20,0x00,0x05,
+ 0x01 }},
+- {{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5, /* TW: 1024x768 */
++ {{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5,
+ 0x28,0x88,0xff,0x6a,0x10,0x00,0x02,
+ 0x01 }}
+ };
+
+-/* TW: Data for Chrontel 7019 */
+ typedef struct _SiS310_CHTVRegDataStruct
+ {
+ UCHAR Reg[16];
+Index: linux-2.6.0-test5/drivers/video/sis/init301.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/sis/init301.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/sis/init301.c 2003-09-27 11:38:35.072196600 +0800
+@@ -1,27 +1,16 @@
+ /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init301.c,v 1.3 2002/22/04 01:16:16 dawes Exp $ */
+ /*
+- * Mode switching code (CRT2 section) for SiS 300/540/630/730/315/550/650/740/330
+- * (Universal module for Linux kernel framebuffer, XFree86 4.x)
++ * Mode switching code (CRT2 section) for SiS 300/540/630/730/315/550/650/740/330/660
++ * (Universal module for Linux kernel framebuffer and XFree86 4.x)
+ *
+ * Assembler-To-C translation
+ * Copyright 2002, 2003 by Thomas Winischhofer <thomas@winischhofer.net>
+- * Minor parts Copyright SiS, Inc.
++ * Formerly based on non-functional code-fragements by SiS, Inc.
+ *
+- * Based on BIOS
+- * 1.10.07, 1.10a for 650/CH7019
+- * 1.11.21a for 740/CH7019
+- * 1.11.05 for 650/LVDS (w/o Chrontel)
+- * 1.07.1b, 1.10.6s, 1.11.6w, 1.11.7w, 1.11.8r for 650/301(B/LV), 650/302LV
+- * 2.04.50 (I) and 2.04.5c (II) for 630/301(B)
+- * 2.02.3b, 2.03.02, 2.04.2c, 2.04.5c, 2.07a and 2.08.b3 for 630/LVDS/LVDS+CH7005
+- * 2.04.5c, 2.04.6c for 730+LVDS+CH7005
+- * 1.09b for 315/301(B)
+- * 1.16.51 for 300+301LV (ECS A907)
+- * 1.01.03 for 330 (Xabre 400)
++ * If distributed as part of the linux kernel, the contents of this file
++ * is entirely covered by the GPL.
+ *
+- * Known bugs:
+- * 1024x768 panel, expanding (CR37=1): Mode 640x480 does not work on SOME panels
+- * therefore, we always do the scaling ourselves for now.
++ * Otherwise, the following terms apply:
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+@@ -73,8 +62,8 @@
+ #define SiS_I2CDELAYSHORT 150
+
+ BOOLEAN
+-SiS_SetCRT2Group301(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+- PSIS_HW_DEVICE_INFO HwDeviceExtension)
++SiS_SetCRT2Group(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
++ PSIS_HW_DEVICE_INFO HwDeviceExtension)
+ {
+ USHORT ModeIdIndex;
+ USHORT RefreshRateTableIndex;
+@@ -85,9 +74,9 @@
+ SiS_SearchModeID(SiS_Pr,ROMAddr,&ModeNo,&ModeIdIndex);
+ } else {
+ ModeIdIndex = 0;
+- }
++ }
+
+- /* TW: Used for shifting CR33 */
++ /* Used for shifting CR33 */
+ SiS_Pr->SiS_SelectCRT2Rate = 4;
+
+ SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
+@@ -110,8 +99,6 @@
+ return(TRUE);
+ }
+
+- if(SiS_Pr->UseCustomMode) return(FALSE);
+-
+ SiS_GetCRT2Data(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+ HwDeviceExtension);
+
+@@ -153,9 +140,9 @@
+ SiS_SetGroup5(SiS_Pr,HwDeviceExtension, BaseAddr,ROMAddr,
+ ModeNo,ModeIdIndex);
+
+- /* TW: For 301BDH (Panel link initialization): */
++ /* For 301BDH (Panel link initialization): */
+ if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
++ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+ if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo = 0x10)))) {
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ SiS_ModCRT1CRTC(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+@@ -176,10 +163,10 @@
+ RefreshRateTableIndex,HwDeviceExtension);
+ }
+ }
+- if(SiS_Pr->SiS_IF_DEF_FSTN == 0) {
+- SiS_SetCRT2ECLK(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+- RefreshRateTableIndex,HwDeviceExtension);
+- }
++
++ SiS_SetCRT2ECLK(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
++ RefreshRateTableIndex,HwDeviceExtension);
++
+ if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+@@ -199,74 +186,64 @@
+ }
+
+ #ifdef SIS300
+- if ( (HwDeviceExtension->jChipType == SIS_540) ||
+- (HwDeviceExtension->jChipType == SIS_630) ||
+- (HwDeviceExtension->jChipType == SIS_730) ||
+- (HwDeviceExtension->jChipType == SIS_300) )
+- {
+- if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
+- if(SiS_Pr->SiS_UseOEM) {
+- if((SiS_Pr->SiS_UseROM) && ROMAddr && (SiS_Pr->SiS_UseOEM == -1)) {
+- if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
+- SiS_OEM300Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
+- }
+- } else {
+- SiS_OEM300Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
+- }
+- }
+- }
+- }
+-#endif
+-
+-#ifdef SIS315H
+- if ( (HwDeviceExtension->jChipType == SIS_315H) ||
+- (HwDeviceExtension->jChipType == SIS_315) ||
+- (HwDeviceExtension->jChipType == SIS_315PRO)||
+- (HwDeviceExtension->jChipType == SIS_550) ||
+- (HwDeviceExtension->jChipType == SIS_740) ||
+- (HwDeviceExtension->jChipType == SIS_650) ||
+- (HwDeviceExtension->jChipType == SIS_330) )
+- {
+- if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
+- SiS_FinalizeLCD(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex, HwDeviceExtension);
+-#if 0 /* Instead of FinalizeLCD(), older BIOSes (A92x) used OEMLCD() */
+- SiS_OEMLCD(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+-#endif
+- if(SiS_Pr->SiS_UseOEM) {
+- SiS_OEM310Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+- }
+- SiS_CRT2AutoThreshold(SiS_Pr,BaseAddr);
+- }
+- }
+-#endif
+-
+ if(HwDeviceExtension->jChipType < SIS_315H) {
++ if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
++ if(SiS_Pr->SiS_UseOEM) {
++ if((SiS_Pr->SiS_UseROM) && ROMAddr && (SiS_Pr->SiS_UseOEM == -1)) {
++ if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
++ SiS_OEM300Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
++ RefreshRateTableIndex);
++ }
++ } else {
++ SiS_OEM300Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
++ RefreshRateTableIndex);
++ }
++ }
++ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
++ if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
++ (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
++ SetOEMLCDData2(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,
++ ModeIdIndex,RefreshRateTableIndex);
++ }
++ if(HwDeviceExtension->jChipType == SIS_730) {
++ SiS_DisplayOn(SiS_Pr);
++ }
++ }
++ }
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ if(HwDeviceExtension->jChipType != SIS_730) {
+ SiS_DisplayOn(SiS_Pr);
+ }
+ }
+ }
++#endif
+
+- if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
+- if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+- if(HwDeviceExtension->jChipType == SIS_730) {
+- SiS_DisplayOn(SiS_Pr);
+- }
++#ifdef SIS315H
++ if(HwDeviceExtension->jChipType >= SIS_315H) {
++ if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
++ SiS_FinalizeLCD(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex, HwDeviceExtension);
++ if(SiS_Pr->SiS_UseOEM) {
++ SiS_OEM310Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
++ }
++ SiS_CRT2AutoThreshold(SiS_Pr,BaseAddr);
+ }
++ }
++#endif
++
++ if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
+ SiS_EnableBridge(SiS_Pr,HwDeviceExtension,BaseAddr);
+ }
+
+ SiS_DisplayOn(SiS_Pr);
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
+- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+- /* TW: Disable LCD panel when using TV */
+- SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x11,0x0C);
+- } else {
+- /* TW: Disable TV when using LCD */
+- SiS_SetCH70xxANDOR(SiS_Pr,0x010E,0xF8);
+- }
++ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
++ /* Disable LCD panel when using TV */
++ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x11,0x0C);
++ } else {
++ /* Disable TV when using LCD */
++ SiS_SetCH70xxANDOR(SiS_Pr,0x010E,0xF8);
++ }
+ }
+
+ if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
+@@ -283,7 +260,7 @@
+ USHORT temp,temp1,temp2;
+
+ if((ModeNo != 0x03) && (ModeNo != 0x10) && (ModeNo != 0x12))
+- return(1);
++ return(1);
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x11);
+ SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x11,0x80);
+ temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x00);
+@@ -304,7 +281,7 @@
+ }
+ }
+
+-/* TW: Set Part1 registers */
++/* Set Part1 registers */
+ void
+ SiS_SetGroup1(SiS_Private *SiS_Pr,USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+ USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+@@ -313,31 +290,35 @@
+ USHORT temp=0, tempax=0, tempbx=0, tempcx=0;
+ USHORT pushbx=0, CRT1Index=0;
+ #ifdef SIS315H
+- USHORT pushcx=0, tempbl=0;
++ USHORT tempbl=0;
+ #endif
+ USHORT modeflag, resinfo=0;
+
+- if(ModeNo<=0x13) {
+- modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
++ if(ModeNo <= 0x13) {
++ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ } else {
++ if(SiS_Pr->UseCustomMode) {
++ modeflag = SiS_Pr->CModeFlag;
++ } else {
+ CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+ resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++ }
+ }
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+-
+- SiS_SetCRT2Sync(SiS_Pr,BaseAddr,ROMAddr,ModeNo,
+- RefreshRateTableIndex,HwDeviceExtension);
+ #ifdef SIS315H
+- SiS_SetGroup1_LCDA(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+- HwDeviceExtension,RefreshRateTableIndex);
++ SiS_SetCRT2Sync(SiS_Pr,BaseAddr,ROMAddr,ModeNo,
++ RefreshRateTableIndex,HwDeviceExtension);
++
++ SiS_SetGroup1_LCDA(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
++ HwDeviceExtension,RefreshRateTableIndex);
+ #endif
+ } else {
+
+ if( (HwDeviceExtension->jChipType >= SIS_315H) &&
+ (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
+- (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
++ (SiS_Pr->SiS_VBInfo & SetInSlaveMode) ) {
+
+ SiS_SetCRT2Sync(SiS_Pr,BaseAddr,ROMAddr,ModeNo,
+ RefreshRateTableIndex,HwDeviceExtension);
+@@ -367,13 +348,13 @@
+ #ifdef SIS300 /* ------------- 300 series --------------*/
+
+ temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,temp); /* TW: CRT2 Horizontal Total */
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */
+
+ temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp); /* TW: CRT2 Horizontal Total Overflow [7:4] */
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp); /* CRT2 Horizontal Total Overflow [7:4] */
+
+ temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp); /* TW: CRT2 Horizontal Display Enable End */
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp); /* CRT2 Horizontal Display Enable End */
+
+ pushbx = SiS_Pr->SiS_VGAHDE + 12; /* bx BTVGA@HRS 0x0B,0x0C */
+ tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
+@@ -382,108 +363,129 @@
+ tempcx += tempbx;
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+- if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
+- /* CRT1Index &= 0x3F; - Not any longer */
+- tempbx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
+- tempbx |= ((SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14] & 0xC0) << 2);
+- tempbx = (tempbx - 1) << 3;
+- tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
+- tempcx &= 0x1F;
+- temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
+- temp = (temp & 0x04) << (6-2);
+- tempcx = (tempcx | temp);
+- tempcx--;
+- tempcx <<= 3;
+- }
+-
+- if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == 0x08)){
+- if(!(SiS_Pr->SiS_VBInfo & SetPALTV)){
+- tempbx = 1040;
+- tempcx = 1042;
+- }
+- }
++
++ if(SiS_Pr->UseCustomMode) {
++ tempbx = SiS_Pr->CHSyncStart + 12;
++ tempcx = SiS_Pr->CHSyncEnd + 12;
++ }
++
++ if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
++ unsigned char cr4, cr14, cr5, cr15;
++ if(SiS_Pr->UseCustomMode) {
++ cr4 = SiS_Pr->CCRT1CRTC[4];
++ cr14 = SiS_Pr->CCRT1CRTC[14];
++ cr5 = SiS_Pr->CCRT1CRTC[5];
++ cr15 = SiS_Pr->CCRT1CRTC[15];
++ } else {
++ cr4 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
++ cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
++ cr5 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
++ cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
++ }
++ tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 1) << 3;
++ tempcx = (((cr5 & 0x1F) | ((cr15 & 0x04) << (6-2))) - 1) << 3;
++ }
++
++ if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == SIS_RI_1024x768)){
++ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)){
++ tempbx = 1040;
++ tempcx = 1042;
++ }
++ }
+ }
+
+ temp = tempbx & 0x00FF;
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp); /* TW: CRT2 Horizontal Retrace Start */
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp); /* CRT2 Horizontal Retrace Start */
+ #endif /* SIS300 */
+
+ } else {
+
+-#ifdef SIS315H /* ----------------- 310/325/330 series ------------- */
++#ifdef SIS315H /* ------------------- 315/330 series --------------- */
+
+ tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HT 0x08,0x09 */
+- pushcx = tempcx;
+ if(modeflag & HalfDCLK) {
+-#ifndef NEWCH701x
+- if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->SiS_IF_DEF_CH70xx == 0)) {
+-#endif
++ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ tempax = SiS_Pr->SiS_VGAHDE >> 1;
+ tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+ tempcx = SiS_Pr->SiS_HT - tempax;
+ }
+-#ifndef NEWCH701x
+ } else {
+ tempcx >>= 1;
+ }
+-#endif
+ }
+ tempcx--;
+
+ temp = tempcx & 0xff;
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,temp); /* TW: CRT2 Horizontal Total */
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */
+
+ temp = ((tempcx & 0xff00) >> 8) << 4;
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp); /* TW: CRT2 Horizontal Total Overflow [7:4] */
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp); /* CRT2 Horizontal Total Overflow [7:4] */
+
+- tempcx = pushcx; /* BTVGA2HDEE 0x0A,0x0C */
++ tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HDEE 0x0A,0x0C */
+ tempbx = SiS_Pr->SiS_VGAHDE;
+ tempcx -= tempbx;
+ tempcx >>= 2;
+ if(modeflag & HalfDCLK) {
+- tempbx >>= 1;
+- tempcx >>= 1;
++ tempbx >>= 1;
++ tempcx >>= 1;
+ }
+ tempbx += 16;
+
+ temp = tempbx & 0xff;
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp); /* TW: CRT2 Horizontal Display Enable End */
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp); /* CRT2 Horizontal Display Enable End */
+
+ pushbx = tempbx;
+ tempcx >>= 1;
+ tempbx += tempcx;
+ tempcx += tempbx;
+
+- if(SiS_Pr->SiS_IF_DEF_LVDS==0) {
++ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
++
++ if(SiS_Pr->UseCustomMode) {
++ tempbx = SiS_Pr->CHSyncStart + 16;
++ tempcx = SiS_Pr->CHSyncEnd + 16;
++ tempax = SiS_Pr->SiS_VGAHT;
++ if(modeflag & HalfDCLK) tempax >>= 1;
++ tempax--;
++ if(tempcx > tempax) tempcx = tempax;
++ }
++
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
+- tempbx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
+- tempbx |= ((SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14] & 0xC0) << 2);
+- tempbx = (tempbx - 3) << 3; /*(VGAHRS-3)*8 */
+- tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
+- tempcx &= 0x1F;
+- temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
+- temp = (temp & 0x04) << (5-2); /* VGAHRE D[5] */
+- tempcx = (tempcx | temp); /* (VGAHRE-3)*8 */
+- tempcx -= 3;
+- tempcx <<= 3;
+- tempcx &= 0x00FF;
+- tempcx |= (tempbx & 0xFF00);
+- tempbx += 16;
+- tempcx += 16;
+- tempax = SiS_Pr->SiS_VGAHT;
+- if(modeflag & HalfDCLK) tempax >>= 1;
+- tempax--;
+- if(tempcx > tempax) tempcx = tempax;
++ unsigned char cr4, cr14, cr5, cr15;
++ if(SiS_Pr->UseCustomMode) {
++ cr4 = SiS_Pr->CCRT1CRTC[4];
++ cr14 = SiS_Pr->CCRT1CRTC[14];
++ cr5 = SiS_Pr->CCRT1CRTC[5];
++ cr15 = SiS_Pr->CCRT1CRTC[15];
++ } else {
++ cr4 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
++ cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
++ cr5 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
++ cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
++ }
++ tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; /* (VGAHRS-3)*8 */
++ tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3; /* (VGAHRE-3)*8 */
++ tempcx &= 0x00FF;
++ tempcx |= (tempbx & 0xFF00);
++ tempbx += 16;
++ tempcx += 16;
++ tempax = SiS_Pr->SiS_VGAHT;
++ if(modeflag & HalfDCLK) tempax >>= 1;
++ tempax--;
++ if(tempcx > tempax) tempcx = tempax;
+ }
+- if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == 0x08)){
+- if(!(SiS_Pr->SiS_VBInfo & SetPALTV)){
+- tempbx = 1040;
+- tempcx = 1042;
+- }
++ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
++ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
++ if(resinfo == SIS_RI_1024x768) {
++ tempbx = 1040;
++ tempcx = 1042;
++ }
++ }
+ }
+- /* TW: Makes no sense, but is in 650/302LV 1.10.6s */
+- if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == 0x08)){
++#if 0
++ /* Makes no sense, but is in 650/30xLV 1.10.6s */
++ if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == SIS_RI_1024x768)){
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) {
+ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+ tempbx = 1040;
+@@ -491,25 +493,26 @@
+ }
+ }
+ }
++#endif
+ }
+
+ temp = tempbx & 0xff;
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp); /* TW: CRT2 Horizontal Retrace Start */
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp); /* CRT2 Horizontal Retrace Start */
+ #endif /* SIS315H */
+
+- } /* 310/325/330 series */
++ } /* 315/330 series */
+
+- /* TW: The following is done for all bridge/chip types/series */
++ /* The following is done for all bridge/chip types/series */
+
+ tempax = tempbx & 0xFF00;
+ tempbx = pushbx;
+ tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4);
+ tempax |= (tempbx & 0xFF00);
+ temp = (tempax & 0xFF00) >> 8;
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0C,temp); /* TW: Overflow */
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0C,temp); /* Overflow */
+
+ temp = tempcx & 0x00FF;
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0D,temp); /* TW: CRT2 Horizontal Retrace End */
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0D,temp); /* CRT2 Horizontal Retrace End */
+
+ /* 2. Vertical setup */
+
+@@ -517,30 +520,30 @@
+ temp = tempcx & 0x00FF;
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+- if(HwDeviceExtension->jChipType < SIS_315H) {
+- if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+- if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
+- temp--;
+- }
+- }
+- } else {
+- temp--;
+- }
++ if(HwDeviceExtension->jChipType < SIS_315H) {
++ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
++ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
++ temp--;
++ }
++ }
++ } else {
++ temp--;
++ }
+ } else if(HwDeviceExtension->jChipType >= SIS_315H) {
+- /* TW: 650/30xLV 1.10.6s */
+- temp--;
++ /* 650/30xLV 1.10.6s */
++ temp--;
+ }
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0E,temp); /* TW: CRT2 Vertical Total */
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0E,temp); /* CRT2 Vertical Total */
+
+ tempbx = SiS_Pr->SiS_VGAVDE - 1;
+ temp = tempbx & 0x00FF;
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0F,temp); /* TW: CRT2 Vertical Display Enable End */
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0F,temp); /* CRT2 Vertical Display Enable End */
+
+ temp = ((tempbx & 0xFF00) << 3) >> 8;
+ temp |= ((tempcx & 0xFF00) >> 8);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x12,temp); /* TW: Overflow (and HWCursor Test Mode) */
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x12,temp); /* Overflow (and HWCursor Test Mode) */
+
+- /* TW: 650/LVDS (1.10.07), 650/30xLV (1.10.6s) */
++ /* 650/LVDS (1.10.07), 650/30xLV (1.10.6s) */
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ tempbx++;
+ tempax = tempbx;
+@@ -553,29 +556,44 @@
+ tempcx += tempbx;
+ tempcx++;
+ } else {
+- /* TW: 300 series, LVDS/301B: */
++ /* 300 series, LVDS/301B: */
+ tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
+ tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
+ }
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+- if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
+- tempbx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
+- temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
+- if(temp & 0x04) tempbx |= 0x0100;
+- if(temp & 0x80) tempbx |= 0x0200;
+- temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
+- if(temp & 0x08) tempbx |= 0x0400;
+- temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
+- tempcx = (tempcx & 0xFF00) | (temp & 0x00FF);
++
++ if(SiS_Pr->UseCustomMode) {
++ tempbx = SiS_Pr->CVSyncStart;
++ tempcx = (tempcx & 0xFF00) | (SiS_Pr->CVSyncEnd & 0x00FF);
++ }
++
++ if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
++ unsigned char cr8, cr7, cr13, cr9;
++ if(SiS_Pr->UseCustomMode) {
++ cr8 = SiS_Pr->CCRT1CRTC[8];
++ cr7 = SiS_Pr->CCRT1CRTC[7];
++ cr13 = SiS_Pr->CCRT1CRTC[13];
++ cr9 = SiS_Pr->CCRT1CRTC[9];
++ } else {
++ cr8 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
++ cr7 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
++ cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
++ cr9 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
++ }
++ tempbx = cr8;
++ if(cr7 & 0x04) tempbx |= 0x0100;
++ if(cr7 & 0x80) tempbx |= 0x0200;
++ if(cr13 & 0x08) tempbx |= 0x0400;
++ tempcx = (tempcx & 0xFF00) | (cr9 & 0x00FF);
+ }
+ }
+ temp = tempbx & 0x00FF;
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp); /* TW: CRT2 Vertical Retrace Start */
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp); /* CRT2 Vertical Retrace Start */
+
+ temp = ((tempbx & 0xFF00) >> 8) << 4;
+ temp |= (tempcx & 0x000F);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x11,temp); /* TW: CRT2 Vert. Retrace End; Overflow; "Enable CRTC Check" */
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x11,temp); /* CRT2 Vert. Retrace End; Overflow; "Enable CRTC Check" */
+
+ /* 3. Panel compensation delay */
+
+@@ -590,18 +608,18 @@
+ temp = 0x10;
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) temp = 0x2c;
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20;
+- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) temp = 0x24;
+ }
+ if(SiS_Pr->SiS_VBType & VB_SIS301) {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20;
+ }
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) temp = 0x24;
++ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) temp = 0x2c;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x08;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) temp = 0x2c;
+ else temp = 0x20;
+ }
+- if((ROMAddr) && (SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
++ if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
+ if(ROMAddr[0x220] & 0x80) {
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV-SetCRT2ToHiVisionTV))
+ temp = ROMAddr[0x221];
+@@ -636,19 +654,20 @@
+ }
+ }
+
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x03C,temp); /* TW: Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x03C,temp); /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
+
+ #endif /* SIS300 */
+
+ } else {
+
+-#ifdef SIS315H /* ----------- 310/325/330 series ---------------*/
++#ifdef SIS315H /* --------------- 315/330 series ---------------*/
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ temp = 0x10;
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) temp = 0x2c;
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20;
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) temp = 0x24;
++ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) temp = 0x2c;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ temp = 0x08;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+@@ -664,7 +683,7 @@
+ }
+ }
+ }
+- if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
++ if((SiS_Pr->SiS_VBType & VB_SIS301B302B) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
+ tempbl = 0x00;
+ if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
+ if(HwDeviceExtension->jChipType < SIS_330) {
+@@ -689,8 +708,16 @@
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
+ }
+ }
++
++ if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
++ temp = 0x08;
++ tempbl = 0;
++ if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
++ if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
++ }
++ }
+ }
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp); /* TW: Panel Link Delay Compensation */
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp); /* Panel Link Delay Compensation */
+
+ tempax = 0;
+ if (modeflag & DoubleScanMode) tempax |= 0x80;
+@@ -705,14 +732,13 @@
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+
+- /* TW: For 301BDH, we set up the Panel Link */
+- if( (SiS_Pr->SiS_VBType & VB_NoLCD) &&
+- (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) {
++ /* For 301BDH with LCD, we set up the Panel Link */
++ if( (SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) {
+
+ SiS_SetGroup1_LVDS(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+ HwDeviceExtension,RefreshRateTableIndex);
+
+- } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
++ } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+
+ SiS_SetGroup1_301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+ HwDeviceExtension,RefreshRateTableIndex);
+@@ -749,23 +775,27 @@
+ USHORT push1,push2;
+ USHORT tempax,tempbx,tempcx,temp;
+ USHORT resinfo,modeflag;
++ unsigned char p1_7, p1_8;
+
+ if(ModeNo <= 0x13) {
+- modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+- resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
++ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
++ resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+ } else {
++ if(SiS_Pr->UseCustomMode) {
++ modeflag = SiS_Pr->CModeFlag;
++ resinfo = 0;
++ } else {
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
++ }
+ }
+
+- /* TW: The following is only done if bridge is in slave mode: */
++ /* The following is only done if bridge is in slave mode: */
+
+ tempax = 0xFFFF;
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempax = SiS_GetVGAHT2(SiS_Pr);
+
+- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+- modeflag |= Charx8Dot;
+- }
++ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) modeflag |= Charx8Dot;
+
+ if(modeflag & Charx8Dot) tempcx = 0x08;
+ else tempcx = 0x09;
+@@ -777,8 +807,7 @@
+ tempax = (tempax / tempcx) - 5;
+ tempbx = tempax & 0x00FF;
+
+- temp = 0xFF; /* set MAX HT */
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,temp);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,0xff); /* set MAX HT */
+
+ tempax = SiS_Pr->SiS_VGAHDE; /* 0x04 Horizontal Display End */
+ if(modeflag & HalfDCLK) tempax >>= 1;
+@@ -789,13 +818,13 @@
+
+ temp = (tempbx & 0xFF00) >> 8;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+- if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
+- temp += 2;
+- }
+- }
++ if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
++ temp += 2;
++ }
++ }
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+ if(SiS_Pr->SiS_HiVision == 3) {
+- if(resinfo == 7) temp -= 2;
++ if(resinfo == SIS_RI_800x600) temp -= 2;
+ }
+ }
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x05,temp); /* 0x05 Horizontal Display Start */
+@@ -804,140 +833,133 @@
+
+ if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
+ (SiS_Pr->SiS_HiVision == 3)) {
+- temp = (tempbx & 0x00FF) - 1;
+- if(!(modeflag & HalfDCLK)) {
+- temp -= 6;
+- if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+- temp -= 2;
+- if(ModeNo > 0x13) temp -= 10;
+- }
+- }
++ temp = (tempbx & 0x00FF) - 1;
++ if(!(modeflag & HalfDCLK)) {
++ temp -= 6;
++ if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
++ temp -= 2;
++ if(ModeNo > 0x13) temp -= 10;
++ }
++ }
+ } else {
+- tempcx = tempbx & 0x00FF;
+- tempbx = (tempbx & 0xFF00) >> 8;
+- tempcx = (tempcx + tempbx) >> 1;
+- temp = (tempcx & 0x00FF) + 2;
+- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV){
+- temp--;
+- if(!(modeflag & HalfDCLK)){
+- if((modeflag & Charx8Dot)){
+- temp += 4;
+- if(SiS_Pr->SiS_VGAHDE >= 800) temp -= 6;
+- if(HwDeviceExtension->jChipType >= SIS_315H) {
+- if(SiS_Pr->SiS_VGAHDE == 800) temp += 2;
+- }
+- }
+- }
+- } else {
+- if(!(modeflag & HalfDCLK)) {
+- temp -= 4;
+- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) {
+- if(SiS_Pr->SiS_VGAHDE >= 800) {
+- temp -= 7;
+- if(HwDeviceExtension->jChipType < SIS_315H) {
+- /* 650/301LV(x) does not do this, 630/301B, 300/301LV do */
+- if(SiS_Pr->SiS_ModeType == ModeEGA) {
+- if(SiS_Pr->SiS_VGAVDE == 1024) {
+- temp += 15;
+- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)
+- temp += 7;
+- }
+- }
+- }
+- if(SiS_Pr->SiS_VGAHDE >= 1280) {
+- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) {
+- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) temp += 28;
+- }
+- }
+- }
+- }
+- }
+- }
++ tempcx = tempbx & 0x00FF;
++ tempbx = (tempbx & 0xFF00) >> 8;
++ tempcx = (tempcx + tempbx) >> 1;
++ temp = (tempcx & 0x00FF) + 2;
++ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
++ temp--;
++ if(!(modeflag & HalfDCLK)) {
++ if((modeflag & Charx8Dot)) {
++ temp += 4;
++ if(SiS_Pr->SiS_VGAHDE >= 800) temp -= 6;
++ if(HwDeviceExtension->jChipType >= SIS_315H) {
++ if(SiS_Pr->SiS_VGAHDE == 800) temp += 2;
++ }
++ }
++ }
++ } else {
++ if(!(modeflag & HalfDCLK)) {
++ temp -= 4;
++ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) {
++ if(SiS_Pr->SiS_VGAHDE >= 800) {
++ temp -= 7;
++ if(HwDeviceExtension->jChipType < SIS_315H) {
++ /* 650/301LV(x) does not do this, 630/301B, 300/301LV do */
++ if(SiS_Pr->SiS_ModeType == ModeEGA) {
++ if(SiS_Pr->SiS_VGAVDE == 1024) {
++ temp += 15;
++ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)
++ temp += 7;
++ }
++ }
++ }
++ if(SiS_Pr->SiS_VGAHDE >= 1280) {
++ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) temp += 28;
++ }
++ }
++ }
++ }
++ }
+ }
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,temp); /* 0x07 Horizontal Retrace Start */
+
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x00); /* 0x08 Horizontal Retrace End */
++ p1_7 = temp;
++ p1_8 = 0x00;
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+- if(ModeNo <= 0x01) {
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x2a);
+- if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x61);
+- } else {
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x41);
+- }
+- } else if(SiS_Pr->SiS_ModeType == ModeText) {
+- if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x54);
+- } else {
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x55);
+- }
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x00);
+- } else if(ModeNo <= 0x13) {
+- if(modeflag & HalfDCLK) {
+- if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x30);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x03);
+- } else {
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x2f);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x02);
+- }
+- } else {
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x5b);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x03);
+- }
+- } else if( ((HwDeviceExtension->jChipType >= SIS_315H) && (ModeNo == 0x50)) ||
+- ((HwDeviceExtension->jChipType < SIS_315H) && (resinfo == 0 || resinfo == 1)) ) {
+- if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x30);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x03);
+- } else {
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x2f);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x03);
+- }
+- }
+-
++ if(ModeNo <= 0x01) {
++ p1_7 = 0x2a;
++ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) p1_8 = 0x61;
++ else p1_8 = 0x41;
++ } else if(SiS_Pr->SiS_ModeType == ModeText) {
++ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) p1_7 = 0x54;
++ else p1_7 = 0x55;
++ p1_8 = 0x00;
++ } else if(ModeNo <= 0x13) {
++ if(modeflag & HalfDCLK) {
++ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
++ p1_7 = 0x30;
++ p1_8 = 0x03;
++ } else {
++ p1_7 = 0x2f;
++ p1_8 = 0x02;
++ }
++ } else {
++ p1_7 = 0x5b;
++ p1_8 = 0x03;
++ }
++ } else if( ((HwDeviceExtension->jChipType >= SIS_315H) &&
++ ((ModeNo == 0x50) || (ModeNo = 0x56) || (ModeNo = 0x53))) ||
++ ((HwDeviceExtension->jChipType < SIS_315H) &&
++ (resinfo == SIS_RI_320x200 || resinfo == SIS_RI_320x240)) ) {
++ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
++ p1_7 = 0x30,
++ p1_8 = 0x03;
++ } else {
++ p1_7 = 0x2f;
++ p1_8 = 0x03;
++ }
++ }
+ }
+ }
++
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+ if(SiS_Pr->SiS_HiVision & 0x03) {
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0xb2);
++ p1_7 = 0xb2;
+ if(SiS_Pr->SiS_HiVision & 0x02) {
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0xab);
++ p1_7 = 0xab;
+ }
+ }
+ }
+
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,p1_7); /* 0x07 Horizontal Retrace Start */
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,p1_8); /* 0x08 Horizontal Retrace End */
++
++
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x03); /* 0x18 SR08 (FIFO Threshold?) */
+
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x19,0xF0);
+
+- tempbx = SiS_Pr->SiS_VGAVT;
+- push1 = tempbx;
+-
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x09,0xFF); /* 0x09 Set Max VT */
+
+ tempcx = 0x121;
+ tempbx = SiS_Pr->SiS_VGAVDE; /* 0x0E Vertical Display End */
+- if(tempbx == 357) tempbx = 350;
+- if(tempbx == 360) tempbx = 350;
+- if(tempbx == 375) tempbx = 350;
+- if(tempbx == 405) tempbx = 400;
+- if(tempbx == 420) tempbx = 400;
+- if(tempbx == 525) tempbx = 480;
++ if (tempbx == 357) tempbx = 350;
++ else if(tempbx == 360) tempbx = 350;
++ else if(tempbx == 375) tempbx = 350;
++ else if(tempbx == 405) tempbx = 400;
++ else if(tempbx == 420) tempbx = 400;
++ else if(tempbx == 525) tempbx = 480;
+ push2 = tempbx;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+- if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
+- if(tempbx == 350) tempbx += 5;
+- if(tempbx == 480) tempbx += 5;
+- }
+- }
++ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
++ if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
++ if (tempbx == 350) tempbx += 5;
++ else if(tempbx == 480) tempbx += 5;
++ }
++ }
+ }
+- tempbx--;
+- temp = tempbx & 0x00FF;
+- tempbx--;
++ tempbx -= 2;
+ temp = tempbx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp); /* 0x10 vertical Blank Start */
+
+@@ -945,126 +967,91 @@
+ tempbx--;
+ temp = tempbx & 0x00FF;
+ #if 0
+- /* TW: Missing code from 630/301B 2.04.5a and 650/302LV 1.10.6s (calles int 2f) */
++ /* Missing code from 630/301B 2.04.5a and 650/302LV 1.10.6s (calles int 2f) */
+ if(xxx()) {
+ if(temp == 0xdf) temp = 0xda;
+ }
+ #endif
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0E,temp);
+
+- if(tempbx & 0x0100) {
+- tempcx |= 0x0002;
+- if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x000a;
+- }
++ if(tempbx & 0x0100) tempcx |= 0x0002;
+
+ tempax = 0x000B;
+ if(modeflag & DoubleScanMode) tempax |= 0x8000;
+
+- if(tempbx & 0x0200) {
+- tempcx |= 0x0040;
+- if(SiS_Pr->SiS_VBType & VB_SIS301) tempax |= 0x2000;
+- }
+-
+- if(SiS_Pr->SiS_VBType & VB_SIS301) {
+- if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+- if(SiS_Pr->SiS_VGAVDE == 480) {
+- tempax = (tempax & 0x00ff) | 0x2000;
+- if(modeflag & DoubleScanMode) tempax |= 0x8000;
+- }
+- }
+- }
++ if(tempbx & 0x0200) tempcx |= 0x0040;
+
+ temp = (tempax & 0xFF00) >> 8;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp);
+
+- if(tempbx & 0x0400) tempcx |= 0x0600;
++ if(tempbx & 0x0400) tempcx |= 0x0600;
+
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x11,0x00); /* 0x11 Vertical Blank End */
+
+- tempax = push1;
+- tempax -= tempbx;
+- tempax >>= 2;
+- push1 = tempax;
++ tempax = (SiS_Pr->SiS_VGAVT - tempbx) >> 2;
+
+- if(HwDeviceExtension->jChipType >= SIS_315H) {
+- /* TW: 650/30xLV 1.10.6s */
+- if(ModeNo > 0x13) {
+- if(resinfo != 0x09) { /* 1280x1024 */
+- tempax <<= 1;
+- tempbx += tempax;
+- }
+- } else {
+- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) {
+- tempax <<= 1;
+- tempbx += tempax;
+- }
+- }
+- } else if((resinfo != 0x09) || (SiS_Pr->SiS_VBType & VB_SIS301)) {
+- tempax <<= 1;
+- tempbx += tempax;
++ if((ModeNo > 0x13) || (HwDeviceExtension->jChipType < SIS_315H)) {
++ if(resinfo != SIS_RI_1280x1024) {
++ tempbx += (tempax << 1);
++ }
++ } else if(HwDeviceExtension->jChipType >= SIS_315H) {
++ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) {
++ tempbx += (tempax << 1);
++ }
+ }
+
+- if( (SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
+- (SiS_Pr->SiS_HiVision == 3) ) {
+- tempbx -= 10;
++ if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
++ (SiS_Pr->SiS_HiVision == 3)) {
++ tempbx -= 10;
+ } else {
+- if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+- if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+- if(!(SiS_Pr->SiS_HiVision & 0x03)) {
+- tempbx += 40;
+- if(HwDeviceExtension->jChipType >= SIS_315H) {
+- if(SiS_Pr->SiS_VGAHDE == 800) tempbx += 10;
+- }
+- }
+- }
+- }
++ if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
++ if(SiS_Pr->SiS_VBInfo & SetPALTV) {
++ if(!(SiS_Pr->SiS_HiVision & 0x03)) {
++ tempbx += 40;
++ if(HwDeviceExtension->jChipType >= SIS_315H) {
++ if(SiS_Pr->SiS_VGAHDE == 800) tempbx += 10;
++ }
++ }
++ }
++ }
+ }
+- tempax = push1;
+ tempax >>= 2;
+ tempax++;
+ tempax += tempbx;
+ push1 = tempax;
+ if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+- if(tempbx <= 513) {
+- if(tempax >= 513) tempbx = 513;
+- }
++ if(tempbx <= 513) {
++ if(tempax >= 513) tempbx = 513;
++ }
+ }
+ temp = tempbx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0C,temp); /* 0x0C Vertical Retrace Start */
+
+- if(!(SiS_Pr->SiS_VBType & VB_SIS301)) {
+- tempbx--;
+- temp = tempbx & 0x00FF;
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp);
+-
+- if(tempbx & 0x0100) tempcx |= 0x0008;
++ tempbx--;
++ temp = tempbx & 0x00FF;
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp);
+
+- if(tempbx & 0x0200) {
+- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x0B,0x20);
+- }
++ if(tempbx & 0x0100) tempcx |= 0x0008;
+
+- tempbx++;
++ if(tempbx & 0x0200) {
++ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x0B,0x20);
+ }
++ tempbx++;
++
+ if(tempbx & 0x0100) tempcx |= 0x0004;
+ if(tempbx & 0x0200) tempcx |= 0x0080;
+ if(tempbx & 0x0400) {
+- if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x0800;
+- else tempcx |= 0x0C00;
++ if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x0800;
++ else tempcx |= 0x0C00;
+ }
+
+ tempbx = push1;
+- temp = tempbx & 0x00FF;
+- temp &= 0x0F;
++ temp = tempbx & 0x000F;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0D,temp); /* 0x0D vertical Retrace End */
+
+ if(tempbx & 0x0010) tempcx |= 0x2000;
+
+ temp = tempcx & 0x00FF;
+- if(SiS_Pr->SiS_VBType & VB_SIS301) {
+- if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+- if(SiS_Pr->SiS_VGAVDE == 480) temp = 0xa3;
+- }
+- }
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp); /* 0x0A CR07 */
+
+ temp = (tempcx & 0xFF00) >> 8;
+@@ -1074,8 +1061,8 @@
+ temp = (tempax & 0xFF00) >> 8;
+ temp = (temp >> 1) & 0x09;
+ if(!(SiS_Pr->SiS_VBType & VB_SIS301)) {
+- /* Only use 8 dot clock */
+- temp |= 0x01;
++ /* Only use 8 dot clock */
++ temp |= 0x01;
+ }
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,temp); /* 0x16 SR01 */
+
+@@ -1084,16 +1071,15 @@
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x12,0x00); /* 0x12 CR17 */
+
+ if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
+- if(IS_SIS650) {
+- /* TW: 650/30xLV 1.10.6s */
+- if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
+- temp = 0x80;
+- }
+- } else temp = 0x80;
+- } else temp = 0x00;
++ if(IS_SIS650) {
++ /* 650/30xLV 1.10.6s */
++ if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
++ temp = 0x80;
++ }
++ } else temp = 0x80;
++ } else temp = 0x00;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1A,temp); /* 0x1A SR0E */
+
+- return;
+ }
+
+ void
+@@ -1108,40 +1094,52 @@
+ #endif
+ ULONG tempeax=0, tempebx, tempecx, tempvcfact=0;
+
++ /* This is not supported on LVDS */
++ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
++ if(SiS_Pr->UseCustomMode) return;
++
+ if(ModeNo <= 0x13) {
+- modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+- resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
++ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
++ resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+ } else {
+- modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+- resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
++ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++ resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ }
+
+- /* TW: Set up Panel Link */
++ /* Set up Panel Link */
+
+ /* 1. Horizontal setup */
+
+ tempax = SiS_Pr->SiS_LCDHDES;
+
+- if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) &&
+- (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
+- tempax -= 8;
++ if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
++ if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) &&
++ (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
++ tempax -= 8;
++ }
+ }
+
+ tempcx = SiS_Pr->SiS_HT; /* Horiz. Total */
+
+ tempbx = SiS_Pr->SiS_HDE; /* Horiz. Display End */
+
++ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
++ SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) {
++ tempbx >>= 1;
++ }
++
+ if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+- if((!SiS_Pr->SiS_IF_DEF_DSTN) && (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)) {
+- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) tempbx = 800;
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) tempbx = 1024; /* TW */
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx = 1024;
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) tempbx = 1152; /* TW */
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) tempbx = 1280;
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempbx = 1280;
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempbx = 1400;
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempbx = 1600;
++ if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
++ tempbx = SiS_Pr->PanelXRes;
++ } else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
++ tempbx = SiS_Pr->PanelXRes;
++ if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
++ tempbx = 800;
++ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
++ tempbx = 1024;
++ }
++ }
+ }
+ }
+ }
+@@ -1154,13 +1152,18 @@
+ if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
+
+ push2 = tempax;
+-
+- if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+- if((!SiS_Pr->SiS_IF_DEF_DSTN) && (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)) {
+- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) tempcx = 0x0028;
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) tempcx = 0x0018;
+- else if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
++
++ if((!SiS_Pr->SiS_IF_DEF_FSTN) &&
++ (!SiS_Pr->SiS_IF_DEF_DSTN) &&
++ (SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
++ (SiS_Pr->SiS_CustomT != CUT_BARCO1024) &&
++ (SiS_Pr->SiS_CustomT != CUT_PANEL848)) {
++ if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
++ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
++ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
++ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) tempcx = 0x0028;
++ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) tempcx = 0x0018;
++ else if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
+ (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) ) {
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+@@ -1174,11 +1177,12 @@
+ } else {
+ tempcx = 0x0018;
+ }
++ }
++ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) tempcx = 0x0028;
++ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 0x0030;
++ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x0030;
++ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x0040;
+ }
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) tempcx = 0x0028;
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 0x0030;
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x0030;
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x0040;
+ }
+ }
+ }
+@@ -1188,14 +1192,18 @@
+
+ tempax = tempcx >> 3; /* BPLHRS */
+ temp = tempax & 0x00FF;
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,temp); /* Part1_14h; TW: Panel Link Horizontal Retrace Start */
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,temp); /* Part1_14h; Panel Link Horizontal Retrace Start */
+
+ if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+ temp = (tempax & 0x00FF) + 2;
+ } else {
+ temp = (tempax & 0x00FF) + 10;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+- if(!SiS_Pr->SiS_IF_DEF_DSTN) {
++ if((!SiS_Pr->SiS_IF_DEF_DSTN) &&
++ (!SiS_Pr->SiS_IF_DEF_FSTN) &&
++ (SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
++ (SiS_Pr->SiS_CustomT != CUT_BARCO1024) &&
++ (SiS_Pr->SiS_CustomT != CUT_PANEL848)) {
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+ temp += 6;
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
+@@ -1219,47 +1227,57 @@
+
+ temp &= 0x1F;
+ temp |= ((tempcx & 0x0007) << 5);
+- if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0x20;
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x15,temp); /* Part1_15h; TW: Panel Link Horizontal Retrace End/Skew */
++#if 0
++ if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0x20; /* WRONG? BIOS loads cl, not ah */
++#endif
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x15,temp); /* Part1_15h; Panel Link Horizontal Retrace End/Skew */
+
+ tempbx = push2;
+ tempcx = push1; /* lcdhdes */
+
+ temp = (tempcx & 0x0007); /* BPLHDESKEW */
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1A,temp); /* Part1_1Ah; TW: Panel Link Vertical Retrace Start (2:0) */
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1A,temp); /* Part1_1Ah; Panel Link Vertical Retrace Start (2:0) */
+
+ tempcx >>= 3; /* BPLHDES */
+ temp = (tempcx & 0x00FF);
+- if(ModeNo == 0x5b) temp--;
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,temp); /* Part1_16h; TW: Panel Link Horizontal Display Enable Start */
++#if 0 /* Not 550 FSTN */
++ if(HwDeviceExtension->jChipType >= SIS_315H) {
++ if(ModeNo == 0x5b) temp--; */
++ }
++#endif
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,temp); /* Part1_16h; Panel Link Horizontal Display Enable Start */
+
+- if(HwDeviceExtension->jChipType < SIS_315H) {
++ if((HwDeviceExtension->jChipType < SIS_315H) ||
++ (SiS_Pr->SiS_IF_DEF_FSTN) ||
++ (SiS_Pr->SiS_IF_DEF_DSTN)) {
+ if(tempbx & 0x07) tempbx += 8;
+ }
+ tempbx >>= 3; /* BPLHDEE */
+ temp = tempbx & 0x00FF;
+- if(ModeNo == 0x5b) temp--;
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x17,temp); /* Part1_17h; TW: Panel Link Horizontal Display Enable End */
++#if 0 /* Not 550 FSTN */
++ if(HwDeviceExtension->jChipType >= SIS_315H) {
++ if(ModeNo == 0x5b) temp--;
++ }
++#endif
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x17,temp); /* Part1_17h; Panel Link Horizontal Display Enable End */
+
+ /* 2. Vertical setup */
+
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ tempcx = SiS_Pr->SiS_VGAVT;
+ tempbx = SiS_Pr->SiS_VGAVDE;
+- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) tempbx = 600;
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) tempbx = 600;
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx = 768;
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) tempbx = 768;
+- else tempbx = 1024;
+- }
++ if((SiS_Pr->SiS_CustomT != CUT_BARCO1366) && (SiS_Pr->SiS_CustomT != CUT_BARCO1024)) {
++ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
++ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
++ tempbx = SiS_Pr->PanelYRes;
++ }
++ }
+ }
+ tempcx -= tempbx;
+
+ } else {
+
+- tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE; /* VGAVT-VGAVDE */
++ tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE; /* VGAVT-VGAVDE */
+
+ }
+
+@@ -1268,18 +1286,20 @@
+
+ tempax = SiS_Pr->SiS_VGAVDE;
+
+- if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
+- if( (SiS_Pr->SiS_IF_DEF_TRUMPION == 0) &&
+- (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
+- (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) ) {
+- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) tempax = 600;
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) tempax = 600;
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempax = 768;
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) tempax = 768;
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) tempax = 768;
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempax = 1024;
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempax = 1050;
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempax = 1200;
++ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
++ if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
++ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
++ tempax = 600;
++ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
++ tempax = 768;
++ }
++ }
++ } else if( (SiS_Pr->SiS_IF_DEF_TRUMPION == 0) &&
++ (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
++ ((SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) ||
++ (SiS_Pr->SiS_IF_DEF_FSTN) ||
++ (SiS_Pr->SiS_IF_DEF_DSTN)) ) {
++ tempax = SiS_Pr->PanelYRes;
+ }
+ }
+
+@@ -1290,11 +1310,25 @@
+
+ tempcx >>= 1;
+
+- if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)) {
+- if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+- if(!SiS_Pr->SiS_IF_DEF_DSTN) {
+- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) tempcx = 0x0001;
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) tempcx = 0x0001;
++ if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
++ (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) &&
++ (SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
++ (SiS_Pr->SiS_CustomT != CUT_BARCO1024) &&
++ (SiS_Pr->SiS_CustomT != CUT_PANEL848)) {
++ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
++ SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) {
++ tempcx = 0x0017;
++ } else if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
++ if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
++ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) tempcx = 0x0003;
++ else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
++ (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)) tempcx = 0x0003;
++ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 0x0001;
++ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x0001;
++ else tempcx = 0x0057;
++ } else {
++ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) tempcx = 0x0001;
++ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) tempcx = 0x0001;
+ else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
+ (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)) {
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+@@ -1304,7 +1338,7 @@
+ tempcx = 0x0003;
+ #endif
+ } else {
+- tempcx = 0x0002; /* TW: A901; sometimes 0x0003; */
++ tempcx = 0x0002; /* A901; sometimes 0x0003; */
+ }
+ } else tempcx = 0x0003;
+ }
+@@ -1319,26 +1353,33 @@
+
+ tempbx += tempcx; /* BPLVRS */
+
+- if(HwDeviceExtension->jChipType < SIS_315H) {
+- tempbx++;
++ if((HwDeviceExtension->jChipType < SIS_315H) ||
++ (SiS_Pr->SiS_IF_DEF_FSTN) ||
++ (SiS_Pr->SiS_IF_DEF_DSTN)) {
++ tempbx++;
+ }
+
+ if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
+
+ temp = tempbx & 0x00FF;
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,temp); /* Part1_18h; TW: Panel Link Vertical Retrace Start */
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,temp); /* Part1_18h; Panel Link Vertical Retrace Start */
+
+ tempcx >>= 3;
+
+- if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
++ if((!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
++ (SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
++ (SiS_Pr->SiS_CustomT != CUT_BARCO1024) &&
++ (SiS_Pr->SiS_CustomT != CUT_PANEL848)) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ if( (HwDeviceExtension->jChipType < SIS_315H) &&
+ (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) ) tempcx = 0x0001;
++ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2) tempcx = 0x0002;
++ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempcx = 0x0002;
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) tempcx = 0x0003;
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) tempcx = 0x0005;
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) tempcx = 0x0005;
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) tempcx = 0x0011;
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 0x0005;
++ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 0x0005;
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x0002;
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x0011;
+ else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+@@ -1360,26 +1401,37 @@
+
+ tempcx = tempcx + tempbx + 1; /* BPLVRE */
+ temp = tempcx & 0x000F;
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xf0,temp); /* Part1_19h; TW: Panel Link Vertical Retrace End (3:0); Misc. */
++ if(SiS_Pr->SiS_IF_DEF_FSTN ||
++ SiS_Pr->SiS_IF_DEF_DSTN ||
++ (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
++ (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
++ (SiS_Pr->SiS_CustomT == CUT_PANEL848)) {
++ temp |= 0x30;
++ }
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xf0,temp); /* Part1_19h; Panel Link Vertical Retrace End (3:0); Misc. */
+
+ temp = ((tempbx & 0x0700) >> 8) << 3; /* BPLDESKEW =0 */
+- if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
+- if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) temp |= 0x40;
++ if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
++ if(SiS_Pr->SiS_HDE != 640) {
++ if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
++ }
++ } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
++ if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) temp |= 0x40;
+ if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
+- if(HwDeviceExtension->jChipType >= SIS_315H) {
+- if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
+- temp |= 0x80;
+- }
+- } else {
+- if( (HwDeviceExtension->jChipType == SIS_630) ||
+- (HwDeviceExtension->jChipType == SIS_730) ) {
+- if(HwDeviceExtension->jChipRevision >= 0x30) {
+- temp |= 0x80;
+- }
+- }
+- }
++ if(HwDeviceExtension->jChipType >= SIS_315H) {
++ if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
++ temp |= 0x80;
++ }
++ } else {
++ if( (HwDeviceExtension->jChipType == SIS_630) ||
++ (HwDeviceExtension->jChipType == SIS_730) ) {
++ if(HwDeviceExtension->jChipRevision >= 0x30) {
++ temp |= 0x80;
++ }
++ }
++ }
+ }
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,0x87,temp); /* Part1_1Ah; TW: Panel Link Control Signal (7:3); Vertical Retrace Start (2:0) */
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,0x87,temp); /* Part1_1Ah; Panel Link Control Signal (7:3); Vertical Retrace Start (2:0) */
+
+ if (HwDeviceExtension->jChipType < SIS_315H) {
+
+@@ -1396,19 +1448,19 @@
+ }
+
+ temp = (USHORT)(tempebx & 0x00FF);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,temp); /* Part1_1Eh; TW: Panel Link Vertical Scaling Factor */
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,temp); /* Part1_1Eh; Panel Link Vertical Scaling Factor */
+
+ #endif /* SIS300 */
+
+ } else {
+
+-#ifdef SIS315H /* 310/325 series */
++#ifdef SIS315H /* 315 series */
+
+-#ifdef NEWCH701x
+- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x03);
+-#else
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,0x23);
+-#endif
++ if(HwDeviceExtension->jChipType == SIS_740) {
++ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x03);
++ } else {
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,0x23);
++ }
+
+ tempeax = SiS_Pr->SiS_VGAVDE << 18;
+ temp = (USHORT)(tempeax % (ULONG)SiS_Pr->SiS_VDE);
+@@ -1417,12 +1469,13 @@
+ tempebx = tempeax; /* BPLVCFACT */
+ tempvcfact = tempeax;
+ temp = (USHORT)(tempebx & 0x00FF);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x37,temp); /* Part1_37h; TW: Panel Link Vertical Scaling Factor */
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x37,temp); /* Part1_37h; Panel Link Vertical Scaling Factor */
+ temp = (USHORT)((tempebx & 0x00FF00) >> 8);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x36,temp); /* Part1_36h; TW: Panel Link Vertical Scaling Factor */
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x36,temp); /* Part1_36h; Panel Link Vertical Scaling Factor */
+ temp = (USHORT)((tempebx & 0x00030000) >> 16);
++ temp &= 0x03;
+ if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x35,temp); /* Part1_35h; TW: Panel Link Vertical Scaling Factor */
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x35,temp); /* Part1_35h; Panel Link Vertical Scaling Factor */
+
+ #endif /* SIS315H */
+
+@@ -1434,47 +1487,50 @@
+ push1 = temp;
+
+ if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+- if(!SiS_Pr->SiS_IF_DEF_DSTN){
++ if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) {
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
+- if(resinfo == 15) tempcx++;
++ if(resinfo == SIS_RI_1024x600) tempcx++;
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+- if(resinfo == 7) tempcx++;
++ if(resinfo == SIS_RI_800x600) tempcx++;
+ }
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
+- if(resinfo == 7) tempcx++;
+- if(resinfo == 8) tempcx++; /* TW: Doesnt make sense anyway... */
+- } else if(resinfo == 8) tempcx++;
++ if(resinfo == SIS_RI_800x600) tempcx++;
++ if(resinfo == SIS_RI_1024x768) tempcx++; /* Doesnt make sense anyway... */
++ } else if(resinfo == SIS_RI_1024x768) tempcx++;
+ } else {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
+- if(resinfo == 7) tempcx++;
++ if(resinfo == SIS_RI_800x600) tempcx++;
+ }
+ }
+ }
+ }
+
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
+- tempcx = SiS_Pr->SiS_VGAVDE;
+- tempbx = SiS_Pr->SiS_VGAVDE - 1;
++ if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
++ tempcx = SiS_Pr->SiS_VGAVDE;
++ tempbx = SiS_Pr->SiS_VGAVDE - 1;
++ }
+ }
+
+ temp = ((tempbx & 0x0700) >> 8) << 3;
+ temp |= ((tempcx & 0x0700) >> 8);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1D,temp); /* Part1_1Dh; TW: Vertical Display Overflow; Control Signal */
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1D,temp); /* Part1_1Dh; Vertical Display Overflow; Control Signal */
+
+ temp = tempbx & 0x00FF;
+- if(SiS_Pr->SiS_IF_DEF_FSTN) temp++;
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1C,temp); /* Part1_1Ch; TW: Panel Link Vertical Display Enable End */
++ /* if(SiS_Pr->SiS_IF_DEF_FSTN) temp++; */
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1C,temp); /* Part1_1Ch; Panel Link Vertical Display Enable End */
+
+ temp = tempcx & 0x00FF;
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1B,temp); /* Part1_1Bh; TW: Panel Link Vertical Display Enable Start */
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1B,temp); /* Part1_1Bh; Panel Link Vertical Display Enable Start */
+
+ /* 3. Additional horizontal setup (scaling, etc) */
+
+ tempecx = SiS_Pr->SiS_VGAHDE;
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+- if(modeflag & HalfDCLK)
+- tempecx >>= 1;
++ if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
++ if(modeflag & HalfDCLK) tempecx >>= 1;
++ }
+ }
+ tempebx = SiS_Pr->SiS_HDE;
+ if(tempecx == tempebx) tempeax = 0xFFFF;
+@@ -1484,139 +1540,165 @@
+ temp = (USHORT)(tempeax % tempebx);
+ tempeax = tempeax / tempebx;
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+- if(temp) tempeax++;
++ if(temp) tempeax++;
+ }
+ }
+ tempecx = tempeax;
+
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+- tempeax = SiS_Pr->SiS_VGAHDE;
+- if(modeflag & HalfDCLK) tempeax >>= 1;
+- tempeax <<= 16;
+- tempeax = (tempeax / tempecx) - 1;
++ tempeax = SiS_Pr->SiS_VGAHDE;
++ if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
++ if(modeflag & HalfDCLK) tempeax >>= 1;
++ }
++ tempeax <<= 16;
++ tempeax = (tempeax / tempecx) - 1;
+ } else {
+- tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
++ tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
+ }
+ tempecx <<= 16;
+ tempecx |= (tempeax & 0xFFFF);
+ temp = (USHORT)(tempecx & 0x00FF);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1F,temp); /* Part1_1Fh; TW: Panel Link DDA Operational Number in each horiz. line */
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1F,temp); /* Part1_1Fh; Panel Link DDA Operational Number in each horiz. line */
+
+ tempbx = SiS_Pr->SiS_VDE;
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+- tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
+- tempbx = (USHORT)(tempeax & 0x0FFFF);
++ tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
++ tempbx = (USHORT)(tempeax & 0x0FFFF);
+ } else {
+- tempax = SiS_Pr->SiS_VGAVDE << 6;
+- tempbx = push1;
+- tempbx &= 0x3f;
+- if(tempbx == 0) tempbx = 64;
+- tempax = tempax / tempbx;
+- tempbx = tempax;
++ tempeax = SiS_Pr->SiS_VGAVDE << 6;
++ tempbx = push1 & 0x3f;
++ if(tempbx == 0) tempbx = 64;
++ tempeax /= tempbx;
++ tempbx = (USHORT)(tempeax & 0x0FFFF);
+ }
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx--;
+- if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempbx = 1;
++ if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
++ if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
++ else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) tempbx = 1;
++ }
+
+ temp = ((tempbx & 0xFF00) >> 8) << 3;
+ temp |= (USHORT)((tempecx & 0x0700) >> 8);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x20,temp); /* Part1_20h; TW: Overflow register */
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x20,temp); /* Part1_20h; Overflow register */
+
+ temp = tempbx & 0x00FF;
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x21,temp); /* Part1_21h; TW: Panel Link Vertical Accumulator Register */
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x21,temp); /* Part1_21h; Panel Link Vertical Accumulator Register */
+
+ tempecx >>= 16; /* BPLHCFACT */
+- if(HwDeviceExtension->jChipType < SIS_315H) {
+- if(modeflag & HalfDCLK) tempecx >>= 1;
++ if((HwDeviceExtension->jChipType < SIS_315H) || (SiS_Pr->SiS_IF_DEF_FSTN) || (SiS_Pr->SiS_IF_DEF_DSTN)) {
++ if(modeflag & HalfDCLK) tempecx >>= 1;
+ }
+ temp = (USHORT)((tempecx & 0xFF00) >> 8);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x22,temp); /* Part1_22h; TW: Panel Link Horizontal Scaling Factor High */
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x22,temp); /* Part1_22h; Panel Link Horizontal Scaling Factor High */
+
+ temp = (USHORT)(tempecx & 0x00FF);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x23,temp); /* Part1_22h; TW: Panel Link Horizontal Scaling Factor Low */
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x23,temp); /* Part1_22h; Panel Link Horizontal Scaling Factor Low */
+
+ /* 630/301B and 630/LVDS do something for 640x480 panels here */
+
+ #ifdef SIS315H
+- /* TW: DSTN/FSTN initialisation - hardcoded for 320x480 panel */
+- if(SiS_Pr->SiS_IF_DEF_DSTN) {
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,0x01);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x25,0x00);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x26,0x00);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x27,0x00);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x28,0x87);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x29,0x5A);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x007,0x03);
+- tempbx = SiS_Pr->SiS_HDE + 64; /*Blps = lcdhdee(lcdhdes+HDE) + 64*/
+- temp = tempbx & 0x00FF;
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x38,temp);
+- temp=((tempbx & 0xFF00) >> 8) << 3;
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
+- tempbx += 32; /*Blpe=lBlps+32*/
+- temp = tempbx & 0x00FF;
+- if(SiS_Pr->SiS_IF_DEF_FSTN) temp=0;
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x39,temp);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3A,0x00); /*Bflml=0*/
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x007,0x00);
+- tempbx = SiS_Pr->SiS_VDE / 2;
+- temp = tempbx & 0x00FF;
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3B,temp);
+- temp = ((tempbx & 0xFF00) >> 8) << 3;
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
+- tempeax = SiS_Pr->SiS_HDE << 2; /* BDxFIFOSTOP = (HDE*4)/128 */
+- tempebx = 128;
+- temp = (USHORT)(tempeax % tempebx);
+- tempeax = tempeax / tempebx;
+- if(temp != 0) tempeax++;
+- temp = (USHORT)(tempeax & 0x003F);
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x45,~0x0FF,temp);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3F,0x00); /* BDxWadrst0 */
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3E,0x00);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3D,0x10);
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x040,0x00);
+- tempax = SiS_Pr->SiS_HDE >> 4; /* BDxWadroff = HDE*4/8/8 */
+- pushcx = tempax;
+- temp = tempax & 0x00FF;
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x43,temp);
+- temp = ((tempax & 0xFF00) >> 8) << 3;
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
+- tempax = SiS_Pr->SiS_VDE; /*BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
+- tempeax = (tempax * pushcx);
+- tempebx = 0x00100000 + tempeax;
+- temp = (USHORT)tempebx & 0x000000FF;
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x42,temp);
+- temp = (USHORT)((tempebx & 0x0000FF00)>>8);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x41,temp);
+- temp = (USHORT)((tempebx & 0x00FF0000)>>16);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x40,temp);
+- temp = (USHORT)(((tempebx & 0x01000000)>>24) << 7);
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2F,0x03);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,0x50);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x04,0x00);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2F,0x01);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x13,0x00);
+- SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86); /* Unlock */
+- SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1e,0x62);
+- if(SiS_Pr->SiS_IF_DEF_FSTN){
+- SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2b,0x1b);
+- SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2c,0xe3);
+- SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1e,0x62);
+- SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2e,0x04);
+- SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2f,0x42);
+- SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,0x01);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2b,0x02);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2c,0x00);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2d,0x00);
+- }
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,0x30);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1e,0x7d);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2e,0xe0);
++ if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x25,0x00);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x26,0x00);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x27,0x00);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x28,0x87);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x29,0x5A);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x007,0x03);
++ tempax = SiS_Pr->SiS_HDE; /* Blps = lcdhdee(lcdhdes+HDE) + 64 */
++ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
++ SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1;
++ tempax += 64;
++ temp = tempax & 0x00FF;
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x38,temp);
++ temp = ((tempax & 0xFF00) >> 8) << 3;
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
++ tempax += 32; /* Blpe=lBlps+32 */
++ temp = tempax & 0x00FF;
++ if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0;
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x39,temp);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3A,0x00); /* Bflml=0 */
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x007,0x00);
++
++ tempax = SiS_Pr->SiS_VDE;
++ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
++ SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1;
++ tempax >>= 1;
++ temp = tempax & 0x00FF;
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3B,temp);
++ temp = ((tempax & 0xFF00) >> 8) << 3;
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
++
++ tempeax = SiS_Pr->SiS_HDE;
++ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
++ SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempeax >>= 1;
++ tempeax <<= 2; /* BDxFIFOSTOP = (HDE*4)/128 */
++ tempebx = 128;
++ temp = (USHORT)(tempeax % tempebx);
++ tempeax = tempeax / tempebx;
++ if(temp) tempeax++;
++ temp = (USHORT)(tempeax & 0x003F);
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x45,~0x0FF,temp);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3F,0x00); /* BDxWadrst0 */
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3E,0x00);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3D,0x10);
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x040,0x00);
++
++ tempax = SiS_Pr->SiS_HDE;
++ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
++ SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1;
++ tempax >>= 4; /* BDxWadroff = HDE*4/8/8 */
++ pushcx = tempax;
++ temp = tempax & 0x00FF;
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x43,temp);
++ temp = ((tempax & 0xFF00) >> 8) << 3;
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
++
++ tempax = SiS_Pr->SiS_VDE; /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
++ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
++ SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1;
++ tempeax = (tempax * pushcx);
++ tempebx = 0x00100000 + tempeax;
++ temp = (USHORT)tempebx & 0x000000FF;
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x42,temp);
++ temp = (USHORT)((tempebx & 0x0000FF00) >> 8);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x41,temp);
++ temp = (USHORT)((tempebx & 0x00FF0000) >> 16);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x40,temp);
++ temp = (USHORT)(((tempebx & 0x01000000) >> 24) << 7);
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp);
++
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2F,0x03);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,0x50);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x04,0x00);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2F,0x01);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x19,0x38);
++
++ if(SiS_Pr->SiS_IF_DEF_FSTN) {
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2b,0x02);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2c,0x00);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2d,0x00);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x35,0x0c);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x36,0x00);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x37,0x00);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x38,0x80);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x39,0xA0);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3a,0x00);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3c,0x00);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3d,0x10);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3e,0x00);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3f,0x00);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x40,0x10);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x41,0x25);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x42,0x80);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x43,0x14);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x44,0x03);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x45,0x0a);
++ }
+ }
+ #endif /* SIS315H */
+
+- return;
+-
+ }
+
+ #ifdef SIS315H
+@@ -1629,7 +1711,7 @@
+
+
+ #ifdef SIS315H
+-/* TW: For LVDS / 302B/30xLV - LCDA (this must only be called on 310/325 series!) */
++/* For LVDS / 302B/30xLV - LCDA (this must only be called on 315 series!) */
+ void
+ SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex)
+@@ -1638,6 +1720,10 @@
+ USHORT push1,push2,tempax,tempbx,tempcx,temp;
+ ULONG tempeax=0,tempebx,tempecx,tempvcfact;
+
++ /* This is not supported with LCDA */
++ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
++ if(SiS_Pr->UseCustomMode) return;
++
+ if(IS_SIS330) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10); /* Xabre 1.01.03 */
+ } else if(IS_SIS740) {
+@@ -1645,7 +1731,7 @@
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04); /* 740/LVDS */
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
+ } else {
+- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10); /* 740/301LV 1.10.1i */
++ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10); /* 740/301LV, 301BDH */
+ }
+ } else {
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* 650/LVDS */
+@@ -1669,10 +1755,7 @@
+ tempcx = SiS_Pr->SiS_HT;
+
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx = 1024;
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempbx = 1400;
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempbx = 1600;
+- else tempbx = 1280;
++ tempbx = SiS_Pr->PanelXRes;
+ }
+ tempcx -= tempbx; /* HT-HDE */
+ push1 = tempax;
+@@ -1684,7 +1767,7 @@
+
+ tempcx >>= 2;
+
+- /* TW: 650/30xLV 1.10.6s, 740/LVDS */
++ /* 650/30xLV 1.10.6s, 740/LVDS */
+ if( ((SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) ||
+ ((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ) {
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+@@ -1748,13 +1831,10 @@
+ tempbx = SiS_Pr->SiS_LCDVDES; /* VGAVDES */
+ push1 = tempbx;
+ if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
+- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempax = 768;
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) tempax = 768;
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempax = 1024;
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempax = 1050;
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempax = 1200;
+- else tempax = 960;
+- } else tempax = SiS_Pr->SiS_VGAVDE; /* Trumpion */
++ tempax = SiS_Pr->PanelYRes;
++ } else {
++ tempax = SiS_Pr->SiS_VGAVDE;
++ }
+
+ tempbx += tempax;
+ tempax = SiS_Pr->SiS_VT; /* VT */
+@@ -1764,7 +1844,7 @@
+
+ tempcx >>= 2;
+
+- /* TW: 650/30xLV 1.10.6s, 740/LVDS */
++ /* 650/30xLV 1.10.6s, 740/LVDS */
+ if( ((SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) ||
+ ((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ) {
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+@@ -1806,7 +1886,7 @@
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp);
+ } else {
+- /* TW: 650/30xLV 1.10.6s, Xabre */
++ /* 650/30xLV 1.10.6s, Xabre */
+ temp |= 0xC0;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp); /* Part1_19h */
+ }
+@@ -1823,7 +1903,7 @@
+ }
+ } else {
+ if(IS_SIS650) {
+- /* TW: 650/30xLV 1.10.6s */
++ /* 650/30xLV 1.10.6s */
+ if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
+ if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
+ }
+@@ -1839,7 +1919,7 @@
+
+ if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
+- if(resinfo == 7) tempcx++;
++ if(resinfo == SIS_RI_800x600) tempcx++;
+ }
+ }
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
+@@ -1925,18 +2005,17 @@
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x23,temp);
+
+ #if 0
+- /* TW: Missing code (calles int 2f) (650/302LV 1.10.6s; 1.10.7w doesn't do this) */
++ /* Missing code (calles int 2f) (650/302LV 1.10.6s; 1.10.7w doesn't do this) */
+ if(xxx()) {
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0e,0xda);
+ }
+ #endif
+
+- /* TW: Only for LVDS and 301LV/302LV */
++ /* Only for LVDS and 301LV/302LV */
+ if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBInfo & VB_SIS301LV302LV)){
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1e,0x20);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1e,0x20);
+ }
+
+- return;
+ }
+ #endif /* SIS 315 */
+
+@@ -1951,10 +2030,10 @@
+
+ offset = SiS_GetOffset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+ HwDeviceExtension);
+-#if 0
+- if(SiS_Pr->LCDResInfo == 13) offset >>= 1;
+- if(SiS_Pr->LCDResInfo == 12) offset >>= 1;
+-#endif
++
++ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
++ SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) offset >>= 1;
++
+ temp = (UCHAR)(offset & 0xFF);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,temp);
+ temp = (UCHAR)((offset & 0xFF00) >> 8);
+@@ -1976,13 +2055,7 @@
+ } else {
+ infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+ modeinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeInfo;
+-
+- if(HwDeviceExtension->jChipType < SIS_315H ) {
+- index = (modeinfo >> 4) & 0xFF;
+- } else {
+- index = (modeinfo >> 8) & 0xFF;
+- }
+-
++ index = (modeinfo >> 8) & 0xFF;
+ temp = SiS_Pr->SiS_ScreenOffset[index];
+ }
+
+@@ -1992,9 +2065,8 @@
+
+ temp *= colordepth;
+
+- /* TW: For 1400x1050 and 856x480 */
+- if( ( ((ModeNo >= 0x26) && (ModeNo <= 0x28)) ||
+- ModeNo == 0x3f ||
++ if( ( ((ModeNo >= 0x26) && (ModeNo <= 0x28)) ||
++ ModeNo == 0x3f ||
+ ModeNo == 0x42 ||
+ ModeNo == 0x45 ) ||
+ (SiS_Pr->UseCustomMode && (SiS_Pr->CHDisplay % 16)) ) {
+@@ -2012,7 +2084,8 @@
+ SHORT index;
+ USHORT modeflag;
+
+- if(SiS_Pr->UseCustomMode) {
++ /* Do NOT check UseCustomMode, will skrew up FIFO */
++ if(ModeNo == 0xfe) {
+ modeflag = SiS_Pr->CModeFlag;
+ } else {
+ if(ModeNo <= 0x13)
+@@ -2035,7 +2108,11 @@
+ flag = 0;
+ tempbl = 0xC0;
+
+- infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
++ if(SiS_Pr->UseCustomMode) {
++ infoflag = SiS_Pr->CInfoFlag;
++ } else {
++ infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
++ }
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* LVDS */
+
+@@ -2044,12 +2121,19 @@
+ } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
+ tempah = SiS_Pr->SiS_LCDInfo;
+ } else tempah = infoflag >> 8;
+-
++
+ tempah &= 0xC0;
+-
++
+ tempah |= 0x20;
+ if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+
++ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
++ if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
++ (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
++ tempah |= 0xc0;
++ }
++ }
++
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ tempah >>= 3;
+@@ -2079,9 +2163,11 @@
+ tempah |= 0x20;
+ if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+
++#if 0
+ if (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
+- /* TW: BIOS does something here @@@ */
++ /* BIOS does something here @@@ */
+ }
++#endif
+
+ tempah &= 0x3f;
+ tempah |= tempbl;
+@@ -2089,16 +2175,11 @@
+
+ } else { /* 630 - 301 */
+
+- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+- tempah = SiS_Pr->SiS_LCDInfo;
+- if(SiS_Pr->SiS_LCDInfo & DontExpandLCDShift) { /* ! */
+- flag = 1;
+- }
+- }
+- if(flag != 1) tempah = infoflag >> 8;
++ tempah = infoflag >> 8;
+ tempah &= 0xC0;
+- tempah |= 0x30;
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x3F,tempah);
++ tempah |= 0x20;
++ if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+
+ }
+
+@@ -2106,34 +2187,50 @@
+
+ } else {
+
+-#ifdef SIS315H /* ----- 310/325 series ---- */
++#ifdef SIS315H /* ------- 315 series ------ */
+
+- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { /* 310/325 - 30xLV */
++ if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { /* 315 - 30xLV */
++
++ if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
++ tempah = infoflag >> 8;
++ if(SiS_Pr->SiS_LCDInfo & LCDSync) {
++ tempah = SiS_Pr->SiS_LCDInfo;
++ }
++ } else {
++ tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);
++ }
++ tempah &= 0xC0;
+
+- tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);
+- tempah &= 0xC0;
+ tempah |= 0x20;
+ if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+
+- } else { /* 310/325 - 301, 301B */
++ } else { /* 315 - 301, 301B */
+
+ tempah = infoflag >> 8;
+- tempah &= 0xC0;
+- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+- if(SiS_Pr->SiS_LCDInfo & LCDSync) {
+- tempah = SiS_Pr->SiS_LCDInfo;
+- tempah &= 0xC0;
++ if(!SiS_Pr->UseCustomMode) {
++ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
++ if(SiS_Pr->SiS_LCDInfo & LCDSync) {
++ tempah = SiS_Pr->SiS_LCDInfo;
++ }
+ }
+ }
++ tempah &= 0xC0;
+
+ tempah |= 0x20;
+ if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
++
+ #if 0
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
+- /* TW: BIOS does something here @@@ */
++ /* BIOS does something here @@@ */
+ }
+-#endif
++#endif
++
++ if(SiS_Pr->SiS_VBType & VB_NoLCD) { /* TEST, imitate BIOS bug */
++ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
++ tempah |= 0xc0;
++ }
++ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+
+ }
+@@ -2143,7 +2240,7 @@
+ }
+ }
+
+-/* TW: Set CRT2 FIFO on 300/630/730 */
++/* Set CRT2 FIFO on 300/630/730 */
+ #ifdef SIS300
+ void
+ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
+@@ -2197,7 +2294,7 @@
+
+ if(!SiS_Pr->CRT1UsesCustomMode) {
+
+- CRT1ModeNo = SiS_Pr->SiS_CRT1Mode; /* get CRT1 ModeNo */
++ CRT1ModeNo = SiS_Pr->SiS_CRT1Mode; /* get CRT1 ModeNo */
+ SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT1ModeNo,&modeidindex);
+ SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
+ SiS_Pr->SiS_SelectCRT2Rate = 0;
+@@ -2205,20 +2302,32 @@
+ modeidindex,HwDeviceExtension);
+
+ if(CRT1ModeNo >= 0x13) {
+- index = SiS_Pr->SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK;
+- index &= 0x3F;
+- VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
+- data2 = SiS_Pr->SiS_ModeType - 2;
++ index = SiS_Pr->SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK;
++ index &= 0x3F;
++ VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
++
++ colorth = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT1ModeNo,modeidindex); /* Get colordepth */
++ colorth >>= 1;
++ if(!colorth) colorth++;
+ }
+-
++
+ } else {
+
+ CRT1ModeNo = 0xfe;
+- VCLK = SiS_Pr->CSRClock; /* Get VCLK */
+- data2 = (SiS_Pr->CModeFlag & ModeInfoFlag) - 2;
+-
+- }
+-
++ VCLK = SiS_Pr->CSRClock_CRT1; /* Get VCLK */
++ data2 = (SiS_Pr->CModeFlag_CRT1 & ModeInfoFlag) - 2;
++ switch(data2) { /* Get color depth */
++ case 0 : colorth = 1; break;
++ case 1 : colorth = 1; break;
++ case 2 : colorth = 2; break;
++ case 3 : colorth = 2; break;
++ case 4 : colorth = 3; break;
++ case 5 : colorth = 4; break;
++ default: colorth = 2;
++ }
++
++ }
++
+ if(CRT1ModeNo >= 0x13) {
+ if(HwDeviceExtension->jChipType == SIS_300) {
+ index = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3A);
+@@ -2227,22 +2336,8 @@
+ }
+ index &= 0x07;
+ MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK; /* Get MCLK */
+-
+-#ifdef TWDEBUG
+- xf86DrvMsg(0, X_INFO, "FIFO2: CRT1Mode 0x%x VCLK %d MCLK %d modetype-2 = %d\n",
+- CRT1ModeNo, VCLK, MCLK, data2);
+-#endif
+-
+- switch(data2) { /* Get color depth */
+- case 0 : colorth = 1; break;
+- case 1 : colorth = 1; break;
+- case 2 : colorth = 2; break;
+- case 3 : colorth = 2; break;
+- case 4 : colorth = 3; break;
+- case 5 : colorth = 4; break;
+- default: colorth = 2; break;
+- }
+- data2 = (colorth * VCLK) / MCLK;
++
++ data2 = (colorth * VCLK) / MCLK;
+
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
+ temp = ((temp & 0x00FF) >> 6) << 1;
+@@ -2252,22 +2347,12 @@
+
+ data2 = temp - data2;
+
+-#ifdef TWDEBUG
+- xf86DrvMsg(0, X_INFO, "FIFO2: data2 (step1) = %d\n",
+- data2);
+-#endif
+-
+ if((28 * 16) % data2) {
+ data2 = (28 * 16) / data2;
+ data2++;
+ } else {
+ data2 = (28 * 16) / data2;
+ }
+-
+-#ifdef TWDEBUG
+- xf86DrvMsg(0, X_INFO, "FIFO2: data2 (step2) = %d\n",
+- data2);
+-#endif
+
+ if(HwDeviceExtension->jChipType == SIS_300) {
+
+@@ -2313,10 +2398,6 @@
+ temp &= 0x0F;
+ tempal |= temp;
+
+-#ifdef TWDEBUG
+- xf86DrvMsg(0, X_INFO, "FIFO2: Latencyfactorindex = 0x%x\n", tempal);
+-#endif
+-
+ tempbx = tempal; /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
+ tempbx = 0; /* -- do it like the BIOS anyway... */
+ tempax = tempbx;
+@@ -2341,7 +2422,7 @@
+ SiS_SetReg4(0xcf8,0x800000A0);
+ eax = SiS_GetReg3(0xcfc);
+ #else
+- /* TW: We use pci functions X offers. We use tag 0, because
++ /* We use pci functions X offers. We use tag 0, because
+ * we want to read/write to the host bridge (which is always
+ * 00:00.0 on 630, 730 and 540), not the VGA device.
+ */
+@@ -2368,43 +2449,41 @@
+ if(!(temp & 0x80)) data += 5;
+ }
+
+-#ifdef TWDEBUG
+- xf86DrvMsg(0, X_INFO, "FIFO2: latencyfactor (CRT1) = %d\n", data);
+-#endif
+-
+ data += data2; /* CRT1 Request Period */
+
+-#ifdef TWDEBUG
+- xf86DrvMsg(0, X_INFO, "FIFO2: CRT1 request period = %d\n", data);
+-#endif
+-
+- CRT2ModeNo = ModeNo;
+ SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+ SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
+- SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT2ModeNo,&modeidindex);
+
+- refreshratetableindex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT2ModeNo,
+- modeidindex,HwDeviceExtension);
++ if(!SiS_Pr->UseCustomMode) {
++
++ CRT2ModeNo = ModeNo;
++ SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT2ModeNo,&modeidindex);
++
++ refreshratetableindex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT2ModeNo,
++ modeidindex,HwDeviceExtension);
++
++ index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,CRT2ModeNo,modeidindex,
++ refreshratetableindex,HwDeviceExtension);
++ VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
++
++ if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
++ if((ROMAddr) && SiS_Pr->SiS_UseROM) {
++ if(ROMAddr[0x220] & 0x01) {
++ VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
++ }
++ }
++ }
++
++ } else {
++
++ CRT2ModeNo = 0xfe;
++ VCLK = SiS_Pr->CSRClock; /* Get VCLK */
+
+- index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,CRT2ModeNo,modeidindex,
+- refreshratetableindex,HwDeviceExtension);
+- VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
+-
+- data2 = SiS_Pr->SiS_ModeType - 2;
+- switch(data2) { /* Get color depth */
+- case 0 : colorth = 1; break;
+- case 1 : colorth = 1; break;
+- case 2 : colorth = 2; break;
+- case 3 : colorth = 2; break;
+- case 4 : colorth = 3; break;
+- case 5 : colorth = 4; break;
+- default: colorth = 2; break;
+ }
+-
+-#ifdef TWDEBUG
+- xf86DrvMsg(0, X_INFO, "FIFO2: CRT2Mode 0x%x VCLK %d MCLK %d modetype-2 = %d, colorth %d\n",
+- CRT2ModeNo, VCLK, MCLK, data2, colorth);
+-#endif
++
++ colorth = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT2ModeNo,modeidindex); /* Get colordepth */
++ colorth >>= 1;
++ if(!colorth) colorth++;
+
+ data = data * VCLK * colorth;
+ if(data % (MCLK << 4)) {
+@@ -2414,10 +2493,6 @@
+ data = data / (MCLK << 4);
+ }
+
+-#ifdef TWDEBUG
+- xf86DrvMsg(0, X_INFO, "FIFO2: data (unclipped) = 0x%x\n", data);
+-#endif
+-
+ if(data <= 6) data = 6;
+ if(data > 0x14) data = 0x14;
+
+@@ -2456,13 +2531,13 @@
+ }
+ #endif
+
+-/* TW: Set FIFO on 310/325/330 series */
++/* Set FIFO on 315/330 series */
+ #ifdef SIS315H
+ void
+ SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension)
+ {
+-
++#if 0 /* This code is obsolete */
+ UCHAR CombCode[] = { 1, 1, 1, 4, 3, 1, 3, 4,
+ 4, 1, 4, 4, 5, 1, 5, 4};
+ UCHAR CRT2ThLow[] = { 39, 63, 55, 79, 78,102, 90,114,
+@@ -2474,11 +2549,13 @@
+ USHORT ModeIdIndex;
+ USHORT RefreshRateTableIndex;
+ USHORT SelectRate_backup;
+-
++
+ SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
+-
++#endif
++
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x01,0x3B);
+
++#if 0
+ if(!SiS_Pr->CRT1UsesCustomMode) {
+
+ CRT1ModeNo = SiS_Pr->SiS_CRT1Mode; /* get CRT1 ModeNo */
+@@ -2489,28 +2566,27 @@
+
+ /* Get REFIndex for crt1 refreshrate */
+ RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT1ModeNo,
+- ModeIdIndex,HwDeviceExtension);
++ ModeIdIndex,HwDeviceExtension);
++ index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
++ tempax = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
+
+- index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,CRT1ModeNo,ModeIdIndex,
+- RefreshRateTableIndex,HwDeviceExtension);
+- tempax = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
+-
+ tempbx = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT1ModeNo,ModeIdIndex); /* Get colordepth */
+ tempbx >>= 1;
+- if(!tempbx) tempbx++;
+-
++ if(!tempbx) tempbx++;
++
+ } else {
+-
+- tempax = SiS_Pr->CSRClock; /* Get VCLK */
+- tempbx = (SiS_Pr->CModeFlag & ModeInfoFlag) - 2;
++
++ CRT1ModeNo = 0xfe;
++ tempax = SiS_Pr->CSRClock_CRT1; /* Get VCLK */
++ tempbx = (SiS_Pr->CModeFlag_CRT1 & ModeInfoFlag) - 2;
+ switch(tempbx) { /* Get color depth */
+- case 0 : tempbx = 1; break;
+- case 1 : tempbx = 1; break;
+- case 2 : tempbx = 2; break;
+- case 3 : tempbx = 2; break;
+- case 4 : tempbx = 3; break;
+- case 5 : tempbx = 4; break;
+- default: tempbx = 2; break;
++ case 0 : tempbx = 1; break;
++ case 1 : tempbx = 1; break;
++ case 2 : tempbx = 2; break;
++ case 3 : tempbx = 2; break;
++ case 4 : tempbx = 3; break;
++ case 5 : tempbx = 4; break;
++ default: tempbx = 2;
+ }
+
+ }
+@@ -2523,13 +2599,6 @@
+
+ tempbx = tempax;
+
+-#if 0 /* TW: BIOS code is skrewed */
+- if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14) & 0x02) {
+- tempax = 16;
+- } else {
+- tempax = 8;
+- }
+-#endif
+ tempax = 16;
+
+ tempax -= tempbx;
+@@ -2556,24 +2625,33 @@
+
+ tempcx += temp3; /* CRT1 Request Period */
+
+- CRT2ModeNo = ModeNo; /* get CRT2 ModeNo */
+- SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT2ModeNo,&ModeIdIndex); /* Get ModeID Table */
+-
+ SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+ SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
+
+- RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT2ModeNo,
+- ModeIdIndex,HwDeviceExtension);
++ if(!SiS_Pr->UseCustomMode) {
++
++ CRT2ModeNo = ModeNo; /* get CRT2 ModeNo */
++ SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT2ModeNo,&ModeIdIndex);
++
++ RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT2ModeNo,
++ ModeIdIndex,HwDeviceExtension);
++
++ index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,CRT2ModeNo,ModeIdIndex,
++ RefreshRateTableIndex,HwDeviceExtension);
++ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
++ tempax = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
++ } else {
++ tempax = SiS_Pr->SiS_VBVCLKData[index].CLOCK;
++ }
+
+- index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,CRT2ModeNo,ModeIdIndex,
+- RefreshRateTableIndex,HwDeviceExtension);
+- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+- tempax = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
+ } else {
+- tempax = SiS_Pr->SiS_VBVCLKData[index].CLOCK; /* Get VCLK */
++
++ CRT2ModeNo = 0xfe; /* Get VCLK */
++ tempax = SiS_Pr->CSRClock;
++
+ }
+
+- tempbx = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT2ModeNo,ModeIdIndex); /* Get colordepth */
++ tempbx = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT2ModeNo,ModeIdIndex); /* Get colordepth */
+ tempbx >>= 1;
+ if(!tempbx) tempbx++;
+
+@@ -2590,12 +2668,16 @@
+
+ if (tempax > 0x37) tempax = 0x37;
+
+- /* TW: 650/LVDS (1.10.07, 1.10.00), 650/301LV, 740, 330 overrule calculated value; 315 does not */
++ /* 650/LVDS, 650/301LV, 740, 330 overrule calculated value; 315 does not */
+ if(HwDeviceExtension->jChipType >= SIS_650) {
+ tempax = 0x04;
+ }
+-
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3F,tempax);
++#else
++
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3F,0x04);
++
++#endif
+ }
+
+ USHORT
+@@ -2611,9 +2693,10 @@
+ return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
+ }
+ }
++
+ #endif
+
+-/* TW: Checked against 650/LVDS 1.10.07 BIOS */
++/* Checked against 650/LVDS 1.10.07 BIOS */
+ void
+ SiS_GetLVDSDesData(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,
+@@ -2623,7 +2706,15 @@
+ USHORT PanelIndex,ResIndex;
+ const SiS_LVDSDesStruct *PanelDesPtr = NULL;
+
+- if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ) {
++ if((SiS_Pr->UseCustomMode) ||
++ (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) ||
++ (SiS_Pr->SiS_CustomT == CUT_PANEL848)) {
++ SiS_Pr->SiS_LCDHDES = 0;
++ SiS_Pr->SiS_LCDVDES = 0;
++ return;
++ }
++
++ if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+
+ #ifdef SIS315H
+ SiS_GetLVDSDesPtrA(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+@@ -2689,11 +2780,11 @@
+ case 52: PanelDesPtr = SiS_Pr->SiS_CHTVUPALDesData; break;
+ case 53: PanelDesPtr = SiS_Pr->SiS_CHTVOPALDesData; break;
+ default:
+- if(HwDeviceExtension->jChipType < SIS_315H)
+- PanelDesPtr = SiS_Pr->SiS_PanelType0e_1;
+- else
+- PanelDesPtr = SiS_Pr->SiS_PanelType01_1;
+- break;
++ if(HwDeviceExtension->jChipType < SIS_315H)
++ PanelDesPtr = SiS_Pr->SiS_PanelType0e_1;
++ else
++ PanelDesPtr = SiS_Pr->SiS_PanelType01_1;
++ break;
+ }
+ }
+ SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
+@@ -2710,7 +2801,7 @@
+ } else {
+ if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
+ if( (HwDeviceExtension->jChipType < SIS_315H) ||
+- (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) ) {
++ (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) ) {
+ if(SiS_Pr->SiS_LCDResInfo >= SiS_Pr->SiS_Panel1024x768){
+ if(ModeNo <= 0x13) {
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+@@ -2737,7 +2828,7 @@
+ }
+ }
+ }
+- return;
++
+ }
+
+ void
+@@ -2757,11 +2848,11 @@
+
+ tempbx = 0;
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+- if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
++ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ tempbx = 50;
+ if((SiS_Pr->SiS_VBInfo & SetPALTV) && (!SiS_Pr->SiS_CHPALM)) tempbx += 2;
+ if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+- /* TW: Nothing special needed for SOverscan */
++ /* Nothing special needed for SOverscan */
+ /* PALM uses NTSC data, PALN uses PAL data */
+ }
+ }
+@@ -2773,7 +2864,7 @@
+ if(modeflag & HalfDCLK) tempbx++;
+ }
+ }
+- /* TW: 630/LVDS and 650/LVDS (1.10.07) BIOS */
++ /* 630/LVDS and 650/LVDS (1.10.07) BIOS */
+ if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+ tempal = 0x07;
+@@ -2833,14 +2924,13 @@
+ }
+ }
+
+- /* TW: BIOS does not do this (neither 301 nor LVDS) */
++ /* BIOS does not do this (neither 301 nor LVDS) */
+ /* (But it's harmless; see SetCRT2Offset) */
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,0x00); /* fix write part1 index 0 BTDRAM bit Bug */
+
+- /* TW: Removed 301B302B301LV302LV check here to match 650/LVDS BIOS */
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+
+- /* TW: 1. for LVDS/302B/302LV **LCDA** */
++ /* 1. for LVDS/302B/302LV **LCDA** */
+
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40); /* FUNCTION CONTROL */
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
+@@ -2855,23 +2945,23 @@
+
+ #ifdef SIS300 /* ---- 300 series ---- */
+
+- /* For 301BDH: */
++ /* For 301BDH: (with LCD via LVDS) */
+ if(SiS_Pr->SiS_VBType & VB_NoLCD) {
+- temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32);
+- temp &= 0xef;
+- temp |= 0x02;
+- if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
+- temp |= 0x10;
+- temp &= 0xfd;
+- }
+- SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
++ temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32);
++ temp &= 0xef;
++ temp |= 0x02;
++ if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
++ temp |= 0x10;
++ temp &= 0xfd;
++ }
++ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
+ }
+
+ if(ModeNo > 0x13) {
+- tempcl -= ModeVGA;
+- if((tempcl > 0) || (tempcl == 0)) { /* TW: tempcl is USHORT -> always true! */
+- tempah = ((0x10 >> tempcl) | 0x80);
+- }
++ tempcl -= ModeVGA;
++ if((tempcl > 0) || (tempcl == 0)) { /* tempcl is USHORT -> always true! */
++ tempah = ((0x10 >> tempcl) | 0x80);
++ }
+ } else tempah = 0x80;
+
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0xA0;
+@@ -2880,7 +2970,7 @@
+
+ } else {
+
+-#ifdef SIS315H /* ---- 310/325/330 series ---- */
++#ifdef SIS315H /* ------- 315/330 series ------ */
+
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(SiS_Pr->SiS_VBInfo & CRT2DisplayFlag) {
+@@ -2889,12 +2979,12 @@
+ }
+
+ if(ModeNo > 0x13) {
+- tempcl -= ModeVGA;
+- if((tempcl > 0) || (tempcl == 0)) { /* TW: tempcl is USHORT -> always true! */
+- tempah = (0x08 >> tempcl);
+- if (tempah == 0) tempah = 1;
+- tempah |= 0x40;
+- }
++ tempcl -= ModeVGA;
++ if((tempcl > 0) || (tempcl == 0)) { /* tempcl is USHORT -> always true! */
++ tempah = (0x08 >> tempcl);
++ if (tempah == 0) tempah = 1;
++ tempah |= 0x40;
++ }
+ } else tempah = 0x40;
+
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
+@@ -2921,7 +3011,7 @@
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+
+- /* TW: 2. for 301 (301B, 302B 301LV, 302LV non-LCDA) */
++ /* 2. for 301 (301B, 302B 301LV, 302LV non-LCDA) */
+
+ tempah = 0x01;
+ if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+@@ -2938,7 +3028,7 @@
+
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+
+- /* --- 300 series --- */
++ /* ---- 300 series ---- */
+
+ tempah = (tempah << 5) & 0xFF;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x01,tempah);
+@@ -2946,7 +3036,7 @@
+
+ } else {
+
+- /* --- 310 series --- */
++ /* ---- 315 series ---- */
+
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF8,tempah);
+
+@@ -2956,9 +3046,9 @@
+ tempah |= 0x10;
+ }
+
+- /* TW: 630/301 BIOS */
+ if((HwDeviceExtension->jChipType < SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301)) {
+- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
++ if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
++ (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)) {
+ tempah |= 0x80;
+ }
+ } else {
+@@ -2996,28 +3086,31 @@
+ }
+ }
+ }
+- /* TW: For 302LV dual-channel */
++
++ /* For 302LV dual-channel */
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+- if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04)
+- tempah |= 0x40;
+- }
++ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
++ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04)
++ tempah |= 0x40;
++ }
+ }
+
+ if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
+- (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)) {
+- tempah |= 0x80;
++ (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) ||
++ ((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) &&
++ (SiS_Pr->CP_MaxX >= 1280) && (SiS_Pr->CP_MaxY >= 960))) {
++ tempah |= 0x80;
+ }
+
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0C,tempah);
+
+ } else {
+
+- /* TW: 3. for LVDS */
++ /* 3. for LVDS */
+
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+
+- /* TW: Inserted this entire section (BIOS 650/LVDS); added ModeType check
++ /* Inserted this entire section (BIOS 650/LVDS); added ModeType check
+ * (LVDS can only be slave in 8bpp modes)
+ */
+ tempah = 0x80;
+@@ -3043,7 +3136,7 @@
+
+ } else {
+
+- /* TW: (added ModeType check) */
++ /* (added ModeType check) */
+ tempah = 0;
+ if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
+ tempah |= 0x02;
+@@ -3060,50 +3153,69 @@
+
+ }
+
+- /* TW: Inserted the entire following section */
++ /* Inserted the entire following section */
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+
+ #ifdef SIS315H
++
++ unsigned char bridgerev = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x01);;
++
++ /* The following is nearly unpreditable and varies from machine
++ * to machine. Especially the 301DH seems to be a real trouble
++ * maker. Some BIOSes simply set the registers (like in the
++ * NoLCD-if-statements here), some set them according to the
++ * LCDA stuff. It is very likely that some machines are not
++ * treated correctly in the following, very case-orientated
++ * code. What do I do then...?
++ */
++
++ /* 740 variants match for 30xB, 301B-DH, 30xLV */
++
+ if(!(IS_SIS740)) {
+ tempah = 0x04; /* For all bridges */
+ tempbl = 0xfb;
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+ tempah = 0x00;
+- if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr))
++ if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)) {
+ tempbl = 0xff;
++ }
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
+ }
+-
+- if(IS_SIS740) {
++
++ /* The following two are responsible for eventually wrong colors
++ * in TV output. The DH (VB_NoLCD) conditions are unknown; the
++ * b0 was found in some 651 machine (Pim); the b1 version in a
++ * 650 box (Jake). What is the criteria?
++ */
++
++ if(IS_SIS740) {
+ tempah = 0x30;
+ tempbl = 0xcf;
+ if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
+ tempah = 0x00;
+ }
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
++ } else if(SiS_Pr->SiS_VBType & VB_SIS301) {
++ /* Fixes "TV-blue-bug" on 315+301 */
++ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xCF); /* For 301 */
++ } else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xCF,0x30); /* For 30xLV */
++ } else if((SiS_Pr->SiS_VBType & VB_NoLCD) && (bridgerev == 0xb0)) {
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xCF,0x30); /* For 30xB-DH rev b0 (or "DH on 651"?) */
+ } else {
+- /* TW: This in order to fix "TV-blue-bug" on 315+301 */
+- if(SiS_Pr->SiS_VBType & VB_SIS301) {
+- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xCF); /* For 301 */
+- } else {
+- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xCF,0x30); /* For 30xLV */
+- } else {
+- tempah = 0x30; /* For 301B */
+- tempbl = 0xcf;
+- if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+- tempah = 0x00;
+- if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)) {
+- tempbl = 0xff;
+- }
+- }
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
++ tempah = 0x30; /* For 30xB (and 301BDH rev b1) */
++ tempbl = 0xcf;
++ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
++ tempah = 0x00;
++ if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)) {
++ tempbl = 0xff;
+ }
+ }
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
+ }
+
+ if(IS_SIS740) {
+@@ -3111,25 +3223,25 @@
+ tempbl = 0x3f;
+ if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
+ tempah = 0x00;
+- }
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl,tempah);
++ }
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl,tempah);
++ } else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,0xc0); /* For 30xLV */
++ } else if((SiS_Pr->SiS_VBType & VB_NoLCD) && (bridgerev == 0xb0)) {
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,0xc0); /* For 30xB-DH rev b0 (or "DH on 651"? */
+ } else {
+- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { /* For 30xLV */
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,0xc0);
+- } else { /* For 301, 301B */
+- tempah = 0xc0;
+- tempbl = 0x3f;
+- if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+- tempah = 0x00;
+- if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)) {
+- tempbl = 0xff;
+- }
+- }
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl,tempah);
++ tempah = 0xc0; /* For 301, 301B (and 301BDH rev b1) */
++ tempbl = 0x3f;
++ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
++ tempah = 0x00;
++ if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)) {
++ tempbl = 0xff;
++ }
+ }
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl,tempah);
+ }
+
+- if(IS_SIS740) {
++ if(IS_SIS740) {
+ tempah = 0x80;
+ tempbl = 0x7f;
+ if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
+@@ -3141,8 +3253,9 @@
+ tempbl = 0x7f;
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+ tempbl = 0xff;
+- if(!(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)))
++ if(!(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr))) {
+ tempah |= 0x80;
++ }
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
+ }
+@@ -3174,16 +3287,32 @@
+ tempbl = 0xfb;
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+ tempah = 0x00;
+- if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr))
++ if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)) {
+ tempbl = 0xff;
++ }
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
+
+- if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)
++ if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x00);
++ }
+
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,0x30);
+
++ } else if(HwDeviceExtension->jChipType == SIS_550) {
++
++#if 0
++ tempah = 0x00;
++ tempbl = 0xfb;
++ if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
++ tempah = 0x00;
++ tempbl = 0xfb;
++ }
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
++#endif
++ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
++
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,0x30);
+ }
+
+ }
+@@ -3209,10 +3338,9 @@
+ HwDeviceExtension);
+ } else {
+
+- if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
+- (SiS_Pr->SiS_VBType & VB_NoLCD) ) {
+-
+- /* TW: Need LVDS Data for LCD on 301BDH */
++ if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_VBType & VB_NoLCD) ) {
++
++ /* Need LVDS Data for LCD on 301B-DH */
+ SiS_GetCRT2DataLVDS(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+ HwDeviceExtension);
+
+@@ -3282,18 +3410,16 @@
+
+ } else {
+
+- /* TW: 301BDH needs LVDS Data */
+- if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
+- (SiS_Pr->SiS_VBType & VB_NoLCD) ) {
++ /* 301BDH needs LVDS Data */
++ if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_VBType & VB_NoLCD) ) {
+ SiS_Pr->SiS_IF_DEF_LVDS = 1;
+ }
+
+ SiS_GetCRT2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+ &CRT2Index,&ResIndex,HwDeviceExtension);
+
+- /* TW: 301BDH needs LVDS Data */
+- if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
+- (SiS_Pr->SiS_VBType & VB_NoLCD) ) {
++ /* 301BDH needs LVDS Data */
++ if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_VBType & VB_NoLCD) ) {
+ SiS_Pr->SiS_IF_DEF_LVDS = 0;
+ }
+
+@@ -3321,11 +3447,18 @@
+ case 20: LVDSData = SiS_Pr->SiS_LVDS1280x768Data_2; break;
+ case 21: LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_1; break;
+ case 22: LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_2; break;
++ case 30: LVDSData = SiS_Pr->SiS_LVDS640x480Data_2; break;
++ case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1; break;
++ case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2; break;
++ case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1; break;
++ case 83: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_2; break;
++ case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1; break;
++ case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2; break;
+ case 90: LVDSData = SiS_Pr->SiS_CHTVUPALMData; break;
+ case 91: LVDSData = SiS_Pr->SiS_CHTVOPALMData; break;
+ case 92: LVDSData = SiS_Pr->SiS_CHTVUPALNData; break;
+ case 93: LVDSData = SiS_Pr->SiS_CHTVOPALNData; break;
+- case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData; break; /* TW: Super Overscan */
++ case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData; break; /* Super Overscan */
+ default: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
+ }
+ }
+@@ -3337,67 +3470,36 @@
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+
+- if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)){
+- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768){
+- SiS_Pr->SiS_HDE = 1024;
+- SiS_Pr->SiS_VDE = 768;
+- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024){
+- SiS_Pr->SiS_HDE = 1280;
+- SiS_Pr->SiS_VDE = 1024;
+- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050){
+- SiS_Pr->SiS_HDE = 1400;
+- SiS_Pr->SiS_VDE = 1050;
+- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200){
+- SiS_Pr->SiS_HDE = 1600;
+- SiS_Pr->SiS_VDE = 1200;
+- } else {
+- SiS_Pr->SiS_HDE = 1280;
+- SiS_Pr->SiS_VDE = 960;
+- }
+- }
++ if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
++ SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
++ SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
++ }
+
+ } else {
+
+- if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
+- if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
+- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+- if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
+- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
+- SiS_Pr->SiS_HDE = 800;
+- SiS_Pr->SiS_VDE = 600;
+- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
+- SiS_Pr->SiS_HDE = 1024;
+- SiS_Pr->SiS_VDE = 600;
+- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+- SiS_Pr->SiS_HDE = 1024;
+- SiS_Pr->SiS_VDE = 768;
+- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
+- SiS_Pr->SiS_HDE = 1152;
+- SiS_Pr->SiS_VDE = 768;
+- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x864) {
+- SiS_Pr->SiS_HDE = 1152;
+- SiS_Pr->SiS_VDE = 864;
+- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
+- SiS_Pr->SiS_HDE = 1280;
+- SiS_Pr->SiS_VDE = 768;
+- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+- SiS_Pr->SiS_HDE = 1280;
+- SiS_Pr->SiS_VDE = 1024;
+- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+- SiS_Pr->SiS_HDE = 1400;
+- SiS_Pr->SiS_VDE = 1050;
+- } else {
+- SiS_Pr->SiS_HDE = 1600;
+- SiS_Pr->SiS_VDE = 1200;
+- }
+- if(SiS_Pr->SiS_IF_DEF_FSTN) {
+- SiS_Pr->SiS_HDE = 320;
+- SiS_Pr->SiS_VDE = 480;
+- }
+- }
++ if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
++ if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
++ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
++ if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
++ SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
++ SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
++
++ if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
++ if(ResIndex < 0x08) {
++ SiS_Pr->SiS_HDE = 1280;
++ SiS_Pr->SiS_VDE = 1024;
++ }
++ }
++#if 0
++ if(SiS_Pr->SiS_IF_DEF_FSTN) {
++ SiS_Pr->SiS_HDE = 320;
++ SiS_Pr->SiS_VDE = 480;
++ }
++#endif
++ }
++ }
+ }
+- }
+- }
++ }
+ }
+ }
+
+@@ -3413,11 +3515,16 @@
+ const SiS_TVDataStruct *TVPtr = NULL;
+
+ if(ModeNo <= 0x13) {
+- modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+- resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
++ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
++ resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+ } else {
++ if(SiS_Pr->UseCustomMode) {
++ modeflag = SiS_Pr->CModeFlag;
++ resinfo = 0;
++ } else {
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
++ }
+ }
+
+ SiS_Pr->SiS_NewFlickerMode = 0;
+@@ -3429,17 +3536,26 @@
+
+ SiS_GetCRT2ResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+
+- /* TW: For VGA2 ("RAMDAC2") */
+-
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
+- SiS_GetRAMDAC2DATA(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+- HwDeviceExtension);
+- return;
+- }
+
+- /* TW: For TV */
++ if(SiS_Pr->UseCustomMode) {
+
+- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
++ SiS_Pr->SiS_RVBHCMAX = 1;
++ SiS_Pr->SiS_RVBHCFACT = 1;
++ SiS_Pr->SiS_VGAHT = SiS_Pr->CHTotal;
++ SiS_Pr->SiS_VGAVT = SiS_Pr->CVTotal;
++ SiS_Pr->SiS_HT = SiS_Pr->CHTotal;
++ SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
++ SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
++ SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
++
++ } else {
++
++ SiS_GetRAMDAC2DATA(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
++ HwDeviceExtension);
++ }
++
++ } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+
+ SiS_GetCRT2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+ &CRT2Index,&ResIndex,HwDeviceExtension);
+@@ -3452,7 +3568,7 @@
+ case 4: TVPtr = SiS_Pr->SiS_ExtNTSCData; break;
+ case 8: TVPtr = SiS_Pr->SiS_StPALData; break;
+ case 9: TVPtr = SiS_Pr->SiS_StNTSCData; break;
+- default: TVPtr = SiS_Pr->SiS_StPALData; break; /* TW: Just to avoid a crash */
++ default: TVPtr = SiS_Pr->SiS_StPALData; break; /* Just to avoid a crash */
+ }
+
+ SiS_Pr->SiS_RVBHCMAX = (TVPtr+ResIndex)->RVBHCMAX;
+@@ -3464,18 +3580,16 @@
+ SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->RVBHRS;
+ SiS_Pr->SiS_NewFlickerMode = (TVPtr+ResIndex)->FlickerMode;
+ if(modeflag & HalfDCLK) {
+- SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
++ SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
+ }
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+
+ if(SiS_Pr->SiS_HiVision != 3) {
+-
+- if(resinfo == 0x08) SiS_Pr->SiS_NewFlickerMode = 0x40;
+- if(resinfo == 0x09) SiS_Pr->SiS_NewFlickerMode = 0x40;
+- if(resinfo == 0x12) SiS_Pr->SiS_NewFlickerMode = 0x40;
+-
+- }
++ if(resinfo == SIS_RI_1024x768) SiS_Pr->SiS_NewFlickerMode = 0x40;
++ if(resinfo == SIS_RI_1280x1024) SiS_Pr->SiS_NewFlickerMode = 0x40;
++ if(resinfo == SIS_RI_1280x720) SiS_Pr->SiS_NewFlickerMode = 0x40;
++ }
+
+ switch(SiS_Pr->SiS_HiVision) {
+ case 2:
+@@ -3504,119 +3618,136 @@
+
+ } else {
+
+- SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
+- SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
+- SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
+- SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
+-
+- if(modeflag & HalfDCLK) {
+- SiS_Pr->SiS_RY1COE = 0x00;
+- SiS_Pr->SiS_RY2COE = 0xf4;
+- SiS_Pr->SiS_RY3COE = 0x10;
+- SiS_Pr->SiS_RY4COE = 0x38;
+- }
+-
+- if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+- SiS_Pr->SiS_HT = NTSCHT;
+- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+- if((ModeNo == 0x4a) || (ModeNo == 0x38)) SiS_Pr->SiS_HT = NTSC2HT;
+- }
+- SiS_Pr->SiS_VT = NTSCVT;
+- } else {
+- SiS_Pr->SiS_HT = PALHT;
+- SiS_Pr->SiS_VT = PALVT;
+- }
++ SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
++ SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
++ SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
++ SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
++
++ if(modeflag & HalfDCLK) {
++ SiS_Pr->SiS_RY1COE = 0x00;
++ SiS_Pr->SiS_RY2COE = 0xf4;
++ SiS_Pr->SiS_RY3COE = 0x10;
++ SiS_Pr->SiS_RY4COE = 0x38;
++ }
++
++ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
++ SiS_Pr->SiS_HT = NTSCHT;
++ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
++ if((ModeNo == 0x64) || (ModeNo == 0x4a) || (ModeNo == 0x38)) SiS_Pr->SiS_HT = NTSC2HT;
++ }
++ SiS_Pr->SiS_VT = NTSCVT;
++ } else {
++ SiS_Pr->SiS_HT = PALHT;
++ SiS_Pr->SiS_VT = PALVT;
++ }
+
+ }
+
+- return;
+- }
++ } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+
+- /* TW: For LCD */
++ if(SiS_Pr->UseCustomMode) {
+
+- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
++ SiS_Pr->SiS_RVBHCMAX = 1;
++ SiS_Pr->SiS_RVBHCFACT = 1;
++ SiS_Pr->SiS_VGAHT = SiS_Pr->CHTotal;
++ SiS_Pr->SiS_VGAVT = SiS_Pr->CVTotal;
++ SiS_Pr->SiS_HT = SiS_Pr->CHTotal;
++ SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
++ SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
++ SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
+
+- SiS_GetCRT2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+- &CRT2Index,&ResIndex,HwDeviceExtension);
++ } else {
++
++ SiS_GetCRT2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
++ &CRT2Index,&ResIndex,HwDeviceExtension);
++
++ switch(CRT2Index) {
++ case 0: LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break; /* VESA Timing */
++ case 1: LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data; break; /* VESA Timing */
++ case 5: LCDPtr = SiS_Pr->SiS_StLCD1024x768Data; break; /* Obviously unused */
++ case 6: LCDPtr = SiS_Pr->SiS_StLCD1280x1024Data; break; /* Obviously unused */
++ case 10: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data; break; /* Non-VESA Timing */
++ case 11: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break; /* Non-VESA Timing */
++ case 13: LCDPtr = SiS_Pr->SiS_NoScaleData1024x768; break; /* Non-expanding */
++ case 14: LCDPtr = SiS_Pr->SiS_NoScaleData1280x1024; break; /* Non-expanding */
++ case 15: LCDPtr = SiS_Pr->SiS_LCD1280x960Data; break; /* 1280x960 */
++ case 20: LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data; break; /* VESA Timing */
++ case 21: LCDPtr = SiS_Pr->SiS_NoScaleData1400x1050; break; /* Non-expanding (let panel scale) */
++ case 22: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data; break; /* Non-VESA Timing (let panel scale) */
++ case 23: LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data; break; /* VESA Timing */
++ case 24: LCDPtr = SiS_Pr->SiS_NoScaleData1600x1200; break; /* Non-expanding */
++ case 25: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data; break; /* Non-VESA Timing */
++ case 26: LCDPtr = SiS_Pr->SiS_ExtLCD1280x768Data; break; /* VESA Timing */
++ case 27: LCDPtr = SiS_Pr->SiS_NoScaleData1280x768; break; /* Non-expanding */
++ case 28: LCDPtr = SiS_Pr->SiS_StLCD1280x768Data; break; /* Non-VESA Timing */
++ case 29: LCDPtr = SiS_Pr->SiS_NoScaleData; break; /* Generic no-scale data */
++#ifdef SIS315H
++ case 50: LCDPtr = (SiS_LCDDataStruct *)SiS310_ExtCompaq1280x1024Data; break;
++ case 51: LCDPtr = SiS_Pr->SiS_NoScaleData1280x1024; break;
++ case 52: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
++#endif
++ default: LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break; /* Just to avoid a crash */
++ }
++
++ SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX;
++ SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
++ SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT;
++ SiS_Pr->SiS_VGAVT = (LCDPtr+ResIndex)->VGAVT;
++ SiS_Pr->SiS_HT = (LCDPtr+ResIndex)->LCDHT;
++ SiS_Pr->SiS_VT = (LCDPtr+ResIndex)->LCDVT;
+
+- switch (CRT2Index) {
+- case 0: LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break; /* VESA Timing */
+- case 1: LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data; break; /* VESA Timing */
+- case 5: LCDPtr = SiS_Pr->SiS_StLCD1024x768Data; break; /* Obviously unused */
+- case 6: LCDPtr = SiS_Pr->SiS_StLCD1280x1024Data; break; /* Obviously unused */
+- case 10: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data; break; /* Non-VESA Timing */
+- case 11: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break; /* Non-VESA Timing */
+- case 13: LCDPtr = SiS_Pr->SiS_NoScaleData1024x768; break; /* Non-expanding */
+- case 14: LCDPtr = SiS_Pr->SiS_NoScaleData1280x1024; break; /* Non-expanding */
+- case 15: LCDPtr = SiS_Pr->SiS_LCD1280x960Data; break; /* 1280x960 */
+- case 20: LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data; break; /* VESA Timing */
+- case 21: LCDPtr = SiS_Pr->SiS_NoScaleData1400x1050; break; /* Non-expanding (let panel scale) */
+- case 22: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data; break; /* Non-VESA Timing (let panel scale) */
+- case 23: LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data; break; /* VESA Timing */
+- case 24: LCDPtr = SiS_Pr->SiS_NoScaleData1600x1200; break; /* Non-expanding */
+- case 25: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data; break; /* Non-VESA Timing */
+- default: LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break; /* Just to avoid a crash */
+- }
+-
+- SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX;
+- SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
+- SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT;
+- SiS_Pr->SiS_VGAVT = (LCDPtr+ResIndex)->VGAVT;
+- SiS_Pr->SiS_HT = (LCDPtr+ResIndex)->LCDHT;
+- SiS_Pr->SiS_VT = (LCDPtr+ResIndex)->LCDVT;
+-
+ #ifdef TWDEBUG
+- xf86DrvMsg(0, X_INFO,
+- "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
+-#endif
++ xf86DrvMsg(0, X_INFO,
++ "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
++#endif
+
+- tempax = 1024;
+- if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
+- if(HwDeviceExtension->jChipType < SIS_315H) {
+- if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
+- else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
+- else tempbx = 768;
+- } else {
+- tempbx = 768;
+- }
+- } else {
+- if (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
+- else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
+- else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
+- else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
+- else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
+- else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
+- else tempbx = 768;
+- }
+- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+- tempax = 1280;
+- if (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
+- else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
+- else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
+- else tempbx = 1024;
+- }
+- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
+- tempax = 1280;
+- if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 700;
+- else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 800;
+- else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
+- else tempbx = 960;
+- }
+- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+- tempax = 1400;
+- tempbx = 1050;
+- }
+- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+- tempax = 1600;
+- tempbx = 1200;
+- }
+- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+- tempax = SiS_Pr->SiS_VGAHDE;
+- tempbx = SiS_Pr->SiS_VGAVDE;
+- }
+- SiS_Pr->SiS_HDE = tempax;
+- SiS_Pr->SiS_VDE = tempbx;
+- return;
++ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
++ tempax = 1024;
++ if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
++ if(HwDeviceExtension->jChipType < SIS_315H) {
++ if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
++ else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
++ else tempbx = 768;
++ } else {
++ tempbx = 768;
++ }
++ } else {
++ if (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
++ else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
++ else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
++ else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
++ else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
++ else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
++ else tempbx = 768;
++ }
++ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
++ tempax = 1280;
++ if (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
++ else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
++ else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
++ else tempbx = 1024;
++ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
++ tempax = 1280;
++ if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 700;
++ else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 800;
++ else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
++ else tempbx = 960;
++ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
++ tempax = 1600;
++ if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 875;
++ else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 1000;
++ else tempbx = 1200;
++ } else {
++ tempax = SiS_Pr->PanelXRes;
++ tempbx = SiS_Pr->PanelYRes;
++ }
++ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
++ tempax = SiS_Pr->SiS_VGAHDE;
++ tempbx = SiS_Pr->SiS_VGAVDE;
++ }
++ SiS_Pr->SiS_HDE = tempax;
++ SiS_Pr->SiS_VDE = tempbx;
++ }
+ }
+ }
+
+@@ -3626,9 +3757,9 @@
+ USHORT resindex;
+
+ if(ModeNo <= 0x13)
+- resindex=SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
++ resindex=SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+ else
+- resindex=SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
++ resindex=SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+
+ return(resindex);
+ }
+@@ -3639,41 +3770,46 @@
+ {
+ USHORT xres,yres,modeflag=0,resindex;
+
++ if(SiS_Pr->UseCustomMode) {
++ SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = SiS_Pr->CHDisplay;
++ SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
++ return;
++ }
++
+ resindex = SiS_GetResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
+
+ if(ModeNo <= 0x13) {
+- xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
+- yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
++ xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
++ yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
+ } else {
+- xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
+- yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
+- modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++ xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
++ yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
++ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ }
+
+- if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
+- if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
+- if(yres == 350) yres = 400;
+- }
+- if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
+- if(ModeNo == 0x12) yres = 400;
+- }
+- }
++ if((!SiS_Pr->SiS_IF_DEF_DSTN) && (!SiS_Pr->SiS_IF_DEF_FSTN)) {
++
++ if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
++ if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
++ if(yres == 350) yres = 400;
++ }
++ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
++ if(ModeNo == 0x12) yres = 400;
++ }
++ }
++
++ if(ModeNo > 0x13) {
++ if(modeflag & HalfDCLK) xres *= 2;
++ if(modeflag & DoubleScanMode) yres *= 2;
++ }
+
+- if(ModeNo > 0x13) {
+- if(SiS_Pr->SiS_IF_DEF_FSTN == 1){
+- xres *= 2;
+- yres *= 2;
+- } else {
+- if(modeflag & HalfDCLK) xres *= 2;
+- if(modeflag & DoubleScanMode) yres *= 2;
+- }
+ }
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+ if(xres == 720) xres = 640;
+ } else {
+- if(SiS_Pr->SiS_VBType & VB_NoLCD) { /* TW: 301BDH */
++ if(SiS_Pr->SiS_VBType & VB_NoLCD) { /* 301BDH */
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ if(xres == 720) xres = 640;
+ }
+@@ -3694,17 +3830,16 @@
+ if(xres == 720) xres = 640;
+ }
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+- if(ModeNo <= 0x13) {
+- /* TW: This is wrong for 640x400 *graphics* mode */
++ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
++ if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
++ /* BIOS bug - does this regardless of scaling */
+ if(yres == 400) yres = 405;
+ }
+ if(yres == 350) yres = 360;
+ if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
+ if(yres == 360) yres = 375;
+ }
+- }
+- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768){
++ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+ if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
+ if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+ if(yres == 350) yres = 357;
+@@ -3719,12 +3854,15 @@
+ } else {
+ if(xres == 720) xres = 640;
+ if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
+- yres = 400;
+- if(HwDeviceExtension->jChipType >= SIS_315H) {
+- if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
+- } else {
+- if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
+- }
++ yres = 400;
++ if(HwDeviceExtension->jChipType >= SIS_315H) {
++ if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
++ } else {
++ if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
++ }
++ if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
++ yres = 480;
++ }
+ }
+ }
+ SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
+@@ -3739,6 +3877,13 @@
+ USHORT tempbx=0,tempal=0;
+ USHORT Flag,resinfo=0;
+
++ if(ModeNo <= 0x13) {
++ tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
++ } else {
++ tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
++ resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
++ }
++
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { /* LCD */
+@@ -3753,19 +3898,44 @@
+ tempbx = 23;
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx = 24;
+ else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 25;
++#if 0
++ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
++ tempbx = 26;
++ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx = 27;
++ else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 28;
++#endif
+ } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+- tempbx = 13;
+- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempbx++;
++ if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
++ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx = 13;
++ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempbx = 14;
++ else tempbx = 29;
++ } else {
++ tempbx = 29;
++ if(ModeNo >= 0x13) {
++ /* 1280x768 and 1280x960 have same CRT2CRTC,
++ * so we change it here if 1280x960 is chosen
++ */
++ if(resinfo == SIS_RI_1280x960) tempal = 10;
++ }
++ }
+ } else {
+ tempbx = SiS_Pr->SiS_LCDResInfo - SiS_Pr->SiS_Panel1024x768;
+ if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
+ tempbx += 5;
+ /* GetRevisionID(); */
+- /* TW: BIOS only adds 5 once */
++ /* BIOS only adds 5 once */
+ tempbx += 5;
+ }
+ }
+
++#ifdef SIS315H
++ if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
++ tempbx = 50;
++ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx = 51;
++ else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 52;
++ }
++#endif
++
+ } else { /* TV */
+
+ if((SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
+@@ -3773,7 +3943,7 @@
+ if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_SetFlag &= (~TVSimuMode);
+ tempbx = 2;
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+- if(!(SiS_Pr->SiS_SetFlag & TVSimuMode)) tempbx = 12;
++ if(!(SiS_Pr->SiS_SetFlag & TVSimuMode)) tempbx = 12;
+ }
+ } else {
+ if(SiS_Pr->SiS_VBInfo & SetPALTV) tempbx = 3;
+@@ -3783,34 +3953,18 @@
+
+ }
+
+- if(ModeNo <= 0x13) {
+- tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+- } else {
+- tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+- resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+- }
+-
+- tempal &= 0x3F;
+-
+- if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
+- (SiS_Pr->SiS_VBInfo & (SetCRT2ToTV-SetCRT2ToHiVisionTV))) {
+- if(tempal == 0x06) tempal = 0x07;
+- }
+-
+- /* TW: 300/301LV BIOS */
+- if((HwDeviceExtension->jChipType == SIS_300) &&
+- (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
+- if(ModeNo > 0x13) {
+- if((resinfo == 0x0c) || (resinfo == 0x0d)) /* 720 (index diff. on 310/325!) */
+- tempal = 6;
+- }
+- }
++ tempal &= 0x3F;
+
+- if(HwDeviceExtension->jChipType != SIS_300) {
+- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+- if((ModeNo == 0x31) || (ModeNo == 0x32)) tempal = 6;
++ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) {
++ if(ModeNo > 0x13) {
++ if(tempal == 6) tempal = 7;
++ if((resinfo == SIS_RI_720x480) ||
++ (resinfo == SIS_RI_720x576) ||
++ (resinfo == SIS_RI_768x576)) {
++ tempal = 6;
++ }
+ }
+- }
++ }
+
+ *CRT2Index = tempbx;
+ *ResIndex = tempal;
+@@ -3820,25 +3974,22 @@
+ Flag = 1;
+ tempbx = 0;
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+-
+- if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+- Flag = 0;
+- tempbx = 10;
+- if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+- if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+- tempbx += 2;
+- if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
+- if(SiS_Pr->SiS_CHPALM) {
+- tempbx = 90;
+- if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+- } else if(SiS_Pr->SiS_CHPALN) {
+- tempbx = 92;
+- if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+- }
+-
+- }
+- }
+-
++ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
++ Flag = 0;
++ tempbx = 10;
++ if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
++ if(SiS_Pr->SiS_VBInfo & SetPALTV) {
++ tempbx += 2;
++ if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
++ if(SiS_Pr->SiS_CHPALM) {
++ tempbx = 90;
++ if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
++ } else if(SiS_Pr->SiS_CHPALN) {
++ tempbx = 92;
++ if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
++ }
++ }
++ }
+ }
+
+ if(Flag) {
+@@ -3846,11 +3997,19 @@
+ if(SiS_Pr->SiS_LCDResInfo <= SiS_Pr->SiS_Panel1280x1024) {
+ tempbx = SiS_Pr->SiS_LCDResInfo - SiS_Pr->SiS_PanelMinLVDS;
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
++ if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
++ tempbx = 82;
++ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
++ }
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
+ tempbx = 18;
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
+- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
++ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
+ tempbx = 6;
++ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2) {
++ tempbx = 30;
++ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) {
++ tempbx = 30;
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
+ tempbx = 15;
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
+@@ -3863,27 +4022,30 @@
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+ tempbx = 21;
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
++ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelBarco1366) {
++ tempbx = 80;
++ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
+ }
+-
++
+ if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+ tempbx = 7;
+ }
+-
+- }
+
+- if(ModeNo <= 0x13)
+- tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+- else {
+- tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+- resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
++ if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
++ tempbx = 84;
++ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
++ }
++
+ }
+
++#if 0
+ if(SiS_Pr->SiS_IF_DEF_FSTN){
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){
+ tempbx = 14;
+ tempal = 6;
+ }
+ }
++#endif
+
+ if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) tempal = 7;
+@@ -3895,13 +4057,10 @@
+
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(ModeNo > 0x13) {
+- if(HwDeviceExtension->jChipType < SIS_315H) {
+- if((resinfo == 0x0c) || (resinfo == 0x0d)) /* 720 */
+- tempal = 6;
+- } else {
+- if((resinfo == 0x0d) || (resinfo == 0x0e)) /* 720 */
+- tempal = 6;
+- }
++ if((resinfo == SIS_RI_720x480) ||
++ (resinfo == SIS_RI_720x576) ||
++ (resinfo == SIS_RI_768x576))
++ tempal = 6;
+ }
+ }
+
+@@ -3940,7 +4099,7 @@
+ void
+ SiS_GetCRT2Part2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,USHORT *CRT2Index,
+- USHORT *ResIndex)
++ USHORT *ResIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+ {
+ USHORT tempbx,tempal;
+
+@@ -3954,6 +4113,16 @@
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 16;
+ else if(SiS_Pr->SiS_SetFlag & LCDVESATiming) tempbx += 32;
+
++#ifdef SIS315H
++ if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
++ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
++ tempbx = 100;
++ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx = 101;
++ else if(SiS_Pr->SiS_SetFlag & LCDVESATiming) tempbx = 102;
++ }
++ }
++#endif
++
+ *CRT2Index = tempbx;
+ *ResIndex = tempal & 0x3F;
+ }
+@@ -3962,15 +4131,17 @@
+ SiS_GetRatePtrCRT2(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension)
+ {
+- SHORT LCDRefreshIndex[] = { 0x00, 0x00, 0x03, 0x01,
++ SHORT LCDRefreshIndex[] = { 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01,
+- 0x01, 0x01, 0x01, 0x01 };
++ 0x01, 0x01, 0x01, 0x01,
++ 0x00, 0x00, 0x00, 0x00 };
+ USHORT RefreshRateTableIndex,i,backup_i;
+ USHORT modeflag,index,temp,backupindex;
+
+- if(SiS_Pr->UseCustomMode) return 0;
+-
++ /* Do NOT check for UseCustomMode here, will skrew up FIFO */
++ if(ModeNo == 0xfe) return 0;
++
+ if(ModeNo <= 0x13)
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ else
+@@ -3984,7 +4155,7 @@
+
+ if(ModeNo < 0x14) return(0xFFFF);
+
+- /* TW: CR33 holds refresh rate index for CRT1 [3:0] and CRT2 [7:4].
++ /* CR33 holds refresh rate index for CRT1 [3:0] and CRT2 [7:4].
+ * On LVDS machines, CRT2 index is always 0 and will be
+ * set to 0 by the following code; this causes the function
+ * to take the first non-interlaced mode in SiS_Ext2Struct
+@@ -3998,40 +4169,38 @@
+ if(index > 0) index--;
+
+ if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
+- if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
++ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
+- } else {
++ } else {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+- if(SiS_Pr->SiS_VBType & VB_NoLCD)
+- index = 0;
+- else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)
+- index = backupindex = 0;
++ if(SiS_Pr->SiS_VBType & VB_NoLCD)
++ index = 0;
++ else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)
++ index = backupindex = 0;
+ }
+- }
+- }
++ }
+
+- if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
+- if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+- index = 0;
+- }
+- }
+- if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+- if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+- if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
+- temp = LCDRefreshIndex[SiS_Pr->SiS_LCDResInfo];
+- if(index > temp) index = temp;
+- }
+- } else {
+- index = 0;
+- }
+- }
++ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
++ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
++ index = 0;
++ }
++ }
++ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
++ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
++ if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
++ temp = LCDRefreshIndex[SiS_Pr->SiS_LCDResInfo];
++ if(index > temp) index = temp;
++ }
++ } else {
++ index = 0;
++ }
++ }
+ }
+
+ RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
+ ModeNo = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].ModeID;
+
+- /* TW: 650/LVDS 1.10.07, 650/30xLV 1.10.6s */
++ /* 650/LVDS 1.10.07, 650/30xLV 1.10.6s */
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
+ if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
+@@ -4066,7 +4235,7 @@
+ backup_i = i;
+ if (!(SiS_AdjustCRT2Rate(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+ RefreshRateTableIndex,&i,HwDeviceExtension))) {
+- /* TW: This is for avoiding random data to be used; i is
++ /* This is for avoiding random data to be used; i is
+ * in an undefined state if no matching CRT2 mode is
+ * found.
+ */
+@@ -4085,196 +4254,199 @@
+ USHORT tempax,tempbx,resinfo;
+ USHORT modeflag,infoflag;
+
+- if (ModeNo <= 0x13)
++ if(ModeNo <= 0x13) {
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+- else
++ resinfo = 0;
++ } else {
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++ resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
++ }
+
+- resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ tempbx = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID;
+
+ tempax = 0;
++
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
++
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
+ tempax |= SupportRAMDAC2;
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+- tempax |= SupportTV;
+- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+- if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+- if(resinfo == 0x0a) tempax |= SupportTV1024;
+- }
+- }
++ tempax |= SupportTV;
++ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
++ if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
++ if(resinfo == SIS_RI_1600x1200) tempax |= SupportTV1024;
++ }
++ }
+ }
+- }
+- if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
++ } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ tempax |= SupportLCD;
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) {
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) {
+- if((resinfo == 6) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
++ if((resinfo == SIS_RI_640x480) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+ (*i) = 0;
+ return(1);
+ } else {
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) {
+- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) {
+- if((resinfo == 6) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+- return(0);
+- } else {
+- if((resinfo >= 9) && (resinfo != 0x14)) {
++ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) {
++ if((resinfo == SIS_RI_640x480) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
++ return(0);
++ } else {
++ if((resinfo >= SIS_RI_1280x1024) && (resinfo != SIS_RI_1280x768)) {
+ return(0);
+- }
+- }
+- }
++ }
++ }
++ }
+ }
+ }
+ }
+ }
+ } else {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
+- if((resinfo != 0x0f) && ((resinfo == 4) || (resinfo >= 8))) return(0);
++ if( (resinfo != SIS_RI_1024x600) &&
++ ((resinfo == SIS_RI_512x384) || (resinfo >= SIS_RI_1024x768))) return(0);
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
+- if((resinfo != 0x10) && (resinfo > 8)) return(0);
++ if((resinfo != SIS_RI_1152x768) && (resinfo > SIS_RI_1024x768)) return(0);
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
+- if((resinfo != 0x0e) && (resinfo > 8)) return(0);
++ if((resinfo != SIS_RI_1280x960) && (resinfo > SIS_RI_1024x768)) return(0);
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+- if(resinfo > 9) return(0);
++ if(resinfo > SIS_RI_1280x1024) return(0);
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+- if(resinfo > 8) return(0);
++ if(resinfo > SIS_RI_1024x768) return(0);
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
+- if((resinfo == 4) || (resinfo > 7)) return(0);
++ if((resinfo == SIS_RI_512x384) || (resinfo > SIS_RI_800x600)) return(0);
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
+- if((resinfo == 4) || (resinfo == 3) || (resinfo > 6)) return(0);
++ if((resinfo == SIS_RI_512x384) ||
++ (resinfo == SIS_RI_400x300) ||
++ (resinfo > SIS_RI_640x480)) return(0);
+ }
+ }
+- }
+- if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
++ } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+ if(SiS_Pr->SiS_HiVision == 3) {
+ tempax |= SupportHiVisionTV2;
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode){
+- if(resinfo == 4) return(0);
+- if(resinfo == 3) return(0);
+- if(resinfo == 7) {
++ if(resinfo == SIS_RI_512x384) return(0);
++ if(resinfo == SIS_RI_400x300) return(0);
++ if(resinfo == SIS_RI_800x600) {
+ if(SiS_Pr->SiS_SetFlag & TVSimuMode) return(0);
+ }
+- if(resinfo > 7) return(0);
++ if(resinfo > SIS_RI_800x600) return(0);
+ }
+ } else {
+ tempax |= SupportHiVisionTV;
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode){
+- if(resinfo == 4) return(0);
+- if((resinfo == 3) || (resinfo == 7)) {
++ if(resinfo == SIS_RI_512x384) return(0);
++ if((resinfo == SIS_RI_400x300) || (resinfo == SIS_RI_800x600)) {
+ if(SiS_Pr->SiS_SetFlag & TVSimuMode) return(0);
+ }
+- if(resinfo > 7) return(0);
++ if(resinfo > SIS_RI_800x600) return(0);
+ }
+ }
+- } else {
+- if(SiS_Pr->SiS_VBInfo & (SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
++ } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
+ tempax |= SupportTV;
+ tempax |= SupportTV1024;
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+- if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+- if((SiS_Pr->SiS_VBInfo & SetNotSimuMode) && (SiS_Pr->SiS_VBInfo & SetPALTV)) {
+- if(resinfo != 8) {
+- if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+- ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 4)) ) {
+- tempax &= ~(SupportTV1024);
+- if(HwDeviceExtension->jChipType >= SIS_315H) {
+- if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+- if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+- ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 7)) ) {
+- if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
+- }
+- }
+- } else {
+- if( (resinfo != 3) ||
+- (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+- (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
+- if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+- if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+- if(resinfo == 3) return(0);
+- if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
+- }
+- }
+- } else return(0);
+- }
+- }
+- }
+- } else {
+- tempax &= ~(SupportTV1024);
+- if(HwDeviceExtension->jChipType >= SIS_315H) {
+- if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+- if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+- ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 7)) ) {
++ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
++ if((SiS_Pr->SiS_VBInfo & SetNotSimuMode) && (SiS_Pr->SiS_VBInfo & SetPALTV)) {
++ if(resinfo != SIS_RI_1024x768) {
++ if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
++ ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_512x384)) ) {
++ tempax &= ~(SupportTV1024);
++ if(HwDeviceExtension->jChipType >= SIS_315H) {
++ if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
++ if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
++ ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_800x600)) ) {
+ if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
+- }
+- }
+- } else {
+- if( (resinfo != 3) ||
+- (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+- (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
+- if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+- if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+- if(resinfo == 3) return(0);
+- if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
+- }
+ }
+- } else return(0);
+- }
+- }
+- } else { /* slavemode */
+- if(resinfo != 8) {
+- if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+- ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 4) ) ) {
+- tempax &= ~(SupportTV1024);
+- if(HwDeviceExtension->jChipType >= SIS_315H) {
+- if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+- if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+- ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 7)) ) {
+- if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
+- }
++ }
++ } else {
++ if( (resinfo != SIS_RI_400x300) ||
++ (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
++ (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
++ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
++ if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
++ if(resinfo == SIS_RI_400x300) return(0);
++ if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
++ }
+ }
+- } else {
+- if( (resinfo != 3) ||
+- (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+- (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
+- if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+- if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+- if(resinfo == 3) return(0);
+- if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
+- }
+- }
+- } else return(0);
+- }
++ } else return(0);
++ }
+ }
+- }
+- }
+- } else { /* 301 */
+- tempax &= ~(SupportTV1024);
+- if(HwDeviceExtension->jChipType >= SIS_315H) {
+- if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+- if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+- ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 7)) ) {
+- if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
+- }
+- }
+- } else {
+- if( (resinfo != 3) ||
+- (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+- (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
+- if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+- if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+- if(resinfo == 3) return(0);
+- if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
+- }
++ }
++ } else {
++ tempax &= ~(SupportTV1024);
++ if(HwDeviceExtension->jChipType >= SIS_315H) {
++ if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
++ if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
++ ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_800x600)) ) {
++ if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
++ }
+ }
+- } else return(0);
+- }
+- }
+- }
+- }
+-
+- } else { /* TW: for LVDS */
++ } else {
++ if( (resinfo != SIS_RI_400x300) ||
++ (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
++ (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
++ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
++ if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
++ if(resinfo == SIS_RI_400x300) return(0);
++ if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
++ }
++ }
++ } else return(0);
++ }
++ }
++ } else { /* slavemode */
++ if(resinfo != SIS_RI_1024x768) {
++ if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
++ ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_512x384) ) ) {
++ tempax &= ~(SupportTV1024);
++ if(HwDeviceExtension->jChipType >= SIS_315H) {
++ if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
++ if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
++ ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_800x600)) ) {
++ if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
++ }
++ }
++ } else {
++ if( (resinfo != SIS_RI_400x300) ||
++ (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
++ (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
++ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
++ if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
++ if(resinfo == SIS_RI_400x300) return(0);
++ if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
++ }
++ }
++ } else return(0);
++ }
++ }
++ }
++ }
++ } else { /* 301 */
++ tempax &= ~(SupportTV1024);
++ if(HwDeviceExtension->jChipType >= SIS_315H) {
++ if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
++ if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
++ ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_800x600)) ) {
++ if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
++ }
++ }
++ } else {
++ if( (resinfo != SIS_RI_400x300) ||
++ (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
++ (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
++ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
++ if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
++ if(resinfo == SIS_RI_400x300) return(0);
++ if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
++ }
++ }
++ } else return(0);
++ }
++ }
++ }
++
++ } else { /* for LVDS */
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+@@ -4284,24 +4456,33 @@
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ tempax |= SupportLCD;
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
+- if((resinfo != 0x14) && (resinfo > 0x09)) return(0);
++ if((resinfo != SIS_RI_1280x768) && (resinfo >= SIS_RI_1280x1024)) return(0);
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
+- if((resinfo != 0x0f) && (resinfo > 0x08)) return(0);
++ if((resinfo != SIS_RI_1024x600) && (resinfo >= SIS_RI_1024x768)) return(0);
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
+- if((resinfo != 0x10) && (resinfo > 0x08)) return(0);
++ if((resinfo != SIS_RI_1152x768) && (resinfo > SIS_RI_1024x768)) return(0);
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+- if((resinfo != 0x15) && (resinfo > 0x09)) return(0);
++ if((resinfo != SIS_RI_1400x1050) && (resinfo > SIS_RI_1280x1024)) return(0);
++ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
++ if(resinfo > SIS_RI_1600x1200) return(0);
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+- if(resinfo > 0x09) return(0);
++ if(resinfo > SIS_RI_1280x1024) return(0);
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+- if(resinfo > 0x08) return(0);
++ if(resinfo > SIS_RI_1024x768) return(0);
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600){
+- if(resinfo > 0x07) return(0);
+- if(resinfo == 0x04) return(0);
++ if(resinfo > SIS_RI_800x600) return(0);
++ if(resinfo == SIS_RI_512x384) return(0);
++ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelBarco1366) {
++ if((resinfo != SIS_RI_1360x1024) && (resinfo > SIS_RI_1280x1024)) return(0);
++ } else if(SiS_Pr->SiS_LCDResInfo == Panel_848x480) {
++ if((resinfo != SIS_RI_1360x768) &&
++ (resinfo != SIS_RI_848x480) &&
++ (resinfo > SIS_RI_1024x768)) return(0);
+ }
+ }
+ }
+- /* TW: Look backwards in table for matching CRT2 mode */
++
++ /* Look backwards in table for matching CRT2 mode */
+ for(; SiS_Pr->SiS_RefIndex[RefreshRateTableIndex+(*i)].ModeID == tempbx; (*i)--) {
+ infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
+ if(infoflag & tempax) {
+@@ -4309,7 +4490,7 @@
+ }
+ if ((*i) == 0) break;
+ }
+- /* TW: Look through the whole mode-section of the table from the beginning
++ /* Look through the whole mode-section of the table from the beginning
+ * for a matching CRT2 mode if no mode was found yet.
+ */
+ for((*i) = 0; ; (*i)++) {
+@@ -4329,7 +4510,7 @@
+ {
+ USHORT temp1,temp2;
+
+- /* TW: We store CRT1 ModeNo in CR34 */
++ /* We store CRT1 ModeNo in CR34 */
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x34,ModeNo);
+ temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
+ temp2 = ~(SetInSlaveMode >> 8);
+@@ -4345,16 +4526,16 @@
+ USHORT modeflag, resinfo=0;
+ UCHAR OutputSelect = *SiS_Pr->pSiS_OutputSelect;
+
+- if(SiS_Pr->UseCustomMode) {
+- modeflag = SiS_Pr->CModeFlag;
++ if(ModeNo <= 0x13) {
++ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ } else {
+- if (ModeNo <= 0x13)
+- modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+- else {
++ if(SiS_Pr->UseCustomMode) {
++ modeflag = SiS_Pr->CModeFlag;
++ } else {
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+- }
+- }
++ }
++ }
+
+ SiS_Pr->SiS_SetFlag = 0;
+
+@@ -4364,22 +4545,24 @@
+ if(SiS_BridgeIsOn(SiS_Pr,BaseAddr,HwDeviceExtension) == 0) {
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+ #if 0
+- /* SiS_HiVision is only used on 310/325/330+30xLV */
++ /* SiS_HiVision is only used on 315/330+30xLV */
+ if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV)) {
+- if(SiS_Pr->SiS_HiVision & 0x03) { /* TW: New from 650/30xLV 1.10.6s */
++ if(SiS_Pr->SiS_HiVision & 0x03) { /* New from 650/30xLV 1.10.6s */
+ temp &= (SetCRT2ToHiVisionTV | SwitchToCRT2 | SetSimuScanMode); /* 0x83 */
+ temp |= SetCRT2ToHiVisionTV; /* 0x80 */
+ }
+- if(SiS_Pr->SiS_HiVision & 0x04) { /* TW: New from 650/30xLV 1.10.6s */
++ if(SiS_Pr->SiS_HiVision & 0x04) { /* New from 650/30xLV 1.10.6s */
+ temp &= (SetCRT2ToHiVisionTV | SwitchToCRT2 | SetSimuScanMode); /* 0x83 */
+ temp |= SetCRT2ToSVIDEO; /* 0x08 */
+ }
+ }
+-#endif
++#endif
++#if 0
+ if(SiS_Pr->SiS_IF_DEF_FSTN) { /* fstn must set CR30=0x21 */
+ temp = (SetCRT2ToLCD | SetSimuScanMode);
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x30,temp);
+ }
++#endif
+ tempbx |= temp;
+ tempax = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) << 8;
+ tempax &= (LoadDACFlag | DriverMode | SetDispDevSwitch | SetNotSimuMode | SetPALTV);
+@@ -4519,7 +4702,7 @@
+ tempbx |= SetSimuScanMode;
+ }
+
+- /* TW: LVDS (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
++ /* LVDS (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
+ if(SiS_Pr->SiS_ModeType <= ModeVGA) {
+ if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
+ ((tempbx & SetCRT2ToLCD) && (SiS_Pr->SiS_VBType & VB_NoLCD)) ) {
+@@ -4527,12 +4710,12 @@
+ }
+ }
+
+- if(!(tempbx & SetSimuScanMode)){
++ if(!(tempbx & SetSimuScanMode)) {
+ if(tempbx & SwitchToCRT2) {
+ if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
+ if( (HwDeviceExtension->jChipType >= SIS_315H) &&
+ (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
+- if(resinfo != 0x0a)
++ if(resinfo != SIS_RI_1600x1200)
+ tempbx |= SetSimuScanMode;
+ } else {
+ tempbx |= SetSimuScanMode;
+@@ -4555,7 +4738,7 @@
+ if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
+ if( (HwDeviceExtension->jChipType >= SIS_315H) &&
+ (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
+- if(resinfo != 0x0a) { /* TW: 650/301 BIOS */
++ if(resinfo != SIS_RI_1600x1200) { /* 650/301 BIOS */
+ tempbx |= SetInSlaveMode;
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ if(tempbx & SetCRT2ToTV) {
+@@ -4563,7 +4746,7 @@
+ SiS_Pr->SiS_SetFlag |= TVSimuMode;
+ }
+ }
+- } /* TW: 650/301 BIOS */
++ } /* 650/301 BIOS */
+ } else {
+ tempbx |= SetInSlaveMode;
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+@@ -4621,7 +4804,7 @@
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(ROMAddr && SiS_Pr->SiS_UseROM) {
+ OutputSelect = ROMAddr[0xf3];
+- if(HwDeviceExtension->jChipType == SIS_330) {
++ if(HwDeviceExtension->jChipType >= SIS_330) {
+ OutputSelect = ROMAddr[0x11b];
+ }
+ }
+@@ -4652,7 +4835,7 @@
+ SiS_Pr->SiS_VBInfo = tempbx;
+
+ if(HwDeviceExtension->jChipType == SIS_630) {
+- SiS_WhatIsThis(SiS_Pr, SiS_Pr->SiS_VBInfo);
++ SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
+ }
+
+ #ifdef TWDEBUG
+@@ -4666,61 +4849,35 @@
+ #endif
+ #endif
+
+-#if 0 /* TW: Incomplete! (But does not seem to be required) */
+- if(HwDeviceExtension->jChipType < SIS_315H) {
+- /* TW: From A901/630+301B BIOS */
+- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+- if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80)
+- }
+- if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+- if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80)
+- if( [si] == 3) ModeIdIndex = 0x3f2b;
+- }
+- }
+- SiS_SetRegAND(SiS_Pr->SiS_P3d4, 0x31, 0xF7);
+- if(ModeNo == 0x13) bp+4 = 0x03;
+- } else {
+- /* From 650/30xLV BIOS: */
+- SiS_SetRegAND(SiS_Pr->SiS_P3d4, 0x31, 0xF7);
+- if(ModeNo == 0x13) bp+4 = 0x03;
+- else bp+4 = ModeNo;
+- }
+-#endif
+-
+- /* TW: 630/301B and 650/301 (not 301LV!) BIOSes do more here, but this seems for DOS mode */
+-
+ }
+
++/* Setup general purpose IO for Chrontel communication */
+ void
+-SiS_WhatIsThis(SiS_Private *SiS_Pr, USHORT myvbinfo)
++SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo)
+ {
+- unsigned long eax, temp;
+- unsigned short temp1;
++ unsigned long acpibase;
++ unsigned short temp;
+
+ if(!(SiS_Pr->SiS_ChSW)) return;
+
+ #ifndef LINUX_XF86
+- SiS_SetReg4(0xcf8,0x80000874);
+- eax = SiS_GetReg3(0xcfc);
++ SiS_SetReg4(0xcf8,0x80000874); /* get ACPI base */
++ acpibase = SiS_GetReg3(0xcfc);
+ #else
+- eax = pciReadLong(0x00000800, 0x74);
++ acpibase = pciReadLong(0x00000800, 0x74);
+ #endif
+- eax &= 0xFFFF;
+- temp = eax;
+- eax += 0x3c;
+- temp1 = SiS_GetReg4((USHORT)eax);
+- temp1 &= 0xFEFF;
+- SiS_SetReg5((USHORT)eax, temp1);
+- temp1 = SiS_GetReg4((USHORT)eax);
+- eax = temp;
+- eax += 0x3a;
+- temp1 = SiS_GetReg4((USHORT)eax);
+- temp1 &= 0xFEFF;
++ acpibase &= 0xFFFF;
++ temp = SiS_GetReg4((USHORT)(acpibase + 0x3c)); /* ACPI register 0x3c: GP Event 1 I/O mode select */
++ temp &= 0xFEFF;
++ SiS_SetReg5((USHORT)(acpibase + 0x3c), temp);
++ temp = SiS_GetReg4((USHORT)(acpibase + 0x3c));
++ temp = SiS_GetReg4((USHORT)(acpibase + 0x3a)); /* ACPI register 0x3a: GP Pin Level (low/high) */
++ temp &= 0xFEFF;
+ if(!(myvbinfo & SetCRT2ToTV)) {
+- temp1 |= 0x0100;
++ temp |= 0x0100;
+ }
+- SiS_SetReg5((USHORT)eax, temp1);
+- temp1 = SiS_GetReg4((USHORT)eax);
++ SiS_SetReg5((USHORT)(acpibase + 0x3a), temp);
++ temp = SiS_GetReg4((USHORT)(acpibase + 0x3a));
+ }
+
+ void
+@@ -4731,14 +4888,14 @@
+ USHORT temp1=0,modeflag=0,tempcx=0;
+ USHORT StandTableIndex,CRT1Index;
+ #ifdef SIS315H
+- USHORT ResInfo,DisplayType,temp=0;
++ USHORT ResIndex,DisplayType,temp=0;
+ const SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr = NULL;
+ #endif
+
+ SiS_Pr->SiS_RVBHCMAX = 1;
+ SiS_Pr->SiS_RVBHCFACT = 1;
+
+- if(ModeNo <= 0x13){
++ if(ModeNo <= 0x13) {
+
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ StandTableIndex = SiS_GetModePtr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
+@@ -4752,7 +4909,7 @@
+
+ #ifdef SIS315H
+ temp = SiS_GetLVDSCRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+- RefreshRateTableIndex,&ResInfo,&DisplayType);
++ RefreshRateTableIndex,&ResIndex,&DisplayType);
+
+ if(temp == 0) return;
+
+@@ -4795,16 +4952,16 @@
+ case 99: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break;
+ default: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1; break;
+ }
+- tempax = (LVDSCRT1Ptr+ResInfo)->CR[0];
+- tempax |= (LVDSCRT1Ptr+ResInfo)->CR[14] << 8;
++ tempax = (LVDSCRT1Ptr+ResIndex)->CR[0];
++ tempax |= (LVDSCRT1Ptr+ResIndex)->CR[14] << 8;
+ tempax &= 0x03FF;
+- tempbx = (LVDSCRT1Ptr+ResInfo)->CR[6];
+- tempcx = (LVDSCRT1Ptr+ResInfo)->CR[13] << 8;
++ tempbx = (LVDSCRT1Ptr+ResIndex)->CR[6];
++ tempcx = (LVDSCRT1Ptr+ResIndex)->CR[13] << 8;
+ tempcx &= 0x0100;
+ tempcx <<= 2;
+ tempbx |= tempcx;
+- temp1 = (LVDSCRT1Ptr+ResInfo)->CR[7];
+-#endif
++ temp1 = (LVDSCRT1Ptr+ResIndex)->CR[7];
++#endif
+
+ } else {
+
+@@ -4840,11 +4997,12 @@
+ if(modeflag & Charx8Dot) tempax *= 8;
+ else tempax *= 9;
+
+- /* TW: From 650/30xLV 1.10.6s */
++ /* From 650/30xLV 1.10.6s */
+ if(modeflag & HalfDCLK) tempax <<= 1;
+
+- SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
+ tempbx++;
++
++ SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
+ SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
+ }
+
+@@ -4852,18 +5010,18 @@
+ SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
+ {
+ if(HwDeviceExtension->jChipType >= SIS_315H)
+- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
++ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
+ else
+- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
++ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
+ }
+
+ void
+ SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
+ {
+ if(HwDeviceExtension->jChipType >= SIS_315H)
+- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
++ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
+ else
+- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
++ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
+ }
+
+ void
+@@ -4872,7 +5030,6 @@
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
+ }
+
+-/* Checked against all BIOSes */
+ void
+ SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
+ {
+@@ -4882,9 +5039,9 @@
+ USHORT temp=0;
+ UCHAR *ROMAddr = HwDeviceExtension->pjVirtualRomBase;
+
+- if (SiS_Pr->SiS_IF_DEF_LVDS == 0) {
++ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+
+- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* ===== TW: For 30xB/LV ===== */
++ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* ===== For 30xB/LV ===== */
+
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+
+@@ -4940,9 +5097,9 @@
+
+ } else {
+
+-#ifdef SIS315H /* 310/325 series */
++#ifdef SIS315H /* 315 series */
+
+- if(IS_SIS650740) { /* 650, 740 */
++ if(IS_SIS550650740660) { /* 550, 650, 740, 660 */
+
+ #if 0
+ if(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00) != 1) return; /* From 1.10.7w */
+@@ -4950,40 +5107,67 @@
+
+ modenum = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x34);
+
+- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
++ if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { /* LV */
+
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
+
+ if( (modenum <= 0x13) ||
+ (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) ||
+ (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ) {
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00);
++ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
++ if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
++ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
++ }
+ }
+- SiS_DDC2Delay(SiS_Pr,0xff00);
+- SiS_DDC2Delay(SiS_Pr,0x6000);
+- SiS_DDC2Delay(SiS_Pr,0x8000);
+
+- SiS_SetReg3(SiS_Pr->SiS_P3c6,0x00);
++ if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
++ SiS_DDC2Delay(SiS_Pr,0xff00);
++ SiS_DDC2Delay(SiS_Pr,0x6000);
++ SiS_DDC2Delay(SiS_Pr,0x8000);
+
+- pushax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06);
+-
+- if(IS_SIS740) {
+- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
++ SiS_SetReg3(SiS_Pr->SiS_P3c6,0x00);
++
++ pushax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06);
++
++ if(IS_SIS740) {
++ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
++ }
++
++ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
++
++ if(!(IS_SIS740)) {
++ if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
++ tempah = 0xef;
++ if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
++ tempah = 0xf7;
++ }
++ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
++ }
++ }
+ }
+
+- SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+-
+- if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+- tempah = 0xef;
+- if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+- tempah = 0xf7;
+- }
+- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
+- }
++ } else if(SiS_Pr->SiS_VBType & VB_NoLCD) { /* B-DH */
++ /* This is actually bullshit. The B-DH bridge has cetainly no
++ * Part4 Index 26, since it has no ability to drive LCD panels
++ * at all. But as the BIOS does it, we do it, too...
++ */
++ if(HwDeviceExtension->jChipType == SIS_650) {
++ if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
++ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,0xef);
++ }
++ if((!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) ||
++ (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ) {
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00);
++ }
++ SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 3);
++ }
++ }
+
+- }
++ if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
++ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,0xef);
++ }
+
+- if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
++ if((SiS_Pr->SiS_VBType & VB_SIS301B302B) || (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280)) {
+ tempah = 0x3f;
+ if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ tempah = 0x7f;
+@@ -4997,7 +5181,7 @@
+ if((SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
+ ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) {
+
+- if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
++ if((SiS_Pr->SiS_VBType & VB_SIS301B302B) || (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280)) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
+ SiS_DisplayOff(SiS_Pr);
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+@@ -5020,7 +5204,7 @@
+
+ } else {
+
+- if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
++ if((SiS_Pr->SiS_VBType & VB_SIS301B302B) || (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280)) {
+ if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
+ SiS_DisplayOff(SiS_Pr);
+@@ -5044,10 +5228,10 @@
+
+ }
+
+- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
++ if((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (SiS_Pr->SiS_CustomT != CUT_COMPAQ1280)) {
++
++ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,~0x10); /* 1.10.8r, 8m */
+
+- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,~0x10); /* 1.10.8r */
+-
+ tempah = 0x3f;
+ if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ tempah = 0x7f;
+@@ -5057,9 +5241,9 @@
+ }
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
+
+- if(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr)) { /* 1.10.8r */
++ if(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr)) { /* 1.10.8r, 8m */
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
+- } /* 1.10.8r */
++ } /* 1.10.8r, 8m */
+
+ if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
+@@ -5075,80 +5259,47 @@
+
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax);
+
+- }
++ } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
+
+-#if 0
+- } else if(IS_SIS740) { /* 740 */
+-
+- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { /* 30xLV */
+-
+- if( (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) ||
+- (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ) {
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00);
+- }
+-
+- SiS_SetReg3(SiS_Pr->SiS_P3c6,0x00);
++ if(HwDeviceExtension->jChipType == SIS_650) {
++ if((SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
++ (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)))) {
++ if((!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) ||
++ (!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)))) {
++ SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 2);
++ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
++ SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 4);
++ }
++ }
++ }
+
+- pushax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06);
+-
+- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
++ } else if((SiS_Pr->SiS_VBType & VB_SIS301B302B) || (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280)) {
+
+- SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+-
+- if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+- SiS_DisplayOff(SiS_Pr);
+- SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
+- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
+- } else {
+- SiS_DisplayOff(SiS_Pr);
+- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
+- SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
+- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+- temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
+- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
+- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp);
+- }
+-
+- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,0x3F);
+- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,0xEF); /* (from 650) */
+-
+- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
+-
+- if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+- SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
+- }
+-
+- if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+- if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+- if(!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) {
+- if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFD,0x00);
+- }
+- }
+- }
+- }
+- SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax);
+-
+- } else { /* (301,) 301B */
+-
+- if(SiS_Is301B(SiS_Pr,BaseAddr)) {
+- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,0x3F);
+- }
+-
+- SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
+- SiS_DisplayOff(SiS_Pr);
+- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
+- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
++ if(HwDeviceExtension->jChipType == SIS_650) {
++ if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
++ tempah = 0xef;
++ if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
++ if(modenum > 0x13) {
++ tempah = 0xf7;
++ }
++ }
++ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
++ }
++ if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
++ if((SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
++ (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)))) {
++ if((!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) ||
++ (!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)))) {
++ SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 2);
++ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
++ SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 4);
++ }
++ }
++ }
++ }
++
++ }
+
+- temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
+- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
+- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp);
+-
+- }
+-#endif
+ } else { /* 315, 330 - all bridge types */
+
+ if(SiS_Is301B(SiS_Pr,BaseAddr)) {
+@@ -5193,13 +5344,13 @@
+
+ }
+
+- } else { /* ============ TW: For 301 ================ */
++ } else { /* ============ For 301 ================ */
+
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+- if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
+- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF0,0x0B);
+- SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 1);
+- }
++ if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
++ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
++ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
++ }
+ }
+
+ SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); /* disable VB */
+@@ -5218,18 +5369,23 @@
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp);
+ } else {
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); /* disable CRT2 */
++ if( (!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) ||
++ (!(SiS_CR36BIOSWord23d(SiS_Pr,HwDeviceExtension))) ) {
++ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
++ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xFB,0x04);
++ }
+ }
+
+ }
+
+- } else { /* ============ TW: For LVDS =============*/
++ } else { /* ============ For LVDS =============*/
+
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+
+ #ifdef SIS300 /* 300 series */
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
+- SiS_SetCH700x(SiS_Pr,0x090E);
++ SiS_SetCH700x(SiS_Pr,0x090E);
+ }
+
+ if(HwDeviceExtension->jChipType == SIS_730) {
+@@ -5245,17 +5401,17 @@
+
+ if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
+
+- if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
++ if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
+
+- SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
++ SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
+
+- if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
+- SiS_DisplayOff(SiS_Pr);
+- }
++ if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
++ SiS_DisplayOff(SiS_Pr);
++ }
+
+- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
+- SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+- }
++ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
++ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
++ }
+ }
+ }
+ }
+@@ -5279,29 +5435,40 @@
+
+ } else {
+
+-#ifdef SIS315H /* 310/325 series */
++#ifdef SIS315H /* 315 series */
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+- temp = SiS_GetCH701x(SiS_Pr,0x61);
+- if(temp < 1) {
+- SiS_SetCH701x(SiS_Pr,0xac76);
+- SiS_SetCH701x(SiS_Pr,0x0066);
+- }
+-
+- if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
++
++ if(HwDeviceExtension->jChipType == SIS_740) {
++ temp = SiS_GetCH701x(SiS_Pr,0x61);
++ if(temp < 1) {
++ SiS_SetCH701x(SiS_Pr,0xac76);
++ SiS_SetCH701x(SiS_Pr,0x0066);
++ }
++
++ if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ SiS_SetCH701x(SiS_Pr,0x3e49);
+- } else if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwDeviceExtension, BaseAddr)) {
++ } else if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ SiS_SetCH701x(SiS_Pr,0x3e49);
++ }
+ }
+-
++
+ if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ SiS_Chrontel701xBLOff(SiS_Pr);
+- SiS_Chrontel701xOff(SiS_Pr);
++ SiS_Chrontel701xOff(SiS_Pr,HwDeviceExtension);
+ } else if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ SiS_Chrontel701xBLOff(SiS_Pr);
+- SiS_Chrontel701xOff(SiS_Pr);
++ SiS_Chrontel701xOff(SiS_Pr,HwDeviceExtension);
+ }
+-
++
++ if(HwDeviceExtension->jChipType != SIS_740) {
++ if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
++ SiS_SetCH701x(SiS_Pr,0x0149);
++ } else if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwDeviceExtension, BaseAddr)) {
++ SiS_SetCH701x(SiS_Pr,0x0149);
++ }
++ }
++
+ }
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+@@ -5325,6 +5492,10 @@
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
+ }
+
++ if(HwDeviceExtension->jChipType == SIS_740) {
++ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
++ }
++
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+@@ -5337,15 +5508,27 @@
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+ if(SiS_CRT2IsLCD(SiS_Pr, BaseAddr,HwDeviceExtension)) {
+- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
++ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
++ if(HwDeviceExtension->jChipType == SIS_550) {
++ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
++ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
++ }
++ }
++ } else {
++ if(HwDeviceExtension->jChipType == SIS_740) {
++ if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension, BaseAddr)) {
++ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
+ }
+- } else if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
++ } else {
++ if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
++ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
++ }
++ }
+ }
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+ if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff);
++ /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
+ } else {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
+ }
+@@ -5353,7 +5536,10 @@
+
+ SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr);
+
+- if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
++ if(HwDeviceExtension->jChipType == SIS_550) {
++ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
++ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
++ } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
+ } else if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
+@@ -5361,7 +5547,7 @@
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
+ }
+
+-#if 0 /* TW: BIOS code makes no sense */
++#if 0 /* BIOS code makes no sense */
+ if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+@@ -5387,7 +5573,6 @@
+
+ }
+
+-/* TW: Checked against all BIOSes */
+ void
+ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+ {
+@@ -5400,7 +5585,7 @@
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+
+- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* TW: ====== For 301B et al ====== */
++ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* ====== For 301B et al ====== */
+
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+
+@@ -5497,48 +5682,95 @@
+
+ } else {
+
+-#ifdef SIS315H /* 310/325 series */
++#ifdef SIS315H /* 315 series */
+
+- if(IS_SIS650740) { /* 650 */
++ if(IS_SIS550650740660) { /* 550, 650, 740, 660 */
+
+ #if 0
+ if(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00) != 1) return; /* From 1.10.7w */
+ #endif
+
+ if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+-
+- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef); /* 1.10.7u */
+- SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00); /* 1.10.7u */
++
++ if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
++ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef); /* 1.10.7u */
++ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00); /* 1.10.7u */
++ }
+
+ if(!(IS_SIS740)) {
+ if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ tempah = 0x10;
+- if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+- tempah = 0x08;
+- }
+- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,tempah);
++ if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
++ if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x13) & 0x04) {
++ if((SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) == 0x0c) {
++ tempah = 0x08;
++ } else {
++ tempah = 0x18;
++ }
++ }
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x4c,tempah);
++ } else {
++ if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
++ tempah = 0x08;
++ }
++ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,tempah);
++ }
+ }
+ }
+
+- SiS_SetReg3(SiS_Pr->SiS_P3c6,0x00);
+- SiS_DisplayOff(SiS_Pr);
+- pushax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06);
+- if(IS_SIS740) {
+- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
++ if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
++ SiS_SetReg3(SiS_Pr->SiS_P3c6,0x00);
++ SiS_DisplayOff(SiS_Pr);
++ pushax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06);
++ if(IS_SIS740) {
++ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
++ }
+ }
+
+ if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
+ (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
+- if(!(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
+- SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 2);
+- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
+- SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 2);
+- }
++ if(!(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
++ if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
++ SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 2);
++ }
++ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
++ SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 2);
++ }
++ }
++
++ if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
++ if(!(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
++ SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
++ delaylong = TRUE;
++ }
++ }
++
++ } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
++
++ if(HwDeviceExtension->jChipType == SIS_650) {
++ if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
++ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x10);
++ }
++ if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
++ (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
++ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
++ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 0);
++ }
+ }
+
+- if(!(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
+- SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
+- delaylong = TRUE;
++ } else if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
++
++ if(HwDeviceExtension->jChipType == SIS_650) {
++ if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
++ tempah = 0x10;
++ if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x13) & 0x04) {
++ tempah = 0x18;
++ if((SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) == 0x0c) {
++ tempah = 0x08;
++ }
++ }
++ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,tempah);
++ }
+ }
+
+ }
+@@ -5547,13 +5779,17 @@
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
+ if(SiS_BridgeInSlave(SiS_Pr)) {
+ tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+- if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
++ if(!(tempah & SetCRT2ToRAMDAC)) {
++ if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
++ if(!(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x13) & 0x04)) temp |= 0x20;
++ } else temp |= 0x20;
++ }
+ }
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
+
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
+
+- if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
++ if((SiS_Pr->SiS_VBType & VB_SIS301B302B) || (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280)) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
+ temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2e);
+ if(!(temp & 0x80)) {
+@@ -5565,12 +5801,12 @@
+ }
+
+ if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
++ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
+ }
+
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
+
+- if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
++ if((SiS_Pr->SiS_VBType & VB_SIS301B302B) || (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280)) {
+ temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2e);
+ if(!(temp & 0x80)) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
+@@ -5586,7 +5822,9 @@
+ }
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
+
+- if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
++ if((SiS_Pr->SiS_VBType & VB_SIS301B302B) ||
++ ((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
++ (!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))))) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+ }
+
+@@ -5595,186 +5833,144 @@
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00); /* All this from 1.10.7u */
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
+- SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x05);
+- SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x60);
+- SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x00);
+- SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
+- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);
+-
+- SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
+-
++
++ if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
++
++ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x08);
++ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x10);
++ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x4d);
++ if((SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0x0f) != 0x02) {
++ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x0d);
++ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x70);
++ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x6b);
++ }
++ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
++
++ } else {
++
++ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x12);
++ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0xd0);
++ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x6b);
++ if((SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0x0f) == 0x02) { /* @@@@ really == ? */
++ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x0d);
++ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x70);
++ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x40);
++ if(((SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xf0) != 0x03)) {
++ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x05);
++ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x60);
++ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x33); /* 00 */
++ }
++ }
++ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
++ if((SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0x0f) != 0x03) {
++ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);
++ }
++ }
++
++ if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
++ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
++ }
++
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10); /* 1.10.8r */
+
+- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
++ if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
+
+- if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
+ ((SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) ) {
+- SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
+- if(delaylong) {
+- SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
+- }
+- SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xfe,0x01);
+- }
+- }
++ SiS_DisplayOn(SiS_Pr);
++ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
++ SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
++ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
++ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);
++ if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xfe,0x01);
++ }
++ }
+
+- SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax);
+- SiS_DisplayOn(SiS_Pr);
+- SiS_SetReg3(SiS_Pr->SiS_P3c6,0xff);
++ } else {
+
+- if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+- }
+-#if 0
+- SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
+- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
+- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
+- SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x05); /* 1.10.8r: 0x0d */
+- SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x60); /* 1.10.8r: 0x70 */
+- SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x00); /* 1.10.8r: 0x40 */
+- SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
+- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);
+-#endif
++ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
+
+- }
++ if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
++ if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
++ ((SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) ) {
++ SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
++ if(delaylong) {
++ SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
++ }
++ SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xfe,0x01);
++ }
++ }
+
+-#if 0
+- } else if(IS_SIS740) { /* 740 */
+-
+- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { /* 30xLV */
+-
+- SiS_SetReg3(SiS_Pr->SiS_P3c6,0x00);
+- SiS_DisplayOff(SiS_Pr);
+- pushax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06);
+- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
+-
+- if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
+- (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
+- if(!(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
+- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
+- SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+- }
+- }
+-
+- if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+- temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
+- if(SiS_BridgeInSlave(SiS_Pr)) {
+- tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+- if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
+- }
+- SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
++ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax);
++ SiS_DisplayOn(SiS_Pr);
++ SiS_SetReg3(SiS_Pr->SiS_P3c6,0xff);
+
+- SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
+- SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
+- }
+-
+- if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
+- }
+-
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
+- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
+- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0x10); /* (taken from 650 1.10.8r) */
+- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
+-
+- if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+- if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
+- (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
+- SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
+- if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
+- SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
+- }
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xfe,0x01);
+- SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
+- SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
+- }
+- }
+-
+- SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax);
+- SiS_DisplayOn(SiS_Pr);
+- SiS_SetReg3(SiS_Pr->SiS_P3c6,0xff);
+-
+- if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+- }
+-
+- } else { /* (301), 301B */
+-
+- if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+- temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
+- if(SiS_BridgeInSlave(SiS_Pr)) {
+- tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+- if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
+- }
+- SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
++ if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
++ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
++ }
+
+- SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
++ }
+
+- temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
+- if(!(temp & 0x80))
+- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
+- }
++ } if(SiS_Pr->SiS_VBType & VB_NoLCD) {
++
++ if(HwDeviceExtension->jChipType == SIS_650) {
++ if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
++ if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
++ (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
++ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
++ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
++ }
++ }
++ }
+
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
++ }
+
+- if(SiS_Is301B(SiS_Pr,BaseAddr)) {
+- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
+- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+- } else {
+- SiS_VBLongWait(SiS_Pr);
+- SiS_DisplayOn(SiS_Pr);
+- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7F);
+- SiS_VBLongWait(SiS_Pr);
+- }
+-
+- }
+-#endif
+-
+ } else { /* 315, 330 */
+
+- if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+- temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
+- if(SiS_BridgeInSlave(SiS_Pr)) {
+- tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+- if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
+- }
+- SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
++ if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
++ temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
++ if(SiS_BridgeInSlave(SiS_Pr)) {
++ tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
++ if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
++ }
++ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
+
+- SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
++ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
+
+- temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
+- if(!(temp & 0x80))
+- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
+- }
++ temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
++ if(!(temp & 0x80))
++ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
++ }
+
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
+
+- if(SiS_Is301B(SiS_Pr,BaseAddr)) {
++ if(SiS_Is301B(SiS_Pr,BaseAddr)) {
+
+- temp=SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
+- if (!(temp & 0x80))
+- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
++ temp=SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
++ if(!(temp & 0x80))
++ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
++
++ tempah = 0xc0;
++ if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
++ tempah = 0x80;
++ if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
++ tempah = 0x40;
++ }
++ }
++ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
+
+- tempah = 0xc0;
+- if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+- tempah = 0x80;
+- if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+- tempah = 0x40;
+- }
+- }
+- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
++ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+
+- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
++ } else {
+
+- } else {
+-
+- SiS_VBLongWait(SiS_Pr);
+- SiS_DisplayOn(SiS_Pr);
+- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7F);
+- SiS_VBLongWait(SiS_Pr);
++ SiS_VBLongWait(SiS_Pr);
++ SiS_DisplayOn(SiS_Pr);
++ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7F);
++ SiS_VBLongWait(SiS_Pr);
+
+- }
++ }
+
+ } /* 315, 330 */
+
+@@ -5782,11 +5978,11 @@
+
+ }
+
+- } else { /* ============ TW: For 301 ================ */
++ } else { /* ============ For 301 ================ */
+
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
+- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF0,0x0B);
++ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xFB);
+ SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 0);
+ }
+ }
+@@ -5818,13 +6014,13 @@
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
+ SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 1);
+- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF0,0x03);
++ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xF7);
+ }
+ }
+
+ }
+
+- } else { /* =================== TW: For LVDS ================== */
++ } else { /* =================== For LVDS ================== */
+
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+
+@@ -5847,35 +6043,35 @@
+ SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr);
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
+ if(SiS_BridgeInSlave(SiS_Pr)) {
+- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
++ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
+ } else {
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
+ }
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
+- if(!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) {
+- SiS_SetCH700x(SiS_Pr,0x0B0E);
+- }
++ if(!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) {
++ SiS_SetCH700x(SiS_Pr,0x0B0E);
++ }
+ }
+
+ if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
+- if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
+- if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
+- if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
+- SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
+- SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
+- }
+- SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
+- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xF7);
+- }
+- }
++ if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
++ if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
++ if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
++ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
++ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
++ }
++ SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
++ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xF7);
++ }
++ }
+ }
+
+ #endif /* SIS300 */
+
+ } else {
+
+-#ifdef SIS315H /* 310/325 series */
++#ifdef SIS315H /* 315 series */
+
+ #if 0 /* BIOS code makes no sense */
+ if(SiS_IsVAMode()) {
+@@ -5902,36 +6098,41 @@
+ SiS_Chrontel701xBLOff(SiS_Pr);
+ }
+
+- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
+-
+-#ifdef NEWCH701x
+- if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+- if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension,BaseAddr)) {
++ if(HwDeviceExtension->jChipType != SIS_550) {
++ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
++ }
++
++ if(HwDeviceExtension->jChipType == SIS_740) {
++ if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
++ if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension,BaseAddr)) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
+- }
++ }
++ }
+ }
+-#endif
+
+ temp1 = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
+- if (!(temp1 & 0x80))
++ if(!(temp1 & 0x80))
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+ if(temp) {
+- SiS_Chrontel701xBLOn(SiS_Pr);
++ SiS_Chrontel701xBLOn(SiS_Pr, HwDeviceExtension);
+ }
+ }
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+ if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
++ if(HwDeviceExtension->jChipType == SIS_550) {
++ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
++ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
++ }
++ }
++ } else if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
++ if(HwDeviceExtension->jChipType != SIS_740) {
++ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
+ }
+- }
+-#ifndef NEWCH701x
+- else if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
+ }
+-#endif
+
+ if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+@@ -5954,10 +6155,10 @@
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+ if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+- SiS_Chrontel701xBLOn(SiS_Pr);
++ SiS_Chrontel701xBLOn(SiS_Pr, HwDeviceExtension);
+ SiS_ChrontelDoSomething4(SiS_Pr,HwDeviceExtension, BaseAddr);
+ } else if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+- SiS_Chrontel701xBLOn(SiS_Pr);
++ SiS_Chrontel701xBLOn(SiS_Pr, HwDeviceExtension);
+ SiS_ChrontelDoSomething4(SiS_Pr,HwDeviceExtension, BaseAddr);
+ }
+ }
+@@ -5983,7 +6184,7 @@
+ {
+ USHORT BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
+
+- /* TW: Switch on LCD backlight on SiS30xLV */
++ /* Switch on LCD backlight on SiS30xLV */
+ if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
+ (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
+ if(!(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
+@@ -6001,7 +6202,7 @@
+ {
+ USHORT BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
+
+- /* TW: Switch off LCD backlight on SiS30xLV */
++ /* Switch off LCD backlight on SiS30xLV */
+ if( (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) ||
+ (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00);
+@@ -6023,12 +6224,14 @@
+ UCHAR *ROMAddr;
+
+ if((ROMAddr = (UCHAR *)HwDeviceExtension->pjVirtualRomBase) && SiS_Pr->SiS_UseROM) {
+- temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xff;
+- temp >>= 4;
+- temp = 1 << temp;
+- temp1 = (ROMAddr[0x23c] << 8) | ROMAddr[0x23b];
+- if(temp1 & temp) return(1);
+- else return(0);
++ if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
++ temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xff;
++ temp >>= 4;
++ temp = 1 << temp;
++ temp1 = (ROMAddr[0x23c] << 8) | ROMAddr[0x23b];
++ if(temp1 & temp) return(1);
++ else return(0);
++ } else return(0);
+ } else {
+ return(0);
+ }
+@@ -6041,12 +6244,14 @@
+ UCHAR *ROMAddr;
+
+ if((ROMAddr = (UCHAR *)HwDeviceExtension->pjVirtualRomBase) && SiS_Pr->SiS_UseROM) {
+- temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xff;
+- temp >>= 4;
+- temp = 1 << temp;
+- temp1 = (ROMAddr[0x23e] << 8) | ROMAddr[0x23d];
+- if(temp1 & temp) return(1);
+- else return(0);
++ if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
++ temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xff;
++ temp >>= 4;
++ temp = 1 << temp;
++ temp1 = (ROMAddr[0x23e] << 8) | ROMAddr[0x23d];
++ if(temp1 & temp) return(1);
++ else return(0);
++ } else return(0);
+ } else {
+ return(0);
+ }
+@@ -6143,7 +6348,7 @@
+
+ #ifdef SIS315H
+
+- if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* 310/325 series, LVDS */
++ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* 315 series, LVDS */
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+ PanelID = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
+@@ -6171,7 +6376,7 @@
+ SiS_ShortDelay(SiS_Pr,Delay);
+ }
+
+- } else { /* 310/325 series, 301(B) */
++ } else { /* 315 series, 301(B) */
+
+ PanelID = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
+ DelayIndex = PanelID >> 4;
+@@ -6271,14 +6476,7 @@
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
+ if((flag & EnableDualEdge) && (flag & SetToLCDA)) return(1);
+-#if 0 /* Not done in 650/30xLV 1.10.6s, but in 650/301LV */
+- else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+- if(flag) return(1);
+- else return(0);
+- }
+-#endif
+- else
+- return(0);
++ else return(0);
+ } else
+ #endif
+ return(0);
+@@ -6325,7 +6523,9 @@
+ if(HwDeviceExtension->jChipType == SIS_650) {
+ flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f);
+ flag &= 0xF0;
+- if((flag == 0xb0) || (flag == 0x90)) return 0;
++ /* Check for revision != A0 only */
++ if((flag == 0xe0) || (flag == 0xc0) ||
++ (flag == 0xb0) || (flag == 0x90)) return 0;
+ else return 1;
+ } else
+ #endif
+@@ -6443,7 +6643,7 @@
+ if((flag == 0x80) || (flag == 0x20)) return 0;
+ else return 1;
+ } else {
+- /* 310/325 series (650/30xLV 1.10.6s) */
++ /* 315 series (650/30xLV 1.10.6s) */
+ flag &= 0x50;
+ if((flag == 0x40) || (flag == 0x10)) return 0;
+ else return 1;
+@@ -6487,14 +6687,14 @@
+ }
+ }
+
+-BOOLEAN
++void
+ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
+ USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+ {
+ USHORT temp,modeflag,resinfo=0;
+ const unsigned char SiS300SeriesLCDRes[] =
+- { 0, 1, 2, 3, 7, 4, 5, 8,
+- 0, 0, 0, 0, 0, 0, 0, 0 };
++ { 0, 1, 2, 3, 7, 4, 5, 8,
++ 0, 0, 10, 0, 0, 0, 0, 15 };
+
+ SiS_Pr->SiS_LCDResInfo = 0;
+ SiS_Pr->SiS_LCDTypeInfo = 0;
+@@ -6511,17 +6711,19 @@
+ }
+ }
+
+- if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return 0;
++ if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
+
+- if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2))) return 0;
++ if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2))) return;
+
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
+
++#if 0
+ /* FSTN: Fake CR36 (TypeInfo 2, ResInfo SiS_Panel320x480) */
+ if(SiS_Pr->SiS_IF_DEF_FSTN) {
+ temp = 0x20 | SiS_Pr->SiS_Panel320x480;
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,temp);
+ }
++#endif
+
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
+@@ -6530,14 +6732,16 @@
+ }
+ temp &= 0x0f;
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+- /* TW: Translate 300 series LCDRes to 310/325 series for unified usage */
++ /* Translate 300 series LCDRes to 315 series for unified usage */
+ temp = SiS300SeriesLCDRes[temp];
+ }
+ SiS_Pr->SiS_LCDResInfo = temp;
+
++#if 0
+ if(SiS_Pr->SiS_IF_DEF_FSTN){
+ SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_Panel320x480;
+ }
++#endif
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
+@@ -6547,75 +6751,115 @@
+ SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
+ }
+
+- if(SiS_Pr->SiS_LCDResInfo > SiS_Pr->SiS_PanelMax)
++ if((!SiS_Pr->CP_HaveCustomData) || (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_PanelCustom)) {
++ if(SiS_Pr->SiS_LCDResInfo > SiS_Pr->SiS_PanelMax)
+ SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_Panel1024x768;
++ }
++
++ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
++ if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
++ SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
++ } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
++ SiS_Pr->SiS_LCDResInfo = Panel_848x480;
++ }
++ }
++
++ switch(SiS_Pr->SiS_LCDResInfo) {
++ case Panel_800x600: SiS_Pr->PanelXRes = 800; SiS_Pr->PanelYRes = 600; break;
++ case Panel_1024x768: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768; break;
++ case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024; break;
++ case Panel_640x480_3:
++ case Panel_640x480_2:
++ case Panel_640x480: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480; break;
++ case Panel_1024x600: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 600; break;
++ case Panel_1152x864: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 864; break;
++ case Panel_1280x960: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 960; break;
++ case Panel_1152x768: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 768; break;
++ case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050; break;
++ case Panel_1280x768: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768; break;
++ case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200; break;
++ case Panel_320x480: SiS_Pr->PanelXRes = 320; SiS_Pr->PanelYRes = 480; break;
++ case Panel_Custom: SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
++ SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
++ break;
++ case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024; break;
++ case Panel_848x480: SiS_Pr->PanelXRes = 848; SiS_Pr->PanelYRes = 480; break;
++ default: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768; break;
++ }
+
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);
++#if 0
+ if(SiS_Pr->SiS_IF_DEF_FSTN){
+- /* TW: Fake LVDS bridge for FSTN */
++ /* Fake LVDS bridge for FSTN */
+ temp = 0x04;
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,temp);
+ }
++#endif
+ SiS_Pr->SiS_LCDInfo = temp;
+-
++
++ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
++ if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
++ SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20; /* neg sync, RGB24 */
++ }
++ }
++
+ if(!(SiS_Pr->UsePanelScaler)) SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
+ else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+
+- /* TW: Inserted entire 315-block from 650/LVDS/30xLV BIOSes */
++ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
++ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
++ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) {
++ /* For non-standard LCD resolution, we let the panel scale */
++ SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
++ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
++ if(ModeNo == 0x7c || ModeNo == 0x7d || ModeNo == 0x7e) {
++ /* Bridge does not scale to 1280x960 */
++ SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
++ }
++ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
++ /* TEMP - no idea about the timing and zoom factors */
++ SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
++ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
++ if(ModeNo == 0x3a || ModeNo == 0x4d || ModeNo == 0x65) {
++ /* Bridge does not scale to 1280x1024 */
++ SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
++ }
++ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
++ /* TEMP - no idea about the timing and zoom factors */
++ SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
++ }
++ }
++ }
++
++
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ #ifdef SIS315H
+- if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+- if(ModeNo == 0x3a || ModeNo == 0x4d || ModeNo == 0x65) {
+- /* Bridge does not scale to 1280x1024 */
+- SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+- }
+- }
+- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+- if(ModeNo == 0x7c || ModeNo == 0x7d || ModeNo == 0x7e) {
+- /* TW: Bridge does not scale to 1280x960 */
+- SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+- }
+- if(ModeNo == 0x2f || ModeNo == 0x5d || ModeNo == 0x5e) {
+- /* TW: Bridge does not scale to 640x400 */
+- SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+- }
+- }
+- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+- if(ModeNo == 0x2f || ModeNo == 0x5d || ModeNo == 0x5e) {
+- /* TW: Most panels can't scale to 640x400 */
+- SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
+- }
+- }
+- }
+- }
+ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x01) {
+- SiS_Pr->SiS_LCDInfo &= 0xFFEF;
+- SiS_Pr->SiS_LCDInfo |= LCDPass11;
++ SiS_Pr->SiS_LCDInfo &= 0xFFEF;
++ SiS_Pr->SiS_LCDInfo |= LCDPass11;
+ }
+ #endif
+ } else {
+ #ifdef SIS300
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+- if(!(ROMAddr[0x235] & 0x02)) {
+- SiS_Pr->SiS_LCDInfo &= 0xEF;
++ if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
++ if(!(ROMAddr[0x235] & 0x02)) {
++ SiS_Pr->SiS_LCDInfo &= 0xEF;
++ }
+ }
+ }
+- } else {
+- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+- if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
+- SiS_Pr->SiS_LCDInfo &= 0xEF;
+- }
++ } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
++ if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
++ SiS_Pr->SiS_LCDInfo &= 0xEF;
+ }
+ }
+ #endif
+ }
+-
+- /* TW: With Trumpion, always Expanding */
+- if(SiS_Pr->SiS_IF_DEF_TRUMPION != 0){
+- SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
++
++ /* Trumpion: Assume non-expanding */
++ if(SiS_Pr->SiS_IF_DEF_TRUMPION != 0) {
++ SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
+ }
+
+ if(!((HwDeviceExtension->jChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
+@@ -6624,7 +6868,7 @@
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
+ if(ModeNo > 0x13) {
+ if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+- if((resinfo == 7) || (resinfo == 3)) {
++ if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
+ SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+ }
+ }
+@@ -6644,9 +6888,9 @@
+ (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480))) {
+ if(ModeNo > 0x13) {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+- if(resinfo == 4) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; /* 512x384 */
++ if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
+- if(resinfo == 3) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; /* 400x300 */
++ if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+ }
+ }
+ } else SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+@@ -6665,19 +6909,21 @@
+ }
+
+ #ifdef SIS315H
+- /* TW: 650/30xLV 1.10.6s */
++ /* 650/30xLV 1.10.6s */
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+- if(SiS_Pr->SiS_VBType & (VB_SIS302B | VB_SIS302LV)) {
+- /* Enable 302B/302LV dual link mode */
+- /* (302B is a theory - not in any BIOS */
+- temp = 0x00;
+- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) temp = 0x04;
+- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x04;
+- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) temp = 0x04;
+- SiS_SetReg1(SiS_Pr->SiS_P3d4,0x39,temp);
+- } else if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+- SiS_SetReg1(SiS_Pr->SiS_P3d4,0x39,0x00);
+- }
++ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
++ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,~0x04);
++ if(SiS_Pr->SiS_VBType & (VB_SIS302B | VB_SIS302LV)) {
++ /* Enable 302B/302LV dual link mode.
++ * (302B is a theory - not in any BIOS)
++ */
++ if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
++ (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
++ (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) {
++ SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x39,0x04);
++ }
++ }
++ }
+ }
+ #endif
+
+@@ -6693,20 +6939,6 @@
+ SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo, SiS_Pr->SiS_SetFlag);
+ #endif
+
+- return 1;
+-}
+-
+-void
+-SiS_PresetScratchregister(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+-{
+- return;
+- /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x30,0x21); */
+- /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x31,0x41); */
+- /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x32,0x28); */
+- /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x33,0x22); */
+- /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x35,0x43); */
+- /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,0x01); */
+- /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,0x00); */
+ }
+
+ void
+@@ -6736,7 +6968,6 @@
+ } else {
+ SiS_LongWait(SiS_Pr);
+ }
+- return;
+ }
+
+ void
+@@ -6803,7 +7034,7 @@
+ #endif
+ } else {
+ #ifdef SIS300
+-#if 0 /* TW: Not done in A901 BIOS */
++#if 0 /* Not done in A901 BIOS */
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
+ }
+@@ -6898,7 +7129,51 @@
+
+ /* ========================================================= */
+
+-/* TW: Set 301 TV Encoder (and some LCD relevant) registers */
++static void
++SiS_SetTVSpecial(SiS_Private *SiS_Pr, USHORT ModeNo)
++{
++ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
++ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
++ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
++ if((ModeNo == 0x64) || (ModeNo == 0x4a) || (ModeNo == 0x38)) {
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1c,0xa7);
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1d,0x07);
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1e,0xf2);
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1f,0x6e);
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x20,0x17);
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x21,0x8b);
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x22,0x73);
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,0x53);
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x24,0x13);
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x25,0x40);
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x26,0x34);
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x27,0xf4);
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x28,0x63);
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x29,0xbb);
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2a,0xcc);
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2b,0x7a);
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2c,0x58); /* 48 */
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2d,0xe4);
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2e,0x73);
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,0xda); /* de */
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0x13);
++ if((SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38)) & 0x40) {
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x14);
++ } else {
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x15);
++ }
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x1b);
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,0x72);
++ }
++ } else {
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x21);
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x5a);
++ }
++ }
++ }
++}
++
++/* Set 301 TV Encoder (and some LCD relevant) registers */
+ void
+ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr, USHORT ModeNo,
+ USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
+@@ -6911,67 +7186,46 @@
+ #ifdef SIS315H
+ const SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
+ USHORT resindex, CRT2Index;
+-#endif
++#endif
+ USHORT modeflag, resinfo, crt2crtc;
+- ULONG longtemp, tempeax, tempebx, temp2, tempecx;
++ ULONG longtemp, tempeax;
++#ifdef SIS300
+ const UCHAR atable[] = {
+ 0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
+ 0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
+ };
++#endif
+
+ #ifdef SIS315H
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+- /* TW: 650/30xLV 1.10.6s: (Is at end of SetGroup2!) */
++ /* 650/30xLV 1.10.6s: (Is at end of SetGroup2!) */
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xfc,0x03);
+- temp = 1;
+- if(ModeNo <= 0x13) temp = 3;
++ temp = 0x01;
++ if(ModeNo <= 0x13) temp = 0x03;
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0b,temp);
+ }
+ }
+- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+- if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+- if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1c,0xa7);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1d,0x07);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1e,0xf2);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1f,0x6e);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x20,0x17);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x21,0x8b);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x22,0x73);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,0x53);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x24,0x13);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x25,0x40);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x26,0x34);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x27,0xf4);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x28,0x63);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x29,0xbb);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2a,0xcc);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2b,0x7a);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2c,0x58);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2d,0xe4);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2e,0x73);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,0xda);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0x13);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,0x72);
+- }
+- }
+- }
+- }
++ SiS_SetTVSpecial(SiS_Pr, ModeNo);
+ return;
+ }
+-#endif
++#endif
+
+- if(ModeNo<=0x13) {
+- modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+- resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+- crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
++ if(ModeNo <= 0x13) {
++ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
++ resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
++ crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ } else {
+- modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
++ if(SiS_Pr->UseCustomMode) {
++ modeflag = SiS_Pr->CModeFlag;
++ resinfo = 0;
++ crt2crtc = 0;
++ } else {
++ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
++ }
+ }
+
+ tempcx = SiS_Pr->SiS_VBInfo;
+@@ -6984,9 +7238,9 @@
+ temp |= ((tempbx & 0x00FF) >> 3);
+ temp ^= 0x0C;
+
+- /* TW: From 1.10.7w (no vb check there; don't care - this only disables SVIDEO and CVBS signal) */
++ /* From 1.10.7w (no vb check there; don't care - this only disables SVIDEO and CVBS signal) */
+ if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+- temp |= 0x0c;
++ temp |= 0x0c;
+ }
+
+ PhasePoint = SiS_Pr->SiS_PALPhase;
+@@ -6994,44 +7248,44 @@
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+
+- temp ^= 0x01;
+- if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+- TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
+- if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+- if(modeflag & Charx8Dot) TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
+- else TimingPoint = SiS_Pr->SiS_HiTVTextTiming;
+- }
+- } else TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
+-
+- if(SiS_Pr->SiS_HiVision & 0x03) temp &= 0xfe;
+-
++ temp ^= 0x01;
++ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
++ TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
++ if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
++ if(modeflag & Charx8Dot) TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
++ else TimingPoint = SiS_Pr->SiS_HiTVTextTiming;
++ }
++ } else TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
++
++ if(SiS_Pr->SiS_HiVision & 0x03) temp &= 0xfe;
++
+ } else {
+-
+- if(SiS_Pr->SiS_VBInfo & SetPALTV){
+
+- TimingPoint = SiS_Pr->SiS_PALTiming;
+- PhasePoint = SiS_Pr->SiS_PALPhase;
++ if(SiS_Pr->SiS_VBInfo & SetPALTV){
+
+- if( (SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
+- ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+- (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
+- PhasePoint = SiS_Pr->SiS_PALPhase2;
+- }
++ TimingPoint = SiS_Pr->SiS_PALTiming;
++ PhasePoint = SiS_Pr->SiS_PALPhase;
+
+- } else {
++ if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
++ ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
++ (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
++ PhasePoint = SiS_Pr->SiS_PALPhase2;
++ }
++
++ } else {
+
+ temp |= 0x10;
+- TimingPoint = SiS_Pr->SiS_NTSCTiming;
+- PhasePoint = SiS_Pr->SiS_NTSCPhase;
++ TimingPoint = SiS_Pr->SiS_NTSCTiming;
++ PhasePoint = SiS_Pr->SiS_NTSCPhase;
+
+- if( (SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
++ if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
+ ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+ (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
+- PhasePoint = SiS_Pr->SiS_NTSCPhase2;
++ PhasePoint = SiS_Pr->SiS_NTSCPhase2;
+ }
+
+- }
+-
++ }
++
+ }
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,temp);
+
+@@ -7044,36 +7298,35 @@
+ temp = 0x38;
+ }
+ if(temp) {
+- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+- if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
+- temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,temp);
+- if(temp1 & EnablePALM) { /* 0x40 */
+- PhasePoint = SiS_Pr->SiS_PALMPhase;
+- if( (SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
+- ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+- (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
+- PhasePoint = SiS_Pr->SiS_PALMPhase2;
+- }
+- }
+- if(temp1 & EnablePALN) { /* 0x80 */
+- PhasePoint = SiS_Pr->SiS_PALNPhase;
+- if( (SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
+- ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+- (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
+- PhasePoint = SiS_Pr->SiS_PALNPhase2;
+- }
+- }
+- }
+- }
++ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
++ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
++ temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,temp);
++ if(temp1 & EnablePALM) { /* 0x40 */
++ PhasePoint = SiS_Pr->SiS_PALMPhase;
++ if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
++ ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
++ (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
++ PhasePoint = SiS_Pr->SiS_PALMPhase2;
++ }
++ }
++ if(temp1 & EnablePALN) { /* 0x80 */
++ PhasePoint = SiS_Pr->SiS_PALNPhase;
++ if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
++ ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
++ (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
++ PhasePoint = SiS_Pr->SiS_PALNPhase2;
++ }
++ }
++ }
++ }
+ }
+
+ #ifdef SIS315H
+- /* TW: 650/301LV BIOS */
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+- if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
++ if((ModeNo == 0x64) || (ModeNo == 0x4a) || (ModeNo == 0x38)) {
+ PhasePoint = SiS_Pr->SiS_SpecialPhase;
+ }
+ }
+@@ -7094,12 +7347,12 @@
+ }
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+- if(HwDeviceExtension->jChipType >= SIS_315H) {
+- if(!(SiS_Pr->SiS_ModeType & 0x07))
++ if(HwDeviceExtension->jChipType >= SIS_315H) {
++ if(!(SiS_Pr->SiS_ModeType & 0x07))
++ SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
++ } else {
+ SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
+- } else {
+- SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
+- }
++ }
+ }
+
+ SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
+@@ -7110,11 +7363,11 @@
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+- if(SiS_Pr->SiS_HiVision == 3) tempax = 950;
+- else tempax = 440;
++ if(SiS_Pr->SiS_HiVision == 3) tempax = 950;
++ else tempax = 440;
+ } else {
+- if(SiS_Pr->SiS_VBInfo & SetPALTV) tempax = 520;
+- else tempax = 440;
++ if(SiS_Pr->SiS_VBInfo & SetPALTV) tempax = 520;
++ else tempax = 440;
+ }
+
+ if( ( ( (!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_HiVision == 3) ) && (SiS_Pr->SiS_VDE <= tempax) ) ||
+@@ -7134,18 +7387,18 @@
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,temp);
+
+ if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) &&
+- (SiS_Pr->SiS_HiVision != 3) &&
+- (SiS_Pr->SiS_VGAHDE >= 1024) ) {
++ (SiS_Pr->SiS_HiVision != 3) &&
++ (SiS_Pr->SiS_VGAHDE >= 1024) ) {
+ if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x19);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x52);
+ } else {
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x17);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x1d);
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x17);
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x1d);
+ } else {
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x0b);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x11);
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x0b);
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x11);
+ }
+ }
+ }
+@@ -7154,7 +7407,7 @@
+
+ tempcx = SiS_Pr->SiS_HT;
+
+- /* TW: 650/30xLV 1.10.6s */
++ /* 650/30xLV 1.10.6s */
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) {
+ tempcx >>= 1;
+@@ -7181,7 +7434,7 @@
+ tempcx += 7;
+ if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
+ (SiS_Pr->SiS_HiVision == 3)) {
+- tempcx -= 4;
++ tempcx -= 4;
+ }
+ temp = (tempcx & 0x00FF) << 4;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,temp);
+@@ -7201,8 +7454,8 @@
+ tempbx += 8;
+ if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
+ (SiS_Pr->SiS_HiVision == 3)) {
+- tempbx -= 4;
+- tempcx = tempbx;
++ tempbx -= 4;
++ tempcx = tempbx;
+ }
+ temp = (tempbx & 0x00FF) << 4;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,temp);
+@@ -7231,8 +7484,8 @@
+
+ tempcx -= 11;
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
+- tempax = SiS_GetVGAHT2(SiS_Pr) - 1;
+- tempcx = tempax;
++ tempax = SiS_GetVGAHT2(SiS_Pr) - 1;
++ tempcx = tempax;
+ }
+ temp = tempcx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2E,temp);
+@@ -7242,38 +7495,38 @@
+ if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
+ if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempbx >>= 1;
++ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempbx >>= 1;
+ } else {
+- if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
+- tempbx >>= 1;
+- if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+- if(ModeNo <= 0x13) {
+- if(crt2crtc == 1) {
+- tempbx++;
+- }
+- }
+- } else {
+- if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+- if(crt2crtc == 4) /* TW: BIOS calls GetRatePtrCRT2 here - does not make sense */
+- if(SiS_Pr->SiS_ModeType <= 3) tempbx++;
+- }
++ if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
++ tempbx >>= 1;
++ if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
++ if(ModeNo <= 0x13) {
++ if(crt2crtc == 1) {
++ tempbx++;
++ }
+ }
+- }
++ } else {
++ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
++ if(crt2crtc == 4) /* BIOS calls GetRatePtrCRT2 here - does not make sense */
++ if(SiS_Pr->SiS_ModeType <= 3) tempbx++;
++ }
++ }
++ }
+ }
+ tempbx -= 2;
+ temp = tempbx & 0x00FF;
+ if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
+ (SiS_Pr->SiS_HiVision == 3)) {
+- if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+- if(ModeNo == 0x2f) temp++;
+- }
++ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
++ if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) temp++;
++ }
+ }
+- /* TW: From 1.10.7w - doesn't make sense */
++ /* From 1.10.7w - doesn't make sense */
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+ if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) { /* SetFlag?? */
+- if(ModeNo == 0x03) temp++;
++ if(ModeNo == 0x03) temp++;
+ }
+ }
+ }
+@@ -7285,15 +7538,15 @@
+ tempax |= (tempbx & 0xFF00);
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) {
+- if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)) { /* TW: New from 630/301B (II) BIOS */
++ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)) { /* New from 630/301B (II) BIOS */
+ tempax |= 0x1000;
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) tempax |= 0x2000;
+ }
+ }
+ } else {
+ /* TODO Check this with other BIOSes */
+- if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) &&
+- (SiS_Pr->SiS_HiVision == 3)) {
++ if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV))
++ /* && (SiS_Pr->SiS_HiVision == 3) */ ) {
+ tempax |= 0x1000;
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) tempax |= 0x2000;
+ }
+@@ -7301,12 +7554,12 @@
+ temp = (tempax & 0xFF00) >> 8;
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,temp);
+
+- /* TW: 650/30xLV 1.10.6s */
++ /* 650/30xLV 1.10.6s */
+ if(HwDeviceExtension->jChipType > SIS_315H) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
+ (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) ) {
+- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x10,0x60);
++ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x10,0x60);
+ }
+ }
+ }
+@@ -7322,79 +7575,70 @@
+ }
+ }
+
+- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+- tempbx = SiS_Pr->SiS_VDE;
+- if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
+- tempbx >>= 1;
+- }
+- tempbx -= 3;
+- tempbx &= 0x03ff;
+- temp = ((tempbx & 0xFF00) >> 8) << 5;
+- temp |= 0x18;
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x46,temp);
+- temp = tempbx & 0x00FF;
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x47,temp); /* tv gatingno */
+- if(HwDeviceExtension->jChipType >= SIS_315H) { /* TW: 650/30xLV 1.10.6s */
+- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+- tempax = 0;
+- if(SiS_Pr->SiS_HiVision & 0x03) {
+- tempax = 0x3000;
+- if(SiS_Pr->SiS_HiVision & 0x01) tempax = 0x5000;
+- }
+- temp = (tempax & 0xFF00) >> 8;
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4d,temp);
+- }
+- }
++ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
++ tempbx = SiS_Pr->SiS_VDE;
++ if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
++ tempbx >>= 1;
++ }
++ tempbx -= 3;
++ tempbx &= 0x03ff;
++ temp = ((tempbx & 0xFF00) >> 8) << 5;
++ temp |= 0x18;
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x46,temp);
++ temp = tempbx & 0x00FF;
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x47,temp); /* tv gatingno */
++ if(HwDeviceExtension->jChipType >= SIS_315H) {
++ if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
++ tempax = 0;
++ if(SiS_Pr->SiS_HiVision & 0x03) {
++ tempax = 0x3000;
++ if(SiS_Pr->SiS_HiVision & 0x01) tempax = 0x5000;
++ }
++ temp = (tempax & 0xFF00) >> 8;
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4d,temp);
++ }
++ }
+ }
+
+ tempbx &= 0x00FF;
+ if(!(modeflag & HalfDCLK)) {
+- tempcx = SiS_Pr->SiS_VGAHDE;
+- if(tempcx >= SiS_Pr->SiS_HDE) {
+- tempbx |= 0x2000;
+- tempax &= 0x00FF;
+- }
++ if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
++ tempbx |= 0x2000;
++ tempax &= 0x00FF;
++ }
+ }
+
+ tempcx = 0x0101;
+-/*if(SiS_Pr->SiS_VBInfo & (SetPALTV | SetCRT2ToTV)) { */ /*301b- TW: BIOS BUG? */
++/*if(SiS_Pr->SiS_VBInfo & (SetPALTV | SetCRT2ToTV)) { */ /* BIOS BUG? */
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) {
+- if(!(SiS_Pr->SiS_HiVision & 0x03)) {
+- if(SiS_Pr->SiS_VGAHDE >= 1024) {
+- if((!(modeflag & HalfDCLK)) || (HwDeviceExtension->jChipType < SIS_315H)) { /* TW: This check not in 630/301B */
+- tempcx = 0x1920;
+- if(SiS_Pr->SiS_VGAHDE >= 1280) {
+- tempcx = 0x1420;
+- tempbx &= 0xDFFF;
+- }
++ if(!(SiS_Pr->SiS_HiVision & 0x03)) {
++ if(SiS_Pr->SiS_VGAHDE >= 1024) {
++ if((!(modeflag & HalfDCLK)) || (HwDeviceExtension->jChipType < SIS_315H)) {
++ tempcx = 0x1920;
++ if(SiS_Pr->SiS_VGAHDE >= 1280) {
++ tempcx = 0x1420;
++ tempbx &= 0xDFFF;
++ }
++ }
+ }
+- }
+- }
++ }
+ }
+
+ if(!(tempbx & 0x2000)) {
+- if(modeflag & HalfDCLK) {
+- tempcx = (tempcx & 0xFF00) | (((tempcx & 0x00FF) << 1) & 0xff);
+- }
+- push1 = tempbx;
+- tempeax = SiS_Pr->SiS_VGAHDE;
+- tempebx = (tempcx & 0xFF00) >> 8;
+- longtemp = tempeax * tempebx;
+- tempecx = tempcx & 0x00FF;
+- longtemp /= tempecx;
+- longtemp <<= 0x0d;
+- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
++ if(modeflag & HalfDCLK) {
++ tempcx = (tempcx & 0xFF00) | ((tempcx << 1) & 0x00FF);
++ }
++ longtemp = (SiS_Pr->SiS_VGAHDE * ((tempcx & 0xFF00) >> 8)) / (tempcx & 0x00FF);
++ longtemp <<= 13;
++ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ longtemp <<= 3;
+- }
+- tempecx = SiS_Pr->SiS_HDE;
+- temp2 = longtemp % tempecx;
+- tempeax = longtemp / tempecx;
+- if(temp2 != 0) tempeax++;
+- tempax = (USHORT)tempeax;
+- tempbx = push1;
+- tempcx = (tempcx & 0xff00) | (((tempax & 0xFF00) >> 8) >> 5);
+- tempbx |= (tempax & 0x1F00);
+- tempax = ((tempax & 0x00FF) << 8) | (tempax & 0x00FF);
++ }
++ tempeax = longtemp / SiS_Pr->SiS_HDE;
++ if(longtemp % SiS_Pr->SiS_HDE) tempeax++;
++ tempax = (USHORT)tempeax;
++ tempcx = (tempcx & 0xFF00) | ((tempax & 0xFF00) >> (8 + 5));
++ tempbx |= (tempax & 0x1F00);
++ tempax = ((tempax & 0x00FF) << 8) | (tempax & 0x00FF);
+ }
+
+ temp = (tempax & 0xFF00) >> 8;
+@@ -7403,33 +7647,32 @@
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,temp);
+
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+- temp = tempcx & 0x00FF;
+- if(tempbx & 0x2000) temp = 0;
+- temp |= 0x18;
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xE0,temp);
+- if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+- tempbx = 0x0382;
+- tempcx = 0x007e;
+- } else {
+- tempbx = 0x0369;
+- tempcx = 0x0061;
+- }
+- temp = (tempbx & 0x00FF) ;
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4B,temp);
+- temp = (tempcx & 0x00FF) ;
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4C,temp);
+- tempbx &= 0x03FF;
+- temp = (tempcx & 0xFF00) >> 8;
+- temp = (temp & 0x0003) << 2;
+- temp |= (tempbx >> 8);
+- if(HwDeviceExtension->jChipType < SIS_315H) {
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4D,temp);
+- } else {
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4D,0xF0,temp);
+- }
++ temp = tempcx & 0x00FF;
++ if(tempbx & 0x2000) temp = 0;
++ temp |= 0x18;
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xE0,temp);
+
+- temp = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x43);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,(USHORT)(temp - 3));
++ if(SiS_Pr->SiS_VBInfo & SetPALTV) {
++ tempbx = 0x0382;
++ tempcx = 0x007e;
++ } else {
++ tempbx = 0x0369;
++ tempcx = 0x0061;
++ }
++ temp = (tempbx & 0x00FF) ;
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4B,temp);
++ temp = (tempcx & 0x00FF) ;
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4C,temp);
++ temp = (tempcx & 0x0300) >> (8 - 2);
++ temp |= ((tempbx >> 8) & 0x03);
++ if(HwDeviceExtension->jChipType < SIS_315H) {
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4D,temp);
++ } else {
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4D,0xF0,temp);
++ }
++
++ temp = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x43);
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,(USHORT)(temp - 3));
+ }
+
+ temp = 0;
+@@ -7440,23 +7683,33 @@
+ temp = 0x38;
+ }
+ if(temp) {
+- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+- if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
+- if(SiS_GetReg1(SiS_Pr->SiS_P3d4,temp) & EnablePALM) { /* 0x40 */
+- SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
+- temp = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x01);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,temp - 1);
+- }
+- }
+- }
++ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
++ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
++ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,temp) & EnablePALM) { /* 0x40 */
++ SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
++ temp = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x01);
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,temp - 1);
++ }
++ }
++ }
+ }
+
++ if(HwDeviceExtension->jChipType >= SIS_315H) {
++ if((SiS_Pr->SiS_VBType & VB_SIS301B302B) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
++ if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0B,0x00);
++ }
++ }
++ }
++
++#if 0 /* Old: Why HiVision? */
+ if( (SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
+ (!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) ) {
+- if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0B,0x00);
+- }
++ if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0B,0x00);
++ }
+ }
++#endif
+
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+@@ -7465,74 +7718,43 @@
+ return;
+ }
+ } else {
+- /* TW: !!! The following is a duplicate, done for LCDA as well (see above) */
++ /* !!! The following is a duplicate, done for LCDA as well (see above) */
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+- if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+- if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1c,0xa7);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1d,0x07);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1e,0xf2);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1f,0x6e);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x20,0x17);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x21,0x8b);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x22,0x73);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,0x53);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x24,0x13);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x25,0x40);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x26,0x34);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x27,0xf4);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x28,0x63);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x29,0xbb);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2a,0xcc);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2b,0x7a);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2c,0x58);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2d,0xe4);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2e,0x73);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,0xda);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0x13);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,0x72);
+- }
+- }
+- }
+- }
+- return;
++ SiS_SetTVSpecial(SiS_Pr, ModeNo);
++ return;
+ }
+ }
+
+- /* TW: From here: Part2 LCD setup */
++ /* From here: Part2 LCD setup */
+
+ tempbx = SiS_Pr->SiS_HDE;
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+- /* TW: 650/30xLV 1.10.6s */
+- if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempbx >>= 1;
++ /* 650/30xLV 1.10.6s */
++ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempbx >>= 1;
+ }
+ tempbx--; /* RHACTE=HDE-1 */
+ temp = tempbx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2C,temp);
+- temp = (tempbx & 0xFF00) >> 8;
+- temp <<= 4;
++ temp = (tempbx & 0xFF00) >> 4;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,temp);
+
+ temp = 0x01;
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+- if(SiS_Pr->SiS_ModeType == ModeEGA) {
+- if(SiS_Pr->SiS_VGAHDE >= 1024) {
+- temp = 0x02;
+- if(HwDeviceExtension->jChipType >= SIS_315H) {
+- if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
+- temp = 0x01;
++ if(SiS_Pr->SiS_ModeType == ModeEGA) {
++ if(SiS_Pr->SiS_VGAHDE >= 1024) {
++ temp = 0x02;
++ if(HwDeviceExtension->jChipType >= SIS_315H) {
++ if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
++ temp = 0x01;
++ }
+ }
+- }
+- }
+- }
++ }
++ }
+ }
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0B,temp);
+
+- tempbx = SiS_Pr->SiS_VDE; /* RTVACTEO=(VDE-1)&0xFF */
+- push1 = tempbx;
+-
++ tempbx = SiS_Pr->SiS_VDE; /* RTVACTEO = VDE - 1 */
++ /* push1 = tempbx; */
+ tempbx--;
+ temp = tempbx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x03,temp);
+@@ -7540,10 +7762,9 @@
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,temp);
+
+ tempcx = SiS_Pr->SiS_VT;
+- push2 = tempcx;
+-
++ /* push2 = tempcx; */
+ tempcx--;
+- temp = tempcx & 0x00FF; /* RVTVT=VT-1 */
++ temp = tempcx & 0x00FF; /* RVTVT = VT - 1 */
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x19,temp);
+
+ temp = (tempcx & 0xFF00) >> 8;
+@@ -7551,40 +7772,42 @@
+
+ /* Enable dithering; newer versions only do this for 32bpp mode */
+ if((HwDeviceExtension->jChipType == SIS_300) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
+- if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp |= 0x10;
++ if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp |= 0x10;
+ } else if(HwDeviceExtension->jChipType < SIS_315H) {
+- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp |= 0x10;
+- else {
+- if(SiS_Pr->SiS_LCDInfo & LCDSync) /* TW: 630/301 BIOS checks this */
+- temp |= 0x10;
+- }
++ temp |= 0x10;
+ } else {
+- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+- /* TW: 650/30xLV 1.10.6s */
+- if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
+- if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) { /* 32bpp mode? */
+- temp |= 0x10;
+- }
+- }
+- } else {
+- temp |= 0x10;
+- }
++ if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
++ /* 650/30xLV 1.10.6s */
++ if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
++ if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) { /* 32bpp mode? */
++ temp |= 0x10;
++ }
++ }
++ } else {
++ temp |= 0x10;
++ }
+ }
+
+ /* 630/301 does not do all this */
+ if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+ if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
+- /* TW: 650/30xLV 1.10.6s */
+- temp |= (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37) >> 6);
+- temp |= 0x08; /* From 1.10.7w */
+- if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) temp |= 0x04; /* From 1.10.7w */
+- } else {
+- tempbx = (tempbx & 0xFF00) | (SiS_Pr->SiS_LCDInfo & 0x0FF);
+- if(tempbx & LCDSync) {
+- tempbx &= 0xFFE0;
+- tempbx = (tempbx & 0xFF00) | ((tempbx & 0x00FF) >> 6);
+- temp |= (tempbx & 0x00FF);
+- }
++ if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
++ (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)) {
++#ifdef SIS315H
++ if(SiS_Pr->SiS_LCDInfo & LCDSync) {
++ temp |= (SiS_Pr->SiS_LCDInfo >> 6);
++ }
++#endif
++ } else {
++ /* 650/30xLV 1.10.6s */
++ temp |= (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37) >> 6);
++ temp |= 0x08; /* From 1.10.7w */
++ if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) temp |= 0x04; /* From 1.10.7w */
++ }
++ } else {
++ if(SiS_Pr->SiS_LCDInfo & LCDSync) {
++ temp |= (SiS_Pr->SiS_LCDInfo >> 6);
++ }
+ }
+ }
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1A,temp);
+@@ -7595,24 +7818,22 @@
+ SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
+ SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
+
+- /* 1280x960, 1280x1024 and 1600x1200 data invalid/missing in tables, use old calculation */
+- if((HwDeviceExtension->jChipType >= SIS_315H) &&
+- (SiS_Pr->SiS_VBType & VB_SIS301LV302LV) &&
+- (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) &&
+- (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) &&
+- (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960)) {
++ if((HwDeviceExtension->jChipType >= SIS_315H) &&
++ (SiS_Pr->SiS_VBType & VB_SIS301LV302LV) &&
++ ((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
++ (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
++ (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
++ (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) ) {
+
+-#ifdef SIS315H /* ------------- 310/325/330 series ------------ */
++#ifdef SIS315H /* ------------- 315/330 series ------------ */
+
+- /* TW: Inserted this entire section from 650/301LV(x) BIOS */
+-
+ /* Using this on the 301B with an auto-expanding 1024 panel (CR37=1) results
+ * in a black bar in modes < 1024; if the panel is non-expanding, the bridge
+ * scales all modes to 1024. All modes in both variants (exp/non-exp) work.
+ */
+
+ SiS_GetCRT2Part2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+- &CRT2Index,&resindex);
++ &CRT2Index,&resindex,HwDeviceExtension);
+
+ switch(CRT2Index) {
+ case Panel_1024x768 : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; break; /* "Normal" */
+@@ -7627,6 +7848,9 @@
+ case Panel_1280x1024 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1280x1024_3; break;
+ case Panel_1400x1050 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1400x1050_3; break;
+ case Panel_1600x1200 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1600x1200_3; break;
++ case 100: CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Compaq1280x1024_1; break; /* Custom */
++ case 101: CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Compaq1280x1024_2; break;
++ case 102: CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Compaq1280x1024_3; break;
+ default: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_3; break;
+ }
+
+@@ -7653,8 +7877,7 @@
+ }
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0xb3);
+- }
+- if(SiS_Pr->SiS_VGAVDE == 420) {
++ } else if(SiS_Pr->SiS_VGAVDE == 420) {
+ temp = 0x4d;
+ if(SiS_Pr->SiS_ModeType <= ModeVGA) {
+ temp++;
+@@ -7664,7 +7887,6 @@
+ }
+ }
+
+- /* TW: 650/30xLV 1.10.6s: */
+ /* !!! This is a duplicate, done for LCDA as well - see above */
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+@@ -7683,59 +7905,46 @@
+ * the bridge scales all modes to 1024.
+ * !!! Malfunction at 640x480 and 640x400 when panel is auto-expanding - black screen !!!
+ */
+-
++
++ /* cx = VT - 1 */
++
+ tempcx++;
+-
+- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx = 768;
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempbx = 1024;
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempbx = 1200;
+- else if(SiS_Pr->SiS_VDE != 1024) tempbx = 960;
+- else tempbx = 1024;
+-
+-#if 0 /* old */
+- tempbx = 768;
+- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1024x768) {
+- tempbx = 1024;
+- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) {
+- tempbx = 1200;
+- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) {
+- if(tempbx != SiS_Pr->SiS_VDE) {
+- tempbx = 960;
+- }
+- }
+- }
+- }
+-#endif
+-
++
++ tempbx = SiS_Pr->PanelYRes;
++
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+- tempbx = SiS_Pr->SiS_VDE - 1;
+- tempcx--;
++ tempbx = SiS_Pr->SiS_VDE - 1;
++ tempcx--;
+ }
+-
++
+ tempax = 1;
+ if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+- if(tempbx != SiS_Pr->SiS_VDE) {
+- tempax = tempbx;
+-/* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 60; in 650/301B BIOS */
+- if(tempax < SiS_Pr->SiS_VDE) {
+- tempax = 0;
+- tempcx = 0;
+- } else {
+- tempax -= SiS_Pr->SiS_VDE;
+- }
+- tempax >>= 1;
+- }
+- tempcx -= tempax; /* lcdvdes */
+- tempbx -= tempax; /* lcdvdee */
+- } else {
+- tempax >>= 1;
+- tempcx -= tempax; /* lcdvdes */
+- tempbx -= tempax; /* lcdvdee */
++ if(tempbx != SiS_Pr->SiS_VDE) {
++ tempax = tempbx;
++ if(tempax < SiS_Pr->SiS_VDE) {
++ tempax = 0;
++ tempcx = 0;
++ } else {
++ tempax -= SiS_Pr->SiS_VDE;
++ }
++ tempax >>= 1;
++ }
++ tempcx -= tempax; /* lcdvdes */
++ tempbx -= tempax; /* lcdvdee */
+ }
+-
++#if 0 /* meaningless: 1 / 2 = 0... */
++ else {
++ tempax >>= 1;
++ tempcx -= tempax; /* lcdvdes */
++ tempbx -= tempax; /* lcdvdee */
++ }
++#endif
++
++ /* Non-expanding: lcdvdees = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
++
+ #ifdef TWDEBUG
+- xf86DrvMsg(0, X_INFO, "lcdvds 0x%x lcdvde 0x%x\n", tempcx, tempbx);
+-#endif
++ xf86DrvMsg(0, X_INFO, "lcdvdes 0x%x lcdvdee 0x%x\n", tempcx, tempbx);
++#endif
+
+ temp = tempcx & 0x00FF; /* RVEQ1EQ=lcdvdes */
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,temp);
+@@ -7746,140 +7955,178 @@
+ temp |= ((tempcx & 0xFF00) >> 8);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,temp);
+
+- tempbx = push2;
+- tempax = push1;
+- tempcx = tempbx;
+- tempcx -= tempax;
+- tempcx >>= 4;
++ tempbx = SiS_Pr->SiS_VT; /* push2; */
++ tempax = SiS_Pr->SiS_VDE; /* push1; */
++ tempcx = (tempbx - tempax) >> 4;
+ tempbx += tempax;
+ tempbx >>= 1;
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx -= 10;
+-
++
++ /* non-expanding: lcdvrs = tempbx = ((VT + VDE) / 2) - 10 */
++
++ if(SiS_Pr->UseCustomMode) {
++ tempbx = SiS_Pr->CVSyncStart;
++ }
++
+ #ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "lcdvrs 0x%x\n", tempbx);
+ #endif
+
+- temp = tempbx & 0x00FF; /* RTVACTEE=lcdvrs */
++ temp = tempbx & 0x00FF; /* RTVACTEE = lcdvrs */
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,temp);
+
+ temp = ((tempbx & 0xFF00) >> 8) << 4;
+ tempbx += (tempcx + 1);
+ temp |= (tempbx & 0x000F);
++
++ if(SiS_Pr->UseCustomMode) {
++ temp &= 0xf0;
++ temp |= (SiS_Pr->CVSyncEnd & 0x0f);
++ }
++
++#ifdef TWDEBUG
++ xf86DrvMsg(0, X_INFO, "lcdvre[3:0] 0x%x\n", (temp & 0x0f));
++#endif
++
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,temp);
+
+- /* TW: Code from 630/301B (I+II) BIOS */
++ /* Code from 630/301B (I+II) BIOS */
+
+- if( ( ( (HwDeviceExtension->jChipType == SIS_630) ||
+- (HwDeviceExtension->jChipType == SIS_730) ) &&
+- (HwDeviceExtension->jChipRevision > 2) ) &&
+- (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) &&
+- (!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) &&
+- (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
+- if(ModeNo == 0x13) {
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,0xB9);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,0xCC);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xA6);
+- } else {
+- if((crt2crtc & 0x3F) == 4) {
++ if(!SiS_Pr->UseCustomMode) {
++ if( ( ( (HwDeviceExtension->jChipType == SIS_630) ||
++ (HwDeviceExtension->jChipType == SIS_730) ) &&
++ (HwDeviceExtension->jChipRevision > 2) ) &&
++ (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) &&
++ (!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) &&
++ (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
++ if(ModeNo == 0x13) {
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,0xB9);
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,0xCC);
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xA6);
++ } else {
++ if((crt2crtc & 0x3F) == 4) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x2B);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x13);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,0xE5);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,0x08);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xE2);
+- }
+- }
++ }
++ }
++ }
+ }
+
+- /* TW: Inserted missing code from 630/301B BIOS;
+- * Strangely, this is done in all 650 BIOSes as
+- * well (although LCDTypeInfo is not used there
+- * in the same way as on 300 series)
+- */
+-
+- if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
+- crt2crtc &= 0x1f;
+- tempcx = 0;
+- if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
+- if (SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+- tempcx += 7;
+- }
+- }
+- tempcx += crt2crtc;
+- if (crt2crtc >= 4) {
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xff);
+- }
++#ifdef SIS300
++ if(HwDeviceExtension->jChipType < SIS_315H) {
++ if(!SiS_Pr->UseCustomMode) {
++ if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
++ crt2crtc &= 0x1f;
++ tempcx = 0;
++ if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
++ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
++ tempcx += 7;
++ }
++ }
++ tempcx += crt2crtc;
++ if(crt2crtc >= 4) {
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xff);
++ }
+
+- if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
+- if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+- if(crt2crtc == 4) {
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x28);
++ if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
++ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
++ if(crt2crtc == 4) {
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x28);
++ }
++ }
+ }
+- }
+- }
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x18);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x18);
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
++ }
++ }
+ }
++#endif
+
+- tempcx = (SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE) >> 2; /* (HT-HDE)>>2 */
++ tempcx = (SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE) >> 2; /* (HT - HDE) >> 2 */
+ tempbx = SiS_Pr->SiS_HDE + 7; /* lcdhdee */
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+- tempbx += 2;
++ tempbx += 2;
+ }
+ push1 = tempbx;
++
+ #ifdef TWDEBUG
+- xf86DrvMsg(0, X_INFO, "lcdhde 0x%x\n", tempbx);
+-#endif
+- temp = tempbx & 0x00FF; /* RHEQPLE=lcdhdee */
++ xf86DrvMsg(0, X_INFO, "lcdhdee 0x%x\n", tempbx);
++#endif
++
++ temp = tempbx & 0x00FF; /* RHEQPLE = lcdhdee */
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,temp);
+ temp = (tempbx & 0xFF00) >> 8;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,temp);
+
+ temp = 7;
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+- temp += 2;
++ temp += 2;
+ }
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1F,temp); /* RHBLKE=lcdhdes[7:0] */
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1F,temp); /* RHBLKE = lcdhdes[7:0] */
+ SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x20,0x0F); /* lcdhdes [11:8] */
+
+ tempbx += tempcx;
+ push2 = tempbx;
++
++ if(SiS_Pr->UseCustomMode) {
++ tempbx = SiS_Pr->CHSyncStart + 7;
++ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
++ tempbx += 2;
++ }
++ }
++
+ #ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "lcdhrs 0x%x\n", tempbx);
+ #endif
+- temp = tempbx & 0x00FF; /* RHBURSTS=lcdhrs */
+- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+- if(SiS_Pr->SiS_HDE == 1280) temp = 0x47;
++
++ temp = tempbx & 0x00FF; /* RHBURSTS = lcdhrs */
++ if(!SiS_Pr->UseCustomMode) {
++ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
++ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
++ if(SiS_Pr->SiS_HDE == 1280) temp = 0x47;
++ }
+ }
+ }
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1C,temp);
+- temp = ((tempbx & 0xFF00) >> 8) << 4;
++ temp = (tempbx & 0x0F00) >> 4;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,temp);
+
+ tempbx = push2;
+ tempcx <<= 1;
+ tempbx += tempcx;
++
++ if(SiS_Pr->UseCustomMode) {
++ tempbx = SiS_Pr->CHSyncEnd + 7;
++ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
++ tempbx += 2;
++ }
++ }
++
+ #ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "lcdhre 0x%x\n", tempbx);
+-#endif
+- temp = tempbx & 0x00FF; /* RHSYEXP2S=lcdhre */
++#endif
++
++ temp = tempbx & 0x00FF; /* RHSYEXP2S = lcdhre */
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x21,temp);
+
+ if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
+- if(SiS_Pr->SiS_VGAVDE == 525) {
+- if(SiS_Pr->SiS_ModeType <= ModeVGA)
+- temp=0xC6;
+- else
+- temp=0xC3;
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0xB3);
+- } else if(SiS_Pr->SiS_VGAVDE == 420) {
+- if(SiS_Pr->SiS_ModeType <= ModeVGA)
+- temp=0x4F;
+- else
+- temp=0x4D;
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
+- }
++ if(SiS_Pr->SiS_VGAVDE == 525) {
++ if(SiS_Pr->SiS_ModeType <= ModeVGA)
++ temp=0xC6;
++ else
++ temp=0xC3;
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0xB3);
++ } else if(SiS_Pr->SiS_VGAVDE == 420) {
++ if(SiS_Pr->SiS_ModeType <= ModeVGA)
++ temp=0x4F;
++ else
++ temp=0x4D;
++ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
++ }
+ }
+ SiS_Set300Part2Regs(SiS_Pr, HwDeviceExtension, ModeIdIndex,
+ RefreshRateTableIndex, BaseAddr, ModeNo);
+@@ -7898,7 +8145,7 @@
+ return((USHORT) tempax);
+ }
+
+-/* TW: New from 300/301LV BIOS 1.16.51 for ECS A907. Seems highly preliminary. */
++/* New from 300/301LV BIOS 1.16.51 for ECS A907. Seems highly preliminary. */
+ void
+ SiS_Set300Part2Regs(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
+@@ -7910,18 +8157,19 @@
+
+ if(HwDeviceExtension->jChipType != SIS_300) return;
+ if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
++ if(SiS_Pr->UseCustomMode) return;
+
+- if(ModeNo<=0x13) {
+- crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
++ if(ModeNo <= 0x13) {
++ crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ } else {
+- crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
++ crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+ }
+
+ resindex = crt2crtc & 0x3F;
+ if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
+ else CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
+
+- /* TW: The BIOS code (1.16.51) is obviously a fragment! */
++ /* The BIOS code (1.16.51) is obviously a fragment! */
+ if(ModeNo > 0x13) {
+ CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
+ resindex = 4;
+@@ -7942,7 +8190,6 @@
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
+ }
+
+-/* TW: Set 301 Macrovision(tm) registers */
+ void
+ SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+ USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+@@ -7954,24 +8201,35 @@
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
+
+- if(ModeNo<=0x13)
+- modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+- else
++ if(ModeNo<=0x13) {
++ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
++ } else {
++ if(SiS_Pr->UseCustomMode) {
++ modeflag = SiS_Pr->CModeFlag;
++ } else {
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++ }
++ }
+
++#ifndef SIS_CP
+ SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x00,0x00);
++#endif
++
++#ifdef SIS_CP
++ SIS_CP_INIT301_CP
++#endif
+
+ if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+- SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xFA);
+- SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xC8);
++ SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xFA);
++ SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xC8);
+ } else {
+- if(HwDeviceExtension->jChipType >= SIS_315H) {
+- SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xF5);
+- SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xB7);
+- } else {
+- SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xF6);
+- SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xBf);
+- }
++ if(HwDeviceExtension->jChipType >= SIS_315H) {
++ SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xF5);
++ SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xB7);
++ } else {
++ SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xF6);
++ SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xBf);
++ }
+ }
+
+ temp = 0;
+@@ -7982,38 +8240,41 @@
+ temp = 0x38;
+ }
+ if(temp) {
+- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+- if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
+- if(SiS_GetReg1(SiS_Pr->SiS_P3d4,temp) & EnablePALM){ /* 0x40 */
+- SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xFA);
+- SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xC8);
+- SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
+- }
+- }
+- }
++ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
++ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
++ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,temp) & EnablePALM){ /* 0x40 */
++ SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xFA);
++ SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xC8);
++ SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
++ }
++ }
++ }
+ }
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+- tempdi = SiS_Pr->SiS_HiTVGroup3Data;
+- if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+- tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
+- if(!(modeflag & Charx8Dot)) {
+- tempdi = SiS_Pr->SiS_HiTVGroup3Text;
+- }
+- }
+- if(SiS_Pr->SiS_HiVision & 0x03) {
+- tempdi = SiS_HiTVGroup3_1;
+- if(SiS_Pr->SiS_HiVision & 0x02) tempdi = SiS_HiTVGroup3_2;
+- }
+- for(i=0; i<=0x3E; i++){
+- SiS_SetReg1(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
+- }
++ tempdi = SiS_Pr->SiS_HiTVGroup3Data;
++ if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
++ tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
++ if(!(modeflag & Charx8Dot)) {
++ tempdi = SiS_Pr->SiS_HiTVGroup3Text;
++ }
++ }
++ if(SiS_Pr->SiS_HiVision & 0x03) {
++ tempdi = SiS_HiTVGroup3_1;
++ if(SiS_Pr->SiS_HiVision & 0x02) tempdi = SiS_HiTVGroup3_2;
++ }
++ for(i=0; i<=0x3E; i++){
++ SiS_SetReg1(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
++ }
+ }
+
+- return;
++#ifdef SIS_CP
++ SIS_CP_INIT301_CP2
++#endif
++
+ }
+
+-/* TW: Set 301 VGA2 registers */
++/* Set 301 VGA2 registers */
+ void
+ SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+ USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
+@@ -8022,17 +8283,20 @@
+ USHORT tempax,tempcx,tempbx,modeflag,temp,temp2,resinfo;
+ ULONG tempebx,tempeax,templong;
+
+-
+- if(ModeNo<=0x13) {
+- modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+- resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
++ if(ModeNo <= 0x13) {
++ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
++ resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+ } else {
++ if(SiS_Pr->UseCustomMode) {
++ modeflag = SiS_Pr->CModeFlag;
++ resinfo = 0;
++ } else {
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
++ }
+ }
+
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+- /* TW: From 650/302LV 1.10.6s (not for 300/301LV - no LCDA on this combination) */
+ if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x24,0x0e);
+@@ -8049,10 +8313,10 @@
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+ if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+- /* TW: From 650/301LV (any, incl. 1.10.6s, 1.10.7w) */
+- /* TW: This is a duplicate; done at the end, too */
++ /* From 650/301LV (any, incl. 1.10.6s, 1.10.7w) */
++ /* This is a duplicate; done at the end, too */
+ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) {
+- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
++ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
+ }
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
+@@ -8090,39 +8354,33 @@
+ tempbx = SiS_Pr->SiS_VGAHDE;
+ if(modeflag & HalfDCLK) tempbx >>= 1;
+
+- /* TW: New for 650/301LV and 630/301B */
+ temp = 0xA0;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+- temp = 0;
+- if(tempbx > 800) {
+- temp = 0xA0;
+- if(tempbx != 1024) {
+- temp = 0xC0;
+- if(tempbx != 1280) temp = 0;
+- }
+- }
+- } else
+- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+- if(tempbx <= 800) {
+- temp = 0x80;
+- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+- temp = 0;
+- if(tempbx > 800) temp = 0x60;
+- }
+- }
++ temp = 0;
++ if(tempbx > 800) {
++ temp = 0xA0;
++ if(tempbx != 1024) {
++ temp = 0xC0;
++ if(tempbx != 1280) temp = 0;
++ }
++ }
++ } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
++ if(tempbx <= 800) {
++ temp = 0x80;
++ }
+ } else {
+- temp = 0x80;
+- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+- temp = 0;
+- if(tempbx > 800) temp = 0x60;
+- }
++ temp = 0x80;
++ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
++ temp = 0;
++ if(tempbx > 800) temp = 0x60;
++ }
+ }
+ if(SiS_Pr->SiS_HiVision & 0x03) {
+ temp = 0;
+ if(SiS_Pr->SiS_VGAHDE == 1024) temp = 0x20;
+ }
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+- if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) temp = 0;
++ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) temp = 0;
+ }
+
+ if(SiS_Pr->SiS_VBType & VB_SIS301) {
+@@ -8144,10 +8402,10 @@
+
+ tempeax = SiS_Pr->SiS_VGAVDE;
+ tempcx |= 0x4000;
+- if(tempeax <= tempebx){
+- tempcx ^= 0x4000;
++ if(tempeax <= tempebx) {
++ tempcx ^= 0x4000;
+ } else {
+- tempeax -= tempebx;
++ tempeax -= tempebx;
+ }
+
+ templong = (tempeax * 256 * 1024) % tempebx;
+@@ -8173,64 +8431,64 @@
+ tempax = SiS_Pr->SiS_VGAHDE;
+ if(modeflag & HalfDCLK) tempax >>= 1;
+ if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) || (SiS_Pr->SiS_HiVision & 0x03)) {
+- if(HwDeviceExtension->jChipType >= SIS_315H) {
+- if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempax >>= 1;
+- else if(tempax > 800) tempax -= 800;
+- } else {
+- if(tempax > 800) tempax -= 800;
+- }
++ if(HwDeviceExtension->jChipType >= SIS_315H) {
++ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempax >>= 1;
++ else if(tempax > 800) tempax -= 800;
++ } else {
++ if(tempax > 800) tempax -= 800;
++ }
+ }
+
+ /* if((SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetPALTV)) && (!(SiS_Pr->SiS_HiVision & 0x03))) { */
+ if((SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
+- if(tempax > 800) {
+- tempbx = 8;
+- if(tempax == 1024)
+- tempax *= 25;
+- else
+- tempax *= 20;
+-
+- temp = tempax % 32;
+- tempax /= 32;
+- tempax--;
+- if (temp!=0) tempax++;
+- }
++ if(tempax > 800) {
++ tempbx = 8;
++ if(tempax == 1024)
++ tempax *= 25;
++ else
++ tempax *= 20;
++
++ temp = tempax % 32;
++ tempax /= 32;
++ tempax--;
++ if (temp!=0) tempax++;
++ }
+ }
+ tempax--;
+ temp = (tempax & 0xFF00) >> 8;
+ temp &= 0x03;
+- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* From 1.10.7w */
+- if(ModeNo > 0x13) { /* From 1.10.7w */
+- if(resinfo == 8) tempax = 0x1f; /* From 1.10.7w */
+- } /* From 1.10.7w */
+- } /* From 1.10.7w */
++ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* From 1.10.7w */
++ if(ModeNo > 0x13) { /* From 1.10.7w */
++ if(resinfo == SIS_RI_1024x768) tempax = 0x1f; /* From 1.10.7w */
++ } /* From 1.10.7w */
++ } /* From 1.10.7w */
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1D,tempax & 0x00FF);
+ temp <<= 4;
+ temp |= tempbx;
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1E,temp);
+
+ if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+- if(IS_SIS650740) {
+- temp = 0x0026; /* 1.10.7w; 1.10.8r; needs corresponding code in Dis/EnableBridge! */
++ if(IS_SIS550650740660) {
++ temp = 0x0026; /* 1.10.7w; 1.10.8r; needs corresponding code in Dis/EnableBridge! */
+ } else {
+- temp = 0x0036;
++ temp = 0x0036;
+ }
+ } else {
+- temp = 0x0036;
++ temp = 0x0036;
+ }
+ if((SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) &&
+ (!(SiS_Pr->SiS_HiVision & 0x03))) {
+- temp |= 0x01;
+- if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+- if(!(SiS_Pr->SiS_SetFlag & TVSimuMode))
+- temp &= 0xFE;
+- }
++ temp |= 0x01;
++ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
++ if(!(SiS_Pr->SiS_SetFlag & TVSimuMode))
++ temp &= 0xFE;
++ }
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0,temp);
+
+ tempbx = SiS_Pr->SiS_HT;
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+- if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempbx >>= 1;
++ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempbx >>= 1;
+ }
+ tempbx >>= 1;
+ tempbx -= 2;
+@@ -8238,7 +8496,7 @@
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
+ temp = tempbx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x22,temp);
+-
++
+ if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x24,0x0e);
+@@ -8246,24 +8504,24 @@
+ }
+
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+- /* TW: 650/LV BIOS does this for all bridge types - assumingly wrong */
+- /* 315, 330, 650+301B BIOS don't do this at all */
+- /* TW: This is a duplicate; done for LCDA as well (see above) */
+- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+- if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) {
+- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
+- }
+- SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
+- SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
+- SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
+- }
++ /* 650/LV BIOS does this for all bridge types - assumingly wrong */
++ /* 315, 330, 650+301B BIOS don't do this at all */
++ /* This is a duplicate; done for LCDA as well (see above) */
++ if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
++ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) {
++ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
++ }
++ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
++ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
++ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
++ }
+ } else if(HwDeviceExtension->jChipType == SIS_300) {
+- /* TW: 300/301LV BIOS does this for all bridge types - assumingly wrong */
+- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+- SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
+- SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
+- SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
+- }
++ /* 300/301LV BIOS does this for all bridge types - assumingly wrong */
++ if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
++ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
++ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
++ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
++ }
+ }
+
+ } /* 301B */
+@@ -8278,21 +8536,26 @@
+ USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+ {
+ USHORT vclkindex;
+- USHORT tempah;
++ USHORT temp, reg1, reg2;
+
+- vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+- HwDeviceExtension);
++ if(SiS_Pr->UseCustomMode) {
++ reg1 = SiS_Pr->CSR2B;
++ reg2 = SiS_Pr->CSR2C;
++ } else {
++ vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
++ HwDeviceExtension);
++ reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
++ reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
++ }
+
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+- tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
+- SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,tempah);
+- tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
+- SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0B,tempah);
++ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,reg1);
++ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0B,reg2);
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+- if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
++ if((ModeNo == 0x64) || (ModeNo == 0x4a) || (ModeNo == 0x38)) {
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0a,0x57);
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0b,0x46);
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
+@@ -8303,15 +8566,13 @@
+ }
+ } else {
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,0x01);
+- tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
+- SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0B,tempah);
+- tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
+- SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,tempah);
++ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0B,reg2);
++ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,reg1);
+ }
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x12,0x00);
+- tempah = 0x08;
+- if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) tempah |= 0x20;
+- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,tempah);
++ temp = 0x08;
++ if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
++ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
+ }
+
+ USHORT
+@@ -8319,23 +8580,24 @@
+ USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+ {
+ USHORT tempbx;
+- const USHORT LCDXlat0VCLK[4] = {VCLK40, VCLK40, VCLK40, VCLK40};
+- const USHORT LVDSXlat1VCLK[4] = {VCLK40, VCLK40, VCLK40, VCLK40};
++ const USHORT LCDXlat0VCLK[4] = {VCLK40, VCLK40, VCLK40, VCLK40};
++ const USHORT LVDSXlat1VCLK[4] = {VCLK40, VCLK40, VCLK40, VCLK40};
++ const USHORT LVDSXlat4VCLK[4] = {VCLK28, VCLK28, VCLK28, VCLK28};
+ #ifdef SIS300
+- const USHORT LCDXlat1VCLK300[4] = {VCLK65, VCLK65, VCLK65, VCLK65};
+- const USHORT LCDXlat2VCLK300[4] = {VCLK108_2,VCLK108_2,VCLK108_2,VCLK108_2};
+- const USHORT LVDSXlat2VCLK300[4]= {VCLK65, VCLK65, VCLK65, VCLK65};
+- const USHORT LVDSXlat3VCLK300[4]= {VCLK65, VCLK65, VCLK65, VCLK65};
++ const USHORT LCDXlat1VCLK300[4] = {VCLK65_300, VCLK65_300, VCLK65_300, VCLK65_300};
++ const USHORT LCDXlat2VCLK300[4] = {VCLK108_2_300,VCLK108_2_300,VCLK108_2_300,VCLK108_2_300};
++ const USHORT LVDSXlat2VCLK300[4]= {VCLK65_300, VCLK65_300, VCLK65_300, VCLK65_300};
++ const USHORT LVDSXlat3VCLK300[4]= {VCLK65_300, VCLK65_300, VCLK65_300, VCLK65_300};
+ #endif
+ #ifdef SIS315H
+- const USHORT LCDXlat1VCLK310[4] = {VCLK65+2, VCLK65+2, VCLK65+2, VCLK65+2};
+- const USHORT LCDXlat2VCLK310[4] = {VCLK108_2+5,VCLK108_2+5,VCLK108_2+5,VCLK108_2+5};
+- const USHORT LVDSXlat2VCLK310[4]= {VCLK65+2, VCLK65+2, VCLK65+2, VCLK65+2};
+- const USHORT LVDSXlat3VCLK310[4]= {VCLK108_2+5,VCLK108_2+5,VCLK108_2+5,VCLK108_2+5};
++ const USHORT LCDXlat1VCLK310[4] = {VCLK65_315, VCLK65_315, VCLK65_315, VCLK65_315};
++ const USHORT LCDXlat2VCLK310[4] = {VCLK108_2_315,VCLK108_2_315,VCLK108_2_315,VCLK108_2_315};
++ const USHORT LVDSXlat2VCLK310[4]= {VCLK65_315, VCLK65_315, VCLK65_315, VCLK65_315};
++ const USHORT LVDSXlat3VCLK310[4]= {VCLK108_2_315,VCLK108_2_315,VCLK108_2_315,VCLK108_2_315};
+ #endif
+ USHORT CRT2Index,VCLKIndex=0;
+ USHORT modeflag,resinfo;
+- const UCHAR *CHTVVCLKPtr=NULL;
++ const UCHAR *CHTVVCLKPtr = NULL;
+ const USHORT *LCDXlatVCLK1 = NULL;
+ const USHORT *LCDXlatVCLK2 = NULL;
+ const USHORT *LVDSXlatVCLK2 = NULL;
+@@ -8372,33 +8634,40 @@
+ if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
+
+ CRT2Index >>= 6;
+- if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)){ /* LCD */
++ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* LCD */
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)
++ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
+ VCLKIndex = LCDXlat0VCLK[CRT2Index];
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)
++ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+ VCLKIndex = LCDXlatVCLK1[CRT2Index];
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)
++ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
+ VCLKIndex = LCDXlatVCLK1[CRT2Index];
+- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)
++ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
+ VCLKIndex = LCDXlatVCLK1[CRT2Index];
+- else
++ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
++ VCLKIndex = VCLK81_300; /* guessed */
++ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
++ VCLKIndex = VCLK108_3_300;
++ if(resinfo == SIS_RI_1280x1024) VCLKIndex = VCLK100_300;
++ } else {
+ VCLKIndex = LCDXlatVCLK2[CRT2Index];
++ }
+ } else {
+- /* TW: 330, 650/301LV BIOS does not check expanding, 315 does */
+- if( (HwDeviceExtension->jChipType > SIS_315PRO) ||
++ if( (SiS_Pr->SiS_VBType & VB_SIS301LV302LV) ||
+ (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+- VCLKIndex = 0x19;
++ VCLKIndex = VCLK108_2_315;
++ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
++ VCLKIndex = VCLK81_315; /* guessed */
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+- VCLKIndex = 0x19;
++ VCLKIndex = VCLK108_2_315;
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+- VCLKIndex = 0x21;
++ VCLKIndex = VCLK162_315;
++ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
++ VCLKIndex = VCLK108_3_315;
++ if(resinfo == SIS_RI_1280x1024) VCLKIndex = VCLK100_315;
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+ VCLKIndex = LCDXlatVCLK1[CRT2Index];
+- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
+- VCLKIndex = 0x45; /* TW: in VBVCLK table */
+- if(resinfo == 0x09) VCLKIndex++;
+ } else {
+ VCLKIndex = LCDXlatVCLK2[CRT2Index];
+ }
+@@ -8408,12 +8677,18 @@
+ if(ModeNo > 0x13) {
+ VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+ }
+- if(ModeNo <= 0x13) { /* TW: 315 BIOS */
+- if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
++ if(ModeNo <= 0x13) {
++ if(HwDeviceExtension->jChipType <= SIS_315PRO) {
++ if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
++ } else {
++ if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
++ }
++ }
++ if(HwDeviceExtension->jChipType <= SIS_315PRO) {
++ if(VCLKIndex == 0) VCLKIndex = 0x41;
++ if(VCLKIndex == 1) VCLKIndex = 0x43;
++ if(VCLKIndex == 4) VCLKIndex = 0x44;
+ }
+- if(VCLKIndex == 0) VCLKIndex = 0x41;
+- if(VCLKIndex == 1) VCLKIndex = 0x43;
+- if(VCLKIndex == 4) VCLKIndex = 0x44;
+ }
+ }
+ } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* TV */
+@@ -8429,9 +8704,11 @@
+ if(SiS_Pr->SiS_SetFlag & RPLLDIV2XO) VCLKIndex = TVVCLKDIV2;
+ else VCLKIndex = TVVCLK;
+ }
+- if(HwDeviceExtension->jChipType >= SIS_315H) {
+- VCLKIndex += 25;
+- }
++ if(HwDeviceExtension->jChipType < SIS_315H) {
++ VCLKIndex += TVCLKBASE_300;
++ } else {
++ VCLKIndex += TVCLKBASE_315;
++ }
+ } else { /* RAMDAC2 */
+ VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02));
+ VCLKIndex = ((VCLKIndex >> 2) & 0x03);
+@@ -8441,7 +8718,11 @@
+ VCLKIndex &= 0x3f;
+ if( (HwDeviceExtension->jChipType == SIS_630) &&
+ (HwDeviceExtension->jChipRevision >= 0x30)) {
+- if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
++ /* This is certainly wrong: It replaces clock
++ * 108 by 47...
++ */
++ /* if(VCLKIndex == 0x14) VCLKIndex = 0x2e; */
++ if(VCLKIndex == 0x14) VCLKIndex = 0x34;
+ }
+ }
+ }
+@@ -8505,6 +8786,10 @@
+ if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) ||
+ (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480))
+ VCLKIndex = LVDSXlat1VCLK[VCLKIndex];
++ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480 ||
++ SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
++ SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3)
++ VCLKIndex = LVDSXlat4VCLK[VCLKIndex];
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)
+ VCLKIndex = LVDSXlatVCLK2[VCLKIndex];
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)
+@@ -8513,6 +8798,21 @@
+ VCLKIndex = LVDSXlatVCLK2[VCLKIndex];
+ else VCLKIndex = LVDSXlatVCLK3[VCLKIndex];
+
++ if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
++ /* Special Timing: Barco iQ Pro R300/400/... */
++ VCLKIndex = 0x44;
++ }
++
++ if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
++ if(HwDeviceExtension->jChipType < SIS_315H) {
++ VCLKIndex = VCLK34_300;
++ /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
++ } else {
++ VCLKIndex = VCLK34_315;
++ /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
++ }
++ }
++
+ } else {
+
+ VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02));
+@@ -8556,11 +8856,11 @@
+ #ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex);
+ #endif
+- return (VCLKIndex);
++ return(VCLKIndex);
+ }
+
+-/* TW: Set 301 Palette address port registers */
+-/* TW: Checked against 650/301LV BIOS */
++/* Set 301 Palette address port registers */
++/* Checked against 650/301LV BIOS */
+ void
+ SiS_SetGroup5(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
+ UCHAR *ROMAddr, USHORT ModeNo, USHORT ModeIdIndex)
+@@ -8568,7 +8868,7 @@
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
+
+- if(SiS_Pr->SiS_ModeType == ModeVGA){
++ if(SiS_Pr->SiS_ModeType == ModeVGA) {
+ if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))){
+ SiS_EnableCRT2(SiS_Pr);
+ SiS_LoadDAC(SiS_Pr,HwDeviceExtension,ROMAddr,ModeNo,ModeIdIndex);
+@@ -8581,17 +8881,22 @@
+ USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+ {
+ USHORT temp,tempah,i,modeflag,j;
+- USHORT ResInfo,DisplayType;
++ USHORT ResIndex,DisplayType;
+ const SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL;
+
+ if(ModeNo <= 0x13) {
+- modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
++ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ } else {
+- modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ }
+
++ if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
++ (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
++ (SiS_Pr->SiS_CustomT == CUT_PANEL848))
++ return;
++
+ temp = SiS_GetLVDSCRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+- &ResInfo,&DisplayType);
++ &ResIndex,&DisplayType);
+
+ if(temp == 0) return;
+
+@@ -8639,47 +8944,53 @@
+ case 41: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_1_H; break;
+ case 42: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2; break;
+ case 43: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2_H; break;
++ case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1; break;
++ case 51: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H; break;
++ case 52: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2; break;
++ case 53: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2_H; break;
++ case 54: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3; break;
++ case 55: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3_H; break;
+ case 99: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL; break;
+ default: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1; break;
+ }
+
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f); /*unlock cr0-7 */
+
+- tempah = (LVDSCRT1Ptr+ResInfo)->CR[0];
++ tempah = (LVDSCRT1Ptr + ResIndex)->CR[0];
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,tempah);
+
+ for(i=0x02,j=1;i<=0x05;i++,j++){
+- tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
++ tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
+ }
+ for(i=0x06,j=5;i<=0x07;i++,j++){
+- tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
++ tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
+ }
+ for(i=0x10,j=7;i<=0x11;i++,j++){
+- tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
++ tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
+ }
+ for(i=0x15,j=9;i<=0x16;i++,j++){
+- tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
++ tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
+ }
+ for(i=0x0A,j=11;i<=0x0C;i++,j++){
+- tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
++ tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,i,tempah);
+ }
+
+- tempah = (LVDSCRT1Ptr+ResInfo)->CR[14];
++ tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
+ tempah &= 0xE0;
+- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
++ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
+
+- tempah = (LVDSCRT1Ptr+ResInfo)->CR[14];
++ tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
+ tempah &= 0x01;
+ tempah <<= 5;
+ if(modeflag & DoubleScanMode) tempah |= 0x080;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
+
+- /* TW: 650/LVDS BIOS - doesn't make sense */
++ /* 650/LVDS BIOS - doesn't make sense */
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ if(modeflag & HalfDCLK)
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
+@@ -8688,7 +8999,7 @@
+
+ BOOLEAN
+ SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex,USHORT *ResInfo,
++ USHORT RefreshRateTableIndex,USHORT *ResIndex,
+ USHORT *DisplayType)
+ {
+ USHORT tempbx,modeflag=0;
+@@ -8757,19 +9068,33 @@
+ tempbx = 40;
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
+ if(modeflag & HalfDCLK) tempbx++;
++ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) {
++ tempbx = 54;
++ if(modeflag & HalfDCLK) tempbx++;
++ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2) {
++ tempbx = 52;
++ if(modeflag & HalfDCLK) tempbx++;
++ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
++ tempbx = 50;
++ if(modeflag & HalfDCLK) tempbx++;
+ }
++
+ }
+ if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+ tempbx = 12;
+ if(modeflag & HalfDCLK) tempbx++;
+ }
+ }
+- if(SiS_Pr->SiS_IF_DEF_FSTN){
++
++#if 0
++ if(SiS_Pr->SiS_IF_DEF_FSTN) {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){
+ tempbx = 22;
+ }
+ }
+- *ResInfo = CRT2CRTC & 0x3F;
++#endif
++
++ *ResIndex = CRT2CRTC & 0x3F;
+ *DisplayType = tempbx;
+ return 1;
+ }
+@@ -8778,54 +9103,54 @@
+ SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+ {
+- USHORT tempah,tempal,pushax;
+- USHORT vclkindex=0;
+-
++ USHORT clkbase, vclkindex=0;
++ UCHAR sr2b, sr2c;
++
+ if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) || (SiS_Pr->SiS_IF_DEF_TRUMPION == 1)) {
+ SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
+- tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+- tempal &= 0x3F;
+- if(tempal == 2) RefreshRateTableIndex--;
++ if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK & 0x3f) == 2) {
++ RefreshRateTableIndex--;
++ }
+ vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+- RefreshRateTableIndex,HwDeviceExtension);
++ RefreshRateTableIndex,HwDeviceExtension);
+ SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+ } else {
+ vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+- RefreshRateTableIndex,HwDeviceExtension);
++ RefreshRateTableIndex,HwDeviceExtension);
+ }
+-
+- tempal = 0x02B;
++
++ sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
++ sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
++
++ if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
++ if((ROMAddr) && SiS_Pr->SiS_UseROM) {
++ if(ROMAddr[0x220] & 0x01) {
++ sr2b = ROMAddr[0x227];
++ sr2c = ROMAddr[0x228];
++ }
++ }
++ }
++
++ clkbase = 0x02B;
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+ if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+- tempal += 3;
++ clkbase += 3;
+ }
+ }
++
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
+- pushax = tempal;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x20);
+- tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
+- SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
+- tempal++;
+- tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
+- SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
++ SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase,sr2b);
++ SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x10);
+- tempal = pushax;
+- tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
+- SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
+- tempal++;
+- tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
+- SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
++ SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase,sr2b);
++ SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x00);
+- tempal = pushax;
+- tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
+- SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
+- tempal++;
+- tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
+- SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
+- return;
++ SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase,sr2b);
++ SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
+ }
+
+-#if 0 /* TW: Not used */
++#if 0 /* Not used */
+ void
+ SiS_SetDefCRT2ExtRegs(SiS_Private *SiS_Pr, USHORT BaseAddr)
+ {
+@@ -8844,7 +9169,7 @@
+ }
+ #endif
+
+-/* TW: Start of Chrontel 70xx functions ---------------------- */
++/* Start of Chrontel 70xx functions ---------------------- */
+
+ /* Set-up the Chrontel Registers */
+ void
+@@ -8890,44 +9215,44 @@
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
+
+ #ifdef SIS300
+-
+- /* Chrontel 7005 - I assume that it does not come with a 310/325 series chip */
+
+- /* TW: We don't support modes >800x600 */
++ /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
++
++ /* We don't support modes >800x600 */
+ if (resindex > 5) return;
+
+ if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+- SiS_SetCH700x(SiS_Pr,0x4304); /* TW: 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
+- SiS_SetCH700x(SiS_Pr,0x6909); /* TW: Black level for PAL (105)*/
++ SiS_SetCH700x(SiS_Pr,0x4304); /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
++ SiS_SetCH700x(SiS_Pr,0x6909); /* Black level for PAL (105)*/
+ } else {
+- SiS_SetCH700x(SiS_Pr,0x0304); /* TW: upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
+- SiS_SetCH700x(SiS_Pr,0x7109); /* TW: Black level for NTSC (113)*/
++ SiS_SetCH700x(SiS_Pr,0x0304); /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
++ SiS_SetCH700x(SiS_Pr,0x7109); /* Black level for NTSC (113)*/
+ }
+
+ temp = CHTVRegData[resindex].Reg[0];
+- tempbx=((temp&0x00FF)<<8)|0x00; /* TW: Mode register */
++ tempbx=((temp&0x00FF)<<8)|0x00; /* Mode register */
+ SiS_SetCH700x(SiS_Pr,tempbx);
+ temp = CHTVRegData[resindex].Reg[1];
+- tempbx=((temp&0x00FF)<<8)|0x07; /* TW: Start active video register */
++ tempbx=((temp&0x00FF)<<8)|0x07; /* Start active video register */
+ SiS_SetCH700x(SiS_Pr,tempbx);
+ temp = CHTVRegData[resindex].Reg[2];
+- tempbx=((temp&0x00FF)<<8)|0x08; /* TW: Position overflow register */
++ tempbx=((temp&0x00FF)<<8)|0x08; /* Position overflow register */
+ SiS_SetCH700x(SiS_Pr,tempbx);
+ temp = CHTVRegData[resindex].Reg[3];
+- tempbx=((temp&0x00FF)<<8)|0x0A; /* TW: Horiz Position register */
++ tempbx=((temp&0x00FF)<<8)|0x0A; /* Horiz Position register */
+ SiS_SetCH700x(SiS_Pr,tempbx);
+ temp = CHTVRegData[resindex].Reg[4];
+- tempbx=((temp&0x00FF)<<8)|0x0B; /* TW: Vertical Position register */
++ tempbx=((temp&0x00FF)<<8)|0x0B; /* Vertical Position register */
+ SiS_SetCH700x(SiS_Pr,tempbx);
+
+- /* TW: Set minimum flicker filter for Luma channel (SR1-0=00),
++ /* Set minimum flicker filter for Luma channel (SR1-0=00),
+ minimum text enhancement (S3-2=10),
+ maximum flicker filter for Chroma channel (S5-4=10)
+ =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
+ */
+ SiS_SetCH700x(SiS_Pr,0x2801);
+
+- /* TW: Set video bandwidth
++ /* Set video bandwidth
+ High bandwith Luma composite video filter(S0=1)
+ low bandwith Luma S-video filter (S2-1=00)
+ disable peak filter in S-video channel (S3=0)
+@@ -8936,22 +9261,24 @@
+ */
+ SiS_SetCH700x(SiS_Pr,0xb103); /* old: 3103 */
+
+- /* TW: Register 0x3D does not exist in non-macrovision register map
++ /* Register 0x3D does not exist in non-macrovision register map
+ (Maybe this is a macrovision register?)
+ */
+- /* SiS_SetCH70xx(SiS_Pr,0x003D); */
++#ifndef SIS_CP
++ SiS_SetCH70xx(SiS_Pr,0x003D);
++#endif
+
+- /* TW: Register 0x10 only contains 1 writable bit (S0) for sensing,
++ /* Register 0x10 only contains 1 writable bit (S0) for sensing,
+ all other bits a read-only. Macrovision?
+ */
+ SiS_SetCH70xxANDOR(SiS_Pr,0x0010,0x1F);
+
+- /* TW: Register 0x11 only contains 3 writable bits (S0-S2) for
++ /* Register 0x11 only contains 3 writable bits (S0-S2) for
+ contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
+ */
+ SiS_SetCH70xxANDOR(SiS_Pr,0x0211,0xF8);
+
+- /* TW: Clear DSEN
++ /* Clear DSEN
+ */
+ SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xEF);
+
+@@ -8994,7 +9321,7 @@
+ }
+ }
+ } else { /* ---- PAL ---- */
+- /* TW: We don't play around with FSCI in PAL mode */
++ /* We don't play around with FSCI in PAL mode */
+ if (resindex == 0x04) {
+ SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
+ SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE); /* ACIV on */
+@@ -9012,7 +9339,7 @@
+
+ #ifdef SIS315H
+
+- /* TW: We don't support modes >1024x768 */
++ /* We don't support modes >1024x768 */
+ if (resindex > 6) return;
+
+ temp = CHTVRegData[resindex].Reg[0];
+@@ -9082,26 +9409,29 @@
+ #endif /* 315 */
+
+ }
++
++#ifdef SIS_CP
++ SIS_CP_INIT301_CP3
++#endif
++
+ }
+
+-/* TW: Chrontel 701x functions ================================= */
++/* Chrontel 701x functions ================================= */
+
+ void
+-SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr)
++SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+ {
+-#ifndef NEWCH701x
+ USHORT temp;
+-#endif
+
+- /* TW: Enable Chrontel 7019 LCD panel backlight */
++ /* Enable Chrontel 7019 LCD panel backlight */
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+-#ifdef NEWCH701x
++ if(HwDeviceExtension->jChipType == SIS_740) {
+ SiS_SetCH701x(SiS_Pr,0x6566);
+-#else
++ } else {
+ temp = SiS_GetCH701x(SiS_Pr,0x66);
+ temp |= 0x20;
+ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
+-#endif
++ }
+ }
+ }
+
+@@ -9110,7 +9440,7 @@
+ {
+ USHORT temp;
+
+- /* TW: Disable Chrontel 7019 LCD panel backlight */
++ /* Disable Chrontel 7019 LCD panel backlight */
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+ temp = SiS_GetCH701x(SiS_Pr,0x66);
+ temp &= 0xDF;
+@@ -9118,47 +9448,54 @@
+ }
+ }
+
+-#ifdef SIS315H /* -------- 310/325 series only --------- */
++#ifdef SIS315H /* ----------- 315 series only ---------- */
+
+ void
+ SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
+ {
+-#ifdef NEWCH701x
+- UCHAR regtable[] = { 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
+- 0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66 };
+- UCHAR table1024[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
+- 0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44 };
+- UCHAR table1280[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
+- 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
+- UCHAR table1400[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
+- 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
+- UCHAR table1600[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
+- 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44 };
+-#else
+- UCHAR regtable[] = { 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
+- 0x72, 0x73, 0x74, 0x76, 0x78, 0x7d };
+- UCHAR table1024[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
+- 0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02 };
+- UCHAR table1280[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
+- 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02 };
+- UCHAR table1400[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
+- 0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02 };
+- UCHAR table1600[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
+- 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a };
+-#endif
++ UCHAR regtable[] = { 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
++ 0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66 };
++ UCHAR table1024_740[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
++ 0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44 };
++ UCHAR table1280_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
++ 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
++ UCHAR table1400_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
++ 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
++ UCHAR table1600_740[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
++ 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44 };
++ UCHAR table1024_650[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
++ 0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02 };
++ UCHAR table1280_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
++ 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02 };
++ UCHAR table1400_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
++ 0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02 };
++ UCHAR table1600_650[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
++ 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a };
+ UCHAR *tableptr = NULL;
+ USHORT tempbh;
+ int i;
+
+- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+- tableptr = table1024;
+- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+- tableptr = table1280;
+- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+- tableptr = table1400;
+- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+- tableptr = table1600;
+- } else return;
++ if(HwDeviceExtension->jChipType == SIS_740) {
++ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
++ tableptr = table1024_740;
++ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
++ tableptr = table1280_740;
++ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
++ tableptr = table1400_740;
++ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
++ tableptr = table1600_740;
++ } else return;
++ } else {
++ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
++ tableptr = table1024_650;
++ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
++ tableptr = table1280_650;
++ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
++ tableptr = table1400_650;
++ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
++ tableptr = table1600_650;
++ } else return;
++ }
+
+ tempbh = SiS_GetCH701x(SiS_Pr,0x74);
+ if((tempbh == 0xf6) || (tempbh == 0xc7)) {
+@@ -9172,54 +9509,64 @@
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) return;
+ }
+ }
+-#ifdef NEWCH701x /* New from 740/LVDS: */
+- for(i=0; i<0x0d; i++) {
+-#else
+- for(i=0; i<0x0c; i++) {
+-#endif
++
++ if(HwDeviceExtension->jChipType == SIS_740) {
++ tempbh = 0x0d;
++ } else {
++ tempbh = 0x0c;
++ }
++ for(i = 0; i < tempbh; i++) {
+ SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
+ }
+- SiS_ChrontelPowerSequencing(SiS_Pr);
++ SiS_ChrontelPowerSequencing(SiS_Pr,HwDeviceExtension);
+ tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
+ tempbh |= 0xc0;
+ SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1e);
+-
+-#ifdef NEWCH701x /* 740/LVDS: */
+- tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
+- tempbh &= 0xfb;
+- SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1c);
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port, 0x2d, 0x03);
+- tempbh = SiS_GetCH701x(SiS_Pr,0x64);
+- tempbh |= 0x40;
+- SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x64);
+- tempbh = SiS_GetCH701x(SiS_Pr,0x03);
+- tempbh &= 0x3f;
+- SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x03);
+-#endif /* End 740/LVDS */
++
++ if(HwDeviceExtension->jChipType == SIS_740) {
++ tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
++ tempbh &= 0xfb;
++ SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1c);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2d,0x03);
++ tempbh = SiS_GetCH701x(SiS_Pr,0x64);
++ tempbh |= 0x40;
++ SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x64);
++ tempbh = SiS_GetCH701x(SiS_Pr,0x03);
++ tempbh &= 0x3f;
++ SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x03);
++ }
+ }
+
+ void
+-SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr)
+-{
+- UCHAR regtable[] = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
+-#ifdef NEWCH701x
+- UCHAR table1024[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
+- UCHAR table1400[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
+-#else
+- UCHAR table1024[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
+- UCHAR table1400[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
+-#endif
++SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
++{
++ UCHAR regtable[] = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
++ UCHAR table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
++ UCHAR table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
++ UCHAR table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
++ UCHAR table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
+ UCHAR *tableptr = NULL;
+ int i;
+
+ /* Set up Power up/down timing */
+- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+- tableptr = table1024;
+- } else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
+- (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
+- (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) {
+- tableptr = table1400;
+- } else return;
++
++ if(HwDeviceExtension->jChipType == SIS_740) {
++ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
++ tableptr = table1024_740;
++ } else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
++ (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
++ (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) {
++ tableptr = table1400_740;
++ } else return;
++ } else {
++ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
++ tableptr = table1024_650;
++ } else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
++ (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
++ (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) {
++ tableptr = table1400_650;
++ } else return;
++ }
+
+ for(i=0; i<5; i++) {
+ SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
+@@ -9232,66 +9579,72 @@
+ USHORT temp;
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+-#ifdef NEWCH701x
+- temp = SiS_GetCH701x(SiS_Pr,0x1c);
+- temp |= 0x04;
+- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
+-#endif
++ if(HwDeviceExtension->jChipType == SIS_740) {
++ temp = SiS_GetCH701x(SiS_Pr,0x1c);
++ temp |= 0x04;
++ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
++ }
+ if(SiS_IsYPbPr(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ temp = SiS_GetCH701x(SiS_Pr,0x01);
+ temp &= 0x3f;
+- temp |= 0x80; /* TW: Enable YPrPb (HDTV) */
++ temp |= 0x80; /* Enable YPrPb (HDTV) */
+ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
+ }
+ if(SiS_IsChScart(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ temp = SiS_GetCH701x(SiS_Pr,0x01);
+ temp &= 0x3f;
+- temp |= 0xc0; /* TW: Enable SCART + CVBS */
++ temp |= 0xc0; /* Enable SCART + CVBS */
+ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
+ }
+-#ifdef NEWCH701x
+- SiS_ChrontelDoSomething5(SiS_Pr);
+- SiS_SetCH701x(SiS_Pr,0x2049); /* TW: Enable TV path */
+-#else
+- SiS_SetCH701x(SiS_Pr,0x2049); /* TW: Enable TV path */
+- temp = SiS_GetCH701x(SiS_Pr,0x49);
+- if(SiS_IsYPbPr(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+- temp = SiS_GetCH701x(SiS_Pr,0x73);
+- temp |= 0x60;
+- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x73);
++ if(HwDeviceExtension->jChipType == SIS_740) {
++ SiS_ChrontelDoSomething5(SiS_Pr);
++ SiS_SetCH701x(SiS_Pr,0x2049); /* Enable TV path */
++ } else {
++ SiS_SetCH701x(SiS_Pr,0x2049); /* Enable TV path */
++ temp = SiS_GetCH701x(SiS_Pr,0x49);
++ if(SiS_IsYPbPr(SiS_Pr,HwDeviceExtension, BaseAddr)) {
++ temp = SiS_GetCH701x(SiS_Pr,0x73);
++ temp |= 0x60;
++ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x73);
++ }
++ temp = SiS_GetCH701x(SiS_Pr,0x47);
++ temp &= 0x7f;
++ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
++ SiS_LongDelay(SiS_Pr,2);
++ temp = SiS_GetCH701x(SiS_Pr,0x47);
++ temp |= 0x80;
++ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
+ }
+- temp = SiS_GetCH701x(SiS_Pr,0x47);
+- temp &= 0x7f;
+- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
+- SiS_LongDelay(SiS_Pr,2);
+- temp = SiS_GetCH701x(SiS_Pr,0x47);
+- temp |= 0x80;
+- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
+-#endif
+ }
+ }
+
+ void
+-SiS_Chrontel701xOff(SiS_Private *SiS_Pr)
++SiS_Chrontel701xOff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+ {
+ USHORT temp;
+
++ /* Complete power down of LVDS */
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
++ if(HwDeviceExtension->jChipType == SIS_740) {
++ SiS_LongDelay(SiS_Pr,1);
++ SiS_GenericDelay(SiS_Pr,0x16ff);
++ SiS_SetCH701x(SiS_Pr,0xac76);
++ SiS_SetCH701x(SiS_Pr,0x0066);
++ } else {
+ SiS_LongDelay(SiS_Pr,2);
+- /* TW: Complete power down of LVDS */
+ temp = SiS_GetCH701x(SiS_Pr,0x76);
+ temp &= 0xfc;
+ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
+ SiS_SetCH701x(SiS_Pr,0x0066);
++ }
+ }
+ }
+
+-#ifdef NEWCH701x
+ void
+ SiS_ChrontelDoSomething5(SiS_Private *SiS_Pr)
+ {
+ unsigned char temp, temp1;
+-
++
+ temp1 = SiS_GetCH701x(SiS_Pr,0x49);
+ SiS_SetCH701x(SiS_Pr,0x3e49);
+ temp = SiS_GetCH701x(SiS_Pr,0x47);
+@@ -9303,130 +9656,134 @@
+ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
+ SiS_SetCH701x(SiS_Pr,(temp1 << 8) | 0x49);
+ }
+-#endif
+
+ void
+ SiS_ChrontelResetDB(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+ {
+-#ifdef NEWCH701x
+ USHORT temp;
+-
+- /* 740/LVDS: */
+- temp = SiS_GetCH701x(SiS_Pr,0x4a);
+- temp &= 0x01;
+- if(!(temp)) {
+-
+- if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+- temp = SiS_GetCH701x(SiS_Pr,0x49);
+- SiS_SetCH701x(SiS_Pr,0x3e49);
+- }
+- /* TW: Reset Chrontel 7019 datapath */
++
++ if(HwDeviceExtension->jChipType == SIS_740) {
++ temp = SiS_GetCH701x(SiS_Pr,0x4a);
++ temp &= 0x01;
++ if(!(temp)) {
++
++ if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
++ temp = SiS_GetCH701x(SiS_Pr,0x49);
++ SiS_SetCH701x(SiS_Pr,0x3e49);
++ }
++ /* Reset Chrontel 7019 datapath */
++ SiS_SetCH701x(SiS_Pr,0x1048);
++ SiS_LongDelay(SiS_Pr,1);
++ SiS_SetCH701x(SiS_Pr,0x1848);
++
++ if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
++ SiS_ChrontelDoSomething5(SiS_Pr);
++ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x49);
++ }
++
++ } else {
++
++ temp = SiS_GetCH701x(SiS_Pr,0x5c);
++ temp &= 0xef;
++ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
++ temp = SiS_GetCH701x(SiS_Pr,0x5c);
++ temp |= 0x10;
++ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
++ temp = SiS_GetCH701x(SiS_Pr,0x5c);
++ temp &= 0xef;
++ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
++ temp = SiS_GetCH701x(SiS_Pr,0x61);
++ if(!temp) {
++ SiS_SetCH701xForLCD(SiS_Pr,HwDeviceExtension,BaseAddr);
++ }
++ }
++ } else { /* 650 */
++ /* Reset Chrontel 7019 datapath */
+ SiS_SetCH701x(SiS_Pr,0x1048);
+ SiS_LongDelay(SiS_Pr,1);
+ SiS_SetCH701x(SiS_Pr,0x1848);
+-
+- if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+- SiS_ChrontelDoSomething5(SiS_Pr);
+- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x49);
+- }
+- } else {
+-
+- temp = SiS_GetCH701x(SiS_Pr,0x5c);
+- temp &= 0xef;
+- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
+- temp = SiS_GetCH701x(SiS_Pr,0x5c);
+- temp |= 0x10;
+- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
+- temp = SiS_GetCH701x(SiS_Pr,0x5c);
+- temp &= 0xef;
+- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
+- temp = SiS_GetCH701x(SiS_Pr,0x61);
+- if(!temp) {
+- SiS_SetCH701xForLCD(SiS_Pr,HwDeviceExtension,BaseAddr);
+- }
+- }
+-#else /* pre 740/LVDS code */
+- /* TW: Reset Chrontel 7019 datapath */
+- SiS_SetCH701x(SiS_Pr,0x1048);
+- SiS_LongDelay(SiS_Pr,1);
+- SiS_SetCH701x(SiS_Pr,0x1848);
+-#endif
++ }
+ }
+
+ void
+ SiS_ChrontelDoSomething4(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+ {
+-#ifdef NEWCH701x
+- if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+- SiS_ChrontelDoSomething5(SiS_Pr);
+- }
+-#else
+ USHORT temp;
+
+- SiS_SetCH701x(SiS_Pr,0xaf76); /* Power up LVDS block */
+- temp = SiS_GetCH701x(SiS_Pr,0x49);
+- temp &= 1;
+- if(temp != 1) { /* TV block powered? (0 = yes, 1 = no) */
+- temp = SiS_GetCH701x(SiS_Pr,0x47);
+- temp &= 0x70;
+- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47); /* enable VSYNC */
+- SiS_LongDelay(SiS_Pr,3);
+- temp = SiS_GetCH701x(SiS_Pr,0x47);
+- temp |= 0x80;
+- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47); /* disable VSYNC */
++ if(HwDeviceExtension->jChipType == SIS_740) {
++
++ if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
++ SiS_ChrontelDoSomething5(SiS_Pr);
++ }
++
++ } else {
++
++ SiS_SetCH701x(SiS_Pr,0xaf76); /* Power up LVDS block */
++ temp = SiS_GetCH701x(SiS_Pr,0x49);
++ temp &= 1;
++ if(temp != 1) { /* TV block powered? (0 = yes, 1 = no) */
++ temp = SiS_GetCH701x(SiS_Pr,0x47);
++ temp &= 0x70;
++ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47); /* enable VSYNC */
++ SiS_LongDelay(SiS_Pr,3);
++ temp = SiS_GetCH701x(SiS_Pr,0x47);
++ temp |= 0x80;
++ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47); /* disable VSYNC */
++ }
++
+ }
+-#endif
+ }
+
+ void
+ SiS_ChrontelDoSomething3(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT BaseAddr)
+ {
+-#ifdef NEWCH701x
+- USHORT temp;
+-
+- temp = SiS_GetCH701x(SiS_Pr,0x61);
+- if(temp < 1) {
+- temp++;
+- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
+- }
+- SiS_SetCH701x(SiS_Pr,0x4566);
+- SiS_SetCH701x(SiS_Pr,0xaf76);
+- SiS_LongDelay(SiS_Pr,1);
+- SiS_GenericDelay(SiS_Pr,0x16ff);
+-
+-#else
+ USHORT temp,temp1;
+-
+- temp1 = 0;
+- temp = SiS_GetCH701x(SiS_Pr,0x61);
+- if(temp < 2) {
+- temp++;
+- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
+- temp1 = 1;
+- }
+- SiS_SetCH701x(SiS_Pr,0xac76);
+- temp = SiS_GetCH701x(SiS_Pr,0x66);
+- temp |= 0x5f;
+- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
+- if(ModeNo > 0x13) {
+- if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+- SiS_GenericDelay(SiS_Pr,0x3ff);
+- } else {
+- SiS_GenericDelay(SiS_Pr,0x2ff);
+- }
+- } else {
+- if(!temp1)
+- SiS_GenericDelay(SiS_Pr,0x2ff);
++
++ if(HwDeviceExtension->jChipType == SIS_740) {
++
++ temp = SiS_GetCH701x(SiS_Pr,0x61);
++ if(temp < 1) {
++ temp++;
++ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
++ }
++ SiS_SetCH701x(SiS_Pr,0x4566);
++ SiS_SetCH701x(SiS_Pr,0xaf76);
++ SiS_LongDelay(SiS_Pr,1);
++ SiS_GenericDelay(SiS_Pr,0x16ff);
++
++ } else { /* 650 */
++
++ temp1 = 0;
++ temp = SiS_GetCH701x(SiS_Pr,0x61);
++ if(temp < 2) {
++ temp++;
++ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
++ temp1 = 1;
++ }
++ SiS_SetCH701x(SiS_Pr,0xac76);
++ temp = SiS_GetCH701x(SiS_Pr,0x66);
++ temp |= 0x5f;
++ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
++ if(ModeNo > 0x13) {
++ if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
++ SiS_GenericDelay(SiS_Pr,0x3ff);
++ } else {
++ SiS_GenericDelay(SiS_Pr,0x2ff);
++ }
++ } else {
++ if(!temp1)
++ SiS_GenericDelay(SiS_Pr,0x2ff);
++ }
++ temp = SiS_GetCH701x(SiS_Pr,0x76);
++ temp |= 0x03;
++ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
++ temp = SiS_GetCH701x(SiS_Pr,0x66);
++ temp &= 0x7f;
++ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
++ SiS_LongDelay(SiS_Pr,1);
++
+ }
+- temp = SiS_GetCH701x(SiS_Pr,0x76);
+- temp |= 0x03;
+- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
+- temp = SiS_GetCH701x(SiS_Pr,0x66);
+- temp &= 0x7f;
+- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
+- SiS_LongDelay(SiS_Pr,1);
+-#endif
+ }
+
+ void
+@@ -9443,9 +9800,9 @@
+ temp &= 0x04;
+ if(temp == 0x04) break;
+
+-#ifdef NEWCH701x
+- SiS_SetCH701x(SiS_Pr,0xac76); /* 740/LVDS */
+-#endif
++ if(HwDeviceExtension->jChipType == SIS_740) {
++ SiS_SetCH701x(SiS_Pr,0xac76);
++ }
+
+ SiS_SetCH701xForLCD(SiS_Pr,HwDeviceExtension,BaseAddr);
+
+@@ -9463,11 +9820,11 @@
+ temp = SiS_GetCH701x(SiS_Pr,0x76);
+ temp |= 0x04;
+ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
+-#ifdef NEWCH701x
+- SiS_SetCH701x(SiS_Pr,0xe078);
+-#else
+- SiS_SetCH701x(SiS_Pr,0x6078);
+-#endif
++ if(HwDeviceExtension->jChipType == SIS_740) {
++ SiS_SetCH701x(SiS_Pr,0xe078);
++ } else {
++ SiS_SetCH701x(SiS_Pr,0x6078);
++ }
+ SiS_LongDelay(SiS_Pr,2);
+ } while(0);
+
+@@ -9485,51 +9842,52 @@
+ temp &= 0xbf; /* Set datapath 2 to LVDS */
+ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
+
+-#ifdef NEWCH701x /* 740/LVDS: */
++ if(HwDeviceExtension->jChipType == SIS_740) {
++
++ temp = SiS_GetCH701x(SiS_Pr,0x1c);
++ temp &= 0xfb;
++ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
++
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2d,0x03);
++
++ temp = SiS_GetCH701x(SiS_Pr,0x64);
++ temp |= 0x40;
++ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x64);
++
++ temp = SiS_GetCH701x(SiS_Pr,0x03);
++ temp &= 0x3f;
++ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
++
++ temp = SiS_GetCH701x(SiS_Pr,0x66);
++ if(temp != 0x45) {
++ SiS_ChrontelResetDB(SiS_Pr,HwDeviceExtension,BaseAddr);
++ SiS_ChrontelDoSomething2(SiS_Pr,HwDeviceExtension,BaseAddr);
++ temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x34);
++ SiS_ChrontelDoSomething3(SiS_Pr,temp,HwDeviceExtension,BaseAddr);
++ }
++
++ } else { /* 650 */
+
+- temp = SiS_GetCH701x(SiS_Pr,0x1c);
+- temp &= 0xfb;
+- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
+-
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2d,0x03);
+-
+- temp = SiS_GetCH701x(SiS_Pr,0x64);
+- temp |= 0x40;
+- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x64);
+-
+- temp = SiS_GetCH701x(SiS_Pr,0x03);
+- temp &= 0x3f;
+- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
+-
+- temp = SiS_GetCH701x(SiS_Pr,0x66);
+- if(temp != 0x45) {
+ SiS_ChrontelResetDB(SiS_Pr,HwDeviceExtension,BaseAddr);
+- SiS_ChrontelDoSomething2(SiS_Pr,HwDeviceExtension,BaseAddr);
+- temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x34);
+- SiS_ChrontelDoSomething3(SiS_Pr,temp,HwDeviceExtension,BaseAddr);
+- }
+
+-#else /* pre-740/LVDS: */
++ SiS_ChrontelDoSomething2(SiS_Pr,HwDeviceExtension,BaseAddr);
+
+- SiS_ChrontelResetDB(SiS_Pr);
++ temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x34);
++ SiS_ChrontelDoSomething3(SiS_Pr,temp,HwDeviceExtension,BaseAddr);
+
+- SiS_ChrontelDoSomething2(SiS_Pr,HwDeviceExtension,BaseAddr);
++ SiS_SetCH701x(SiS_Pr,0xaf76);
+
+- temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x34);
+- SiS_ChrontelDoSomething3(SiS_Pr,temp,HwDeviceExtension,BaseAddr);
++ }
+
+- SiS_SetCH701x(SiS_Pr,0xaf76);
+-
+-#endif /* End of pre-740/LVDS */
+ }
+
+-#endif /* 310/325 series --------------------------------- */
++#endif /* 315 series ------------------------------------ */
+
+-/* TW: End of Chrontel 701x functions ==================================== */
++/* End of Chrontel 701x functions ==================================== */
+
+-/* TW: Generic Read/write routines for Chrontel ========================== */
++/* Generic Read/write routines for Chrontel ========================== */
+
+-/* TW: The Chrontel is connected to the 630/730 via
++/* The Chrontel is connected to the 630/730 via
+ * the 630/730's DDC/I2C port.
+ *
+ * On 630(S)T chipset, the index changed from 0x11 to 0x0a,
+@@ -9539,13 +9897,13 @@
+ void
+ SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
+ {
+- if (SiS_Pr->SiS_IF_DEF_CH70xx == 1)
++ if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
+ SiS_SetCH700x(SiS_Pr,tempbx);
+ else
+ SiS_SetCH701x(SiS_Pr,tempbx);
+ }
+
+-/* TW: Write to Chrontel 700x */
++/* Write to Chrontel 700x */
+ /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
+ void
+ SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
+@@ -9553,100 +9911,100 @@
+ USHORT tempah,temp,i;
+
+ if(!(SiS_Pr->SiS_ChrontelInit)) {
+- SiS_Pr->SiS_DDC_Index = 0x11; /* TW: Bit 0 = SC; Bit 1 = SD */
++ SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
+ SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
+ SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
+ SiS_Pr->SiS_DDC_DataShift = 0x00;
+- SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* TW: DAB (Device Address Byte) */
++ SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
+ }
+
+- for(i=0;i<10;i++) { /* TW: Do only 10 attempts to write */
++ for(i=0;i<10;i++) { /* Do only 10 attempts to write */
+ /* SiS_SetSwitchDDC2(SiS_Pr); */
+- if(SiS_SetStart(SiS_Pr)) continue; /* TW: Set start condition */
++ if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
+ tempah = SiS_Pr->SiS_DDC_DeviceAddr;
+- temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: Write DAB (S0=0=write) */
+- if(temp) continue; /* TW: (ERROR: no ack) */
+- tempah = tempbx & 0x00FF; /* TW: Write RAB */
+- tempah |= 0x80; /* TW: (set bit 7, see datasheet) */
++ temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
++ if(temp) continue; /* (ERROR: no ack) */
++ tempah = tempbx & 0x00FF; /* Write RAB */
++ tempah |= 0x80; /* (set bit 7, see datasheet) */
+ temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
+- if(temp) continue; /* TW: (ERROR: no ack) */
++ if(temp) continue; /* (ERROR: no ack) */
+ tempah = (tempbx & 0xFF00) >> 8;
+- temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: Write data */
+- if(temp) continue; /* TW: (ERROR: no ack) */
+- if(SiS_SetStop(SiS_Pr)) continue; /* TW: Set stop condition */
++ temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write data */
++ if(temp) continue; /* (ERROR: no ack) */
++ if(SiS_SetStop(SiS_Pr)) continue; /* Set stop condition */
+ SiS_Pr->SiS_ChrontelInit = 1;
+ return;
+ }
+
+- /* TW: For 630ST */
++ /* For 630ST */
+ if(!(SiS_Pr->SiS_ChrontelInit)) {
+- SiS_Pr->SiS_DDC_Index = 0x0a; /* TW: Bit 7 = SC; Bit 6 = SD */
++ SiS_Pr->SiS_DDC_Index = 0x0a; /* Bit 7 = SC; Bit 6 = SD */
+ SiS_Pr->SiS_DDC_Data = 0x80; /* Bitmask in IndexReg for Data */
+ SiS_Pr->SiS_DDC_Clk = 0x40; /* Bitmask in IndexReg for Clk */
+ SiS_Pr->SiS_DDC_DataShift = 0x00;
+- SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* TW: DAB (Device Address Byte) */
++ SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
+
+- for(i=0;i<10;i++) { /* TW: Do only 10 attempts to write */
++ for(i=0;i<10;i++) { /* Do only 10 attempts to write */
+ /* SiS_SetSwitchDDC2(SiS_Pr); */
+- if (SiS_SetStart(SiS_Pr)) continue; /* TW: Set start condition */
++ if (SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
+ tempah = SiS_Pr->SiS_DDC_DeviceAddr;
+- temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: Write DAB (S0=0=write) */
+- if(temp) continue; /* TW: (ERROR: no ack) */
+- tempah = tempbx & 0x00FF; /* TW: Write RAB */
+- tempah |= 0x80; /* TW: (set bit 7, see datasheet) */
++ temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
++ if(temp) continue; /* (ERROR: no ack) */
++ tempah = tempbx & 0x00FF; /* Write RAB */
++ tempah |= 0x80; /* (set bit 7, see datasheet) */
+ temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
+- if(temp) continue; /* TW: (ERROR: no ack) */
++ if(temp) continue; /* (ERROR: no ack) */
+ tempah = (tempbx & 0xFF00) >> 8;
+- temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: Write data */
+- if(temp) continue; /* TW: (ERROR: no ack) */
+- if(SiS_SetStop(SiS_Pr)) continue; /* TW: Set stop condition */
++ temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write data */
++ if(temp) continue; /* (ERROR: no ack) */
++ if(SiS_SetStop(SiS_Pr)) continue; /* Set stop condition */
+ SiS_Pr->SiS_ChrontelInit = 1;
+ return;
+ }
+ }
+ }
+
+-/* TW: Write to Chrontel 701x */
++/* Write to Chrontel 701x */
+ /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
+ void
+ SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
+ {
+ USHORT tempah,temp,i;
+
+- SiS_Pr->SiS_DDC_Index = 0x11; /* TW: Bit 0 = SC; Bit 1 = SD */
++ SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
+ SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
+ SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
+ SiS_Pr->SiS_DDC_DataShift = 0x00;
+- SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* TW: DAB (Device Address Byte) */
++ SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
+
+- for(i=0;i<10;i++) { /* TW: Do only 10 attempts to write */
+- if (SiS_SetStart(SiS_Pr)) continue; /* TW: Set start condition */
++ for(i=0;i<10;i++) { /* Do only 10 attempts to write */
++ if (SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
+ tempah = SiS_Pr->SiS_DDC_DeviceAddr;
+- temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: Write DAB (S0=0=write) */
+- if(temp) continue; /* TW: (ERROR: no ack) */
++ temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
++ if(temp) continue; /* (ERROR: no ack) */
+ tempah = tempbx & 0x00FF;
+- temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: Write RAB */
+- if(temp) continue; /* TW: (ERROR: no ack) */
++ temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write RAB */
++ if(temp) continue; /* (ERROR: no ack) */
+ tempah = (tempbx & 0xFF00) >> 8;
+- temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: Write data */
+- if(temp) continue; /* TW: (ERROR: no ack) */
+- if(SiS_SetStop(SiS_Pr)) continue; /* TW: Set stop condition */
++ temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write data */
++ if(temp) continue; /* (ERROR: no ack) */
++ if(SiS_SetStop(SiS_Pr)) continue; /* Set stop condition */
+ return;
+ }
+ }
+
+-/* TW: Read from Chrontel 70xx */
++/* Read from Chrontel 70xx */
+ /* Parameter is [Register no (S7-S0)] */
+ USHORT
+ SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
+ {
+- if (SiS_Pr->SiS_IF_DEF_CH70xx == 1)
++ if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
+ return(SiS_GetCH700x(SiS_Pr,tempbx));
+ else
+ return(SiS_GetCH701x(SiS_Pr,tempbx));
+ }
+
+-/* TW: Read from Chrontel 700x */
++/* Read from Chrontel 700x */
+ /* Parameter is [Register no (S7-S0)] */
+ USHORT
+ SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
+@@ -9654,57 +10012,57 @@
+ USHORT tempah,temp,i;
+
+ if(!(SiS_Pr->SiS_ChrontelInit)) {
+- SiS_Pr->SiS_DDC_Index = 0x11; /* TW: Bit 0 = SC; Bit 1 = SD */
++ SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
+ SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
+ SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
+ SiS_Pr->SiS_DDC_DataShift = 0x00;
+- SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* TW: DAB */
++ SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
+ }
+
+ SiS_Pr->SiS_DDC_ReadAddr = tempbx;
+
+- for(i=0;i<20;i++) { /* TW: Do only 20 attempts to read */
++ for(i=0;i<20;i++) { /* Do only 20 attempts to read */
+ /* SiS_SetSwitchDDC2(SiS_Pr); */
+- if(SiS_SetStart(SiS_Pr)) continue; /* TW: Set start condition */
++ if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
+ tempah = SiS_Pr->SiS_DDC_DeviceAddr;
+- temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: Write DAB (S0=0=write) */
+- if(temp) continue; /* TW: (ERROR: no ack) */
+- tempah = SiS_Pr->SiS_DDC_ReadAddr | 0x80; /* TW: Write RAB | 0x80 */
++ temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
++ if(temp) continue; /* (ERROR: no ack) */
++ tempah = SiS_Pr->SiS_DDC_ReadAddr | 0x80; /* Write RAB | 0x80 */
+ temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
+- if(temp) continue; /* TW: (ERROR: no ack) */
+- if (SiS_SetStart(SiS_Pr)) continue; /* TW: Re-start */
++ if(temp) continue; /* (ERROR: no ack) */
++ if (SiS_SetStart(SiS_Pr)) continue; /* Re-start */
+ tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01; /* DAB | 0x01 = Read */
+- temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: DAB (S0=1=read) */
+- if(temp) continue; /* TW: (ERROR: no ack) */
+- tempah = SiS_ReadDDC2Data(SiS_Pr,tempah); /* TW: Read byte */
+- if (SiS_SetStop(SiS_Pr)) continue; /* TW: Stop condition */
++ temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* DAB (S0=1=read) */
++ if(temp) continue; /* (ERROR: no ack) */
++ tempah = SiS_ReadDDC2Data(SiS_Pr,tempah); /* Read byte */
++ if (SiS_SetStop(SiS_Pr)) continue; /* Stop condition */
+ SiS_Pr->SiS_ChrontelInit = 1;
+ return(tempah);
+ }
+
+- /* TW: For 630ST */
++ /* For 630ST */
+ if(!SiS_Pr->SiS_ChrontelInit) {
+- SiS_Pr->SiS_DDC_Index = 0x0a; /* TW: Bit 0 = SC; Bit 1 = SD */
++ SiS_Pr->SiS_DDC_Index = 0x0a; /* Bit 0 = SC; Bit 1 = SD */
+ SiS_Pr->SiS_DDC_Data = 0x80; /* Bitmask in IndexReg for Data */
+ SiS_Pr->SiS_DDC_Clk = 0x40; /* Bitmask in IndexReg for Clk */
+ SiS_Pr->SiS_DDC_DataShift = 0x00;
+- SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* TW: DAB (Device Address Byte) */
++ SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
+
+- for(i=0;i<20;i++) { /* TW: Do only 20 attempts to read */
++ for(i=0;i<20;i++) { /* Do only 20 attempts to read */
+ /* SiS_SetSwitchDDC2(SiS_Pr); */
+- if(SiS_SetStart(SiS_Pr)) continue; /* TW: Set start condition */
++ if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
+ tempah = SiS_Pr->SiS_DDC_DeviceAddr;
+- temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: Write DAB (S0=0=write) */
+- if(temp) continue; /* TW: (ERROR: no ack) */
+- tempah = SiS_Pr->SiS_DDC_ReadAddr | 0x80; /* TW: Write RAB | 0x80 */
++ temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
++ if(temp) continue; /* (ERROR: no ack) */
++ tempah = SiS_Pr->SiS_DDC_ReadAddr | 0x80; /* Write RAB | 0x80 */
+ temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
+- if(temp) continue; /* TW: (ERROR: no ack) */
+- if (SiS_SetStart(SiS_Pr)) continue; /* TW: Re-start */
++ if(temp) continue; /* (ERROR: no ack) */
++ if (SiS_SetStart(SiS_Pr)) continue; /* Re-start */
+ tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01; /* DAB | 0x01 = Read */
+- temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: DAB (S0=1=read) */
+- if(temp) continue; /* TW: (ERROR: no ack) */
+- tempah = SiS_ReadDDC2Data(SiS_Pr,tempah); /* TW: Read byte */
+- if (SiS_SetStop(SiS_Pr)) continue; /* TW: Stop condition */
++ temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* DAB (S0=1=read) */
++ if(temp) continue; /* (ERROR: no ack) */
++ tempah = SiS_ReadDDC2Data(SiS_Pr,tempah); /* Read byte */
++ if (SiS_SetStop(SiS_Pr)) continue; /* Stop condition */
+ SiS_Pr->SiS_ChrontelInit = 1;
+ return(tempah);
+ }
+@@ -9712,52 +10070,51 @@
+ return(0xFFFF);
+ }
+
+-/* TW: Read from Chrontel 701x */
++/* Read from Chrontel 701x */
+ /* Parameter is [Register no (S7-S0)] */
+ USHORT
+ SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
+ {
+ USHORT tempah,temp,i;
+
+- SiS_Pr->SiS_DDC_Index = 0x11; /* TW: Bit 0 = SC; Bit 1 = SD */
++ SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
+ SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
+ SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
+ SiS_Pr->SiS_DDC_DataShift = 0x00;
+- SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* TW: DAB */
++ SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
+ SiS_Pr->SiS_DDC_ReadAddr = tempbx;
+
+- for(i=0;i<20;i++) { /* TW: Do only 20 attempts to read */
+- if(SiS_SetStart(SiS_Pr)) continue; /* TW: Set start condition */
++ for(i=0;i<20;i++) { /* Do only 20 attempts to read */
++ if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
+ tempah = SiS_Pr->SiS_DDC_DeviceAddr;
+- temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: Write DAB (S0=0=write) */
+- if(temp) continue; /* TW: (ERROR: no ack) */
+- tempah = SiS_Pr->SiS_DDC_ReadAddr; /* TW: Write RAB */
++ temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
++ if(temp) continue; /* (ERROR: no ack) */
++ tempah = SiS_Pr->SiS_DDC_ReadAddr; /* Write RAB */
+ temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
+- if(temp) continue; /* TW: (ERROR: no ack) */
+- if (SiS_SetStart(SiS_Pr)) continue; /* TW: Re-start */
++ if(temp) continue; /* (ERROR: no ack) */
++ if (SiS_SetStart(SiS_Pr)) continue; /* Re-start */
+ tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01; /* DAB | 0x01 = Read */
+- temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: DAB (S0=1=read) */
+- if(temp) continue; /* TW: (ERROR: no ack) */
+- tempah = SiS_ReadDDC2Data(SiS_Pr,tempah); /* TW: Read byte */
+- SiS_SetStop(SiS_Pr); /* TW: Stop condition */
++ temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* DAB (S0=1=read) */
++ if(temp) continue; /* (ERROR: no ack) */
++ tempah = SiS_ReadDDC2Data(SiS_Pr,tempah); /* Read byte */
++ SiS_SetStop(SiS_Pr); /* Stop condition */
+ return(tempah);
+ }
+ return 0xFFFF;
+ }
+
+-#ifdef LINUX_XF86
+-/* TW: Our own DDC functions */
++/* Our own DDC functions */
+ USHORT
+-SiS_InitDDCRegs(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT adaptnum, USHORT DDCdatatype,
+- BOOLEAN checkcr32)
++SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
++ USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32)
+ {
+ unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
+ unsigned char flag, cr32;
+ USHORT temp = 0, myadaptnum = adaptnum;
+
+ if(adaptnum != 0) {
+- if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_302B))) return 0xFFFF;
+- if((pSiS->VBFlags & VB_30xBDH) && (adaptnum == 1)) return 0xFFFF;
++ if(!(VBFlags & (VB_301|VB_301B|VB_302B))) return 0xFFFF;
++ if((VBFlags & VB_30xBDH) && (adaptnum == 1)) return 0xFFFF;
+ }
+
+ /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
+@@ -9771,8 +10128,9 @@
+ flag = 0xff;
+
+ cr32 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x32);
+-
+- if(pSiS->VBFlags & VB_SISBRIDGE) {
++
++#if 0
++ if(VBFlags & VB_SISBRIDGE) {
+ if(myadaptnum == 0) {
+ if(!(cr32 & 0x20)) {
+ myadaptnum = 2;
+@@ -9785,18 +10143,19 @@
+ }
+ }
+ }
++#endif
+
+- if(pSiS->VGAEngine == SIS_300_VGA) { /* 300 series */
++ if(VGAEngine == SIS_300_VGA) { /* 300 series */
+
+ if(myadaptnum != 0) {
+ flag = 0;
+- if(pSiS->VBFlags & VB_SISBRIDGE) {
++ if(VBFlags & VB_SISBRIDGE) {
+ SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
+ SiS_Pr->SiS_DDC_Index = 0x0f;
+ }
+ }
+
+- if(!(pSiS->VBFlags & VB_301)) {
++ if(!(VBFlags & VB_301)) {
+ if((cr32 & 0x80) && (checkcr32)) {
+ if(myadaptnum >= 1) {
+ if(!(cr32 & 0x08)) {
+@@ -9810,11 +10169,11 @@
+ temp = 4 - (myadaptnum * 2);
+ if(flag) temp = 0;
+
+- } else { /* 310/325/330 series */
++ } else { /* 315/330 series */
+
+ /* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
+
+- if(pSiS->VBFlags & VB_SISBRIDGE) {
++ if(VBFlags & VB_SISBRIDGE) {
+ if(myadaptnum == 2) {
+ myadaptnum = 1;
+ }
+@@ -9822,7 +10181,7 @@
+
+ if(myadaptnum == 1) {
+ flag = 0;
+- if(pSiS->VBFlags & VB_SISBRIDGE) {
++ if(VBFlags & VB_SISBRIDGE) {
+ SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
+ SiS_Pr->SiS_DDC_Index = 0x0f;
+ }
+@@ -9840,7 +10199,7 @@
+ temp = myadaptnum;
+ if(myadaptnum == 1) {
+ temp = 0;
+- if(pSiS->VBFlags & VB_LVDS) flag = 0xff;
++ if(VBFlags & VB_LVDS) flag = 0xff;
+ }
+
+ if(flag) temp = 0;
+@@ -9852,7 +10211,7 @@
+ #ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "DDC Port %x Index %x Shift %d\n",
+ SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index, temp);
+-#endif
++#endif
+
+ return 0;
+ }
+@@ -9862,15 +10221,9 @@
+ {
+ if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
+ if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
+-#ifdef TWDEBUG
+- xf86DrvMsg(0, X_INFO, "WriteDAB 1 failed\n");
+-#endif
+ return 0xFFFF;
+ }
+ if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
+-#ifdef TWDEBUG
+- xf86DrvMsg(0, X_INFO, "WriteDAB 2 failed\n");
+-#endif
+ return 0xFFFF;
+ }
+ return(0);
+@@ -9881,9 +10234,6 @@
+ {
+ if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
+ if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
+-#ifdef TWDEBUG
+- xf86DrvMsg(0, X_INFO, "PrepareReadDDC 1 failed\n");
+-#endif
+ return 0xFFFF;
+ }
+ return(0);
+@@ -9921,9 +10271,6 @@
+ SiS_SetSwitchDDC2(SiS_Pr);
+ if(SiS_PrepareDDC(SiS_Pr)) {
+ SiS_SetStop(SiS_Pr);
+-#ifdef TWDEBUG
+- xf86DrvMsg(0, X_INFO, "DoProbeDDC 1 failed at PrepareDDC\n");
+-#endif
+ return(0xFFFF);
+ }
+ mask = 0xf0;
+@@ -9972,7 +10319,7 @@
+ }
+
+ USHORT
+-SiS_ReadDDC(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT DDCdatatype, unsigned char *buffer)
++SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer)
+ {
+ USHORT flag, length, i;
+ unsigned char chksum,gotcha;
+@@ -10004,28 +10351,7 @@
+ return(flag);
+ }
+
+-USHORT
+-SiS_ReadLCDDDC(SiS_Private *SiS_Pr, USHORT length, unsigned char *buffer)
+-{
+- USHORT i=0, flag=0;
+-
+- length--;
+-
+- SiS_SetSwitchDDC2(SiS_Pr);
+- if(!(SiS_PrepareDDC(SiS_Pr))) {
+- for(i=0; i<length; i++) {
+- buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
+- SiS_SendACK(SiS_Pr, 0);
+- }
+- buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
+- SiS_SendACK(SiS_Pr, 1);
+- } else flag = 0xFFFF;
+-
+- SiS_SetStop(SiS_Pr);
+- return(0);
+-}
+-
+-/* TW: Our private DDC function
++/* Our private DDC functions
+
+ It complies somewhat with the corresponding VESA function
+ in arguments and return values.
+@@ -10036,7 +10362,7 @@
+
+ Arguments:
+ adaptnum: 0=CRT1, 1=LCD, 2=VGA2
+- CRT2 DDC is only supported on SiS301, 301B (non-DH version), 302B.
++ CRT2 DDC is only supported on SiS301, 301B, 302B.
+ DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
+ buffer: ptr to 256 data bytes which will be filled with read data.
+
+@@ -10046,43 +10372,48 @@
+
+ */
+ USHORT
+-SiS_HandleDDC(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT adaptnum,
+- USHORT DDCdatatype, unsigned char *buffer)
++SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
++ USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer)
+ {
+ if(adaptnum > 2) return 0xFFFF;
+ if(DDCdatatype > 4) return 0xFFFF;
+- if((!(pSiS->VBFlags & VB_VIDEOBRIDGE)) && (adaptnum > 0)) return 0xFFFF;
+- if(SiS_InitDDCRegs(SiS_Pr, pSiS, adaptnum, DDCdatatype, TRUE) == 0xFFFF) return 0xFFFF;
++ if((!(VBFlags & VB_VIDEOBRIDGE)) && (adaptnum > 0)) return 0xFFFF;
++ if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, TRUE) == 0xFFFF) return 0xFFFF;
+ if(DDCdatatype == 0) {
+ return(SiS_ProbeDDC(SiS_Pr));
+ } else {
+- return(SiS_ReadDDC(SiS_Pr, pSiS, DDCdatatype, buffer));
++ return(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer));
+ }
+ }
+
++#ifdef LINUX_XF86
+ /* Sense the LCD parameters (CR36, CR37) via DDC */
+ /* SiS30x(B) only */
+ USHORT
+ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
+ {
+- USHORT DDCdatatype, paneltype, flag, xres, yres;
++ USHORT DDCdatatype, paneltype, flag, xres=0, yres=0;
+ USHORT index, myindex, lumsize, numcodes;
+ unsigned char cr37=0, seekcode;
+ BOOLEAN checkexpand = FALSE;
+ int retry, i;
+ unsigned char buffer[256];
+-
++
++ for(i=0; i<7; i++) SiS_Pr->CP_DataValid[i] = FALSE;
++ SiS_Pr->CP_HaveCustomData = FALSE;
++ SiS_Pr->CP_MaxX = SiS_Pr->CP_MaxY = SiS_Pr->CP_MaxClock = 0;
++
+ if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_302B))) return 0;
+ if(pSiS->VBFlags & VB_30xBDH) return 0;
+
+- if(SiS_InitDDCRegs(SiS_Pr, pSiS, 1, 0, FALSE) == 0xFFFF) return 0;
++ if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 1, 0, FALSE) == 0xFFFF) return 0;
+
+ SiS_Pr->SiS_DDC_SecAddr = 0x00;
+
+ /* Probe supported DA's */
+ flag = SiS_ProbeDDC(SiS_Pr);
+ #ifdef TWDEBUG
+- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
++ xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
+ "CRT2 DDC capabilities 0x%x\n", flag);
+ #endif
+ if(flag & 0x10) {
+@@ -10099,7 +10430,7 @@
+ /* Read the entire EDID */
+ retry = 2;
+ do {
+- if(SiS_ReadDDC(SiS_Pr, pSiS, DDCdatatype, buffer)) {
++ if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
+ xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
+ "CRT2: DDC read failed (attempt %d), %s\n",
+ (3-retry), (retry == 1) ? "giving up" : "retrying");
+@@ -10132,7 +10463,7 @@
+ }
+
+ if((buffer[0x18] & 0x18) != 0x08) {
+- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
++ xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
+ "CRT2: Attached display is not of RGB but of %s type (0x%02x)\n",
+ ((buffer[0x18] & 0x18) == 0x00) ? "monochrome/greyscale" :
+ ( ((buffer[0x18] & 0x18) == 0x10) ? "non-RGB multicolor" :
+@@ -10140,103 +10471,226 @@
+ buffer[0x18]);
+ return 0;
+ }
+-
+- /* Now analyze the first Detailed Timing Block and hope
+- * that the preferred timing mode is stored there.
+- */
+- xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4);
+- yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4);
++
++ /* Now analyze the first Detailed Timing Block and see
++ * if the preferred timing mode is stored there. If so,
++ * check if this is a standard panel for which we already
++ * know the timing.
++ */
++
++ paneltype = Panel_Custom;
+ checkexpand = FALSE;
+- switch(xres) {
+- case 800:
+- if(yres == 600) {
+- paneltype = Panel310_800x600;
+- checkexpand = TRUE;
+- }
+- break;
+- case 1024:
+- if(yres == 768) {
+- paneltype = Panel310_1024x768;
+- checkexpand = FALSE; /* expand causes error at 640x480, should otherwise be TRUE; */
+- }
+- break;
+- case 1280:
+- if(yres == 960) {
+- if(pSiS->VGAEngine == SIS_300_VGA) {
+- paneltype = Panel300_1280x960;
+- } else {
+- paneltype = Panel310_1280x960;
+- }
+- } else if(yres == 1024) {
+- paneltype = Panel310_1280x1024;
+- checkexpand = TRUE;
+- } else if(pSiS->VGAEngine == SIS_315_VGA) {
++
++ if(buffer[0x18] & 0x02) {
++
++ xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4);
++ yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4);
++
++ SiS_Pr->CP_PreferredX = xres;
++ SiS_Pr->CP_PreferredY = yres;
++
++ switch(xres) {
++ case 800:
++ if(yres == 600) {
++ paneltype = Panel_800x600;
++ checkexpand = TRUE;
++ }
++ break;
++ case 1024:
+ if(yres == 768) {
+- paneltype = Panel310_1280x768; /* Panel size 1280x768 not supported yet */
+- checkexpand = TRUE;
+- }
+- }
+- break;
+- case 1400:
+- if(pSiS->VGAEngine == SIS_315_VGA) {
+- if(yres == 1050) {
+- paneltype = Panel310_1400x1050;
+- checkexpand = TRUE;
+- }
+- }
+- break;
+- case 1600:
+- if(pSiS->VGAEngine == SIS_315_VGA) {
+- if(yres == 1200) {
+- paneltype = Panel310_1600x1200;
++ paneltype = Panel_1024x768;
++ checkexpand = TRUE;
++ }
++ break;
++ case 1280:
++ if(yres == 1024) {
++ paneltype = Panel_1280x1024;
+ checkexpand = TRUE;
+- }
+- }
+- break;
++ } else if(yres == 960) {
++ if(pSiS->VGAEngine == SIS_300_VGA) {
++ paneltype = Panel300_1280x960;
++ } else {
++ paneltype = Panel310_1280x960;
++ }
++ } else if(yres == 768) {
++ paneltype = Panel_1280x768;
++ checkexpand = FALSE;
++ cr37 |= 0x10;
++ }
++ break;
++ case 1400:
++ if(pSiS->VGAEngine == SIS_315_VGA) {
++ if(yres == 1050) {
++ paneltype = Panel310_1400x1050;
++ checkexpand = TRUE;
++ }
++ }
++ break;
++#if 0 /* Treat this as custom, as we have no valid timing data yet */
++ case 1600:
++ if(pSiS->VGAEngine == SIS_315_VGA) {
++ if(yres == 1200) {
++ paneltype = Panel310_1600x1200;
++ checkexpand = TRUE;
++ }
++ }
++ break;
++#endif
++ }
++
++ if(paneltype != Panel_Custom) {
++ if((buffer[0x47] & 0x18) == 0x18) {
++ cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20);
++ } else {
++ /* What now? There is no digital separate output timing... */
++ xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
++ "CRT2: Unable to retrieve Sync polarity information\n");
++ }
++ }
++
+ }
+
+- if(buffer[0x18] & 0x02) {
+- /* If the preferred timing mode is stored in the first
+- * detailed timing block, we now can extract the sync
+- * polarisation information as well. This only works
+- * if the Flags indicate a digital separate output.
+- */
+- if((buffer[0x47] & 0x18) == 0x18) {
+- cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20);
+- } else {
+- /* What now? There is no digital separate output timing... */
+- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
+- "CRT2: Unable to retrieve Sync polarity information\n");
+- }
+-
+- } else {
+- /* If the preferred timing mode is *not* stored in the first
+- * detailed timing block, we need to guess the resolution
+- * from the supported Established Timings and assume the
+- * default sync polarity
+- */
++ /* If we still don't know what panel this is, we take it
++ * as a custom panel and derive the timing data from the
++ * detailed timing blocks
++ */
++ if(paneltype == Panel_Custom) {
++
++ BOOLEAN havesync = FALSE;
++ int i, temp, base = 0x36;
++ unsigned long estpack;
++ unsigned short estx[] = {
++ 720, 720, 640, 640, 640, 640, 800, 800,
++ 800, 800, 832,1024,1024,1024,1024,1280,
++ 1152
++ };
++ unsigned short esty[] = {
++ 400, 400, 480, 480, 480, 480, 600, 600,
++ 600, 600, 624, 768, 768, 768, 768,1024,
++ 870
++ };
++
+ paneltype = 0;
+- if(buffer[0x24] & 0x01) {
+- paneltype = Panel310_1280x1024;
+- checkexpand = TRUE;
+- cr37 |= 0x20;
+- } else if(buffer[0x24] & 0x0e) {
+- paneltype = Panel310_1024x768;
+- cr37 |= 0xe0;
+- checkexpand = FALSE; /* Bug at 640x480 */
+- } else if(buffer[0x23] & 0x01) {
+- paneltype = Panel310_800x600;
+- cr37 |= 0xe0;
+- checkexpand = TRUE;
+- }
++
++ /* Find the maximum resolution */
++
++ /* 1. From Established timings */
++ estpack = (buffer[0x23] << 9) | (buffer[0x24] << 1) | ((buffer[0x25] >> 7) & 0x01);
++ for(i=16; i>=0; i--) {
++ if(estpack & (1 << i)) {
++ if(estx[16 - i] > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = estx[16 - i];
++ if(esty[16 - i] > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = esty[16 - i];
++ }
++ }
++
++ /* 2. From Standard Timings */
++ for(i=0x26; i < 0x36; i+=2) {
++ if((buffer[i] != 0x01) && (buffer[i+1] != 0x01)) {
++ temp = (buffer[i] + 31) * 8;
++ if(temp > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = temp;
++ switch((buffer[i+1] & 0xc0) >> 6) {
++ case 0x03: temp = temp * 9 / 16; break;
++ case 0x02: temp = temp * 4 / 5; break;
++ case 0x01: temp = temp * 3 / 4; break;
++ }
++ if(temp > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = temp;
++ }
++ }
++
++ /* Now extract the Detailed Timings and convert them into modes */
++
++ for(i = 0; i < 4; i++, base += 18) {
++
++ /* Is this a detailed timing block or a monitor descriptor? */
++ if(buffer[base] || buffer[base+1] || buffer[base+2]) {
++
++ xres = buffer[base+2] | ((buffer[base+4] & 0xf0) << 4);
++ yres = buffer[base+5] | ((buffer[base+7] & 0xf0) << 4);
++
++ SiS_Pr->CP_HDisplay[i] = xres;
++ SiS_Pr->CP_HSyncStart[i] = xres + (buffer[base+8] | ((buffer[base+11] & 0xc0) << 2));
++ SiS_Pr->CP_HSyncEnd[i] = SiS_Pr->CP_HSyncStart[i] + (buffer[base+9] | ((buffer[base+11] & 0x30) << 4));
++ SiS_Pr->CP_HTotal[i] = xres + (buffer[base+3] | ((buffer[base+4] & 0x0f) << 8));
++ SiS_Pr->CP_HBlankStart[i] = xres + 1;
++ SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
++
++ SiS_Pr->CP_VDisplay[i] = yres;
++ SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[base+10] & 0xf0) >> 4) | ((buffer[base+11] & 0x0c) << 2));
++ SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[base+10] & 0x0f) | ((buffer[base+11] & 0x03) << 4));
++ SiS_Pr->CP_VTotal[i] = yres + (buffer[base+6] | ((buffer[base+7] & 0x0f) << 8));
++ SiS_Pr->CP_VBlankStart[i] = yres + 1;
++ SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
++
++ SiS_Pr->CP_Clock[i] = (buffer[base] | (buffer[base+1] << 8)) * 10;
++
++ SiS_Pr->CP_DataValid[i] = TRUE;
++
++ /* Sort out invalid timings, interlace and too high clocks */
++ if((SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i]) ||
++ (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
++ (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i]) ||
++ (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
++ (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i]) ||
++ (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i]) ||
++ (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i]) ||
++ (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i]) ||
++ (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i]) ||
++ (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i]) ||
++ (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i]) ||
++ (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i]) ||
++ (SiS_Pr->CP_Clock[i] > 108000) ||
++ (buffer[base+17] & 0x80)) {
++
++ SiS_Pr->CP_DataValid[i] = FALSE;
++
++ } else {
++
++ paneltype = Panel_Custom;
++
++ SiS_Pr->CP_HaveCustomData = TRUE;
++
++ if(xres > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = xres;
++ if(yres > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = yres;
++ if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
++
++ SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
++ SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8);
++
++ /* We must assume the panel can scale, since we have
++ * no scaling data
++ */
++ checkexpand = FALSE;
++ cr37 |= 0x10;
++
++ /* Extract the sync polarisation information. This only works
++ * if the Flags indicate a digital separate output.
++ */
++ if((buffer[base+17] & 0x18) == 0x18) {
++ SiS_Pr->CP_HSync_P[i] = (buffer[base+17] & 0x02) ? TRUE : FALSE;
++ SiS_Pr->CP_VSync_P[i] = (buffer[base+17] & 0x04) ? TRUE : FALSE;
++ SiS_Pr->CP_SyncValid[i] = TRUE;
++ if(!havesync) {
++ cr37 |= ((((buffer[base+17] & 0x06) ^ 0x06) << 5) | 0x20);
++ havesync = TRUE;
++ }
++ } else {
++ SiS_Pr->CP_SyncValid[i] = FALSE;
++ }
++ }
++ }
++ }
++ if(!havesync) {
++ xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
++ "CRT2: Unable to retrieve Sync polarity information\n");
++ }
+ }
+-
+- if(checkexpand) {
+- /* If any of the Established low-res modes is supported, the
++
++ if(paneltype && checkexpand) {
++ /* If any of the Established low-res modes is supported, the
+ * panel can scale automatically. For 800x600 panels, we only
+ * check the even lower ones.
+ */
+- if(paneltype == Panel310_800x600) {
++ if(paneltype == Panel_800x600) {
+ if(buffer[0x23] & 0xfc) cr37 |= 0x10;
+ } else {
+ if(buffer[0x23]) cr37 |= 0x10;
+@@ -10262,20 +10716,31 @@
+ buffer[0x41]);
+ return 0;
+ }
+-
+- xres = buffer[0x76] | (buffer[0x77] << 8);
+- yres = buffer[0x78] | (buffer[0x79] << 8);
++
++ paneltype = Panel_Custom;
++ SiS_Pr->CP_MaxX = xres = buffer[0x76] | (buffer[0x77] << 8);
++ SiS_Pr->CP_MaxY = yres = buffer[0x78] | (buffer[0x79] << 8);
+ switch(xres) {
+ case 800:
+ if(yres == 600) {
+- paneltype = Panel310_800x600;
++ paneltype = Panel_800x600;
+ checkexpand = TRUE;
+ }
+ break;
+ case 1024:
+ if(yres == 768) {
+- paneltype = Panel310_1024x768;
+- checkexpand = FALSE; /* Bug at 640x480; we do the scaling ourselves */
++ paneltype = Panel_1024x768;
++ checkexpand = TRUE;
++ }
++ break;
++ case 1152:
++ if(yres == 768) {
++ if(pSiS->VGAEngine == SIS_300_VGA) {
++ paneltype = Panel300_1152x768;
++ } else {
++ paneltype = Panel310_1152x768;
++ }
++ checkexpand = TRUE;
+ }
+ break;
+ case 1280:
+@@ -10286,45 +10751,46 @@
+ paneltype = Panel300_1280x960;
+ }
+ } else if(yres == 1024) {
+- paneltype = Panel310_1280x1024;
++ paneltype = Panel_1280x1024;
+ checkexpand = TRUE;
+- } else if(pSiS->VGAEngine == SIS_315_VGA) {
+- if(yres == 768) {
+- paneltype = Panel310_1280x768; /* Panel size 1280x768 not supported yet */
+- checkexpand = TRUE;
+- }
+- }
++ } else if(yres == 768) {
++ paneltype = Panel_1280x768;
++ checkexpand = FALSE;
++ cr37 |= 0x10;
++ }
+ break;
+ case 1400:
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ if(yres == 1050) {
+ paneltype = Panel310_1400x1050;
+ checkexpand = TRUE;
+- }
++ }
+ }
+ break;
++#if 0 /* Treat this one as custom since we have no timing data yet */
+ case 1600:
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ if(yres == 1200) {
+ paneltype = Panel310_1600x1200;
+ checkexpand = TRUE;
+- }
++ }
+ }
+ break;
++#endif
+ }
+-
++
+ /* Determine if RGB18 or RGB24 */
+ if(index) {
+ if((buffer[index] == 0x20) || (buffer[index] == 0x34)) {
+ cr37 |= 0x01;
+ }
+ }
+-
++
+ if(checkexpand) {
+ /* TODO - for now, we let the panel scale */
+ cr37 |= 0x10;
+ }
+-
++
+ /* Now seek 4-Byte Timing codes and extract sync pol info */
+ index = 0x80;
+ if(buffer[0x7e] & 0x20) { /* skip Luminance Table (if provided) */
+@@ -10346,28 +10812,117 @@
+ if(buffer[myindex] == seekcode) {
+ cr37 |= ((((buffer[myindex + 1] & 0x0c) ^ 0x0c) << 4) | 0x20);
+ } else {
+- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
+- "CRT2: Unable to retrieve Sync polarity information\n");
++ xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
++ "CRT2: Unable to retrieve Sync polarity information\n");
+ }
+ } else {
+- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
+- "CRT2: Unable to retrieve Sync polarity information\n");
++ xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
++ "CRT2: Unable to retrieve Sync polarity information\n");
++ }
++
++ /* Now seek the detailed timing descriptions for custom panels */
++ if(paneltype == Panel_Custom) {
++ index += (numcodes * 4);
++ numcodes = buffer[0x7f] & 0x07;
++ for(i=0; i<numcodes; i++) {
++ xres = buffer[index+2] | ((buffer[index+4] & 0xf0) << 4);
++ yres = buffer[index+5] | ((buffer[index+7] & 0xf0) << 4);
++
++ SiS_Pr->CP_HDisplay[i] = xres;
++ SiS_Pr->CP_HSyncStart[i] = xres + (buffer[index+8] | ((buffer[index+11] & 0xc0) << 2));
++ SiS_Pr->CP_HSyncEnd[i] = SiS_Pr->CP_HSyncStart[i] + (buffer[index+9] | ((buffer[index+11] & 0x30) << 4));
++ SiS_Pr->CP_HTotal[i] = xres + (buffer[index+3] | ((buffer[index+4] & 0x0f) << 8));
++ SiS_Pr->CP_HBlankStart[i] = xres + 1;
++ SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
++
++ SiS_Pr->CP_VDisplay[i] = yres;
++ SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[index+10] & 0xf0) >> 4) | ((buffer[index+11] & 0x0c) << 2));
++ SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[index+10] & 0x0f) | ((buffer[index+11] & 0x03) << 4));
++ SiS_Pr->CP_VTotal[i] = yres + (buffer[index+6] | ((buffer[index+7] & 0x0f) << 8));
++ SiS_Pr->CP_VBlankStart[i] = yres + 1;
++ SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
++
++ SiS_Pr->CP_Clock[i] = (buffer[index] | (buffer[index+1] << 8)) * 10;
++
++ SiS_Pr->CP_DataValid[i] = TRUE;
++
++ if((SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i]) ||
++ (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
++ (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i]) ||
++ (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
++ (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i]) ||
++ (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i]) ||
++ (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i]) ||
++ (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i]) ||
++ (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i]) ||
++ (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i]) ||
++ (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i]) ||
++ (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i]) ||
++ (SiS_Pr->CP_Clock[i] > 108000) ||
++ (buffer[index + 17] & 0x80)) {
++
++ SiS_Pr->CP_DataValid[i] = FALSE;
++
++ } else {
++
++ SiS_Pr->CP_HaveCustomData = TRUE;
++
++ if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
++
++ SiS_Pr->CP_HSync_P[i] = (buffer[index + 17] & 0x02) ? TRUE : FALSE;
++ SiS_Pr->CP_VSync_P[i] = (buffer[index + 17] & 0x04) ? TRUE : FALSE;
++ SiS_Pr->CP_SyncValid[i] = TRUE;
++
++ SiS_Pr->CP_Vendor = buffer[2] | (buffer[1] << 8);
++ SiS_Pr->CP_Product = buffer[3] | (buffer[4] << 8);
++
++ /* We must assume the panel can scale, since we have
++ * no scaling data
++ */
++ cr37 |= 0x10;
++
++ }
++ }
++
+ }
+
+ break;
+-
++
+ }
+-
++
+ /* 1280x960 panels are always RGB24, unable to scale and use
+ * high active sync polarity
+ */
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+- if(paneltype == Panel310_1280x960) cr37 &= 0x0e;
++ if(paneltype == Panel310_1280x960) cr37 &= 0x0e;
+ } else {
+- if(paneltype == Panel300_1280x960) cr37 &= 0x0e;
++ if(paneltype == Panel300_1280x960) cr37 &= 0x0e;
+ }
+-
++
++ for(i = 0; i < 7; i++) {
++ if(SiS_Pr->CP_DataValid[i]) {
++ xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
++ "Non-standard LCD timing data no. %d:\n", i);
++ xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
++ " HDisplay %d HSync %d HSyncEnd %d HTotal %d\n",
++ SiS_Pr->CP_HDisplay[i], SiS_Pr->CP_HSyncStart[i],
++ SiS_Pr->CP_HSyncEnd[i], SiS_Pr->CP_HTotal[i]);
++ xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
++ " VDisplay %d VSync %d VSyncEnd %d VTotal %d\n",
++ SiS_Pr->CP_VDisplay[i], SiS_Pr->CP_VSyncStart[i],
++ SiS_Pr->CP_VSyncEnd[i], SiS_Pr->CP_VTotal[i]);
++ xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
++ " Pixel clock: %3.3fMhz\n", (float)SiS_Pr->CP_Clock[i] / 1000);
++ xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
++ " To use this, add \"%dx%d\" to the list of Modes in the Display section\n",
++ SiS_Pr->CP_HDisplay[i],
++ SiS_Pr->CP_VDisplay[i]);
++ }
++ }
++
+ if(paneltype) {
++ if(!SiS_Pr->CP_PreferredX) SiS_Pr->CP_PreferredX = SiS_Pr->CP_MaxX;
++ if(!SiS_Pr->CP_PreferredY) SiS_Pr->CP_PreferredY = SiS_Pr->CP_MaxY;
+ cr37 &= 0xf1;
+ cr37 |= 0x02; /* SiS301 */
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x36,0xf0,paneltype);
+@@ -10392,7 +10947,7 @@
+ if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_302B))) return 0;
+ /* if(pSiS->VBFlags & VB_30xBDH) return 0; */
+
+- if(SiS_InitDDCRegs(SiS_Pr, pSiS, 2, 0, FALSE) == 0xFFFF) return 0;
++ if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 2, 0, FALSE) == 0xFFFF) return 0;
+
+ SiS_Pr->SiS_DDC_SecAddr = 0x00;
+
+@@ -10416,7 +10971,7 @@
+ /* Read the entire EDID */
+ retry = 2;
+ do {
+- if(SiS_ReadDDC(SiS_Pr, pSiS, DDCdatatype, buffer)) {
++ if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
+ xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
+ "CRT2: DDC read failed (attempt %d), %s\n",
+ (3-retry), (retry == 1) ? "giving up" : "retrying");
+@@ -10435,6 +10990,8 @@
+ "CRT2: Attached display expects digital input\n");
+ return 0;
+ }
++ SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
++ SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8);
+ foundcrt = TRUE;
+ break;
+ case 3:
+@@ -10448,198 +11005,19 @@
+ buffer[0x41]);
+ return 0;
+ }
++ SiS_Pr->CP_Vendor = buffer[2] | (buffer[1] << 8);
++ SiS_Pr->CP_Product = buffer[3] | (buffer[4] << 8);
+ foundcrt = TRUE;
+- break;
++ break;
+ }
+-
++
+ if(foundcrt) {
+ SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x10);
+ }
+ return(0);
+ }
+
+-#if 0
+- /* ----- */
+-USHORT
+-SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
+-{
+- USHORT DDCdatatype, paneltype, flag;
+- unsigned char cr36=0, cr37=0;
+- unsigned char tempal, tempah, tempbl, tempbh;
+- USHORT tempax, tempbx, tempcx, push1, push2, push3;
+- unsigned char addresstable[] = { 0x00, 0x22, 0x30, 0x40 };
+- int i;
+- unsigned char buffer[256];
+-
+- if(pSiS->VGAEngine != SIS_315_VGA) return 0xFFFF;
+- if(!(pSiS->VBFlags & (VB_301B|VB_302B))) return 0xFFFF;
+-
+- if(SiS_InitDDCRegs(SiS_Pr, pSiS, 1, 0, FALSE) == 0xFFFF) return 0xFFFF;
+-
+- flag = SiS_ProbeDDC(SiS_Pr);
+- if(flag & 0x02) {
+- SiS_Pr->SiS_DDC_DeviceAddr = 0xa0; /* EDID V1 */
+- DDCdatatype = 1;
+- SiS_Pr->SiS_DDC_SecAddr = 0x3a;
+- } else if(flag & 0x08) {
+- SiS_Pr->SiS_DDC_DeviceAddr = 0xa2; /* EDID V2 (P&D-D Monitor) */
+- DDCdatatype = 3;
+- SiS_Pr->SiS_DDC_SecAddr = 0x76;
+- } else if(flag & 0x10) {
+- SiS_Pr->SiS_DDC_DeviceAddr = 0xa6; /* EDID V2 (FP) */
+- DDCdatatype = 4;
+- SiS_Pr->SiS_DDC_SecAddr = 0x76;
+- } else return 0xFFFF;
+-
+-
+- SiS_ReadLCDDDC(SiS_Pr, 4, buffer);
+- tempbl = buffer[0]; /* 3a - 76 */
+- tempbh = buffer[1]; /* 3b - 77 */
+-
+- if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
+-
+- /* Read and analyze EDID V1 (res) */
+-
+- tempah = 0x02; /* 1024x768 by default */
+- tempbl &= 0xf0;
+- if(tempbl != 0x40) {
+- tempah = 0x03; /* 1280x1024 by default */
+- if(tempbl == 0x50) {
+- if(!tempbh) {
+- tempbh = buffer[3] & 0xf0;
+- if(tempbh == 0x30) {
+- SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
+- SiS_Pr->SiS_DDC_SecAddr = 0x23;
+- SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+- tempbl = buffer[0]; /* 0x23 */
+- tempbh = buffer[1]; /* 0x24 */
+- if(tempbl) cr37 |= 0x10;
+- tempah = 0x0a; /* 1280x768 */
+- }
+- if(tempbh == 0x40) {
+- SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
+- SiS_Pr->SiS_DDC_SecAddr = 0x23;
+- SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+- tempbl = buffer[0]; /* 0x23 */
+- tempbh = buffer[1]; /* 0x24 */
+- if(tempbl) cr37 |= 0x10;
+- tempah = 0x03; /* 1280x1024 */
+- }
+- tempbh = 0x00;
+- }
+- }
+- if(tempbh == 0x00) goto cr36ready;
+- tempah = 0x07; /* 1280x960 */
+- if(tempbh == 0xc0) goto cr36ready;
+- }
+- SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
+- SiS_Pr->SiS_DDC_SecAddr = 0x18; /* feature support */
+- SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+- tempbl = buffer[0];
+- tempbh = buffer[1];
+- if(tempbl & 0x02) goto cr36ready;
+- SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
+- SiS_Pr->SiS_DDC_SecAddr = 0x23; /* Established Timings */
+- SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+- tempbl = buffer[0];
+- tempbh = buffer[1];
+- tempah = 0x03;
+- if(!(tempbh & 0x01)) tempah = 0x02;
+- if(!tempbl) cr37 |= 0x10;
+-
+- } else {
+-
+- /* Read and analyze EDID V2 (res) */
+-
+- tempah = 0x02;
+- tempbx = tempbl | (tempbh << 8);
+- if(tempbx != 1024) tempah = 0x03;
+-
+- }
+-
+-cr36ready:
+- cr36 = tempah;
+-
+- if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
+-
+- /* Read and analyze EDID V1 (pol) */
+-
+- SiS_Pr->SiS_DDC_SecAddr = 0x47;
+- SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+- tempah = buffer[0];
+- tempah &= 0x06;
+- tempah ^= 0x06;
+- tempah <<= 5;
+- tempah |= 0x20;
+- cr37 &= 0x1f;
+- cr37 |= tempah;
+- if((cr36 & 0x07) == 0x07) cr37 &= 0x0e;
+-
+- } else {
+-
+- /* Read and analyze EDID V2 (depth, pol) */
+-
+- push1 = tempah;
+- SiS_Pr->SiS_DDC_SecAddr = 0x45;
+- SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+- tempah = 0x01;
+- if((buffer[0] != 0x20) && (buffer[0] != 0x34)) { /* RGB18 or 24? */
+- tempah = 0x00;
+- }
+- cr37 &= 0xfe;
+- cr37 |= tempah;
+-
+- SiS_Pr->SiS_DDC_SecAddr = 0x7e;
+- SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+- tempax = (USHORT)(buffer[0] | (buffer[1] << 8));
+- push2 = tempax;
+- tempax &= 0x0003;
+- tempax *= 0x1b;
+- push3 = tempax;
+- tempax = (USHORT)buffer[0];
+- tempax &= 0x001c;
+- tempax >>= 2;
+- tempax *= 8;
+- tempbx = push3;
+- tempbx += tempax;
+- if(buffer[0] & 0x20) { /* Luminance table provided? */
+- SiS_Pr->SiS_DDC_SecAddr = 0x80;
+- SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+- tempax = buffer[0] | (buffer[1] << 8);
+- tempax &= 0x1f;
+- if(buffer[0] & 0x70) tempax <<= 1;
+- tempax++;
+- tempbx += tempax; /* yes -> skip it */
+- }
+- tempcx = push2;
+- tempax = push1 << 8;
+- tempbx = (tempbx & 0xff00) | (((tempbx & 0x00ff) + 0x80) & 0x00ff);
+- if(tempcx & 0xf800) {
+- tempal = addresstable[((tempax & 0xff00) >> 8)];
+- tempcx &= 0xf8ff;
+- tempcx >>= 11;
+- for(i=0; i<tempcx; i++) {
+- SiS_Pr->SiS_DDC_SecAddr = (tempbx & 0x00ff);
+- SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+- tempbx += 0x04;
+- if(buffer[0] == tempal) break;
+- }
+- tempah = buffer[1];
+- tempah &= 0x0c;
+- tempah ^= 0x0c;
+- tempah <<= 4;
+- tempah |= 0x20;
+- cr37 &= 0x1f;
+- cr37 |= tempah;
+- if((cr36 & 0x07) == 0x07) cr37 &= 0x0e;
+- }
+- }
+- xf86DrvMsg(0, X_INFO, "DDC: cr36 = 0x%02x, cr37 = 0x%02x\n", cr36, cr37);
+- return 0;
+-}
+-#endif
+-
+-/* TW: Generic I2C functions (compliant to i2c library) */
++/* Generic I2C functions (compliant to i2c library) */
+
+ #if 0
+ USHORT
+@@ -10675,16 +11053,14 @@
+ void
+ SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh)
+ {
+- USHORT tempal,tempah,tempbl;
++ USHORT tempbl;
+
+- tempal = tempax & 0x00FF;
+- tempah =(tempax >> 8) & 0x00FF;
+- tempbl = SiS_GetCH70xx(SiS_Pr,tempal);
+- tempbl = (((tempbl & tempbh) | tempah) << 8 | tempal);
++ tempbl = SiS_GetCH70xx(SiS_Pr,(tempax & 0x00FF));
++ tempbl = (((tempbl & tempbh) << 8) | tempax);
+ SiS_SetCH70xx(SiS_Pr,tempbl);
+ }
+
+-/* TW: Generic I2C functions for Chrontel --------- */
++/* Generic I2C functions for Chrontel --------- */
+
+ void
+ SiS_SetSwitchDDC2(SiS_Private *SiS_Pr)
+@@ -10698,37 +11074,37 @@
+ SiS_WaitRetraceDDC(SiS_Pr);
+ }
+
+-/* TW: Set I2C start condition */
+-/* TW: This is done by a SD high-to-low transition while SC is high */
++/* Set I2C start condition */
++/* This is done by a SD high-to-low transition while SC is high */
+ USHORT
+ SiS_SetStart(SiS_Private *SiS_Pr)
+ {
+- if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* TW: (SC->low) */
++ if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
+ SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
+- ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data); /* TW: SD->high */
+- if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* TW: SC->high */
++ ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data); /* SD->high */
++ if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
+ SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
+- ~SiS_Pr->SiS_DDC_Data,0x00); /* TW: SD->low = start condition */
+- if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* TW: (SC->low) */
++ ~SiS_Pr->SiS_DDC_Data,0x00); /* SD->low = start condition */
++ if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->low) */
+ return 0;
+ }
+
+-/* TW: Set I2C stop condition */
+-/* TW: This is done by a SD low-to-high transition while SC is high */
++/* Set I2C stop condition */
++/* This is done by a SD low-to-high transition while SC is high */
+ USHORT
+ SiS_SetStop(SiS_Private *SiS_Pr)
+ {
+- if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* TW: (SC->low) */
++ if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
+ SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
+- ~SiS_Pr->SiS_DDC_Data,0x00); /* TW: SD->low */
+- if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* TW: SC->high */
++ ~SiS_Pr->SiS_DDC_Data,0x00); /* SD->low */
++ if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
+ SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
+- ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data); /* TW: SD->high = stop condition */
+- if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* TW: (SC->high) */
++ ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data); /* SD->high = stop condition */
++ if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->high) */
+ return 0;
+ }
+
+-/* TW: Write 8 bits of data */
++/* Write 8 bits of data */
+ USHORT
+ SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
+ {
+@@ -10736,18 +11112,18 @@
+
+ flag=0x80;
+ for(i=0;i<8;i++) {
+- SiS_SetSCLKLow(SiS_Pr); /* TW: SC->low */
++ SiS_SetSCLKLow(SiS_Pr); /* SC->low */
+ if(tempax & flag) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
+- ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data); /* TW: Write bit (1) to SD */
++ ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data); /* Write bit (1) to SD */
+ } else {
+ SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
+- ~SiS_Pr->SiS_DDC_Data,0x00); /* TW: Write bit (0) to SD */
++ ~SiS_Pr->SiS_DDC_Data,0x00); /* Write bit (0) to SD */
+ }
+- SiS_SetSCLKHigh(SiS_Pr); /* TW: SC->high */
++ SiS_SetSCLKHigh(SiS_Pr); /* SC->high */
+ flag >>= 1;
+ }
+- temp = SiS_CheckACK(SiS_Pr); /* TW: Check acknowledge */
++ temp = SiS_CheckACK(SiS_Pr); /* Check acknowledge */
+ return(temp);
+ }
+
+@@ -10808,27 +11184,27 @@
+ }
+ }
+
+-/* TW: Check I2C acknowledge */
++/* Check I2C acknowledge */
+ /* Returns 0 if ack ok, non-0 if ack not ok */
+ USHORT
+ SiS_CheckACK(SiS_Private *SiS_Pr)
+ {
+ USHORT tempah;
+
+- SiS_SetSCLKLow(SiS_Pr); /* TW: (SC->low) */
++ SiS_SetSCLKLow(SiS_Pr); /* (SC->low) */
+ SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
+- ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data); /* TW: (SD->high) */
+- SiS_SetSCLKHigh(SiS_Pr); /* TW: SC->high = clock impulse for ack */
+- tempah = SiS_GetReg1(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);/* TW: Read SD */
+- SiS_SetSCLKLow(SiS_Pr); /* TW: SC->low = end of clock impulse */
+- if(tempah & SiS_Pr->SiS_DDC_Data) return(1); /* TW: Ack OK if bit = 0 */
++ ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data); /* (SD->high) */
++ SiS_SetSCLKHigh(SiS_Pr); /* SC->high = clock impulse for ack */
++ tempah = SiS_GetReg1(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);/* Read SD */
++ SiS_SetSCLKLow(SiS_Pr); /* SC->low = end of clock impulse */
++ if(tempah & SiS_Pr->SiS_DDC_Data) return(1); /* Ack OK if bit = 0 */
+ else return(0);
+ }
+
+-/* TW: End of I2C functions ----------------------- */
++/* End of I2C functions ----------------------- */
+
+
+-/* =============== SiS 310/325/330 O.E.M. ================= */
++/* =============== SiS 315/330 O.E.M. ================= */
+
+ #ifdef SIS315H
+
+@@ -10838,11 +11214,11 @@
+ USHORT romptr;
+
+ if(HwDeviceExtension->jChipType < SIS_330) {
+- romptr = ROMAddr[0x128] | (ROMAddr[0x129] << 8);
++ romptr = ROMAddr[0x128] | (ROMAddr[0x129] << 8);
+ if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
+ romptr = ROMAddr[0x12a] | (ROMAddr[0x12b] << 8);
+ } else {
+- romptr = ROMAddr[0x1a8] | (ROMAddr[0x1a9] << 8);
++ romptr = ROMAddr[0x1a8] | (ROMAddr[0x1a9] << 8);
+ if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
+ romptr = ROMAddr[0x1aa] | (ROMAddr[0x1ab] << 8);
+ }
+@@ -10855,11 +11231,11 @@
+ USHORT romptr;
+
+ if(HwDeviceExtension->jChipType < SIS_330) {
+- romptr = ROMAddr[0x120] | (ROMAddr[0x121] << 8);
++ romptr = ROMAddr[0x120] | (ROMAddr[0x121] << 8);
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
+ romptr = ROMAddr[0x122] | (ROMAddr[0x123] << 8);
+ } else {
+- romptr = ROMAddr[0x1a0] | (ROMAddr[0x1a1] << 8);
++ romptr = ROMAddr[0x1a0] | (ROMAddr[0x1a1] << 8);
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
+ romptr = ROMAddr[0x1a2] | (ROMAddr[0x1a3] << 8);
+ }
+@@ -10884,10 +11260,22 @@
+ }
+
+ static USHORT
+-GetLCDPtrIndexBIOS(SiS_Private *SiS_Pr)
++GetLCDPtrIndexBIOS(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+ {
+ USHORT index;
+-
++
++ if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
++ if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
++ if((index = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
++ index >>= 4;
++ index *= 3;
++ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
++ else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
++ return index;
++ }
++ }
++ }
++
+ index = SiS_Pr->SiS_LCDResInfo & 0x0F;
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) index -= 5;
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) index -= 6;
+@@ -10895,7 +11283,6 @@
+ index *= 3;
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
+ else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
+-
+ return index;
+ }
+
+@@ -10945,8 +11332,9 @@
+ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+ UCHAR *ROMAddr, USHORT ModeNo)
+ {
+- USHORT delay,index,myindex,temp,romptr=0;
+-
++ USHORT delay=0,index,myindex,temp,romptr=0;
++ BOOLEAN dochiptest = TRUE;
++
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { /* VGA */
+
+ if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+@@ -10969,61 +11357,81 @@
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1)
+ delay = 0x00;
+ }
+-
++
+ } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { /* LCD */
+-
+- index = GetLCDPtrIndexBIOS(SiS_Pr);
+- myindex = GetLCDPtrIndex(SiS_Pr);
+-
+- if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) { /* 650+30xLV */
+- if(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+- if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+-#if 0 /* Always use the second pointer on 650; some BIOSes */
+- /* still carry old 301 data at the first location */
+- romptr = ROMAddr[0x120] | (ROMAddr[0x121] << 8);
+- if(SiS_Pr->SiS_VBType & VB_SIS302LV)
+-#endif
+- romptr = ROMAddr[0x122] | (ROMAddr[0x123] << 8);
+- if(!romptr) return;
+- delay = ROMAddr[(romptr + index)];
+- } else {
+- delay = SiS310_LCDDelayCompensation_650301B[myindex];
+-#if 0
++
++ BOOLEAN gotitfrompci = FALSE;
++
++ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
++
++ /* This is a piece of typical SiS crap: They code the OEM LCD
++ * delay into the code, at none defined place in the BIOS.
++ * We now have to start doing a PCI subsystem check here.
++ */
++
++ if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
++ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
++ gotitfrompci = TRUE;
++ dochiptest = FALSE;
++ delay = 0x03;
++ }
++ }
++
++ if(!gotitfrompci) {
++
++ index = GetLCDPtrIndexBIOS(SiS_Pr, HwDeviceExtension, BaseAddr);
++ myindex = GetLCDPtrIndex(SiS_Pr);
++
++ if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) { /* 650+30xLV */
++ if(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr)) {
++ if((ROMAddr) && SiS_Pr->SiS_UseROM) {
++#if 0 /* Always use the second pointer on 650; some BIOSes */
++ /* still carry old 301 data at the first location */
++ romptr = ROMAddr[0x120] | (ROMAddr[0x121] << 8);
++ if(SiS_Pr->SiS_VBType & VB_SIS302LV)
++#endif
++ romptr = ROMAddr[0x122] | (ROMAddr[0x123] << 8);
++ if(!romptr) return;
++ delay = ROMAddr[(romptr + index)];
++ } else {
++ delay = SiS310_LCDDelayCompensation_650301B[myindex];
++#if 0
++ if(SiS_Pr->SiS_VBType & VB_SIS302LV)
++ delay = SiS310_LCDDelayCompensation_650301B[myindex];
++#endif
++ }
++ } else {
++ delay = SiS310_LCDDelayCompensation_651301LV[myindex];
+ if(SiS_Pr->SiS_VBType & VB_SIS302LV)
+- delay = SiS310_LCDDelayCompensation_650301B[myindex];
+-#endif
+- }
+- } else {
+- delay = SiS310_LCDDelayCompensation_651301LV[myindex];
+- if(SiS_Pr->SiS_VBType & VB_SIS302LV)
+- delay = SiS310_LCDDelayCompensation_651302LV[myindex];
+- }
+- } else {
+- if((ROMAddr) && SiS_Pr->SiS_UseROM && /* 315, 330, 740, 650+301B */
+- (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)) {
+- romptr = GetLCDromptr(SiS_Pr, HwDeviceExtension, ROMAddr);
+- if(!romptr) return;
+- delay = ROMAddr[(romptr + index)];
++ delay = SiS310_LCDDelayCompensation_651302LV[myindex];
++ }
+ } else {
+- delay = SiS310_LCDDelayCompensation_301[myindex];
+- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+-#if 0 /* This data is (like the one in the BIOS) wrong. */
+- if(IS_SIS650740) { /* V */
+- delay = SiS310_LCDDelayCompensation_650301B[myindex];
+- } else {
+-#endif
+- delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
+-#if 0
++ if((ROMAddr) && SiS_Pr->SiS_UseROM && /* 315, 330, 740, 650+301B */
++ (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)) {
++ romptr = GetLCDromptr(SiS_Pr, HwDeviceExtension, ROMAddr);
++ if(!romptr) return;
++ delay = ROMAddr[(romptr + index)];
++ } else {
++ delay = SiS310_LCDDelayCompensation_301[myindex];
++ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
++#if 0 /* This data is (like the one in the BIOS) wrong. */
++ if(IS_SIS550650740660) {
++ delay = SiS310_LCDDelayCompensation_650301B[myindex];
++ } else {
++#endif
++ delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
++#if 0
++ }
++#endif
+ }
+-#endif
+- }
+- if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+- if(IS_SIS650) {
+- delay = SiS310_LCDDelayCompensation_LVDS650[myindex];
+- } else {
+- delay = SiS310_LCDDelayCompensation_LVDS740[myindex];
++ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
++ if(IS_SIS650) {
++ delay = SiS310_LCDDelayCompensation_LVDS650[myindex];
++ } else {
++ delay = SiS310_LCDDelayCompensation_LVDS740[myindex];
++ }
+ }
+- }
++ }
+ }
+ }
+
+@@ -11086,16 +11494,18 @@
+ }
+ }
+ } else {
+- if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
++ if(dochiptest && IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
+ temp = (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
+- if(temp == 8) {
++ if(temp == 8) { /* 1400x1050 BIOS */
+ delay &= 0x0f;
+ delay |= 0xb0;
+ } else if(temp == 6) {
+ delay &= 0x0f;
+ delay |= 0xc0;
++ } else if(temp > 7) { /* 1280x1024 BIOS */
++ delay = 0x35;
+ }
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2D,delay); /* index 2D D[3:0] */
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2D,delay);
+ } else {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
+ }
+@@ -11118,7 +11528,7 @@
+
+ if(ROMAddr && SiS_Pr->SiS_UseROM) {
+ romptr = ROMAddr[0x112] | (ROMAddr[0x113] << 8);
+- if(HwDeviceExtension->jChipType == SIS_330) {
++ if(HwDeviceExtension->jChipType >= SIS_330) {
+ romptr = ROMAddr[0x192] | (ROMAddr[0x193] << 8);
+ }
+ }
+@@ -11150,7 +11560,7 @@
+
+ if(ROMAddr && SiS_Pr->SiS_UseROM) {
+ romptr = ROMAddr[0x124] | (ROMAddr[0x125] << 8);
+- if(HwDeviceExtension->jChipType == SIS_330) {
++ if(HwDeviceExtension->jChipType >= SIS_330) {
+ romptr = ROMAddr[0x1a4] | (ROMAddr[0x1a5] << 8);
+ }
+ }
+@@ -11198,7 +11608,7 @@
+
+ if(ROMAddr && SiS_Pr->SiS_UseROM) {
+ OutputSelect = ROMAddr[0xf3];
+- if(HwDeviceExtension->jChipType == SIS_330) {
++ if(HwDeviceExtension->jChipType >= SIS_330) {
+ OutputSelect = ROMAddr[0x11b];
+ }
+ }
+@@ -11220,6 +11630,7 @@
+ }
+ }
+ }
++ /* PALN : Is this data correct? */
+ if(temp == EnablePALN) {
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ for(i=0x35, j=0; i<=0x38; i++, j++) {
+@@ -11247,13 +11658,13 @@
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
+
+ temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38); /* if PALM/N not set */
+- temp1 &= (EnablePALM | EnablePALN);
++ temp1 &= (EnablePALM | EnablePALN);
+ if(temp1) return;
+
+- if (ModeNo<=0x13) {
+- resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
++ if(ModeNo<=0x13) {
++ resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+ } else {
+- resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
++ resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ }
+
+ temp = GetTVPtrIndex(SiS_Pr);
+@@ -11262,17 +11673,17 @@
+ */
+ if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+ romptr = ROMAddr[0x116] | (ROMAddr[0x117] << 8);
+- if(HwDeviceExtension->jChipType == SIS_330) {
++ if(HwDeviceExtension->jChipType >= SIS_330) {
+ romptr = ROMAddr[0x196] | (ROMAddr[0x197] << 8);
+ }
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ romptr = ROMAddr[0x11c] | (ROMAddr[0x11d] << 8);
+- if(HwDeviceExtension->jChipType == SIS_330) {
++ if(HwDeviceExtension->jChipType >= SIS_330) {
+ romptr = ROMAddr[0x19c] | (ROMAddr[0x19d] << 8);
+ }
+ if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_SetFlag & TVSimuMode))) {
+ romptr = ROMAddr[0x116] | (ROMAddr[0x117] << 8);
+- if(HwDeviceExtension->jChipType == SIS_330) {
++ if(HwDeviceExtension->jChipType >= SIS_330) {
+ romptr = ROMAddr[0x196] | (ROMAddr[0x197] << 8);
+ }
+ }
+@@ -11296,19 +11707,19 @@
+ }
+ }
+
+- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* TW: 650/301LV: (VB_SIS301LV | VB_SIS302LV)) */
++ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* 650/301LV: (VB_SIS301LV | VB_SIS302LV)) */
+ if((!(SiS_Pr->SiS_VBInfo & SetPALTV)) && (ModeNo > 0x13)) {
+- if(resinfo == 6) {
++ if(resinfo == SIS_RI_640x480) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x31,0x21);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x32,0xf0);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x33,0xf5);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x34,0x7f);
+- } else if (resinfo == 7) {
++ } else if (resinfo == SIS_RI_800x600) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x31,0x21);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x32,0xf0);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x33,0xf5);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x34,0x7f);
+- } else if (resinfo == 8) {
++ } else if (resinfo == SIS_RI_1024x768) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x31,0x1e);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x32,0x8b);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x33,0xfb);
+@@ -11323,7 +11734,9 @@
+ UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+ {
+ SetDelayComp(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
+- /* TW: The TV functions are not for LVDS */
++
++ if(SiS_Pr->UseCustomMode) return;
++
+ if( (SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
+ SetAntiFlicker(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+ SetPhaseIncr(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+@@ -11335,7 +11748,7 @@
+ }
+
+ /* FinalizeLCD
+- * This finalizes some Part1 registers for the very panel used.
++ * This finalizes some CRT2 registers for the very panel used.
+ * If we have a backup if these registers, we use it; otherwise
+ * we set the register according to most BIOSes. However, this
+ * function looks quite different in every BIOS, so you better
+@@ -11350,6 +11763,11 @@
+
+ if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) return;
+
++ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
++ if(SiS_Pr->UseCustomMode) return;
++
++ if(SiS_Pr->SiS_CustomT == CUT_COMPAQ12802) return;
++
+ if(ModeNo <= 0x13) {
+ resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+@@ -11358,20 +11776,34 @@
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ }
+
++ if(IS_SIS650) {
++ if((SiS_GetReg1(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
++ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
++ }
++ }
++
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
++ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) { /* For all panels? */
++ /* Maybe ACER only? */
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
+ }
+ tempch = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
+ tempch &= 0xf0;
+ tempch >>= 4;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
++ if(tempch == 0x03) {
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x02);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1b,0x25);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1c,0x00);
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
++ }
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1f,0x76);
+- }
+- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
++ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+ if((SiS_Pr->Backup == TRUE) && (SiS_Pr->Backup_Mode == ModeNo)) {
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
+@@ -11387,14 +11819,14 @@
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,0x90);
+ if(ModeNo <= 0x13) {
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x11);
+- if((resinfo == 0) && (resinfo == 2)) return;
++ if((resinfo == 0) || (resinfo == 2)) return;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x18);
+- if((resinfo == 1) && (resinfo == 3)) return;
++ if((resinfo == 1) || (resinfo == 3)) return;
+ }
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x02);
+- if((ModeNo > 0x13) && (resinfo == 8)) {
++ if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x02); /* 1.10.7u */
+-#if 0
++#if 0
+ tempbx = 806; /* 0x326 */ /* other older BIOSes */
+ tempbx--;
+ temp = tempbx & 0xff;
+@@ -11449,7 +11881,7 @@
+ tempbl = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x04);
+ tempbx = (tempbh << 8) | tempbl;
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+- if((resinfo == 8) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
++ if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
+ if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
+ tempbx = 770;
+ } else {
+@@ -11477,67 +11909,56 @@
+ }
+ }
+
+-#if 0
+-/* TW: New and checked from 650/301LV BIOS */
+-/* This might clash with newer "FinalizeLCD()" function */
++#endif
++
++
++/* ================= SiS 300 O.E.M. ================== */
++
++#ifdef SIS300
++
+ void
+-SiS_OEMLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+- UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
++SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
++ UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, USHORT RefTabIndex)
+ {
+- USHORT tempbx,tempah,tempbl,tempbh,tempcl;
+-
+- if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
++ USHORT crt2crtc=0, modeflag, myindex=0;
++ UCHAR temp;
++ int i;
+
+- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+- SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension,BaseAddr);
+- tempbh = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x1a);
+- tempbh &= 0x38;
+- tempbh >>= 3;
+- tempbl = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x18);
+- tempbx = (tempbh << 8) | tempbl;
+- if(SiS_Pr->SiS_LCDTypeInfo == 1) tempbx -= 0x12;
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,tempbx & 0x00ff);
+- tempah = (tempbx & 0xff00) >> 8;
+- tempah &= 0x07;
+- tempah <<= 3;
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0xc7,tempah);
+- tempah = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x19);
+- tempah &= 0x0f;
+- if(SiS_Pr->SiS_LCDTypeInfo == 1) tempah -= 2;
+- tempah &= 0x0f;
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,tempah);
+- tempah = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x14);
+- if(SiS_Pr->SiS_LCDTypeInfo == 1) tempah++;
+- tempah -= 8;
+- SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,tempah);
+- } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+- tempcl = tempbh = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x01);
+- tempbh &= 0x70;
+- tempbh >>= 4;
+- tempbl = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x04);
+- tempbx = (tempbh << 8) | tempbl;
+- if(SiS_Pr->SiS_LCDTypeInfo == 1) {
+- tempbx -= 0x1e;
+- tempcl &= 0x0f;
+- tempcl -= 4;
+- tempcl &= 0x0f;
+- }
+- tempbl = tempbx & 0x00ff;
+- tempbh = (tempbx >> 8) & 0x00ff;
+- SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,tempbl);
+- tempbh <<= 4;
+- tempbh |= tempcl;
+- SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,tempbh);
+- }
+-}
+-#endif
++ if(ModeNo <= 0x13) {
++ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
++ crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
++ } else {
++ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++ crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
++ }
+
+-#endif
++ crt2crtc &= 0x3f;
+
++ if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
++ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);
++ }
+
+-/* ================= SiS 300 O.E.M. ================== */
++ if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
++ if(modeflag & HalfDCLK) myindex = 1;
+
+-#ifdef SIS300
++ if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
++ for(i=0; i<7; i++) {
++ if(barco_p1[myindex][crt2crtc][i][0]) {
++ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
++ barco_p1[myindex][crt2crtc][i][0],
++ barco_p1[myindex][crt2crtc][i][2],
++ barco_p1[myindex][crt2crtc][i][1]);
++ }
++ }
++ }
++ temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
++ if(temp & 0x80) {
++ temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x18);
++ temp++;
++ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,temp);
++ }
++ }
++}
+
+ #if 0 /* Not used */
+ static USHORT
+@@ -11582,7 +12003,7 @@
+
+ if(HwDeviceExtension->jChipType == SIS_300) {
+
+- tempbx = SiS_Pr->SiS_LCDResInfo - 2;
++ tempbx = (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0x0f) - 2;
+ if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
+@@ -11636,24 +12057,29 @@
+ {
+ USHORT index,temp,romptr=0;
+
++ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
++
+ if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+ if(!(ROMAddr[0x237] & 0x01)) return;
+ if(!(ROMAddr[0x237] & 0x02)) return;
+ romptr = ROMAddr[0x24b] | (ROMAddr[0x24c] << 8);
+ }
+
+- /* TW: The Panel Compensation Delay should be set according to tables
+- * here. Unfortunately, various BIOS versions don't case about
+- * a uniform way using eg. ROM byte 0x220, but use different
+- * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
+- * Thus we don't set this if the user select a custom pdc or if
+- * we otherwise detected a valid pdc.
++ /* The Panel Compensation Delay should be set according to tables
++ * here. Unfortunately, various BIOS versions don't case about
++ * a uniform way using eg. ROM byte 0x220, but use different
++ * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
++ * Thus we don't set this if the user select a custom pdc or if
++ * we otherwise detected a valid pdc.
+ */
+ if(HwDeviceExtension->pdc) return;
+
+ temp = GetOEMLCDPtr(SiS_Pr,HwDeviceExtension, ROMAddr, 0);
+
+- index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
++ if(SiS_Pr->UseCustomMode)
++ index = 0;
++ else
++ index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
+
+ if(HwDeviceExtension->jChipType != SIS_300) {
+ if(romptr) {
+@@ -11700,9 +12126,9 @@
+
+ static void
+ SetOEMLCDData(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+- UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
++ UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+ {
+-#if 0 /* TW: Unfinished; VData table missing */
++#if 0 /* Unfinished; Data table missing */
+ USHORT index,temp;
+
+ if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+@@ -11899,25 +12325,29 @@
+
+ void
+ SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+- USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo)
++ USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
++ USHORT RefTableIndex)
+ {
+- USHORT ModeIdIndex;
++ USHORT OEMModeIdIndex=0;
+
+- ModeIdIndex = SiS_SearchVBModeID(SiS_Pr,ROMAddr,&ModeNo);
+- if(!(ModeIdIndex)) return;
++ if(!SiS_Pr->UseCustomMode) {
++ OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,ROMAddr,&ModeNo);
++ if(!(OEMModeIdIndex)) return;
++ }
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+- SetOEMLCDDelay(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
++ SetOEMLCDDelay(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex);
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+- SetOEMLCDData(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
++ SetOEMLCDData(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex);
+ }
+ }
++ if(SiS_Pr->UseCustomMode) return;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+- SetOEMTVDelay(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
++ SetOEMTVDelay(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex);
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+- SetOEMAntiFlicker(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+- SetOEMPhaseIncr(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+- SetOEMYFilter(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
++ SetOEMAntiFlicker(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex);
++ SetOEMPhaseIncr(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex);
++ SetOEMYFilter(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex);
+ }
+ }
+ }
+Index: linux-2.6.0-test5/drivers/video/sis/init301.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/sis/init301.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/sis/init301.h 2003-09-27 11:38:35.081195232 +0800
+@@ -1,20 +1,47 @@
+-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init301.h,v 1.4 2000/12/02 01:16:17 dawes Exp $ */
++/* $XFree86$ */
++/*
++ * Data and prototypes for init301.c
++ *
++ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
++ *
++ * If distributed as part of the linux kernel, the contents of this file
++ * is entirely covered by the GPL.
++ *
++ * Otherwise, the following terms apply:
++ *
++ * Permission to use, copy, modify, distribute, and sell this software and its
++ * documentation for any purpose is hereby granted without fee, provided that
++ * the above copyright notice appear in all copies and that both that
++ * copyright notice and this permission notice appear in supporting
++ * documentation, and that the name of the copyright holder not be used in
++ * advertising or publicity pertaining to distribution of the software without
++ * specific, written prior permission. The copyright holder makes no representations
++ * about the suitability of this software for any purpose. It is provided
++ * "as is" without express or implied warranty.
++ *
++ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
++ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
++ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
++ * PERFORMANCE OF THIS SOFTWARE.
++ *
++ * Author: Thomas Winischhofer <thomas@winischhofer.net>
++ *
++ * Based on code by Silicon Intergrated Systems
++ *
++ */
++
+ #ifndef _INIT301_
+ #define _INIT301_
+
+ #include "osdef.h"
++
+ #include "initdef.h"
+ #include "vgatypes.h"
+ #include "vstruct.h"
+
+-#ifdef TC
+-#include <stdio.h>
+-#include <string.h>
+-#include <conio.h>
+-#include <dos.h>
+-#include <stdlib.h>
+-#endif
+-
+ #ifdef LINUX_XF86
+ #include "xf86.h"
+ #include "xf86Pci.h"
+@@ -24,6 +51,9 @@
+ #endif
+
+ #ifdef LINUX_KERNEL
++#ifdef SIS_CP
++#undef SIS_CP
++#endif
+ #include <linux/config.h>
+ #include <linux/version.h>
+ #include <asm/io.h>
+@@ -35,24 +65,60 @@
+ #endif
+ #endif
+
+-#ifdef WIN2000
+-#include <stdio.h>
+-#include <string.h>
+-#include <miniport.h>
+-#include "dderror.h"
+-#include "devioctl.h"
+-#include "miniport.h"
+-#include "ntddvdeo.h"
+-#include "video.h"
+-#include "sisv.h"
+-#endif
++const UCHAR SiS_HiVisionTable[3][64] = {
++ {
++ 0x17, 0x1d, 0x03, 0x09, 0x05, 0x06, 0x0c, 0x0c,
++ 0x94, 0x49, 0x01, 0x0a, 0x06, 0x0d, 0x04, 0x0a,
++ 0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x1b,
++ 0x0c, 0x50, 0x00, 0x97, 0x00, 0xd4, 0x4a, 0x17,
++ 0x7d, 0x05, 0x4b, 0x00, 0x00, 0xe2, 0x00, 0x02,
++ 0x03, 0x0a, 0x65, 0x9d, 0x08, 0x92, 0x8f, 0x40,
++ 0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x53,
++ 0x00, 0x40, 0x44, 0x00, 0xdb, 0x02, 0x3b, 0x00
++ },
++ {
++ 0x1d, 0x1d, 0x06, 0x09, 0x0b, 0x0c, 0x0c, 0x0c,
++ 0x98, 0x0a, 0x01, 0x0d, 0x06, 0x0d, 0x04, 0x0a,
++ 0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x3f,
++ 0x0c, 0x50, 0xb2, 0x2e, 0x16, 0xb5, 0xf4, 0x03,
++ 0x7d, 0x11, 0x7d, 0xea, 0x30, 0x36, 0x18, 0x96,
++ 0x21, 0x0a, 0x58, 0xee, 0x42, 0x92, 0x0f, 0x40,
++ 0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x04, 0xf3,
++ 0x00, 0x40, 0x11, 0x00, 0xfc, 0xff, 0x32, 0x00
++ },
++ {
++ 0x13, 0x1d, 0xe8, 0x09, 0x09, 0xed, 0x0c, 0x0c,
++ 0x98, 0x0a, 0x01, 0x0c, 0x06, 0x0d, 0x04, 0x0a,
++ 0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x3f,
++ 0xed, 0x50, 0x70, 0x9f, 0x16, 0x59, 0x2b, 0x13,
++ 0x27, 0x0b, 0x27, 0xfc, 0x30, 0x27, 0x1c, 0xb0,
++ 0x4b, 0x4b, 0x6f, 0x2f, 0x63, 0x92, 0x0f, 0x40,
++ 0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x2a,
++ 0x00, 0x40, 0x11, 0x00, 0xfc, 0xff, 0x32, 0x00
++ }
++};
+
+-#if 0
+-extern const USHORT SiS_MDA_DAC[];
+-extern const USHORT SiS_CGA_DAC[];
+-extern const USHORT SiS_EGA_DAC[];
+-extern const USHORT SiS_VGA_DAC[];
+-#endif
++const UCHAR SiS_HiTVGroup3_1[] = {
++ 0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x13,
++ 0xb1, 0x41, 0x62, 0x62, 0xff, 0xf4, 0x45, 0xa6,
++ 0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
++ 0xac, 0xda, 0x60, 0xfe, 0x6a, 0x9a, 0x06, 0x10,
++ 0xd1, 0x04, 0x18, 0x0a, 0xff, 0x80, 0x00, 0x80,
++ 0x3b, 0x77, 0x00, 0xef, 0xe0, 0x10, 0xb0, 0xe0,
++ 0x10, 0x4f, 0x0f, 0x0f, 0x05, 0x0f, 0x08, 0x6e,
++ 0x1a, 0x1f, 0x25, 0x2a, 0x4c, 0xaa, 0x01
++};
++
++const UCHAR SiS_HiTVGroup3_2[] = {
++ 0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x7a,
++ 0x54, 0x41, 0xe7, 0xe7, 0xff, 0xf4, 0x45, 0xa6,
++ 0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
++ 0xac, 0x6a, 0x60, 0x2b, 0x52, 0xcd, 0x61, 0x10,
++ 0x51, 0x04, 0x18, 0x0a, 0x1f, 0x80, 0x00, 0x80,
++ 0xff, 0xa4, 0x04, 0x2b, 0x94, 0x21, 0x72, 0x94,
++ 0x26, 0x05, 0x01, 0x0f, 0xed, 0x0f, 0x0a, 0x64,
++ 0x18, 0x1d, 0x23, 0x28, 0x4c, 0xaa, 0x01
++};
+
+ extern BOOLEAN SiS_SearchVBModeID(SiS_Private *SiS_Pr, UCHAR *RomAddr, USHORT *);
+
+@@ -77,7 +143,8 @@
+ USHORT RefreshRateTableIndex,USHORT *CRT2Index,USHORT *ResIndex);
+ #endif
+ void SiS_GetCRT2Part2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex,USHORT *CRT2Index, USHORT *ResIndex);
++ USHORT RefreshRateTableIndex,USHORT *CRT2Index, USHORT *ResIndex,
++ PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ void SiS_GetCRT2Data301(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ USHORT SiS_GetResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+@@ -129,7 +196,6 @@
+ BOOLEAN SiS_BridgeIsOn(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO);
+ BOOLEAN SiS_BridgeIsEnable(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO);
+ BOOLEAN SiS_BridgeInSlave(SiS_Private *SiS_Pr);
+-void SiS_PresetScratchregister(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ void SiS_SetTVSystem(SiS_Private *SiS_Pr);
+ void SiS_LongWait(SiS_Private *SiS_Pr);
+ USHORT SiS_GetQueueConfig(SiS_Private *SiS_Pr);
+@@ -149,7 +215,7 @@
+ USHORT RefreshRateTableIndex,USHORT *PanelIndex,USHORT *ResIndex);
+ #endif
+ void SiS_SetTPData(SiS_Private *SiS_Pr);
+-void SiS_WhatIsThis(SiS_Private *SiS_Pr, USHORT myvbinfo);
++void SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo);
+ void SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ void SiS_SetCHTVReg(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+@@ -178,30 +244,28 @@
+ USHORT SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
+ USHORT SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
+ USHORT SiS_CheckACK(SiS_Private *SiS_Pr);
+-USHORT SiS_ReadLCDDDC(SiS_Private *SiS_Pr, USHORT length, unsigned char *buffer);
+-#ifdef LINUX_XF86
+-USHORT SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS);
+-USHORT SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS);
+-#endif
++
+ #ifdef SIS315H
+ void SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+ UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+ void SiS_OEMLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+- UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
++ UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex);
+ #endif
+ #ifdef SIS300
+ void SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+- UCHAR *ROMAddr,USHORT ModeNo);
++ UCHAR *ROMAddr,USHORT ModeNo, USHORT ModeIdIndex, USHORT RefTabindex);
++void SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
++ UCHAR *ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,USHORT RefTableIndex);
+ #endif
+ BOOLEAN SiS_LowModeStuff(SiS_Private *SiS_Pr, USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+
+-BOOLEAN SiS_GetLCDResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo, USHORT ModeIdIndex,
++void SiS_GetLCDResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo, USHORT ModeIdIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ /* void SiS_CHACRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex); */
+
+-BOOLEAN SiS_SetCRT2Group301(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+- PSIS_HW_DEVICE_INFO HwDeviceExtension);
++BOOLEAN SiS_SetCRT2Group(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
++ PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ void SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex);
+ void SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+@@ -237,19 +301,19 @@
+ void SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ void SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+
+-void SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr);
++void SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ void SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr);
+ #ifdef SIS315H
+ void SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT BaseAddr);
+-void SiS_Chrontel701xOff(SiS_Private *SiS_Pr);
++void SiS_Chrontel701xOff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ void SiS_ChrontelResetDB(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+ void SiS_ChrontelDoSomething4(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+ void SiS_ChrontelDoSomething3(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+ void SiS_ChrontelDoSomething2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+ void SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+ BOOLEAN SiS_WeHaveBacklightCtrl(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+-void SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr);
++void SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ void SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+ #ifdef NEWCH701x
+ void SiS_ChrontelDoSomething5(SiS_Private *SiS_Pr);
+@@ -289,73 +353,21 @@
+ extern UCHAR SiS_Get310DRAMType(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ #endif
+
+-#ifdef LINUX_XF86
+ /* DDC functions */
+-USHORT SiS_InitDDCRegs(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32);
++USHORT SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
++ USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32);
+ USHORT SiS_WriteDABDDC(SiS_Private *SiS_Pr);
+ USHORT SiS_PrepareReadDDC(SiS_Private *SiS_Pr);
+ USHORT SiS_PrepareDDC(SiS_Private *SiS_Pr);
+ void SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno);
+ USHORT SiS_DoProbeDDC(SiS_Private *SiS_Pr);
+ USHORT SiS_ProbeDDC(SiS_Private *SiS_Pr);
+-USHORT SiS_ReadDDC(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT DDCdatatype, unsigned char *buffer);
+-USHORT SiS_HandleDDC(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT adaptnum,
+- USHORT DDCdatatype, unsigned char *buffer);
++USHORT SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer);
++USHORT SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
++ USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer);
++#ifdef LINUX_XF86
++USHORT SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS);
++USHORT SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS);
+ #endif
+
+-const UCHAR SiS_HiVisionTable[3][64] = {
+- {
+- 0x17, 0x1d, 0x03, 0x09, 0x05, 0x06, 0x0c, 0x0c,
+- 0x94, 0x49, 0x01, 0x0a, 0x06, 0x0d, 0x04, 0x0a,
+- 0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x1b,
+- 0x0c, 0x50, 0x00, 0x97, 0x00, 0xd4, 0x4a, 0x17,
+- 0x7d, 0x05, 0x4b, 0x00, 0x00, 0xe2, 0x00, 0x02,
+- 0x03, 0x0a, 0x65, 0x9d, 0x08, 0x92, 0x8f, 0x40,
+- 0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x53,
+- 0x00, 0x40, 0x44, 0x00, 0xdb, 0x02, 0x3b, 0x00
+- },
+- {
+- 0x1d, 0x1d, 0x06, 0x09, 0x0b, 0x0c, 0x0c, 0x0c,
+- 0x98, 0x0a, 0x01, 0x0d, 0x06, 0x0d, 0x04, 0x0a,
+- 0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x3f,
+- 0x0c, 0x50, 0xb2, 0x2e, 0x16, 0xb5, 0xf4, 0x03,
+- 0x7d, 0x11, 0x7d, 0xea, 0x30, 0x36, 0x18, 0x96,
+- 0x21, 0x0a, 0x58, 0xee, 0x42, 0x92, 0x0f, 0x40,
+- 0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x04, 0xf3,
+- 0x00, 0x40, 0x11, 0x00, 0xfc, 0xff, 0x32, 0x00
+- },
+- {
+- 0x13, 0x1d, 0xe8, 0x09, 0x09, 0xed, 0x0c, 0x0c,
+- 0x98, 0x0a, 0x01, 0x0c, 0x06, 0x0d, 0x04, 0x0a,
+- 0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x3f,
+- 0xed, 0x50, 0x70, 0x9f, 0x16, 0x59, 0x2b, 0x13,
+- 0x27, 0x0b, 0x27, 0xfc, 0x30, 0x27, 0x1c, 0xb0,
+- 0x4b, 0x4b, 0x6f, 0x2f, 0x63, 0x92, 0x0f, 0x40,
+- 0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x2a,
+- 0x00, 0x40, 0x11, 0x00, 0xfc, 0xff, 0x32, 0x00
+- }
+-};
+-
+-const UCHAR SiS_HiTVGroup3_1[] = {
+- 0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x13,
+- 0xb1, 0x41, 0x62, 0x62, 0xff, 0xf4, 0x45, 0xa6,
+- 0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
+- 0xac, 0xda, 0x60, 0xfe, 0x6a, 0x9a, 0x06, 0x10,
+- 0xd1, 0x04, 0x18, 0x0a, 0xff, 0x80, 0x00, 0x80,
+- 0x3b, 0x77, 0x00, 0xef, 0xe0, 0x10, 0xb0, 0xe0,
+- 0x10, 0x4f, 0x0f, 0x0f, 0x05, 0x0f, 0x08, 0x6e,
+- 0x1a, 0x1f, 0x25, 0x2a, 0x4c, 0xaa, 0x01
+-};
+-
+-const UCHAR SiS_HiTVGroup3_2[] = {
+- 0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x7a,
+- 0x54, 0x41, 0xe7, 0xe7, 0xff, 0xf4, 0x45, 0xa6,
+- 0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
+- 0xac, 0x6a, 0x60, 0x2b, 0x52, 0xcd, 0x61, 0x10,
+- 0x51, 0x04, 0x18, 0x0a, 0x1f, 0x80, 0x00, 0x80,
+- 0xff, 0xa4, 0x04, 0x2b, 0x94, 0x21, 0x72, 0x94,
+- 0x26, 0x05, 0x01, 0x0f, 0xed, 0x0f, 0x0a, 0x64,
+- 0x18, 0x1d, 0x23, 0x28, 0x4c, 0xaa, 0x01
+-};
+-
+ #endif
+Index: linux-2.6.0-test5/drivers/video/sis/init.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/sis/init.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/sis/init.c 2003-09-27 11:38:35.169181856 +0800
+@@ -1,24 +1,17 @@
+ /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init.c,v 1.3 2002/24/04 01:16:16 dawes Exp $ */
+ /*
+- * Mode switching code (CRT1 section) for SiS 300/540/630/730/315/550/650/740/330
++ * Mode switching code (CRT1 section) for
++ * SiS 300/540/630/730/315/550/650/M650/651/M652/740/330/660/M660/760
+ * (Universal module for Linux kernel framebuffer and XFree86 4.x)
+ *
+ * Assembler-To-C translation
+- * Copyright 2002 by Thomas Winischhofer <thomas@winischhofer.net>
+- * Minor parts Copyright SiS, Inc.
++ * Copyright 2002, 2003 by Thomas Winischhofer <thomas@winischhofer.net>
++ * Formerly based on non-functional code-fragements by SiS, Inc.
+ *
+- * Based on BIOS
+- * 1.10.07, 1.10a for 650/CH7019
+- * 1.11.21a for 740/CH7019
+- * 1.11.05 for 650/LVDS (w/o Chrontel)
+- * 1.07.1b, 1.11.6s, 1.11.6w, 1.11.7w, 1.11.8r for 650/301(B/LV)
+- * 2.04.50 (I) and 2.04.5c (II) for 630/301(B)
+- * 2.06.50 for 630/301B (dual VGA)
+- * 2.02.3b, 2.03.02, 2.04.5c, 2.07a and 2.08.b3 for 630/LVDS/LVDS+CH7005
+- * 2.04.5c, 2.04.6c for 730+LVDS+CH7005
+- * 1.09b for 315/301(B)
+- * 1.16.51 for 300+301LV (ECS A907)
+- * 1.01.03 for 330 (Xabre 400)
++ * If distributed as part of the linux kernel, the contents of this file
++ * is entirely covered by the GPL.
++ *
++ * Otherwise, the following terms apply:
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+@@ -61,12 +54,12 @@
+ #ifdef LINUX_XF86
+ BOOLEAN SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom);
+-DisplayModePtr SiSBuildBuiltInModeList(ScrnInfoPtr pScrn);
+-#ifdef SISDUALHEAD /* TW: For dual head */
++DisplayModePtr SiSBuildBuiltInModeList(ScrnInfoPtr pScrn, BOOLEAN includelcdmodes, BOOLEAN isfordvi);
++#ifdef SISDUALHEAD
+ BOOLEAN SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom);
+ BOOLEAN SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+- ScrnInfoPtr pScrn, DisplayModePtr mode);
++ ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom);
+ #endif /* dual head */
+ #endif /* linux_xf86 */
+
+@@ -90,49 +83,201 @@
+ static ULONG GetDRAMSize(SiS_Private *SiS_Pr,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension);
+
+-static void DelaySeconds(int seconds);
+-void SiS_DebugCode(SiS_Private *SiS_Pr, UCHAR code);
+-
+ static void
+-DelaySeconds(int seconds)
+-{
+- int i;
+-#ifdef WIN2000
+- int j;
+-#endif
+-
+- for (i=0;i<seconds;i++) {
+-#ifdef TC
+- delay(1000);
+-#endif
+-
+-#ifdef WIN2000
+- for (j=0;j<20000;j++)
+- VideoPortStallExecution(50);
+-#endif
+-
+-#ifdef WINCE_HEADER
+-#endif
+-
+-#ifdef LINUX_KERNEL
+-#endif
+- }
+-}
+-
+-void
+-SiS_DebugCode(SiS_Private *SiS_Pr, UCHAR code)
++InitCommonPointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+ {
+- OutPortByte(0x80, code);
+- DelaySeconds(0x3);
++ SiS_Pr->SiS_StResInfo = SiS_StResInfo;
++ SiS_Pr->SiS_ModeResInfo = SiS_ModeResInfo;
++ SiS_Pr->SiS_StandTable = SiS_StandTable;
++ if(HwDeviceExtension->jChipType < SIS_315H) {
++ SiS_StandTable[0x04].CRTC[4] = 0x2b;
++ SiS_StandTable[0x05].CRTC[4] = 0x2b;
++ SiS_StandTable[0x06].CRTC[4] = 0x54;
++ SiS_StandTable[0x06].CRTC[5] = 0x80;
++ SiS_StandTable[0x0d].CRTC[4] = 0x2b;
++ SiS_StandTable[0x0e].CRTC[4] = 0x54;
++ SiS_StandTable[0x0e].CRTC[5] = 0x80;
++ SiS_StandTable[0x11].CRTC[4] = 0x54;
++ SiS_StandTable[0x11].CRTC[5] = 0x80;
++ SiS_StandTable[0x11].CRTC[16] = 0x83;
++ SiS_StandTable[0x11].CRTC[17] = 0x85;
++ SiS_StandTable[0x12].CRTC[4] = 0x54;
++ SiS_StandTable[0x12].CRTC[5] = 0x80;
++ SiS_StandTable[0x12].CRTC[16] = 0x83;
++ SiS_StandTable[0x12].CRTC[17] = 0x85;
++ SiS_StandTable[0x13].CRTC[5] = 0xa0;
++ SiS_StandTable[0x17].CRTC[5] = 0xa0;
++ SiS_StandTable[0x1a].CRTC[4] = 0x54;
++ SiS_StandTable[0x1a].CRTC[5] = 0x80;
++ SiS_StandTable[0x1a].CRTC[16] = 0xea;
++ SiS_StandTable[0x1a].CRTC[17] = 0x8c;
++ SiS_StandTable[0x1b].CRTC[4] = 0x54;
++ SiS_StandTable[0x1b].CRTC[5] = 0x80;
++ SiS_StandTable[0x1b].CRTC[16] = 0xea;
++ SiS_StandTable[0x1b].CRTC[17] = 0x8c;
++ SiS_StandTable[0x1c].CRTC[4] = 0x54;
++ SiS_StandTable[0x1c].CRTC[5] = 0x80;
++ } else {
++ SiS_StandTable[0x04].CRTC[4] = 0x2c;
++ SiS_StandTable[0x05].CRTC[4] = 0x2c;
++ SiS_StandTable[0x06].CRTC[4] = 0x55;
++ SiS_StandTable[0x06].CRTC[5] = 0x81;
++ SiS_StandTable[0x0d].CRTC[4] = 0x2c;
++ SiS_StandTable[0x0e].CRTC[4] = 0x55;
++ SiS_StandTable[0x0e].CRTC[5] = 0x81;
++ SiS_StandTable[0x11].CRTC[4] = 0x55;
++ SiS_StandTable[0x11].CRTC[5] = 0x81;
++ SiS_StandTable[0x11].CRTC[16] = 0x82;
++ SiS_StandTable[0x11].CRTC[17] = 0x84;
++ SiS_StandTable[0x12].CRTC[4] = 0x55;
++ SiS_StandTable[0x12].CRTC[5] = 0x81;
++ SiS_StandTable[0x12].CRTC[16] = 0x82;
++ SiS_StandTable[0x12].CRTC[17] = 0x84;
++ SiS_StandTable[0x13].CRTC[5] = 0xb1;
++ SiS_StandTable[0x17].CRTC[5] = 0xb1;
++ SiS_StandTable[0x1a].CRTC[4] = 0x55;
++ SiS_StandTable[0x1a].CRTC[5] = 0x81;
++ SiS_StandTable[0x1a].CRTC[16] = 0xe9;
++ SiS_StandTable[0x1a].CRTC[17] = 0x8b;
++ SiS_StandTable[0x1b].CRTC[4] = 0x55;
++ SiS_StandTable[0x1b].CRTC[5] = 0x81;
++ SiS_StandTable[0x1b].CRTC[16] = 0xe9;
++ SiS_StandTable[0x1b].CRTC[17] = 0x8b;
++ SiS_StandTable[0x1c].CRTC[4] = 0x55;
++ SiS_StandTable[0x1c].CRTC[5] = 0x81;
++ }
++
++ SiS_Pr->SiS_NTSCPhase = SiS_NTSCPhase;
++ SiS_Pr->SiS_PALPhase = SiS_PALPhase;
++ SiS_Pr->SiS_NTSCPhase2 = SiS_NTSCPhase2;
++ SiS_Pr->SiS_PALPhase2 = SiS_PALPhase2;
++ SiS_Pr->SiS_PALMPhase = SiS_PALMPhase;
++ SiS_Pr->SiS_PALNPhase = SiS_PALNPhase;
++ SiS_Pr->SiS_PALMPhase2 = SiS_PALMPhase2;
++ SiS_Pr->SiS_PALNPhase2 = SiS_PALNPhase2;
++ SiS_Pr->SiS_SpecialPhase = SiS_SpecialPhase;
++
++ SiS_Pr->SiS_NTSCTiming = SiS_NTSCTiming;
++ SiS_Pr->SiS_PALTiming = SiS_PALTiming;
++ SiS_Pr->SiS_HiTVSt1Timing = SiS_HiTVSt1Timing;
++ SiS_Pr->SiS_HiTVSt2Timing = SiS_HiTVSt2Timing;
++ SiS_Pr->SiS_HiTVTextTiming = SiS_HiTVTextTiming;
++ SiS_Pr->SiS_HiTVExtTiming = SiS_HiTVExtTiming;
++ SiS_Pr->SiS_HiTVGroup3Data = SiS_HiTVGroup3Data;
++ SiS_Pr->SiS_HiTVGroup3Simu = SiS_HiTVGroup3Simu;
++ SiS_Pr->SiS_HiTVGroup3Text = SiS_HiTVGroup3Text;
++
++ SiS_Pr->SiS_StPALData = SiS_StPALData;
++ SiS_Pr->SiS_ExtPALData = SiS_ExtPALData;
++ SiS_Pr->SiS_StNTSCData = SiS_StNTSCData;
++ SiS_Pr->SiS_ExtNTSCData = SiS_ExtNTSCData;
++/* SiS_Pr->SiS_St1HiTVData = SiS_St1HiTVData; */
++ SiS_Pr->SiS_St2HiTVData = SiS_St2HiTVData;
++ SiS_Pr->SiS_ExtHiTVData = SiS_ExtHiTVData;
++
++ SiS_Pr->pSiS_OutputSelect = &SiS_OutputSelect;
++ SiS_Pr->pSiS_SoftSetting = &SiS_SoftSetting;
++
++ SiS_Pr->SiS_LCD1280x960Data = SiS_LCD1280x960Data;
++ SiS_Pr->SiS_ExtLCD1400x1050Data = SiS_ExtLCD1400x1050Data;
++ SiS_Pr->SiS_ExtLCD1600x1200Data = SiS_ExtLCD1600x1200Data;
++ SiS_Pr->SiS_StLCD1400x1050Data = SiS_StLCD1400x1050Data;
++ SiS_Pr->SiS_StLCD1600x1200Data = SiS_StLCD1600x1200Data;
++ SiS_Pr->SiS_NoScaleData1400x1050 = SiS_NoScaleData1400x1050;
++ SiS_Pr->SiS_NoScaleData1600x1200 = SiS_NoScaleData1600x1200;
++ SiS_Pr->SiS_ExtLCD1280x768Data = SiS_ExtLCD1280x768Data;
++ SiS_Pr->SiS_StLCD1280x768Data = SiS_StLCD1280x768Data;
++ SiS_Pr->SiS_NoScaleData1280x768 = SiS_NoScaleData1280x768;
++ SiS_Pr->SiS_NoScaleData = SiS_NoScaleData;
++
++ SiS_Pr->SiS_LVDS320x480Data_1 = SiS_LVDS320x480Data_1;
++ SiS_Pr->SiS_LVDS800x600Data_1 = SiS_LVDS800x600Data_1;
++ SiS_Pr->SiS_LVDS800x600Data_2 = SiS_LVDS800x600Data_2;
++ SiS_Pr->SiS_LVDS1024x768Data_1 = SiS_LVDS1024x768Data_1;
++ SiS_Pr->SiS_LVDS1024x768Data_2 = SiS_LVDS1024x768Data_2;
++ SiS_Pr->SiS_LVDS1280x1024Data_1 = SiS_LVDS1280x1024Data_1;
++ SiS_Pr->SiS_LVDS1280x1024Data_2 = SiS_LVDS1280x1024Data_2;
++ SiS_Pr->SiS_LVDS1400x1050Data_1 = SiS_LVDS1400x1050Data_1;
++ SiS_Pr->SiS_LVDS1400x1050Data_2 = SiS_LVDS1400x1050Data_2;
++ SiS_Pr->SiS_LVDS1600x1200Data_1 = SiS_LVDS1600x1200Data_1;
++ SiS_Pr->SiS_LVDS1600x1200Data_2 = SiS_LVDS1600x1200Data_2;
++ SiS_Pr->SiS_LVDS1280x768Data_1 = SiS_LVDS1280x768Data_1;
++ SiS_Pr->SiS_LVDS1280x768Data_2 = SiS_LVDS1280x768Data_2;
++ SiS_Pr->SiS_LVDS1024x600Data_1 = SiS_LVDS1024x600Data_1;
++ SiS_Pr->SiS_LVDS1024x600Data_2 = SiS_LVDS1024x600Data_2;
++ SiS_Pr->SiS_LVDS1152x768Data_1 = SiS_LVDS1152x768Data_1;
++ SiS_Pr->SiS_LVDS1152x768Data_2 = SiS_LVDS1152x768Data_2;
++ SiS_Pr->SiS_LVDSXXXxXXXData_1 = SiS_LVDSXXXxXXXData_1;
++ SiS_Pr->SiS_LVDS1280x960Data_1 = SiS_LVDS1280x960Data_1;
++ SiS_Pr->SiS_LVDS1280x960Data_2 = SiS_LVDS1280x960Data_2;
++ SiS_Pr->SiS_LVDS640x480Data_1 = SiS_LVDS640x480Data_1;
++ SiS_Pr->SiS_LVDS1280x960Data_1 = SiS_LVDS1280x1024Data_1;
++ SiS_Pr->SiS_LVDS1280x960Data_2 = SiS_LVDS1280x1024Data_2;
++ SiS_Pr->SiS_LVDS640x480Data_1 = SiS_LVDS640x480Data_1;
++ SiS_Pr->SiS_LVDS640x480Data_2 = SiS_LVDS640x480Data_2;
++
++ SiS_Pr->SiS_LVDSBARCO1366Data_1 = SiS_LVDSBARCO1366Data_1;
++ SiS_Pr->SiS_LVDSBARCO1366Data_2 = SiS_LVDSBARCO1366Data_2;
++ SiS_Pr->SiS_LVDSBARCO1024Data_1 = SiS_LVDSBARCO1024Data_1;
++ SiS_Pr->SiS_LVDSBARCO1024Data_2 = SiS_LVDSBARCO1024Data_2;
++ SiS_Pr->SiS_LVDS848x480Data_1 = SiS_LVDS848x480Data_1;
++ SiS_Pr->SiS_LVDS848x480Data_2 = SiS_LVDS848x480Data_2;
++
++ SiS_Pr->SiS_LCDA1400x1050Data_1 = SiS_LCDA1400x1050Data_1;
++ SiS_Pr->SiS_LCDA1400x1050Data_2 = SiS_LCDA1400x1050Data_2;
++ SiS_Pr->SiS_LCDA1600x1200Data_1 = SiS_LCDA1600x1200Data_1;
++ SiS_Pr->SiS_LCDA1600x1200Data_2 = SiS_LCDA1600x1200Data_2;
++ SiS_Pr->SiS_CHTVUNTSCData = SiS_CHTVUNTSCData;
++ SiS_Pr->SiS_CHTVONTSCData = SiS_CHTVONTSCData;
++
++ SiS_Pr->LVDS1024x768Des_1 = SiS_PanelType1076_1;
++ SiS_Pr->LVDS1280x1024Des_1 = SiS_PanelType1210_1;
++ SiS_Pr->LVDS1400x1050Des_1 = SiS_PanelType1296_1;
++ SiS_Pr->LVDS1600x1200Des_1 = SiS_PanelType1600_1;
++ SiS_Pr->LVDS1024x768Des_2 = SiS_PanelType1076_2;
++ SiS_Pr->LVDS1280x1024Des_2 = SiS_PanelType1210_2;
++ SiS_Pr->LVDS1400x1050Des_2 = SiS_PanelType1296_2;
++ SiS_Pr->LVDS1600x1200Des_2 = SiS_PanelType1600_2;
++
++ SiS_Pr->SiS_PanelTypeNS_1 = SiS_PanelTypeNS_1;
++ SiS_Pr->SiS_PanelTypeNS_2 = SiS_PanelTypeNS_2;
++
++ SiS_Pr->SiS_CHTVUNTSCDesData = SiS_CHTVUNTSCDesData;
++ SiS_Pr->SiS_CHTVONTSCDesData = SiS_CHTVONTSCDesData;
++ SiS_Pr->SiS_CHTVUPALDesData = SiS_CHTVUPALDesData;
++ SiS_Pr->SiS_CHTVOPALDesData = SiS_CHTVOPALDesData;
++
++ SiS_Pr->SiS_LVDSCRT11280x768_1 = SiS_LVDSCRT11280x768_1;
++ SiS_Pr->SiS_LVDSCRT11024x600_1 = SiS_LVDSCRT11024x600_1;
++ SiS_Pr->SiS_LVDSCRT11152x768_1 = SiS_LVDSCRT11152x768_1;
++ SiS_Pr->SiS_LVDSCRT11280x768_1_H = SiS_LVDSCRT11280x768_1_H;
++ SiS_Pr->SiS_LVDSCRT11024x600_1_H = SiS_LVDSCRT11024x600_1_H;
++ SiS_Pr->SiS_LVDSCRT11152x768_1_H = SiS_LVDSCRT11152x768_1_H;
++ SiS_Pr->SiS_LVDSCRT11280x768_2 = SiS_LVDSCRT11280x768_2;
++ SiS_Pr->SiS_LVDSCRT11024x600_2 = SiS_LVDSCRT11024x600_2;
++ SiS_Pr->SiS_LVDSCRT11152x768_2 = SiS_LVDSCRT11152x768_2;
++ SiS_Pr->SiS_LVDSCRT11280x768_2_H = SiS_LVDSCRT11280x768_2_H;
++ SiS_Pr->SiS_LVDSCRT11024x600_2_H = SiS_LVDSCRT11024x600_2_H;
++ SiS_Pr->SiS_LVDSCRT11152x768_2_H = SiS_LVDSCRT11152x768_2_H;
++ SiS_Pr->SiS_LVDSCRT1320x480_1 = SiS_LVDSCRT1320x480_1;
++ SiS_Pr->SiS_LVDSCRT1XXXxXXX_1 = SiS_LVDSCRT1XXXxXXX_1;
++ SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H = SiS_LVDSCRT1XXXxXXX_1_H;
++ SiS_Pr->SiS_LVDSCRT1640x480_1 = SiS_LVDSCRT1640x480_1;
++ SiS_Pr->SiS_LVDSCRT1640x480_1_H = SiS_LVDSCRT1640x480_1_H;
++ SiS_Pr->SiS_LVDSCRT1640x480_2 = SiS_LVDSCRT1640x480_2;
++ SiS_Pr->SiS_LVDSCRT1640x480_2_H = SiS_LVDSCRT1640x480_2_H;
++ SiS_Pr->SiS_LVDSCRT1640x480_3 = SiS_LVDSCRT1640x480_3;
++ SiS_Pr->SiS_LVDSCRT1640x480_3_H = SiS_LVDSCRT1640x480_3_H;
+ }
+
+ #ifdef SIS300
+ static void
+ InitTo300Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+ {
++ InitCommonPointer(SiS_Pr, HwDeviceExtension);
++
+ SiS_Pr->SiS_SModeIDTable = (SiS_StStruct *)SiS300_SModeIDTable;
+ SiS_Pr->SiS_VBModeIDTable = (SiS_VBModeStruct *)SiS300_VBModeIDTable;
+- SiS_Pr->SiS_StandTable = (SiS_StandTableStruct *)SiS300_StandTable;
+ SiS_Pr->SiS_EModeIDTable = (SiS_ExtStruct *)SiS300_EModeIDTable;
+ SiS_Pr->SiS_RefIndex = (SiS_Ext2Struct *)SiS300_RefIndex;
+ SiS_Pr->SiS_CRT1Table = (SiS_CRT1TableStruct *)SiS300_CRT1Table;
+@@ -141,15 +286,12 @@
+ } else {
+ SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS300_MCLKData_630; /* 630, 730 */
+ }
++#ifdef LINUXBIOS
+ SiS_Pr->SiS_ECLKData = (SiS_ECLKDataStruct *)SiS300_ECLKData;
++#endif
+ SiS_Pr->SiS_VCLKData = (SiS_VCLKDataStruct *)SiS300_VCLKData;
+ SiS_Pr->SiS_VBVCLKData = (SiS_VBVCLKDataStruct *)SiS300_VCLKData;
+ SiS_Pr->SiS_ScreenOffset = SiS300_ScreenOffset;
+- SiS_Pr->SiS_StResInfo = (SiS_StResInfoStruct *)SiS300_StResInfo;
+- SiS_Pr->SiS_ModeResInfo = (SiS_ModeResInfoStruct *)SiS300_ModeResInfo;
+-
+- SiS_Pr->pSiS_OutputSelect = &SiS300_OutputSelect;
+- SiS_Pr->pSiS_SoftSetting = &SiS300_SoftSetting;
+
+ SiS_Pr->SiS_SR15 = SiS300_SR15;
+
+@@ -178,15 +320,6 @@
+ SiS_Pr->pSiS_YCSenseData2 = &SiS300_YCSenseData2;
+ #endif
+
+- SiS_Pr->SiS_NTSCPhase = SiS300_NTSCPhase;
+- SiS_Pr->SiS_PALPhase = SiS300_PALPhase;
+- SiS_Pr->SiS_NTSCPhase2 = SiS300_NTSCPhase2;
+- SiS_Pr->SiS_PALPhase2 = SiS300_PALPhase2;
+- SiS_Pr->SiS_PALMPhase = SiS300_PALMPhase;
+- SiS_Pr->SiS_PALNPhase = SiS300_PALNPhase;
+- SiS_Pr->SiS_PALMPhase2 = SiS300_PALMPhase2;
+- SiS_Pr->SiS_PALNPhase2 = SiS300_PALNPhase2;
+-
+ SiS_Pr->SiS_StLCD1024x768Data = (SiS_LCDDataStruct *)SiS300_StLCD1024x768Data;
+ SiS_Pr->SiS_ExtLCD1024x768Data = (SiS_LCDDataStruct *)SiS300_ExtLCD1024x768Data;
+ SiS_Pr->SiS_St2LCD1024x768Data = (SiS_LCDDataStruct *)SiS300_St2LCD1024x768Data;
+@@ -195,68 +328,18 @@
+ SiS_Pr->SiS_St2LCD1280x1024Data = (SiS_LCDDataStruct *)SiS300_St2LCD1280x1024Data;
+ SiS_Pr->SiS_NoScaleData1024x768 = (SiS_LCDDataStruct *)SiS300_NoScaleData1024x768;
+ SiS_Pr->SiS_NoScaleData1280x1024 = (SiS_LCDDataStruct *)SiS300_NoScaleData1280x1024;
+- SiS_Pr->SiS_LCD1280x960Data = (SiS_LCDDataStruct *)SiS300_LCD1280x960Data;
+- SiS_Pr->SiS_ExtLCD1400x1050Data = (SiS_LCDDataStruct *)SiS300_ExtLCD1400x1050Data;
+- SiS_Pr->SiS_ExtLCD1600x1200Data = (SiS_LCDDataStruct *)SiS300_ExtLCD1600x1200Data;
+- SiS_Pr->SiS_StLCD1400x1050Data = (SiS_LCDDataStruct *)SiS300_StLCD1400x1050Data;
+- SiS_Pr->SiS_StLCD1600x1200Data = (SiS_LCDDataStruct *)SiS300_StLCD1600x1200Data;
+- SiS_Pr->SiS_NoScaleData1400x1050 = (SiS_LCDDataStruct *)SiS300_NoScaleData1400x1050;
+- SiS_Pr->SiS_NoScaleData1600x1200 = (SiS_LCDDataStruct *)SiS300_NoScaleData1600x1200;
+-
+- SiS_Pr->SiS_StPALData = (SiS_TVDataStruct *)SiS300_StPALData;
+- SiS_Pr->SiS_ExtPALData = (SiS_TVDataStruct *)SiS300_ExtPALData;
+- SiS_Pr->SiS_StNTSCData = (SiS_TVDataStruct *)SiS300_StNTSCData;
+- SiS_Pr->SiS_ExtNTSCData = (SiS_TVDataStruct *)SiS300_ExtNTSCData;
+-/* SiS_Pr->SiS_St1HiTVData = (SiS_TVDataStruct *)SiS300_St1HiTVData; */
+- SiS_Pr->SiS_St2HiTVData = (SiS_TVDataStruct *)SiS300_St2HiTVData;
+- SiS_Pr->SiS_ExtHiTVData = (SiS_TVDataStruct *)SiS300_ExtHiTVData;
+-
+- SiS_Pr->SiS_NTSCTiming = SiS300_NTSCTiming;
+- SiS_Pr->SiS_PALTiming = SiS300_PALTiming;
+- SiS_Pr->SiS_HiTVSt1Timing = SiS300_HiTVSt1Timing;
+- SiS_Pr->SiS_HiTVSt2Timing = SiS300_HiTVSt2Timing;
+- SiS_Pr->SiS_HiTVTextTiming = SiS300_HiTVTextTiming;
+- SiS_Pr->SiS_HiTVGroup3Data = SiS300_HiTVGroup3Data;
+- SiS_Pr->SiS_HiTVGroup3Simu = SiS300_HiTVGroup3Simu;
+- SiS_Pr->SiS_HiTVGroup3Text = SiS300_HiTVGroup3Text;
+
+ SiS_Pr->SiS_PanelDelayTbl = (SiS_PanelDelayTblStruct *)SiS300_PanelDelayTbl;
+ SiS_Pr->SiS_PanelDelayTblLVDS = (SiS_PanelDelayTblStruct *)SiS300_PanelDelayTblLVDS;
+
+- SiS_Pr->SiS_LVDS800x600Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS800x600Data_1;
+- SiS_Pr->SiS_LVDS800x600Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS800x600Data_2;
+- SiS_Pr->SiS_LVDS1024x768Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1024x768Data_1;
+- SiS_Pr->SiS_LVDS1024x768Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1024x768Data_2;
+- SiS_Pr->SiS_LVDS1280x1024Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_1;
+- SiS_Pr->SiS_LVDS1280x1024Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_2;
+- SiS_Pr->SiS_LVDS1280x960Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_1;
+- SiS_Pr->SiS_LVDS1280x960Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_2;
+- SiS_Pr->SiS_LVDS1400x1050Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1400x1050Data_1;
+- SiS_Pr->SiS_LVDS1400x1050Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1400x1050Data_2;
+- SiS_Pr->SiS_LVDS1600x1200Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1600x1200Data_1;
+- SiS_Pr->SiS_LVDS1600x1200Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1600x1200Data_2;
+- SiS_Pr->SiS_LVDS1280x768Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x768Data_1;
+- SiS_Pr->SiS_LVDS1280x768Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x768Data_2;
+- SiS_Pr->SiS_LVDS1024x600Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1024x600Data_1;
+- SiS_Pr->SiS_LVDS1024x600Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1024x600Data_2;
+- SiS_Pr->SiS_LVDS1152x768Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1152x768Data_1;
+- SiS_Pr->SiS_LVDS1152x768Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1152x768Data_2;
+- SiS_Pr->SiS_LVDSXXXxXXXData_1 = (SiS_LVDSDataStruct *)SiS300_LVDSXXXxXXXData_1;
+- SiS_Pr->SiS_LVDS320x480Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS320x480Data_1;
+- SiS_Pr->SiS_LVDS640x480Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS640x480Data_1;
+- SiS_Pr->SiS_LCDA1400x1050Data_1 = (SiS_LVDSDataStruct *)SiS300_LCDA1400x1050Data_1;
+- SiS_Pr->SiS_LCDA1400x1050Data_2 = (SiS_LVDSDataStruct *)SiS300_LCDA1400x1050Data_2;
+- SiS_Pr->SiS_LCDA1600x1200Data_1 = (SiS_LVDSDataStruct *)SiS300_LCDA1600x1200Data_1;
+- SiS_Pr->SiS_LCDA1600x1200Data_2 = (SiS_LVDSDataStruct *)SiS300_LCDA1600x1200Data_2;
+- SiS_Pr->SiS_CHTVUNTSCData = (SiS_LVDSDataStruct *)SiS300_CHTVUNTSCData;
+- SiS_Pr->SiS_CHTVONTSCData = (SiS_LVDSDataStruct *)SiS300_CHTVONTSCData;
+ SiS_Pr->SiS_CHTVUPALData = (SiS_LVDSDataStruct *)SiS300_CHTVUPALData;
+ SiS_Pr->SiS_CHTVOPALData = (SiS_LVDSDataStruct *)SiS300_CHTVOPALData;
+- SiS_Pr->SiS_CHTVUPALMData = (SiS_LVDSDataStruct *)SiS300_CHTVUNTSCData; /* not supported on 300 series */
+- SiS_Pr->SiS_CHTVOPALMData = (SiS_LVDSDataStruct *)SiS300_CHTVONTSCData; /* not supported on 300 series */
++ SiS_Pr->SiS_CHTVUPALMData = SiS_CHTVUNTSCData; /* not supported on 300 series */
++ SiS_Pr->SiS_CHTVOPALMData = SiS_CHTVONTSCData; /* not supported on 300 series */
+ SiS_Pr->SiS_CHTVUPALNData = (SiS_LVDSDataStruct *)SiS300_CHTVUPALData; /* not supported on 300 series */
+ SiS_Pr->SiS_CHTVOPALNData = (SiS_LVDSDataStruct *)SiS300_CHTVOPALData; /* not supported on 300 series */
+ SiS_Pr->SiS_CHTVSOPALData = (SiS_LVDSDataStruct *)SiS300_CHTVSOPALData;
++
+ SiS_Pr->SiS_PanelType00_1 = (SiS_LVDSDesStruct *)SiS300_PanelType00_1;
+ SiS_Pr->SiS_PanelType01_1 = (SiS_LVDSDesStruct *)SiS300_PanelType01_1;
+ SiS_Pr->SiS_PanelType02_1 = (SiS_LVDSDesStruct *)SiS300_PanelType02_1;
+@@ -289,32 +372,28 @@
+ SiS_Pr->SiS_PanelType0d_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0d_2;
+ SiS_Pr->SiS_PanelType0e_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0e_2;
+ SiS_Pr->SiS_PanelType0f_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0f_2;
+- SiS_Pr->SiS_PanelTypeNS_1 = (SiS_LVDSDesStruct *)SiS300_PanelTypeNS_1;
+- SiS_Pr->SiS_PanelTypeNS_2 = (SiS_LVDSDesStruct *)SiS300_PanelTypeNS_2;
+- SiS_Pr->SiS_CHTVUNTSCDesData = (SiS_LVDSDesStruct *)SiS300_CHTVUNTSCDesData;
+- SiS_Pr->SiS_CHTVONTSCDesData = (SiS_LVDSDesStruct *)SiS300_CHTVONTSCDesData;
+- SiS_Pr->SiS_CHTVUPALDesData = (SiS_LVDSDesStruct *)SiS300_CHTVUPALDesData;
+- SiS_Pr->SiS_CHTVOPALDesData = (SiS_LVDSDesStruct *)SiS300_CHTVOPALDesData;
++
++ if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
++ SiS_Pr->SiS_PanelType04_1 = (SiS_LVDSDesStruct *)SiS300_PanelType04_1a;
++ SiS_Pr->SiS_PanelType04_2 = (SiS_LVDSDesStruct *)SiS300_PanelType04_2a;
++ }
++ if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
++ SiS_Pr->SiS_PanelType04_1 = (SiS_LVDSDesStruct *)SiS300_PanelType04_1b;
++ SiS_Pr->SiS_PanelType04_2 = (SiS_LVDSDesStruct *)SiS300_PanelType04_2b;
++ }
++
+ SiS_Pr->SiS_LVDSCRT1800x600_1 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_1;
+ SiS_Pr->SiS_LVDSCRT11024x768_1 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_1;
+ SiS_Pr->SiS_LVDSCRT11280x1024_1 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_1;
+- SiS_Pr->SiS_LVDSCRT11024x600_1 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_1;
+- SiS_Pr->SiS_LVDSCRT11152x768_1 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_1;
+ SiS_Pr->SiS_LVDSCRT1800x600_1_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_1_H;
+ SiS_Pr->SiS_LVDSCRT11024x768_1_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_1_H;
+ SiS_Pr->SiS_LVDSCRT11280x1024_1_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_1_H;
+- SiS_Pr->SiS_LVDSCRT11024x600_1_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_1_H;
+- SiS_Pr->SiS_LVDSCRT11152x768_1_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_1_H;
+ SiS_Pr->SiS_LVDSCRT1800x600_2 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_2;
+ SiS_Pr->SiS_LVDSCRT11024x768_2 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_2;
+ SiS_Pr->SiS_LVDSCRT11280x1024_2 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_2;
+- SiS_Pr->SiS_LVDSCRT11024x600_2 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_2;
+- SiS_Pr->SiS_LVDSCRT11152x768_2 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_2;
+ SiS_Pr->SiS_LVDSCRT1800x600_2_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_2_H;
+ SiS_Pr->SiS_LVDSCRT11024x768_2_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_2_H;
+ SiS_Pr->SiS_LVDSCRT11280x1024_2_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_2_H;
+- SiS_Pr->SiS_LVDSCRT11024x600_2_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_2_H;
+- SiS_Pr->SiS_LVDSCRT11152x768_2_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_2_H;
+ SiS_Pr->SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1UNTSC;
+ SiS_Pr->SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1ONTSC;
+ SiS_Pr->SiS_CHTVCRT1UPAL = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1UPAL;
+@@ -339,7 +418,6 @@
+ SiS_Pr->SiS_CHTVVCLKOPALN = SiS300_CHTVVCLKOPAL; /* not supported on 300 series */
+ SiS_Pr->SiS_CHTVVCLKSOPAL = SiS300_CHTVVCLKSOPAL;
+
+- /* TW: New from 300/301LV BIOS */
+ SiS_Pr->SiS_CRT2Part2_1024x768_1 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1024x768_1;
+ SiS_Pr->SiS_CRT2Part2_1280x1024_1 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1280x1024_1;
+ SiS_Pr->SiS_CRT2Part2_1400x1050_1 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1400x1050_1;
+@@ -353,7 +431,7 @@
+ SiS_Pr->SiS_CRT2Part2_1400x1050_3 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1400x1050_3;
+ SiS_Pr->SiS_CRT2Part2_1600x1200_3 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1600x1200_3;
+
+- /* TW: LCDResInfo will on 300 series be translated to 310/325 series definitions */
++ /* TW: LCDResInfo will on 300 series be translated to 315 series definitions */
+ SiS_Pr->SiS_Panel320x480 = Panel_320x480;
+ SiS_Pr->SiS_Panel640x480 = Panel_640x480;
+ SiS_Pr->SiS_Panel800x600 = Panel_800x600;
+@@ -362,13 +440,17 @@
+ SiS_Pr->SiS_Panel1280x960 = Panel_1280x960;
+ SiS_Pr->SiS_Panel1024x600 = Panel_1024x600;
+ SiS_Pr->SiS_Panel1152x768 = Panel_1152x768;
+- SiS_Pr->SiS_Panel1600x1200 = 16; /* TW: Something illegal */
+- SiS_Pr->SiS_Panel1400x1050 = 16; /* TW: Something illegal */
+- SiS_Pr->SiS_Panel1152x864 = 16; /* TW: Something illegal */
+- SiS_Pr->SiS_Panel1280x768 = 16; /* TW: Something illegal */
++ SiS_Pr->SiS_Panel1280x768 = Panel_1280x768;
++ SiS_Pr->SiS_Panel1600x1200 = 255; /* TW: Something illegal */
++ SiS_Pr->SiS_Panel1400x1050 = 255; /* TW: Something illegal */
++ SiS_Pr->SiS_Panel640x480_2 = 255; /* TW: Something illegal */
++ SiS_Pr->SiS_Panel640x480_3 = 255; /* TW: Something illegal */
++ SiS_Pr->SiS_Panel1152x864 = 255; /* TW: Something illegal */
+ SiS_Pr->SiS_PanelMax = Panel_320x480; /* TW: highest value */
+ SiS_Pr->SiS_PanelMinLVDS = Panel_800x600; /* TW: Lowest value LVDS */
+ SiS_Pr->SiS_PanelMin301 = Panel_1024x768; /* TW: lowest value 301 */
++ SiS_Pr->SiS_PanelCustom = Panel_Custom;
++ SiS_Pr->SiS_PanelBarco1366 = Panel_Barco1366;
+ }
+ #endif
+
+@@ -376,29 +458,33 @@
+ static void
+ InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+ {
++ InitCommonPointer(SiS_Pr, HwDeviceExtension);
++
+ SiS_Pr->SiS_SModeIDTable = (SiS_StStruct *)SiS310_SModeIDTable;
+- SiS_Pr->SiS_StandTable = (SiS_StandTableStruct *)SiS310_StandTable;
+ SiS_Pr->SiS_EModeIDTable = (SiS_ExtStruct *)SiS310_EModeIDTable;
+ SiS_Pr->SiS_RefIndex = (SiS_Ext2Struct *)SiS310_RefIndex;
+ SiS_Pr->SiS_CRT1Table = (SiS_CRT1TableStruct *)SiS310_CRT1Table;
+ /* TW: MCLK is different */
+- if(HwDeviceExtension->jChipType == SIS_330) {
++#ifdef LINUXBIOS
++ if(HwDeviceExtension->jChipType >= SIS_660) {
++ SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_660; /* 660/760 */
++ } else if(HwDeviceExtension->jChipType == SIS_330) {
++#endif
+ SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_330; /* 330 */
++#ifdef LINUXBIOS
+ } else if(HwDeviceExtension->jChipType > SIS_315PRO) {
+ SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_650; /* 550, 650, 740 */
+ } else {
+ SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_315; /* 315 */
+ }
++#endif
+ SiS_Pr->SiS_MCLKData_1 = (SiS_MCLKDataStruct *)SiS310_MCLKData_1;
++#ifdef LINUXBIOS
+ SiS_Pr->SiS_ECLKData = (SiS_ECLKDataStruct *)SiS310_ECLKData;
++#endif
+ SiS_Pr->SiS_VCLKData = (SiS_VCLKDataStruct *)SiS310_VCLKData;
+ SiS_Pr->SiS_VBVCLKData = (SiS_VBVCLKDataStruct *)SiS310_VBVCLKData;
+ SiS_Pr->SiS_ScreenOffset = SiS310_ScreenOffset;
+- SiS_Pr->SiS_StResInfo = (SiS_StResInfoStruct *)SiS310_StResInfo;
+- SiS_Pr->SiS_ModeResInfo = (SiS_ModeResInfoStruct *)SiS310_ModeResInfo;
+-
+- SiS_Pr->pSiS_OutputSelect = &SiS310_OutputSelect;
+- SiS_Pr->pSiS_SoftSetting = &SiS310_SoftSetting;
+
+ SiS_Pr->SiS_SR15 = SiS310_SR15;
+
+@@ -427,16 +513,6 @@
+ SiS_Pr->pSiS_YCSenseData2 = &SiS310_YCSenseData2;
+ #endif
+
+- SiS_Pr->SiS_NTSCPhase = SiS310_NTSCPhase;
+- SiS_Pr->SiS_PALPhase = SiS310_PALPhase;
+- SiS_Pr->SiS_NTSCPhase2 = SiS310_NTSCPhase2;
+- SiS_Pr->SiS_PALPhase2 = SiS310_PALPhase2;
+- SiS_Pr->SiS_PALMPhase = SiS310_PALMPhase;
+- SiS_Pr->SiS_PALNPhase = SiS310_PALNPhase;
+- SiS_Pr->SiS_PALMPhase2 = SiS310_PALMPhase2;
+- SiS_Pr->SiS_PALNPhase2 = SiS310_PALNPhase2;
+- SiS_Pr->SiS_SpecialPhase = SiS310_SpecialPhase;
+-
+ SiS_Pr->SiS_StLCD1024x768Data = (SiS_LCDDataStruct *)SiS310_StLCD1024x768Data;
+ SiS_Pr->SiS_ExtLCD1024x768Data = (SiS_LCDDataStruct *)SiS310_ExtLCD1024x768Data;
+ SiS_Pr->SiS_St2LCD1024x768Data = (SiS_LCDDataStruct *)SiS310_St2LCD1024x768Data;
+@@ -445,62 +521,10 @@
+ SiS_Pr->SiS_St2LCD1280x1024Data = (SiS_LCDDataStruct *)SiS310_St2LCD1280x1024Data;
+ SiS_Pr->SiS_NoScaleData1024x768 = (SiS_LCDDataStruct *)SiS310_NoScaleData1024x768;
+ SiS_Pr->SiS_NoScaleData1280x1024 = (SiS_LCDDataStruct *)SiS310_NoScaleData1280x1024;
+- SiS_Pr->SiS_LCD1280x960Data = (SiS_LCDDataStruct *)SiS310_LCD1280x960Data;
+- SiS_Pr->SiS_ExtLCD1400x1050Data = (SiS_LCDDataStruct *)SiS310_ExtLCD1400x1050Data;
+- SiS_Pr->SiS_ExtLCD1600x1200Data = (SiS_LCDDataStruct *)SiS310_ExtLCD1600x1200Data;
+- SiS_Pr->SiS_StLCD1400x1050Data = (SiS_LCDDataStruct *)SiS310_StLCD1400x1050Data;
+- SiS_Pr->SiS_StLCD1600x1200Data = (SiS_LCDDataStruct *)SiS310_StLCD1600x1200Data;
+- SiS_Pr->SiS_NoScaleData1400x1050 = (SiS_LCDDataStruct *)SiS310_NoScaleData1400x1050;
+- SiS_Pr->SiS_NoScaleData1600x1200 = (SiS_LCDDataStruct *)SiS310_NoScaleData1600x1200;
+-
+- SiS_Pr->SiS_StPALData = (SiS_TVDataStruct *)SiS310_StPALData;
+- SiS_Pr->SiS_ExtPALData = (SiS_TVDataStruct *)SiS310_ExtPALData;
+- SiS_Pr->SiS_StNTSCData = (SiS_TVDataStruct *)SiS310_StNTSCData;
+- SiS_Pr->SiS_ExtNTSCData = (SiS_TVDataStruct *)SiS310_ExtNTSCData;
+-/* SiS_Pr->SiS_St1HiTVData = (SiS_TVDataStruct *)SiS310_St1HiTVData; */
+- SiS_Pr->SiS_St2HiTVData = (SiS_TVDataStruct *)SiS310_St2HiTVData;
+- SiS_Pr->SiS_ExtHiTVData = (SiS_TVDataStruct *)SiS310_ExtHiTVData;
+-
+- SiS_Pr->SiS_NTSCTiming = SiS310_NTSCTiming;
+- SiS_Pr->SiS_PALTiming = SiS310_PALTiming;
+- SiS_Pr->SiS_HiTVSt1Timing = SiS310_HiTVSt1Timing;
+- SiS_Pr->SiS_HiTVSt2Timing = SiS310_HiTVSt2Timing;
+- SiS_Pr->SiS_HiTVTextTiming = SiS310_HiTVTextTiming;
+- SiS_Pr->SiS_HiTVExtTiming = SiS310_HiTVExtTiming;
+- SiS_Pr->SiS_HiTVGroup3Data = SiS310_HiTVGroup3Data;
+- SiS_Pr->SiS_HiTVGroup3Simu = SiS310_HiTVGroup3Simu;
+- SiS_Pr->SiS_HiTVGroup3Text = SiS310_HiTVGroup3Text;
+
+- SiS_Pr->SiS_PanelDelayTbl = (SiS_PanelDelayTblStruct *)SiS310_PanelDelayTbl;
++ SiS_Pr->SiS_PanelDelayTbl = (SiS_PanelDelayTblStruct *)SiS310_PanelDelayTbl;
+ SiS_Pr->SiS_PanelDelayTblLVDS = (SiS_PanelDelayTblStruct *)SiS310_PanelDelayTblLVDS;
+
+- SiS_Pr->SiS_LVDS800x600Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS800x600Data_1;
+- SiS_Pr->SiS_LVDS800x600Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS800x600Data_2;
+- SiS_Pr->SiS_LVDS1024x768Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1024x768Data_1;
+- SiS_Pr->SiS_LVDS1024x768Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1024x768Data_2;
+- SiS_Pr->SiS_LVDS1280x1024Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x1024Data_1;
+- SiS_Pr->SiS_LVDS1280x1024Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x1024Data_2;
+- SiS_Pr->SiS_LVDS1280x960Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x960Data_1;
+- SiS_Pr->SiS_LVDS1280x960Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x960Data_2;
+- SiS_Pr->SiS_LVDS1400x1050Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1400x1050Data_1;
+- SiS_Pr->SiS_LVDS1400x1050Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1400x1050Data_2;
+- SiS_Pr->SiS_LVDS1600x1200Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1600x1200Data_1;
+- SiS_Pr->SiS_LVDS1600x1200Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1600x1200Data_2;
+- SiS_Pr->SiS_LVDS1280x768Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x768Data_1;
+- SiS_Pr->SiS_LVDS1280x768Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x768Data_2;
+- SiS_Pr->SiS_LVDS1024x600Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1024x600Data_1;
+- SiS_Pr->SiS_LVDS1024x600Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1024x600Data_2;
+- SiS_Pr->SiS_LVDS1152x768Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1152x768Data_1;
+- SiS_Pr->SiS_LVDS1152x768Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1152x768Data_2;
+- SiS_Pr->SiS_LVDSXXXxXXXData_1 = (SiS_LVDSDataStruct *)SiS310_LVDSXXXxXXXData_1;
+- SiS_Pr->SiS_LVDS320x480Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS320x480Data_1;
+- SiS_Pr->SiS_LVDS640x480Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS640x480Data_1;
+- SiS_Pr->SiS_LCDA1400x1050Data_1 = (SiS_LVDSDataStruct *)SiS310_LCDA1400x1050Data_1;
+- SiS_Pr->SiS_LCDA1400x1050Data_2 = (SiS_LVDSDataStruct *)SiS310_LCDA1400x1050Data_2;
+- SiS_Pr->SiS_LCDA1600x1200Data_1 = (SiS_LVDSDataStruct *)SiS310_LCDA1600x1200Data_1;
+- SiS_Pr->SiS_LCDA1600x1200Data_2 = (SiS_LVDSDataStruct *)SiS310_LCDA1600x1200Data_2;
+- SiS_Pr->SiS_CHTVUNTSCData = (SiS_LVDSDataStruct *)SiS310_CHTVUNTSCData;
+- SiS_Pr->SiS_CHTVONTSCData = (SiS_LVDSDataStruct *)SiS310_CHTVONTSCData;
+ SiS_Pr->SiS_CHTVUPALData = (SiS_LVDSDataStruct *)SiS310_CHTVUPALData;
+ SiS_Pr->SiS_CHTVOPALData = (SiS_LVDSDataStruct *)SiS310_CHTVOPALData;
+ SiS_Pr->SiS_CHTVUPALMData = (SiS_LVDSDataStruct *)SiS310_CHTVUPALMData;
+@@ -508,6 +532,7 @@
+ SiS_Pr->SiS_CHTVUPALNData = (SiS_LVDSDataStruct *)SiS310_CHTVUPALNData;
+ SiS_Pr->SiS_CHTVOPALNData = (SiS_LVDSDataStruct *)SiS310_CHTVOPALNData;
+ SiS_Pr->SiS_CHTVSOPALData = (SiS_LVDSDataStruct *)SiS310_CHTVSOPALData;
++
+ SiS_Pr->SiS_PanelType00_1 = (SiS_LVDSDesStruct *)SiS310_PanelType00_1;
+ SiS_Pr->SiS_PanelType01_1 = (SiS_LVDSDesStruct *)SiS310_PanelType01_1;
+ SiS_Pr->SiS_PanelType02_1 = (SiS_LVDSDesStruct *)SiS310_PanelType02_1;
+@@ -540,19 +565,7 @@
+ SiS_Pr->SiS_PanelType0d_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0d_2;
+ SiS_Pr->SiS_PanelType0e_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0e_2;
+ SiS_Pr->SiS_PanelType0f_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0f_2;
+- SiS_Pr->SiS_PanelTypeNS_1 = (SiS_LVDSDesStruct *)SiS310_PanelTypeNS_1;
+- SiS_Pr->SiS_PanelTypeNS_2 = (SiS_LVDSDesStruct *)SiS310_PanelTypeNS_2;
+
+- SiS_Pr->LVDS1024x768Des_1 = (SiS_LVDSDesStruct *)SiS310_PanelType1076_1;
+- SiS_Pr->LVDS1280x1024Des_1 = (SiS_LVDSDesStruct *)SiS310_PanelType1210_1;
+- SiS_Pr->LVDS1400x1050Des_1 = (SiS_LVDSDesStruct *)SiS310_PanelType1296_1 ;
+- SiS_Pr->LVDS1600x1200Des_1 = (SiS_LVDSDesStruct *)SiS310_PanelType1600_1 ;
+- SiS_Pr->LVDS1024x768Des_2 = (SiS_LVDSDesStruct *)SiS310_PanelType1076_2;
+- SiS_Pr->LVDS1280x1024Des_2 = (SiS_LVDSDesStruct *)SiS310_PanelType1210_2;
+- SiS_Pr->LVDS1400x1050Des_2 = (SiS_LVDSDesStruct *)SiS310_PanelType1296_2;
+- SiS_Pr->LVDS1600x1200Des_2 = (SiS_LVDSDesStruct *)SiS310_PanelType1600_2 ;
+-
+- /* TW: New from 650/301LV BIOS */
+ SiS_Pr->SiS_CRT2Part2_1024x768_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1024x768_1;
+ SiS_Pr->SiS_CRT2Part2_1280x1024_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1280x1024_1;
+ SiS_Pr->SiS_CRT2Part2_1400x1050_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1400x1050_1;
+@@ -566,51 +579,32 @@
+ SiS_Pr->SiS_CRT2Part2_1400x1050_3 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1400x1050_3;
+ SiS_Pr->SiS_CRT2Part2_1600x1200_3 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1600x1200_3;
+
+- SiS_Pr->SiS_CHTVUNTSCDesData = (SiS_LVDSDesStruct *)SiS310_CHTVUNTSCDesData;
+- SiS_Pr->SiS_CHTVONTSCDesData = (SiS_LVDSDesStruct *)SiS310_CHTVONTSCDesData;
+- SiS_Pr->SiS_CHTVUPALDesData = (SiS_LVDSDesStruct *)SiS310_CHTVUPALDesData;
+- SiS_Pr->SiS_CHTVOPALDesData = (SiS_LVDSDesStruct *)SiS310_CHTVOPALDesData;
+-
+ SiS_Pr->SiS_LVDSCRT1800x600_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_1;
+ SiS_Pr->SiS_LVDSCRT11024x768_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_1;
+ SiS_Pr->SiS_LVDSCRT11280x1024_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_1;
+ SiS_Pr->SiS_LVDSCRT11400x1050_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_1;
+- SiS_Pr->SiS_LVDSCRT11280x768_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_1;
+- SiS_Pr->SiS_LVDSCRT11024x600_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_1;
+- SiS_Pr->SiS_LVDSCRT11152x768_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_1;
+ SiS_Pr->SiS_LVDSCRT11600x1200_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_1;
+ SiS_Pr->SiS_LVDSCRT1800x600_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_1_H;
+ SiS_Pr->SiS_LVDSCRT11024x768_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_1_H;
+ SiS_Pr->SiS_LVDSCRT11280x1024_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_1_H;
+ SiS_Pr->SiS_LVDSCRT11400x1050_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_1_H;
+- SiS_Pr->SiS_LVDSCRT11280x768_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_1_H;
+- SiS_Pr->SiS_LVDSCRT11024x600_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_1_H;
+- SiS_Pr->SiS_LVDSCRT11152x768_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_1_H;
+ SiS_Pr->SiS_LVDSCRT11600x1200_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_1_H;
+ SiS_Pr->SiS_LVDSCRT1800x600_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_2;
+ SiS_Pr->SiS_LVDSCRT11024x768_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_2;
+ SiS_Pr->SiS_LVDSCRT11280x1024_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_2;
+ SiS_Pr->SiS_LVDSCRT11400x1050_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_2;
+- SiS_Pr->SiS_LVDSCRT11280x768_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_2;
+- SiS_Pr->SiS_LVDSCRT11024x600_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_2;
+- SiS_Pr->SiS_LVDSCRT11152x768_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_2;
+ SiS_Pr->SiS_LVDSCRT11600x1200_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_2;
+ SiS_Pr->SiS_LVDSCRT1800x600_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_2_H;
+ SiS_Pr->SiS_LVDSCRT11024x768_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_2_H;
+ SiS_Pr->SiS_LVDSCRT11280x1024_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_2_H;
+ SiS_Pr->SiS_LVDSCRT11400x1050_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_2_H;
+- SiS_Pr->SiS_LVDSCRT11280x768_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_2_H;
+- SiS_Pr->SiS_LVDSCRT11024x600_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_2_H;
+- SiS_Pr->SiS_LVDSCRT11152x768_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_2_H;
+ SiS_Pr->SiS_LVDSCRT11600x1200_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_2_H;
+- SiS_Pr->SiS_LVDSCRT1XXXxXXX_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1XXXxXXX_1;
+- SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1XXXxXXX_1_H;
+- SiS_Pr->SiS_LVDSCRT1320x480_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1320x480_1;
+- SiS_Pr->SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UNTSC;
+- SiS_Pr->SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1ONTSC;
+- SiS_Pr->SiS_CHTVCRT1UPAL = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UPAL;
+- SiS_Pr->SiS_CHTVCRT1OPAL = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1OPAL;
+- SiS_Pr->SiS_CHTVCRT1SOPAL = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1SOPAL;
++ SiS_Pr->SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UNTSC;
++ SiS_Pr->SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1ONTSC;
++ SiS_Pr->SiS_CHTVCRT1UPAL = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UPAL;
++ SiS_Pr->SiS_CHTVCRT1OPAL = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1OPAL;
++ SiS_Pr->SiS_CHTVCRT1SOPAL = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1SOPAL;
++
+ SiS_Pr->SiS_CHTVReg_UNTSC = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UNTSC;
+ SiS_Pr->SiS_CHTVReg_ONTSC = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_ONTSC;
+ SiS_Pr->SiS_CHTVReg_UPAL = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UPAL;
+@@ -620,6 +614,7 @@
+ SiS_Pr->SiS_CHTVReg_UPALN = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UPALN;
+ SiS_Pr->SiS_CHTVReg_OPALN = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_OPALN;
+ SiS_Pr->SiS_CHTVReg_SOPAL = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_SOPAL;
++
+ SiS_Pr->SiS_LCDACRT1800x600_1 = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT1800x600_1;
+ SiS_Pr->SiS_LCDACRT11024x768_1 = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11024x768_1;
+ SiS_Pr->SiS_LCDACRT11280x1024_1 = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_1;
+@@ -640,6 +635,7 @@
+ SiS_Pr->SiS_LCDACRT11280x1024_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_2_H;
+ SiS_Pr->SiS_LCDACRT11400x1050_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11400x1050_2_H;
+ SiS_Pr->SiS_LCDACRT11600x1200_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11600x1200_2_H;
++
+ SiS_Pr->SiS_CHTVVCLKUNTSC = SiS310_CHTVVCLKUNTSC;
+ SiS_Pr->SiS_CHTVVCLKONTSC = SiS310_CHTVVCLKONTSC;
+ SiS_Pr->SiS_CHTVVCLKUPAL = SiS310_CHTVVCLKUPAL;
+@@ -662,9 +658,13 @@
+ SiS_Pr->SiS_Panel1152x864 = Panel_1152x864;
+ SiS_Pr->SiS_Panel1280x768 = Panel_1280x768;
+ SiS_Pr->SiS_Panel1024x600 = Panel_1024x600;
++ SiS_Pr->SiS_Panel640x480_2 = Panel_640x480_2;
++ SiS_Pr->SiS_Panel640x480_3 = Panel_640x480_3;
+ SiS_Pr->SiS_PanelMax = Panel_320x480; /* TW: highest value */
+ SiS_Pr->SiS_PanelMinLVDS = Panel_800x600; /* TW: lowest value LVDS/LCDA */
+ SiS_Pr->SiS_PanelMin301 = Panel_1024x768; /* TW: lowest value 301 */
++ SiS_Pr->SiS_PanelCustom = Panel_Custom;
++ SiS_Pr->SiS_PanelBarco1366 = 255;
+ }
+ #endif
+
+@@ -727,7 +727,9 @@
+ (HwDeviceExtension->jChipType == SIS_550) ||
+ (HwDeviceExtension->jChipType == SIS_650) ||
+ (HwDeviceExtension->jChipType == SIS_740) ||
+- (HwDeviceExtension->jChipType == SIS_330))
++ (HwDeviceExtension->jChipType == SIS_330) ||
++ (HwDeviceExtension->jChipType == SIS_660) ||
++ (HwDeviceExtension->jChipType == SIS_760))
+ InitTo310Pointer(SiS_Pr, HwDeviceExtension);
+ #endif
+
+@@ -896,7 +898,9 @@
+ (HwDeviceExtension->jChipType == SIS_550) ||
+ (HwDeviceExtension->jChipType == SIS_650) ||
+ (HwDeviceExtension->jChipType == SIS_740) ||
+- (HwDeviceExtension->jChipType == SIS_330)) {
++ (HwDeviceExtension->jChipType == SIS_330) ||
++ (HwDeviceExtension->jChipType == SIS_660) ||
++ (HwDeviceExtension->jChipType == SIS_760)) {
+ for(i=0x12; i<=0x1B; i++) SiS_SetReg1(SiS_Pr->SiS_P3c4,i,0);
+ for(i=0x79; i<=0x7C; i++) SiS_SetReg1(SiS_Pr->SiS_P3d4,i,0);
+ }
+@@ -953,14 +957,16 @@
+ if((HwDeviceExtension->jChipType == SIS_315H) ||
+ (HwDeviceExtension->jChipType == SIS_315) ||
+ (HwDeviceExtension->jChipType == SIS_315PRO) ||
+- (HwDeviceExtension->jChipType == SIS_330) ) {
++ (HwDeviceExtension->jChipType == SIS_330)) {
+ if((*SiS_Pr->pSiS_SoftSetting & SoftDRAMType) == 0) {
+ temp = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3A) & 0x03;
+ }
+ }
+ if((HwDeviceExtension->jChipType == SIS_550) ||
+ (HwDeviceExtension->jChipType == SIS_740) ||
+- (HwDeviceExtension->jChipType == SIS_650)) {
++ (HwDeviceExtension->jChipType == SIS_650) ||
++ (HwDeviceExtension->jChipType == SIS_660) ||
++ (HwDeviceExtension->jChipType == SIS_760)) {
+ if((*SiS_Pr->pSiS_SoftSetting & SoftDRAMType) == 0) {
+ temp = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x07;
+ }
+@@ -977,7 +983,7 @@
+ if((HwDeviceExtension->jChipType != SIS_540) &&
+ (HwDeviceExtension->jChipType != SIS_630) &&
+ (HwDeviceExtension->jChipType != SIS_730)){
+- for(i=0x15;i<0x1C;i++) {
++ for(i=0x15; i<0x1C; i++) {
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,i,SiS_Pr->SiS_SR15[i-0x15][SiS_Pr->SiS_RAMType]);
+ }
+ }
+@@ -1023,7 +1029,9 @@
+ (HwDeviceExtension->jChipType == SIS_550) ||
+ (HwDeviceExtension->jChipType == SIS_650) ||
+ (HwDeviceExtension->jChipType == SIS_740) ||
+- (HwDeviceExtension->jChipType == SIS_330))
++ (HwDeviceExtension->jChipType == SIS_330) ||
++ (HwDeviceExtension->jChipType == SIS_660) ||
++ (HwDeviceExtension->jChipType == SIS_760))
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2E,0x08); /* use VB */
+ #endif
+
+@@ -1180,7 +1188,9 @@
+ #ifdef SIS315H
+ if((HwDeviceExtension->jChipType == SIS_650) ||
+ (HwDeviceExtension->jChipType == SIS_740) ||
+- (HwDeviceExtension->jChipType == SIS_330)) {
++ (HwDeviceExtension->jChipType == SIS_330) ||
++ (HwDeviceExtension->jChipType == SIS_660) ||
++ (HwDeviceExtension->jChipType == SIS_760)) {
+ #if 0 /* TW: This is not required */
+ /* TW: Read POWER_ON_TRAP and copy to CR37 */
+ temp = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A);
+@@ -1299,7 +1309,7 @@
+ #endif
+ /* =============== SiS 300 dram sizing end =============== */
+
+-/* ============ SiS 310/325 dram sizing begin ============== */
++/* ============ SiS 315 dram sizing begin ============== */
+ #ifdef SIS315H
+
+ /* TW: Moved Get310DRAMType further down */
+@@ -1893,8 +1903,7 @@
+ if(*SiS_Pr->pSiS_SoftSetting & SoftDRAMType) {
+ data = *SiS_Pr->pSiS_SoftSetting & 0x03;
+ } else {
+- if((HwDeviceExtension->jChipType > SIS_315PRO) &&
+- (HwDeviceExtension->jChipType < SIS_330)) {
++ if(IS_SIS550650740660) {
+ data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x07;
+ } else { /* TW: 315, 330 */
+ data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3a) & 0x03;
+@@ -1934,13 +1943,17 @@
+ SiS_Pr->SiS_P3c7 = BaseAddr + 0x17;
+ SiS_Pr->SiS_P3c8 = BaseAddr + 0x18;
+ SiS_Pr->SiS_P3c9 = BaseAddr + 0x19;
+- SiS_Pr->SiS_P3da = BaseAddr + 0x2A;
+- SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04; /* Digital video interface registers (LCD) */
+- SiS_Pr->SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10; /* 301 TV Encoder registers */
+- SiS_Pr->SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12; /* 301 Macrovision registers */
+- SiS_Pr->SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14; /* 301 VGA2 (and LCD) registers */
+- SiS_Pr->SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14+2; /* 301 palette address port registers */
+- SiS_Pr->SiS_DDC_Port = BaseAddr + 0x14; /* DDC Port ( = P3C4, SR11/0A) */
++ SiS_Pr->SiS_P3cb = BaseAddr + 0x1b;
++ SiS_Pr->SiS_P3cd = BaseAddr + 0x1d;
++ SiS_Pr->SiS_P3da = BaseAddr + 0x2a;
++ SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04; /* Digital video interface registers (LCD) */
++ SiS_Pr->SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10; /* 301 TV Encoder registers */
++ SiS_Pr->SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12; /* 301 Macrovision registers */
++ SiS_Pr->SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14; /* 301 VGA2 (and LCD) registers */
++ SiS_Pr->SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2; /* 301 palette address port registers */
++ SiS_Pr->SiS_DDC_Port = BaseAddr + 0x14; /* DDC Port ( = P3C4, SR11/0A) */
++ SiS_Pr->SiS_VidCapt = BaseAddr + SIS_VIDEO_CAPTURE;
++ SiS_Pr->SiS_VidPlay = BaseAddr + SIS_VIDEO_PLAYBACK;
+ }
+
+ void
+@@ -1965,7 +1978,9 @@
+ (HwDeviceExtension->jChipType == SIS_550) ||
+ (HwDeviceExtension->jChipType == SIS_650) ||
+ (HwDeviceExtension->jChipType == SIS_740) ||
+- (HwDeviceExtension->jChipType == SIS_330)) {
++ (HwDeviceExtension->jChipType == SIS_330) ||
++ (HwDeviceExtension->jChipType == SIS_660) ||
++ (HwDeviceExtension->jChipType == SIS_760)) {
+ /* TW: This seems to be done the same way on these chipsets */
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x20,0xa1);
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1E,0xFF,0x5A);
+@@ -1987,10 +2002,14 @@
+
+ SiS_Pr->SiS_ChrontelInit = 0;
+
+- if((ModeNo == 0x5a) || (ModeNo == 0x5b)) {
+- SiS_Pr->SiS_IF_DEF_DSTN = 1; /* for 550 dstn */
+- SiS_Pr->SiS_IF_DEF_FSTN = 1; /* for fstn */
++#if 0
++ if(HwDeviceExtension->jChipType >= SIS_315H) {
++ if((ModeNo == 0x5a) || (ModeNo == 0x5b)) {
++ SiS_Pr->SiS_IF_DEF_DSTN = 1; /* for 550 dstn */
++ SiS_Pr->SiS_IF_DEF_FSTN = 1; /* for fstn */
++ }
+ }
++#endif
+
+ #ifdef SIS300
+ if((HwDeviceExtension->jChipType == SIS_540) ||
+@@ -2015,11 +2034,15 @@
+ if((HwDeviceExtension->jChipType == SIS_550) ||
+ (HwDeviceExtension->jChipType == SIS_650) ||
+ (HwDeviceExtension->jChipType == SIS_740) ||
+- (HwDeviceExtension->jChipType == SIS_330))
++ (HwDeviceExtension->jChipType == SIS_330) ||
++ (HwDeviceExtension->jChipType == SIS_660) ||
++ (HwDeviceExtension->jChipType == SIS_760))
+ {
+- /* TW: CR37 is different on 310/325 series */
++ /* TW: CR37 is different on 315 series */
++#if 0
+ if(SiS_Pr->SiS_IF_DEF_FSTN) /* fstn: set CR37=0x04 */
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,0x04); /* (fake LVDS bridge) */
++#endif
+
+ temp=SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);
+ temp = (temp & 0x0E) >> 1;
+@@ -2044,7 +2067,9 @@
+ (HwDeviceExtension->jChipType == SIS_550) ||
+ (HwDeviceExtension->jChipType == SIS_650) ||
+ (HwDeviceExtension->jChipType == SIS_740) ||
+- (HwDeviceExtension->jChipType == SIS_330))
++ (HwDeviceExtension->jChipType == SIS_330) ||
++ (HwDeviceExtension->jChipType == SIS_660) ||
++ (HwDeviceExtension->jChipType == SIS_760))
+ InitTo310Pointer(SiS_Pr, HwDeviceExtension);
+ #endif
+
+@@ -2073,14 +2098,21 @@
+ SiS_Pr->SiS_UseROM = TRUE;
+ else SiS_Pr->SiS_UseROM = FALSE;
+ } else if(HwDeviceExtension->jChipType < SIS_315H) {
++#if 0
+ /* TW: Rest of 300 series: We don't use the ROM image if
+ * the BIOS version < 2.0.0 as such old BIOSes don't
+ * have the needed data at the expected locations.
+ */
+ if(ROMAddr[0x06] < '2') SiS_Pr->SiS_UseROM = FALSE;
+ else SiS_Pr->SiS_UseROM = TRUE;
++#else
++ /* Sony's VAIO BIOS 1.09 follows the standard, so perhaps
++ * the others do as well
++ */
++ SiS_Pr->SiS_UseROM = TRUE;
++#endif
+ } else {
+- /* TW: 310/325/330 series stick to the standard */
++ /* TW: 315/330 series stick to the standard */
+ SiS_Pr->SiS_UseROM = TRUE;
+ }
+ } else SiS_Pr->SiS_UseROM = FALSE;
+@@ -2104,24 +2136,27 @@
+ SiS_Pr->UseCustomMode = FALSE;
+
+ if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
+-
+- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting custom mode %dx%d\n",
+- SiS_Pr->CHDisplay, SiS_Pr->CVDisplay);
+-
++
++ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting custom mode %dx%d\n",
++ SiS_Pr->CHDisplay,
++ (mode->Flags & V_INTERLACE ? SiS_Pr->CVDisplay * 2 :
++ (mode->Flags & V_DBLSCAN ? SiS_Pr->CVDisplay / 2 :
++ SiS_Pr->CVDisplay)));
++
+ return(SiSSetMode(SiS_Pr, HwDeviceExtension, pScrn, ModeNo, TRUE));
+-
++
+ }
+-
+- ModeNo = SiS_CalcModeIndex(pScrn, mode);
++
++ ModeNo = SiS_CalcModeIndex(pScrn, mode, pSiS->HaveCustomModes);
+ if(!ModeNo) return FALSE;
+
+- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting mode 0x%x\n", ModeNo);
++ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting standard mode 0x%x\n", ModeNo);
+
+- return(SiSSetMode(SiS_Pr, HwDeviceExtension, pScrn, ModeNo, TRUE));
++ return(SiSSetMode(SiS_Pr, HwDeviceExtension, pScrn, ModeNo, TRUE));
+ }
+
+ #ifdef SISDUALHEAD
+-/* TW: Set CRT1 mode (used for dual head) */
++/* TW: Set CRT1 mode (used for dual head and MergedFB) */
+ BOOLEAN
+ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn,
+ DisplayModePtr mode, BOOLEAN IsCustom)
+@@ -2134,31 +2169,37 @@
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+ unsigned char backupreg=0;
+ BOOLEAN backupcustom;
+-
+ UShort ModeNo=0;
+
+ SiS_Pr->UseCustomMode = FALSE;
+-
++
+ if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
+-
++
++ USHORT temptemp = SiS_Pr->CVDisplay;
++
++ if(SiS_Pr->CModeFlag & DoubleScanMode) temptemp >>= 1;
++ else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1;
++
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+- "Setting custom mode %dx%d in CRT1\n",
+- SiS_Pr->CHDisplay, SiS_Pr->CVDisplay);
++ "Setting custom mode %dx%d on CRT1\n",
++ SiS_Pr->CHDisplay, temptemp);
+ ModeNo = 0xfe;
+-
++
+ } else {
+
+- ModeNo = SiS_CalcModeIndex(pScrn, mode);
++ ModeNo = SiS_CalcModeIndex(pScrn, mode, pSiS->HaveCustomModes);
+ if(!ModeNo) return FALSE;
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+- "Setting mode 0x%x on CRT1\n", ModeNo);
++ "Setting standard mode 0x%x on CRT1\n", ModeNo);
+ }
+
+ SiSInitPtr(SiS_Pr, HwDeviceExtension);
+
+ SiSRegInit(SiS_Pr, BaseAddr);
+
++ SiS_GetSysFlags(SiS_Pr, HwDeviceExtension);
++
+ SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
+
+ SiSInitPCIetc(SiS_Pr, HwDeviceExtension);
+@@ -2167,7 +2208,7 @@
+
+ SiSDetermineROMUsage(SiS_Pr, HwDeviceExtension, ROMAddr);
+
+- /* TW: We don't clear the buffer under X */
++ /* We don't clear the buffer under X */
+ SiS_Pr->SiS_flag_clearbuffer = 0;
+
+ /* 1.Openkey */
+@@ -2175,8 +2216,8 @@
+
+ SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
+
++ /* 2.Get ModeID Table */
+ if(!SiS_Pr->UseCustomMode) {
+- /* 2.Get ModeID Table */
+ temp = SiS_SearchModeID(SiS_Pr, ROMAddr,&ModeNo,&ModeIdIndex);
+ if(temp == 0) return(0);
+ } else {
+@@ -2201,53 +2242,65 @@
+ SiS_GetLCDResInfo(SiS_Pr, ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+- if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+- if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08) {
++ if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08) {
++ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ if(ModeNo != 0x10) SiS_Pr->SiS_SetFlag |= SetDOSMode;
++ } else if((IS_SIS651) && (SiS_Pr->SiS_VBType & VB_NoLCD)) {
++ SiS_Pr->SiS_SetFlag |= SetDOSMode;
+ }
+ }
+
+- /* TW: New from 650/LV 1.10.6x */
+ if(IS_SIS650) {
+- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+- SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
+- SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
+- }
++ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
++ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
++ if(IS_SIS651) SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x20);
++ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
++ }
+ }
+ }
+
+- /* TW: Set mode on CRT1 */
++ /* Set mode on CRT1 */
+ SiS_SetCRT1Group(SiS_Pr, ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,BaseAddr);
+
+- pSiSEnt->CRT1ModeNo = ModeNo;
+- pSiSEnt->CRT1DMode = mode;
+-
+- /* TW: SetPitch: Adapt to virtual size & position */
++ /* SetPitch: Adapt to virtual size & position */
+ SiS_SetPitchCRT1(SiS_Pr, pScrn, BaseAddr);
+
++ if(pSiS->DualHeadMode) {
++ pSiSEnt->CRT1ModeNo = ModeNo;
++ pSiSEnt->CRT1DMode = mode;
++ }
++
++ if(SiS_Pr->UseCustomMode) {
++ SiS_Pr->CRT1UsesCustomMode = TRUE;
++ SiS_Pr->CSRClock_CRT1 = SiS_Pr->CSRClock;
++ SiS_Pr->CModeFlag_CRT1 = SiS_Pr->CModeFlag;
++ } else {
++ SiS_Pr->CRT1UsesCustomMode = FALSE;
++ }
++
+ /* We have to reset CRT2 if changing mode on CRT1 */
+- if(pSiSEnt->CRT2ModeNo != -1) {
+- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+- "(Re-)Setting mode 0x%x on CRT2\n",
+- pSiSEnt->CRT2ModeNo);
+- backupcustom = SiS_Pr->UseCustomMode;
+- if(SiS_Pr->UseCustomMode) {
+- SiS_Pr->CRT1UsesCustomMode = TRUE;
+- } else {
+- SiS_Pr->CRT1UsesCustomMode = FALSE;
+- }
+- SiSBIOSSetModeCRT2(SiS_Pr, HwDeviceExtension, pSiSEnt->pScrn_1,
+- pSiSEnt->CRT2DMode);
+- SiS_Pr->UseCustomMode = backupcustom;
+- SiS_Pr->CRT1UsesCustomMode = FALSE;
++ if(pSiS->DualHeadMode) {
++ if(pSiSEnt->CRT2ModeNo != -1) {
++ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
++ "(Re-)Setting mode for CRT2\n");
++ backupcustom = SiS_Pr->UseCustomMode;
++ SiSBIOSSetModeCRT2(SiS_Pr, HwDeviceExtension, pSiSEnt->pScrn_1,
++ pSiSEnt->CRT2DMode, pSiSEnt->CRT2IsCustom);
++ SiS_Pr->UseCustomMode = backupcustom;
++ }
+ }
+-
++
++ /* Warning: From here, the custom mode entries in SiS_Pr are
++ * possibly overwritten
++ */
++
+ SiS_HandleCRT1(SiS_Pr);
+
++ SiS_StrangeStuff(SiS_Pr, HwDeviceExtension);
++
+ SiS_DisplayOn(SiS_Pr);
+ SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF);
+
+- /* TW: New from 650/LV 1.10.6x and 1.10.7w, 630/301B 2.06.50 */
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x38,backupreg);
+@@ -2266,7 +2319,7 @@
+ /* TW: Set CRT2 mode (used for dual head) */
+ BOOLEAN
+ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn,
+- DisplayModePtr mode)
++ DisplayModePtr mode, BOOLEAN IsCustom)
+ {
+ ULONG temp;
+ USHORT ModeIdIndex;
+@@ -2276,16 +2329,52 @@
+ SISPtr pSiS = SISPTR(pScrn);
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+ unsigned char tempr1, tempr2, backupreg=0;
+-
++
+ SiS_Pr->UseCustomMode = FALSE;
+-
+- ModeNo = SiS_CalcModeIndex(pScrn, mode);
+- if(!ModeNo) return FALSE;
++
++ /* Remember: Custom modes for CRT2 are ONLY supported
++ * -) on 315/330 series,
++ * -) on the 301 and 30xB, and
++ * -) if CRT2 is LCD or VGA
++ */
++
++ if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
++
++ ModeNo = 0xfe;
++
++ } else {
++
++ BOOLEAN havecustommodes = pSiS->HaveCustomModes;
++
++#ifdef SISMERGED
++ if(pSiS->MergedFB) havecustommodes = pSiS->HaveCustomModes2;
++#endif
++
++ ModeNo = SiS_CalcModeIndex(pScrn, mode, havecustommodes);
++ if(!ModeNo) return FALSE;
++
++ }
++
++ /* Save mode info so we can set it from within SetMode for CRT1 */
++ if(pSiS->DualHeadMode) {
++ pSiSEnt->CRT2ModeNo = ModeNo;
++ pSiSEnt->CRT2DMode = mode;
++ pSiSEnt->CRT2IsCustom = IsCustom;
++
++ /* We can't set CRT2 mode before CRT1 mode is set */
++ if(pSiSEnt->CRT1ModeNo == -1) {
++ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
++ "Setting CRT2 mode delayed until after setting CRT1 mode\n");
++ return TRUE;
++ }
++ }
+
+ SiSInitPtr(SiS_Pr, HwDeviceExtension);
+
+ SiSRegInit(SiS_Pr, BaseAddr);
+
++ SiS_GetSysFlags(SiS_Pr, HwDeviceExtension);
++
+ SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
+
+ SiSInitPCIetc(SiS_Pr, HwDeviceExtension);
+@@ -2294,22 +2383,26 @@
+
+ SiSDetermineROMUsage(SiS_Pr, HwDeviceExtension, ROMAddr);
+
+- /* TW: We don't clear the buffer under X */
++ /* We don't clear the buffer under X */
+ SiS_Pr->SiS_flag_clearbuffer=0;
+
+- /* TW: Save ModeNo so we can set it from within SetMode for CRT1 */
+- pSiSEnt->CRT2ModeNo = ModeNo;
+- pSiSEnt->CRT2DMode = mode;
+-
+- /* TW: We can't set CRT2 mode before CRT1 mode is set */
+- if(pSiSEnt->CRT1ModeNo == -1) {
+- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+- "Setting CRT2 mode delayed until after setting CRT1 mode\n");
+- return TRUE;
+- }
++ if(SiS_Pr->UseCustomMode) {
++
++ USHORT temptemp = SiS_Pr->CVDisplay;
++
++ if(SiS_Pr->CModeFlag & DoubleScanMode) temptemp >>= 1;
++ else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1;
++
++ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
++ "Setting custom mode %dx%d on CRT2\n",
++ SiS_Pr->CHDisplay, temptemp);
+
+- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+- "Setting mode 0x%x on CRT2\n", ModeNo);
++ } else {
++
++ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
++ "Setting standard mode 0x%x on CRT2\n", ModeNo);
++
++ }
+
+ /* 1.Openkey */
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
+@@ -2317,10 +2410,14 @@
+ SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
+
+ /* 2.Get ModeID */
+- temp = SiS_SearchModeID(SiS_Pr, ROMAddr,&ModeNo,&ModeIdIndex);
+- if(temp == 0) return(0);
++ if(!SiS_Pr->UseCustomMode) {
++ temp = SiS_SearchModeID(SiS_Pr, ROMAddr,&ModeNo,&ModeIdIndex);
++ if(temp == 0) return(0);
++ } else {
++ ModeIdIndex = 0;
++ }
+
+- /* TW: Determine VBType (301,301B,301LV,302B,302LV) */
++ /* Determine VBType (301,301B,301LV,302B,302LV) */
+ SiS_GetVBType(SiS_Pr, BaseAddr,HwDeviceExtension);
+
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+@@ -2343,15 +2440,22 @@
+ }
+ }
+
+- /* TW: Get VB information (connectors, connected devices) */
+- SiS_GetVBInfo(SiS_Pr, BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,1);
++ /* Get VB information (connectors, connected devices) */
++ if(!SiS_Pr->UseCustomMode) {
++ SiS_GetVBInfo(SiS_Pr, BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,1);
++ } else {
++ /* If this is a custom mode, we don't check the modeflag for CRT2Mode */
++ SiS_GetVBInfo(SiS_Pr, BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,0);
++ }
+ SiS_SetHiVision(SiS_Pr, BaseAddr,HwDeviceExtension);
+ SiS_GetLCDResInfo(SiS_Pr, ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+- if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+- if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08) {
++ if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08) {
++ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ if(ModeNo != 0x10) SiS_Pr->SiS_SetFlag |= SetDOSMode;
++ } else if((IS_SIS651) && (SiS_Pr->SiS_VBType & VB_NoLCD)) {
++ SiS_Pr->SiS_SetFlag |= SetDOSMode;
+ }
+ }
+ }
+@@ -2364,17 +2468,19 @@
+ case VB_CHIP_302:
+ case VB_CHIP_302B:
+ case VB_CHIP_302LV:
+- SiS_SetCRT2Group301(SiS_Pr, BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
++ SiS_SetCRT2Group(SiS_Pr, BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
+ break;
+ case VB_CHIP_UNKNOWN:
+- if (SiS_Pr->SiS_IF_DEF_LVDS == 1 ||
+- SiS_Pr->SiS_IF_DEF_CH70xx != 0 ||
+- SiS_Pr->SiS_IF_DEF_TRUMPION != 0) {
+- SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
++ if(SiS_Pr->SiS_IF_DEF_LVDS == 1 ||
++ SiS_Pr->SiS_IF_DEF_CH70xx != 0 ||
++ SiS_Pr->SiS_IF_DEF_TRUMPION != 0) {
++ SiS_SetCRT2Group(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
+ }
+ break;
+ }
+
++ SiS_StrangeStuff(SiS_Pr, HwDeviceExtension);
++
+ SiS_DisplayOn(SiS_Pr);
+ SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF);
+
+@@ -2386,7 +2492,6 @@
+ }
+ }
+
+- /* TW: New from 650/LV 1.10.6x and 1.10.7w, 630 2.06.50 */
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+@@ -2412,7 +2517,7 @@
+ }
+ }
+
+- /* TW: SetPitch: Adapt to virtual size & position */
++ /* SetPitch: Adapt to virtual size & position */
+ SiS_SetPitchCRT2(SiS_Pr, pScrn, BaseAddr);
+
+ return TRUE;
+@@ -2442,12 +2547,14 @@
+
+ if(SiS_Pr->UseCustomMode) {
+ ModeNo = 0xfe;
+- }
+-
++ }
++
+ SiSInitPtr(SiS_Pr, HwDeviceExtension);
+
+ SiSRegInit(SiS_Pr, BaseAddr);
+
++ SiS_GetSysFlags(SiS_Pr, HwDeviceExtension);
++
+ #ifdef LINUX_XF86
+ if(pScrn) SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
+ else
+@@ -2458,7 +2565,7 @@
+ #ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "VGAInfo 0x%02x\n", SiS_Pr->SiS_VGAINFO);
+ #endif
+-#endif
++#endif
+
+ SiSInitPCIetc(SiS_Pr, HwDeviceExtension);
+
+@@ -2469,10 +2576,10 @@
+ if(!SiS_Pr->UseCustomMode) {
+ /* TW: Shift the clear-buffer-bit away */
+ ModeNo = ((ModeNo & 0x80) << 8) | (ModeNo & 0x7f);
+- }
++ }
+
+ #ifdef LINUX_XF86
+- /* TW: We never clear the buffer in X */
++ /* We never clear the buffer in X */
+ ModeNo |= 0x8000;
+ #endif
+
+@@ -2490,21 +2597,21 @@
+ SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
+
+ if(!SiS_Pr->UseCustomMode) {
+-
++
+ /* 2.Get ModeID Table */
+ temp = SiS_SearchModeID(SiS_Pr,ROMAddr,&ModeNo,&ModeIdIndex);
+ if(temp == 0) return(0);
+-
++
+ } else {
+-
++
+ ModeIdIndex = 0;
+-
++
+ }
+-
+- /* TW: Determine VBType (301,301B,301LV,302B,302LV) */
++
++ /* Determine VBType (301,301B,301LV,302B,302LV) */
+ SiS_GetVBType(SiS_Pr,BaseAddr,HwDeviceExtension);
+
+- /* TW: Init/restore some VB registers */
++ /* Init/restore some VB registers */
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension,BaseAddr);
+@@ -2525,8 +2632,12 @@
+ }
+ }
+
+- /* TW: Get VB information (connectors, connected devices) */
+- SiS_GetVBInfo(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,1);
++ /* Get VB information (connectors, connected devices) */
++ if(SiS_Pr->UseCustomMode) {
++ SiS_GetVBInfo(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,0);
++ } else {
++ SiS_GetVBInfo(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,1);
++ }
+ SiS_SetHiVision(SiS_Pr,BaseAddr,HwDeviceExtension);
+ SiS_GetLCDResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+
+@@ -2535,22 +2646,32 @@
+ if(!temp) return(0);
+
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+- if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+- if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08) {
++ if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08) {
++ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ if(ModeNo != 0x10) SiS_Pr->SiS_SetFlag |= SetDOSMode;
++ } else if((IS_SIS651) && (SiS_Pr->SiS_VBType & VB_NoLCD)) {
++ SiS_Pr->SiS_SetFlag |= SetDOSMode;
+ }
+ }
+
+- /* TW: New from 650/LV 1.10.6x; not in any BIOS for other chipsets */
+ if(IS_SIS650) {
+- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+- SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
+- SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
+- }
++ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
++ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
++ if(IS_SIS651) SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x20);
++ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
++ }
+ }
+ }
+
+- /* TW: Set mode on CRT1 */
++ if(SiS_Pr->UseCustomMode) {
++ SiS_Pr->CRT1UsesCustomMode = TRUE;
++ SiS_Pr->CSRClock_CRT1 = SiS_Pr->CSRClock;
++ SiS_Pr->CModeFlag_CRT1 = SiS_Pr->CModeFlag;
++ } else {
++ SiS_Pr->CRT1UsesCustomMode = FALSE;
++ }
++
++ /* Set mode on CRT1 */
+ if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) {
+ SiS_SetCRT1Group(SiS_Pr,ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,BaseAddr);
+ } else {
+@@ -2559,7 +2680,7 @@
+ }
+ }
+
+- /* TW: Set mode on CRT2 */
++ /* Set mode on CRT2 */
+ if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2 | SetCRT2ToLCDA)) {
+ switch (HwDeviceExtension->ujVBChipID) {
+ case VB_CHIP_301:
+@@ -2568,18 +2689,20 @@
+ case VB_CHIP_302:
+ case VB_CHIP_302B:
+ case VB_CHIP_302LV:
+- SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
++ SiS_SetCRT2Group(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
+ break;
+ case VB_CHIP_UNKNOWN:
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1 ||
+ SiS_Pr->SiS_IF_DEF_CH70xx != 0 ||
+ SiS_Pr->SiS_IF_DEF_TRUMPION != 0)
+- SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
++ SiS_SetCRT2Group(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
+ break;
+ }
+ }
+
+ SiS_HandleCRT1(SiS_Pr);
++
++ SiS_StrangeStuff(SiS_Pr, HwDeviceExtension);
+
+ SiS_DisplayOn(SiS_Pr);
+ SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF);
+@@ -2592,7 +2715,6 @@
+ }
+ }
+
+- /* TW: New from 650/LV 1.10.6x and 1.10.7w */
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+@@ -2627,7 +2749,7 @@
+
+ #ifdef LINUX_XF86
+ if(pScrn) {
+- /* TW: SetPitch: Adapt to virtual size & position */
++ /* SetPitch: Adapt to virtual size & position */
+ if((ModeNo > 0x13) && (dosetpitch)) {
+ SiS_SetPitch(SiS_Pr, pScrn, BaseAddr);
+ }
+@@ -2637,7 +2759,7 @@
+ }
+ #endif
+
+-#ifndef LINUX_XF86 /* TW: We never lock registers in XF86 */
++#ifndef LINUX_XF86 /* We never lock registers in XF86 */
+ if(KeepLockReg == 0xA1) SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
+ else SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x00);
+ #endif
+@@ -2646,10 +2768,15 @@
+ }
+
+ void
+-SiS_SetEnableDstn(SiS_Private *SiS_Pr) /* TW: Called from sis_main.c */
++SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable)
++{
++ SiS_Pr->SiS_IF_DEF_DSTN = enable ? 1 : 0;
++}
++
++void
++SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable)
+ {
+- /* For 550 dstn */
+- SiS_Pr->SiS_IF_DEF_DSTN = 1;
++ SiS_Pr->SiS_IF_DEF_FSTN = enable ? 1 : 0;
+ }
+
+ void
+@@ -2663,13 +2790,73 @@
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x63,0xbf);
+
+ #if 0
+- if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15) & 0x01))
+- SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x63,0x40);
++ if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15) & 0x01)) {
++ if((SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15) & 0x0a) ||
++ (SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16) & 0x01)) {
++ SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x63,0x40);
++ }
+ }
+ #endif
+ }
+
+ void
++SiS_GetSysFlags(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
++{
++ unsigned char cr5f, temp1, temp2;
++
++ /* You should use the macros, not these flags directly */
++
++ SiS_Pr->SiS_SysFlags = 0;
++ if(HwDeviceExtension->jChipType == SIS_650) {
++ cr5f = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
++ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x5c,0x07);
++ temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
++ SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x5c,0xf8);
++ temp2 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
++ if((!temp1) || (temp2)) {
++ switch(cr5f) {
++ case 0x80:
++ case 0x90:
++ case 0xc0:
++ SiS_Pr->SiS_SysFlags |= SF_IsM650; break;
++ case 0xa0:
++ case 0xb0:
++ case 0xe0:
++ SiS_Pr->SiS_SysFlags |= SF_Is651; break;
++ }
++ } else {
++ switch(cr5f) {
++ case 0x90:
++ temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
++ switch(temp1) {
++ case 0x00: SiS_Pr->SiS_SysFlags |= SF_IsM652; break;
++ case 0x40: SiS_Pr->SiS_SysFlags |= SF_IsM653; break;
++ default: SiS_Pr->SiS_SysFlags |= SF_IsM650; break;
++ }
++ break;
++ case 0xb0:
++ SiS_Pr->SiS_SysFlags |= SF_Is652; break;
++ default:
++ SiS_Pr->SiS_SysFlags |= SF_IsM650; break;
++ }
++ }
++ }
++}
++
++void
++SiS_StrangeStuff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
++{
++ if((IS_SIS651) || (IS_SISM650)) {
++ SiS_SetReg1(SiS_Pr->SiS_VidCapt, 0x3f, 0x00); /* Fiddle with capture regs */
++ SiS_SetReg1(SiS_Pr->SiS_VidCapt, 0x00, 0x00);
++ SiS_SetReg1(SiS_Pr->SiS_VidPlay, 0x00, 0x86); /* (BIOS does NOT unlock) */
++ SiS_SetRegAND(SiS_Pr->SiS_VidPlay, 0x30, 0xfe); /* Fiddle with video regs */
++ SiS_SetRegAND(SiS_Pr->SiS_VidPlay, 0x3f, 0xef);
++ }
++ /* !!! This does not support modes < 0x13 !!! */
++}
++
++void
+ SiS_SetCRT1Group(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT ModeNo,USHORT ModeIdIndex,USHORT BaseAddr)
+ {
+@@ -2683,6 +2870,9 @@
+ }
+ }
+
++ /* 550, 651 */
++ SiS_WhatTheHellIsThis(SiS_Pr,HwDeviceExtension,BaseAddr);
++
+ SiS_SetSeqRegs(SiS_Pr,ROMAddr,StandTableIndex);
+ SiS_SetMiscRegs(SiS_Pr,ROMAddr,StandTableIndex);
+ SiS_SetCRTCRegs(SiS_Pr,ROMAddr,HwDeviceExtension,StandTableIndex);
+@@ -2759,15 +2949,20 @@
+ SiS_SetPitch(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr)
+ {
+ SISPtr pSiS = SISPTR(pScrn);
++ BOOLEAN isslavemode = FALSE;
++
++ if( (pSiS->VBFlags & VB_VIDEOBRIDGE) &&
++ ( ((pSiS->VGAEngine == SIS_300_VGA) && (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0xa0) == 0x20) ||
++ ((pSiS->VGAEngine == SIS_315_VGA) && (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x50) == 0x10) ) ) {
++ isslavemode = TRUE;
++ }
+
+- /* TW: We need to set pitch for CRT1 if bridge is in SlaveMode, too */
+- if( (pSiS->VBFlags & DISPTYPE_DISP1) ||
+- ( (pSiS->VBFlags & VB_VIDEOBRIDGE) &&
+- ( ((pSiS->VGAEngine == SIS_300_VGA) && (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0xa0) == 0x20) ||
+- ((pSiS->VGAEngine == SIS_315_VGA) && (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x50) == 0x10) ) ) ) {
++ /* We need to set pitch for CRT1 if bridge is in slave mode, too */
++ if( (pSiS->VBFlags & DISPTYPE_DISP1) || (isslavemode) ) {
+ SiS_SetPitchCRT1(SiS_Pr, pScrn, BaseAddr);
+ }
+- if (pSiS->VBFlags & DISPTYPE_DISP2) {
++ /* We must not set the pitch for CRT2 if bridge is in slave mode */
++ if( (pSiS->VBFlags & DISPTYPE_DISP2) && (!isslavemode) ) {
+ SiS_SetPitchCRT2(SiS_Pr, pScrn, BaseAddr);
+ }
+ }
+@@ -2790,7 +2985,7 @@
+ SISPtr pSiS = SISPTR(pScrn);
+ ULong HDisplay,temp;
+
+- HDisplay = pSiS->scrnPitch / 8;
++ HDisplay = pSiS->scrnPitch2 / 8;
+
+ /* Unlock CRT2 */
+ if (pSiS->VGAEngine == SIS_315_VGA)
+@@ -2880,7 +3075,6 @@
+ return TRUE;
+ }
+
+-/* For SiS 300 oem util: Search VBModeID */
+ BOOLEAN
+ SiS_SearchVBModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo)
+ {
+@@ -2946,6 +3140,81 @@
+ return index;
+ }
+
++static void
++SiS_WhatIsThis1a(SiS_Private *SiS_Pr, USHORT somevalue)
++{
++ USHORT temp, tempbl, tempbh;
++
++ tempbl = tempbh = somevalue;
++ temp = SiS_GetReg2(SiS_Pr->SiS_P3cb);
++ temp &= 0xf0;
++ tempbl >>= 4;
++ temp |= tempbl;
++ SiS_SetReg3(SiS_Pr->SiS_P3cb, temp);
++ temp = SiS_GetReg2(SiS_Pr->SiS_P3cd);
++ temp &= 0xf0;
++ tempbh &= 0x0f;
++ temp |= tempbh;
++ SiS_SetReg3(SiS_Pr->SiS_P3cd, temp);
++}
++
++static void
++SiS_WhatIsThis1b(SiS_Private *SiS_Pr, USHORT somevalue)
++{
++ USHORT temp, tempbl, tempbh;
++
++ tempbl = tempbh = somevalue;
++ temp = SiS_GetReg2(SiS_Pr->SiS_P3cb);
++ temp &= 0x0f;
++ tempbl &= 0xf0;
++ temp |= tempbl;
++ SiS_SetReg3(SiS_Pr->SiS_P3cb, temp);
++ temp = SiS_GetReg2(SiS_Pr->SiS_P3cd);
++ temp &= 0x0f;
++ tempbh <<= 4;
++ temp |= tempbh;
++ SiS_SetReg3(SiS_Pr->SiS_P3cd, temp);
++}
++
++static void
++SiS_WhatIsThis2b(SiS_Private *SiS_Pr, USHORT somevalue)
++{
++ SiS_WhatIsThis1a(SiS_Pr, somevalue);
++ SiS_WhatIsThis1b(SiS_Pr, somevalue);
++}
++
++static void
++SiS_WhatIsThis1(SiS_Private *SiS_Pr)
++{
++ SiS_WhatIsThis2b(SiS_Pr, 0);
++}
++
++static void
++SiS_WhatIsThis2a(SiS_Private *SiS_Pr, USHORT somevalue)
++{
++ USHORT temp = somevalue >> 8;
++
++ temp &= 0x07;
++ temp |= (temp << 4);
++ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1d,temp);
++ SiS_WhatIsThis2b(SiS_Pr, somevalue);
++}
++
++static void
++SiS_WhatIsThis2(SiS_Private *SiS_Pr)
++{
++ SiS_WhatIsThis2a(SiS_Pr, 0);
++}
++
++void
++SiS_WhatTheHellIsThis(SiS_Private *SiS_Pr,PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
++{
++ if(IS_SIS65x) {
++ SiS_WhatIsThis1(SiS_Pr);
++ SiS_WhatIsThis2(SiS_Pr);
++ }
++}
++
+ void
+ SiS_SetSeqRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex)
+ {
+@@ -3027,7 +3296,7 @@
+ (HwDeviceExtension->jChipRevision >= 0x30) ) { /* for 630S0 */
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
+- SiS_SetReg1(SiS_Pr->SiS_P3d4,0x18,0xFE);
++ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x18,0xFE);
+ }
+ }
+ }
+@@ -3065,7 +3334,7 @@
+ }
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+- if(IS_SIS650740 || IS_SIS550) {
++ if(IS_SIS550650740660) {
+ /* 315, 330 don't do this */
+ if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata=0;
+@@ -3148,7 +3417,7 @@
+ USHORT tempah,i,modeflag,j;
+ #ifdef SIS315H
+ USHORT temp;
+- USHORT ResInfo,DisplayType;
++ USHORT ResIndex,DisplayType;
+ const SiS_LCDACRT1DataStruct *LCDACRT1Ptr = NULL;
+ #endif
+
+@@ -3171,7 +3440,7 @@
+ /* LCDA */
+
+ temp = SiS_GetLCDACRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+- RefreshRateTableIndex,&ResInfo,&DisplayType);
++ RefreshRateTableIndex,&ResIndex,&DisplayType);
+
+ switch(DisplayType) {
+ case Panel_800x600 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_1; break;
+@@ -3197,30 +3466,30 @@
+ default: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1; break;
+ }
+
+- tempah = (LCDACRT1Ptr+ResInfo)->CR[0];
++ tempah = (LCDACRT1Ptr+ResIndex)->CR[0];
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,tempah);
+ for(i=0x01,j=1;i<=0x07;i++,j++){
+- tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
++ tempah = (LCDACRT1Ptr+ResIndex)->CR[j];
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
+ }
+ for(i=0x10,j=8;i<=0x12;i++,j++){
+- tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
++ tempah = (LCDACRT1Ptr+ResIndex)->CR[j];
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
+ }
+ for(i=0x15,j=11;i<=0x16;i++,j++){
+- tempah =(LCDACRT1Ptr+ResInfo)->CR[j];
++ tempah =(LCDACRT1Ptr+ResIndex)->CR[j];
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
+ }
+ for(i=0x0A,j=13;i<=0x0C;i++,j++){
+- tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
++ tempah = (LCDACRT1Ptr+ResIndex)->CR[j];
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,i,tempah);
+ }
+
+- tempah = (LCDACRT1Ptr+ResInfo)->CR[16];
++ tempah = (LCDACRT1Ptr+ResIndex)->CR[16];
+ tempah &= 0x0E0;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x0E,tempah);
+
+- tempah = (LCDACRT1Ptr+ResInfo)->CR[16];
++ tempah = (LCDACRT1Ptr+ResIndex)->CR[16];
+ tempah &= 0x01;
+ tempah <<= 5;
+ if(modeflag & DoubleScanMode) tempah |= 0x080;
+@@ -3301,7 +3570,7 @@
+
+ BOOLEAN
+ SiS_GetLCDACRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex,USHORT *ResInfo,
++ USHORT RefreshRateTableIndex,USHORT *ResIndex,
+ USHORT *DisplayType)
+ {
+ USHORT tempbx=0,modeflag=0;
+@@ -3320,7 +3589,7 @@
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 32;
+ if(modeflag & HalfDCLK) tempbx += 16;
+
+- *ResInfo = CRT2CRTC & 0x3F;
++ *ResIndex = CRT2CRTC & 0x3F;
+ *DisplayType = tempbx;
+
+ return 1;
+@@ -3470,6 +3739,9 @@
+ USHORT data,data2,data3;
+ USHORT infoflag=0,modeflag;
+ USHORT resindex,xres;
++#ifdef SIS315H
++ ULONG longdata;
++#endif
+
+ if(SiS_Pr->UseCustomMode) {
+ modeflag = SiS_Pr->CModeFlag;
+@@ -3490,11 +3762,11 @@
+
+ data2 = 0;
+ if(ModeNo > 0x13) {
+- if(SiS_Pr->SiS_ModeType > 0x02) {
+- data2 |= 0x02;
+- data3 = (SiS_Pr->SiS_ModeType - ModeVGA) << 2;
+- data2 |= data3;
+- }
++ if(SiS_Pr->SiS_ModeType > 0x02) {
++ data2 |= 0x02;
++ data3 = (SiS_Pr->SiS_ModeType - ModeVGA) << 2;
++ data2 |= data3;
++ }
+ }
+ #ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "Debug: Mode infoflag = %x, Chiptype %d\n",
+@@ -3517,7 +3789,8 @@
+ if(HwDeviceExtension->jChipType != SIS_300) {
+ data = 0x0000;
+ if(infoflag & InterlaceMode) {
+- if(xres == 1024) data = 0x0035;
++ if(xres <= 800) data = 0x0020;
++ else if(xres <= 1024) data = 0x0035;
+ else data = 0x0048;
+ }
+ data2 = data & 0x00FF;
+@@ -3549,6 +3822,7 @@
+ } else {
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0xB7);
+ }
++ /* 651 BIOS does something for mode 0x12 here */
+ }
+
+ if(HwDeviceExtension->jChipType != SIS_300) {
+@@ -3604,9 +3878,9 @@
+ data2 *= data3;
+
+ data3 = SiS_GetMCLK(SiS_Pr,ROMAddr, HwDeviceExtension);
+- data3 *= 1024;
++ longdata = data3 * 1024;
+
+- data2 = data3 / data2;
++ data2 = longdata / data2;
+
+ if(SiS_Pr->SiS_ModeType != Mode16Bpp) {
+ if(data2 >= 0x19c) data = 0xba;
+@@ -3679,7 +3953,7 @@
+ if(VCLK >= 150) data2 |= 0x08; /* VCLK > 150 */
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xF7,data2);
+
+- } else { /* 310/325 series */
++ } else { /* 315 series */
+
+ data = 0;
+ if(VCLK >= 166) data |= 0x0c; /* TW: Was 200; is 166 in 650, 315 and 330 BIOSes */
+@@ -3688,12 +3962,6 @@
+ if(VCLK >= 166) { /* TW: Was 200, is 166 in 650, 315 and 330 BIOSes */
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1f,0xe7);
+ }
+-#if 0 /* Not done in 315 and 650/301LV/LVDS BIOSes: */
+- data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1F); /* DAC pedestal */
+- data &= 0xE7;
+- if(VCLK<200) data |= 0x10;
+- SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1F,data); /* DAC pedestal */
+-#endif
+ }
+
+ data2 = 0x03;
+@@ -3918,7 +4186,9 @@
+
+ } else if((HwDeviceExtension->jChipType == SIS_550) ||
+ (HwDeviceExtension->jChipType == SIS_740) ||
+- (HwDeviceExtension->jChipType == SIS_650)) {
++ (HwDeviceExtension->jChipType == SIS_650) ||
++ (HwDeviceExtension->jChipType == SIS_660) ||
++ (HwDeviceExtension->jChipType == SIS_760)) {
+
+ counter = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14) & 0x3F;
+ counter++;
+@@ -4728,7 +4998,7 @@
+ SiS_Pr->SiS_SetFlag = 0x00;
+ SiS_Pr->SiS_ModeType = ModeVGA;
+ SiS_Pr->SiS_VBInfo = SetCRT2ToRAMDAC |LoadDACFlag |SetInSlaveMode;
+- SiS_SetCRT2Group301(SiS_Pr, BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension);
++ SiS_SetCRT2Group(SiS_Pr, BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension);
+ for(i=0;i<20;i++) {
+ SiS_LongWait(SiS_Pr);
+ }
+@@ -4766,7 +5036,7 @@
+ #ifdef SIS315H
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ OutputSelect = ROMAddr[0xf3];
+- if(HwDeviceExtension->jChipType == SIS_330) {
++ if(HwDeviceExtension->jChipType >= SIS_330) {
+ OutputSelect = ROMAddr[0x11b];
+ }
+ }
+@@ -4814,7 +5084,7 @@
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,P2reg0);
+ if(!(P2reg0 & 0x20)) {
+ SiS_Pr->SiS_VBInfo = DisableCRT2Display;
+- SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension);
++ SiS_SetCRT2Group(SiS_Pr,BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension);
+ }
+ }
+ }
+@@ -4884,111 +5154,6 @@
+ }
+ #endif /* LINUXBIOS */
+
+-/* ================ for TC only ================= */
+-
+-#ifdef TC
+-
+-int
+-INT1AReturnCode(union REGS regs)
+-{
+- if (regs.x.cflag)
+- {
+- /*printf("Error to find pci device!\n"); */
+- return 1;
+- }
+-
+- switch(regs.h.ah)
+- {
+- case 0: return 0;
+- break;
+- case 0x81: printf("Function not support\n");
+- break;
+- case 0x83: printf("bad vendor id\n");
+- break;
+- case 0x86: printf("device not found\n");
+- break;
+- case 0x87: printf("bad register number\n");
+- break;
+- case 0x88: printf("set failed\n");
+- break;
+- case 0x89: printf("buffer too small");
+- break;
+- }
+- return 1;
+-}
+-
+-unsigned
+-FindPCIIOBase(unsigned index,unsigned deviceid)
+-{
+- union REGS regs;
+-
+- regs.h.ah = 0xb1; /*PCI_FUNCTION_ID */
+- regs.h.al = 0x02; /*FIND_PCI_DEVICE */
+- regs.x.cx = deviceid;
+- regs.x.dx = 0x1039;
+- regs.x.si = index; /* find n-th device */
+-
+- int86(0x1A, ®s, ®s);
+-
+- if (INT1AReturnCode(regs)!=0)
+- return 0;
+-
+- /* regs.h.bh *//* bus number */
+- /* regs.h.bl *//* device number */
+- regs.h.ah = 0xb1; /*PCI_FUNCTION_ID */
+- regs.h.al = 0x09; /*READ_CONFIG_WORD */
+- regs.x.cx = deviceid;
+- regs.x.dx = 0x1039;
+- regs.x.di = 0x18; /* register number */
+- int86(0x1A, ®s, ®s);
+-
+- if (INT1AReturnCode(regs)!=0)
+- return 0;
+- return regs.x.cx;
+-}
+-
+-
+-void
+-main(int argc, char *argv[])
+-{
+- SIS_HW_DEVICE_INFO HwDeviceExtension;
+- USHORT temp;
+- USHORT ModeNo;
+-
+- /*HwDeviceExtension.pjVirtualRomBase =(PUCHAR) MK_FP(0xC000,0); */
+- /*HwDeviceExtension.pjVideoMemoryAddress = (PUCHAR)MK_FP(0xA000,0);*/
+-
+-#ifdef SIS300
+- HwDeviceExtension.ulIOAddress = (FindPCIIOBase(0,0x6300)&0xFF80) + 0x30;
+- HwDeviceExtension.jChipType = SIS_630;
+-#endif
+-
+-#ifdef SIS315H
+-// HwDeviceExtension.ulIOAddress = (FindPCIIOBase(0,0x5315)&0xFF80) + 0x30;
+-// HwDeviceExtension.jChipType = SIS_550;
+- HwDeviceExtension.ulIOAddress = (FindPCIIOBase(0,0x325)&0xFF80) + 0x30;
+- HwDeviceExtension.jChipType = SIS_315H;
+-#endif
+-
+- HwDeviceExtension.ujVBChipID = VB_CHIP_301;
+- strcpy(HwDeviceExtension.szVBIOSVer,"0.84");
+- HwDeviceExtension.bSkipDramSizing = FALSE;
+- HwDeviceExtension.ulVideoMemorySize = 0;
+- if(argc==2) {
+- ModeNo=atoi(argv[1]);
+- }
+- else {
+- ModeNo=0x2e;
+- /*ModeNo=0x37; */ /* 1024x768x 4bpp */
+- /*ModeNo=0x38; *//* 1024x768x 8bpp */
+- /*ModeNo=0x4A; *//* 1024x768x 16bpp */
+- /*ModeNo=0x47;*/ /* 800x600x 16bpp */
+- }
+- /* SiSInit(SiS_Pr, &HwDeviceExtension);*/
+- SiSSetMode(SiS_Pr, &HwDeviceExtension, ModeNo);
+-}
+-#endif /* TC END */
+-
+ /* ================ XFREE86 ================= */
+
+ /* Helper functions */
+@@ -5000,44 +5165,78 @@
+ SISPtr pSiS = SISPTR(pScrn);
+ int out_n, out_dn, out_div, out_sbit, out_scale;
+ int depth = pSiS->CurrentLayout.bitsPerPixel;
+-
+-#ifdef SISDUALHEAD
+- if( ((!pSiS->DualHeadMode) && (VBFlags & DISPTYPE_DISP2)) ||
+- ((pSiS->DualHeadMode) && (!pSiS->SecondHead)) ) return 0;
+-#else
+- if(VBFlags & DISPTYPE_DISP2) return 0;
+-#endif
++ unsigned int vclk[5];
++
++#define Midx 0
++#define Nidx 1
++#define VLDidx 2
++#define Pidx 3
++#define PSNidx 4
++
++ pSiS->SiS_Pr->CModeFlag = 0;
+
+ pSiS->SiS_Pr->CDClock = mode->Clock;
+-
++
+ pSiS->SiS_Pr->CHDisplay = mode->HDisplay;
+ pSiS->SiS_Pr->CHSyncStart = mode->HSyncStart;
+ pSiS->SiS_Pr->CHSyncEnd = mode->HSyncEnd;
+ pSiS->SiS_Pr->CHTotal = mode->HTotal;
+- pSiS->SiS_Pr->CHBlankStart = pSiS->SiS_Pr->CHDisplay;
+- pSiS->SiS_Pr->CHBlankEnd = pSiS->SiS_Pr->CHTotal;
+-
++
+ pSiS->SiS_Pr->CVDisplay = mode->VDisplay;
+ pSiS->SiS_Pr->CVSyncStart = mode->VSyncStart;
+ pSiS->SiS_Pr->CVSyncEnd = mode->VSyncEnd;
+ pSiS->SiS_Pr->CVTotal = mode->VTotal;
++
++ pSiS->SiS_Pr->CFlags = mode->Flags;
++
++ if(pSiS->SiS_Pr->CFlags & V_INTERLACE) {
++ pSiS->SiS_Pr->CVDisplay >>= 1;
++ pSiS->SiS_Pr->CVSyncStart >>= 1;
++ pSiS->SiS_Pr->CVSyncEnd >>= 1;
++ pSiS->SiS_Pr->CVTotal >>= 1;
++ }
++ if(pSiS->SiS_Pr->CFlags & V_DBLSCAN) {
++ /* pSiS->SiS_Pr->CDClock <<= 1; */
++ pSiS->SiS_Pr->CVDisplay <<= 1;
++ pSiS->SiS_Pr->CVSyncStart <<= 1;
++ pSiS->SiS_Pr->CVSyncEnd <<= 1;
++ pSiS->SiS_Pr->CVTotal <<= 1;
++ }
++
++ pSiS->SiS_Pr->CHBlankStart = pSiS->SiS_Pr->CHDisplay;
++ pSiS->SiS_Pr->CHBlankEnd = pSiS->SiS_Pr->CHTotal;
+ pSiS->SiS_Pr->CVBlankStart = pSiS->SiS_Pr->CVSyncStart - 1;
+ pSiS->SiS_Pr->CVBlankEnd = pSiS->SiS_Pr->CVTotal;
+-
+- pSiS->SiS_Pr->CFlags = mode->Flags;
+
+- SiS_compute_vclk(pSiS->SiS_Pr->CDClock, &out_n, &out_dn, &out_div, &out_sbit, &out_scale);
+-
++ if(SiS_compute_vclk(pSiS->SiS_Pr->CDClock, &out_n, &out_dn, &out_div, &out_sbit, &out_scale)) {
++ pSiS->SiS_Pr->CSR2B = (out_div == 2) ? 0x80 : 0x00;
++ pSiS->SiS_Pr->CSR2B |= ((out_n - 1) & 0x7f);
++ pSiS->SiS_Pr->CSR2C = (out_dn - 1) & 0x1f;
++ pSiS->SiS_Pr->CSR2C |= (((out_scale - 1) & 3) << 5);
++ pSiS->SiS_Pr->CSR2C |= ((out_sbit & 0x01) << 7);
+ #ifdef TWDEBUG
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sb %d sc %d\n",
+- pSiS->SiS_Pr->CDClock, out_n, out_dn, out_div, out_sbit, out_scale);
+-#endif
+-
+- pSiS->SiS_Pr->CSR2B = (out_div == 2) ? 0x80 : 0x00;
+- pSiS->SiS_Pr->CSR2B |= ((out_n - 1) & 0x7f);
+- pSiS->SiS_Pr->CSR2C = (out_dn - 1) & 0x1f;
+- pSiS->SiS_Pr->CSR2C |= (((out_scale - 1) & 3) << 5);
+- pSiS->SiS_Pr->CSR2C |= ((out_sbit & 0x01) << 7);
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sb %d sc %d\n",
++ pSiS->SiS_Pr->CDClock, out_n, out_dn, out_div, out_sbit, out_scale);
++#endif
++ } else {
++ SiSCalcClock(pScrn, pSiS->SiS_Pr->CDClock, 2, vclk);
++ pSiS->SiS_Pr->CSR2B = (vclk[VLDidx] == 2) ? 0x80 : 0x00;
++ pSiS->SiS_Pr->CSR2B |= (vclk[Midx] - 1) & 0x7f;
++ pSiS->SiS_Pr->CSR2C = (vclk[Nidx] - 1) & 0x1f;
++ if(vclk[Pidx] <= 4) {
++ /* postscale 1,2,3,4 */
++ pSiS->SiS_Pr->CSR2C |= ((vclk[Pidx] - 1) & 3) << 5;
++ } else {
++ /* postscale 6,8 */
++ pSiS->SiS_Pr->CSR2C |= (((vclk[Pidx] / 2) - 1) & 3) << 5;
++ pSiS->SiS_Pr->CSR2C |= 0x80;
++ }
++#ifdef TWDEBUG
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sc %d\n",
++ pSiS->SiS_Pr->CDClock, vclk[Midx], vclk[Nidx], vclk[VLDidx], vclk[Pidx]);
++#endif
++ }
++
+ pSiS->SiS_Pr->CSRClock = (pSiS->SiS_Pr->CDClock / 1000) + 1;
+
+ pSiS->SiS_Pr->CCRT1CRTC[0] = ((pSiS->SiS_Pr->CHTotal >> 3) - 5) & 0xff;
+@@ -5045,9 +5244,9 @@
+ pSiS->SiS_Pr->CCRT1CRTC[2] = (pSiS->SiS_Pr->CHBlankStart >> 3) - 1;
+ pSiS->SiS_Pr->CCRT1CRTC[3] = (((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1) & 0x1F) | 0x80;
+ pSiS->SiS_Pr->CCRT1CRTC[4] = (pSiS->SiS_Pr->CHSyncStart >> 3) + 3;
+- pSiS->SiS_Pr->CCRT1CRTC[5] = ((((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1) & 0x20) << 2) |
++ pSiS->SiS_Pr->CCRT1CRTC[5] = ((((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1) & 0x20) << 2) |
+ (((pSiS->SiS_Pr->CHSyncEnd >> 3) + 3) & 0x1F);
+-
++
+ pSiS->SiS_Pr->CCRT1CRTC[6] = (pSiS->SiS_Pr->CVTotal - 2) & 0xFF;
+ pSiS->SiS_Pr->CCRT1CRTC[7] = (((pSiS->SiS_Pr->CVTotal - 2) & 0x100) >> 8)
+ | (((pSiS->SiS_Pr->CVDisplay - 1) & 0x100) >> 7)
+@@ -5057,50 +5256,50 @@
+ | (((pSiS->SiS_Pr->CVTotal - 2) & 0x200) >> 4)
+ | (((pSiS->SiS_Pr->CVDisplay - 1) & 0x200) >> 3)
+ | ((pSiS->SiS_Pr->CVSyncStart & 0x200) >> 2);
+-
++
+ pSiS->SiS_Pr->CCRT1CRTC[16] = ((((pSiS->SiS_Pr->CVBlankStart - 1) & 0x200) >> 4) >> 5); /* cr9 */
+-
+-#if 0
++
++#if 0
+ if (mode->VScan >= 32)
+ regp->CRTC[9] |= 0x1F;
+ else if (mode->VScan > 1)
+ regp->CRTC[9] |= mode->VScan - 1;
+-#endif
++#endif
+
+- pSiS->SiS_Pr->CCRT1CRTC[8] = (pSiS->SiS_Pr->CVSyncStart - 1) & 0xFF; /* cr10 */
+- pSiS->SiS_Pr->CCRT1CRTC[9] = ((pSiS->SiS_Pr->CVSyncEnd - 1) & 0x0F) | 0x80; /* cr11 */
+- pSiS->SiS_Pr->CCRT1CRTC[10] = (pSiS->SiS_Pr->CVDisplay - 1) & 0xFF; /* cr12 */
+- pSiS->SiS_Pr->CCRT1CRTC[11] = (pSiS->SiS_Pr->CVBlankStart - 1) & 0xFF; /* cr15 */
+- pSiS->SiS_Pr->CCRT1CRTC[12] = (pSiS->SiS_Pr->CVBlankEnd - 1) & 0xFF; /* cr16 */
+-
+- pSiS->SiS_Pr->CCRT1CRTC[13] =
++ pSiS->SiS_Pr->CCRT1CRTC[8] = (pSiS->SiS_Pr->CVSyncStart ) & 0xFF; /* cr10 */
++ pSiS->SiS_Pr->CCRT1CRTC[9] = ((pSiS->SiS_Pr->CVSyncEnd ) & 0x0F) | 0x80; /* cr11 */
++ pSiS->SiS_Pr->CCRT1CRTC[10] = (pSiS->SiS_Pr->CVDisplay - 1) & 0xFF; /* cr12 */
++ pSiS->SiS_Pr->CCRT1CRTC[11] = (pSiS->SiS_Pr->CVBlankStart - 1) & 0xFF; /* cr15 */
++ pSiS->SiS_Pr->CCRT1CRTC[12] = (pSiS->SiS_Pr->CVBlankEnd - 1) & 0xFF; /* cr16 */
++
++ pSiS->SiS_Pr->CCRT1CRTC[13] =
+ GETBITSTR((pSiS->SiS_Pr->CVTotal -2), 10:10, 0:0) |
+ GETBITSTR((pSiS->SiS_Pr->CVDisplay -1), 10:10, 1:1) |
+ GETBITSTR((pSiS->SiS_Pr->CVBlankStart-1), 10:10, 2:2) |
+ GETBITSTR((pSiS->SiS_Pr->CVSyncStart ), 10:10, 3:3) |
+ GETBITSTR((pSiS->SiS_Pr->CVBlankEnd -1), 8:8, 4:4) |
+- GETBITSTR((pSiS->SiS_Pr->CVSyncEnd -1), 4:4, 5:5) ;
++ GETBITSTR((pSiS->SiS_Pr->CVSyncEnd ), 4:4, 5:5) ;
+
+- pSiS->SiS_Pr->CCRT1CRTC[14] =
++ pSiS->SiS_Pr->CCRT1CRTC[14] =
+ GETBITSTR((pSiS->SiS_Pr->CHTotal >> 3) - 5, 9:8, 1:0) |
+ GETBITSTR((pSiS->SiS_Pr->CHDisplay >> 3) - 1, 9:8, 3:2) |
+ GETBITSTR((pSiS->SiS_Pr->CHBlankStart >> 3) - 1, 9:8, 5:4) |
+ GETBITSTR((pSiS->SiS_Pr->CHSyncStart >> 3) + 3, 9:8, 7:6) ;
+
+-
++
+ pSiS->SiS_Pr->CCRT1CRTC[15] =
+ GETBITSTR((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1, 7:6, 1:0) |
+- GETBITSTR((pSiS->SiS_Pr->CHSyncEnd >> 3) + 3, 5:5, 2:2) ;
+-
++ GETBITSTR((pSiS->SiS_Pr->CHSyncEnd >> 3) + 3, 5:5, 2:2) ;
++
+ switch(depth) {
+- case 8:
+- pSiS->SiS_Pr->CModeFlag = 0x223b;
++ case 8:
++ pSiS->SiS_Pr->CModeFlag |= 0x223b;
+ break;
+- case 16:
+- pSiS->SiS_Pr->CModeFlag = 0x227d;
++ case 16:
++ pSiS->SiS_Pr->CModeFlag |= 0x227d;
+ break;
+- case 32:
+- pSiS->SiS_Pr->CModeFlag = 0x22ff;
++ case 32:
++ pSiS->SiS_Pr->CModeFlag |= 0x22ff;
+ break;
+ default:
+ return 0;
+@@ -5114,9 +5313,9 @@
+ pSiS->SiS_Pr->CModeFlag |= LineCompareOff;
+ if(pSiS->SiS_Pr->CFlags & V_CLKDIV2)
+ pSiS->SiS_Pr->CModeFlag |= HalfDCLK;
+-
++
+ pSiS->SiS_Pr->CInfoFlag = 0x0007;
+- if(pSiS->SiS_Pr->CFlags & V_NHSYNC)
++ if(pSiS->SiS_Pr->CFlags & V_NHSYNC)
+ pSiS->SiS_Pr->CInfoFlag |= 0x4000;
+ if(pSiS->SiS_Pr->CFlags & V_NVSYNC)
+ pSiS->SiS_Pr->CInfoFlag |= 0x8000;
+@@ -5152,13 +5351,13 @@
+ pSiS->SiS_Pr->CSR2B,
+ pSiS->SiS_Pr->CSR2C,
+ pSiS->SiS_Pr->CSRClock);
+-#endif
++#endif
+ return 1;
+ }
+
+ /* TW: Build a list of supported modes */
+ DisplayModePtr
+-SiSBuildBuiltInModeList(ScrnInfoPtr pScrn)
++SiSBuildBuiltInModeList(ScrnInfoPtr pScrn, BOOLEAN includelcdmodes, BOOLEAN isfordvi)
+ {
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned short VRE, VBE, VRS, VBS, VDE, VT;
+@@ -5166,11 +5365,16 @@
+ unsigned char sr_data, cr_data, cr_data2, cr_data3;
+ unsigned char sr2b, sr2c;
+ float num, denum, postscalar, divider;
+- int A, B, C, D, E, F, temp, i, j, index, vclkindex;
+- DisplayModePtr new = NULL, current = NULL, first = NULL, backup = NULL;
++ int A, B, C, D, E, F, temp, i, j, k, l, index, vclkindex;
++ DisplayModePtr new = NULL, current = NULL, first = NULL;
++ BOOLEAN done = FALSE;
++#if 0
++ DisplayModePtr backup = NULL;
++#endif
+
+ pSiS->backupmodelist = NULL;
+-
++ pSiS->AddedPlasmaModes = FALSE;
++
+ /* Initialize our pointers */
+ if(pSiS->VGAEngine == SIS_300_VGA) {
+ #ifdef SIS300
+@@ -5194,15 +5398,20 @@
+ if(pSiS->VGAEngine == SIS_300_VGA) index &= 0x3F;
+ #endif
+
+- if(((pSiS->SiS_Pr->SiS_RefIndex[i].XRes < 512) && (!pSiS->DSTN)) ||
+- ((pSiS->DSTN) &&
+- (pSiS->SiS_Pr->SiS_RefIndex[i].XRes < 512) &&
+- (pSiS->SiS_Pr->SiS_RefIndex[i].XRes != 320) &&
+- (pSiS->SiS_Pr->SiS_RefIndex[i].YRes != 480))) {
++ /* 0x5a (320x240) is a pure FTSN mode, not DSTN! */
++ if((!pSiS->FSTN) &&
++ (pSiS->SiS_Pr->SiS_RefIndex[i].ModeID == 0x5a)) {
+ i++;
+ continue;
+ }
+-
++ if((pSiS->FSTN) &&
++ (pSiS->SiS_Pr->SiS_RefIndex[i].XRes == 320) &&
++ (pSiS->SiS_Pr->SiS_RefIndex[i].YRes == 240) &&
++ (pSiS->SiS_Pr->SiS_RefIndex[i].ModeID != 0x5a)) {
++ i++;
++ continue;
++ }
++
+ if(!(new = xalloc(sizeof(DisplayModeRec)))) return first;
+ memset(new, 0, sizeof(DisplayModeRec));
+ if(!(new->name = xalloc(10))) {
+@@ -5216,13 +5425,13 @@
+ }
+
+ current = new;
+-
++
+ sprintf(current->name, "%dx%d", pSiS->SiS_Pr->SiS_RefIndex[i].XRes,
+ pSiS->SiS_Pr->SiS_RefIndex[i].YRes);
+
+ current->status = MODE_OK;
+
+- current->type = M_T_DEFAULT;
++ current->type = M_T_DEFAULT;
+
+ vclkindex = pSiS->SiS_Pr->SiS_RefIndex[i].Ext_CRTVCLK;
+ if(pSiS->VGAEngine == SIS_300_VGA) vclkindex &= 0x3F;
+@@ -5235,7 +5444,7 @@
+ ( (((sr2c >> 5) & 0x03) == 0x02) ? 6.0 : 8.0) : (((sr2c >> 5) & 0x03) + 1.0);
+ num = (sr2b & 0x7f) + 1.0;
+ denum = (sr2c & 0x1f) + 1.0;
+-
++
+ #ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "------------\n");
+ xf86DrvMsg(0, X_INFO, "sr2b: %x sr2c %x div %f ps %f num %f denum %f\n",
+@@ -5303,10 +5512,29 @@
+
+ D = B - F - C;
+
+- current->HDisplay = (E * 8);
+- current->HSyncStart = (E * 8) + (F * 8);
+- current->HSyncEnd = (E * 8) + (F * 8) + (C * 8);
+- current->HTotal = (E * 8) + (F * 8) + (C * 8) + (D * 8);
++ if((pSiS->SiS_Pr->SiS_RefIndex[i].XRes == 320) &&
++ ((pSiS->SiS_Pr->SiS_RefIndex[i].YRes == 200) ||
++ (pSiS->SiS_Pr->SiS_RefIndex[i].YRes == 240))) {
++
++ /* Terrible hack, but correct CRTC data for
++ * these modes only produces a black screen...
++ * (HRE is 0, leading into a too large C and
++ * a negative D. The CRT controller does not
++ * seem to like correcting HRE to 50
++ */
++ current->HDisplay = 320;
++ current->HSyncStart = 328;
++ current->HSyncEnd = 376;
++ current->HTotal = 400;
++
++ } else {
++
++ current->HDisplay = (E * 8);
++ current->HSyncStart = (E * 8) + (F * 8);
++ current->HSyncEnd = (E * 8) + (F * 8) + (C * 8);
++ current->HTotal = (E * 8) + (F * 8) + (C * 8) + (D * 8);
++
++ }
+
+ #ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO,
+@@ -5430,7 +5658,7 @@
+ current->VSyncStart <<= 1;
+ current->VSyncEnd <<= 1;
+ current->VTotal <<= 1;
+- current->VTotal |= 1;
++ current->VTotal |= 1;
+ }
+ if(current->Flags & V_DBLSCAN) {
+ current->Clock >>= 1;
+@@ -5440,6 +5668,7 @@
+ current->VTotal >>= 1;
+ }
+
++#if 0
+ if((backup = xalloc(sizeof(DisplayModeRec)))) {
+ if(!pSiS->backupmodelist) pSiS->backupmodelist = backup;
+ else {
+@@ -5458,6 +5687,7 @@
+ backup->Flags = current->Flags;
+ backup->Clock = current->Clock;
+ }
++#endif
+
+ #ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+@@ -5470,6 +5700,187 @@
+ i++;
+ }
+
++ /* Add non-standard LCD modes for panel's detailed timings */
++
++ if(!includelcdmodes) return first;
++
++ xf86DrvMsg(0, X_INFO, "Checking database for vendor %x, product %x\n",
++ pSiS->SiS_Pr->CP_Vendor, pSiS->SiS_Pr->CP_Product);
++
++ i = 0;
++ while((!done) && (SiS_PlasmaTable[i].vendor) && (pSiS->SiS_Pr->CP_Vendor)) {
++
++ if(SiS_PlasmaTable[i].vendor == pSiS->SiS_Pr->CP_Vendor) {
++
++ for(j=0; j<SiS_PlasmaTable[i].productnum; j++) {
++
++ if(SiS_PlasmaTable[i].product[j] == pSiS->SiS_Pr->CP_Product) {
++
++ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
++ "Identified %s panel, adding specific modes\n",
++ SiS_PlasmaTable[i].plasmaname);
++
++ for(k=0; k<SiS_PlasmaTable[i].modenum; k++) {
++
++ if(isfordvi) {
++ if(!(SiS_PlasmaTable[i].plasmamodes[k] & 0x80)) continue;
++ } else {
++ if(!(SiS_PlasmaTable[i].plasmamodes[k] & 0x40)) continue;
++ }
++
++ if(!(new = xalloc(sizeof(DisplayModeRec)))) return first;
++
++ memset(new, 0, sizeof(DisplayModeRec));
++ if(!(new->name = xalloc(10))) {
++ xfree(new);
++ return first;
++ }
++ if(!first) first = new;
++ if(current) {
++ current->next = new;
++ new->prev = current;
++ }
++
++ current = new;
++
++ pSiS->AddedPlasmaModes = TRUE;
++
++ l = SiS_PlasmaTable[i].plasmamodes[k] & 0x3f;
++
++ sprintf(current->name, "%dx%d", SiS_PlasmaMode[l].HDisplay,
++ SiS_PlasmaMode[l].VDisplay);
++
++ current->status = MODE_OK;
++
++ current->type = M_T_BUILTIN;
++
++ current->Clock = SiS_PlasmaMode[l].clock;
++ current->SynthClock = current->Clock;
++
++ current->HDisplay = SiS_PlasmaMode[l].HDisplay;
++ current->HSyncStart = current->HDisplay + SiS_PlasmaMode[l].HFrontPorch;
++ current->HSyncEnd = current->HSyncStart + SiS_PlasmaMode[l].HSyncWidth;
++ current->HTotal = SiS_PlasmaMode[l].HTotal;
++
++ current->VDisplay = SiS_PlasmaMode[l].VDisplay;
++ current->VSyncStart = current->VDisplay + SiS_PlasmaMode[l].VFrontPorch;
++ current->VSyncEnd = current->VSyncStart + SiS_PlasmaMode[l].VSyncWidth;
++ current->VTotal = SiS_PlasmaMode[l].VTotal;
++
++ current->CrtcHDisplay = current->HDisplay;
++ current->CrtcHBlankStart = current->HSyncStart;
++ current->CrtcHSyncStart = current->HSyncStart;
++ current->CrtcHSyncEnd = current->HSyncEnd;
++ current->CrtcHBlankEnd = current->HSyncEnd;
++ current->CrtcHTotal = current->HTotal;
++
++ current->CrtcVDisplay = current->VDisplay;
++ current->CrtcVBlankStart = current->VSyncStart;
++ current->CrtcVSyncStart = current->VSyncStart;
++ current->CrtcVSyncEnd = current->VSyncEnd;
++ current->CrtcVBlankEnd = current->VSyncEnd;
++ current->CrtcVTotal = current->VTotal;
++
++ if(SiS_PlasmaMode[l].SyncFlags & SIS_PL_HSYNCP)
++ current->Flags |= V_PHSYNC;
++ else
++ current->Flags |= V_NHSYNC;
++
++ if(SiS_PlasmaMode[l].SyncFlags & SIS_PL_VSYNCP)
++ current->Flags |= V_PVSYNC;
++ else
++ current->Flags |= V_NVSYNC;
++
++ if(current->HDisplay > pSiS->LCDwidth)
++ pSiS->LCDwidth = pSiS->SiS_Pr->CP_MaxX = current->HDisplay;
++ if(current->VDisplay > pSiS->LCDheight)
++ pSiS->LCDheight = pSiS->SiS_Pr->CP_MaxY = current->VDisplay;
++
++ }
++ done = TRUE;
++ break;
++ }
++ }
++ }
++
++ i++;
++
++ }
++
++ if(pSiS->SiS_Pr->CP_HaveCustomData) {
++
++ for(i=0; i<7; i++) {
++
++ if(pSiS->SiS_Pr->CP_DataValid[i]) {
++
++ if(!(new = xalloc(sizeof(DisplayModeRec)))) return first;
++
++ memset(new, 0, sizeof(DisplayModeRec));
++ if(!(new->name = xalloc(10))) {
++ xfree(new);
++ return first;
++ }
++ if(!first) first = new;
++ if(current) {
++ current->next = new;
++ new->prev = current;
++ }
++
++ current = new;
++
++ sprintf(current->name, "%dx%d", pSiS->SiS_Pr->CP_HDisplay[i],
++ pSiS->SiS_Pr->CP_VDisplay[i]);
++
++ current->status = MODE_OK;
++
++ current->type = M_T_BUILTIN;
++
++ current->Clock = pSiS->SiS_Pr->CP_Clock[i];
++ current->SynthClock = current->Clock;
++
++ current->HDisplay = pSiS->SiS_Pr->CP_HDisplay[i];
++ current->HSyncStart = pSiS->SiS_Pr->CP_HSyncStart[i];
++ current->HSyncEnd = pSiS->SiS_Pr->CP_HSyncEnd[i];
++ current->HTotal = pSiS->SiS_Pr->CP_HTotal[i];
++
++ current->VDisplay = pSiS->SiS_Pr->CP_VDisplay[i];
++ current->VSyncStart = pSiS->SiS_Pr->CP_VSyncStart[i];
++ current->VSyncEnd = pSiS->SiS_Pr->CP_VSyncEnd[i];
++ current->VTotal = pSiS->SiS_Pr->CP_VTotal[i];
++
++ current->CrtcHDisplay = current->HDisplay;
++ current->CrtcHBlankStart = pSiS->SiS_Pr->CP_HBlankStart[i];
++ current->CrtcHSyncStart = current->HSyncStart;
++ current->CrtcHSyncEnd = current->HSyncEnd;
++ current->CrtcHBlankEnd = pSiS->SiS_Pr->CP_HBlankEnd[i];
++ current->CrtcHTotal = current->HTotal;
++
++ current->CrtcVDisplay = current->VDisplay;
++ current->CrtcVBlankStart = pSiS->SiS_Pr->CP_VBlankStart[i];
++ current->CrtcVSyncStart = current->VSyncStart;
++ current->CrtcVSyncEnd = current->VSyncEnd;
++ current->CrtcVBlankEnd = pSiS->SiS_Pr->CP_VBlankEnd[i];
++ current->CrtcVTotal = current->VTotal;
++
++ if(pSiS->SiS_Pr->CP_SyncValid[i]) {
++ if(pSiS->SiS_Pr->CP_HSync_P[i])
++ current->Flags |= V_PHSYNC;
++ else
++ current->Flags |= V_NHSYNC;
++
++ if(pSiS->SiS_Pr->CP_VSync_P[i])
++ current->Flags |= V_PVSYNC;
++ else
++ current->Flags |= V_NVSYNC;
++ } else {
++ /* No sync data? Use positive sync... */
++ current->Flags |= V_PHSYNC;
++ current->Flags |= V_PVSYNC;
++ }
++ }
++ }
++ }
++
+ return first;
+
+ }
+@@ -5486,25 +5897,25 @@
+ UCHAR *ROMAddr = HwDeviceExtension->pjVirtualRomBase;
+ ULONG temp = 0;
+ int Clock;
+-
++
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ #ifdef SIS300
+ InitTo300Pointer(SiS_Pr, HwDeviceExtension);
+ #else
+- return 65;
++ return 65 * 1000 * 1000;
+ #endif
+ } else {
+ #ifdef SIS315H
+ InitTo310Pointer(SiS_Pr, HwDeviceExtension);
+ #else
+- return 65;
++ return 65 * 1000 * 1000;
+ #endif
+ }
+-
++
+ temp = SiS_SearchModeID(SiS_Pr, ROMAddr, &ModeNo, &ModeIdIndex);
+ if(!temp) {
+ printk(KERN_ERR "Could not find mode %x\n", ModeNo);
+- return 65;
++ return 65 * 1000 * 1000;
+ }
+
+ RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
+@@ -5518,6 +5929,56 @@
+ return(Clock);
+ }
+
++BOOLEAN
++sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
++ unsigned char modeno, int *htotal, int *vtotal, unsigned char rateindex)
++{
++ USHORT ModeNo = modeno;
++ USHORT ModeIdIndex = 0, CRT1Index = 0;
++ USHORT RefreshRateTableIndex = 0;
++ UCHAR *ROMAddr = HwDeviceExtension->pjVirtualRomBase;
++ ULONG temp = 0;
++ unsigned char sr_data, cr_data, cr_data2;
++
++ if(HwDeviceExtension->jChipType < SIS_315H) {
++#ifdef SIS300
++ InitTo300Pointer(SiS_Pr, HwDeviceExtension);
++#else
++ return FALSE;
++#endif
++ } else {
++#ifdef SIS315H
++ InitTo310Pointer(SiS_Pr, HwDeviceExtension);
++#else
++ return FALSE;
++#endif
++ }
++
++ temp = SiS_SearchModeID(SiS_Pr, ROMAddr, &ModeNo, &ModeIdIndex);
++ if(!temp) return FALSE;
++
++ RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
++ RefreshRateTableIndex += (rateindex - 1);
++ CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
++
++ sr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
++ cr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[0];
++ *htotal = (((cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8)) + 5) * 8;
++
++ sr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
++ cr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[6];
++ cr_data2 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
++ *vtotal = ((cr_data & 0xFF) |
++ ((unsigned short)(cr_data2 & 0x01) << 8) |
++ ((unsigned short)(cr_data2 & 0x20) << 4) |
++ ((unsigned short)(sr_data & 0x01) << 10)) + 2;
++
++ if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & InterlaceMode)
++ *vtotal *= 2;
++
++ return TRUE;
++}
++
+ int
+ sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ unsigned char modeno, unsigned char rateindex,
+@@ -5606,17 +6067,32 @@
+ C = (temp > 0) ? temp : (temp + 64);
+
+ D = B - F - C;
+-
+- *left_margin = D * 8;
+- *right_margin = F * 8;
+- *hsync_len = C * 8;
++
++ if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes == 320) &&
++ ((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes == 200) ||
++ (SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes == 240))) {
++
++ /* Terrible hack, but the correct CRTC data for
++ * these modes only produces a black screen...
++ */
++ *left_margin = (400 - 376);
++ *right_margin = (328 - 320);
++ *hsync_len = (376 - 328);
++
++ } else {
++
++ *left_margin = D * 8;
++ *right_margin = F * 8;
++ *hsync_len = C * 8;
++
++ }
+
+ sr_data = SiS_Pr->SiS_CRT1Table[index].CR[13];
+
+ cr_data = SiS_Pr->SiS_CRT1Table[index].CR[6];
+-
++
+ cr_data2 = SiS_Pr->SiS_CRT1Table[index].CR[7];
+-
++
+ /* Vertical total */
+ VT = (cr_data & 0xFF) |
+ ((unsigned short) (cr_data2 & 0x01) << 8) |
+@@ -5699,19 +6175,19 @@
+ j++;
+ }
+ }
+-
+-#if 0 /* That's bullshit, only the resolution needs to be shifted */
++
+ if((*vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
++#if 0 /* Do this? */
+ *upper_margin <<= 1;
+ *lower_margin <<= 1;
+ *vsync_len <<= 1;
++#endif
+ } else if((*vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+ *upper_margin >>= 1;
+ *lower_margin >>= 1;
+ *vsync_len >>= 1;
+- }
+-#endif
+-
++ }
++
+ return 1;
+ }
+
+Index: linux-2.6.0-test5/drivers/video/sis/initdef.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/sis/initdef.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/sis/initdef.h 2003-09-27 11:38:35.183179728 +0800
+@@ -1,5 +1,37 @@
+ /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/initdef.h,v 1.4 2000/12/02 01:16:17 dawes Exp $ */
+-
++/*
++ * Global definitions for init.c and init301.c
++ *
++ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
++ *
++ * If distributed as part of the linux kernel, the contents of this file
++ * is entirely covered by the GPL.
++ *
++ * Otherwise, the following terms apply:
++ *
++ * Permission to use, copy, modify, distribute, and sell this software and its
++ * documentation for any purpose is hereby granted without fee, provided that
++ * the above copyright notice appear in all copies and that both that
++ * copyright notice and this permission notice appear in supporting
++ * documentation, and that the name of the copyright holder not be used in
++ * advertising or publicity pertaining to distribution of the software without
++ * specific, written prior permission. The copyright holder makes no representations
++ * about the suitability of this software for any purpose. It is provided
++ * "as is" without express or implied warranty.
++ *
++ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
++ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
++ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
++ * PERFORMANCE OF THIS SOFTWARE.
++ *
++ * Author: Thomas Winischhofer <thomas@winischhofer.net>
++ *
++ * Based on code by Silicon Intergrated Systems
++ *
++ */
+
+ #ifndef _INITDEF_
+ #define _INITDEF_
+@@ -22,12 +54,19 @@
+ #define VB_SIS301B302B (VB_SIS301B|VB_SIS302B)
+ #define VB_SIS301LV302LV (VB_SIS301LV|VB_SIS302LV)
+
+-#define IS_SIS650740 ((HwDeviceExtension->jChipType >= SIS_650) && (HwDeviceExtension->jChipType < SIS_330))
+-
+ #define IS_SIS650 (HwDeviceExtension->jChipType == SIS_650)
+ #define IS_SIS740 (HwDeviceExtension->jChipType == SIS_740)
+ #define IS_SIS330 (HwDeviceExtension->jChipType == SIS_330)
+ #define IS_SIS550 (HwDeviceExtension->jChipType == SIS_550)
++#define IS_SIS651 (SiS_Pr->SiS_SysFlags & (SF_Is651 | SF_Is652))
++#define IS_SISM650 (SiS_Pr->SiS_SysFlags & (SF_IsM650 | SF_IsM652 | SF_IsM653))
++#define IS_SIS65x (IS_SIS651 || IS_SISM650)
++#define IS_SIS660 (HwDeviceExtension->jChipType == SIS_660)
++#define IS_SIS760 (HwDeviceExtension->jChipType == SIS_760)
++#define IS_SIS650660 (IS_SIS650 || IS_SIS660)
++#define IS_SIS650740 ((HwDeviceExtension->jChipType >= SIS_650) && (HwDeviceExtension->jChipType < SIS_330))
++#define IS_SIS650740660 (IS_SIS650 || IS_SIS660 || IS_SIS740 || IS_SIS760)
++#define IS_SIS550650740660 (IS_SIS550 || IS_SIS650 || IS_SIS660 || IS_SIS740 || IS_SIS760)
+
+ #define CRT1Len 17
+ #define LVDSCRT1Len 15
+@@ -63,7 +102,7 @@
+ #define SupportTV 0x0008
+ #define SupportHiVisionTV 0x0010
+ #define SupportLCD 0x0020
+-#define SupportRAMDAC2 0x0040
++#define SupportRAMDAC2 0x0040
+ #define NoSupportTV 0x0070
+ #define NoSupportHiVisionTV 0x0060
+ #define NoSupportLCD 0x0058
+@@ -105,6 +144,24 @@
+ #define HotKeySwitch 0x8000 /* TW: ? */
+ #define SetCRT2ToLCDA 0x8000
+
++/* SetFlag */
++#define ProgrammingCRT2 0x01
++#define TVSimuMode 0x02
++#define RPLLDIV2XO 0x04
++#define LCDVESATiming 0x08
++#define EnableLVDSDDA 0x10
++#define SetDispDevSwitchFlag 0x20
++#define CheckWinDos 0x40
++#define SetDOSMode 0x80
++
++/* SysFlags */
++#define SF_Is651 0x0001
++#define SF_IsM650 0x0002
++#define SF_Is652 0x0004
++#define SF_IsM652 0x0008
++#define SF_IsM653 0x0010
++#define SF_Is660 0x8000
++
+ #define PanelRGB18Bit 0x0100
+ #define PanelRGB24Bit 0x0000
+
+@@ -112,7 +169,7 @@
+ #define TVOverScanShift 4
+ #define ClearBufferFlag 0x20
+
+-/* CR32 (Newer 630, and 310/325 series)
++/* CR32 (Newer 630, and 315 series)
+
+ [0] VB connected with CVBS
+ [1] VB connected with SVHS
+@@ -134,7 +191,7 @@
+ 011 LVDS + Tumpion Zurac
+ 100 LVDS + Chrontel 7005
+ 110 Chrontel 7005
+- 310/325 series
++ 315 series
+ 001 SiS30x (never seen)
+ 010 LVDS
+ 011 LVDS + Chrontel 7019
+@@ -163,14 +220,15 @@
+ #define LCDSyncBit 0x00e0
+ #define LCDSyncShift 6
+
+-/* CR38 (310/325 series) */
++/* CR38 (315 series) */
+ #define EnableDualEdge 0x01
+ #define SetToLCDA 0x02 /* LCD channel A (302B/LV and 650+LVDS only) */
+ #define EnableSiSHiVision 0x04 /* HiVision (HDTV) on SiS bridge */
+ #define EnableLVDSScart 0x04 /* Scart on Ch7019 (unofficial definition - TW) */
+ #define EnableLVDSHiVision 0x08 /* YPbPr color format (480i HDTV); only on 650/Ch7019 systems */
+-#define SiSHiVision1 0x10 /* See SetHiVision() */
+-#define SiSHiVision2 0x20
++#define EnableHiVision750 0x08 /* Enable 750P HiVision mode (30xLV only) */
++#define EnableHiVision525 0x10 /* Enable 525P HiVision mode (30xLV only) */
++#define SiSHiVision2 0x20 /* ? - | --- mask 0x38 combinations have different meaning! */
+ #define EnablePALM 0x40 /* 1 = Set PALM */
+ #define EnablePALN 0x80 /* 1 = Set PALN */
+
+@@ -184,7 +242,7 @@
+ #define Enable302LV_DualLink 0x04 /* 30xNEW (302LV) only; set by mode switching function */
+
+
+-/* CR79 (310/325 series only)
++/* CR79 (315 series only)
+ [3-0] Notify driver
+ 0001 Mode Switch event (set by BIOS)
+ 0010 Epansion On/Off event
+@@ -202,16 +260,6 @@
+ [7] TV UnderScan/OverScan (set by BIOS)
+ */
+
+-/* SetFlag */
+-#define ProgrammingCRT2 0x01
+-#define TVSimuMode 0x02
+-#define RPLLDIV2XO 0x04
+-#define LCDVESATiming 0x08
+-#define EnableLVDSDDA 0x10
+-#define SetDispDevSwitchFlag 0x20
+-#define CheckWinDos 0x40
+-#define SetDOSMode 0x80
+-
+ /* LCDResInfo */
+ #define Panel300_800x600 0x01 /* CR36 */
+ #define Panel300_1024x768 0x02
+@@ -220,7 +268,10 @@
+ #define Panel300_640x480 0x05
+ #define Panel300_1024x600 0x06
+ #define Panel300_1152x768 0x07
+-#define Panel300_320x480 0x08 /* fstn - TW: This is fake, can be any */
++#define Panel300_1280x768 0x0a
++#define Panel300_320x480 0x0e /* fstn - TW: This is fake, can be any */
++#define Panel300_Custom 0x0f
++#define Panel300_Barco1366 0x10
+
+ #define Panel310_800x600 0x01
+ #define Panel310_1024x768 0x02
+@@ -231,9 +282,12 @@
+ #define Panel310_1280x960 0x07
+ #define Panel310_1152x768 0x08 /* LVDS only */
+ #define Panel310_1400x1050 0x09
+-#define Panel310_1280x768 0x0a /* LVDS only */
++#define Panel310_1280x768 0x0a
+ #define Panel310_1600x1200 0x0b
+-#define Panel310_320x480 0x0c /* fstn - TW: This is fake, can be any */
++#define Panel310_640x480_2 0x0c
++#define Panel310_640x480_3 0x0d
++#define Panel310_320x480 0x0e /* fstn - TW: This is fake, can be any */
++#define Panel310_Custom 0x0f
+
+ #define Panel_800x600 0x01 /* Unified values */
+ #define Panel_1024x768 0x02
+@@ -246,7 +300,43 @@
+ #define Panel_1400x1050 0x09
+ #define Panel_1280x768 0x0a /* LVDS only */
+ #define Panel_1600x1200 0x0b
+-#define Panel_320x480 0x0c /* fstn - TW: This is fake, can be any */
++#define Panel_640x480_2 0x0c
++#define Panel_640x480_3 0x0d
++#define Panel_320x480 0x0e /* fstn - TW: This is fake, can be any */
++#define Panel_Custom 0x0f
++#define Panel_Barco1366 0x10
++#define Panel_848x480 0x11
++
++/* Index in ModeResInfo table */
++#define SIS_RI_320x200 0
++#define SIS_RI_320x240 1
++#define SIS_RI_320x400 2
++#define SIS_RI_400x300 3
++#define SIS_RI_512x384 4
++#define SIS_RI_640x400 5
++#define SIS_RI_640x480 6
++#define SIS_RI_800x600 7
++#define SIS_RI_1024x768 8
++#define SIS_RI_1280x1024 9
++#define SIS_RI_1600x1200 10
++#define SIS_RI_1920x1440 11
++#define SIS_RI_2048x1536 12
++#define SIS_RI_720x480 13
++#define SIS_RI_720x576 14
++#define SIS_RI_1280x960 15
++#define SIS_RI_800x480 16
++#define SIS_RI_1024x576 17
++#define SIS_RI_1280x720 18
++#define SIS_RI_856x480 19
++#define SIS_RI_1280x768 20
++#define SIS_RI_1400x1050 21
++#define SIS_RI_1152x864 22
++#define SIS_RI_848x480 23
++#define SIS_RI_1360x768 24
++#define SIS_RI_1024x600 25
++#define SIS_RI_1152x768 26
++#define SIS_RI_768x576 27
++#define SIS_RI_1360x1024 28
+
+ #define ExtChipType 0x0e
+ #define ExtChip301 0x02
+@@ -278,15 +368,34 @@
+ #define VCLKStartFreq 25
+ #define SoftDramType 0x80
+
+-#define VCLK40 0x04 /* Index in VCLKData array */
+-#define VCLK65 0x09 /* Index in VCLKData array */
+-#define VCLK108_2 0x14 /* Index in VCLKData array */
+-#define TVVCLKDIV2 0x21 /* Indices in (VB)VCLKData arrays */
+-#define TVVCLK 0x22
+-#define HiTVVCLKDIV2 0x23
+-#define HiTVVCLK 0x24
+-#define HiTVSimuVCLK 0x25
+-#define HiTVTextVCLK 0x26
++/* Indices in (VB)VCLKData tables */
++
++#define VCLK28 0x00 /* Index in VCLKData table (300 and 315) */
++#define VCLK40 0x04 /* Index in VCLKData table (300 and 315) */
++#define VCLK65_300 0x09 /* Index in VCLKData table (300) */
++#define VCLK108_2_300 0x14 /* Index in VCLKData table (300) */
++#define VCLK81_300 0x3f /* Index in VCLKData table (300) */
++#define VCLK108_3_300 0x42 /* Index in VCLKData table (300) */
++#define VCLK100_300 0x43 /* Index in VCLKData table (300) */
++#define VCLK34_300 0x3d /* Index in VCLKData table (300) */
++#define VCLK65_315 0x0b /* Index in (VB)VCLKData table (315) */
++#define VCLK108_2_315 0x19 /* Index in (VB)VCLKData table (315) */
++#define VCLK81_315 0x5b /* Index in (VB)VCLKData table (315) */
++#define VCLK162_315 0x21 /* Index in (VB)VCLKData table (315) */
++#define VCLK108_3_315 0x45 /* Index in VBVCLKData table (315) */
++#define VCLK100_315 0x46 /* Index in VBVCLKData table (315) */
++#define VCLK34_315 0x55 /* Index in VBVCLKData table (315) */
++
++#define TVCLKBASE_300 0x21 /* Indices on TV clocks in VCLKData table (300) */
++#define TVCLKBASE_315 0x3a /* Indices on TV clocks in (VB)VCLKData table (315) */
++#define TVVCLKDIV2 0x00 /* Index relative to TVCLKBASE */
++#define TVVCLK 0x01 /* Index relative to TVCLKBASE */
++#define HiTVVCLKDIV2 0x02 /* Index relative to TVCLKBASE */
++#define HiTVVCLK 0x03 /* Index relative to TVCLKBASE */
++#define HiTVSimuVCLK 0x04 /* Index relative to TVCLKBASE */
++#define HiTVTextVCLK 0x05 /* Index relative to TVCLKBASE */
++
++/* ------------------------------ */
+
+ #define LoadDACFlag 0x1000
+ #define AfterLockCRT2 0x4000
+@@ -306,6 +415,8 @@
+ #define HotPlugFunction 0x08
+ #define StStructSize 0x06
+
++#define SIS_VIDEO_CAPTURE 0x00 - 0x30
++#define SIS_VIDEO_PLAYBACK 0x02 - 0x30
+ #define SIS_CRT2_PORT_04 0x04 - 0x30
+ #define SIS_CRT2_PORT_10 0x10 - 0x30
+ #define SIS_CRT2_PORT_12 0x12 - 0x30
+@@ -393,7 +504,7 @@
+
+ /*
+ =============================================================
+- for 310/325 series
++ for 315 series
+ =============================================================
+ */
+ #define SoftDRAMType 0x80
+Index: linux-2.6.0-test5/drivers/video/sis/init.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/sis/init.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/sis/init.h 2003-09-27 11:38:35.204176536 +0800
+@@ -1,19 +1,47 @@
++/* $XFree86$ */
++/*
++ * Data and prototypes for init.c
++ *
++ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
++ *
++ * If distributed as part of the linux kernel, the contents of this file
++ * is entirely covered by the GPL.
++ *
++ * Otherwise, the following terms apply:
++ *
++ * Permission to use, copy, modify, distribute, and sell this software and its
++ * documentation for any purpose is hereby granted without fee, provided that
++ * the above copyright notice appear in all copies and that both that
++ * copyright notice and this permission notice appear in supporting
++ * documentation, and that the name of the copyright holder not be used in
++ * advertising or publicity pertaining to distribution of the software without
++ * specific, written prior permission. The copyright holder makes no representations
++ * about the suitability of this software for any purpose. It is provided
++ * "as is" without express or implied warranty.
++ *
++ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
++ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
++ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
++ * PERFORMANCE OF THIS SOFTWARE.
++ *
++ * Author: Thomas Winischhofer <thomas@winischhofer.net>
++ *
++ * Based on code by Silicon Intergrated Systems
++ *
++ */
++
+ #ifndef _INIT_
+ #define _INIT_
+
+ #include "osdef.h"
++
+ #include "initdef.h"
+ #include "vgatypes.h"
+ #include "vstruct.h"
+
+-#ifdef TC
+-#include <stdio.h>
+-#include <string.h>
+-#include <conio.h>
+-#include <dos.h>
+-#include <stdlib.h>
+-#endif
+-
+ #ifdef LINUX_XF86
+ #include "xf86.h"
+ #include "xf86Pci.h"
+@@ -24,6 +52,9 @@
+ #endif
+
+ #ifdef LINUX_KERNEL
++#ifdef SIS_CP
++#undef SIS_CP
++#endif
+ #include <linux/config.h>
+ #include <linux/version.h>
+ #include <linux/types.h>
+@@ -36,19 +67,6 @@
+ #endif
+ #endif
+
+-#ifdef WIN2000
+-#include <stdio.h>
+-#include <string.h>
+-#include <miniport.h>
+-#include "dderror.h"
+-#include "devioctl.h"
+-#include "miniport.h"
+-#include "ntddvdeo.h"
+-#include "video.h"
+-#include "sisv.h"
+-#include "tools.h"
+-#endif
+-
+ const USHORT SiS_DRAMType[17][5]={
+ {0x0C,0x0A,0x02,0x40,0x39},
+ {0x0D,0x0A,0x01,0x40,0x48},
+@@ -144,6 +162,2227 @@
+ 0x0B,0x0C,0x0D,0x0F,0x10
+ };
+
++static const SiS_StResInfoStruct SiS_StResInfo[]=
++{
++ { 640,400},
++ { 640,350},
++ { 720,400},
++ { 720,350},
++ { 640,480}
++};
++
++static const SiS_ModeResInfoStruct SiS_ModeResInfo[] =
++{
++ { 320, 200, 8, 8}, /* 0x00 */
++ { 320, 240, 8, 8}, /* 0x01 */
++ { 320, 400, 8, 8}, /* 0x02 */
++ { 400, 300, 8, 8}, /* 0x03 */
++ { 512, 384, 8, 8}, /* 0x04 */
++ { 640, 400, 8,16}, /* 0x05 */
++ { 640, 480, 8,16}, /* 0x06 */
++ { 800, 600, 8,16}, /* 0x07 */
++ { 1024, 768, 8,16}, /* 0x08 */
++ { 1280,1024, 8,16}, /* 0x09 */
++ { 1600,1200, 8,16}, /* 0x0a */
++ { 1920,1440, 8,16}, /* 0x0b */
++ { 2048,1536, 8,16}, /* 0x0c */
++ { 720, 480, 8,16}, /* 0x0d */
++ { 720, 576, 8,16}, /* 0x0e */
++ { 1280, 960, 8,16}, /* 0x0f */
++ { 800, 480, 8,16}, /* 0x10 */
++ { 1024, 576, 8,16}, /* 0x11 */
++ { 1280, 720, 8,16}, /* 0x12 */
++ { 856, 480, 8,16}, /* 0x13 */
++ { 1280, 768, 8,16}, /* 0x14 */
++ { 1400,1050, 8,16}, /* 0x15 */
++ { 1152, 864, 8,16}, /* 0x16 */
++ { 848, 480, 8,16}, /* 0x17 */
++ { 1360, 768, 8,16}, /* 0x18 */
++ { 1024, 600, 8,16}, /* 0x19 */
++ { 1152, 768, 8,16}, /* 0x1a */
++ { 768, 576, 8,16}, /* 0x1b */
++ { 1360,1024, 8,16} /* 0x1c */
++};
++
++static SiS_StandTableStruct SiS_StandTable[]=
++{
++/* 0x00: MD_0_200 */
++ {
++ 0x28,0x18,0x08,0x0800,
++ {0x09,0x03,0x00,0x02},
++ 0x63,
++ {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
++ 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
++ 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
++ 0xff},
++ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
++ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
++ 0x08,0x00,0x0f,0x00},
++ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
++ 0xff}
++ },
++/* 0x01: MD_1_200 */
++ {
++ 0x28,0x18,0x08,0x0800,
++ {0x09,0x03,0x00,0x02},
++ 0x63,
++ {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
++ 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
++ 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
++ 0xff},
++ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
++ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
++ 0x08,0x00,0x0f,0x00},
++ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
++ 0xff}
++ },
++/* 0x02: MD_2_200 */
++ {
++ 0x50,0x18,0x08,0x1000,
++ {0x01,0x03,0x00,0x02},
++ 0x63,
++ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
++ 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
++ 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
++ 0xff},
++ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
++ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
++ 0x08,0x00,0x0f,0x00},
++ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
++ 0xff}
++ },
++/* 0x03: MD_3_200 - mode 0x03 - 0 */
++ {
++ 0x50,0x18,0x08,0x1000,
++ {0x01,0x03,0x00,0x02},
++ 0x63,
++ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
++ 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
++ 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
++ 0xff},
++ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
++ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
++ 0x08,0x00,0x0f,0x00},
++ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
++ 0xff}
++ },
++/* 0x04: MD_4 */
++ {
++ 0x28,0x18,0x08,0x4000,
++ {0x09,0x03,0x00,0x02},
++ 0x63,
++ {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f, /* 0x2c is 2b for 300 */
++ 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
++ 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
++ 0xff},
++ {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
++ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
++ 0x01,0x00,0x03,0x00},
++ {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
++ 0xff}
++ },
++/* 0x05: MD_5 */
++ {
++ 0x28,0x18,0x08,0x4000,
++ {0x09,0x03,0x00,0x02},
++ 0x63,
++ {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f, /* 0x2c is 2b for 300 */
++ 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
++ 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
++ 0xff},
++ {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
++ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
++ 0x01,0x00,0x03,0x00},
++ {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
++ 0xff}
++ },
++/* 0x06: MD_6 */
++ {
++ 0x50,0x18,0x08,0x4000,
++ {0x01,0x01,0x00,0x06},
++ 0x63,
++ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, /* 55,81 is 54,80 for 300 */
++ 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
++ 0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xc2,
++ 0xff},
++ {0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
++ 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
++ 0x01,0x00,0x01,0x00},
++ {0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00,
++ 0xff}
++ },
++/* 0x07: MD_7 */
++ {
++ 0x50,0x18,0x0e,0x1000,
++ {0x00,0x03,0x00,0x03},
++ 0xa6,
++ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
++ 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
++ 0x83,0x85,0x5d,0x28,0x0d,0x63,0xba,0xa3,
++ 0xff},
++ {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
++ 0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
++ 0x0e,0x00,0x0f,0x08},
++ {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
++ 0xff}
++ },
++/* 0x08: MDA_DAC */
++ {
++ 0x00,0x00,0x00,0x0000,
++ {0x00,0x00,0x00,0x15},
++ 0x15,
++ {0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
++ 0x15,0x15,0x15,0x15,0x15,0x15,0x3f,0x3f,
++ 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00,
++ 0x00},
++ {0x00,0x00,0x00,0x00,0x00,0x15,0x15,0x15,
++ 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
++ 0x15,0x15,0x15,0x15},
++ {0x15,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
++ 0x3f}
++ },
++/* 0x09: CGA_DAC */
++ {
++ 0x00,0x10,0x04,0x0114,
++ {0x11,0x09,0x15,0x00},
++ 0x10,
++ {0x04,0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,
++ 0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x2a,0x3a,
++ 0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x10,
++ 0x04},
++ {0x14,0x01,0x11,0x09,0x15,0x00,0x10,0x04,
++ 0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,0x2e,
++ 0x3e,0x2b,0x3b,0x2f},
++ {0x3f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
++ 0x3f}
++ },
++/* 0x0a: EGA_DAC */
++ {
++ 0x00,0x10,0x04,0x0114,
++ {0x11,0x05,0x15,0x20},
++ 0x30,
++ {0x24,0x34,0x21,0x31,0x25,0x35,0x08,0x18,
++ 0x0c,0x1c,0x09,0x19,0x0d,0x1d,0x28,0x38,
++ 0x2c,0x3c,0x29,0x39,0x2d,0x3d,0x02,0x12,
++ 0x06},
++ {0x16,0x03,0x13,0x07,0x17,0x22,0x32,0x26,
++ 0x36,0x23,0x33,0x27,0x37,0x0a,0x1a,0x0e,
++ 0x1e,0x0b,0x1b,0x0f},
++ {0x1f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
++ 0x3f}
++ },
++/* 0x0b: VGA_DAC */
++ {
++ 0x00,0x10,0x04,0x0114,
++ {0x11,0x09,0x15,0x2a},
++ 0x3a,
++ {0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x05,
++ 0x08,0x0b,0x0e,0x11,0x14,0x18,0x1c,0x20,
++ 0x24,0x28,0x2d,0x32,0x38,0x3f,0x00,0x10,
++ 0x1f},
++ {0x2f,0x3f,0x1f,0x27,0x2f,0x37,0x3f,0x2d,
++ 0x31,0x36,0x3a,0x3f,0x00,0x07,0x0e,0x15,
++ 0x1c,0x0e,0x11,0x15},
++ {0x18,0x1c,0x14,0x16,0x18,0x1a,0x1c,0x00,
++ 0x04}
++ },
++/* 0x0c */
++ {
++ 0x08,0x0c,0x10,0x0a08,
++ {0x0c,0x0e,0x10,0x0b},
++ 0x0c,
++ {0x0d,0x0f,0x10,0x10,0x01,0x08,0x00,0x00,
++ 0x00,0x00,0x01,0x00,0x02,0x02,0x01,0x00,
++ 0x04,0x04,0x01,0x00,0x05,0x02,0x05,0x00,
++ 0x06},
++ {0x01,0x06,0x05,0x06,0x00,0x08,0x01,0x08,
++ 0x00,0x07,0x02,0x07,0x06,0x07,0x00,0x00,
++ 0x00,0x00,0x00,0x00},
++ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++ 0x00}
++ },
++/* 0x0d: MD_D */
++ {
++ 0x28,0x18,0x08,0x2000,
++ {0x09,0x0f,0x00,0x06},
++ 0x63,
++ {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f, /* 2c is 2b for 300 */
++ 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
++ 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xe3,
++ 0xff},
++ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
++ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
++ 0x01,0x00,0x0f,0x00},
++ {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
++ 0xff}
++ },
++/* 0x0e: MD_E */
++ {
++ 0x50,0x18,0x08,0x4000,
++ {0x01,0x0f,0x00,0x06},
++ 0x63,
++ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, /* 55,81 is 54,80 for 300 */
++ 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
++ 0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xe3,
++ 0xff},
++ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
++ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
++ 0x01,0x00,0x0f,0x00},
++ {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
++ 0xff}
++ },
++/* 0x0f: ExtVGATable - modes > 0x13 */
++ {
++ 0x00,0x00,0x00,0x0000,
++ {0x01,0x0f,0x00,0x0e},
++ 0x23,
++ {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
++ 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
++ 0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3,
++ 0xff},
++ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
++ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
++ 0x01,0x00,0x00,0x00},
++ {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
++ 0xff}
++ },
++/* 0x10: ROM_SAVEPTR - totally different for 300 */
++ {
++ 0x9f,0x3b,0x00,0x00c0,
++ {0x00,0x00,0x00,0x00},
++ 0x00,
++ {0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x3f,
++ 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
++ 0x00,0x00,0x1a,0x00,0xac,0x3e,0x00,0xc0,
++ 0x00},
++ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++ 0x00,0x00,0x00,0x00},
++ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++ 0x00}
++ },
++/* 0x11: MD_F */
++ {
++ 0x50,0x18,0x0e,0x8000,
++ {0x01,0x0f,0x00,0x06},
++ 0xa2,
++ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, /* 55,81 is 54,80 on 300 */
++ 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
++ 0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3, /* 82,84 is 83,85 on 300 */
++ 0xff},
++ {0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00,
++ 0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00,
++ 0x0b,0x00,0x05,0x00},
++ {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x05,
++ 0xff}
++ },
++/* 0x12: MD_10 */
++ {
++ 0x50,0x18,0x0e,0x8000,
++ {0x01,0x0f,0x00,0x06},
++ 0xa3,
++ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, /* 55,81 is 54,80 on 300 */
++ 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
++ 0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3, /* 82,84 is 83,85 on 300 */
++ 0xff},
++ {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
++ 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
++ 0x01,0x00,0x0f,0x00},
++ {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
++ 0xff}
++ },
++/* 0x13: MD_0_350 */
++ {
++ 0x28,0x18,0x0e,0x0800,
++ {0x09,0x03,0x00,0x02},
++ 0xa3,
++ {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f, /* b1 is a0 on 300 */
++ 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
++ 0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
++ 0xff},
++ {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
++ 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
++ 0x08,0x00,0x0f,0x00},
++ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
++ 0xff}
++ },
++/* 0x14: MD_1_350 */
++ {
++ 0x28,0x18,0x0e,0x0800,
++ {0x09,0x03,0x00,0x02},
++ 0xa3,
++ {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
++ 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
++ 0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
++ 0xff},
++ {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
++ 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
++ 0x08,0x00,0x0f,0x00},
++ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
++ 0xff}
++ },
++/* 0x15: MD_2_350 */
++ {
++ 0x50,0x18,0x0e,0x1000,
++ {0x01,0x03,0x00,0x02},
++ 0xa3,
++ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
++ 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
++ 0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
++ 0xff},
++ {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
++ 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
++ 0x08,0x00,0x0f,0x00},
++ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
++ 0xff}
++ },
++/* 0x16: MD_3_350 - mode 0x03 - 1 */
++ {
++ 0x50,0x18,0x0e,0x1000,
++ {0x01,0x03,0x00,0x02},
++ 0xa3,
++ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
++ 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
++ 0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
++ 0xff},
++ {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
++ 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
++ 0x08,0x00,0x0f,0x00},
++ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
++ 0xff}
++ },
++/* 0x17: MD_0_1_400 */
++ {
++ 0x28,0x18,0x10,0x0800,
++ {0x08,0x03,0x00,0x02},
++ 0x67,
++ {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f, /* b1 is a0 on 300 */
++ 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
++ 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
++ 0xff},
++ {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
++ 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
++ 0x0c,0x00,0x0f,0x08},
++ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
++ 0xff}
++ },
++/* 0x18: MD_2_3_400 - mode 0x03 - 2 */
++ {
++ 0x50,0x18,0x10,0x1000,
++ {0x00,0x03,0x00,0x02},
++ 0x67,
++ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
++ 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
++ 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
++ 0xff},
++ {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
++ 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
++ 0x0c,0x00,0x0f,0x08},
++ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
++ 0xff}
++ },
++/* 0x19: MD_7_400 */
++ {
++ 0x50,0x18,0x10,0x1000,
++ {0x00,0x03,0x00,0x02},
++ 0x66,
++ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
++ 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
++ 0x9c,0x8e,0x8f,0x28,0x0f,0x96,0xb9,0xa3,
++ 0xff},
++ {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
++ 0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
++ 0x0e,0x00,0x0f,0x08},
++ {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
++ 0xff}
++ },
++/* 0x1a: MD_11 */
++ {
++ 0x50,0x1d,0x10,0xa000,
++ {0x01,0x0f,0x00,0x06},
++ 0xe3,
++ {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e, /* 55,81 is 54,80 on 300 */
++ 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
++ 0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xc3, /* e9,8b is ea,8c on 300 */
++ 0xff},
++ {0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
++ 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
++ 0x01,0x00,0x0f,0x00},
++ {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01,
++ 0xff}
++ },
++/* 0x1b: ExtEGATable - Modes <= 0x02 */
++ {
++ 0x50,0x1d,0x10,0xa000,
++ {0x01,0x0f,0x00,0x06},
++ 0xe3,
++ {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e, /* 55,81 is 54,80 on 300 */
++ 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
++ 0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xe3, /* e9,8b is ea,8c on 300 */
++ 0xff},
++ {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
++ 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
++ 0x01,0x00,0x0f,0x00},
++ {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
++ 0xff}
++ },
++/* 0x1c: MD_13 */
++ {
++ 0x28,0x18,0x08,0x2000,
++ {0x01,0x0f,0x00,0x0e},
++ 0x63,
++ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, /* 55,81 is 54,80 on 300 */
++ 0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
++ 0x9c,0x8e,0x8f,0x28,0x40,0x96,0xb9,0xa3,
++ 0xff},
++ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
++ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
++ 0x41,0x00,0x0f,0x00},
++ {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
++ 0xff}
++ }
++};
++
++static const UCHAR SiS_NTSCTiming[] = {
++ 0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
++ 0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
++ 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
++ 0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17,
++ 0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02,
++ 0x03,0x0a,0x65,0x9d,0x08,0x92,0x8f,0x40,
++ 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x50,
++ 0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
++};
++
++static const UCHAR SiS_PALTiming[] = {
++ 0x19,0x52,0x35,0x6e,0x04,0x38,0x3d,0x70,
++ 0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d,
++ 0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b,
++ 0x70,0x50,0x00,0x9b,0x00,0xd9,0x5d,0x17,
++ 0x7d,0x05,0x45,0x00,0x00,0xe8,0x00,0x02,
++ 0x0d,0x00,0x68,0xb0,0x0b,0x92,0x8f,0x40,
++ 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x63,
++ 0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00
++};
++
++static const UCHAR SiS_HiTVExtTiming[] = {
++ 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
++ 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
++ 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
++ 0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
++ 0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
++ 0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
++ 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
++ 0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
++};
++
++static const UCHAR SiS_HiTVSt1Timing[] = {
++ 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
++ 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
++ 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
++ 0x65,0x90,0x7b,0xa8,0x03,0xf0,0x87,0x03,
++ 0x11,0x15,0x11,0xcf,0x10,0x11,0xcf,0x10,
++ 0x35,0x35,0x3b,0x69,0x1d,0x92,0x0f,0x40,
++ 0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x86,
++ 0xaf,0x5d,0x0e,0x00,0xfc,0xff,0x2d,0x00
++};
++
++static const UCHAR SiS_HiTVSt2Timing[] = {
++ 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
++ 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
++ 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
++ 0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
++ 0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
++ 0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
++ 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
++ 0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
++};
++
++static const UCHAR SiS_HiTVTextTiming[] = {
++ 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
++ 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
++ 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
++ 0x65,0x90,0xe7,0xbc,0x03,0x0c,0x97,0x03,
++ 0x14,0x78,0x14,0x08,0x20,0x14,0x08,0x20,
++ 0xc8,0xc8,0x3b,0xd2,0x26,0x92,0x0f,0x40,
++ 0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x96,
++ 0x72,0x5c,0x11,0x00,0xfc,0xff,0x32,0x00
++};
++
++static const UCHAR SiS_HiTVGroup3Data[] = {
++ 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x5f,
++ 0x05,0x21,0xb2,0xb2,0x55,0x77,0x2a,0xa6,
++ 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
++ 0x8c,0x6e,0x60,0x2e,0x58,0x48,0x72,0x44,
++ 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
++ 0x4f,0x7f,0x03,0xa8,0x7d,0x20,0x1a,0xa9,
++ 0x14,0x05,0x03,0x7e,0x64,0x31,0x14,0x75,
++ 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
++};
++
++static const UCHAR SiS_HiTVGroup3Simu[] = {
++ 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x95,
++ 0xdb,0x20,0xb8,0xb8,0x55,0x47,0x2a,0xa6,
++ 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
++ 0x8c,0x6e,0x60,0x15,0x26,0xd3,0xe4,0x11,
++ 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
++ 0x67,0x36,0x01,0x47,0x0e,0x10,0xbe,0xb4,
++ 0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
++ 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
++};
++
++static const UCHAR SiS_HiTVGroup3Text[] = {
++ 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0xa7,
++ 0xf5,0x20,0xce,0xce,0x55,0x47,0x2a,0xa6,
++ 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
++ 0x8c,0x6e,0x60,0x18,0x2c,0x0c,0x20,0x22,
++ 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
++ 0x93,0x3c,0x01,0x50,0x2f,0x10,0xf4,0xca,
++ 0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
++ 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
++};
++
++static const UCHAR SiS_NTSCPhase[] = {0x21,0xed,0xba,0x08}; /* Was {0x21,0xed,0x8a,0x08}; */
++static const UCHAR SiS_PALPhase[] = {0x2a,0x05,0xe3,0x00}; /* Was {0x2a,0x05,0xd3,0x00}; */
++static const UCHAR SiS_PALMPhase[] = {0x21,0xE4,0x2E,0x9B};
++static const UCHAR SiS_PALNPhase[] = {0x21,0xF4,0x3E,0xBA};
++static const UCHAR SiS_NTSCPhase2[] = {0x21,0xF0,0x7B,0xD6};
++static const UCHAR SiS_PALPhase2[] = {0x2a,0x09,0x86,0xe9};
++static const UCHAR SiS_PALMPhase2[] = {0x21,0xE6,0xEF,0xA4};
++static const UCHAR SiS_PALNPhase2[] = {0x21,0xF6,0x94,0x46};
++static const UCHAR SiS_SpecialPhase[] = {0x1e,0x8c,0x5c,0x7a};
++
++static const SiS_TVDataStruct SiS_StPALData[]=
++{
++ { 1, 1, 864, 525,1270, 400, 100, 0, 760,0xf4,0xff,0x1c,0x22},
++ { 1, 1, 864, 525,1270, 350, 100, 0, 760,0xf4,0xff,0x1c,0x22},
++ { 1, 1, 864, 525,1270, 400, 0, 0, 720,0xf1,0x04,0x1f,0x18},
++ { 1, 1, 864, 525,1270, 350, 0, 0, 720,0xf4,0x0b,0x1c,0x0a},
++ { 1, 1, 864, 525,1270, 480, 50, 0, 760,0xf4,0xff,0x1c,0x22},
++ { 1, 1, 864, 525,1270, 600, 50, 0, 0,0xf4,0xff,0x1c,0x22}
++};
++
++static const SiS_TVDataStruct SiS_ExtPALData[] =
++{
++ { 27, 10, 848, 448,1270, 530, 50, 0, 50,0xf4,0xff,0x1c,0x22}, /* 640x400, 320x200 */
++ { 108, 35, 848, 398,1270, 530, 50, 0, 50,0xf4,0xff,0x1c,0x22},
++ { 12, 5, 954, 448,1270, 530, 50, 0, 50,0xf1,0x04,0x1f,0x18},
++ { 9, 4, 960, 463,1644, 438, 50, 0, 50,0xf4,0x0b,0x1c,0x0a},
++ { 9, 4, 848, 528,1270, 530, 0, 0, 50,0xf5,0xfb,0x1b,0x2a}, /* 640x480, 320x240 */
++ { 36, 25,1060, 648,1316, 530, 438, 0, 438,0xeb,0x05,0x25,0x16}, /* 800x600, 400x300 */
++ { 3, 2,1080, 619,1270, 540, 438, 0, 438,0xf3,0x00,0x1d,0x20}, /* 720x576 */
++ { 1, 1,1170, 821,1270, 520, 686, 0, 686,0xF3,0x00,0x1D,0x20} /* 1024x768 */
++};
++
++static const SiS_TVDataStruct SiS_StNTSCData[]=
++{
++ { 1, 1, 858, 525,1270, 400, 50, 0, 760,0xf1,0x04,0x1f,0x18},
++ { 1, 1, 858, 525,1270, 350, 50, 0, 640,0xf1,0x04,0x1f,0x18},
++ { 1, 1, 858, 525,1270, 400, 0, 0, 720,0xf1,0x04,0x1f,0x18},
++ { 1, 1, 858, 525,1270, 350, 0, 0, 720,0xf4,0x0b,0x1c,0x0a},
++ { 1, 1, 858, 525,1270, 480, 0, 0, 760,0xf1,0x04,0x1f,0x18}
++};
++
++static const SiS_TVDataStruct SiS_ExtNTSCData[]=
++{
++ { 143, 65, 858, 443,1270, 440, 171, 0, 171,0xf1,0x04,0x1f,0x18}, /* 640x400, 320x200 */
++ { 88, 35, 858, 393,1270, 440, 171, 0, 171,0xf1,0x04,0x1f,0x18},
++ { 143, 70, 924, 443,1270, 440, 92, 0, 92,0xf1,0x04,0x1f,0x18},
++ { 143, 70, 924, 393,1270, 440, 92, 0, 92,0xf4,0x0b,0x1c,0x0a},
++ { 143, 76, 836, 523,1270, 440, 224, 0, 0,0xf1,0x05,0x1f,0x16}, /* 640x480, 320x240 */
++ { 143, 120,1056, 643,1270, 440, 0, 128, 0,0xf4,0x10,0x1c,0x00}, /* 800x600, 400x300 */
++ { 143, 76, 836, 523,1270, 440, 0, 128, 0,0xee,0x0c,0x22,0x08}, /* 720x480 - BETTER (from 300 series) */
++/*{ 2, 1, 858, 503,1270, 480, 0, 128, 0,0xee,0x0c,0x22,0x08},*/ /* 720x480 (old, from 650) */
++ { 1, 1,1100, 811,1412, 440, 0, 128, 0,0xee,0x0c,0x22,0x08} /* 1024x768 CORRECTED */
++/*{ 65, 64,1056, 791,1270, 480, 638, 0, 0,0xEE,0x0C,0x22,0x08} */ /* 1024x768 */
++#if 0 /* 300 series was: */
++ { 143, 65, 858, 443,1270, 440, 171, 0, 171,0xf1,0x04,0x1f,0x18},
++ { 88, 35, 858, 393,1270, 440, 171, 0, 171,0xf1,0x04,0x1f,0x18},
++ { 143, 70, 924, 443,1270, 440, 92, 0, 92,0xf1,0x04,0x1f,0x18},
++ { 143, 70, 924, 393,1270, 440, 92, 0, 92,0xf4,0x0b,0x1c,0x0a},
++ { 143, 76, 836, 523,1270, 440, 224, 0, 0,0xf1,0x05,0x1f,0x16},
++ { 143, 120,1056, 643,1270, 440, 0, 128, 0,0xf4,0x10,0x1c,0x00},
++ { 143, 76, 836, 523,1270, 440, 0, 128, 0,0xee,0x0c,0x22,0x08},
++ { 65, 64,1056, 791,1270, 480, 638, 0, 0,0xf1,0x04,0x1f,0x18}
++#endif
++};
++
++
++static const SiS_TVDataStruct SiS_St2HiTVData[]=
++{
++ { 3, 1, 0x348,0x1e3,0x670,0x3c0,0x032, 0, 0, 0x00,0x00,0x00,0x00},
++ { 1, 1, 0x37c,0x233,0x2b2,0x2bc, 0, 0, 0, 0x00,0x00,0x00,0x00},
++ { 3, 1, 0x348,0x1e3,0x670,0x3c0,0x032, 0, 0, 0x00,0x00,0x00,0x00},
++ { 1, 1, 0x3e8,0x233,0x311,0x2bc, 0, 0, 0, 0x00,0x00,0x00,0x00},
++ { 5, 2, 0x348,0x233,0x670,0x3c0,0x08d,128, 0, 0x00,0x00,0x00,0x00},
++ { 8, 5, 0x41a,0x2ab,0x670,0x3c0,0x17c,128, 0, 0x00,0x00,0x00,0x00}
++};
++
++static const SiS_TVDataStruct SiS_ExtHiTVData[]=
++{
++ { 6, 1, 0x348,0x233,0x660,0x3c0, 0, 0, 0, 0x00,0x00,0x00,0x00},
++ { 3, 1, 0x3c0,0x233,0x660,0x3c0, 0, 0, 0, 0x00,0x00,0x00,0x00},
++ { 3, 1, 0x348,0x1e3,0x660,0x3c0, 0, 0, 0, 0x00,0x00,0x00,0x00},
++ { 3, 1, 0x3c0,0x233,0x660,0x3c0, 0, 0, 0, 0x00,0x00,0x00,0x00},
++ { 5, 1, 0x348,0x233,0x670,0x3c0,0x166,128, 0, 0x00,0x00,0x00,0x00}, /* 640x480 */
++ { 16, 5, 0x41a,0x2ab,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00}, /* 800x600 */
++ { 25, 12, 0x4ec,0x353,0x670,0x3c0,0x032, 0, 0, 0x00,0x00,0x00,0x00}, /* 1024x768 */
++ { 5, 4, 0x627,0x464,0x670,0x3c0,0x128, 0, 0, 0x00,0x00,0x00,0x00}, /* 1280x1024 */
++ { 4, 1, 0x41a,0x233,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00}, /* 800x480 */
++ { 5, 2, 0x578,0x293,0x670,0x3c0,0x032, 0, 0, 0x00,0x00,0x00,0x00}, /* 1024x576 */
++ { 8, 5, 0x6d6,0x323,0x670,0x3c0,0x128, 0, 0, 0x00,0x00,0x00,0x00} /* 1280x720 */
++};
++
++static const UCHAR SiS_OutputSelect = 0x40;
++
++static const UCHAR SiS_SoftSetting = 0x30; /* RAM setting */
++
++static const SiS_LCDDataStruct SiS_LCD1280x960Data[] =
++{
++ { 9, 2, 800, 500,1800,1000},
++ { 9, 2, 800, 500,1800,1000},
++ { 4, 1, 900, 500,1800,1000},
++ { 4, 1, 900, 500,1800,1000},
++ { 9, 2, 800, 500,1800,1000},
++ { 30, 11,1056, 625,1800,1000},
++ { 5, 3,1350, 800,1800,1000},
++ { 1, 1,1576,1050,1576,1050},
++ { 1, 1,1800,1000,1800,1000}
++};
++
++static const SiS_LCDDataStruct SiS_StLCD1280x768Data[] =
++{
++ { 211, 100, 2100, 408, 1688, 802 }, /* These values are *wrong* */
++ { 211, 64, 1536, 358, 1688, 802 }, /* (which is why they aren't used yet) */
++ { 211, 100, 2100, 408, 1688, 802 },
++ { 211, 64, 1536, 358, 1688, 802 },
++ { 211, 48, 840, 488, 1688, 802 },
++ { 211, 72, 1008, 609, 1688, 802 },
++ { 211, 128, 1400, 776, 1688, 802 },
++ { 211, 205, 1680, 1041, 1688, 802 },
++ { 1, 1, 1688, 802, 1688, 802 } /* That's the only one that *might* be correct */
++};
++
++static const SiS_LCDDataStruct SiS_ExtLCD1280x768Data[] =
++{
++ { 211, 100, 2100, 408, 1688, 802 }, /* These values are *wrong* */
++ { 211, 64, 1536, 358, 1688, 802 }, /* (which is why they aren't used yet) */
++ { 211, 100, 2100, 408, 1688, 802 },
++ { 211, 64, 1536, 358, 1688, 802 },
++ { 211, 48, 840, 488, 1688, 802 },
++ { 211, 72, 1008, 609, 1688, 802 },
++ { 211, 128, 1400, 776, 1688, 802 },
++ { 211, 205, 1680, 1041, 1688, 802 },
++ { 1, 1, 1688, 802, 1688, 802 } /* That's the only one that *might* be correct */
++};
++
++static const SiS_LCDDataStruct SiS_NoScaleData1280x768[] =
++{ /* All values guessed */
++ { 1, 1, 1688, 802, 1688, 802},
++ { 1, 1, 1688, 802, 1688, 802},
++ { 1, 1, 1688, 802, 1688, 802},
++ { 1, 1, 1688, 802, 1688, 802},
++ { 1, 1, 1688, 802, 1688, 802},
++ { 1, 1, 1688, 802, 1688, 802},
++ { 1, 1, 1688, 802, 1688, 802},
++ { 1, 1, 1688, 802, 1688, 802},
++ { 1, 1, 1688, 802, 1688, 802}
++};
++
++static const SiS_LCDDataStruct SiS_StLCD1400x1050Data[] =
++{
++ { 211, 100, 2100, 408, 1688, 1066 },
++ { 211, 64, 1536, 358, 1688, 1066 },
++ { 211, 100, 2100, 408, 1688, 1066 },
++ { 211, 64, 1536, 358, 1688, 1066 },
++ { 211, 48, 840, 488, 1688, 1066 },
++ { 211, 72, 1008, 609, 1688, 1066 },
++ { 211, 128, 1400, 776, 1688, 1066 },
++ { 211, 205, 1680, 1041, 1688, 1066 },
++ { 1, 1, 1688, 1066, 1688, 1066 }
++};
++
++static const SiS_LCDDataStruct SiS_ExtLCD1400x1050Data[] =
++{
++ { 211, 100, 2100, 408, 1688, 1066 },
++ { 211, 64, 1536, 358, 1688, 1066 },
++ { 211, 100, 2100, 408, 1688, 1066 },
++ { 211, 64, 1536, 358, 1688, 1066 },
++ { 211, 48, 840, 488, 1688, 1066 },
++ { 211, 72, 1008, 609, 1688, 1066 },
++ { 211, 128, 1400, 776, 1688, 1066 },
++ { 211, 205, 1680, 1041, 1688, 1066 },
++ { 1, 1, 1688, 1066, 1688, 1066 }
++};
++
++static const SiS_LCDDataStruct SiS_NoScaleData1400x1050[] =
++{
++ { 1, 1, 1688, 1066, 1688, 1066 },
++ { 1, 1, 1688, 1066, 1688, 1066 },
++ { 1, 1, 1688, 1066, 1688, 1066 },
++ { 1, 1, 1688, 1066, 1688, 1066 },
++ { 1, 1, 1688, 1066, 1688, 1066 },
++ { 1, 1, 1688, 1066, 1688, 1066 },
++ { 1, 1, 1688, 1066, 1688, 1066 },
++ { 1, 1, 1688, 1066, 1688, 1066 },
++ { 1, 1, 1688, 1066, 1688, 1066 }
++};
++
++static const SiS_LCDDataStruct SiS_StLCD1600x1200Data[] =
++{
++ {27, 4, 800, 500, 2160, 1250 },
++ {27, 4, 800, 500, 2160, 1250 },
++ { 6, 1, 900, 500, 2160, 1250 },
++ { 6, 1, 900, 500, 2160, 1250 },
++ {27, 1, 800, 500, 2160, 1250 },
++ { 4, 1,1080, 625, 2160, 1250 },
++ { 5, 2,1350, 800, 2160, 1250 },
++ {135,88,1600,1100, 2160, 1250 },
++ {135,88,1600,1100, 2160, 1250 },
++ { 1, 1,2160,1250, 2160, 1250 }
++};
++
++static const SiS_LCDDataStruct SiS_ExtLCD1600x1200Data[] =
++{
++ {27, 4, 800, 500, 2160, 1250 },
++ {27, 4, 800, 500, 2160, 1250 },
++ { 6, 1, 900, 500, 2160, 1250 },
++ { 6, 1, 900, 500, 2160, 1250 },
++ {27, 1, 800, 500, 2160, 1250 },
++ { 4, 1,1080, 625, 2160, 1250 },
++ { 5, 2,1350, 800, 2160, 1250 },
++ {27,16,1500,1064, 2160, 1250 },
++ {27,16,1500,1064, 2160, 1250 },
++ { 1, 1,2160,1250, 2160, 1250 }
++};
++
++static const SiS_LCDDataStruct SiS_NoScaleData1600x1200[] =
++{
++ {1, 1, 2160, 1250, 2048, 1250},
++ {1, 1, 2160, 1250, 2048, 1250},
++ {1, 1, 2160, 1250, 2048, 1250},
++ {1, 1, 2160, 1250, 2048, 1250},
++ {1, 1, 2160, 1250, 2048, 1250},
++ {1, 1, 2160, 1250, 2048, 1250},
++ {1, 1, 2160, 1250, 2048, 1250},
++ {1, 1, 2160, 1250, 2048, 1250},
++ {1, 1, 2160, 1250, 2048, 1250},
++ {1, 1, 2160, 1250, 2048, 1250},
++};
++
++static const SiS_LCDDataStruct SiS_NoScaleData[] =
++{
++ { 1, 1, 800, 449, 800, 449 },
++ { 1, 1, 800, 449, 800, 449 },
++ { 1, 1, 900, 449, 900, 449 },
++ { 1, 1, 900, 449, 900, 449 },
++ { 1, 1, 800, 525, 800, 525 },
++ { 1, 1,1056, 628,1056, 628 },
++ { 1, 1,1344, 806,1344, 806 },
++ { 1, 1,1688,1066,1688,1066 },
++ { 1, 1,1688, 802,1688, 802 }, /* 1280x768: 802 was 806 in both cases */
++ { 1, 1,2160,1250,2160,1250 }, /* 1600x1200 */
++ { 1, 1,1800,1000,1800,1000 } /* 1280x960 */
++};
++
++static const SiS_LVDSDataStruct SiS_LVDS320x480Data_1[]=
++{
++ { 848, 433, 400, 525},
++ { 848, 389, 400, 525},
++ { 848, 433, 400, 525},
++ { 848, 389, 400, 525},
++ { 848, 518, 400, 525},
++ {1056, 628, 400, 525},
++ { 400, 525, 400, 525},
++ { 800, 449,1000, 644},
++ { 800, 525,1000, 635}
++};
++
++static const SiS_LVDSDataStruct SiS_LVDS800x600Data_1[]=
++{
++ { 848, 433,1060, 629},
++ { 848, 389,1060, 629},
++ { 848, 433,1060, 629},
++ { 848, 389,1060, 629},
++ { 848, 518,1060, 629},
++ {1056, 628,1056, 628},
++ {1056, 628,1056, 628},
++ { 800, 449,1000, 644},
++ { 800, 525,1000, 635}
++};
++
++static const SiS_LVDSDataStruct SiS_LVDS800x600Data_2[]=
++{
++ {1056, 628,1056, 628},
++ {1056, 628,1056, 628},
++ {1056, 628,1056, 628},
++ {1056, 628,1056, 628},
++ {1056, 628,1056, 628},
++ {1056, 628,1056, 628},
++ {1056, 628,1056, 628},
++ { 800, 449,1000, 644},
++ { 800, 525,1000, 635}
++};
++
++
++
++static const SiS_LVDSDataStruct SiS_LVDS1280x1024Data_1[]=
++{
++ {1048, 442,1688,1066},
++ {1048, 392,1688,1066},
++ {1048, 442,1688,1066},
++ {1048, 392,1688,1066},
++ {1048, 522,1688,1066},
++ {1208, 642,1688,1066},
++ {1432, 810,1688,1066},
++ {1688,1066,1688,1066}
++};
++
++static const SiS_LVDSDataStruct SiS_LVDS1280x1024Data_2[]=
++{
++ {1688,1066,1688,1066},
++ {1688,1066,1688,1066},
++ {1688,1066,1688,1066},
++ {1688,1066,1688,1066},
++ {1688,1066,1688,1066},
++ {1688,1066,1688,1066},
++ {1688,1066,1688,1066},
++ {1688,1066,1688,1066}
++};
++
++static const SiS_LVDSDataStruct SiS_LVDS1024x768Data_1[]=
++{
++ { 840, 438,1344, 806},
++ { 840, 409,1344, 806},
++ { 840, 438,1344, 806},
++ { 840, 409,1344, 806},
++ { 840, 518,1344, 806}, /* 640x480 */
++ {1050, 638,1344, 806}, /* 800x600 */
++ {1344, 806,1344, 806}, /* 1024x768 */
++ { 800, 449,1280, 801},
++ { 800, 525,1280, 813}
++};
++
++static const SiS_LVDSDataStruct SiS_LVDS1024x768Data_2[]=
++{
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ { 800, 449,1280, 801},
++ { 800, 525,1280, 813}
++};
++
++/* Custom data for Barco iQ R300 */
++static const SiS_LVDSDataStruct SiS_LVDSBARCO1366Data_1[]=
++{
++ { 832, 438,1331, 806},
++ { 832, 388,1331, 806},
++ { 832, 438,1331, 806},
++ { 832, 388,1331, 806},
++ { 832, 518,1331, 806},
++ {1050, 638,1344, 806},
++ {1344, 806,1344, 806},
++ {1688,1066,1688,1066},
++ {1688,1066,1688,1066} /* 1360x1024 */
++};
++
++/* Custom data for Barco iQ R300 */
++static const SiS_LVDSDataStruct SiS_LVDSBARCO1366Data_2[]=
++{
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1688,1066,1688,1066},
++ {1688,1066,1688,1066} /* 1360x1024 */
++};
++
++static const SiS_LVDSDataStruct SiS_LVDSBARCO1024Data_1[]=
++{
++ { 832, 438,1331, 806},
++ { 832, 409,1331, 806},
++ { 832, 438,1331, 806},
++ { 832, 409,1331, 806},
++ { 832, 518,1331, 806}, /* 640x480 */
++ {1050, 638,1344, 806}, /* 800x600 */
++ {1344, 806,1344, 806}, /* 1024x768 */
++};
++
++static const SiS_LVDSDataStruct SiS_LVDSBARCO1024Data_2[]=
++{
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++};
++
++static const SiS_LVDSDataStruct SiS_LVDS1400x1050Data_1[]=
++{
++ { 928, 416, 1688,1066},
++ { 928, 366, 1688,1066},
++ { 928, 416, 1688,1066},
++ { 928, 366, 1688,1066},
++ { 928, 496, 1688,1066},
++ {1088, 616, 1688,1066},
++ {1312, 784, 1688,1066},
++ {1568,1040, 1688,1066},
++ {1688,1066, 1688,1066}
++};
++
++static const SiS_LVDSDataStruct SiS_LVDS1400x1050Data_2[]=
++{
++ {1688,1066, 1688,1066},
++ {1688,1066, 1688,1066},
++ {1688,1066, 1688,1066},
++ {1688,1066, 1688,1066},
++ {1688,1066, 1688,1066},
++ {1688,1066, 1688,1066},
++ {1688,1066, 1688,1066},
++ {1688,1066, 1688,1066},
++ {1688,1066, 1688,1066},
++};
++
++static const SiS_LVDSDataStruct SiS_LVDS1600x1200Data_1[]=
++{
++ {1088, 450, 2048,1250},
++ {1088, 400, 2048,1250},
++ {1088, 450, 2048,1250},
++ {1088, 400, 2048,1250},
++ {1088, 530, 2048,1250},
++ {1248, 650, 2048,1250},
++ {1472, 818, 2048,1250},
++ {1728,1066, 2048,1250},
++ {1848,1066, 2048,1250},
++ {2048,1250, 2048,1250}
++};
++
++static const SiS_LVDSDataStruct SiS_LVDS1600x1200Data_2[]=
++{
++ {2048,1250, 2048,1250},
++ {2048,1250, 2048,1250},
++ {2048,1250, 2048,1250},
++ {2048,1250, 2048,1250},
++ {2048,1250, 2048,1250},
++ {2048,1250, 2048,1250},
++ {2048,1250, 2048,1250},
++ {2048,1250, 2048,1250},
++ {2048,1250, 2048,1250},
++ {2048,1250, 2048,1250}
++};
++
++static const SiS_LVDSDataStruct SiS_LVDS1280x768Data_1[]=
++{
++ { 768, 438, 1408, 806},
++ { 768, 388, 1408, 806},
++ { 768, 438, 1408, 806},
++ { 768, 388, 1408, 806},
++ { 768, 518, 1408, 806},
++ { 928, 638, 1408, 806},
++ {1152, 806, 1408, 806},
++ {1408, 806, 1408, 806},
++ {1408, 806, 1408, 806}
++};
++
++static const SiS_LVDSDataStruct SiS_LVDS1280x768Data_2[]=
++{
++ {1408, 806, 1408, 806},
++ {1408, 806, 1408, 806},
++ {1408, 806, 1408, 806},
++ {1408, 806, 1408, 806},
++ {1408, 806, 1408, 806},
++ {1408, 806, 1408, 806},
++ {1408, 806, 1408, 806},
++ {1408, 806, 1408, 806},
++ {1408, 806, 1408, 806}
++};
++
++static const SiS_LVDSDataStruct SiS_LVDS1024x600Data_1[] =
++{
++ {840, 604,1344, 800},
++ {840, 560,1344, 800},
++ {840, 604,1344, 800},
++ {840, 560,1344, 800},
++ {840, 689,1344, 800},
++ {1050, 800,1344, 800},
++ {1344, 800,1344, 800},
++ {800, 449,1280, 789},
++ {800, 525,1280, 785}
++};
++
++static const SiS_LVDSDataStruct SiS_LVDS1024x600Data_2[] =
++{
++ {1344, 800,1344, 800},
++ {1344, 800,1344, 800},
++ {1344, 800,1344, 800},
++ {1344, 800,1344, 800},
++ {1344, 800,1344, 800},
++ {1344, 800,1344, 800},
++ {1344, 800,1344, 800},
++ { 800, 449,1280, 801},
++ { 800, 525,1280, 813}
++};
++
++static const SiS_LVDSDataStruct SiS_LVDS1152x768Data_1[] =
++{
++ { 840, 438,1344, 806},
++ { 840, 409,1344, 806},
++ { 840, 438,1344, 806},
++ { 840, 409,1344, 806},
++ { 840, 518,1344, 806},
++ {1050, 638,1344, 806},
++ {1344, 806,1344, 806},
++ { 800, 449,1280, 801},
++ { 800, 525,1280, 813}
++};
++
++static const SiS_LVDSDataStruct SiS_LVDS1152x768Data_2[] =
++{
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ { 800, 449,1280, 801},
++ { 800, 525,1280, 813}
++};
++
++/* TW: Pass 1:1 data */
++static const SiS_LVDSDataStruct SiS_LVDSXXXxXXXData_1[]=
++{
++ { 800, 449, 800, 449},
++ { 800, 449, 800, 449},
++ { 900, 449, 900, 449},
++ { 900, 449, 900, 449},
++ { 800, 525, 800, 525}, /* 640x480 */
++ {1056, 628, 1056, 628}, /* 800x600 */
++ {1344, 806, 1344, 806}, /* 1024x768 */
++ {1344,1066, 1344,1066}, /* 1280x1024 */ /* INSERTED ! */
++ {1688, 806, 1688, 806}, /* 1280x768 */
++ /* No other panels ! */
++};
++
++static const SiS_LVDSDataStruct SiS_LVDS640x480Data_1[]=
++{
++ { 800, 445, 800, 525}, /* 800, 449, 800, 449 */
++ { 800, 395, 800, 525},
++ { 800, 445, 800, 525},
++ { 800, 395, 800, 525},
++ { 800, 525, 800, 525},
++ { 800, 525, 800, 525}, /* pseudo */
++ { 800, 525, 800, 525} /* pseudo */
++};
++
++/* FSTN 320x240 */
++static const SiS_LVDSDataStruct SiS_LVDS640x480Data_2[]=
++{
++ { 800, 445, 800, 525},
++ { 800, 395, 800, 525},
++ { 800, 445, 800, 525},
++ { 800, 395, 800, 525},
++ { 800, 525, 800, 525},
++ { 800, 525, 800, 525}, /* pseudo */
++ { 800, 525, 800, 525} /* pseudo */
++};
++
++
++static const SiS_LVDSDataStruct SiS_LVDS1280x960Data_1[]=
++{
++ { 840, 438,1344, 806},
++ { 840, 409,1344, 806},
++ { 840, 438,1344, 806},
++ { 840, 409,1344, 806},
++ { 840, 518,1344, 806},
++ {1050, 638,1344, 806},
++ {1344, 806,1344, 806},
++ { 800, 449,1280, 801},
++ { 800, 525,1280, 813}
++};
++
++static const SiS_LVDSDataStruct SiS_LVDS1280x960Data_2[]=
++{
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ { 800, 449,1280, 801},
++ { 800, 525,1280, 813}
++};
++
++static const SiS_LVDSDataStruct SiS_LVDS848x480Data_1[]=
++{
++ { 0, 0, 0, 0},
++ { 0, 0, 0, 0},
++ { 0, 0, 0, 0},
++ { 0, 0, 0, 0},
++ {1088, 525,1088, 525}, /* 640x480 TODO */
++ {1088, 525,1088, 525}, /* 800x600 TODO */
++ {1088, 525,1088, 525}, /* 1024x768 TODO */
++ { 0, 0, 0, 0},
++ { 0, 0, 0, 0},
++ { 0, 0, 0, 0},
++ { 0, 0, 0, 0},
++ {1088, 525,1088, 525}, /* 848x480 */
++ {1088, 525,1088, 525} /* 1360x768 TODO */
++};
++
++static const SiS_LVDSDataStruct SiS_LVDS848x480Data_2[]=
++{
++ { 0, 0, 0, 0},
++ { 0, 0, 0, 0},
++ { 0, 0, 0, 0},
++ { 0, 0, 0, 0},
++ {1088, 525,1088, 525}, /* 640x480 */
++ {1088, 525,1088, 525}, /* 800x600 */
++ {1088, 525,1088, 525}, /* 1024x768 */
++ { 0, 0, 0, 0},
++ { 0, 0, 0, 0},
++ { 0, 0, 0, 0},
++ { 0, 0, 0, 0},
++ {1088, 525,1088, 525}, /* 848x480 */
++ {1088, 525,1088, 525} /* 1360x768 TODO */
++};
++
++/* LCDA */
++
++static const SiS_LVDSDataStruct SiS_LCDA1400x1050Data_1[]=
++{ /* TW: Might be temporary (invalid) data */
++ { 928, 416, 1688,1066},
++ { 928, 366, 1688,1066},
++ {1008, 416, 1688,1066},
++ {1008, 366, 1688,1066},
++ {1200, 530, 1688,1066},
++ {1088, 616, 1688,1066},
++ {1312, 784, 1688,1066},
++ {1568,1040, 1688,1066},
++ {1688,1066, 1688,1066}
++};
++
++static const SiS_LVDSDataStruct SiS_LCDA1400x1050Data_2[]=
++{ /* TW: Temporary data. Not valid */
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ { 800, 449,1280, 801},
++ { 800, 525,1280, 813}
++};
++
++static const SiS_LVDSDataStruct SiS_LCDA1600x1200Data_1[]=
++{ /* TW: Temporary data. Not valid */
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ {1344, 806,1344, 806},
++ { 800, 449,1280, 801},
++ { 800, 525,1280, 813}
++};
++
++static const SiS_LVDSDataStruct SiS_LCDA1600x1200Data_2[]=
++{ /* TW: Temporary data. Not valid */
++ {0, 0, 0, 0},
++ {0, 0, 0, 0},
++ {0, 0, 0, 0},
++ {0, 0, 0, 0},
++ {0, 0, 0, 0},
++ {0, 0, 0, 0},
++ {0, 0, 0, 0},
++ {0, 0, 0, 0},
++ {0, 0, 0, 0},
++ {0, 0, 0, 0},
++ {0, 0, 0, 0},
++ {0, 0, 0, 0}
++};
++
++static const SiS_LVDSDataStruct SiS_CHTVUNTSCData[]=
++{
++ { 840, 600, 840, 600},
++ { 840, 600, 840, 600},
++ { 840, 600, 840, 600},
++ { 840, 600, 840, 600},
++ { 784, 600, 784, 600},
++ {1064, 750,1064, 750},
++ {1160, 945,1160, 945}
++};
++
++static const SiS_LVDSDataStruct SiS_CHTVONTSCData[]=
++{
++ { 840, 525, 840, 525},
++ { 840, 525, 840, 525},
++ { 840, 525, 840, 525},
++ { 840, 525, 840, 525},
++ { 784, 525, 784, 525},
++ {1040, 700,1040, 700},
++ {1160, 840,1160, 840}
++};
++
++static const SiS_LVDSDesStruct SiS_PanelType1076_1[]=
++{ /* 1024x768 */
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0}
++};
++
++static const SiS_LVDSDesStruct SiS_PanelType1076_2[]=
++{ /* 1024x768 */
++ { 1184, 622 },
++ { 1184, 597 },
++ { 1184, 622 },
++ { 1184, 597 },
++ { 1152, 622 },
++ { 1232, 722 },
++ { 0, 0 },
++ { 0, 794 },
++ { 0, 0 }
++};
++
++static const SiS_LVDSDesStruct SiS_PanelType1210_1[]=
++{ /* 1280x1024 */
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0}
++};
++
++static const SiS_LVDSDesStruct SiS_PanelType1210_2[]=
++{ /* 1280x1024 */
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0}
++};
++
++static const SiS_LVDSDesStruct SiS_PanelType1296_1[]=
++{ /* 1400x1050 */
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0}
++};
++
++static const SiS_LVDSDesStruct SiS_PanelType1296_2[]=
++{ /* 1400x1050 - looks heavily invalid */
++ { 808 , 740},
++ { 0 , 715},
++ { 632 , 740},
++ { 632 , 715},
++ { 1307, 780},
++ { 1387,1157},
++ { 1499, 924},
++ { 1627,1052},
++ { 0 , 0}
++};
++
++static const SiS_LVDSDesStruct SiS_PanelType1600_1[]=
++{ /* 1600x1200 */
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0}
++};
++
++static const SiS_LVDSDesStruct SiS_PanelType1600_2[]=
++{ /* 1600x1200 - BIOS looks heavily invalid, not copied */
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0}
++};
++
++static const SiS_LVDSDesStruct SiS_PanelTypeNS_1[]=
++{
++ { 8, 0},
++ { 8, 0},
++ { 8, 0},
++ { 8, 0},
++ { 8, 0},
++ { 0, 0},
++ { 0, 0},
++ { 0, 0},
++ { 0, 806},
++ { 0, 0 }
++};
++
++static const SiS_LVDSDesStruct SiS_PanelTypeNS_2[] =
++{
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0},
++ { 0 , 0}
++};
++
++static const SiS_LVDSDesStruct SiS_CHTVUNTSCDesData[]=
++{
++ { 0, 0},
++ { 0, 0},
++ { 0, 0},
++ { 0, 0},
++ { 0, 0},
++ { 0, 0},
++ { 0, 0}
++};
++
++static const SiS_LVDSDesStruct SiS_CHTVONTSCDesData[]=
++{
++ { 0, 0},
++ { 0, 0},
++ { 0, 0},
++ { 0, 0},
++ { 0, 0},
++ { 0, 0},
++ { 0, 0}
++};
++
++static const SiS_LVDSDesStruct SiS_CHTVUPALDesData[]=
++{
++ {256, 0},
++ {256, 0},
++ {256, 0},
++ {256, 0},
++ { 0, 0},
++ { 0, 0},
++ { 0, 0}
++};
++
++static const SiS_LVDSDesStruct SiS_CHTVOPALDesData[]=
++{
++ {256, 0},
++ {256, 0},
++ {256, 0},
++ {256, 0},
++ { 0, 0},
++ { 0, 0},
++ { 0, 0}
++};
++
++static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1320x480_1[] =
++{
++ {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
++ 0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
++ 0x00 }},
++ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
++ 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
++ 0x00 }},
++ {{0x65,0x4f,0x89,0x54,0x9f,0xc4,0x1f,
++ 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
++ 0x00 }},
++ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
++ 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
++ 0x00 }},
++ {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
++ 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
++ 0x00 }},
++ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
++ 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
++ 0x01 }},
++ {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
++ 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
++ 0x00 }}
++};
++
++static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11024x600_1[] =
++{
++ {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
++ 0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
++ 0x00}},
++ {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
++ 0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
++ 0x00}},
++ {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
++ 0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
++ 0x00}},
++ {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
++ 0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
++ 0x00}},
++ {{0x64,0x4f,0x88,0x54,0x9f,0xaf,0xba,
++ 0x3b,0x82,0xdf,0xb0,0x00,0x00,0x01,
++ 0x00}},
++ {{0x7e,0x63,0x82,0x68,0x15,0x1e,0xf1,
++ 0xae,0x85,0x57,0x1f,0x30,0x00,0x26,
++ 0x01}},
++ {{0xa3,0x7f,0x87,0x86,0x97,0x1e,0xf1,
++ 0xae,0x85,0x57,0x1f,0x30,0x00,0x02,
++ 0x01}}
++};
++
++static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11024x600_1_H[] =
++{
++ {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
++ 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
++ 0x00}},
++ {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
++ 0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
++ 0x00}},
++ {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
++ 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
++ 0x00}},
++ {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
++ 0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
++ 0x00}},
++ {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
++ 0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
++ 0x00}},
++ {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
++ 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
++ 0x01}},
++ {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
++ 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
++ 0x01}}
++};
++
++static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11024x600_2[] =
++{
++ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
++ 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
++ 0x00}},
++ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
++ 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
++ 0x00}},
++ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
++ 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
++ 0x00}},
++ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
++ 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
++ 0x00}},
++ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
++ 0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
++ 0x00}},
++ {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
++ 0xae,0x84,0x57,0x25,0x30,0x00,0x02,
++ 0x01}},
++ {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
++ 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
++ 0x01}}
++};
++
++static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11024x600_2_H[] =
++{
++ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
++ 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
++ 0x00}},
++ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
++ 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
++ 0x00}},
++ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
++ 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
++ 0x00}},
++ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
++ 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
++ 0x00}},
++ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
++ 0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
++ 0x00}},
++ {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
++ 0xae,0x84,0x57,0x25,0x30,0x00,0x01,
++ 0x01}},
++ {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
++ 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
++ 0x01}}
++};
++
++static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11152x768_1[] =
++{
++ {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
++ 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
++ 0x00}},
++ {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
++ 0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
++ 0x00}},
++ {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
++ 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
++ 0x00}},
++ {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
++ 0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
++ 0x00}},
++ {{0x64,0x4f,0x88,0x54,0x9f,0x04,0x3e,
++ 0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
++ 0x00}},
++ {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
++ 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
++ 0x01}},
++ {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
++ 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
++ 0x01}}
++};
++
++static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11152x768_1_H[] =
++{
++ {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
++ 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
++ 0x00}},
++ {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
++ 0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
++ 0x00}},
++ {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
++ 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
++ 0x00}},
++ {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
++ 0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
++ 0x00}},
++ {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
++ 0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
++ 0x00}},
++ {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
++ 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
++ 0x01}},
++ {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
++ 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
++ 0x01}}
++};
++
++static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11152x768_2[] =
++{
++ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
++ 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
++ 0x00}},
++ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
++ 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
++ 0x00}},
++ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
++ 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
++ 0x00}},
++ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
++ 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
++ 0x00}},
++ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
++ 0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
++ 0x00}},
++ {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
++ 0xae,0x84,0x57,0x25,0x30,0x00,0x02,
++ 0x01}},
++ {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
++ 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
++ 0x01}}
++};
++
++static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11152x768_2_H[] =
++{
++ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
++ 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
++ 0x00}},
++ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
++ 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
++ 0x00}},
++ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
++ 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
++ 0x00}},
++ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
++ 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
++ 0x00}},
++ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
++ 0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
++ 0x00}},
++ {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
++ 0xae,0x84,0x57,0x25,0x30,0x00,0x01,
++ 0x01}},
++ {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
++ 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
++ 0x01}}
++};
++
++static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11280x768_1[] =
++{
++ {{0x5b,0x4f,0x9f,0x55,0x19,0xb4,0x1f,
++ 0x9c,0x8e,0x8f,0xb5,0x10,0x00,0x01,
++ 0x00}},
++ {{0x5b,0x4f,0x9f,0x55,0x19,0x82,0x1f,
++ 0x6a,0x8c,0x5d,0x83,0x30,0x00,0x01,
++ 0x00}},
++ {{0x5b,0x4f,0x9f,0x55,0x19,0xb4,0x1f,
++ 0x9c,0x8e,0x8f,0xb5,0x10,0x00,0x01,
++ 0x00}},
++ {{0x5b,0x4f,0x9f,0x55,0x19,0x82,0x1f,
++ 0x6a,0x8c,0x5d,0x83,0x30,0x00,0x01,
++ 0x00}},
++ {{0x5b,0x4f,0x9f,0x55,0x19,0x04,0x3e,
++ 0xec,0x8e,0xdf,0x05,0x20,0x00,0x01,
++ 0x00}},
++ {{0x6f,0x63,0x93,0x69,0x8d,0x7c,0xf0,
++ 0x64,0x86,0x57,0x7d,0x20,0x00,0x05,
++ 0x01}},
++ {{0x8b,0x7f,0x8f,0x85,0x09,0x24,0xf5,
++ 0x0c,0x8e,0xff,0x25,0x30,0x00,0x02,
++ 0x01}},
++ {{0xab,0x9f,0x8f,0xa5,0x89,0x24,0xf5,
++ 0x0c,0x8e,0xff,0x25,0x30,0x00,0x06,
++ 0x01}},
++ {{0xab,0x9f,0x8f,0xa5,0x89,0x24,0xf5,
++ 0x0c,0x8e,0xff,0x25,0x30,0x00,0x06,
++ 0x01}}
++};
++
++static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11280x768_1_H[] =
++{
++ {{0x47,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
++ 0x93,0x86,0x8f,0x9f,0x30,0x00,0x05,
++ 0x00}},
++ {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
++ 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
++ 0x00}},
++ {{0x47,0x27,0x8b,0x30,0x1e,0x9e,0x1f,
++ 0x92,0x86,0x8f,0x9f,0x30,0x00,0x05,
++ 0x00}},
++ {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
++ 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
++ 0x00}},
++ {{0x47,0x27,0x8b,0x2c,0x1a,0xee,0x1f,
++ 0xe2,0x86,0xdf,0xef,0x10,0x00,0x05,
++ 0x00}},
++ {{0x51,0x31,0x95,0x36,0x04,0x66,0xf0,
++ 0x5a,0x8e,0x57,0x67,0x20,0x00,0x01,
++ 0x01}},
++ {{0x5f,0x3f,0x83,0x44,0x92,0x0e,0xf5,
++ 0x02,0x86,0xff,0x0f,0x10,0x00,0x01,
++ 0x01}},
++ {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
++ 0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
++ 0x01}},
++ {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
++ 0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
++ 0x01}}
++};
++
++static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11280x768_2[] =
++{
++ {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
++ 0x54,0x86,0xdb,0xda,0x00,0x00,0x02,
++ 0x00}},
++ {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
++ 0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x02,
++ 0x00}},
++ {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
++ 0x54,0x86,0xdb,0xda,0x00,0x00,0x02,
++ 0x00}},
++ {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
++ 0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x02,
++ 0x00}},
++ {{0xab,0x60,0x9f,0x80,0x04,0x24,0xb3,
++ 0x7c,0x8e,0x03,0x02,0x10,0x00,0x02,
++ 0x01}},
++ {{0xab,0x63,0x8f,0x8a,0x8e,0x24,0xf1,
++ 0xb6,0x88,0x57,0x25,0x10,0x00,0x02,
++ 0x01}},
++ {{0xab,0x7f,0x8f,0x98,0x9c,0x24,0xf5,
++ 0x0a,0x8c,0xff,0x25,0x30,0x00,0x02,
++ 0x01}},
++ {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
++ 0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
++ 0x01}},
++ {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
++ 0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
++ 0x01}}
++};
++
++static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11280x768_2_H[] =
++{
++ {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
++ 0x54,0x86,0xdb,0xda,0x00,0x00,0x01,
++ 0x00}},
++ {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
++ 0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x01,
++ 0x00}},
++ {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
++ 0x54,0x86,0xdb,0xda,0x00,0x00,0x01,
++ 0x00}},
++ {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
++ 0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x01,
++ 0x00}},
++ {{0x83,0x38,0x97,0x58,0x9c,0x24,0xb3,
++ 0x7c,0x8e,0x03,0x02,0x10,0x00,0x01,
++ 0x01}},
++ {{0x79,0x31,0x9d,0x58,0x9c,0x24,0xf1,
++ 0xb6,0x88,0x57,0x25,0x10,0x00,0x01,
++ 0x01}},
++ {{0x6b,0x3f,0x8f,0x58,0x9c,0x24,0xf5,
++ 0x0a,0x8c,0xff,0x25,0x30,0x00,0x01,
++ 0x01}},
++ {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
++ 0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
++ 0x01}},
++ {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
++ 0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
++ 0x01}}
++};
++
++static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1XXXxXXX_1[] =
++{
++ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
++ 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
++ 0x00}},
++ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
++ 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
++ 0x00}},
++ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
++ 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
++ 0x00}},
++ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
++ 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
++ 0x00}},
++ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
++ 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x05,
++ 0x00}},
++ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
++ 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
++ 0x01}},
++ {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
++ 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
++ 0x01}},
++ {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
++ 0x00,0x84,0xff,0x29,0x09,0x00,0x07,
++ 0x01}},
++ {{0xce,0x9f,0x92,0xa9,0x17,0x24,0xf5,
++ 0x02,0x88,0xff,0x25,0x10,0x00,0x07,
++ 0x01}}
++};
++
++static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1XXXxXXX_1_H[] =
++{
++ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
++ 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
++ 0x00}},
++ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
++ 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
++ 0x00}},
++ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
++ 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
++ 0x00}},
++ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
++ 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
++ 0x00}},
++ {{0x38,0x27,0x9c,0x2c,0x80,0x0b,0x3e,
++ 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
++ 0x00}},
++ {{0x4d,0x31,0x91,0x3b,0x03,0x72,0xf0,
++ 0x58,0x8c,0x57,0x73,0x20,0x00,0x01,
++ 0x01}},
++ {{0x63,0x3f,0x87,0x4a,0x92,0x24,0xf5,
++ 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
++ 0x01}}
++};
++
++static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_1[] =
++{
++ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
++ 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
++ 0x00}},
++ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
++ 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
++ 0x00}},
++ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
++ 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
++ 0x00}},
++ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
++ 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
++ 0x00}},
++ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
++ 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
++ 0x00}},
++ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
++ 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
++ 0x01}}
++};
++
++static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_1_H[] =
++{
++ {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
++ 0x9c,0x8e,0x96,0xb9,0x00,0x00,0x00,
++ 0x00}},
++ {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
++ 0x83,0x85,0x63,0xba,0x00,0x00,0x00,
++ 0x00}},
++ {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
++ 0x9c,0x8e,0x96,0xb9,0x00,0x00,0x00,
++ 0x00}},
++ {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
++ 0x83,0x85,0x63,0xba,0x00,0x00,0x00,
++ 0x00}},
++ {{0x2d,0x28,0x90,0x2c,0x80,0x0b,0x3e,
++ 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
++ 0x00}}
++};
++
++static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_2[] =
++{
++ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
++ 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
++ 0x00}},
++ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
++ 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
++ 0x00}},
++ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
++ 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
++ 0x00}},
++ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
++ 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
++ 0x00}},
++ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
++ 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
++ 0x00}},
++ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
++ 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
++ 0x01}},
++ {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
++ 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
++ 0x00}}
++};
++
++static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_2_H[] =
++{
++ {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
++ 0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
++ 0x00}},
++ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
++ 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
++ 0x00}},
++ {{0x65,0x4f,0x89,0x54,0x9f,0xc4,0x1f,
++ 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
++ 0x00}},
++ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
++ 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
++ 0x00}},
++ {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
++ 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
++ 0x00}},
++ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
++ 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
++ 0x01}},
++ {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
++ 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
++ 0x00}}
++};
++
++static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_3[] =
++{
++ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
++ 0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
++ 0x00}},
++ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
++ 0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
++ 0x00}},
++ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
++ 0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
++ 0x00}},
++ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
++ 0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
++ 0x00}},
++ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
++ 0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
++ 0x00}},
++ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
++ 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
++ 0x01}},
++ {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
++ 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
++ 0x00}}
++};
++
++static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_3_H[] =
++{
++ {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
++ 0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
++ 0x00}},
++ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
++ 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
++ 0x00}},
++ {{0x65,0x4f,0x89,0x54,0x9f,0xc4,0x1f,
++ 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
++ 0x00}},
++ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
++ 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
++ 0x00}},
++ {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
++ 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
++ 0x00}},
++ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
++ 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
++ 0x01}},
++ {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
++ 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
++ 0x00}}
++};
++
++#define SIS_PL_HSYNCP 0x01
++#define SIS_PL_HSYNCN 0x02
++#define SIS_PL_VSYNCP 0x04
++#define SIS_PL_VSYNCN 0x08
++#define SIS_PL_DVI 0x80
++
++typedef struct _SiS_PlasmaModes
++{
++ const char *name;
++ ULONG clock;
++ USHORT HDisplay, HTotal, HFrontPorch, HSyncWidth;
++ USHORT VDisplay, VTotal, VFrontPorch, VSyncWidth;
++ UCHAR SyncFlags;
++} SiS_PlasmaModes;
++
++
++typedef struct _SiS_PlasmaTables
++{
++ USHORT vendor;
++ UCHAR productnum;
++ USHORT product[5];
++ const char *plasmaname;
++ UCHAR modenum;
++ UCHAR plasmamodes[20]; /* | 0x80 = DVI-capable, | 0x40 = analog */
++} SiS_PlasmaTables;
++
++static const SiS_PlasmaModes SiS_PlasmaMode[] = {
++ { "640x400", /* 00: IBM 400@70 */
++ 25175,
++ 640, 800, 17, 64,
++ 400, 449, 13, 2,
++ SIS_PL_HSYNCN | SIS_PL_VSYNCN },
++ { "640x480", /* 01: VESA 480@72 */
++ 31500,
++ 640, 832, 24, 40,
++ 480, 520, 9, 3,
++ SIS_PL_HSYNCN | SIS_PL_VSYNCN },
++ { "800x600", /* 02: VESA 600@72 */
++ 50000,
++ 800, 1040, 56, 120,
++ 600, 666, 37, 6,
++ SIS_PL_HSYNCP | SIS_PL_VSYNCP },
++ { "864x480", /* 03: Cereb wide 1 */
++ 42526,
++ 864, 1134, 22, 86,
++ 480, 500, 1, 3,
++ SIS_PL_HSYNCP | SIS_PL_VSYNCN },
++ { "848x480", /* 04: VESA wide (NEC1) */
++ 33750,
++ 848, 1088, 16, 112,
++ 480, 517, 6, 8,
++ SIS_PL_HSYNCP | SIS_PL_VSYNCP },
++ { "1024x576", /* 05: VESA wide (NEC2) */
++ 47250,
++ 1024, 1320, 16, 144,
++ 576, 596, 2, 4,
++ SIS_PL_HSYNCP | SIS_PL_VSYNCP },
++ { "1280x720", /* 06: VESA wide (NEC3) */
++ 76500,
++ 1280, 1696, 48, 176,
++ 720, 750, 4, 8,
++ SIS_PL_HSYNCP | SIS_PL_VSYNCP },
++ { "1360x765", /* 07: VESA wide (NEC4) */
++ 85500,
++ 1360, 1792, 64, 176,
++ 765, 795, 4, 8,
++ SIS_PL_HSYNCP | SIS_PL_VSYNCP },
++ { "1024x600", /* 08: CEREB wide 2 */
++ 51200,
++ 1024, 1352, 51, 164,
++ 600, 628, 1, 4,
++ SIS_PL_HSYNCN | SIS_PL_VSYNCP },
++ { "1024x768", /* 09: VESA 768@75 */
++ 78750,
++ 1024, 1312, 16, 96,
++ 768, 800, 1, 3,
++ SIS_PL_HSYNCP | SIS_PL_VSYNCP },
++ { "1152x864", /* 10: VESA 1152x864@75 */
++ 108000,
++ 1152, 1600, 64, 128,
++ 864, 900, 1, 3,
++ SIS_PL_HSYNCP | SIS_PL_VSYNCP },
++ { "1280x1024", /* 11: VESA 1024@60 */
++ 108000,
++ 1280, 1688, 48, 112,
++ 1024, 1066, 1, 3,
++ SIS_PL_HSYNCP | SIS_PL_VSYNCP },
++ { "1280x768", /* 12: W_XGA */
++ 81000,
++ 1280, 1688, 48, 112,
++ 768, 802, 3, 6,
++ SIS_PL_HSYNCP | SIS_PL_VSYNCN },
++ { "1280x768", /* 13: I/O Data W_XGA@56Hz */
++ 76064,
++ 1280, 1688, 48, 112,
++ 768, 802, 2, 3,
++ SIS_PL_HSYNCP | SIS_PL_VSYNCP },
++ { "1376x768", /* 14: I/O Wide XGA */
++ 87340,
++ 1376, 1808, 32, 128,
++ 768, 806, 3, 6,
++ SIS_PL_HSYNCN | SIS_PL_VSYNCP },
++ { "1280x960", /* 15: VESA 960@60 */
++ 108000,
++ 1280, 1800, 96, 112,
++ 960, 1000, 1, 3,
++ SIS_PL_HSYNCP | SIS_PL_VSYNCP },
++ { "1400x1050", /* 16: VESA 1050@60Hz */
++ 108000,
++ 1400, 1688, 48, 112,
++ 1050, 1066, 1, 3,
++ SIS_PL_HSYNCN | SIS_PL_VSYNCN },
++ { "1360x768", /* 17: VESA wide (NEC4/2) */
++ 85500,
++ 1360, 1792, 64, 112,
++ 765, 795, 3, 6,
++ SIS_PL_HSYNCP | SIS_PL_VSYNCP },
++ { "800x600", /* 18: VESA 600@56 */
++ 36000,
++ 800, 1024, 24, 2,
++ 600, 625, 1, 2,
++ SIS_PL_HSYNCP | SIS_PL_VSYNCP }
++};
++
++static const SiS_PlasmaTables SiS_PlasmaTable[] = {
++#if 0 /* Product IDs missing */
++ { 0x38a3, 4,
++ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
++ "NEC PlasmaSync 42VP4/42VP4D/42VP4G/42VP4DG",
++ 14, /* All DVI, except 0, 7, 13; 3, 15, 16 unknown */
++ { 0|0x40, 1|0xc0, 2|0xc0, 3|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,12|0xc0,
++ 13|0x40,14|0xc0,15|0xc0,16|0xc0, 0 , 0 , 0 , 0 , 0 , 0 }
++ },
++ { 0x38a3, 3,
++ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
++ "NEC PlasmaSync 42PD1/50PD1/50PD2",
++ 5, /* DVI entirely unknown */
++ { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0, 0 , 0 , 0 , 0 , 0 ,
++ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
++ },
++ { 0x38a3, 1,
++ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
++ "NEC PlasmaSync 42PD3",
++ 10, /* DVI entirely unknown */
++ { 0|0x40, 1|0xc0, 2|0xc0, 3|0xc0, 4|0xc0, 5|0xc0, 6|0xc0, 7|0x40, 8|0xc0, 9|0xc0,
++ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
++ },
++ { 0x38a3, 2,
++ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
++ "NEC PlasmaSync 42VM3/61XM1",
++ 11, /* DVI entirely unknown */
++ { 0|0x40, 1|0xc0, 2|0xc0, 3|0xc0, 4|0xc0, 5|0xc0, 6|0xc0, 8|0xc0, 9|0xc0,11|0xc0,
++ 17|0xc0, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
++ },
++ { 0x38a3, 2,
++ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
++ "NEC PlasmaSync 42MP1/42MP2",
++ 6, /* DVI entirely unknown */
++ { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0,11|0xc0, 0 , 0 , 0 , 0 ,
++ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
++ },
++ { 0x38a3, 1,
++ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
++ "NEC PlasmaSync 50MP1",
++ 10, /* DVI entirely unknown */
++ { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,13|0x40,14|0xc0,
++ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
++ },
++#endif
++ { 0x38a3, 4,
++ { 0xa482, 0xa483, 0x0000, 0x0000, 0x0000 },
++ "NEC PlasmaSync 42MP3/42MP4/50MP2/61MP1",
++ 11, /* All DVI except 0, 7, 13, 17 */
++ { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,13|0x40,14|0xc0,
++ 17|0x40, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
++ },
++#if 0 /* Product IDs missing */
++ { 0x38a3, 1,
++ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
++ "NEC PlasmaSync 3300W",
++ 3,
++ { 0|0x40, 1|0xc0,18|0xc0, 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
++ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
++ },
++ { 0x38a3, 1,
++ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
++ "NEC PlasmaSync 4200W",
++ 4, /* DVI entirely unknown */
++ { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 0 , 0 , 0 , 0 , 0 , 0 ,
++ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
++ },
++ { 0x38a3, 1,
++ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
++ "NEC PlasmaSync 4210W",
++ 6, /* DVI entirely unknown */
++ { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0,11|0xc0, 0 , 0 , 0 , 0 ,
++ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
++ },
++ { 0x38a3, 1,
++ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
++ "NEC PlasmaSync 5000W",
++ 7, /* DVI entirely unknown */
++ { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,11|0xc0, 0 , 0 , 0 ,
++ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
++ },
++#endif
++ { 0x412f, 2,
++ { 0x000c, 0x000b, 0x0000, 0x0000, 0x0000 },
++ "Pioneer 503CMX/PDA-5002",
++ 6, /* DVI unknown */
++ { 1|0xc0, 2|0xc0, 9|0xc0,11|0xc0,12|0xc0,15|0xc0, 0 , 0 , 0 , 0 ,
++ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
++ },
++ { 0x34a9, 1,
++ { 0xa00e, 0x0000, 0x0000, 0x0000, 0x0000 },
++ "Panasonic TH-42",
++ 5, /* No DVI output */
++ { 1|0x40, 2|0x40, 4|0x40, 9|0x40,15|0x40, 0 , 0 , 0 , 0 , 0 ,
++ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
++ },
++ { 0x0000 }
++};
++
+ void SiS_SetReg1(USHORT, USHORT, USHORT);
+ void SiS_SetReg2(SiS_Private *, USHORT, USHORT, USHORT);
+ void SiS_SetReg3(USHORT, USHORT);
+@@ -158,6 +2397,7 @@
+ void SiS_SetDRAMModeRegister(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ BOOLEAN SiS_SearchVBModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo);
+ void SiS_IsLowResolution(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
++void SiS_GetSysFlags(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+
+ #ifdef SIS300
+ void SiS_SetDRAMSize_300(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+@@ -192,12 +2432,15 @@
+
+ void SiS_HandleCRT1(SiS_Private *SiS_Pr);
+ void SiS_Handle301B_1400x1050(SiS_Private *SiS_Pr, USHORT ModeNo);
+-void SiS_SetEnableDstn(SiS_Private *SiS_Pr);
++void SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable);
++void SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable);
+ void SiS_Delay15us(SiS_Private *SiS_Pr);
+ BOOLEAN SiS_SearchModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo,USHORT *ModeIdIndex);
+ BOOLEAN SiS_CheckMemorySize(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT ModeNo,USHORT ModeIdIndex);
+ UCHAR SiS_GetModePtr(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex);
++void SiS_WhatTheHellIsThis(SiS_Private *SiS_Pr,PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr);
++void SiS_StrangeStuff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ void SiS_SetSeqRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex);
+ void SiS_SetMiscRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex);
+ void SiS_SetCRTCRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+@@ -267,26 +2510,26 @@
+ void SiS_SetPitchCRT2(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr);
+ extern int SiS_compute_vclk(int Clock, int *out_n, int *out_dn, int *out_div,
+ int *out_sbit, int *out_scale);
++extern void SiSCalcClock(ScrnInfoPtr pScrn, int clock, int max_VLD, unsigned int *vclk);
++
+ extern unsigned char SiS_GetSetBIOSScratch(ScrnInfoPtr pScrn, USHORT offset, unsigned char value);
+ extern unsigned char SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id);
+-extern USHORT SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode);
++extern USHORT SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN hcm);
+ #endif
+
+ extern USHORT SiS_GetOffset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ extern USHORT SiS_GetColorDepth(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+ extern void SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+-extern BOOLEAN SiS_SetCRT2Group301(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+- PSIS_HW_DEVICE_INFO HwDeviceExtension);
+-extern void SiS_PresetScratchregister(SiS_Private *SiS_Pr, USHORT SiS_P3d4,
+- PSIS_HW_DEVICE_INFO HwDeviceExtension);
++extern BOOLEAN SiS_SetCRT2Group(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
++ PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ extern void SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr);
+ extern void SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr);
+ extern BOOLEAN SiS_BridgeIsOn(SiS_Private *SiS_Pr, USHORT BaseAddr);
+ extern BOOLEAN SiS_BridgeIsEnable(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO );
+ extern void SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+ USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension, int chkcrt2mode);
+-extern BOOLEAN SiS_GetLCDResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
++extern void SiS_GetLCDResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
+ USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ extern void SiS_SetHiVision(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ extern USHORT SiS_GetRatePtrCRT2(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex,
+@@ -321,10 +2564,12 @@
+ unsigned char modeno, unsigned char rateindex);
+ int sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ unsigned char modeno, unsigned char rateindex,
+- ULONG *left_margin, ULONG *right_margin,
++ ULONG *left_margin, ULONG *right_margin,
+ ULONG *upper_margin, ULONG *lower_margin,
+ ULONG *hsync_len, ULONG *vsync_len,
+ ULONG *sync, ULONG *vmode);
++BOOLEAN sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
++ unsigned char modeno, int *htotal, int *vtotal, unsigned char rateindex);
+ #endif
+
+ #endif
+Index: linux-2.6.0-test5/drivers/video/sis/oem300.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/sis/oem300.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/sis/oem300.h 2003-09-27 11:38:35.233172128 +0800
+@@ -1,5 +1,37 @@
+-
+-/* OEM Data for 300 series */
++/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/oem300.h.c,v 1.0 2001/11/30 12:12:01 eich Exp $ */
++/*
++ * OEM Data for 300 series
++ *
++ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
++ *
++ * If distributed as part of the linux kernel, the contents of this file
++ * is entirely covered by the GPL.
++ *
++ * Otherwise, the following terms apply:
++ *
++ * Permission to use, copy, modify, distribute, and sell this software and its
++ * documentation for any purpose is hereby granted without fee, provided that
++ * the above copyright notice appear in all copies and that both that
++ * copyright notice and this permission notice appear in supporting
++ * documentation, and that the name of the copyright holder not be used in
++ * advertising or publicity pertaining to distribution of the software without
++ * specific, written prior permission. The copyright holder makes no representations
++ * about the suitability of this software for any purpose. It is provided
++ * "as is" without express or implied warranty.
++ *
++ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
++ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
++ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
++ * PERFORMANCE OF THIS SOFTWARE.
++ *
++ * Author: Thomas Winischhofer <thomas@winischhofer.net>
++ *
++ * Based on code by Silicon Intergrated Systems
++ *
++ */
+
+ const UCHAR SiS300_OEMTVDelay301[8][4] =
+ {
+@@ -680,325 +712,147 @@
+ }
+ };
+
+-const UCHAR SiS300_LCDHData[24][11][5] = {
++/* Custom data for Barco iQ Pro R300 */
++const UCHAR barco_p1[2][9][7][3] = {
+ {
+- {0x67,0x91,0x84,0x5e,0x00},
+- {0x67,0x91,0x84,0x5e,0x00},
+- {0x67,0x91,0x84,0x5e,0x00},
+- {0x67,0x91,0x84,0x5e,0x00},
+- {0x67,0x91,0x84,0x5e,0x00},
+- {0x67,0x91,0x84,0x5e,0x00},
+- {0x67,0x91,0x84,0x5e,0x00},
+- {0x65,0xef,0x83,0x5c,0x00},
+- {0x65,0xef,0x83,0x5c,0x00},
+- {0x8a,0x14,0x00,0x80,0x00},
+- {0x8a,0x14,0x00,0x80,0x00}
+- },
+- {
+- {0x4e,0x18,0x90,0x38,0x00},
+- {0x4e,0x18,0x90,0x38,0x00},
+- {0x8e,0x18,0x28,0x78,0x00},
+- {0x8e,0x18,0x28,0x78,0x00},
+- {0x8e,0x18,0x28,0x78,0x00},
+- {0x4e,0x18,0x90,0x38,0x00},
+- {0x4e,0x18,0x90,0x38,0x00},
+- {0x67,0x11,0x9a,0x56,0x00},
+- {0x67,0x11,0x9a,0x56,0x00},
+- {0x8a,0x14,0x00,0x80,0x00},
+- {0x8a,0x14,0x00,0x80,0x00}
+- },
+- {
+- {0x67,0x91,0x84,0x5e,0x00},
+- {0x67,0x91,0x84,0x5e,0x00},
+- {0x67,0x91,0x84,0x5e,0x00},
+- {0x67,0x91,0x84,0x5e,0x00},
+- {0x67,0x91,0x84,0x5e,0x00},
+- {0x67,0x91,0x84,0x5e,0x00},
+- {0x67,0x91,0x84,0x5e,0x00},
+- {0x65,0xef,0x83,0x5c,0x00},
+- {0x65,0xef,0x83,0x5c,0x00},
+- {0x8a,0x14,0x00,0x80,0x00},
+- {0x8a,0x14,0x00,0x80,0x00}
+- },
+- {
+- {0x4e,0x18,0x90,0x38,0x00},
+- {0x4e,0x18,0x90,0x38,0x00},
+- {0x8e,0x18,0x28,0x78,0x00},
+- {0x8e,0x18,0x28,0x78,0x00},
+- {0x8e,0x18,0x28,0x78,0x00},
+- {0x4e,0x18,0x90,0x38,0x00},
+- {0x4e,0x18,0x90,0x38,0x00},
+- {0x67,0x11,0x9a,0x56,0x00},
+- {0x67,0x11,0x9a,0x56,0x00},
+- {0x8a,0x14,0x00,0x80,0x00},
+- {0x8a,0x14,0x00,0x80,0x00}
+- },
+- {
+- {0x67,0x91,0x84,0x5e,0x00},
+- {0x67,0x91,0x84,0x5e,0x00},
+- {0x67,0x91,0x84,0x5e,0x00},
+- {0x67,0x91,0x84,0x5e,0x00},
+- {0x67,0x91,0x84,0x5e,0x00},
+- {0x67,0x91,0x84,0x5e,0x00},
+- {0x67,0x91,0x84,0x5e,0x00},
+- {0x65,0xef,0x83,0x5c,0x00},
+- {0x65,0xef,0x83,0x5c,0x00},
+- {0x8a,0x14,0x00,0x80,0x00},
+- {0x8a,0x14,0x00,0x80,0x00}
+- },
+- {
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x8E,0x18,0x28,0x78,0x00},
+- {0x8E,0x18,0x28,0x78,0x00},
+- {0x8E,0x18,0x28,0x78,0x00},
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x67,0x11,0x9A,0x56,0x00},
+- {0x67,0x11,0x9A,0x56,0x00},
+- {0x8A,0x14,0x00,0x80,0x00},
+- {0x8A,0x14,0x00,0x80,0x00}
+- },
+- {
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x65,0xEF,0x83,0x5C,0x00},
+- {0x65,0xEF,0x83,0x5C,0x00},
+- {0x8A,0x14,0x00,0x80,0x00},
+- {0x8A,0x14,0x00,0x80,0x00}
+- },
+- {
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x8E,0x18,0x28,0x78,0x00},
+- {0x8E,0x18,0x28,0x78,0x00},
+- {0x8E,0x18,0x28,0x78,0x00},
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x67,0x11,0x9A,0x56,0x00},
+- {0x67,0x11,0x9A,0x56,0x00},
+- {0x8A,0x14,0x00,0x80,0x00},
+- {0x8A,0x14,0x00,0x80,0x00}
+- },
+- {
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x65,0xEF,0x83,0x5C,0x00},
+- {0x65,0xEF,0x83,0x5C,0x00},
+- {0x8A,0x14,0x00,0x80,0x00},
+- {0x8A,0x14,0x00,0x80,0x00}
+- },
+- {
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x8E,0x18,0x28,0x78,0x00},
+- {0x8E,0x18,0x28,0x78,0x00},
+- {0x8E,0x18,0x28,0x78,0x00},
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x67,0x11,0x9A,0x56,0x00},
+- {0x67,0x11,0x9A,0x56,0x00},
+- {0x8A,0x14,0x00,0x80,0x00},
+- {0x8A,0x14,0x00,0x80,0x00}
+- },
+- {
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x65,0xEF,0x83,0x5C,0x00},
+- {0x65,0xEF,0x83,0x5C,0x00},
+- {0x8A,0x14,0x00,0x80,0x00},
+- {0x8A,0x14,0x00,0x80,0x00}
+- },
+- {
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x8E,0x18,0x28,0x78,0x00},
+- {0x8E,0x18,0x28,0x78,0x00},
+- {0x8E,0x18,0x28,0x78,0x00},
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x67,0x11,0x9A,0x56,0x00},
+- {0x67,0x11,0x9A,0x56,0x00},
+- {0x8A,0x14,0x00,0x80,0x00},
+- {0x8A,0x14,0x00,0x80,0x00}
+- },
+- {
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x65,0xEF,0x83,0x5C,0x00},
+- {0x65,0xEF,0x83,0x5C,0x00},
+- {0x8A,0x14,0x00,0x80,0x00},
+- {0x8A,0x14,0x00,0x80,0x00}
+- },
+- {
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x8E,0x18,0x28,0x78,0x00},
+- {0x8E,0x18,0x28,0x78,0x00},
+- {0x8E,0x18,0x28,0x78,0x00},
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x67,0x11,0x9A,0x56,0x00},
+- {0x67,0x11,0x9A,0x56,0x00},
+- {0x8A,0x14,0x00,0x80,0x00},
+- {0x8A,0x14,0x00,0x80,0x00}
+- },
+- {
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x65,0xEF,0x83,0x5C,0x00},
+- {0x65,0xEF,0x83,0x5C,0x00},
+- {0x8A,0x14,0x00,0x80,0x00},
+- {0x8A,0x14,0x00,0x80,0x00}
+- },
+- {
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x8E,0x18,0x28,0x78,0x00},
+- {0x8E,0x18,0x28,0x78,0x00},
+- {0x8E,0x18,0x28,0x78,0x00},
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x67,0x11,0x9A,0x56,0x00},
+- {0x67,0x11,0x9A,0x56,0x00},
+- {0x8A,0x14,0x00,0x80,0x00},
+- {0x8A,0x14,0x00,0x80,0x00}
+- },
+- {
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x65,0xEF,0x83,0x5C,0x00},
+- {0x65,0xEF,0x83,0x5C,0x00},
+- {0x8A,0x14,0x00,0x80,0x00},
+- {0x8A,0x14,0x00,0x80,0x00}
+- },
+- {
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x8E,0x18,0x28,0x78,0x00},
+- {0x8E,0x18,0x28,0x78,0x00},
+- {0x8E,0x18,0x28,0x78,0x00},
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x67,0x11,0x9A,0x56,0x00},
+- {0x67,0x11,0x9A,0x56,0x00},
+- {0x8A,0x14,0x00,0x80,0x00},
+- {0x8A,0x14,0x00,0x80,0x00}
+- },
+- {
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x65,0xEF,0x83,0x5C,0x00},
+- {0x65,0xEF,0x83,0x5C,0x00},
+- {0x8A,0x14,0x00,0x80,0x00},
+- {0x8A,0x14,0x00,0x80,0x00}
+- },
+- {
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x8E,0x18,0x28,0x78,0x00},
+- {0x8E,0x18,0x28,0x78,0x00},
+- {0x8E,0x18,0x28,0x78,0x00},
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x67,0x11,0x9A,0x56,0x00},
+- {0x67,0x11,0x9A,0x56,0x00},
+- {0x8A,0x14,0x00,0x80,0x00},
+- {0x8A,0x14,0x00,0x80,0x00}
+- },
+- {
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x65,0xEF,0x83,0x5C,0x00},
+- {0x65,0xEF,0x83,0x5C,0x00},
+- {0x8A,0x14,0x00,0x80,0x00},
+- {0x8A,0x14,0x00,0x80,0x00}
+- },
+- {
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x8E,0x18,0x28,0x78,0x00},
+- {0x8E,0x18,0x28,0x78,0x00},
+- {0x8E,0x18,0x28,0x78,0x00},
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x67,0x11,0x9A,0x56,0x00},
+- {0x67,0x11,0x9A,0x56,0x00},
+- {0x8A,0x14,0x00,0x80,0x00},
+- {0x8A,0x14,0x00,0x80,0x00}
+- },
+- {
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x67,0x91,0x84,0x5E,0x00},
+- {0x65,0xEF,0x83,0x5C,0x00},
+- {0x65,0xEF,0x83,0x5C,0x00},
+- {0x8A,0x14,0x00,0x80,0x00},
+- {0x8A,0x14,0x00,0x80,0x00}
+- },
+- {
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x8E,0x18,0x28,0x78,0x00},
+- {0x8E,0x18,0x28,0x78,0x00},
+- {0x8E,0x18,0x28,0x78,0x00},
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x4E,0x18,0x90,0x38,0x00},
+- {0x67,0x11,0x9A,0x56,0x00},
+- {0x67,0x11,0x9A,0x56,0x00},
+- {0x8A,0x14,0x00,0x80,0x00},
+- {0x8A,0x14,0x00,0x80,0x00}
++ { { 0x16, 0xcf, 0x00 },
++ { 0x18, 0x00, 0x00 },
++ { 0x1a, 0xe7, 0x00 },
++ { 0x1b, 0x26, 0x00 },
++ { 0x1c, 0xff, 0x00 },
++ { 0x1d, 0x1c, 0x00 },
++ { 0x1e, 0x19, 0x00 }
++ },
++ {
++ { 0x16, 0xcf, 0x00 },
++ { 0x18, 0x00, 0x00 },
++ { 0x1a, 0xe7, 0x00 },
++ { 0x1b, 0x1e, 0x00 },
++ { 0x1c, 0xff, 0x00 },
++ { 0x1d, 0x1c, 0x00 },
++ { 0x1e, 0x16, 0x00 }
++ },
++ {
++ { 0x16, 0xcf, 0x00 },
++ { 0x1a, 0xe7, 0x00 },
++ { 0x1b, 0x26, 0x00 },
++ { 0x1c, 0xff, 0x00 },
++ { 0x1d, 0x1c, 0x00 },
++ { 0x1e, 0x19, 0x00 },
++ { 0, 0, 0 }
++ },
++ {
++ { 0, 0, 0 }
++ },
++ {
++ { 0x16, 0xcf, 0x00 },
++ { 0x1a, 0xe7, 0x00 },
++ { 0x1b, 0x26, 0x00 },
++ { 0x1c, 0xff, 0x00 },
++ { 0x1d, 0x1c, 0x00 },
++ { 0x1e, 0x1e, 0x00 },
++ { 0, 0, 0 }
++ },
++ {
++ { 0x16, 0xd1, 0x00 },
++ { 0x18, 0x00, 0x00 },
++ { 0x1a, 0xe7, 0x00 },
++ { 0x1b, 0x11, 0x00 },
++ { 0x1c, 0xff, 0x00 },
++ { 0x1d, 0x1c, 0x00 },
++ { 0x1e, 0x26, 0x00 }
++ },
++ {
++ { 0x16, 0xd1, 0x00 },
++ { 0x1a, 0xe7, 0x00 },
++ { 0x1b, 0x26, 0x00 },
++ { 0x1c, 0xff, 0x00 },
++ { 0x1d, 0x1c, 0x00 },
++ { 0x1e, 0x30, 0x00 },
++ { 0, 0, 0 }
++ },
++ {
++ { 0x16, 0x00, 0x00 },
++ { 0x17, 0xa0, 0x00 },
++ { 0x1a, 0xa0, 0x00 },
++ { 0x1b, 0x2a, 0x00 },
++ { 0x1c, 0xff, 0x00 },
++ { 0x1d, 0x1c, 0x00 },
++ { 0, 0, 0 }
++ },
++ {
++ { 0x16, 0x00, 0x00 },
++ { 0x17, 0xaa, 0x00 },
++ { 0x1a, 0xa0, 0x00 },
++ { 0x1b, 0x2a, 0x00 },
++ { 0x1c, 0xff, 0x00 },
++ { 0x1d, 0x1c, 0x00 },
++ { 0, 0, 0 }
++ }
++ },
++ {
++ {
++ { 0x16, 0xcf, 0x00 },
++ { 0x18, 0x00, 0x00 },
++ { 0x1a, 0xe7, 0x00 },
++ { 0x1b, 0x26, 0x00 },
++ { 0x1c, 0xff, 0x00 },
++ { 0x1d, 0x1c, 0x00 },
++ { 0x1e, 0x19, 0x00 }
++ },
++ {
++ { 0, 0, 0 }
++ },
++ {
++ { 0x16, 0xcf, 0x00 },
++ { 0x18, 0x00, 0x00 },
++ { 0x1a, 0xe7, 0x00 },
++ { 0x1b, 0x26, 0x00 },
++ { 0x1c, 0xff, 0x00 },
++ { 0x1d, 0x1c, 0x00 },
++ { 0x1e, 0x19, 0x00 },
++ },
++ {
++ { 0, 0, 0 }
++ },
++ {
++ { 0x16, 0xcf, 0x00 },
++ { 0x18, 0x00, 0x00 },
++ { 0x1a, 0xe7, 0x00 },
++ { 0x1b, 0x26, 0x00 },
++ { 0x1c, 0xff, 0x00 },
++ { 0x1d, 0x1c, 0x00 },
++ { 0x1e, 0x1e, 0x00 }
++ },
++ {
++ { 0x16, 0xd1, 0x00 },
++ { 0x18, 0x00, 0x00 },
++ { 0x1a, 0xe6, 0x00 },
++ { 0x1b, 0x11, 0x00 },
++ { 0x1c, 0xff, 0x00 },
++ { 0x1d, 0x1c, 0x00 },
++ { 0x1e, 0x26, 0x00 }
++ },
++ {
++ { 0x18, 0x00, 0x00 },
++ { 0x1a, 0xe0, 0x00 },
++ { 0x1b, 0x26, 0x00 },
++ { 0x1c, 0xff, 0x00 },
++ { 0x1d, 0x1c, 0x00 },
++ { 0x1e, 0x30, 0x00 },
++ { 0, 0, 0 }
++ },
++ {
++ { 0, 0, 0 }
++ },
++ {
++ { 0, 0, 0 }
++ }
+ }
+ };
+
+-#if 0
+-const UCHAR SiS300_LCDVData[24][11][6] = {
+- {
+- {
+- },
+-};
+-#endif
++
++
++
++
++
+Index: linux-2.6.0-test5/drivers/video/sis/oem310.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/sis/oem310.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/sis/oem310.h 2003-09-27 11:38:35.261167872 +0800
+@@ -1,5 +1,37 @@
+-
+-/* OEM Data for 310/325/330 series */
++/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/oem300.h.c,v 1.0 2001/11/30 12:12:01 eich Exp $ */
++/*
++ * OEM Data for 315/330 series
++ *
++ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
++ *
++ * If distributed as part of the linux kernel, the contents of this file
++ * is entirely covered by the GPL.
++ *
++ * Otherwise, the following terms apply:
++ *
++ * Permission to use, copy, modify, distribute, and sell this software and its
++ * documentation for any purpose is hereby granted without fee, provided that
++ * the above copyright notice appear in all copies and that both that
++ * copyright notice and this permission notice appear in supporting
++ * documentation, and that the name of the copyright holder not be used in
++ * advertising or publicity pertaining to distribution of the software without
++ * specific, written prior permission. The copyright holder makes no representations
++ * about the suitability of this software for any purpose. It is provided
++ * "as is" without express or implied warranty.
++ *
++ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
++ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
++ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
++ * PERFORMANCE OF THIS SOFTWARE.
++ *
++ * Author: Thomas Winischhofer <thomas@winischhofer.net>
++ *
++ * Based on code by Silicon Intergrated Systems
++ *
++ */
+
+ const UCHAR SiS310_LCDDelayCompensation_301[] = /* 301 */
+ {
+@@ -100,7 +132,7 @@
+
+ const UCHAR SiS310_LCDDelayCompensation_651301LV[] = /* M650/651 301LV */
+ {
+- 0x33,0x33,0x33, /* 800x600 (guessed) */
++ 0x33,0x33,0x33, /* 800x600 (guessed) - new: PanelType, not PanelRes ! */
+ 0x33,0x33,0x33, /* 1024x768 */
+ 0x33,0x33,0x33, /* 1280x1024 */
+ 0x33,0x33,0x33, /* 640x480 (unknown) */
+@@ -361,5 +393,55 @@
+ }
+ };
+
++/* OEM data for Compaq Presario 3045US */
++static const SiS_LCDDataStruct SiS310_ExtCompaq1280x1024Data[] =
++{
++ { 211, 60,1024, 501,1688,1066},
++ { 211, 60,1024, 508,1688,1066},
++ { 211, 60,1024, 501,1688,1066},
++ { 211, 60,1024, 508,1688,1066},
++ { 32, 15,1696, 501,1696,1066},
++ { 212, 75,1024, 621,1696,1066},
++ { 4, 3,1696, 810,1696,1066},
++ { 1, 1,1696,1066,1696,1066}
++};
++
++static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Compaq1280x1024_1[] =
++{
++ {{0x3F,0x1B,0xD0,0xF0,0xB0,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
++ {{0x35,0x1B,0xA0,0xC0,0x80,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
++ {{0x3F,0x1B,0xD0,0xF0,0xB0,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
++ {{0x3F,0x1B,0xD0,0xF0,0xB0,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
++ {{0x45,0x1C,0x20,0x3F,0xFF,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
++ {{0x49,0x1C,0x40,0x7F,0xFF,0xAD,0x23,0x0A,0x07,0xF3,0x8A,0x12}},
++ {{0x4C,0x1C,0x18,0x2F,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
++ {{0x48,0x1C,0x15,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}}
++};
++
++static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Compaq1280x1024_2[] =
++{
++ {{0x2B,0x12,0xD9,0xE5,0xD5,0x2C,0x23,0x98,0x27,0x3E,0x08,0x42}},
++ {{0x22,0x12,0xC0,0xCC,0xBC,0x2C,0x23,0x98,0x27,0x3E,0x08,0x42}},
++ {{0x2B,0x12,0xD9,0xE5,0xD5,0x2C,0x23,0x98,0x27,0x3E,0x08,0x42}},
++ {{0x22,0x12,0xC0,0xCC,0xBC,0x2C,0x23,0x98,0x27,0x3E,0x08,0x42}},
++ {{0x33,0x13,0x01,0x0D,0xFD,0x2C,0x23,0x98,0x27,0x3E,0x08,0x42}},
++ {{0x3F,0x1B,0x3D,0x49,0x39,0x54,0x23,0xC0,0x27,0x66,0x30,0x42}},
++ {{0x33,0x1B,0x91,0x9D,0x8D,0x8C,0x23,0xF8,0x27,0x9E,0x68,0x42}},
++ {{0x43,0x24,0x11,0x1D,0x0D,0xCC,0x23,0x38,0x37,0xDE,0xA8,0x42}},
++ {{0x43,0x24,0x21,0x29,0x19,0xEA,0x23,0x0A,0x07,0x32,0xC6,0x42}}
++};
++
++static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Compaq1280x1024_3[] =
++{
++ {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
++ {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
++ {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
++ {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
++ {{0x47,0x1C,0x14,0x29,0xFF,0xBE,0x23,0x0A,0x07,0x26,0x8A,0x42}},
++ {{0x47,0x1C,0x14,0x29,0xFF,0xBE,0x23,0x0A,0x07,0x26,0x8A,0x42}},
++ {{0x47,0x1C,0x14,0x29,0xFF,0xBE,0x23,0x0A,0x07,0x26,0x8A,0x42}},
++ {{0x47,0x1C,0x14,0x29,0xFF,0xBE,0x23,0x0A,0x07,0x26,0x8A,0x42}}
++};
++
+
+
+Index: linux-2.6.0-test5/drivers/video/sis/osdef.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/sis/osdef.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/sis/osdef.h 2003-09-27 11:38:35.297162400 +0800
+@@ -1,79 +1,43 @@
+-/* #define WINCE_HEADER */
+-/* #define WIN2000 */
+-/* #define TC */
++
++/* OS depending defines */
++
++/* The choices are: */
++
+ #define LINUX_KERNEL /* Kernel framebuffer */
+ /* #define LINUX_XF86 */ /* XFree86 */
+
+ /**********************************************************************/
+-#ifdef LINUX_KERNEL
+- #include <linux/config.h>
+- #include <linux/version.h>
+- #ifdef CONFIG_FB_SIS_300
+- #define SIS300
+- #endif
+-
+- #ifdef CONFIG_FB_SIS_315
+- #define SIS315H
+- #endif
+- #if 1
+- #define SISFBACCEL /* Include 2D acceleration */
+- #endif
+- #if 1
+- #define SISFB_PAN /* Include Y-Panning code */
+- #endif
+-#else
+-/* #define SIS300*/
+- #define SIS315H
+-#endif
+-#ifdef LINUX_XF86
+- #define SIS300
+- /* #define SIS315H */ /* TW: done above */
+-#endif
++#ifdef LINUX_KERNEL /* -------------------------- */
++#include <linux/config.h>
++#include <linux/version.h>
+
+-/**********************************************************************/
+-#ifdef TC
+-#endif
+-#ifdef WIN2000
+-#endif
+-#ifdef WINCE_HEADER
+-#endif
+-#ifdef LINUX_XF86
++#ifdef CONFIG_FB_SIS_300
++#define SIS300
+ #endif
+-#ifdef LINUX_KERNEL
+-#endif
+-/**********************************************************************/
+-#ifdef TC
+-#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize);
+-#endif
+-#ifdef WIN2000
+-#define SiS_SetMemory(MemoryAddress,MemorySize,value) MemFill((PVOID) MemoryAddress,(ULONG) MemorySize,(UCHAR) value);
++
++#ifdef CONFIG_FB_SIS_315
++#define SIS315H
+ #endif
+-#ifdef WINCE_HEADER
+-#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize);
++
++#if 1
++#define SISFBACCEL /* Include 2D acceleration */
+ #endif
+-#ifdef LINUX_XF86
+-#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
++
+ #endif
+-#ifdef LINUX_KERNEL
+-#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
++
++#ifdef LINUX_XF86 /* ----------------------------- */
++#define SIS300
++#define SIS315H
+ #endif
+-/**********************************************************************/
+
+ /**********************************************************************/
+-
+-#ifdef TC
+-#define SiS_MemoryCopy(Destination,Soruce,Length) memmove(Destination, Soruce, Length);
+-#endif
+-#ifdef WIN2000
+-#define SiS_MemoryCopy(Destination,Soruce,Length) /*VideoPortMoveMemory((PUCHAR)Destination , Soruce,length);*/
+-#endif
+-#ifdef WINCE_HEADER
+-#define SiS_MemoryCopy(Destination,Soruce,Length) memmove(Destination, Soruce, Length);
+-#endif
+ #ifdef LINUX_XF86
++#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
+ #define SiS_MemoryCopy(Destination,Soruce,Length) memcpy(Destination,Soruce,Length)
+ #endif
++
+ #ifdef LINUX_KERNEL
++#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
+ #define SiS_MemoryCopy(Destination,Soruce,Length) memcpy(Destination,Soruce,Length)
+ #endif
+
+@@ -104,19 +68,6 @@
+ #endif /* InPortLong */
+
+ /**********************************************************************/
+-/* TC */
+-/**********************************************************************/
+-
+-#ifdef TC
+-#define OutPortByte(p,v) outp((unsigned short)(p),(unsigned char)(v))
+-#define OutPortWord(p,v) outp((unsigned short)(p),(unsigned short)(v))
+-#define OutPortLong(p,v) outp((unsigned short)(p),(unsigned long)(v))
+-#define InPortByte(p) inp((unsigned short)(p))
+-#define InPortWord(p) inp((unsigned short)(p))
+-#define InPortLong(p) ((inp((unsigned short)(p+2))<<16) | inp((unsigned short)(p)))
+-#endif
+-
+-/**********************************************************************/
+ /* LINUX XF86 */
+ /**********************************************************************/
+
+@@ -142,29 +93,4 @@
+ #define InPortLong(p) inl((u16)(p))
+ #endif
+
+-/**********************************************************************/
+-/* WIN 2000 */
+-/**********************************************************************/
+-
+-#ifdef WIN2000
+-#define OutPortByte(p,v) VideoPortWritePortUchar ((PUCHAR) (p), (UCHAR) (v))
+-#define OutPortWord(p,v) VideoPortWritePortUshort((PUSHORT) (p), (USHORT) (v))
+-#define OutPortLong(p,v) VideoPortWritePortUlong ((PULONG) (p), (ULONG) (v))
+-#define InPortByte(p) VideoPortReadPortUchar ((PUCHAR) (p))
+-#define InPortWord(p) VideoPortReadPortUshort ((PUSHORT) (p))
+-#define InPortLong(p) VideoPortReadPortUlong ((PULONG) (p))
+-#endif
+
+-
+-/**********************************************************************/
+-/* WIN CE */
+-/**********************************************************************/
+-
+-#ifdef WINCE_HEADER
+-#define OutPortByte(p,v) WRITE_PORT_UCHAR ((PUCHAR) (p), (UCHAR) (v))
+-#define OutPortWord(p,v) WRITE_PORT_USHORT((PUSHORT) (p), (USHORT) (v))
+-#define OutPortLong(p,v) WRITE_PORT_ULONG ((PULONG) (p), (ULONG) (v))
+-#define InPortByte(p) READ_PORT_UCHAR ((PUCHAR) (p))
+-#define InPortWord(p) READ_PORT_USHORT ((PUSHORT) (p))
+-#define InPortLong(p) READ_PORT_ULONG ((PULONG) (p))
+-#endif
+Index: linux-2.6.0-test5/drivers/video/sis/sis_accel.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/sis/sis_accel.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/sis/sis_accel.c 2003-09-27 11:38:35.334156776 +0800
+@@ -1,5 +1,5 @@
+ /*
+- * SiS 300/630/730/540/315/550/650/740 frame buffer driver
++ * SiS 300/630/730/540/315/550/650/740/330/660 frame buffer driver
+ * for Linux kernels 2.4.x and 2.5.x
+ *
+ * 2D acceleration part
+@@ -211,7 +211,7 @@
+ SiS300DoCMD
+ }
+
+-/* 310/325 series ------------------------------------------------ */
++/* 315 series ---------------------------------------------------- */
+
+ static void
+ SiS310SetupForScreenToScreenCopy(int xdir, int ydir, int rop,
+@@ -230,7 +230,7 @@
+ /* SiSSetupCMDFlag(BITBLT | SRCVIDEO) */
+ }
+ SiS310SetupCMDFlag(ivideo.SiS310_AccelDepth)
+- /* TW: The 310/325 series is smart enough to know the direction */
++ /* The 315 series is smart enough to know the direction */
+ }
+
+ static void
+@@ -328,11 +328,13 @@
+ }
+ }
+
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34) /* --- KERNEL 2.5.34 and later --- */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) /* --------------- 2.5 --------------- */
+
+ int fbcon_sis_sync(struct fb_info *info)
+ {
+- if(!sisfb_accel) return 0;
++ if(!ivideo.accel)
++ return 0;
++
+ CRITFLAGS
+ if(sisvga_engine == SIS_300_VGA) {
+ SiS300Sync();
+@@ -352,7 +354,7 @@
+ if(!rect->width || !rect->height)
+ return;
+
+- if(!sisfb_accel) {
++ if(!ivideo.accel) {
+ cfb_fillrect(info, rect);
+ return;
+ }
+@@ -388,7 +390,7 @@
+ CRITFLAGS
+
+ TWDEBUG("Inside sis_copyarea");
+- if(!sisfb_accel) {
++ if(!ivideo.accel) {
+ cfb_copyarea(info, area);
+ return;
+ }
+@@ -418,7 +420,7 @@
+
+ #endif
+
+-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,33) /* ------ KERNEL <2.5.34 ------ */
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* -------------- 2.4 --------------- */
+
+ void fbcon_sis_bmove(struct display *p, int srcy, int srcx,
+ int dsty, int dstx, int height, int width)
+@@ -591,38 +593,38 @@
+
+ #ifdef FBCON_HAS_CFB8
+ struct display_switch fbcon_sis8 = {
+- setup: fbcon_cfb8_setup,
+- bmove: fbcon_sis_bmove,
+- clear: fbcon_sis_clear8,
+- putc: fbcon_cfb8_putc,
+- putcs: fbcon_cfb8_putcs,
+- revc: fbcon_cfb8_revc,
+- clear_margins: fbcon_cfb8_clear_margins,
+- fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
++ .setup = fbcon_cfb8_setup,
++ .bmove = fbcon_sis_bmove,
++ .clear = fbcon_sis_clear8,
++ .putc = fbcon_cfb8_putc,
++ .putcs = fbcon_cfb8_putcs,
++ .revc = fbcon_cfb8_revc,
++ .clear_margins = fbcon_cfb8_clear_margins,
++ .fontwidthmask = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+ };
+ #endif
+ #ifdef FBCON_HAS_CFB16
+ struct display_switch fbcon_sis16 = {
+- setup: fbcon_cfb16_setup,
+- bmove: fbcon_sis_bmove,
+- clear: fbcon_sis_clear16,
+- putc: fbcon_cfb16_putc,
+- putcs: fbcon_cfb16_putcs,
+- revc: fbcon_sis_revc,
+- clear_margins: fbcon_cfb16_clear_margins,
+- fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
++ .setup = fbcon_cfb16_setup,
++ .bmove = fbcon_sis_bmove,
++ .clear = fbcon_sis_clear16,
++ .putc = fbcon_cfb16_putc,
++ .putcs = fbcon_cfb16_putcs,
++ .revc = fbcon_sis_revc,
++ .clear_margins = fbcon_cfb16_clear_margins,
++ .fontwidthmask = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+ };
+ #endif
+ #ifdef FBCON_HAS_CFB32
+ struct display_switch fbcon_sis32 = {
+- setup: fbcon_cfb32_setup,
+- bmove: fbcon_sis_bmove,
+- clear: fbcon_sis_clear32,
+- putc: fbcon_cfb32_putc,
+- putcs: fbcon_cfb32_putcs,
+- revc: fbcon_sis_revc,
+- clear_margins: fbcon_cfb32_clear_margins,
+- fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
++ .setup = fbcon_cfb32_setup,
++ .bmove = fbcon_sis_bmove,
++ .clear = fbcon_sis_clear32,
++ .putc = fbcon_cfb32_putc,
++ .putcs = fbcon_cfb32_putcs,
++ .revc = fbcon_sis_revc,
++ .clear_margins = fbcon_cfb32_clear_margins,
++ .fontwidthmask = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+ };
+ #endif
+
+Index: linux-2.6.0-test5/drivers/video/sis/sis_accel.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/sis/sis_accel.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/sis/sis_accel.h 2003-09-27 11:38:35.395147504 +0800
+@@ -47,7 +47,7 @@
+ #define TRAPAZOID_FILL 0x00000005 /* Fill trapezoid */
+ #define TRANSPARENT_BITBLT 0x00000006 /* Transparent Blit */
+
+-/* Additional engine commands for 310/325 */
++/* Additional engine commands for 315 */
+ #define ALPHA_BLEND 0x00000007 /* Alpha blend ? */
+ #define A3D_FUNCTION 0x00000008 /* 3D command ? */
+ #define CLEAR_Z_BUFFER 0x00000009 /* ? */
+@@ -90,11 +90,11 @@
+ #define NO_RESET_COUNTER 0x00400000
+ #define NO_LAST_PIXEL 0x00200000
+
+-/* Subfunctions for Color/Enhanced Color Expansion (310/325 only) */
++/* Subfunctions for Color/Enhanced Color Expansion (315 only) */
+ #define COLOR_TO_MONO 0x00100000
+ #define AA_TEXT 0x00200000
+
+-/* Some general registers for 310/325 series */
++/* Some general registers for 315 series */
+ #define SRC_ADDR 0x8200
+ #define SRC_PITCH 0x8204
+ #define AGP_BASE 0x8206 /* color-depth dependent value */
+@@ -326,7 +326,7 @@
+
+
+
+-/* ----------- SiS 310/325 series --------------- */
++/* -------------- SiS 315 series --------------- */
+
+ /* Q_STATUS:
+ bit 31 = 1: All engines idle and all queues empty
+@@ -342,16 +342,27 @@
+ bits 7:0: 2D counter 1
+
+ Where is the command queue length (current amount of commands the queue
+- can accept) on the 310/325 series? (The current implementation is taken
+- from 300 series and certainly wrong...)
++ can accept) on the 315 series?
+ */
+
+ /* TW: FIXME: CmdQueLen is... where....? */
++/* We assume a length of 4 bytes per command; since 512K of
++ * of RAM are allocated, the number of commands is easily
++ * calculated (assuming that there is no 3D support yet)
++ * We calculate it very cautiously (128K only) and let the
++ * rest to the (never?)-to-come (?) 3D engine. (The 3D engine
++ * can use a similar technique, using the remaining 384K,
++ * hence a queue overflow is avoided)
++ * UPDATE: This technique causes a terrible system latency
++ * on integrated chipsets. Disable the queue handling for
++ * now.
++ */
+ #define SiS310Idle \
+ { \
+ while( (MMIO_IN16(ivideo.mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
+ while( (MMIO_IN16(ivideo.mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
+- CmdQueLen=MMIO_IN16(ivideo.mmio_vbase, Q_STATUS); \
++ CmdQueLen = 0; \
++ /*CmdQueLen = ((128 * 1024) / 4) - 64; */ \
+ }
+
+ #define SiS310SetupSRCBase(base) \
+Index: linux-2.6.0-test5/drivers/video/sis/sis_main.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/sis/sis_main.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/sis/sis_main.c 2003-09-27 11:38:35.516129112 +0800
+@@ -1,25 +1,20 @@
+ /*
+- * SiS 300/630/730/540/315/550/650/740 frame buffer device
++ * SiS 300/630/730/540/315/550/650/740/330/660/760 frame buffer driver
+ * for Linux kernels 2.4.x and 2.5.x
+ *
+- * Partly based on the VBE 2.0 compliant graphic boards framebuffer driver,
++ * (C) 1999 Silicon Integrated Systems, Inc.
++ * (C) 2001-2003 Thomas Winischhofer, Vienna, Austria.
++ *
++ * Author: Thomas Winischhofer <thomas@winischhofer.net>
++ *
++ * Author of code base:
++ * SiS (www.sis.com.tw)
++ *
++ * See http://www.winischhofer.net/ for more information and updates
++ *
++ * Originally based on the VBE 2.0 compliant graphic boards framebuffer driver,
+ * which is (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de>
+ *
+- * Authors: SiS (www.sis.com.tw)
+- * (Various others)
+- * Thomas Winischhofer <thomas@winischhofer.net>:
+- * - SiS Xabre (330) support
+- * - many fixes and enhancements for all chipset series,
+- * - extended bridge handling, TV output for Chrontel 7005
+- * - 650/LVDS support (for LCD panels up to 1600x1200)
+- * - 650/740/Chrontel 7019 support
+- * - 30xB/30xLV LCD, TV and VGA2 support
+- * - memory queue handling enhancements,
+- * - 2D acceleration and y-panning,
+- * - portation to 2.5 API
+- * - etc.
+- * (see http://www.winischhofer.net/
+- * for more information and updates)
+ */
+
+ #include <linux/config.h>
+@@ -43,6 +38,8 @@
+ #include <linux/fs.h>
+ #include <linux/agp_backend.h>
+ #include <linux/types.h>
++#include <linux/vmalloc.h>
++#include <asm/uaccess.h>
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ #include <linux/spinlock.h>
+@@ -79,6 +76,12 @@
+ #endif
+ #endif
+
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,69)
++#error "This version of sisfb requires at least 2.5.69"
++#endif
++#endif
++
+ /* -------------------- Macro definitions ---------------------------- */
+
+ #undef SISFBDEBUG /* TW: no debugging */
+@@ -134,9 +137,19 @@
+
+ if (!init) {
+ init = TRUE;
+- pdev = pci_find_device(PCI_VENDOR_ID_SI, ivideo.chip_id, pdev);
+- if (pdev)
+- valid_pdev = TRUE;
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,74)
++ pci_for_each_dev(pdev) {
++#else
++ while((pdev = pci_find_device(PCI_VENDOR_ID_SI, PCI_ANY_ID, pdev))) {
++#endif
++ DPRINTK("sisfb: Current: 0x%x, target: 0x%x\n",
++ pdev->device, ivideo.chip_id);
++ if ((pdev->vendor == PCI_VENDOR_ID_SI)
++ && (pdev->device == ivideo.chip_id)) {
++ valid_pdev = TRUE;
++ break;
++ }
++ }
+ }
+
+ if (!valid_pdev) {
+@@ -163,6 +176,7 @@
+ if (!init) {
+ init = TRUE;
+ switch (ivideo.chip) {
++#ifdef CONFIG_FB_SIS_300
+ case SIS_540:
+ nbridge_id = PCI_DEVICE_ID_SI_540;
+ break;
+@@ -172,23 +186,42 @@
+ case SIS_730:
+ nbridge_id = PCI_DEVICE_ID_SI_730;
+ break;
++#endif
++#ifdef CONFIG_FB_SIS_315
+ case SIS_550:
+ nbridge_id = PCI_DEVICE_ID_SI_550;
+ break;
+ case SIS_650:
+ nbridge_id = PCI_DEVICE_ID_SI_650;
+ break;
+- case SIS_740:
++ case SIS_740:
+ nbridge_id = PCI_DEVICE_ID_SI_740;
+ break;
++ case SIS_660:
++ nbridge_id = PCI_DEVICE_ID_SI_660;
++ break;
++ case SIS_760:
++ nbridge_id = PCI_DEVICE_ID_SI_760;
++ break;
++#endif
+ default:
+ nbridge_id = 0;
+ break;
+ }
+
+- pdev = pci_find_device(PCI_VENDOR_ID_SI, nbridge_id, pdev);
+- if (pdev)
+- valid_pdev = TRUE;
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,74)
++ pci_for_each_dev(pdev) {
++#else
++ while((pdev = pci_find_device(PCI_VENDOR_ID_SI, PCI_ANY_ID, pdev))) {
++#endif
++ DPRINTK("Current: 0x%x, target: 0x%x\n",
++ pdev->device, ivideo.chip_id);
++ if ((pdev->vendor == PCI_VENDOR_ID_SI)
++ && (pdev->device == nbridge_id)) {
++ valid_pdev = TRUE;
++ break;
++ }
++ }
+ }
+
+ if (!valid_pdev) {
+@@ -207,66 +240,291 @@
+
+ /* ------------------ Internal helper routines ----------------- */
+
+-static void sisfb_search_mode(const char *name)
++static BOOLEAN sisfb_verify_rate(struct sisfb_monitor *monitor, int mode_idx, int rate_idx, int rate)
+ {
+- int i = 0, j = 0;
++ int htotal, vtotal;
++ unsigned int dclock, hsync;
+
+- if(name == NULL) {
+- printk(KERN_ERR "sisfb: Internal error, using default mode.\n");
+- sisfb_mode_idx = DEFAULT_MODE;
+- return;
++ if(!monitor->datavalid) return TRUE;
++
++ if(mode_idx < 0) return FALSE;
++
++ if(rate < (monitor->vmin - 1)) return FALSE;
++ if(rate > (monitor->vmax + 1)) return FALSE;
++
++ if(sisfb_gettotalfrommode(&SiS_Pr, &sishw_ext, sisbios_mode[mode_idx].mode_no,
++ &htotal, &vtotal, rate_idx)) {
++ dclock = (htotal * vtotal * rate) / 1000;
++ if(dclock > (monitor->dclockmax + 1000)) return FALSE;
++ hsync = dclock / htotal;
++ if(hsync < (monitor->hmin - 1)) return FALSE;
++ if(hsync > (monitor->hmax + 1)) return FALSE;
++ } else {
++ return FALSE;
+ }
+-
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+- if (!strcmp(name, sisbios_mode[MODE_INDEX_NONE].name)) {
+- printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
+- sisfb_mode_idx = DEFAULT_MODE;
+- return;
++ return TRUE;
++};
++
++static BOOLEAN sisfb_interpret_edid(struct sisfb_monitor *monitor, unsigned char *buffer)
++{
++ int i, j, xres, yres, refresh, index;
++ u32 emodes;
++
++ if(buffer[0] != 0x00 || buffer[1] != 0xff ||
++ buffer[2] != 0xff || buffer[3] != 0xff ||
++ buffer[4] != 0xff || buffer[5] != 0xff ||
++ buffer[6] != 0xff || buffer[7] != 0x00) {
++ printk(KERN_DEBUG "sisfb: Bad EDID header\n");
++ return FALSE;
+ }
+-#endif
+
+- while(sisbios_mode[i].mode_no != 0) {
+- if (!strcmp(name, sisbios_mode[i].name)) {
+- sisfb_mode_idx = i;
+- j = 1;
+- break;
+- }
+- i++;
++ if(buffer[0x12] != 0x01) {
++ printk(KERN_INFO "sisfb: EDID version %d not supported\n",
++ buffer[0x12]);
++ return FALSE;
++ }
++
++ monitor->feature = buffer[0x18];
++
++ if(!buffer[0x14] & 0x80) {
++ if(!(buffer[0x14] & 0x08)) {
++ printk(KERN_INFO "sisfb: WARNING: Monitor does not support separate syncs\n");
++ }
++ }
++
++ if(buffer[0x13] >= 0x01) {
++ /* EDID V1 rev 1 and 2: Search for monitor descriptor
++ * to extract ranges
++ */
++ j = 0x36;
++ for(i=0; i<4; i++) {
++ if(buffer[j] == 0x00 && buffer[j + 1] == 0x00 &&
++ buffer[j + 2] == 0x00 && buffer[j + 3] == 0xfd &&
++ buffer[j + 4] == 0x00) {
++ monitor->hmin = buffer[j + 7];
++ monitor->hmax = buffer[j + 8];
++ monitor->vmin = buffer[j + 5];
++ monitor->vmax = buffer[j + 6];
++ monitor->dclockmax = buffer[j + 9] * 10 * 1000;
++ monitor->datavalid = TRUE;
++ break;
++ }
++ j += 18;
++ }
++ }
++
++ if(!monitor->datavalid) {
++ /* Otherwise: Get a range from the list of supported
++ * Estabished Timings. This is not entirely accurate,
++ * because fixed frequency monitors are not supported
++ * that way.
++ */
++ monitor->hmin = 65535; monitor->hmax = 0;
++ monitor->vmin = 65535; monitor->vmax = 0;
++ monitor->dclockmax = 0;
++ emodes = buffer[0x23] | (buffer[0x24] << 8) | (buffer[0x25] << 16);
++ for(i = 0; i < 13; i++) {
++ if(emodes & sisfb_ddcsmodes[i].mask) {
++ if(monitor->hmin > sisfb_ddcsmodes[i].h) monitor->hmin = sisfb_ddcsmodes[i].h;
++ if(monitor->hmax < sisfb_ddcsmodes[i].h) monitor->hmax = sisfb_ddcsmodes[i].h + 1;
++ if(monitor->vmin > sisfb_ddcsmodes[i].v) monitor->vmin = sisfb_ddcsmodes[i].v;
++ if(monitor->vmax < sisfb_ddcsmodes[i].v) monitor->vmax = sisfb_ddcsmodes[i].v;
++ if(monitor->dclockmax < sisfb_ddcsmodes[i].d) monitor->dclockmax = sisfb_ddcsmodes[i].d;
++ }
++ }
++ index = 0x26;
++ for(i = 0; i < 8; i++) {
++ xres = (buffer[index] + 31) * 8;
++ switch(buffer[index + 1] & 0xc0) {
++ case 0xc0: yres = (xres * 9) / 16; break;
++ case 0x80: yres = (xres * 4) / 5; break;
++ case 0x40: yres = (xres * 3) / 4; break;
++ default: yres = xres; break;
++ }
++ refresh = (buffer[index + 1] & 0x3f) + 60;
++ if((xres >= 640) && (yres >= 480)) {
++ for(j = 0; j < 8; j++) {
++ if((xres == sisfb_ddcfmodes[j].x) &&
++ (yres == sisfb_ddcfmodes[j].y) &&
++ (refresh == sisfb_ddcfmodes[j].v)) {
++ if(monitor->hmin > sisfb_ddcfmodes[j].h) monitor->hmin = sisfb_ddcfmodes[j].h;
++ if(monitor->hmax < sisfb_ddcfmodes[j].h) monitor->hmax = sisfb_ddcfmodes[j].h + 1;
++ if(monitor->vmin > sisfb_ddcsmodes[j].v) monitor->vmin = sisfb_ddcsmodes[j].v;
++ if(monitor->vmax < sisfb_ddcsmodes[j].v) monitor->vmax = sisfb_ddcsmodes[j].v;
++ if(monitor->dclockmax < sisfb_ddcsmodes[j].d) monitor->dclockmax = sisfb_ddcsmodes[i].d;
++ }
++ }
++ }
++ index += 2;
++ }
++ if((monitor->hmin <= monitor->hmax) && (monitor->vmin <= monitor->vmax)) {
++ monitor->datavalid = TRUE;
++ }
++ }
++
++ return(monitor->datavalid);
++}
++
++static void sisfb_handle_ddc(struct sisfb_monitor *monitor, int crtno)
++{
++ USHORT temp, i, realcrtno = crtno;
++ unsigned char buffer[256];
++
++ monitor->datavalid = FALSE;
++
++ if(crtno) {
++ if(ivideo.vbflags & CRT2_LCD) realcrtno = 1;
++ else if(ivideo.vbflags & CRT2_VGA) realcrtno = 2;
++ else return;
++ }
++
++ if((sisfb_crt1off) && (!crtno)) return;
++
++ temp = SiS_HandleDDC(&SiS_Pr, ivideo.vbflags, sisvga_engine, realcrtno, 0, &buffer[0]);
++ if((!temp) || (temp == 0xffff)) {
++ printk(KERN_INFO "sisfb: CRT%d DDC probing failed\n", crtno + 1);
++ return;
++ } else {
++ printk(KERN_INFO "sisfb: CRT%d DDC supported\n", crtno + 1);
++ printk(KERN_INFO "sisfb: CRT%d DDC level: %s%s%s%s\n",
++ crtno + 1,
++ (temp & 0x1a) ? "" : "[none of the supported]",
++ (temp & 0x02) ? "2 " : "",
++ (temp & 0x08) ? "D&P" : "",
++ (temp & 0x10) ? "FPDI-2" : "");
++ if(temp & 0x02) {
++ i = 3; /* Number of retrys */
++ do {
++ temp = SiS_HandleDDC(&SiS_Pr, ivideo.vbflags, sisvga_engine,
++ realcrtno, 1, &buffer[0]);
++ } while((temp) && i--);
++ if(!temp) {
++ if(sisfb_interpret_edid(monitor, &buffer[0])) {
++ printk(KERN_INFO "sisfb: Monitor range H %d-%dKHz, V %d-%dHz, Max. dotclock %dMHz\n",
++ monitor->hmin, monitor->hmax, monitor->vmin, monitor->vmax,
++ monitor->dclockmax / 1000);
++ } else {
++ printk(KERN_INFO "sisfb: CRT%d DDC EDID corrupt\n", crtno + 1);
++ }
++ } else {
++ printk(KERN_INFO "sisfb: CRT%d DDC reading failed\n", crtno + 1);
++ }
++ } else {
++ printk(KERN_INFO "sisfb: VESA D&P and FPDI-2 not supported yet\n");
++ }
+ }
+- if(!j) printk(KERN_INFO "sisfb: Invalid mode '%s'\n", name);
+ }
+
+-static void sisfb_search_vesamode(unsigned int vesamode)
++static void sisfb_search_vesamode(unsigned int vesamode, BOOLEAN quiet)
+ {
+ int i = 0, j = 0;
+
+ if(vesamode == 0) {
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ sisfb_mode_idx = MODE_INDEX_NONE;
+ #else
+- printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
++ if(!quiet)
++ printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
+ sisfb_mode_idx = DEFAULT_MODE;
+-#endif
++#endif
+ return;
+ }
+
+ vesamode &= 0x1dff; /* Clean VESA mode number from other flags */
+
++ while(sisbios_mode[i++].mode_no != 0) {
++ if( (sisbios_mode[i-1].vesa_mode_no_1 == vesamode) ||
++ (sisbios_mode[i-1].vesa_mode_no_2 == vesamode) ) {
++ if(sisfb_fstn) {
++ if(sisbios_mode[i-1].mode_no == 0x50 ||
++ sisbios_mode[i-1].mode_no == 0x56 ||
++ sisbios_mode[i-1].mode_no == 0x53) continue;
++ } else {
++ if(sisbios_mode[i-1].mode_no == 0x5a ||
++ sisbios_mode[i-1].mode_no == 0x5b) continue;
++ }
++ sisfb_mode_idx = i - 1;
++ j = 1;
++ break;
++ }
++ }
++ if((!j) && !quiet) printk(KERN_ERR "sisfb: Invalid VESA mode 0x%x'\n", vesamode);
++}
++
++static void sisfb_search_mode(char *name, BOOLEAN quiet)
++{
++ int i = 0;
++ unsigned int j = 0, xres = 0, yres = 0, depth = 0, rate = 0;
++ char strbuf[16], strbuf1[20];
++ char *nameptr = name;
++
++ if(name == NULL) {
++ if(!quiet)
++ printk(KERN_ERR "sisfb: Internal error, using default mode.\n");
++ sisfb_mode_idx = DEFAULT_MODE;
++ return;
++ }
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
++ if (!strnicmp(name, sisbios_mode[MODE_INDEX_NONE].name, strlen(name))) {
++ if(!quiet)
++ printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
++ sisfb_mode_idx = DEFAULT_MODE;
++ return;
++ }
++#endif
++ if(strlen(name) <= 19) {
++ strcpy(strbuf1, name);
++ for(i=0; i<strlen(strbuf1); i++) {
++ if(strbuf1[i] < '0' || strbuf1[i] > '9') strbuf1[i] = ' ';
++ }
++
++ /* This does some fuzzy mode naming detection */
++ if(sscanf(strbuf1, "%u %u %u %u", &xres, &yres, &depth, &rate) == 4) {
++ if((rate <= 32) || (depth > 32)) {
++ j = rate; rate = depth; depth = j;
++ }
++ sprintf(strbuf, "%ux%ux%u", xres, yres, depth);
++ nameptr = strbuf;
++ ivideo.refresh_rate = sisfb_parm_rate = rate;
++ } else if(sscanf(strbuf1, "%u %u %u", &xres, &yres, &depth) == 3) {
++ sprintf(strbuf, "%ux%ux%u", xres, yres, depth);
++ nameptr = strbuf;
++ } else {
++ xres = 0;
++ if((sscanf(strbuf1, "%u %u", &xres, &yres) == 2) && (xres != 0)) {
++ sprintf(strbuf, "%ux%ux8", xres, yres);
++ nameptr = strbuf;
++ } else {
++ sisfb_search_vesamode(simple_strtoul(name, NULL, 0), quiet);
++ return;
++ }
++ }
++ }
++
++ i = 0; j = 0;
+ while(sisbios_mode[i].mode_no != 0) {
+- if( (sisbios_mode[i].vesa_mode_no_1 == vesamode) ||
+- (sisbios_mode[i].vesa_mode_no_2 == vesamode) ) {
+- sisfb_mode_idx = i;
+- j = 1;
+- break;
++ if(!strnicmp(nameptr, sisbios_mode[i++].name, strlen(nameptr))) {
++ if(sisfb_fstn) {
++ if(sisbios_mode[i-1].mode_no == 0x50 ||
++ sisbios_mode[i-1].mode_no == 0x56 ||
++ sisbios_mode[i-1].mode_no == 0x53) continue;
++ } else {
++ if(sisbios_mode[i-1].mode_no == 0x5a ||
++ sisbios_mode[i-1].mode_no == 0x5b) continue;
++ }
++ sisfb_mode_idx = i - 1;
++ j = 1;
++ break;
+ }
+- i++;
+ }
+- if(!j) printk(KERN_INFO "sisfb: Invalid VESA mode 0x%x'\n", vesamode);
++ if((!j) && !quiet) printk(KERN_ERR "sisfb: Invalid mode '%s'\n", nameptr);
++
+ }
+
+-static int sisfb_validate_mode(int myindex)
++static int sisfb_validate_mode(int myindex, unsigned long vbflags)
+ {
+- u16 xres, yres;
++ u16 xres, yres, myres;
+
+ #ifdef CONFIG_FB_SIS_300
+ if(sisvga_engine == SIS_300_VGA) {
+@@ -283,8 +541,10 @@
+ }
+ #endif
+
+- switch (ivideo.disp_state & DISPTYPE_DISP2) {
+- case DISPTYPE_LCD:
++ myres = sisbios_mode[myindex].yres;
++
++ switch (vbflags & VB_DISPTYPE_DISP2) {
++ case CRT2_LCD:
+ switch (sishw_ext.ulCRT2LCDType) {
+ case LCD_640x480:
+ xres = 640; yres = 480; break;
+@@ -306,140 +566,209 @@
+ xres = 1400; yres = 1050; break;
+ case LCD_1600x1200:
+ xres = 1600; yres = 1200; break;
+- case LCD_320x480: /* TW: FSTN */
++ case LCD_320x480: /* FSTN (old) */
+ xres = 320; yres = 480; break;
++ case LCD_640x480_2: /* FSTN (new) */
++ case LCD_640x480_3:
++ xres = 640; yres = 480; break;
+ default:
+ xres = 0; yres = 0; break;
+ }
+- if(sisbios_mode[myindex].xres > xres) {
+- return(-1);
++
++ if(SiS_Pr.SiS_CustomT == CUT_BARCO1366) {
++ xres = 1360; yres = 1024;
+ }
+- if(sisbios_mode[myindex].yres > yres) {
++
++ if(SiS_Pr.SiS_CustomT == CUT_PANEL848) {
++ xres = 848; yres = 480;
++ } else {
++ if(sisbios_mode[myindex].xres > xres) {
++ return(-1);
++ }
++ if(myres > yres) {
+ return(-1);
++ }
+ }
+- if((sishw_ext.usExternalChip == 0x01) || /* LVDS */
+- (sishw_ext.usExternalChip == 0x05) || /* LVDS+Chrontel */
+- (sishw_ext.Is301BDH)) { /* 301B-DH */
++
++ if(vbflags & (VB_LVDS | VB_30xBDH)) {
+ switch (sisbios_mode[myindex].xres) {
++ case 320:
++ if((myres != 200) && (myres != 240))
++ return(-1);
++ if((myres == 240) || (myres == 480)) {
++ if(!sisfb_fstn) {
++ if(sisbios_mode[myindex].mode_no == 0x5a ||
++ sisbios_mode[myindex].mode_no == 0x5b)
++ return(-1);
++ } else {
++ if(sisbios_mode[myindex].mode_no == 0x50 ||
++ sisbios_mode[myindex].mode_no == 0x56 ||
++ sisbios_mode[myindex].mode_no == 0x53)
++ return(-1);
++ }
++ }
++ if(SiS_Pr.SiS_CustomT == CUT_PANEL848) return(-1);
++ break;
++ case 400:
++ if(myres != 300) return(-1);
++ if(SiS_Pr.SiS_CustomT == CUT_PANEL848) return(-1);
++ break;
+ case 512:
+- if(sisbios_mode[myindex].yres != 512) return -1;
+- if(sishw_ext.ulCRT2LCDType == LCD_1024x600) return -1;
++ if(myres != 384) return(-1);
++ if(sishw_ext.ulCRT2LCDType == LCD_1024x600) return(-1);
++ if(SiS_Pr.SiS_CustomT == CUT_PANEL848) return(-1);
+ break;
+ case 640:
+- if((sisbios_mode[myindex].yres != 400) &&
+- (sisbios_mode[myindex].yres != 480))
++ if((myres != 400) && (myres != 480))
+ return -1;
++ if(SiS_Pr.SiS_CustomT == CUT_PANEL848) {
++ if(myres == 400)
++ return(-1);
++ }
+ break;
+ case 800:
+- if(sisbios_mode[myindex].yres != 600) return -1;
++ if(myres != 600) return(-1);
++ break;
++ case 848:
++ if(SiS_Pr.SiS_CustomT != CUT_PANEL848) return(-1);
++ if(myres != 480) return(-1);
+ break;
+ case 1024:
+- if((sisbios_mode[myindex].yres != 600) &&
+- (sisbios_mode[myindex].yres != 768))
+- return -1;
+- if((sisbios_mode[myindex].yres == 600) &&
++ if((myres != 600) && (myres != 768))
++ return(-1);
++ if((myres == 600) &&
+ (sishw_ext.ulCRT2LCDType != LCD_1024x600))
+- return -1;
++ return(-1);
+ break;
+ case 1152:
+- if((sisbios_mode[myindex].yres) != 768) return -1;
+- if(sishw_ext.ulCRT2LCDType != LCD_1152x768) return -1;
++ if(myres != 768) return(-1);
++ if(sishw_ext.ulCRT2LCDType != LCD_1152x768) return(-1);
+ break;
+ case 1280:
+- if((sisbios_mode[myindex].yres != 768) &&
+- (sisbios_mode[myindex].yres != 1024))
+- return -1;
+- if((sisbios_mode[myindex].yres == 768) &&
++ if((myres != 768) && (myres != 1024))
++ return(-1);
++ if((myres == 768) &&
+ (sishw_ext.ulCRT2LCDType != LCD_1280x768))
+- return -1;
++ return(-1);
++ if(SiS_Pr.SiS_CustomT == CUT_PANEL848) return(-1);
++ break;
++ case 1360:
++ if(SiS_Pr.SiS_CustomT != CUT_BARCO1366) return(-1);
++ if(myres != 1024) return(-1);
+ break;
+ case 1400:
+- if(sisbios_mode[myindex].yres != 1050) return -1;
++ if(myres != 1050) return(-1);
++ if(SiS_Pr.SiS_CustomT == CUT_PANEL848) return(-1);
+ break;
+ case 1600:
+- if(sisbios_mode[myindex].yres != 1200) return -1;
++ if(myres != 1200) return(-1);
++ if(SiS_Pr.SiS_CustomT == CUT_PANEL848) return(-1);
+ break;
+ default:
+- return -1;
++ return(-1);
+ }
+ } else {
+ switch (sisbios_mode[myindex].xres) {
++ case 320:
++ if((myres != 200) && (myres != 240))
++ return -1;
++ break;
++ case 400:
++ if(myres != 300) return(-1);
++ break;
+ case 512:
+- if(sisbios_mode[myindex].yres != 512) return -1;
++ if(myres != 384) return(-1);
+ break;
+ case 640:
+- if((sisbios_mode[myindex].yres != 400) &&
+- (sisbios_mode[myindex].yres != 480))
+- return -1;
++ if((myres != 400) && (myres != 480))
++ return(-1);
+ break;
+ case 800:
+- if(sisbios_mode[myindex].yres != 600) return -1;
++ if(myres != 600) return(-1);
+ break;
+ case 1024:
+- if(sisbios_mode[myindex].yres != 768) return -1;
++ if(myres != 768) return(-1);
+ break;
+ case 1280:
+- if((sisbios_mode[myindex].yres != 960) &&
+- (sisbios_mode[myindex].yres != 1024))
+- return -1;
+- if(sisbios_mode[myindex].yres == 960) {
+- if(sishw_ext.ulCRT2LCDType == LCD_1400x1050)
+- return -1;
++ if((myres != 960) && (myres != 768) && (myres != 1024))
++ return(-1);
++ if((myres == 768) || (myres == 960)) {
++ if(sishw_ext.ulCRT2LCDType == LCD_1400x1050)
++ return(-1);
++ }
++ if(myres == 768) {
++ if(sishw_ext.ulCRT2LCDType == LCD_1280x960)
++ return(-1);
+ }
+ break;
+ case 1400:
+- if(sisbios_mode[myindex].yres != 1050) return -1;
++ if(myres != 1050) return(-1);
+ break;
+ case 1600:
+- if(sisbios_mode[myindex].yres != 1200) return -1;
++ if(myres != 1200) return(-1);
+ break;
+ default:
+- return -1;
++ return(-1);
+ }
+ }
+ break;
+- case DISPTYPE_TV:
++
++ case CRT2_TV:
+ switch (sisbios_mode[myindex].xres) {
++ case 320:
++ if(vbflags & VB_CHRONTEL) return(-1);
++ if((myres != 200) && (myres != 240))
++ return(-1);
++ break;
++ case 400:
++ if(vbflags & VB_CHRONTEL) return(-1);
++ if(myres != 300) return(-1);
++ break;
+ case 512:
++ if(vbflags & VB_CHRONTEL) return(-1);
++ if((vbflags & VB_SISBRIDGE) && (vbflags & TV_NTSC))
++ return(-1);
++ if(myres != 384) return(-1);
++ break;
+ case 640:
+- case 800:
++ if((myres != 400) && (myres != 480))
++ return(-1);
++ if((vbflags & VB_CHRONTEL) && (myres == 400))
++ return(-1);
+ break;
+ case 720:
+- if (ivideo.TV_type == TVMODE_NTSC) {
+- if (sisbios_mode[myindex].yres != 480) {
+- return(-1);
+- }
+- } else if (ivideo.TV_type == TVMODE_PAL) {
+- if (sisbios_mode[myindex].yres != 576) {
+- return(-1);
+- }
+- }
+- /* TW: LVDS/CHRONTEL does not support 720 */
+- if (ivideo.hasVB == HASVB_LVDS_CHRONTEL ||
+- ivideo.hasVB == HASVB_CHRONTEL) {
+- return(-1);
+- }
++ if(vbflags & VB_CHRONTEL) return(-1);
++ if((vbflags & TV_NTSC) && (myres != 480))
++ return(-1);
++ if((vbflags & TV_PAL) && (myres != 576))
++ return(-1);
++ break;
++ case 768:
++ if(vbflags & VB_CHRONTEL) return(-1);
++ if(!(vbflags & TV_PAL)) return(-1);
++ if(myres != 576) return(-1);
++ break;
++ case 800:
++ if(myres != 600) return(-1);
+ break;
+ case 1024:
+- if (ivideo.TV_type == TVMODE_NTSC) {
+- if(sisbios_mode[myindex].bpp == 32) {
+- return(-1);
+- }
+- }
+- /* TW: LVDS/CHRONTEL only supports < 800 (1024 on 650/Ch7019)*/
+- if (ivideo.hasVB == HASVB_LVDS_CHRONTEL ||
+- ivideo.hasVB == HASVB_CHRONTEL) {
+- if(ivideo.chip < SIS_315H) {
++ if(vbflags & VB_301) return(-1);
++ if(vbflags & VB_CHRONTEL) {
++ if(ivideo.chip < SIS_315H) {
+ return(-1);
+- }
++ }
+ }
+ break;
+ default:
+ return(-1);
+ }
+ break;
+- case DISPTYPE_CRT2:
+- if(sisbios_mode[myindex].xres > 1280) return -1;
++
++ case CRT2_VGA:
++ if(sisbios_mode[myindex].xres > 1600) return(-1);
++ if(!(vbflags & (VB_301B|VB_302B))) {
++ if(sisbios_mode[myindex].xres > 1400) return(-1);
++ }
+ break;
+ }
+ return(myindex);
+@@ -453,15 +782,20 @@
+ return;
+
+ while(sis_crt2type[i].type_no != -1) {
+- if (!strcmp(name, sis_crt2type[i].name)) {
++ if (!strnicmp(name, sis_crt2type[i].name, strlen(sis_crt2type[i].name))) {
+ sisfb_crt2type = sis_crt2type[i].type_no;
+ sisfb_tvplug = sis_crt2type[i].tvplug_no;
++ sisfb_dstn = (sis_crt2type[i].flags & FL_550_DSTN) ? 1 : 0;
++ sisfb_fstn = (sis_crt2type[i].flags & FL_550_FSTN) ? 1 : 0;
+ break;
+ }
+ i++;
+ }
+ if(sisfb_crt2type < 0)
+- printk(KERN_INFO "sisfb: Invalid CRT2 type: %s\n", name);
++ printk(KERN_ERR "sisfb: Invalid CRT2 type: %s\n", name);
++ if(ivideo.chip != SIS_550) {
++ sisfb_dstn = sisfb_fstn = 0;
++ }
+ }
+
+ static void sisfb_search_queuemode(const char *name)
+@@ -472,23 +806,23 @@
+ return;
+
+ while (sis_queuemode[i].type_no != -1) {
+- if (!strcmp(name, sis_queuemode[i].name)) {
++ if (!strnicmp(name, sis_queuemode[i].name, strlen(sis_queuemode[i].name))) {
+ sisfb_queuemode = sis_queuemode[i].type_no;
+ break;
+ }
+ i++;
+ }
+ if (sisfb_queuemode < 0)
+- printk(KERN_INFO "sisfb: Invalid queuemode type: %s\n", name);
++ printk(KERN_ERR "sisfb: Invalid queuemode type: %s\n", name);
+ }
+
+-static u8 sisfb_search_refresh_rate(unsigned int rate)
++static u8 sisfb_search_refresh_rate(unsigned int rate, int mode_idx)
+ {
+ u16 xres, yres;
+ int i = 0;
+
+- xres = sisbios_mode[sisfb_mode_idx].xres;
+- yres = sisbios_mode[sisfb_mode_idx].yres;
++ xres = sisbios_mode[mode_idx].xres;
++ yres = sisbios_mode[mode_idx].yres;
+
+ sisfb_rate_idx = 0;
+ while ((sisfb_vrate[i].idx != 0) && (sisfb_vrate[i].xres <= xres)) {
+@@ -536,23 +870,60 @@
+ return;
+
+ while (sis_tvtype[i].type_no != -1) {
+- if (!strcmp(name, sis_tvtype[i].name)) {
+- sisfb_tvmode = sis_tvtype[i].type_no;
++ if (!strnicmp(name, sis_tvtype[i].name, strlen(sis_tvtype[i].name))) {
++ ivideo.vbflags |= sis_tvtype[i].type_no;
+ break;
+ }
+ i++;
+ }
+ }
+
++static void sisfb_search_specialtiming(const char *name)
++{
++ int i = 0;
++ BOOLEAN found = FALSE;
++
++ if(name == NULL)
++ return;
++
++ if(!strnicmp(name, "none", 4)) {
++ SiS_Pr.SiS_CustomT = CUT_FORCENONE;
++ printk(KERN_DEBUG "sisfb: Special timing disabled\n");
++ } else {
++ while(mycustomttable[i].chipID != 0) {
++ if(!strnicmp(name,mycustomttable[i].optionName, strlen(mycustomttable[i].optionName))) {
++ SiS_Pr.SiS_CustomT = mycustomttable[i].SpecialID;
++ found = TRUE;
++ printk(KERN_INFO "sisfb: Special timing for %s %s forced\n",
++ mycustomttable[i].vendorName, mycustomttable[i].cardName);
++ break;
++ }
++ i++;
++ }
++ if(!found) {
++ printk(KERN_WARNING "sisfb: Invalid SpecialTiming parameter, valid are:");
++ printk(KERN_WARNING "\t\"none\" (to disable special timings)\n");
++ i = 0;
++ while(mycustomttable[i].chipID != 0) {
++ printk(KERN_WARNING "\t\"%s\" (for %s %s)\n",
++ mycustomttable[i].optionName,
++ mycustomttable[i].vendorName,
++ mycustomttable[i].cardName);
++ i++;
++ }
++ }
++ }
++}
++
+ static BOOLEAN sisfb_bridgeisslave(void)
+ {
+- unsigned char usScratchP1_00;
++ unsigned char P1_00;
+
+- if(ivideo.hasVB == HASVB_NONE) return FALSE;
++ if(!(ivideo.vbflags & VB_VIDEOBRIDGE)) return FALSE;
+
+- inSISIDXREG(SISPART1,0x00,usScratchP1_00);
+- if( ((sisvga_engine == SIS_300_VGA) && (usScratchP1_00 & 0xa0) == 0x20) ||
+- ((sisvga_engine == SIS_315_VGA) && (usScratchP1_00 & 0x50) == 0x10) ) {
++ inSISIDXREG(SISPART1,0x00,P1_00);
++ if( ((sisvga_engine == SIS_300_VGA) && (P1_00 & 0xa0) == 0x20) ||
++ ((sisvga_engine == SIS_315_VGA) && (P1_00 & 0x50) == 0x10) ) {
+ return TRUE;
+ } else {
+ return FALSE;
+@@ -597,7 +968,7 @@
+
+ static BOOLEAN sisfb_CheckVBRetrace(void)
+ {
+- if(ivideo.disp_state & DISPTYPE_DISP2) {
++ if(ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
+ if(sisfb_bridgeisslave()) {
+ return(sisfbcheckvretracecrt1());
+ } else {
+@@ -607,60 +978,195 @@
+ return(sisfbcheckvretracecrt1());
+ }
+
++static int sisfb_myblank(int blank)
++{
++ u8 sr01, sr11, sr1f, cr63=0, p2_0, p1_13;
++ BOOLEAN backlight = TRUE;
++
++ switch(blank) {
++ case 0: /* on */
++ sr01 = 0x00;
++ sr11 = 0x00;
++ sr1f = 0x00;
++ cr63 = 0x00;
++ p2_0 = 0x20;
++ p1_13 = 0x00;
++ backlight = TRUE;
++ break;
++ case 1: /* blank */
++ sr01 = 0x20;
++ sr11 = 0x00;
++ sr1f = 0x00;
++ cr63 = 0x00;
++ p2_0 = 0x20;
++ p1_13 = 0x00;
++ backlight = TRUE;
++ break;
++ case 2: /* no vsync */
++ sr01 = 0x20;
++ sr11 = 0x08;
++ sr1f = 0x80;
++ cr63 = 0x40;
++ p2_0 = 0x40;
++ p1_13 = 0x80;
++ backlight = FALSE;
++ break;
++ case 3: /* no hsync */
++ sr01 = 0x20;
++ sr11 = 0x08;
++ sr1f = 0x40;
++ cr63 = 0x40;
++ p2_0 = 0x80;
++ p1_13 = 0x40;
++ backlight = FALSE;
++ break;
++ case 4: /* off */
++ sr01 = 0x20;
++ sr11 = 0x08;
++ sr1f = 0xc0;
++ cr63 = 0x40;
++ p2_0 = 0xc0;
++ p1_13 = 0xc0;
++ backlight = FALSE;
++ break;
++ default:
++ return 1;
++ }
++
++ if(ivideo.currentvbflags & VB_DISPTYPE_CRT1) {
++
++ setSISIDXREG(SISSR, 0x01, ~0x20, sr01);
++
++ if( (!sisfb_thismonitor.datavalid) ||
++ ((sisfb_thismonitor.datavalid) &&
++ (sisfb_thismonitor.feature & 0xe0))) {
++
++ if(sisvga_engine == SIS_315_VGA) {
++ setSISIDXREG(SISCR, 0x63, 0xbf, cr63);
++ }
++
++ setSISIDXREG(SISSR, 0x1f, 0x3f, sr1f);
++ }
++
++ }
++
++ if(ivideo.currentvbflags & CRT2_LCD) {
++
++ if(ivideo.vbflags & (VB_301LV|VB_302LV)) {
++ if(backlight) {
++ SiS_SiS30xBLOn(&SiS_Pr, &sishw_ext);
++ } else {
++ SiS_SiS30xBLOff(&SiS_Pr, &sishw_ext);
++ }
++ } else if(sisvga_engine == SIS_315_VGA) {
++ if(ivideo.vbflags & VB_CHRONTEL) {
++ if(backlight) {
++ SiS_Chrontel701xBLOn(&SiS_Pr,&sishw_ext);
++ } else {
++ SiS_Chrontel701xBLOff(&SiS_Pr);
++ }
++ }
++ }
++
++ if(((sisvga_engine == SIS_300_VGA) &&
++ (ivideo.vbflags & (VB_301|VB_30xBDH|VB_LVDS))) ||
++ ((sisvga_engine == SIS_315_VGA) &&
++ ((ivideo.vbflags & (VB_LVDS | VB_CHRONTEL)) == VB_LVDS))) {
++ setSISIDXREG(SISSR, 0x11, ~0x0c, sr11);
++ }
++
++ if(sisvga_engine == SIS_300_VGA) {
++ if((ivideo.vbflags & (VB_301B|VB_302B)) &&
++ (!(ivideo.vbflags & VB_30xBDH))) {
++ setSISIDXREG(SISPART1, 0x13, 0x3f, p1_13);
++ }
++ } else if(sisvga_engine == SIS_315_VGA) {
++ if((ivideo.vbflags & (VB_301B|VB_302B)) &&
++ (!(ivideo.vbflags & VB_30xBDH))) {
++ setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0);
++ }
++ }
++
++ } else if(ivideo.currentvbflags & CRT2_VGA) {
++
++ if(ivideo.vbflags & (VB_301B|VB_302B)) {
++ setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0);
++ }
++
++ }
++
++ return(0);
++}
++
+ /* ----------- FBDev related routines for all series ----------- */
+
++static void sisfb_set_vparms(void)
++{
++ switch(ivideo.video_bpp) {
++ case 8:
++ ivideo.DstColor = 0x0000;
++ ivideo.SiS310_AccelDepth = 0x00000000;
++ ivideo.video_cmap_len = 256;
++ break;
++ case 16:
++ ivideo.DstColor = 0x8000;
++ ivideo.SiS310_AccelDepth = 0x00010000;
++ ivideo.video_cmap_len = 16;
++ break;
++ case 32:
++ ivideo.DstColor = 0xC000;
++ ivideo.SiS310_AccelDepth = 0x00020000;
++ ivideo.video_cmap_len = 16;
++ break;
++ default:
++ ivideo.video_cmap_len = 16;
++ printk(KERN_ERR "sisfb: Unsupported depth %d", ivideo.video_bpp);
++ ivideo.accel = 0;
++ break;
++ }
++}
++
+ static int sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
+ struct fb_info *info)
+ {
+- unsigned int htotal =
+- var->left_margin + var->xres + var->right_margin +
+- var->hsync_len;
+- unsigned int vtotal = 0;
++ unsigned int htotal = 0, vtotal = 0;
+ double drate = 0, hrate = 0;
+ int found_mode = 0;
+ int old_mode;
+- unsigned char reg;
++ u32 pixclock;
+
+- TWDEBUG("Inside do_set_var");
+-
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+- inSISIDXREG(SISCR,0x34,reg);
+- if(reg & 0x80) {
+- printk(KERN_INFO "sisfb: Cannot change display mode, X server is active\n");
+- return -EBUSY;
+- }
+-#endif
++ htotal = var->left_margin + var->xres + var->right_margin + var->hsync_len;
++
++ vtotal = var->upper_margin + var->lower_margin + var->vsync_len;
++
++ pixclock = var->pixclock;
+
+ if((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
+- vtotal = var->upper_margin + var->yres + var->lower_margin +
+- var->vsync_len;
++ vtotal += var->yres;
+ vtotal <<= 1;
+ } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+- vtotal = var->upper_margin + var->yres + var->lower_margin +
+- var->vsync_len;
++ vtotal += var->yres;
+ vtotal <<= 2;
+ } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+- vtotal = var->upper_margin + (var->yres/2) + var->lower_margin +
+- var->vsync_len;
+- } else vtotal = var->upper_margin + var->yres + var->lower_margin +
+- var->vsync_len;
++ vtotal += var->yres;
++ vtotal <<= 1;
++ } else vtotal += var->yres;
+
+ if(!(htotal) || !(vtotal)) {
+ DPRINTK("sisfb: Invalid 'var' information\n");
+ return -EINVAL;
+ }
+
+- if(var->pixclock && htotal && vtotal) {
+- drate = 1E12 / var->pixclock;
++ if(pixclock && htotal && vtotal) {
++ drate = 1E12 / pixclock;
+ hrate = drate / htotal;
+ ivideo.refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
+ } else ivideo.refresh_rate = 60;
+
+- /* TW: Calculation wrong for 1024x600 - force it to 60Hz */
+- if((var->xres == 1024) && (var->yres == 600)) ivideo.refresh_rate = 60;
+-
++#if 0
+ printk(KERN_DEBUG "sisfb: Change mode to %dx%dx%d-%dHz\n",
+ var->xres,var->yres,var->bits_per_pixel,ivideo.refresh_rate);
++#endif
+
+ old_mode = sisfb_mode_idx;
+ sisfb_mode_idx = 0;
+@@ -678,7 +1184,7 @@
+ }
+
+ if(found_mode)
+- sisfb_mode_idx = sisfb_validate_mode(sisfb_mode_idx);
++ sisfb_mode_idx = sisfb_validate_mode(sisfb_mode_idx, ivideo.currentvbflags);
+ else
+ sisfb_mode_idx = -1;
+
+@@ -689,12 +1195,21 @@
+ return -EINVAL;
+ }
+
+- if(sisfb_search_refresh_rate(ivideo.refresh_rate) == 0) {
++ if(sisfb_search_refresh_rate(ivideo.refresh_rate, sisfb_mode_idx) == 0) {
+ sisfb_rate_idx = sisbios_mode[sisfb_mode_idx].rate_idx;
+ ivideo.refresh_rate = 60;
+ }
+
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++ if(sisfb_thismonitor.datavalid) {
++ if(!sisfb_verify_rate(&sisfb_thismonitor, sisfb_mode_idx,
++ sisfb_rate_idx, ivideo.refresh_rate)) {
++ printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
++ }
++ }
++#endif
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ if(((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) && isactive) {
+ #else
+ if(isactive) {
+@@ -708,14 +1223,6 @@
+
+ outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
+
+- sisfb_post_setmode();
+-
+- DPRINTK("sisfb: Set new mode: %dx%dx%d-%d \n",
+- sisbios_mode[sisfb_mode_idx].xres,
+- sisbios_mode[sisfb_mode_idx].yres,
+- sisbios_mode[sisfb_mode_idx].bpp,
+- ivideo.refresh_rate);
+-
+ ivideo.video_bpp = sisbios_mode[sisfb_mode_idx].bpp;
+ ivideo.video_vwidth = ivideo.video_width = sisbios_mode[sisfb_mode_idx].xres;
+ ivideo.video_vheight = ivideo.video_height = sisbios_mode[sisfb_mode_idx].yres;
+@@ -725,53 +1232,38 @@
+ if(sisfb_accel) {
+ ivideo.accel = (var->accel_flags & FB_ACCELF_TEXT) ? -1 : 0;
+ }
+- switch(ivideo.video_bpp) {
+- case 8:
+- ivideo.DstColor = 0x0000;
+- ivideo.SiS310_AccelDepth = 0x00000000;
+- ivideo.video_cmap_len = 256;
+- break;
+- case 16:
+- ivideo.DstColor = 0x8000;
+- ivideo.SiS310_AccelDepth = 0x00010000;
+- ivideo.video_cmap_len = 16;
+- break;
+- case 32:
+- ivideo.DstColor = 0xC000;
+- ivideo.SiS310_AccelDepth = 0x00020000;
+- ivideo.video_cmap_len = 16;
+- break;
+- default:
+- ivideo.video_cmap_len = 16;
+- printk(KERN_ERR "sisfb: Unsupported depth %d", ivideo.video_bpp);
+- ivideo.accel = 0;
+- break;
+- }
++
++ sisfb_set_vparms();
++
++ ivideo.current_width = ivideo.video_width;
++ ivideo.current_height = ivideo.video_height;
++ ivideo.current_bpp = ivideo.video_bpp;
++ ivideo.current_htotal = htotal;
++ ivideo.current_vtotal = vtotal;
++ ivideo.current_pixclock = var->pixclock;
++ ivideo.current_refresh_rate = ivideo.refresh_rate;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
++ sisfb_lastrates[sisfb_mode_no] = ivideo.refresh_rate;
++#endif
++
++ sisfb_post_setmode();
+
+ }
+- TWDEBUG("End of do_set_var");
+ return 0;
+ }
+
+-#ifdef SISFB_PAN
+ static int sisfb_pan_var(struct fb_var_screeninfo *var)
+ {
+ unsigned int base;
+
+- TWDEBUG("Inside pan_var");
+-
+ if (var->xoffset > (var->xres_virtual - var->xres)) {
+- printk(KERN_INFO "Pan: xo: %d xv %d xr %d\n",
+- var->xoffset, var->xres_virtual, var->xres);
+ return -EINVAL;
+ }
+ if(var->yoffset > (var->yres_virtual - var->yres)) {
+- printk(KERN_INFO "Pan: yo: %d yv %d yr %d\n",
+- var->yoffset, var->yres_virtual, var->yres);
+ return -EINVAL;
+ }
+
+- base = var->yoffset * var->xres_virtual + var->xoffset;
++ base = var->yoffset * var->xres_virtual + var->xoffset;
+
+ /* calculate base bpp dep. */
+ switch(var->bits_per_pixel) {
+@@ -794,7 +1286,7 @@
+ if(sisvga_engine == SIS_315_VGA) {
+ setSISIDXREG(SISSR, 0x37, 0xFE, (base >> 24) & 0x01);
+ }
+- if(ivideo.disp_state & DISPTYPE_DISP2) {
++ if(ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
+ orSISIDXREG(SISPART1, sisfb_CRT2_write_enable, 0x01);
+ outSISIDXREG(SISPART1, 0x06, (base & 0xFF));
+ outSISIDXREG(SISPART1, 0x05, ((base >> 8) & 0xFF));
+@@ -803,10 +1295,8 @@
+ setSISIDXREG(SISPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);
+ }
+ }
+- TWDEBUG("End of pan_var");
+ return 0;
+ }
+-#endif
+
+ static void sisfb_bpp_to_var(struct fb_var_screeninfo *var)
+ {
+@@ -843,22 +1333,24 @@
+
+ void sis_dispinfo(struct ap_data *rec)
+ {
+- rec->minfo.bpp = ivideo.video_bpp;
+- rec->minfo.xres = ivideo.video_width;
+- rec->minfo.yres = ivideo.video_height;
+- rec->minfo.v_xres = ivideo.video_vwidth;
+- rec->minfo.v_yres = ivideo.video_vheight;
+- rec->minfo.org_x = ivideo.org_x;
+- rec->minfo.org_y = ivideo.org_y;
+- rec->minfo.vrate = ivideo.refresh_rate;
+- rec->iobase = ivideo.vga_base - 0x30;
+- rec->mem_size = ivideo.video_size;
+- rec->disp_state = ivideo.disp_state;
+- rec->version = (VER_MAJOR << 24) | (VER_MINOR << 16) | VER_LEVEL;
+- rec->hasVB = ivideo.hasVB;
+- rec->TV_type = ivideo.TV_type;
+- rec->TV_plug = ivideo.TV_plug;
+- rec->chip = ivideo.chip;
++ rec->minfo.bpp = ivideo.video_bpp;
++ rec->minfo.xres = ivideo.video_width;
++ rec->minfo.yres = ivideo.video_height;
++ rec->minfo.v_xres = ivideo.video_vwidth;
++ rec->minfo.v_yres = ivideo.video_vheight;
++ rec->minfo.org_x = ivideo.org_x;
++ rec->minfo.org_y = ivideo.org_y;
++ rec->minfo.vrate = ivideo.refresh_rate;
++ rec->iobase = ivideo.vga_base - 0x30;
++ rec->mem_size = ivideo.video_size;
++ rec->disp_state = ivideo.disp_state;
++ rec->version = (VER_MAJOR << 24) | (VER_MINOR << 16) | VER_LEVEL;
++ rec->hasVB = ivideo.hasVB;
++ rec->TV_type = ivideo.TV_type;
++ rec->TV_plug = ivideo.TV_plug;
++ rec->chip = ivideo.chip;
++ rec->vbflags = ivideo.vbflags;
++ rec->currentvbflags = ivideo.currentvbflags;
+ }
+
+ /* ------------ FBDev related routines for 2.4 series ----------- */
+@@ -873,7 +1365,6 @@
+ int A, B, C, D, E, F, temp;
+ double hrate, drate;
+
+- TWDEBUG("Inside crtc_to_var");
+ inSISIDXREG(SISSR, IND_SIS_COLOR_MODE, sr_data);
+
+ if (sr_data & SIS_INTERLACED_MODE)
+@@ -921,6 +1412,8 @@
+
+ inSISIDXREG(SISCR, 0x09, cr_data3);
+
++ if(cr_data3 & 0x80) var->vmode = FB_VMODE_DOUBLE;
++
+ VBS = (cr_data & 0xff) | ((u16) (cr_data2 & 0x08) << 5) |
+ ((u16) (cr_data3 & 0x20) << 4) | ((u16) (sr_data & 0x04) << 8);
+
+@@ -939,26 +1432,22 @@
+ D = B - F - C;
+
+ var->yres = E;
+-#ifndef SISFB_PAN
+- var->yres_virtual = E;
+-#endif
+- /* TW: We have to report the physical dimension to the console! */
++ var->upper_margin = D;
++ var->lower_margin = F;
++ var->vsync_len = C;
++
+ if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+ var->yres <<= 1;
+-#ifndef SISFB_PAN
+- var->yres_virtual <<= 1;
+-#endif
++ var->upper_margin <<= 1;
++ var->lower_margin <<= 1;
++ var->vsync_len <<= 1;
+ } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+ var->yres >>= 1;
+-#ifndef SISFB_PAN
+- var->yres_virtual >>= 1;
+-#endif
++ var->upper_margin >>= 1;
++ var->lower_margin >>= 1;
++ var->vsync_len >>= 1;
+ }
+
+- var->upper_margin = D;
+- var->lower_margin = F;
+- var->vsync_len = C;
+-
+ inSISIDXREG(SISSR, 0x0b, sr_data);
+
+ inSISIDXREG(SISCR, 0x00, cr_data);
+@@ -999,10 +1488,20 @@
+ D = B - F - C;
+
+ var->xres = var->xres_virtual = E * 8;
+- var->left_margin = D * 8;
+- var->right_margin = F * 8;
+- var->hsync_len = C * 8;
+
++ if((var->xres == 320) &&
++ (var->yres == 200 || var->yres == 240)) {
++ /* Terrible hack, but the correct CRTC data for
++ * these modes only produces a black screen...
++ */
++ var->left_margin = (400 - 376);
++ var->right_margin = (328 - 320);
++ var->hsync_len = (376 - 328);
++ } else {
++ var->left_margin = D * 8;
++ var->right_margin = F * 8;
++ var->hsync_len = C * 8;
++ }
+ var->activate = FB_ACTIVATE_NOW;
+
+ var->sync = 0;
+@@ -1022,21 +1521,21 @@
+ VT <<= 1;
+ HT = (HT + 5) * 8;
+
++ if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
++ VT <<= 1;
++ }
+ hrate = (double) ivideo.refresh_rate * (double) VT / 2;
+ drate = hrate * HT;
+ var->pixclock = (u32) (1E12 / drate);
+
+-#ifdef SISFB_PAN
+ if(sisfb_ypan) {
+ var->yres_virtual = ivideo.heapstart / (var->xres * (var->bits_per_pixel >> 3));
+ if(var->yres_virtual <= var->yres) {
+ var->yres_virtual = var->yres;
+ }
+ } else
+-#endif
+- var->yres_virtual = var->yres;
++ var->yres_virtual = var->yres;
+
+- TWDEBUG("end of crtc_to_var");
+ }
+
+ static int sis_getcolreg(unsigned regno, unsigned *red, unsigned *green, unsigned *blue,
+@@ -1069,7 +1568,7 @@
+ outSISREG(SISDACD, (red >> 10));
+ outSISREG(SISDACD, (green >> 10));
+ outSISREG(SISDACD, (blue >> 10));
+- if (ivideo.disp_state & DISPTYPE_DISP2) {
++ if (ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
+ outSISREG(SISDAC2A, regno);
+ outSISREG(SISDAC2D, (red >> 8));
+ outSISREG(SISDAC2D, (green >> 8));
+@@ -1118,7 +1617,7 @@
+ display->ywrapstep = fix.ywrapstep;
+ display->line_length = fix.line_length;
+ display->next_line = fix.line_length;
+- display->can_soft_blank = 0;
++ display->can_soft_blank = 1;
+ display->inverse = sisfb_inverse;
+ display->var = *var;
+
+@@ -1162,17 +1661,12 @@
+ display->dispsw = &sisfb_sw;
+ restore_flags(flags);
+
+-#ifdef SISFB_PAN
+- if((ivideo.accel) && (sisfb_ypan)) {
+- /* display->scrollmode = SCROLL_YPAN; - not defined */
++ if(sisfb_ypan) {
++ /* display->scrollmode = 0; */
+ } else {
+ display->scrollmode = SCROLL_YREDRAW;
+ sisfb_sw.bmove = fbcon_redraw_bmove;
+ }
+-#else
+- display->scrollmode = SCROLL_YREDRAW;
+- sisfb_sw.bmove = fbcon_redraw_bmove;
+-#endif
+ }
+
+ static void sisfb_do_install_cmap(int con, struct fb_info *info)
+@@ -1191,17 +1685,16 @@
+ static int sisfb_get_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
+ {
+- TWDEBUG("inside get_var");
+ if(con == -1)
+ memcpy(var, &default_var, sizeof(struct fb_var_screeninfo));
+ else
+ *var = fb_display[con].var;
+
+- /* For FSTN, DSTN */
+- if (var->xres == 320 && var->yres == 480)
++ if(sisfb_fstn) {
++ if (var->xres == 320 && var->yres == 480)
+ var->yres = 240;
+-
+- TWDEBUG("end of get_var");
++ }
++
+ return 0;
+ }
+
+@@ -1211,8 +1704,6 @@
+ int err;
+ unsigned int cols, rows;
+
+- TWDEBUG("inside set_var");
+-
+ fb_display[con].var.activate = FB_ACTIVATE_NOW;
+ if(sisfb_do_set_var(var, con == currcon, info)) {
+ sisfb_crtc_to_var(var);
+@@ -1233,16 +1724,17 @@
+
+ cols = sisbios_mode[sisfb_mode_idx].cols;
+ rows = sisbios_mode[sisfb_mode_idx].rows;
+- vc_resize_con(rows, cols, fb_display[con].conp->vc_num);
++#if 0
++ /* Why was this called here? */
++ vc_resize_con(rows, cols, fb_display[con].conp->vc_num);
++#endif
+
+- TWDEBUG("end of set_var");
+ return 0;
+ }
+
+ static int sisfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info)
+ {
+- TWDEBUG("inside get_cmap");
+ if (con == currcon)
+ return fb_get_cmap(cmap, kspc, sis_getcolreg, info);
+
+@@ -1251,7 +1743,6 @@
+ else
+ fb_copy_cmap(fb_default_cmap(ivideo.video_cmap_len), cmap, kspc ? 0 : 2);
+
+- TWDEBUG("end of get_cmap");
+ return 0;
+ }
+
+@@ -1260,7 +1751,6 @@
+ {
+ int err;
+
+- TWDEBUG("inside set_cmap");
+ if (!fb_display[con].cmap.len) {
+ err = fb_alloc_cmap(&fb_display[con].cmap, ivideo.video_cmap_len, 0);
+ if (err)
+@@ -1272,17 +1762,15 @@
+
+ else
+ fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+- TWDEBUG("end of set_cmap");
++
+ return 0;
+ }
+
+-#ifdef SISFB_PAN
+ static int sisfb_pan_display(struct fb_var_screeninfo *var, int con,
+ struct fb_info* info)
+ {
+ int err;
+-
+- TWDEBUG("inside pan_display");
++
+ if (var->vmode & FB_VMODE_YWRAP) {
+ if (var->yoffset < 0 || var->yoffset >= fb_display[con].var.yres_virtual || var->xoffset)
+ return -EINVAL;
+@@ -1303,10 +1791,8 @@
+ else
+ fb_display[con].var.vmode &= ~FB_VMODE_YWRAP;
+
+- TWDEBUG("end of pan_display");
+ return 0;
+ }
+-#endif
+
+ static int sisfb_mmap(struct fb_info *info, struct file *file,
+ struct vm_area_struct *vma)
+@@ -1316,7 +1802,6 @@
+ unsigned long off;
+ u32 len, mmio_off;
+
+- TWDEBUG("inside mmap");
+ if(vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) return -EINVAL;
+
+ off = vma->vm_pgoff << PAGE_SHIFT;
+@@ -1351,11 +1836,11 @@
+ if (boot_cpu_data.x86 > 3)
+ pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
+ #endif
++ /* RedHat requires vma as the first paramater to the following call */
+ if (io_remap_page_range(vma->vm_start, off, vma->vm_end - vma->vm_start,
+ vma->vm_page_prot))
+ return -EAGAIN;
+
+- TWDEBUG("end of mmap");
+ return 0;
+ }
+
+@@ -1368,7 +1853,6 @@
+ u8 *gbuf = gly->gmask;
+ int size;
+
+- TWDEBUG("Inside get_glyph");
+ gly->fontheight = fontheight(p);
+ gly->fontwidth = fontwidth(p);
+ widthb = (fontwidth(p) + 7) / 8;
+@@ -1382,16 +1866,11 @@
+ size = fontheight(p) * widthb;
+ memcpy(gbuf, cdat, size);
+ gly->ngmask = size;
+- TWDEBUG("End of get_glyph");
+ }
+
+ static int sisfb_update_var(int con, struct fb_info *info)
+ {
+-#ifdef SISFB_PAN
+ return(sisfb_pan_var(&fb_display[con].var));
+-#else
+- return 0;
+-#endif
+ }
+
+ static int sisfb_switch(int con, struct fb_info *info)
+@@ -1428,127 +1907,7 @@
+
+ static void sisfb_blank(int blank, struct fb_info *info)
+ {
+- u8 reg;
+-
+- inSISIDXREG(SISCR, 0x17, reg);
+-
+- if(blank > 0)
+- reg &= 0x7f;
+- else
+- reg |= 0x80;
+-
+- outSISIDXREG(SISCR, 0x17, reg);
+- outSISIDXREG(SISSR, 0x00, 0x01); /* Synchronous Reset */
+- outSISIDXREG(SISSR, 0x00, 0x03); /* End Reset */
+- printk(KERN_DEBUG "sisfb_blank() called (%d)\n", blank);
+-}
+-
+-
+-static int sisfb_ioctl(struct inode *inode, struct file *file,
+- unsigned int cmd, unsigned long arg, int con,
+- struct fb_info *info)
+-{
+- TWDEBUG("inside ioctl");
+- switch (cmd) {
+- case FBIO_ALLOC:
+- if (!capable(CAP_SYS_RAWIO))
+- return -EPERM;
+- sis_malloc((struct sis_memreq *) arg);
+- break;
+- case FBIO_FREE:
+- if (!capable(CAP_SYS_RAWIO))
+- return -EPERM;
+- sis_free(*(unsigned long *) arg);
+- break;
+- case FBIOGET_GLYPH:
+- sis_get_glyph(info,(SIS_GLYINFO *) arg);
+- break;
+- case FBIOGET_HWCINFO:
+- {
+- unsigned long *hwc_offset = (unsigned long *) arg;
+-
+- if (sisfb_caps & HW_CURSOR_CAP)
+- *hwc_offset = sisfb_hwcursor_vbase -
+- (unsigned long) ivideo.video_vbase;
+- else
+- *hwc_offset = 0;
+-
+- break;
+- }
+- case FBIOPUT_MODEINFO:
+- {
+- struct mode_info *x = (struct mode_info *)arg;
+-
+- ivideo.video_bpp = x->bpp;
+- ivideo.video_width = x->xres;
+- ivideo.video_height = x->yres;
+- ivideo.video_vwidth = x->v_xres;
+- ivideo.video_vheight = x->v_yres;
+- ivideo.org_x = x->org_x;
+- ivideo.org_y = x->org_y;
+- ivideo.refresh_rate = x->vrate;
+- ivideo.video_linelength = ivideo.video_vwidth * (ivideo.video_bpp >> 3);
+- switch(ivideo.video_bpp) {
+- case 8:
+- ivideo.DstColor = 0x0000;
+- ivideo.SiS310_AccelDepth = 0x00000000;
+- ivideo.video_cmap_len = 256;
+- break;
+- case 16:
+- ivideo.DstColor = 0x8000;
+- ivideo.SiS310_AccelDepth = 0x00010000;
+- ivideo.video_cmap_len = 16;
+- break;
+- case 32:
+- ivideo.DstColor = 0xC000;
+- ivideo.SiS310_AccelDepth = 0x00020000;
+- ivideo.video_cmap_len = 16;
+- break;
+- default:
+- ivideo.video_cmap_len = 16;
+- printk(KERN_ERR "sisfb: Unsupported depth %d", ivideo.video_bpp);
+- ivideo.accel = 0;
+- break;
+- }
+-
+- break;
+- }
+- case FBIOGET_DISPINFO:
+- sis_dispinfo((struct ap_data *)arg);
+- break;
+- case SISFB_GET_INFO: /* TW: New for communication with X driver */
+- {
+- sisfb_info *x = (sisfb_info *)arg;
+-
+- x->sisfb_id = SISFB_ID;
+- x->sisfb_version = VER_MAJOR;
+- x->sisfb_revision = VER_MINOR;
+- x->sisfb_patchlevel = VER_LEVEL;
+- x->chip_id = ivideo.chip_id;
+- x->memory = ivideo.video_size / 1024;
+- x->heapstart = ivideo.heapstart / 1024;
+- x->fbvidmode = sisfb_mode_no;
+- x->sisfb_caps = sisfb_caps;
+- x->sisfb_tqlen = 512; /* yet unused */
+- x->sisfb_pcibus = ivideo.pcibus;
+- x->sisfb_pcislot = ivideo.pcislot;
+- x->sisfb_pcifunc = ivideo.pcifunc;
+- x->sisfb_lcdpdc = sisfb_detectedpdc;
+- x->sisfb_lcda = sisfb_detectedlcda;
+- break;
+- }
+- case SISFB_GET_VBRSTATUS:
+- {
+- unsigned long *vbrstatus = (unsigned long *) arg;
+- if(sisfb_CheckVBRetrace()) *vbrstatus = 1;
+- else *vbrstatus = 0;
+- }
+- default:
+- return -EINVAL;
+- }
+- TWDEBUG("end of ioctl");
+- return 0;
+-
++ sisfb_myblank(blank);
+ }
+ #endif
+
+@@ -1575,11 +1934,9 @@
+ rc = 256;
+ break;
+ case 16:
+- rc = 16;
+- break;
+ case 32:
+ rc = 16;
+- break;
++ break;
+ }
+ return rc;
+ }
+@@ -1596,7 +1953,7 @@
+ outSISREG(SISDACD, (red >> 10));
+ outSISREG(SISDACD, (green >> 10));
+ outSISREG(SISDACD, (blue >> 10));
+- if (ivideo.disp_state & DISPTYPE_DISP2) {
++ if (ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
+ outSISREG(SISDAC2A, regno);
+ outSISREG(SISDAC2D, (red >> 8));
+ outSISREG(SISDAC2D, (green >> 8));
+@@ -1622,63 +1979,52 @@
+ {
+ int err;
+
+- TWDEBUG("inside set_par");
+ if((err = sisfb_do_set_var(&info->var, 1, info)))
+ return err;
+
+ sisfb_get_fix(&info->fix, info->currcon, info);
+
+- TWDEBUG("end of set_par");
+ return 0;
+ }
+
+ static int sisfb_check_var(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+ {
+- unsigned int htotal =
+- var->left_margin + var->xres + var->right_margin +
+- var->hsync_len;
+- unsigned int vtotal = 0;
++ unsigned int htotal = 0, vtotal = 0, myrateindex = 0;
+ double drate = 0, hrate = 0;
+ int found_mode = 0;
+ int refresh_rate, search_idx;
++ BOOLEAN recalc_clock = FALSE;
++ u32 pixclock;
++
++ htotal = var->left_margin + var->xres + var->right_margin + var->hsync_len;
++
++ vtotal = var->upper_margin + var->lower_margin + var->vsync_len;
+
+- TWDEBUG("Inside check_var");
++ pixclock = var->pixclock;
+
+ if((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
+- vtotal = var->upper_margin + var->yres + var->lower_margin +
+- var->vsync_len;
++ vtotal += var->yres;
+ vtotal <<= 1;
+ } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+- vtotal = var->upper_margin + var->yres + var->lower_margin +
+- var->vsync_len;
++ vtotal += var->yres;
+ vtotal <<= 2;
+ } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+- vtotal = var->upper_margin + (var->yres/2) + var->lower_margin +
+- var->vsync_len;
+- } else vtotal = var->upper_margin + var->yres + var->lower_margin +
+- var->vsync_len;
++ vtotal += var->yres;
++ vtotal <<= 1;
++ } else vtotal += var->yres;
+
+ if(!(htotal) || !(vtotal)) {
+ SISFAIL("sisfb: no valid timing data");
+ }
+
+- if((var->pixclock) && (htotal)) {
+- drate = 1E12 / var->pixclock;
+- hrate = drate / htotal;
+- refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
+- } else refresh_rate = 60;
+-
+- /* TW: Calculation wrong for 1024x600 - force it to 60Hz */
+- if((var->xres == 1024) && (var->yres == 600)) refresh_rate = 60;
+-
+ search_idx = 0;
+ while( (sisbios_mode[search_idx].mode_no != 0) &&
+ (sisbios_mode[search_idx].xres <= var->xres) ) {
+ if( (sisbios_mode[search_idx].xres == var->xres) &&
+ (sisbios_mode[search_idx].yres == var->yres) &&
+ (sisbios_mode[search_idx].bpp == var->bits_per_pixel)) {
+- if(sisfb_validate_mode(search_idx) > 0) {
++ if(sisfb_validate_mode(search_idx, ivideo.currentvbflags) > 0) {
+ found_mode = 1;
+ break;
+ }
+@@ -1687,38 +2033,95 @@
+ }
+
+ if(!found_mode) {
+-
+- printk(KERN_ERR "sisfb: %dx%dx%d is no valid mode\n",
+- var->xres, var->yres, var->bits_per_pixel);
+-
++
+ search_idx = 0;
+ while(sisbios_mode[search_idx].mode_no != 0) {
+-
+ if( (var->xres <= sisbios_mode[search_idx].xres) &&
+- (var->yres <= sisbios_mode[search_idx].yres) &&
++ (var->yres <= sisbios_mode[search_idx].yres) &&
+ (var->bits_per_pixel == sisbios_mode[search_idx].bpp) ) {
+- if(sisfb_validate_mode(search_idx) > 0) {
++ if(sisfb_validate_mode(search_idx, ivideo.currentvbflags) > 0) {
+ found_mode = 1;
+ break;
+ }
+ }
+ search_idx++;
+- }
++ }
+ if(found_mode) {
++ printk(KERN_DEBUG "sisfb: Adapted from %dx%dx%d to %dx%dx%d\n",
++ var->xres, var->yres, var->bits_per_pixel,
++ sisbios_mode[search_idx].xres,
++ sisbios_mode[search_idx].yres,
++ var->bits_per_pixel);
+ var->xres = sisbios_mode[search_idx].xres;
+ var->yres = sisbios_mode[search_idx].yres;
+- printk(KERN_DEBUG "sisfb: Adapted to mode %dx%dx%d\n",
+- var->xres, var->yres, var->bits_per_pixel);
+-
++
++
+ } else {
+- printk(KERN_ERR "sisfb: Failed to find similar mode to %dx%dx%d\n",
++ printk(KERN_ERR "sisfb: Failed to find supported mode near %dx%dx%d\n",
+ var->xres, var->yres, var->bits_per_pixel);
+ return -EINVAL;
+ }
+ }
+
+- /* TW: TODO: Check the refresh rate */
+-
++ if( ((ivideo.vbflags & VB_LVDS) || /* Slave modes on LVDS and 301B-DH */
++ ((ivideo.vbflags & VB_30xBDH) && (ivideo.currentvbflags & CRT2_LCD))) &&
++ (var->bits_per_pixel == 8) ) {
++ refresh_rate = 60;
++ recalc_clock = TRUE;
++ } else if( (ivideo.current_htotal == htotal) && /* x=x & y=y & c=c -> assume depth change */
++ (ivideo.current_vtotal == vtotal) &&
++ (ivideo.current_pixclock == pixclock) ) {
++ drate = 1E12 / pixclock;
++ hrate = drate / htotal;
++ refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
++ } else if( ( (ivideo.current_htotal != htotal) || /* x!=x | y!=y & c=c -> invalid pixclock */
++ (ivideo.current_vtotal != vtotal) ) &&
++ (ivideo.current_pixclock == var->pixclock) ) {
++ if(sisfb_lastrates[sisbios_mode[search_idx].mode_no]) {
++ refresh_rate = sisfb_lastrates[sisbios_mode[search_idx].mode_no];
++ } else if(sisfb_parm_rate != -1) {
++ refresh_rate = sisfb_parm_rate;
++ } else {
++ refresh_rate = 60;
++ }
++ recalc_clock = TRUE;
++ } else if((pixclock) && (htotal) && (vtotal)) {
++ drate = 1E12 / pixclock;
++ hrate = drate / htotal;
++ refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
++ } else if(ivideo.current_refresh_rate) {
++ refresh_rate = ivideo.current_refresh_rate;
++ recalc_clock = TRUE;
++ } else {
++ refresh_rate = 60;
++ recalc_clock = TRUE;
++ }
++
++ myrateindex = sisfb_search_refresh_rate(refresh_rate, search_idx);
++
++ /* Eventually recalculate timing and clock */
++ if(recalc_clock) {
++ if(!myrateindex) myrateindex = sisbios_mode[search_idx].rate_idx;
++ var->pixclock = (u32) (1E12 / sisfb_mode_rate_to_dclock(&SiS_Pr, &sishw_ext,
++ sisbios_mode[search_idx].mode_no, myrateindex));
++ sisfb_mode_rate_to_ddata(&SiS_Pr, &sishw_ext,
++ sisbios_mode[search_idx].mode_no, myrateindex,
++ &var->left_margin, &var->right_margin,
++ &var->upper_margin, &var->lower_margin,
++ &var->hsync_len, &var->vsync_len,
++ &var->sync, &var->vmode);
++ if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
++ var->pixclock <<= 1;
++ }
++ }
++
++ if(sisfb_thismonitor.datavalid) {
++ if(!sisfb_verify_rate(&sisfb_thismonitor, search_idx,
++ myrateindex, refresh_rate)) {
++ printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
++ }
++ }
++
+ /* Adapt RGB settings */
+ sisfb_bpp_to_var(var);
+
+@@ -1732,17 +2135,19 @@
+ if(var->xres != var->xres_virtual)
+ var->xres_virtual = var->xres;
+
+- if(!sisfb_ypan) {
+- if(var->yres != var->yres_virtual)
+- var->yres_virtual = var->yres;
+- } else {
++ if(sisfb_ypan) {
+ /* TW: Now patch yres_virtual if we use panning */
+ /* *** May I do this? *** */
+ var->yres_virtual = ivideo.heapstart / (var->xres * (var->bits_per_pixel >> 3));
+- if(var->yres_virtual <= var->yres) {
++ if(var->yres_virtual <= var->yres) {
+ /* TW: Paranoia check */
+ var->yres_virtual = var->yres;
+- }
++ }
++ } else {
++ if(var->yres != var->yres_virtual)
++ var->yres_virtual = var->yres;
++ var->xoffset = 0;
++ var->yoffset = 0;
+ }
+
+ /* Truncate offsets to maximum if too high */
+@@ -1757,28 +2162,25 @@
+ var->green.msb_right =
+ var->blue.msb_right =
+ var->transp.offset = var->transp.length = var->transp.msb_right = 0;
+-
+- TWDEBUG("end of check_var");
++
+ return 0;
+ }
+
+-#ifdef SISFB_PAN
+ static int sisfb_pan_display(struct fb_var_screeninfo *var,
+ struct fb_info* info)
+ {
+ int err;
+-
+- TWDEBUG("inside pan_display");
+-
++
+ if (var->xoffset > (var->xres_virtual - var->xres))
+ return -EINVAL;
+ if (var->yoffset > (var->yres_virtual - var->yres))
+ return -EINVAL;
+
+ if (var->vmode & FB_VMODE_YWRAP) {
+- if (var->yoffset < 0
+- || var->yoffset >= info->var.yres_virtual
+- || var->xoffset) return -EINVAL;
++ if (var->yoffset < 0 ||
++ var->yoffset >= info->var.yres_virtual ||
++ var->xoffset)
++ return -EINVAL;
+ } else {
+ if (var->xoffset + info->var.xres > info->var.xres_virtual ||
+ var->yoffset + info->var.yres > info->var.yres_virtual)
+@@ -1794,10 +2196,8 @@
+ else
+ info->var.vmode &= ~FB_VMODE_YWRAP;
+
+- TWDEBUG("end of pan_display");
+ return 0;
+ }
+-#endif
+
+ static int sisfb_mmap(struct fb_info *info, struct file *file,
+ struct vm_area_struct *vma)
+@@ -1806,7 +2206,6 @@
+ unsigned long off;
+ u32 len, mmio_off;
+
+- TWDEBUG("inside mmap");
+ if(vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) return -EINVAL;
+
+ off = vma->vm_pgoff << PAGE_SHIFT;
+@@ -1844,139 +2243,143 @@
+ vma->vm_page_prot))
+ return -EAGAIN;
+
+- TWDEBUG("end of mmap");
+ return 0;
+ }
+
+ static int sisfb_blank(int blank, struct fb_info *info)
+ {
+- u8 reg;
++ return(sisfb_myblank(blank));
++}
+
+- inSISIDXREG(SISCR, 0x17, reg);
++#endif
+
+- if(blank > 0)
+- reg &= 0x7f;
+- else
+- reg |= 0x80;
++/* ----------- FBDev related routines for all series ---------- */
+
+- outSISIDXREG(SISCR, 0x17, reg);
+- outSISIDXREG(SISSR, 0x00, 0x01); /* Synchronous Reset */
+- outSISIDXREG(SISSR, 0x00, 0x03); /* End Reset */
+- return(0);
+-}
+
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
++static int sisfb_ioctl(struct inode *inode, struct file *file,
++ unsigned int cmd, unsigned long arg,
++ struct fb_info *info)
++#else
+ static int sisfb_ioctl(struct inode *inode, struct file *file,
+- unsigned int cmd, unsigned long arg,
++ unsigned int cmd, unsigned long arg, int con,
+ struct fb_info *info)
++#endif
+ {
+- TWDEBUG("inside ioctl");
++ struct sis_memreq sismemreq;
++ struct ap_data sisapdata;
++ unsigned long sismembase = 0;
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++ SIS_GLYINFO sisglyinfo;
++#endif
++
+ switch (cmd) {
+ case FBIO_ALLOC:
+- if (!capable(CAP_SYS_RAWIO))
++ if(!capable(CAP_SYS_RAWIO))
+ return -EPERM;
+- sis_malloc((struct sis_memreq *) arg);
++ if(copy_from_user(&sismemreq, (void *)arg, sizeof(sismemreq)))
++ return -EFAULT;
++ sis_malloc(&sismemreq);
++ if(copy_to_user((void *)arg, &sismemreq, sizeof(sismemreq))) {
++ sis_free(sismemreq.offset);
++ return -EFAULT;
++ }
+ break;
+ case FBIO_FREE:
+- if (!capable(CAP_SYS_RAWIO))
++ if(!capable(CAP_SYS_RAWIO))
+ return -EPERM;
+- sis_free(*(unsigned long *) arg);
++ if(get_user(sismembase, (unsigned long *) arg))
++ return -EFAULT;
++ sis_free(sismembase);
+ break;
+- case FBIOGET_HWCINFO:
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++ case FBIOGET_GLYPH:
++ if(copy_from_user(&sisglyinfo, (void *)arg, sizeof(sisglyinfo)))
++ return -EFAULT;
++ sis_get_glyph(info, &sisglyinfo);
++ break;
++ case FBIOPUT_MODEINFO:
+ {
+- unsigned long *hwc_offset = (unsigned long *) arg;
++ struct mode_info x;
+
+- if (sisfb_caps & HW_CURSOR_CAP)
+- *hwc_offset = sisfb_hwcursor_vbase -
+- (unsigned long) ivideo.video_vbase;
+- else
+- *hwc_offset = 0;
++ if(copy_from_user(&x, (void *)arg, sizeof(x)))
++ return -EFAULT;
+
++ ivideo.video_bpp = x.bpp;
++ ivideo.video_width = x.xres;
++ ivideo.video_height = x.yres;
++ ivideo.video_vwidth = x.v_xres;
++ ivideo.video_vheight = x.v_yres;
++ ivideo.org_x = x.org_x;
++ ivideo.org_y = x.org_y;
++ ivideo.refresh_rate = x.vrate;
++ ivideo.video_linelength = ivideo.video_vwidth * (ivideo.video_bpp >> 3);
++ sisfb_set_vparms();
+ break;
+ }
+- case FBIOPUT_MODEINFO:
++#endif
++ case FBIOGET_HWCINFO:
+ {
+- struct mode_info *x = (struct mode_info *)arg;
++ unsigned long myhwcoffset = 0;
+
+- ivideo.video_bpp = x->bpp;
+- ivideo.video_width = x->xres;
+- ivideo.video_height = x->yres;
+- ivideo.video_vwidth = x->v_xres;
+- ivideo.video_vheight = x->v_yres;
+- ivideo.org_x = x->org_x;
+- ivideo.org_y = x->org_y;
+- ivideo.refresh_rate = x->vrate;
+- ivideo.video_linelength = ivideo.video_vwidth * (ivideo.video_bpp >> 3);
+- switch(ivideo.video_bpp) {
+- case 8:
+- ivideo.DstColor = 0x0000;
+- ivideo.SiS310_AccelDepth = 0x00000000;
+- ivideo.video_cmap_len = 256;
+- break;
+- case 16:
+- ivideo.DstColor = 0x8000;
+- ivideo.SiS310_AccelDepth = 0x00010000;
+- ivideo.video_cmap_len = 16;
+- break;
+- case 32:
+- ivideo.DstColor = 0xC000;
+- ivideo.SiS310_AccelDepth = 0x00020000;
+- ivideo.video_cmap_len = 16;
+- break;
+- default:
+- ivideo.video_cmap_len = 16;
+- printk(KERN_ERR "sisfb: Unsupported accel depth %d", ivideo.video_bpp);
+- ivideo.accel = 0;
+- break;
+- }
++ if(sisfb_caps & HW_CURSOR_CAP)
++ myhwcoffset = sisfb_hwcursor_vbase -
++ (unsigned long) ivideo.video_vbase;
++
++ return put_user(myhwcoffset, (unsigned long *)arg);
+
+ break;
+ }
+ case FBIOGET_DISPINFO:
+- sis_dispinfo((struct ap_data *)arg);
++ sis_dispinfo(&sisapdata);
++ if(copy_to_user((void *)arg, &sisapdata, sizeof(sisapdata)))
++ return -EFAULT;
+ break;
+- case SISFB_GET_INFO: /* TW: New for communication with X driver */
++ case SISFB_GET_INFO: /* For communication with X driver */
+ {
+- sisfb_info *x = (sisfb_info *)arg;
++ sisfb_info x;
+
+- x->sisfb_id = SISFB_ID;
+- x->sisfb_version = VER_MAJOR;
+- x->sisfb_revision = VER_MINOR;
+- x->sisfb_patchlevel = VER_LEVEL;
+- x->chip_id = ivideo.chip_id;
+- x->memory = ivideo.video_size / 1024;
+- x->heapstart = ivideo.heapstart / 1024;
+- x->fbvidmode = sisfb_mode_no;
+- x->sisfb_caps = sisfb_caps;
+- x->sisfb_tqlen = 512; /* yet unused */
+- x->sisfb_pcibus = ivideo.pcibus;
+- x->sisfb_pcislot = ivideo.pcislot;
+- x->sisfb_pcifunc = ivideo.pcifunc;
+- x->sisfb_lcdpdc = sisfb_detectedpdc;
+- x->sisfb_lcda = sisfb_detectedlcda;
++ x.sisfb_id = SISFB_ID;
++ x.sisfb_version = VER_MAJOR;
++ x.sisfb_revision = VER_MINOR;
++ x.sisfb_patchlevel = VER_LEVEL;
++ x.chip_id = ivideo.chip_id;
++ x.memory = ivideo.video_size / 1024;
++ x.heapstart = ivideo.heapstart / 1024;
++ x.fbvidmode = sisfb_mode_no;
++ x.sisfb_caps = sisfb_caps;
++ x.sisfb_tqlen = 512; /* yet unused */
++ x.sisfb_pcibus = ivideo.pcibus;
++ x.sisfb_pcislot = ivideo.pcislot;
++ x.sisfb_pcifunc = ivideo.pcifunc;
++ x.sisfb_lcdpdc = sisfb_detectedpdc;
++ x.sisfb_lcda = sisfb_detectedlcda;
++ x.sisfb_vbflags = ivideo.vbflags;
++ x.sisfb_currentvbflags = ivideo.currentvbflags;
++ x.sisfb_scalelcd = SiS_Pr.UsePanelScaler;
++ x.sisfb_specialtiming = SiS_Pr.SiS_CustomT;
++ if(copy_to_user((void *)arg, &x, sizeof(x)))
++ return -EFAULT;
+ break;
+ }
+ case SISFB_GET_VBRSTATUS:
+ {
+- unsigned long *vbrstatus = (unsigned long *) arg;
+- if(sisfb_CheckVBRetrace()) *vbrstatus = 1;
+- else *vbrstatus = 0;
++ if(sisfb_CheckVBRetrace())
++ return put_user(1UL, (unsigned long *) arg);
++ else
++ return put_user(0UL, (unsigned long *) arg);
++ break;
+ }
+ default:
+ return -EINVAL;
+ }
+- TWDEBUG("end of ioctl");
+ return 0;
+-
+ }
+
+-#endif
+-
+-/* ----------- FBDev related routines for all series ---------- */
+
+ static int sisfb_get_fix(struct fb_fix_screeninfo *fix, int con,
+ struct fb_info *info)
+ {
+- TWDEBUG("inside get_fix");
+ memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+@@ -1987,45 +2390,47 @@
+
+ fix->smem_start = ivideo.video_base;
+
+- /* TW */
+ if((!sisfb_mem) || (sisfb_mem > (ivideo.video_size/1024))) {
+- if (ivideo.video_size > 0x1000000) {
+- fix->smem_len = 0xc00000;
+- } else if (ivideo.video_size > 0x800000)
+- fix->smem_len = 0x800000;
+- else
+- fix->smem_len = 0x400000;
++ if(sisvga_engine == SIS_300_VGA) {
++ if(ivideo.video_size > 0x1000000) {
++ fix->smem_len = 0xc00000;
++ } else if(ivideo.video_size > 0x800000)
++ fix->smem_len = 0x800000;
++ else
++ fix->smem_len = 0x400000;
++ } else {
++ fix->smem_len = ivideo.video_size - 0x100000;
++ }
+ } else
+ fix->smem_len = sisfb_mem * 1024;
+
+- fix->type = video_type;
++ fix->type = FB_TYPE_PACKED_PIXELS;
+ fix->type_aux = 0;
+ if(ivideo.video_bpp == 8)
+ fix->visual = FB_VISUAL_PSEUDOCOLOR;
+ else
+ fix->visual = FB_VISUAL_TRUECOLOR;
+ fix->xpanstep = 0;
+-#ifdef SISFB_PAN
++
+ if(sisfb_ypan) fix->ypanstep = 1;
+-#endif
++
+ fix->ywrapstep = 0;
+ fix->line_length = ivideo.video_linelength;
+ fix->mmio_start = ivideo.mmio_base;
+ fix->mmio_len = sisfb_mmio_size;
+ if(sisvga_engine == SIS_300_VGA)
+ fix->accel = FB_ACCEL_SIS_GLAMOUR;
+- else if(ivideo.chip == SIS_330)
++ else if((ivideo.chip == SIS_330) || (ivideo.chip == SIS_660) || (ivideo.chip == SIS_760))
+ fix->accel = FB_ACCEL_SIS_XABRE;
+- else
++ else
+ fix->accel = FB_ACCEL_SIS_GLAMOUR_2;
+-
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ fix->reserved[0] = ivideo.video_size & 0xFFFF;
+ fix->reserved[1] = (ivideo.video_size >> 16) & 0xFFFF;
+ fix->reserved[2] = sisfb_caps;
+-#endif
++#endif
+
+- TWDEBUG("end of get_fix");
+ return 0;
+ }
+
+@@ -2033,17 +2438,15 @@
+
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ static struct fb_ops sisfb_ops = {
+- owner: THIS_MODULE,
+- fb_get_fix: sisfb_get_fix,
+- fb_get_var: sisfb_get_var,
+- fb_set_var: sisfb_set_var,
+- fb_get_cmap: sisfb_get_cmap,
+- fb_set_cmap: sisfb_set_cmap,
+-#ifdef SISFB_PAN
+- fb_pan_display: sisfb_pan_display,
+-#endif
+- fb_ioctl: sisfb_ioctl,
+- fb_mmap: sisfb_mmap,
++ .owner = THIS_MODULE,
++ .fb_get_fix = sisfb_get_fix,
++ .fb_get_var = sisfb_get_var,
++ .fb_set_var = sisfb_set_var,
++ .fb_get_cmap = sisfb_get_cmap,
++ .fb_set_cmap = sisfb_set_cmap,
++ .fb_pan_display = sisfb_pan_display,
++ .fb_ioctl = sisfb_ioctl,
++ .fb_mmap = sisfb_mmap,
+ };
+ #endif
+
+@@ -2056,9 +2459,7 @@
+ .fb_check_var = sisfb_check_var,
+ .fb_set_par = sisfb_set_par,
+ .fb_setcolreg = sisfb_setcolreg,
+-#ifdef SISFB_PAN
+ .fb_pan_display = sisfb_pan_display,
+-#endif
+ .fb_blank = sisfb_blank,
+ .fb_fillrect = fbcon_sis_fillrect,
+ .fb_copyarea = fbcon_sis_copyarea,
+@@ -2105,35 +2506,42 @@
+
+ } else { /* 540, 630, 730 */
+
+- pdev = pci_find_device(PCI_VENDOR_ID_SI, nbridge_id, pdev);
+- if (pdev) {
+- pci_read_config_byte(pdev, IND_BRI_DRAM_STATUS, &pci_data);
+- pci_data = (pci_data & BRI_DRAM_SIZE_MASK) >> 4;
+- ivideo.video_size = (unsigned int)(1 << (pci_data+21));
+- pdev_valid = 1;
+-
+- reg = SIS_DATA_BUS_64 << 6;
+- switch (pci_data) {
+- case BRI_DRAM_SIZE_2MB:
+- reg |= SIS_DRAM_SIZE_2MB;
+- break;
+- case BRI_DRAM_SIZE_4MB:
+- reg |= SIS_DRAM_SIZE_4MB;
+- break;
+- case BRI_DRAM_SIZE_8MB:
+- reg |= SIS_DRAM_SIZE_8MB;
+- break;
+- case BRI_DRAM_SIZE_16MB:
+- reg |= SIS_DRAM_SIZE_16MB;
+- break;
+- case BRI_DRAM_SIZE_32MB:
+- reg |= SIS_DRAM_SIZE_32MB;
+- break;
+- case BRI_DRAM_SIZE_64MB:
+- reg |= SIS_DRAM_SIZE_64MB;
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,74)
++ pci_for_each_dev(pdev) {
++#else
++ while((pdev = pci_find_device(PCI_VENDOR_ID_SI, PCI_ANY_ID, pdev))) {
++#endif
++ if ((pdev->vendor == PCI_VENDOR_ID_SI)
++ && (pdev->device == nbridge_id)) {
++ pci_read_config_byte(pdev, IND_BRI_DRAM_STATUS, &pci_data);
++ pci_data = (pci_data & BRI_DRAM_SIZE_MASK) >> 4;
++ ivideo.video_size = (unsigned int)(1 << (pci_data+21));
++ pdev_valid = 1;
++
++ reg = SIS_DATA_BUS_64 << 6;
++ switch (pci_data) {
++ case BRI_DRAM_SIZE_2MB:
++ reg |= SIS_DRAM_SIZE_2MB;
++ break;
++ case BRI_DRAM_SIZE_4MB:
++ reg |= SIS_DRAM_SIZE_4MB;
++ break;
++ case BRI_DRAM_SIZE_8MB:
++ reg |= SIS_DRAM_SIZE_8MB;
++ break;
++ case BRI_DRAM_SIZE_16MB:
++ reg |= SIS_DRAM_SIZE_16MB;
++ break;
++ case BRI_DRAM_SIZE_32MB:
++ reg |= SIS_DRAM_SIZE_32MB;
++ break;
++ case BRI_DRAM_SIZE_64MB:
++ reg |= SIS_DRAM_SIZE_64MB;
++ break;
++ }
++ outSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
+ break;
+ }
+- outSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
+ }
+
+ if (!pdev_valid) return -1;
+@@ -2141,171 +2549,10 @@
+ return 0;
+ }
+
+-static void sisfb_detect_VB_connect_300()
+-{
+- u8 sr16, sr17, cr32, temp;
+-
+- ivideo.TV_plug = ivideo.TV_type = 0;
+-
+- switch(ivideo.hasVB) {
+- case HASVB_LVDS_CHRONTEL:
+- case HASVB_CHRONTEL:
+- SiS_SenseCh();
+- break;
+- case HASVB_301:
+- case HASVB_302:
+- SiS_Sense30x();
+- break;
+- }
+-
+- inSISIDXREG(SISSR, IND_SIS_SCRATCH_REG_17, sr17);
+- inSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR32, cr32);
+-
+- if ((sr17 & 0x0F) && (ivideo.chip != SIS_300)) {
+-
+- if ((sr17 & 0x01) && !sisfb_crt1off)
+- sisfb_crt1off = 0;
+- else {
+- if (sr17 & 0x0E)
+- sisfb_crt1off = 1;
+- else
+- sisfb_crt1off = 0;
+- }
+-
+- if (sisfb_crt2type != -1)
+- /* TW: override detected CRT2 type */
+- ivideo.disp_state = sisfb_crt2type;
+- else if (sr17 & 0x04)
+- ivideo.disp_state = DISPTYPE_TV;
+- else if (sr17 & 0x02)
+- ivideo.disp_state = DISPTYPE_LCD;
+- else if (sr17 & 0x08 )
+- ivideo.disp_state = DISPTYPE_CRT2;
+- else
+- ivideo.disp_state = 0;
+-
+- if(sisfb_tvplug != -1)
+- /* PR/TW: override detected TV type */
+- ivideo.TV_plug = sisfb_tvplug;
+- else if (sr17 & 0x20)
+- ivideo.TV_plug = TVPLUG_SVIDEO;
+- else if (sr17 & 0x10)
+- ivideo.TV_plug = TVPLUG_COMPOSITE;
+-
+- inSISIDXREG(SISSR, IND_SIS_SCRATCH_REG_16, sr16);
+- if (sr16 & 0x20)
+- ivideo.TV_type = TVMODE_PAL;
+- else
+- ivideo.TV_type = TVMODE_NTSC;
+-
+- } else {
+-
+- if ((cr32 & SIS_CRT1) && !sisfb_crt1off)
+- sisfb_crt1off = 0;
+- else {
+- if (cr32 & 0x5F)
+- sisfb_crt1off = 1;
+- else
+- sisfb_crt1off = 0;
+- }
+-
+- if (sisfb_crt2type != -1)
+- /* TW: override detected CRT2 type */
+- ivideo.disp_state = sisfb_crt2type;
+- else if (cr32 & SIS_VB_TV)
+- ivideo.disp_state = DISPTYPE_TV;
+- else if (cr32 & SIS_VB_LCD)
+- ivideo.disp_state = DISPTYPE_LCD;
+- else if (cr32 & SIS_VB_CRT2)
+- ivideo.disp_state = DISPTYPE_CRT2;
+- else
+- ivideo.disp_state = 0;
+-
+- /* TW: Detect TV plug & type */
+- if(sisfb_tvplug != -1)
+- /* PR/TW: override with option */
+- ivideo.TV_plug = sisfb_tvplug;
+- else if (cr32 & SIS_VB_HIVISION) {
+- ivideo.TV_type = TVMODE_HIVISION;
+- ivideo.TV_plug = TVPLUG_SVIDEO;
+- }
+- else if (cr32 & SIS_VB_SVIDEO)
+- ivideo.TV_plug = TVPLUG_SVIDEO;
+- else if (cr32 & SIS_VB_COMPOSITE)
+- ivideo.TV_plug = TVPLUG_COMPOSITE;
+- else if (cr32 & SIS_VB_SCART)
+- ivideo.TV_plug = TVPLUG_SCART;
+-
+- if (ivideo.TV_type == 0) {
+- inSISIDXREG(SISSR, IND_SIS_POWER_ON_TRAP, temp);
+- if (temp & 0x01)
+- ivideo.TV_type = TVMODE_PAL;
+- else
+- ivideo.TV_type = TVMODE_NTSC;
+- }
+-
+- }
+-
+- /* TW: Copy forceCRT1 option to CRT1off if option is given */
+- if (sisfb_forcecrt1 != -1) {
+- if(sisfb_forcecrt1) sisfb_crt1off = 0;
+- else sisfb_crt1off = 1;
+- }
+-}
+-
+-static void sisfb_get_VB_type_300(void)
+-{
+- u8 reg;
+-
+- if(ivideo.chip != SIS_300) {
+- if(!sisfb_has_VB_300()) {
+- inSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR37, reg);
+- switch ((reg & SIS_EXTERNAL_CHIP_MASK) >> 1) {
+- case SIS_EXTERNAL_CHIP_LVDS:
+- ivideo.hasVB = HASVB_LVDS;
+- break;
+- case SIS_EXTERNAL_CHIP_TRUMPION:
+- ivideo.hasVB = HASVB_TRUMPION;
+- break;
+- case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL:
+- ivideo.hasVB = HASVB_LVDS_CHRONTEL;
+- break;
+- case SIS_EXTERNAL_CHIP_CHRONTEL:
+- ivideo.hasVB = HASVB_CHRONTEL;
+- break;
+- default:
+- break;
+- }
+- }
+- } else {
+- sisfb_has_VB_300();
+- }
+-}
+-
+-static int sisfb_has_VB_300(void)
+-{
+- u8 vb_chipid;
+-
+- inSISIDXREG(SISPART4, 0x00, vb_chipid);
+- switch (vb_chipid) {
+- case 0x01:
+- ivideo.hasVB = HASVB_301;
+- break;
+- case 0x02:
+- ivideo.hasVB = HASVB_302;
+- break;
+- default:
+- ivideo.hasVB = HASVB_NONE;
+- return FALSE;
+- }
+- return TRUE;
+-
+-}
+-
+ #endif /* CONFIG_FB_SIS_300 */
+
+
+-#ifdef CONFIG_FB_SIS_315 /* for SiS 315/550/650/740/330 */
++#ifdef CONFIG_FB_SIS_315 /* for SiS 315/550/650/740/330/660/760 */
+
+ static int sisfb_get_dram_size_315(void)
+ {
+@@ -2314,21 +2561,33 @@
+ u8 pci_data;
+ u8 reg = 0;
+
+- if (ivideo.chip == SIS_550 || ivideo.chip == SIS_650 || ivideo.chip == SIS_740) {
++ if (ivideo.chip == SIS_550 ||
++ ivideo.chip == SIS_650 ||
++ ivideo.chip == SIS_740 ||
++ ivideo.chip == SIS_660 ||
++ ivideo.chip == SIS_760) {
+
+ #ifdef LINUXBIOS
+
+- while ((pdev = pci_find_device(PCI_VENDOR_ID_SI, PCI_ANY_ID, pdev)) != NULL) {
+- if ((pdev->device == PCI_DEVICE_ID_SI_550) ||
+- (pdev->device == PCI_DEVICE_ID_SI_650) ||
+- (pdev->device == PCI_DEVICE_ID_SI_740)) {
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,74)
++ pci_for_each_dev(pdev) {
++#else
++ while((pdev = pci_find_device(PCI_VENDOR_ID_SI, PCI_ANY_ID, pdev))) {
++#endif
++
++ if ( (pdev->vendor == PCI_VENDOR_ID_SI)
++ && ( (pdev->device == PCI_DEVICE_ID_SI_550) ||
++ (pdev->device == PCI_DEVICE_ID_SI_650) ||
++ (pdev->device == PCI_DEVICE_ID_SI_740) ||
++ (pdev->device == PCI_DEVICE_ID_SI_660) ||
++ (pdev->device == PCI_DEVICE_ID_SI_760))) {
+ pci_read_config_byte(pdev, IND_BRI_DRAM_STATUS,
+ &pci_data);
+ pci_data = (pci_data & BRI_DRAM_SIZE_MASK) >> 4;
+ ivideo.video_size = (unsigned int)(1 << (pci_data + 21));
+ pdev_valid = 1;
+
+- /* TW: Initialize SR14 "by hand" */
++ /* Initialize SR14 "by hand" */
+ inSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
+ reg &= 0xC0;
+ switch (pci_data) {
+@@ -2390,7 +2649,15 @@
+ "now reading from PCI config\n");
+ pdev_valid = 0;
+
+- while ((pdev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_550, pdev)) != NULL) {
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,74)
++ pci_for_each_dev(pdev) {
++#else
++ while((pdev = pci_find_device(PCI_VENDOR_ID_SI, PCI_ANY_ID, pdev))) {
++#endif
++
++ if ( (pdev->vendor == PCI_VENDOR_ID_SI)
++ && (pdev->device == PCI_DEVICE_ID_SI_550) ) {
++
+ pci_read_config_byte(pdev, IND_BRI_DRAM_STATUS,
+ &pci_data);
+ pci_data = (pci_data & BRI_DRAM_SIZE_MASK) >> 4;
+@@ -2415,6 +2682,7 @@
+ return -1;
+ }
+ outSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
++ }
+ }
+ if (!pdev_valid) {
+ printk(KERN_INFO "sisfb: Total confusion - No SiS PCI VGA device found?!\n");
+@@ -2425,7 +2693,7 @@
+ #endif
+ return 0;
+
+- } else { /* 315 */
++ } else { /* 315, 330 */
+
+ inSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
+ switch ((reg & SIS315_DRAM_SIZE_MASK) >> 4) {
+@@ -2458,7 +2726,7 @@
+ reg >>= 2;
+
+ if(ivideo.chip == SIS_330) {
+-
++
+ if(reg) ivideo.video_size <<= 1;
+
+ } else {
+@@ -2470,7 +2738,7 @@
+ case SIS315_DUAL_CHANNEL_1_RANK:
+ ivideo.video_size <<= 1;
+ break;
+- case SIS315_ASYM_DDR: /* TW: DDR asymentric */
++ case SIS315_ASYM_DDR: /* TW: DDR asymetric */
+ ivideo.video_size += (ivideo.video_size/2);
+ break;
+ }
+@@ -2483,127 +2751,241 @@
+
+ }
+
+-static void sisfb_detect_VB_connect_315(void)
++#endif /* CONFIG_FB_SIS_315 */
++
++
++/* -------------- video bridge detection --------------- */
++
++static void sisfb_detect_VB_connect()
+ {
+- u8 cr32, temp=0;
++ u8 sr16, sr17, cr32, temp;
++
++ if(sisvga_engine == SIS_300_VGA) {
+
+- ivideo.TV_plug = ivideo.TV_type = 0;
++ inSISIDXREG(SISSR, IND_SIS_SCRATCH_REG_17, sr17);
++
++ if ((sr17 & 0x0F) && (ivideo.chip != SIS_300)) {
++
++ /* Old BIOSes store the detected CRT2 type in SR17
++ * instead of CR32. However, since our detection
++ * routines store their results to CR32, we now copy
++ * the remaining bits (for LCD and VGA) to CR32 for
++ * unified usage.
++ * SR17[0] CRT1 [1] LCD [2] TV [3] VGA2
++ * [4] AVIDEO [5] SVIDEO
++ */
++
++#if 0
++ if (sr17 & 0x01) orSISIDXREG(SISCR, 0x32, SIS_CRT1);
++ else andSISIDXREG(SISCR, 0x32, ~SIS_CRT1);
++
++ if (sr17 & 0x02) orSISIDXREG(SISCR, 0x32, SIS_VB_LCD);
++ else andSISIDXREG(SISCR, 0x32, ~SIS_VB_LCD);
++
++ /* no HiVision and no DVI connector here */
++ andSISIDXREG(SISCR, 0x32, ~0xc0);
++#endif
++
++ /* PAL/NTSC is stored on SR16 on such machines */
++ if (!(ivideo.vbflags & (TV_PAL | TV_NTSC))) {
++ inSISIDXREG(SISSR, IND_SIS_SCRATCH_REG_16, sr16);
++ if (sr16 & 0x20)
++ ivideo.vbflags |= TV_PAL;
++ else
++ ivideo.vbflags |= TV_NTSC;
++ }
++
++ }
+
+- switch(ivideo.hasVB) {
+- case HASVB_LVDS_CHRONTEL:
+- case HASVB_CHRONTEL:
+- SiS_SenseCh();
+- break;
+- case HASVB_301:
+- case HASVB_302:
+- SiS_Sense30x();
+- break;
+ }
+
+ inSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR32, cr32);
+
+- if ((cr32 & SIS_CRT1) && !sisfb_crt1off)
++ if (cr32 & SIS_CRT1)
+ sisfb_crt1off = 0;
+ else {
+- if (cr32 & 0x5F)
++ if (cr32 & 0x5F)
+ sisfb_crt1off = 1;
+ else
+ sisfb_crt1off = 0;
+ }
+
+- if (sisfb_crt2type != -1)
+- /* TW: Override with option */
+- ivideo.disp_state = sisfb_crt2type;
+- else if (cr32 & SIS_VB_TV)
+- ivideo.disp_state = DISPTYPE_TV;
+- else if (cr32 & SIS_VB_LCD)
+- ivideo.disp_state = DISPTYPE_LCD;
+- else if (cr32 & SIS_VB_CRT2)
+- ivideo.disp_state = DISPTYPE_CRT2;
+- else
+- ivideo.disp_state = 0;
++ ivideo.vbflags &= ~(CRT2_TV | CRT2_LCD | CRT2_VGA);
+
++ if (cr32 & SIS_VB_TV)
++ ivideo.vbflags |= CRT2_TV;
++ if (cr32 & SIS_VB_LCD)
++ ivideo.vbflags |= CRT2_LCD;
++ if (cr32 & SIS_VB_CRT2)
++ ivideo.vbflags |= CRT2_VGA;
++
++ /* TW: Detect/set TV plug & type */
+ if(sisfb_tvplug != -1)
+- /* PR/TW: Override with option */
+- ivideo.TV_plug = sisfb_tvplug;
+- else if (cr32 & SIS_VB_HIVISION) {
+- ivideo.TV_type = TVMODE_HIVISION;
+- ivideo.TV_plug = TVPLUG_SVIDEO;
+- }
++ ivideo.vbflags |= sisfb_tvplug;
++ if (cr32 & SIS_VB_HIVISION)
++ ivideo.vbflags |= (TV_HIVISION | TV_SVIDEO);
+ else if (cr32 & SIS_VB_SVIDEO)
+- ivideo.TV_plug = TVPLUG_SVIDEO;
++ ivideo.vbflags |= TV_SVIDEO;
+ else if (cr32 & SIS_VB_COMPOSITE)
+- ivideo.TV_plug = TVPLUG_COMPOSITE;
++ ivideo.vbflags |= TV_AVIDEO;
+ else if (cr32 & SIS_VB_SCART)
+- ivideo.TV_plug = TVPLUG_SCART;
++ ivideo.vbflags |= TV_SCART;
+
+- if(ivideo.TV_type == 0) {
+- /* TW: PAL/NTSC changed for 650 */
+- if((ivideo.chip <= SIS_315PRO) || (ivideo.chip >= SIS_330)) {
+-
+- inSISIDXREG(SISCR, 0x38, temp);
+- if(temp & 0x10)
+- ivideo.TV_type = TVMODE_PAL;
+- else
+- ivideo.TV_type = TVMODE_NTSC;
++ if (!(ivideo.vbflags & (TV_PAL | TV_NTSC))) {
++ if(sisvga_engine == SIS_300_VGA) {
++ inSISIDXREG(SISSR, IND_SIS_POWER_ON_TRAP, temp);
++ if (temp & 0x01)
++ ivideo.vbflags |= TV_PAL;
++ else
++ ivideo.vbflags |= TV_NTSC;
++ } else if((ivideo.chip <= SIS_315PRO) || (ivideo.chip == SIS_330)) {
+
+- } else {
++ inSISIDXREG(SISCR, 0x38, temp);
++ if(temp & 0x10)
++ ivideo.vbflags |= TV_PAL;
++ else
++ ivideo.vbflags |= TV_NTSC;
+
+- inSISIDXREG(SISCR, 0x79, temp);
+- if(temp & 0x20)
+- ivideo.TV_type = TVMODE_PAL;
+- else
+- ivideo.TV_type = TVMODE_NTSC;
+- }
++ } else {
++
++ inSISIDXREG(SISCR, 0x79, temp);
++ if(temp & 0x20)
++ ivideo.vbflags |= TV_PAL;
++ else
++ ivideo.vbflags |= TV_NTSC;
++ }
+ }
+
+ /* TW: Copy forceCRT1 option to CRT1off if option is given */
+ if (sisfb_forcecrt1 != -1) {
+- if (sisfb_forcecrt1) sisfb_crt1off = 0;
+- else sisfb_crt1off = 1;
++ if(sisfb_forcecrt1) sisfb_crt1off = 0;
++ else sisfb_crt1off = 1;
+ }
+-}
+-
+-static void sisfb_get_VB_type_315(void)
+-{
+- u8 reg;
+
+- if (!sisfb_has_VB_315()) {
+- inSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR37, reg);
+- switch ((reg & SIS_EXTERNAL_CHIP_MASK) >> 1) {
+- case SIS310_EXTERNAL_CHIP_LVDS:
+- ivideo.hasVB = HASVB_LVDS;
+- break;
+- case SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL:
+- ivideo.hasVB = HASVB_LVDS_CHRONTEL;
+- break;
+- default:
+- break;
+- }
+- }
+ }
+
+-
+-static int sisfb_has_VB_315(void)
++static void sisfb_get_VB_type(void)
+ {
+ u8 vb_chipid;
++ u8 reg;
++ char stdstr[] = "sisfb: Detected";
++ char bridgestr[] = "video bridge";
++ char lvdsstr[] = "LVDS transmitter";
++ char chrstr[] = "Chrontel TV encoder";
++
++ ivideo.hasVB = HASVB_NONE;
++ sishw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
++ sishw_ext.Is301BDH = FALSE;
++ sishw_ext.usExternalChip = 0;
+
+ inSISIDXREG(SISPART4, 0x00, vb_chipid);
+ switch (vb_chipid) {
+ case 0x01:
+ ivideo.hasVB = HASVB_301;
++ inSISIDXREG(SISPART4, 0x01, reg);
++ if(reg < 0xb0) {
++ ivideo.vbflags |= VB_301;
++ sishw_ext.ujVBChipID = VB_CHIP_301;
++ printk(KERN_INFO "%s SiS301 %s\n", stdstr, bridgestr);
++ } else if(reg < 0xd0) {
++ ivideo.vbflags |= VB_301B;
++ sishw_ext.ujVBChipID = VB_CHIP_301B;
++ printk(KERN_INFO "%s SiS301B %s\n", stdstr, bridgestr);
++ } else if(reg < 0xe0) {
++ ivideo.vbflags |= VB_301LV;
++ sishw_ext.ujVBChipID = VB_CHIP_301LV;
++ printk(KERN_INFO "%s SiS301LV %s\n", stdstr, bridgestr);
++ } else if(reg <= 0xe1) {
++ ivideo.vbflags |= VB_302LV;
++ sishw_ext.ujVBChipID = VB_CHIP_302LV;
++ printk(KERN_INFO "%s SiS302LV %s\n", stdstr, bridgestr);
++ }
+ break;
+ case 0x02:
+ ivideo.hasVB = HASVB_302;
++ inSISIDXREG(SISPART4, 0x01, reg);
++ if(reg < 0xd0) {
++ ivideo.vbflags |= VB_302B;
++ sishw_ext.ujVBChipID = VB_CHIP_302B;
++ printk(KERN_INFO "%s SiS302B %s\n", stdstr, bridgestr);
++ } else if(reg < 0xe0) {
++ ivideo.vbflags |= VB_301LV;
++ sishw_ext.ujVBChipID = VB_CHIP_301LV;
++ printk(KERN_INFO "%s SiS301LV %s\n", stdstr, bridgestr);
++ } else if(reg <= 0xe1) {
++ ivideo.vbflags |= VB_302LV;
++ sishw_ext.ujVBChipID = VB_CHIP_302LV;
++ printk(KERN_INFO "%s SiS302LV %s\n", stdstr, bridgestr);
++ }
+ break;
+- default:
+- ivideo.hasVB = HASVB_NONE;
+- return FALSE;
+ }
+- return TRUE;
+-}
+
+-#endif /* CONFIG_FB_SIS_315 */
++ if(ivideo.vbflags & (VB_301B | VB_302B)) {
++ inSISIDXREG(SISPART4,0x23,reg);
++ if(!(reg & 0x02)) {
++ sishw_ext.Is301BDH = TRUE;
++ ivideo.vbflags |= VB_30xBDH;
++ printk(KERN_INFO "This %s does not support LCD output\n", bridgestr);
++ }
++ }
++
++ if((!(ivideo.vbflags & VB_VIDEOBRIDGE)) && (ivideo.chip != SIS_300)) {
++ inSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR37, reg);
++ reg &= SIS_EXTERNAL_CHIP_MASK;
++ reg >>= 1;
++ if(sisvga_engine == SIS_300_VGA) {
++ switch (reg) {
++ case SIS_EXTERNAL_CHIP_LVDS:
++ ivideo.hasVB = HASVB_LVDS;
++ ivideo.vbflags |= VB_LVDS;
++ sishw_ext.usExternalChip = 0x01;
++ printk(KERN_INFO "%s %s\n", stdstr, lvdsstr);
++ break;
++ case SIS_EXTERNAL_CHIP_TRUMPION:
++ ivideo.hasVB = HASVB_TRUMPION;
++ ivideo.vbflags |= VB_TRUMPION;
++ sishw_ext.usExternalChip = 0x02;
++ printk(KERN_INFO "%s Trumpion LCD scaler\n", stdstr);
++ break;
++ case SIS_EXTERNAL_CHIP_CHRONTEL:
++ ivideo.hasVB = HASVB_CHRONTEL;
++ ivideo.vbflags |= VB_CHRONTEL;
++ sishw_ext.usExternalChip = 0x04;
++ printk(KERN_INFO "%s %s\n", stdstr, chrstr);
++ break;
++ case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL:
++ ivideo.hasVB = HASVB_LVDS_CHRONTEL;
++ ivideo.vbflags |= (VB_LVDS | VB_CHRONTEL);
++ sishw_ext.usExternalChip = 0x05;
++ printk(KERN_INFO "%s %s and %s\n", stdstr, lvdsstr, chrstr);
++ break;
++ }
++ } else {
++ switch (reg) {
++ case SIS310_EXTERNAL_CHIP_LVDS:
++ ivideo.hasVB = HASVB_LVDS;
++ ivideo.vbflags |= VB_LVDS;
++ sishw_ext.usExternalChip = 0x01;
++ printk(KERN_INFO "%s %s\n", stdstr, lvdsstr);
++ break;
++ case SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL:
++ ivideo.hasVB = HASVB_LVDS_CHRONTEL;
++ ivideo.vbflags |= (VB_LVDS | VB_CHRONTEL);
++ sishw_ext.usExternalChip = 0x05;
++ printk(KERN_INFO "%s %s and %s\n", stdstr, lvdsstr, chrstr);
++ break;
++ }
++ }
++
++ }
++
++ if(ivideo.vbflags & VB_SISBRIDGE) {
++ SiS_Sense30x();
++ } else if(ivideo.vbflags & VB_CHRONTEL) {
++ SiS_SenseCh();
++ }
++
++}
+
+ /* ------------------ Sensing routines ------------------ */
+
+@@ -2621,34 +3003,39 @@
+ inSISIDXREG(SISPART4,0x03,temp);
+ temp ^= 0x0e;
+ temp &= tempch;
+- return(temp);
++ return((temp == tempch));
+ }
+
+ void
+ SiS_Sense30x(void)
+ {
+- u8 backupP4_0d;
++ u8 backupP4_0d,backupP2_00;
+ u8 testsvhs_tempbl, testsvhs_tempbh;
+ u8 testsvhs_tempcl, testsvhs_tempch;
+ u8 testcvbs_tempbl, testcvbs_tempbh;
+ u8 testcvbs_tempcl, testcvbs_tempch;
+ u8 testvga2_tempbl, testvga2_tempbh;
+ u8 testvga2_tempcl, testvga2_tempch;
+- int myflag, result;
++ int myflag, result, haveresult, i, j;
++ char stdstr[] = "sisfb: Detected";
++ char tvstr[] = "TV connected to";
+
+ inSISIDXREG(SISPART4,0x0d,backupP4_0d);
+ outSISIDXREG(SISPART4,0x0d,(backupP4_0d | 0x04));
+
++ inSISIDXREG(SISPART2,0x00,backupP2_00);
++ outSISIDXREG(SISPART2,0x00,(backupP2_00 | 0x1c));
++
+ if(sisvga_engine == SIS_300_VGA) {
+
+- testvga2_tempbh = 0x00; testvga2_tempbl = 0xd1;
+- testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xb9;
+- testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xb3;
+- if((sishw_ext.ujVBChipID != VB_CHIP_301) &&
+- (sishw_ext.ujVBChipID != VB_CHIP_302) ) {
+- testvga2_tempbh = 0x01; testvga2_tempbl = 0x90;
+- testsvhs_tempbh = 0x01; testsvhs_tempbl = 0x6b;
+- testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x74;
++ if(ivideo.vbflags & (VB_301B|VB_302B|VB_301LV|VB_302LV)) {
++ testvga2_tempbh = 0x01; testvga2_tempbl = 0x90;
++ testsvhs_tempbh = 0x01; testsvhs_tempbl = 0x6b;
++ testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x74;
++ } else {
++ testvga2_tempbh = 0x00; testvga2_tempbl = 0xd1;
++ testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xb9;
++ testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xb3;
+ }
+ inSISIDXREG(SISPART4,0x01,myflag);
+ if(myflag & 0x04) {
+@@ -2657,35 +3044,36 @@
+ testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xee;
+ }
+ testvga2_tempch = 0x0e; testvga2_tempcl = 0x08;
+- testsvhs_tempch = 0x06; testsvhs_tempcl = 0x04;
++ testsvhs_tempch = 0x04; testsvhs_tempcl = 0x04;
+ testcvbs_tempch = 0x08; testcvbs_tempcl = 0x04;
++ if(ivideo.vbflags & (VB_301LV|VB_302LV)) {
++ testvga2_tempbh = 0x00; testvga2_tempbl = 0x00;
++ testvga2_tempch = 0x00; testvga2_tempcl = 0x00;
++ }
+ if(ivideo.chip == SIS_300) {
+ inSISIDXREG(SISSR,0x3b,myflag);
+ if(!(myflag & 0x01)) {
+- testvga2_tempbh = 0x00; testvga2_tempbl = 0x00;
+- testvga2_tempch = 0x00; testvga2_tempcl = 0x00;
++ testvga2_tempbh = 0x00; testvga2_tempbl = 0x00;
++ testvga2_tempch = 0x00; testvga2_tempcl = 0x00;
+ }
+ }
+
+ } else {
+
+- testvga2_tempbh = 0x00; testvga2_tempbl = 0xd1;
+- testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xb9;
+- testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xb3;
+- if((sishw_ext.ujVBChipID != VB_CHIP_301) &&
+- (sishw_ext.ujVBChipID != VB_CHIP_302)) {
+- testvga2_tempbh = 0x01; testvga2_tempbl = 0x90;
+- testsvhs_tempbh = 0x01; testsvhs_tempbl = 0x6b;
+- testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x74;
+- if(sishw_ext.ujVBChipID == VB_CHIP_301LV ||
+- sishw_ext.ujVBChipID == VB_CHIP_302LV) {
+- testvga2_tempbh = 0x00; testvga2_tempbl = 0x00;
+- testsvhs_tempbh = 0x02; testsvhs_tempbl = 0x00;
+- testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x00;
+- }
++ if(ivideo.vbflags & (VB_301B|VB_302B)) {
++ testvga2_tempbh = 0x01; testvga2_tempbl = 0x90;
++ testsvhs_tempbh = 0x01; testsvhs_tempbl = 0x6b;
++ testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x74;
++ } else if(ivideo.vbflags & (VB_301LV|VB_302LV)) {
++ testvga2_tempbh = 0x00; testvga2_tempbl = 0x00;
++ testsvhs_tempbh = 0x02; testsvhs_tempbl = 0x00;
++ testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x00;
++ } else {
++ testvga2_tempbh = 0x00; testvga2_tempbl = 0xd1;
++ testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xb9;
++ testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xb3;
+ }
+- if(sishw_ext.ujVBChipID != VB_CHIP_301LV &&
+- sishw_ext.ujVBChipID != VB_CHIP_302LV) {
++ if(ivideo.vbflags & (VB_301|VB_301B|VB_302B)) {
+ inSISIDXREG(SISPART4,0x01,myflag);
+ if(myflag & 0x04) {
+ testvga2_tempbh = 0x00; testvga2_tempbl = 0xfd;
+@@ -2693,49 +3081,78 @@
+ testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xee;
+ }
+ }
+- if((sishw_ext.ujVBChipID == VB_CHIP_301LV) ||
+- (sishw_ext.ujVBChipID == VB_CHIP_302LV) ) {
++ if(ivideo.vbflags & (VB_301LV|VB_302LV)) {
+ testvga2_tempbh = 0x00; testvga2_tempbl = 0x00;
+ testvga2_tempch = 0x00; testvga2_tempcl = 0x00;
+ testsvhs_tempch = 0x04; testsvhs_tempcl = 0x08;
+ testcvbs_tempch = 0x08; testcvbs_tempcl = 0x08;
+ } else {
+ testvga2_tempch = 0x0e; testvga2_tempcl = 0x08;
+- testsvhs_tempch = 0x06; testsvhs_tempcl = 0x04;
++ testsvhs_tempch = 0x04; testsvhs_tempcl = 0x04;
+ testcvbs_tempch = 0x08; testcvbs_tempcl = 0x04;
+ }
+ }
+
+ if(testvga2_tempch || testvga2_tempcl || testvga2_tempbh || testvga2_tempbl) {
+- result = SISDoSense(testvga2_tempbl, testvga2_tempbh,
+- testvga2_tempcl, testvga2_tempch);
+- if(result) {
+- printk(KERN_INFO "sisfb: Detected secondary VGA connection\n");
+- orSISIDXREG(SISCR, 0x32, 0x10);
+- }
++ haveresult = 0;
++ for(j = 0; j < 10; j++) {
++ result = 0;
++ for(i = 0; i < 3; i++) {
++ if(SISDoSense(testvga2_tempbl, testvga2_tempbh,
++ testvga2_tempcl, testvga2_tempch))
++ result++;
++ }
++ if((result == 0) || (result >= 2)) break;
++ }
++ if(result) {
++ printk(KERN_INFO "%s secondary VGA connection\n", stdstr);
++ orSISIDXREG(SISCR, 0x32, 0x10);
++ } else {
++ andSISIDXREG(SISCR, 0x32, ~0x10);
++ }
++ }
++
++ haveresult = 0;
++ for(j = 0; j < 10; j++) {
++ result = 0;
++ for(i = 0; i < 3; i++) {
++ if(SISDoSense(testsvhs_tempbl, testsvhs_tempbh,
++ testsvhs_tempcl, testsvhs_tempch))
++ result++;
++ }
++ if((result == 0) || (result >= 2)) break;
+ }
+-
+- result = SISDoSense(testsvhs_tempbl, testsvhs_tempbh,
+- testsvhs_tempcl, testsvhs_tempch);
+ if(result) {
+- printk(KERN_INFO "sisfb: Detected TV connected to SVHS output\n");
+- /* TW: So we can be sure that there IS a SVHS output */
+- ivideo.TV_plug = TVPLUG_SVIDEO;
++ printk(KERN_INFO "%s %s SVIDEO output\n", stdstr, tvstr);
++ ivideo.vbflags |= TV_SVIDEO;
+ orSISIDXREG(SISCR, 0x32, 0x02);
++ andSISIDXREG(SISCR, 0x32, ~0x05);
+ }
+
+ if(!result) {
+- result = SISDoSense(testcvbs_tempbl, testcvbs_tempbh,
+- testcvbs_tempcl, testcvbs_tempch);
++
++ haveresult = 0;
++ for(j = 0; j < 10; j++) {
++ result = 0;
++ for(i = 0; i < 3; i++) {
++ if(SISDoSense(testcvbs_tempbl, testcvbs_tempbh,
++ testcvbs_tempcl, testcvbs_tempch))
++ result++;
++ }
++ if((result == 0) || (result >= 2)) break;
++ }
+ if(result) {
+- printk(KERN_INFO "sisfb: Detected TV connected to CVBS output\n");
+- /* TW: So we can be sure that there IS a CVBS output */
+- ivideo.TV_plug = TVPLUG_COMPOSITE;
++ printk(KERN_INFO "%s %s COMPOSITE output\n", stdstr, tvstr);
++ ivideo.vbflags |= TV_AVIDEO;
+ orSISIDXREG(SISCR, 0x32, 0x01);
++ andSISIDXREG(SISCR, 0x32, ~0x06);
++ } else {
++ andSISIDXREG(SISCR, 0x32, ~0x07);
+ }
+ }
+ SISDoSense(0, 0, 0, 0);
+
++ outSISIDXREG(SISPART2,0x00,backupP2_00);
+ outSISIDXREG(SISPART4,0x0d,backupP4_0d);
+ }
+
+@@ -2744,51 +3161,84 @@
+ SiS_SenseCh(void)
+ {
+
+- u8 temp1;
+-#ifdef CONFIG_FB_SIS_315
+- u8 temp2;
++ u8 temp1, temp2;
++#ifdef CONFIG_FB_SIS_300
++ unsigned char test[3];
++ int i;
+ #endif
++ char stdstr[] = "sisfb: Chrontel: Detected TV connected to";
+
+ if(ivideo.chip < SIS_315H) {
+
+ #ifdef CONFIG_FB_SIS_300
+- SiS_Pr.SiS_IF_DEF_CH70xx = 1; /* TW: Chrontel 7005 */
++ SiS_Pr.SiS_IF_DEF_CH70xx = 1; /* Chrontel 700x */
++ SiS_SetChrontelGPIO(&SiS_Pr, 0x9c); /* Set general purpose IO for Chrontel communication */
++ SiS_DDC2Delay(&SiS_Pr, 1000);
+ temp1 = SiS_GetCH700x(&SiS_Pr, 0x25);
+- if ((temp1 >= 50) && (temp1 <= 100)) {
+- /* TW: Read power status */
++ /* TW: See Chrontel TB31 for explanation */
++ temp2 = SiS_GetCH700x(&SiS_Pr, 0x0e);
++ if(((temp2 & 0x07) == 0x01) || (temp2 & 0x04)) {
++ SiS_SetCH700x(&SiS_Pr, 0x0b0e);
++ SiS_DDC2Delay(&SiS_Pr, 300);
++ }
++ temp2 = SiS_GetCH700x(&SiS_Pr, 0x25);
++ if(temp2 != temp1) temp1 = temp2;
++
++ if((temp1 >= 0x22) && (temp1 <= 0x50)) {
++ /* Read power status */
+ temp1 = SiS_GetCH700x(&SiS_Pr, 0x0e);
+ if((temp1 & 0x03) != 0x03) {
+- /* TW: Power all outputs */
+- SiS_SetCH70xxANDOR(&SiS_Pr, 0x030E,0xF8);
++ /* Power all outputs */
++ SiS_SetCH700x(&SiS_Pr, 0x0B0E);
++ SiS_DDC2Delay(&SiS_Pr, 300);
+ }
+- /* TW: Sense connected TV devices */
+- SiS_SetCH700x(&SiS_Pr, 0x0110);
+- SiS_SetCH700x(&SiS_Pr, 0x0010);
+- temp1 = SiS_GetCH700x(&SiS_Pr, 0x10);
+- if(!(temp1 & 0x08)) {
+- printk(KERN_INFO
+- "sisfb: Chrontel: Detected TV connected to SVHS output\n");
+- /* TW: So we can be sure that there IS a SVHS output */
+- ivideo.TV_plug = TVPLUG_SVIDEO;
++ /* Sense connected TV devices */
++ for(i = 0; i < 3; i++) {
++ SiS_SetCH700x(&SiS_Pr, 0x0110);
++ SiS_DDC2Delay(&SiS_Pr, 0x96);
++ SiS_SetCH700x(&SiS_Pr, 0x0010);
++ SiS_DDC2Delay(&SiS_Pr, 0x96);
++ temp1 = SiS_GetCH700x(&SiS_Pr, 0x10);
++ if(!(temp1 & 0x08)) test[i] = 0x02;
++ else if(!(temp1 & 0x02)) test[i] = 0x01;
++ else test[i] = 0;
++ SiS_DDC2Delay(&SiS_Pr, 0x96);
++ }
++
++ if(test[0] == test[1]) temp1 = test[0];
++ else if(test[0] == test[2]) temp1 = test[0];
++ else if(test[1] == test[2]) temp1 = test[1];
++ else {
++ printk(KERN_INFO
++ "sisfb: TV detection unreliable - test results varied\n");
++ temp1 = test[2];
++ }
++ if(temp1 == 0x02) {
++ printk(KERN_INFO "%s SVIDEO output\n", stdstr);
++ ivideo.vbflags |= TV_SVIDEO;
+ orSISIDXREG(SISCR, 0x32, 0x02);
+- } else if (!(temp1 & 0x02)) {
+- printk(KERN_INFO
+- "sisfb: Chrontel: Detected TV connected to CVBS output\n");
+- /* TW: So we can be sure that there IS a CVBS output */
+- ivideo.TV_plug = TVPLUG_COMPOSITE;
++ andSISIDXREG(SISCR, 0x32, ~0x05);
++ } else if (temp1 == 0x01) {
++ printk(KERN_INFO "%s CVBS output\n", stdstr);
++ ivideo.vbflags |= TV_AVIDEO;
+ orSISIDXREG(SISCR, 0x32, 0x01);
++ andSISIDXREG(SISCR, 0x32, ~0x06);
+ } else {
+ SiS_SetCH70xxANDOR(&SiS_Pr, 0x010E,0xF8);
++ andSISIDXREG(SISCR, 0x32, ~0x07);
+ }
+ } else if(temp1 == 0) {
+ SiS_SetCH70xxANDOR(&SiS_Pr, 0x010E,0xF8);
++ andSISIDXREG(SISCR, 0x32, ~0x07);
+ }
++ /* Set general purpose IO for Chrontel communication */
++ SiS_SetChrontelGPIO(&SiS_Pr, 0x00);
+ #endif
+
+ } else {
+
+ #ifdef CONFIG_FB_SIS_315
+- SiS_Pr.SiS_IF_DEF_CH70xx = 2; /* TW: Chrontel 7019 */
++ SiS_Pr.SiS_IF_DEF_CH70xx = 2; /* Chrontel 7019 */
+ temp1 = SiS_GetCH701x(&SiS_Pr, 0x49);
+ SiS_SetCH701x(&SiS_Pr, 0x2049);
+ SiS_DDC2Delay(&SiS_Pr, 0x96);
+@@ -2808,22 +3258,24 @@
+ if( (temp1 & 0x01) && (temp1 & 0x02) ) temp1 = 0x04;
+ switch(temp1) {
+ case 0x01:
+- printk(KERN_INFO
+- "sisfb: Chrontel: Detected TV connected to CVBS output\n");
+- ivideo.TV_plug = TVPLUG_COMPOSITE;
++ printk(KERN_INFO "%s CVBS output\n", stdstr);
++ ivideo.vbflags |= TV_AVIDEO;
+ orSISIDXREG(SISCR, 0x32, 0x01);
++ andSISIDXREG(SISCR, 0x32, ~0x06);
+ break;
+ case 0x02:
+- printk(KERN_INFO
+- "sisfb: Chrontel: Detected TV connected to SVHS output\n");
+- ivideo.TV_plug = TVPLUG_SVIDEO;
++ printk(KERN_INFO "%s SVIDEO output\n", stdstr);
++ ivideo.vbflags |= TV_SVIDEO;
+ orSISIDXREG(SISCR, 0x32, 0x02);
++ andSISIDXREG(SISCR, 0x32, ~0x05);
+ break;
+ case 0x04:
+- /* TW: This should not happen */
+- printk(KERN_INFO
+- "sisfb: Chrontel: Detected TV connected to SCART output\n");
++ printk(KERN_INFO "%s SCART output\n", stdstr);
++ orSISIDXREG(SISCR, 0x32, 0x04);
++ andSISIDXREG(SISCR, 0x32, ~0x03);
+ break;
++ default:
++ andSISIDXREG(SISCR, 0x32, ~0x07);
+ }
+ #endif
+
+@@ -2845,8 +3297,8 @@
+ unsigned long *write_port = 0;
+ SIS_CMDTYPE cmd_type;
+ #ifndef AGPOFF
+- struct agp_kern_info *agp_info;
+- struct agp_memory *agp;
++ agp_kern_info *agp_info;
++ agp_memory *agp;
+ u32 agp_phys;
+ #endif
+ #endif
+@@ -2860,14 +3312,21 @@
+ * in XF86Config-4.
+ * The heap start can also be specified by parameter "mem" when starting the sisfb
+ * driver. sisfb mem=1024 lets heap starts at 1MB, etc.
++ *
++ * On the 315 and Xabre series, the default is a 1MB heap since DRI is not
++ * supported there.
+ */
+ if ((!sisfb_mem) || (sisfb_mem > (ivideo.video_size/1024))) {
+- if (ivideo.video_size > 0x1000000) {
++ if(sisvga_engine == SIS_300_VGA) {
++ if (ivideo.video_size > 0x1000000) {
+ ivideo.heapstart = 0xc00000;
+- } else if (ivideo.video_size > 0x800000) {
++ } else if (ivideo.video_size > 0x800000) {
+ ivideo.heapstart = 0x800000;
+- } else {
++ } else {
+ ivideo.heapstart = 0x400000;
++ }
++ } else {
++ ivideo.heapstart = ivideo.video_size - 0x100000;
+ }
+ } else {
+ ivideo.heapstart = sisfb_mem * 1024;
+@@ -2883,7 +3342,7 @@
+ #ifdef CONFIG_FB_SIS_315
+ if (sisvga_engine == SIS_315_VGA) {
+ /* TW: Now initialize the 310 series' command queue mode.
+- * On 310/325, there are three queue modes available which
++ * On 315, there are three queue modes available which
+ * are chosen by setting bits 7:5 in SR26:
+ * 1. MMIO queue mode (bit 5, 0x20). The hardware will keep
+ * track of the queue, the FIFO, command parsing and so
+@@ -2923,8 +3382,8 @@
+
+ #ifndef AGPOFF
+ if (sisfb_queuemode == AGP_CMD_QUEUE) {
+- agp_info = vmalloc(sizeof(*agp_info));
+- memset((void*)agp_info, 0x00, sizeof(*agp_info));
++ agp_info = vmalloc(sizeof(agp_kern_info));
++ memset((void*)agp_info, 0x00, sizeof(agp_kern_info));
+ agp_copy_info(agp_info);
+
+ agp_backend_acquire();
+@@ -3025,10 +3484,6 @@
+ break;
+
+ default: /* MMIO */
+- /* TW: This previously only wrote SIS_MMIO_CMD_ENABLE
+- * to IND_SIS_CMDQUEUE_SET. I doubt that this is
+- * enough. Reserve memory in any way.
+- */
+ sisfb_heap_end -= COMMAND_QUEUE_AREA_SIZE;
+ sisfb_heap_size -= COMMAND_QUEUE_AREA_SIZE;
+
+@@ -3037,7 +3492,7 @@
+
+ *write_port = *read_port;
+
+- /* TW: Set Auto_Correction bit */
++ /* Set Auto_Correction bit */
+ temp |= (SIS_MMIO_CMD_ENABLE | SIS_CMD_AUTO_CORR);
+ outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, temp);
+
+@@ -3333,7 +3788,6 @@
+ req->offset = poh->offset;
+ req->size = poh->size;
+ }
+-
+ }
+
+ void sis_free(unsigned long base)
+@@ -3352,35 +3806,70 @@
+
+ static void sisfb_pre_setmode(void)
+ {
+- u8 cr30 = 0, cr31 = 0;
++ u8 cr30 = 0, cr31 = 0, cr33 = 0;
++
++ ivideo.currentvbflags &= (VB_VIDEOBRIDGE | VB_DISPTYPE_DISP2);
+
+ inSISIDXREG(SISCR, 0x31, cr31);
+ cr31 &= ~0x60;
++ cr31 |= 0x04;
+
+- switch (ivideo.disp_state & DISPTYPE_DISP2) {
+- case DISPTYPE_CRT2:
+- cr30 = (SIS_VB_OUTPUT_CRT2 | SIS_SIMULTANEOUS_VIEW_ENABLE);
+- cr31 |= SIS_DRIVER_MODE;
+- break;
+- case DISPTYPE_LCD:
+- cr30 = (SIS_VB_OUTPUT_LCD | SIS_SIMULTANEOUS_VIEW_ENABLE);
+- cr31 |= SIS_DRIVER_MODE;
+- break;
+- case DISPTYPE_TV:
+- if (ivideo.TV_type == TVMODE_HIVISION)
++ cr33 = sisfb_rate_idx & 0x0F;
++
++ SiS_SetEnableDstn(&SiS_Pr, FALSE);
++ SiS_SetEnableFstn(&SiS_Pr, FALSE);
++
++ switch (ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
++ case CRT2_TV:
++ ivideo.disp_state = DISPTYPE_TV;
++ if (ivideo.vbflags & TV_HIVISION) {
+ cr30 = (SIS_VB_OUTPUT_HIVISION | SIS_SIMULTANEOUS_VIEW_ENABLE);
+- else if (ivideo.TV_plug == TVPLUG_SVIDEO)
++ ivideo.currentvbflags |= (TV_HIVISION | TV_SVIDEO);
++ ivideo.TV_type = TVMODE_HIVISION;
++ ivideo.TV_plug = TVPLUG_SVIDEO;
++ } else if (ivideo.vbflags & TV_SVIDEO) {
+ cr30 = (SIS_VB_OUTPUT_SVIDEO | SIS_SIMULTANEOUS_VIEW_ENABLE);
+- else if (ivideo.TV_plug == TVPLUG_COMPOSITE)
++ ivideo.currentvbflags |= TV_SVIDEO;
++ ivideo.TV_plug = TVPLUG_SVIDEO;
++ } else if (ivideo.vbflags & TV_AVIDEO) {
+ cr30 = (SIS_VB_OUTPUT_COMPOSITE | SIS_SIMULTANEOUS_VIEW_ENABLE);
+- else if (ivideo.TV_plug == TVPLUG_SCART)
++ ivideo.currentvbflags |= TV_AVIDEO;
++ ivideo.TV_plug = TVPLUG_COMPOSITE;
++ } else if (ivideo.vbflags & TV_SCART) {
+ cr30 = (SIS_VB_OUTPUT_SCART | SIS_SIMULTANEOUS_VIEW_ENABLE);
++ ivideo.currentvbflags |= TV_SCART;
++ ivideo.TV_plug = TVPLUG_SCART;
++ }
+ cr31 |= SIS_DRIVER_MODE;
+
+- if (sisfb_tvmode == 1 || ivideo.TV_type == TVMODE_PAL)
+- cr31 |= 0x01;
+- else
+- cr31 &= ~0x01;
++ if(!(ivideo.vbflags & TV_HIVISION)) {
++ if (ivideo.vbflags & TV_PAL) {
++ cr31 |= 0x01;
++ ivideo.currentvbflags |= TV_PAL;
++ ivideo.TV_type = TVMODE_PAL;
++ } else {
++ cr31 &= ~0x01;
++ ivideo.currentvbflags |= TV_NTSC;
++ ivideo.TV_type = TVMODE_NTSC;
++ }
++ }
++ break;
++ case CRT2_LCD:
++ ivideo.disp_state = DISPTYPE_LCD;
++ cr30 = (SIS_VB_OUTPUT_LCD | SIS_SIMULTANEOUS_VIEW_ENABLE);
++ cr31 |= SIS_DRIVER_MODE;
++ SiS_SetEnableDstn(&SiS_Pr, sisfb_dstn);
++ SiS_SetEnableFstn(&SiS_Pr, sisfb_fstn);
++ break;
++ case CRT2_VGA:
++ ivideo.disp_state = DISPTYPE_CRT2;
++ cr30 = (SIS_VB_OUTPUT_CRT2 | SIS_SIMULTANEOUS_VIEW_ENABLE);
++ cr31 |= SIS_DRIVER_MODE;
++ if(sisfb_nocrt2rate) {
++ cr33 |= (sisbios_mode[sisfb_mode_idx].rate_idx << 4);
++ } else {
++ cr33 |= ((sisfb_rate_idx & 0x0F) << 4);
++ }
+ break;
+ default: /* disable CRT2 */
+ cr30 = 0x00;
+@@ -3389,8 +3878,14 @@
+
+ outSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR30, cr30);
+ outSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR31, cr31);
++ outSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR33, cr33);
+
+- outSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR33, (sisfb_rate_idx & 0x0F));
++#ifdef CONFIG_FB_SIS_315
++ if(sisvga_engine == SIS_315_VGA) {
++ /* Clear LCDA and PAL-N/M bits */
++ andSISIDXREG(SISCR,0x38,~0xc3);
++ }
++#endif
+
+ if(ivideo.accel) sisfb_syncaccel();
+
+@@ -3400,67 +3895,89 @@
+ static void sisfb_post_setmode(void)
+ {
+ u8 reg;
++ BOOLEAN crt1isoff = FALSE;
++#ifdef CONFIG_FB_SIS_315
++ u8 reg1;
++#endif
++#ifdef CONFIG_FB_SIS_300
+ BOOLEAN doit = TRUE;
+-#if 0 /* TW: Wrong: Is not in MMIO space, but in RAM */
+- /* Backup mode number to MMIO space */
+- if(ivideo.mmio_vbase) {
+- *(volatile u8 *)(((u8*)ivideo.mmio_vbase) + 0x449) = (unsigned char)sisfb_mode_no;
+- }
+-#endif
+-
+- if (ivideo.video_bpp == 8) {
+- /* TW: We can't switch off CRT1 on LVDS/Chrontel in 8bpp Modes */
+- if ((ivideo.hasVB == HASVB_LVDS) || (ivideo.hasVB == HASVB_LVDS_CHRONTEL)) {
+- doit = FALSE;
+- }
+- /* TW: We can't switch off CRT1 on 301B-DH in 8bpp Modes if using LCD */
+- if ( (sishw_ext.Is301BDH) && (ivideo.disp_state & DISPTYPE_LCD) ) {
+- doit = FALSE;
+- }
+- }
+-
++#endif
+ /* TW: We can't switch off CRT1 if bridge is in slave mode */
+- if(ivideo.hasVB != HASVB_NONE) {
+- inSISIDXREG(SISPART1, 0x00, reg);
++ if(ivideo.vbflags & VB_VIDEOBRIDGE) {
++#ifdef CONFIG_FB_SIS_300
+ if(sisvga_engine == SIS_300_VGA) {
++ inSISIDXREG(SISPART1, 0x00, reg);
+ if((reg & 0xa0) == 0x20) {
+ doit = FALSE;
+ }
+ }
+- if(sisvga_engine == SIS_315_VGA) {
+- if((reg & 0x50) == 0x10) {
+- doit = FALSE;
+- }
+- }
++#endif
+ } else sisfb_crt1off = 0;
+
+- inSISIDXREG(SISCR, 0x17, reg);
+- if((sisfb_crt1off) && (doit))
+- reg &= ~0x80;
+- else
+- reg |= 0x80;
+- outSISIDXREG(SISCR, 0x17, reg);
++ if(sisvga_engine == SIS_300_VGA) {
+
+- andSISIDXREG(SISSR, IND_SIS_RAMDAC_CONTROL, ~0x04);
++#ifdef CONFIG_FB_SIS_300
++ if((sisfb_crt1off) && (doit)) {
++ crt1isoff = TRUE;
++ reg = 0x00;
++ } else {
++ crt1isoff = FALSE;
++ reg = 0x80;
++ }
++ setSISIDXREG(SISCR, 0x17, 0x7f, reg);
++#endif
++
++ } else {
++
++#ifdef CONFIG_FB_SIS_315
++ if(sisfb_crt1off) {
++ crt1isoff = TRUE;
++ reg = 0x40;
++ reg1 = 0xc0;
++ } else {
++ crt1isoff = FALSE;
++ reg = 0x00;
++ reg1 = 0x00;
+
+- if((ivideo.disp_state & DISPTYPE_TV) && (ivideo.hasVB == HASVB_301)) {
++ }
++ setSISIDXREG(SISCR, 0x63, ~0x40, reg);
++ setSISIDXREG(SISSR, 0x1f, ~0xc0, reg1);
++#endif
++
++ }
++
++ if(crt1isoff) {
++ ivideo.currentvbflags &= ~VB_DISPTYPE_CRT1;
++ ivideo.currentvbflags |= VB_SINGLE_MODE;
++ ivideo.disp_state |= DISPMODE_SINGLE;
++ } else {
++ ivideo.currentvbflags |= VB_DISPTYPE_CRT1;
++ ivideo.disp_state |= DISPTYPE_CRT1;
++ if(ivideo.currentvbflags & VB_DISPTYPE_CRT2) {
++ ivideo.currentvbflags |= VB_MIRROR_MODE;
++ ivideo.disp_state |= DISPMODE_MIRROR;
++ } else {
++ ivideo.currentvbflags |= VB_SINGLE_MODE;
++ ivideo.disp_state |= DISPMODE_SINGLE;
++ }
++ }
+
+- inSISIDXREG(SISPART4, 0x01, reg);
++ andSISIDXREG(SISSR, IND_SIS_RAMDAC_CONTROL, ~0x04);
+
+- if(reg < 0xB0) { /* Set filter for SiS301 */
++ if((ivideo.currentvbflags & CRT2_TV) && (ivideo.vbflags & VB_301)) { /* Set filter for SiS301 */
+
+ switch (ivideo.video_width) {
+ case 320:
+- filter_tb = (ivideo.TV_type == TVMODE_NTSC) ? 4 : 12;
++ filter_tb = (ivideo.vbflags & TV_NTSC) ? 4 : 12;
+ break;
+ case 640:
+- filter_tb = (ivideo.TV_type == TVMODE_NTSC) ? 5 : 13;
++ filter_tb = (ivideo.vbflags & TV_NTSC) ? 5 : 13;
+ break;
+ case 720:
+- filter_tb = (ivideo.TV_type == TVMODE_NTSC) ? 6 : 14;
++ filter_tb = (ivideo.vbflags & TV_NTSC) ? 6 : 14;
+ break;
+ case 800:
+- filter_tb = (ivideo.TV_type == TVMODE_NTSC) ? 7 : 15;
++ filter_tb = (ivideo.vbflags & TV_NTSC) ? 7 : 15;
+ break;
+ default:
+ filter = -1;
+@@ -3469,15 +3986,15 @@
+
+ orSISIDXREG(SISPART1, sisfb_CRT2_write_enable, 0x01);
+
+- if(ivideo.TV_type == TVMODE_NTSC) {
++ if(ivideo.vbflags & TV_NTSC) {
+
+ andSISIDXREG(SISPART2, 0x3a, 0x1f);
+
+- if (ivideo.TV_plug == TVPLUG_SVIDEO) {
++ if (ivideo.vbflags & TV_SVIDEO) {
+
+ andSISIDXREG(SISPART2, 0x30, 0xdf);
+
+- } else if (ivideo.TV_plug == TVPLUG_COMPOSITE) {
++ } else if (ivideo.vbflags & TV_AVIDEO) {
+
+ orSISIDXREG(SISPART2, 0x30, 0x20);
+
+@@ -3503,15 +4020,15 @@
+ }
+ }
+
+- } else if(ivideo.TV_type == TVMODE_PAL) {
++ } else if(ivideo.vbflags & TV_PAL) {
+
+ andSISIDXREG(SISPART2, 0x3A, 0x1F);
+
+- if (ivideo.TV_plug == TVPLUG_SVIDEO) {
++ if (ivideo.vbflags & TV_SVIDEO) {
+
+ andSISIDXREG(SISPART2, 0x30, 0xDF);
+
+- } else if (ivideo.TV_plug == TVPLUG_COMPOSITE) {
++ } else if (ivideo.vbflags & TV_AVIDEO) {
+
+ orSISIDXREG(SISPART2, 0x30, 0x20);
+
+@@ -3539,7 +4056,7 @@
+ }
+
+ if ((filter >= 0) && (filter <=7)) {
+- DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n", filter_tb, filter,
++ DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n", filter_tb, filter,
+ sis_TV_filter[filter_tb].filter[filter][0],
+ sis_TV_filter[filter_tb].filter[filter][1],
+ sis_TV_filter[filter_tb].filter[filter][2],
+@@ -3550,8 +4067,6 @@
+ outSISIDXREG(SISPART2, 0x37, (sis_TV_filter[filter_tb].filter[filter][2]));
+ outSISIDXREG(SISPART2, 0x38, (sis_TV_filter[filter_tb].filter[filter][3]));
+ }
+-
+- }
+
+ }
+
+@@ -3567,8 +4082,10 @@
+ #endif
+
+ ivideo.refresh_rate = 0;
++ SiS_Pr.SiS_CustomT = CUT_NONE;
++ SiS_Pr.UsePanelScaler = -1;
+
+- printk(KERN_INFO "sisfb: Options %s\n", options);
++ printk(KERN_DEBUG "sisfb: Options %s\n", options);
+
+ if (!options || !*options)
+ return 0;
+@@ -3577,72 +4094,75 @@
+
+ if (!*this_opt) continue;
+
+- if (!strncmp(this_opt, "mode:", 5)) {
+- sisfb_search_mode(this_opt + 5);
+- } else if (!strncmp(this_opt, "vesa:", 5)) {
+- sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+- } else if (!strcmp(this_opt, "inverse")) {
++ if (!strnicmp(this_opt, "mode:", 5)) {
++ sisfb_search_mode(this_opt + 5, FALSE);
++ } else if (!strnicmp(this_opt, "vesa:", 5)) {
++ sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0), FALSE);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++ } else if (!strnicmp(this_opt, "inverse", 7)) {
+ sisfb_inverse = 1;
+ /* fb_invert_cmaps(); */
+- } else if (!strncmp(this_opt, "font:", 5)) {
++ } else if (!strnicmp(this_opt, "font:", 5)) {
+ strcpy(sis_fb_info.fontname, this_opt + 5);
+-#endif
+- } else if (!strncmp(this_opt, "mode:", 5)) {
+- sisfb_search_mode(this_opt + 5);
+- } else if (!strncmp(this_opt, "vesa:", 5)) {
+- sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
+- } else if (!strncmp(this_opt, "vrate:", 6)) {
++#endif
++ } else if (!strnicmp(this_opt, "vrate:", 6)) {
+ ivideo.refresh_rate = simple_strtoul(this_opt + 6, NULL, 0);
+- } else if (!strncmp(this_opt, "rate:", 5)) {
++ sisfb_parm_rate = ivideo.refresh_rate;
++ } else if (!strnicmp(this_opt, "rate:", 5)) {
+ ivideo.refresh_rate = simple_strtoul(this_opt + 5, NULL, 0);
+- } else if (!strncmp(this_opt, "off", 3)) {
++ sisfb_parm_rate = ivideo.refresh_rate;
++ } else if (!strnicmp(this_opt, "off", 3)) {
+ sisfb_off = 1;
+- } else if (!strncmp(this_opt, "crt1off", 7)) {
++ } else if (!strnicmp(this_opt, "crt1off", 7)) {
+ sisfb_crt1off = 1;
+- } else if (!strncmp(this_opt, "filter:", 7)) {
++ } else if (!strnicmp(this_opt, "filter:", 7)) {
+ filter = (int)simple_strtoul(this_opt + 7, NULL, 0);
+- } else if (!strncmp(this_opt, "forcecrt2type:", 14)) {
++ } else if (!strnicmp(this_opt, "forcecrt2type:", 14)) {
+ sisfb_search_crt2type(this_opt + 14);
+- } else if (!strncmp(this_opt, "forcecrt1:", 10)) {
++ } else if (!strnicmp(this_opt, "forcecrt1:", 10)) {
+ sisfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0);
+- } else if (!strncmp(this_opt, "tvmode:",7)) {
++ } else if (!strnicmp(this_opt, "tvmode:",7)) {
+ sisfb_search_tvstd(this_opt + 7);
+- } else if (!strncmp(this_opt, "tvstandard:",11)) {
++ } else if (!strnicmp(this_opt, "tvstandard:",11)) {
+ sisfb_search_tvstd(this_opt + 7);
+- } else if (!strncmp(this_opt, "mem:",4)) {
++ } else if (!strnicmp(this_opt, "mem:",4)) {
+ sisfb_mem = simple_strtoul(this_opt + 4, NULL, 0);
+- } else if (!strncmp(this_opt, "dstn", 4)) {
+- enable_dstn = 1;
+- /* TW: DSTN overrules forcecrt2type */
+- sisfb_crt2type = DISPTYPE_LCD;
+- } else if (!strncmp(this_opt, "queuemode:", 10)) {
++ } else if (!strnicmp(this_opt, "queuemode:", 10)) {
+ sisfb_search_queuemode(this_opt + 10);
+- } else if (!strncmp(this_opt, "pdc:", 4)) {
++ } else if (!strnicmp(this_opt, "pdc:", 4)) {
+ sisfb_pdc = simple_strtoul(this_opt + 4, NULL, 0);
+ if(sisfb_pdc & ~0x3c) {
+ printk(KERN_INFO "sisfb: Illegal pdc parameter\n");
+ sisfb_pdc = 0;
+ }
+- } else if (!strncmp(this_opt, "noaccel", 7)) {
++ } else if (!strnicmp(this_opt, "noaccel", 7)) {
+ sisfb_accel = 0;
+- } else if (!strncmp(this_opt, "noypan", 6)) {
++ } else if (!strnicmp(this_opt, "noypan", 6)) {
+ sisfb_ypan = 0;
+- } else if (!strncmp(this_opt, "userom:", 7)) {
++ } else if (!strnicmp(this_opt, "userom:", 7)) {
+ sisfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0);
+- } else if (!strncmp(this_opt, "useoem:", 7)) {
++ } else if (!strnicmp(this_opt, "useoem:", 7)) {
+ sisfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0);
++ } else if (!strnicmp(this_opt, "nocrt2rate", 10)) {
++ sisfb_nocrt2rate = 1;
++ } else if (!strnicmp(this_opt, "scalelcd:", 9)) {
++ unsigned long temp = 2;
++ temp = simple_strtoul(this_opt + 9, NULL, 0);
++ if((temp == 0) || (temp == 1)) {
++ SiS_Pr.UsePanelScaler = temp ^ 1;
++ }
++ } else if (!strnicmp(this_opt, "specialtiming:", 14)) {
++ sisfb_search_specialtiming(this_opt + 14);
++ } else if(this_opt[0] >= '0' && this_opt[0] <= '9') {
++ sisfb_search_mode(this_opt, TRUE);
+ } else {
+ printk(KERN_INFO "sisfb: Invalid option %s\n", this_opt);
+ }
+
+ /* TW: Acceleration only with MMIO mode */
+ if((sisfb_queuemode != -1) && (sisfb_queuemode != MMIO_CMD)) {
+- sisfb_ypan = 0;
+ sisfb_accel = 0;
+ }
+- /* TW: Panning only with acceleration */
+- if(sisfb_accel == 0) sisfb_ypan = 0;
+
+ }
+ return 0;
+@@ -3661,14 +4181,14 @@
+ char *sis_sig_300[4] = {
+ "300", "540", "630", "730"
+ };
+- char *sis_sig_310[7] = {
+- "315", "315", "315", "5315", "6325", "6325", "Xabre"
++ char *sis_sig_310[9] = {
++ "315", "315", "315", "5315", "6325", "6325", "Xabre", "6330", "6330"
+ };
+ ushort sis_nums_300[4] = {
+ SIS_300, SIS_540, SIS_630, SIS_730
+ };
+- unsigned short sis_nums_310[7] = {
+- SIS_315PRO, SIS_315H, SIS_315, SIS_550, SIS_650, SIS_740, SIS_330
++ unsigned short sis_nums_310[9] = {
++ SIS_315PRO, SIS_315H, SIS_315, SIS_550, SIS_650, SIS_740, SIS_330, SIS_660, SIS_760
+ };
+
+ for(segstart=0x000c0000; segstart<0x000f0000; segstart+=0x00001000) {
+@@ -3705,7 +4225,7 @@
+ }
+ }
+ if(stage != 4) {
+- for(i = 0;(i < 7) && (stage != 4); i++) {
++ for(i = 0;(i < 9) && (stage != 4); i++) {
+ if(strncmp(sis_sig_310[i], rom, strlen(sis_sig_310[i])) == 0) {
+ if(sis_nums_310[i] == ivideo.chip) {
+ stage = 4;
+@@ -3735,7 +4255,7 @@
+ int pdev_valid = 0;
+ u32 reg32;
+ u16 reg16;
+- u8 reg, reg1;
++ u8 reg;
+
+ /* outb(0x77, 0x80); */ /* What is this? */
+
+@@ -3751,18 +4271,24 @@
+ if (sisfb_off)
+ return -ENXIO;
+
+- if (enable_dstn)
+- SiS_SetEnableDstn(&SiS_Pr);
+-
+ sisfb_registered = 0;
++ sisfb_thismonitor.datavalid = FALSE;
+
+ memset(&sis_fb_info, 0, sizeof(sis_fb_info));
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
++ memset(&sisfb_lastrates[0], 0, 128);
++#endif
+
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ memset(&sis_disp, 0, sizeof(sis_disp));
+ #endif
+
+- while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,74)
++ pci_for_each_dev(pdev) {
++#else
++ while((pdev = pci_find_device(PCI_VENDOR_ID_SI, PCI_ANY_ID, pdev))) {
++#endif
+ for (b = sisdev_list; b->vendor; b++) {
+ if ((b->vendor == pdev->vendor)
+ && (b->device == pdev->device)) {
+@@ -3804,18 +4330,17 @@
+ break;
+ case PCI_DEVICE_ID_SI_630_VGA:
+ {
++ ivideo.chip = SIS_630;
+ sisfb_set_reg4(0xCF8, 0x80000000);
+ reg32 = sisfb_get_reg3(0xCFC);
+ if(reg32 == 0x07301039) {
+ ivideo.chip = SIS_730;
+-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
+ strcpy(sis_fb_info.modename, "SIS 730");
+ #else
+ strcpy(myid, "SIS 730");
+-#endif
+- } else
+- ivideo.chip = SIS_630;
+-
++#endif
++ }
+ sisvga_engine = SIS_300_VGA;
+ sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_300 * 2;
+ sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_300;
+@@ -3860,11 +4385,11 @@
+ reg32 = sisfb_get_reg3(0xCFC);
+ if(reg32 == 0x07401039) {
+ ivideo.chip = SIS_740;
+-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
+ strcpy(sis_fb_info.modename, "SIS 740");
+ #else
+- strcpy(myid, "SIS 740");
+-#endif
++ strcpy(myid, "SIS 740");
++#endif
+ }
+ sisvga_engine = SIS_315_VGA;
+ sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
+@@ -3877,6 +4402,24 @@
+ sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
+ sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
+ break;
++ case PCI_DEVICE_ID_SI_660_VGA:
++ {
++ ivideo.chip = SIS_660;
++ sisfb_set_reg4(0xCF8, 0x80000000);
++ reg32 = sisfb_get_reg3(0xCFC);
++ if(reg32 == 0x07601039) {
++ ivideo.chip = SIS_760;
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
++ strcpy(sis_fb_info.modename, "SIS 760");
++#else
++ strcpy(myid, "SIS 760");
++#endif
++ }
++ sisvga_engine = SIS_315_VGA;
++ sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
++ sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
++ break;
++ }
+ #endif
+ default:
+ return -ENODEV;
+@@ -3903,29 +4446,31 @@
+ SiS_Pr.SiS_CHOverScan = -1;
+ SiS_Pr.SiS_ChSW = FALSE;
+ SiS_Pr.SiS_UseLCDA = FALSE;
+- SiS_Pr.UsePanelScaler = -1;
+ SiSRegInit(&SiS_Pr, (USHORT)sishw_ext.ulIOAddress);
+
+ #ifdef CONFIG_FB_SIS_300
+- /* TW: Find PCI systems for Chrontel/ISA bridge manipulation */
++ /* TW: Find PCI systems for Chrontel/GPIO communication setup */
+ if(ivideo.chip == SIS_630) {
+- int i=0;
+- do {
+- if(mychswtable[i].subsysVendor == ivideo.subsysvendor &&
+- mychswtable[i].subsysCard == ivideo.subsysdevice) {
+- SiS_Pr.SiS_ChSW = TRUE;
+- }
+- i++;
+- } while(mychswtable[i].subsysVendor != 0);
++ int i=0;
++ do {
++ if(mychswtable[i].subsysVendor == ivideo.subsysvendor &&
++ mychswtable[i].subsysCard == ivideo.subsysdevice) {
++ SiS_Pr.SiS_ChSW = TRUE;
++ printk(KERN_DEBUG "sisfb: Identified [%s %s] requiring Chrontel/GPIO setup\n",
++ mychswtable[i].vendorName, mychswtable[i].cardName);
++ break;
++ }
++ i++;
++ } while(mychswtable[i].subsysVendor != 0);
+ }
+ #endif
+
+ outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
+
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+-#ifdef MODULE
++#ifdef MODULE
+ inSISIDXREG(SISCR,0x34,reg);
+- if(reg & 0x80) {
++ if((reg & 0x80) && (reg != 0xff)) {
+ if((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF) {
+ printk(KERN_INFO "sisfb: Cannot initialize display mode, X server is active\n");
+ return -EBUSY;
+@@ -3938,7 +4483,7 @@
+
+ #ifdef CONFIG_FB_SIS_300
+ if (sisvga_engine == SIS_300_VGA) {
+- outSISIDXREG(SISSR, 0x28, 0x37);
++ outSISIDXREG(SISSR, 0x28, 0x37); /* Reset memory clock */
+
+ outSISIDXREG(SISSR, 0x29, 0x61);
+
+@@ -3946,7 +4491,9 @@
+ }
+ #endif
+ #ifdef CONFIG_FB_SIS_315
+- if (ivideo.chip == SIS_550 || ivideo.chip == SIS_650 || ivideo.chip == SIS_740) {
++ if (ivideo.chip == SIS_550 || ivideo.chip == SIS_650 ||
++ ivideo.chip == SIS_740 || ivideo.chip == SIS_660 ||
++ ivideo.chip == SIS_760) {
+ outSISIDXREG(SISSR, 0x28, 0x5a);
+
+ outSISIDXREG(SISSR, 0x29, 0x64);
+@@ -3967,6 +4514,8 @@
+ case SIS_550:
+ case SIS_650:
+ case SIS_740:
++ case SIS_660:
++ case SIS_760:
+ sishw_ext.bIntegratedMMEnabled = TRUE;
+ break;
+ default:
+@@ -4006,13 +4555,56 @@
+ sishw_ext.pQueryNorthBridgeSpace = &sisfb_query_north_bridge_space;
+ strcpy(sishw_ext.szVBIOSVer, "0.84");
+
+- /* TW: Mode numbers for 1280x960 are different for 300 and 310/325 series */
++ /* Find systems for special custom timing */
++ if((sishw_ext.UseROM) && (SiS_Pr.SiS_CustomT == CUT_NONE)) {
++ int i=0,j;
++ unsigned char *biosver = sishw_ext.pjVirtualRomBase + 0x06;
++ unsigned char *biosdate = sishw_ext.pjVirtualRomBase + 0x2c;
++ BOOLEAN footprint;
++ unsigned long chksum = 0;
++
++ for(i=0; i<32768; i++) chksum += sishw_ext.pjVirtualRomBase[i];
++
++ i=0;
++ do {
++ if( (mycustomttable[i].chipID == ivideo.chip) &&
++ ((!strlen(mycustomttable[i].biosversion)) ||
++ (!strncmp(mycustomttable[i].biosversion, biosver, strlen(mycustomttable[i].biosversion)))) &&
++ ((!strlen(mycustomttable[i].biosdate)) ||
++ (!strncmp(mycustomttable[i].biosdate, biosdate, strlen(mycustomttable[i].biosdate)))) &&
++ ((!mycustomttable[i].bioschksum) ||
++ (mycustomttable[i].bioschksum == chksum)) &&
++ (mycustomttable[i].pcisubsysvendor == ivideo.subsysvendor) &&
++ (mycustomttable[i].pcisubsyscard == ivideo.subsysdevice) ) {
++ footprint = TRUE;
++ for(j=0; j<5; j++) {
++ if(mycustomttable[i].biosFootprintAddr[j]) {
++ if(sishw_ext.pjVirtualRomBase[mycustomttable[i].biosFootprintAddr[j]] !=
++ mycustomttable[i].biosFootprintData[j])
++ footprint = FALSE;
++ }
++ }
++ if(footprint) {
++ SiS_Pr.SiS_CustomT = mycustomttable[i].SpecialID;
++ printk(KERN_DEBUG "sisfb: Identified [%s %s], special timing applies\n",
++ mycustomttable[i].vendorName,
++ mycustomttable[i].cardName);
++ break;
++ }
++ }
++ i++;
++ } while(mycustomttable[i].chipID);
++ }
++
++#ifdef CONFIG_FB_SIS_300
++ /* Mode numbers for 1280x768 are different for 300 and 315 series */
+ if(sisvga_engine == SIS_300_VGA) {
+- sisbios_mode[MODEINDEX_1280x960].mode_no = 0x6e;
+- sisbios_mode[MODEINDEX_1280x960+1].mode_no = 0x6f;
+- sisbios_mode[MODEINDEX_1280x960+2].mode_no = 0x7b;
+- sisbios_mode[MODEINDEX_1280x960+3].mode_no = 0x7b;
++ sisbios_mode[MODEINDEX_1280x768].mode_no = 0x55;
++ sisbios_mode[MODEINDEX_1280x768+1].mode_no = 0x5a;
++ sisbios_mode[MODEINDEX_1280x768+2].mode_no = 0x5b;
++ sisbios_mode[MODEINDEX_1280x768+3].mode_no = 0x5b;
+ }
++#endif
+
+ sishw_ext.pSR = vmalloc(sizeof(SIS_DSReg) * SR_BUFFER_SIZE);
+ if (sishw_ext.pSR == NULL) {
+@@ -4168,120 +4760,53 @@
+
+ ivideo.mtrr = (unsigned int) 0;
+
+- if((sisfb_mode_idx < 0) || ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF)) {
+-
+-#ifdef CONFIG_FB_SIS_300
+- if (sisvga_engine == SIS_300_VGA) {
+- sisfb_get_VB_type_300();
+- }
+-#endif
++ ivideo.vbflags = 0;
+
+-#ifdef CONFIG_FB_SIS_315
+- if (sisvga_engine == SIS_315_VGA) {
+- sisfb_get_VB_type_315();
+- }
+-#endif
++ if((sisfb_mode_idx < 0) || ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF)) {
+
+ sishw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
+ sishw_ext.Is301BDH = FALSE;
+ sishw_ext.usExternalChip = 0;
+
+- switch (ivideo.hasVB) {
++ sisfb_get_VB_type();
+
+- case HASVB_301:
+- inSISIDXREG(SISPART4, 0x01, reg);
+- if (reg >= 0xE0) {
+- sishw_ext.ujVBChipID = VB_CHIP_302LV;
+- printk(KERN_INFO "sisfb: SiS302LV bridge detected (revision 0x%02x)\n",reg);
+- } else if (reg >= 0xD0) {
+- sishw_ext.ujVBChipID = VB_CHIP_301LV;
+- printk(KERN_INFO "sisfb: SiS301LV bridge detected (revision 0x%02x)\n",reg);
+- } else if (reg >= 0xB0) {
+- sishw_ext.ujVBChipID = VB_CHIP_301B;
+- inSISIDXREG(SISPART4,0x23,reg1);
+- if(!(reg1 & 0x02)) sishw_ext.Is301BDH = TRUE;
+- printk(KERN_INFO "sisfb: SiS301B%s bridge detected (revision 0x%02x)\n",
+- (sishw_ext.Is301BDH ? "-DH" : ""), reg);
+- } else {
+- sishw_ext.ujVBChipID = VB_CHIP_301;
+- printk(KERN_INFO "sisfb: SiS301 bridge detected\n");
+- }
+- break;
+- case HASVB_302:
+- inSISIDXREG(SISPART4, 0x01, reg);
+- if (reg >= 0xE0) {
+- sishw_ext.ujVBChipID = VB_CHIP_302LV;
+- printk(KERN_INFO "sisfb: SiS302LV bridge detected (revision 0x%02x)\n",reg);
+- } else if (reg >= 0xD0) {
+- sishw_ext.ujVBChipID = VB_CHIP_301LV;
+- printk(KERN_INFO "sisfb: SiS302LV bridge detected (revision 0x%02x)\n",reg);
+- } else if (reg >= 0xB0) {
+- inSISIDXREG(SISPART4,0x23,reg1);
+- if(!(reg1 & 0x02)) sishw_ext.Is301BDH = TRUE;
+- sishw_ext.ujVBChipID = VB_CHIP_302B;
+- printk(KERN_INFO "sisfb: SiS302B%s bridge detected (revision 0x%02x)\n",
+- (sishw_ext.Is301BDH ? "-DH" : ""), reg);
+- } else {
+- sishw_ext.ujVBChipID = VB_CHIP_302;
+- printk(KERN_INFO "sisfb: SiS302 bridge detected\n");
+- }
+- break;
+- case HASVB_LVDS:
+- sishw_ext.usExternalChip = 0x1;
+- printk(KERN_INFO "sisfb: LVDS transmitter detected\n");
+- break;
+- case HASVB_TRUMPION:
+- sishw_ext.usExternalChip = 0x2;
+- printk(KERN_INFO "sisfb: Trumpion Zurac LVDS scaler detected\n");
+- break;
+- case HASVB_CHRONTEL:
+- sishw_ext.usExternalChip = 0x4;
+- printk(KERN_INFO "sisfb: Chrontel TV encoder detected\n");
+- break;
+- case HASVB_LVDS_CHRONTEL:
+- sishw_ext.usExternalChip = 0x5;
+- printk(KERN_INFO "sisfb: LVDS transmitter and Chrontel TV encoder detected\n");
+- break;
+- default:
+- printk(KERN_INFO "sisfb: No or unknown bridge type detected\n");
+- break;
++ if(ivideo.vbflags & VB_VIDEOBRIDGE) {
++ sisfb_detect_VB_connect();
+ }
+
+- if (ivideo.hasVB != HASVB_NONE) {
+-#ifdef CONFIG_FB_SIS_300
+- if (sisvga_engine == SIS_300_VGA) {
+- sisfb_detect_VB_connect_300();
+- }
+-#endif
+-#ifdef CONFIG_FB_SIS_315
+- if (sisvga_engine == SIS_315_VGA) {
+- sisfb_detect_VB_connect_315();
+- }
+-#endif
+- }
++ ivideo.currentvbflags = ivideo.vbflags & VB_VIDEOBRIDGE;
+
+- if (ivideo.disp_state & DISPTYPE_DISP2) {
+- if (sisfb_crt1off)
+- ivideo.disp_state |= DISPMODE_SINGLE;
+- else
+- ivideo.disp_state |= (DISPMODE_MIRROR | DISPTYPE_CRT1);
+- } else {
+- ivideo.disp_state = DISPMODE_SINGLE | DISPTYPE_CRT1;
++ if(ivideo.vbflags & VB_VIDEOBRIDGE) {
++ if(sisfb_crt2type != -1) {
++ if((sisfb_crt2type == CRT2_LCD) && (ivideo.vbflags & CRT2_LCD)) {
++ ivideo.currentvbflags |= CRT2_LCD;
++ } else if(sisfb_crt2type != CRT2_LCD) {
++ ivideo.currentvbflags |= sisfb_crt2type;
++ }
++ } else {
++ /* Chrontel 700x TV detection often unreliable, therefore use a
++ * different default order on such machines
++ */
++ if((sisvga_engine == SIS_300_VGA) && (ivideo.vbflags & VB_CHRONTEL)) {
++ if(ivideo.vbflags & CRT2_LCD) ivideo.currentvbflags |= CRT2_LCD;
++ else if(ivideo.vbflags & CRT2_TV) ivideo.currentvbflags |= CRT2_TV;
++ else if(ivideo.vbflags & CRT2_VGA) ivideo.currentvbflags |= CRT2_VGA;
++ } else {
++ if(ivideo.vbflags & CRT2_TV) ivideo.currentvbflags |= CRT2_TV;
++ else if(ivideo.vbflags & CRT2_LCD) ivideo.currentvbflags |= CRT2_LCD;
++ else if(ivideo.vbflags & CRT2_VGA) ivideo.currentvbflags |= CRT2_VGA;
++ }
++ }
+ }
+
+- if (ivideo.disp_state & DISPTYPE_LCD) {
+- if (!enable_dstn) {
+- inSISIDXREG(SISCR, IND_SIS_LCD_PANEL, reg);
+- reg &= 0x0f;
+- if (sisvga_engine == SIS_300_VGA) {
+- sishw_ext.ulCRT2LCDType = sis300paneltype[reg];
+- } else {
+- sishw_ext.ulCRT2LCDType = sis310paneltype[reg];
+- }
+- } else {
+- /* TW: FSTN/DSTN */
+- sishw_ext.ulCRT2LCDType = LCD_320x480;
+- }
++ if(ivideo.vbflags & CRT2_LCD) {
++ inSISIDXREG(SISCR, IND_SIS_LCD_PANEL, reg);
++ reg &= 0x0f;
++ if(sisvga_engine == SIS_300_VGA) {
++ sishw_ext.ulCRT2LCDType = sis300paneltype[reg];
++ } else {
++ sishw_ext.ulCRT2LCDType = sis310paneltype[reg];
++ }
+ }
+
+ sisfb_detectedpdc = 0;
+@@ -4289,9 +4814,7 @@
+ #ifdef CONFIG_FB_SIS_300
+ /* TW: Save the current PanelDelayCompensation if the LCD is currently used */
+ if(sisvga_engine == SIS_300_VGA) {
+- if((sishw_ext.usExternalChip == 0x01) || /* LVDS */
+- (sishw_ext.usExternalChip == 0x05) || /* LVDS+Chrontel */
+- (sishw_ext.Is301BDH)) { /* 301B-DH */
++ if(ivideo.vbflags & (VB_LVDS | VB_30xBDH)) {
+ int tmp;
+ inSISIDXREG(SISCR,0x30,tmp);
+ if(tmp & 0x20) {
+@@ -4320,54 +4843,57 @@
+ #ifdef CONFIG_FB_SIS_315
+ /* TW: Try to find about LCDA */
+ if(sisvga_engine == SIS_315_VGA) {
+- if((sishw_ext.ujVBChipID == VB_CHIP_302B) ||
+- (sishw_ext.ujVBChipID == VB_CHIP_301LV) ||
+- (sishw_ext.ujVBChipID == VB_CHIP_302LV)) {
+- int tmp;
+- inSISIDXREG(SISCR,0x34,tmp);
+- if(tmp <= 0x13) {
+- /* Currently on LCDA? (Some BIOSes leave CR38) */
+- inSISIDXREG(SISCR,0x38,tmp);
+- if((tmp & 0x03) == 0x03) {
+- SiS_Pr.SiS_UseLCDA = TRUE;
+- } else {
+- /* Currently on LCDA? (Some newer BIOSes set D0 in CR35) */
+- inSISIDXREG(SISCR,0x35,tmp);
+- if(tmp & 0x01) {
+- SiS_Pr.SiS_UseLCDA = TRUE;
+- } else {
+- /* Currently on LCD? If so, we can find out
+- by peeking the mode register
+- */
+- inSISIDXREG(SISCR,0x30,tmp);
+- if(tmp & 0x20) {
+- inSISIDXREG(SISPART1,0x13,tmp);
+- if(tmp & 0x04) {
+- SiS_Pr.SiS_UseLCDA = TRUE;
+- }
+- }
+- }
+- }
+- }
+- if(SiS_Pr.SiS_UseLCDA) {
+- sisfb_detectedlcda = 0x03;
+- printk(KERN_INFO
+- "sisfb: Bridge uses LCDA for low resolution and text modes\n");
+- }
++ if(ivideo.vbflags & (VB_302B | VB_301LV | VB_302LV)) {
++ int tmp;
++ inSISIDXREG(SISCR,0x34,tmp);
++ if((tmp <= 0x13) || (tmp == 0xff)) {
++ /* Currently on LCDA? (Some BIOSes leave CR38) */
++ inSISIDXREG(SISCR,0x38,tmp);
++ if((tmp & 0x03) == 0x03) SiS_Pr.SiS_UseLCDA = TRUE;
++ else {
++ /* Currently on LCDA? (Some newer BIOSes set D0 in CR35) */
++ inSISIDXREG(SISCR,0x35,tmp);
++ if(tmp & 0x01) SiS_Pr.SiS_UseLCDA = TRUE;
++ else {
++ /* Currently on LCD? If so, we can find out
++ * by peeking the mode register
++ */
++ inSISIDXREG(SISCR,0x30,tmp);
++ if(tmp & 0x20) {
++ inSISIDXREG(SISPART1,0x13,tmp);
++ if(tmp & 0x04) SiS_Pr.SiS_UseLCDA = TRUE;
++ }
++ }
++ }
++ }
++ if(SiS_Pr.SiS_UseLCDA) {
++ sisfb_detectedlcda = 0x03;
++ printk(KERN_DEBUG
++ "sisfb: Bridge uses LCDA for low resolution and text modes\n");
++ }
+ }
+ }
+ #endif
+ #endif
+
++ if (!sisfb_crt1off) {
++ sisfb_handle_ddc(&sisfb_thismonitor, 0);
++ } else {
++ if ((ivideo.vbflags & (VB_301|VB_301B|VB_302B)) &&
++ (ivideo.vbflags & (CRT2_VGA | CRT2_LCD))) {
++ sisfb_handle_ddc(&sisfb_thismonitor, 1);
++ }
++ }
++
+ if (sisfb_mode_idx >= 0)
+- sisfb_mode_idx = sisfb_validate_mode(sisfb_mode_idx);
++ sisfb_mode_idx = sisfb_validate_mode(sisfb_mode_idx, ivideo.currentvbflags);
+
+ if (sisfb_mode_idx < 0) {
+- switch (ivideo.disp_state & DISPTYPE_DISP2) {
+- case DISPTYPE_LCD:
++ switch (ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
++ case CRT2_LCD:
+ sisfb_mode_idx = DEFAULT_LCDMODE;
+ break;
+- case DISPTYPE_TV:
++ case CRT2_TV:
+ sisfb_mode_idx = DEFAULT_TVMODE;
+ break;
+ default:
+@@ -4379,39 +4905,27 @@
+ sisfb_mode_no = sisbios_mode[sisfb_mode_idx].mode_no;
+
+ if (ivideo.refresh_rate != 0)
+- sisfb_search_refresh_rate(ivideo.refresh_rate);
++ sisfb_search_refresh_rate(ivideo.refresh_rate, sisfb_mode_idx);
+
+ if (sisfb_rate_idx == 0) {
+ sisfb_rate_idx = sisbios_mode[sisfb_mode_idx].rate_idx;
+ ivideo.refresh_rate = 60;
+ }
+
++ if (sisfb_thismonitor.datavalid) {
++ if(!sisfb_verify_rate(&sisfb_thismonitor, sisfb_mode_idx,
++ sisfb_rate_idx, ivideo.refresh_rate)) {
++ printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
++ }
++ }
++
+ ivideo.video_bpp = sisbios_mode[sisfb_mode_idx].bpp;
+ ivideo.video_vwidth = ivideo.video_width = sisbios_mode[sisfb_mode_idx].xres;
+ ivideo.video_vheight = ivideo.video_height = sisbios_mode[sisfb_mode_idx].yres;
+ ivideo.org_x = ivideo.org_y = 0;
+ ivideo.video_linelength = ivideo.video_width * (ivideo.video_bpp >> 3);
+- switch(ivideo.video_bpp) {
+- case 8:
+- ivideo.DstColor = 0x0000;
+- ivideo.SiS310_AccelDepth = 0x00000000;
+- ivideo.video_cmap_len = 256;
+- break;
+- case 16:
+- ivideo.DstColor = 0x8000;
+- ivideo.SiS310_AccelDepth = 0x00010000;
+- ivideo.video_cmap_len = 16;
+- break;
+- case 32:
+- ivideo.DstColor = 0xC000;
+- ivideo.SiS310_AccelDepth = 0x00020000;
+- ivideo.video_cmap_len = 16;
+- break;
+- default:
+- ivideo.video_cmap_len = 16;
+- printk(KERN_INFO "sisfb: Unsupported depth %d", ivideo.video_bpp);
+- break;
+- }
++
++ sisfb_set_vparms();
+
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+
+@@ -4424,27 +4938,49 @@
+ sisfb_pre_setmode();
+
+ if (SiSSetMode(&SiS_Pr, &sishw_ext, sisfb_mode_no) == 0) {
+- printk(KERN_ERR "sisfb: Setting mode[0x%x] failed, using default mode\n",
++ printk(KERN_ERR "sisfb: Fatal error: Setting mode[0x%x] failed\n",
+ sisfb_mode_no);
+- return -1;
++ vfree(sishw_ext.pSR);
++ vfree(sishw_ext.pCR);
++ release_mem_region(ivideo.video_base, ivideo.video_size);
++ release_mem_region(ivideo.mmio_base, sisfb_mmio_size);
++ return -EINVAL;
+ }
+
+ outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
+
+ sisfb_post_setmode();
+
++ ivideo.accel = 0;
++ if(sisfb_accel) {
++ ivideo.accel = -1;
++ default_var.accel_flags |= FB_ACCELF_TEXT;
++ sisfb_initaccel();
++ }
++
+ sisfb_crtc_to_var(&default_var);
+
++ sis_fb_info.node = -1;
++ sis_fb_info.flags = FBINFO_FLAG_DEFAULT;
++ sis_fb_info.blank = &sisfb_blank;
++ sis_fb_info.fbops = &sisfb_ops;
++ sis_fb_info.switch_con = &sisfb_switch;
++ sis_fb_info.updatevar = &sisfb_update_var;
++ sis_fb_info.changevar = NULL;
++ sis_fb_info.disp = &sis_disp;
++
++ sisfb_set_disp(-1, &default_var, &sis_fb_info);
++
+ #else /* --------- For 2.5: Setup a somewhat sane default var ------------ */
+
+ printk(KERN_INFO "sisfb: Default mode is %dx%dx%d (%dHz)\n",
+ ivideo.video_width, ivideo.video_height, ivideo.video_bpp,
+ ivideo.refresh_rate);
+-
++
+ default_var.xres = default_var.xres_virtual = ivideo.video_width;
+ default_var.yres = default_var.yres_virtual = ivideo.video_height;
+ default_var.bits_per_pixel = ivideo.video_bpp;
+-
++
+ sisfb_bpp_to_var(&default_var);
+
+ default_var.pixclock = (u32) (1E12 /
+@@ -4457,28 +4993,10 @@
+ &default_var.upper_margin, &default_var.lower_margin,
+ &default_var.hsync_len, &default_var.vsync_len,
+ &default_var.sync, &default_var.vmode)) {
+-
+- if((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+- default_var.yres <<= 1;
+- default_var.yres_virtual <<= 1;
+- } else if((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+- default_var.pixclock >>= 1;
+- default_var.yres >>= 1;
+- default_var.yres_virtual >>= 1;
+- }
+-
++ if((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
++ default_var.pixclock <<= 1;
++ }
+ }
+-#ifdef SISFB_PAN
+- if(sisfb_ypan) {
+- default_var.yres_virtual =
+- ivideo.heapstart / (default_var.xres * (default_var.bits_per_pixel >> 3));
+- if(default_var.yres_virtual <= default_var.yres) {
+- default_var.yres_virtual = default_var.yres;
+- }
+- }
+-#endif
+-
+-#endif
+
+ ivideo.accel = 0;
+ if(sisfb_accel) {
+@@ -4487,20 +5005,14 @@
+ sisfb_initaccel();
+ }
+
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* ---- 2.4 series init ---- */
+- sis_fb_info.node = -1;
+- sis_fb_info.flags = FBINFO_FLAG_DEFAULT;
+- sis_fb_info.blank = &sisfb_blank;
+- sis_fb_info.fbops = &sisfb_ops;
+- sis_fb_info.switch_con = &sisfb_switch;
+- sis_fb_info.updatevar = &sisfb_update_var;
+- sis_fb_info.changevar = NULL;
+- sis_fb_info.disp = &sis_disp;
+-
+- sisfb_set_disp(-1, &default_var, &sis_fb_info);
+-#endif
++ if(sisfb_ypan) {
++ default_var.yres_virtual =
++ ivideo.heapstart / (default_var.xres * (default_var.bits_per_pixel >> 3));
++ if(default_var.yres_virtual <= default_var.yres) {
++ default_var.yres_virtual = default_var.yres;
++ }
++ }
+
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) /* ---- 2.5 series init ---- */
+ sis_fb_info.flags = FBINFO_FLAG_DEFAULT;
+ sis_fb_info.var = default_var;
+ sis_fb_info.fix = sisfb_fix;
+@@ -4513,6 +5025,8 @@
+ fb_alloc_cmap(&sis_fb_info.cmap, 256 , 0);
+ #endif
+
++ printk(KERN_INFO "sisfb: Initial vbflags 0x%lx\n", ivideo.vbflags);
++
+ #ifdef CONFIG_MTRR
+ ivideo.mtrr = mtrr_add((unsigned int) ivideo.video_base,
+ (unsigned int) ivideo.video_size,
+@@ -4520,20 +5034,28 @@
+ if(ivideo.mtrr) {
+ printk(KERN_INFO "sisfb: Added MTRRs\n");
+ }
++
+ #endif
+
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ vc_resize_con(1, 1, 0);
+ #endif
+
+- TWDEBUG("Before calling register_framebuffer");
+-
+- if(register_framebuffer(&sis_fb_info) < 0)
++ if(register_framebuffer(&sis_fb_info) < 0) {
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
++ vfree(sishw_ext.pSR);
++ vfree(sishw_ext.pCR);
++ release_mem_region(ivideo.video_base, ivideo.video_size);
++ release_mem_region(ivideo.mmio_base, sisfb_mmio_size);
++#endif
++ printk(KERN_ERR "sisfb: Fatal error: Failed to register framebuffer\n");
+ return -EINVAL;
+-
++ }
++
+ sisfb_registered = 1;
+
+ printk(KERN_INFO "sisfb: Installed SISFB_GET_INFO ioctl (%x)\n", SISFB_GET_INFO);
++ printk(KERN_INFO "sisfb: Installed SISFB_GET_VBRSTATUS ioctl (%x)\n", SISFB_GET_VBRSTATUS);
+
+ printk(KERN_INFO "sisfb: 2D acceleration is %s, scrolling mode %s\n",
+ sisfb_accel ? "enabled" : "disabled",
+@@ -4547,9 +5069,11 @@
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
+- sis_fb_info.node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
++ sis_fb_info.node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
+ #endif
+
++ printk(KERN_INFO "sisfb: (C) 2001-2003 Thomas Winischhofer. All rights reserved.\n");
++
+ } /* TW: if mode = "none" */
+ return 0;
+ }
+@@ -4562,7 +5086,6 @@
+ static unsigned int rate = 0;
+ static unsigned int crt1off = 1;
+ static unsigned int mem = 0;
+-static unsigned int dstn = 0;
+ static char *forcecrt2type = NULL;
+ static int forcecrt1 = -1;
+ static char *queuemode = NULL;
+@@ -4575,25 +5098,33 @@
+ static int userom = 1;
+ static int useoem = -1;
+ static char *tvstandard = NULL;
++static int nocrt2rate = 0;
++static int scalelcd = -1;
++static char *specialtiming = NULL;
+
+-MODULE_DESCRIPTION("SiS 300/540/630/730/315/550/650/740/330 framebuffer driver");
++MODULE_DESCRIPTION("SiS 300/540/630/730/315/550/650/740/330/660/760 framebuffer driver");
+ MODULE_LICENSE("GPL");
+-MODULE_AUTHOR("SiS; Thomas Winischhofer <thomas@winischhofer.net>; Various others");
++MODULE_AUTHOR("Thomas Winischhofer <thomas@winischhofer.net>; SiS; Various others");
+
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ MODULE_PARM(mode, "s");
+ MODULE_PARM_DESC(mode,
+ "\nSelects the desired display mode in the format [X]x[Y]x[Depth], eg.\n"
+- "800x600x16 (default: none if sisfb is a module; this leaves the\n"
+- "console untouched and the driver will only do the video memory\n"
+- "management for eg. DRM/DRI; 800x600x8 if sisfb is in the kernel)");
++ "1024x768x16. Other formats supported include XxY-Depth and\n"
++ "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
++ "number, it will be interpreted as a VESA mode number. (default: none if\n"
++ "sisfb is a module; this leaves the console untouched and the driver will\n"
++ "only do the video memory management for eg. DRM/DRI; 800x600x8 if sisfb\n"
++ "is in the kernel)");
+ #endif
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ MODULE_PARM(mode, "s");
+ MODULE_PARM_DESC(mode,
+- "\nSelects the desired default display mode in the format [X]x[Y]x[Depth],\n"
+- "eg. 1024x768x16 (default: 800x600x8)");
+-#endif
++ "\nSelects the desired default display mode in the format XxYxDepth,\n"
++ "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
++ "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
++ "number, it will be interpreted as a VESA mode number. (default: 800x600x8)");
++#endif
+
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ MODULE_PARM(vesa, "i");
+@@ -4603,17 +5134,18 @@
+ "and the driver will only do the video memory management for eg. DRM/DRI;\n"
+ "0x0103 if sisfb is in the kernel)");
+ #endif
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ MODULE_PARM(vesa, "i");
+ MODULE_PARM_DESC(vesa,
+ "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
+ "0x117 (default: 0x0103)");
+-#endif
++#endif
+
+ MODULE_PARM(rate, "i");
+ MODULE_PARM_DESC(rate,
+ "\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
+- "(default: 60)");
++ "If the mode is specified in the format XxY-Depth@Rate, this parameter\n"
++ "will be ignored (default: 60)");
+
+ MODULE_PARM(crt1off, "i");
+ MODULE_PARM_DESC(crt1off,
+@@ -4624,14 +5156,9 @@
+ "\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
+ "(Possible values 0-7, default: [no filter])");
+
+-MODULE_PARM(dstn, "i");
+-MODULE_PARM_DESC(dstn,
+- "\nSelects DSTN/FSTN display mode for SiS550. This sets CRT2 type to LCD and\n"
+- "overrides forcecrt2type setting. (1=ON, 0=OFF) (default: 0)");
+-
+ MODULE_PARM(queuemode, "s");
+ MODULE_PARM_DESC(queuemode,
+- "\nSelects the queue mode on 315/550/650/740/330. Possible choices are AGP, VRAM or\n"
++ "\nSelects the queue mode on 315/550/650/740/330/660. Possible choices are AGP, VRAM,\n"
+ "MMIO. AGP is only available if the kernel has AGP support. The queue mode is\n"
+ "important to programs using the 2D/3D accelerator of the SiS chip. The modes\n"
+ "require a totally different way of programming the engines. If any mode than\n"
+@@ -4642,11 +5169,12 @@
+ MODULE_PARM(mem, "i");
+ MODULE_PARM_DESC(mem,
+ "\nDetermines the beginning of the video memory heap in KB. This heap is used\n"
+- "for video RAM management for eg. DRM/DRI. The default depends on the amount\n"
+- "of video RAM available. If 8MB of video RAM or less is available, the heap\n"
+- "starts at 4096KB, if between 8 and 16MB are available at 8192KB, otherwise\n"
+- "at 12288KB. The value is to be specified without 'KB' and should match\n"
+- "the MaxXFBMem setting for XFree 4.x (x>=2).");
++ "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n"
++ "on the amount of video RAM available. If 8MB of video RAM or less is available,\n"
++ "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n"
++ "otherwise at 12288KB. On 315 and Xabre series, the heap is 1MB by default. The\n"
++ "value is to be specified without 'KB' and should match the MaxXFBMem setting for\n"
++ "XFree 4.x (x>=2).");
+
+ MODULE_PARM(forcecrt2type, "s");
+ MODULE_PARM_DESC(forcecrt2type,
+@@ -4673,56 +5201,76 @@
+ MODULE_PARM(noaccel, "i");
+ MODULE_PARM_DESC(noaccel,
+ "\nIf set to anything other than 0, 2D acceleration and y-panning will be\n"
+- "disabled. (default: 0)");
++ "disabled. (default: 0)");
+
+ MODULE_PARM(noypan, "i");
+ MODULE_PARM_DESC(noypan,
+ "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
+- "will be performed by redrawing the screen. This required 2D acceleration, so\n"
+- "if the option noaccel is set, y-panning will be disabled. (default: 0)");
++ "will be performed by redrawing the screen. (default: 0)");
+
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ MODULE_PARM(inverse, "i");
+ MODULE_PARM_DESC(inverse,
+ "\nSetting this to anything but 0 should invert the display colors, but this\n"
+- "does not seem to work. (default: 0)");
++ "does not seem to work. (default: 0)");
+ #endif
+
+ MODULE_PARM(userom, "i");
+ MODULE_PARM_DESC(userom,
+ "\nSetting this to 0 keeps sisfb from using the video BIOS data which is needed\n"
+- "for some LCD and TV setup. (default: 1)");
++ "for some LCD and TV setup. (default: 1)");
+
+ MODULE_PARM(useoem, "i");
+ MODULE_PARM_DESC(useoem,
+ "\nSetting this to 0 keeps sisfb from using its internel OEM data for some LCD\n"
+- "panels and TV connector types. (default: auto)");
++ "panels and TV connector types. (default: [auto])");
+
+ MODULE_PARM(tvstandard, "s");
+ MODULE_PARM_DESC(tvstandard,
+ "\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n"
+- "pal and ntsc. (default: auto)");
++ "pal and ntsc. (default: [auto])");
++
++MODULE_PARM(nocrt2rate, "i");
++MODULE_PARM_DESC(nocrt2rate,
++ "\nSetting this to 1 will force the driver to use the default refresh rate for\n"
++ "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)");
++
++MODULE_PARM(scalelcd, "i");
++MODULE_PARM_DESC(scalelcd,
++ "\nSetting this to 1 will force the driver to scale the LCD image to the panel's\n"
++ "native resolution. Setting it to 0 will disable scaling; if the panel can scale\n"
++ "by itself, it will probably do this, otherwise you will see a black bar around\n"
++ "the screen image. Default: [autodetect if panel can scale]");
++
++MODULE_PARM(specialtiming, "s");
+
+ int init_module(void)
+ {
+ int err;
+-
++
++ SiS_Pr.UsePanelScaler = -1;
++ SiS_Pr.SiS_CustomT = CUT_NONE;
++
++ ivideo.refresh_rate = sisfb_parm_rate = rate;
++
++ if((scalelcd == 0) || (scalelcd == 1)) {
++ SiS_Pr.UsePanelScaler = scalelcd ^ 1;
++ }
++
+ if(mode)
+- sisfb_search_mode(mode);
++ sisfb_search_mode(mode, FALSE);
+ else if(vesa != -1)
+- sisfb_search_vesamode(vesa);
+- else
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++ sisfb_search_vesamode(vesa, FALSE);
++ else
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ /* For 2.4, set mode=none if no mode is given */
+ sisfb_mode_idx = MODE_INDEX_NONE;
+ #endif
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+- /* For 2.5, we don't need this "mode=none" stuff anymore */
++ /* For 2.5, we don't need this "mode=none" stuff anymore */
+ sisfb_mode_idx = DEFAULT_MODE;
+ #endif
+
+- ivideo.refresh_rate = rate;
+-
+ if(forcecrt2type)
+ sisfb_search_crt2type(forcecrt2type);
+
+@@ -4745,9 +5293,6 @@
+
+ if(noypan == 1) sisfb_ypan = 0;
+ else if(noypan == 0) sisfb_ypan = 1;
+-
+- /* TW: Panning only with acceleration */
+- if(sisfb_accel == 0) sisfb_ypan = 0;
+
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ if(inverse) sisfb_inverse = 1;
+@@ -4759,17 +5304,11 @@
+
+ sisfb_useoem = useoem;
+
+- enable_dstn = dstn;
+-
+- /* TW: DSTN overrules forcecrt2type */
+- if (enable_dstn) sisfb_crt2type = DISPTYPE_LCD;
+-
+ if (queuemode) sisfb_search_queuemode(queuemode);
+
+ /* TW: If other queuemode than MMIO, disable 2D accel and ypan */
+ if((sisfb_queuemode != -1) && (sisfb_queuemode != MMIO_CMD)) {
+ sisfb_accel = 0;
+- sisfb_ypan = 0;
+ }
+
+ if(pdc) {
+@@ -4778,6 +5317,11 @@
+ }
+ }
+
++ sisfb_nocrt2rate = nocrt2rate;
++
++ if(specialtiming)
++ sisfb_search_specialtiming(specialtiming);
++
+ if((err = sisfb_init()) < 0) return err;
+
+ return 0;
+@@ -4788,7 +5332,7 @@
+ /* TW: Release mem regions */
+ release_mem_region(ivideo.video_base, ivideo.video_size);
+ release_mem_region(ivideo.mmio_base, sisfb_mmio_size);
+-
++
+ #ifdef CONFIG_MTRR
+ /* TW: Release MTRR region */
+ if(ivideo.mtrr) {
+@@ -4802,11 +5346,17 @@
+ if(sisfb_registered) {
+ unregister_framebuffer(&sis_fb_info);
+ }
+-
++
+ if(sishw_ext.pSR) vfree(sishw_ext.pSR);
+ if(sishw_ext.pCR) vfree(sishw_ext.pCR);
+
+- /* TODO: Restore the initial mode */
++ /* TODO: Restore the initial mode
++ * This sounds easy but is as good as impossible
++ * on many machines with SiS chip and video bridge
++ * since text modes are always set up differently
++ * from machine to machine. Depends on the type
++ * of integration between chipset and bridge.
++ */
+
+ printk(KERN_INFO "sisfb: Module unloaded\n");
+ }
+Index: linux-2.6.0-test5/drivers/video/sis/sis_main.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/sis/sis_main.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/sis/sis_main.h 2003-09-27 11:38:35.546124552 +0800
+@@ -1,8 +1,6 @@
+ #ifndef _SISFB_MAIN
+ #define _SISFB_MAIN
+
+-/* Comments and changes marked with "TW" by Thomas Winischhofer <thomas@winischhofer.net> */
+-
+ #include "vstruct.h"
+
+ /* ------------------- Constant Definitions ------------------------- */
+@@ -14,11 +12,11 @@
+
+ #define VER_MAJOR 1
+ #define VER_MINOR 6
+-#define VER_LEVEL 1
++#define VER_LEVEL 13
+
+ #include "sis.h"
+
+-/* TW: To be included in pci_ids.h */
++/* To be included in pci_ids.h */
+ #ifndef PCI_DEVICE_ID_SI_650_VGA
+ #define PCI_DEVICE_ID_SI_650_VGA 0x6325
+ #endif
+@@ -31,13 +29,22 @@
+ #ifndef PCI_DEVICE_ID_SI_330
+ #define PCI_DEVICE_ID_SI_330 0x0330
+ #endif
++#ifndef PCI_DEVICE_ID_SI_660
++#define PCI_DEVICE_ID_SI_660 0x0660
++#endif
++#ifndef PCI_DEVICE_ID_SI_660_VGA
++#define PCI_DEVICE_ID_SI_660_VGA 0x6330
++#endif
++#ifndef PCI_DEVICE_ID_SI_760
++#define PCI_DEVICE_ID_SI_760 0x0760
++#endif
+
+ /* To be included in fb.h */
+ #ifndef FB_ACCEL_SIS_GLAMOUR_2
+ #define FB_ACCEL_SIS_GLAMOUR_2 40 /* SiS 315, 650, 740 */
+ #endif
+ #ifndef FB_ACCEL_SIS_XABRE
+-#define FB_ACCEL_SIS_XABRE 41 /* SiS 330 ("Xabre") */
++#define FB_ACCEL_SIS_XABRE 41 /* SiS 330, 660, 760 ("Xabre") */
+ #endif
+
+ #define MAX_ROM_SCAN 0x10000
+@@ -53,13 +60,12 @@
+ #define TURBO_QUEUE_AREA_SIZE 0x80000 /* 512K */
+ #endif
+
+-/* For 315 series */
++/* For 315/Xabre series */
+ #ifdef CONFIG_FB_SIS_315
+ #define COMMAND_QUEUE_AREA_SIZE 0x80000 /* 512K */
+ #define COMMAND_QUEUE_THRESHOLD 0x1F
+ #endif
+
+-/* TW */
+ #define HW_CURSOR_AREA_SIZE_315 0x4000 /* 16K */
+ #define HW_CURSOR_AREA_SIZE_300 0x1000 /* 4K */
+
+@@ -283,48 +289,46 @@
+ /* Fbcon variables */
+ static struct fb_info sis_fb_info;
+
+-static int video_type = FB_TYPE_PACKED_PIXELS;
+-
+ static struct fb_var_screeninfo default_var = {
+- .xres = 0,
+- .yres = 0,
+- .xres_virtual = 0,
+- .yres_virtual = 0,
+- .xoffset = 0,
+- .yoffset = 0,
+- .bits_per_pixel = 0,
+- .grayscale = 0,
+- .red = {0, 8, 0},
+- .green = {0, 8, 0},
+- .blue = {0, 8, 0},
+- .transp = {0, 0, 0},
+- .nonstd = 0,
+- .activate = FB_ACTIVATE_NOW,
+- .height = -1,
+- .width = -1,
+- .accel_flags = 0,
+- .pixclock = 0,
+- .left_margin = 0,
+- .right_margin = 0,
+- .upper_margin = 0,
+- .lower_margin = 0,
+- .hsync_len = 0,
+- .vsync_len = 0,
+- .sync = 0,
+- .vmode = FB_VMODE_NONINTERLACED,
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+- .reserved = {0, 0, 0, 0, 0, 0}
+-#endif
++ .xres = 0,
++ .yres = 0,
++ .xres_virtual = 0,
++ .yres_virtual = 0,
++ .xoffset = 0,
++ .yoffset = 0,
++ .bits_per_pixel = 0,
++ .grayscale = 0,
++ .red = {0, 8, 0},
++ .green = {0, 8, 0},
++ .blue = {0, 8, 0},
++ .transp = {0, 0, 0},
++ .nonstd = 0,
++ .activate = FB_ACTIVATE_NOW,
++ .height = -1,
++ .width = -1,
++ .accel_flags = 0,
++ .pixclock = 0,
++ .left_margin = 0,
++ .right_margin = 0,
++ .upper_margin = 0,
++ .lower_margin = 0,
++ .hsync_len = 0,
++ .vsync_len = 0,
++ .sync = 0,
++ .vmode = FB_VMODE_NONINTERLACED,
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++ .reserved = {0, 0, 0, 0, 0, 0}
++#endif
+ };
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ static struct fb_fix_screeninfo sisfb_fix = {
+ .id = "SiS",
+ .type = FB_TYPE_PACKED_PIXELS,
+- .xpanstep = 1,
++ .xpanstep = 0,
+ .ypanstep = 1,
+ };
+-static char myid[20];
++static char myid[40];
+ static u32 pseudo_palette[17];
+ #endif
+
+@@ -347,26 +351,24 @@
+ } sis_fbcon_cmap;
+
+ static int sisfb_inverse = 0;
++static int currcon = 0;
+ #endif
+
+-/* display status */
++/* global flags */
+ static int sisfb_off = 0;
+ static int sisfb_crt1off = 0;
+ static int sisfb_forcecrt1 = -1;
+ static int sisvga_enabled = 0;
+ static int sisfb_userom = 1;
+ static int sisfb_useoem = -1;
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+-static int currcon = 0;
+-#endif
+-
+-/* global flags */
+-static int sisfb_registered;
+-static int sisfb_tvmode = 0;
++static int sisfb_parm_rate = -1;
++static int sisfb_registered = 0;
+ static int sisfb_mem = 0;
+ static int sisfb_pdc = 0;
+-static int enable_dstn = 0;
+ static int sisfb_ypan = -1;
++static int sisfb_nocrt2rate = 0;
++static int sisfb_dstn = 0;
++static int sisfb_fstn = 0;
+
+ VGA_ENGINE sisvga_engine = UNKNOWN_VGA;
+ int sisfb_accel = -1;
+@@ -375,22 +377,22 @@
+ static int sisfb_hwcursor_size = 0;
+ static int sisfb_CRT2_write_enable = 0;
+
+-int sisfb_crt2type = -1; /* TW: CRT2 type (for overriding autodetection) */
+-int sisfb_tvplug = -1; /* PR: Tv plug type (for overriding autodetection) */
++int sisfb_crt2type = -1; /* CRT2 type (for overriding autodetection) */
++int sisfb_tvplug = -1; /* Tv plug type (for overriding autodetection) */
+
+-int sisfb_queuemode = -1; /* TW: Use MMIO queue mode by default (310/325 series only) */
++int sisfb_queuemode = -1; /* Use MMIO queue mode by default (315 series only) */
+
+ unsigned char sisfb_detectedpdc = 0;
+
+ unsigned char sisfb_detectedlcda = 0xff;
+
+-/* data for sis components */
++/* data for sis hardware ("par") */
+ struct video_info ivideo;
+
+-/* TW: For ioctl SISFB_GET_INFO */
++/* For ioctl SISFB_GET_INFO */
+ sisfb_info sisfbinfo;
+
+-/* TW: Hardware extension; contains data on hardware */
++/* Hardware extension; contains data on hardware */
+ HW_DEVICE_EXTENSION sishw_ext = {
+ NULL, NULL, FALSE, NULL, NULL,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+@@ -399,10 +401,10 @@
+ 0
+ };
+
+-/* TW: SiS private structure */
++/* SiS private structure */
+ SiS_Private SiS_Pr;
+
+-/* card parameters */
++/* Card parameters */
+ static unsigned long sisfb_mmio_size = 0;
+ static u8 sisfb_caps = 0;
+
+@@ -412,7 +414,7 @@
+ VM_CMD_QUEUE,
+ } SIS_CMDTYPE;
+
+-/* Supported SiS Chips list */
++/* List of supported chips */
+ static struct board {
+ u16 vendor, device;
+ const char *name;
+@@ -424,16 +426,17 @@
+ {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315, "SIS 315"},
+ {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315PRO, "SIS 315PRO"},
+ {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_550_VGA, "SIS 550 VGA"},
+- {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_650_VGA, "SIS 650/M650/651/740 VGA"},
++ {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_650_VGA, "SIS 650/M650/651/M652/740 VGA"},
+ {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_330, "SIS 330"},
++ {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_660_VGA, "SIS 660/M660/760/M760 VGA"},
+ {0, 0, NULL}
+ };
+
+ #define MD_SIS300 1
+ #define MD_SIS315 2
+
+-/* mode table */
+-/* NOT const - will be patched for 1280x960 mode number chaos reasons */
++/* Mode table */
++/* NOT const - will be patched for 1280x768 mode number chaos reasons */
+ struct _sisbios_mode {
+ char name[15];
+ u8 mode_no;
+@@ -447,14 +450,33 @@
+ u16 rows;
+ u8 chipset;
+ } sisbios_mode[] = {
+-#define MODE_INDEX_NONE 0 /* TW: index for mode=none */
+- {"none", 0xFF, 0x0000, 0x0000, 0, 0, 0, 0, 0, 0, MD_SIS300|MD_SIS315}, /* TW: for mode "none" */
+- {"320x240x16", 0x56, 0x0000, 0x0000, 320, 240, 16, 1, 40, 15, MD_SIS315},
+- {"320x480x8", 0x5A, 0x0000, 0x0000, 320, 480, 8, 1, 40, 30, MD_SIS315}, /* TW: FSTN */
+- {"320x480x16", 0x5B, 0x0000, 0x0000, 320, 480, 16, 1, 40, 30, MD_SIS315}, /* TW: FSTN */
+- {"640x480x8", 0x2E, 0x0101, 0x0101, 640, 480, 8, 1, 80, 30, MD_SIS300|MD_SIS315},
++#define MODE_INDEX_NONE 0 /* index for mode=none */
++ {"none", 0xff, 0x0000, 0x0000, 0, 0, 0, 0, 0, 0, MD_SIS300|MD_SIS315},
++ {"320x200x8", 0x59, 0x0138, 0x0000, 320, 200, 8, 1, 40, 12, MD_SIS300|MD_SIS315},
++ {"320x200x16", 0x41, 0x010e, 0x0000, 320, 200, 16, 1, 40, 12, MD_SIS300|MD_SIS315},
++ {"320x200x24", 0x4f, 0x0000, 0x0000, 320, 200, 32, 1, 40, 12, MD_SIS300|MD_SIS315}, /* TW: That's for people who mix up color- and fb depth */
++ {"320x200x32", 0x4f, 0x0000, 0x0000, 320, 200, 32, 1, 40, 12, MD_SIS300|MD_SIS315},
++ {"320x240x8", 0x50, 0x0132, 0x0000, 320, 240, 8, 1, 40, 15, MD_SIS300|MD_SIS315},
++ {"320x240x16", 0x56, 0x0135, 0x0000, 320, 240, 16, 1, 40, 15, MD_SIS300|MD_SIS315},
++ {"320x240x24", 0x53, 0x0000, 0x0000, 320, 240, 32, 1, 40, 15, MD_SIS300|MD_SIS315},
++ {"320x240x32", 0x53, 0x0000, 0x0000, 320, 240, 32, 1, 40, 15, MD_SIS300|MD_SIS315},
++ {"320x240x8", 0x5a, 0x0132, 0x0000, 320, 480, 8, 1, 40, 30, MD_SIS315}, /* TW: FSTN */
++ {"320x240x16", 0x5b, 0x0135, 0x0000, 320, 480, 16, 1, 40, 30, MD_SIS315}, /* TW: FSTN */
++ {"400x300x8", 0x51, 0x0133, 0x0000, 400, 300, 8, 1, 50, 18, MD_SIS300|MD_SIS315},
++ {"400x300x16", 0x57, 0x0136, 0x0000, 400, 300, 16, 1, 50, 18, MD_SIS300|MD_SIS315},
++ {"400x300x24", 0x54, 0x0000, 0x0000, 400, 300, 32, 1, 50, 18, MD_SIS300|MD_SIS315},
++ {"400x300x32", 0x54, 0x0000, 0x0000, 400, 300, 32, 1, 50, 18, MD_SIS300|MD_SIS315},
++ {"512x384x8", 0x52, 0x0000, 0x0000, 512, 384, 8, 1, 64, 24, MD_SIS300|MD_SIS315},
++ {"512x384x16", 0x58, 0x0000, 0x0000, 512, 384, 16, 1, 64, 24, MD_SIS300|MD_SIS315},
++ {"512x384x24", 0x5c, 0x0000, 0x0000, 512, 384, 32, 1, 64, 24, MD_SIS300|MD_SIS315},
++ {"512x384x32", 0x5c, 0x0000, 0x0000, 512, 384, 32, 1, 64, 24, MD_SIS300|MD_SIS315},
++ {"640x400x8", 0x2f, 0x0000, 0x0000, 640, 400, 8, 1, 80, 25, MD_SIS300|MD_SIS315},
++ {"640x400x16", 0x5d, 0x0000, 0x0000, 640, 400, 16, 1, 80, 25, MD_SIS300|MD_SIS315},
++ {"640x400x24", 0x5e, 0x0000, 0x0000, 640, 400, 32, 1, 80, 25, MD_SIS300|MD_SIS315},
++ {"640x400x32", 0x5e, 0x0000, 0x0000, 640, 400, 32, 1, 80, 25, MD_SIS300|MD_SIS315},
++ {"640x480x8", 0x2e, 0x0101, 0x0101, 640, 480, 8, 1, 80, 30, MD_SIS300|MD_SIS315},
+ {"640x480x16", 0x44, 0x0111, 0x0111, 640, 480, 16, 1, 80, 30, MD_SIS300|MD_SIS315},
+- {"640x480x24", 0x62, 0x013a, 0x0112, 640, 480, 32, 1, 80, 30, MD_SIS300|MD_SIS315}, /* TW: That's for people who mix up color- and fb depth */
++ {"640x480x24", 0x62, 0x013a, 0x0112, 640, 480, 32, 1, 80, 30, MD_SIS300|MD_SIS315},
+ {"640x480x32", 0x62, 0x013a, 0x0112, 640, 480, 32, 1, 80, 30, MD_SIS300|MD_SIS315},
+ {"720x480x8", 0x31, 0x0000, 0x0000, 720, 480, 8, 1, 90, 30, MD_SIS300|MD_SIS315},
+ {"720x480x16", 0x33, 0x0000, 0x0000, 720, 480, 16, 1, 90, 30, MD_SIS300|MD_SIS315},
+@@ -464,63 +486,87 @@
+ {"720x576x16", 0x34, 0x0000, 0x0000, 720, 576, 16, 1, 90, 36, MD_SIS300|MD_SIS315},
+ {"720x576x24", 0x36, 0x0000, 0x0000, 720, 576, 32, 1, 90, 36, MD_SIS300|MD_SIS315},
+ {"720x576x32", 0x36, 0x0000, 0x0000, 720, 576, 32, 1, 90, 36, MD_SIS300|MD_SIS315},
++ {"768x576x8", 0x5f, 0x0000, 0x0000, 768, 576, 8, 1, 96, 36, MD_SIS300|MD_SIS315},
++ {"768x576x16", 0x60, 0x0000, 0x0000, 768, 576, 16, 1, 96, 36, MD_SIS300|MD_SIS315},
++ {"768x576x24", 0x61, 0x0000, 0x0000, 768, 576, 32, 1, 96, 36, MD_SIS300|MD_SIS315},
++ {"768x576x32", 0x61, 0x0000, 0x0000, 768, 576, 32, 1, 96, 36, MD_SIS300|MD_SIS315},
+ {"800x480x8", 0x70, 0x0000, 0x0000, 800, 480, 8, 1, 100, 30, MD_SIS300|MD_SIS315},
+ {"800x480x16", 0x7a, 0x0000, 0x0000, 800, 480, 16, 1, 100, 30, MD_SIS300|MD_SIS315},
+ {"800x480x24", 0x76, 0x0000, 0x0000, 800, 480, 32, 1, 100, 30, MD_SIS300|MD_SIS315},
+ {"800x480x32", 0x76, 0x0000, 0x0000, 800, 480, 32, 1, 100, 30, MD_SIS300|MD_SIS315},
+-#define DEFAULT_MODE 20 /* TW: index for 800x600x8 */
+-#define DEFAULT_LCDMODE 20 /* TW: index for 800x600x8 */
+-#define DEFAULT_TVMODE 20 /* TW: index for 800x600x8 */
++#define DEFAULT_MODE 43 /* index for 800x600x8 */
++#define DEFAULT_LCDMODE 43 /* index for 800x600x8 */
++#define DEFAULT_TVMODE 43 /* index for 800x600x8 */
+ {"800x600x8", 0x30, 0x0103, 0x0103, 800, 600, 8, 2, 100, 37, MD_SIS300|MD_SIS315},
+ {"800x600x16", 0x47, 0x0114, 0x0114, 800, 600, 16, 2, 100, 37, MD_SIS300|MD_SIS315},
+ {"800x600x24", 0x63, 0x013b, 0x0115, 800, 600, 32, 2, 100, 37, MD_SIS300|MD_SIS315},
+ {"800x600x32", 0x63, 0x013b, 0x0115, 800, 600, 32, 2, 100, 37, MD_SIS300|MD_SIS315},
++ {"848x480x8", 0x39, 0x0000, 0x0000, 848, 480, 8, 2, 106, 30, MD_SIS300|MD_SIS315},
++ {"848x480x16", 0x3b, 0x0000, 0x0000, 848, 480, 16, 2, 106, 30, MD_SIS300|MD_SIS315},
++ {"848x480x24", 0x3e, 0x0000, 0x0000, 848, 480, 32, 2, 106, 30, MD_SIS300|MD_SIS315},
++ {"848x480x32", 0x3e, 0x0000, 0x0000, 848, 480, 32, 2, 106, 30, MD_SIS300|MD_SIS315},
++ {"856x480x8", 0x3f, 0x0000, 0x0000, 856, 480, 8, 2, 107, 30, MD_SIS300|MD_SIS315},
++ {"856x480x16", 0x42, 0x0000, 0x0000, 856, 480, 16, 2, 107, 30, MD_SIS300|MD_SIS315},
++ {"856x480x24", 0x45, 0x0000, 0x0000, 856, 480, 32, 2, 107, 30, MD_SIS300|MD_SIS315},
++ {"856x480x32", 0x45, 0x0000, 0x0000, 856, 480, 32, 2, 107, 30, MD_SIS300|MD_SIS315},
+ {"1024x576x8", 0x71, 0x0000, 0x0000, 1024, 576, 8, 1, 128, 36, MD_SIS300|MD_SIS315},
+ {"1024x576x16", 0x74, 0x0000, 0x0000, 1024, 576, 16, 1, 128, 36, MD_SIS300|MD_SIS315},
+ {"1024x576x24", 0x77, 0x0000, 0x0000, 1024, 576, 32, 1, 128, 36, MD_SIS300|MD_SIS315},
+ {"1024x576x32", 0x77, 0x0000, 0x0000, 1024, 576, 32, 1, 128, 36, MD_SIS300|MD_SIS315},
+- {"1024x600x8", 0x20, 0x0000, 0x0000, 1024, 600, 8, 1, 128, 37, MD_SIS300 }, /* TW: 300 series only */
++ {"1024x600x8", 0x20, 0x0000, 0x0000, 1024, 600, 8, 1, 128, 37, MD_SIS300 },
+ {"1024x600x16", 0x21, 0x0000, 0x0000, 1024, 600, 16, 1, 128, 37, MD_SIS300 },
+ {"1024x600x24", 0x22, 0x0000, 0x0000, 1024, 600, 32, 1, 128, 37, MD_SIS300 },
+ {"1024x600x32", 0x22, 0x0000, 0x0000, 1024, 600, 32, 1, 128, 37, MD_SIS300 },
+ {"1024x768x8", 0x38, 0x0105, 0x0105, 1024, 768, 8, 2, 128, 48, MD_SIS300|MD_SIS315},
+- {"1024x768x16", 0x4A, 0x0117, 0x0117, 1024, 768, 16, 2, 128, 48, MD_SIS300|MD_SIS315},
++ {"1024x768x16", 0x4a, 0x0117, 0x0117, 1024, 768, 16, 2, 128, 48, MD_SIS300|MD_SIS315},
+ {"1024x768x24", 0x64, 0x013c, 0x0118, 1024, 768, 32, 2, 128, 48, MD_SIS300|MD_SIS315},
+ {"1024x768x32", 0x64, 0x013c, 0x0118, 1024, 768, 32, 2, 128, 48, MD_SIS300|MD_SIS315},
+- {"1152x768x8", 0x23, 0x0000, 0x0000, 1152, 768, 8, 1, 144, 48, MD_SIS300 }, /* TW: 300 series only */
++ {"1152x768x8", 0x23, 0x0000, 0x0000, 1152, 768, 8, 1, 144, 48, MD_SIS300 },
+ {"1152x768x16", 0x24, 0x0000, 0x0000, 1152, 768, 16, 1, 144, 48, MD_SIS300 },
+ {"1152x768x24", 0x25, 0x0000, 0x0000, 1152, 768, 32, 1, 144, 48, MD_SIS300 },
+ {"1152x768x32", 0x25, 0x0000, 0x0000, 1152, 768, 32, 1, 144, 48, MD_SIS300 },
++ {"1152x864x8", 0x29, 0x0000, 0x0000, 1152, 864, 8, 1, 144, 54, MD_SIS300|MD_SIS315},
++ {"1152x864x16", 0x2a, 0x0000, 0x0000, 1152, 864, 16, 1, 144, 54, MD_SIS300|MD_SIS315},
++ {"1152x864x24", 0x2b, 0x0000, 0x0000, 1152, 864, 32, 1, 144, 54, MD_SIS300|MD_SIS315},
++ {"1152x864x32", 0x2b, 0x0000, 0x0000, 1152, 864, 32, 1, 144, 54, MD_SIS300|MD_SIS315},
+ {"1280x720x8", 0x79, 0x0000, 0x0000, 1280, 720, 8, 1, 160, 45, MD_SIS300|MD_SIS315},
+ {"1280x720x16", 0x75, 0x0000, 0x0000, 1280, 720, 16, 1, 160, 45, MD_SIS300|MD_SIS315},
+ {"1280x720x24", 0x78, 0x0000, 0x0000, 1280, 720, 32, 1, 160, 45, MD_SIS300|MD_SIS315},
+ {"1280x720x32", 0x78, 0x0000, 0x0000, 1280, 720, 32, 1, 160, 45, MD_SIS300|MD_SIS315},
+- {"1280x768x8", 0x23, 0x0000, 0x0000, 1280, 768, 8, 1, 160, 48, MD_SIS315}, /* TW: 310/325 series only */
+- {"1280x768x16", 0x24, 0x0000, 0x0000, 1280, 768, 16, 1, 160, 48, MD_SIS315},
+- {"1280x768x24", 0x25, 0x0000, 0x0000, 1280, 768, 32, 1, 160, 48, MD_SIS315},
+- {"1280x768x32", 0x25, 0x0000, 0x0000, 1280, 768, 32, 1, 160, 48, MD_SIS315},
+-#define MODEINDEX_1280x960 48
+- {"1280x960x8", 0x7C, 0x0000, 0x0000, 1280, 960, 8, 1, 160, 60, MD_SIS300|MD_SIS315}, /* TW: Modenumbers being patched */
+- {"1280x960x16", 0x7D, 0x0000, 0x0000, 1280, 960, 16, 1, 160, 60, MD_SIS300|MD_SIS315},
+- {"1280x960x24", 0x7E, 0x0000, 0x0000, 1280, 960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
+- {"1280x960x32", 0x7E, 0x0000, 0x0000, 1280, 960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
+- {"1280x1024x8", 0x3A, 0x0107, 0x0107, 1280, 1024, 8, 2, 160, 64, MD_SIS300|MD_SIS315},
+- {"1280x1024x16", 0x4D, 0x011a, 0x011a, 1280, 1024, 16, 2, 160, 64, MD_SIS300|MD_SIS315},
++#define MODEINDEX_1280x768 79
++ {"1280x768x8", 0x23, 0x0000, 0x0000, 1280, 768, 8, 1, 160, 48, MD_SIS300|MD_SIS315},
++ {"1280x768x16", 0x24, 0x0000, 0x0000, 1280, 768, 16, 1, 160, 48, MD_SIS300|MD_SIS315},
++ {"1280x768x24", 0x25, 0x0000, 0x0000, 1280, 768, 32, 1, 160, 48, MD_SIS300|MD_SIS315},
++ {"1280x768x32", 0x25, 0x0000, 0x0000, 1280, 768, 32, 1, 160, 48, MD_SIS300|MD_SIS315},
++ {"1280x960x8", 0x7c, 0x0000, 0x0000, 1280, 960, 8, 1, 160, 60, MD_SIS300|MD_SIS315},
++ {"1280x960x16", 0x7d, 0x0000, 0x0000, 1280, 960, 16, 1, 160, 60, MD_SIS300|MD_SIS315},
++ {"1280x960x24", 0x7e, 0x0000, 0x0000, 1280, 960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
++ {"1280x960x32", 0x7e, 0x0000, 0x0000, 1280, 960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
++ {"1280x1024x8", 0x3a, 0x0107, 0x0107, 1280, 1024, 8, 2, 160, 64, MD_SIS300|MD_SIS315},
++ {"1280x1024x16", 0x4d, 0x011a, 0x011a, 1280, 1024, 16, 2, 160, 64, MD_SIS300|MD_SIS315},
+ {"1280x1024x24", 0x65, 0x013d, 0x011b, 1280, 1024, 32, 2, 160, 64, MD_SIS300|MD_SIS315},
+ {"1280x1024x32", 0x65, 0x013d, 0x011b, 1280, 1024, 32, 2, 160, 64, MD_SIS300|MD_SIS315},
+- {"1400x1050x8", 0x26, 0x0000, 0x0000, 1400, 1050, 8, 1, 175, 65, MD_SIS315}, /* TW: 310/325 series only */
++ {"1360x768x8", 0x48, 0x0000, 0x0000, 1360, 768, 8, 1, 170, 48, MD_SIS300|MD_SIS315},
++ {"1360x768x16", 0x4b, 0x0000, 0x0000, 1360, 768, 16, 1, 170, 48, MD_SIS300|MD_SIS315},
++ {"1360x768x24", 0x4e, 0x0000, 0x0000, 1360, 768, 32, 1, 170, 48, MD_SIS300|MD_SIS315},
++ {"1360x768x32", 0x4e, 0x0000, 0x0000, 1360, 768, 32, 1, 170, 48, MD_SIS300|MD_SIS315},
++ {"1360x1024x8", 0x67, 0x0000, 0x0000, 1360, 1024, 8, 1, 170, 64, MD_SIS300 },
++ {"1360x1024x16", 0x6f, 0x0000, 0x0000, 1360, 1024, 16, 1, 170, 64, MD_SIS300 },
++ {"1360x1024x24", 0x72, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300 },
++ {"1360x1024x32", 0x72, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300 },
++ {"1400x1050x8", 0x26, 0x0000, 0x0000, 1400, 1050, 8, 1, 175, 65, MD_SIS315},
+ {"1400x1050x16", 0x27, 0x0000, 0x0000, 1400, 1050, 16, 1, 175, 65, MD_SIS315},
+ {"1400x1050x24", 0x28, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65, MD_SIS315},
+ {"1400x1050x32", 0x28, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65, MD_SIS315},
+- {"1600x1200x8", 0x3C, 0x0130, 0x011c, 1600, 1200, 8, 1, 200, 75, MD_SIS300|MD_SIS315},
+- {"1600x1200x16", 0x3D, 0x0131, 0x011e, 1600, 1200, 16, 1, 200, 75, MD_SIS300|MD_SIS315},
++ {"1600x1200x8", 0x3c, 0x0130, 0x011c, 1600, 1200, 8, 1, 200, 75, MD_SIS300|MD_SIS315},
++ {"1600x1200x16", 0x3d, 0x0131, 0x011e, 1600, 1200, 16, 1, 200, 75, MD_SIS300|MD_SIS315},
+ {"1600x1200x24", 0x66, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_SIS300|MD_SIS315},
+ {"1600x1200x32", 0x66, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_SIS300|MD_SIS315},
+ {"1920x1440x8", 0x68, 0x013f, 0x0000, 1920, 1440, 8, 1, 240, 75, MD_SIS300|MD_SIS315},
+ {"1920x1440x16", 0x69, 0x0140, 0x0000, 1920, 1440, 16, 1, 240, 75, MD_SIS300|MD_SIS315},
+- {"1920x1440x24", 0x6B, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
+- {"1920x1440x32", 0x6B, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
+- {"2048x1536x8", 0x6c, 0x0000, 0x0000, 2048, 1536, 8, 1, 256, 96, MD_SIS315}, /* TW: 310/325 series only */
++ {"1920x1440x24", 0x6b, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
++ {"1920x1440x32", 0x6b, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
++ {"2048x1536x8", 0x6c, 0x0000, 0x0000, 2048, 1536, 8, 1, 256, 96, MD_SIS315},
+ {"2048x1536x16", 0x6d, 0x0000, 0x0000, 2048, 1536, 16, 1, 256, 96, MD_SIS315},
+ {"2048x1536x24", 0x6e, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96, MD_SIS315},
+ {"2048x1536x32", 0x6e, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96, MD_SIS315},
+@@ -538,37 +584,36 @@
+
+ /* TW: CR36 evaluation */
+ const USHORT sis300paneltype[] =
+- { LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024,
+- LCD_1280x960, LCD_640x480, LCD_1024x600, LCD_1152x768,
+- LCD_320x480, LCD_1024x768, LCD_1024x768, LCD_1024x768,
+- LCD_1024x768, LCD_1024x768, LCD_1024x768, LCD_1024x768 };
++ { LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024,
++ LCD_1280x960, LCD_640x480, LCD_1024x600, LCD_1152x768,
++ LCD_1024x768, LCD_1024x768, LCD_1024x768, LCD_1024x768,
++ LCD_1024x768, LCD_1024x768, LCD_320x480, LCD_1024x768 };
+
+ const USHORT sis310paneltype[] =
+- { LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024,
+- LCD_640x480, LCD_1024x600, LCD_1152x864, LCD_1280x960,
+- LCD_1152x768, LCD_1400x1050,LCD_1280x768, LCD_1600x1200,
+- LCD_320x480, LCD_1024x768, LCD_1024x768, LCD_1024x768 };
++ { LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024,
++ LCD_640x480, LCD_1024x600, LCD_1152x864, LCD_1280x960,
++ LCD_1152x768, LCD_1400x1050, LCD_1280x768, LCD_1600x1200,
++ LCD_640x480_2, LCD_640x480_3, LCD_320x480, LCD_1024x768 };
++
++#define FL_550_DSTN 0x01
++#define FL_550_FSTN 0x02
+
+ static const struct _sis_crt2type {
+ char name[10];
+ int type_no;
+ int tvplug_no;
++ unsigned short flags;
+ } sis_crt2type[] = {
+- {"NONE", 0, -1},
+- {"LCD", DISPTYPE_LCD, -1},
+- {"TV", DISPTYPE_TV, -1},
+- {"VGA", DISPTYPE_CRT2, -1},
+- {"SVIDEO", DISPTYPE_TV, TVPLUG_SVIDEO},
+- {"COMPOSITE", DISPTYPE_TV, TVPLUG_COMPOSITE},
+- {"SCART", DISPTYPE_TV, TVPLUG_SCART},
+- {"none", 0, -1},
+- {"lcd", DISPTYPE_LCD, -1},
+- {"tv", DISPTYPE_TV, -1},
+- {"vga", DISPTYPE_CRT2, -1},
+- {"svideo", DISPTYPE_TV, TVPLUG_SVIDEO},
+- {"composite", DISPTYPE_TV, TVPLUG_COMPOSITE},
+- {"scart", DISPTYPE_TV, TVPLUG_SCART},
+- {"\0", -1, -1}
++ {"NONE", 0, -1, 0},
++ {"LCD", CRT2_LCD, -1, 0},
++ {"TV", CRT2_TV, -1, 0},
++ {"VGA", CRT2_VGA, -1, 0},
++ {"SVIDEO", CRT2_TV, TV_SVIDEO, 0},
++ {"COMPOSITE", CRT2_TV, TV_AVIDEO, 0},
++ {"SCART", CRT2_TV, TV_SCART, 0},
++ {"DSTN", CRT2_LCD, -1, FL_550_DSTN},
++ {"FSTN", CRT2_LCD, -1, FL_550_FSTN},
++ {"\0", -1, -1, 0}
+ };
+
+ /* Queue mode selection for 310 series */
+@@ -579,9 +624,6 @@
+ {"AGP", AGP_CMD_QUEUE},
+ {"VRAM", VM_CMD_QUEUE},
+ {"MMIO", MMIO_CMD},
+- {"agp", AGP_CMD_QUEUE},
+- {"vram", VM_CMD_QUEUE},
+- {"mmio", MMIO_CMD},
+ {"\0", -1}
+ };
+
+@@ -590,10 +632,8 @@
+ char name[6];
+ int type_no;
+ } sis_tvtype[] = {
+- {"PAL", 1},
+- {"NTSC", 2},
+- {"pal", 1},
+- {"ntsc", 2},
++ {"PAL", TV_PAL},
++ {"NTSC", TV_NTSC},
+ {"\0", -1}
+ };
+
+@@ -602,33 +642,102 @@
+ u16 xres;
+ u16 yres;
+ u16 refresh;
++ BOOLEAN SiS730valid32bpp;
+ } sisfb_vrate[] = {
+- {1, 640, 480, 60}, {2, 640, 480, 72}, {3, 640, 480, 75}, {4, 640, 480, 85},
+- {5, 640, 480,100}, {6, 640, 480, 120}, {7, 640, 480, 160}, {8, 640, 480, 200},
+- {1, 720, 480, 60},
+- {1, 720, 576, 58},
+- {1, 800, 480, 60}, {2, 800, 480, 75}, {3, 800, 480, 85},
+- {1, 800, 600, 56}, {2, 800, 600, 60}, {3, 800, 600, 72}, {4, 800, 600, 75},
+- {5, 800, 600, 85}, {6, 800, 600, 100}, {7, 800, 600, 120}, {8, 800, 600, 160},
+- {1, 1024, 768, 43}, {2, 1024, 768, 60}, {3, 1024, 768, 70}, {4, 1024, 768, 75},
+- {5, 1024, 768, 85}, {6, 1024, 768, 100}, {7, 1024, 768, 120},
+- {1, 1024, 576, 60}, {2, 1024, 576, 75}, {3, 1024, 576, 85},
+- {1, 1024, 600, 60},
+- {1, 1152, 768, 60},
+- {1, 1280, 720, 60}, {2, 1280, 720, 75}, {3, 1280, 720, 85},
+- {1, 1280, 768, 60},
+- {1, 1280, 1024, 43}, {2, 1280, 1024, 60}, {3, 1280, 1024, 75}, {4, 1280, 1024, 85},
+- {1, 1280, 960, 70},
+- {1, 1400, 1050, 60},
+- {1, 1600, 1200, 60}, {2, 1600, 1200, 65}, {3, 1600, 1200, 70}, {4, 1600, 1200, 75},
+- {5, 1600, 1200, 85}, {6, 1600, 1200, 100}, {7, 1600, 1200, 120},
+- {1, 1920, 1440, 60}, {2, 1920, 1440, 65}, {3, 1920, 1440, 70}, {4, 1920, 1440, 75},
+- {5, 1920, 1440, 85}, {6, 1920, 1440, 100},
+- {1, 2048, 1536, 60}, {2, 2048, 1536, 65}, {3, 2048, 1536, 70}, {4, 2048, 1536, 75},
+- {5, 2048, 1536, 85},
+- {0, 0, 0, 0}
++ {1, 320, 200, 70, TRUE},
++ {1, 320, 240, 60, TRUE},
++ {1, 320, 480, 60, TRUE},
++ {1, 400, 300, 60, TRUE},
++ {1, 512, 384, 60, TRUE},
++ {1, 640, 400, 72, TRUE},
++ {1, 640, 480, 60, TRUE}, {2, 640, 480, 72, TRUE}, {3, 640, 480, 75, TRUE},
++ {4, 640, 480, 85, TRUE}, {5, 640, 480, 100, TRUE}, {6, 640, 480, 120, TRUE},
++ {7, 640, 480, 160, TRUE}, {8, 640, 480, 200, TRUE},
++ {1, 720, 480, 60, TRUE},
++ {1, 720, 576, 58, TRUE},
++ {1, 800, 480, 60, TRUE}, {2, 800, 480, 75, TRUE}, {3, 800, 480, 85, TRUE},
++ {1, 800, 600, 56, TRUE}, {2, 800, 600, 60, TRUE}, {3, 800, 600, 72, TRUE},
++ {4, 800, 600, 75, TRUE}, {5, 800, 600, 85, TRUE}, {6, 800, 600, 105, TRUE},
++ {7, 800, 600, 120, TRUE}, {8, 800, 600, 160, TRUE},
++ {1, 848, 480, 39, TRUE}, {2, 848, 480, 60, TRUE},
++ {1, 856, 480, 39, TRUE}, {2, 856, 480, 60, TRUE},
++ {1, 1024, 576, 60, TRUE}, {2, 1024, 576, 75, TRUE}, {3, 1024, 576, 85, TRUE},
++ {1, 1024, 600, 60, TRUE},
++ {1, 1024, 768, 43, TRUE}, {2, 1024, 768, 60, TRUE}, {3, 1024, 768, 70, FALSE},
++ {4, 1024, 768, 75, FALSE}, {5, 1024, 768, 85, TRUE}, {6, 1024, 768, 100, TRUE},
++ {7, 1024, 768, 120, TRUE},
++ {1, 1152, 768, 60, TRUE},
++ {1, 1152, 864, 75, TRUE}, {2, 1152, 864, 84, TRUE},
++ {1, 1280, 720, 60, TRUE}, {2, 1280, 720, 75, TRUE}, {3, 1280, 720, 85, TRUE},
++ {1, 1280, 768, 60, TRUE},
++ {1, 1280, 960, 60, TRUE}, {2, 1280, 960, 85, TRUE},
++ {1, 1280, 1024, 43, TRUE}, {2, 1280, 1024, 60, TRUE}, {3, 1280, 1024, 75, TRUE},
++ {4, 1280, 1024, 85, TRUE},
++ {1, 1360, 768, 60, TRUE},
++ {1, 1360, 1024, 59, TRUE},
++ {1, 1400, 1050, 60, TRUE}, {2, 1400, 1050, 75, TRUE},
++ {1, 1600, 1200, 60, TRUE}, {2, 1600, 1200, 65, TRUE}, {3, 1600, 1200, 70, TRUE},
++ {4, 1600, 1200, 75, TRUE}, {5, 1600, 1200, 85, TRUE}, {6, 1600, 1200, 100, TRUE},
++ {7, 1600, 1200, 120, TRUE},
++ {1, 1920, 1440, 60, TRUE}, {2, 1920, 1440, 65, TRUE}, {3, 1920, 1440, 70, TRUE},
++ {4, 1920, 1440, 75, TRUE}, {5, 1920, 1440, 85, TRUE}, {6, 1920, 1440, 100, TRUE},
++ {1, 2048, 1536, 60, TRUE}, {2, 2048, 1536, 65, TRUE}, {3, 2048, 1536, 70, TRUE},
++ {4, 2048, 1536, 75, TRUE}, {5, 2048, 1536, 85, TRUE},
++ {0, 0, 0, 0, FALSE}
+ };
+
++static struct sisfb_monitor {
++ u16 hmin;
++ u16 hmax;
++ u16 vmin;
++ u16 vmax;
++ u32 dclockmax;
++ u8 feature;
++ BOOLEAN datavalid;
++} sisfb_thismonitor;
++
++static const struct _sisfbddcsmodes {
++ u32 mask;
++ u16 h;
++ u16 v;
++ u32 d;
++} sisfb_ddcsmodes[] = {
++ { 0x10000, 67, 75, 108000},
++ { 0x08000, 48, 72, 50000},
++ { 0x04000, 46, 75, 49500},
++ { 0x01000, 35, 43, 44900},
++ { 0x00800, 48, 60, 65000},
++ { 0x00400, 56, 70, 75000},
++ { 0x00200, 60, 75, 78800},
++ { 0x00100, 80, 75, 135000},
++ { 0x00020, 31, 60, 25200},
++ { 0x00008, 38, 72, 31500},
++ { 0x00004, 37, 75, 31500},
++ { 0x00002, 35, 56, 36000},
++ { 0x00001, 38, 60, 40000}
++};
++
++static const struct _sisfbddcfmodes {
++ u16 x;
++ u16 y;
++ u16 v;
++ u16 h;
++ u32 d;
++} sisfb_ddcfmodes[] = {
++ { 1280, 1024, 85, 92, 157500},
++ { 1600, 1200, 60, 75, 162000},
++ { 1600, 1200, 65, 82, 175500},
++ { 1600, 1200, 70, 88, 189000},
++ { 1600, 1200, 75, 94, 202500},
++ { 1600, 1200, 85, 107,229500},
++ { 1920, 1440, 60, 90, 234000},
++ { 1920, 1440, 75, 113,297000}
++};
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
++static u8 sisfb_lastrates[128];
++#endif
++
+ static const struct _chswtable {
+ int subsysVendor;
+ int subsysCard;
+@@ -636,9 +745,61 @@
+ char *cardName;
+ } mychswtable[] = {
+ { 0x1631, 0x1002, "Mitachi", "0x1002" },
++ { 0x1071, 0x7521, "Mitac" , "7521P" },
+ { 0, 0, "" , "" }
+ };
+
++static const struct _customttable {
++ unsigned short chipID;
++ char *biosversion;
++ char *biosdate;
++ unsigned long bioschksum;
++ unsigned short biosFootprintAddr[5];
++ unsigned char biosFootprintData[5];
++ unsigned short pcisubsysvendor;
++ unsigned short pcisubsyscard;
++ char *vendorName;
++ char *cardName;
++ unsigned long SpecialID;
++ char *optionName;
++} mycustomttable[] = {
++ { SIS_630, "2.00.07", "09/27/2002-13:38:25",
++ 0x3240A8,
++ { 0x220, 0x227, 0x228, 0x229, 0x22a },
++ { 0x01, 0xe3, 0x9a, 0x6a, 0x00 },
++ 0x1039, 0x6300,
++ "Barco", "iQ R200L/300/400", CUT_BARCO1366, "BARCO1366"
++ },
++ { SIS_630, "2.00.07", "09/27/2002-13:38:25",
++ 0x323FBD,
++ { 0x220, 0x227, 0x228, 0x229, 0x22a },
++ { 0x00, 0x5a, 0x64, 0x41, 0x00 },
++ 0x1039, 0x6300,
++ "Barco", "iQ G200L/300/400/500", CUT_BARCO1024, "BARCO1024"
++ },
++ { SIS_650, "", "",
++ 0,
++ { 0, 0, 0, 0, 0 },
++ { 0, 0, 0, 0, 0 },
++ 0x0e11, 0x083c,
++ "Compaq", "Presario 3045US", CUT_COMPAQ12802, "COMPAQ1280"
++ },
++ { 4321, "", "", /* This is hopefully NEVER autodetected */
++ 0,
++ { 0, 0, 0, 0, 0 },
++ { 0, 0, 0, 0, 0 },
++ 0, 0,
++ "Generic", "LVDS/Parallel 848x480", CUT_PANEL848, "PANEL848x480"
++ },
++ { 0, "", "",
++ 0,
++ { 0, 0, 0, 0 },
++ { 0, 0, 0, 0 },
++ 0, 0,
++ "", "", CUT_NONE, ""
++ }
++};
++
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ /* Offscreen layout */
+ typedef struct _SIS_GLYINFO {
+@@ -677,7 +838,6 @@
+ static unsigned long sisfb_heap_size;
+ static SIS_HEAP sisfb_heap;
+
+-// Eden Chen
+ static const struct _sis_TV_filter {
+ u8 filter[9][4];
+ } sis_TV_filter[] = {
+@@ -829,9 +989,8 @@
+
+ static int filter = -1;
+ static unsigned char filter_tb;
+-//~Eden Chen
+
+-/* ---------------------- Routine prototypes ------------------------- */
++/* ---------------------- Prototypes ------------------------- */
+
+ /* Interface used by the world */
+ #ifndef MODULE
+@@ -894,10 +1053,6 @@
+ const struct fb_fillrect *rect);
+ extern void fbcon_sis_copyarea(struct fb_info *info,
+ const struct fb_copyarea *area);
+-#if 0
+-extern void cfb_imageblit(struct fb_info *info,
+- const struct fb_image *image);
+-#endif
+ extern int fbcon_sis_sync(struct fb_info *info);
+ static int sisfb_ioctl(struct inode *inode,
+ struct file *file,
+@@ -912,7 +1067,7 @@
+ unsigned int *left_margin, unsigned int *right_margin,
+ unsigned int *upper_margin, unsigned int *lower_margin,
+ unsigned int *hsync_len, unsigned int *vsync_len,
+- unsigned int *sync, unsigned int *vmode);
++ unsigned int *sync, unsigned int *vmode);
+ #endif
+
+ static int sisfb_get_fix(struct fb_fix_screeninfo *fix, int con,
+@@ -923,9 +1078,9 @@
+ extern void sisfb_syncaccel(void);
+
+ /* Internal general routines */
+-static void sisfb_search_mode(const char *name);
+-static int sisfb_validate_mode(int modeindex);
+-static u8 sisfb_search_refresh_rate(unsigned int rate);
++static void sisfb_search_mode(char *name, BOOLEAN quiet);
++static int sisfb_validate_mode(int modeindex, unsigned long vbflags);
++static u8 sisfb_search_refresh_rate(unsigned int rate, int index);
+ static int sisfb_setcolreg(unsigned regno, unsigned red, unsigned green,
+ unsigned blue, unsigned transp,
+ struct fb_info *fb_info);
+@@ -939,6 +1094,12 @@
+ static BOOLEAN sisfbcheckvretracecrt2(void);
+ static BOOLEAN sisfbcheckvretracecrt1(void);
+ static BOOLEAN sisfb_bridgeisslave(void);
++static void sisfb_detect_VB_connect(void);
++static void sisfb_get_VB_type(void);
++
++static void sisfb_handle_ddc(struct sisfb_monitor *monitor, int crtno);
++static BOOLEAN sisfb_interpret_edid(struct sisfb_monitor *monitor, unsigned char *buffer);
++
+
+ /* SiS-specific Export functions */
+ void sis_dispinfo(struct ap_data *rec);
+@@ -952,15 +1113,9 @@
+ /* Chipset-dependent internal routines */
+ #ifdef CONFIG_FB_SIS_300
+ static int sisfb_get_dram_size_300(void);
+-static void sisfb_detect_VB_connect_300(void);
+-static void sisfb_get_VB_type_300(void);
+-static int sisfb_has_VB_300(void);
+ #endif
+ #ifdef CONFIG_FB_SIS_315
+ static int sisfb_get_dram_size_315(void);
+-static void sisfb_detect_VB_connect_315(void);
+-static void sisfb_get_VB_type_315(void);
+-static int sisfb_has_VB_315(void);
+ #endif
+
+ /* Internal heap routines */
+@@ -978,23 +1133,33 @@
+ BOOLEAN sisfb_query_north_bridge_space(PSIS_HW_DEVICE_INFO psishw_ext,
+ unsigned long offset, unsigned long set, unsigned long *value);
+
+-
+ /* Routines from init.c/init301.c */
+ extern void SiSRegInit(SiS_Private *SiS_Pr, USHORT BaseAddr);
+ extern BOOLEAN SiSInit(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ extern BOOLEAN SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo);
+-extern void SiS_SetEnableDstn(SiS_Private *SiS_Pr);
++extern void SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable);
++extern void SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable);
+ extern void SiS_LongWait(SiS_Private *SiS_Pr);
+
+-/* TW: Chrontel TV functions */
++extern BOOLEAN sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
++ unsigned char modeno, int *htotal, int *vtotal, unsigned char rateindex);
++
++/* Chrontel TV functions */
+ extern USHORT SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx);
+ extern void SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx);
+ extern USHORT SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx);
+ extern void SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx);
+ extern void SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh);
+ extern void SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime);
++extern void SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo);
++extern USHORT SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
++ USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer);
++extern void SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
++extern void SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr);
++extern void SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
++extern void SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+
+-/* TW: Sensing routines */
++/* Sensing routines */
+ void SiS_Sense30x(void);
+ int SISDoSense(int tempbl, int tempbh, int tempcl, int tempch);
+ void SiS_SenseCh(void);
+Index: linux-2.6.0-test5/drivers/video/sis/vgatypes.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/sis/vgatypes.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/sis/vgatypes.h 2003-09-27 11:38:35.552123640 +0800
+@@ -1,3 +1,36 @@
++/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/vgatypes.h,v 1.0 2001/06/15 21:23:00 dawes Exp $ */
++/*
++ * General type definitions for universal mode switching modules
++ *
++ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
++ *
++ * If distributed as part of the linux kernel, the contents of this file
++ * is entirely covered by the GPL.
++ *
++ * Otherwise, the following terms apply:
++ *
++ * Permission to use, copy, modify, distribute, and sell this software and its
++ * documentation for any purpose is hereby granted without fee, provided that
++ * the above copyright notice appear in all copies and that both that
++ * copyright notice and this permission notice appear in supporting
++ * documentation, and that the name of the copyright holder not be used in
++ * advertising or publicity pertaining to distribution of the software without
++ * specific, written prior permission. The copyright holder makes no representations
++ * about the suitability of this software for any purpose. It is provided
++ * "as is" without express or implied warranty.
++ *
++ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
++ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
++ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
++ * PERFORMANCE OF THIS SOFTWARE.
++ *
++ * Authors: Thomas Winischhofer <thomas@winischhofer.net>
++ * Silicon Integrated Systems
++ *
++ */
+ #ifndef _VGATYPES_
+ #define _VGATYPES_
+
+@@ -5,7 +38,7 @@
+ #include "xf86Pci.h"
+ #endif
+
+-#ifdef LINUX_KERNEL /* TW: We don't want the X driver to depend on kernel source */
++#ifdef LINUX_KERNEL /* We don't want the X driver to depend on kernel source */
+ #include <linux/ioctl.h>
+ #endif
+
+@@ -72,18 +105,15 @@
+ typedef UCHAR BOOLEAN;
+ #endif
+
+-#ifndef WINCE_HEADER
+ #ifndef bool
+ typedef UCHAR bool;
+ #endif
+-#endif /*WINCE_HEADER*/
+
+ #ifndef VBIOS_VER_MAX_LENGTH
+ #define VBIOS_VER_MAX_LENGTH 4
+ #endif
+
+ #ifndef LINUX_KERNEL /* For kernel, this is defined in sisfb.h */
+-#ifndef WIN2000
+ #ifndef SIS_CHIP_TYPE
+ typedef enum _SIS_CHIP_TYPE {
+ SIS_VGALegacy = 0,
+@@ -101,19 +131,19 @@
+ SIS_550,
+ SIS_650,
+ SIS_740,
+- SIS_330,
++ SIS_330,
++ SIS_660,
++ SIS_760,
+ MAX_SIS_CHIP
+ } SIS_CHIP_TYPE;
+ #endif
+ #endif
+-#endif
+
+-#ifndef WIN2000
+ #ifndef SIS_VB_CHIP_TYPE
+ typedef enum _SIS_VB_CHIP_TYPE {
+ VB_CHIP_Legacy = 0,
+ VB_CHIP_301,
+- VB_CHIP_301B,
++ VB_CHIP_301B,
+ VB_CHIP_301LV,
+ VB_CHIP_302,
+ VB_CHIP_302B,
+@@ -122,9 +152,7 @@
+ MAX_VB_CHIP
+ } SIS_VB_CHIP_TYPE;
+ #endif
+-#endif
+
+-#ifndef WIN2000
+ #ifndef SIS_LCD_TYPE
+ typedef enum _SIS_LCD_TYPE {
+ LCD_INVALID = 0,
+@@ -136,18 +164,20 @@
+ LCD_1600x1200,
+ LCD_1920x1440,
+ LCD_2048x1536,
+- LCD_320x480, /* TW: FSTN */
++ LCD_320x480, /* FSTN, DSTN */
+ LCD_1400x1050,
+ LCD_1152x864,
+ LCD_1152x768,
+ LCD_1280x768,
+ LCD_1024x600,
++ LCD_640x480_2, /* FSTN, DSTN */
++ LCD_640x480_3, /* FSTN, DSTN */
++ LCD_848x480,
++ LCD_CUSTOM,
+ LCD_UNKNOWN
+ } SIS_LCD_TYPE;
+ #endif
+-#endif
+
+-#ifndef WIN2000 /* mark by Paul, Move definition to sisv.h*/
+ #ifndef PSIS_DSReg
+ typedef struct _SIS_DSReg
+ {
+@@ -162,7 +192,6 @@
+
+ typedef BOOLEAN (*PSIS_QUERYSPACE) (PSIS_HW_DEVICE_INFO, ULONG, ULONG, ULONG *);
+
+-
+ struct _SIS_HW_DEVICE_INFO
+ {
+ PVOID pDevice; /* The pointer to the physical device data structure
+@@ -173,7 +202,7 @@
+ /* Note:ROM image file is the file of VBIOS ROM */
+
+ BOOLEAN UseROM; /* TW: Use the ROM image if provided */
+-
++
+ UCHAR *pjCustomizedROMImage;/* base virtual address of ROM image file. */
+ /* wincE:ROM image file is the file for OEM */
+ /* customized table */
+@@ -195,7 +224,7 @@
+ /* defined in the data structure type */
+ /* "SIS_VB_CHIP_TYPE" */
+
+- USHORT usExternalChip; /* NO VB or other video bridge(not */
++ USHORT usExternalChip; /* NO VB or other video bridge (other than */
+ /* SiS video bridge) */
+ /* if ujVBChipID = VB_CHIP_UNKNOWN, */
+ /* then bit0=1 : LVDS,bit1=1 : trumpion, */
+@@ -207,7 +236,7 @@
+ /* 011:Trumpion LVDS Scaling Chip */
+ /* 100:LVDS(LCD-out)+Chrontel 7005 */
+ /* 101:Single Chrontel 7005 */
+- /* TW: This has changed on 310/325 series! */
++ /* TW: This has changed on 315 series! */
+
+ ULONG ulCRT2LCDType; /* defined in the data structure type */
+ /* "SIS_LCD_TYPE" */
+@@ -244,7 +273,6 @@
+ #endif
+ };
+ #endif
+-#endif
+
+
+ /* TW: Addtional IOCTL for communication sisfb <> X driver */
+@@ -284,12 +312,16 @@
+
+ unsigned char sisfb_lcda;
+
+- char reserved[235]; /* for future use */
++ unsigned long sisfb_vbflags;
++ unsigned long sisfb_currentvbflags;
++
++ int sisfb_scalelcd;
++ unsigned long sisfb_specialtiming;
++
++ char reserved[219]; /* for future use */
+ };
+ #endif
+
+-#ifndef WIN2000
+-#ifndef WINCE_HEADER
+ #ifndef BUS_DATA_TYPE
+ typedef enum _BUS_DATA_TYPE {
+ ConfigurationSpaceUndefined = -1,
+@@ -307,7 +339,6 @@
+ MaximumBusDataType
+ } BUS_DATA_TYPE, *PBUS_DATA_TYPE;
+ #endif
+-#endif /* WINCE_HEADER */
+
+ #ifndef PCI_TYPE0_ADDRESSES
+ #define PCI_TYPE0_ADDRESSES 6
+@@ -317,7 +348,6 @@
+ #define PCI_TYPE1_ADDRESSES 2
+ #endif
+
+-#ifndef WINCE_HEADER
+ #ifndef PCI_COMMON_CONFIG
+ typedef struct _PCI_COMMON_CONFIG {
+ USHORT VendorID; /* (ro) */
+@@ -355,7 +385,6 @@
+
+ } PCI_COMMON_CONFIG, *PPCI_COMMON_CONFIG;
+ #endif
+-#endif /* WINCE_HEADER */
+
+ #ifndef FIELD_OFFSET
+ #define FIELD_OFFSET(type, field) ((LONG)&(((type *)0)->field))
+@@ -364,6 +393,6 @@
+ #ifndef PCI_COMMON_HDR_LENGTH
+ #define PCI_COMMON_HDR_LENGTH (FIELD_OFFSET (PCI_COMMON_CONFIG, DeviceSpecific))
+ #endif
+-#endif
+
+ #endif
++
+Index: linux-2.6.0-test5/drivers/video/sis/vstruct.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/sis/vstruct.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/sis/vstruct.h 2003-09-27 11:38:35.602116040 +0800
+@@ -1,3 +1,37 @@
++/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/vstruct.h,v 1.0 2001/06/15 21:23:00 dawes Exp $ */
++/*
++ * General structure definitions for universal mode switching modules
++ *
++ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
++ *
++ * If distributed as part of the linux kernel, the contents of this file
++ * is entirely covered by the GPL.
++ *
++ * Otherwise, the following terms apply:
++ *
++ * Permission to use, copy, modify, distribute, and sell this software and its
++ * documentation for any purpose is hereby granted without fee, provided that
++ * the above copyright notice appear in all copies and that both that
++ * copyright notice and this permission notice appear in supporting
++ * documentation, and that the name of the copyright holder not be used in
++ * advertising or publicity pertaining to distribution of the software without
++ * specific, written prior permission. The copyright holder makes no representations
++ * about the suitability of this software for any purpose. It is provided
++ * "as is" without express or implied warranty.
++ *
++ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
++ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
++ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
++ * PERFORMANCE OF THIS SOFTWARE.
++ *
++ * Authors: Thomas Winischhofer <thomas@winischhofer.net>
++ * Silicon Integrated Systems
++ *
++ */
++
+ #ifdef _INIT_
+ #define EXTERN
+ #else
+@@ -58,7 +92,6 @@
+ UCHAR CR[15];
+ } SiS_LVDSCRT1DataStruct;
+
+-/*add for LCDA*/
+ typedef struct _SiS_LCDACRT1DataStruct
+ {
+ UCHAR CR[17];
+@@ -111,9 +144,7 @@
+ UCHAR Ext_ModeID;
+ USHORT Ext_ModeFlag;
+ USHORT Ext_ModeInfo;
+- USHORT Ext_Point;
+ USHORT Ext_VESAID;
+- UCHAR Ext_VESAMEMSize;
+ UCHAR Ext_RESINFO;
+ UCHAR VB_ExtTVFlickerIndex;
+ UCHAR VB_ExtTVEdgeIndex;
+@@ -130,7 +161,6 @@
+ UCHAR ModeID;
+ USHORT XRes;
+ USHORT YRes;
+- USHORT ROM_OFFSET;
+ } SiS_Ext2Struct;
+
+ typedef struct _SiS_Part2PortTblStruct
+@@ -183,6 +213,15 @@
+
+ typedef UCHAR DRAM4Type[4];
+
++/* Defines for SiS_Customt */
++#define CUT_NONE 0
++#define CUT_FORCENONE 1
++#define CUT_BARCO1366 2
++#define CUT_BARCO1024 3
++#define CUT_COMPAQ1280 4
++#define CUT_COMPAQ12802 5
++#define CUT_PANEL848 6
++
+ typedef struct _SiS_Private
+ {
+ #ifdef LINUX_KERNEL
+@@ -198,25 +237,34 @@
+ USHORT SiS_P3c7;
+ USHORT SiS_P3c8;
+ USHORT SiS_P3c9;
++ USHORT SiS_P3cb;
++ USHORT SiS_P3cd;
+ USHORT SiS_P3da;
+ USHORT SiS_Part1Port;
+ USHORT SiS_Part2Port;
+ USHORT SiS_Part3Port;
+ USHORT SiS_Part4Port;
+ USHORT SiS_Part5Port;
++ USHORT SiS_VidCapt;
++ USHORT SiS_VidPlay;
+ USHORT SiS_IF_DEF_LVDS;
+ USHORT SiS_IF_DEF_TRUMPION;
+ USHORT SiS_IF_DEF_DSTN;
+ USHORT SiS_IF_DEF_FSTN;
+ USHORT SiS_IF_DEF_CH70xx;
+ USHORT SiS_IF_DEF_HiVision;
++ USHORT SiS_SysFlags;
+ UCHAR SiS_VGAINFO;
++#ifndef LINUX_KERNEL
++ USHORT SiS_CP1, SiS_CP2, SiS_CP3, SiS_CP4;
++#endif
+ BOOLEAN SiS_UseROM;
+ int SiS_CHOverScan;
+ BOOLEAN SiS_CHSOverScan;
+ BOOLEAN SiS_ChSW;
+ BOOLEAN SiS_UseLCDA;
+ int SiS_UseOEM;
++ ULONG SiS_CustomT;
+ USHORT SiS_Backup70xx;
+ USHORT SiS_CRT1Mode;
+ USHORT SiS_flag_clearbuffer;
+@@ -270,15 +318,18 @@
+ USHORT SiS_Panel1280x768;
+ USHORT SiS_Panel1024x600;
+ USHORT SiS_Panel640x480;
++ USHORT SiS_Panel640x480_2;
++ USHORT SiS_Panel640x480_3;
+ USHORT SiS_Panel1152x864;
++ USHORT SiS_PanelCustom;
++ USHORT SiS_PanelBarco1366;
+ USHORT SiS_PanelMax;
+ USHORT SiS_PanelMinLVDS;
+ USHORT SiS_PanelMin301;
+ USHORT SiS_ChrontelInit;
+
+- /* Pointers: */
+ const SiS_StStruct *SiS_SModeIDTable;
+- const SiS_StandTableStruct *SiS_StandTable;
++ SiS_StandTableStruct *SiS_StandTable;
+ const SiS_ExtStruct *SiS_EModeIDTable;
+ const SiS_Ext2Struct *SiS_RefIndex;
+ const SiS_VBModeStruct *SiS_VBModeIDTable;
+@@ -316,7 +367,7 @@
+ const USHORT *pSiS_RGBSenseData;
+ const USHORT *pSiS_VideoSenseData;
+ const USHORT *pSiS_YCSenseData;
+- const USHORT *pSiS_RGBSenseData2; /*301b*/
++ const USHORT *pSiS_RGBSenseData2;
+ const USHORT *pSiS_VideoSenseData2;
+ const USHORT *pSiS_YCSenseData2;
+ #endif
+@@ -340,15 +391,18 @@
+ const SiS_LCDDataStruct *SiS_LCD1280x960Data;
+ const SiS_LCDDataStruct *SiS_NoScaleData1400x1050;
+ const SiS_LCDDataStruct *SiS_NoScaleData1600x1200;
++ const SiS_LCDDataStruct *SiS_NoScaleData1280x768;
+ const SiS_LCDDataStruct *SiS_StLCD1400x1050Data;
+ const SiS_LCDDataStruct *SiS_StLCD1600x1200Data;
++ const SiS_LCDDataStruct *SiS_StLCD1280x768Data;
+ const SiS_LCDDataStruct *SiS_ExtLCD1400x1050Data;
+ const SiS_LCDDataStruct *SiS_ExtLCD1600x1200Data;
++ const SiS_LCDDataStruct *SiS_ExtLCD1280x768Data;
++ const SiS_LCDDataStruct *SiS_NoScaleData;
+ const SiS_TVDataStruct *SiS_StPALData;
+ const SiS_TVDataStruct *SiS_ExtPALData;
+ const SiS_TVDataStruct *SiS_StNTSCData;
+ const SiS_TVDataStruct *SiS_ExtNTSCData;
+-/* const SiS_TVDataStruct *SiS_St1HiTVData; */
+ const SiS_TVDataStruct *SiS_St2HiTVData;
+ const SiS_TVDataStruct *SiS_ExtHiTVData;
+ const UCHAR *SiS_NTSCTiming;
+@@ -381,12 +435,19 @@
+ const SiS_LVDSDataStruct *SiS_LVDS1152x768Data_1;
+ const SiS_LVDSDataStruct *SiS_LVDS1152x768Data_2;
+ const SiS_LVDSDataStruct *SiS_LVDS640x480Data_1;
++ const SiS_LVDSDataStruct *SiS_LVDS640x480Data_2;
+ const SiS_LVDSDataStruct *SiS_LVDS320x480Data_1;
+ const SiS_LVDSDataStruct *SiS_LCDA1400x1050Data_1;
+ const SiS_LVDSDataStruct *SiS_LCDA1400x1050Data_2;
+ const SiS_LVDSDataStruct *SiS_LCDA1600x1200Data_1;
+ const SiS_LVDSDataStruct *SiS_LCDA1600x1200Data_2;
+ const SiS_LVDSDataStruct *SiS_LVDSXXXxXXXData_1;
++ const SiS_LVDSDataStruct *SiS_LVDSBARCO1366Data_1;
++ const SiS_LVDSDataStruct *SiS_LVDSBARCO1366Data_2;
++ const SiS_LVDSDataStruct *SiS_LVDSBARCO1024Data_1;
++ const SiS_LVDSDataStruct *SiS_LVDSBARCO1024Data_2;
++ const SiS_LVDSDataStruct *SiS_LVDS848x480Data_1;
++ const SiS_LVDSDataStruct *SiS_LVDS848x480Data_2;
+ const SiS_LVDSDataStruct *SiS_CHTVUNTSCData;
+ const SiS_LVDSDataStruct *SiS_CHTVONTSCData;
+ const SiS_LVDSDataStruct *SiS_CHTVUPALData;
+@@ -478,6 +539,12 @@
+ const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11600x1200_2_H;
+ const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1XXXxXXX_1;
+ const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1XXXxXXX_1_H;
++ const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1640x480_1;
++ const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1640x480_1_H;
++ const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1640x480_2;
++ const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1640x480_2_H;
++ const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1640x480_3;
++ const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1640x480_3_H;
+ const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1UNTSC;
+ const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1ONTSC;
+ const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1UPAL;
+@@ -507,7 +574,6 @@
+ const SiS_LCDACRT1DataStruct *SiS_LCDACRT11400x1050_2_H;
+ const SiS_LCDACRT1DataStruct *SiS_LCDACRT11600x1200_2_H;
+
+- /* TW: New for 650/301LV */
+ const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_1;
+ const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_1;
+ const SiS_Part2PortTblStruct *SiS_CRT2Part2_1400x1050_1;
+@@ -539,6 +605,9 @@
+ const UCHAR *SiS_CHTVVCLKUPALN;
+ const UCHAR *SiS_CHTVVCLKOPALN;
+ const UCHAR *SiS_CHTVVCLKSOPAL;
++
++ USHORT PanelXRes;
++ USHORT PanelYRes;
+
+ BOOLEAN UseCustomMode;
+ BOOLEAN CRT1UsesCustomMode;
+@@ -560,8 +629,11 @@
+ UCHAR CSR2B;
+ UCHAR CSR2C;
+ USHORT CSRClock;
++ USHORT CSRClock_CRT1;
+ USHORT CModeFlag;
++ USHORT CModeFlag_CRT1;
+ USHORT CInfoFlag;
++
+ BOOLEAN SiS_CHPALM;
+ BOOLEAN SiS_CHPALN;
+
+@@ -578,7 +650,21 @@
+ UCHAR Backup_1c;
+ UCHAR Backup_1d;
+
+- int UsePanelScaler;
++ int UsePanelScaler;
++
++ USHORT CP_Vendor, CP_Product;
++ BOOLEAN CP_HaveCustomData;
++ int CP_PreferredX, CP_PreferredY;
++ int CP_MaxX, CP_MaxY, CP_MaxClock;
++ int CP_HDisplay[7], CP_VDisplay[7]; /* For Custom LCD panel dimensions */
++ int CP_HTotal[7], CP_VTotal[7];
++ int CP_HSyncStart[7], CP_VSyncStart[7];
++ int CP_HSyncEnd[7], CP_VSyncEnd[7];
++ int CP_HBlankStart[7], CP_VBlankStart[7];
++ int CP_HBlankEnd[7], CP_VBlankEnd[7];
++ int CP_Clock[7];
++ BOOLEAN CP_DataValid[7];
++ BOOLEAN CP_HSync_P[7], CP_VSync_P[7], CP_SyncValid[7];
+ } SiS_Private;
+
+ #endif
+Index: linux-2.6.0-test5/drivers/video/skeletonfb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/skeletonfb.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/skeletonfb.c 2003-09-27 11:38:35.705100384 +0800
+@@ -1,7 +1,7 @@
+ /*
+ * linux/drivers/video/skeletonfb.c -- Skeleton for a frame buffer device
+ *
+- * Modified to new api Jan 2001 by James Simmons (jsimmons@transvirtual.com)
++ * Modified to new api Jan 2001 by James Simmons (jsimmons@infradead.org)
+ *
+ * Created 28 Dec 1997 by Geert Uytterhoeven
+ *
+@@ -469,15 +469,71 @@
+ int xxxfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
+ {
+ /*
+- * @set: Which fields we are altering in struct fb_cursor
++ * @set: Which fields we are altering in struct fb_cursor
+ * @enable: Disable or enable the cursor
+- * @rop: The bit operation we want to do.
+- * @mask: This is the cursor mask bitmap.
+- * @dest: A image of the area we are going to display the cursor.
+- * Used internally by the driver.
+- * @hot: The hot spot.
+- * @image: The actual data for the cursor image.
+- */
++ * @rop: The bit operation we want to do.
++ * @hot: The hot spot.
++ * @image: The actual data for the cursor image.
++ * @mask: This is the cursor mask bitmap.
++ */
++
++ /* Disable hardware cursor. We don't want to display the cursor
++ while changing it. Note we use the enable and rop fields in
++ struct fb_cursor that is apart of struct fb_info. Not the
++ cursor data passed in from userland. */
++
++ if (cursor->set & FB_CUR_SETHOT) {
++ info->cursor.hot = cursor->hot;
++ /* Set the hardware cursor's hot spot */
++ }
++
++ if (cursor->set & FB_CUR_SETPOS) {
++ info->cursor.image.dx = cursor->image.dx;
++ info->cursor.image.dy = cursor->image.dy;
++ /* Set the hardware cursor's position */
++ }
++
++ if (cursor->set & FB_CUR_SETSIZE) {
++ info->cursor.image.height = cursor->image.height;
++ info->cursor.image.width = cursor->image.width;
++ /* Set the hardware cursor's size */
++ }
++
++ if (cursor->set & FB_CUR_SETCMAP) {
++ if (cursor->image.depth == 1) {
++ info->cursor.image.fg_color = cursor->image.fg_color;
++ info->cursor.image.bg_color = cursor->image.bg_color;
++ } else {
++ if (cursor->image.cmap.len)
++ fb_copy_cmap(&cursor->image.cmap, &info->cursor.image.cmap, 0);
++ }
++ info->curosr.image.depth = cursor->image.depth;
++
++ /* Set the hardware cursor's color map */
++ }
++
++ /*
++ * Set the cursor shape. The two pieces needed to create
++ * the final image is mask and image.data. The mask is
++ * combined with image.data according to the rop field.
++ */
++ if (cursor->set & FB_CUR_SETSHAPE) {
++ switch (info->cursor.rop) {
++ case ROP_XOR:
++ /* ... */
++ break;
++ case ROP_COPY:
++ default:
++ /* ... */
++ break;
++ }
++ /* ... */
++ }
++
++ if (info->cursor.enable) {
++ /* Now we turn the hardware cursor on */
++ }
++ return 0;
+ }
+
+ /**
+Index: linux-2.6.0-test5/drivers/video/softcursor.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/softcursor.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/softcursor.c 2003-09-27 11:38:35.726097192 +0800
+@@ -21,8 +21,13 @@
+ {
+ unsigned int scan_align = info->pixmap.scan_align - 1;
+ unsigned int buf_align = info->pixmap.buf_align - 1;
+- unsigned int i, size, dsize, s_pitch, d_pitch;
+- u8 *dst, src[64];
++ u8 *dst = (u8 *) info->cursor.image.data;
++ unsigned int i, size, pitch;
++
++ pitch = ((info->cursor.image.width + 7) >> 3) + scan_align;
++ pitch &= ~scan_align;
++ size = pitch * info->cursor.image.height + buf_align;
++ size &= ~buf_align;
+
+ if (cursor->set & FB_CUR_SETSIZE) {
+ info->cursor.image.height = cursor->image.height;
+@@ -48,34 +53,33 @@
+ info->cursor.image.depth = cursor->image.depth;
+ }
+
+- s_pitch = (info->cursor.image.width + 7) >> 3;
+- dsize = s_pitch * info->cursor.image.height;
+- d_pitch = (s_pitch + scan_align) & ~scan_align;
+- size = d_pitch * info->cursor.image.height + buf_align;
+- size &= ~buf_align;
+- dst = info->pixmap.addr + fb_get_buffer_offset(info, size);
+-
+- if (info->cursor.enable) {
++ if (cursor->set & FB_CUR_SETSHAPE) {
+ switch (info->cursor.rop) {
+ case ROP_XOR:
+- for (i = 0; i < dsize; i++)
+- src[i] = cursor->image.data[i] ^ info->cursor.mask[i];
++ for (i = 0; i < size; i++)
++ dst[i] ^= info->cursor.mask[i];
+ break;
+ case ROP_COPY:
+ default:
+- for (i = 0; i < dsize; i++)
+- src[i] = cursor->image.data[i] & info->cursor.mask[i];
++ for (i = 0; i < size; i++)
++ dst[i] &= info->cursor.mask[i];
+ break;
+ }
+- } else
+- memcpy(src, cursor->image.data, dsize);
+-
+- move_buf_aligned(info, dst, src, d_pitch, s_pitch, info->cursor.image.height);
+- info->cursor.image.data = dst;
++ }
+
+- info->fbops->fb_imageblit(info, &info->cursor.image);
+- atomic_dec(&info->pixmap.count);
+- smp_mb__after_atomic_dec();
++ if (!info->cursor.enable) {
++ for (i = 0; i < size; i++)
++ dst[i] ^= info->cursor.mask[i];
++ }
++
++ if (info->cursor.image.data)
++ info->fbops->fb_imageblit(info, &info->cursor.image);
++
++ if (!info->cursor.enable) {
++ for (i = 0; i < size; i++)
++ dst[i] ^= info->cursor.mask[i];
++ }
++
+ return 0;
+ }
+
+Index: linux-2.6.0-test5/drivers/video/valkyriefb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/valkyriefb.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/valkyriefb.c 2003-09-27 11:38:35.756092632 +0800
+@@ -51,7 +51,6 @@
+ #include <linux/delay.h>
+ #include <linux/interrupt.h>
+ #include <linux/fb.h>
+-#include <linux/selection.h>
+ #include <linux/init.h>
+ #include <linux/pci.h>
+ #include <linux/nvram.h>
+Index: linux-2.6.0-test5/fs/adfs/super.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/adfs/super.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/adfs/super.c 2003-09-27 11:38:35.810084424 +0800
+@@ -18,6 +18,7 @@
+ #include <linux/init.h>
+ #include <linux/buffer_head.h>
+ #include <linux/vfs.h>
++#include <linux/parser.h>
+
+ #include <asm/bitops.h>
+ #include <asm/uaccess.h>
+@@ -133,50 +134,56 @@
+ sb->s_fs_info = NULL;
+ }
+
++enum {Opt_uid, Opt_gid, Opt_ownmask, Opt_othmask, Opt_err};
++
++static match_table_t tokens = {
++ {Opt_uid, "uid=%u"},
++ {Opt_gid, "gid=%u"},
++ {Opt_ownmask, "ownmask=%o"},
++ {Opt_othmask, "othmask=%o"},
++ {Opt_err, NULL}
++};
++
+ static int parse_options(struct super_block *sb, char *options)
+ {
+- char *value, *opt;
++ char *p;
+ struct adfs_sb_info *asb = ADFS_SB(sb);
++ int option;
+
+ if (!options)
+ return 0;
+
+- while ((opt = strsep(&options, ",")) != NULL) {
+- if (!*opt)
++ while ((p = strsep(&options, ",")) != NULL) {
++ substring_t args[MAX_OPT_ARGS];
++ int token;
++ if (!*p)
+ continue;
+- value = strchr(opt, '=');
+- if (value)
+- *value++ = '\0';
+
+- if (!strcmp(opt, "uid")) { /* owner of all files */
+- if (!value || !*value)
+- return -EINVAL;
+- asb->s_uid = simple_strtoul(value, &value, 0);
+- if (*value)
+- return -EINVAL;
+- } else
+- if (!strcmp(opt, "gid")) { /* group owner of all files */
+- if (!value || !*value)
+- return -EINVAL;
+- asb->s_gid = simple_strtoul(value, &value, 0);
+- if (*value)
+- return -EINVAL;
+- } else
+- if (!strcmp(opt, "ownmask")) { /* owner permission mask */
+- if (!value || !*value)
++ token = match_token(p, tokens, args);
++ switch (token) {
++ case Opt_uid:
++ if (match_int(args, &option))
+ return -EINVAL;
+- asb->s_owner_mask = simple_strtoul(value, &value, 8);
+- if (*value)
++ asb->s_uid = option;
++ break;
++ case Opt_gid:
++ if (match_int(args, &option))
+ return -EINVAL;
+- } else
+- if (!strcmp(opt, "othmask")) { /* others permission mask */
+- if (!value || !*value)
++ asb->s_gid = option;
++ break;
++ case Opt_ownmask:
++ if (match_octal(args, &option))
+ return -EINVAL;
+- asb->s_other_mask = simple_strtoul(value, &value, 8);
+- if (*value)
++ asb->s_owner_mask = option;
++ break;
++ case Opt_othmask:
++ if (match_octal(args, &option))
+ return -EINVAL;
+- } else { /* eh? say again. */
+- printk("ADFS-fs: unrecognised mount option %s\n", opt);
++ asb->s_other_mask = option;
++ break;
++ default:
++ printk("ADFS-fs: unrecognised mount option \"%s\" "
++ "or missing value\n", p);
+ return -EINVAL;
+ }
+ }
+Index: linux-2.6.0-test5/fs/affs/super.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/affs/super.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/affs/super.c 2003-09-27 11:38:35.856077432 +0800
+@@ -28,6 +28,7 @@
+ #include <linux/smp_lock.h>
+ #include <linux/buffer_head.h>
+ #include <linux/vfs.h>
++#include <linux/parser.h>
+ #include <asm/system.h>
+ #include <asm/uaccess.h>
+
+@@ -142,12 +143,37 @@
+ .remount_fs = affs_remount,
+ };
+
++enum {
++ Opt_bs, Opt_mode, Opt_mufs, Opt_prefix, Opt_protect,
++ Opt_reserved, Opt_root, Opt_setgid, Opt_setuid,
++ Opt_verbose, Opt_volume, Opt_ignore, Opt_err,
++};
++
++static match_table_t tokens = {
++ {Opt_bs, "bs=%d"},
++ {Opt_mode, "mode=%o"},
++ {Opt_mufs, "mufs"},
++ {Opt_prefix, "prefix=%s"},
++ {Opt_protect, "protect"},
++ {Opt_reserved, "reserved=%d"},
++ {Opt_root, "root=%d"},
++ {Opt_setgid, "setgid=%d"},
++ {Opt_setuid, "setuid=%d"},
++ {Opt_verbose, "verbose"},
++ {Opt_volume, "volume=%s"},
++ {Opt_ignore, "grpquota"},
++ {Opt_ignore, "noquota"},
++ {Opt_ignore, "quota"},
++ {Opt_ignore, "usrquota"},
++ {Opt_err, NULL},
++};
++
+ static int
+ parse_options(char *options, uid_t *uid, gid_t *gid, int *mode, int *reserved, s32 *root,
+ int *blocksize, char **prefix, char *volume, unsigned long *mount_opts)
+ {
+- char *this_char, *value, *optn;
+- int f;
++ char *p;
++ substring_t args[MAX_OPT_ARGS];
+
+ /* Fill in defaults */
+
+@@ -161,109 +187,85 @@
+ *mount_opts = 0;
+ if (!options)
+ return 1;
+- while ((this_char = strsep(&options, ",")) != NULL) {
+- if (!*this_char)
++
++ while ((p = strsep(&options, ",")) != NULL) {
++ int token, n, option;
++ if (!*p)
+ continue;
+- f = 0;
+- if ((value = strchr(this_char,'=')) != NULL)
+- *value++ = 0;
+- if ((optn = "protect") && !strcmp(this_char, optn)) {
+- if (value)
+- goto out_inv_arg;
+- *mount_opts |= SF_IMMUTABLE;
+- } else if ((optn = "verbose") && !strcmp(this_char, optn)) {
+- if (value)
+- goto out_inv_arg;
+- *mount_opts |= SF_VERBOSE;
+- } else if ((optn = "mufs") && !strcmp(this_char, optn)) {
+- if (value)
+- goto out_inv_arg;
+- *mount_opts |= SF_MUFS;
+- } else if ((f = !strcmp(this_char,"setuid")) || !strcmp(this_char,"setgid")) {
+- if (value) {
+- if (!*value) {
+- printk("AFFS: Argument for set[ug]id option missing\n");
+- return 0;
+- } else {
+- (f ? *uid : *gid) = simple_strtoul(value,&value,0);
+- if (*value) {
+- printk("AFFS: Bad set[ug]id argument\n");
+- return 0;
+- }
+- *mount_opts |= f ? SF_SETUID : SF_SETGID;
+- }
++
++ token = match_token(p, tokens, args);
++ switch (token) {
++ case Opt_bs:
++ if (match_int(&args[0], &n))
++ return -EINVAL;
++ if (n != 512 && n != 1024 && n != 2048
++ && n != 4096) {
++ printk ("AFFS: Invalid blocksize (512, 1024, 2048, 4096 allowed)\n");
++ return 0;
+ }
+- } else if (!strcmp(this_char,"prefix")) {
+- optn = "prefix";
+- if (!value || !*value)
+- goto out_no_arg;
++ *blocksize = n;
++ break;
++ case Opt_mode:
++ if (match_octal(&args[0], &option))
++ return 1;
++ *mode = option & 0777;
++ *mount_opts |= SF_SETMODE;
++ break;
++ case Opt_mufs:
++ *mount_opts |= SF_MUFS;
++ break;
++ case Opt_prefix:
+ if (*prefix) { /* Free any previous prefix */
+ kfree(*prefix);
+ *prefix = NULL;
+ }
+- *prefix = kmalloc(strlen(value) + 1,GFP_KERNEL);
++ *prefix = match_strdup(&args[0]);
+ if (!*prefix)
+ return 0;
+- strcpy(*prefix,value);
+ *mount_opts |= SF_PREFIX;
+- } else if (!strcmp(this_char,"volume")) {
+- optn = "volume";
+- if (!value || !*value)
+- goto out_no_arg;
+- strlcpy(volume,value,31);
+- } else if (!strcmp(this_char,"mode")) {
+- optn = "mode";
+- if (!value || !*value)
+- goto out_no_arg;
+- *mode = simple_strtoul(value,&value,8) & 0777;
+- if (*value)
+- return 0;
+- *mount_opts |= SF_SETMODE;
+- } else if (!strcmp(this_char,"reserved")) {
+- optn = "reserved";
+- if (!value || !*value)
+- goto out_no_arg;
+- *reserved = simple_strtoul(value,&value,0);
+- if (*value)
+- return 0;
+- } else if (!strcmp(this_char,"root")) {
+- optn = "root";
+- if (!value || !*value)
+- goto out_no_arg;
+- *root = simple_strtoul(value,&value,0);
+- if (*value)
+- return 0;
+- } else if (!strcmp(this_char,"bs")) {
+- optn = "bs";
+- if (!value || !*value)
+- goto out_no_arg;
+- *blocksize = simple_strtoul(value,&value,0);
+- if (*value)
+- return 0;
+- if (*blocksize != 512 && *blocksize != 1024 && *blocksize != 2048
+- && *blocksize != 4096) {
+- printk ("AFFS: Invalid blocksize (512, 1024, 2048, 4096 allowed)\n");
+- return 0;
+- }
+- } else if (!strcmp (this_char, "grpquota")
+- || !strcmp (this_char, "noquota")
+- || !strcmp (this_char, "quota")
+- || !strcmp (this_char, "usrquota"))
+- /* Silently ignore the quota options */
+- ;
+- else {
+- printk("AFFS: Unrecognized mount option %s\n", this_char);
++ break;
++ case Opt_protect:
++ *mount_opts |= SF_IMMUTABLE;
++ break;
++ case Opt_reserved:
++ if (match_int(&args[0], reserved))
++ return 1;
++ break;
++ case Opt_root:
++ if (match_int(&args[0], root))
++ return 1;
++ break;
++ case Opt_setgid:
++ if (match_int(&args[0], &option))
++ return 1;
++ *gid = option;
++ *mount_opts |= SF_SETGID;
++ break;
++ case Opt_setuid:
++ if (match_int(&args[0], &option))
++ return -EINVAL;
++ *uid = option;
++ *mount_opts |= SF_SETUID;
++ break;
++ case Opt_verbose:
++ *mount_opts |= SF_VERBOSE;
++ break;
++ case Opt_volume: {
++ char *vol = match_strdup(&args[0]);
++ strlcpy(volume, vol, 32);
++ kfree(vol);
++ break;
++ }
++ case Opt_ignore:
++ /* Silently ignore the quota options */
++ break;
++ default:
++ printk("AFFS: Unrecognized mount option \"%s\" "
++ "or missing value\n", p);
+ return 0;
+ }
+ }
+ return 1;
+-
+-out_no_arg:
+- printk("AFFS: The %s option requires an argument\n", optn);
+- return 0;
+-out_inv_arg:
+- printk("AFFS: Option %s does not take an argument\n", optn);
+- return 0;
+ }
+
+ /* This function definitely needs to be split up. Some fine day I'll
+Index: linux-2.6.0-test5/fs/afs/cache.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/cache.h 2003-09-27 11:38:18.465721168 +0800
++++ linux-2.6.0-test5/fs/afs/cache.h 2003-09-27 11:38:35.857077280 +0800
+@@ -0,0 +1,27 @@
++/* cache.h: AFS local cache management interface
++ *
++ * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
++ * Written by David Howells (dhowells@redhat.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.
++ */
++
++#ifndef _LINUX_AFS_CACHE_H
++#define _LINUX_AFS_CACHE_H
++
++#undef AFS_CACHING_SUPPORT
++
++#include <linux/mm.h>
++#ifdef AFS_CACHING_SUPPORT
++#include <linux/cachefs.h>
++#endif
++#include "types.h"
++
++#ifdef __KERNEL__
++
++#endif /* __KERNEL__ */
++
++#endif /* _LINUX_AFS_CACHE_H */
+Index: linux-2.6.0-test5/fs/afs/callback.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/callback.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/callback.c 2003-09-27 11:38:35.918068008 +0800
+@@ -68,7 +68,7 @@
+ spin_unlock(&vnode->lock);
+
+ iput(inode);
+- if (release) afs_put_server(server);
++ afs_put_server(server);
+
+ spin_lock(&server->cb_lock);
+ }
+Index: linux-2.6.0-test5/fs/afs/cell.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/cell.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/cell.c 2003-09-27 11:38:35.975059344 +0800
+@@ -36,6 +36,19 @@
+ MODULE_PARM(rootcell,"s");
+ MODULE_PARM_DESC(rootcell,"root AFS cell name and VL server IP addr list");
+
++#ifdef AFS_CACHING_SUPPORT
++static cachefs_match_val_t afs_cell_cache_match(void *target, const void *entry);
++static void afs_cell_cache_update(void *source, void *entry);
++
++struct cachefs_index_def afs_cache_cell_index_def = {
++ .name = "cell_ix",
++ .data_size = sizeof(afs_cell_t),
++ .keys[0] = { CACHEFS_INDEX_KEYS_ASCIIZ, 64 },
++ .match = afs_cell_cache_match,
++ .update = afs_cell_cache_update,
++};
++#endif
++
+ /*****************************************************************************/
+ /*
+ * create a cell record
+@@ -65,7 +78,6 @@
+ atomic_set(&cell->usage,0);
+
+ INIT_LIST_HEAD(&cell->link);
+- INIT_LIST_HEAD(&cell->caches);
+
+ rwlock_init(&cell->sv_lock);
+ INIT_LIST_HEAD(&cell->sv_list);
+@@ -96,7 +108,7 @@
+ cell->vl_addrs[cell->vl_naddrs++].s_addr =
+ htonl((a<<24)|(b<<16)|(c<<8)|d);
+
+- if (cell->vl_naddrs>=16)
++ if (cell->vl_naddrs >= AFS_CELL_MAX_ADDRS)
+ break;
+
+ } while(vllist=next, vllist);
+@@ -106,6 +118,14 @@
+ if (ret<0)
+ goto error;
+
++#ifdef AFS_CACHING_SUPPORT
++ /* put it up for caching */
++ cachefs_acquire_cookie(afs_cache_netfs.primary_index,
++ &afs_vlocation_cache_index_def,
++ cell,
++ &cell->cache);
++#endif
++
+ /* add to the cell lists */
+ write_lock(&afs_cells_lock);
+ list_add_tail(&cell->link,&afs_cells);
+@@ -166,36 +186,45 @@
+ /*
+ * lookup a cell record
+ */
+-int afs_cell_lookup(const char *name, afs_cell_t **_cell)
++int afs_cell_lookup(const char *name, unsigned namesz, struct afs_cell **_cell)
+ {
+ struct list_head *_p;
+ afs_cell_t *cell;
++ int ret;
+
+- _enter("\"%s\",",name?name:"*thiscell*");
++ _enter("\"%*.*s\",", namesz, namesz, name ? name : "");
+
+- cell = afs_cell_root;
++ *_cell = NULL;
+
+ if (name) {
+ /* if the cell was named, look for it in the cell record list */
++ ret = -ENOENT;
+ cell = NULL;
+ read_lock(&afs_cells_lock);
+
+ list_for_each(_p,&afs_cells) {
+- cell = list_entry(_p,afs_cell_t,link);
+- if (strcmp(cell->name,name)==0)
++ cell = list_entry(_p, struct afs_cell, link);
++ if (strncmp(cell->name, name, namesz) == 0) {
++ afs_get_cell(cell);
+ break;
++ }
+ cell = NULL;
+ }
+
+ read_unlock(&afs_cells_lock);
+- }
+
+- if (cell)
++ if (cell)
++ ret = 0;
++ }
++ else {
++ cell = afs_cell_root;
+ afs_get_cell(cell);
++ ret = 0;
++ }
+
+ *_cell = cell;
+- _leave(" = %d (%p)",cell?0:-ENOENT,cell);
+- return cell ? 0 : -ENOENT;
++ _leave(" = %d (%p)", ret, cell);
++ return ret;
+
+ } /* end afs_cell_lookup() */
+
+@@ -211,8 +240,8 @@
+
+ cell = *_cell;
+ if (cell && !list_empty(&cell->link))
+- atomic_inc(&cell->usage);
+- else
++ afs_get_cell(cell);
++ else
+ cell = NULL;
+
+ write_unlock(&afs_cells_lock);
+@@ -226,6 +255,9 @@
+ */
+ void afs_put_cell(afs_cell_t *cell)
+ {
++ if (!cell)
++ return;
++
+ _enter("%p{%d,%s}",cell,atomic_read(&cell->usage),cell->name);
+
+ /* sanity check */
+@@ -278,6 +310,10 @@
+ list_del_init(&cell->proc_link);
+ up_write(&afs_proc_cells_sem);
+
++#ifdef AFS_CACHING_SUPPORT
++ cachefs_relinquish_cookie(cell->cache,0);
++#endif
++
+ up_write(&afs_cells_sem);
+
+ if (!list_empty(&cell->sv_list)) BUG();
+@@ -377,8 +413,7 @@
+
+ _enter("");
+
+- if (afs_cell_root)
+- afs_put_cell(afs_cell_root);
++ afs_put_cell(afs_cell_root);
+
+ while (!list_empty(&afs_cells)) {
+ cell = NULL;
+@@ -450,3 +485,46 @@
+
+ _leave("");
+ } /* end afs_cell_purge() */
++
++/*****************************************************************************/
++/*
++ * match a cell record obtained from the cache
++ */
++#ifdef AFS_CACHING_SUPPORT
++static cachefs_match_val_t afs_cell_cache_match(void *target, const void *entry)
++{
++ const struct afs_cache_cell *ccell = entry;
++ struct afs_cell *cell = target;
++
++ _enter("{%s},{%s}", ccell->name, cell->name);
++
++ if (strncmp(ccell->name, cell->name, sizeof(ccell->name)) == 0) {
++ _leave(" = SUCCESS");
++ return CACHEFS_MATCH_SUCCESS;
++ }
++
++ _leave(" = FAILED");
++ return CACHEFS_MATCH_FAILED;
++} /* end afs_cell_cache_match() */
++#endif
++
++/*****************************************************************************/
++/*
++ * update a cell record in the cache
++ */
++#ifdef AFS_CACHING_SUPPORT
++static void afs_cell_cache_update(void *source, void *entry)
++{
++ struct afs_cache_cell *ccell = entry;
++ struct afs_cell *cell = source;
++
++ _enter("%p,%p", source, entry);
++
++ strncpy(ccell->name, cell->name, sizeof(ccell->name));
++
++ memcpy(ccell->vl_servers,
++ cell->vl_addrs,
++ min(sizeof(ccell->vl_servers), sizeof(cell->vl_addrs)));
++
++} /* end afs_cell_cache_update() */
++#endif
+Index: linux-2.6.0-test5/fs/afs/cell.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/cell.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/cell.h 2003-09-27 11:38:35.978058888 +0800
+@@ -13,11 +13,24 @@
+ #define _LINUX_AFS_CELL_H
+
+ #include "types.h"
++#include "cache.h"
++
++#define AFS_CELL_MAX_ADDRS 15
+
+ extern volatile int afs_cells_being_purged; /* T when cells are being purged by rmmod */
+
+ /*****************************************************************************/
+ /*
++ * entry in the cached cell catalogue
++ */
++struct afs_cache_cell
++{
++ char name[64]; /* cell name (padded with NULs) */
++ struct in_addr vl_servers[15]; /* cached cell VL servers */
++};
++
++/*****************************************************************************/
++/*
+ * AFS cell record
+ */
+ struct afs_cell
+@@ -26,7 +39,9 @@
+ struct list_head link; /* main cell list link */
+ struct list_head proc_link; /* /proc cell list link */
+ struct proc_dir_entry *proc_dir; /* /proc dir for this cell */
+- struct list_head caches; /* list of caches currently backing this cell */
++#ifdef AFS_CACHING_SUPPORT
++ struct cachefs_cookie *cache; /* caching cookie */
++#endif
+
+ /* server record management */
+ rwlock_t sv_lock; /* active server list lock */
+@@ -41,22 +56,22 @@
+ spinlock_t vl_gylock; /* graveyard lock */
+ unsigned short vl_naddrs; /* number of VL servers in addr list */
+ unsigned short vl_curr_svix; /* current server index */
+- struct in_addr vl_addrs[16]; /* cell VL server addresses */
++ struct in_addr vl_addrs[AFS_CELL_MAX_ADDRS]; /* cell VL server addresses */
+
+ char name[0]; /* cell name - must go last */
+ };
+
+ extern int afs_cell_init(void);
+
+-extern int afs_cell_create(const char *name, char *vllist, afs_cell_t **_cell);
++extern int afs_cell_create(const char *name, char *vllist, struct afs_cell **_cell);
+
+-extern int afs_cell_lookup(const char *name, afs_cell_t **_cell);
++extern int afs_cell_lookup(const char *name, unsigned nmsize, struct afs_cell **_cell);
+
+ #define afs_get_cell(C) do { atomic_inc(&(C)->usage); } while(0)
+
+-extern afs_cell_t *afs_get_cell_maybe(afs_cell_t **_cell);
++extern struct afs_cell *afs_get_cell_maybe(struct afs_cell **_cell);
+
+-extern void afs_put_cell(afs_cell_t *cell);
++extern void afs_put_cell(struct afs_cell *cell);
+
+ extern void afs_cell_purge(void);
+
+Index: linux-2.6.0-test5/fs/afs/cmservice.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/cmservice.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/cmservice.c 2003-09-27 11:38:35.982058280 +0800
+@@ -119,6 +119,7 @@
+ int die;
+
+ printk("kAFS: Started kafscmd %d\n",current->pid);
++
+ daemonize("kafscmd");
+
+ complete(&kafscmd_alive);
+@@ -293,15 +294,20 @@
+
+ down_write(&afscm_sem);
+ if (!afscm_usage) {
+- ret = kernel_thread(kafscmd,NULL,0);
+- if (ret<0)
++ ret = kernel_thread(kafscmd, NULL, 0);
++ if (ret < 0)
+ goto out;
+
+ wait_for_completion(&kafscmd_alive);
+
+- ret = rxrpc_add_service(afs_transport,&AFSCM_service);
++ ret = rxrpc_add_service(afs_transport, &AFSCM_service);
+ if (ret<0)
+ goto kill;
++
++#ifdef AFS_AUTOMOUNT_SUPPORT
++ afs_kafstimod_add_timer(&afs_mntpt_expiry_timer,
++ afs_mntpt_expiry_timeout * HZ);
++#endif
+ }
+
+ afscm_usage++;
+@@ -330,17 +336,20 @@
+
+ down_write(&afscm_sem);
+
+- if (afscm_usage==0) BUG();
++ if (afscm_usage == 0) BUG();
+ afscm_usage--;
+
+- if (afscm_usage==0) {
++ if (afscm_usage == 0) {
+ /* don't want more incoming calls */
+- rxrpc_del_service(afs_transport,&AFSCM_service);
++ rxrpc_del_service(afs_transport, &AFSCM_service);
+
+ /* abort any calls I've still got open (the afscm_error() will dequeue them) */
+ spin_lock(&afscm_calls_lock);
+ while (!list_empty(&afscm_calls)) {
+- call = list_entry(afscm_calls.next,struct rxrpc_call,app_link);
++ call = list_entry(afscm_calls.next,
++ struct rxrpc_call,
++ app_link);
++
+ list_del_init(&call->app_link);
+ rxrpc_get_call(call);
+ spin_unlock(&afscm_calls_lock);
+@@ -348,7 +357,8 @@
+ rxrpc_call_abort(call,-ESRCH); /* abort, dequeue and put */
+
+ _debug("nuking active call %08x.%d",
+- ntohl(call->conn->conn_id),ntohl(call->call_id));
++ ntohl(call->conn->conn_id),
++ ntohl(call->call_id));
+ rxrpc_put_call(call);
+ rxrpc_put_call(call);
+
+@@ -376,6 +386,10 @@
+ spin_lock(&kafscmd_attention_lock);
+ }
+ spin_unlock(&kafscmd_attention_lock);
++
++#ifdef AFS_AUTOMOUNT_SUPPORT
++ afs_kafstimod_del_timer(&afs_mntpt_expiry_timer);
++#endif
+ }
+
+ up_write(&afscm_sem);
+@@ -490,7 +504,7 @@
+ if (ret<0)
+ rxrpc_call_abort(call,ret);
+
+- if (server) afs_put_server(server);
++ afs_put_server(server);
+
+ _leave(" = %d",ret);
+
+@@ -556,7 +570,7 @@
+ if (ret<0)
+ rxrpc_call_abort(call,ret);
+
+- if (server) afs_put_server(server);
++ afs_put_server(server);
+
+ _leave(" = %d",ret);
+
+@@ -622,7 +636,7 @@
+ if (ret<0)
+ rxrpc_call_abort(call,ret);
+
+- if (server) afs_put_server(server);
++ afs_put_server(server);
+
+ _leave(" = %d",ret);
+
+Index: linux-2.6.0-test5/fs/afs/dir.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/dir.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/dir.c 2003-09-27 11:38:35.993056608 +0800
+@@ -23,10 +23,11 @@
+ #include "super.h"
+ #include "internal.h"
+
+-static struct dentry *afs_dir_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *);
++static struct dentry *afs_dir_lookup(struct inode *dir, struct dentry *dentry,
++ struct nameidata *nd);
+ static int afs_dir_open(struct inode *inode, struct file *file);
+ static int afs_dir_readdir(struct file *file, void *dirent, filldir_t filldir);
+-static int afs_d_revalidate(struct dentry *dentry, struct nameidata *);
++static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd);
+ static int afs_d_delete(struct dentry *dentry);
+ static int afs_dir_lookup_filldir(void *_cookie, const char *name, int nlen, loff_t fpos,
+ ino_t ino, unsigned dtype);
+@@ -70,7 +71,7 @@
+ u8 name[16];
+ u8 overflow[4]; /* if any char of the name (inc NUL) reaches here, consume
+ * the next dirent too */
+- } parts;
++ } u;
+ u8 extended_name[32];
+ } afs_dirent_t;
+
+@@ -256,7 +257,7 @@
+
+ /* got a valid entry */
+ dire = &block->dirents[offset];
+- nlen = strnlen(dire->parts.name,sizeof(*block) - offset*sizeof(afs_dirent_t));
++ nlen = strnlen(dire->u.name,sizeof(*block) - offset*sizeof(afs_dirent_t));
+
+ _debug("ENT[%Zu.%u]: %s %Zu \"%s\"\n",
+ blkoff/sizeof(afs_dir_block_t),offset,
+@@ -288,11 +289,11 @@
+
+ /* found the next entry */
+ ret = filldir(cookie,
+- dire->parts.name,
++ dire->u.name,
+ nlen,
+ blkoff + offset * sizeof(afs_dirent_t),
+- ntohl(dire->parts.vnode),
+- filldir==afs_dir_lookup_filldir ? dire->parts.unique : DT_UNKNOWN);
++ ntohl(dire->u.vnode),
++ filldir==afs_dir_lookup_filldir ? dire->u.unique : DT_UNKNOWN);
+ if (ret<0) {
+ _leave(" = 0 [full]");
+ return 0;
+@@ -414,7 +415,8 @@
+ /*
+ * look up an entry in a directory
+ */
+-static struct dentry *afs_dir_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
++static struct dentry *afs_dir_lookup(struct inode *dir, struct dentry *dentry,
++ struct nameidata *nd)
+ {
+ struct afs_dir_lookup_cookie cookie;
+ struct afs_super_info *as;
+@@ -423,11 +425,11 @@
+ unsigned fpos;
+ int ret;
+
+- _enter("{%lu},{%s}",dir->i_ino,dentry->d_name.name);
++ _enter("{%lu},%p{%s}",dir->i_ino,dentry,dentry->d_name.name);
+
+ /* insanity checks first */
+- if (sizeof(afs_dir_block_t) != 2048) BUG();
+- if (sizeof(afs_dirent_t) != 32) BUG();
++ BUG_ON(sizeof(afs_dir_block_t) != 2048);
++ BUG_ON(sizeof(afs_dirent_t) != 32);
+
+ if (dentry->d_name.len > 255) {
+ _leave(" = -ENAMETOOLONG");
+@@ -495,9 +497,11 @@
+ unsigned fpos;
+ int ret;
+
+- _enter("%s,%p",dentry->d_name.name,nd);
++ _enter("{sb=%p n=%s},",dentry->d_sb,dentry->d_name.name);
++
++ /* lock down the parent dentry so we can peer at it */
++ parent = dget_parent(dentry->d_parent);
+
+- parent = dget_parent(dentry);
+ dir = parent->d_inode;
+ inode = dentry->d_inode;
+
+Index: linux-2.6.0-test5/fs/afs/file.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/file.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/file.c 2003-09-27 11:38:35.995056304 +0800
+@@ -16,6 +16,7 @@
+ #include <linux/slab.h>
+ #include <linux/fs.h>
+ #include <linux/pagemap.h>
++#include <linux/buffer_head.h>
+ #include "volume.h"
+ #include "vnode.h"
+ #include <rxrpc/call.h>
+@@ -27,6 +28,8 @@
+ #endif
+
+ static int afs_file_readpage(struct file *file, struct page *page);
++static int afs_file_invalidatepage(struct page *page, unsigned long offset);
++static int afs_file_releasepage(struct page *page, int gfp_flags);
+
+ static ssize_t afs_file_write(struct file *file, const char *buf, size_t size, loff_t *off);
+
+@@ -37,7 +40,7 @@
+ struct file_operations afs_file_file_operations = {
+ .read = generic_file_read,
+ .write = afs_file_write,
+- .mmap = generic_file_readonly_mmap,
++ .mmap = generic_file_mmap,
+ #if 0
+ .open = afs_file_open,
+ .release = afs_file_release,
+@@ -47,6 +50,10 @@
+
+ struct address_space_operations afs_fs_aops = {
+ .readpage = afs_file_readpage,
++ .sync_page = block_sync_page,
++ .set_page_dirty = __set_page_dirty_nobuffers,
++ .releasepage = afs_file_releasepage,
++ .invalidatepage = afs_file_invalidatepage,
+ };
+
+ /*****************************************************************************/
+@@ -66,11 +73,48 @@
+
+ /*****************************************************************************/
+ /*
++ * deal with notification that a page was read from the cache
++ */
++#ifdef AFS_CACHING_SUPPORT
++static void afs_file_readpage_read_complete(void *cookie_data, struct page *page, void *data,
++ int error)
++{
++ _enter("%p,%p,%p,%d",cookie_data,page,data,error);
++
++ if (error)
++ SetPageError(page);
++ else
++ SetPageUptodate(page);
++ unlock_page(page);
++
++} /* end afs_file_readpage_read_complete() */
++#endif
++
++/*****************************************************************************/
++/*
++ * deal with notification that a page was written to the cache
++ */
++#ifdef AFS_CACHING_SUPPORT
++static void afs_file_readpage_write_complete(void *cookie_data, struct page *page, void *data,
++ int error)
++{
++ _enter("%p,%p,%p,%d",cookie_data,page,data,error);
++
++ unlock_page(page);
++
++} /* end afs_file_readpage_write_complete() */
++#endif
++
++/*****************************************************************************/
++/*
+ * AFS read page from file (or symlink)
+ */
+ static int afs_file_readpage(struct file *file, struct page *page)
+ {
+ struct afs_rxfs_fetch_descriptor desc;
++#ifdef AFS_CACHING_SUPPORT
++ struct cachefs_page *pageio;
++#endif
+ struct inode *inode;
+ afs_vnode_t *vnode;
+ int ret;
+@@ -88,28 +132,73 @@
+ if (vnode->flags & AFS_VNODE_DELETED)
+ goto error;
+
+- /* work out how much to get and from where */
+- desc.fid = vnode->fid;
+- desc.offset = page->index << PAGE_CACHE_SHIFT;
+- desc.size = min((size_t)(inode->i_size - desc.offset),(size_t)PAGE_SIZE);
+- desc.buffer = kmap(page);
+-
+- clear_page(desc.buffer);
+-
+- /* read the contents of the file from the server into the page */
+- ret = afs_vnode_fetch_data(vnode,&desc);
+- kunmap(page);
+- if (ret<0) {
+- if (ret==-ENOENT) {
+- _debug("got NOENT from server - marking file deleted and stale");
+- vnode->flags |= AFS_VNODE_DELETED;
+- ret = -ESTALE;
+- }
++#ifdef AFS_CACHING_SUPPORT
++ ret = cachefs_page_get_private(page,&pageio,GFP_NOIO);
++ if (ret<0)
+ goto error;
+- }
+
+- SetPageUptodate(page);
+- unlock_page(page);
++ /* is it cached? */
++ ret = cachefs_read_or_alloc_page(vnode->cache,
++ page,
++ afs_file_readpage_read_complete,
++ NULL,
++ GFP_KERNEL);
++#else
++ ret = -ENOBUFS;
++#endif
++
++ switch (ret) {
++ /* read BIO submitted and wb-journal entry found */
++ case 1:
++ BUG(); // TODO - handle wb-journal match
++
++ /* read BIO submitted (page in cache) */
++ case 0:
++ break;
++
++ /* no page available in cache */
++ case -ENOBUFS:
++ case -ENODATA:
++ default:
++ desc.fid = vnode->fid;
++ desc.offset = page->index << PAGE_CACHE_SHIFT;
++ desc.size = min((size_t)(inode->i_size - desc.offset),(size_t)PAGE_SIZE);
++ desc.buffer = kmap(page);
++
++ clear_page(desc.buffer);
++
++ /* read the contents of the file from the server into the page */
++ ret = afs_vnode_fetch_data(vnode,&desc);
++ kunmap(page);
++ if (ret<0) {
++ if (ret==-ENOENT) {
++ _debug("got NOENT from server - marking file deleted and stale");
++ vnode->flags |= AFS_VNODE_DELETED;
++ ret = -ESTALE;
++ }
++
++#ifdef AFS_CACHING_SUPPORT
++ cachefs_uncache_page(vnode->cache,page);
++#endif
++ goto error;
++ }
++
++ SetPageUptodate(page);
++
++#ifdef AFS_CACHING_SUPPORT
++ if (cachefs_write_page(vnode->cache,
++ page,
++ afs_file_readpage_write_complete,
++ NULL,
++ GFP_KERNEL) != 0
++ ) {
++ cachefs_uncache_page(vnode->cache,page);
++ unlock_page(page);
++ }
++#else
++ unlock_page(page);
++#endif
++ }
+
+ _leave(" = 0");
+ return 0;
+@@ -122,3 +211,83 @@
+ return ret;
+
+ } /* end afs_file_readpage() */
++
++/*****************************************************************************/
++/*
++ * get a page cookie for the specified page
++ */
++#ifdef AFS_CACHING_SUPPORT
++int afs_cache_get_page_cookie(struct page *page, struct cachefs_page **_page_cookie)
++{
++ int ret;
++
++ _enter("");
++ ret = cachefs_page_get_private(page,_page_cookie,GFP_NOIO);
++
++ _leave(" = %d",ret);
++ return ret;
++} /* end afs_cache_get_page_cookie() */
++#endif
++
++/*****************************************************************************/
++/*
++ * invalidate part or all of a page
++ */
++static int afs_file_invalidatepage(struct page *page, unsigned long offset)
++{
++ int ret = 1;
++
++ _enter("{%lu},%lu",page->index,offset);
++
++ BUG_ON(!PageLocked(page));
++ if (PagePrivate(page)) {
++#ifdef AFS_CACHING_SUPPORT
++ struct afs_vnode *vnode = AFS_FS_I(page->mapping->host);
++ cachefs_uncache_page(vnode->cache,page);
++#endif
++
++ /*
++ * We release buffers only if the entire page is being invalidated.
++ * The get_block cached value has been unconditionally invalidated,
++ * so real IO is not possible anymore.
++ */
++ if (offset == 0) {
++ BUG_ON(!PageLocked(page));
++
++ ret = 0;
++ if (!PageWriteback(page))
++ ret = page->mapping->a_ops->releasepage(page, 0);
++ }
++ }
++
++ _leave(" = %d",ret);
++ return ret;
++} /* end afs_file_invalidatepage() */
++
++/*****************************************************************************/
++/*
++ * release a page and cleanup its private data
++ */
++static int afs_file_releasepage(struct page *page, int gfp_flags)
++{
++ struct cachefs_page *pageio;
++
++ _enter("{%lu},%x",page->index,gfp_flags);
++
++ if (PagePrivate(page)) {
++#ifdef AFS_CACHING_SUPPORT
++ struct afs_vnode *vnode = AFS_FS_I(page->mapping->host);
++ cachefs_uncache_page(vnode->cache,page);
++#endif
++
++ pageio = (struct cachefs_page *) page->private;
++ page->private = 0;
++ ClearPagePrivate(page);
++
++ if (pageio)
++ kfree(pageio);
++ }
++
++ _leave(" = 0");
++ return 0;
++} /* end afs_file_releasepage() */
+Index: linux-2.6.0-test5/fs/afs/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/inode.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/inode.c 2003-09-27 11:38:35.997056000 +0800
+@@ -69,17 +69,16 @@
+ inode->i_uid = vnode->status.owner;
+ inode->i_gid = 0;
+ inode->i_size = vnode->status.size;
+- inode->i_atime.tv_sec = inode->i_mtime.tv_sec = inode->i_ctime.tv_sec = vnode->status.mtime_server;
+- inode->i_atime.tv_nsec =
+- inode->i_mtime.tv_nsec =
+- inode->i_ctime.tv_nsec = 0;
++ inode->i_ctime.tv_sec = vnode->status.mtime_server;
++ inode->i_ctime.tv_nsec = 0;
++ inode->i_atime = inode->i_mtime = inode->i_ctime;
+ inode->i_blksize = PAGE_CACHE_SIZE;
+ inode->i_blocks = 0;
+ inode->i_version = vnode->fid.unique;
+ inode->i_mapping->a_ops = &afs_fs_aops;
+
+ /* check to see whether a symbolic link is really a mountpoint */
+- if (vnode->status.type==AFS_FTYPE_SYMLINK) {
++ if (vnode->status.type == AFS_FTYPE_SYMLINK) {
+ afs_mntpt_check_symlink(vnode);
+
+ if (vnode->flags & AFS_VNODE_MOUNTPOINT) {
+@@ -105,7 +104,7 @@
+
+ ret = afs_vnode_fetch_status(vnode);
+
+- if (ret==0)
++ if (ret == 0)
+ ret = afs_inode_map_status(vnode);
+
+ return ret;
+@@ -120,8 +119,8 @@
+ {
+ struct afs_iget_data *data = opaque;
+
+- /* only match inodes with the same version number */
+- return inode->i_ino==data->fid.vnode && inode->i_version==data->fid.unique;
++ return inode->i_ino == data->fid.vnode &&
++ inode->i_version == data->fid.unique;
+ } /* end afs_iget5_test() */
+
+ /*****************************************************************************/
+@@ -145,20 +144,22 @@
+ /*
+ * inode retrieval
+ */
+-inline int afs_iget(struct super_block *sb, afs_fid_t *fid, struct inode **_inode)
++inline int afs_iget(struct super_block *sb, afs_fid_t *fid,
++ struct inode **_inode)
+ {
+- struct afs_iget_data data = { .fid = *fid };
++ struct afs_iget_data data = { fid: *fid };
+ struct afs_super_info *as;
++ struct afs_vnode *vnode;
+ struct inode *inode;
+- afs_vnode_t *vnode;
+ int ret;
+
+- _enter(",{%u,%u,%u},,",fid->vid,fid->vnode,fid->unique);
++ _enter(",{%u,%u,%u},,", fid->vid, fid->vnode, fid->unique);
+
+ as = sb->s_fs_info;
+ data.volume = as->volume;
+
+- inode = iget5_locked(sb,fid->vnode,afs_iget5_test,afs_iget5_set,&data);
++ inode = iget5_locked(sb, fid->vnode, afs_iget5_test, afs_iget5_set,
++ &data);
+ if (!inode) {
+ _leave(" = -ENOMEM");
+ return -ENOMEM;
+@@ -173,10 +174,19 @@
+ *_inode = inode;
+ else
+ iput(inode);
+- _leave(" = %d",ret);
++ _leave(" = %d", ret);
+ return ret;
+ }
+
++#ifdef AFS_CACHING_SUPPORT
++ /* set up caching before reading the status, as fetch-status reads the
++ * first page of symlinks to see if they're really mntpts */
++ cachefs_acquire_cookie(vnode->volume->cache,
++ NULL,
++ vnode,
++ &vnode->cache);
++#endif
++
+ /* okay... it's a new inode */
+ vnode->flags |= AFS_VNODE_CHANGED;
+ ret = afs_inode_fetch_status(inode);
+@@ -187,11 +197,11 @@
+ unlock_new_inode(inode);
+
+ *_inode = inode;
+- _leave(" = 0 [CB { v=%u x=%lu t=%u nix=%u }]",
++ _leave(" = 0 [CB { v=%u x=%lu t=%u } c=%p]",
+ vnode->cb_version,
+ vnode->cb_timeout.timo_jif,
+ vnode->cb_type,
+- vnode->nix
++ vnode->cache
+ );
+ return 0;
+
+@@ -201,7 +211,7 @@
+ unlock_new_inode(inode);
+ iput(inode);
+
+- _leave(" = %d [bad]",ret);
++ _leave(" = %d [bad]", ret);
+ return ret;
+ } /* end afs_iget() */
+
+@@ -209,7 +219,8 @@
+ /*
+ * read the attributes of an inode
+ */
+-int afs_inode_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
++int afs_inode_getattr(struct vfsmount *mnt, struct dentry *dentry,
++ struct kstat *stat)
+ {
+ struct inode *inode;
+ afs_vnode_t *vnode;
+@@ -217,23 +228,25 @@
+
+ inode = dentry->d_inode;
+
+- _enter("{ ino=%lu v=%lu }",inode->i_ino,inode->i_version);
++ _enter("{ ino=%lu v=%lu }", inode->i_ino, inode->i_version);
+
+ vnode = AFS_FS_I(inode);
+
+ ret = afs_inode_fetch_status(inode);
+- if (ret==-ENOENT) {
+- _leave(" = %d [%d %p]",ret,atomic_read(&dentry->d_count),dentry->d_inode);
++ if (ret == -ENOENT) {
++ _leave(" = %d [%d %p]",
++ ret, atomic_read(&dentry->d_count), dentry->d_inode);
+ return ret;
+ }
+- else if (ret<0) {
++ else if (ret < 0) {
+ make_bad_inode(inode);
+- _leave(" = %d",ret);
++ _leave(" = %d", ret);
+ return ret;
+ }
+
+- /* transfer attributes from the inode structure to the stat structure */
+- generic_fillattr(inode,stat);
++ /* transfer attributes from the inode structure to the stat
++ * structure */
++ generic_fillattr(inode, stat);
+
+ _leave(" = 0 CB { v=%u x=%u t=%u }",
+ vnode->cb_version,
+@@ -261,9 +274,14 @@
+ vnode->cb_type
+ );
+
+- if (inode->i_ino!=vnode->fid.vnode) BUG();
++ BUG_ON(inode->i_ino != vnode->fid.vnode);
+
+ afs_vnode_give_up_callback(vnode);
+
++#ifdef AFS_CACHING_SUPPORT
++ cachefs_relinquish_cookie(vnode->cache, 0);
++ vnode->cache = NULL;
++#endif
++
+ _leave("");
+ } /* end afs_clear_inode() */
+Index: linux-2.6.0-test5/fs/afs/internal.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/internal.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/internal.h 2003-09-27 11:38:35.999055696 +0800
+@@ -26,7 +26,7 @@
+ #define kproto(FMT, a...) printk("### "FMT"\n" , ## a)
+ #define knet(FMT, a...) printk(FMT"\n" , ## a)
+
+-#if 0
++#ifdef __KDEBUG
+ #define _enter(FMT, a...) kenter(FMT , ## a)
+ #define _leave(FMT, a...) kleave(FMT , ## a)
+ #define _debug(FMT, a...) kdebug(FMT , ## a)
+@@ -56,6 +56,9 @@
+ */
+ extern struct rw_semaphore afs_proc_cells_sem;
+ extern struct list_head afs_proc_cells;
++#ifdef AFS_CACHING_SUPPORT
++extern struct cachefs_index_def afs_cache_cell_index_def;
++#endif
+
+ /*
+ * dir.c
+@@ -70,6 +73,10 @@
+ extern struct inode_operations afs_file_inode_operations;
+ extern struct file_operations afs_file_file_operations;
+
++#ifdef AFS_CACHING_SUPPORT
++extern int afs_cache_get_page_cookie(struct page *page, struct cachefs_page **_page_cookie);
++#endif
++
+ /*
+ * inode.c
+ */
+@@ -78,10 +85,22 @@
+ extern void afs_clear_inode(struct inode *inode);
+
+ /*
++ * main.c
++ */
++#ifdef AFS_CACHING_SUPPORT
++extern struct cachefs_netfs afs_cache_netfs;
++#endif
++
++/*
+ * mntpt.c
+ */
+ extern struct inode_operations afs_mntpt_inode_operations;
+ extern struct file_operations afs_mntpt_file_operations;
++#ifdef AFS_AUTOMOUNT_SUPPORT
++extern struct afs_timer afs_mntpt_expiry_timer;
++extern struct afs_timer_ops afs_mntpt_expiry_timer_ops;
++extern unsigned long afs_mntpt_expiry_timeout;
++#endif
+
+ extern int afs_mntpt_check_symlink(afs_vnode_t *vnode);
+
+Index: linux-2.6.0-test5/fs/afs/kafsasyncd.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/kafsasyncd.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/kafsasyncd.c 2003-09-27 11:38:36.001055392 +0800
+@@ -153,8 +153,7 @@
+ spin_lock(&kafsasyncd_async_lock);
+
+ /* fold the busy and attention queues together */
+- list_splice(&kafsasyncd_async_busyq,&kafsasyncd_async_attnq);
+- list_del_init(&kafsasyncd_async_busyq);
++ list_splice_init(&kafsasyncd_async_busyq,&kafsasyncd_async_attnq);
+
+ /* dequeue kafsasyncd from all their wait queues */
+ list_for_each(_p,&kafsasyncd_async_attnq) {
+@@ -197,6 +196,7 @@
+ spin_lock(&kafsasyncd_async_lock);
+
+ init_waitqueue_entry(&op->waiter,kafsasyncd_task);
++ add_wait_queue(&op->call->waitq,&op->waiter);
+
+ list_del(&op->link);
+ list_add_tail(&op->link,&kafsasyncd_async_busyq);
+@@ -238,7 +238,10 @@
+
+ spin_lock(&kafsasyncd_async_lock);
+
+- list_del_init(&op->link);
++ if (!list_empty(&op->link)) {
++ list_del_init(&op->link);
++ remove_wait_queue(&op->call->waitq,&op->waiter);
++ }
+
+ spin_unlock(&kafsasyncd_async_lock);
+
+Index: linux-2.6.0-test5/fs/afs/kafstimod.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/kafstimod.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/kafstimod.c 2003-09-27 11:38:36.004054936 +0800
+@@ -82,7 +82,7 @@
+
+ for (;;) {
+ unsigned long jif;
+- unsigned long timeout;
++ signed long timeout;
+
+ /* deal with the server being asked to die */
+ if (kafstimod_die) {
+@@ -98,18 +98,18 @@
+ spin_lock(&kafstimod_lock);
+ if (list_empty(&kafstimod_list)) {
+ timeout = MAX_SCHEDULE_TIMEOUT;
+- } else {
+- unsigned long tmo;
+-
+- timer = list_entry(kafstimod_list.next,
+- afs_timer_t, link);
+- tmo = timer->timo_jif;
++ }
++ else {
++ timer = list_entry(kafstimod_list.next,afs_timer_t,link);
++ timeout = timer->timo_jif;
+ jif = jiffies;
+
+- if (time_before_eq(tmo,jif))
++ if (time_before_eq((unsigned long)timeout,jif))
+ goto immediate;
+
+- timeout = (long)tmo - (long)jiffies;
++ else {
++ timeout = (long)timeout - (long)jiffies;
++ }
+ }
+ spin_unlock(&kafstimod_lock);
+
+@@ -170,7 +170,7 @@
+ wake_up(&kafstimod_sleepq);
+
+ _leave("");
+-} /* end afs_kafstimod_queue_vlocation() */
++} /* end afs_kafstimod_add_timer() */
+
+ /*****************************************************************************/
+ /*
+Index: linux-2.6.0-test5/fs/afs/main.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/main.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/main.c 2003-09-27 11:38:36.006054632 +0800
+@@ -17,6 +17,7 @@
+ #include <rxrpc/transport.h>
+ #include <rxrpc/call.h>
+ #include <rxrpc/peer.h>
++#include "cache.h"
+ #include "cell.h"
+ #include "server.h"
+ #include "fsclient.h"
+@@ -47,6 +48,18 @@
+ struct list_head afs_cb_hash_tbl[AFS_CB_HASH_COUNT];
+ spinlock_t afs_cb_hash_lock = SPIN_LOCK_UNLOCKED;
+
++#ifdef AFS_CACHING_SUPPORT
++static struct cachefs_netfs_operations afs_cache_ops = {
++ .get_page_cookie = afs_cache_get_page_cookie,
++};
++
++struct cachefs_netfs afs_cache_netfs = {
++ .name = "afs",
++ .version = 0,
++ .ops = &afs_cache_ops,
++};
++#endif
++
+ /*****************************************************************************/
+ /*
+ * initialise the AFS client FS module
+@@ -64,34 +77,41 @@
+
+ /* register the /proc stuff */
+ ret = afs_proc_init();
+- if (ret<0)
++ if (ret < 0)
+ return ret;
+
++#ifdef AFS_CACHING_SUPPORT
++ /* we want to be able to cache */
++ ret = cachefs_register_netfs(&afs_cache_netfs,&afs_cache_cell_index_def);
++ if (ret < 0)
++ goto error;
++#endif
++
+ /* initialise the cell DB */
+ ret = afs_cell_init();
+- if (ret<0)
+- goto error;
++ if (ret < 0)
++ goto error_cache;
+
+ /* start the timeout daemon */
+ ret = afs_kafstimod_start();
+- if (ret<0)
+- goto error;
++ if (ret < 0)
++ goto error_cache;
+
+ /* start the async operation daemon */
+ ret = afs_kafsasyncd_start();
+- if (ret<0)
++ if (ret < 0)
+ goto error_kafstimod;
+
+ /* create the RxRPC transport */
+ ret = rxrpc_create_transport(7001,&afs_transport);
+- if (ret<0)
++ if (ret < 0)
+ goto error_kafsasyncd;
+
+ afs_transport->peer_ops = &afs_peer_ops;
+
+ /* register the filesystems */
+ ret = afs_fs_init();
+- if (ret<0)
++ if (ret < 0)
+ goto error_transport;
+
+ return ret;
+@@ -102,7 +122,11 @@
+ afs_kafsasyncd_stop();
+ error_kafstimod:
+ afs_kafstimod_stop();
++ error_cache:
++#ifdef AFS_CACHING_SUPPORT
++ cachefs_unregister_netfs(&afs_cache_netfs);
+ error:
++#endif
+ afs_cell_purge();
+ afs_proc_cleanup();
+ printk(KERN_ERR "kAFS: failed to register: %d\n",ret);
+@@ -122,6 +146,9 @@
+ afs_kafstimod_stop();
+ afs_kafsasyncd_stop();
+ afs_cell_purge();
++#ifdef AFS_CACHING_SUPPORT
++ cachefs_unregister_netfs(&afs_cache_netfs);
++#endif
+ afs_proc_cleanup();
+
+ } /* end afs_exit() */
+@@ -142,7 +169,7 @@
+
+ /* determine which server the peer resides in (if any) */
+ ret = afs_server_find_by_peer(peer,&server);
+- if (ret<0)
++ if (ret < 0)
+ return ret; /* none that we recognise, so abort */
+
+ _debug("Server %p{u=%d}\n",server,atomic_read(&server->usage));
+@@ -191,3 +218,48 @@
+ _leave("");
+
+ } /* end afs_discarding_peer() */
++
++/*****************************************************************************/
++/*
++ * clear the dead space between task_struct and kernel stack
++ * - called by supplying -finstrument-functions to gcc
++ */
++#if 0
++void __cyg_profile_func_enter (void *this_fn, void *call_site)
++__attribute__((no_instrument_function));
++
++void __cyg_profile_func_enter (void *this_fn, void *call_site)
++{
++ asm volatile(" movl %%esp,%%edi \n"
++ " andl %0,%%edi \n"
++ " addl %1,%%edi \n"
++ " movl %%esp,%%ecx \n"
++ " subl %%edi,%%ecx \n"
++ " shrl $2,%%ecx \n"
++ " movl $0xedededed,%%eax \n"
++ " rep stosl \n"
++ :
++ : "i"(~(THREAD_SIZE-1)), "i"(sizeof(struct thread_info))
++ : "eax", "ecx", "edi", "memory", "cc"
++ );
++}
++
++void __cyg_profile_func_exit(void *this_fn, void *call_site)
++__attribute__((no_instrument_function));
++
++void __cyg_profile_func_exit(void *this_fn, void *call_site)
++{
++ asm volatile(" movl %%esp,%%edi \n"
++ " andl %0,%%edi \n"
++ " addl %1,%%edi \n"
++ " movl %%esp,%%ecx \n"
++ " subl %%edi,%%ecx \n"
++ " shrl $2,%%ecx \n"
++ " movl $0xdadadada,%%eax \n"
++ " rep stosl \n"
++ :
++ : "i"(~(THREAD_SIZE-1)), "i"(sizeof(struct thread_info))
++ : "eax", "ecx", "edi", "memory", "cc"
++ );
++}
++#endif
+Index: linux-2.6.0-test5/fs/afs/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/Makefile 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/Makefile 2003-09-27 11:38:36.008054328 +0800
+@@ -2,6 +2,8 @@
+ # Makefile for Red Hat Linux AFS client.
+ #
+
++#CFLAGS += -finstrument-functions
++
+ kafs-objs := \
+ callback.o \
+ cell.o \
+Index: linux-2.6.0-test5/fs/afs/mntpt.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/mntpt.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/mntpt.c 2003-09-27 11:38:36.010054024 +0800
+@@ -16,24 +16,52 @@
+ #include <linux/slab.h>
+ #include <linux/fs.h>
+ #include <linux/pagemap.h>
++#include <linux/mount.h>
++#include <linux/namei.h>
++#include <linux/namespace.h>
++#include "super.h"
++#include "cell.h"
+ #include "volume.h"
+ #include "vnode.h"
+ #include "internal.h"
+
+
+-static struct dentry *afs_mntpt_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *);
++static struct dentry *afs_mntpt_lookup(struct inode *dir,
++ struct dentry *dentry,
++ struct nameidata *nd);
+ static int afs_mntpt_open(struct inode *inode, struct file *file);
+
++#ifdef AFS_AUTOMOUNT_SUPPORT
++static int afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd);
++#endif
++
+ struct file_operations afs_mntpt_file_operations = {
+ .open = afs_mntpt_open,
+ };
+
+ struct inode_operations afs_mntpt_inode_operations = {
+ .lookup = afs_mntpt_lookup,
++#ifdef AFS_AUTOMOUNT_SUPPORT
++ .follow_link = afs_mntpt_follow_link,
++#endif
+ .readlink = page_readlink,
+ .getattr = afs_inode_getattr,
+ };
+
++#ifdef AFS_AUTOMOUNT_SUPPORT
++static LIST_HEAD(afs_vfsmounts);
++
++static void afs_mntpt_expiry_timed_out(struct afs_timer *timer);
++
++struct afs_timer_ops afs_mntpt_expiry_timer_ops = {
++ .timed_out = afs_mntpt_expiry_timed_out,
++};
++
++struct afs_timer afs_mntpt_expiry_timer;
++
++unsigned long afs_mntpt_expiry_timeout = 20;
++#endif
++
+ /*****************************************************************************/
+ /*
+ * check a symbolic link to see whether it actually encodes a mountpoint
+@@ -93,8 +121,17 @@
+ /*
+ * no valid lookup procedure on this sort of dir
+ */
+-static struct dentry *afs_mntpt_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
++static struct dentry *afs_mntpt_lookup(struct inode *dir,
++ struct dentry *dentry,
++ struct nameidata *nd)
+ {
++ kenter("%p,%p{%p{%s},%s}",
++ dir,
++ dentry,
++ dentry->d_parent,
++ dentry->d_parent ? dentry->d_parent->d_name.name : (const unsigned char*)"",
++ dentry->d_name.name);
++
+ return ERR_PTR(-EREMOTE);
+ } /* end afs_mntpt_lookup() */
+
+@@ -104,5 +141,146 @@
+ */
+ static int afs_mntpt_open(struct inode *inode, struct file *file)
+ {
++ kenter("%p,%p{%p{%s},%s}",
++ inode, file,
++ file->f_dentry->d_parent,
++ file->f_dentry->d_parent ? file->f_dentry->d_parent->d_name.name : (const unsigned char*)"",
++ file->f_dentry->d_name.name);
++
+ return -EREMOTE;
+ } /* end afs_mntpt_open() */
++
++#ifdef AFS_AUTOMOUNT_SUPPORT
++/*****************************************************************************/
++/*
++ * create a vfsmount to be automounted
++ */
++static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt)
++{
++ struct afs_super_info *super;
++ struct vfsmount *mnt;
++ struct page *page = NULL;
++ size_t size;
++ char *buf, *devname = NULL, *options = NULL;
++ int ret;
++
++ kenter("{%s}", mntpt->d_name.name);
++
++ BUG_ON(!mntpt->d_inode);
++
++ ret = -EINVAL;
++ size = mntpt->d_inode->i_size;
++ if (size > PAGE_SIZE - 1)
++ goto error;
++
++ ret = -ENOMEM;
++ devname = (char *) get_zeroed_page(GFP_KERNEL);
++ if (!devname)
++ goto error;
++
++ options = (char *) get_zeroed_page(GFP_KERNEL);
++ if (!options)
++ goto error;
++
++ /* read the contents of the AFS special symlink */
++ page = read_cache_page(mntpt->d_inode->i_mapping,
++ 0,
++ (filler_t*)mntpt->d_inode->i_mapping->a_ops->readpage,
++ NULL);
++ if (IS_ERR(page)) {
++ ret = PTR_ERR(page);
++ goto error;
++ }
++
++ ret = -EIO;
++ wait_on_page_locked(page);
++ if (!PageUptodate(page) || PageError(page))
++ goto error;
++
++ buf = kmap(page);
++ memcpy(devname, buf, size);
++ kunmap(page);
++ page_cache_release(page);
++ page = NULL;
++
++ /* work out what options we want */
++ super = AFS_FS_S(mntpt->d_sb);
++ memcpy(options, "cell=", 5);
++ strcpy(options + 5, super->volume->cell->name);
++ if (super->volume->type == AFSVL_RWVOL)
++ strcat(options,",rwpath");
++
++ /* try and do the mount */
++ kdebug("--- attempting mount %s -o %s ---", devname, options);
++ mnt = do_kern_mount("afs", 0, devname, options);
++ kdebug("--- mount result %p ---", mnt);
++
++ free_page((unsigned long)devname);
++ free_page((unsigned long)options);
++ kleave(" = %p",mnt);
++ return mnt;
++
++ error:
++ if (page)
++ page_cache_release(page);
++ if (devname)
++ free_page((unsigned long)devname);
++ if (options)
++ free_page((unsigned long)options);
++ kleave(" = %d",ret);
++ return ERR_PTR(ret);
++} /* end afs_mntpt_do_automount() */
++
++/*****************************************************************************/
++/*
++ * follow a link from a mountpoint directory, thus causing it to be mounted
++ */
++static int afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd)
++{
++ struct nameidata newnd;
++ struct vfsmount *newmnt;
++ int err;
++
++ kenter("%p{%s},{%s:%p{%s}}",
++ dentry,
++ dentry->d_name.name,
++ nd->mnt->mnt_devname,
++ dentry,
++ nd->dentry->d_name.name);
++
++ newmnt = afs_mntpt_do_automount(dentry);
++ if (IS_ERR(newmnt))
++ return PTR_ERR(newmnt);
++
++ struct_cpy(&newnd,nd);
++ newnd.dentry = dentry;
++ err = do_add_mount(newmnt, &newnd, 0, &afs_vfsmounts);
++
++ if (!err) {
++ path_release(nd);
++ mntget(newmnt);
++ nd->mnt = newmnt;
++ dget(newmnt->mnt_root);
++ nd->dentry = newmnt->mnt_root;
++ }
++
++ kleave(" = %d", err);
++ return err;
++} /* end afs_mntpt_follow_link() */
++
++/*****************************************************************************/
++/*
++ * handle mountpoint expiry timer going off
++ */
++static void afs_mntpt_expiry_timed_out(struct afs_timer *timer)
++{
++ kenter("");
++
++ mark_mounts_for_expiry(&afs_vfsmounts);
++
++ afs_kafstimod_add_timer(&afs_mntpt_expiry_timer,
++ afs_mntpt_expiry_timeout * HZ);
++
++ kleave("");
++} /* end afs_mntpt_expiry_timed_out() */
++#endif
+Index: linux-2.6.0-test5/fs/afs/mount.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/mount.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/mount.h 2003-09-27 11:38:36.011053872 +0800
+@@ -17,7 +17,7 @@
+ const char *cell; /* name of cell containing volume */
+ const char *cache; /* name of cache block device */
+ size_t nservers; /* number of server addresses listed */
+- u_int32_t servers[10]; /* IP addresses of servers in this cell */
++ uint32_t servers[10]; /* IP addresses of servers in this cell */
+ };
+
+ #endif /* _LINUX_AFS_MOUNT_H */
+Index: linux-2.6.0-test5/fs/afs/server.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/server.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/server.c 2003-09-27 11:38:36.014053416 +0800
+@@ -148,6 +148,9 @@
+ {
+ afs_cell_t *cell;
+
++ if (!server)
++ return;
++
+ _enter("%p",server);
+
+ cell = server->cell;
+Index: linux-2.6.0-test5/fs/afs/super.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/super.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/super.c 2003-09-27 11:38:36.019052656 +0800
+@@ -29,15 +29,22 @@
+
+ #define AFS_FS_MAGIC 0x6B414653 /* 'kAFS' */
+
++struct afs_mount_params {
++ int rwpath;
++ struct afs_cell *default_cell;
++ struct afs_volume *volume;
++};
++
+ static inline char *strdup(const char *s)
+ {
+- char *ns = kmalloc(strlen(s)+1,GFP_KERNEL);
++ char *ns = kmalloc(strlen(s) + 1, GFP_KERNEL);
+ if (ns)
+- strcpy(ns,s);
++ strcpy(ns, s);
+ return ns;
+ }
+
+-static void afs_i_init_once(void *foo, kmem_cache_t *cachep, unsigned long flags);
++static void afs_i_init_once(void *foo, kmem_cache_t *cachep,
++ unsigned long flags);
+
+ static struct super_block *afs_get_sb(struct file_system_type *fs_type,
+ int flags, const char *dev_name,
+@@ -66,6 +73,7 @@
+ };
+
+ static kmem_cache_t *afs_inode_cachep;
++static atomic_t afs_count_active_inodes;
+
+ /*****************************************************************************/
+ /*
+@@ -75,16 +83,22 @@
+ {
+ int ret;
+
+- kenter("");
++ _enter("");
++
++#ifdef AFS_AUTOMOUNT_SUPPORT
++ afs_timer_init(&afs_mntpt_expiry_timer, &afs_mntpt_expiry_timer_ops);
++#endif
+
+ /* create ourselves an inode cache */
++ atomic_set(&afs_count_active_inodes, 0);
++
+ ret = -ENOMEM;
+ afs_inode_cachep = kmem_cache_create("afs_inode_cache",
+- sizeof(afs_vnode_t),
+- 0,
+- SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
+- afs_i_init_once,
+- NULL);
++ sizeof(afs_vnode_t),
++ 0,
++ SLAB_HWCACHE_ALIGN,
++ afs_i_init_once,
++ NULL);
+ if (!afs_inode_cachep) {
+ printk(KERN_NOTICE "kAFS: Failed to allocate inode cache\n");
+ return ret;
+@@ -92,9 +106,9 @@
+
+ /* now export our filesystem to lesser mortals */
+ ret = register_filesystem(&afs_fs_type);
+- if (ret<0) {
++ if (ret < 0) {
+ kmem_cache_destroy(afs_inode_cachep);
+- kleave(" = %d",ret);
++ kleave(" = %d", ret);
+ return ret;
+ }
+
+@@ -108,11 +122,16 @@
+ */
+ void __exit afs_fs_exit(void)
+ {
+- /* destroy our private inode cache */
+- kmem_cache_destroy(afs_inode_cachep);
+-
+ unregister_filesystem(&afs_fs_type);
+
++ if (atomic_read(&afs_count_active_inodes) != 0) {
++ printk("kAFS: %d active inode objects still present\n",
++ atomic_read(&afs_count_active_inodes));
++ BUG();
++ }
++
++ kmem_cache_destroy(afs_inode_cachep);
++
+ } /* end afs_fs_exit() */
+
+ /*****************************************************************************/
+@@ -122,7 +141,7 @@
+ static int want_arg(char **_value, const char *option)
+ {
+ if (!_value || !*_value || !**_value) {
+- printk(KERN_NOTICE "kAFS: %s: argument missing\n",option);
++ printk(KERN_NOTICE "kAFS: %s: argument missing\n", option);
+ return 0;
+ }
+ return 1;
+@@ -130,27 +149,13 @@
+
+ /*****************************************************************************/
+ /*
+- * check that there is a value
+- */
+-#if 0
+-static int want_value(char **_value, const char *option)
+-{
+- if (!_value || !*_value || !**_value) {
+- printk(KERN_NOTICE "kAFS: %s: argument incomplete\n",option);
+- return 0;
+- }
+- return 1;
+-} /* end want_value() */
+-#endif
+-
+-/*****************************************************************************/
+-/*
+ * check that there's no subsequent value
+ */
+ static int want_no_value(char *const *_value, const char *option)
+ {
+ if (*_value && **_value) {
+- printk(KERN_NOTICE "kAFS: %s: Invalid argument: %s\n",option,*_value);
++ printk(KERN_NOTICE "kAFS: %s: Invalid argument: %s\n",
++ option, *_value);
+ return 0;
+ }
+ return 1;
+@@ -158,150 +163,55 @@
+
+ /*****************************************************************************/
+ /*
+- * extract a number from an option string value
+- */
+-#if 0
+-static int want_number(char **_value, const char *option, unsigned long *number,
+- unsigned long limit)
+-{
+- char *value = *_value;
+-
+- if (!want_value(_value,option))
+- return 0;
+-
+- *number = simple_strtoul(value,_value,0);
+-
+- if (value==*_value) {
+- printk(KERN_NOTICE "kAFS: %s: Invalid number: %s\n",option,value);
+- return 0;
+- }
+-
+- if (*number>limit) {
+- printk(KERN_NOTICE "kAFS: %s: numeric value %lu > %lu\n",option,*number,limit);
+- return 0;
+- }
+-
+- return 1;
+-} /* end want_number() */
+-#endif
+-
+-/*****************************************************************************/
+-/*
+- * extract a separator from an option string value
+- */
+-#if 0
+-static int want_sep(char **_value, const char *option, char sep)
+-{
+- if (!want_value(_value,option))
+- return 0;
+-
+- if (*(*_value)++ != sep) {
+- printk(KERN_NOTICE "kAFS: %s: '%c' expected: %s\n",option,sep,*_value-1);
+- return 0;
+- }
+-
+- return 1;
+-} /* end want_number() */
+-#endif
+-
+-/*****************************************************************************/
+-/*
+- * extract an IP address from an option string value
+- */
+-#if 0
+-static int want_ipaddr(char **_value, const char *option, struct in_addr *addr)
+-{
+- unsigned long number[4];
+-
+- if (!want_value(_value,option))
+- return 0;
+-
+- if (!want_number(_value,option,&number[0],255) ||
+- !want_sep(_value,option,'.') ||
+- !want_number(_value,option,&number[1],255) ||
+- !want_sep(_value,option,'.') ||
+- !want_number(_value,option,&number[2],255) ||
+- !want_sep(_value,option,'.') ||
+- !want_number(_value,option,&number[3],255))
+- return 0;
+-
+- ((u8*)addr)[0] = number[0];
+- ((u8*)addr)[1] = number[1];
+- ((u8*)addr)[2] = number[2];
+- ((u8*)addr)[3] = number[3];
+-
+- return 1;
+-} /* end want_numeric() */
+-#endif
+-
+-/*****************************************************************************/
+-/*
+ * parse the mount options
+ * - this function has been shamelessly adapted from the ext3 fs which shamelessly adapted it from
+ * the msdos fs
+ */
+-static int afs_super_parse_options(struct afs_super_info *as, char *options, const char ** devname)
++static int afs_super_parse_options(struct afs_mount_params *params,
++ char *options,
++ const char **devname)
+ {
+ char *key, *value;
+ int ret;
+
+- _enter("%s",options);
++ _enter("%s", options);
++
++ options[PAGE_SIZE - 1] = 0;
+
+ ret = 0;
+- while ((key = strsep(&options,",")))
++ while ((key = strsep(&options, ",")))
+ {
+- value = strchr(key,'=');
++ value = strchr(key, '=');
+ if (value)
+ *value++ = 0;
+
+- printk("kAFS: KEY: %s, VAL:%s\n",key,value?:"-");
++ printk("kAFS: KEY: %s, VAL:%s\n", key, value ?: "-");
+
+- if (strcmp(key,"rwpath")==0) {
+- if (!want_no_value(&value,"rwpath")) return -EINVAL;
+- as->rwparent = 1;
++ if (strcmp(key, "rwpath") == 0) {
++ if (!want_no_value(&value, "rwpath"))
++ return -EINVAL;
++ params->rwpath = 1;
+ continue;
+ }
+- else if (strcmp(key,"vol")==0) {
+- if (!want_arg(&value,"vol")) return -EINVAL;
++ else if (strcmp(key, "vol") == 0) {
++ if (!want_arg(&value, "vol"))
++ return -EINVAL;
+ *devname = value;
+ continue;
+ }
+-
+-#if 0
+- if (strcmp(key,"servers")==0) {
+- if (!want_arg(&value,"servers")) return -EINVAL;
+-
+- _debug("servers=%s",value);
+-
+- for (;;) {
+- struct in_addr addr;
+-
+- if (!want_ipaddr(&value,"servers",&addr))
+- return -EINVAL;
+-
+- ret = afs_create_server(as->cell,&addr,&as->server);
+- if (ret<0) {
+- printk("kAFS: unable to create server: %d\n",ret);
+- return ret;
+- }
+-
+- if (!*value)
+- break;
+-
+- if (as->server) {
+- printk(KERN_NOTICE
+- "kAFS: only one server can be specified\n");
+- return -EINVAL;
+- }
+-
+- if (!want_sep(&value,"servers",':'))
+- return -EINVAL;
+- }
++ else if (strcmp(key, "cell") == 0) {
++ if (!want_arg(&value, "cell"))
++ return -EINVAL;
++ afs_put_cell(params->default_cell);
++ ret = afs_cell_lookup(value,
++ strlen(value),
++ ¶ms->default_cell);
++ if (ret < 0)
++ return -EINVAL;
+ continue;
+ }
+-#endif
+
+- printk("kAFS: Unknown mount option: '%s'\n",key);
++ printk("kAFS: Unknown mount option: '%s'\n", key);
+ ret = -EINVAL;
+ goto error;
+ }
+@@ -309,67 +219,48 @@
+ ret = 0;
+
+ error:
+- _leave(" = %d",ret);
+-
++ _leave(" = %d", ret);
+ return ret;
+ } /* end afs_super_parse_options() */
+
+-struct fill_super_options {
+- const char *dev_name;
+- void *options;
+-};
++/*****************************************************************************/
++/*
++ * check a superblock to see if it's the one we're looking for
++ */
++static int afs_test_super(struct super_block *sb, void *data)
++{
++ struct afs_mount_params *params = data;
++ struct afs_super_info *as = sb->s_fs_info;
++
++ return as->volume == params->volume;
++} /* end afs_test_super() */
+
+ /*****************************************************************************/
+ /*
+ * fill in the superblock
+ */
+-static int afs_fill_super(struct super_block *sb, void *_data, int silent)
++static int afs_fill_super(struct super_block *sb, void *data, int silent)
+ {
++ struct afs_mount_params *params = data;
+ struct afs_super_info *as = NULL;
+ struct dentry *root = NULL;
+ struct inode *inode = NULL;
+ afs_fid_t fid;
+- struct fill_super_options *data = _data;
+- const char *devname;
+- char *options;
+ int ret;
+
+- _enter("");
+-
+- if (!data) {
+- _leave(" = -EINVAL");
+- return -EINVAL;
+- }
+- devname = data->dev_name;
+- options = data->options;
+- if (options)
+- options[PAGE_SIZE-1] = 0;
++ kenter("");
+
+ /* allocate a superblock info record */
+- as = kmalloc(sizeof(struct afs_super_info),GFP_KERNEL);
++ as = kmalloc(sizeof(struct afs_super_info), GFP_KERNEL);
+ if (!as) {
+ _leave(" = -ENOMEM");
+ return -ENOMEM;
+ }
+
+- memset(as,0,sizeof(struct afs_super_info));
++ memset(as, 0, sizeof(struct afs_super_info));
+
+- /* parse the options */
+- if (options) {
+- ret = afs_super_parse_options(as,options,&devname);
+- if (ret<0)
+- goto error;
+- if (!devname) {
+- printk("kAFS: no volume name specified\n");
+- ret = -EINVAL;
+- goto error;
+- }
+- }
+-
+- /* parse the device name */
+- ret = afs_volume_lookup(devname,as->rwparent,&as->volume);
+- if (ret<0)
+- goto error;
++ afs_get_volume(params->volume);
++ as->volume = params->volume;
+
+ /* fill in the superblock */
+ sb->s_blocksize = PAGE_CACHE_SIZE;
+@@ -382,8 +273,8 @@
+ fid.vid = as->volume->vid;
+ fid.vnode = 1;
+ fid.unique = 1;
+- ret = afs_iget(sb,&fid,&inode);
+- if (ret<0)
++ ret = afs_iget(sb, &fid, &inode);
++ if (ret < 0)
+ goto error;
+
+ ret = -ENOMEM;
+@@ -393,19 +284,18 @@
+
+ sb->s_root = root;
+
+- _leave(" = 0");
++ kleave(" = 0");
+ return 0;
+
+ error:
+- if (root) dput(root);
+- if (inode) iput(inode);
+- if (as) {
+- if (as->volume) afs_put_volume(as->volume);
+- kfree(as);
+- }
++ dput(root);
++ iput(inode);
++ afs_put_volume(as->volume);
++ kfree(as);
++
+ sb->s_fs_info = NULL;
+
+- _leave(" = %d",ret);
++ kleave(" = %d", ret);
+ return ret;
+ } /* end afs_fill_super() */
+
+@@ -414,32 +304,72 @@
+ * get an AFS superblock
+ * - TODO: don't use get_sb_nodev(), but rather call sget() directly
+ */
+-static struct super_block *
+-afs_get_sb(struct file_system_type *fs_type, int flags,
+- const char *dev_name, void *options)
++static struct super_block *afs_get_sb(struct file_system_type *fs_type,
++ int flags,
++ const char *dev_name,
++ void *options)
+ {
++ struct afs_mount_params params;
+ struct super_block *sb;
+- struct fill_super_options data = { dev_name, options };
+ int ret;
+
+- _enter(",,%s,%p",dev_name,options);
++ _enter(",,%s,%p", dev_name, options);
++
++ memset(¶ms, 0, sizeof(params));
+
+ /* start the cache manager */
+ ret = afscm_start();
+- if (ret<0) {
+- _leave(" = %d",ret);
++ if (ret < 0) {
++ _leave(" = %d", ret);
+ return ERR_PTR(ret);
+ }
+
++ /* parse the options */
++ if (options) {
++ ret = afs_super_parse_options(¶ms, options, &dev_name);
++ if (ret < 0)
++ goto error;
++ if (!dev_name) {
++ printk("kAFS: no volume name specified\n");
++ ret = -EINVAL;
++ goto error;
++ }
++ }
++
++ /* parse the device name */
++ ret = afs_volume_lookup(dev_name,
++ params.default_cell,
++ params.rwpath,
++ ¶ms.volume);
++ if (ret < 0)
++ goto error;
++
+ /* allocate a deviceless superblock */
+- sb = get_sb_nodev(fs_type, flags, &data, afs_fill_super);
+- if (IS_ERR(sb)) {
+- afscm_stop();
+- return sb;
++ sb = sget(fs_type, afs_test_super, set_anon_super, ¶ms);
++ if (IS_ERR(sb))
++ goto error;
++
++ sb->s_flags = flags;
++
++ ret = afs_fill_super(sb, ¶ms, flags & MS_VERBOSE ? 1 : 0);
++ if (ret < 0) {
++ up_write(&sb->s_umount);
++ deactivate_super(sb);
++ goto error;
+ }
++ sb->s_flags |= MS_ACTIVE;
+
+- _leave("");
++ afs_put_volume(params.volume);
++ afs_put_cell(params.default_cell);
++ _leave(" = %p", sb);
+ return sb;
++
++ error:
++ afs_put_volume(params.volume);
++ afs_put_cell(params.default_cell);
++ afscm_stop();
++ _leave(" = %d", ret);
++ return ERR_PTR(ret);
+ } /* end afs_get_sb() */
+
+ /*****************************************************************************/
+@@ -452,11 +382,7 @@
+
+ _enter("");
+
+- if (as) {
+- if (as->volume) afs_put_volume(as->volume);
+- }
+-
+- /* stop the cache manager */
++ afs_put_volume(as->volume);
+ afscm_stop();
+
+ _leave("");
+@@ -466,18 +392,21 @@
+ /*
+ * initialise an inode cache slab element prior to any use
+ */
+-static void afs_i_init_once(void *_vnode, kmem_cache_t *cachep, unsigned long flags)
++static void afs_i_init_once(void *_vnode, kmem_cache_t *cachep,
++ unsigned long flags)
+ {
+ afs_vnode_t *vnode = (afs_vnode_t *) _vnode;
+
+- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) {
+- memset(vnode,0,sizeof(*vnode));
++ if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
++ SLAB_CTOR_CONSTRUCTOR) {
++ memset(vnode, 0, sizeof(*vnode));
+ inode_init_once(&vnode->vfs_inode);
+ init_waitqueue_head(&vnode->update_waitq);
+ spin_lock_init(&vnode->lock);
+ INIT_LIST_HEAD(&vnode->cb_link);
+ INIT_LIST_HEAD(&vnode->cb_hash_link);
+- afs_timer_init(&vnode->cb_timeout,&afs_vnode_cb_timed_out_ops);
++ afs_timer_init(&vnode->cb_timeout,
++ &afs_vnode_cb_timed_out_ops);
+ }
+
+ } /* end afs_i_init_once() */
+@@ -490,16 +419,19 @@
+ {
+ afs_vnode_t *vnode;
+
+- vnode = (afs_vnode_t *) kmem_cache_alloc(afs_inode_cachep,SLAB_KERNEL);
++ vnode = (afs_vnode_t *)
++ kmem_cache_alloc(afs_inode_cachep, SLAB_KERNEL);
+ if (!vnode)
+ return NULL;
+
+- memset(&vnode->fid,0,sizeof(vnode->fid));
+- memset(&vnode->status,0,sizeof(vnode->status));
++ atomic_inc(&afs_count_active_inodes);
++
++ memset(&vnode->fid, 0, sizeof(vnode->fid));
++ memset(&vnode->status, 0, sizeof(vnode->status));
+
+- vnode->volume = NULL;
+- vnode->update_cnt = 0;
+- vnode->flags = 0;
++ vnode->volume = NULL;
++ vnode->update_cnt = 0;
++ vnode->flags = 0;
+
+ return &vnode->vfs_inode;
+ } /* end afs_alloc_inode() */
+@@ -510,6 +442,10 @@
+ */
+ static void afs_destroy_inode(struct inode *inode)
+ {
+- _enter("{%lu}",inode->i_ino);
++ _enter("{%lu}", inode->i_ino);
++
+ kmem_cache_free(afs_inode_cachep, AFS_FS_I(inode));
++
++ atomic_dec(&afs_count_active_inodes);
++
+ } /* end afs_destroy_inode() */
+Index: linux-2.6.0-test5/fs/afs/super.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/super.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/super.h 2003-09-27 11:38:36.020052504 +0800
+@@ -29,7 +29,7 @@
+ */
+ struct afs_super_info
+ {
+- afs_volume_t *volume; /* volume record */
++ struct afs_volume *volume; /* volume record */
+ char rwparent; /* T if parent is R/W AFS volume */
+ };
+
+Index: linux-2.6.0-test5/fs/afs/types.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/types.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/types.h 2003-09-27 11:38:36.022052200 +0800
+@@ -33,26 +33,13 @@
+ typedef struct afs_volume afs_volume_t;
+ typedef struct afs_volume_info afs_volume_info_t;
+
+-typedef struct afsc_cache afsc_cache_t;
+-typedef struct afsc_cache_cell afsc_cache_cell_t;
+-typedef struct afsc_cache_vldb afsc_cache_vldb_t;
+-typedef struct afsc_cell_record afsc_cell_record_t;
+-typedef struct afsc_inode afsc_inode_t;
+-typedef struct afsc_io afsc_io_t;
+-typedef struct afsc_io_subop afsc_io_subop_t;
+-typedef struct afsc_io_queue afsc_io_queue_t;
+-typedef struct afsc_super_block afsc_super_block_t;
+-typedef struct afsc_vldb_record afsc_vldb_record_t;
+-typedef struct afsc_vnode_catalogue afsc_vnode_catalogue_t;
+-typedef struct afsc_vnode_meta afsc_vnode_meta_t;
+-
+ typedef struct afsvl_dbentry afsvl_dbentry_t;
+
+ typedef enum {
+ AFSVL_RWVOL, /* read/write volume */
+ AFSVL_ROVOL, /* read-only volume */
+ AFSVL_BACKVOL, /* backup volume */
+-} afs_voltype_t;
++} __attribute__((packed)) afs_voltype_t;
+
+ extern const char *afs_voltypes[];
+
+Index: linux-2.6.0-test5/fs/afs/vlclient.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/vlclient.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/vlclient.c 2003-09-27 11:38:36.028051288 +0800
+@@ -176,8 +176,8 @@
+ /*
+ * look up a volume location database entry by name
+ */
+-int afs_rxvl_get_entry_by_name(afs_server_t *server, const char *volname,
+- afsc_vldb_record_t *entry)
++int afs_rxvl_get_entry_by_name(afs_server_t *server, const char *volname, unsigned volnamesz,
++ struct afs_cache_vlocation *entry)
+ {
+ DECLARE_WAITQUEUE(myself,current);
+
+@@ -189,29 +189,29 @@
+ int ret, loop;
+ u32 *bp, param[2], zero;
+
+- _enter(",%s,",volname);
++ _enter(",%*.*s,%u,", volnamesz, volnamesz, volname, volnamesz);
+
+- memset(entry,0,sizeof(*entry));
++ memset(entry, 0, sizeof(*entry));
+
+ /* get hold of the vlserver connection */
+- ret = afs_server_get_vlconn(server,&conn);
++ ret = afs_server_get_vlconn(server, &conn);
+ if (ret<0)
+ goto out;
+
+ /* create a call through that connection */
+- ret = rxrpc_create_call(conn,NULL,NULL,afs_rxvl_aemap,&call);
+- if (ret<0) {
+- printk("kAFS: Unable to create call: %d\n",ret);
++ ret = rxrpc_create_call(conn, NULL, NULL, afs_rxvl_aemap, &call);
++ if (ret < 0) {
++ printk("kAFS: Unable to create call: %d\n", ret);
+ goto out_put_conn;
+ }
+ call->app_opcode = VLGETENTRYBYNAME;
+
+ /* we want to get event notifications from the call */
+- add_wait_queue(&call->waitq,&myself);
++ add_wait_queue(&call->waitq, &myself);
+
+ /* marshall the parameters */
+- piov[1].iov_len = strlen(volname);
+- piov[1].iov_base = (char*)volname;
++ piov[1].iov_len = volnamesz;
++ piov[1].iov_base = (char*) volname;
+
+ zero = 0;
+ piov[2].iov_len = (4 - (piov[1].iov_len & 3)) & 3;
+@@ -224,16 +224,16 @@
+ piov[0].iov_base = param;
+
+ /* send the parameters to the server */
+- ret = rxrpc_call_write_data(call,3,piov,RXRPC_LAST_PACKET,GFP_NOFS,0,&sent);
++ ret = rxrpc_call_write_data(call, 3, piov, RXRPC_LAST_PACKET, GFP_NOFS, 0, &sent);
+ if (ret<0)
+ goto abort;
+
+ /* wait for the reply to completely arrive */
+- bp = rxrpc_call_alloc_scratch(call,384);
++ bp = rxrpc_call_alloc_scratch(call, 384);
+
+- ret = rxrpc_call_read_data(call,bp,384,RXRPC_CALL_READ_BLOCK|RXRPC_CALL_READ_ALL);
+- if (ret<0) {
+- if (ret==-ECONNABORTED) {
++ ret = rxrpc_call_read_data(call, bp, 384, RXRPC_CALL_READ_BLOCK|RXRPC_CALL_READ_ALL);
++ if (ret < 0) {
++ if (ret == -ECONNABORTED) {
+ ret = call->app_errno;
+ goto out_unwait;
+ }
+@@ -255,9 +255,9 @@
+
+ for (loop=0; loop<8; loop++) {
+ tmp = ntohl(*bp++);
+- if (tmp & AFS_VLSF_RWVOL ) entry->srvtmask[loop] |= AFSC_VOL_STM_RW;
+- if (tmp & AFS_VLSF_ROVOL ) entry->srvtmask[loop] |= AFSC_VOL_STM_RO;
+- if (tmp & AFS_VLSF_BACKVOL) entry->srvtmask[loop] |= AFSC_VOL_STM_BAK;
++ if (tmp & AFS_VLSF_RWVOL ) entry->srvtmask[loop] |= AFS_VOL_VTM_RW;
++ if (tmp & AFS_VLSF_ROVOL ) entry->srvtmask[loop] |= AFS_VOL_VTM_RO;
++ if (tmp & AFS_VLSF_BACKVOL) entry->srvtmask[loop] |= AFS_VOL_VTM_BAK;
+ }
+
+ entry->vid[0] = ntohl(*bp++);
+@@ -267,26 +267,26 @@
+ bp++; /* clone ID */
+
+ tmp = ntohl(*bp++); /* flags */
+- if (tmp & AFS_VLF_RWEXISTS ) entry->vidmask |= AFSC_VOL_STM_RW;
+- if (tmp & AFS_VLF_ROEXISTS ) entry->vidmask |= AFSC_VOL_STM_RO;
+- if (tmp & AFS_VLF_BACKEXISTS) entry->vidmask |= AFSC_VOL_STM_BAK;
++ if (tmp & AFS_VLF_RWEXISTS ) entry->vidmask |= AFS_VOL_VTM_RW;
++ if (tmp & AFS_VLF_ROEXISTS ) entry->vidmask |= AFS_VOL_VTM_RO;
++ if (tmp & AFS_VLF_BACKEXISTS) entry->vidmask |= AFS_VOL_VTM_BAK;
+
+ ret = -ENOMEDIUM;
+ if (!entry->vidmask)
+ goto abort;
+
+ /* success */
+- entry->ctime = get_seconds();
++ entry->rtime = get_seconds();
+ ret = 0;
+
+ out_unwait:
+ set_current_state(TASK_RUNNING);
+- remove_wait_queue(&call->waitq,&myself);
++ remove_wait_queue(&call->waitq, &myself);
+ rxrpc_put_call(call);
+ out_put_conn:
+ rxrpc_put_connection(conn);
+ out:
+- _leave(" = %d",ret);
++ _leave(" = %d", ret);
+ return ret;
+
+ abort:
+@@ -303,7 +303,7 @@
+ int afs_rxvl_get_entry_by_id(afs_server_t *server,
+ afs_volid_t volid,
+ afs_voltype_t voltype,
+- afsc_vldb_record_t *entry)
++ struct afs_cache_vlocation *entry)
+ {
+ DECLARE_WAITQUEUE(myself,current);
+
+@@ -375,9 +375,9 @@
+
+ for (loop=0; loop<8; loop++) {
+ tmp = ntohl(*bp++);
+- if (tmp & AFS_VLSF_RWVOL ) entry->srvtmask[loop] |= AFSC_VOL_STM_RW;
+- if (tmp & AFS_VLSF_ROVOL ) entry->srvtmask[loop] |= AFSC_VOL_STM_RO;
+- if (tmp & AFS_VLSF_BACKVOL) entry->srvtmask[loop] |= AFSC_VOL_STM_BAK;
++ if (tmp & AFS_VLSF_RWVOL ) entry->srvtmask[loop] |= AFS_VOL_VTM_RW;
++ if (tmp & AFS_VLSF_ROVOL ) entry->srvtmask[loop] |= AFS_VOL_VTM_RO;
++ if (tmp & AFS_VLSF_BACKVOL) entry->srvtmask[loop] |= AFS_VOL_VTM_BAK;
+ }
+
+ entry->vid[0] = ntohl(*bp++);
+@@ -387,9 +387,9 @@
+ bp++; /* clone ID */
+
+ tmp = ntohl(*bp++); /* flags */
+- if (tmp & AFS_VLF_RWEXISTS ) entry->vidmask |= AFSC_VOL_STM_RW;
+- if (tmp & AFS_VLF_ROEXISTS ) entry->vidmask |= AFSC_VOL_STM_RO;
+- if (tmp & AFS_VLF_BACKEXISTS) entry->vidmask |= AFSC_VOL_STM_BAK;
++ if (tmp & AFS_VLF_RWEXISTS ) entry->vidmask |= AFS_VOL_VTM_RW;
++ if (tmp & AFS_VLF_ROEXISTS ) entry->vidmask |= AFS_VOL_VTM_RO;
++ if (tmp & AFS_VLF_BACKEXISTS) entry->vidmask |= AFS_VOL_VTM_BAK;
+
+ ret = -ENOMEDIUM;
+ if (!entry->vidmask)
+@@ -401,13 +401,13 @@
+ entry->servers[1].s_addr = htonl(0xac101243);
+ entry->servers[2].s_addr = htonl(0xac10125b /*0xac10125b*/);
+
+- entry->srvtmask[0] = AFSC_VOL_STM_RO;
+- entry->srvtmask[1] = AFSC_VOL_STM_RO;
+- entry->srvtmask[2] = AFSC_VOL_STM_RO | AFSC_VOL_STM_RW;
++ entry->srvtmask[0] = AFS_VOL_VTM_RO;
++ entry->srvtmask[1] = AFS_VOL_VTM_RO;
++ entry->srvtmask[2] = AFS_VOL_VTM_RO | AFS_VOL_VTM_RW;
+ #endif
+
+ /* success */
+- entry->ctime = get_seconds();
++ entry->rtime = get_seconds();
+ ret = 0;
+
+ out_unwait:
+@@ -520,7 +520,7 @@
+ * attend to the asynchronous get VLDB entry by ID
+ */
+ int afs_rxvl_get_entry_by_id_async2(afs_async_op_t *op,
+- afsc_vldb_record_t *entry)
++ struct afs_cache_vlocation *entry)
+ {
+ unsigned *bp, tmp;
+ int loop, ret;
+@@ -550,9 +550,9 @@
+
+ for (loop=0; loop<8; loop++) {
+ tmp = ntohl(*bp++);
+- if (tmp & AFS_VLSF_RWVOL ) entry->srvtmask[loop] |= AFSC_VOL_STM_RW;
+- if (tmp & AFS_VLSF_ROVOL ) entry->srvtmask[loop] |= AFSC_VOL_STM_RO;
+- if (tmp & AFS_VLSF_BACKVOL) entry->srvtmask[loop] |= AFSC_VOL_STM_BAK;
++ if (tmp & AFS_VLSF_RWVOL ) entry->srvtmask[loop] |= AFS_VOL_VTM_RW;
++ if (tmp & AFS_VLSF_ROVOL ) entry->srvtmask[loop] |= AFS_VOL_VTM_RO;
++ if (tmp & AFS_VLSF_BACKVOL) entry->srvtmask[loop] |= AFS_VOL_VTM_BAK;
+ }
+
+ entry->vid[0] = ntohl(*bp++);
+@@ -562,9 +562,9 @@
+ bp++; /* clone ID */
+
+ tmp = ntohl(*bp++); /* flags */
+- if (tmp & AFS_VLF_RWEXISTS ) entry->vidmask |= AFSC_VOL_STM_RW;
+- if (tmp & AFS_VLF_ROEXISTS ) entry->vidmask |= AFSC_VOL_STM_RO;
+- if (tmp & AFS_VLF_BACKEXISTS) entry->vidmask |= AFSC_VOL_STM_BAK;
++ if (tmp & AFS_VLF_RWEXISTS ) entry->vidmask |= AFS_VOL_VTM_RW;
++ if (tmp & AFS_VLF_ROEXISTS ) entry->vidmask |= AFS_VOL_VTM_RO;
++ if (tmp & AFS_VLF_BACKEXISTS) entry->vidmask |= AFS_VOL_VTM_BAK;
+
+ ret = -ENOMEDIUM;
+ if (!entry->vidmask) {
+@@ -578,13 +578,13 @@
+ entry->servers[1].s_addr = htonl(0xac101243);
+ entry->servers[2].s_addr = htonl(0xac10125b /*0xac10125b*/);
+
+- entry->srvtmask[0] = AFSC_VOL_STM_RO;
+- entry->srvtmask[1] = AFSC_VOL_STM_RO;
+- entry->srvtmask[2] = AFSC_VOL_STM_RO | AFSC_VOL_STM_RW;
++ entry->srvtmask[0] = AFS_VOL_VTM_RO;
++ entry->srvtmask[1] = AFS_VOL_VTM_RO;
++ entry->srvtmask[2] = AFS_VOL_VTM_RO | AFS_VOL_VTM_RW;
+ #endif
+
+ /* success */
+- entry->ctime = get_seconds();
++ entry->rtime = get_seconds();
+ ret = 0;
+ goto done;
+ }
+@@ -626,7 +626,8 @@
+ case RXRPC_CSTATE_CLNT_GOT_REPLY:
+ if (call->app_read_count==0)
+ break;
+- printk("kAFS: Reply bigger than expected {cst=%u asyn=%d mark=%Zu rdy=%Zu pr=%u%s}",
++ printk("kAFS: Reply bigger than expected"
++ " {cst=%u asyn=%d mark=%Zu rdy=%Zu pr=%u%s}",
+ call->app_call_state,
+ call->app_async_read,
+ call->app_mark,
+Index: linux-2.6.0-test5/fs/afs/vlclient.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/vlclient.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/vlclient.h 2003-09-27 11:38:36.030050984 +0800
+@@ -46,7 +46,7 @@
+ };
+
+ /* maps to "struct vldbentry" in vvl-spec.pdf */
+-struct afsvl_dbentry {
++struct afs_vldbentry {
+ char name[65]; /* name of volume (including NUL char) */
+ afs_voltype_t type; /* volume type */
+ unsigned num_servers; /* num servers that hold instances of this vol */
+@@ -77,19 +77,20 @@
+ /* look up a volume location database entry by name */
+ extern int afs_rxvl_get_entry_by_name(afs_server_t *server,
+ const char *volname,
+- afsc_vldb_record_t *entry);
++ unsigned volnamesz,
++ struct afs_cache_vlocation *entry);
+
+ /* look up a volume location database entry by ID */
+ extern int afs_rxvl_get_entry_by_id(afs_server_t *server,
+ afs_volid_t volid,
+ afs_voltype_t voltype,
+- afsc_vldb_record_t *entry);
++ struct afs_cache_vlocation *entry);
+
+ extern int afs_rxvl_get_entry_by_id_async(afs_async_op_t *op,
+ afs_volid_t volid,
+ afs_voltype_t voltype);
+
+ extern int afs_rxvl_get_entry_by_id_async2(afs_async_op_t *op,
+- afsc_vldb_record_t *entry);
++ struct afs_cache_vlocation *entry);
+
+ #endif /* _LINUX_AFS_VLCLIENT_H */
+Index: linux-2.6.0-test5/fs/afs/vlocation.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/vlocation.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/vlocation.c 2003-09-27 11:38:36.037049920 +0800
+@@ -56,6 +56,19 @@
+ static afs_vlocation_t *afs_vlocation_update; /* VL currently being updated */
+ static spinlock_t afs_vlocation_update_lock = SPIN_LOCK_UNLOCKED; /* lock guarding update queue */
+
++#ifdef AFS_CACHING_SUPPORT
++static cachefs_match_val_t afs_vlocation_cache_match(void *target, const void *entry);
++static void afs_vlocation_cache_update(void *source, void *entry);
++
++struct cachefs_index_def afs_vlocation_cache_index_def = {
++ .name = "vldb",
++ .data_size = sizeof(struct afs_cache_vlocation),
++ .keys[0] = { CACHEFS_INDEX_KEYS_ASCIIZ, 64 },
++ .match = afs_vlocation_cache_match,
++ .update = afs_vlocation_cache_update,
++};
++#endif
++
+ /*****************************************************************************/
+ /*
+ * iterate through the VL servers in a cell until one of them admits knowing about the volume in
+@@ -64,21 +77,23 @@
+ */
+ static int afs_vlocation_access_vl_by_name(afs_vlocation_t *vlocation,
+ const char *name,
+- afsc_vldb_record_t *vldb)
++ unsigned namesz,
++ struct afs_cache_vlocation *vldb)
+ {
+ afs_server_t *server = NULL;
+ afs_cell_t *cell = vlocation->cell;
+ int count, ret;
+
+- _enter("%s,%s,",cell->name,name);
++ _enter("%s,%*.*s,%u", cell->name, namesz, namesz, name, namesz);
+
+ ret = -ENOMEDIUM;
+ for (count=cell->vl_naddrs; count>0; count--) {
+ _debug("CellServ[%hu]: %08x",
+- cell->vl_curr_svix,cell->vl_addrs[cell->vl_curr_svix].s_addr);
++ cell->vl_curr_svix,
++ cell->vl_addrs[cell->vl_curr_svix].s_addr);
+
+ /* try and create a server */
+- ret = afs_server_lookup(cell,&cell->vl_addrs[cell->vl_curr_svix],&server);
++ ret = afs_server_lookup(cell, &cell->vl_addrs[cell->vl_curr_svix], &server);
+ switch (ret) {
+ case 0:
+ break;
+@@ -90,7 +105,7 @@
+ }
+
+ /* attempt to access the VL server */
+- ret = afs_rxvl_get_entry_by_name(server,name,vldb);
++ ret = afs_rxvl_get_entry_by_name(server, name, namesz, vldb);
+ switch (ret) {
+ case 0:
+ afs_put_server(server);
+@@ -107,7 +122,7 @@
+ }
+ up_write(&server->sem);
+ afs_put_server(server);
+- if (ret==-ENOMEM || ret==-ENONET)
++ if (ret == -ENOMEM || ret == -ENONET)
+ goto out;
+ goto rotate;
+ case -ENOMEDIUM:
+@@ -140,21 +155,22 @@
+ static int afs_vlocation_access_vl_by_id(afs_vlocation_t *vlocation,
+ afs_volid_t volid,
+ afs_voltype_t voltype,
+- afsc_vldb_record_t *vldb)
++ struct afs_cache_vlocation *vldb)
+ {
+ afs_server_t *server = NULL;
+ afs_cell_t *cell = vlocation->cell;
+ int count, ret;
+
+- _enter("%s,%x,%d,",cell->name,volid,voltype);
++ _enter("%s,%x,%d,", cell->name, volid, voltype);
+
+ ret = -ENOMEDIUM;
+ for (count=cell->vl_naddrs; count>0; count--) {
+ _debug("CellServ[%hu]: %08x",
+- cell->vl_curr_svix,cell->vl_addrs[cell->vl_curr_svix].s_addr);
++ cell->vl_curr_svix,
++ cell->vl_addrs[cell->vl_curr_svix].s_addr);
+
+ /* try and create a server */
+- ret = afs_server_lookup(cell,&cell->vl_addrs[cell->vl_curr_svix],&server);
++ ret = afs_server_lookup(cell, &cell->vl_addrs[cell->vl_curr_svix], &server);
+ switch (ret) {
+ case 0:
+ break;
+@@ -166,7 +182,7 @@
+ }
+
+ /* attempt to access the VL server */
+- ret = afs_rxvl_get_entry_by_id(server,volid,voltype,vldb);
++ ret = afs_rxvl_get_entry_by_id(server, volid, voltype, vldb);
+ switch (ret) {
+ case 0:
+ afs_put_server(server);
+@@ -183,7 +199,7 @@
+ }
+ up_write(&server->sem);
+ afs_put_server(server);
+- if (ret==-ENOMEM || ret==-ENONET)
++ if (ret == -ENOMEM || ret == -ENONET)
+ goto out;
+ goto rotate;
+ case -ENOMEDIUM:
+@@ -216,74 +232,83 @@
+ * - lookup in the local cache if not able to find on the VL server
+ * - insert/update in the local cache if did get a VL response
+ */
+-int afs_vlocation_lookup(afs_cell_t *cell, const char *name, afs_vlocation_t **_vlocation)
++int afs_vlocation_lookup(afs_cell_t *cell, const char *name, unsigned namesz,
++ afs_vlocation_t **_vlocation)
+ {
+- afsc_vldb_record_t vldb;
++ struct afs_cache_vlocation vldb;
+ struct list_head *_p;
+ afs_vlocation_t *vlocation;
+ afs_voltype_t voltype;
+ afs_volid_t vid;
+ int active = 0, ret;
+
+- _enter(",%s,%s,",cell->name,name);
++ _enter("{%s},%*.*s,%u,", cell->name, namesz, namesz, name, namesz);
+
+- if (strlen(name)>sizeof(vlocation->vldb.name)) {
++ if (namesz > sizeof(vlocation->vldb.name)) {
+ _leave(" = -ENAMETOOLONG");
+ return -ENAMETOOLONG;
+ }
+
+ /* search the cell's active list first */
+- list_for_each(_p,&cell->vl_list) {
+- vlocation = list_entry(_p,afs_vlocation_t,link);
+- if (strncmp(vlocation->vldb.name,name,sizeof(vlocation->vldb.name))==0)
++ list_for_each(_p, &cell->vl_list) {
++ vlocation = list_entry(_p, afs_vlocation_t, link);
++ if (namesz < sizeof(vlocation->vldb.name) &&
++ vlocation->vldb.name[namesz] != '\0')
++ continue;
++
++ if (memcmp(vlocation->vldb.name, name, namesz) == 0)
+ goto found_in_memory;
+ }
+
+ /* search the cell's graveyard list second */
+ spin_lock(&cell->vl_gylock);
+- list_for_each(_p,&cell->vl_graveyard) {
+- vlocation = list_entry(_p,afs_vlocation_t,link);
+- if (strncmp(vlocation->vldb.name,name,sizeof(vlocation->vldb.name))==0)
++ list_for_each(_p, &cell->vl_graveyard) {
++ vlocation = list_entry(_p, afs_vlocation_t, link);
++ if (namesz < sizeof(vlocation->vldb.name) &&
++ vlocation->vldb.name[namesz] != '\0')
++ continue;
++
++ if (memcmp(vlocation->vldb.name, name, namesz) == 0)
+ goto found_in_graveyard;
+ }
+ spin_unlock(&cell->vl_gylock);
+
+ /* not in the cell's in-memory lists - create a new record */
+- vlocation = kmalloc(sizeof(afs_vlocation_t),GFP_KERNEL);
++ vlocation = kmalloc(sizeof(afs_vlocation_t), GFP_KERNEL);
+ if (!vlocation)
+ return -ENOMEM;
+
+- memset(vlocation,0,sizeof(afs_vlocation_t));
+- atomic_set(&vlocation->usage,1);
++ memset(vlocation, 0, sizeof(afs_vlocation_t));
++ atomic_set(&vlocation->usage, 1);
+ INIT_LIST_HEAD(&vlocation->link);
+ rwlock_init(&vlocation->lock);
+- strncpy(vlocation->vldb.name,name,sizeof(vlocation->vldb.name));
++ memcpy(vlocation->vldb.name, name, namesz);
+
+- afs_timer_init(&vlocation->timeout,&afs_vlocation_timer_ops);
+- afs_timer_init(&vlocation->upd_timer,&afs_vlocation_update_timer_ops);
+- afs_async_op_init(&vlocation->upd_op,&afs_vlocation_update_op_ops);
+-
+- INIT_LIST_HEAD(&vlocation->caches);
++ afs_timer_init(&vlocation->timeout, &afs_vlocation_timer_ops);
++ afs_timer_init(&vlocation->upd_timer, &afs_vlocation_update_timer_ops);
++ afs_async_op_init(&vlocation->upd_op, &afs_vlocation_update_op_ops);
+
+ afs_get_cell(cell);
+ vlocation->cell = cell;
+
+- list_add_tail(&vlocation->link,&cell->vl_list);
++ list_add_tail(&vlocation->link, &cell->vl_list);
+
+-#if 0
+- /* search local cache if wasn't in memory */
+- ret = afsc_lookup_vlocation(vlocation);
+- switch (ret) {
+- default: goto error; /* disk error */
+- case 0: goto found_in_cache; /* pulled from local cache into memory */
+- case -ENOENT: break; /* not in local cache */
+- }
++#ifdef AFS_CACHING_SUPPORT
++ /* we want to store it in the cache, plus it might already be encached */
++ cachefs_acquire_cookie(cell->cache,
++ &afs_volume_cache_index_def,
++ vlocation,
++ &vlocation->cache);
++
++ if (vlocation->valid)
++ goto found_in_cache;
+ #endif
+
+ /* try to look up an unknown volume in the cell VL databases by name */
+- ret = afs_vlocation_access_vl_by_name(vlocation,name,&vldb);
++ ret = afs_vlocation_access_vl_by_name(vlocation, name, namesz, &vldb);
+ if (ret<0) {
+- printk("kAFS: failed to locate '%s' in cell '%s'\n",name,cell->name);
++ printk("kAFS: failed to locate '%*.*s' in cell '%s'\n",
++ namesz, namesz, name, cell->name);
+ goto error;
+ }
+
+@@ -294,7 +319,7 @@
+ _debug("found in graveyard");
+ atomic_inc(&vlocation->usage);
+ list_del(&vlocation->link);
+- list_add_tail(&vlocation->link,&cell->vl_list);
++ list_add_tail(&vlocation->link, &cell->vl_list);
+ spin_unlock(&cell->vl_gylock);
+
+ afs_kafstimod_del_timer(&vlocation->timeout);
+@@ -308,30 +333,32 @@
+ active:
+ active = 1;
+
+-/* found_in_cache: */
++#ifdef AFS_CACHING_SUPPORT
++ found_in_cache:
++#endif
+ /* try to look up a cached volume in the cell VL databases by ID */
+ _debug("found in cache");
+
+ _debug("Locally Cached: %s %02x { %08x(%x) %08x(%x) %08x(%x) }",
+ vlocation->vldb.name,
+ vlocation->vldb.vidmask,
+- ntohl(vlocation->vldb.servers[0].s_addr),vlocation->vldb.srvtmask[0],
+- ntohl(vlocation->vldb.servers[1].s_addr),vlocation->vldb.srvtmask[1],
+- ntohl(vlocation->vldb.servers[2].s_addr),vlocation->vldb.srvtmask[2]
++ ntohl(vlocation->vldb.servers[0].s_addr), vlocation->vldb.srvtmask[0],
++ ntohl(vlocation->vldb.servers[1].s_addr), vlocation->vldb.srvtmask[1],
++ ntohl(vlocation->vldb.servers[2].s_addr), vlocation->vldb.srvtmask[2]
+ );
+
+ _debug("Vids: %08x %08x %08x",
+- vlocation->vldb.vid[0],vlocation->vldb.vid[1],vlocation->vldb.vid[2]);
++ vlocation->vldb.vid[0], vlocation->vldb.vid[1], vlocation->vldb.vid[2]);
+
+- if (vlocation->vldb.vidmask & AFSC_VOL_STM_RW) {
++ if (vlocation->vldb.vidmask & AFS_VOL_VTM_RW) {
+ vid = vlocation->vldb.vid[0];
+ voltype = AFSVL_RWVOL;
+ }
+- else if (vlocation->vldb.vidmask & AFSC_VOL_STM_RO) {
++ else if (vlocation->vldb.vidmask & AFS_VOL_VTM_RO) {
+ vid = vlocation->vldb.vid[1];
+ voltype = AFSVL_ROVOL;
+ }
+- else if (vlocation->vldb.vidmask & AFSC_VOL_STM_BAK) {
++ else if (vlocation->vldb.vidmask & AFS_VOL_VTM_BAK) {
+ vid = vlocation->vldb.vid[2];
+ voltype = AFSVL_BACKVOL;
+ }
+@@ -341,41 +368,44 @@
+ voltype = 0;
+ }
+
+- ret = afs_vlocation_access_vl_by_id(vlocation,vid,voltype,&vldb);
++ ret = afs_vlocation_access_vl_by_id(vlocation, vid, voltype, &vldb);
+ switch (ret) {
+ /* net error */
+ default:
+- printk("kAFS: failed to volume '%s' (%x) up in '%s': %d\n",
+- name,vid,cell->name,ret);
++ printk("kAFS: failed to volume '%*.*s' (%x) up in '%s': %d\n",
++ namesz, namesz, name, vid, cell->name, ret);
+ goto error;
+
+ /* pulled from local cache into memory */
+- case 0:
++ case 0:
+ goto found_on_vlserver;
+
+ /* uh oh... looks like the volume got deleted */
+ case -ENOMEDIUM:
+- printk("kAFS: volume '%s' (%x) does not exist '%s'\n",name,vid,cell->name);
++ printk("kAFS: volume '%*.*s' (%x) does not exist '%s'\n",
++ namesz, namesz, name, vid, cell->name);
+
+ /* TODO: make existing record unavailable */
+ goto error;
+ }
+
+ found_on_vlserver:
+- _debug("Done VL Lookup: %s %02x { %08x(%x) %08x(%x) %08x(%x) }",
+- name,
++ _debug("Done VL Lookup: %*.*s %02x { %08x(%x) %08x(%x) %08x(%x) }",
++ namesz, namesz, name,
+ vldb.vidmask,
+- ntohl(vldb.servers[0].s_addr),vldb.srvtmask[0],
+- ntohl(vldb.servers[1].s_addr),vldb.srvtmask[1],
+- ntohl(vldb.servers[2].s_addr),vldb.srvtmask[2]
++ ntohl(vldb.servers[0].s_addr), vldb.srvtmask[0],
++ ntohl(vldb.servers[1].s_addr), vldb.srvtmask[1],
++ ntohl(vldb.servers[2].s_addr), vldb.srvtmask[2]
+ );
+
+- _debug("Vids: %08x %08x %08x",vldb.vid[0],vldb.vid[1],vldb.vid[2]);
++ _debug("Vids: %08x %08x %08x", vldb.vid[0], vldb.vid[1], vldb.vid[2]);
+
+- if (strncmp(vldb.name,name,sizeof(vlocation->vldb.name))!=0)
+- printk("kAFS: name of volume '%s' changed to '%s' on server\n",name,vldb.name);
++ if ((namesz < sizeof(vlocation->vldb.name) && vlocation->vldb.name[namesz] != '\0') ||
++ memcmp(vldb.name, name, namesz) != 0)
++ printk("kAFS: name of volume '%*.*s' changed to '%s' on server\n",
++ namesz, namesz, name, vldb.name);
+
+- memcpy(&vlocation->vldb,&vldb,sizeof(vlocation->vldb));
++ memcpy(&vlocation->vldb, &vldb, sizeof(vlocation->vldb));
+
+ #if 0
+ /* add volume entry to local cache */
+@@ -384,7 +414,7 @@
+ goto error;
+ #endif
+
+- afs_kafstimod_add_timer(&vlocation->upd_timer,10*HZ);
++ afs_kafstimod_add_timer(&vlocation->upd_timer, 10*HZ);
+
+ *_vlocation = vlocation;
+ _leave(" = 0 (%p)",vlocation);
+@@ -397,10 +427,10 @@
+ }
+ else {
+ list_del(&vlocation->link);
+- afs_put_cell(vlocation->cell);
+-#if 0
+- afs_put_cache(vlocation->cache);
++#ifdef AFS_CACHING_SUPPORT
++ cachefs_relinquish_cookie(vlocation->cache, 0);
+ #endif
++ afs_put_cell(vlocation->cell);
+ kfree(vlocation);
+ }
+ }
+@@ -414,12 +444,17 @@
+ * finish using a volume location record
+ * - caller must have cell->vol_sem write-locked
+ */
+-void __afs_put_vlocation(afs_vlocation_t *vlocation)
++void __afs_put_vlocation(struct afs_vlocation *vlocation)
+ {
+- afs_cell_t *cell = vlocation->cell;
++ struct afs_cell *cell;
++
++ if (!vlocation)
++ return;
+
+ _enter("%s",vlocation->vldb.name);
+
++ cell = vlocation->cell;
++
+ /* sanity check */
+ if (atomic_read(&vlocation->usage)<=0)
+ BUG();
+@@ -453,11 +488,13 @@
+ */
+ void afs_put_vlocation(afs_vlocation_t *vlocation)
+ {
+- afs_cell_t *cell = vlocation->cell;
++ if (vlocation) {
++ struct afs_cell *cell = vlocation->cell;
+
+- down_write(&cell->vl_sem);
+- __afs_put_vlocation(vlocation);
+- up_write(&cell->vl_sem);
++ down_write(&cell->vl_sem);
++ __afs_put_vlocation(vlocation);
++ up_write(&cell->vl_sem);
++ }
+ } /* end afs_put_vlocation() */
+
+ /*****************************************************************************/
+@@ -489,10 +526,10 @@
+ }
+
+ /* we can now destroy it properly */
+- afs_put_cell(cell);
+-#if 0
+- afs_put_cache(vlocation->cache);
++#ifdef AFS_CACHING_SUPPORT
++ cachefs_relinquish_cookie(vlocation->cache,0);
+ #endif
++ afs_put_cell(cell);
+
+ kfree(vlocation);
+
+@@ -513,15 +550,15 @@
+ vlocation->vldb.name,vlocation->upd_first_svix,vlocation->upd_curr_svix);
+
+ /* try to look up a cached volume in the cell VL databases by ID */
+- if (vlocation->vldb.vidmask & AFSC_VOL_STM_RW) {
++ if (vlocation->vldb.vidmask & AFS_VOL_VTM_RW) {
+ vid = vlocation->vldb.vid[0];
+ voltype = AFSVL_RWVOL;
+ }
+- else if (vlocation->vldb.vidmask & AFSC_VOL_STM_RO) {
++ else if (vlocation->vldb.vidmask & AFS_VOL_VTM_RO) {
+ vid = vlocation->vldb.vid[1];
+ voltype = AFSVL_ROVOL;
+ }
+- else if (vlocation->vldb.vidmask & AFSC_VOL_STM_BAK) {
++ else if (vlocation->vldb.vidmask & AFS_VOL_VTM_BAK) {
+ vid = vlocation->vldb.vid[2];
+ voltype = AFSVL_BACKVOL;
+ }
+@@ -571,10 +608,8 @@
+ printk("kAFS: Abandoning VL update '%s': %d\n",vlocation->vldb.name,ret);
+
+ /* discard the server record */
+- if (vlocation->upd_op.server) {
+- afs_put_server(vlocation->upd_op.server);
+- vlocation->upd_op.server = NULL;
+- }
++ afs_put_server(vlocation->upd_op.server);
++ vlocation->upd_op.server = NULL;
+
+ spin_lock(&afs_vlocation_update_lock);
+ afs_vlocation_update = NULL;
+@@ -669,7 +704,7 @@
+ */
+ static void afs_vlocation_update_attend(afs_async_op_t *op)
+ {
+- afsc_vldb_record_t vldb;
++ struct afs_cache_vlocation vldb;
+ afs_vlocation_t *vlocation = list_entry(op,afs_vlocation_t,upd_op);
+ unsigned tmp;
+ int ret;
+@@ -762,11 +797,9 @@
+ try_next:
+ vlocation->upd_busy_cnt = 0;
+
+- if (vlocation->upd_op.server) {
+- /* discard the server record */
+- afs_put_server(vlocation->upd_op.server);
+- vlocation->upd_op.server = NULL;
+- }
++ /* discard the server record */
++ afs_put_server(vlocation->upd_op.server);
++ vlocation->upd_op.server = NULL;
+
+ tmp = vlocation->cell->vl_naddrs;
+ if (tmp==0)
+@@ -822,3 +855,68 @@
+
+ _leave("");
+ } /* end afs_vlocation_update_discard() */
++
++/*****************************************************************************/
++/*
++ * match a VLDB record stored in the cache
++ * - may also load target from entry
++ */
++#ifdef AFS_CACHING_SUPPORT
++static cachefs_match_val_t afs_vlocation_cache_match(void *target,
++ const void *entry)
++{
++ const struct afs_cache_vlocation *vldb = entry;
++ struct afs_vlocation *vlocation = target;
++
++ _enter("{%s},{%s}", vlocation->vldb.name, vldb->name);
++
++ if (strncmp(vlocation->vldb.name,
++ vldb->name,
++ sizeof(vldb->name)) == 0) {
++ if (!vlocation->valid ||
++ vlocation->vldb.rtime == vldb->rtime) {
++ struct_cpy(&vlocation->vldb, vldb);
++ vlocation->valid = 1;
++ _leave(" = SUCCESS [c->m]");
++ return CACHEFS_MATCH_SUCCESS;
++ }
++ /* need to update cache if cached info differs */
++ else if (memcmp(&vlocation->vldb, vldb, sizeof(*vldb)) != 0) {
++ /* delete if VIDs for this name differ */
++ if (memcmp(&vlocation->vldb.vid,
++ &vldb->vid,
++ sizeof(vldb->vid)) != 0) {
++ _leave(" = DELETE");
++ return CACHEFS_MATCH_SUCCESS_DELETE;
++ }
++
++ _leave(" = UPDATE");
++ return CACHEFS_MATCH_SUCCESS_UPDATE;
++ }
++ else {
++ _leave(" = SUCCESS");
++ return CACHEFS_MATCH_SUCCESS;
++ }
++ }
++
++ _leave(" = FAILED");
++ return CACHEFS_MATCH_FAILED;
++} /* end afs_vlocation_cache_match() */
++#endif
++
++/*****************************************************************************/
++/*
++ * update a VLDB record stored in the cache
++ */
++#ifdef AFS_CACHING_SUPPORT
++static void afs_vlocation_cache_update(void *source, void *entry)
++{
++ struct afs_cache_vlocation *vldb = entry;
++ struct afs_vlocation *vlocation = source;
++
++ _enter("");
++
++ struct_cpy(vldb,&vlocation->vldb);
++
++} /* end afs_vlocation_cache_update() */
++#endif
+Index: linux-2.6.0-test5/fs/afs/vnode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/vnode.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/vnode.c 2003-09-27 11:38:36.040049464 +0800
+@@ -29,6 +29,19 @@
+ .timed_out = afs_vnode_cb_timed_out,
+ };
+
++#ifdef AFS_CACHING_SUPPORT
++static cachefs_match_val_t afs_vnode_cache_match(void *target, const void *entry);
++static void afs_vnode_cache_update(void *source, void *entry);
++
++struct cachefs_index_def afs_vnode_cache_index_def = {
++ .name = "vnode",
++ .data_size = sizeof(struct afs_cache_vnode),
++ .keys[0] = { CACHEFS_INDEX_KEYS_BIN, 4 },
++ .match = afs_vnode_cache_match,
++ .update = afs_vnode_cache_update,
++};
++#endif
++
+ /*****************************************************************************/
+ /*
+ * handle a callback timing out
+@@ -61,8 +74,7 @@
+
+ spin_unlock(&vnode->lock);
+
+- if (oldserver)
+- afs_put_server(oldserver);
++ afs_put_server(oldserver);
+
+ _leave("");
+ } /* end afs_vnode_cb_timed_out() */
+@@ -126,8 +138,7 @@
+
+ wake_up_all(&vnode->update_waitq);
+
+- if (oldserver)
+- afs_put_server(oldserver);
++ afs_put_server(oldserver);
+
+ _leave("");
+
+@@ -272,7 +283,7 @@
+ /*****************************************************************************/
+ /*
+ * break any outstanding callback on a vnode
+- * - only relevant to server that issued it
++ * - only relevent to server that issued it
+ */
+ int afs_vnode_give_up_callback(afs_vnode_t *vnode)
+ {
+@@ -314,3 +325,56 @@
+ _leave(" = %d",ret);
+ return ret;
+ } /* end afs_vnode_give_up_callback() */
++
++/*****************************************************************************/
++/*
++ * match a vnode record stored in the cache
++ */
++#ifdef AFS_CACHING_SUPPORT
++static cachefs_match_val_t afs_vnode_cache_match(void *target, const void *entry)
++{
++ const struct afs_cache_vnode *cvnode = entry;
++ struct afs_vnode *vnode = target;
++
++ _enter("{%x,%x,%Lx},{%x,%x,%Lx}",
++ vnode->fid.vnode,
++ vnode->fid.unique,
++ vnode->status.version,
++ cvnode->vnode_id,
++ cvnode->vnode_unique,
++ cvnode->data_version);
++
++ if (vnode->fid.vnode != cvnode->vnode_id) {
++ _leave(" = FAILED");
++ return CACHEFS_MATCH_FAILED;
++ }
++
++ if (vnode->fid.unique != cvnode->vnode_unique ||
++ vnode->status.version != cvnode->data_version) {
++ _leave(" = DELETE");
++ return CACHEFS_MATCH_SUCCESS_DELETE;
++ }
++
++ _leave(" = SUCCESS");
++ return CACHEFS_MATCH_SUCCESS;
++} /* end afs_vnode_cache_match() */
++#endif
++
++/*****************************************************************************/
++/*
++ * update a vnode record stored in the cache
++ */
++#ifdef AFS_CACHING_SUPPORT
++static void afs_vnode_cache_update(void *source, void *entry)
++{
++ struct afs_cache_vnode *cvnode = entry;
++ struct afs_vnode *vnode = source;
++
++ _enter("");
++
++ cvnode->vnode_id = vnode->fid.vnode;
++ cvnode->vnode_unique = vnode->fid.unique;
++ cvnode->data_version = vnode->status.version;
++
++} /* end afs_vnode_cache_update() */
++#endif
+Index: linux-2.6.0-test5/fs/afs/vnode.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/vnode.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/vnode.h 2003-09-27 11:38:36.042049160 +0800
+@@ -15,6 +15,7 @@
+ #include <linux/fs.h>
+ #include "server.h"
+ #include "kafstimod.h"
++#include "cache.h"
+
+ #ifdef __KERNEL__
+
+@@ -22,16 +23,33 @@
+
+ /*****************************************************************************/
+ /*
++ * vnode catalogue entry
++ */
++struct afs_cache_vnode
++{
++ afs_vnodeid_t vnode_id; /* vnode ID */
++ unsigned vnode_unique; /* vnode ID uniquifier */
++ afs_dataversion_t data_version; /* data version */
++};
++
++#ifdef AFS_CACHING_SUPPORT
++extern struct cachefs_index_def afs_vnode_cache_index_def;
++#endif
++
++/*****************************************************************************/
++/*
+ * AFS inode private data
+ */
+ struct afs_vnode
+ {
+ struct inode vfs_inode; /* the VFS's inode record */
+
+- afs_volume_t *volume; /* volume on which vnode resides */
+- afs_fid_t fid; /* the file identifier for this inode */
+- afs_file_status_t status; /* AFS status info for this file */
+- unsigned nix; /* vnode index in cache */
++ struct afs_volume *volume; /* volume on which vnode resides */
++ struct afs_fid fid; /* the file identifier for this inode */
++ struct afs_file_status status; /* AFS status info for this file */
++#ifdef AFS_CACHING_SUPPORT
++ struct cachefs_cookie *cache; /* caching cookie */
++#endif
+
+ wait_queue_head_t update_waitq; /* status fetch waitqueue */
+ unsigned update_cnt; /* number of outstanding ops that will update the
+@@ -43,10 +61,10 @@
+ #define AFS_VNODE_MOUNTPOINT 0x00000004 /* set if vnode is a mountpoint symlink */
+
+ /* outstanding callback notification on this file */
+- afs_server_t *cb_server; /* server that made the current promise */
++ struct afs_server *cb_server; /* server that made the current promise */
+ struct list_head cb_link; /* link in server's promises list */
+ struct list_head cb_hash_link; /* link in master callback hash */
+- afs_timer_t cb_timeout; /* timeout on promise */
++ struct afs_timer cb_timeout; /* timeout on promise */
+ unsigned cb_version; /* callback version */
+ unsigned cb_expiry; /* callback expiry time */
+ afs_callback_type_t cb_type; /* type of callback */
+Index: linux-2.6.0-test5/fs/afs/volume.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/volume.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/volume.c 2003-09-27 11:38:36.046048552 +0800
+@@ -16,7 +16,9 @@
+ #include <linux/fs.h>
+ #include <linux/pagemap.h>
+ #include "volume.h"
++#include "vnode.h"
+ #include "cell.h"
++#include "cache.h"
+ #include "cmservice.h"
+ #include "fsclient.h"
+ #include "vlclient.h"
+@@ -24,6 +26,20 @@
+
+ const char *afs_voltypes[] = { "R/W", "R/O", "BAK" };
+
++#ifdef AFS_CACHING_SUPPORT
++static cachefs_match_val_t afs_volume_cache_match(void *target, const void *entry);
++static void afs_volume_cache_update(void *source, void *entry);
++
++struct cachefs_index_def afs_volume_cache_index_def = {
++ .name = "volume",
++ .data_size = sizeof(struct afs_cache_vhash),
++ .keys[0] = { CACHEFS_INDEX_KEYS_BIN, 1 },
++ .keys[1] = { CACHEFS_INDEX_KEYS_BIN, 1 },
++ .match = afs_volume_cache_match,
++ .update = afs_volume_cache_update,
++};
++#endif
++
+ /*****************************************************************************/
+ /*
+ * lookup a volume by name
+@@ -43,19 +59,19 @@
+ * - Rule 2: If parent volume is R/O, then mount R/O volume by preference, R/W if not available
+ * - Rule 3: If parent volume is R/W, then only mount R/W volume unless explicitly told otherwise
+ */
+-int afs_volume_lookup(const char *name, int rwparent, afs_volume_t **_volume)
++int afs_volume_lookup(const char *name, struct afs_cell *cell, int rwpath,
++ afs_volume_t **_volume)
+ {
+- afs_vlocation_t *vlocation = NULL;
++ struct afs_vlocation *vlocation = NULL;
++ struct afs_volume *volume = NULL;
+ afs_voltype_t type;
+- afs_volume_t *volume = NULL;
+- afs_cell_t *cell = NULL;
+- char *cellname, *volname, *suffix;
++ const char *cellname, *volname, *suffix;
+ char srvtmask;
+- int force, ret, loop;
++ int force, ret, loop, cellnamesz, volnamesz;
+
+- _enter(",%s,",name);
++ _enter("%s,,%d,", name, rwpath);
+
+- if (!name || (name[0]!='%' && name[0]!='#') || !name[1]) {
++ if (!name || (name[0] != '%' && name[0] != '#') || !name[1]) {
+ printk("kAFS: unparsable volume name\n");
+ return -EINVAL;
+ }
+@@ -64,24 +80,22 @@
+ force = 0;
+ type = AFSVL_ROVOL;
+
+- if (rwparent || name[0]=='%') {
++ if (rwpath || name[0] == '%') {
+ type = AFSVL_RWVOL;
+ force = 1;
+ }
+
+- suffix = strrchr(name,'.');
++ suffix = strrchr(name, '.');
+ if (suffix) {
+- if (strcmp(suffix,".readonly")==0) {
++ if (strcmp(suffix, ".readonly") == 0) {
+ type = AFSVL_ROVOL;
+ force = 1;
+ }
+- else if (strcmp(suffix,".backup")==0) {
++ else if (strcmp(suffix, ".backup") == 0) {
+ type = AFSVL_BACKVOL;
+ force = 1;
+ }
+- else if (suffix[1]==0) {
+- *suffix = 0;
+- suffix = NULL;
++ else if (suffix[1] == 0) {
+ }
+ else {
+ suffix = NULL;
+@@ -90,38 +104,45 @@
+
+ /* split the cell and volume names */
+ name++;
+- volname = strchr(name,':');
++ volname = strchr(name, ':');
+ if (volname) {
+- *volname++ = 0;
+ cellname = name;
++ cellnamesz = volname - name;
+ }
+ else {
+ volname = name;
+ cellname = NULL;
++ cellnamesz = 0;
+ }
+
+- _debug("CELL:%s VOLUME:%s SUFFIX:%s TYPE:%d%s",
+- cellname,volname,suffix?:"-",type,force?" FORCE":"");
++ volnamesz = suffix ? suffix - volname : strlen(volname);
+
+- /* lookup the cell record */
+- ret = afs_cell_lookup(cellname,&cell);
+- if (ret<0)
+- printk("kAFS: unable to lookup cell '%s'\n",cellname?:"");
++ _debug("CELL:%*.*s [%p] VOLUME:%*.*s SUFFIX:%s TYPE:%d%s",
++ cellnamesz, cellnamesz, cellname ?: "", cell,
++ volnamesz, volnamesz, volname, suffix ?: "-",
++ type,
++ force ? " FORCE" : "");
+
+- if (cellname) volname[-1] = ':';
+- if (ret<0)
+- goto error;
++ /* lookup the cell record */
++ if (cellname || !cell) {
++ ret = afs_cell_lookup(cellname, cellnamesz, &cell);
++ if (ret<0) {
++ printk("kAFS: unable to lookup cell '%s'\n", cellname ?: "");
++ goto error;
++ }
++ }
++ else {
++ afs_get_cell(cell);
++ }
+
+ /* lookup the volume location record */
+- if (suffix) *suffix = 0;
+- ret = afs_vlocation_lookup(cell,volname,&vlocation);
+- if (suffix) *suffix = '.';
+- if (ret<0)
++ ret = afs_vlocation_lookup(cell, volname, volnamesz, &vlocation);
++ if (ret < 0)
+ goto error;
+
+ /* make the final decision on the type we want */
+ ret = -ENOMEDIUM;
+- if (force && !(vlocation->vldb.vidmask & (1<<type)))
++ if (force && !(vlocation->vldb.vidmask & (1 << type)))
+ goto error;
+
+ srvtmask = 0;
+@@ -129,13 +150,13 @@
+ srvtmask |= vlocation->vldb.srvtmask[loop];
+
+ if (force) {
+- if (!(srvtmask & (1 <<type)))
++ if (!(srvtmask & (1 << type)))
+ goto error;
+ }
+- else if (srvtmask & AFSC_VOL_STM_RO) {
++ else if (srvtmask & AFS_VOL_VTM_RO) {
+ type = AFSVL_ROVOL;
+ }
+- else if (srvtmask & AFSC_VOL_STM_RW) {
++ else if (srvtmask & AFS_VOL_VTM_RW) {
+ type = AFSVL_RWVOL;
+ }
+ else {
+@@ -156,16 +177,16 @@
+ _debug("creating new volume record");
+
+ ret = -ENOMEM;
+- volume = kmalloc(sizeof(afs_volume_t),GFP_KERNEL);
++ volume = kmalloc(sizeof(afs_volume_t), GFP_KERNEL);
+ if (!volume)
+ goto error_up;
+
+- memset(volume,0,sizeof(afs_volume_t));
+- atomic_set(&volume->usage,1);
+- volume->type = type;
+- volume->type_force = force;
+- volume->cell = cell;
+- volume->vid = vlocation->vldb.vid[type];
++ memset(volume, 0, sizeof(afs_volume_t));
++ atomic_set(&volume->usage, 1);
++ volume->type = type;
++ volume->type_force = force;
++ volume->cell = cell;
++ volume->vid = vlocation->vldb.vid[type];
+
+ init_rwsem(&volume->server_sem);
+
+@@ -183,15 +204,20 @@
+ }
+
+ /* attach the cache and volume location */
+-#if 0
+- afs_get_cache(cache); volume->cache = cache;
++#ifdef AFS_CACHING_SUPPORT
++ cachefs_acquire_cookie(vlocation->cache,
++ &afs_vnode_cache_index_def,
++ volume,
++ &volume->cache);
+ #endif
+- afs_get_vlocation(vlocation); volume->vlocation = vlocation;
++
++ afs_get_vlocation(vlocation);
++ volume->vlocation = vlocation;
+
+ vlocation->vols[type] = volume;
+
+ success:
+- _debug("kAFS selected %s volume %08x",afs_voltypes[volume->type],volume->vid);
++ _debug("kAFS selected %s volume %08x", afs_voltypes[volume->type], volume->vid);
+ *_volume = volume;
+ ret = 0;
+
+@@ -199,18 +225,17 @@
+ error_up:
+ up_write(&cell->vl_sem);
+ error:
+- if (vlocation) afs_put_vlocation(vlocation);
+- if (cell) afs_put_cell(cell);
++ afs_put_vlocation(vlocation);
++ afs_put_cell(cell);
+
+- _leave(" = %d (%p)",ret,volume);
++ _leave(" = %d (%p)", ret, volume);
+ return ret;
+
+ error_discard:
+ up_write(&cell->vl_sem);
+
+ for (loop=volume->nservers-1; loop>=0; loop--)
+- if (volume->servers[loop])
+- afs_put_server(volume->servers[loop]);
++ afs_put_server(volume->servers[loop]);
+
+ kfree(volume);
+ goto error;
+@@ -225,6 +250,9 @@
+ afs_vlocation_t *vlocation;
+ int loop;
+
++ if (!volume)
++ return;
++
+ _enter("%p",volume);
+
+ vlocation = volume->vlocation;
+@@ -246,16 +274,14 @@
+
+ up_write(&vlocation->cell->vl_sem);
+
+- afs_put_vlocation(vlocation);
+-
+ /* finish cleaning up the volume */
+-#if 0
+- if (volume->cache) afs_put_cache(volume->cache);
++#ifdef AFS_CACHING_SUPPORT
++ cachefs_relinquish_cookie(volume->cache,0);
+ #endif
++ afs_put_vlocation(vlocation);
+
+ for (loop=volume->nservers-1; loop>=0; loop--)
+- if (volume->servers[loop])
+- afs_put_server(volume->servers[loop]);
++ afs_put_server(volume->servers[loop]);
+
+ kfree(volume);
+
+@@ -428,3 +454,42 @@
+ return 0;
+
+ } /* end afs_volume_release_fileserver() */
++
++/*****************************************************************************/
++/*
++ * match a volume hash record stored in the cache
++ */
++#ifdef AFS_CACHING_SUPPORT
++static cachefs_match_val_t afs_volume_cache_match(void *target, const void *entry)
++{
++ const struct afs_cache_vhash *vhash = entry;
++ struct afs_volume *volume = target;
++
++ _enter("{%u},{%u}", volume->type, vhash->vtype);
++
++ if (volume->type == vhash->vtype) {
++ _leave(" = SUCCESS");
++ return CACHEFS_MATCH_SUCCESS;
++ }
++
++ _leave(" = FAILED");
++ return CACHEFS_MATCH_FAILED;
++} /* end afs_volume_cache_match() */
++#endif
++
++/*****************************************************************************/
++/*
++ * update a volume hash record stored in the cache
++ */
++#ifdef AFS_CACHING_SUPPORT
++static void afs_volume_cache_update(void *source, void *entry)
++{
++ struct afs_cache_vhash *vhash = entry;
++ struct afs_volume *volume = source;
++
++ _enter("");
++
++ vhash->vtype = volume->type;
++
++} /* end afs_volume_cache_update() */
++#endif
+Index: linux-2.6.0-test5/fs/afs/volume.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/volume.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/volume.h 2003-09-27 11:38:36.048048248 +0800
+@@ -16,7 +16,7 @@
+ #include "fsclient.h"
+ #include "kafstimod.h"
+ #include "kafsasyncd.h"
+-#include "cache-layout.h"
++#include "cache.h"
+
+ #define __packed __attribute__((packed))
+
+@@ -30,21 +30,60 @@
+
+ /*****************************************************************************/
+ /*
++ * entry in the cached volume location catalogue
++ */
++struct afs_cache_vlocation
++{
++ uint8_t name[64]; /* volume name (lowercase, padded with NULs) */
++ uint8_t nservers; /* number of entries used in servers[] */
++ uint8_t vidmask; /* voltype mask for vid[] */
++ uint8_t srvtmask[8]; /* voltype masks for servers[] */
++#define AFS_VOL_VTM_RW 0x01 /* R/W version of the volume is available (on this server) */
++#define AFS_VOL_VTM_RO 0x02 /* R/O version of the volume is available (on this server) */
++#define AFS_VOL_VTM_BAK 0x04 /* backup version of the volume is available (on this server) */
++
++ afs_volid_t vid[3]; /* volume IDs for R/W, R/O and Bak volumes */
++ struct in_addr servers[8]; /* fileserver addresses */
++ time_t rtime; /* last retrieval time */
++};
++
++#ifdef AFS_CACHING_SUPPORT
++extern struct cachefs_index_def afs_vlocation_cache_index_def;
++#endif
++
++/*****************************************************************************/
++/*
++ * volume -> vnode hash table entry
++ */
++struct afs_cache_vhash
++{
++ afs_voltype_t vtype; /* which volume variation */
++ uint8_t hash_bucket; /* which hash bucket this represents */
++} __attribute__((packed));
++
++#ifdef AFS_CACHING_SUPPORT
++extern struct cachefs_index_def afs_volume_cache_index_def;
++#endif
++
++/*****************************************************************************/
++/*
+ * AFS volume location record
+ */
+ struct afs_vlocation
+ {
+ atomic_t usage;
+ struct list_head link; /* link in cell volume location list */
+- afs_timer_t timeout; /* decaching timer */
+- afs_cell_t *cell; /* cell to which volume belongs */
+- struct list_head caches; /* backing caches */
+- afsc_vldb_record_t vldb; /* volume information DB record */
++ struct afs_timer timeout; /* decaching timer */
++ struct afs_cell *cell; /* cell to which volume belongs */
++#ifdef AFS_CACHING_SUPPORT
++ struct cachefs_cookie *cache; /* caching cookie */
++#endif
++ struct afs_cache_vlocation vldb; /* volume information DB record */
+ struct afs_volume *vols[3]; /* volume access record pointer (index by type) */
+ rwlock_t lock; /* access lock */
+ unsigned long read_jif; /* time at which last read from vlserver */
+- afs_timer_t upd_timer; /* update timer */
+- afs_async_op_t upd_op; /* update operation */
++ struct afs_timer upd_timer; /* update timer */
++ struct afs_async_op upd_op; /* update operation */
+ afs_vlocation_upd_t upd_state; /* update state */
+ unsigned short upd_first_svix; /* first server index during update */
+ unsigned short upd_curr_svix; /* current server index during update */
+@@ -53,13 +92,16 @@
+ unsigned short valid; /* T if valid */
+ };
+
+-extern int afs_vlocation_lookup(afs_cell_t *cell, const char *name, afs_vlocation_t **_vlocation);
++extern int afs_vlocation_lookup(struct afs_cell *cell,
++ const char *name,
++ unsigned namesz,
++ struct afs_vlocation **_vlocation);
+
+ #define afs_get_vlocation(V) do { atomic_inc(&(V)->usage); } while(0)
+
+-extern void __afs_put_vlocation(afs_vlocation_t *vlocation);
+-extern void afs_put_vlocation(afs_vlocation_t *vlocation);
+-extern void afs_vlocation_do_timeout(afs_vlocation_t *vlocation);
++extern void __afs_put_vlocation(struct afs_vlocation *vlocation);
++extern void afs_put_vlocation(struct afs_vlocation *vlocation);
++extern void afs_vlocation_do_timeout(struct afs_vlocation *vlocation);
+
+ /*****************************************************************************/
+ /*
+@@ -68,25 +110,34 @@
+ struct afs_volume
+ {
+ atomic_t usage;
+- afs_cell_t *cell; /* cell to which belongs (unrefd ptr) */
+- afs_vlocation_t *vlocation; /* volume location */
++ struct afs_cell *cell; /* cell to which belongs (unrefd ptr) */
++ struct afs_vlocation *vlocation; /* volume location */
++#ifdef AFS_CACHING_SUPPORT
++ struct cachefs_cookie *cache; /* caching cookie */
++#endif
+ afs_volid_t vid; /* volume ID */
+ afs_voltype_t __packed type; /* type of volume */
+ char type_force; /* force volume type (suppress R/O -> R/W) */
+ unsigned short nservers; /* number of server slots filled */
+ unsigned short rjservers; /* number of servers discarded due to -ENOMEDIUM */
+- afs_server_t *servers[8]; /* servers on which volume resides (ordered) */
++ struct afs_server *servers[8]; /* servers on which volume resides (ordered) */
+ struct rw_semaphore server_sem; /* lock for accessing current server */
+ };
+
+-extern int afs_volume_lookup(const char *name, int ro, afs_volume_t **_volume);
++extern int afs_volume_lookup(const char *name,
++ struct afs_cell *cell,
++ int rwpath,
++ struct afs_volume **_volume);
+
+ #define afs_get_volume(V) do { atomic_inc(&(V)->usage); } while(0)
+
+-extern void afs_put_volume(afs_volume_t *volume);
++extern void afs_put_volume(struct afs_volume *volume);
+
+-extern int afs_volume_pick_fileserver(afs_volume_t *volume, afs_server_t **_server);
++extern int afs_volume_pick_fileserver(struct afs_volume *volume,
++ struct afs_server **_server);
+
+-extern int afs_volume_release_fileserver(afs_volume_t *volume, afs_server_t *server, int result);
++extern int afs_volume_release_fileserver(struct afs_volume *volume,
++ struct afs_server *server,
++ int result);
+
+ #endif /* _LINUX_AFS_VOLUME_H */
+Index: linux-2.6.0-test5/fs/aio.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/aio.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/aio.c 2003-09-27 11:38:36.057046880 +0800
+@@ -28,6 +28,8 @@
+ #include <linux/module.h>
+ #include <linux/highmem.h>
+ #include <linux/workqueue.h>
++#include <linux/writeback.h>
++#include <linux/pagemap.h>
+
+ #include <asm/kmap_types.h>
+ #include <asm/uaccess.h>
+@@ -39,6 +41,9 @@
+ #define dprintk(x...) do { ; } while (0)
+ #endif
+
++long aio_run = 0; /* for testing only */
++long aio_wakeups = 0; /* for testing only */
++
+ /*------ sysctl variables----*/
+ atomic_t aio_nr = ATOMIC_INIT(0); /* current system wide number of aio requests */
+ unsigned aio_max_nr = 0x10000; /* system wide maximum number of aio requests */
+@@ -48,6 +53,7 @@
+ static kmem_cache_t *kioctx_cachep;
+
+ static struct workqueue_struct *aio_wq;
++static struct workqueue_struct *aio_fput_wq;
+
+ /* Used for rare fput completion. */
+ static void aio_fput_routine(void *);
+@@ -75,6 +81,7 @@
+ panic("unable to create kioctx cache");
+
+ aio_wq = create_workqueue("aio");
++ aio_fput_wq = create_workqueue("aio_fput");
+
+ pr_debug("aio_setup: sizeof(struct page) = %d\n", (int)sizeof(struct page));
+
+@@ -282,6 +289,7 @@
+ struct kiocb *iocb = list_kiocb(pos);
+ list_del_init(&iocb->ki_list);
+ cancel = iocb->ki_cancel;
++ kiocbSetCancelled(iocb);
+ if (cancel) {
+ iocb->ki_users++;
+ spin_unlock_irq(&ctx->ctx_lock);
+@@ -342,6 +350,11 @@
+ aio_cancel_all(ctx);
+
+ wait_for_all_aios(ctx);
++ /*
++ * this is an overkill, but ensures we don't leave
++ * the ctx on the aio_wq
++ */
++ flush_workqueue(aio_wq);
+
+ if (1 != atomic_read(&ctx->users))
+ printk(KERN_DEBUG
+@@ -396,6 +409,7 @@
+ req->ki_cancel = NULL;
+ req->ki_retry = NULL;
+ req->ki_user_obj = NULL;
++ INIT_LIST_HEAD(&req->ki_run_list);
+
+ /* Check if the completion queue has enough free space to
+ * accept an event from this io.
+@@ -495,7 +509,7 @@
+ spin_lock(&fput_lock);
+ list_add(&req->ki_list, &fput_head);
+ spin_unlock(&fput_lock);
+- queue_work(aio_wq, &fput_work);
++ queue_work(aio_fput_wq, &fput_work);
+ } else
+ really_put_req(ctx, req);
+ return 1;
+@@ -537,65 +551,302 @@
+ return ioctx;
+ }
+
++/*
++ * use_mm
++ * Makes the calling kernel thread take on the specified
++ * mm context.
++ * Called by the retry thread execute retries within the
++ * iocb issuer's mm context, so that copy_from/to_user
++ * operations work seamlessly for aio.
++ * (Note: this routine is intended to be called only
++ * from a kernel thread context)
++ */
+ static void use_mm(struct mm_struct *mm)
+ {
+- struct mm_struct *active_mm = current->active_mm;
++ struct mm_struct *active_mm;
++ struct task_struct *tsk = current;
++
++ task_lock(tsk);
++ active_mm = tsk->active_mm;
+ atomic_inc(&mm->mm_count);
+- current->mm = mm;
+- if (mm != active_mm) {
+- current->active_mm = mm;
+- activate_mm(active_mm, mm);
+- }
++ tsk->mm = mm;
++ tsk->active_mm = mm;
++ activate_mm(active_mm, mm);
++ task_unlock(tsk);
++
+ mmdrop(active_mm);
+ }
+
+-static void unuse_mm(struct mm_struct *mm)
++/*
++ * unuse_mm
++ * Reverses the effect of use_mm, i.e. releases the
++ * specified mm context which was earlier taken on
++ * by the calling kernel thread
++ * (Note: this routine is intended to be called only
++ * from a kernel thread context)
++ *
++ * Comments: Called with ctx->ctx_lock held. This nests
++ * task_lock instead ctx_lock.
++ */
++void unuse_mm(struct mm_struct *mm)
+ {
+- current->mm = NULL;
++ struct task_struct *tsk = current;
++
++ task_lock(tsk);
++ tsk->mm = NULL;
+ /* active_mm is still 'mm' */
+- enter_lazy_tlb(mm, current);
++ enter_lazy_tlb(mm, tsk);
++ task_unlock(tsk);
+ }
+
+-/* Run on kevent's context. FIXME: needs to be per-cpu and warn if an
+- * operation blocks.
++/*
++ * Queue up a kiocb to be retried. Assumes that the kiocb
++ * has already been marked as kicked, and places it on
++ * the retry run list for the corresponding ioctx, if it
++ * isn't already queued. Returns 1 if it actually queued
++ * the kiocb (to tell the caller to activate the work
++ * queue to process it), or 0, if it found that it was
++ * already queued.
++ *
++ * Should be called with the spin lock iocb->ki_ctx->ctx_lock
++ * held
+ */
+-static void aio_kick_handler(void *data)
++static inline int __queue_kicked_iocb(struct kiocb *iocb)
+ {
+- struct kioctx *ctx = data;
++ struct kioctx *ctx = iocb->ki_ctx;
+
+- use_mm(ctx->mm);
++ if (list_empty(&iocb->ki_run_list)) {
++ list_add_tail(&iocb->ki_run_list,
++ &ctx->run_list);
++ iocb->ki_queued++;
++ return 1;
++ }
++ return 0;
++}
+
+- spin_lock_irq(&ctx->ctx_lock);
+- while (!list_empty(&ctx->run_list)) {
+- struct kiocb *iocb;
+- long ret;
++/* aio_run_iocb
++ * This is the core aio execution routine. It is
++ * invoked both for initial i/o submission and
++ * subsequent retries via the aio_kick_handler.
++ * Expects to be invoked with iocb->ki_ctx->lock
++ * already held. The lock is released and reaquired
++ * as needed during processing.
++ *
++ * Calls the iocb retry method (already setup for the
++ * iocb on initial submission) for operation specific
++ * handling, but takes care of most of common retry
++ * execution details for a given iocb. The retry method
++ * needs to be non-blocking as far as possible, to avoid
++ * holding up other iocbs waiting to be serviced by the
++ * retry kernel thread.
++ *
++ * The trickier parts in this code have to do with
++ * ensuring that only one retry instance is in progress
++ * for a given iocb at any time. Providing that guarantee
++ * simplifies the coding of individual aio operations as
++ * it avoids various potential races.
++ */
++static ssize_t aio_run_iocb(struct kiocb *iocb)
++{
++ struct kioctx *ctx = iocb->ki_ctx;
++ ssize_t (*retry)(struct kiocb *);
++ ssize_t ret;
+
+- iocb = list_entry(ctx->run_list.next, struct kiocb,
+- ki_run_list);
+- list_del(&iocb->ki_run_list);
+- iocb->ki_users ++;
+- spin_unlock_irq(&ctx->ctx_lock);
++ if (iocb->ki_retried++ > 1024*1024) {
++ printk("Maximal retry count. Bytes done %Zd\n",
++ iocb->ki_nbytes - iocb->ki_left);
++ return -EAGAIN;
++ }
++
++ if (!(iocb->ki_retried & 0xff)) {
++ pr_debug("%ld retry: %d of %d (kick %ld, Q %ld run %ld, wake %ld)\n",
++ iocb->ki_retried,
++ iocb->ki_nbytes - iocb->ki_left, iocb->ki_nbytes,
++ iocb->ki_kicked, iocb->ki_queued, aio_run, aio_wakeups);
++ }
++
++ if (!(retry = iocb->ki_retry)) {
++ printk("aio_run_iocb: iocb->ki_retry = NULL\n");
++ return 0;
++ }
++
++ /*
++ * We don't want the next retry iteration for this
++ * operation to start until this one has returned and
++ * updated the iocb state. However, wait_queue functions
++ * can trigger a kick_iocb from interrupt context in the
++ * meantime, indicating that data is available for the next
++ * iteration. We want to remember that and enable the
++ * next retry iteration _after_ we are through with
++ * this one.
++ *
++ * So, in order to be able to register a "kick", but
++ * prevent it from being queued now, we clear the kick
++ * flag, but make the kick code *think* that the iocb is
++ * still on the run list until we are actually done.
++ * When we are done with this iteration, we check if
++ * the iocb was kicked in the meantime and if so, queue
++ * it up afresh.
++ */
++
++ kiocbClearKicked(iocb);
++
++ /*
++ * This is so that aio_complete knows it doesn't need to
++ * pull the iocb off the run list (We can't just call
++ * INIT_LIST_HEAD because we don't want a kick_iocb to
++ * queue this on the run list yet)
++ */
++ iocb->ki_run_list.next = iocb->ki_run_list.prev = NULL;
++ iocb->ki_retry = NULL;
++ spin_unlock_irq(&ctx->ctx_lock);
++
++ /* Quit retrying if the i/o has been cancelled */
++ if (kiocbIsCancelled(iocb)) {
++ ret = -EINTR;
++ aio_complete(iocb, ret, 0);
++ /* must not access the iocb after this */
++ goto out;
++ }
++
++ /*
++ * Now we are all set to call the retry method in async
++ * context. By setting this thread's io_wait context
++ * to point to the wait queue entry inside the currently
++ * running iocb for the duration of the retry, we ensure
++ * that async notification wakeups are queued by the
++ * operation instead of blocking waits, and when notified,
++ * cause the iocb to be kicked for continuation (through
++ * the aio_wake_function callback).
++ */
++ BUG_ON(current->io_wait != NULL);
++ current->io_wait = &iocb->ki_wait;
++ ret = retry(iocb);
++ current->io_wait = NULL;
+
+- kiocbClearKicked(iocb);
+- ret = iocb->ki_retry(iocb);
++ if (-EIOCBRETRY != ret) {
+ if (-EIOCBQUEUED != ret) {
++ BUG_ON(!list_empty(&iocb->ki_wait.task_list));
+ aio_complete(iocb, ret, 0);
+- iocb = NULL;
++ /* must not access the iocb after this */
+ }
++ } else {
++ /*
++ * Issue an additional retry to avoid waiting forever if
++ * no waits were queued (e.g. in case of a short read).
++ */
++ if (list_empty(&iocb->ki_wait.task_list))
++ kiocbSetKicked(iocb);
++ }
++out:
++ spin_lock_irq(&ctx->ctx_lock);
+
+- spin_lock_irq(&ctx->ctx_lock);
+- if (NULL != iocb)
+- __aio_put_req(ctx, iocb);
++ if (-EIOCBRETRY == ret) {
++ /*
++ * OK, now that we are done with this iteration
++ * and know that there is more left to go,
++ * this is where we let go so that a subsequent
++ * "kick" can start the next iteration
++ */
++ iocb->ki_retry = retry;
++ /* will make __queue_kicked_iocb succeed from here on */
++ INIT_LIST_HEAD(&iocb->ki_run_list);
++ /* we must queue the next iteration ourselves, if it
++ * has already been kicked */
++ if (kiocbIsKicked(iocb)) {
++ __queue_kicked_iocb(iocb);
++ }
+ }
++ return ret;
++}
++
++/*
++ * __aio_run_iocbs:
++ * Process all pending retries queued on the ioctx
++ * run list.
++ * Assumes it is operating within the aio issuer's mm
++ * context. Expects to be called with ctx->ctx_lock held
++ */
++static void __aio_run_iocbs(struct kioctx *ctx)
++{
++ struct kiocb *iocb;
++ ssize_t ret;
++ int count = 0;
++
++ while (!list_empty(&ctx->run_list)) {
++ iocb = list_entry(ctx->run_list.next, struct kiocb,
++ ki_run_list);
++ list_del(&iocb->ki_run_list);
++ ret = aio_run_iocb(iocb);
++ count++;
++ }
++ aio_run++;
++}
++
++/*
++ * aio_run_iocbs:
++ * Process all pending retries queued on the ioctx
++ * run list.
++ * Assumes it is operating within the aio issuer's mm
++ * context.
++ */
++static inline void aio_run_iocbs(struct kioctx *ctx)
++{
++ spin_lock_irq(&ctx->ctx_lock);
++ __aio_run_iocbs(ctx);
+ spin_unlock_irq(&ctx->ctx_lock);
++}
+
++/*
++ * aio_kick_handler:
++ * Work queue handler triggered to process pending
++ * retries on an ioctx. Takes on the aio issuer's
++ * mm context before running the iocbs.
++ * Run on aiod's context.
++ */
++static void aio_kick_handler(void *data)
++{
++ struct kioctx *ctx = data;
++
++ use_mm(ctx->mm);
++ spin_lock_irq(&ctx->ctx_lock);
++ __aio_run_iocbs(ctx);
+ unuse_mm(ctx->mm);
++ spin_unlock_irq(&ctx->ctx_lock);
+ }
+
+-void kick_iocb(struct kiocb *iocb)
++
++/*
++ * Called by kick_iocb to queue the kiocb for retry
++ * and if required activate the aio work queue to process
++ * it
++ */
++void queue_kicked_iocb(struct kiocb *iocb)
+ {
+ struct kioctx *ctx = iocb->ki_ctx;
++ unsigned long flags;
++ int run = 0;
++
++ WARN_ON((!list_empty(&iocb->ki_wait.task_list)));
++
++ spin_lock_irqsave(&ctx->ctx_lock, flags);
++ run = __queue_kicked_iocb(iocb);
++ spin_unlock_irqrestore(&ctx->ctx_lock, flags);
++ if (run) {
++ queue_work(aio_wq, &ctx->wq);
++ aio_wakeups++;
++ }
++}
+
++/*
++ * kick_iocb:
++ * Called typically from a wait queue callback context
++ * (aio_wake_function) to trigger a retry of the iocb.
++ * The retry is usually executed by aio workqueue
++ * threads (See aio_kick_handler).
++ */
++void kick_iocb(struct kiocb *iocb)
++{
+ /* sync iocbs are easy: they can only ever be executing from a
+ * single context. */
+ if (is_sync_kiocb(iocb)) {
+@@ -604,12 +855,10 @@
+ return;
+ }
+
++ iocb->ki_kicked++;
++ /* If its already kicked we shouldn't queue it again */
+ if (!kiocbTryKick(iocb)) {
+- unsigned long flags;
+- spin_lock_irqsave(&ctx->ctx_lock, flags);
+- list_add_tail(&iocb->ki_run_list, &ctx->run_list);
+- spin_unlock_irqrestore(&ctx->ctx_lock, flags);
+- schedule_work(&ctx->wq);
++ queue_kicked_iocb(iocb);
+ }
+ }
+
+@@ -662,6 +911,9 @@
+ */
+ spin_lock_irqsave(&ctx->ctx_lock, flags);
+
++ if (iocb->ki_run_list.prev && !list_empty(&iocb->ki_run_list))
++ list_del_init(&iocb->ki_run_list);
++
+ ring = kmap_atomic(info->ring_pages[0], KM_IRQ1);
+
+ tail = info->tail;
+@@ -690,6 +942,11 @@
+
+ pr_debug("added to ring %p at [%lu]\n", iocb, tail);
+
++ pr_debug("%ld retries: %d of %d (kicked %ld, Q %ld run %ld wake %ld)\n",
++ iocb->ki_retried,
++ iocb->ki_nbytes - iocb->ki_left, iocb->ki_nbytes,
++ iocb->ki_kicked, iocb->ki_queued, aio_run, aio_wakeups);
++
+ /* everything turned out well, dispose of the aiocb. */
+ ret = __aio_put_req(ctx, iocb);
+
+@@ -804,6 +1061,7 @@
+ int i = 0;
+ struct io_event ent;
+ struct timeout to;
++ int event_loop = 0; /* testing only */
+
+ /* needed to zero any padding within an entry (there shouldn't be
+ * any, but C is fun!
+@@ -853,7 +1111,6 @@
+ add_wait_queue_exclusive(&ctx->wait, &wait);
+ do {
+ set_task_state(tsk, TASK_INTERRUPTIBLE);
+-
+ ret = aio_read_evt(ctx, &ent);
+ if (ret)
+ break;
+@@ -863,6 +1120,7 @@
+ if (to.timed_out) /* Only check after read evt */
+ break;
+ schedule();
++ event_loop++;
+ if (signal_pending(tsk)) {
+ ret = -EINTR;
+ break;
+@@ -890,6 +1148,9 @@
+ if (timeout)
+ clear_timeout(&to);
+ out:
++ pr_debug("event loop executed %d times\n", event_loop);
++ pr_debug("aio_run %ld\n", aio_run);
++ pr_debug("aio_wakeups %ld\n", aio_wakeups);
+ return i ? i : ret;
+ }
+
+@@ -919,6 +1180,11 @@
+
+ aio_cancel_all(ioctx);
+ wait_for_all_aios(ioctx);
++ /*
++ * this is an overkill, but ensures we don't leave
++ * the ctx on the aio_wq
++ */
++ flush_workqueue(aio_wq);
+ put_ioctx(ioctx); /* once for the lookup */
+ }
+
+@@ -981,13 +1247,191 @@
+ return -EINVAL;
+ }
+
++/*
++ * Retry method for aio_read (also used for first time submit)
++ * Responsible for updating iocb state as retries progress
++ */
++static ssize_t aio_pread(struct kiocb *iocb)
++{
++ struct file *file = iocb->ki_filp;
++ ssize_t ret = 0;
++
++ ret = file->f_op->aio_read(iocb, iocb->ki_buf,
++ iocb->ki_left, iocb->ki_pos);
++
++ /*
++ * Can't just depend on iocb->ki_left to determine
++ * whether we are done. This may have been a short read.
++ */
++ if (ret > 0) {
++ iocb->ki_buf += ret;
++ iocb->ki_left -= ret;
++
++ ret = -EIOCBRETRY;
++ }
++
++ /* This means we must have transferred all that we could */
++ /* No need to retry anymore */
++ if ((ret == 0) || (iocb->ki_left == 0))
++ ret = iocb->ki_nbytes - iocb->ki_left;
++
++ return ret;
++}
++
++/*
++ * Retry method for aio_write (also used for first time submit)
++ * Responsible for updating iocb state as retries progress
++ */
++static ssize_t aio_pwrite(struct kiocb *iocb)
++{
++ struct file *file = iocb->ki_filp;
++ struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
++ struct inode *inode = mapping->host;
++ ssize_t ret = 0;
++
++ ret = file->f_op->aio_write(iocb, iocb->ki_buf,
++ iocb->ki_left, iocb->ki_pos);
++
++ /*
++ * Even if iocb->ki_left = 0, we may need to wait
++ * for a balance_dirty_pages to complete
++ */
++ if (ret > 0) {
++ iocb->ki_buf += iocb->ki_buf ? ret : 0;
++ iocb->ki_left -= ret;
++
++ ret = -EIOCBRETRY;
++ }
++
++ /* This means we must have transferred all that we could */
++ /* No need to retry anymore unless we need to osync data */
++ if (ret == 0) {
++ ret = iocb->ki_nbytes - iocb->ki_left;
++ if (!iocb->ki_buf)
++ return ret;
++
++ /* Set things up for potential O_SYNC */
++ if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
++ iocb->ki_buf = NULL;
++ iocb->ki_pos -= ret; /* back up fpos */
++ iocb->ki_left = ret; /* sync what we have written out */
++ iocb->ki_nbytes = ret;
++ ret = -EIOCBRETRY;
++ }
++ }
++
++ return ret;
++}
++
++static ssize_t aio_fdsync(struct kiocb *iocb)
++{
++ struct file *file = iocb->ki_filp;
++ ssize_t ret = -EINVAL;
++
++ if (file->f_op->aio_fsync)
++ ret = file->f_op->aio_fsync(iocb, 1);
++ return ret;
++}
++
++static ssize_t aio_fsync(struct kiocb *iocb)
++{
++ struct file *file = iocb->ki_filp;
++ ssize_t ret = -EINVAL;
++
++ if (file->f_op->aio_fsync)
++ ret = file->f_op->aio_fsync(iocb, 0);
++ return ret;
++}
++
++/*
++ * aio_setup_iocb:
++ * Performs the initial checks and aio retry method
++ * setup for the kiocb at the time of io submission.
++ */
++ssize_t aio_setup_iocb(struct kiocb *kiocb)
++{
++ struct file *file = kiocb->ki_filp;
++ ssize_t ret = 0;
++
++ switch (kiocb->ki_opcode) {
++ case IOCB_CMD_PREAD:
++ ret = -EBADF;
++ if (unlikely(!(file->f_mode & FMODE_READ)))
++ break;
++ ret = -EFAULT;
++ if (unlikely(!access_ok(VERIFY_WRITE, kiocb->ki_buf,
++ kiocb->ki_left)))
++ break;
++ ret = -EINVAL;
++ if (file->f_op->aio_read)
++ kiocb->ki_retry = aio_pread;
++ break;
++ case IOCB_CMD_PWRITE:
++ ret = -EBADF;
++ if (unlikely(!(file->f_mode & FMODE_WRITE)))
++ break;
++ ret = -EFAULT;
++ if (unlikely(!access_ok(VERIFY_READ, kiocb->ki_buf,
++ kiocb->ki_left)))
++ break;
++ ret = -EINVAL;
++ if (file->f_op->aio_write)
++ kiocb->ki_retry = aio_pwrite;
++ break;
++ case IOCB_CMD_FDSYNC:
++ ret = -EINVAL;
++ if (file->f_op->aio_fsync)
++ kiocb->ki_retry = aio_fdsync;
++ break;
++ case IOCB_CMD_FSYNC:
++ ret = -EINVAL;
++ if (file->f_op->aio_fsync)
++ kiocb->ki_retry = aio_fsync;
++ break;
++ default:
++ dprintk("EINVAL: io_submit: no operation provided\n");
++ ret = -EINVAL;
++ }
++
++ if (!kiocb->ki_retry)
++ return ret;
++
++ return 0;
++}
++
++/*
++ * aio_wake_function:
++ * wait queue callback function for aio notification,
++ * Simply triggers a retry of the operation via kick_iocb.
++ *
++ * This callback is specified in the wait queue entry in
++ * a kiocb (current->io_wait points to this wait queue
++ * entry when an aio operation executes; it is used
++ * instead of a synchronous wait when an i/o blocking
++ * condition is encountered during aio).
++ *
++ * Note:
++ * This routine is executed with the wait queue lock held.
++ * Since kick_iocb acquires iocb->ctx->ctx_lock, it nests
++ * the ioctx lock inside the wait queue lock. This is safe
++ * because this callback isn't used for wait queues which
++ * are nested inside ioctx lock (i.e. ctx->wait)
++ */
++int aio_wake_function(wait_queue_t *wait, unsigned mode, int sync)
++{
++ struct kiocb *iocb = container_of(wait, struct kiocb, ki_wait);
++
++ list_del_init(&wait->task_list);
++ kick_iocb(iocb);
++ return 1;
++}
++
+ int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
+ struct iocb *iocb)
+ {
+ struct kiocb *req;
+ struct file *file;
+ ssize_t ret;
+- char *buf;
+
+ /* enforce forwards compatibility on users */
+ if (unlikely(iocb->aio_reserved1 || iocb->aio_reserved2 ||
+@@ -1028,51 +1472,31 @@
+ req->ki_user_data = iocb->aio_data;
+ req->ki_pos = iocb->aio_offset;
+
+- buf = (char *)(unsigned long)iocb->aio_buf;
++ req->ki_buf = (char *)(unsigned long)iocb->aio_buf;
++ req->ki_left = req->ki_nbytes = iocb->aio_nbytes;
++ req->ki_opcode = iocb->aio_lio_opcode;
++ init_waitqueue_func_entry(&req->ki_wait, aio_wake_function);
++ INIT_LIST_HEAD(&req->ki_wait.task_list);
++ req->ki_run_list.next = req->ki_run_list.prev = NULL;
++ req->ki_retry = NULL;
++ req->ki_retried = 0;
++ req->ki_kicked = 0;
++ req->ki_queued = 0;
++ aio_run = 0;
++ aio_wakeups = 0;
+
+- switch (iocb->aio_lio_opcode) {
+- case IOCB_CMD_PREAD:
+- ret = -EBADF;
+- if (unlikely(!(file->f_mode & FMODE_READ)))
+- goto out_put_req;
+- ret = -EFAULT;
+- if (unlikely(!access_ok(VERIFY_WRITE, buf, iocb->aio_nbytes)))
+- goto out_put_req;
+- ret = -EINVAL;
+- if (file->f_op->aio_read)
+- ret = file->f_op->aio_read(req, buf,
+- iocb->aio_nbytes, req->ki_pos);
+- break;
+- case IOCB_CMD_PWRITE:
+- ret = -EBADF;
+- if (unlikely(!(file->f_mode & FMODE_WRITE)))
+- goto out_put_req;
+- ret = -EFAULT;
+- if (unlikely(!access_ok(VERIFY_READ, buf, iocb->aio_nbytes)))
+- goto out_put_req;
+- ret = -EINVAL;
+- if (file->f_op->aio_write)
+- ret = file->f_op->aio_write(req, buf,
+- iocb->aio_nbytes, req->ki_pos);
+- break;
+- case IOCB_CMD_FDSYNC:
+- ret = -EINVAL;
+- if (file->f_op->aio_fsync)
+- ret = file->f_op->aio_fsync(req, 1);
+- break;
+- case IOCB_CMD_FSYNC:
+- ret = -EINVAL;
+- if (file->f_op->aio_fsync)
+- ret = file->f_op->aio_fsync(req, 0);
+- break;
+- default:
+- dprintk("EINVAL: io_submit: no operation provided\n");
+- ret = -EINVAL;
+- }
++ ret = aio_setup_iocb(req);
++
++ if (ret)
++ goto out_put_req;
++
++ spin_lock_irq(&ctx->ctx_lock);
++ ret = aio_run_iocb(req);
++ spin_unlock_irq(&ctx->ctx_lock);
++
++ if (-EIOCBRETRY == ret)
++ queue_work(aio_wq, &ctx->wq);
+
+- if (likely(-EIOCBQUEUED == ret))
+- return 0;
+- aio_complete(req, ret, 0);
+ return 0;
+
+ out_put_req:
+Index: linux-2.6.0-test5/fs/autofs4/autofs_i.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/autofs4/autofs_i.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/autofs4/autofs_i.h 2003-09-27 11:38:36.060046424 +0800
+@@ -113,7 +113,7 @@
+ filesystem without "magic".) */
+
+ static inline int autofs4_oz_mode(struct autofs_sb_info *sbi) {
+- return sbi->catatonic || current->pgrp == sbi->oz_pgrp;
++ return sbi->catatonic || process_group(current) == sbi->oz_pgrp;
+ }
+
+ /* Does a dentry have some pending activity? */
+Index: linux-2.6.0-test5/fs/autofs4/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/autofs4/inode.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/autofs4/inode.c 2003-09-27 11:38:36.062046120 +0800
+@@ -14,6 +14,7 @@
+ #include <linux/slab.h>
+ #include <linux/file.h>
+ #include <linux/pagemap.h>
++#include <linux/parser.h>
+ #include <asm/bitops.h>
+ #include "autofs_i.h"
+ #include <linux/module.h>
+@@ -94,69 +95,76 @@
+ .statfs = simple_statfs,
+ };
+
++enum {Opt_err, Opt_fd, Opt_uid, Opt_gid, Opt_pgrp, Opt_minproto, Opt_maxproto};
++
++static match_table_t tokens = {
++ {Opt_fd, "fd=%d"},
++ {Opt_uid, "uid=%d"},
++ {Opt_gid, "gid=%d"},
++ {Opt_pgrp, "pgrp=%d"},
++ {Opt_minproto, "minproto=%d"},
++ {Opt_maxproto, "maxproto=%d"},
++ {Opt_err, NULL}
++};
++
+ static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid,
+ pid_t *pgrp, int *minproto, int *maxproto)
+ {
+- char *this_char, *value;
+-
++ char *p;
++ substring_t args[MAX_OPT_ARGS];
++ int option;
++
+ *uid = current->uid;
+ *gid = current->gid;
+- *pgrp = current->pgrp;
++ *pgrp = process_group(current);
+
+ *minproto = AUTOFS_MIN_PROTO_VERSION;
+ *maxproto = AUTOFS_MAX_PROTO_VERSION;
+
+ *pipefd = -1;
+
+- if ( !options ) return 1;
+- while ((this_char = strsep(&options,",")) != NULL) {
+- if (!*this_char)
++ if (!options)
++ return 1;
++
++ while ((p = strsep(&options, ",")) != NULL) {
++ int token;
++ if (!*p)
+ continue;
+- if ((value = strchr(this_char,'=')) != NULL)
+- *value++ = 0;
+- if (!strcmp(this_char,"fd")) {
+- if (!value || !*value)
+- return 1;
+- *pipefd = simple_strtoul(value,&value,0);
+- if (*value)
+- return 1;
+- }
+- else if (!strcmp(this_char,"uid")) {
+- if (!value || !*value)
+- return 1;
+- *uid = simple_strtoul(value,&value,0);
+- if (*value)
+- return 1;
+- }
+- else if (!strcmp(this_char,"gid")) {
+- if (!value || !*value)
+- return 1;
+- *gid = simple_strtoul(value,&value,0);
+- if (*value)
+- return 1;
+- }
+- else if (!strcmp(this_char,"pgrp")) {
+- if (!value || !*value)
+- return 1;
+- *pgrp = simple_strtoul(value,&value,0);
+- if (*value)
+- return 1;
+- }
+- else if (!strcmp(this_char,"minproto")) {
+- if (!value || !*value)
+- return 1;
+- *minproto = simple_strtoul(value,&value,0);
+- if (*value)
+- return 1;
+- }
+- else if (!strcmp(this_char,"maxproto")) {
+- if (!value || !*value)
+- return 1;
+- *maxproto = simple_strtoul(value,&value,0);
+- if (*value)
+- return 1;
++
++ token = match_token(p, tokens, args);
++ switch (token) {
++ case Opt_fd:
++ if (match_int(args, pipefd))
++ return 1;
++ break;
++ case Opt_uid:
++ if (match_int(args, &option))
++ return 1;
++ *uid = option;
++ break;
++ case Opt_gid:
++ if (match_int(args, &option))
++ return 1;
++ *gid = option;
++ break;
++ case Opt_pgrp:
++ if (match_int(args, &option))
++ return 1;
++ *pgrp = option;
++ break;
++ case Opt_minproto:
++ if (match_int(args, &option))
++ return 1;
++ *minproto = option;
++ break;
++ case Opt_maxproto:
++ if (match_int(args, &option))
++ return 1;
++ *maxproto = option;
++ break;
++ default:
++ return 1;
+ }
+- else break;
+ }
+ return (*pipefd < 0);
+ }
+@@ -192,7 +200,7 @@
+ sbi->magic = AUTOFS_SBI_MAGIC;
+ sbi->catatonic = 0;
+ sbi->exp_timeout = 0;
+- sbi->oz_pgrp = current->pgrp;
++ sbi->oz_pgrp = process_group(current);
+ sbi->sb = s;
+ sbi->version = 0;
+ sbi->queues = NULL;
+Index: linux-2.6.0-test5/fs/autofs4/root.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/autofs4/root.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/autofs4/root.c 2003-09-27 11:38:36.067045360 +0800
+@@ -255,7 +255,7 @@
+ lock_kernel();
+ oz_mode = autofs4_oz_mode(sbi);
+ DPRINTK(("autofs_lookup: pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d\n",
+- current->pid, current->pgrp, sbi->catatonic, oz_mode));
++ current->pid, process_group(current), sbi->catatonic, oz_mode));
+
+ /*
+ * Mark the dentry incomplete, but add it. This is needed so
+@@ -518,7 +518,7 @@
+ struct autofs_sb_info *sbi = autofs4_sbi(inode->i_sb);
+
+ DPRINTK(("autofs_ioctl: cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u\n",
+- cmd,arg,sbi,current->pgrp));
++ cmd,arg,sbi,process_group(current)));
+
+ if ( _IOC_TYPE(cmd) != _IOC_TYPE(AUTOFS_IOC_FIRST) ||
+ _IOC_NR(cmd) - _IOC_NR(AUTOFS_IOC_FIRST) >= AUTOFS_IOC_COUNT )
+Index: linux-2.6.0-test5/fs/autofs/autofs_i.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/autofs/autofs_i.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/autofs/autofs_i.h 2003-09-27 11:38:36.069045056 +0800
+@@ -123,7 +123,7 @@
+ filesystem without "magic".) */
+
+ static inline int autofs_oz_mode(struct autofs_sb_info *sbi) {
+- return sbi->catatonic || current->pgrp == sbi->oz_pgrp;
++ return sbi->catatonic || process_group(current) == sbi->oz_pgrp;
+ }
+
+ /* Hash operations */
+Index: linux-2.6.0-test5/fs/autofs/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/autofs/inode.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/autofs/inode.c 2003-09-27 11:38:36.071044752 +0800
+@@ -14,6 +14,7 @@
+ #include <linux/mm.h>
+ #include <linux/slab.h>
+ #include <linux/file.h>
++#include <linux/parser.h>
+ #include <asm/bitops.h>
+ #include "autofs_i.h"
+ #include <linux/module.h>
+@@ -45,67 +46,75 @@
+ .statfs = simple_statfs,
+ };
+
++enum {Opt_err, Opt_fd, Opt_uid, Opt_gid, Opt_pgrp, Opt_minproto, Opt_maxproto};
++
++static match_table_t autofs_tokens = {
++ {Opt_fd, "fd=%d"},
++ {Opt_uid, "uid=%d"},
++ {Opt_gid, "gid=%d"},
++ {Opt_pgrp, "pgrp=%d"},
++ {Opt_minproto, "minproto=%d"},
++ {Opt_maxproto, "maxproto=%d"},
++ {Opt_err, NULL}
++};
++
+ static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid, pid_t *pgrp, int *minproto, int *maxproto)
+ {
+- char *this_char, *value;
+-
++ char *p;
++ substring_t args[MAX_OPT_ARGS];
++ int option;
++
+ *uid = current->uid;
+ *gid = current->gid;
+- *pgrp = current->pgrp;
++ *pgrp = process_group(current);
+
+ *minproto = *maxproto = AUTOFS_PROTO_VERSION;
+
+ *pipefd = -1;
+
+- if ( !options ) return 1;
+- while ((this_char = strsep(&options,",")) != NULL) {
+- if (!*this_char)
++ if (!options)
++ return 1;
++
++ while ((p = strsep(&options, ",")) != NULL) {
++ int token;
++ if (!*p)
+ continue;
+- if ((value = strchr(this_char,'=')) != NULL)
+- *value++ = 0;
+- if (!strcmp(this_char,"fd")) {
+- if (!value || !*value)
+- return 1;
+- *pipefd = simple_strtoul(value,&value,0);
+- if (*value)
+- return 1;
+- }
+- else if (!strcmp(this_char,"uid")) {
+- if (!value || !*value)
+- return 1;
+- *uid = simple_strtoul(value,&value,0);
+- if (*value)
+- return 1;
+- }
+- else if (!strcmp(this_char,"gid")) {
+- if (!value || !*value)
+- return 1;
+- *gid = simple_strtoul(value,&value,0);
+- if (*value)
+- return 1;
+- }
+- else if (!strcmp(this_char,"pgrp")) {
+- if (!value || !*value)
+- return 1;
+- *pgrp = simple_strtoul(value,&value,0);
+- if (*value)
+- return 1;
+- }
+- else if (!strcmp(this_char,"minproto")) {
+- if (!value || !*value)
+- return 1;
+- *minproto = simple_strtoul(value,&value,0);
+- if (*value)
+- return 1;
+- }
+- else if (!strcmp(this_char,"maxproto")) {
+- if (!value || !*value)
+- return 1;
+- *maxproto = simple_strtoul(value,&value,0);
+- if (*value)
+- return 1;
++
++ token = match_token(p, autofs_tokens, args);
++ switch (token) {
++ case Opt_fd:
++ if (match_int(&args[0], &option))
++ return 1;
++ *pipefd = option;
++ break;
++ case Opt_uid:
++ if (match_int(&args[0], &option))
++ return 1;
++ *uid = option;
++ break;
++ case Opt_gid:
++ if (match_int(&args[0], &option))
++ return 1;
++ *gid = option;
++ break;
++ case Opt_pgrp:
++ if (match_int(&args[0], &option))
++ return 1;
++ *pgrp = option;
++ break;
++ case Opt_minproto:
++ if (match_int(&args[0], &option))
++ return 1;
++ *minproto = option;
++ break;
++ case Opt_maxproto:
++ if (match_int(&args[0], &option))
++ return 1;
++ *maxproto = option;
++ break;
++ default:
++ return 1;
+ }
+- else break;
+ }
+ return (*pipefd < 0);
+ }
+@@ -129,7 +138,7 @@
+ sbi->magic = AUTOFS_SBI_MAGIC;
+ sbi->catatonic = 0;
+ sbi->exp_timeout = 0;
+- sbi->oz_pgrp = current->pgrp;
++ sbi->oz_pgrp = process_group(current);
+ autofs_initialize_hash(&sbi->dirhash);
+ sbi->queues = NULL;
+ memset(sbi->symlink_bitmap, 0, sizeof(long)*AUTOFS_SYMLINK_BITMAP_LEN);
+Index: linux-2.6.0-test5/fs/autofs/root.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/autofs/root.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/autofs/root.c 2003-09-27 11:38:36.076043992 +0800
+@@ -213,7 +213,7 @@
+
+ oz_mode = autofs_oz_mode(sbi);
+ DPRINTK(("autofs_lookup: pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d\n",
+- current->pid, current->pgrp, sbi->catatonic, oz_mode));
++ current->pid, process_group(current), sbi->catatonic, oz_mode));
+
+ /*
+ * Mark the dentry incomplete, but add it. This is needed so
+@@ -527,7 +527,7 @@
+ {
+ struct autofs_sb_info *sbi = autofs_sbi(inode->i_sb);
+
+- DPRINTK(("autofs_ioctl: cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u\n",cmd,arg,sbi,current->pgrp));
++ DPRINTK(("autofs_ioctl: cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u\n",cmd,arg,sbi,process_group(current)));
+
+ if ( _IOC_TYPE(cmd) != _IOC_TYPE(AUTOFS_IOC_FIRST) ||
+ _IOC_NR(cmd) - _IOC_NR(AUTOFS_IOC_FIRST) >= AUTOFS_IOC_COUNT )
+Index: linux-2.6.0-test5/fs/befs/linuxvfs.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/befs/linuxvfs.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/befs/linuxvfs.c 2003-09-27 11:38:36.082043080 +0800
+@@ -13,6 +13,7 @@
+ #include <linux/nls.h>
+ #include <linux/buffer_head.h>
+ #include <linux/vfs.h>
++#include <linux/parser.h>
+
+ #include "befs.h"
+ #include "btree.h"
+@@ -667,12 +668,26 @@
+ return -EILSEQ;
+ }
+
++/**
++ * Use the
++ *
++ */
++enum {
++ Opt_uid, Opt_gid, Opt_charset, Opt_debug,
++};
++
++static match_table_t befs_tokens = {
++ {Opt_uid, "uid=%d"},
++ {Opt_gid, "gid=%d"},
++ {Opt_charset, "iocharset=%s"},
++ {Opt_debug, "debug"}
++};
++
+ static int
+ parse_options(char *options, befs_mount_options * opts)
+ {
+- char *this_char;
+- char *value;
+- int ret = 1;
++ char *p;
++ substring_t args[MAX_OPT_ARGS];
+
+ /* Initialize options */
+ opts->uid = 0;
+@@ -683,64 +698,60 @@
+ opts->debug = 0;
+
+ if (!options)
+- return ret;
++ return 1;
+
+- while ((this_char = strsep(&options, ",")) != NULL) {
+-
+- if ((value = strchr(this_char, '=')) != NULL)
+- *value++ = 0;
+-
+- if (!strcmp(this_char, "uid")) {
+- if (!value || !*value) {
+- ret = 0;
+- } else {
+- opts->uid = simple_strtoul(value, &value, 0);
+- opts->use_uid = 1;
+- if (*value) {
+- printk(KERN_ERR "BEFS: Invalid uid "
+- "option: %s\n", value);
+- ret = 0;
++ while ((p = strsep(&options, ",")) != NULL) {
++ int token;
++ if (!*p)
++ continue;
++
++ token = match_token(p, befs_tokens, args);
++ switch (token) {
++ case Opt_uid:
++ {
++ int uid = match_int(&args[0]);
++ if (uid < 0) {
++ printk(KERN_ERR "BeFS: Invalid uid %d, "
++ "using default\n", uid);
++ break;
+ }
++ opts->uid = uid;
++ opts->use_uid = 1;
++ break;
+ }
+- } else if (!strcmp(this_char, "gid")) {
+- if (!value || !*value)
+- ret = 0;
+- else {
+- opts->gid = simple_strtoul(value, &value, 0);
+- opts->use_gid = 1;
+- if (*value) {
+- printk(KERN_ERR
+- "BEFS: Invalid gid option: "
+- "%s\n", value);
+- ret = 0;
++ case Opt_gid:
++ {
++ int gid = match_int(&args[0]);
++ if (gid < 0) {
++ printk(KERN_ERR "BeFS: Invalid gid %d, "
++ "using default\n", gid);
++ break;
+ }
++ opts->gid = gid;
++ opts->use_gid = 1;
++ break;
+ }
+- } else if (!strcmp(this_char, "iocharset") && value) {
+- char *p = value;
+- int len;
+-
+- while (*value && *value != ',')
+- value++;
+- len = value - p;
+- if (len) {
+- char *buffer = kmalloc(len + 1, GFP_NOFS);
+- if (buffer) {
+- opts->iocharset = buffer;
+- memcpy(buffer, p, len);
+- buffer[len] = 0;
+-
+- } else {
+- printk(KERN_ERR "BEFS: "
+- "cannot allocate memory\n");
+- ret = 0;
++ case Opt_charset:
++ {
++ kfree(opts->iocharset);
++ opts->iocharset = match_strdup(&args[0]);
++ if (!opts->iocharset) {
++ printk(KERN_ERR "BeFS: allocation failure for "
++ "iocharset string\n");
++ return 0;
+ }
++ break;
+ }
+- } else if (!strcmp(this_char, "debug")) {
+- opts->debug = 1;
++ case Opt_debug:
++ opts->debug = 1;
++ break;
++ default:
++ printk(KERN_ERR "BeFS: Unrecognized mount option \"%s\" "
++ "or missing value\n", p);
++ return 0;
+ }
+ }
+-
+- return ret;
++ return 1;
+ }
+
+ /* This function has the responsibiltiy of getting the
+Index: linux-2.6.0-test5/fs/bfs/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/bfs/inode.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/bfs/inode.c 2003-09-27 11:38:36.086042472 +0800
+@@ -194,13 +194,15 @@
+ static int bfs_statfs(struct super_block *s, struct kstatfs *buf)
+ {
+ struct bfs_sb_info *info = BFS_SB(s);
++ u64 id = huge_encode_dev(s->s_bdev->bd_dev);
+ buf->f_type = BFS_MAGIC;
+ buf->f_bsize = s->s_blocksize;
+ buf->f_blocks = info->si_blocks;
+ buf->f_bfree = buf->f_bavail = info->si_freeb;
+ buf->f_files = info->si_lasti + 1 - BFS_ROOT_INO;
+ buf->f_ffree = info->si_freei;
+- buf->f_fsid.val[0] = s->s_dev;
++ buf->f_fsid.val[0] = (u32)id;
++ buf->f_fsid.val[1] = (u32)(id >> 32);
+ buf->f_namelen = BFS_NAMELEN;
+ return 0;
+ }
+Index: linux-2.6.0-test5/fs/binfmt_elf.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/binfmt_elf.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/binfmt_elf.c 2003-09-27 11:38:36.096040952 +0800
+@@ -1023,6 +1023,7 @@
+ elf->e_ident[EI_CLASS] = ELF_CLASS;
+ elf->e_ident[EI_DATA] = ELF_DATA;
+ elf->e_ident[EI_VERSION] = EV_CURRENT;
++ elf->e_ident[EI_OSABI] = ELF_OSABI;
+ memset(elf->e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD);
+
+ elf->e_type = ET_CORE;
+@@ -1076,7 +1077,7 @@
+ prstatus->pr_sighold = p->blocked.sig[0];
+ prstatus->pr_pid = p->pid;
+ prstatus->pr_ppid = p->parent->pid;
+- prstatus->pr_pgrp = p->pgrp;
++ prstatus->pr_pgrp = process_group(p);
+ prstatus->pr_sid = p->session;
+ jiffies_to_timeval(p->utime, &prstatus->pr_utime);
+ jiffies_to_timeval(p->stime, &prstatus->pr_stime);
+@@ -1104,7 +1105,7 @@
+
+ psinfo->pr_pid = p->pid;
+ psinfo->pr_ppid = p->parent->pid;
+- psinfo->pr_pgrp = p->pgrp;
++ psinfo->pr_pgrp = process_group(p);
+ psinfo->pr_sid = p->session;
+
+ i = p->state ? ffz(~p->state) + 1 : 0;
+Index: linux-2.6.0-test5/fs/bio.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/bio.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/bio.c 2003-09-27 11:38:36.101040192 +0800
+@@ -532,6 +532,12 @@
+ * check that the pages are still dirty. If so, fine. If not, redirty them
+ * in process context.
+ *
++ * We special-case compound pages here: normally this means reads into hugetlb
++ * pages. The logic in here doesn't really work right for compound pages
++ * because the VM does not uniformly chase down the head page in all cases.
++ * But dirtiness of compound pages is pretty meaningless anyway: the VM doesn't
++ * handle them at all. So we skip compound pages here at an early stage.
++ *
+ * Note that this code is very hard to test under normal circumstances because
+ * direct-io pins the pages with get_user_pages(). This makes
+ * is_page_cache_freeable return false, and the VM will not clean the pages.
+@@ -553,8 +559,21 @@
+ for (i = 0; i < bio->bi_vcnt; i++) {
+ struct page *page = bvec[i].bv_page;
+
++ if (page && !PageCompound(page))
++ set_page_dirty_lock(page);
++ }
++}
++
++static void bio_release_pages(struct bio *bio)
++{
++ struct bio_vec *bvec = bio->bi_io_vec;
++ int i;
++
++ for (i = 0; i < bio->bi_vcnt; i++) {
++ struct page *page = bvec[i].bv_page;
++
+ if (page)
+- set_page_dirty_lock(bvec[i].bv_page);
++ put_page(page);
+ }
+ }
+
+@@ -592,6 +611,7 @@
+ struct bio *next = bio->bi_private;
+
+ bio_set_pages_dirty(bio);
++ bio_release_pages(bio);
+ bio_put(bio);
+ bio = next;
+ }
+@@ -606,7 +626,7 @@
+ for (i = 0; i < bio->bi_vcnt; i++) {
+ struct page *page = bvec[i].bv_page;
+
+- if (PageDirty(page)) {
++ if (PageDirty(page) || PageCompound(page)) {
+ page_cache_release(page);
+ bvec[i].bv_page = NULL;
+ } else {
+Index: linux-2.6.0-test5/fs/buffer.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/buffer.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/buffer.c 2003-09-27 11:38:36.122037000 +0800
+@@ -116,27 +116,50 @@
+ }
+
+ /*
+- * Block until a buffer comes unlocked. This doesn't stop it
++ * Wait until a buffer comes unlocked. This doesn't stop it
+ * from becoming locked again - you have to lock it yourself
+ * if you want to preserve its state.
++ * If the wait queue parameter specifies an async i/o callback,
++ * then instead of blocking, we just queue up the callback
++ * on the wait queue for async notification when the buffer gets
++ * unlocked.
++ * A NULL wait queue parameter defaults to synchronous behaviour
+ */
+-void __wait_on_buffer(struct buffer_head * bh)
++int __wait_on_buffer_wq(struct buffer_head * bh, wait_queue_t *wait)
+ {
+ wait_queue_head_t *wqh = bh_waitq_head(bh);
+- DEFINE_WAIT(wait);
++ DEFINE_WAIT(local_wait);
++
++ if (!wait)
++ wait = &local_wait;
+
+ if (atomic_read(&bh->b_count) == 0 &&
+ (!bh->b_page || !PageLocked(bh->b_page)))
+ buffer_error();
+
+ do {
+- prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE);
++ prepare_to_wait(wqh, wait, TASK_UNINTERRUPTIBLE);
+ if (buffer_locked(bh)) {
+ blk_run_queues();
++ if (!is_sync_wait(wait)) {
++ /*
++ * if we've queued an async wait queue
++ * callback do not block; just tell the
++ * caller to return and retry later when
++ * the callback is notified
++ */
++ return -EIOCBRETRY;
++ }
+ io_schedule();
+ }
+ } while (buffer_locked(bh));
+- finish_wait(wqh, &wait);
++ finish_wait(wqh, wait);
++ return 0;
++}
++
++void __wait_on_buffer(struct buffer_head * bh)
++{
++ __wait_on_buffer_wq(bh, NULL);
+ }
+
+ static void
+@@ -351,26 +374,18 @@
+ return ret;
+ }
+
+-asmlinkage long sys_fdatasync(unsigned int fd)
++int do_fdatasync(struct file * file)
+ {
+- struct file * file;
+ struct dentry * dentry;
+ struct inode * inode;
+ int ret, err;
+
+- ret = -EBADF;
+- file = fget(fd);
+- if (!file)
+- goto out;
++ if (unlikely(!file->f_op || !file->f_op->fsync))
++ return -EINVAL;
+
+ dentry = file->f_dentry;
+ inode = dentry->d_inode;
+
+- ret = -EINVAL;
+- if (!file->f_op || !file->f_op->fsync)
+- goto out_putf;
+-
+- down(&inode->i_sem);
+ current->flags |= PF_SYNCWRITE;
+ ret = filemap_fdatawrite(inode->i_mapping);
+ err = file->f_op->fsync(file, dentry, 1);
+@@ -380,11 +395,24 @@
+ if (!ret)
+ ret = err;
+ current->flags &= ~PF_SYNCWRITE;
+- up(&inode->i_sem);
++ return ret;
++}
+
+-out_putf:
+- fput(file);
+-out:
++asmlinkage long sys_fdatasync(unsigned int fd)
++{
++ struct file * file;
++ struct inode * inode;
++ int ret;
++
++ ret = -EBADF;
++ file = fget(fd);
++ if (file) {
++ inode = file->f_dentry->d_inode;
++ down(&inode->i_sem);
++ ret = do_fdatasync(file);
++ up(&inode->i_sem);
++ fput(file);
++ }
+ return ret;
+ }
+
+@@ -1296,9 +1324,12 @@
+ __brelse(bh);
+ }
+
+-static struct buffer_head *__bread_slow(struct buffer_head *bh)
++static struct buffer_head *__bread_slow_wq(struct buffer_head *bh,
++ wait_queue_t *wait)
+ {
+- lock_buffer(bh);
++ if (-EIOCBRETRY == lock_buffer_wq(bh, wait))
++ return ERR_PTR(-EIOCBRETRY);
++
+ if (buffer_uptodate(bh)) {
+ unlock_buffer(bh);
+ return bh;
+@@ -1308,7 +1339,8 @@
+ get_bh(bh);
+ bh->b_end_io = end_buffer_read_sync;
+ submit_bh(READ, bh);
+- wait_on_buffer(bh);
++ if (-EIOCBRETRY == wait_on_buffer_wq(bh, wait))
++ return ERR_PTR(-EIOCBRETRY);
+ if (buffer_uptodate(bh))
+ return bh;
+ }
+@@ -1316,6 +1348,11 @@
+ return NULL;
+ }
+
++static inline struct buffer_head *__bread_slow(struct buffer_head *bh)
++{
++ return __bread_slow_wq(bh, NULL);
++}
++
+ /*
+ * Per-cpu buffer LRU implementation. To reduce the cost of __find_get_block().
+ * The bhs[] array is sorted - newest buffer is at bhs[0]. Buffers have their
+@@ -1503,6 +1540,18 @@
+ }
+ EXPORT_SYMBOL(__bread);
+
++struct buffer_head *
++__bread_wq(struct block_device *bdev, sector_t block, int size,
++ wait_queue_t *wait)
++{
++ struct buffer_head *bh = __getblk(bdev, block, size);
++
++ if (!buffer_uptodate(bh))
++ bh = __bread_slow_wq(bh, wait);
++ return bh;
++}
++EXPORT_SYMBOL(__bread_wq);
++
+ /*
+ * invalidate_bh_lrus() is called rarely - at unmount. Because it is only for
+ * unmount it only needs to ensure that all buffers from the target device are
+@@ -1980,8 +2029,9 @@
+ /*
+ * If we issued read requests - let them complete.
+ */
+- while(wait_bh > wait) {
+- wait_on_buffer(*--wait_bh);
++ while (wait_bh > wait) {
++ if ((err = wait_on_buffer_wq(*--wait_bh, current->io_wait)))
++ return err;
+ if (!buffer_uptodate(*wait_bh))
+ return -EIO;
+ }
+Index: linux-2.6.0-test5/fs/char_dev.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/char_dev.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/char_dev.c 2003-09-27 11:38:36.126036392 +0800
+@@ -445,3 +445,18 @@
+ kset_register(&kset_dynamic);
+ cdev_map = kobj_map_init(base_probe, &cdev_subsys);
+ }
++
++
++/* Let modules do char dev stuff */
++EXPORT_SYMBOL(register_chrdev_region);
++EXPORT_SYMBOL(unregister_chrdev_region);
++EXPORT_SYMBOL(alloc_chrdev_region);
++EXPORT_SYMBOL(cdev_init);
++EXPORT_SYMBOL(cdev_alloc);
++EXPORT_SYMBOL(cdev_get);
++EXPORT_SYMBOL(cdev_put);
++EXPORT_SYMBOL(cdev_del);
++EXPORT_SYMBOL(cdev_add);
++EXPORT_SYMBOL(cdev_unmap);
++EXPORT_SYMBOL(register_chrdev);
++EXPORT_SYMBOL(unregister_chrdev);
+Index: linux-2.6.0-test5/fs/coda/cache.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/coda/cache.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/coda/cache.c 2003-09-27 11:38:36.128036088 +0800
+@@ -23,13 +23,16 @@
+ #include <linux/coda_fs_i.h>
+ #include <linux/coda_cache.h>
+
++static atomic_t permission_epoch = ATOMIC_INIT(0);
++
+ /* replace or extend an acl cache hit */
+ void coda_cache_enter(struct inode *inode, int mask)
+ {
+ struct coda_inode_info *cii = ITOC(inode);
+
+- if ( !coda_cred_ok(&cii->c_cached_cred) ) {
+- coda_load_creds(&cii->c_cached_cred);
++ cii->c_cached_epoch = atomic_read(&permission_epoch);
++ if (cii->c_uid != current->fsuid) {
++ cii->c_uid = current->fsuid;
+ cii->c_cached_perm = mask;
+ } else
+ cii->c_cached_perm |= mask;
+@@ -42,22 +45,15 @@
+ cii->c_cached_perm = 0;
+ }
+
+-/* remove all acl caches for a principal (or all principals when cred == NULL)*/
+-void coda_cache_clear_all(struct super_block *sb, struct coda_cred *cred)
++/* remove all acl caches */
++void coda_cache_clear_all(struct super_block *sb)
+ {
+ struct coda_sb_info *sbi;
+- struct coda_inode_info *cii;
+- struct list_head *tmp;
+
+ sbi = coda_sbp(sb);
+ if (!sbi) BUG();
+
+- list_for_each(tmp, &sbi->sbi_cihead)
+- {
+- cii = list_entry(tmp, struct coda_inode_info, c_cilist);
+- if (!cred || coda_cred_eq(cred, &cii->c_cached_cred))
+- cii->c_cached_perm = 0;
+- }
++ atomic_inc(&permission_epoch);
+ }
+
+
+@@ -67,8 +63,9 @@
+ struct coda_inode_info *cii = ITOC(inode);
+ int hit;
+
+- hit = ((mask & cii->c_cached_perm) == mask) &&
+- coda_cred_ok(&cii->c_cached_cred);
++ hit = (mask & cii->c_cached_perm) == mask &&
++ cii->c_uid == current->fsuid &&
++ cii->c_cached_epoch == atomic_read(&permission_epoch);
+
+ return hit;
+ }
+Index: linux-2.6.0-test5/fs/coda/cnode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/coda/cnode.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/coda/cnode.c 2003-09-27 11:38:36.130035784 +0800
+@@ -11,18 +11,9 @@
+ #include <linux/coda_fs_i.h>
+ #include <linux/coda_psdev.h>
+
+-inline int coda_fideq(ViceFid *fid1, ViceFid *fid2)
++inline int coda_fideq(struct CodaFid *fid1, struct CodaFid *fid2)
+ {
+- if (fid1->Vnode != fid2->Vnode) return 0;
+- if (fid1->Volume != fid2->Volume) return 0;
+- if (fid1->Unique != fid2->Unique) return 0;
+- return 1;
+-}
+-
+-inline int coda_isnullfid(ViceFid *fid)
+-{
+- if (fid->Vnode || fid->Volume || fid->Unique) return 0;
+- return 1;
++ return memcmp(fid1, fid2, sizeof(*fid1)) == 0;
+ }
+
+ static struct inode_operations coda_symlink_inode_operations = {
+@@ -47,18 +38,18 @@
+ inode->i_data.a_ops = &coda_symlink_aops;
+ inode->i_mapping = &inode->i_data;
+ } else
+- init_special_inode(inode, inode->i_mode, attr->va_rdev);
++ init_special_inode(inode, inode->i_mode, huge_decode_dev(attr->va_rdev));
+ }
+
+ static int coda_test_inode(struct inode *inode, void *data)
+ {
+- ViceFid *fid = (ViceFid *)data;
++ struct CodaFid *fid = (struct CodaFid *)data;
+ return coda_fideq(&(ITOC(inode)->c_fid), fid);
+ }
+
+ static int coda_set_inode(struct inode *inode, void *data)
+ {
+- ViceFid *fid = (ViceFid *)data;
++ struct CodaFid *fid = (struct CodaFid *)data;
+ ITOC(inode)->c_fid = *fid;
+ return 0;
+ }
+@@ -68,12 +59,11 @@
+ return -1;
+ }
+
+-struct inode * coda_iget(struct super_block * sb, ViceFid * fid,
++struct inode * coda_iget(struct super_block * sb, struct CodaFid * fid,
+ struct coda_vattr * attr)
+ {
+ struct inode *inode;
+ struct coda_inode_info *cii;
+- struct coda_sb_info *sbi = coda_sbp(sb);
+ unsigned long hash = coda_f2i(fid);
+
+ inode = iget5_locked(sb, hash, coda_test_inode, coda_set_inode, fid);
+@@ -86,7 +76,6 @@
+ /* we still need to set i_ino for things like stat(2) */
+ inode->i_ino = hash;
+ cii->c_mapcount = 0;
+- list_add(&cii->c_cilist, &sbi->sbi_cihead);
+ unlock_new_inode(inode);
+ }
+
+@@ -101,7 +90,7 @@
+ - link the two up if this is needed
+ - fill in the attributes
+ */
+-int coda_cnode_make(struct inode **inode, ViceFid *fid, struct super_block *sb)
++int coda_cnode_make(struct inode **inode, struct CodaFid *fid, struct super_block *sb)
+ {
+ struct coda_vattr attr;
+ int error;
+@@ -122,8 +111,8 @@
+ }
+
+
+-void coda_replace_fid(struct inode *inode, struct ViceFid *oldfid,
+- struct ViceFid *newfid)
++void coda_replace_fid(struct inode *inode, struct CodaFid *oldfid,
++ struct CodaFid *newfid)
+ {
+ struct coda_inode_info *cii;
+ unsigned long hash = coda_f2i(newfid);
+@@ -142,7 +131,7 @@
+ }
+
+ /* convert a fid to an inode. */
+-struct inode *coda_fid_to_inode(ViceFid *fid, struct super_block *sb)
++struct inode *coda_fid_to_inode(struct CodaFid *fid, struct super_block *sb)
+ {
+ struct inode *inode;
+ unsigned long hash = coda_f2i(fid);
+Index: linux-2.6.0-test5/fs/coda/coda_linux.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/coda/coda_linux.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/coda/coda_linux.c 2003-09-27 11:38:36.133035328 +0800
+@@ -25,10 +25,14 @@
+ int coda_fake_statfs;
+
+ /* print a fid */
+-char * coda_f2s(ViceFid *f)
++char * coda_f2s(struct CodaFid *f)
+ {
+ static char s[60];
+- sprintf(s, "(%-#lx.%-#lx.%-#lx)", f->Volume, f->Vnode, f->Unique);
++#ifdef CODA_FS_OLD_API
++ sprintf(s, "(%08x.%08x.%08x)", f->opaque[0], f->opaque[1], f->opaque[2]);
++#else
++ sprintf(s, "(%08x.%08x.%08x.%08x)", f->opaque[0], f->opaque[1], f->opaque[2], f->opaque[3]);
++#endif
+ return s;
+ }
+
+@@ -45,30 +49,6 @@
+ return ( i->i_sb->s_root->d_inode == i );
+ }
+
+-/* put the current process credentials in the cred */
+-void coda_load_creds(struct coda_cred *cred)
+-{
+- cred->cr_uid = (vuid_t) current->uid;
+- cred->cr_euid = (vuid_t) current->euid;
+- cred->cr_suid = (vuid_t) current->suid;
+- cred->cr_fsuid = (vuid_t) current->fsuid;
+-
+- cred->cr_groupid = (vgid_t) current->gid;
+- cred->cr_egid = (vgid_t) current->egid;
+- cred->cr_sgid = (vgid_t) current->sgid;
+- cred->cr_fsgid = (vgid_t) current->fsgid;
+-}
+-
+-int coda_cred_ok(struct coda_cred *cred)
+-{
+- return(current->fsuid == cred->cr_fsuid);
+-}
+-
+-int coda_cred_eq(struct coda_cred *cred1, struct coda_cred *cred2)
+-{
+- return (cred1->cr_fsuid == cred2->cr_fsuid);
+-}
+-
+ unsigned short coda_flags_to_cflags(unsigned short flags)
+ {
+ unsigned short coda_flags = 0;
+@@ -215,58 +195,3 @@
+ }
+ }
+
+-void print_vattr(struct coda_vattr *attr)
+-{
+- char *typestr;
+-
+- switch (attr->va_type) {
+- case C_VNON:
+- typestr = "C_VNON";
+- break;
+- case C_VREG:
+- typestr = "C_VREG";
+- break;
+- case C_VDIR:
+- typestr = "C_VDIR";
+- break;
+- case C_VBLK:
+- typestr = "C_VBLK";
+- break;
+- case C_VCHR:
+- typestr = "C_VCHR";
+- break;
+- case C_VLNK:
+- typestr = "C_VLNK";
+- break;
+- case C_VSOCK:
+- typestr = "C_VSCK";
+- break;
+- case C_VFIFO:
+- typestr = "C_VFFO";
+- break;
+- case C_VBAD:
+- typestr = "C_VBAD";
+- break;
+- default:
+- typestr = "????";
+- break;
+- }
+-
+-
+- printk("attr: type %s (%o) mode %o uid %d gid %d rdev %d\n",
+- typestr, (int)attr->va_type, (int)attr->va_mode,
+- (int)attr->va_uid, (int)attr->va_gid, (int)attr->va_rdev);
+-
+- printk(" fileid %d nlink %d size %d blocksize %d bytes %d\n",
+- (int)attr->va_fileid, (int)attr->va_nlink,
+- (int)attr->va_size,
+- (int)attr->va_blocksize,(int)attr->va_bytes);
+- printk(" gen %ld flags %ld\n",
+- attr->va_gen, attr->va_flags);
+- printk(" atime sec %d nsec %d\n",
+- (int)attr->va_atime.tv_sec, (int)attr->va_atime.tv_nsec);
+- printk(" mtime sec %d nsec %d\n",
+- (int)attr->va_mtime.tv_sec, (int)attr->va_mtime.tv_nsec);
+- printk(" ctime sec %d nsec %d\n",
+- (int)attr->va_ctime.tv_sec, (int)attr->va_ctime.tv_nsec);
+-}
+Index: linux-2.6.0-test5/fs/coda/dir.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/coda/dir.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/coda/dir.c 2003-09-27 11:38:36.138034568 +0800
+@@ -93,7 +93,7 @@
+ static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, struct nameidata *nd)
+ {
+ struct inode *res_inode = NULL;
+- struct ViceFid resfid = {0,0,0};
++ struct CodaFid resfid = { { 0, } };
+ int dropme = 0; /* to indicate entry should not be cached */
+ int type = 0;
+ int error = 0;
+@@ -196,7 +196,7 @@
+ const char *name=de->d_name.name;
+ int length=de->d_name.len;
+ struct inode *inode;
+- struct ViceFid newfid;
++ struct CodaFid newfid;
+ struct coda_vattr attrs;
+
+ lock_kernel();
+@@ -236,7 +236,7 @@
+ const char *name=de->d_name.name;
+ int length=de->d_name.len;
+ struct inode *inode;
+- struct ViceFid newfid;
++ struct CodaFid newfid;
+ struct coda_vattr attrs;
+
+ if ( coda_hasmknod == 0 )
+@@ -283,7 +283,7 @@
+ const char *name = de->d_name.name;
+ int len = de->d_name.len;
+ int error;
+- struct ViceFid newfid;
++ struct CodaFid newfid;
+
+ lock_kernel();
+ coda_vfs_stat.mkdir++;
+@@ -588,8 +588,7 @@
+ break;
+ }
+ /* validate whether the directory file actually makes sense */
+- if (vdir->d_reclen < vdir_size + vdir->d_namlen ||
+- vdir->d_namlen > CODA_MAXNAMLEN) {
++ if (vdir->d_reclen < vdir_size + vdir->d_namlen) {
+ printk("coda_venus_readdir: Invalid dir: %ld\n",
+ filp->f_dentry->d_inode->i_ino);
+ ret = -EBADF;
+Index: linux-2.6.0-test5/fs/coda/file.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/coda/file.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/coda/file.c 2003-09-27 11:38:36.141034112 +0800
+@@ -136,7 +136,6 @@
+ cfi->cfi_magic = CODA_MAGIC;
+ cfi->cfi_mapcount = 0;
+ cfi->cfi_container = host_file;
+- coda_load_creds(&cfi->cfi_cred);
+
+ BUG_ON(coda_file->private_data != NULL);
+ coda_file->private_data = cfi;
+@@ -176,7 +175,7 @@
+ coda_inode = coda_file->f_dentry->d_inode;
+
+ err = venus_store(coda_inode->i_sb, coda_i2f(coda_inode), coda_flags,
+- &cfi->cfi_cred);
++ coda_file->f_uid);
+
+ if (err == -EOPNOTSUPP) {
+ use_coda_close = 1;
+@@ -214,7 +213,7 @@
+
+ if (use_coda_close)
+ err = venus_close(coda_inode->i_sb, coda_i2f(coda_inode),
+- coda_flags, &cfi->cfi_cred);
++ coda_flags, coda_file->f_uid);
+
+ host_inode = cfi->cfi_container->f_dentry->d_inode;
+ cii = ITOC(coda_inode);
+Index: linux-2.6.0-test5/fs/coda/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/coda/inode.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/coda/inode.c 2003-09-27 11:38:36.143033808 +0800
+@@ -44,10 +44,9 @@
+ ei = (struct coda_inode_info *)kmem_cache_alloc(coda_inode_cachep, SLAB_KERNEL);
+ if (!ei)
+ return NULL;
+- memset(&ei->c_fid, 0, sizeof(struct ViceFid));
++ memset(&ei->c_fid, 0, sizeof(struct CodaFid));
+ ei->c_flags = 0;
+- INIT_LIST_HEAD(&ei->c_cilist);
+- memset(&ei->c_cached_cred, 0, sizeof(struct coda_cred));
++ ei->c_uid = 0;
+ ei->c_cached_perm = 0;
+ return &ei->vfs_inode;
+ }
+@@ -139,7 +138,7 @@
+ struct inode *root = 0;
+ struct coda_sb_info *sbi = NULL;
+ struct venus_comm *vc = NULL;
+- ViceFid fid;
++ struct CodaFid fid;
+ int error;
+ int idx;
+
+@@ -169,9 +168,7 @@
+
+ vc->vc_sb = sb;
+
+- sbi->sbi_sb = sb;
+ sbi->sbi_vcomm = vc;
+- INIT_LIST_HEAD(&sbi->sbi_cihead);
+
+ sb->s_fs_info = sbi;
+ sb->s_blocksize = 1024; /* XXXXX what do we put here?? */
+@@ -218,7 +215,6 @@
+
+ sbi = coda_sbp(sb);
+ sbi->sbi_vcomm->vc_sb = NULL;
+- list_del_init(&sbi->sbi_cihead);
+
+ printk("Coda: Bye bye.\n");
+ kfree(sbi);
+@@ -226,9 +222,6 @@
+
+ static void coda_clear_inode(struct inode *inode)
+ {
+- struct coda_inode_info *cii = ITOC(inode);
+-
+- list_del_init(&cii->c_cilist);
+ coda_cache_clear_inode(inode);
+ }
+
+Index: linux-2.6.0-test5/fs/coda/psdev.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/coda/psdev.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/coda/psdev.c 2003-09-27 11:38:36.147033200 +0800
+@@ -61,7 +61,6 @@
+
+
+ struct venus_comm coda_comms[MAX_CODADEVS];
+-kmem_cache_t *cii_cache, *cred_cache, *upc_cache;
+
+ /*
+ * Device operations
+@@ -126,13 +125,13 @@
+ }
+
+ if ( nbytes < sizeof(struct coda_out_hdr) ) {
+- printk("coda_downcall opc %ld uniq %ld, not enough!\n",
++ printk("coda_downcall opc %d uniq %d, not enough!\n",
+ hdr.opcode, hdr.unique);
+ count = nbytes;
+ goto out;
+ }
+ if ( nbytes > size ) {
+- printk("Coda: downcall opc %ld, uniq %ld, too much!",
++ printk("Coda: downcall opc %d, uniq %d, too much!",
+ hdr.opcode, hdr.unique);
+ nbytes = size;
+ }
+@@ -171,7 +170,7 @@
+ unlock_kernel();
+
+ if (!req) {
+- printk("psdev_write: msg (%ld, %ld) not found\n",
++ printk("psdev_write: msg (%d, %d) not found\n",
+ hdr.opcode, hdr.unique);
+ retval = -ESRCH;
+ goto out;
+@@ -179,7 +178,7 @@
+
+ /* move data into response buffer. */
+ if (req->uc_outSize < nbytes) {
+- printk("psdev_write: too much cnt: %d, cnt: %ld, opc: %ld, uniq: %ld.\n",
++ printk("psdev_write: too much cnt: %d, cnt: %ld, opc: %d, uniq: %d.\n",
+ req->uc_outSize, (long)nbytes, hdr.opcode, hdr.unique);
+ nbytes = req->uc_outSize; /* don't have more space! */
+ }
+@@ -325,10 +324,7 @@
+ }
+
+ /* Wakeup clients so they can return. */
+- lh = vcp->vc_pending.next;
+- next = lh;
+- while ( (lh = next) != &vcp->vc_pending) {
+- next = lh->next;
++ list_for_each_safe(lh, next, &vcp->vc_pending) {
+ req = list_entry(lh, struct upc_req, uc_chain);
+ /* Async requests need to be freed here */
+ if (req->uc_flags & REQ_ASYNC) {
+@@ -340,9 +336,7 @@
+ wake_up(&req->uc_sleep);
+ }
+
+- lh = &vcp->vc_processing;
+- while ( (lh = lh->next) != &vcp->vc_processing) {
+- req = list_entry(lh, struct upc_req, uc_chain);
++ list_for_each_entry(req, &vcp->vc_processing, uc_chain) {
+ req->uc_flags |= REQ_ABORT;
+ wake_up(&req->uc_sleep);
+ }
+@@ -390,7 +384,13 @@
+ {
+ int status;
+ int i;
+- printk(KERN_INFO "Coda Kernel/Venus communications, v5.3.15, coda@cs.cmu.edu\n");
++ printk(KERN_INFO "Coda Kernel/Venus communications, "
++#ifdef CODA_FS_OLD_API
++ "v5.3.20"
++#else
++ "v6.0.0"
++#endif
++ ", coda@cs.cmu.edu\n");
+
+ status = coda_init_inodecache();
+ if (status)
+Index: linux-2.6.0-test5/fs/coda/upcall.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/coda/upcall.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/coda/upcall.c 2003-09-27 11:38:36.155031984 +0800
+@@ -54,9 +54,13 @@
+
+ inp->ih.opcode = opcode;
+ inp->ih.pid = current->pid;
+- inp->ih.pgid = current->pgrp;
+- coda_load_creds(&(inp->ih.cred));
+-
++ inp->ih.pgid = process_group(current);
++#ifdef CODA_FS_OLD_API
++ memset(&inp->ih.cred, 0, sizeof(struct coda_cred));
++ inp->ih.cred.cr_fsuid = current->fsuid;
++#else
++ inp->ih.uid = current->fsuid;
++#endif
+ return (void*)inp;
+ }
+
+@@ -74,7 +78,7 @@
+
+
+ /* the upcalls */
+-int venus_rootfid(struct super_block *sb, ViceFid *fidp)
++int venus_rootfid(struct super_block *sb, struct CodaFid *fidp)
+ {
+ union inputArgs *inp;
+ union outputArgs *outp;
+@@ -88,14 +92,14 @@
+ if (error) {
+ printk("coda_get_rootfid: error %d\n", error);
+ } else {
+- *fidp = (ViceFid) outp->coda_root.VFid;
++ *fidp = outp->coda_root.VFid;
+ }
+
+ CODA_FREE(inp, insize);
+ return error;
+ }
+
+-int venus_getattr(struct super_block *sb, struct ViceFid *fid,
++int venus_getattr(struct super_block *sb, struct CodaFid *fid,
+ struct coda_vattr *attr)
+ {
+ union inputArgs *inp;
+@@ -114,7 +118,7 @@
+ return error;
+ }
+
+-int venus_setattr(struct super_block *sb, struct ViceFid *fid,
++int venus_setattr(struct super_block *sb, struct CodaFid *fid,
+ struct coda_vattr *vattr)
+ {
+ union inputArgs *inp;
+@@ -133,9 +137,9 @@
+ return error;
+ }
+
+-int venus_lookup(struct super_block *sb, struct ViceFid *fid,
++int venus_lookup(struct super_block *sb, struct CodaFid *fid,
+ const char *name, int length, int * type,
+- struct ViceFid *resfid)
++ struct CodaFid *resfid)
+ {
+ union inputArgs *inp;
+ union outputArgs *outp;
+@@ -162,17 +166,25 @@
+ return error;
+ }
+
+-int venus_store(struct super_block *sb, struct ViceFid *fid, int flags,
+- struct coda_cred *cred)
++int venus_store(struct super_block *sb, struct CodaFid *fid, int flags,
++ vuid_t uid)
+ {
+ union inputArgs *inp;
+ union outputArgs *outp;
+ int insize, outsize, error;
++#ifdef CODA_FS_OLD_API
++ struct coda_cred cred = { 0, };
++ cred.cr_fsuid = uid;
++#endif
+
+ insize = SIZE(store);
+ UPARG(CODA_STORE);
+
+- memcpy(&(inp->ih.cred), cred, sizeof(*cred));
++#ifdef CODA_FS_OLD_API
++ memcpy(&(inp->ih.cred), &cred, sizeof(cred));
++#else
++ inp->ih.uid = uid;
++#endif
+
+ inp->coda_store.VFid = *fid;
+ inp->coda_store.flags = flags;
+@@ -183,7 +195,7 @@
+ return error;
+ }
+
+-int venus_release(struct super_block *sb, struct ViceFid *fid, int flags)
++int venus_release(struct super_block *sb, struct CodaFid *fid, int flags)
+ {
+ union inputArgs *inp;
+ union outputArgs *outp;
+@@ -201,17 +213,25 @@
+ return error;
+ }
+
+-int venus_close(struct super_block *sb, struct ViceFid *fid, int flags,
+- struct coda_cred *cred)
++int venus_close(struct super_block *sb, struct CodaFid *fid, int flags,
++ vuid_t uid)
+ {
+ union inputArgs *inp;
+ union outputArgs *outp;
+ int insize, outsize, error;
++#ifdef CODA_FS_OLD_API
++ struct coda_cred cred = { 0, };
++ cred.cr_fsuid = uid;
++#endif
+
+ insize = SIZE(release);
+ UPARG(CODA_CLOSE);
+
+- memcpy(&(inp->ih.cred), cred, sizeof(*cred));
++#ifdef CODA_FS_OLD_API
++ memcpy(&(inp->ih.cred), &cred, sizeof(cred));
++#else
++ inp->ih.uid = uid;
++#endif
+
+ inp->coda_close.VFid = *fid;
+ inp->coda_close.flags = flags;
+@@ -222,7 +242,7 @@
+ return error;
+ }
+
+-int venus_open(struct super_block *sb, struct ViceFid *fid,
++int venus_open(struct super_block *sb, struct CodaFid *fid,
+ int flags, struct file **fh)
+ {
+ union inputArgs *inp;
+@@ -243,9 +263,9 @@
+ return error;
+ }
+
+-int venus_mkdir(struct super_block *sb, struct ViceFid *dirfid,
++int venus_mkdir(struct super_block *sb, struct CodaFid *dirfid,
+ const char *name, int length,
+- struct ViceFid *newfid, struct coda_vattr *attrs)
++ struct CodaFid *newfid, struct coda_vattr *attrs)
+ {
+ union inputArgs *inp;
+ union outputArgs *outp;
+@@ -273,8 +293,8 @@
+ }
+
+
+-int venus_rename(struct super_block *sb, struct ViceFid *old_fid,
+- struct ViceFid *new_fid, size_t old_length,
++int venus_rename(struct super_block *sb, struct CodaFid *old_fid,
++ struct CodaFid *new_fid, size_t old_length,
+ size_t new_length, const char *old_name,
+ const char *new_name)
+ {
+@@ -310,9 +330,9 @@
+ return error;
+ }
+
+-int venus_create(struct super_block *sb, struct ViceFid *dirfid,
++int venus_create(struct super_block *sb, struct CodaFid *dirfid,
+ const char *name, int length, int excl, int mode, dev_t rdev,
+- struct ViceFid *newfid, struct coda_vattr *attrs)
++ struct CodaFid *newfid, struct coda_vattr *attrs)
+ {
+ union inputArgs *inp;
+ union outputArgs *outp;
+@@ -325,7 +345,7 @@
+
+ inp->coda_create.VFid = *dirfid;
+ inp->coda_create.attr.va_mode = mode;
+- inp->coda_create.attr.va_rdev = rdev;
++ inp->coda_create.attr.va_rdev = huge_encode_dev(rdev);
+ inp->coda_create.excl = excl;
+ inp->coda_create.mode = mode;
+ inp->coda_create.name = offset;
+@@ -343,7 +363,7 @@
+ return error;
+ }
+
+-int venus_rmdir(struct super_block *sb, struct ViceFid *dirfid,
++int venus_rmdir(struct super_block *sb, struct CodaFid *dirfid,
+ const char *name, int length)
+ {
+ union inputArgs *inp;
+@@ -366,7 +386,7 @@
+ return error;
+ }
+
+-int venus_remove(struct super_block *sb, struct ViceFid *dirfid,
++int venus_remove(struct super_block *sb, struct CodaFid *dirfid,
+ const char *name, int length)
+ {
+ union inputArgs *inp;
+@@ -388,7 +408,7 @@
+ return error;
+ }
+
+-int venus_readlink(struct super_block *sb, struct ViceFid *fid,
++int venus_readlink(struct super_block *sb, struct CodaFid *fid,
+ char *buffer, int *length)
+ {
+ union inputArgs *inp;
+@@ -421,8 +441,8 @@
+
+
+
+-int venus_link(struct super_block *sb, struct ViceFid *fid,
+- struct ViceFid *dirfid, const char *name, int len )
++int venus_link(struct super_block *sb, struct CodaFid *fid,
++ struct CodaFid *dirfid, const char *name, int len )
+ {
+ union inputArgs *inp;
+ union outputArgs *outp;
+@@ -447,7 +467,7 @@
+ return error;
+ }
+
+-int venus_symlink(struct super_block *sb, struct ViceFid *fid,
++int venus_symlink(struct super_block *sb, struct CodaFid *fid,
+ const char *name, int len,
+ const char *symname, int symlen)
+ {
+@@ -482,7 +502,7 @@
+ return error;
+ }
+
+-int venus_fsync(struct super_block *sb, struct ViceFid *fid)
++int venus_fsync(struct super_block *sb, struct CodaFid *fid)
+ {
+ union inputArgs *inp;
+ union outputArgs *outp;
+@@ -499,7 +519,7 @@
+ return error;
+ }
+
+-int venus_access(struct super_block *sb, struct ViceFid *fid, int mask)
++int venus_access(struct super_block *sb, struct CodaFid *fid, int mask)
+ {
+ union inputArgs *inp;
+ union outputArgs *outp;
+@@ -518,7 +538,7 @@
+ }
+
+
+-int venus_pioctl(struct super_block *sb, struct ViceFid *fid,
++int venus_pioctl(struct super_block *sb, struct CodaFid *fid,
+ unsigned int cmd, struct PioctlData *data)
+ {
+ union inputArgs *inp;
+@@ -808,7 +828,7 @@
+ * The last allows Venus to replace local fids with global ones
+ * during reintegration.
+ *
+- * CODA_REPLACE -- replace one ViceFid with another throughout the name cache */
++ * CODA_REPLACE -- replace one CodaFid with another throughout the name cache */
+
+ int coda_downcall(int opcode, union outputArgs * out, struct super_block *sb)
+ {
+@@ -819,25 +839,20 @@
+ switch (opcode) {
+
+ case CODA_FLUSH : {
+- coda_cache_clear_all(sb, NULL);
++ coda_cache_clear_all(sb);
+ shrink_dcache_sb(sb);
+ coda_flag_inode(sb->s_root->d_inode, C_FLUSH);
+ return(0);
+ }
+
+ case CODA_PURGEUSER : {
+- struct coda_cred *cred = &out->coda_purgeuser.cred;
+- if ( !cred ) {
+- printk("PURGEUSER: null cred!\n");
+- return 0;
+- }
+- coda_cache_clear_all(sb, cred);
++ coda_cache_clear_all(sb);
+ return(0);
+ }
+
+ case CODA_ZAPDIR : {
+ struct inode *inode;
+- ViceFid *fid = &out->coda_zapdir.CodaFid;
++ struct CodaFid *fid = &out->coda_zapdir.CodaFid;
+
+ inode = coda_fid_to_inode(fid, sb);
+ if (inode) {
+@@ -851,7 +866,7 @@
+
+ case CODA_ZAPFILE : {
+ struct inode *inode;
+- struct ViceFid *fid = &out->coda_zapfile.CodaFid;
++ struct CodaFid *fid = &out->coda_zapfile.CodaFid;
+ inode = coda_fid_to_inode(fid, sb);
+ if ( inode ) {
+ coda_flag_inode(inode, C_VATTR);
+@@ -862,7 +877,7 @@
+
+ case CODA_PURGEFID : {
+ struct inode *inode;
+- ViceFid *fid = &out->coda_purgefid.CodaFid;
++ struct CodaFid *fid = &out->coda_purgefid.CodaFid;
+ inode = coda_fid_to_inode(fid, sb);
+ if ( inode ) {
+ coda_flag_inode_children(inode, C_PURGE);
+@@ -878,8 +893,8 @@
+
+ case CODA_REPLACE : {
+ struct inode *inode;
+- ViceFid *oldfid = &out->coda_replace.OldFid;
+- ViceFid *newfid = &out->coda_replace.NewFid;
++ struct CodaFid *oldfid = &out->coda_replace.OldFid;
++ struct CodaFid *newfid = &out->coda_replace.NewFid;
+ inode = coda_fid_to_inode(oldfid, sb);
+ if ( inode ) {
+ coda_replace_fid(inode, oldfid, newfid);
+Index: linux-2.6.0-test5/fs/dcache.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/dcache.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/dcache.c 2003-09-27 11:38:36.166030312 +0800
+@@ -82,7 +82,7 @@
+ /*
+ * Release the dentry's inode, using the filesystem
+ * d_iput() operation if defined.
+- * Called with dcache_lock held, drops it.
++ * Called with dcache_lock and per dentry lock held, drops both.
+ */
+ static inline void dentry_iput(struct dentry * dentry)
+ {
+@@ -90,13 +90,16 @@
+ if (inode) {
+ dentry->d_inode = NULL;
+ list_del_init(&dentry->d_alias);
++ spin_unlock(&dentry->d_lock);
+ spin_unlock(&dcache_lock);
+ if (dentry->d_op && dentry->d_op->d_iput)
+ dentry->d_op->d_iput(dentry, inode);
+ else
+ iput(inode);
+- } else
++ } else {
++ spin_unlock(&dentry->d_lock);
+ spin_unlock(&dcache_lock);
++ }
+ }
+
+ /*
+@@ -177,9 +180,8 @@
+ dentry_stat.nr_unused--;
+ }
+ list_del(&dentry->d_child);
+- spin_unlock(&dentry->d_lock);
+ dentry_stat.nr_dentry--; /* For d_free, below */
+- /* drops the lock, at that point nobody can reach this dentry */
++ /*drops the locks, at that point nobody can reach this dentry */
+ dentry_iput(dentry);
+ parent = dentry->d_parent;
+ d_free(dentry);
+@@ -341,7 +343,6 @@
+
+ __d_drop(dentry);
+ list_del(&dentry->d_child);
+- spin_unlock(&dentry->d_lock);
+ dentry_stat.nr_dentry--; /* For d_free, below */
+ dentry_iput(dentry);
+ parent = dentry->d_parent;
+@@ -1116,7 +1117,6 @@
+ spin_lock(&dcache_lock);
+ spin_lock(&dentry->d_lock);
+ if (atomic_read(&dentry->d_count) == 1) {
+- spin_unlock(&dentry->d_lock);
+ dentry_iput(dentry);
+ return;
+ }
+Index: linux-2.6.0-test5/fs/devfs/base.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/devfs/base.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/devfs/base.c 2003-09-27 11:38:36.189026816 +0800
+@@ -1334,7 +1334,7 @@
+ struct task_struct *p = current;
+
+ if (p == fs_info->devfsd_task) return (TRUE);
+- if (p->pgrp == fs_info->devfsd_pgrp) return (TRUE);
++ if (process_group(p) == fs_info->devfsd_pgrp) return (TRUE);
+ read_lock(&tasklist_lock);
+ for ( ; p != &init_task; p = p->real_parent)
+ {
+@@ -2744,8 +2744,8 @@
+ }
+ fs_info->devfsd_task = current;
+ spin_unlock (&lock);
+- fs_info->devfsd_pgrp = (current->pgrp == current->pid) ?
+- current->pgrp : 0;
++ fs_info->devfsd_pgrp = (process_group(current) == current->pid) ?
++ process_group(current) : 0;
+ fs_info->devfsd_file = file;
+ fs_info->devfsd_info = kmalloc (sizeof *fs_info->devfsd_info,
+ GFP_KERNEL);
+Index: linux-2.6.0-test5/fs/direct-io.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/direct-io.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/direct-io.c 2003-09-27 11:38:36.197025600 +0800
+@@ -58,6 +58,7 @@
+ struct bio *bio; /* bio under assembly */
+ struct inode *inode;
+ int rw;
++ int is_reg_file;
+ unsigned blkbits; /* doesn't change */
+ unsigned blkfactor; /* When we're using an alignment which
+ is finer than the filesystem's soft
+@@ -205,6 +206,8 @@
+ {
+ if (dio->end_io)
+ dio->end_io(dio->inode, offset, bytes, dio->map_bh.b_private);
++ if (dio->is_reg_file)
++ up_read(&dio->inode->i_alloc_sem);
+ }
+
+ /*
+@@ -448,6 +451,7 @@
+ unsigned long fs_count; /* Number of filesystem-sized blocks */
+ unsigned long dio_count;/* Number of dio_block-sized blocks */
+ unsigned long blkmask;
++ int beyond_eof = 0;
+
+ /*
+ * If there was a memory error and we've overwritten all the
+@@ -465,8 +469,17 @@
+ if (dio_count & blkmask)
+ fs_count++;
+
++ if (dio->is_reg_file) {
++ if (dio->block_in_file >= (i_size_read(dio->inode) >>
++ dio->blkbits))
++ beyond_eof = 1;
++ }
++ /*
++ * AKPM: huh? We call get_blocks(create==0) for hole
++ * overwrites?
++ */
+ ret = (*dio->get_blocks)(dio->inode, fs_startblk, fs_count,
+- map_bh, dio->rw == WRITE);
++ map_bh, (dio->rw == WRITE) && beyond_eof);
+ }
+ return ret;
+ }
+@@ -773,6 +786,10 @@
+ if (!buffer_mapped(map_bh)) {
+ char *kaddr;
+
++ /* AKPM: eargh, -ENOTBLK is a hack */
++ if (dio->rw == WRITE)
++ return -ENOTBLK;
++
+ if (dio->block_in_file >=
+ i_size_read(dio->inode)>>blkbits) {
+ /* We hit eof */
+@@ -841,18 +858,15 @@
+ static int
+ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode,
+ const struct iovec *iov, loff_t offset, unsigned long nr_segs,
+- unsigned blkbits, get_blocks_t get_blocks, dio_iodone_t end_io)
++ unsigned blkbits, get_blocks_t get_blocks, dio_iodone_t end_io,
++ struct dio *dio)
+ {
+ unsigned long user_addr;
+ int seg;
+ int ret = 0;
+ int ret2;
+- struct dio *dio;
+ size_t bytes;
+
+- dio = kmalloc(sizeof(*dio), GFP_KERNEL);
+- if (!dio)
+- return -ENOMEM;
+ dio->is_async = !is_sync_kiocb(iocb);
+
+ dio->bio = NULL;
+@@ -863,6 +877,10 @@
+ dio->start_zero_done = 0;
+ dio->block_in_file = offset >> blkbits;
+ dio->blocks_available = 0;
++ if (S_ISREG(inode->i_mode))
++ dio->is_reg_file = 1;
++ else
++ dio->is_reg_file = 0;
+
+ dio->cur_page = NULL;
+
+@@ -949,6 +967,8 @@
+ * OK, all BIOs are submitted, so we can decrement bio_count to truly
+ * reflect the number of to-be-processed BIOs.
+ */
++ if (dio->is_reg_file)
++ up(&dio->inode->i_sem); /* Don't need i_sem any more */
+ if (dio->is_async) {
+ if (ret == 0)
+ ret = dio->result; /* Bytes written */
+@@ -993,6 +1013,7 @@
+ unsigned bdev_blkbits = 0;
+ unsigned blocksize_mask = (1 << blkbits) - 1;
+ ssize_t retval = -EINVAL;
++ struct dio *dio;
+
+ if (bdev)
+ bdev_blkbits = blksize_bits(bdev_hardsect_size(bdev));
+@@ -1018,8 +1039,16 @@
+ }
+ }
+
+- retval = direct_io_worker(rw, iocb, inode, iov, offset,
+- nr_segs, blkbits, get_blocks, end_io);
++ dio = kmalloc(sizeof(*dio), GFP_KERNEL);
++ retval = -ENOMEM;
++ if (!dio)
++ goto out;
++
++ return direct_io_worker(rw, iocb, inode, iov, offset,
++ nr_segs, blkbits, get_blocks, end_io, dio);
+ out:
++ up(&inode->i_sem);
++ if (S_ISREG(inode->i_mode))
++ up_read(&inode->i_alloc_sem);
+ return retval;
+ }
+Index: linux-2.6.0-test5/fs/efs/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/efs/inode.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/efs/inode.c 2003-09-27 11:38:36.201024992 +0800
+@@ -47,9 +47,11 @@
+ return;
+ }
+
+-void efs_read_inode(struct inode *inode) {
++void efs_read_inode(struct inode *inode)
++{
+ int i, inode_index;
+ dev_t device;
++ u32 rdev;
+ struct buffer_head *bh;
+ struct efs_sb_info *sb = SUPER_INFO(inode->i_sb);
+ struct efs_inode_info *in = INODE_INFO(inode);
+@@ -104,20 +106,15 @@
+ inode->i_blocks = ((inode->i_size - 1) >> EFS_BLOCKSIZE_BITS) + 1;
+ }
+
+- /*
+- * BUG: irix dev_t is 32-bits. linux dev_t is only 16-bits.
+- *
+- * apparently linux will change to 32-bit dev_t sometime during
+- * linux 2.3.
+- *
+- * as is, this code maps devices that can't be represented in
+- * 16-bits (ie major > 255 or minor > 255) to major = minor = 255.
+- *
+- * during 2.3 when 32-bit dev_t become available, we should test
+- * to see whether odev contains 65535. if this is the case then we
+- * should then do device = be32_to_cpu(efs_inode->di_u.di_dev.ndev).
+- */
+- device = old_decode_dev(be16_to_cpu(efs_inode->di_u.di_dev.odev));
++ rdev = be16_to_cpu(efs_inode->di_u.di_dev.odev);
++ if (rdev == 0xffff) {
++ rdev = be32_to_cpu(efs_inode->di_u.di_dev.ndev);
++ if (sysv_major(rdev) > 0xfff)
++ device = 0;
++ else
++ device = MKDEV(sysv_major(rdev), sysv_minor(rdev));
++ } else
++ device = old_decode_dev(rdev);
+
+ /* get the number of extents for this object */
+ in->numextents = be16_to_cpu(efs_inode->di_numextents);
+Index: linux-2.6.0-test5/fs/eventpoll.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/eventpoll.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/eventpoll.c 2003-09-27 11:38:36.213023168 +0800
+@@ -288,8 +288,10 @@
+ static int ep_alloc_pages(char **pages, int numpages);
+ static int ep_free_pages(char **pages, int numpages);
+ static int ep_file_init(struct file *file, unsigned int hashbits);
+-static unsigned int ep_hash_index(struct eventpoll *ep, struct file *file, int fd);
+-static struct list_head *ep_hash_entry(struct eventpoll *ep, unsigned int index);
++static unsigned int ep_hash_index(struct eventpoll *ep, struct file *file,
++ int fd);
++static struct list_head *ep_hash_entry(struct eventpoll *ep,
++ unsigned int index);
+ static int ep_init(struct eventpoll *ep, unsigned int hashbits);
+ static void ep_free(struct eventpoll *ep);
+ static struct epitem *ep_find(struct eventpoll *ep, struct file *file, int fd);
+@@ -299,7 +301,8 @@
+ poll_table *pt);
+ static int ep_insert(struct eventpoll *ep, struct epoll_event *event,
+ struct file *tfile, int fd);
+-static int ep_modify(struct eventpoll *ep, struct epitem *epi, struct epoll_event *event);
++static int ep_modify(struct eventpoll *ep, struct epitem *epi,
++ struct epoll_event *event);
+ static void ep_unregister_pollwait(struct eventpoll *ep, struct epitem *epi);
+ static int ep_unlink(struct eventpoll *ep, struct epitem *epi);
+ static int ep_remove(struct eventpoll *ep, struct epitem *epi);
+@@ -309,11 +312,12 @@
+ static int ep_collect_ready_items(struct eventpoll *ep,
+ struct list_head *txlist, int maxevents);
+ static int ep_send_events(struct eventpoll *ep, struct list_head *txlist,
+- struct epoll_event *events);
++ struct epoll_event __user *events);
+ static void ep_reinject_items(struct eventpoll *ep, struct list_head *txlist);
+ static int ep_events_transfer(struct eventpoll *ep,
+- struct epoll_event *events, int maxevents);
+-static int ep_poll(struct eventpoll *ep, struct epoll_event *events,
++ struct epoll_event __user *events,
++ int maxevents);
++static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
+ int maxevents, long timeout);
+ static int eventpollfs_delete_dentry(struct dentry *dentry);
+ static struct inode *ep_eventpoll_inode(void);
+@@ -532,11 +536,13 @@
+
+
+ /*
+- * The following function implement the controller interface for the eventpoll
+- * file that enable the insertion/removal/change of file descriptors inside
+- * the interest set. It rapresents the kernel part of the user space epoll_ctl(2).
++ * The following function implements the controller interface for
++ * the eventpoll file that enables the insertion/removal/change of
++ * file descriptors inside the interest set. It represents
++ * the kernel part of the user space epoll_ctl(2).
+ */
+-asmlinkage long sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
++asmlinkage long
++sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event __user *event)
+ {
+ int error;
+ struct file *file, *tfile;
+@@ -637,8 +643,8 @@
+ * Implement the event wait interface for the eventpoll file. It is the kernel
+ * part of the user space epoll_wait(2).
+ */
+-asmlinkage long sys_epoll_wait(int epfd, struct epoll_event *events, int maxevents,
+- int timeout)
++asmlinkage long sys_epoll_wait(int epfd, struct epoll_event __user *events,
++ int maxevents, int timeout)
+ {
+ int error;
+ struct file *file;
+@@ -662,7 +668,7 @@
+ goto eexit_1;
+
+ /*
+- * We have to check that the file structure underneath the file descriptor
++ * We have to check that the file structure underneath the fd
+ * the user passed to us _is_ an eventpoll file.
+ */
+ error = -EINVAL;
+@@ -1409,7 +1415,7 @@
+ * because of the way poll() is traditionally implemented in Linux.
+ */
+ static int ep_send_events(struct eventpoll *ep, struct list_head *txlist,
+- struct epoll_event *events)
++ struct epoll_event __user *events)
+ {
+ int eventcnt = 0, eventbuf = 0;
+ unsigned int revents;
+@@ -1521,7 +1527,8 @@
+ /*
+ * Perform the transfer of events to user space.
+ */
+-static int ep_events_transfer(struct eventpoll *ep, struct epoll_event *events, int maxevents)
++static int ep_events_transfer(struct eventpoll *ep,
++ struct epoll_event __user *events, int maxevents)
+ {
+ int eventcnt = 0;
+ struct list_head txlist;
+@@ -1549,8 +1556,8 @@
+ }
+
+
+-static int ep_poll(struct eventpoll *ep, struct epoll_event *events, int maxevents,
+- long timeout)
++static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
++ int maxevents, long timeout)
+ {
+ int res, eavail;
+ unsigned long flags;
+Index: linux-2.6.0-test5/fs/exec.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/exec.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/exec.c 2003-09-27 11:38:36.221021952 +0800
+@@ -56,7 +56,7 @@
+
+ int core_uses_pid;
+ char core_pattern[65] = "core";
+-/* The maximal length of core_pattern is also specified in sysctl.c */
++/* The maximal length of core_pattern is also specified in sysctl.c */
+
+ static struct linux_binfmt *formats;
+ static rwlock_t binfmt_lock = RW_LOCK_UNLOCKED;
+@@ -190,7 +190,7 @@
+ * memory to free pages in kernel mem. These are in a format ready
+ * to be put directly into the top of new user memory.
+ */
+-int copy_strings(int argc,char __user * __user * argv, struct linux_binprm *bprm)
++int copy_strings(int argc,char __user * __user * argv, struct linux_binprm *bprm)
+ {
+ struct page *kmapped_page = NULL;
+ char *kaddr = NULL;
+@@ -213,7 +213,7 @@
+ }
+
+ bprm->p -= len;
+- /* XXX: add architecture specific overflow check here. */
++ /* XXX: add architecture specific overflow check here. */
+ pos = bprm->p;
+
+ while (len > 0) {
+@@ -275,10 +275,10 @@
+ {
+ int r;
+ mm_segment_t oldfs = get_fs();
+- set_fs(KERNEL_DS);
++ set_fs(KERNEL_DS);
+ r = copy_strings(argc, (char __user * __user *)argv, bprm);
+ set_fs(oldfs);
+- return r;
++ return r;
+ }
+
+ #ifdef CONFIG_MMU
+@@ -374,7 +374,13 @@
+
+ /* Adjust bprm->p to point to the end of the strings. */
+ bprm->p = PAGE_SIZE * i - offset;
+- stack_base = STACK_TOP - current->rlim[RLIMIT_STACK].rlim_max;
++
++ /* Limit stack size to 1GB */
++ stack_base = current->rlim[RLIMIT_STACK].rlim_max;
++ if (stack_base > (1 << 30))
++ stack_base = 1 << 30;
++ stack_base = PAGE_ALIGN(STACK_TOP - stack_base);
++
+ mm->arg_start = stack_base;
+ arg_size = i << PAGE_SHIFT;
+
+@@ -421,7 +427,7 @@
+ mpnt->vm_private_data = (void *) 0;
+ insert_vm_struct(mm, mpnt);
+ mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
+- }
++ }
+
+ for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
+ struct page *page = bprm->page[i];
+@@ -803,7 +809,7 @@
+
+ /* An exec changes our domain. We are no longer part of the thread
+ group */
+-
++
+ current->self_exec_id++;
+
+ flush_signal_handlers(current, 0);
+@@ -887,7 +893,7 @@
+ *
+ */
+
+-void compute_creds(struct linux_binprm *bprm)
++void compute_creds(struct linux_binprm *bprm)
+ {
+ task_lock(current);
+ if (bprm->e_uid != current->uid || bprm->e_gid != current->gid) {
+@@ -1052,7 +1058,7 @@
+ return retval;
+
+ bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
+- memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0]));
++ memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0]));
+
+ bprm.file = file;
+ bprm.filename = filename;
+@@ -1083,21 +1089,21 @@
+ goto out;
+
+ retval = prepare_binprm(&bprm);
+- if (retval < 0)
+- goto out;
++ if (retval < 0)
++ goto out;
+
+ retval = copy_strings_kernel(1, &bprm.filename, &bprm);
+- if (retval < 0)
+- goto out;
++ if (retval < 0)
++ goto out;
+
+ bprm.exec = bprm.p;
+ retval = copy_strings(bprm.envc, envp, &bprm);
+- if (retval < 0)
+- goto out;
++ if (retval < 0)
++ goto out;
+
+ retval = copy_strings(bprm.argc, argv, &bprm);
+- if (retval < 0)
+- goto out;
++ if (retval < 0)
++ goto out;
+
+ retval = search_binary_handler(&bprm,regs);
+ if (retval >= 0) {
+Index: linux-2.6.0-test5/fs/ext2/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/ext2/inode.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/ext2/inode.c 2003-09-27 11:38:36.232020280 +0800
+@@ -257,11 +257,12 @@
+ * or when it reads all @depth-1 indirect blocks successfully and finds
+ * the whole chain, all way to the data (returns %NULL, *err == 0).
+ */
+-static Indirect *ext2_get_branch(struct inode *inode,
++static Indirect *ext2_get_branch_wq(struct inode *inode,
+ int depth,
+ int *offsets,
+ Indirect chain[4],
+- int *err)
++ int *err,
++ wait_queue_t *wait)
+ {
+ struct super_block *sb = inode->i_sb;
+ Indirect *p = chain;
+@@ -273,8 +274,8 @@
+ if (!p->key)
+ goto no_block;
+ while (--depth) {
+- bh = sb_bread(sb, le32_to_cpu(p->key));
+- if (!bh)
++ bh = sb_bread_wq(sb, le32_to_cpu(p->key), wait);
++ if (!bh || IS_ERR(bh))
+ goto failure;
+ read_lock(&EXT2_I(inode)->i_meta_lock);
+ if (!verify_chain(chain, p))
+@@ -292,11 +293,21 @@
+ *err = -EAGAIN;
+ goto no_block;
+ failure:
+- *err = -EIO;
++ *err = IS_ERR(bh) ? PTR_ERR(bh) : -EIO;
+ no_block:
+ return p;
+ }
+
++static Indirect *ext2_get_branch(struct inode *inode,
++ int depth,
++ int *offsets,
++ Indirect chain[4],
++ int *err)
++{
++ return ext2_get_branch_wq(inode, depth, offsets, chain,
++ err, NULL);
++}
++
+ /**
+ * ext2_find_near - find a place for allocation with sufficient locality
+ * @inode: owner
+@@ -536,7 +547,8 @@
+ * reachable from inode.
+ */
+
+-static int ext2_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create)
++static int ext2_get_block_wq(struct inode *inode, sector_t iblock,
++ struct buffer_head *bh_result, int create, wait_queue_t *wait)
+ {
+ int err = -EIO;
+ int offsets[4];
+@@ -551,7 +563,8 @@
+ goto out;
+
+ reread:
+- partial = ext2_get_branch(inode, depth, offsets, chain, &err);
++ partial = ext2_get_branch_wq(inode, depth, offsets, chain, &err,
++ wait);
+
+ /* Simplest case - block found, no allocation needed */
+ if (!partial) {
+@@ -565,7 +578,7 @@
+ }
+
+ /* Next simple case - plain lookup or failed read of indirect block */
+- if (!create || err == -EIO) {
++ if (!create || err == -EIO || err == -EIOCBRETRY) {
+ cleanup:
+ while (partial > chain) {
+ brelse(partial->bh);
+@@ -606,6 +619,19 @@
+ goto reread;
+ }
+
++static int ext2_get_block_async(struct inode *inode, sector_t iblock,
++ struct buffer_head *bh_result, int create)
++{
++ return ext2_get_block_wq(inode, iblock, bh_result, create,
++ current->io_wait);
++}
++
++static int ext2_get_block(struct inode *inode, sector_t iblock,
++ struct buffer_head *bh_result, int create)
++{
++ return ext2_get_block_wq(inode, iblock, bh_result, create, NULL);
++}
++
+ static int ext2_writepage(struct page *page, struct writeback_control *wbc)
+ {
+ return block_write_full_page(page, ext2_get_block, wbc);
+@@ -627,7 +653,7 @@
+ ext2_prepare_write(struct file *file, struct page *page,
+ unsigned from, unsigned to)
+ {
+- return block_prepare_write(page,from,to,ext2_get_block);
++ return block_prepare_write(page,from,to,ext2_get_block_async);
+ }
+
+ static int
+@@ -1126,8 +1152,12 @@
+ }
+ } else {
+ inode->i_op = &ext2_special_inode_operations;
+- init_special_inode(inode, inode->i_mode,
++ if (raw_inode->i_block[0])
++ init_special_inode(inode, inode->i_mode,
+ old_decode_dev(le32_to_cpu(raw_inode->i_block[0])));
++ else
++ init_special_inode(inode, inode->i_mode,
++ new_decode_dev(le32_to_cpu(raw_inode->i_block[1])));
+ }
+ brelse (bh);
+ ext2_set_inode_flags(inode);
+@@ -1215,9 +1245,17 @@
+ }
+
+ raw_inode->i_generation = cpu_to_le32(inode->i_generation);
+- if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
+- raw_inode->i_block[0] = cpu_to_le32(old_encode_dev(inode->i_rdev));
+- else for (n = 0; n < EXT2_N_BLOCKS; n++)
++ if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
++ if (old_valid_dev(inode->i_rdev)) {
++ raw_inode->i_block[0] =
++ cpu_to_le32(old_encode_dev(inode->i_rdev));
++ raw_inode->i_block[1] = 0;
++ } else {
++ raw_inode->i_block[0] = 0;
++ raw_inode->i_block[1] =
++ cpu_to_le32(new_encode_dev(inode->i_rdev));
++ }
++ } else for (n = 0; n < EXT2_N_BLOCKS; n++)
+ raw_inode->i_block[n] = ei->i_data[n];
+ mark_buffer_dirty(bh);
+ if (do_sync) {
+Index: linux-2.6.0-test5/fs/ext2/ioctl.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/ext2/ioctl.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/ext2/ioctl.c 2003-09-27 11:38:36.234019976 +0800
+@@ -10,6 +10,7 @@
+ #include "ext2.h"
+ #include <linux/time.h>
+ #include <linux/sched.h>
++#include <linux/mount.h>
+ #include <asm/current.h>
+ #include <asm/uaccess.h>
+
+@@ -29,7 +30,7 @@
+ case EXT2_IOC_SETFLAGS: {
+ unsigned int oldflags;
+
+- if (IS_RDONLY(inode))
++ if (IS_RDONLY(inode) || MNT_IS_RDONLY(filp->f_vfsmnt))
+ return -EROFS;
+
+ if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+@@ -68,7 +69,7 @@
+ case EXT2_IOC_SETVERSION:
+ if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+ return -EPERM;
+- if (IS_RDONLY(inode))
++ if (IS_RDONLY(inode) || MNT_IS_RDONLY(filp->f_vfsmnt))
+ return -EROFS;
+ if (get_user(inode->i_generation, (int *) arg))
+ return -EFAULT;
+Index: linux-2.6.0-test5/fs/ext2/namei.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/ext2/namei.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/ext2/namei.c 2003-09-27 11:38:36.237019520 +0800
+@@ -142,7 +142,7 @@
+ struct inode * inode;
+ int err;
+
+- if (!old_valid_dev(rdev))
++ if (!new_valid_dev(rdev))
+ return -EINVAL;
+
+ inode = ext2_new_inode (dir, mode);
+Index: linux-2.6.0-test5/fs/ext2/super.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/ext2/super.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/ext2/super.c 2003-09-27 11:38:36.246018152 +0800
+@@ -22,6 +22,7 @@
+ #include <linux/slab.h>
+ #include <linux/init.h>
+ #include <linux/blkdev.h>
++#include <linux/parser.h>
+ #include <linux/random.h>
+ #include <linux/buffer_head.h>
+ #include <linux/smp_lock.h>
+@@ -265,149 +266,157 @@
+ return sb_block;
+ }
+
+-static int want_value(char *value, char *option)
+-{
+- if (!value || !*value) {
+- printk(KERN_NOTICE "EXT2-fs: the %s option needs an argument\n",
+- option);
+- return -1;
+- }
+- return 0;
+-}
+-
+-static int want_null_value(char *value, char *option)
+-{
+- if (*value) {
+- printk(KERN_NOTICE "EXT2-fs: Invalid %s argument: %s\n",
+- option, value);
+- return -1;
+- }
+- return 0;
+-}
++enum {
++ Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid,
++ Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro,
++ Opt_nouid32, Opt_check, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov, Opt_nobh,
++ Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl,
++ Opt_ignore, Opt_err,
++};
+
+-static int want_numeric(char *value, char *option, unsigned long *number)
+-{
+- if (want_value(value, option))
+- return -1;
+- *number = simple_strtoul(value, &value, 0);
+- if (want_null_value(value, option))
+- return -1;
+- return 0;
+-}
++static match_table_t tokens = {
++ {Opt_bsd_df, "bsddf"},
++ {Opt_minix_df, "minixdf"},
++ {Opt_grpid, "grpid"},
++ {Opt_grpid, "bsdgroups"},
++ {Opt_nogrpid, "nogrpid"},
++ {Opt_nogrpid, "sysvgroups"},
++ {Opt_resgid, "resgid=%d"},
++ {Opt_resuid, "resuid=%d"},
++ {Opt_sb, "sb=%d"},
++ {Opt_err_cont, "errors=continue"},
++ {Opt_err_panic, "errors=panic"},
++ {Opt_err_ro, "errors=remount-ro"},
++ {Opt_nouid32, "nouid32"},
++ {Opt_nocheck, "check=none"},
++ {Opt_nocheck, "nocheck"},
++ {Opt_check, "check"},
++ {Opt_debug, "debug"},
++ {Opt_oldalloc, "oldalloc"},
++ {Opt_orlov, "orlov"},
++ {Opt_nobh, "nobh"},
++ {Opt_user_xattr, "user_xattr"},
++ {Opt_nouser_xattr, "nouser_xattr"},
++ {Opt_acl, "acl"},
++ {Opt_noacl, "noacl"},
++ {Opt_ignore, "grpquota"},
++ {Opt_ignore, "noquota"},
++ {Opt_ignore, "quota"},
++ {Opt_ignore, "usrquota"},
++ {Opt_err, NULL}
++};
+
+-/*
+- * This function has been shamelessly adapted from the msdos fs
+- */
+ static int parse_options (char * options,
+ struct ext2_sb_info *sbi)
+ {
+- char * this_char;
+- char * value;
++ char * p;
++ substring_t args[MAX_OPT_ARGS];
++ unsigned long kind = EXT2_MOUNT_ERRORS_CONT;
++ int option;
+
+ if (!options)
+ return 1;
+- while ((this_char = strsep (&options, ",")) != NULL) {
+- if (!*this_char)
++
++ while ((p = strsep (&options, ",")) != NULL) {
++ int token;
++ if (!*p)
+ continue;
+- if ((value = strchr (this_char, '=')) != NULL)
+- *value++ = 0;
++
++ token = match_token(p, tokens, args);
++ switch (token) {
++ case Opt_bsd_df:
++ clear_opt (sbi->s_mount_opt, MINIX_DF);
++ break;
++ case Opt_minix_df:
++ set_opt (sbi->s_mount_opt, MINIX_DF);
++ break;
++ case Opt_grpid:
++ set_opt (sbi->s_mount_opt, GRPID);
++ break;
++ case Opt_nogrpid:
++ clear_opt (sbi->s_mount_opt, GRPID);
++ break;
++ case Opt_resuid:
++ if (match_int(&args[0], &option))
++ return 0;
++ sbi->s_resuid = option;
++ break;
++ case Opt_resgid:
++ if (match_int(&args[0], &option))
++ return 0;
++ sbi->s_resgid = option;
++ break;
++ case Opt_sb:
++ /* handled by get_sb_block() instead of here */
++ /* *sb_block = match_int(&args[0]); */
++ break;
++ case Opt_err_panic:
++ kind = EXT2_MOUNT_ERRORS_PANIC;
++ break;
++ case Opt_err_ro:
++ kind = EXT2_MOUNT_ERRORS_RO;
++ break;
++ case Opt_err_cont:
++ kind = EXT2_MOUNT_ERRORS_CONT;
++ break;
++ case Opt_nouid32:
++ set_opt (sbi->s_mount_opt, NO_UID32);
++ break;
++ case Opt_check:
++#ifdef CONFIG_EXT2_CHECK
++ set_opt (sbi->s_mount_opt, CHECK);
++#else
++ printk("EXT2 Check option not supported\n");
++#endif
++ break;
++ case Opt_nocheck:
++ clear_opt (sbi->s_mount_opt, CHECK);
++ break;
++ case Opt_debug:
++ set_opt (sbi->s_mount_opt, DEBUG);
++ break;
++ case Opt_oldalloc:
++ set_opt (sbi->s_mount_opt, OLDALLOC);
++ break;
++ case Opt_orlov:
++ clear_opt (sbi->s_mount_opt, OLDALLOC);
++ break;
++ case Opt_nobh:
++ set_opt (sbi->s_mount_opt, NOBH);
++ break;
+ #ifdef CONFIG_EXT2_FS_XATTR
+- if (!strcmp (this_char, "user_xattr"))
++ case Opt_user_xattr:
+ set_opt (sbi->s_mount_opt, XATTR_USER);
+- else if (!strcmp (this_char, "nouser_xattr"))
++ break;
++ case Opt_nouser_xattr:
+ clear_opt (sbi->s_mount_opt, XATTR_USER);
+- else
++ break;
++#else
++ case Opt_user_xattr:
++ case Opt_nouser_xattr:
++ printk("EXT2 (no)user_xattr options not supported\n");
++ break;
+ #endif
+ #ifdef CONFIG_EXT2_FS_POSIX_ACL
+- if (!strcmp(this_char, "acl"))
++ case Opt_acl:
+ set_opt(sbi->s_mount_opt, POSIX_ACL);
+- else if (!strcmp(this_char, "noacl"))
++ break;
++ case Opt_noacl:
+ clear_opt(sbi->s_mount_opt, POSIX_ACL);
+- else
+-#endif
+- if (!strcmp (this_char, "bsddf"))
+- clear_opt (sbi->s_mount_opt, MINIX_DF);
+- else if (!strcmp (this_char, "nouid32")) {
+- set_opt (sbi->s_mount_opt, NO_UID32);
+- }
+- else if (!strcmp (this_char, "check")) {
+- if (!value || !*value || !strcmp (value, "none"))
+- clear_opt (sbi->s_mount_opt, CHECK);
+- else
+-#ifdef CONFIG_EXT2_CHECK
+- set_opt (sbi->s_mount_opt, CHECK);
++ break;
+ #else
+- printk("EXT2 Check option not supported\n");
++ case Opt_acl:
++ case Opt_noacl:
++ printk("EXT2 (no)acl options not supported\n");
++ break;
+ #endif
+- }
+- else if (!strcmp (this_char, "debug"))
+- set_opt (sbi->s_mount_opt, DEBUG);
+- else if (!strcmp (this_char, "errors")) {
+- if (!value || !*value) {
+- printk ("EXT2-fs: the errors option requires "
+- "an argument\n");
+- return 0;
+- }
+- if (!strcmp (value, "continue")) {
+- clear_opt (sbi->s_mount_opt, ERRORS_RO);
+- clear_opt (sbi->s_mount_opt, ERRORS_PANIC);
+- set_opt (sbi->s_mount_opt, ERRORS_CONT);
+- }
+- else if (!strcmp (value, "remount-ro")) {
+- clear_opt (sbi->s_mount_opt, ERRORS_CONT);
+- clear_opt (sbi->s_mount_opt, ERRORS_PANIC);
+- set_opt (sbi->s_mount_opt, ERRORS_RO);
+- }
+- else if (!strcmp (value, "panic")) {
+- clear_opt (sbi->s_mount_opt, ERRORS_CONT);
+- clear_opt (sbi->s_mount_opt, ERRORS_RO);
+- set_opt (sbi->s_mount_opt, ERRORS_PANIC);
+- }
+- else {
+- printk ("EXT2-fs: Invalid errors option: %s\n",
+- value);
+- return 0;
+- }
+- }
+- else if (!strcmp (this_char, "grpid") ||
+- !strcmp (this_char, "bsdgroups"))
+- set_opt (sbi->s_mount_opt, GRPID);
+- else if (!strcmp (this_char, "minixdf"))
+- set_opt (sbi->s_mount_opt, MINIX_DF);
+- else if (!strcmp (this_char, "nocheck"))
+- clear_opt (sbi->s_mount_opt, CHECK);
+- else if (!strcmp (this_char, "nogrpid") ||
+- !strcmp (this_char, "sysvgroups"))
+- clear_opt (sbi->s_mount_opt, GRPID);
+- else if (!strcmp (this_char, "resgid")) {
+- unsigned long v;
+- if (want_numeric(value, "resgid", &v))
+- return 0;
+- sbi->s_resgid = v;
+- }
+- else if (!strcmp (this_char, "resuid")) {
+- unsigned long v;
+- if (want_numeric(value, "resuid", &v))
+- return 0;
+- sbi->s_resuid = v;
+- }
+- else if (!strcmp (this_char, "oldalloc"))
+- set_opt (sbi->s_mount_opt, OLDALLOC);
+- else if (!strcmp (this_char, "orlov"))
+- clear_opt (sbi->s_mount_opt, OLDALLOC);
+- else if (!strcmp (this_char, "nobh"))
+- set_opt(sbi->s_mount_opt, NOBH);
+- /* Silently ignore the quota options */
+- else if (!strcmp (this_char, "grpquota")
+- || !strcmp (this_char, "noquota")
+- || !strcmp (this_char, "quota")
+- || !strcmp (this_char, "usrquota"))
+- /* Don't do anything ;-) */ ;
+- else {
+- printk ("EXT2-fs: Unrecognized mount option %s\n", this_char);
++ case Opt_ignore:
++ break;
++ default:
+ return 0;
+ }
+ }
++ sbi->s_mount_opt |= kind;
+ return 1;
+ }
+
+Index: linux-2.6.0-test5/fs/ext2/symlink.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/ext2/symlink.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/ext2/symlink.c 2003-09-27 11:38:36.247018000 +0800
+@@ -20,7 +20,8 @@
+ #include "ext2.h"
+ #include "xattr.h"
+
+-static int ext2_readlink(struct dentry *dentry, char *buffer, int buflen)
++static int
++ext2_readlink(struct dentry *dentry, char __user *buffer, int buflen)
+ {
+ struct ext2_inode_info *ei = EXT2_I(dentry->d_inode);
+ return vfs_readlink(dentry, buffer, buflen, (char *)ei->i_data);
+Index: linux-2.6.0-test5/fs/ext3/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/ext3/inode.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/ext3/inode.c 2003-09-27 11:38:36.270014504 +0800
+@@ -2565,8 +2565,12 @@
+ }
+ } else {
+ inode->i_op = &ext3_special_inode_operations;
+- init_special_inode(inode, inode->i_mode,
++ if (raw_inode->i_block[0])
++ init_special_inode(inode, inode->i_mode,
+ old_decode_dev(le32_to_cpu(raw_inode->i_block[0])));
++ else
++ init_special_inode(inode, inode->i_mode,
++ new_decode_dev(le32_to_cpu(raw_inode->i_block[1])));
+ }
+ brelse (iloc.bh);
+ ext3_set_inode_flags(inode);
+@@ -2666,10 +2670,17 @@
+ }
+ }
+ raw_inode->i_generation = cpu_to_le32(inode->i_generation);
+- if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
+- raw_inode->i_block[0] =
+- cpu_to_le32(old_encode_dev(inode->i_rdev));
+- else for (block = 0; block < EXT3_N_BLOCKS; block++)
++ if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
++ if (old_valid_dev(inode->i_rdev)) {
++ raw_inode->i_block[0] =
++ cpu_to_le32(old_encode_dev(inode->i_rdev));
++ raw_inode->i_block[1] = 0;
++ } else {
++ raw_inode->i_block[0] = 0;
++ raw_inode->i_block[1] =
++ cpu_to_le32(new_encode_dev(inode->i_rdev));
++ }
++ } else for (block = 0; block < EXT3_N_BLOCKS; block++)
+ raw_inode->i_block[block] = ei->i_data[block];
+
+ BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
+Index: linux-2.6.0-test5/fs/ext3/ioctl.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/ext3/ioctl.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/ext3/ioctl.c 2003-09-27 11:38:36.271014352 +0800
+@@ -12,6 +12,7 @@
+ #include <linux/ext3_fs.h>
+ #include <linux/ext3_jbd.h>
+ #include <linux/time.h>
++#include <linux/mount.h>
+ #include <asm/uaccess.h>
+
+
+@@ -34,7 +35,7 @@
+ unsigned int oldflags;
+ unsigned int jflag;
+
+- if (IS_RDONLY(inode))
++ if (IS_RDONLY(inode) || MNT_IS_RDONLY(filp->f_vfsmnt))
+ return -EROFS;
+
+ if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+@@ -110,7 +111,7 @@
+
+ if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+ return -EPERM;
+- if (IS_RDONLY(inode))
++ if (IS_RDONLY(inode) || MNT_IS_RDONLY(filp->f_vfsmnt))
+ return -EROFS;
+ if (get_user(generation, (int *) arg))
+ return -EFAULT;
+Index: linux-2.6.0-test5/fs/ext3/namei.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/ext3/namei.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/ext3/namei.c 2003-09-27 11:38:36.288011768 +0800
+@@ -1659,7 +1659,7 @@
+ struct inode *inode;
+ int err;
+
+- if (!old_valid_dev(rdev))
++ if (!new_valid_dev(rdev))
+ return -EINVAL;
+
+ handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
+Index: linux-2.6.0-test5/fs/ext3/super.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/ext3/super.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/ext3/super.c 2003-09-27 11:38:36.305009184 +0800
+@@ -27,6 +27,7 @@
+ #include <linux/slab.h>
+ #include <linux/init.h>
+ #include <linux/blkdev.h>
++#include <linux/parser.h>
+ #include <linux/smp_lock.h>
+ #include <linux/buffer_head.h>
+ #include <linux/vfs.h>
+@@ -34,10 +35,6 @@
+ #include "xattr.h"
+ #include "acl.h"
+
+-#ifdef CONFIG_JBD_DEBUG
+-static int ext3_ro_after; /* Make fs read-only after this many jiffies */
+-#endif
+-
+ static int ext3_load_journal(struct super_block *, struct ext3_super_block *);
+ static int ext3_create_journal(struct super_block *, struct ext3_super_block *,
+ int);
+@@ -50,64 +47,6 @@
+ struct ext3_super_block * es);
+ static int ext3_sync_fs(struct super_block *sb, int wait);
+
+-#ifdef CONFIG_JBD_DEBUG
+-int journal_no_write[2];
+-
+-/*
+- * Debug code for turning filesystems "read-only" after a specified
+- * amount of time. This is for crash/recovery testing.
+- */
+-
+-static void make_rdonly(struct block_device *bdev, int *no_write)
+-{
+- char b[BDEVNAME_SIZE];
+-
+- if (bdev) {
+- printk(KERN_WARNING "Turning device %s read-only\n",
+- bdevname(bdev, b));
+- *no_write = 0xdead0000 + bdev->bd_dev;
+- }
+-}
+-
+-static void turn_fs_readonly(unsigned long arg)
+-{
+- struct super_block *sb = (struct super_block *)arg;
+-
+- make_rdonly(sb->s_bdev, &journal_no_write[0]);
+- make_rdonly(EXT3_SB(sb)->s_journal->j_dev, &journal_no_write[1]);
+- wake_up(&EXT3_SB(sb)->ro_wait_queue);
+-}
+-
+-static void setup_ro_after(struct super_block *sb)
+-{
+- struct ext3_sb_info *sbi = EXT3_SB(sb);
+- init_timer(&sbi->turn_ro_timer);
+- if (ext3_ro_after) {
+- printk(KERN_DEBUG "fs will go read-only in %d jiffies\n",
+- ext3_ro_after);
+- init_waitqueue_head(&sbi->ro_wait_queue);
+- journal_no_write[0] = 0;
+- journal_no_write[1] = 0;
+- sbi->turn_ro_timer.function = turn_fs_readonly;
+- sbi->turn_ro_timer.data = (unsigned long)sb;
+- sbi->turn_ro_timer.expires = jiffies + ext3_ro_after;
+- ext3_ro_after = 0;
+- add_timer(&sbi->turn_ro_timer);
+- }
+-}
+-
+-static void clear_ro_after(struct super_block *sb)
+-{
+- del_timer_sync(&EXT3_SB(sb)->turn_ro_timer);
+- journal_no_write[0] = 0;
+- journal_no_write[1] = 0;
+- ext3_ro_after = 0;
+-}
+-#else
+-#define setup_ro_after(sb) do {} while (0)
+-#define clear_ro_after(sb) do {} while (0)
+-#endif
+-
+ /*
+ * Wrappers for journal_start/end.
+ *
+@@ -481,7 +420,6 @@
+ invalidate_bdev(sbi->journal_bdev, 0);
+ ext3_blkdev_remove(sbi);
+ }
+- clear_ro_after(sb);
+ sb->s_fs_info = NULL;
+ kfree(sbi);
+ return;
+@@ -589,36 +527,54 @@
+ .get_parent = ext3_get_parent,
+ };
+
++enum {
++ Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid,
++ Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro,
++ Opt_nouid32, Opt_check, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov,
++ Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, Opt_noload,
++ Opt_commit, Opt_journal_update, Opt_journal_inum,
++ Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
++ Opt_ignore, Opt_err,
++};
+
+-static int want_value(char *value, char *option)
+-{
+- if (!value || !*value) {
+- printk(KERN_NOTICE "EXT3-fs: the %s option needs an argument\n",
+- option);
+- return -1;
+- }
+- return 0;
+-}
+-
+-static int want_null_value(char *value, char *option)
+-{
+- if (*value) {
+- printk(KERN_NOTICE "EXT3-fs: Invalid %s argument: %s\n",
+- option, value);
+- return -1;
+- }
+- return 0;
+-}
+-
+-static int want_numeric(char *value, char *option, unsigned long *number)
+-{
+- if (want_value(value, option))
+- return -1;
+- *number = simple_strtoul(value, &value, 0);
+- if (want_null_value(value, option))
+- return -1;
+- return 0;
+-}
++static match_table_t tokens = {
++ {Opt_bsd_df, "bsddf"},
++ {Opt_minix_df, "minixdf"},
++ {Opt_grpid, "grpid"},
++ {Opt_grpid, "bsdgroups"},
++ {Opt_nogrpid, "nogrpid"},
++ {Opt_nogrpid, "sysvgroups"},
++ {Opt_resgid, "resgid=%d"},
++ {Opt_resuid, "resuid=%d"},
++ {Opt_sb, "sb=%d"},
++ {Opt_err_cont, "errors=continue"},
++ {Opt_err_panic, "errors=panic"},
++ {Opt_err_ro, "errors=remount-ro"},
++ {Opt_nouid32, "nouid32"},
++ {Opt_nocheck, "nocheck"},
++ {Opt_nocheck, "check=none"},
++ {Opt_check, "check"},
++ {Opt_debug, "debug"},
++ {Opt_oldalloc, "oldalloc"},
++ {Opt_orlov, "orlov"},
++ {Opt_user_xattr, "user_xattr"},
++ {Opt_nouser_xattr, "nouser_xattr"},
++ {Opt_acl, "acl"},
++ {Opt_noacl, "noacl"},
++ {Opt_noload, "noload"},
++ {Opt_commit, "commit=%u"},
++ {Opt_journal_update, "journal=update"},
++ {Opt_journal_inum, "journal=%u"},
++ {Opt_abort, "abort"},
++ {Opt_data_journal, "data=journal"},
++ {Opt_data_ordered, "data=ordered"},
++ {Opt_data_writeback, "data=writeback"},
++ {Opt_ignore, "grpquota"},
++ {Opt_ignore, "noquota"},
++ {Opt_ignore, "quota"},
++ {Opt_ignore, "usrquota"},
++ {Opt_err, NULL}
++};
+
+ static unsigned long get_sb_block(void **data)
+ {
+@@ -640,183 +596,180 @@
+ return sb_block;
+ }
+
+-/*
+- * This function has been shamelessly adapted from the msdos fs
+- */
+ static int parse_options (char * options, struct ext3_sb_info *sbi,
+ unsigned long * inum, int is_remount)
+ {
+- char * this_char;
+- char * value;
++ char * p;
++ substring_t args[MAX_OPT_ARGS];
++ int data_opt = 0;
++ int option;
+
+ if (!options)
+ return 1;
+- while ((this_char = strsep (&options, ",")) != NULL) {
+- if (!*this_char)
++
++ while ((p = strsep (&options, ",")) != NULL) {
++ int token;
++ if (!*p)
+ continue;
+- if ((value = strchr (this_char, '=')) != NULL)
+- *value++ = 0;
+-#ifdef CONFIG_EXT3_FS_XATTR
+- if (!strcmp (this_char, "user_xattr"))
+- set_opt (sbi->s_mount_opt, XATTR_USER);
+- else if (!strcmp (this_char, "nouser_xattr"))
+- clear_opt (sbi->s_mount_opt, XATTR_USER);
+- else
+-#endif
+-#ifdef CONFIG_EXT3_FS_POSIX_ACL
+- if (!strcmp(this_char, "acl"))
+- set_opt (sbi->s_mount_opt, POSIX_ACL);
+- else if (!strcmp(this_char, "noacl"))
+- clear_opt (sbi->s_mount_opt, POSIX_ACL);
+- else
+-#endif
+- if (!strcmp (this_char, "bsddf"))
++
++ token = match_token(p, tokens, args);
++ switch (token) {
++ case Opt_bsd_df:
+ clear_opt (sbi->s_mount_opt, MINIX_DF);
+- else if (!strcmp (this_char, "nouid32")) {
++ break;
++ case Opt_minix_df:
++ set_opt (sbi->s_mount_opt, MINIX_DF);
++ break;
++ case Opt_grpid:
++ set_opt (sbi->s_mount_opt, GRPID);
++ break;
++ case Opt_nogrpid:
++ clear_opt (sbi->s_mount_opt, GRPID);
++ break;
++ case Opt_resuid:
++ if (match_int(&args[0], &option))
++ return 0;
++ sbi->s_resuid = option;
++ break;
++ case Opt_resgid:
++ if (match_int(&args[0], &option))
++ return 0;
++ sbi->s_resgid = option;
++ break;
++ case Opt_sb:
++ /* handled by get_sb_block() instead of here */
++ /* *sb_block = match_int(&args[0]); */
++ break;
++ case Opt_err_panic:
++ clear_opt (sbi->s_mount_opt, ERRORS_CONT);
++ clear_opt (sbi->s_mount_opt, ERRORS_RO);
++ set_opt (sbi->s_mount_opt, ERRORS_PANIC);
++ break;
++ case Opt_err_ro:
++ clear_opt (sbi->s_mount_opt, ERRORS_CONT);
++ clear_opt (sbi->s_mount_opt, ERRORS_PANIC);
++ set_opt (sbi->s_mount_opt, ERRORS_RO);
++ break;
++ case Opt_err_cont:
++ clear_opt (sbi->s_mount_opt, ERRORS_RO);
++ clear_opt (sbi->s_mount_opt, ERRORS_PANIC);
++ set_opt (sbi->s_mount_opt, ERRORS_CONT);
++ break;
++ case Opt_nouid32:
+ set_opt (sbi->s_mount_opt, NO_UID32);
+- }
+- else if (!strcmp (this_char, "abort"))
+- set_opt (sbi->s_mount_opt, ABORT);
+- else if (!strcmp (this_char, "check")) {
+- if (!value || !*value || !strcmp (value, "none"))
+- clear_opt (sbi->s_mount_opt, CHECK);
+- else
++ break;
++ case Opt_check:
+ #ifdef CONFIG_EXT3_CHECK
+- set_opt (sbi->s_mount_opt, CHECK);
++ set_opt (sbi->s_mount_opt, CHECK);
+ #else
+- printk(KERN_ERR
+- "EXT3 Check option not supported\n");
++ printk(KERN_ERR
++ "EXT3 Check option not supported\n");
+ #endif
+- }
+- else if (!strcmp (this_char, "debug"))
+- set_opt (sbi->s_mount_opt, DEBUG);
+- else if (!strcmp (this_char, "errors")) {
+- if (want_value(value, "errors"))
+- return 0;
+- if (!strcmp (value, "continue")) {
+- clear_opt (sbi->s_mount_opt, ERRORS_RO);
+- clear_opt (sbi->s_mount_opt, ERRORS_PANIC);
+- set_opt (sbi->s_mount_opt, ERRORS_CONT);
+- }
+- else if (!strcmp (value, "remount-ro")) {
+- clear_opt (sbi->s_mount_opt, ERRORS_CONT);
+- clear_opt (sbi->s_mount_opt, ERRORS_PANIC);
+- set_opt (sbi->s_mount_opt, ERRORS_RO);
+- }
+- else if (!strcmp (value, "panic")) {
+- clear_opt (sbi->s_mount_opt, ERRORS_CONT);
+- clear_opt (sbi->s_mount_opt, ERRORS_RO);
+- set_opt (sbi->s_mount_opt, ERRORS_PANIC);
+- }
+- else {
+- printk (KERN_ERR
+- "EXT3-fs: Invalid errors option: %s\n",
+- value);
+- return 0;
+- }
+- }
+- else if (!strcmp (this_char, "grpid") ||
+- !strcmp (this_char, "bsdgroups"))
+- set_opt (sbi->s_mount_opt, GRPID);
+- else if (!strcmp (this_char, "minixdf"))
+- set_opt (sbi->s_mount_opt, MINIX_DF);
+- else if (!strcmp (this_char, "nocheck"))
++ break;
++ case Opt_nocheck:
+ clear_opt (sbi->s_mount_opt, CHECK);
+- else if (!strcmp (this_char, "nogrpid") ||
+- !strcmp (this_char, "sysvgroups"))
+- clear_opt (sbi->s_mount_opt, GRPID);
+- else if (!strcmp (this_char, "resgid")) {
+- unsigned long v;
+- if (want_numeric(value, "resgid", &v))
+- return 0;
+- sbi->s_resgid = v;
+- }
+- else if (!strcmp (this_char, "resuid")) {
+- unsigned long v;
+- if (want_numeric(value, "resuid", &v))
+- return 0;
+- sbi->s_resuid = v;
+- }
+- else if (!strcmp (this_char, "oldalloc"))
++ break;
++ case Opt_debug:
++ set_opt (sbi->s_mount_opt, DEBUG);
++ break;
++ case Opt_oldalloc:
+ set_opt (sbi->s_mount_opt, OLDALLOC);
+- else if (!strcmp (this_char, "orlov"))
++ break;
++ case Opt_orlov:
+ clear_opt (sbi->s_mount_opt, OLDALLOC);
+-#ifdef CONFIG_JBD_DEBUG
+- else if (!strcmp (this_char, "ro-after")) {
+- unsigned long v;
+- if (want_numeric(value, "ro-after", &v))
+- return 0;
+- ext3_ro_after = v;
+- }
++ break;
++#ifdef CONFIG_EXT3_FS_XATTR
++ case Opt_user_xattr:
++ set_opt (sbi->s_mount_opt, XATTR_USER);
++ break;
++ case Opt_nouser_xattr:
++ clear_opt (sbi->s_mount_opt, XATTR_USER);
++ break;
++#else
++ case Opt_user_xattr:
++ case Opt_nouser_xattr:
++ printk("EXT3 (no)user_xattr options not supported\n");
++ break;
++#endif
++#ifdef CONFIG_EXT3_FS_POSIX_ACL
++ case Opt_acl:
++ set_opt(sbi->s_mount_opt, POSIX_ACL);
++ break;
++ case Opt_noacl:
++ clear_opt(sbi->s_mount_opt, POSIX_ACL);
++ break;
++#else
++ case Opt_acl:
++ case Opt_noacl:
++ printk("EXT3 (no)acl options not supported\n");
++ break;
+ #endif
+- /* Silently ignore the quota options */
+- else if (!strcmp (this_char, "grpquota")
+- || !strcmp (this_char, "noquota")
+- || !strcmp (this_char, "quota")
+- || !strcmp (this_char, "usrquota"))
+- /* Don't do anything ;-) */ ;
+- else if (!strcmp (this_char, "journal")) {
++ case Opt_journal_update:
+ /* @@@ FIXME */
+ /* Eventually we will want to be able to create
+- a journal file here. For now, only allow the
+- user to specify an existing inode to be the
+- journal file. */
++ a journal file here. For now, only allow the
++ user to specify an existing inode to be the
++ journal file. */
+ if (is_remount) {
+ printk(KERN_ERR "EXT3-fs: cannot specify "
+ "journal on remount\n");
+ return 0;
+ }
+-
+- if (want_value(value, "journal"))
++ set_opt (sbi->s_mount_opt, UPDATE_JOURNAL);
++ break;
++ case Opt_journal_inum:
++ if (is_remount) {
++ printk(KERN_ERR "EXT3-fs: cannot specify "
++ "journal on remount\n");
+ return 0;
+- if (!strcmp (value, "update"))
+- set_opt (sbi->s_mount_opt, UPDATE_JOURNAL);
+- else if (want_numeric(value, "journal", inum))
++ }
++ if (match_int(&args[0], &option))
+ return 0;
+- }
+- else if (!strcmp (this_char, "noload"))
++ *inum = option;
++ break;
++ case Opt_noload:
+ set_opt (sbi->s_mount_opt, NOLOAD);
+- else if (!strcmp (this_char, "data")) {
+- int data_opt = 0;
+-
+- if (want_value(value, "data"))
+- return 0;
+- if (!strcmp (value, "journal"))
+- data_opt = EXT3_MOUNT_JOURNAL_DATA;
+- else if (!strcmp (value, "ordered"))
+- data_opt = EXT3_MOUNT_ORDERED_DATA;
+- else if (!strcmp (value, "writeback"))
+- data_opt = EXT3_MOUNT_WRITEBACK_DATA;
+- else {
+- printk (KERN_ERR
+- "EXT3-fs: Invalid data option: %s\n",
+- value);
++ break;
++ case Opt_commit:
++ if (match_int(&args[0], &option))
+ return 0;
+- }
++ sbi->s_commit_interval = HZ * option;
++ break;
++ case Opt_data_journal:
++ data_opt = EXT3_MOUNT_JOURNAL_DATA;
++ goto datacheck;
++ case Opt_data_ordered:
++ data_opt = EXT3_MOUNT_ORDERED_DATA;
++ goto datacheck;
++ case Opt_data_writeback:
++ data_opt = EXT3_MOUNT_WRITEBACK_DATA;
++ datacheck:
+ if (is_remount) {
+- if ((sbi->s_mount_opt & EXT3_MOUNT_DATA_FLAGS) !=
+- data_opt) {
++ if ((sbi->s_mount_opt & EXT3_MOUNT_DATA_FLAGS)
++ != data_opt) {
+ printk(KERN_ERR
+- "EXT3-fs: cannot change data "
+- "mode on remount\n");
++ "EXT3-fs: cannot change data "
++ "mode on remount\n");
+ return 0;
+ }
+ } else {
+ sbi->s_mount_opt &= ~EXT3_MOUNT_DATA_FLAGS;
+ sbi->s_mount_opt |= data_opt;
+ }
+- } else if (!strcmp (this_char, "commit")) {
+- unsigned long v;
+- if (want_numeric(value, "commit", &v))
+- return 0;
+- sbi->s_commit_interval = (HZ * v);
+- } else {
+- printk (KERN_ERR
+- "EXT3-fs: Unrecognized mount option %s\n",
+- this_char);
++ break;
++ case Opt_abort:
++ set_opt(sbi->s_mount_opt, ABORT);
++ break;
++ case Opt_ignore:
++ break;
++ default:
++ printk (KERN_ERR
++ "EXT3-fs: Unrecognized mount option \"%s\" "
++ "or missing value\n", p);
+ return 0;
+ }
+ }
++
+ return 1;
+ }
+
+@@ -892,7 +845,6 @@
+ ext3_check_inodes_bitmap (sb);
+ }
+ #endif
+- setup_ro_after(sb);
+ return res;
+ }
+
+@@ -1092,9 +1044,6 @@
+ int i;
+ int needs_recovery;
+
+-#ifdef CONFIG_JBD_DEBUG
+- ext3_ro_after = 0;
+-#endif
+ sbi = kmalloc(sizeof(*sbi), GFP_KERNEL);
+ if (!sbi)
+ return -ENOMEM;
+@@ -1103,7 +1052,6 @@
+ sbi->s_mount_opt = 0;
+ sbi->s_resuid = EXT3_DEF_RESUID;
+ sbi->s_resgid = EXT3_DEF_RESGID;
+- setup_ro_after(sb);
+
+ blocksize = sb_min_blocksize(sb, EXT3_MIN_BLOCK_SIZE);
+ if (!blocksize) {
+@@ -1603,7 +1551,7 @@
+ {
+ journal_t *journal;
+ int journal_inum = le32_to_cpu(es->s_journal_inum);
+- dev_t journal_dev = old_decode_dev(le32_to_cpu(es->s_journal_dev));
++ dev_t journal_dev = new_decode_dev(le32_to_cpu(es->s_journal_dev));
+ int err = 0;
+ int really_read_only;
+
+@@ -1868,8 +1816,6 @@
+ struct ext3_sb_info *sbi = EXT3_SB(sb);
+ unsigned long tmp;
+
+- clear_ro_after(sb);
+-
+ /*
+ * Allow the "check" option to be passed as a remount option.
+ */
+@@ -1929,7 +1875,6 @@
+ sb->s_flags &= ~MS_RDONLY;
+ }
+ }
+- setup_ro_after(sb);
+ return 0;
+ }
+
+Index: linux-2.6.0-test5/fs/fat/file.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/fat/file.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/fat/file.c 2003-09-27 11:38:36.307008880 +0800
+@@ -11,8 +11,8 @@
+ #include <linux/smp_lock.h>
+ #include <linux/buffer_head.h>
+
+-static ssize_t fat_file_write(struct file *filp, const char *buf, size_t count,
+- loff_t *ppos);
++static ssize_t fat_file_write(struct file *filp, const char __user *buf,
++ size_t count, loff_t *ppos);
+
+ struct file_operations fat_file_operations = {
+ .llseek = generic_file_llseek,
+@@ -66,8 +66,8 @@
+ return 0;
+ }
+
+-static ssize_t fat_file_write(struct file *filp, const char *buf, size_t count,
+- loff_t *ppos)
++static ssize_t fat_file_write(struct file *filp, const char __user *buf,
++ size_t count, loff_t *ppos)
+ {
+ struct inode *inode = filp->f_dentry->d_inode;
+ int retval;
+Index: linux-2.6.0-test5/fs/fat/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/fat/inode.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/fat/inode.c 2003-09-27 11:38:36.317007360 +0800
+@@ -20,6 +20,7 @@
+ #include <linux/buffer_head.h>
+ #include <linux/mount.h>
+ #include <linux/vfs.h>
++#include <linux/parser.h>
+ #include <asm/unaligned.h>
+
+ /*
+@@ -183,20 +184,6 @@
+ kfree(sbi);
+ }
+
+-static int simple_getbool(char *s, int *setval)
+-{
+- if (s) {
+- if (!strcmp(s,"1") || !strcmp(s,"yes") || !strcmp(s,"true"))
+- *setval = 1;
+- else if (!strcmp(s,"0") || !strcmp(s,"no") || !strcmp(s,"false"))
+- *setval = 0;
+- else
+- return 0;
+- } else
+- *setval = 1;
+- return 1;
+-}
+-
+ static int fat_show_options(struct seq_file *m, struct vfsmount *mnt)
+ {
+ struct msdos_sb_info *sbi = MSDOS_SB(mnt->mnt_sb);
+@@ -259,11 +246,95 @@
+ return 0;
+ }
+
++static void print_obsolete_option(char *optname)
++{
++ printk(KERN_INFO "FAT: %s option is obsolete, "
++ "not supported now\n", optname);
++}
++
++enum {
++ Opt_blocksize, Opt_charset, Opt_check_n, Opt_check_r, Opt_check_s,
++ Opt_fat, Opt_codepage, Opt_conv_a, Opt_conv_b, Opt_conv_t,
++ Opt_debug, Opt_dots, Opt_err, Opt_gid, Opt_immutable,
++ Opt_nocase, Opt_nodots, Opt_quiet, Opt_showexec, Opt_uid,
++ Opt_shortname_lower, Opt_shortname_win95, Opt_shortname_winnt, Opt_shortname_mixed,
++ Opt_umask, Opt_dmask, Opt_fmask, Opt_posix, Opt_cvf_format, Opt_cvf_options,
++ Opt_utf8_off, Opt_utf8_no, Opt_utf8_false,
++ Opt_utf8_on, Opt_utf8_yes, Opt_utf8_true, Opt_utf8_opt,
++ Opt_uni_xl_off, Opt_uni_xl_no, Opt_uni_xl_false,
++ Opt_uni_xl_on, Opt_uni_xl_yes, Opt_uni_xl_true, Opt_uni_xl_opt,
++ Opt_nonumtail_off, Opt_nonumtail_no, Opt_nonumtail_false,
++ Opt_nonumtail_on, Opt_nonumtail_yes, Opt_nonumtail_true, Opt_nonumtail_opt,
++};
++
++static match_table_t FAT_tokens = {
++ {Opt_check_r, "check=relaxed"},
++ {Opt_check_s, "check=strict"},
++ {Opt_check_n, "check=normal"},
++ {Opt_check_r, "check=r"},
++ {Opt_check_s, "check=s"},
++ {Opt_check_n, "check=n"},
++ {Opt_conv_b, "conv=binary"},
++ {Opt_conv_t, "conv=text"},
++ {Opt_conv_a, "conv=auto"},
++ {Opt_conv_b, "conv=b"},
++ {Opt_conv_t, "conv=t"},
++ {Opt_conv_a, "conv=a"},
++ {Opt_nodots, "nodots"},
++ {Opt_nodots, "dotsOK=no"},
++ {Opt_dots, "dotsOK=yes"},
++ {Opt_dots, "dots"},
++ {Opt_uid, "uid=%d"},
++ {Opt_gid, "gid=%d"},
++ {Opt_umask, "umask=%o"},
++ {Opt_dmask, "dmask=%o"},
++ {Opt_fmask, "fmask=%o"},
++ {Opt_fat, "fat=%d"},
++ {Opt_codepage, "codepage=%d"},
++ {Opt_charset, "iocharset=%s"},
++ {Opt_blocksize, "blocksize=%d"},
++ {Opt_nocase, "nocase"},
++ {Opt_cvf_format, "cvf_format=%20s"},
++ {Opt_cvf_options, "cvf_options=%100s"},
++ {Opt_shortname_lower, "shortname=lower"},
++ {Opt_shortname_win95, "shortname=win95"},
++ {Opt_shortname_winnt, "shortname=winnt"},
++ {Opt_shortname_mixed, "shortname=mixed"},
++ {Opt_utf8_off, "utf8=0"}, /* 0 or no or false */
++ {Opt_utf8_no, "utf8=no"},
++ {Opt_utf8_false, "utf8=false"},
++ {Opt_utf8_on, "utf8=1"}, /* empty or 1 or yes or true */
++ {Opt_utf8_yes, "utf8=yes"},
++ {Opt_utf8_true, "utf8=true"},
++ {Opt_utf8_opt, "utf8"},
++ {Opt_uni_xl_off, "uni_xlate=0"}, /* 0 or no or false */
++ {Opt_uni_xl_no, "uni_xlate=no"},
++ {Opt_uni_xl_false, "uni_xlate=false"},
++ {Opt_uni_xl_on, "uni_xlate=1"}, /* empty or 1 or yes or true */
++ {Opt_uni_xl_yes, "uni_xlate=yes"},
++ {Opt_uni_xl_true, "uni_xlate=true"},
++ {Opt_uni_xl_opt, "uni_xlate"},
++ {Opt_nonumtail_off, "nonumtail=0"}, /* 0 or no or false */
++ {Opt_nonumtail_no, "nonumtail=no"},
++ {Opt_nonumtail_false, "nonumtail=false"},
++ {Opt_nonumtail_on, "nonumtail=1"}, /* empty or 1 or yes or true */
++ {Opt_nonumtail_yes, "nonumtail=yes"},
++ {Opt_nonumtail_true, "nonumtail=true"},
++ {Opt_nonumtail_opt, "nonumtail"},
++ {Opt_quiet, "quiet"},
++ {Opt_showexec, "showexec"},
++ {Opt_debug, "debug"},
++ {Opt_immutable, "sys_immutable"},
++ {Opt_posix, "posix"},
++ {Opt_err, NULL}
++};
++
+ static int parse_options(char *options, int is_vfat, int *debug,
+ struct fat_mount_options *opts)
+ {
+- char *this_char, *value, *p;
+- int ret = 1, val, len;
++ char *p;
++ substring_t args[MAX_OPT_ARGS];
++ int option;
+
+ opts->isvfat = is_vfat;
+
+@@ -284,183 +355,198 @@
+ *debug = 0;
+
+ if (!options)
+- goto out;
+- while ((this_char = strsep(&options,",")) != NULL) {
+- if (!*this_char)
++ return 1;
++
++ while ((p = strsep(&options, ",")) != NULL) {
++ int token;
++ if (!*p)
+ continue;
+- if ((value = strchr(this_char,'=')) != NULL)
+- *value++ = 0;
+
+- if (!strcmp(this_char,"check") && value) {
+- if (value[0] && !value[1] && strchr("rns",*value))
+- opts->name_check = *value;
+- else if (!strcmp(value,"relaxed"))
+- opts->name_check = 'r';
+- else if (!strcmp(value,"normal"))
+- opts->name_check = 'n';
+- else if (!strcmp(value,"strict"))
+- opts->name_check = 's';
+- else ret = 0;
+- }
+- else if (!strcmp(this_char,"conv") && value) {
+- printk(KERN_INFO "FAT: conv option is obsolete, "
+- "not supported now\n");
+- }
+- else if (!strcmp(this_char,"nocase")) {
++ token = match_token(p, FAT_tokens, args);
++ switch (token) {
++ case Opt_check_s:
++ opts->name_check = 's';
++ break;
++ case Opt_check_r:
++ opts->name_check = 'r';
++ break;
++ case Opt_check_n:
++ opts->name_check = 'n';
++ break;
++ case Opt_dots: /* msdos specific */
++ if (!is_vfat)
++ opts->dotsOK = 1;
++ break;
++ case Opt_nodots: /* msdos specific */
++ if (!is_vfat)
++ opts->dotsOK = 0;
++ break;
++ case Opt_nocase:
+ if (!is_vfat)
+ opts->nocase = 1;
+ else {
+- /* for backward compatible */
++ /* for backward compatibility */
+ opts->shortname = VFAT_SFN_DISPLAY_WIN95
+ | VFAT_SFN_CREATE_WIN95;
+ }
+- }
+- else if (!strcmp(this_char,"showexec")) {
++ break;
++ case Opt_quiet:
++ opts->quiet = 1;
++ break;
++ case Opt_showexec:
+ opts->showexec = 1;
+- }
+- else if (!strcmp(this_char,"uid")) {
+- if (!value || !*value) ret = 0;
+- else {
+- opts->fs_uid = simple_strtoul(value,&value,0);
+- if (*value) ret = 0;
+- }
+- }
+- else if (!strcmp(this_char,"gid")) {
+- if (!value || !*value) ret= 0;
+- else {
+- opts->fs_gid = simple_strtoul(value,&value,0);
+- if (*value) ret = 0;
+- }
+- }
+- else if (!strcmp(this_char,"umask")) {
+- if (!value || !*value) ret = 0;
+- else {
+- opts->fs_fmask = opts->fs_dmask =
+- simple_strtoul(value,&value,8);
+- if (*value) ret = 0;
+- }
+- }
+- else if (!strcmp(this_char,"fmask")) {
+- if (!value || !*value) ret = 0;
+- else {
+- opts->fs_fmask = simple_strtoul(value,&value,8);
+- if (*value) ret = 0;
+- }
+- }
+- else if (!strcmp(this_char,"dmask")) {
+- if (!value || !*value) ret = 0;
+- else {
+- opts->fs_dmask = simple_strtoul(value,&value,8);
+- if (*value) ret = 0;
+- }
+- }
+- else if (!strcmp(this_char,"debug")) {
+- if (value) ret = 0;
+- else *debug = 1;
+- }
+- else if (!strcmp(this_char,"fat")) {
+- printk(KERN_INFO "FAT: fat option is obsolete, "
+- "not supported now\n");
+- }
+- else if (!strcmp(this_char,"quiet")) {
+- if (value) ret = 0;
+- else opts->quiet = 1;
+- }
+- else if (!strcmp(this_char,"blocksize")) {
+- printk(KERN_INFO "FAT: blocksize option is obsolete, "
+- "not supported now\n");
+- }
+- else if (!strcmp(this_char,"sys_immutable")) {
+- if (value) ret = 0;
+- else opts->sys_immutable = 1;
+- }
+- else if (!strcmp(this_char,"codepage") && value) {
+- opts->codepage = simple_strtoul(value,&value,0);
+- if (*value) ret = 0;
+- }
+-
+- /* msdos specific */
+- else if (!is_vfat && !strcmp(this_char,"dots")) {
+- opts->dotsOK = 1;
+- }
+- else if (!is_vfat && !strcmp(this_char,"nodots")) {
+- opts->dotsOK = 0;
+- }
+- else if (!is_vfat && !strcmp(this_char,"dotsOK") && value) {
+- if (!strcmp(value,"yes")) opts->dotsOK = 1;
+- else if (!strcmp(value,"no")) opts->dotsOK = 0;
+- else ret = 0;
+- }
++ break;
++ case Opt_debug:
++ *debug = 1;
++ break;
++ case Opt_immutable:
++ opts->sys_immutable = 1;
++ break;
++ case Opt_uid:
++ if (match_int(&args[0], &option))
++ return 0;
++ opts->fs_uid = option;
++ break;
++ case Opt_gid:
++ if (match_int(&args[0], &option))
++ return 0;
++ opts->fs_gid = option;
++ break;
++ case Opt_umask:
++ if (match_octal(&args[0], &option))
++ return 0;
++ opts->fs_fmask = opts->fs_dmask = option;
++ break;
++ case Opt_dmask:
++ if (match_octal(&args[0], &option))
++ return 0;
++ opts->fs_dmask = option;
++ break;
++ case Opt_fmask:
++ if (match_octal(&args[0], &option))
++ return 0;
++ opts->fs_fmask = option;
++ break;
++ case Opt_codepage:
++ if (match_int(&args[0], &option))
++ return 0;
++ opts->codepage = option;
++ printk("MSDOS FS: Using codepage %d\n",
++ opts->codepage);
++ break;
+
+ /* vfat specific */
+- else if (is_vfat && !strcmp(this_char,"iocharset") && value) {
+- p = value;
+- while (*value && *value != ',')
+- value++;
+- len = value - p;
+- if (len) {
+- char *buffer;
+-
+- if (opts->iocharset != NULL) {
+- kfree(opts->iocharset);
+- opts->iocharset = NULL;
+- }
+- buffer = kmalloc(len + 1, GFP_KERNEL);
+- if (buffer != NULL) {
+- opts->iocharset = buffer;
+- memcpy(buffer, p, len);
+- buffer[len] = 0;
+- } else
+- ret = 0;
++ case Opt_charset:
++ if (is_vfat) {
++ kfree(opts->iocharset);
++ opts->iocharset = match_strdup(&args[0]);
++ if (!opts->iocharset)
++ return 0;
++ printk("MSDOS FS: IO charset %s\n",
++ opts->iocharset);
+ }
+- }
+- else if (is_vfat && !strcmp(this_char,"utf8")) {
+- ret = simple_getbool(value, &val);
+- if (ret) opts->utf8 = val;
+- }
+- else if (is_vfat && !strcmp(this_char,"uni_xlate")) {
+- ret = simple_getbool(value, &val);
+- if (ret) opts->unicode_xlate = val;
+- }
+- else if (is_vfat && !strcmp(this_char,"posix")) {
+- printk(KERN_INFO "FAT: posix option is obsolete, "
+- "not supported now\n");
+- }
+- else if (is_vfat && !strcmp(this_char,"nonumtail")) {
+- ret = simple_getbool(value, &val);
+- if (ret) {
+- opts->numtail = !val;
+- }
+- }
+- else if (is_vfat && !strcmp(this_char, "shortname")) {
+- if (!strcmp(value, "lower"))
++ break;
++ case Opt_shortname_lower:
++ if (is_vfat) {
+ opts->shortname = VFAT_SFN_DISPLAY_LOWER
+ | VFAT_SFN_CREATE_WIN95;
+- else if (!strcmp(value, "win95"))
++ }
++ break;
++ case Opt_shortname_win95:
++ if (is_vfat) {
+ opts->shortname = VFAT_SFN_DISPLAY_WIN95
+ | VFAT_SFN_CREATE_WIN95;
+- else if (!strcmp(value, "winnt"))
++ }
++ break;
++ case Opt_shortname_winnt:
++ if (is_vfat) {
+ opts->shortname = VFAT_SFN_DISPLAY_WINNT
+ | VFAT_SFN_CREATE_WINNT;
+- else if (!strcmp(value, "mixed"))
++ }
++ break;
++ case Opt_shortname_mixed:
++ if (is_vfat) {
+ opts->shortname = VFAT_SFN_DISPLAY_WINNT
+ | VFAT_SFN_CREATE_WIN95;
+- else
+- ret = 0;
+- } else {
+- printk(KERN_ERR "FAT: Unrecognized mount option %s\n",
+- this_char);
+- ret = 0;
+- }
++ }
++ break;
++ case Opt_utf8_off: /* 0 or no or false */
++ case Opt_utf8_no:
++ case Opt_utf8_false:
++ if (is_vfat) {
++ opts->utf8 = 0;
++ }
++ break;
++ case Opt_utf8_on: /* empty or 1 or yes or true */
++ case Opt_utf8_opt:
++ case Opt_utf8_yes:
++ case Opt_utf8_true:
++ if (is_vfat) {
++ opts->utf8 = 1;
++ }
++ break;
++ case Opt_uni_xl_off: /* 0 or no or false */
++ case Opt_uni_xl_no:
++ case Opt_uni_xl_false:
++ if (is_vfat) {
++ opts->unicode_xlate = 0;
++ }
++ break;
++ case Opt_uni_xl_on: /* empty or 1 or yes or true */
++ case Opt_uni_xl_yes:
++ case Opt_uni_xl_true:
++ case Opt_uni_xl_opt:
++ if (is_vfat) {
++ opts->unicode_xlate = 1;
++ }
++ break;
++ case Opt_nonumtail_off: /* 0 or no or false */
++ case Opt_nonumtail_no:
++ case Opt_nonumtail_false:
++ if (is_vfat) {
++ opts->numtail = 1; /* negated option */
++ }
++ break;
++ case Opt_nonumtail_on: /* empty or 1 or yes or true */
++ case Opt_nonumtail_yes:
++ case Opt_nonumtail_true:
++ case Opt_nonumtail_opt:
++ if (is_vfat) {
++ opts->numtail = 0; /* negated option */
++ }
++ break;
+
+- if (ret == 0)
++ /* obsolete mount options */
++ case Opt_conv_b:
++ case Opt_conv_t:
++ case Opt_conv_a:
++ print_obsolete_option("conv");
++ break;
++ case Opt_blocksize:
++ print_obsolete_option("blocksize");
++ break;
++ case Opt_posix:
++ print_obsolete_option("posix");
++ break;
++ case Opt_fat:
++ print_obsolete_option("fat");
++ break;
++ case Opt_cvf_format:
++ case Opt_cvf_options:
++ print_obsolete_option("cvf");
+ break;
++ /* unknown option */
++ default:
++ printk(KERN_ERR "FAT: Unrecognized mount option \"%s\" "
++ "or missing value\n", p);
++ return 0;
++ }
+ }
+-out:
++
+ if (opts->unicode_xlate)
+ opts->utf8 = 0;
+
+- return ret;
++ return 1;
+ }
+
+ static int fat_calc_dir_size(struct inode *inode)
+Index: linux-2.6.0-test5/fs/hfs/super.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/hfs/super.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/hfs/super.c 2003-09-27 11:38:36.322006600 +0800
+@@ -31,6 +31,7 @@
+ #include <linux/blkdev.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
++#include <linux/parser.h>
+ #include <linux/smp_lock.h>
+ #include <linux/vfs.h>
+
+@@ -211,6 +212,60 @@
+ return 0;
+ }
+
++enum {
++ Opt_version, Opt_uid, Opt_gid, Opt_umask, Opt_part,
++ Opt_type, Opt_creator, Opt_quiet, Opt_afpd,
++ Opt_names_netatalk, Opt_names_trivial, Opt_names_alpha, Opt_names_latin,
++ Opt_names_7bit, Opt_names_8bit, Opt_names_cap,
++ Opt_fork_netatalk, Opt_fork_single, Opt_fork_double, Opt_fork_cap,
++ Opt_case_lower, Opt_case_asis,
++ Opt_conv_binary, Opt_conv_text, Opt_conv_auto,
++};
++
++static match_table_t tokens = {
++ {Opt_version, "version=%u"},
++ {Opt_uid, "uid=%u"},
++ {Opt_gid, "gid=%u"},
++ {Opt_umask, "umask=%o"},
++ {Opt_part, "part=%u"},
++ {Opt_type, "type=%s"},
++ {Opt_creator, "creator=%s"},
++ {Opt_quiet, "quiet"},
++ {Opt_afpd, "afpd"},
++ {Opt_names_netatalk, "names=netatalk"},
++ {Opt_names_trivial, "names=trivial"},
++ {Opt_names_alpha, "names=alpha"},
++ {Opt_names_latin, "names=latin"},
++ {Opt_names_7bit, "names=7bit"},
++ {Opt_names_8bit, "names=8bit"},
++ {Opt_names_cap, "names=cap"},
++ {Opt_names_netatalk, "names=n"},
++ {Opt_names_trivial, "names=t"},
++ {Opt_names_alpha, "names=a"},
++ {Opt_names_latin, "names=l"},
++ {Opt_names_7bit, "names=7"},
++ {Opt_names_8bit, "names=8"},
++ {Opt_names_cap, "names=c"},
++ {Opt_fork_netatalk, "fork=netatalk"},
++ {Opt_fork_single, "fork=single"},
++ {Opt_fork_double, "fork=double"},
++ {Opt_fork_cap, "fork=cap"},
++ {Opt_fork_netatalk, "fork=n"},
++ {Opt_fork_single, "fork=s"},
++ {Opt_fork_double, "fork=d"},
++ {Opt_fork_cap, "fork=c"},
++ {Opt_case_lower, "case=lower"},
++ {Opt_case_asis, "case=asis"},
++ {Opt_case_lower, "case=l"},
++ {Opt_case_asis, "case=a"},
++ {Opt_conv_binary, "conv=binary"},
++ {Opt_conv_text, "conv=text"},
++ {Opt_conv_auto, "conv=auto"},
++ {Opt_conv_binary, "conv=b"},
++ {Opt_conv_text, "conv=t"},
++ {Opt_conv_auto, "conv=a"},
++};
++
+ /*
+ * parse_options()
+ *
+@@ -219,8 +274,10 @@
+ */
+ static int parse_options(char *options, struct hfs_sb_info *hsb, int *part)
+ {
+- char *this_char, *value;
++ char *p;
+ char names, fork;
++ substring_t args[MAX_OPT_ARGS];
++ int option;
+
+ /* initialize the sb with defaults */
+ memset(hsb, 0, sizeof(*hsb));
+@@ -243,117 +300,109 @@
+ if (!options) {
+ goto done;
+ }
+- while ((this_char = strsep(&options,",")) != NULL) {
+- if (!*this_char)
++ while ((p = strsep(&options,",")) != NULL) {
++ int token;
++ if (!*p)
+ continue;
+- if ((value = strchr(this_char,'=')) != NULL) {
+- *value++ = 0;
+- }
+- /* Numeric-valued options */
+- if (!strcmp(this_char, "version")) {
+- if (!value || !*value) {
+- return 0;
+- }
+- hsb->s_version = simple_strtoul(value,&value,0);
+- if (*value) {
+- return 0;
+- }
+- } else if (!strcmp(this_char,"uid")) {
+- if (!value || !*value) {
+- return 0;
+- }
+- hsb->s_uid = simple_strtoul(value,&value,0);
+- if (*value) {
+- return 0;
+- }
+- } else if (!strcmp(this_char,"gid")) {
+- if (!value || !*value) {
+- return 0;
+- }
+- hsb->s_gid = simple_strtoul(value,&value,0);
+- if (*value) {
+- return 0;
+- }
+- } else if (!strcmp(this_char,"umask")) {
+- if (!value || !*value) {
+- return 0;
+- }
+- hsb->s_umask = simple_strtoul(value,&value,8);
+- if (*value) {
+- return 0;
+- }
+- } else if (!strcmp(this_char,"part")) {
+- if (!value || !*value) {
+- return 0;
+- }
+- *part = simple_strtoul(value,&value,0);
+- if (*value) {
+- return 0;
+- }
+- /* String-valued options */
+- } else if (!strcmp(this_char,"type") && value) {
+- if (strlen(value) != 4) {
+- return 0;
+- }
+- hsb->s_type = hfs_get_nl(value);
+- } else if (!strcmp(this_char,"creator") && value) {
+- if (strlen(value) != 4) {
+- return 0;
+- }
+- hsb->s_creator = hfs_get_nl(value);
+- /* Boolean-valued options */
+- } else if (!strcmp(this_char,"quiet")) {
+- if (value) {
+- return 0;
+- }
++
++ token = match_token(p, tokens, args);
++ switch (token) {
++ /* Numeric-valued options */
++ case Opt_version:
++ if (match_int(&args[0], &option))
++ return 0;
++ hsb->s_version = option;
++ break;
++ case Opt_uid:
++ if (match_int(&args[0], &option))
++ return 0;
++ hsb->s_uid = option;
++ break;
++ case Opt_gid:
++ if (match_int(&args[0], &option))
++ return 0;
++ hsb->s_gid = option;
++ break;
++ case Opt_umask:
++ if (match_octal(&args[0], &option))
++ return 0;
++ hsb->s_umask = option;
++ break;
++ case Opt_part:
++ if (match_int(&args[0], &option))
++ return 0;
++ *part = option;
++ break;
++ /* String-valued options */
++ case Opt_type:
++ if (strlen(args[0].from) != 4) {
++ return 0;
++ }
++ hsb->s_type = hfs_get_nl(args[0].from);
++ break;
++ case Opt_creator:
++ if (strlen(args[0].from) != 4) {
++ return 0;
++ }
++ hsb->s_creator = hfs_get_nl(args[0].from);
++ break;
++ /* Boolean-valued options */
++ case Opt_quiet:
+ hsb->s_quiet = 1;
+- } else if (!strcmp(this_char,"afpd")) {
+- if (value) {
+- return 0;
+- }
++ break;
++ case Opt_afpd:
+ hsb->s_afpd = 1;
+- /* Multiple choice options */
+- } else if (!strcmp(this_char,"names") && value) {
+- if ((*value && !value[1] && strchr("ntal78c",*value)) ||
+- !strcmp(value,"netatalk") ||
+- !strcmp(value,"trivial") ||
+- !strcmp(value,"alpha") ||
+- !strcmp(value,"latin") ||
+- !strcmp(value,"7bit") ||
+- !strcmp(value,"8bit") ||
+- !strcmp(value,"cap")) {
+- names = *value;
+- } else {
+- return 0;
+- }
+- } else if (!strcmp(this_char,"fork") && value) {
+- if ((*value && !value[1] && strchr("nsdc",*value)) ||
+- !strcmp(value,"netatalk") ||
+- !strcmp(value,"single") ||
+- !strcmp(value,"double") ||
+- !strcmp(value,"cap")) {
+- fork = *value;
+- } else {
+- return 0;
+- }
+- } else if (!strcmp(this_char,"case") && value) {
+- if ((*value && !value[1] && strchr("la",*value)) ||
+- !strcmp(value,"lower") ||
+- !strcmp(value,"asis")) {
+- hsb->s_lowercase = (*value == 'l');
+- } else {
+- return 0;
+- }
+- } else if (!strcmp(this_char,"conv") && value) {
+- if ((*value && !value[1] && strchr("bta",*value)) ||
+- !strcmp(value,"binary") ||
+- !strcmp(value,"text") ||
+- !strcmp(value,"auto")) {
+- hsb->s_conv = *value;
+- } else {
+- return 0;
+- }
+- } else {
++ break;
++ /* Multiple choice options */
++ case Opt_names_netatalk:
++ names = 'n';
++ break;
++ case Opt_names_trivial:
++ names = 't';
++ break;
++ case Opt_names_alpha:
++ names = 'a';
++ break;
++ case Opt_names_latin:
++ names = 'l';
++ break;
++ case Opt_names_7bit:
++ names = '7';
++ break;
++ case Opt_names_8bit:
++ names = '8';
++ break;
++ case Opt_names_cap:
++ names = 'c';
++ break;
++ case Opt_fork_netatalk:
++ fork = 'n';
++ break;
++ case Opt_fork_single:
++ fork = 's';
++ break;
++ case Opt_fork_double:
++ fork = 'd';
++ break;
++ case Opt_fork_cap:
++ fork = 'c';
++ break;
++ case Opt_case_lower:
++ hsb->s_lowercase = 1;
++ break;
++ case Opt_case_asis:
++ hsb->s_lowercase = 0;
++ break;
++ case Opt_conv_binary:
++ hsb->s_conv = 'b';
++ break;
++ case Opt_conv_text:
++ hsb->s_conv = 't';
++ break;
++ case Opt_conv_auto:
++ hsb->s_conv = 'a';
++ break;
++ default:
+ return 0;
+ }
+ }
+Index: linux-2.6.0-test5/fs/hpfs/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/hpfs/inode.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/hpfs/inode.c 2003-09-27 11:38:36.325006144 +0800
+@@ -159,7 +159,7 @@
+ i->i_size = 0;
+ i->i_blocks = 1;
+ init_special_inode(i, mode,
+- old_decode_dev(rdev));
++ new_decode_dev(rdev));
+ return;
+ }
+ }
+@@ -223,7 +223,7 @@
+ hpfs_inode->i_ea_mode = 1;
+ }
+ if (S_ISBLK(i->i_mode) || S_ISCHR(i->i_mode)) {
+- ea = cpu_to_le32(old_encode_dev(i->i_rdev));
++ ea = cpu_to_le32(new_encode_dev(i->i_rdev));
+ hpfs_set_ea(i, fnode, "DEV", (char *)&ea, 4);
+ }
+ }
+Index: linux-2.6.0-test5/fs/hpfs/namei.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/hpfs/namei.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/hpfs/namei.c 2003-09-27 11:38:36.330005384 +0800
+@@ -194,7 +194,7 @@
+ int err;
+ if ((err = hpfs_chk_name((char *)name, &len))) return err==-ENOENT ? -EINVAL : err;
+ if (hpfs_sb(dir->i_sb)->sb_eas < 2) return -EPERM;
+- if (!old_valid_dev(rdev))
++ if (!new_valid_dev(rdev))
+ return -EINVAL;
+ lock_kernel();
+ if (!(fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh))) goto bail;
+Index: linux-2.6.0-test5/fs/hpfs/super.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/hpfs/super.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/hpfs/super.c 2003-09-27 11:38:36.336004472 +0800
+@@ -10,6 +10,7 @@
+ #include <linux/string.h>
+ #include "hpfs_fn.h"
+ #include <linux/module.h>
++#include <linux/parser.h>
+ #include <linux/init.h>
+ #include <linux/vfs.h>
+
+@@ -219,15 +220,52 @@
+
+ /*
+ * A tiny parser for option strings, stolen from dosfs.
+- *
+ * Stolen again from read-only hpfs.
++ * And updated for table-driven option parsing.
+ */
+
++enum {
++ Opt_help, Opt_uid, Opt_gid, Opt_umask, Opt_case_lower, Opt_case_asis,
++ Opt_conv_binary, Opt_conv_text, Opt_conv_auto,
++ Opt_check_none, Opt_check_normal, Opt_check_strict,
++ Opt_err_cont, Opt_err_ro, Opt_err_panic,
++ Opt_eas_no, Opt_eas_ro, Opt_eas_rw,
++ Opt_chkdsk_no, Opt_chkdsk_errors, Opt_chkdsk_always,
++ Opt_timeshift, Opt_err,
++};
++
++static match_table_t tokens = {
++ {Opt_help, "help"},
++ {Opt_uid, "uid=%u"},
++ {Opt_gid, "gid=%u"},
++ {Opt_umask, "umask=%o"},
++ {Opt_case_lower, "case=lower"},
++ {Opt_case_asis, "case=asis"},
++ {Opt_conv_binary, "conv=binary"},
++ {Opt_conv_text, "conv=text"},
++ {Opt_conv_auto, "conv=auto"},
++ {Opt_check_none, "check=none"},
++ {Opt_check_normal, "check=normal"},
++ {Opt_check_strict, "check=strict"},
++ {Opt_err_cont, "errors=continue"},
++ {Opt_err_ro, "errors=remount-ro"},
++ {Opt_err_panic, "errors=panic"},
++ {Opt_eas_no, "eas=no"},
++ {Opt_eas_ro, "eas=ro"},
++ {Opt_eas_rw, "eas=rw"},
++ {Opt_chkdsk_no, "chkdsk=no"},
++ {Opt_chkdsk_errors, "chkdsk=errors"},
++ {Opt_chkdsk_always, "chkdsk=always"},
++ {Opt_timeshift, "timeshift=%d"},
++ {Opt_err, NULL},
++};
++
+ int parse_opts(char *opts, uid_t *uid, gid_t *gid, umode_t *umask,
+ int *lowercase, int *conv, int *eas, int *chk, int *errs,
+ int *chkdsk, int *timeshift)
+ {
+- char *p, *rhs;
++ char *p;
++ int option;
+
+ if (!opts)
+ return 1;
+@@ -235,34 +273,85 @@
+ /*printk("Parsing opts: '%s'\n",opts);*/
+
+ while ((p = strsep(&opts, ",")) != NULL) {
++ substring_t args[MAX_OPT_ARGS];
++ int token;
+ if (!*p)
+ continue;
+- if ((rhs = strchr(p, '=')) != 0)
+- *rhs++ = '\0';
+- if (!strcmp(p, "help")) return 2;
+- if (!strcmp(p, "uid")) {
+- if (!rhs || !*rhs)
+- return 0;
+- *uid = simple_strtoul(rhs, &rhs, 0);
+- if (*rhs)
+- return 0;
+- }
+- else if (!strcmp(p, "gid")) {
+- if (!rhs || !*rhs)
+- return 0;
+- *gid = simple_strtoul(rhs, &rhs, 0);
+- if (*rhs)
+- return 0;
+- }
+- else if (!strcmp(p, "umask")) {
+- if (!rhs || !*rhs)
+- return 0;
+- *umask = simple_strtoul(rhs, &rhs, 8);
+- if (*rhs)
+- return 0;
+- }
+- else if (!strcmp(p, "timeshift")) {
++
++ token = match_token(p, tokens, args);
++ switch (token) {
++ case Opt_help:
++ return 2;
++ case Opt_uid:
++ if (match_int(args, &option))
++ return 0;
++ *uid = option;
++ break;
++ case Opt_gid:
++ if (match_int(args, &option))
++ return 0;
++ *gid = option;
++ break;
++ case Opt_umask:
++ if (match_octal(args, &option))
++ return 0;
++ *umask = option;
++ break;
++ case Opt_case_lower:
++ *lowercase = 1;
++ break;
++ case Opt_case_asis:
++ *lowercase = 0;
++ break;
++ case Opt_conv_binary:
++ *conv = CONV_BINARY;
++ break;
++ case Opt_conv_text:
++ *conv = CONV_TEXT;
++ break;
++ case Opt_conv_auto:
++ *conv = CONV_AUTO;
++ break;
++ case Opt_check_none:
++ *chk = 0;
++ break;
++ case Opt_check_normal:
++ *chk = 1;
++ break;
++ case Opt_check_strict:
++ *chk = 2;
++ break;
++ case Opt_err_cont:
++ *errs = 0;
++ break;
++ case Opt_err_ro:
++ *errs = 1;
++ break;
++ case Opt_err_panic:
++ *errs = 2;
++ break;
++ case Opt_eas_no:
++ *eas = 0;
++ break;
++ case Opt_eas_ro:
++ *eas = 1;
++ break;
++ case Opt_eas_rw:
++ *eas = 2;
++ break;
++ case Opt_chkdsk_no:
++ *chkdsk = 0;
++ break;
++ case Opt_chkdsk_errors:
++ *chkdsk = 1;
++ break;
++ case Opt_chkdsk_always:
++ *chkdsk = 2;
++ break;
++ case Opt_timeshift:
++ {
+ int m = 1;
++ char *rhs = args[0].from;
+ if (!rhs || !*rhs)
+ return 0;
+ if (*rhs == '-') m = -1;
+@@ -270,79 +359,11 @@
+ *timeshift = simple_strtoul(rhs, &rhs, 0) * m;
+ if (*rhs)
+ return 0;
++ break;
+ }
+- else if (!strcmp(p, "case")) {
+- if (!rhs || !*rhs)
+- return 0;
+- if (!strcmp(rhs, "lower"))
+- *lowercase = 1;
+- else if (!strcmp(rhs, "asis"))
+- *lowercase = 0;
+- else
+- return 0;
+- }
+- else if (!strcmp(p, "conv")) {
+- if (!rhs || !*rhs)
+- return 0;
+- if (!strcmp(rhs, "binary"))
+- *conv = CONV_BINARY;
+- else if (!strcmp(rhs, "text"))
+- *conv = CONV_TEXT;
+- else if (!strcmp(rhs, "auto"))
+- *conv = CONV_AUTO;
+- else
+- return 0;
+- }
+- else if (!strcmp(p, "check")) {
+- if (!rhs || !*rhs)
+- return 0;
+- if (!strcmp(rhs, "none"))
+- *chk = 0;
+- else if (!strcmp(rhs, "normal"))
+- *chk = 1;
+- else if (!strcmp(rhs, "strict"))
+- *chk = 2;
+- else
+- return 0;
+- }
+- else if (!strcmp(p, "errors")) {
+- if (!rhs || !*rhs)
+- return 0;
+- if (!strcmp(rhs, "continue"))
+- *errs = 0;
+- else if (!strcmp(rhs, "remount-ro"))
+- *errs = 1;
+- else if (!strcmp(rhs, "panic"))
+- *errs = 2;
+- else
+- return 0;
+- }
+- else if (!strcmp(p, "eas")) {
+- if (!rhs || !*rhs)
+- return 0;
+- if (!strcmp(rhs, "no"))
+- *eas = 0;
+- else if (!strcmp(rhs, "ro"))
+- *eas = 1;
+- else if (!strcmp(rhs, "rw"))
+- *eas = 2;
+- else
+- return 0;
+- }
+- else if (!strcmp(p, "chkdsk")) {
+- if (!rhs || !*rhs)
+- return 0;
+- if (!strcmp(rhs, "no"))
+- *chkdsk = 0;
+- else if (!strcmp(rhs, "errors"))
+- *chkdsk = 1;
+- else if (!strcmp(rhs, "always"))
+- *chkdsk = 2;
+- else
+- return 0;
+- }
+- else
++ default:
+ return 0;
++ }
+ }
+ return 1;
+ }
+Index: linux-2.6.0-test5/fs/hugetlbfs/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/hugetlbfs/inode.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/hugetlbfs/inode.c 2003-09-27 11:38:36.342003560 +0800
+@@ -47,7 +47,6 @@
+ {
+ struct inode *inode = file->f_dentry->d_inode;
+ struct address_space *mapping = inode->i_mapping;
+- struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(inode->i_sb);
+ loff_t len, vma_len;
+ int ret;
+
+@@ -61,19 +60,8 @@
+ return -EINVAL;
+
+ vma_len = (loff_t)(vma->vm_end - vma->vm_start);
+- if (sbinfo->free_blocks >= 0) { /* Check if there is any size limit. */
+- spin_lock(&sbinfo->stat_lock);
+- if ((vma_len >> HPAGE_SHIFT) <= sbinfo->free_blocks) {
+- sbinfo->free_blocks -= (vma_len >> HPAGE_SHIFT);
+- spin_unlock(&sbinfo->stat_lock);
+- } else {
+- spin_unlock(&sbinfo->stat_lock);
+- return -ENOMEM;
+- }
+- }
+
+ down(&inode->i_sem);
+-
+ update_atime(inode);
+ vma->vm_flags |= VM_HUGETLB | VM_RESERVED;
+ vma->vm_ops = &hugetlb_vm_ops;
+@@ -83,15 +71,6 @@
+ inode->i_size = len;
+ up(&inode->i_sem);
+
+- /*
+- * If the huge page allocation has failed then increment free_blocks.
+- */
+- if ((ret != 0) && (sbinfo->free_blocks >= 0)) {
+- spin_lock(&sbinfo->stat_lock);
+- sbinfo->free_blocks += (vma_len >> HPAGE_SHIFT);
+- spin_unlock(&sbinfo->stat_lock);
+- }
+-
+ return ret;
+ }
+
+@@ -178,7 +157,6 @@
+
+ void truncate_hugepages(struct address_space *mapping, loff_t lstart)
+ {
+- struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(mapping->host->i_sb);
+ const pgoff_t start = lstart >> HPAGE_SHIFT;
+ struct pagevec pvec;
+ pgoff_t next;
+@@ -187,7 +165,7 @@
+ pagevec_init(&pvec, 0);
+ next = start;
+ while (1) {
+- if (!pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
++ if (!pagevec_lookup(&pvec, mapping, &next, PAGEVEC_SIZE)) {
+ if (next == start)
+ break;
+ next = start;
+@@ -198,16 +176,9 @@
+ struct page *page = pvec.pages[i];
+
+ lock_page(page);
+- if (page->index > next)
+- next = page->index;
+- ++next;
+ truncate_huge_page(page);
+ unlock_page(page);
+- if (sbinfo->free_blocks >= 0) {
+- spin_lock(&sbinfo->stat_lock);
+- sbinfo->free_blocks++;
+- spin_unlock(&sbinfo->stat_lock);
+- }
++ hugetlb_put_quota(mapping);
+ }
+ huge_pagevec_release(&pvec);
+ }
+@@ -712,6 +683,34 @@
+ return 0;
+ }
+
++int hugetlb_get_quota(struct address_space *mapping)
++{
++ int ret = 0;
++ struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(mapping->host->i_sb);
++
++ if (sbinfo->free_blocks > -1) {
++ spin_lock(&sbinfo->stat_lock);
++ if (sbinfo->free_blocks > 0)
++ sbinfo->free_blocks--;
++ else
++ ret = -ENOMEM;
++ spin_unlock(&sbinfo->stat_lock);
++ }
++
++ return ret;
++}
++
++void hugetlb_put_quota(struct address_space *mapping)
++{
++ struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(mapping->host->i_sb);
++
++ if (sbinfo->free_blocks > -1) {
++ spin_lock(&sbinfo->stat_lock);
++ sbinfo->free_blocks++;
++ spin_unlock(&sbinfo->stat_lock);
++ }
++}
++
+ static struct super_block *hugetlbfs_get_sb(struct file_system_type *fs_type,
+ int flags, const char *dev_name, void *data)
+ {
+Index: linux-2.6.0-test5/fs/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/inode.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/inode.c 2003-09-27 11:38:36.351002192 +0800
+@@ -183,6 +183,7 @@
+ INIT_LIST_HEAD(&inode->i_dentry);
+ INIT_LIST_HEAD(&inode->i_devices);
+ sema_init(&inode->i_sem, 1);
++ init_rwsem(&inode->i_alloc_sem);
+ INIT_RADIX_TREE(&inode->i_data.page_tree, GFP_ATOMIC);
+ spin_lock_init(&inode->i_data.page_lock);
+ init_MUTEX(&inode->i_data.i_shared_sem);
+Index: linux-2.6.0-test5/fs/intermezzo/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/intermezzo/inode.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/intermezzo/inode.c 2003-09-27 11:38:36.353001888 +0800
+@@ -167,7 +167,6 @@
+ exit:
+ CDEBUG(D_MALLOC, "after umount: kmem %ld, vmem %ld\n",
+ presto_kmemory, presto_vmemory);
+- MOD_DEC_USE_COUNT;
+ return ;
+ }
+
+Index: linux-2.6.0-test5/fs/isofs/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/isofs/inode.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/isofs/inode.c 2003-09-27 11:38:36.364000216 +0800
+@@ -29,6 +29,7 @@
+ #include <linux/blkdev.h>
+ #include <linux/buffer_head.h>
+ #include <linux/vfs.h>
++#include <linux/parser.h>
+ #include <asm/system.h>
+ #include <asm/uaccess.h>
+
+@@ -328,9 +329,52 @@
+ }
+ #endif
+
++enum {
++ Opt_block, Opt_check_r, Opt_check_s, Opt_cruft, Opt_gid, Opt_ignore,
++ Opt_iocharset, Opt_map_a, Opt_map_n, Opt_map_o, Opt_mode, Opt_nojoliet,
++ Opt_norock, Opt_sb, Opt_session, Opt_uid, Opt_unhide, Opt_utf8, Opt_err,
++ Opt_nocompress,
++};
++
++static match_table_t tokens = {
++ {Opt_norock, "norock"},
++ {Opt_nojoliet, "nojoliet"},
++ {Opt_unhide, "unhide"},
++ {Opt_cruft, "cruft"},
++ {Opt_utf8, "utf8"},
++ {Opt_iocharset, "iocharset=%s"},
++ {Opt_map_a, "map=acorn"},
++ {Opt_map_a, "map=a"},
++ {Opt_map_n, "map=normal"},
++ {Opt_map_n, "map=n"},
++ {Opt_map_o, "map=off"},
++ {Opt_map_o, "map=o"},
++ {Opt_session, "session=%u"},
++ {Opt_sb, "sbsector=%u"},
++ {Opt_check_r, "check=relaxed"},
++ {Opt_check_r, "check=r"},
++ {Opt_check_s, "check=strict"},
++ {Opt_check_s, "check=s"},
++ {Opt_uid, "uid=%u"},
++ {Opt_gid, "gid=%u"},
++ {Opt_mode, "mode=%u"},
++ {Opt_block, "block=%u"},
++ {Opt_ignore, "conv=binary"},
++ {Opt_ignore, "conv=b"},
++ {Opt_ignore, "conv=text"},
++ {Opt_ignore, "conv=t"},
++ {Opt_ignore, "conv=mtext"},
++ {Opt_ignore, "conv=m"},
++ {Opt_ignore, "conv=auto"},
++ {Opt_ignore, "conv=a"},
++ {Opt_nocompress, "nocompress"},
++ {Opt_err, NULL}
++};
++
+ static int parse_options(char *options, struct iso9660_options * popt)
+ {
+- char *this_char,*value;
++ char *p;
++ int option;
+
+ popt->map = 'n';
+ popt->rock = 'y';
+@@ -350,112 +394,101 @@
+ popt->utf8 = 0;
+ popt->session=-1;
+ popt->sbsector=-1;
+- if (!options) return 1;
+- while ((this_char = strsep(&options,",")) != NULL) {
+- if (!*this_char)
++ if (!options)
++ return 1;
++
++ while ((p = strsep(&options, ",")) != NULL) {
++ int token;
++ substring_t args[MAX_OPT_ARGS];
++ unsigned n;
++
++ if (!*p)
+ continue;
+- if (strncmp(this_char,"norock",6) == 0) {
+- popt->rock = 'n';
+- continue;
+- }
+- if (strncmp(this_char,"nojoliet",8) == 0) {
+- popt->joliet = 'n';
+- continue;
+- }
+- if (strncmp(this_char,"unhide",6) == 0) {
+- popt->unhide = 'y';
+- continue;
+- }
+- if (strncmp(this_char,"cruft",5) == 0) {
+- popt->cruft = 'y';
+- continue;
+- }
+- if (strncmp(this_char,"utf8",4) == 0) {
+- popt->utf8 = 1;
+- continue;
+- }
+- if (strncmp(this_char,"nocompress",10) == 0) {
+- popt->nocompress = 1;
+- continue;
+- }
+- if ((value = strchr(this_char,'=')) != NULL)
+- *value++ = 0;
+
++ token = match_token(p, tokens, args);
++ switch (token) {
++ case Opt_norock:
++ popt->rock = 'n';
++ break;
++ case Opt_nojoliet:
++ popt->joliet = 'n';
++ break;
++ case Opt_unhide:
++ popt->unhide = 'y';
++ break;
++ case Opt_cruft:
++ popt->cruft = 'y';
++ break;
++ case Opt_utf8:
++ popt->utf8 = 1;
++ break;
+ #ifdef CONFIG_JOLIET
+- if (!strcmp(this_char,"iocharset") && value) {
+- popt->iocharset = value;
+- while (*value && *value != ',')
+- value++;
+- if (value == popt->iocharset)
+- return 0;
+- *value = 0;
+- } else
++ case Opt_iocharset:
++ popt->iocharset = match_strdup(&args[0]);
++ break;
+ #endif
+- if (!strcmp(this_char,"map") && value) {
+- if (value[0] && !value[1] && strchr("ano",*value))
+- popt->map = *value;
+- else if (!strcmp(value,"off")) popt->map = 'o';
+- else if (!strcmp(value,"normal")) popt->map = 'n';
+- else if (!strcmp(value,"acorn")) popt->map = 'a';
+- else return 0;
+- }
+- if (!strcmp(this_char,"session") && value) {
+- char * vpnt = value;
+- unsigned int ivalue = simple_strtoul(vpnt, &vpnt, 0);
+- if(ivalue < 0 || ivalue >99) return 0;
+- popt->session=ivalue+1;
+- }
+- if (!strcmp(this_char,"sbsector") && value) {
+- char * vpnt = value;
+- unsigned int ivalue = simple_strtoul(vpnt, &vpnt, 0);
+- if(ivalue < 0 || ivalue >660*512) return 0;
+- popt->sbsector=ivalue;
+- }
+- else if (!strcmp(this_char,"check") && value) {
+- if (value[0] && !value[1] && strchr("rs",*value))
+- popt->check = *value;
+- else if (!strcmp(value,"relaxed")) popt->check = 'r';
+- else if (!strcmp(value,"strict")) popt->check = 's';
+- else return 0;
+- }
+- else if (!strcmp(this_char,"conv") && value) {
+- /* no conversion is done anymore;
+- we still accept the same mount options,
+- but ignore them */
+- if (value[0] && !value[1] && strchr("btma",*value)) ;
+- else if (!strcmp(value,"binary")) ;
+- else if (!strcmp(value,"text")) ;
+- else if (!strcmp(value,"mtext")) ;
+- else if (!strcmp(value,"auto")) ;
+- else return 0;
+- }
+- else if (value &&
+- (!strcmp(this_char,"block") ||
+- !strcmp(this_char,"mode") ||
+- !strcmp(this_char,"uid") ||
+- !strcmp(this_char,"gid"))) {
+- char * vpnt = value;
+- unsigned int ivalue = simple_strtoul(vpnt, &vpnt, 0);
+- if (*vpnt) return 0;
+- switch(*this_char) {
+- case 'b':
+- if ( ivalue != 512
+- && ivalue != 1024
+- && ivalue != 2048) return 0;
+- popt->blocksize = ivalue;
+- break;
+- case 'u':
+- popt->uid = ivalue;
+- break;
+- case 'g':
+- popt->gid = ivalue;
+- break;
+- case 'm':
+- popt->mode = ivalue;
+- break;
+- }
++ case Opt_map_a:
++ popt->map = 'a';
++ break;
++ case Opt_map_o:
++ popt->map = 'o';
++ break;
++ case Opt_map_n:
++ popt->map = 'n';
++ break;
++ case Opt_session:
++ if (match_int(&args[0], &option))
++ return 0;
++ n = option;
++ if (n > 99)
++ return 0;
++ popt->session = n + 1;
++ break;
++ case Opt_sb:
++ if (match_int(&args[0], &option))
++ return 0;
++ n = option;
++ if (n > 660 * 512)
++ return 0;
++ popt->sbsector = n;
++ break;
++ case Opt_check_r:
++ popt->check = 'r';
++ break;
++ case Opt_check_s:
++ popt->check = 's';
++ break;
++ case Opt_ignore:
++ break;
++ case Opt_uid:
++ if (match_int(&args[0], &option))
++ return 0;
++ popt->uid = option;
++ break;
++ case Opt_gid:
++ if (match_int(&args[0], &option))
++ return 0;
++ popt->gid = option;
++ break;
++ case Opt_mode:
++ if (match_int(&args[0], &option))
++ return 0;
++ popt->mode = option;
++ break;
++ case Opt_block:
++ if (match_int(&args[0], &option))
++ return 0;
++ n = option;
++ if (n != 512 && n != 1024 && n != 2048)
++ return 0;
++ popt->blocksize = n;
++ break;
++ case Opt_nocompress:
++ popt->nocompress = 1;
++ break;
++ default:
++ return 0;
+ }
+- else return 1;
+ }
+ return 1;
+ }
+@@ -842,6 +875,9 @@
+ if (opt.check == 'r') table++;
+ s->s_root->d_op = &isofs_dentry_ops[table];
+
++ if (opt.iocharset)
++ kfree(opt.iocharset);
++
+ return 0;
+
+ /*
+@@ -879,6 +915,8 @@
+ out_freebh:
+ brelse(bh);
+ out_freesbi:
++ if (opt.iocharset)
++ kfree(opt.iocharset);
+ kfree(sbi);
+ s->s_fs_info = NULL;
+ return -EINVAL;
+Index: linux-2.6.0-test5/fs/jbd/transaction.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/jbd/transaction.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/jbd/transaction.c 2003-09-27 11:38:36.380997632 +0800
+@@ -1932,9 +1932,6 @@
+ J_ASSERT_JH(jh, jbd_is_locked_bh_state(bh));
+ assert_spin_locked(&transaction->t_journal->j_list_lock);
+
+-#ifdef __SMP__
+- J_ASSERT (current->lock_depth >= 0);
+-#endif
+ J_ASSERT_JH(jh, jh->b_jlist < BJ_Types);
+ J_ASSERT_JH(jh, jh->b_transaction == transaction ||
+ jh->b_transaction == 0);
+Index: linux-2.6.0-test5/fs/jffs2/file.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/jffs2/file.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/jffs2/file.c 2003-09-27 11:38:36.384997024 +0800
+@@ -105,8 +105,7 @@
+ it out again with the appropriate data attached */
+ if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) {
+ /* For these, we don't actually need to read the old node */
+- dev = (imajor(dentry->d_inode) << 8) |
+- iminor(dentry->d_inode);
++ dev = old_encode_dev(dentry->d_inode->i_rdev);
+ mdata = (char *)&dev;
+ mdatalen = sizeof(dev);
+ D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of kdev_t\n", mdatalen));
+Index: linux-2.6.0-test5/fs/jffs2/super.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/jffs2/super.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/jffs2/super.c 2003-09-27 11:38:36.388996416 +0800
+@@ -173,7 +173,6 @@
+ int err;
+ struct nameidata nd;
+ int mtdnr;
+- dev_t dev;
+
+ if (!dev_name)
+ return ERR_PTR(-EINVAL);
+@@ -227,26 +226,31 @@
+ if (err)
+ return ERR_PTR(err);
+
+- if (!S_ISBLK(nd.dentry->d_inode->i_mode)) {
+- path_release(&nd);
+- return ERR_PTR(-EINVAL);
+- }
++ err = -EINVAL;
++
++ if (!S_ISBLK(nd.dentry->d_inode->i_mode))
++ goto out;
++
+ if (nd.mnt->mnt_flags & MNT_NODEV) {
+- path_release(&nd);
+- return ERR_PTR(-EACCES);
++ err = -EACCES;
++ goto out;
+ }
+
+- dev = nd.dentry->d_inode->i_rdev;
+- path_release(&nd);
+-
+- if (MAJOR(dev) != MTD_BLOCK_MAJOR) {
++ if (imajor(nd.dentry->d_inode) != MTD_BLOCK_MAJOR) {
+ if (!(flags & MS_VERBOSE)) /* Yes I mean this. Strangely */
+ printk(KERN_NOTICE "Attempt to mount non-MTD device \"%s\" as JFFS2\n",
+ dev_name);
+- return ERR_PTR(-EINVAL);
++ goto out;
+ }
+
+- return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, MINOR(dev));
++ mtdnr = iminor(nd.dentry->d_inode);
++ path_release(&nd);
++
++ return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, mtdnr);
++
++out:
++ path_release(&nd);
++ return ERR_PTR(err);
+ }
+
+
+Index: linux-2.6.0-test5/fs/jffs/inode-v23.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/jffs/inode-v23.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/jffs/inode-v23.c 2003-09-27 11:38:36.400994592 +0800
+@@ -139,7 +139,7 @@
+
+ c->thread_pid = kernel_thread (jffs_garbage_collect_thread,
+ (void *) c,
+- CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++ CLONE_KERNEL);
+ D1(printk(KERN_NOTICE "JFFS: GC thread pid=%d.\n", (int) c->thread_pid));
+
+ D1(printk(KERN_NOTICE "JFFS: Successfully mounted device %s.\n",
+@@ -1734,7 +1734,7 @@
+ the device should be read from the flash memory and then
+ added to the inode's i_rdev member. */
+ u16 val;
+- jffs_read_data(f, (char *)val, 0, 2);
++ jffs_read_data(f, (char *)&val, 0, 2);
+ init_special_inode(inode, inode->i_mode,
+ old_decode_dev(val));
+ }
+Index: linux-2.6.0-test5/fs/jfs/jfs_imap.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/jfs/jfs_imap.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/jfs/jfs_imap.c 2003-09-27 11:38:36.422991248 +0800
+@@ -3041,10 +3041,11 @@
+ jfs_ip->next_index = le32_to_cpu(dip->di_next_index);
+ jfs_ip->otime = le32_to_cpu(dip->di_otime.tv_sec);
+ jfs_ip->acltype = le32_to_cpu(dip->di_acltype);
+- jfs_ip->dev = le32_to_cpu(dip->di_rdev);
+
+- if (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode))
+- ip->i_rdev = old_decode_dev(jfs_ip->dev);
++ if (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode)) {
++ jfs_ip->dev = le32_to_cpu(dip->di_rdev);
++ ip->i_rdev = new_decode_dev(jfs_ip->dev);
++ }
+
+ if (S_ISDIR(ip->i_mode)) {
+ memcpy(&jfs_ip->i_dirtable, &dip->di_dirtable, 384);
+@@ -3101,7 +3102,8 @@
+ dip->di_otime.tv_sec = cpu_to_le32(jfs_ip->otime);
+ dip->di_otime.tv_nsec = 0;
+ dip->di_acltype = cpu_to_le32(jfs_ip->acltype);
+- dip->di_rdev = cpu_to_le32(jfs_ip->dev);
++ if (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode))
++ dip->di_rdev = cpu_to_le32(jfs_ip->dev);
+ }
+
+ #ifdef _JFS_DEBUG_IMAP
+Index: linux-2.6.0-test5/fs/jfs/jfs_mount.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/jfs/jfs_mount.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/jfs/jfs_mount.c 2003-09-27 11:38:36.427990488 +0800
+@@ -395,7 +395,7 @@
+ if (sbi->mntflag & JFS_INLINELOG)
+ sbi->logpxd = j_sb->s_logpxd;
+ else {
+- sbi->logdev = old_decode_dev(le32_to_cpu(j_sb->s_logdev));
++ sbi->logdev = new_decode_dev(le32_to_cpu(j_sb->s_logdev));
+ memcpy(sbi->uuid, j_sb->s_uuid, sizeof(sbi->uuid));
+ memcpy(sbi->loguuid, j_sb->s_loguuid, sizeof(sbi->uuid));
+ }
+@@ -444,7 +444,7 @@
+
+ if (state == FM_MOUNT) {
+ /* record log's dev_t and mount serial number */
+- j_sb->s_logdev = cpu_to_le32(sbi->log->bdev->bd_dev);
++ j_sb->s_logdev = cpu_to_le32(new_encode_dev(sbi->log->bdev->bd_dev));
+ j_sb->s_logserial = cpu_to_le32(sbi->log->serial);
+ } else if (state == FM_CLEAN) {
+ /*
+@@ -507,7 +507,7 @@
+ lrd.backchain = 0;
+ lrd.type = cpu_to_le16(LOG_MOUNT);
+ lrd.length = 0;
+- lrd.aggregate = cpu_to_le32(sb->s_bdev->bd_dev);
++ lrd.aggregate = cpu_to_le32(new_encode_dev(sb->s_bdev->bd_dev));
+ lmLog(log, NULL, &lrd, NULL);
+
+ return 0;
+Index: linux-2.6.0-test5/fs/jfs/jfs_txnmgr.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/jfs/jfs_txnmgr.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/jfs/jfs_txnmgr.c 2003-09-27 11:38:36.446987600 +0800
+@@ -1354,7 +1354,7 @@
+
+ /* initialize lrd common */
+ ip = tlck->ip;
+- lrd->aggregate = cpu_to_le32(ip->i_sb->s_bdev->bd_dev);
++ lrd->aggregate = cpu_to_le32(new_encode_dev(ip->i_sb->s_bdev->bd_dev));
+ lrd->log.redopage.fileset = cpu_to_le32(JFS_IP(ip)->fileset);
+ lrd->log.redopage.inode = cpu_to_le32(ip->i_ino);
+
+Index: linux-2.6.0-test5/fs/jfs/namei.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/jfs/namei.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/jfs/namei.c 2003-09-27 11:38:36.456986080 +0800
+@@ -1312,7 +1312,7 @@
+ tid_t tid;
+ struct tblock *tblk;
+
+- if (!old_valid_dev(rdev))
++ if (!new_valid_dev(rdev))
+ return -EINVAL;
+
+ jfs_info("jfs_mknod: %s", dentry->d_name.name);
+@@ -1344,7 +1344,7 @@
+ goto out3;
+
+ ip->i_op = &jfs_file_inode_operations;
+- jfs_ip->dev = old_encode_dev(rdev);
++ jfs_ip->dev = new_encode_dev(rdev);
+ init_special_inode(ip, ip->i_mode, rdev);
+
+ insert_inode_hash(ip);
+Index: linux-2.6.0-test5/fs/jfs/super.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/jfs/super.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/jfs/super.c 2003-09-27 11:38:36.460985472 +0800
+@@ -20,6 +20,7 @@
+ #include <linux/fs.h>
+ #include <linux/config.h>
+ #include <linux/module.h>
++#include <linux/parser.h>
+ #include <linux/completion.h>
+ #include <linux/vfs.h>
+ #include <asm/uaccess.h>
+@@ -164,59 +165,82 @@
+ kfree(sbi);
+ }
+
++enum {
++ Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize,
++ Opt_ignore, Opt_err,
++};
++
++static match_table_t tokens = {
++ {Opt_integrity, "integrity"},
++ {Opt_nointegrity, "nointegrity"},
++ {Opt_iocharset, "iocharset=%s"},
++ {Opt_resize, "resize=%u"},
++ {Opt_ignore, "noquota"},
++ {Opt_ignore, "quota"},
++ {Opt_ignore, "usrquota"},
++ {Opt_ignore, "grpquota"},
++ {Opt_err, NULL}
++};
++
+ static int parse_options(char *options, struct super_block *sb, s64 *newLVSize,
+ int *flag)
+ {
+ void *nls_map = NULL;
+- char *this_char;
+- char *value;
++ char *p;
+ struct jfs_sb_info *sbi = JFS_SBI(sb);
+
+ *newLVSize = 0;
+
+ if (!options)
+ return 1;
+- while ((this_char = strsep(&options, ",")) != NULL) {
+- if (!*this_char)
++
++ while ((p = strsep(&options, ",")) != NULL) {
++ substring_t args[MAX_OPT_ARGS];
++ int token;
++ if (!*p)
+ continue;
+- if ((value = strchr(this_char, '=')) != NULL)
+- *value++ = 0;
+- if (!strcmp(this_char, "integrity")) {
++
++ token = match_token(p, tokens, args);
++ switch (token) {
++ case Opt_integrity:
+ *flag &= ~JFS_NOINTEGRITY;
+- } else if (!strcmp(this_char, "nointegrity")) {
++ break;
++ case Opt_nointegrity:
+ *flag |= JFS_NOINTEGRITY;
+- } else if (!strcmp(this_char, "iocharset")) {
+- if (!value || !*value)
+- goto needs_arg;
++ break;
++ case Opt_ignore:
++ /* Silently ignore the quota options */
++ /* Don't do anything ;-) */
++ break;
++ case Opt_iocharset:
+ if (nls_map) /* specified iocharset twice! */
+ unload_nls(nls_map);
+- nls_map = load_nls(value);
++ nls_map = load_nls(args[0].from);
+ if (!nls_map) {
+ printk(KERN_ERR "JFS: charset not found\n");
+ goto cleanup;
+ }
+- } else if (!strcmp(this_char, "resize")) {
+- if (!value || !*value) {
++ break;
++ case Opt_resize:
++ {
++ char *resize = args[0].from;
++ if (!resize || !*resize) {
+ *newLVSize = sb->s_bdev->bd_inode->i_size >>
+ sb->s_blocksize_bits;
+ if (*newLVSize == 0)
+ printk(KERN_ERR
+- "JFS: Cannot determine volume size\n");
++ "JFS: Cannot determine volume size\n");
+ } else
+- *newLVSize = simple_strtoull(value, &value, 0);
+-
+- /* Silently ignore the quota options */
+- } else if (!strcmp(this_char, "grpquota")
+- || !strcmp(this_char, "noquota")
+- || !strcmp(this_char, "quota")
+- || !strcmp(this_char, "usrquota"))
+- /* Don't do anything ;-) */ ;
+- else {
+- printk("jfs: Unrecognized mount option %s\n",
+- this_char);
++ *newLVSize = simple_strtoull(resize, &resize, 0);
++ break;
++ }
++ default:
++ printk("jfs: Unrecognized mount option \"%s\" "
++ " or missing value\n", p);
+ goto cleanup;
+ }
+ }
++
+ if (nls_map) {
+ /* Discard old (if remount) */
+ if (sbi->nls_tab)
+@@ -224,8 +248,7 @@
+ sbi->nls_tab = nls_map;
+ }
+ return 1;
+-needs_arg:
+- printk(KERN_ERR "JFS: %s needs an argument\n", this_char);
++
+ cleanup:
+ if (nls_map)
+ unload_nls(nls_map);
+@@ -284,6 +307,9 @@
+
+ jfs_info("In jfs_read_super: s_flags=0x%lx", sb->s_flags);
+
++ if (!new_valid_dev(sb->s_bdev->bd_dev))
++ return -EOVERFLOW;
++
+ sbi = kmalloc(sizeof (struct jfs_sb_info), GFP_KERNEL);
+ if (!sbi)
+ return -ENOSPC;
+@@ -501,24 +527,21 @@
+ /*
+ * I/O completion thread (endio)
+ */
+- jfsIOthread = kernel_thread(jfsIOWait, 0,
+- CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++ jfsIOthread = kernel_thread(jfsIOWait, 0, CLONE_KERNEL);
+ if (jfsIOthread < 0) {
+ jfs_err("init_jfs_fs: fork failed w/rc = %d", jfsIOthread);
+ goto end_txmngr;
+ }
+ wait_for_completion(&jfsIOwait); /* Wait until thread starts */
+
+- jfsCommitThread = kernel_thread(jfs_lazycommit, 0,
+- CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++ jfsCommitThread = kernel_thread(jfs_lazycommit, 0, CLONE_KERNEL);
+ if (jfsCommitThread < 0) {
+ jfs_err("init_jfs_fs: fork failed w/rc = %d", jfsCommitThread);
+ goto kill_iotask;
+ }
+ wait_for_completion(&jfsIOwait); /* Wait until thread starts */
+
+- jfsSyncThread = kernel_thread(jfs_sync, 0,
+- CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++ jfsSyncThread = kernel_thread(jfs_sync, 0, CLONE_KERNEL);
+ if (jfsSyncThread < 0) {
+ jfs_err("init_jfs_fs: fork failed w/rc = %d", jfsSyncThread);
+ goto kill_committask;
+Index: linux-2.6.0-test5/fs/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/fs/Kconfig 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/Kconfig 2003-09-27 11:38:36.478982736 +0800
+@@ -761,8 +761,12 @@
+ This option will enlarge your kernel by about 67 KB. Several
+ programs depend on this, so everyone should say Y here.
+
++config PROC_KCORE
++ bool
++ default y if !ARM
++
+ config DEVFS_FS
+- bool "/dev file system support (EXPERIMENTAL)"
++ bool "/dev file system support (OBSOLETE)"
+ depends on EXPERIMENTAL
+ help
+ This is support for devfs, a virtual file system (like /proc) which
+@@ -781,6 +785,13 @@
+ ptys, you will also need to enable (and mount) the /dev/pts
+ filesystem (CONFIG_DEVPTS_FS).
+
++ Note that devfs has been obsoleted by udev,
++ <http://www.kernel.org/pub/linux/utils/kernel/hotplug/>.
++ It has been stripped down to a bare minimum and is only provided for
++ legacy installations that use its naming scheme which is
++ unfortunately different from the names normal Linux installations
++ use.
++
+ If unsure, say N.
+
+ config DEVFS_MOUNT
+@@ -864,7 +875,9 @@
+
+ config HUGETLBFS
+ bool "HugeTLB file system support"
+- depends on HUGETLB_PAGE
++
++config HUGETLB_PAGE
++ def_bool HUGETLBFS
+
+ config RAMFS
+ bool
+@@ -1324,6 +1337,31 @@
+
+ If unsure, say N.
+
++config NFS_DIRECTIO
++ bool
++ depends on NFS_FS
++ default y
++ help
++ This option enables applications to perform uncached I/O on files
++ in NFS file systems using the O_DIRECT open() flag. When O_DIRECT
++ is set for a file, its data is not cached in the system's page
++ cache. Data is moved to and from user-level application buffers
++ directly. Unlike local disk-based file systems, NFS O_DIRECT has
++ no alignment restrictions.
++
++ Unless your program is designed to use O_DIRECT properly, you are
++ much better off allowing the NFS client to manage data caching for
++ you. Misusing O_DIRECT can cause poor server performance or network
++ storms. This kernel build option defaults OFF to avoid exposing
++ system administrators unwittingly to a potentially hazardous
++ feature.
++
++ For more details on NFS O_DIRECT, see fs/nfs/direct.c.
++
++ If unsure, say N. This reduces the size of the NFS client, and
++ causes open() to return EINVAL if a file residing in NFS is
++ opened with the O_DIRECT flag.
++
+ config NFSD
+ tristate "NFS server support"
+ depends on INET
+@@ -1505,7 +1543,7 @@
+ cifs module since smbfs is currently more stable and provides
+ support for older servers. The intent of this module is to provide the
+ most advanced network file system function for CIFS compliant servers,
+- including support for dfs (heirarchical name space), secure per-user
++ including support for dfs (hierarchical name space), secure per-user
+ session establishment, safe distributed caching (oplock), optional
+ packet signing, Unicode and other internationalization improvements, and
+ optional Winbind (nsswitch) integration. This module is in an early
+@@ -1562,6 +1600,20 @@
+ whenever you want), say M here and read
+ <file:Documentation/modules.txt>. The module will be called coda.
+
++config CODA_FS_OLD_API
++ bool "Use 96-bit Coda file identifiers"
++ depends on CODA_FS
++ help
++ A new kernel-userspace API had to be introduced for Coda v6.0
++ to support larger 128-bit file identifiers as needed by the
++ new realms implementation.
++
++ However this new API is not backward compatible with older
++ clients. If you really need to run the old Coda userspace
++ cache manager then say Y.
++
++ For most cases you probably want to say N.
++
+ config INTERMEZZO_FS
+ tristate "InterMezzo file system support (replicating fs) (EXPERIMENTAL)"
+ depends on INET && EXPERIMENTAL
+Index: linux-2.6.0-test5/fs/libfs.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/libfs.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/libfs.c 2003-09-27 11:38:36.482982128 +0800
+@@ -429,22 +429,3 @@
+ spin_unlock(&pin_fs_lock);
+ mntput(mnt);
+ }
+-
+-/* acceptable for old filesystems */
+-int old_valid_dev(dev_t dev)
+-{
+- return MAJOR(dev) < 256 && MINOR(dev) < 256;
+-}
+-EXPORT_SYMBOL(old_valid_dev);
+-
+-u16 old_encode_dev(dev_t dev)
+-{
+- return (MAJOR(dev) << 8) | MINOR(dev);
+-}
+-EXPORT_SYMBOL(old_encode_dev);
+-
+-dev_t old_decode_dev(u16 val)
+-{
+- return MKDEV((val >> 8) & 255, val & 255);
+-}
+-EXPORT_SYMBOL(old_decode_dev);
+Index: linux-2.6.0-test5/fs/locks.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/locks.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/locks.c 2003-09-27 11:38:36.496980000 +0800
+@@ -221,7 +221,7 @@
+ static inline int flock_translate_cmd(int cmd) {
+ if (cmd & LOCK_MAND)
+ return cmd & (LOCK_MAND | LOCK_RW);
+- switch (cmd &~ LOCK_NB) {
++ switch (cmd) {
+ case LOCK_SH:
+ return F_RDLCK;
+ case LOCK_EX:
+@@ -233,8 +233,8 @@
+ }
+
+ /* Fill in a file_lock structure with an appropriate FLOCK lock. */
+-static int flock_make_lock(struct file *filp,
+- struct file_lock **lock, unsigned int cmd)
++static int flock_make_lock(struct file *filp, struct file_lock **lock,
++ unsigned int cmd)
+ {
+ struct file_lock *fl;
+ int type = flock_translate_cmd(cmd);
+@@ -247,7 +247,7 @@
+
+ fl->fl_file = filp;
+ fl->fl_pid = current->tgid;
+- fl->fl_flags = (cmd & LOCK_NB) ? FL_FLOCK : FL_FLOCK | FL_SLEEP;
++ fl->fl_flags = FL_FLOCK;
+ fl->fl_type = type;
+ fl->fl_end = OFFSET_MAX;
+
+@@ -1265,9 +1265,8 @@
+ locks_free_lock(fl);
+ goto out_unlock;
+ }
+- fl->fl_next = *before;
+- *before = fl;
+- list_add(&fl->fl_link, &file_lock_list);
++
++ locks_insert_lock(before, fl);
+
+ error = f_setown(filp, current->tgid, 1);
+ out_unlock:
+@@ -1298,6 +1297,7 @@
+ {
+ struct file *filp;
+ struct file_lock *lock;
++ int can_sleep, unlock;
+ int error;
+
+ error = -EBADF;
+@@ -1305,12 +1305,18 @@
+ if (!filp)
+ goto out;
+
+- if ((cmd != LOCK_UN) && !(cmd & LOCK_MAND) && !(filp->f_mode & 3))
++ can_sleep = !(cmd & LOCK_NB);
++ cmd &= ~LOCK_NB;
++ unlock = (cmd == LOCK_UN);
++
++ if (!unlock && !(cmd & LOCK_MAND) && !(filp->f_mode & 3))
+ goto out_putf;
+
+ error = flock_make_lock(filp, &lock, cmd);
+ if (error)
+ goto out_putf;
++ if (can_sleep)
++ lock->fl_flags |= FL_SLEEP;
+
+ error = security_file_lock(filp, cmd);
+ if (error)
+@@ -1318,7 +1324,7 @@
+
+ for (;;) {
+ error = flock_lock_file(filp, lock);
+- if ((error != -EAGAIN) || (cmd & LOCK_NB))
++ if ((error != -EAGAIN) || !can_sleep)
+ break;
+ error = wait_event_interruptible(lock->fl_wait, !lock->fl_next);
+ if (!error)
+@@ -1329,7 +1335,7 @@
+ }
+
+ out_free:
+- if (error) {
++ if (list_empty(&lock->fl_link)) {
+ locks_free_lock(lock);
+ }
+
+Index: linux-2.6.0-test5/fs/namei.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/namei.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/namei.c 2003-09-27 11:38:36.511977720 +0800
+@@ -207,10 +207,14 @@
+ {
+ int retval;
+ int submask;
++ umode_t mode = inode->i_mode;
+
+ /* Ordinary permission routines do not understand MAY_APPEND. */
+ submask = mask & ~MAY_APPEND;
+
++ if (nd && (mask & MAY_WRITE) && MNT_IS_RDONLY(nd->mnt) &&
++ (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
++ return -EROFS;
+ if (inode->i_op && inode->i_op->permission)
+ retval = inode->i_op->permission(inode, submask, nd);
+ else
+@@ -1053,6 +1057,24 @@
+ return permission(dir,MAY_WRITE | MAY_EXEC, nd);
+ }
+
++static inline int mnt_may_create(struct vfsmount *mnt, struct inode *dir, struct dentry *child) {
++ if (child->d_inode)
++ return -EEXIST;
++ if (IS_DEADDIR(dir))
++ return -ENOENT;
++ if (mnt->mnt_flags & MNT_RDONLY)
++ return -EROFS;
++ return 0;
++}
++
++static inline int mnt_may_unlink(struct vfsmount *mnt, struct inode *dir, struct dentry *child) {
++ if (!child->d_inode)
++ return -ENOENT;
++ if (mnt->mnt_flags & MNT_RDONLY)
++ return -EROFS;
++ return 0;
++}
++
+ /*
+ * Special case: O_CREAT|O_EXCL implies O_NOFOLLOW for security
+ * reasons.
+@@ -1174,7 +1196,8 @@
+ return -EACCES;
+
+ flag &= ~O_TRUNC;
+- } else if (IS_RDONLY(inode) && (flag & FMODE_WRITE))
++ } else if ((IS_RDONLY(inode) || MNT_IS_RDONLY(nd->mnt)) &&
++ (flag & FMODE_WRITE))
+ return -EROFS;
+ /*
+ * An append-only file must be opened in append mode for writing.
+@@ -1400,23 +1423,28 @@
+ struct dentry *lookup_create(struct nameidata *nd, int is_dir)
+ {
+ struct dentry *dentry;
++ int error;
+
+ down(&nd->dentry->d_inode->i_sem);
+- dentry = ERR_PTR(-EEXIST);
++ error = -EEXIST;
+ if (nd->last_type != LAST_NORM)
+- goto fail;
++ goto out;
+ nd->flags &= ~LOOKUP_PARENT;
+ dentry = lookup_hash(&nd->last, nd->dentry);
+ if (IS_ERR(dentry))
++ goto ret;
++ error = mnt_may_create(nd->mnt, nd->dentry->d_inode, dentry);
++ if (error)
+ goto fail;
++ error = -ENOENT;
+ if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
+- goto enoent;
++ goto fail;
++ret:
+ return dentry;
+-enoent:
+- dput(dentry);
+- dentry = ERR_PTR(-ENOENT);
+ fail:
+- return dentry;
++ dput(dentry);
++out:
++ return ERR_PTR(error);
+ }
+
+ int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
+@@ -1445,7 +1473,7 @@
+ return error;
+ }
+
+-asmlinkage long sys_mknod(const char __user * filename, int mode, dev_t dev)
++asmlinkage long sys_mknod(const char __user * filename, int mode, unsigned dev)
+ {
+ int error = 0;
+ char * tmp;
+@@ -1471,8 +1499,12 @@
+ case 0: case S_IFREG:
+ error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
+ break;
+- case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK:
+- error = vfs_mknod(nd.dentry->d_inode,dentry,mode,dev);
++ case S_IFCHR: case S_IFBLK:
++ error = vfs_mknod(nd.dentry->d_inode,dentry,mode,
++ new_decode_dev(dev));
++ break;
++ case S_IFIFO: case S_IFSOCK:
++ error = vfs_mknod(nd.dentry->d_inode,dentry,mode,0);
+ break;
+ case S_IFDIR:
+ error = -EPERM;
+@@ -1641,7 +1673,11 @@
+ dentry = lookup_hash(&nd.last, nd.dentry);
+ error = PTR_ERR(dentry);
+ if (!IS_ERR(dentry)) {
++ error = mnt_may_unlink(nd.mnt, nd.dentry->d_inode, dentry);
++ if (error)
++ goto exit2;
+ error = vfs_rmdir(nd.dentry->d_inode, dentry);
++ exit2:
+ dput(dentry);
+ }
+ up(&nd.dentry->d_inode->i_sem);
+@@ -1713,6 +1749,9 @@
+ /* Why not before? Because we want correct error value */
+ if (nd.last.name[nd.last.len])
+ goto slashes;
++ error = mnt_may_unlink(nd.mnt, nd.dentry->d_inode, dentry);
++ if (error)
++ goto exit2;
+ inode = dentry->d_inode;
+ if (inode)
+ atomic_inc(&inode->i_count);
+@@ -2077,6 +2116,9 @@
+ error = -EINVAL;
+ if (old_dentry == trap)
+ goto exit4;
++ error = -EROFS;
++ if (MNT_IS_RDONLY(newnd.mnt))
++ goto exit4;
+ new_dentry = lookup_hash(&newnd.last, new_dir);
+ error = PTR_ERR(new_dentry);
+ if (IS_ERR(new_dentry))
+Index: linux-2.6.0-test5/fs/namespace.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/namespace.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/namespace.c 2003-09-27 11:38:36.519976504 +0800
+@@ -225,7 +225,8 @@
+ seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
+ seq_putc(m, ' ');
+ mangle(m, mnt->mnt_sb->s_type->name);
+- seq_puts(m, mnt->mnt_sb->s_flags & MS_RDONLY ? " ro" : " rw");
++ seq_puts(m, (MNT_IS_RDONLY(mnt) ||
++ (mnt->mnt_sb->s_flags & MS_RDONLY)) ? " ro" : " rw");
+ for (fs_infop = fs_info; fs_infop->flag; fs_infop++) {
+ if (mnt->mnt_sb->s_flags & fs_infop->flag)
+ seq_puts(m, fs_infop->str);
+@@ -516,11 +517,13 @@
+ /*
+ * do loopback mount.
+ */
+-static int do_loopback(struct nameidata *nd, char *old_name, int recurse)
++static int do_loopback(struct nameidata *nd, char *old_name, unsigned long flags, int mnt_flags)
+ {
+ struct nameidata old_nd;
+ struct vfsmount *mnt = NULL;
++ int recurse = flags & MS_REC;
+ int err = mount_is_safe(nd);
++
+ if (err)
+ return err;
+ if (!old_name || !*old_name)
+@@ -547,6 +550,7 @@
+ spin_unlock(&vfsmount_lock);
+ } else
+ mntput(mnt);
++ mnt->mnt_flags = mnt_flags;
+ }
+
+ up_write(¤t->namespace->sem);
+@@ -750,6 +754,8 @@
+ return -EINVAL;
+
+ /* Separate the per-mountpoint flags */
++ if (flags & MS_RDONLY)
++ mnt_flags |= MNT_RDONLY;
+ if (flags & MS_NOSUID)
+ mnt_flags |= MNT_NOSUID;
+ if (flags & MS_NODEV)
+@@ -771,7 +777,7 @@
+ retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
+ data_page);
+ else if (flags & MS_BIND)
+- retval = do_loopback(&nd, dev_name, flags & MS_REC);
++ retval = do_loopback(&nd, dev_name, flags, mnt_flags);
+ else if (flags & MS_MOVE)
+ retval = do_move_mount(&nd, dev_name);
+ else
+Index: linux-2.6.0-test5/fs/ncpfs/dir.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/ncpfs/dir.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/ncpfs/dir.c 2003-09-27 11:38:36.527975288 +0800
+@@ -929,10 +929,10 @@
+ finfo.access = opmode;
+ if (ncp_is_nfs_extras(server, finfo.volume)) {
+ finfo.i.nfs.mode = mode;
+- finfo.i.nfs.rdev = old_encode_dev(rdev);
++ finfo.i.nfs.rdev = new_encode_dev(rdev);
+ if (ncp_modify_nfs_info(server, finfo.volume,
+ finfo.i.dirEntNum,
+- mode, old_encode_dev(rdev)) != 0)
++ mode, new_encode_dev(rdev)) != 0)
+ goto out;
+ }
+
+@@ -1170,7 +1170,7 @@
+ static int ncp_mknod(struct inode * dir, struct dentry *dentry,
+ int mode, dev_t rdev)
+ {
+- if (!old_valid_dev(rdev))
++ if (!new_valid_dev(rdev))
+ return -EINVAL;
+ if (ncp_is_nfs_extras(NCP_SERVER(dir), NCP_FINFO(dir)->volNumber)) {
+ DPRINTK(KERN_DEBUG "ncp_mknod: mode = 0%o\n", mode);
+Index: linux-2.6.0-test5/fs/ncpfs/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/ncpfs/inode.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/ncpfs/inode.c 2003-09-27 11:38:36.534974224 +0800
+@@ -262,7 +262,7 @@
+ #ifdef CONFIG_NCPFS_NFS_NS
+ } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
+ init_special_inode(inode, inode->i_mode,
+- old_decode_dev(info->i.nfs.rdev));
++ new_decode_dev(info->i.nfs.rdev));
+ #endif
+ #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
+ } else if (S_ISLNK(inode->i_mode)) {
+Index: linux-2.6.0-test5/fs/nfsd/export.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nfsd/export.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nfsd/export.c 2003-09-27 11:38:36.542973008 +0800
+@@ -55,11 +55,16 @@
+ #define EXPKEY_HASHMASK (EXPKEY_HASHMAX -1)
+ static struct cache_head *expkey_table[EXPKEY_HASHMAX];
+
++static inline int key_len(int type)
++{
++ return type == 0 ? 8 : type == 1 ? 4 : 12;
++}
++
+ static inline int svc_expkey_hash(struct svc_expkey *item)
+ {
+ int hash = item->ek_fsidtype;
+ char * cp = (char*)item->ek_fsid;
+- int len = (item->ek_fsidtype==0)?8:4;
++ int len = key_len(item->ek_fsidtype);
+
+ hash ^= hash_mem(cp, len, EXPKEY_HASHBITS);
+ hash ^= hash_ptr(item->ek_client, EXPKEY_HASHBITS);
+@@ -89,7 +94,7 @@
+ qword_add(bpp, blen, ek->ek_client->name);
+ snprintf(type, 5, "%d", ek->ek_fsidtype);
+ qword_add(bpp, blen, type);
+- qword_addhex(bpp, blen, (char*)ek->ek_fsid, ek->ek_fsidtype==0?8:4);
++ qword_addhex(bpp, blen, (char*)ek->ek_fsid, key_len(ek->ek_fsidtype));
+ (*bpp)[-1] = '\n';
+ }
+
+@@ -130,12 +135,12 @@
+ if (*ep)
+ goto out;
+ dprintk("found fsidtype %d\n", fsidtype);
+- if (fsidtype > 1)
++ if (fsidtype > 2)
+ goto out;
+ if ((len=qword_get(&mesg, buf, PAGE_SIZE)) <= 0)
+ goto out;
+ dprintk("found fsid length %d\n", len);
+- if (len != ((fsidtype==0)?8:4))
++ if (len != key_len(fsidtype))
+ goto out;
+
+ /* OK, we seem to have a valid key */
+@@ -206,8 +211,10 @@
+ ek = container_of(h, struct svc_expkey, h);
+ seq_printf(m, "%s %d 0x%08x", ek->ek_client->name,
+ ek->ek_fsidtype, ek->ek_fsid[0]);
+- if (ek->ek_fsid == 0)
+- seq_printf(m, "%08x", ek->ek_fsid[0]);
++ if (ek->ek_fsidtype != 1)
++ seq_printf(m, "%08x", ek->ek_fsid[1]);
++ if (ek->ek_fsidtype == 2)
++ seq_printf(m, "%08x", ek->ek_fsid[2]);
+ if (test_bit(CACHE_VALID, &h->flags) &&
+ !test_bit(CACHE_NEGATIVE, &h->flags)) {
+ seq_printf(m, " ");
+@@ -230,13 +237,8 @@
+ static inline int svc_expkey_match (struct svc_expkey *a, struct svc_expkey *b)
+ {
+ if (a->ek_fsidtype != b->ek_fsidtype ||
+- a->ek_client != b->ek_client)
+- return 0;
+- if (a->ek_fsid[0] != b->ek_fsid[0])
+- return 0;
+- if (a->ek_fsidtype == 1)
+- return 1;
+- if (a->ek_fsid[1] != b->ek_fsid[1])
++ a->ek_client != b->ek_client ||
++ memcmp(a->ek_fsid, b->ek_fsid, key_len(a->ek_fsidtype)) != 0)
+ return 0;
+ return 1;
+ }
+@@ -248,6 +250,7 @@
+ new->ek_fsidtype = item->ek_fsidtype;
+ new->ek_fsid[0] = item->ek_fsid[0];
+ new->ek_fsid[1] = item->ek_fsid[1];
++ new->ek_fsid[2] = item->ek_fsid[2];
+ }
+
+ static inline void svc_expkey_update(struct svc_expkey *new, struct svc_expkey *item)
+@@ -502,8 +505,7 @@
+
+ key.ek_client = clp;
+ key.ek_fsidtype = fsid_type;
+- key.ek_fsid[0] = fsidv[0];
+- key.ek_fsid[1] = fsidv[1];
++ memcpy(key.ek_fsid, fsidv, key_len(fsid_type));
+
+ ek = svc_expkey_lookup(&key, 0);
+ if (ek != NULL)
+@@ -519,8 +521,7 @@
+
+ key.ek_client = clp;
+ key.ek_fsidtype = fsid_type;
+- key.ek_fsid[0] = fsidv[0];
+- key.ek_fsid[1] = fsidv[1];
++ memcpy(key.ek_fsid, fsidv, key_len(fsid_type));
+ key.ek_export = exp;
+ key.h.expiry_time = NEVER;
+ key.h.flags = 0;
+@@ -539,10 +540,14 @@
+ static inline struct svc_expkey *
+ exp_get_key(svc_client *clp, dev_t dev, ino_t ino)
+ {
+- u32 fsidv[2];
++ u32 fsidv[3];
+
+- mk_fsid_v0(fsidv, dev, ino);
+- return exp_find_key(clp, 0, fsidv, NULL);
++ if (old_valid_dev(dev)) {
++ mk_fsid_v0(fsidv, dev, ino);
++ return exp_find_key(clp, 0, fsidv, NULL);
++ }
++ mk_fsid_v2(fsidv, dev, ino);
++ return exp_find_key(clp, 2, fsidv, NULL);
+ }
+
+ /*
+@@ -671,11 +676,15 @@
+ static int exp_hash(struct auth_domain *clp, struct svc_export *exp)
+ {
+ u32 fsid[2];
+- struct inode *inode;
++ struct inode *inode = exp->ex_dentry->d_inode;
++ dev_t dev = inode->i_sb->s_dev;
+
+- inode = exp->ex_dentry->d_inode;
+- mk_fsid_v0(fsid, inode->i_sb->s_dev, inode->i_ino);
+- return exp_set_key(clp, 0, fsid, exp);
++ if (old_valid_dev(dev)) {
++ mk_fsid_v0(fsid, dev, inode->i_ino);
++ return exp_set_key(clp, 0, fsid, exp);
++ }
++ mk_fsid_v2(fsid, dev, inode->i_ino);
++ return exp_set_key(clp, 2, fsid, exp);
+ }
+
+ static void exp_unhash(struct svc_export *exp)
+@@ -819,32 +828,42 @@
+ exp_unexport(struct nfsctl_export *nxp)
+ {
+ struct auth_domain *dom;
++ svc_export *exp;
++ struct nameidata nd;
+ int err;
+
+ /* Consistency check */
+- if (!exp_verify_string(nxp->ex_client, NFSCLNT_IDMAX))
++ if (!exp_verify_string(nxp->ex_path, NFS_MAXPATHLEN) ||
++ !exp_verify_string(nxp->ex_client, NFSCLNT_IDMAX))
+ return -EINVAL;
+
+ exp_writelock();
+
+ err = -EINVAL;
+ dom = auth_domain_find(nxp->ex_client);
+-
+- if (dom) {
+- struct svc_expkey *key = exp_get_key(dom, nxp->ex_dev, nxp->ex_ino);
+- if (key && !IS_ERR(key) && key->ek_export) {
+- exp_do_unexport(key->ek_export);
+- err = 0;
+- expkey_put(&key->h, &svc_expkey_cache);
+- } else
+- dprintk("nfsd: no export %x/%lx for %s\n",
+- (unsigned)nxp->ex_dev,
+- (unsigned long) nxp->ex_ino, nxp->ex_client);
+- auth_domain_put(dom);
+- cache_flush();
+- } else
++ if (!dom) {
+ dprintk("nfsd: unexport couldn't find %s\n", nxp->ex_client);
++ goto out_unlock;
++ }
++
++ err = path_lookup(nxp->ex_path, 0, &nd);
++ if (err)
++ goto out_domain;
+
++ err = -EINVAL;
++ exp = exp_get_by_name(dom, nd.mnt, nd.dentry, NULL);
++ path_release(&nd);
++ if (!exp)
++ goto out_domain;
++
++ exp_do_unexport(exp);
++ exp_put(exp);
++ err = 0;
++
++out_domain:
++ auth_domain_put(dom);
++ cache_flush();
++out_unlock:
+ exp_writeunlock();
+ return err;
+ }
+Index: linux-2.6.0-test5/fs/nfs/dir.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nfs/dir.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nfs/dir.c 2003-09-27 11:38:36.551971640 +0800
+@@ -859,7 +859,7 @@
+ dfprintk(VFS, "NFS: mknod(%s/%ld, %s\n", dir->i_sb->s_id,
+ dir->i_ino, dentry->d_name.name);
+
+- if (!old_valid_dev(rdev))
++ if (!new_valid_dev(rdev))
+ return -EINVAL;
+
+ attr.ia_mode = mode;
+Index: linux-2.6.0-test5/fs/nfs/direct.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nfs/direct.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nfs/direct.c 2003-09-27 11:38:36.555971032 +0800
+@@ -1,7 +1,7 @@
+ /*
+ * linux/fs/nfs/direct.c
+ *
+- * Copyright (C) 2001 by Chuck Lever <cel@netapp.com>
++ * Copyright (C) 2003 by Chuck Lever <cel@netapp.com>
+ *
+ * High-performance uncached I/O for the Linux NFS client
+ *
+@@ -26,19 +26,23 @@
+ * also supports uncaching whole NFS partitions with "-o forcedirectio,"
+ * an undocumented mount option.
+ *
+- * Designed by Jeff Kimmel, Chuck Lever, and Trond Myklebust.
++ * Designed by Jeff Kimmel, Chuck Lever, and Trond Myklebust, with
++ * help from Andrew Morton.
+ *
+ * 18 Dec 2001 Initial implementation for 2.4 --cel
+ * 08 Jul 2002 Version for 2.4.19, with bug fixes --trondmy
+- * 24 Sep 2002 Rewrite to use asynchronous RPCs, port to 2.5 --cel
++ * 08 Jun 2003 Port to 2.5 APIs --cel
+ *
+ */
+
+ #include <linux/config.h>
++#include <linux/errno.h>
+ #include <linux/sched.h>
+ #include <linux/kernel.h>
++#include <linux/smp_lock.h>
+ #include <linux/file.h>
+-#include <linux/errno.h>
++#include <linux/pagemap.h>
++
+ #include <linux/nfs_fs.h>
+ #include <linux/nfs_page.h>
+ #include <linux/sunrpc/clnt.h>
+@@ -46,35 +50,41 @@
+ #include <asm/system.h>
+ #include <asm/uaccess.h>
+
+-#define NFSDBG_FACILITY (NFSDBG_PAGECACHE | NFSDBG_VFS)
++#define NFSDBG_FACILITY NFSDBG_VFS
+ #define VERF_SIZE (2 * sizeof(__u32))
++#define MAX_DIRECTIO_SIZE (4096UL << PAGE_SHIFT)
+
+
+ /**
+- * nfs_get_user_pages - find and set up page representing user buffer
+- * addr: user-space address of target buffer
+- * size: total size in bytes of target buffer
+- * @pages: returned array of page struct pointers underlying target buffer
+- * write: whether or not buffer is target of a write operation
++ * nfs_get_user_pages - find and set up pages underlying user's buffer
++ * rw: direction (read or write)
++ * user_addr: starting address of this segment of user's buffer
++ * count: size of this segment
++ * @pages: returned array of page struct pointers underlying user's buffer
+ */
+ static inline int
+-nfs_get_user_pages(unsigned long addr, size_t size,
+- struct page ***pages, int rw)
++nfs_get_user_pages(int rw, unsigned long user_addr, size_t size,
++ struct page ***pages)
+ {
+ int result = -ENOMEM;
+- unsigned page_count = (unsigned) size >> PAGE_SHIFT;
+- unsigned array_size = (page_count * sizeof(struct page *)) + 2U;
++ unsigned long page_count;
++ size_t array_size;
++
++ /* set an arbitrary limit to prevent arithmetic overflow */
++ if (size > MAX_DIRECTIO_SIZE)
++ return -EFBIG;
+
+- *pages = (struct page **) kmalloc(array_size, GFP_KERNEL);
++ page_count = (user_addr + size + PAGE_SIZE - 1) >> PAGE_SHIFT;
++ page_count -= user_addr >> PAGE_SHIFT;
++
++ array_size = (page_count * sizeof(struct page *));
++ *pages = kmalloc(array_size, GFP_KERNEL);
+ if (*pages) {
+ down_read(¤t->mm->mmap_sem);
+- result = get_user_pages(current, current->mm, addr,
+- page_count, (rw == WRITE), 0,
++ result = get_user_pages(current, current->mm, user_addr,
++ page_count, (rw == READ), 0,
+ *pages, NULL);
+ up_read(¤t->mm->mmap_sem);
+- if (result < 0)
+- printk(KERN_ERR "%s: get_user_pages result %d\n",
+- __FUNCTION__, result);
+ }
+ return result;
+ }
+@@ -84,176 +94,349 @@
+ * @pages: array of page struct pointers underlying target buffer
+ */
+ static inline void
+-nfs_free_user_pages(struct page **pages, unsigned count)
++nfs_free_user_pages(struct page **pages)
+ {
+- unsigned page = 0;
++ kfree(pages);
++}
+
+- while (count--)
+- page_cache_release(pages[page++]);
++/**
++ * nfs_direct_read_seg - Read in one iov segment. Generate separate
++ * read RPCs for each "rsize" bytes.
++ * @inode: target inode
++ * @cred: user's credential
++ * user_addr: starting address of this segment of user's buffer
++ * count: size of this segment
++ * file_offset: offset in file to begin the operation
++ * @pages: array of addresses of page structs defining user's buffer
++ * nr_pages: size of pages array
++ */
++static int
++nfs_direct_read_seg(struct inode *inode, struct rpc_cred *cred,
++ unsigned long user_addr, size_t count, loff_t file_offset,
++ struct page **pages, int nr_pages)
++{
++ const unsigned int rsize = NFS_SERVER(inode)->rsize;
++ int tot_bytes = 0;
++ int curpage = 0;
++ struct nfs_read_data rdata = {
++ .flags = 0,
++ .cred = cred,
++ .inode = inode,
++ .args = {
++ .fh = NFS_FH(inode),
++ },
++ .res = {
++ .fattr = &rdata.fattr,
++ },
++ };
++
++ do {
++ int request, result;
++
++ request = count;
++ if (count > rsize)
++ request = rsize;
++ rdata.args.count = request,
++ rdata.args.pgbase = user_addr & ~PAGE_MASK;
++ rdata.args.offset = file_offset;
++ rdata.args.pages = &pages[curpage];
++
++ dprintk("NFS: direct read: c=%u o=%Ld ua=%lu, pb=%u, cp=%u\n",
++ rdata.args.count, (long long) rdata.args.offset,
++ user_addr, rdata.args.pgbase, curpage);
++
++ lock_kernel();
++ result = NFS_PROTO(inode)->read(&rdata);
++ unlock_kernel();
++
++ if (result < 0) {
++ if (result == -EISDIR)
++ result = -EINVAL;
++ return result;
++ }
+
+- kfree(pages);
++ tot_bytes += result;
++ count -= result;
++ file_offset += result;
++ user_addr += result;
++
++ if (rdata.res.eof)
++ break;
++
++ curpage += (rdata.args.pgbase + result) >> PAGE_SHIFT;
++ } while (count);
++
++ /* XXX: should we zero the rest of the user's buffer if we
++ * hit eof? */
++
++ return tot_bytes;
+ }
+
+ /**
+- * nfs_iov2pagelist - convert an array of iovecs to a list of page requests
+- * @inode: inode of target file
+- * @cred: credentials of user who requested I/O
++ * nfs_direct_read - For each iov segment, map the user's buffer
++ * then generate read RPCs.
++ * @inode: target inode
++ * @cred: user's credential
+ * @iov: array of vectors that define I/O buffer
+- * offset: where in file to begin the read
++ * file_offset: offset in file to begin the operation
+ * nr_segs: size of iovec array
+- * @requests: append new page requests to this list head
++ *
++ * generic_file_direct_IO has already pushed out any non-direct
++ * writes so that this read will see them when we read from the
++ * server.
+ */
+ static int
+-nfs_iov2pagelist(int rw, const struct inode *inode,
+- const struct rpc_cred *cred,
+- const struct iovec *iov, loff_t offset,
+- unsigned long nr_segs, struct list_head *requests)
++nfs_direct_read(struct inode *inode, struct rpc_cred *cred,
++ const struct iovec *iov, loff_t file_offset,
++ unsigned long nr_segs)
+ {
+- unsigned seg;
+ int tot_bytes = 0;
+- struct page **pages;
++ unsigned long seg = 0;
+
+- /* for each iovec in the array... */
+- for (seg = 0; seg < nr_segs; seg++) {
+- const unsigned long user_addr =
+- (unsigned long) iov[seg].iov_base;
+- size_t bytes = iov[seg].iov_len;
+- unsigned int pg_offset = (user_addr & ~PAGE_MASK);
+- int page_count, page = 0;
+-
+- page_count = nfs_get_user_pages(user_addr, bytes, &pages, rw);
+- if (page_count < 0) {
+- nfs_release_list(requests);
+- return page_count;
++ while ((seg < nr_segs) && (tot_bytes >= 0)) {
++ int result, page_count;
++ struct page **pages;
++ const struct iovec *vec = &iov[seg++];
++ unsigned long user_addr = (unsigned long) vec->iov_base;
++ size_t size = vec->iov_len;
++
++ page_count = nfs_get_user_pages(READ, user_addr, size, &pages);
++ if (page_count < 0) {
++ nfs_free_user_pages(pages);
++ return page_count;
++ }
++
++ result = nfs_direct_read_seg(inode, cred, user_addr, size,
++ file_offset, pages, page_count);
++ if (result < 0)
++ tot_bytes = result;
++ else {
++ tot_bytes += result;
++ file_offset += result;
+ }
+
+- /* ...build as many page requests as required */
+- while (bytes > 0) {
+- struct nfs_page *new;
+- const unsigned int pg_bytes = (bytes > PAGE_SIZE) ?
+- PAGE_SIZE : bytes;
+-
+- new = nfs_create_request((struct rpc_cred *) cred,
+- (struct inode *) inode,
+- pages[page],
+- pg_offset, pg_bytes);
+- if (IS_ERR(new)) {
+- nfs_free_user_pages(pages, page_count);
+- nfs_release_list(requests);
+- return PTR_ERR(new);
+- }
+- new->wb_index = offset;
+- nfs_list_add_request(new, requests);
+-
+- /* after the first page */
+- pg_offset = 0;
+- offset += PAGE_SIZE;
+- tot_bytes += pg_bytes;
+- bytes -= pg_bytes;
+- page++;
++ nfs_free_user_pages(pages);
++ }
++
++ return tot_bytes;
++}
++
++/**
++ * nfs_direct_write_seg - Write out one iov segment. Generate separate
++ * write RPCs for each "wsize" bytes, then commit.
++ * @inode: target inode
++ * @cred: user's credential
++ * user_addr: starting address of this segment of user's buffer
++ * count: size of this segment
++ * file_offset: offset in file to begin the operation
++ * @pages: array of addresses of page structs defining user's buffer
++ * nr_pages: size of pages array
++ */
++static int
++nfs_direct_write_seg(struct inode *inode, struct rpc_cred *cred,
++ unsigned long user_addr, size_t count, loff_t file_offset,
++ struct page **pages, int nr_pages)
++{
++ const unsigned int wsize = NFS_SERVER(inode)->wsize;
++ loff_t save_offset = file_offset;
++ size_t save_count = count;
++ int need_commit = 0;
++ int tot_bytes = 0;
++ int curpage = 0;
++ struct nfs_writeverf first_verf;
++ struct nfs_write_data wdata = {
++ .cred = cred,
++ .inode = inode,
++ .args = {
++ .fh = NFS_FH(inode),
++ },
++ .res = {
++ .fattr = &wdata.fattr,
++ .verf = &wdata.verf,
++ },
++ };
++
++ wdata.args.stable = NFS_UNSTABLE;
++ if (IS_SYNC(inode) || NFS_PROTO(inode)->version == 2 || count <= wsize)
++ wdata.args.stable = NFS_FILE_SYNC;
++
++retry:
++ do {
++ int request, result;
++
++ request = count;
++ if (count > wsize)
++ request = wsize;
++ wdata.args.count = request,
++ wdata.args.pgbase = user_addr & ~PAGE_MASK;
++ wdata.args.offset = file_offset;
++ wdata.args.pages = &pages[curpage];
++
++ dprintk("NFS: direct write: c=%u o=%Ld ua=%lu, pb=%u, cp=%u\n",
++ wdata.args.count, (long long) wdata.args.offset,
++ user_addr, wdata.args.pgbase, curpage);
++
++ lock_kernel();
++ result = NFS_PROTO(inode)->write(&wdata);
++ unlock_kernel();
++
++ if (result < 0)
++ return result;
++
++ if (!tot_bytes)
++ memcpy(&first_verf.verifier, &wdata.verf.verifier,
++ VERF_SIZE);
++ if (wdata.verf.committed != NFS_FILE_SYNC) {
++ need_commit = 1;
++ if (memcmp(&first_verf.verifier,
++ &wdata.verf.verifier, VERF_SIZE))
++ goto sync_retry;
+ }
+
+- /* don't release pages here -- I/O completion will do that */
+- nfs_free_user_pages(pages, 0);
++ tot_bytes += result;
++ count -= result;
++ file_offset += result;
++ user_addr += result;
++
++ curpage += (wdata.args.pgbase + result) >> PAGE_SHIFT;
++ } while (count);
++
++ /*
++ * Commit data written so far, even in the event of an error
++ */
++ if (need_commit) {
++ int result;
++
++ wdata.args.count = tot_bytes;
++ wdata.args.offset = save_offset;
++
++ lock_kernel();
++ result = NFS_PROTO(inode)->commit(&wdata);
++ unlock_kernel();
++
++ if (result < 0)
++ goto sync_retry;
++ if (memcmp(&first_verf.verifier, &wdata.verf.verifier,
++ VERF_SIZE))
++ goto sync_retry;
+ }
+
+ return tot_bytes;
++
++sync_retry:
++ wdata.args.stable = NFS_FILE_SYNC;
++ file_offset = save_offset;
++ count = save_count;
++ goto retry;
+ }
+
+ /**
+- * do_nfs_direct_IO - Read or write data without caching
+- * @inode: inode of target file
+- * @cred: credentials of user who requested I/O
++ * nfs_direct_write - For each iov segment, map the user's buffer
++ * then generate write and commit RPCs.
++ * @inode: target inode
++ * @cred: user's credential
+ * @iov: array of vectors that define I/O buffer
+- * offset: where in file to begin the read
++ * file_offset: offset in file to begin the operation
+ * nr_segs: size of iovec array
+ *
+- * Break the passed-in iovec into a series of page-sized or smaller
+- * requests, where each page is mapped for direct user-land I/O.
+- *
+- * For each of these pages, create an NFS page request and
+- * append it to an automatic list of page requests.
+- *
+- * When all page requests have been queued, start the I/O on the
+- * whole list. The underlying routines coalesce the pages on the
+- * list into a bunch of asynchronous "r/wsize" network requests.
+- *
+- * I/O completion automatically unmaps and releases the pages.
++ * Upon return, generic_file_direct_IO invalidates any cached pages
++ * that non-direct readers might access, so they will pick up these
++ * writes immediately.
+ */
+ static int
+-do_nfs_direct_IO(int rw, const struct inode *inode,
+- const struct rpc_cred *cred, const struct iovec *iov,
+- loff_t offset, unsigned long nr_segs)
++nfs_direct_write(struct inode *inode, struct rpc_cred *cred,
++ const struct iovec *iov, loff_t file_offset,
++ unsigned long nr_segs)
+ {
+- LIST_HEAD(requests);
+- int result, tot_bytes;
++ int tot_bytes = 0;
++ unsigned long seg = 0;
+
+- result = nfs_iov2pagelist(rw, inode, cred, iov, offset, nr_segs,
+- &requests);
+- if (result < 0)
+- return result;
+- tot_bytes = result;
++ while ((seg < nr_segs) && (tot_bytes >= 0)) {
++ int result, page_count;
++ struct page **pages;
++ const struct iovec *vec = &iov[seg++];
++ unsigned long user_addr = (unsigned long) vec->iov_base;
++ size_t size = vec->iov_len;
++
++ page_count = nfs_get_user_pages(WRITE, user_addr, size, &pages);
++ if (page_count < 0) {
++ nfs_free_user_pages(pages);
++ return page_count;
++ }
+
+- switch (rw) {
+- case READ:
+- if (IS_SYNC(inode) || (NFS_SERVER(inode)->rsize < PAGE_SIZE)) {
+- result = nfs_direct_read_sync(inode, cred, iov, offset, nr_segs);
+- break;
++ result = nfs_direct_write_seg(inode, cred, user_addr, size,
++ file_offset, pages, page_count);
++ if (result < 0)
++ tot_bytes = result;
++ else {
++ tot_bytes += result;
++ file_offset += result;
+ }
+- result = nfs_pagein_list(&requests, NFS_SERVER(inode)->rpages);
+- nfs_wait_for_reads(&requests);
+- break;
+- case WRITE:
+- if (IS_SYNC(inode) || (NFS_SERVER(inode)->wsize < PAGE_SIZE))
+- result = nfs_direct_write_sync(inode, cred, iov, offset, nr_segs);
+- else
+- result = nfs_flush_list(&requests,
+- NFS_SERVER(inode)->wpages, FLUSH_WAIT);
+
+- /* invalidate cache so non-direct readers pick up changes */
+- invalidate_inode_pages((struct inode *) inode);
+- break;
+- default:
+- result = -EINVAL;
+- break;
++ nfs_free_user_pages(pages);
+ }
+
+- if (result < 0)
+- return result;
+ return tot_bytes;
+ }
+
+ /**
+ * nfs_direct_IO - NFS address space operation for direct I/O
+ * rw: direction (read or write)
+- * @file: file struct of target file
++ * @iocb: target I/O control block
+ * @iov: array of vectors that define I/O buffer
+- * offset: offset in file to begin the operation
++ * file_offset: offset in file to begin the operation
+ * nr_segs: size of iovec array
+ *
++ * Usually a file system implements direct I/O by calling out to
++ * blockdev_direct_IO. The NFS client doesn't have a backing block
++ * device, so we do everything by hand instead.
++ *
+ * The inode's i_sem is no longer held by the VFS layer before it calls
+ * this function to do a write.
+ */
+ int
+ nfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
+- loff_t offset, unsigned long nr_segs)
++ loff_t file_offset, unsigned long nr_segs)
+ {
+- /* None of this works yet, so prevent it from compiling. */
+-#if 0
+- int result;
++ int result = -EINVAL;
++ struct file *file = iocb->ki_filp;
+ struct dentry *dentry = file->f_dentry;
+- const struct inode *inode = dentry->d_inode->i_mapping->host;
+- const struct rpc_cred *cred = nfs_file_cred(file);
+-#endif
+-
+- dfprintk(VFS, "NFS: direct_IO(%s) (%s/%s) off/no(%Lu/%lu)\n",
+- ((rw == READ) ? "READ" : "WRITE"),
+- dentry->d_parent->d_name.name,
+- dentry->d_name.name, offset, nr_segs);
++ struct inode *inode = dentry->d_inode;
++ struct rpc_cred *cred;
++
++ /*
++ * No support for async yet
++ */
++ if (!is_sync_kiocb(iocb))
++ goto out;
++
++ cred = get_rpccred(nfs_file_cred(file));
++ if (!cred)
++ cred = get_rpccred(NFS_I(inode)->mm_cred);
++
++ switch (rw) {
++ case READ:
++ dprintk("NFS: direct_IO(read) (%s) off/no(%Lu/%lu)\n",
++ dentry->d_name.name, file_offset, nr_segs);
++
++ result = nfs_direct_read(inode, cred, iov,
++ file_offset, nr_segs);
++ break;
++ case WRITE:
++ dprintk("NFS: direct_IO(write) (%s) off/no(%Lu/%lu)\n",
++ dentry->d_name.name, file_offset, nr_segs);
+
+- result = do_nfs_direct_IO(rw, inode, cred, iov, offset, nr_segs);
++ result = nfs_direct_write(inode, cred, iov,
++ file_offset, nr_segs);
++ break;
++ default:
++ break;
++ }
+
+- dfprintk(VFS, "NFS: direct_IO result = %d\n", result);
++ if (cred)
++ put_rpccred(cred);
+
++out:
++ dprintk("NFS: direct_IO result=%d\n", result);
+ return result;
+ }
+Index: linux-2.6.0-test5/fs/nfsd/nfs3xdr.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nfsd/nfs3xdr.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nfsd/nfs3xdr.c 2003-09-27 11:38:36.561970120 +0800
+@@ -186,12 +186,10 @@
+ p = xdr_encode_hyper(p, ((u64)stat.blocks) << 9);
+ *p++ = htonl((u32) MAJOR(stat.rdev));
+ *p++ = htonl((u32) MINOR(stat.rdev));
+- if (rqstp->rq_reffh->fh_version == 1
+- && rqstp->rq_reffh->fh_fsid_type == 1
+- && (fhp->fh_export->ex_flags & NFSEXP_FSID))
++ if (is_fsid(fhp, rqstp->rq_reffh))
+ p = xdr_encode_hyper(p, (u64) fhp->fh_export->ex_fsid);
+ else
+- p = xdr_encode_hyper(p, (u64) stat.dev);
++ p = xdr_encode_hyper(p, (u64) huge_encode_dev(stat.dev));
+ p = xdr_encode_hyper(p, (u64) stat.ino);
+ p = encode_time3(p, &stat.atime);
+ lease_get_mtime(dentry->d_inode, &time);
+@@ -222,12 +220,10 @@
+ p = xdr_encode_hyper(p, ((u64)fhp->fh_post_blocks) << 9);
+ *p++ = fhp->fh_post_rdev[0];
+ *p++ = fhp->fh_post_rdev[1];
+- if (rqstp->rq_reffh->fh_version == 1
+- && rqstp->rq_reffh->fh_fsid_type == 1
+- && (fhp->fh_export->ex_flags & NFSEXP_FSID))
++ if (is_fsid(fhp, rqstp->rq_reffh))
+ p = xdr_encode_hyper(p, (u64) fhp->fh_export->ex_fsid);
+ else
+- p = xdr_encode_hyper(p, (u64) inode->i_sb->s_dev);
++ p = xdr_encode_hyper(p, (u64)huge_encode_dev(inode->i_sb->s_dev));
+ p = xdr_encode_hyper(p, (u64) inode->i_ino);
+ p = encode_time3(p, &fhp->fh_post_atime);
+ p = encode_time3(p, &fhp->fh_post_mtime);
+Index: linux-2.6.0-test5/fs/nfsd/nfsfh.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nfsd/nfsfh.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nfsd/nfsfh.c 2003-09-27 11:38:36.565969512 +0800
+@@ -125,6 +125,9 @@
+ case 1:
+ len = 1;
+ break;
++ case 2:
++ len = 3;
++ break;
+ default:
+ goto out;
+ }
+@@ -137,7 +140,7 @@
+ if (fh->fh_size != NFS_FHSIZE)
+ goto out;
+ /* assume old filehandle format */
+- xdev = u32_to_dev_t(fh->ofh_xdev);
++ xdev = old_decode_dev(fh->ofh_xdev);
+ xino = u32_to_ino_t(fh->ofh_xino);
+ mk_fsid_v0(tfh, xdev, xino);
+ exp = exp_find(rqstp->rq_client, 0, tfh, &rqstp->rq_chandle);
+@@ -329,12 +332,21 @@
+ parent->d_name.name, dentry->d_name.name,
+ (inode ? inode->i_ino : 0));
+
+- if (ref_fh) {
++ /* for large devnums rules are simple */
++ if (!old_valid_dev(ex_dev)) {
++ ref_fh_version = 1;
++ if (exp->ex_flags & NFSEXP_FSID)
++ ref_fh_fsid_type = 1;
++ else
++ ref_fh_fsid_type = 2;
++ } else if (ref_fh) {
+ ref_fh_version = ref_fh->fh_handle.fh_version;
+ ref_fh_fsid_type = ref_fh->fh_handle.fh_fsid_type;
+- if (ref_fh == fhp)
+- fh_put(ref_fh);
++ if (!(exp->ex_flags & NFSEXP_FSID) || ref_fh_fsid_type == 2)
++ ref_fh_fsid_type = 0;
+ }
++ if (ref_fh == fhp)
++ fh_put(ref_fh);
+
+ if (fhp->fh_locked || fhp->fh_dentry) {
+ printk(KERN_ERR "fh_compose: fh %s/%s not initialized!\n",
+@@ -353,7 +365,7 @@
+ memset(&fhp->fh_handle.fh_base, 0, NFS_FHSIZE);
+ fhp->fh_handle.fh_size = NFS_FHSIZE;
+ fhp->fh_handle.ofh_dcookie = 0xfeebbaca;
+- fhp->fh_handle.ofh_dev = htonl((MAJOR(ex_dev)<<16)| MINOR(ex_dev));
++ fhp->fh_handle.ofh_dev = old_encode_dev(ex_dev);
+ fhp->fh_handle.ofh_xdev = fhp->fh_handle.ofh_dev;
+ fhp->fh_handle.ofh_xino = ino_t_to_u32(exp->ex_dentry->d_inode->i_ino);
+ fhp->fh_handle.ofh_dirino = ino_t_to_u32(parent_ino(dentry));
+@@ -363,19 +375,33 @@
+ fhp->fh_handle.fh_version = 1;
+ fhp->fh_handle.fh_auth_type = 0;
+ datap = fhp->fh_handle.fh_auth+0;
+- if ((exp->ex_flags & NFSEXP_FSID) &&
+- (ref_fh_fsid_type == 1)) {
+- fhp->fh_handle.fh_fsid_type = 1;
+- /* fsid_type 1 == 4 bytes filesystem id */
+- mk_fsid_v1(datap, exp->ex_fsid);
+- datap += 1;
+- fhp->fh_handle.fh_size = 2*4;
+- } else {
+- fhp->fh_handle.fh_fsid_type = 0;
+- /* fsid_type 0 == 2byte major, 2byte minor, 4byte inode */
+- mk_fsid_v0(datap, ex_dev, exp->ex_dentry->d_inode->i_ino);
+- datap += 2;
+- fhp->fh_handle.fh_size = 3*4;
++ fhp->fh_handle.fh_fsid_type = ref_fh_fsid_type;
++ switch (ref_fh_fsid_type) {
++ case 1:
++ /* fsid_type 1 == 4 bytes filesystem id */
++ mk_fsid_v1(datap, exp->ex_fsid);
++ datap += 1;
++ fhp->fh_handle.fh_size = 2*4;
++ break;
++ case 2:
++ /*
++ * fsid_type 2:
++ * 4byte major, 4byte minor, 4byte inode
++ */
++ mk_fsid_v2(datap, ex_dev,
++ exp->ex_dentry->d_inode->i_ino);
++ datap += 3;
++ fhp->fh_handle.fh_size = 4*4;
++ break;
++ default:
++ /*
++ * fsid_type 0:
++ * 2byte major, 2byte minor, 4byte inode
++ */
++ mk_fsid_v0(datap, ex_dev,
++ exp->ex_dentry->d_inode->i_ino);
++ datap += 2;
++ fhp->fh_handle.fh_size = 3*4;
+ }
+ if (inode) {
+ int size = fhp->fh_maxsize/4 - 3;
+Index: linux-2.6.0-test5/fs/nfsd/nfsproc.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nfsd/nfsproc.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nfsd/nfsproc.c 2003-09-27 11:38:36.570968752 +0800
+@@ -184,7 +184,7 @@
+ struct inode *inode;
+ struct dentry *dchild;
+ int nfserr, type, mode;
+- dev_t rdev = 0;
++ dev_t rdev = 0, wanted = new_decode_dev(attr->ia_size);
+
+ dprintk("nfsd: CREATE %s %.*s\n",
+ SVCFH_fmt(dirfhp), argp->len, argp->name);
+@@ -230,7 +230,7 @@
+ inode = newfhp->fh_dentry->d_inode;
+
+ /* Unfudge the mode bits */
+- if (attr->ia_valid & ATTR_MODE) {
++ if (attr->ia_valid & ATTR_MODE) {
+ type = attr->ia_mode & S_IFMT;
+ mode = attr->ia_mode & ~S_IFMT;
+ if (!type) {
+@@ -242,7 +242,7 @@
+ case S_IFCHR:
+ case S_IFBLK:
+ /* reserve rdev for later checking */
+- attr->ia_size = inode->i_rdev;
++ rdev = inode->i_rdev;
+ attr->ia_valid |= ATTR_SIZE;
+
+ /* FALLTHROUGH */
+@@ -277,22 +277,16 @@
+ */
+ if (type != S_IFREG) {
+ int is_borc = 0;
+- u32 size = attr->ia_size;
+-
+- /* may need to change when we widen dev_t */
+- rdev = old_decode_dev(size);
+ if (type != S_IFBLK && type != S_IFCHR) {
+ rdev = 0;
+ } else if (type == S_IFCHR && !(attr->ia_valid & ATTR_SIZE)) {
+ /* If you think you've seen the worst, grok this. */
+ type = S_IFIFO;
+- } else if (size != rdev) {
+- /* dev got truncated because of 16bit Linux dev_t */
+- nfserr = nfserr_inval;
+- goto out_unlock;
+ } else {
+ /* Okay, char or block special */
+ is_borc = 1;
++ if (!rdev)
++ rdev = wanted;
+ }
+
+ /* we've used the SIZE information, so discard it */
+@@ -300,11 +294,10 @@
+
+ /* Make sure the type and device matches */
+ nfserr = nfserr_exist;
+- if (inode && (type != (inode->i_mode & S_IFMT) ||
+- (is_borc && inode->i_rdev != rdev)))
++ if (inode && type != (inode->i_mode & S_IFMT))
+ goto out_unlock;
+ }
+-
++
+ nfserr = 0;
+ if (!inode) {
+ /* File doesn't exist. Create it and set attrs */
+Index: linux-2.6.0-test5/fs/nfsd/nfsxdr.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nfsd/nfsxdr.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nfsd/nfsxdr.c 2003-09-27 11:38:36.573968296 +0800
+@@ -159,16 +159,14 @@
+ }
+ *p++ = htonl((u32) stat.blksize);
+ if (S_ISCHR(type) || S_ISBLK(type))
+- *p++ = htonl((u32) stat.rdev);
++ *p++ = htonl(new_encode_dev(stat.rdev));
+ else
+ *p++ = htonl(0xffffffff);
+ *p++ = htonl((u32) stat.blocks);
+- if (rqstp->rq_reffh->fh_version == 1
+- && rqstp->rq_reffh->fh_fsid_type == 1
+- && (fhp->fh_export->ex_flags & NFSEXP_FSID))
++ if (is_fsid(fhp, rqstp->rq_reffh))
+ *p++ = htonl((u32) fhp->fh_export->ex_fsid);
+ else
+- *p++ = htonl((u32) stat.dev);
++ *p++ = htonl(new_encode_dev(stat.dev));
+ *p++ = htonl((u32) stat.ino);
+ *p++ = htonl((u32) stat.atime.tv_sec);
+ *p++ = htonl(stat.atime.tv_nsec ? stat.atime.tv_nsec / 1000 : 0);
+Index: linux-2.6.0-test5/fs/nfs/nfs2xdr.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nfs/nfs2xdr.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nfs/nfs2xdr.c 2003-09-27 11:38:36.578967536 +0800
+@@ -122,7 +122,7 @@
+ p = xdr_decode_time(p, &fattr->mtime);
+ p = xdr_decode_time(p, &fattr->ctime);
+ fattr->valid |= NFS_ATTR_FATTR;
+- fattr->rdev = old_decode_dev(rdev);
++ fattr->rdev = new_decode_dev(rdev);
+ if (fattr->type == NFCHR && rdev == NFS2_FIFO_DEV) {
+ fattr->type = NFFIFO;
+ fattr->mode = (fattr->mode & ~S_IFMT) | S_IFIFO;
+Index: linux-2.6.0-test5/fs/nfs/nfs3proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nfs/nfs3proc.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nfs/nfs3proc.c 2003-09-27 11:38:36.585966472 +0800
+@@ -225,81 +225,74 @@
+ }
+
+ static int
+-nfs3_proc_read(struct inode *inode, struct rpc_cred *cred,
+- struct nfs_fattr *fattr, int flags,
+- unsigned int base, unsigned int count, struct page *page,
+- int *eofp)
+-{
+- u64 offset = page_offset(page) + base;
+- struct nfs_readargs arg = {
+- .fh = NFS_FH(inode),
+- .offset = offset,
+- .count = count,
+- .pgbase = base,
+- .pages = &page
+- };
+- struct nfs_readres res = {
+- .fattr = fattr,
+- .count = count,
+- };
++nfs3_proc_read(struct nfs_read_data *rdata)
++{
++ int flags = rdata->flags;
++ struct inode * inode = rdata->inode;
++ struct nfs_fattr * fattr = rdata->res.fattr;
+ struct rpc_message msg = {
+ .rpc_proc = &nfs3_procedures[NFS3PROC_READ],
+- .rpc_argp = &arg,
+- .rpc_resp = &res,
+- .rpc_cred = cred
++ .rpc_argp = &rdata->args,
++ .rpc_resp = &rdata->res,
++ .rpc_cred = rdata->cred,
+ };
+ int status;
+
+- dprintk("NFS call read %d @ %Ld\n", count, (long long)offset);
++ dprintk("NFS call read %d @ %Ld\n", rdata->args.count,
++ (long long) rdata->args.offset);
+ fattr->valid = 0;
+ status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
+ if (status >= 0)
+ nfs_refresh_inode(inode, fattr);
+ dprintk("NFS reply read: %d\n", status);
+- *eofp = res.eof;
+ return status;
+ }
+
+ static int
+-nfs3_proc_write(struct inode *inode, struct rpc_cred *cred,
+- struct nfs_fattr *fattr, int flags,
+- unsigned int base, unsigned int count,
+- struct page *page, struct nfs_writeverf *verf)
++nfs3_proc_write(struct nfs_write_data *wdata)
+ {
+- u64 offset = page_offset(page) + base;
+- struct nfs_writeargs arg = {
+- .fh = NFS_FH(inode),
+- .offset = offset,
+- .count = count,
+- .stable = NFS_FILE_SYNC,
+- .pgbase = base,
+- .pages = &page
+- };
+- struct nfs_writeres res = {
+- .fattr = fattr,
+- .verf = verf,
+- };
++ int rpcflags = wdata->flags;
++ struct inode * inode = wdata->inode;
++ struct nfs_fattr * fattr = wdata->res.fattr;
+ struct rpc_message msg = {
+ .rpc_proc = &nfs3_procedures[NFS3PROC_WRITE],
+- .rpc_argp = &arg,
+- .rpc_resp = &res,
+- .rpc_cred = cred
++ .rpc_argp = &wdata->args,
++ .rpc_resp = &wdata->res,
++ .rpc_cred = wdata->cred,
+ };
+- int status, rpcflags = 0;
++ int status;
+
+- dprintk("NFS call write %d @ %Ld\n", count, (long long)offset);
++ dprintk("NFS call write %d @ %Ld\n", wdata->args.count,
++ (long long) wdata->args.offset);
+ fattr->valid = 0;
+- if (flags & NFS_RW_SWAP)
+- rpcflags |= NFS_RPC_SWAPFLAGS;
+- arg.stable = (flags & NFS_RW_SYNC) ? NFS_FILE_SYNC : NFS_UNSTABLE;
+-
+ status = rpc_call_sync(NFS_CLIENT(inode), &msg, rpcflags);
+-
+ if (status >= 0)
+ nfs3_write_refresh_inode(inode, fattr);
++ dprintk("NFS reply write: %d\n", status);
++ return status < 0? status : wdata->res.count;
++}
+
+- dprintk("NFS reply read: %d\n", status);
+- return status < 0? status : res.count;
++static int
++nfs3_proc_commit(struct nfs_write_data *cdata)
++{
++ struct inode * inode = cdata->inode;
++ struct nfs_fattr * fattr = cdata->res.fattr;
++ struct rpc_message msg = {
++ .rpc_proc = &nfs3_procedures[NFS3PROC_COMMIT],
++ .rpc_argp = &cdata->args,
++ .rpc_resp = &cdata->res,
++ .rpc_cred = cdata->cred,
++ };
++ int status;
++
++ dprintk("NFS call commit %d @ %Ld\n", cdata->args.count,
++ (long long) cdata->args.offset);
++ fattr->valid = 0;
++ status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
++ if (status >= 0)
++ nfs3_write_refresh_inode(inode, fattr);
++ dprintk("NFS reply commit: %d\n", status);
++ return status;
+ }
+
+ /*
+@@ -651,7 +644,8 @@
+ default: return -EINVAL;
+ }
+
+- dprintk("NFS call mknod %s %x\n", name->name, (unsigned)rdev);
++ dprintk("NFS call mknod %s %u:%u\n", name->name,
++ MAJOR(rdev), MINOR(rdev));
+ dir_attr.valid = 0;
+ fattr->valid = 0;
+ status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKNOD, &arg, &res, 0);
+@@ -862,6 +856,7 @@
+ .readlink = nfs3_proc_readlink,
+ .read = nfs3_proc_read,
+ .write = nfs3_proc_write,
++ .commit = nfs3_proc_commit,
+ .create = nfs3_proc_create,
+ .remove = nfs3_proc_remove,
+ .unlink_setup = nfs3_proc_unlink_setup,
+Index: linux-2.6.0-test5/fs/nfs/nfs3xdr.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nfs/nfs3xdr.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nfs/nfs3xdr.c 2003-09-27 11:38:36.591965560 +0800
+@@ -163,6 +163,8 @@
+ major = ntohl(*p++);
+ minor = ntohl(*p++);
+ fattr->rdev = MKDEV(major, minor);
++ if (MAJOR(fattr->rdev) != major || MINOR(fattr->rdev) != minor)
++ fattr->rdev = 0;
+
+ p = xdr_decode_hyper(p, &fattr->fsid_u.nfs3);
+ p = xdr_decode_hyper(p, &fattr->fileid);
+Index: linux-2.6.0-test5/fs/nfs/nfs4proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nfs/nfs4proc.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nfs/nfs4proc.c 2003-09-27 11:38:36.606963280 +0800
+@@ -1012,45 +1012,36 @@
+ }
+
+ static int
+-nfs4_proc_read(struct inode *inode, struct rpc_cred *cred,
+- struct nfs_fattr *fattr, int flags,
+- unsigned int base, unsigned int count,
+- struct page *page, int *eofp)
++nfs4_proc_read(struct nfs_read_data *rdata)
+ {
++ int flags = rdata->flags;
++ struct inode *inode = rdata->inode;
++ struct nfs_fattr *fattr = rdata->res.fattr;
++ nfs4_stateid *stateid = &rdata->args.stateid;
+ struct nfs_server *server = NFS_SERVER(inode);
+ struct nfs4_shareowner *sp;
+- uint64_t offset = page_offset(page) + base;
+- struct nfs_readargs arg = {
+- .fh = NFS_FH(inode),
+- .offset = offset,
+- .count = count,
+- .pgbase = base,
+- .pages = &page,
+- };
+- struct nfs_readres res = {
+- .fattr = fattr,
+- .count = count,
+- };
+ struct rpc_message msg = {
+ .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ],
+- .rpc_argp = &arg,
+- .rpc_resp = &res,
+- .rpc_cred = cred,
++ .rpc_argp = &rdata->args,
++ .rpc_resp = &rdata->res,
++ .rpc_cred = rdata->cred,
+ };
+ unsigned long timestamp = jiffies;
+ int status;
+
+- dprintk("NFS call read %d @ %Ld\n", count, (long long)offset);
++ dprintk("NFS call read %d @ %Ld\n", rdata->args.count,
++ (long long) rdata->args.offset);
++
+ /*
+- * Try first to use O_RDONLY, then O_RDWR stateid.
+- */
++ * Try first to use O_RDONLY, then O_RDWR stateid.
++ */
+ sp = nfs4_get_inode_share(inode, O_RDONLY);
+ if (!sp)
+ sp = nfs4_get_inode_share(inode, O_RDWR);
+ if (sp)
+- memcpy(arg.stateid,sp->so_stateid, sizeof(nfs4_stateid));
++ memcpy(stateid, sp->so_stateid, sizeof(nfs4_stateid));
+ else
+- memcpy(arg.stateid, zero_stateid, sizeof(nfs4_stateid));
++ memcpy(stateid, zero_stateid, sizeof(nfs4_stateid));
+
+ fattr->valid = 0;
+ status = rpc_call_sync(server->client, &msg, flags);
+@@ -1061,56 +1052,82 @@
+ nfs_zap_caches(inode);
+ }
+ dprintk("NFS reply read: %d\n", status);
+- *eofp = res.eof;
+ return status;
+ }
+
+ static int
+-nfs4_proc_write(struct inode *inode, struct rpc_cred *cred,
+- struct nfs_fattr *fattr, int flags,
+- unsigned int base, unsigned int count,
+- struct page *page, struct nfs_writeverf *verf)
++nfs4_proc_write(struct nfs_write_data *wdata)
+ {
++ int rpcflags = wdata->flags;
++ struct inode *inode = wdata->inode;
++ struct nfs_fattr *fattr = wdata->res.fattr;
++ nfs4_stateid *stateid = &wdata->args.stateid;
+ struct nfs_server *server = NFS_SERVER(inode);
+- struct nfs4_shareowner *sp;
+- uint64_t offset = page_offset(page) + base;
+- struct nfs_writeargs arg = {
+- .fh = NFS_FH(inode),
+- .offset = offset,
+- .count = count,
+- .stable = (flags & NFS_RW_SYNC) ? NFS_FILE_SYNC : NFS_UNSTABLE,
+- .pgbase = base,
+- .pages = &page,
+- };
+- struct nfs_writeres res = {
+- .fattr = fattr,
+- .count = count,
+- .verf = verf,
+- };
++ struct nfs4_shareowner *sp;
+ struct rpc_message msg = {
+ .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE],
+- .rpc_argp = &arg,
+- .rpc_resp = &res,
+- .rpc_cred = cred,
++ .rpc_argp = &wdata->args,
++ .rpc_resp = &wdata->res,
++ .rpc_cred = wdata->cred,
++ };
++ int status;
++
++ dprintk("NFS call write %d @ %Ld\n", wdata->args.count,
++ (long long) wdata->args.offset);
++
++ /*
++ * Try first to use O_WRONLY, then O_RDWR stateid.
++ */
++ sp = nfs4_get_inode_share(inode, O_WRONLY);
++ if (!sp)
++ sp = nfs4_get_inode_share(inode, O_RDWR);
++
++ if (sp)
++ memcpy(stateid, sp->so_stateid, sizeof(nfs4_stateid));
++ else
++ memcpy(stateid, zero_stateid, sizeof(nfs4_stateid));
++
++ fattr->valid = 0;
++ status = rpc_call_sync(server->client, &msg, rpcflags);
++ dprintk("NFS reply write: %d\n", status);
++ return status;
++}
++
++static int
++nfs4_proc_commit(struct nfs_write_data *cdata)
++{
++ struct inode *inode = cdata->inode;
++ struct nfs_fattr *fattr = cdata->res.fattr;
++ nfs4_stateid *stateid = &cdata->args.stateid;
++ struct nfs_server *server = NFS_SERVER(inode);
++ struct nfs4_shareowner *sp;
++ struct rpc_message msg = {
++ .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT],
++ .rpc_argp = &cdata->args,
++ .rpc_resp = &cdata->res,
++ .rpc_cred = cdata->cred,
+ };
+- int rpcflags = (flags & NFS_RW_SWAP) ? NFS_RPC_SWAPFLAGS : 0;
++ int status;
+
+- dprintk("NFS call write %d @ %Ld\n", count, (long long)offset);
++ dprintk("NFS call commit %d @ %Ld\n", cdata->args.count,
++ (long long) cdata->args.offset);
+
+ /*
+- * Try first to use O_WRONLY, then O_RDWR stateid.
+- */
++ * Try first to use O_WRONLY, then O_RDWR stateid.
++ */
+ sp = nfs4_get_inode_share(inode, O_WRONLY);
+ if (!sp)
+ sp = nfs4_get_inode_share(inode, O_RDWR);
+
+ if (sp)
+- memcpy(arg.stateid,sp->so_stateid, sizeof(nfs4_stateid));
++ memcpy(stateid, sp->so_stateid, sizeof(nfs4_stateid));
+ else
+- memcpy(arg.stateid, zero_stateid, sizeof(nfs4_stateid));
++ memcpy(stateid, zero_stateid, sizeof(nfs4_stateid));
+
+ fattr->valid = 0;
+- return rpc_call_sync(server->client, &msg, rpcflags);
++ status = rpc_call_sync(server->client, &msg, 0);
++ dprintk("NFS reply commit: %d\n", status);
++ return status;
+ }
+
+ /*
+@@ -1752,7 +1769,7 @@
+ .readlink = nfs4_proc_readlink,
+ .read = nfs4_proc_read,
+ .write = nfs4_proc_write,
+- .commit = NULL,
++ .commit = nfs4_proc_commit,
+ .create = nfs4_proc_create,
+ .remove = nfs4_proc_remove,
+ .unlink_setup = nfs4_proc_unlink_setup,
+Index: linux-2.6.0-test5/fs/nfs/nfs4xdr.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nfs/nfs4xdr.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nfs/nfs4xdr.c 2003-09-27 11:38:36.622960848 +0800
+@@ -1503,7 +1503,9 @@
+ READ32(major);
+ READ32(minor);
+ nfp->rdev = MKDEV(major, minor);
+- dprintk("read_attrs: rdev=0x%x\n", nfp->rdev);
++ if (MAJOR(nfp->rdev) != major || MINOR(nfp->rdev) != minor)
++ nfp->rdev = 0;
++ dprintk("read_attrs: rdev=%u:%u\n", major, minor);
+ }
+ if (bmval1 & FATTR4_WORD1_SPACE_AVAIL) {
+ READ_BUF(8);
+Index: linux-2.6.0-test5/fs/nfs/pagelist.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nfs/pagelist.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nfs/pagelist.c 2003-09-27 11:38:36.625960392 +0800
+@@ -154,26 +154,6 @@
+ }
+
+ /**
+- * nfs_release_list - cleanly dispose of an unattached list of page requests
+- * @list: list of doomed page requests
+- */
+-void
+-nfs_release_list(struct list_head *list)
+-{
+- while (!list_empty(list)) {
+- struct nfs_page *req = nfs_list_entry(list);
+-
+- nfs_list_remove_request(req);
+-
+- page_cache_release(req->wb_page);
+-
+- /* Release struct file or cached credential */
+- nfs_clear_request(req);
+- nfs_page_free(req);
+- }
+-}
+-
+-/**
+ * nfs_list_add_request - Insert a request into a sorted list
+ * @req: request
+ * @head: head of list into which to insert the request.
+@@ -222,37 +202,6 @@
+ }
+
+ /**
+- * nfs_wait_for_reads - wait for outstanding requests to complete
+- * @head: list of page requests to wait for
+- */
+-int
+-nfs_wait_for_reads(struct list_head *head)
+-{
+- struct list_head *p = head->next;
+- unsigned int res = 0;
+-
+- while (p != head) {
+- struct nfs_page *req = nfs_list_entry(p);
+- int error;
+-
+- if (!NFS_WBACK_BUSY(req))
+- continue;
+-
+- req->wb_count++;
+- error = nfs_wait_on_request(req);
+- if (error < 0)
+- return error;
+- nfs_list_remove_request(req);
+- nfs_clear_request(req);
+- nfs_page_free(req);
+-
+- p = head->next;
+- res++;
+- }
+- return res;
+-}
+-
+-/**
+ * nfs_coalesce_requests - Split coalesced requests out from a list.
+ * @head: source list
+ * @dst: destination list
+Index: linux-2.6.0-test5/fs/nfs/proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nfs/proc.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nfs/proc.c 2003-09-27 11:38:36.631959480 +0800
+@@ -149,82 +149,62 @@
+ }
+
+ static int
+-nfs_proc_read(struct inode *inode, struct rpc_cred *cred,
+- struct nfs_fattr *fattr, int flags,
+- unsigned int base, unsigned int count, struct page *page,
+- int *eofp)
+-{
+- u64 offset = page_offset(page) + base;
+- struct nfs_readargs arg = {
+- .fh = NFS_FH(inode),
+- .offset = offset,
+- .count = count,
+- .pgbase = base,
+- .pages = &page
+- };
+- struct nfs_readres res = {
+- .fattr = fattr,
+- .count = count
+- };
++nfs_proc_read(struct nfs_read_data *rdata)
++{
++ int flags = rdata->flags;
++ struct inode * inode = rdata->inode;
++ struct nfs_fattr * fattr = rdata->res.fattr;
+ struct rpc_message msg = {
+ .rpc_proc = &nfs_procedures[NFSPROC_READ],
+- .rpc_argp = &arg,
+- .rpc_resp = &res,
+- .rpc_cred = cred
++ .rpc_argp = &rdata->args,
++ .rpc_resp = &rdata->res,
++ .rpc_cred = rdata->cred,
+ };
+ int status;
+
+- dprintk("NFS call read %d @ %Ld\n", count, (long long)offset);
++ dprintk("NFS call read %d @ %Ld\n", rdata->args.count,
++ (long long) rdata->args.offset);
+ fattr->valid = 0;
+ status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
+-
+- if (status >= 0)
++ if (status >= 0) {
+ nfs_refresh_inode(inode, fattr);
++ /* NFSv2 reads don't return an eof flag, so we make
++ * up a value here. XDR has already set eof to 0. */
++ if (status < rdata->args.count)
++ rdata->res.eof = 1;
++ }
+ dprintk("NFS reply read: %d\n", status);
+- *eofp = res.eof;
+ return status;
+ }
+
+ static int
+-nfs_proc_write(struct inode *inode, struct rpc_cred *cred,
+- struct nfs_fattr *fattr, int how,
+- unsigned int base, unsigned int count,
+- struct page *page, struct nfs_writeverf *verf)
++nfs_proc_write(struct nfs_write_data *wdata)
+ {
+- u64 offset = page_offset(page) + base;
+- struct nfs_writeargs arg = {
+- .fh = NFS_FH(inode),
+- .offset = offset,
+- .count = count,
+- .stable = NFS_FILE_SYNC,
+- .pgbase = base,
+- .pages = &page
+- };
+- struct nfs_writeres res = {
+- .fattr = fattr,
+- .verf = verf,
+- .count = count
+- };
++ int flags = wdata->flags;
++ struct inode * inode = wdata->inode;
++ struct nfs_fattr * fattr = wdata->res.fattr;
+ struct rpc_message msg = {
+ .rpc_proc = &nfs_procedures[NFSPROC_WRITE],
+- .rpc_argp = &arg,
+- .rpc_resp = &res,
+- .rpc_cred = cred
++ .rpc_argp = &wdata->args,
++ .rpc_resp = &wdata->res,
++ .rpc_cred = wdata->cred
+ };
+- int status, flags = 0;
++ int status;
+
+- dprintk("NFS call write %d @ %Ld\n", count, (long long)offset);
++ dprintk("NFS call write %d @ %Ld\n", wdata->args.count,
++ (long long) wdata->args.offset);
+ fattr->valid = 0;
+- if (how & NFS_RW_SWAP)
+- flags |= NFS_RPC_SWAPFLAGS;
+ status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
+-
+- if (status >= 0)
++ if (status >= 0) {
+ nfs_write_refresh_inode(inode, fattr);
+-
++ /* NFSv2 writes don't return a byte count or write
++ * verifier, so we make up values here. Note that
++ * v2 writes are always NFS_FILE_SYNC writes. */
++ wdata->res.count = wdata->args.count;
++ wdata->verf.committed = NFS_FILE_SYNC;
++ }
+ dprintk("NFS reply write: %d\n", status);
+- verf->committed = NFS_FILE_SYNC; /* NFSv2 always syncs data */
+- return status < 0? status : count;
++ return status < 0? status : wdata->res.count;
+ }
+
+ static int
+@@ -277,7 +257,7 @@
+ sattr->ia_valid &= ~ATTR_SIZE;
+ } else if (S_ISCHR(mode) || S_ISBLK(mode)) {
+ sattr->ia_valid |= ATTR_SIZE;
+- sattr->ia_size = rdev; /* get out your barf bag */
++ sattr->ia_size = new_encode_dev(rdev);/* get out your barf bag */
+ }
+
+ fattr->valid = 0;
+Index: linux-2.6.0-test5/fs/nfs/read.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nfs/read.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nfs/read.c 2003-09-27 11:38:36.634959024 +0800
+@@ -69,19 +69,28 @@
+ static int
+ nfs_readpage_sync(struct file *file, struct inode *inode, struct page *page)
+ {
+- struct rpc_cred *cred = NULL;
+- struct nfs_fattr fattr;
+- unsigned int offset = 0;
+ unsigned int rsize = NFS_SERVER(inode)->rsize;
+ unsigned int count = PAGE_CACHE_SIZE;
+ int result;
+- int flags = IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0;
+- int eof;
++ struct nfs_read_data rdata = {
++ .flags = (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0),
++ .cred = NULL,
++ .inode = inode,
++ .args = {
++ .fh = NFS_FH(inode),
++ .pages = &page,
++ .pgbase = 0UL,
++ .count = rsize,
++ },
++ .res = {
++ .fattr = &rdata.fattr,
++ }
++ };
+
+ dprintk("NFS: nfs_readpage_sync(%p)\n", page);
+
+ if (file)
+- cred = nfs_file_cred(file);
++ rdata.cred = nfs_file_cred(file);
+
+ /*
+ * This works now because the socket layer never tries to DMA
+@@ -89,17 +98,19 @@
+ */
+ do {
+ if (count < rsize)
+- rsize = count;
++ rdata.args.count = count;
++ rdata.res.count = rdata.args.count;
++ rdata.args.offset = page_offset(page) + rdata.args.pgbase;
+
+ dprintk("NFS: nfs_proc_read(%s, (%s/%Ld), %Lu, %u)\n",
+ NFS_SERVER(inode)->hostname,
+ inode->i_sb->s_id,
+ (long long)NFS_FILEID(inode),
+- (unsigned long long)offset, rsize);
++ (unsigned long long)rdata.args.pgbase,
++ rdata.args.count);
+
+ lock_kernel();
+- result = NFS_PROTO(inode)->read(inode, cred, &fattr, flags,
+- offset, rsize, page, &eof);
++ result = NFS_PROTO(inode)->read(&rdata);
+ unlock_kernel();
+
+ /*
+@@ -111,14 +122,15 @@
+ result = -EINVAL;
+ goto io_error;
+ }
+- count -= result;
+- offset += result;
+- if (result < rsize) /* NFSv2ism */
++ count -= result;
++ rdata.args.pgbase += result;
++
++ if (rdata.res.eof)
+ break;
+ } while (count);
+
+ if (count)
+- memclear_highpage_flush(page, offset, count);
++ memclear_highpage_flush(page, rdata.args.pgbase, count);
+ SetPageUptodate(page);
+ if (PageError(page))
+ ClearPageError(page);
+Index: linux-2.6.0-test5/fs/nfs/write.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nfs/write.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nfs/write.c 2003-09-27 11:38:36.643957656 +0800
+@@ -132,66 +132,73 @@
+ nfs_writepage_sync(struct file *file, struct inode *inode, struct page *page,
+ unsigned int offset, unsigned int count)
+ {
+- struct rpc_cred *cred = NULL;
+- loff_t base;
+ unsigned int wsize = NFS_SERVER(inode)->wsize;
+- int result, refresh = 0, written = 0, flags;
+- u8 *buffer;
+- struct nfs_fattr fattr;
+- struct nfs_writeverf verf;
+-
++ int result, written = 0;
++ int swapfile = IS_SWAPFILE(inode);
++ struct nfs_write_data wdata = {
++ .flags = swapfile ? NFS_RPC_SWAPFLAGS : 0,
++ .cred = NULL,
++ .inode = inode,
++ .args = {
++ .fh = NFS_FH(inode),
++ .pages = &page,
++ .stable = NFS_FILE_SYNC,
++ .pgbase = offset,
++ .count = wsize,
++ },
++ .res = {
++ .fattr = &wdata.fattr,
++ .verf = &wdata.verf,
++ },
++ };
+
+ if (file)
+- cred = get_rpccred(nfs_file_cred(file));
+- if (!cred)
+- cred = get_rpccred(NFS_I(inode)->mm_cred);
++ wdata.cred = get_rpccred(nfs_file_cred(file));
++ if (!wdata.cred)
++ wdata.cred = get_rpccred(NFS_I(inode)->mm_cred);
+
+ dprintk("NFS: nfs_writepage_sync(%s/%Ld %d@%Ld)\n",
+ inode->i_sb->s_id,
+ (long long)NFS_FILEID(inode),
+ count, (long long)(page_offset(page) + offset));
+
+- base = page_offset(page) + offset;
+-
+- flags = ((IS_SWAPFILE(inode)) ? NFS_RW_SWAP : 0) | NFS_RW_SYNC;
+-
+ do {
+- if (count < wsize && !IS_SWAPFILE(inode))
+- wsize = count;
++ if (count < wsize && !swapfile)
++ wdata.args.count = count;
++ wdata.args.offset = page_offset(page) + wdata.args.pgbase;
+
+- result = NFS_PROTO(inode)->write(inode, cred, &fattr, flags,
+- offset, wsize, page, &verf);
++ result = NFS_PROTO(inode)->write(&wdata);
+
+ if (result < 0) {
+ /* Must mark the page invalid after I/O error */
+ ClearPageUptodate(page);
+ goto io_error;
+ }
+- if (result != wsize)
+- printk("NFS: short write, wsize=%u, result=%d\n",
+- wsize, result);
+- refresh = 1;
+- buffer += wsize;
+- base += wsize;
+- offset += wsize;
+- written += wsize;
+- count -= wsize;
++ if (result < wdata.args.count)
++ printk(KERN_WARNING "NFS: short write, count=%u, result=%d\n",
++ wdata.args.count, result);
++
++ wdata.args.offset += result;
++ wdata.args.pgbase += result;
++ written += result;
++ count -= result;
++
+ /*
+ * If we've extended the file, update the inode
+ * now so we don't invalidate the cache.
+ */
+- if (base > i_size_read(inode))
+- i_size_write(inode, base);
++ if (wdata.args.offset > i_size_read(inode))
++ i_size_write(inode, wdata.args.offset);
+ } while (count);
+
+ if (PageError(page))
+ ClearPageError(page);
+
+ io_error:
+- if (cred)
+- put_rpccred(cred);
++ if (wdata.cred)
++ put_rpccred(wdata.cred);
+
+- return written? written : result;
++ return written ? written : result;
+ }
+
+ static int
+Index: linux-2.6.0-test5/fs/nls/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/Makefile 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/Makefile 2003-09-27 11:38:36.644957504 +0800
+@@ -19,14 +19,13 @@
+ obj-$(CONFIG_NLS_CODEPAGE_865) += nls_cp865.o
+ obj-$(CONFIG_NLS_CODEPAGE_866) += nls_cp866.o
+ obj-$(CONFIG_NLS_CODEPAGE_869) += nls_cp869.o
+-obj-$(CONFIG_NLS_CODEPAGE_874) += nls_cp874.o nls_tis-620.o
+-obj-$(CONFIG_NLS_CODEPAGE_932) += nls_cp932.o nls_sjis.o nls_euc-jp.o
+-obj-$(CONFIG_NLS_CODEPAGE_936) += nls_cp936.o nls_gb2312.o
+-obj-$(CONFIG_NLS_CODEPAGE_949) += nls_cp949.o nls_euc-kr.o
+-obj-$(CONFIG_NLS_CODEPAGE_950) += nls_cp950.o nls_big5.o
++obj-$(CONFIG_NLS_CODEPAGE_874) += nls_cp874.o
++obj-$(CONFIG_NLS_CODEPAGE_932) += nls_cp932.o nls_euc-jp.o
++obj-$(CONFIG_NLS_CODEPAGE_936) += nls_cp936.o
++obj-$(CONFIG_NLS_CODEPAGE_949) += nls_cp949.o
++obj-$(CONFIG_NLS_CODEPAGE_950) += nls_cp950.o
+ obj-$(CONFIG_NLS_CODEPAGE_1250) += nls_cp1250.o
+ obj-$(CONFIG_NLS_CODEPAGE_1251) += nls_cp1251.o
+-obj-$(CONFIG_NLS_CODEPAGE_1255) += nls_cp1255.o
+ obj-$(CONFIG_NLS_ISO8859_1) += nls_iso8859-1.o
+ obj-$(CONFIG_NLS_ISO8859_2) += nls_iso8859-2.o
+ obj-$(CONFIG_NLS_ISO8859_3) += nls_iso8859-3.o
+@@ -34,7 +33,7 @@
+ obj-$(CONFIG_NLS_ISO8859_5) += nls_iso8859-5.o
+ obj-$(CONFIG_NLS_ISO8859_6) += nls_iso8859-6.o
+ obj-$(CONFIG_NLS_ISO8859_7) += nls_iso8859-7.o
+-obj-$(CONFIG_NLS_ISO8859_8) += nls_cp1255.o nls_iso8859-8.o
++obj-$(CONFIG_NLS_ISO8859_8) += nls_cp1255.o
+ obj-$(CONFIG_NLS_ISO8859_9) += nls_iso8859-9.o
+ obj-$(CONFIG_NLS_ISO8859_10) += nls_iso8859-10.o
+ obj-$(CONFIG_NLS_ISO8859_13) += nls_iso8859-13.o
+Index: linux-2.6.0-test5/fs/nls/nls_base.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_base.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_base.c 2003-09-27 11:38:36.649956744 +0800
+@@ -203,9 +203,12 @@
+ {
+ struct nls_table *nls;
+ spin_lock(&nls_lock);
+- for (nls = tables; nls; nls = nls->next)
++ for (nls = tables; nls; nls = nls->next) {
+ if (!strcmp(nls->charset, charset))
+ break;
++ if (nls->alias && !strcmp(nls->alias, charset))
++ break;
++ }
+ if (nls && !try_module_get(nls->owner))
+ nls = NULL;
+ spin_unlock(&nls_lock);
+Index: linux-2.6.0-test5/fs/nls/nls_cp1250.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp1250.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp1250.c 2003-09-27 11:38:36.653956136 +0800
+@@ -345,21 +345,3 @@
+ module_exit(exit_nls_cp1250)
+
+ MODULE_LICENSE("Dual BSD/GPL");
+-
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+-
+Index: linux-2.6.0-test5/fs/nls/nls_cp1251.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp1251.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp1251.c 2003-09-27 11:38:36.657955528 +0800
+@@ -299,20 +299,4 @@
+ module_init(init_nls_cp1251)
+ module_exit(exit_nls_cp1251)
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_cp1255.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp1255.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp1255.c 2003-09-27 11:38:36.663954616 +0800
+@@ -360,6 +360,7 @@
+
+ static struct nls_table table = {
+ .charset = "cp1255",
++ .alias = "iso8859-8",
+ .uni2char = uni2char,
+ .char2uni = char2uni,
+ .charset2lower = charset2lower,
+@@ -380,20 +381,5 @@
+ module_init(init_nls_cp1255)
+ module_exit(exit_nls_cp1255)
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
++MODULE_ALIAS_NLS(iso8859-8);
+Index: linux-2.6.0-test5/fs/nls/nls_cp437.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp437.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp437.c 2003-09-27 11:38:36.668953856 +0800
+@@ -385,20 +385,4 @@
+ module_init(init_nls_cp437)
+ module_exit(exit_nls_cp437)
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_cp737.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp737.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp737.c 2003-09-27 11:38:36.672953248 +0800
+@@ -348,20 +348,4 @@
+ module_init(init_nls_cp737)
+ module_exit(exit_nls_cp737)
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_cp775.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp775.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp775.c 2003-09-27 11:38:36.677952488 +0800
+@@ -317,20 +317,4 @@
+ module_init(init_nls_cp775)
+ module_exit(exit_nls_cp775)
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_cp850.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp850.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp850.c 2003-09-27 11:38:36.681951880 +0800
+@@ -313,20 +313,4 @@
+ module_init(init_nls_cp850)
+ module_exit(exit_nls_cp850)
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_cp852.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp852.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp852.c 2003-09-27 11:38:36.685951272 +0800
+@@ -335,20 +335,4 @@
+ module_init(init_nls_cp852)
+ module_exit(exit_nls_cp852)
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_cp855.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp855.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp855.c 2003-09-27 11:38:36.690950512 +0800
+@@ -297,20 +297,4 @@
+ module_init(init_nls_cp855)
+ module_exit(exit_nls_cp855)
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_cp857.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp857.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp857.c 2003-09-27 11:38:36.694949904 +0800
+@@ -299,20 +299,4 @@
+ module_init(init_nls_cp857)
+ module_exit(exit_nls_cp857)
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_cp860.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp860.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp860.c 2003-09-27 11:38:36.699949144 +0800
+@@ -362,20 +362,4 @@
+ module_init(init_nls_cp860)
+ module_exit(exit_nls_cp860)
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_cp861.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp861.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp861.c 2003-09-27 11:38:36.704948384 +0800
+@@ -385,20 +385,4 @@
+ module_init(init_nls_cp861)
+ module_exit(exit_nls_cp861)
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_cp862.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp862.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp862.c 2003-09-27 11:38:36.710947472 +0800
+@@ -419,20 +419,4 @@
+ module_init(init_nls_cp862)
+ module_exit(exit_nls_cp862)
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_cp863.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp863.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp863.c 2003-09-27 11:38:36.715946712 +0800
+@@ -379,20 +379,4 @@
+ module_init(init_nls_cp863)
+ module_exit(exit_nls_cp863)
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_cp864.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp864.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp864.c 2003-09-27 11:38:36.720945952 +0800
+@@ -405,20 +405,4 @@
+ module_init(init_nls_cp864)
+ module_exit(exit_nls_cp864)
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_cp865.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp865.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp865.c 2003-09-27 11:38:36.725945192 +0800
+@@ -385,20 +385,4 @@
+ module_init(init_nls_cp865)
+ module_exit(exit_nls_cp865)
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_cp866.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp866.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp866.c 2003-09-27 11:38:36.730944432 +0800
+@@ -303,20 +303,4 @@
+ module_init(init_nls_cp866)
+ module_exit(exit_nls_cp866)
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_cp869.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp869.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp869.c 2003-09-27 11:38:36.734943824 +0800
+@@ -313,20 +313,4 @@
+ module_init(init_nls_cp869)
+ module_exit(exit_nls_cp869)
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_cp874.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp874.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp874.c 2003-09-27 11:38:36.738943216 +0800
+@@ -251,6 +251,7 @@
+
+ static struct nls_table table = {
+ .charset = "cp874",
++ .alias = "tis-620",
+ .uni2char = uni2char,
+ .char2uni = char2uni,
+ .charset2lower = charset2lower,
+@@ -271,20 +272,5 @@
+ module_init(init_nls_cp874)
+ module_exit(exit_nls_cp874)
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
++MODULE_ALIAS_NLS(tis-620);
+Index: linux-2.6.0-test5/fs/nls/nls_cp932.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp932.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp932.c 2003-09-27 11:38:36.852925888 +0800
+@@ -7885,6 +7885,7 @@
+
+ static struct nls_table table = {
+ .charset = "cp932",
++ .alias = "sjis",
+ .uni2char = uni2char,
+ .char2uni = char2uni,
+ .charset2lower = charset2lower,
+@@ -7904,22 +7905,6 @@
+
+ module_init(init_nls_cp932)
+ module_exit(exit_nls_cp932)
+-MODULE_LICENSE("Dual BSD/GPL");
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- *
+----------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
++MODULE_ALIAS_NLS(sjis);
+Index: linux-2.6.0-test5/fs/nls/nls_cp936.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp936.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp936.c 2003-09-27 11:38:37.025899592 +0800
+@@ -11005,6 +11005,7 @@
+
+ static struct nls_table table = {
+ .charset = "cp936",
++ .alias = "gb2312",
+ .uni2char = uni2char,
+ .char2uni = char2uni,
+ .charset2lower = charset2lower,
+@@ -11024,22 +11025,6 @@
+
+ module_init(init_nls_cp936)
+ module_exit(exit_nls_cp936)
+-MODULE_LICENSE("Dual BSD/GPL");
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- *
+----------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
++MODULE_ALIAS_NLS(gb2312);
+Index: linux-2.6.0-test5/fs/nls/nls_cp949.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp949.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp949.c 2003-09-27 11:38:37.242866608 +0800
+@@ -13922,6 +13922,7 @@
+
+ static struct nls_table table = {
+ .charset = "cp949",
++ .alias = "euc-kr",
+ .uni2char = uni2char,
+ .char2uni = char2uni,
+ .charset2lower = charset2lower,
+@@ -13941,22 +13942,6 @@
+
+ module_init(init_nls_cp949)
+ module_exit(exit_nls_cp949)
+-MODULE_LICENSE("Dual BSD/GPL");
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- *
+----------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
++MODULE_ALIAS_NLS(euc-kr);
+Index: linux-2.6.0-test5/fs/nls/nls_cp950.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp950.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp950.c 2003-09-27 11:38:37.389844264 +0800
+@@ -9461,6 +9461,7 @@
+
+ static struct nls_table table = {
+ .charset = "cp950",
++ .alias = "big5",
+ .uni2char = uni2char,
+ .char2uni = char2uni,
+ .charset2lower = charset2lower,
+@@ -9480,22 +9481,6 @@
+
+ module_init(init_nls_cp950)
+ module_exit(exit_nls_cp950)
+-MODULE_LICENSE("Dual BSD/GPL");
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- *
+----------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
++MODULE_ALIAS_NLS(big5);
+Index: linux-2.6.0-test5/fs/nls/nls_euc-jp.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_euc-jp.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_euc-jp.c 2003-09-27 11:38:37.397843048 +0800
+@@ -579,22 +579,5 @@
+
+ module_init(init_nls_euc_jp)
+ module_exit(exit_nls_euc_jp)
+-MODULE_LICENSE("Dual BSD/GPL");
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- *
+----------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_iso8859-13.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_iso8859-13.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_iso8859-13.c 2003-09-27 11:38:37.400842592 +0800
+@@ -282,21 +282,5 @@
+
+ module_init(init_nls_iso8859_13)
+ module_exit(exit_nls_iso8859_13)
+-MODULE_LICENSE("Dual BSD/GPL");
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_iso8859-14.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_iso8859-14.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_iso8859-14.c 2003-09-27 11:38:37.479830584 +0800
+@@ -338,21 +338,5 @@
+
+ module_init(init_nls_iso8859_14)
+ module_exit(exit_nls_iso8859_14)
+-MODULE_LICENSE("Dual BSD/GPL");
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_iso8859-15.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_iso8859-15.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_iso8859-15.c 2003-09-27 11:38:37.491828760 +0800
+@@ -304,21 +304,5 @@
+
+ module_init(init_nls_iso8859_15)
+ module_exit(exit_nls_iso8859_15)
+-MODULE_LICENSE("Dual BSD/GPL");
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_iso8859-1.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_iso8859-1.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_iso8859-1.c 2003-09-27 11:38:37.583814776 +0800
+@@ -254,21 +254,5 @@
+
+ module_init(init_nls_iso8859_1)
+ module_exit(exit_nls_iso8859_1)
+-MODULE_LICENSE("Dual BSD/GPL");
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_iso8859-2.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_iso8859-2.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_iso8859-2.c 2003-09-27 11:38:37.664802464 +0800
+@@ -305,21 +305,5 @@
+
+ module_init(init_nls_iso8859_2)
+ module_exit(exit_nls_iso8859_2)
+-MODULE_LICENSE("Dual BSD/GPL");
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_iso8859-3.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_iso8859-3.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_iso8859-3.c 2003-09-27 11:38:37.738791216 +0800
+@@ -305,21 +305,5 @@
+
+ module_init(init_nls_iso8859_3)
+ module_exit(exit_nls_iso8859_3)
+-MODULE_LICENSE("Dual BSD/GPL");
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_iso8859-4.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_iso8859-4.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_iso8859-4.c 2003-09-27 11:38:38.169725704 +0800
+@@ -305,21 +305,5 @@
+
+ module_init(init_nls_iso8859_4)
+ module_exit(exit_nls_iso8859_4)
+-MODULE_LICENSE("Dual BSD/GPL");
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_iso8859-5.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_iso8859-5.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_iso8859-5.c 2003-09-27 11:38:38.190722512 +0800
+@@ -269,21 +269,5 @@
+
+ module_init(init_nls_iso8859_5)
+ module_exit(exit_nls_iso8859_5)
+-MODULE_LICENSE("Dual BSD/GPL");
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_iso8859-6.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_iso8859-6.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_iso8859-6.c 2003-09-27 11:38:38.255712632 +0800
+@@ -260,21 +260,5 @@
+
+ module_init(init_nls_iso8859_6)
+ module_exit(exit_nls_iso8859_6)
+-MODULE_LICENSE("Dual BSD/GPL");
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_iso8859-7.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_iso8859-7.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_iso8859-7.c 2003-09-27 11:38:38.312703968 +0800
+@@ -314,21 +314,5 @@
+
+ module_init(init_nls_iso8859_7)
+ module_exit(exit_nls_iso8859_7)
+-MODULE_LICENSE("Dual BSD/GPL");
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_iso8859-9.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_iso8859-9.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_iso8859-9.c 2003-09-27 11:38:38.975603192 +0800
+@@ -269,21 +269,5 @@
+
+ module_init(init_nls_iso8859_9)
+ module_exit(exit_nls_iso8859_9)
+-MODULE_LICENSE("Dual BSD/GPL");
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_koi8-r.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_koi8-r.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_koi8-r.c 2003-09-27 11:38:39.002599088 +0800
+@@ -320,21 +320,5 @@
+
+ module_init(init_nls_koi8_r)
+ module_exit(exit_nls_koi8_r)
+-MODULE_LICENSE("Dual BSD/GPL");
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_koi8-ru.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_koi8-ru.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_koi8-ru.c 2003-09-27 11:38:39.161574920 +0800
+@@ -79,21 +79,5 @@
+
+ module_init(init_nls_koi8_ru)
+ module_exit(exit_nls_koi8_ru)
+-MODULE_LICENSE("Dual BSD/GPL");
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_koi8-u.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_koi8-u.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_koi8-u.c 2003-09-27 11:38:39.166574160 +0800
+@@ -327,21 +327,5 @@
+
+ module_init(init_nls_koi8_u)
+ module_exit(exit_nls_koi8_u)
+-MODULE_LICENSE("Dual BSD/GPL");
+
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/open.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/open.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/open.c 2003-09-27 11:38:39.173573096 +0800
+@@ -187,11 +187,13 @@
+ if (length < 0)
+ return -EINVAL;
+
++ down_write(&dentry->d_inode->i_alloc_sem);
+ newattrs.ia_size = length;
+ newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
+ down(&dentry->d_inode->i_sem);
+ err = notify_change(dentry, &newattrs);
+ up(&dentry->d_inode->i_sem);
++ up_write(&dentry->d_inode->i_alloc_sem);
+ return err;
+ }
+
+@@ -224,7 +226,7 @@
+ goto dput_and_out;
+
+ error = -EROFS;
+- if (IS_RDONLY(inode))
++ if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt))
+ goto dput_and_out;
+
+ error = -EPERM;
+@@ -348,12 +350,16 @@
+ inode = nd.dentry->d_inode;
+
+ error = -EROFS;
+- if (IS_RDONLY(inode))
++ if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt))
+ goto dput_and_out;
+
+ /* Don't worry, the checks are done in inode_change_ok() */
+ newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
+ if (times) {
++ error = -EPERM;
++ if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
++ goto dput_and_out;
++
+ error = get_user(newattrs.ia_atime.tv_sec, ×->actime);
+ newattrs.ia_atime.tv_nsec = 0;
+ if (!error)
+@@ -364,6 +370,10 @@
+
+ newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
+ } else {
++ error = -EACCES;
++ if (IS_IMMUTABLE(inode))
++ goto dput_and_out;
++
+ if (current->fsuid != inode->i_uid &&
+ (error = permission(inode,MAY_WRITE,&nd)) != 0)
+ goto dput_and_out;
+@@ -397,18 +407,26 @@
+ inode = nd.dentry->d_inode;
+
+ error = -EROFS;
+- if (IS_RDONLY(inode))
++ if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt))
+ goto dput_and_out;
+
+ /* Don't worry, the checks are done in inode_change_ok() */
+ newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
+ if (times) {
++ error = -EPERM;
++ if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
++ goto dput_and_out;
++
+ newattrs.ia_atime.tv_sec = times[0].tv_sec;
+ newattrs.ia_atime.tv_nsec = times[0].tv_usec * 1000;
+ newattrs.ia_mtime.tv_sec = times[1].tv_sec;
+ newattrs.ia_mtime.tv_nsec = times[1].tv_usec * 1000;
+ newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
+ } else {
++ error = -EACCES;
++ if (IS_IMMUTABLE(inode))
++ goto dput_and_out;
++
+ if (current->fsuid != inode->i_uid &&
+ (error = permission(inode,MAY_WRITE,&nd)) != 0)
+ goto dput_and_out;
+@@ -471,8 +489,9 @@
+ if (!res) {
+ res = permission(nd.dentry->d_inode, mode, &nd);
+ /* SuS v2 requires we report a read only fs too */
+- if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
+- && !special_file(nd.dentry->d_inode->i_mode))
++ if (!res && (mode & S_IWOTH)
++ && !special_file(nd.dentry->d_inode->i_mode)
++ && (IS_RDONLY(nd.dentry->d_inode) || MNT_IS_RDONLY(nd.mnt)))
+ res = -EROFS;
+ path_release(&nd);
+ }
+@@ -577,7 +596,7 @@
+ inode = dentry->d_inode;
+
+ err = -EROFS;
+- if (IS_RDONLY(inode))
++ if (IS_RDONLY(inode) || MNT_IS_RDONLY(file->f_vfsmnt))
+ goto out_putf;
+ err = -EPERM;
+ if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+@@ -609,7 +628,7 @@
+ inode = nd.dentry->d_inode;
+
+ error = -EROFS;
+- if (IS_RDONLY(inode))
++ if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt))
+ goto dput_and_out;
+
+ error = -EPERM;
+@@ -630,7 +649,7 @@
+ return error;
+ }
+
+-static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
++static int chown_common(struct vfsmount *mnt, struct dentry * dentry, uid_t user, gid_t group)
+ {
+ struct inode * inode;
+ int error;
+@@ -642,7 +661,7 @@
+ goto out;
+ }
+ error = -EROFS;
+- if (IS_RDONLY(inode))
++ if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt))
+ goto out;
+ error = -EPERM;
+ if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+@@ -672,7 +691,7 @@
+
+ error = user_path_walk(filename, &nd);
+ if (!error) {
+- error = chown_common(nd.dentry, user, group);
++ error = chown_common(nd.mnt, nd.dentry, user, group);
+ path_release(&nd);
+ }
+ return error;
+@@ -685,7 +704,7 @@
+
+ error = user_path_walk_link(filename, &nd);
+ if (!error) {
+- error = chown_common(nd.dentry, user, group);
++ error = chown_common(nd.mnt, nd.dentry, user, group);
+ path_release(&nd);
+ }
+ return error;
+@@ -699,7 +718,7 @@
+
+ file = fget(fd);
+ if (file) {
+- error = chown_common(file->f_dentry, user, group);
++ error = chown_common(file->f_vfsmnt, file->f_dentry, user, group);
+ fput(file);
+ }
+ return error;
+Index: linux-2.6.0-test5/fs/proc/array.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/proc/array.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/proc/array.c 2003-09-27 11:38:39.176572640 +0800
+@@ -154,13 +154,16 @@
+ read_lock(&tasklist_lock);
+ buffer += sprintf(buffer,
+ "State:\t%s\n"
++ "SleepAVG:\t%lu%%\n"
+ "Tgid:\t%d\n"
+ "Pid:\t%d\n"
+ "PPid:\t%d\n"
+ "TracerPid:\t%d\n"
+ "Uid:\t%d\t%d\t%d\t%d\n"
+ "Gid:\t%d\t%d\t%d\t%d\n",
+- get_task_state(p), p->tgid,
++ get_task_state(p),
++ (p->sleep_avg/1024)*100/(1000000000/1024),
++ p->tgid,
+ p->pid, p->pid ? p->real_parent->pid : 0,
+ p->pid && p->ptrace ? p->parent->pid : 0,
+ p->uid, p->euid, p->suid, p->fsuid,
+@@ -303,7 +306,7 @@
+ mm = mmgrab(mm);
+ if (task->tty) {
+ tty_pgrp = task->tty->pgrp;
+- tty_nr = task->tty->device;
++ tty_nr = tty_devnum(task->tty);
+ }
+ task_unlock(task);
+ if (mm) {
+@@ -341,7 +344,7 @@
+ task->comm,
+ state,
+ ppid,
+- task->pgrp,
++ process_group(task),
+ task->session,
+ tty_nr,
+ tty_pgrp,
+Index: linux-2.6.0-test5/fs/proc/base.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/proc/base.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/proc/base.c 2003-09-27 11:38:39.187570968 +0800
+@@ -44,28 +44,51 @@
+ #define fake_ino(pid,ino) (((pid)<<16)|(ino))
+
+ enum pid_directory_inos {
+- PROC_PID_INO = 2,
+- PROC_PID_STATUS,
+- PROC_PID_MEM,
+- PROC_PID_CWD,
+- PROC_PID_ROOT,
+- PROC_PID_EXE,
+- PROC_PID_FD,
+- PROC_PID_ENVIRON,
+- PROC_PID_CMDLINE,
+- PROC_PID_STAT,
+- PROC_PID_STATM,
+- PROC_PID_MAPS,
+- PROC_PID_MOUNTS,
+- PROC_PID_WCHAN,
++ PROC_TGID_INO = 2,
++ PROC_TGID_TASK,
++ PROC_TGID_STATUS,
++ PROC_TGID_MEM,
++ PROC_TGID_CWD,
++ PROC_TGID_ROOT,
++ PROC_TGID_EXE,
++ PROC_TGID_FD,
++ PROC_TGID_ENVIRON,
++ PROC_TGID_CMDLINE,
++ PROC_TGID_STAT,
++ PROC_TGID_STATM,
++ PROC_TGID_MAPS,
++ PROC_TGID_MOUNTS,
++ PROC_TGID_WCHAN,
+ #ifdef CONFIG_SECURITY
+- PROC_PID_ATTR,
+- PROC_PID_ATTR_CURRENT,
+- PROC_PID_ATTR_PREV,
+- PROC_PID_ATTR_EXEC,
+- PROC_PID_ATTR_FSCREATE,
++ PROC_TGID_ATTR,
++ PROC_TGID_ATTR_CURRENT,
++ PROC_TGID_ATTR_PREV,
++ PROC_TGID_ATTR_EXEC,
++ PROC_TGID_ATTR_FSCREATE,
+ #endif
+- PROC_PID_FD_DIR = 0x8000, /* 0x8000-0xffff */
++ PROC_TGID_FD_DIR,
++ PROC_TID_INO,
++ PROC_TID_STATUS,
++ PROC_TID_MEM,
++ PROC_TID_CWD,
++ PROC_TID_ROOT,
++ PROC_TID_EXE,
++ PROC_TID_FD,
++ PROC_TID_ENVIRON,
++ PROC_TID_CMDLINE,
++ PROC_TID_STAT,
++ PROC_TID_STATM,
++ PROC_TID_MAPS,
++ PROC_TID_MOUNTS,
++ PROC_TID_WCHAN,
++#ifdef CONFIG_SECURITY
++ PROC_TID_ATTR,
++ PROC_TID_ATTR_CURRENT,
++ PROC_TID_ATTR_PREV,
++ PROC_TID_ATTR_EXEC,
++ PROC_TID_ATTR_FSCREATE,
++#endif
++ PROC_TID_FD_DIR = 0x8000, /* 0x8000-0xffff */
+ };
+
+ struct pid_entry {
+@@ -76,36 +99,68 @@
+ };
+
+ #define E(type,name,mode) {(type),sizeof(name)-1,(name),(mode)}
+-static struct pid_entry base_stuff[] = {
+- E(PROC_PID_FD, "fd", S_IFDIR|S_IRUSR|S_IXUSR),
+- E(PROC_PID_ENVIRON, "environ", S_IFREG|S_IRUSR),
+- E(PROC_PID_STATUS, "status", S_IFREG|S_IRUGO),
+- E(PROC_PID_CMDLINE, "cmdline", S_IFREG|S_IRUGO),
+- E(PROC_PID_STAT, "stat", S_IFREG|S_IRUGO),
+- E(PROC_PID_STATM, "statm", S_IFREG|S_IRUGO),
+- E(PROC_PID_MAPS, "maps", S_IFREG|S_IRUGO),
+- E(PROC_PID_MEM, "mem", S_IFREG|S_IRUSR|S_IWUSR),
+- E(PROC_PID_CWD, "cwd", S_IFLNK|S_IRWXUGO),
+- E(PROC_PID_ROOT, "root", S_IFLNK|S_IRWXUGO),
+- E(PROC_PID_EXE, "exe", S_IFLNK|S_IRWXUGO),
+- E(PROC_PID_MOUNTS, "mounts", S_IFREG|S_IRUGO),
++
++static struct pid_entry tgid_base_stuff[] = {
++ E(PROC_TGID_TASK, "task", S_IFDIR|S_IRUGO|S_IXUGO),
++ E(PROC_TGID_FD, "fd", S_IFDIR|S_IRUSR|S_IXUSR),
++ E(PROC_TGID_ENVIRON, "environ", S_IFREG|S_IRUSR),
++ E(PROC_TGID_STATUS, "status", S_IFREG|S_IRUGO),
++ E(PROC_TGID_CMDLINE, "cmdline", S_IFREG|S_IRUGO),
++ E(PROC_TGID_STAT, "stat", S_IFREG|S_IRUGO),
++ E(PROC_TGID_STATM, "statm", S_IFREG|S_IRUGO),
++ E(PROC_TGID_MAPS, "maps", S_IFREG|S_IRUGO),
++ E(PROC_TGID_MEM, "mem", S_IFREG|S_IRUSR|S_IWUSR),
++ E(PROC_TGID_CWD, "cwd", S_IFLNK|S_IRWXUGO),
++ E(PROC_TGID_ROOT, "root", S_IFLNK|S_IRWXUGO),
++ E(PROC_TGID_EXE, "exe", S_IFLNK|S_IRWXUGO),
++ E(PROC_TGID_MOUNTS, "mounts", S_IFREG|S_IRUGO),
+ #ifdef CONFIG_SECURITY
+- E(PROC_PID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO),
++ E(PROC_TGID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO),
+ #endif
+ #ifdef CONFIG_KALLSYMS
+- E(PROC_PID_WCHAN, "wchan", S_IFREG|S_IRUGO),
++ E(PROC_TGID_WCHAN, "wchan", S_IFREG|S_IRUGO),
+ #endif
+- {0,0,NULL,0}
++ {0,0,NULL,0}
+ };
++static struct pid_entry tid_base_stuff[] = {
++ E(PROC_TID_FD, "fd", S_IFDIR|S_IRUSR|S_IXUSR),
++ E(PROC_TID_ENVIRON, "environ", S_IFREG|S_IRUSR),
++ E(PROC_TID_STATUS, "status", S_IFREG|S_IRUGO),
++ E(PROC_TID_CMDLINE, "cmdline", S_IFREG|S_IRUGO),
++ E(PROC_TID_STAT, "stat", S_IFREG|S_IRUGO),
++ E(PROC_TID_STATM, "statm", S_IFREG|S_IRUGO),
++ E(PROC_TID_MAPS, "maps", S_IFREG|S_IRUGO),
++ E(PROC_TID_MEM, "mem", S_IFREG|S_IRUSR|S_IWUSR),
++ E(PROC_TID_CWD, "cwd", S_IFLNK|S_IRWXUGO),
++ E(PROC_TID_ROOT, "root", S_IFLNK|S_IRWXUGO),
++ E(PROC_TID_EXE, "exe", S_IFLNK|S_IRWXUGO),
++ E(PROC_TID_MOUNTS, "mounts", S_IFREG|S_IRUGO),
++#ifdef CONFIG_SECURITY
++ E(PROC_TID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO),
++#endif
++#ifdef CONFIG_KALLSYMS
++ E(PROC_TID_WCHAN, "wchan", S_IFREG|S_IRUGO),
++#endif
++ {0,0,NULL,0}
++};
++
+ #ifdef CONFIG_SECURITY
+-static struct pid_entry attr_stuff[] = {
+- E(PROC_PID_ATTR_CURRENT, "current", S_IFREG|S_IRUGO|S_IWUGO),
+- E(PROC_PID_ATTR_PREV, "prev", S_IFREG|S_IRUGO),
+- E(PROC_PID_ATTR_EXEC, "exec", S_IFREG|S_IRUGO|S_IWUGO),
+- E(PROC_PID_ATTR_FSCREATE, "fscreate", S_IFREG|S_IRUGO|S_IWUGO),
+- {0,0,NULL,0}
++static struct pid_entry tgid_attr_stuff[] = {
++ E(PROC_TGID_ATTR_CURRENT, "current", S_IFREG|S_IRUGO|S_IWUGO),
++ E(PROC_TGID_ATTR_PREV, "prev", S_IFREG|S_IRUGO),
++ E(PROC_TGID_ATTR_EXEC, "exec", S_IFREG|S_IRUGO|S_IWUGO),
++ E(PROC_TGID_ATTR_FSCREATE, "fscreate", S_IFREG|S_IRUGO|S_IWUGO),
++ {0,0,NULL,0}
++};
++static struct pid_entry tid_attr_stuff[] = {
++ E(PROC_TID_ATTR_CURRENT, "current", S_IFREG|S_IRUGO|S_IWUGO),
++ E(PROC_TID_ATTR_PREV, "prev", S_IFREG|S_IRUGO),
++ E(PROC_TID_ATTR_EXEC, "exec", S_IFREG|S_IRUGO|S_IWUGO),
++ E(PROC_TID_ATTR_FSCREATE, "fscreate", S_IFREG|S_IRUGO|S_IWUGO),
++ {0,0,NULL,0}
+ };
+ #endif
++
+ #undef E
+
+ static inline struct task_struct *proc_task(struct inode *inode)
+@@ -128,7 +183,7 @@
+ struct task_struct *task = proc_task(inode);
+ struct files_struct *files;
+ struct file *file;
+- int fd = proc_type(inode) - PROC_PID_FD_DIR;
++ int fd = proc_type(inode) - PROC_TID_FD_DIR;
+
+ task_lock(task);
+ files = task->files;
+@@ -675,7 +730,7 @@
+ {
+ struct inode *inode = filp->f_dentry->d_inode;
+ struct task_struct *p = proc_task(inode);
+- unsigned int fd, pid, ino;
++ unsigned int fd, tid, ino;
+ int retval;
+ char buf[NUMBUF];
+ struct files_struct * files;
+@@ -684,7 +739,7 @@
+ if (!pid_alive(p))
+ goto out;
+ retval = 0;
+- pid = p->pid;
++ tid = p->pid;
+
+ fd = filp->f_pos;
+ switch (fd) {
+@@ -693,7 +748,7 @@
+ goto out;
+ filp->f_pos++;
+ case 1:
+- ino = fake_ino(pid, PROC_PID_INO);
++ ino = fake_ino(tid, PROC_TID_INO);
+ if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0)
+ goto out;
+ filp->f_pos++;
+@@ -723,7 +778,7 @@
+ i /= 10;
+ } while (i);
+
+- ino = fake_ino(pid, PROC_PID_FD_DIR + fd);
++ ino = fake_ino(tid, PROC_TID_FD_DIR + fd);
+ if (filldir(dirent, buf+j, NUMBUF-j, fd+2, ino, DT_LNK) < 0) {
+ spin_lock(&files->file_lock);
+ break;
+@@ -792,11 +847,18 @@
+ return ret;
+ }
+
+-static int proc_base_readdir(struct file * filp,
++static int proc_tgid_base_readdir(struct file * filp,
++ void * dirent, filldir_t filldir)
++{
++ return proc_pident_readdir(filp,dirent,filldir,
++ tgid_base_stuff,ARRAY_SIZE(tgid_base_stuff));
++}
++
++static int proc_tid_base_readdir(struct file * filp,
+ void * dirent, filldir_t filldir)
+ {
+ return proc_pident_readdir(filp,dirent,filldir,
+- base_stuff,ARRAY_SIZE(base_stuff));
++ tid_base_stuff,ARRAY_SIZE(tid_base_stuff));
+ }
+
+ /* building an inode */
+@@ -843,7 +905,7 @@
+ ei->type = ino;
+ inode->i_uid = 0;
+ inode->i_gid = 0;
+- if (ino == PROC_PID_INO || task_dumpable(task)) {
++ if (ino == PROC_TGID_INO || ino == PROC_TID_INO || task_dumpable(task)) {
+ inode->i_uid = task->euid;
+ inode->i_gid = task->egid;
+ }
+@@ -873,7 +935,7 @@
+ struct inode *inode = dentry->d_inode;
+ struct task_struct *task = proc_task(inode);
+ if (pid_alive(task)) {
+- if (proc_type(inode) == PROC_PID_INO || task_dumpable(task)) {
++ if (proc_type(inode) == PROC_TGID_INO || proc_type(inode) == PROC_TID_INO || task_dumpable(task)) {
+ inode->i_uid = task->euid;
+ inode->i_gid = task->egid;
+ } else {
+@@ -887,11 +949,11 @@
+ return 0;
+ }
+
+-static int pid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
++static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
+ {
+ struct inode *inode = dentry->d_inode;
+ struct task_struct *task = proc_task(inode);
+- int fd = proc_type(inode) - PROC_PID_FD_DIR;
++ int fd = proc_type(inode) - PROC_TID_FD_DIR;
+ struct files_struct *files;
+
+ task_lock(task);
+@@ -940,10 +1002,9 @@
+ return !pid_alive(proc_task(dentry->d_inode));
+ }
+
+-
+-static struct dentry_operations pid_fd_dentry_operations =
++static struct dentry_operations tid_fd_dentry_operations =
+ {
+- .d_revalidate = pid_fd_revalidate,
++ .d_revalidate = tid_fd_revalidate,
+ .d_delete = pid_delete_dentry,
+ };
+
+@@ -999,7 +1060,7 @@
+ if (!pid_alive(task))
+ goto out;
+
+- inode = proc_pid_make_inode(dir->i_sb, task, PROC_PID_FD_DIR+fd);
++ inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_FD_DIR+fd);
+ if (!inode)
+ goto out;
+ ei = PROC_I(inode);
+@@ -1024,7 +1085,7 @@
+ inode->i_op = &proc_pid_link_inode_operations;
+ inode->i_size = 64;
+ ei->op.proc_get_link = proc_fd_link;
+- dentry->d_op = &pid_fd_dentry_operations;
++ dentry->d_op = &tid_fd_dentry_operations;
+ d_add(dentry, inode);
+ return NULL;
+
+@@ -1037,11 +1098,19 @@
+ return ERR_PTR(-ENOENT);
+ }
+
++static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldir);
++static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd);
++
+ static struct file_operations proc_fd_operations = {
+ .read = generic_read_dir,
+ .readdir = proc_readfd,
+ };
+
++static struct file_operations proc_task_operations = {
++ .read = generic_read_dir,
++ .readdir = proc_task_readdir,
++};
++
+ /*
+ * proc directories can do almost nothing..
+ */
+@@ -1050,6 +1119,11 @@
+ .permission = proc_permission,
+ };
+
++static struct inode_operations proc_task_inode_operations = {
++ .lookup = proc_task_lookup,
++ .permission = proc_permission,
++};
++
+ #ifdef CONFIG_SECURITY
+ static ssize_t proc_pid_attr_read(struct file * file, char * buf,
+ size_t count, loff_t *ppos)
+@@ -1122,8 +1196,10 @@
+ .write = proc_pid_attr_write,
+ };
+
+-static struct file_operations proc_attr_operations;
+-static struct inode_operations proc_attr_inode_operations;
++static struct file_operations proc_tid_attr_operations;
++static struct inode_operations proc_tid_attr_inode_operations;
++static struct file_operations proc_tgid_attr_operations;
++static struct inode_operations proc_tgid_attr_inode_operations;
+ #endif
+
+ /* SMP-safe */
+@@ -1161,71 +1237,98 @@
+ inode->i_mode = p->mode;
+ /*
+ * Yes, it does not scale. And it should not. Don't add
+- * new entries into /proc/<pid>/ without very good reasons.
++ * new entries into /proc/<tgid>/ without very good reasons.
+ */
+ switch(p->type) {
+- case PROC_PID_FD:
++ case PROC_TGID_TASK:
++ inode->i_nlink = 3;
++ inode->i_op = &proc_task_inode_operations;
++ inode->i_fop = &proc_task_operations;
++ break;
++ case PROC_TID_FD:
++ case PROC_TGID_FD:
+ inode->i_nlink = 2;
+ inode->i_op = &proc_fd_inode_operations;
+ inode->i_fop = &proc_fd_operations;
+ break;
+- case PROC_PID_EXE:
++ case PROC_TID_EXE:
++ case PROC_TGID_EXE:
+ inode->i_op = &proc_pid_link_inode_operations;
+ ei->op.proc_get_link = proc_exe_link;
+ break;
+- case PROC_PID_CWD:
++ case PROC_TID_CWD:
++ case PROC_TGID_CWD:
+ inode->i_op = &proc_pid_link_inode_operations;
+ ei->op.proc_get_link = proc_cwd_link;
+ break;
+- case PROC_PID_ROOT:
++ case PROC_TID_ROOT:
++ case PROC_TGID_ROOT:
+ inode->i_op = &proc_pid_link_inode_operations;
+ ei->op.proc_get_link = proc_root_link;
+ break;
+- case PROC_PID_ENVIRON:
++ case PROC_TID_ENVIRON:
++ case PROC_TGID_ENVIRON:
+ inode->i_fop = &proc_info_file_operations;
+ ei->op.proc_read = proc_pid_environ;
+ break;
+- case PROC_PID_STATUS:
++ case PROC_TID_STATUS:
++ case PROC_TGID_STATUS:
+ inode->i_fop = &proc_info_file_operations;
+ ei->op.proc_read = proc_pid_status;
+ break;
+- case PROC_PID_STAT:
++ case PROC_TID_STAT:
++ case PROC_TGID_STAT:
+ inode->i_fop = &proc_info_file_operations;
+ ei->op.proc_read = proc_pid_stat;
+ break;
+- case PROC_PID_CMDLINE:
++ case PROC_TID_CMDLINE:
++ case PROC_TGID_CMDLINE:
+ inode->i_fop = &proc_info_file_operations;
+ ei->op.proc_read = proc_pid_cmdline;
+ break;
+- case PROC_PID_STATM:
++ case PROC_TID_STATM:
++ case PROC_TGID_STATM:
+ inode->i_fop = &proc_info_file_operations;
+ ei->op.proc_read = proc_pid_statm;
+ break;
+- case PROC_PID_MAPS:
++ case PROC_TID_MAPS:
++ case PROC_TGID_MAPS:
+ inode->i_fop = &proc_maps_operations;
+ break;
+- case PROC_PID_MEM:
++ case PROC_TID_MEM:
++ case PROC_TGID_MEM:
+ inode->i_op = &proc_mem_inode_operations;
+ inode->i_fop = &proc_mem_operations;
+ break;
+- case PROC_PID_MOUNTS:
++ case PROC_TID_MOUNTS:
++ case PROC_TGID_MOUNTS:
+ inode->i_fop = &proc_mounts_operations;
+ break;
+ #ifdef CONFIG_SECURITY
+- case PROC_PID_ATTR:
++ case PROC_TID_ATTR:
++ inode->i_nlink = 2;
++ inode->i_op = &proc_tid_attr_inode_operations;
++ inode->i_fop = &proc_tid_attr_operations;
++ break;
++ case PROC_TGID_ATTR:
+ inode->i_nlink = 2;
+- inode->i_op = &proc_attr_inode_operations;
+- inode->i_fop = &proc_attr_operations;
++ inode->i_op = &proc_tgid_attr_inode_operations;
++ inode->i_fop = &proc_tgid_attr_operations;
+ break;
+- case PROC_PID_ATTR_CURRENT:
+- case PROC_PID_ATTR_PREV:
+- case PROC_PID_ATTR_EXEC:
+- case PROC_PID_ATTR_FSCREATE:
++ case PROC_TID_ATTR_CURRENT:
++ case PROC_TGID_ATTR_CURRENT:
++ case PROC_TID_ATTR_PREV:
++ case PROC_TGID_ATTR_PREV:
++ case PROC_TID_ATTR_EXEC:
++ case PROC_TGID_ATTR_EXEC:
++ case PROC_TID_ATTR_FSCREATE:
++ case PROC_TGID_ATTR_FSCREATE:
+ inode->i_fop = &proc_pid_attr_operations;
+ break;
+ #endif
+ #ifdef CONFIG_KALLSYMS
+- case PROC_PID_WCHAN:
++ case PROC_TID_WCHAN:
++ case PROC_TGID_WCHAN:
+ inode->i_fop = &proc_info_file_operations;
+ ei->op.proc_read = proc_pid_wchan;
+ break;
+@@ -1243,40 +1346,75 @@
+ return ERR_PTR(error);
+ }
+
+-static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){
+- return proc_pident_lookup(dir, dentry, base_stuff);
++static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){
++ return proc_pident_lookup(dir, dentry, tgid_base_stuff);
++}
++
++static struct dentry *proc_tid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){
++ return proc_pident_lookup(dir, dentry, tid_base_stuff);
+ }
+
+-static struct file_operations proc_base_operations = {
++static struct file_operations proc_tgid_base_operations = {
++ .read = generic_read_dir,
++ .readdir = proc_tgid_base_readdir,
++};
++
++static struct file_operations proc_tid_base_operations = {
+ .read = generic_read_dir,
+- .readdir = proc_base_readdir,
++ .readdir = proc_tid_base_readdir,
++};
++
++static struct inode_operations proc_tgid_base_inode_operations = {
++ .lookup = proc_tgid_base_lookup,
+ };
+
+-static struct inode_operations proc_base_inode_operations = {
+- .lookup = proc_base_lookup,
++static struct inode_operations proc_tid_base_inode_operations = {
++ .lookup = proc_tid_base_lookup,
+ };
+
+ #ifdef CONFIG_SECURITY
+-static int proc_attr_readdir(struct file * filp,
++static int proc_tgid_attr_readdir(struct file * filp,
+ void * dirent, filldir_t filldir)
+ {
+ return proc_pident_readdir(filp,dirent,filldir,
+- attr_stuff,ARRAY_SIZE(attr_stuff));
++ tgid_attr_stuff,ARRAY_SIZE(tgid_attr_stuff));
+ }
+
+-static struct file_operations proc_attr_operations = {
++static int proc_tid_attr_readdir(struct file * filp,
++ void * dirent, filldir_t filldir)
++{
++ return proc_pident_readdir(filp,dirent,filldir,
++ tid_attr_stuff,ARRAY_SIZE(tid_attr_stuff));
++}
++
++static struct file_operations proc_tgid_attr_operations = {
++ .read = generic_read_dir,
++ .readdir = proc_tgid_attr_readdir,
++};
++
++static struct file_operations proc_tid_attr_operations = {
+ .read = generic_read_dir,
+- .readdir = proc_attr_readdir,
++ .readdir = proc_tid_attr_readdir,
+ };
+
+-static struct dentry *proc_attr_lookup(struct inode *dir,
++static struct dentry *proc_tgid_attr_lookup(struct inode *dir,
+ struct dentry *dentry, struct nameidata *nd)
+ {
+- return proc_pident_lookup(dir, dentry, attr_stuff);
++ return proc_pident_lookup(dir, dentry, tgid_attr_stuff);
+ }
+
+-static struct inode_operations proc_attr_inode_operations = {
+- .lookup = proc_attr_lookup,
++static struct dentry *proc_tid_attr_lookup(struct inode *dir,
++ struct dentry *dentry, struct nameidata *nd)
++{
++ return proc_pident_lookup(dir, dentry, tid_attr_stuff);
++}
++
++static struct inode_operations proc_tgid_attr_inode_operations = {
++ .lookup = proc_tgid_attr_lookup,
++};
++
++static struct inode_operations proc_tid_attr_inode_operations = {
++ .lookup = proc_tid_attr_lookup,
+ };
+ #endif
+
+@@ -1286,14 +1424,14 @@
+ static int proc_self_readlink(struct dentry *dentry, char *buffer, int buflen)
+ {
+ char tmp[30];
+- sprintf(tmp, "%d", current->pid);
++ sprintf(tmp, "%d", current->tgid);
+ return vfs_readlink(dentry,buffer,buflen,tmp);
+ }
+
+ static int proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
+ {
+ char tmp[30];
+- sprintf(tmp, "%d", current->pid);
++ sprintf(tmp, "%d", current->tgid);
+ return vfs_follow_link(nd,tmp);
+ }
+
+@@ -1357,7 +1495,7 @@
+ struct task_struct *task;
+ struct inode *inode;
+ struct proc_inode *ei;
+- unsigned pid;
++ unsigned tgid;
+
+ if (dentry->d_name.len == 4 && !memcmp(dentry->d_name.name,"self",4)) {
+ inode = new_inode(dir->i_sb);
+@@ -1365,7 +1503,7 @@
+ return ERR_PTR(-ENOMEM);
+ ei = PROC_I(inode);
+ inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+- inode->i_ino = fake_ino(0, PROC_PID_INO);
++ inode->i_ino = fake_ino(0, PROC_TGID_INO);
+ ei->pde = NULL;
+ inode->i_mode = S_IFLNK|S_IRWXUGO;
+ inode->i_uid = inode->i_gid = 0;
+@@ -1374,19 +1512,19 @@
+ d_add(dentry, inode);
+ return NULL;
+ }
+- pid = name_to_int(dentry);
+- if (pid == ~0U)
++ tgid = name_to_int(dentry);
++ if (tgid == ~0U)
+ goto out;
+
+ read_lock(&tasklist_lock);
+- task = find_task_by_pid(pid);
++ task = find_task_by_pid(tgid);
+ if (task)
+ get_task_struct(task);
+ read_unlock(&tasklist_lock);
+ if (!task)
+ goto out;
+
+- inode = proc_pid_make_inode(dir->i_sb, task, PROC_PID_INO);
++ inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO);
+
+
+ if (!inode) {
+@@ -1394,8 +1532,53 @@
+ goto out;
+ }
+ inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
+- inode->i_op = &proc_base_inode_operations;
+- inode->i_fop = &proc_base_operations;
++ inode->i_op = &proc_tgid_base_inode_operations;
++ inode->i_fop = &proc_tgid_base_operations;
++ inode->i_nlink = 3;
++ inode->i_flags|=S_IMMUTABLE;
++
++ dentry->d_op = &pid_base_dentry_operations;
++
++ spin_lock(&task->proc_lock);
++ task->proc_dentry = dentry;
++ d_add(dentry, inode);
++ spin_unlock(&task->proc_lock);
++
++ put_task_struct(task);
++ return NULL;
++out:
++ return ERR_PTR(-ENOENT);
++}
++
++/* SMP-safe */
++static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
++{
++ struct task_struct *task;
++ struct inode *inode;
++ unsigned tid;
++
++ tid = name_to_int(dentry);
++ if (tid == ~0U)
++ goto out;
++
++ read_lock(&tasklist_lock);
++ task = find_task_by_pid(tid);
++ if (task)
++ get_task_struct(task);
++ read_unlock(&tasklist_lock);
++ if (!task)
++ goto out;
++
++ inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_INO);
++
++
++ if (!inode) {
++ put_task_struct(task);
++ goto out;
++ }
++ inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
++ inode->i_op = &proc_tid_base_inode_operations;
++ inode->i_fop = &proc_tid_base_operations;
+ inode->i_nlink = 3;
+ inode->i_flags|=S_IMMUTABLE;
+
+@@ -1416,55 +1599,84 @@
+ #define PROC_MAXPIDS 20
+
+ /*
+- * Get a few pid's to return for filldir - we need to hold the
++ * Get a few tgid's to return for filldir - we need to hold the
+ * tasklist lock while doing this, and we must release it before
+ * we actually do the filldir itself, so we use a temp buffer..
+ */
+-static int get_pid_list(int index, unsigned int *pids)
++static int get_tgid_list(int index, unsigned int *tgids)
+ {
+ struct task_struct *p;
+- int nr_pids = 0;
++ int nr_tgids = 0;
+
+ index--;
+ read_lock(&tasklist_lock);
+ for_each_process(p) {
+- int pid = p->pid;
++ int tgid = p->pid;
+ if (!pid_alive(p))
+ continue;
+ if (--index >= 0)
+ continue;
+- pids[nr_pids] = pid;
+- nr_pids++;
+- if (nr_pids >= PROC_MAXPIDS)
++ tgids[nr_tgids] = tgid;
++ nr_tgids++;
++ if (nr_tgids >= PROC_MAXPIDS)
+ break;
+ }
+ read_unlock(&tasklist_lock);
+- return nr_pids;
++ return nr_tgids;
++}
++
++/*
++ * Get a few tid's to return for filldir - we need to hold the
++ * tasklist lock while doing this, and we must release it before
++ * we actually do the filldir itself, so we use a temp buffer..
++ */
++static int get_tid_list(int index, unsigned int *tids, struct inode *dir)
++{
++ struct task_struct *leader_task = proc_task(dir);
++ struct task_struct *task = leader_task;
++ int nr_tids = 0;
++
++ index -= 2;
++ read_lock(&tasklist_lock);
++ do {
++ int tid = task->pid;
++ if (!pid_alive(task))
++ continue;
++ if (--index >= 0)
++ continue;
++ tids[nr_tids] = tid;
++ nr_tids++;
++ if (nr_tids >= PROC_MAXPIDS)
++ break;
++ } while ((task = next_thread(task)) != leader_task);
++ read_unlock(&tasklist_lock);
++ return nr_tids;
+ }
+
++/* for the /proc/ directory itself, after non-process stuff has been done */
+ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
+ {
+- unsigned int pid_array[PROC_MAXPIDS];
++ unsigned int tgid_array[PROC_MAXPIDS];
+ char buf[PROC_NUMBUF];
+ unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
+- unsigned int nr_pids, i;
++ unsigned int nr_tgids, i;
+
+ if (!nr) {
+- ino_t ino = fake_ino(0,PROC_PID_INO);
++ ino_t ino = fake_ino(0,PROC_TGID_INO);
+ if (filldir(dirent, "self", 4, filp->f_pos, ino, DT_LNK) < 0)
+ return 0;
+ filp->f_pos++;
+ nr++;
+ }
+
+- nr_pids = get_pid_list(nr, pid_array);
++ nr_tgids = get_tgid_list(nr, tgid_array);
+
+- for (i = 0; i < nr_pids; i++) {
+- int pid = pid_array[i];
+- ino_t ino = fake_ino(pid,PROC_PID_INO);
++ for (i = 0; i < nr_tgids; i++) {
++ int tgid = tgid_array[i];
++ ino_t ino = fake_ino(tgid,PROC_TGID_INO);
+ unsigned long j = PROC_NUMBUF;
+
+- do buf[--j] = '0' + (pid % 10); while (pid/=10);
++ do buf[--j] = '0' + (tgid % 10); while (tgid/=10);
+
+ if (filldir(dirent, buf+j, PROC_NUMBUF-j, filp->f_pos, ino, DT_DIR) < 0)
+ break;
+@@ -1472,3 +1684,55 @@
+ }
+ return 0;
+ }
++
++/* for the /proc/TGID/task/ directories */
++static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldir)
++{
++ unsigned int tid_array[PROC_MAXPIDS];
++ char buf[PROC_NUMBUF];
++ unsigned int nr_tids, i;
++ struct dentry *dentry = filp->f_dentry;
++ struct inode *inode = dentry->d_inode;
++ int retval = -ENOENT;
++ ino_t ino;
++ unsigned long pos = filp->f_pos; /* avoiding "long long" filp->f_pos */
++
++ if (!pid_alive(proc_task(inode)))
++ goto out;
++ retval = 0;
++
++ switch (pos) {
++ case 0:
++ ino = inode->i_ino;
++ if (filldir(dirent, ".", 1, pos, ino, DT_DIR) < 0)
++ goto out;
++ pos++;
++ /* fall through */
++ case 1:
++ ino = parent_ino(dentry);
++ if (filldir(dirent, "..", 2, pos, ino, DT_DIR) < 0)
++ goto out;
++ pos++;
++ /* fall through */
++ }
++
++ nr_tids = get_tid_list(pos, tid_array, inode);
++
++ for (i = 0; i < nr_tids; i++) {
++ unsigned long j = PROC_NUMBUF;
++ int tid = tid_array[i];
++
++ ino = fake_ino(tid,PROC_TID_INO);
++
++ do
++ buf[--j] = '0' + (tid % 10);
++ while (tid /= 10);
++
++ if (filldir(dirent, buf+j, PROC_NUMBUF-j, pos, ino, DT_DIR) < 0)
++ break;
++ pos++;
++ }
++out:
++ filp->f_pos = pos;
++ return retval;
++}
+Index: linux-2.6.0-test5/fs/proc/generic.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/proc/generic.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/proc/generic.c 2003-09-27 11:38:39.192570208 +0800
+@@ -18,13 +18,13 @@
+ #include <asm/uaccess.h>
+ #include <asm/bitops.h>
+
+-static ssize_t proc_file_read(struct file * file, char * buf,
++static ssize_t proc_file_read(struct file *file, char __user *buf,
+ size_t nbytes, loff_t *ppos);
+-static ssize_t proc_file_write(struct file * file, const char * buffer,
++static ssize_t proc_file_write(struct file *file, const char __user *buffer,
+ size_t count, loff_t *ppos);
+ static loff_t proc_file_lseek(struct file *, loff_t, int);
+
+-int proc_match(int len, const char *name,struct proc_dir_entry * de)
++int proc_match(int len, const char *name, struct proc_dir_entry *de)
+ {
+ if (de->namelen != len)
+ return 0;
+@@ -45,7 +45,8 @@
+ #define PROC_BLOCK_SIZE (PAGE_SIZE - 1024)
+
+ static ssize_t
+-proc_file_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
++proc_file_read(struct file *file, char __user *buf, size_t nbytes,
++ loff_t *ppos)
+ {
+ struct inode * inode = file->f_dentry->d_inode;
+ char *page;
+@@ -59,8 +60,7 @@
+ if (!(page = (char*) __get_free_page(GFP_KERNEL)))
+ return -ENOMEM;
+
+- while ((nbytes > 0) && !eof)
+- {
++ while ((nbytes > 0) && !eof) {
+ count = MIN(PROC_BLOCK_SIZE, nbytes);
+
+ start = NULL;
+@@ -184,7 +184,7 @@
+ }
+
+ static ssize_t
+-proc_file_write(struct file * file, const char * buffer,
++proc_file_write(struct file *file, const char __user *buffer,
+ size_t count, loff_t *ppos)
+ {
+ struct inode *inode = file->f_dentry->d_inode;
+@@ -201,7 +201,7 @@
+
+
+ static loff_t
+-proc_file_lseek(struct file * file, loff_t offset, int orig)
++proc_file_lseek(struct file *file, loff_t offset, int orig)
+ {
+ lock_kernel();
+
+@@ -299,15 +299,16 @@
+ return i;
+ }
+
+-static int proc_readlink(struct dentry *dentry, char *buffer, int buflen)
++static int
++proc_readlink(struct dentry *dentry, char __user *buffer, int buflen)
+ {
+- char *s=PDE(dentry->d_inode)->data;
++ char *s = PDE(dentry->d_inode)->data;
+ return vfs_readlink(dentry, buffer, buflen, s);
+ }
+
+ static int proc_follow_link(struct dentry *dentry, struct nameidata *nd)
+ {
+- char *s=PDE(dentry->d_inode)->data;
++ char *s = PDE(dentry->d_inode)->data;
+ return vfs_follow_link(nd, s);
+ }
+
+Index: linux-2.6.0-test5/fs/proc/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/proc/inode.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/proc/inode.c 2003-09-27 11:38:39.194569904 +0800
+@@ -14,6 +14,7 @@
+ #include <linux/limits.h>
+ #include <linux/init.h>
+ #include <linux/module.h>
++#include <linux/parser.h>
+ #include <linux/smp_lock.h>
+ #include <linux/init.h>
+
+@@ -136,34 +137,47 @@
+ .statfs = simple_statfs,
+ };
+
++enum {
++ Opt_uid, Opt_gid, Opt_err
++};
++
++static match_table_t tokens = {
++ {Opt_uid, "uid=%u"},
++ {Opt_gid, "gid=%u"},
++ {Opt_err, NULL}
++};
++
+ static int parse_options(char *options,uid_t *uid,gid_t *gid)
+ {
+- char *this_char,*value;
++ char *p;
++ int option;
+
+ *uid = current->uid;
+ *gid = current->gid;
+ if (!options)
+ return 1;
+- while ((this_char = strsep(&options,",")) != NULL) {
+- if (!*this_char)
++
++ while ((p = strsep(&options, ",")) != NULL) {
++ substring_t args[MAX_OPT_ARGS];
++ int token;
++ if (!*p)
+ continue;
+- if ((value = strchr(this_char,'=')) != NULL)
+- *value++ = 0;
+- if (!strcmp(this_char,"uid")) {
+- if (!value || !*value)
+- return 0;
+- *uid = simple_strtoul(value,&value,0);
+- if (*value)
+- return 0;
+- }
+- else if (!strcmp(this_char,"gid")) {
+- if (!value || !*value)
++
++ token = match_token(p, tokens, args);
++ switch (token) {
++ case Opt_uid:
++ if (match_int(args, &option))
+ return 0;
+- *gid = simple_strtoul(value,&value,0);
+- if (*value)
++ *uid = option;
++ break;
++ case Opt_gid:
++ if (match_int(args, &option))
+ return 0;
++ *gid = option;
++ break;
++ default:
++ return 0;
+ }
+- else return 1;
+ }
+ return 1;
+ }
+Index: linux-2.6.0-test5/fs/proc/kcore.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/proc/kcore.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/proc/kcore.c 2003-09-27 11:38:39.198569296 +0800
+@@ -27,7 +27,7 @@
+ return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
+ }
+
+-static ssize_t read_kcore(struct file *, char *, size_t, loff_t *);
++static ssize_t read_kcore(struct file *, char __user *, size_t, loff_t *);
+
+ struct file_operations proc_kcore_operations = {
+ .read = read_kcore,
+@@ -175,6 +175,7 @@
+ elf->e_ident[EI_CLASS] = ELF_CLASS;
+ elf->e_ident[EI_DATA] = ELF_DATA;
+ elf->e_ident[EI_VERSION]= EV_CURRENT;
++ elf->e_ident[EI_OSABI] = ELF_OSABI;
+ memset(elf->e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD);
+ elf->e_type = ET_CORE;
+ elf->e_machine = ELF_ARCH;
+@@ -267,7 +268,8 @@
+ /*
+ * read from the ELF header and then kernel memory
+ */
+-static ssize_t read_kcore(struct file *file, char *buffer, size_t buflen, loff_t *fpos)
++static ssize_t
++read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos)
+ {
+ ssize_t acc = 0;
+ size_t size, tsz;
+Index: linux-2.6.0-test5/fs/proc/kmsg.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/proc/kmsg.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/proc/kmsg.c 2003-09-27 11:38:39.199569144 +0800
+@@ -17,7 +17,7 @@
+
+ extern wait_queue_head_t log_wait;
+
+-extern int do_syslog(int type, char * bug, int count);
++extern int do_syslog(int type, char __user *bug, int count);
+
+ static int kmsg_open(struct inode * inode, struct file * file)
+ {
+@@ -30,13 +30,13 @@
+ return 0;
+ }
+
+-static ssize_t kmsg_read(struct file * file, char * buf,
++static ssize_t kmsg_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+ {
+- return do_syslog(2,buf,count);
++ return do_syslog(2, buf, count);
+ }
+
+-static unsigned int kmsg_poll(struct file *file, poll_table * wait)
++static unsigned int kmsg_poll(struct file *file, poll_table *wait)
+ {
+ poll_wait(file, &log_wait, wait);
+ if (do_syslog(9, 0, 0))
+Index: linux-2.6.0-test5/fs/proc/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/fs/proc/Makefile 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/proc/Makefile 2003-09-27 11:38:39.201568840 +0800
+@@ -8,6 +8,7 @@
+ proc-$(CONFIG_MMU) := task_mmu.o
+
+ proc-y += inode.o root.o base.o generic.o array.o \
+- kmsg.o proc_tty.o proc_misc.o kcore.o
++ kmsg.o proc_tty.o proc_misc.o
+
+-proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o
++proc-$(CONFIG_PROC_KCORE) += kcore.o
++proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o
+Index: linux-2.6.0-test5/fs/proc/proc_misc.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/proc/proc_misc.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/proc/proc_misc.c 2003-09-27 11:38:39.206568080 +0800
+@@ -343,7 +343,7 @@
+ #endif
+
+ extern struct seq_operations slabinfo_op;
+-extern ssize_t slabinfo_write(struct file *, const char *, size_t, loff_t *);
++extern ssize_t slabinfo_write(struct file *, const char __user *, size_t, loff_t *);
+ static int slabinfo_open(struct inode *inode, struct file *file)
+ {
+ return seq_open(file, &slabinfo_op);
+@@ -548,8 +548,8 @@
+ * buffer. Use of the program readprofile is recommended in order to
+ * get meaningful info out of these data.
+ */
+-static ssize_t read_profile(struct file *file, char *buf,
+- size_t count, loff_t *ppos)
++static ssize_t
++read_profile(struct file *file, char __user *buf, size_t count, loff_t *ppos)
+ {
+ unsigned long p = *ppos;
+ ssize_t read;
+@@ -580,13 +580,13 @@
+ * Writing a 'profiling multiplier' value into it also re-sets the profiling
+ * interrupt frequency, on architectures that support this.
+ */
+-static ssize_t write_profile(struct file * file, const char * buf,
++static ssize_t write_profile(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+ {
+ #ifdef CONFIG_SMP
+ extern int setup_profiling_timer (unsigned int multiplier);
+
+- if (count==sizeof(int)) {
++ if (count == sizeof(int)) {
+ unsigned int multiplier;
+
+ if (copy_from_user(&multiplier, buf, sizeof(int)))
+@@ -610,8 +610,8 @@
+ /*
+ * writing 'C' to /proc/sysrq-trigger is like sysrq-C
+ */
+-static ssize_t write_sysrq_trigger(struct file *file, const char *buf,
+- size_t count, loff_t *ppos)
++static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf,
++ size_t count, loff_t *ppos)
+ {
+ if (count) {
+ char c;
+@@ -638,6 +638,36 @@
+ entry->proc_fops = f;
+ }
+
++#ifdef CONFIG_LOCKMETER
++extern ssize_t get_lockmeter_info(char *, size_t, loff_t *);
++extern ssize_t put_lockmeter_info(const char *, size_t);
++extern int get_lockmeter_info_size(void);
++
++/*
++ * This function accesses lock metering information.
++ */
++static ssize_t read_lockmeter(struct file *file, char *buf,
++ size_t count, loff_t *ppos)
++{
++ return get_lockmeter_info(buf, count, ppos);
++}
++
++/*
++ * Writing to /proc/lockmeter resets the counters
++ */
++static ssize_t write_lockmeter(struct file * file, const char * buf,
++ size_t count, loff_t *ppos)
++{
++ return put_lockmeter_info(buf, count);
++}
++
++static struct file_operations proc_lockmeter_operations = {
++ NULL, /* lseek */
++ read: read_lockmeter,
++ write: write_lockmeter,
++};
++#endif /* CONFIG_LOCKMETER */
++
+ void __init proc_misc_init(void)
+ {
+ struct proc_dir_entry *entry;
+@@ -685,12 +715,14 @@
+ #ifdef CONFIG_MODULES
+ create_seq_entry("modules", 0, &proc_modules_operations);
+ #endif
++#ifdef CONFIG_PROC_KCORE
+ proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
+ if (proc_root_kcore) {
+ proc_root_kcore->proc_fops = &proc_kcore_operations;
+ proc_root_kcore->size =
+ (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE;
+ }
++#endif
+ if (prof_on) {
+ entry = create_proc_entry("profile", S_IWUSR | S_IRUGO, NULL);
+ if (entry) {
+@@ -703,6 +735,13 @@
+ if (entry)
+ entry->proc_fops = &proc_sysrq_trigger_operations;
+ #endif
++#ifdef CONFIG_LOCKMETER
++ entry = create_proc_entry("lockmeter", S_IWUSR | S_IRUGO, NULL);
++ if (entry) {
++ entry->proc_fops = &proc_lockmeter_operations;
++ entry->size = get_lockmeter_info_size();
++ }
++#endif
+ #ifdef CONFIG_PPC32
+ {
+ extern struct file_operations ppc_htab_operations;
+Index: linux-2.6.0-test5/fs/reiserfs/file.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/reiserfs/file.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/reiserfs/file.c 2003-09-27 11:38:39.218566256 +0800
+@@ -485,6 +485,11 @@
+ /* Now the final thing, if we have grew the file, we must update it's size*/
+ if ( pos + write_bytes > inode->i_size) {
+ inode->i_size = pos + write_bytes; // Set new size
++ /* If the file have grown so much that tail packing is no longer possible, reset
++ "need to pack" flag */
++ if ( (have_large_tails (inode->i_sb) && inode->i_size > i_block_size (inode)*4) ||
++ (have_small_tails (inode->i_sb) && inode->i_size > i_block_size(inode)) )
++ REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask ;
+ }
+
+ /* Amount of on-disk blocks used by file have changed, update it */
+@@ -779,7 +784,7 @@
+ /* Now if all the write area lies past the file end, no point in
+ maping blocks, since there is none, so we just zero out remaining
+ parts of first and last pages in write area (if needed) */
+- if ( (pos & ~(PAGE_CACHE_SIZE - 1)) > inode->i_size ) {
++ if ( (pos & ~((loff_t)PAGE_CACHE_SIZE - 1)) > inode->i_size ) {
+ if ( from != 0 ) {/* First page needs to be partially zeroed */
+ char *kaddr = kmap_atomic(prepared_pages[0], KM_USER0);
+ memset(kaddr, 0, from);
+@@ -801,9 +806,9 @@
+ we need to allocate (calculated above) */
+ /* Mask write position to start on blocksize, we do it out of the
+ loop for performance reasons */
+- pos &= ~(inode->i_sb->s_blocksize - 1);
++ pos &= ~((loff_t) inode->i_sb->s_blocksize - 1);
+ /* Set cpu key to the starting position in a file (on left block boundary)*/
+- make_cpu_key (&key, inode, 1 + ((pos) & ~(inode->i_sb->s_blocksize - 1)), TYPE_ANY, 3/*key length*/);
++ make_cpu_key (&key, inode, 1 + ((pos) & ~((loff_t) inode->i_sb->s_blocksize - 1)), TYPE_ANY, 3/*key length*/);
+
+ reiserfs_write_lock(inode->i_sb); // We need that for at least search_by_key()
+ for ( i = 0; i < num_pages ; i++ ) {
+@@ -999,9 +1004,41 @@
+ struct page * prepared_pages[REISERFS_WRITE_PAGES_AT_A_TIME];
+ /* To simplify coding at this time, we store
+ locked pages in array for now */
+- if ( count <= PAGE_CACHE_SIZE || file->f_flags & O_DIRECT)
++ if ( count <= PAGE_CACHE_SIZE )
+ return generic_file_write(file, buf, count, ppos);
+
++ if ( file->f_flags & O_DIRECT) { // Direct IO needs some special threating.
++ int result, after_file_end = 0;
++ if ( (*ppos + count >= inode->i_size) || (file->f_flags & O_APPEND) ) {
++ /* If we are appending a file, we need to put this savelink in here.
++ If we will crash while doing direct io, finish_unfinished will
++ cut the garbage from the file end. */
++ struct reiserfs_transaction_handle th;
++ reiserfs_write_lock(inode->i_sb);
++ journal_begin(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT );
++ reiserfs_update_inode_transaction(inode);
++ add_save_link (&th, inode, 1 /* Truncate */);
++ journal_end(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT );
++ reiserfs_write_unlock(inode->i_sb);
++ after_file_end = 1;
++ }
++ result = generic_file_write(file, buf, count, ppos);
++
++ if ( after_file_end ) { /* Now update i_size and remove the savelink */
++ struct reiserfs_transaction_handle th;
++ reiserfs_write_lock(inode->i_sb);
++ journal_begin(&th, inode->i_sb, 1);
++ reiserfs_update_inode_transaction(inode);
++ reiserfs_update_sd(&th, inode);
++ journal_end(&th, inode->i_sb, 1);
++ remove_save_link (inode, 1/* truncate */);
++ reiserfs_write_unlock(inode->i_sb);
++ }
++
++ return result;
++ }
++
++
+ if ( unlikely((ssize_t) count < 0 ))
+ return -EINVAL;
+
+Index: linux-2.6.0-test5/fs/reiserfs/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/reiserfs/inode.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/reiserfs/inode.c 2003-09-27 11:38:39.253560936 +0800
+@@ -306,7 +306,7 @@
+ ** read old data off disk. Set the up to date bit on the buffer instead
+ ** and jump to the end
+ */
+- if (PageUptodate(bh_result->b_page)) {
++ if (!bh_result->b_page || PageUptodate(bh_result->b_page)) {
+ set_buffer_uptodate(bh_result);
+ goto finished ;
+ }
+@@ -420,6 +420,45 @@
+ return reiserfs_get_block(inode, block, bh_result, GET_BLOCK_NO_HOLE) ;
+ }
+
++/* This is special helper for reiserfs_get_block in case we are executing
++ direct_IO request. */
++static int reiserfs_get_blocks_direct_io(struct inode *inode,
++ sector_t iblock,
++ unsigned long max_blocks,
++ struct buffer_head *bh_result,
++ int create)
++{
++ int ret ;
++
++ bh_result->b_page = NULL;
++
++ /* We set the b_size before reiserfs_get_block call since it is
++ referenced in convert_tail_for_hole() that may be called from
++ reiserfs_get_block() */
++ bh_result->b_size = (1 << inode->i_blkbits);
++
++ ret = reiserfs_get_block(inode, iblock, bh_result, create) ;
++
++ /* don't allow direct io onto tail pages */
++ if (ret == 0 && buffer_mapped(bh_result) && bh_result->b_blocknr == 0) {
++ /* make sure future calls to the direct io funcs for this offset
++ ** in the file fail by unmapping the buffer
++ */
++ reiserfs_unmap_buffer(bh_result);
++ ret = -EINVAL ;
++ }
++ /* Possible unpacked tail. Flush the data before pages have
++ disappeared */
++ if (REISERFS_I(inode)->i_flags & i_pack_on_close_mask) {
++ lock_kernel();
++ reiserfs_commit_for_inode(inode);
++ REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask;
++ unlock_kernel();
++ }
++ return ret ;
++}
++
++
+ /*
+ ** helper function for when reiserfs_get_block is called for a hole
+ ** but the file tail is still in a direct item
+@@ -448,7 +487,10 @@
+ tail_end = (tail_start | (bh_result->b_size - 1)) + 1 ;
+
+ index = tail_offset >> PAGE_CACHE_SHIFT ;
+- if (index != hole_page->index) {
++ /* hole_page can be zero in case of direct_io, we are sure
++ that we cannot get here if we write with O_DIRECT into
++ tail page */
++ if (!hole_page || index != hole_page->index) {
+ tail_page = grab_cache_page(inode->i_mapping, index) ;
+ retval = -ENOMEM;
+ if (!tail_page) {
+@@ -554,7 +596,12 @@
+ return ret;
+ }
+
+- REISERFS_I(inode)->i_flags |= i_pack_on_close_mask ;
++ /* If file is of such a size, that it might have a tail and tails are enabled
++ ** we should mark it as possibly needing tail packing on close
++ */
++ if ( (have_large_tails (inode->i_sb) && inode->i_size < i_block_size (inode)*4) ||
++ (have_small_tails (inode->i_sb) && inode->i_size < i_block_size(inode)) )
++ REISERFS_I(inode)->i_flags |= i_pack_on_close_mask ;
+
+ windex = push_journal_writer("reiserfs_get_block") ;
+
+@@ -745,21 +792,26 @@
+ */
+ set_buffer_uptodate (unbh);
+
+- /* we've converted the tail, so we must
+- ** flush unbh before the transaction commits
+- */
+- add_to_flushlist(inode, unbh) ;
+-
+- /* mark it dirty now to prevent commit_write from adding
+- ** this buffer to the inode's dirty buffer list
++ /* unbh->b_page == NULL in case of DIRECT_IO request, this means
++ buffer will disappear shortly, so it should not be added to
+ */
++ if ( unbh->b_page ) {
++ /* we've converted the tail, so we must
++ ** flush unbh before the transaction commits
++ */
++ add_to_flushlist(inode, unbh) ;
++
++ /* mark it dirty now to prevent commit_write from adding
++ ** this buffer to the inode's dirty buffer list
++ */
+ /*
+ * AKPM: changed __mark_buffer_dirty to mark_buffer_dirty().
+ * It's still atomic, but it sets the page dirty too,
+ * which makes it eligible for writeback at any time by the
+ * VM (which was also the case with __mark_buffer_dirty())
+ */
+- mark_buffer_dirty(unbh) ;
++ mark_buffer_dirty(unbh) ;
++ }
+
+ //inode->i_blocks += inode->i_sb->s_blocksize / 512;
+ //mark_tail_converted (inode);
+@@ -1003,7 +1055,7 @@
+ inode->i_mapping->a_ops = &reiserfs_address_space_operations;
+ } else {
+ inode->i_blocks = 0;
+- init_special_inode(inode, inode->i_mode, old_decode_dev(rdev));
++ init_special_inode(inode, inode->i_mode, new_decode_dev(rdev));
+ }
+ }
+
+@@ -1024,7 +1076,7 @@
+ set_sd_v2_ctime(sd_v2, inode->i_ctime.tv_sec );
+ set_sd_v2_blocks(sd_v2, inode->i_blocks );
+ if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
+- set_sd_v2_rdev(sd_v2, old_encode_dev(inode->i_rdev));
++ set_sd_v2_rdev(sd_v2, new_encode_dev(inode->i_rdev));
+ else
+ set_sd_v2_generation(sd_v2, inode->i_generation);
+ flags = REISERFS_I(inode)->i_attrs;
+@@ -1048,7 +1100,7 @@
+ set_sd_v1_mtime(sd_v1, inode->i_mtime.tv_sec );
+
+ if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
+- set_sd_v1_rdev(sd_v1, old_encode_dev(inode->i_rdev));
++ set_sd_v1_rdev(sd_v1, new_encode_dev(inode->i_rdev));
+ else
+ set_sd_v1_blocks(sd_v1, inode->i_blocks );
+
+@@ -2204,6 +2256,13 @@
+ if (pos > inode->i_size) {
+ struct reiserfs_transaction_handle th ;
+ reiserfs_write_lock(inode->i_sb);
++ /* If the file have grown beyond the border where it
++ can have a tail, unmark it as needing a tail
++ packing */
++ if ( (have_large_tails (inode->i_sb) && inode->i_size > i_block_size (inode)*4) ||
++ (have_small_tails (inode->i_sb) && inode->i_size > i_block_size(inode)) )
++ REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask ;
++
+ journal_begin(&th, inode->i_sb, 1) ;
+ reiserfs_update_inode_transaction(inode) ;
+ inode->i_size = pos ;
+@@ -2310,6 +2369,19 @@
+ return ret ;
+ }
+
++/* We thank Mingming Cao for helping us understand in great detail what
++ to do in this section of the code. */
++static int reiserfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
++ loff_t offset, unsigned long nr_segs)
++{
++ struct file *file = iocb->ki_filp;
++ struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
++
++ return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
++ offset, nr_segs, reiserfs_get_blocks_direct_io, NULL);
++}
++
++
+ struct address_space_operations reiserfs_address_space_operations = {
+ .writepage = reiserfs_writepage,
+ .readpage = reiserfs_readpage,
+@@ -2318,5 +2390,6 @@
+ .sync_page = block_sync_page,
+ .prepare_write = reiserfs_prepare_write,
+ .commit_write = reiserfs_commit_write,
+- .bmap = reiserfs_aop_bmap
++ .bmap = reiserfs_aop_bmap,
++ .direct_IO = reiserfs_direct_IO
+ } ;
+Index: linux-2.6.0-test5/fs/reiserfs/ioctl.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/reiserfs/ioctl.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/reiserfs/ioctl.c 2003-09-27 11:38:39.255560632 +0800
+@@ -5,6 +5,7 @@
+ #include <linux/fs.h>
+ #include <linux/reiserfs_fs.h>
+ #include <linux/time.h>
++#include <linux/mount.h>
+ #include <asm/uaccess.h>
+ #include <linux/pagemap.h>
+ #include <linux/smp_lock.h>
+@@ -38,7 +39,7 @@
+ i_attrs_to_sd_attrs( inode, ( __u16 * ) &flags );
+ return put_user(flags, (int *) arg);
+ case REISERFS_IOC_SETFLAGS: {
+- if (IS_RDONLY(inode))
++ if (IS_RDONLY(inode) || MNT_IS_RDONLY(filp->f_vfsmnt))
+ return -EROFS;
+
+ if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+@@ -70,7 +71,7 @@
+ case REISERFS_IOC_SETVERSION:
+ if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+ return -EPERM;
+- if (IS_RDONLY(inode))
++ if (IS_RDONLY(inode) || MNT_IS_RDONLY(filp->f_vfsmnt))
+ return -EROFS;
+ if (get_user(inode->i_generation, (int *) arg))
+ return -EFAULT;
+Index: linux-2.6.0-test5/fs/reiserfs/journal.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/reiserfs/journal.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/reiserfs/journal.c 2003-09-27 11:38:39.284556224 +0800
+@@ -1406,6 +1406,10 @@
+ *newest_mount_id) ;
+ return -1 ;
+ }
++ if ( get_desc_trans_len(desc) > SB_JOURNAL_TRANS_MAX(p_s_sb) ) {
++ reiserfs_warning("journal-2018: Bad transaction length %d encountered, ignoring transaction\n", get_desc_trans_len(desc));
++ return -1 ;
++ }
+ offset = d_bh->b_blocknr - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) ;
+
+ /* ok, we have a journal description block, lets see if the transaction was valid */
+@@ -1422,11 +1426,12 @@
+ get_commit_trans_id (commit),
+ get_commit_trans_len(commit));
+ brelse(c_bh) ;
+- if (oldest_invalid_trans_id)
+- *oldest_invalid_trans_id = get_desc_trans_id(desc) ;
++ if (oldest_invalid_trans_id) {
++ *oldest_invalid_trans_id = get_desc_trans_id(desc) ;
+ reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1004: "
+ "transaction_is_valid setting oldest invalid trans_id "
+ "to %d\n", get_desc_trans_id(desc)) ;
++ }
+ return -1;
+ }
+ brelse(c_bh) ;
+@@ -1527,9 +1532,14 @@
+ } else {
+ real_blocks[i] = sb_getblk(p_s_sb, le32_to_cpu(commit->j_realblock[i - trans_half])) ;
+ }
++ if ( real_blocks[i]->b_blocknr > SB_BLOCK_COUNT(p_s_sb) ) {
++ reiserfs_warning("journal-1207: REPLAY FAILURE fsck required! Block to replay is outside of filesystem\n");
++ goto abort_replay;
++ }
+ /* make sure we don't try to replay onto log or reserved area */
+ if (is_block_in_log_or_reserved_area(p_s_sb, real_blocks[i]->b_blocknr)) {
+ reiserfs_warning("journal-1204: REPLAY FAILURE fsck required! Trying to replay onto a log block\n") ;
++abort_replay:
+ brelse_array(log_blocks, i) ;
+ brelse_array(real_blocks, i) ;
+ brelse(c_bh) ;
+@@ -1906,7 +1916,7 @@
+ journal -> j_dev_bd = NULL;
+ journal -> j_dev_file = NULL;
+ jdev = SB_ONDISK_JOURNAL_DEVICE( super ) ?
+- old_decode_dev(SB_ONDISK_JOURNAL_DEVICE(super)) : super->s_dev;
++ new_decode_dev(SB_ONDISK_JOURNAL_DEVICE(super)) : super->s_dev;
+
+ if (bdev_read_only(super->s_bdev))
+ blkdev_mode = FMODE_READ;
+Index: linux-2.6.0-test5/fs/reiserfs/namei.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/reiserfs/namei.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/reiserfs/namei.c 2003-09-27 11:38:39.295554552 +0800
+@@ -613,7 +613,7 @@
+ struct reiserfs_transaction_handle th ;
+ int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3;
+
+- if (!old_valid_dev(rdev))
++ if (!new_valid_dev(rdev))
+ return -EINVAL;
+
+ if (!(inode = new_inode(dir->i_sb))) {
+Index: linux-2.6.0-test5/fs/reiserfs/procfs.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/reiserfs/procfs.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/reiserfs/procfs.c 2003-09-27 11:38:39.301553640 +0800
+@@ -13,6 +13,7 @@
+ #include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/time.h>
++#include <linux/seq_file.h>
+ #include <asm/uaccess.h>
+ #include <linux/reiserfs_fs.h>
+ #include <linux/reiserfs_fs_sb.h>
+@@ -29,58 +30,10 @@
+ *
+ */
+
+-static struct super_block *procinfo_prologue(dev_t dev)
++static int show_version(struct seq_file *m, struct super_block *sb)
+ {
+- struct super_block *result;
+-
+- /* get super-block by device */
+- result = user_get_super(dev);
+- if( result != NULL ) {
+- if( !is_reiserfs_super( result ) ) {
+- printk( KERN_DEBUG "reiserfs: procfs-52: "
+- "non-reiserfs super found\n" );
+- drop_super( result );
+- result = NULL;
+- }
+- } else
+- printk( KERN_DEBUG "reiserfs: procfs-74: "
+- "race between procinfo and umount\n" );
+- return result;
+-}
+-
+-int procinfo_epilogue( struct super_block *super )
+-{
+- drop_super( super );
+- return 0;
+-}
+-
+-int reiserfs_proc_tail( int len, char *buffer, char **start,
+- off_t offset, int count, int *eof )
+-{
+- /* this is black procfs magic */
+- if( offset >= len ) {
+- *start = buffer;
+- *eof = 1;
+- return 0;
+- }
+- *start = buffer + offset;
+- if( ( len -= offset ) > count ) {
+- return count;
+- }
+- *eof = 1;
+- return len;
+-}
+-
+-int reiserfs_version_in_proc( char *buffer, char **start, off_t offset,
+- int count, int *eof, void *data )
+-{
+- int len = 0;
+- struct super_block *sb;
+ char *format;
+
+- sb = procinfo_prologue((int)data);
+- if( sb == NULL )
+- return -ENOENT;
+ if ( REISERFS_SB(sb)->s_properties & (1 << REISERFS_3_6) ) {
+ format = "3.6";
+ } else if ( REISERFS_SB(sb)->s_properties & (1 << REISERFS_3_5) ) {
+@@ -89,7 +42,7 @@
+ format = "unknown";
+ }
+
+- len += sprintf( &buffer[ len ], "%s format\twith checks %s\n",
++ seq_printf(m, "%s format\twith checks %s\n",
+ format,
+ #if defined( CONFIG_REISERFS_CHECK )
+ "on"
+@@ -97,15 +50,15 @@
+ "off"
+ #endif
+ );
+- procinfo_epilogue( sb );
+- return reiserfs_proc_tail( len, buffer, start, offset, count, eof );
++ return 0;
+ }
+
+ int reiserfs_global_version_in_proc( char *buffer, char **start, off_t offset,
+ int count, int *eof, void *data )
+ {
+- int len = 0;
+- return reiserfs_proc_tail( len, buffer, start, offset, count, eof );
++ *start = buffer;
++ *eof = 1;
++ return 0;
+ }
+
+ #define SF( x ) ( r -> x )
+@@ -129,19 +82,11 @@
+ #define DJP( x ) le32_to_cpu( jp -> x )
+ #define JF( x ) ( r -> s_journal -> x )
+
+-int reiserfs_super_in_proc( char *buffer, char **start, off_t offset,
+- int count, int *eof, void *data )
++static int show_super(struct seq_file *m, struct super_block *sb)
+ {
+- struct super_block *sb;
+- struct reiserfs_sb_info *r;
+- int len = 0;
++ struct reiserfs_sb_info *r = REISERFS_SB(sb);
+
+- sb = procinfo_prologue((int)data);
+- if( sb == NULL )
+- return -ENOENT;
+- r = REISERFS_SB(sb);
+- len += sprintf( &buffer[ len ],
+- "state: \t%s\n"
++ seq_printf(m, "state: \t%s\n"
+ "mount options: \t%s%s%s%s%s%s%s%s%s%s%s%s\n"
+ "gen. counter: \t%i\n"
+ "s_kmallocs: \t%i\n"
+@@ -217,25 +162,15 @@
+ SFP( leaked_oid ),
+ SFP( leaves_removable ) );
+
+- procinfo_epilogue( sb );
+- return reiserfs_proc_tail( len, buffer, start, offset, count, eof );
++ return 0;
+ }
+
+-int reiserfs_per_level_in_proc( char *buffer, char **start, off_t offset,
+- int count, int *eof, void *data )
++static int show_per_level(struct seq_file *m, struct super_block *sb)
+ {
+- struct super_block *sb;
+- struct reiserfs_sb_info *r;
+- int len = 0;
++ struct reiserfs_sb_info *r = REISERFS_SB(sb);
+ int level;
+-
+- sb = procinfo_prologue((int)data);
+- if( sb == NULL )
+- return -ENOENT;
+- r = REISERFS_SB(sb);
+
+- len += sprintf( &buffer[ len ],
+- "level\t"
++ seq_printf(m, "level\t"
+ " balances"
+ " [sbk: reads"
+ " fs_changed"
+@@ -256,12 +191,7 @@
+ );
+
+ for( level = 0 ; level < MAX_HEIGHT ; ++ level ) {
+- if( len > PAGE_SIZE - 240 ) {
+- len += sprintf( &buffer[ len ], "... and more\n" );
+- break;
+- }
+- len += sprintf( &buffer[ len ],
+- "%i\t"
++ seq_printf(m, "%i\t"
+ " %12lu"
+ " %12lu"
+ " %12lu"
+@@ -296,24 +226,14 @@
+ SFPL( need_r_neighbor )
+ );
+ }
+-
+- procinfo_epilogue( sb );
+- return reiserfs_proc_tail( len, buffer, start, offset, count, eof );
++ return 0;
+ }
+
+-int reiserfs_bitmap_in_proc( char *buffer, char **start, off_t offset,
+- int count, int *eof, void *data )
++static int show_bitmap(struct seq_file *m, struct super_block *sb)
+ {
+- struct super_block *sb;
+- struct reiserfs_sb_info *r;
+- int len = 0;
+-
+- sb = procinfo_prologue((int)data);
+- if( sb == NULL )
+- return -ENOENT;
+- r = REISERFS_SB(sb);
++ struct reiserfs_sb_info *r = REISERFS_SB(sb);
+
+- len += sprintf( &buffer[ len ], "free_block: %lu\n"
++ seq_printf(m, "free_block: %lu\n"
+ " scan_bitmap:"
+ " wait"
+ " bmap"
+@@ -339,30 +259,17 @@
+ SFPF( in_journal_hint ),
+ SFPF( in_journal_nohint ) );
+
+- procinfo_epilogue( sb );
+- return reiserfs_proc_tail( len, buffer, start, offset, count, eof );
++ return 0;
+ }
+
+-int reiserfs_on_disk_super_in_proc( char *buffer, char **start, off_t offset,
+- int count, int *eof, void *data )
++static int show_on_disk_super(struct seq_file *m, struct super_block *sb)
+ {
+- struct super_block *sb;
+- struct reiserfs_sb_info *sb_info;
+- struct reiserfs_super_block *rs;
+- int hash_code;
+- __u32 flags;
+- int len = 0;
+-
+- sb = procinfo_prologue((int)data);
+- if( sb == NULL )
+- return -ENOENT;
+- sb_info = REISERFS_SB(sb);
+- rs = sb_info -> s_rs;
+- hash_code = DFL( s_hash_function_code );
+- flags = DJF( s_flags );
++ struct reiserfs_sb_info *sb_info = REISERFS_SB(sb);
++ struct reiserfs_super_block *rs = sb_info -> s_rs;
++ int hash_code = DFL( s_hash_function_code );
++ __u32 flags = DJF( s_flags );
+
+- len += sprintf( &buffer[ len ],
+- "block_count: \t%i\n"
++ seq_printf(m, "block_count: \t%i\n"
+ "free_blocks: \t%i\n"
+ "root_block: \t%i\n"
+ "blocksize: \t%i\n"
+@@ -399,84 +306,49 @@
+ ? "attrs_cleared" : "",
+ DF (s_reserved_for_journal));
+
+- procinfo_epilogue( sb );
+- return reiserfs_proc_tail( len, buffer, start, offset, count, eof );
++ return 0;
+ }
+
+-int reiserfs_oidmap_in_proc( char *buffer, char **start, off_t offset,
+- int count, int *eof, void *data )
++static int show_oidmap(struct seq_file *m, struct super_block *sb)
+ {
+- struct super_block *sb;
+- struct reiserfs_sb_info *sb_info;
+- struct reiserfs_super_block *rs;
++ struct reiserfs_sb_info *sb_info = REISERFS_SB(sb);
++ struct reiserfs_super_block *rs = sb_info -> s_rs;
++ unsigned int mapsize = le16_to_cpu( rs -> s_v1.s_oid_cursize );
++ unsigned long total_used = 0;
+ int i;
+- unsigned int mapsize;
+- unsigned long total_used;
+- int len = 0;
+- int exact;
+-
+- sb = procinfo_prologue((int)data);
+- if( sb == NULL )
+- return -ENOENT;
+- sb_info = REISERFS_SB(sb);
+- rs = sb_info -> s_rs;
+- mapsize = le16_to_cpu( rs -> s_v1.s_oid_cursize );
+- total_used = 0;
+
+ for( i = 0 ; i < mapsize ; ++i ) {
+ __u32 right;
+
+ right = ( i == mapsize - 1 ) ? MAX_KEY_OBJECTID : MAP( i + 1 );
+- len += sprintf( &buffer[ len ], "%s: [ %x .. %x )\n",
++ seq_printf(m, "%s: [ %x .. %x )\n",
+ ( i & 1 ) ? "free" : "used", MAP( i ), right );
+ if( ! ( i & 1 ) ) {
+ total_used += right - MAP( i );
+ }
+- if( len > PAGE_SIZE - 100 ) {
+- len += sprintf( &buffer[ len ], "... and more\n" );
+- break;
+- }
+ }
+ #if defined( REISERFS_USE_OIDMAPF )
+ if( sb_info -> oidmap.use_file && ( sb_info -> oidmap.mapf != NULL ) ) {
+- loff_t size;
+-
+- size = sb_info -> oidmap.mapf -> f_dentry -> d_inode -> i_size;
++ loff_t size = sb_info->oidmap.mapf->f_dentry->d_inode->i_size;
+ total_used += size / sizeof( reiserfs_oidinterval_d_t );
+- exact = 1;
+- } else
+-#endif
+- {
+- exact = ( i == mapsize );
+ }
+- len += sprintf( &buffer[ len ], "total: \t%i [%i/%i] used: %lu [%s]\n",
+- i,
++#endif
++ seq_printf(m, "total: \t%i [%i/%i] used: %lu [exact]\n",
++ mapsize,
+ mapsize, le16_to_cpu( rs -> s_v1.s_oid_maxsize ),
+- total_used, exact ? "exact" : "estimation" );
+-
+- procinfo_epilogue( sb );
+- return reiserfs_proc_tail( len, buffer, start, offset, count, eof );
++ total_used);
++ return 0;
+ }
+
+-int reiserfs_journal_in_proc( char *buffer, char **start, off_t offset,
+- int count, int *eof, void *data )
++static int show_journal(struct seq_file *m, struct super_block *sb)
+ {
+- struct super_block *sb;
+- struct reiserfs_sb_info *r;
+- struct reiserfs_super_block *rs;
+- struct journal_params *jp;
+- int len = 0;
++ struct reiserfs_sb_info *r = REISERFS_SB(sb);
++ struct reiserfs_super_block *rs = r -> s_rs;
++ struct journal_params *jp = &rs->s_v1.s_journal;
+ char b[BDEVNAME_SIZE];
+
+- sb = procinfo_prologue((int)data);
+- if( sb == NULL )
+- return -ENOENT;
+- r = REISERFS_SB(sb);
+- rs = r -> s_rs;
+- jp = &rs->s_v1.s_journal;
+
+- len += sprintf( &buffer[ len ],
+- /* on-disk fields */
++ seq_printf(m, /* on-disk fields */
+ "jp_journal_1st_block: \t%i\n"
+ "jp_journal_dev: \t%s[%x]\n"
+ "jp_journal_size: \t%i\n"
+@@ -567,21 +439,115 @@
+ SFPJ( prepare ),
+ SFPJ( prepare_retry )
+ );
++ return 0;
++}
++
++/* iterator */
++static int test_sb(struct super_block *sb, void *data)
++{
++ return data == sb;
++}
++
++static int set_sb(struct super_block *sb, void *data)
++{
++ return -ENOENT;
++}
++
++static void *r_start(struct seq_file *m, loff_t *pos)
++{
++ struct proc_dir_entry *de = m->private;
++ struct super_block *s = de->parent->data;
++ loff_t l = *pos;
++
++ if (l)
++ return NULL;
++
++ if (IS_ERR(sget(&reiserfs_fs_type, test_sb, set_sb, s)))
++ return NULL;
++
++ up_write(&s->s_umount);
+
+- procinfo_epilogue( sb );
+- return reiserfs_proc_tail( len, buffer, start, offset, count, eof );
++ if (de->deleted) {
++ deactivate_super(s);
++ return NULL;
++ }
++
++ return s;
++}
++
++static void *r_next(struct seq_file *m, void *v, loff_t *pos)
++{
++ ++*pos;
++ return NULL;
++}
++
++static void r_stop(struct seq_file *m, void *v)
++{
++ struct proc_dir_entry *de = m->private;
++ struct super_block *s = de->data;
++ deactivate_super(s);
++}
++
++static int r_show(struct seq_file *m, void *v)
++{
++ struct proc_dir_entry *de = m->private;
++ int (*show)(struct seq_file *, struct super_block *) = de->data;
++ return show(m, v);
++}
++
++static struct seq_operations r_ops = {
++ .start = r_start,
++ .next = r_next,
++ .stop = r_stop,
++ .show = r_show,
++};
++
++static int r_open(struct inode *inode, struct file *file)
++{
++ int ret = seq_open(file, &r_ops);
++
++ if (!ret) {
++ struct seq_file *m = file->private_data;
++ m->private = PDE(inode);
++ }
++ return ret;
+ }
+
++static struct file_operations r_file_operations = {
++ .open = r_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = seq_release,
++};
+
+ static struct proc_dir_entry *proc_info_root = NULL;
+ static const char proc_info_root_name[] = "fs/reiserfs";
+
++static void add_file(struct super_block *sb, char *name,
++ int (*func)(struct seq_file *, struct super_block *))
++{
++ struct proc_dir_entry *de;
++ de = create_proc_entry(name, 0, REISERFS_SB(sb)->procdir);
++ if (de) {
++ de->data = func;
++ de->proc_fops = &r_file_operations;
++ }
++}
++
+ int reiserfs_proc_info_init( struct super_block *sb )
+ {
+ spin_lock_init( & __PINFO( sb ).lock );
+ REISERFS_SB(sb)->procdir = proc_mkdir(reiserfs_bdevname (sb), proc_info_root);
+ if( REISERFS_SB(sb)->procdir ) {
+- REISERFS_SB(sb)->procdir -> owner = THIS_MODULE;
++ REISERFS_SB(sb)->procdir->owner = THIS_MODULE;
++ REISERFS_SB(sb)->procdir->data = sb;
++ add_file(sb, "version", show_version);
++ add_file(sb, "super", show_super);
++ add_file(sb, "per-level", show_per_level);
++ add_file(sb, "bitmap", show_bitmap);
++ add_file(sb, "on-disk-super", show_on_disk_super);
++ add_file(sb, "oidmap", show_oidmap);
++ add_file(sb, "journal", show_journal);
+ return 0;
+ }
+ reiserfs_warning( "reiserfs: cannot create /proc/%s/%s\n",
+@@ -589,9 +555,18 @@
+ return 1;
+ }
+
+-
+ int reiserfs_proc_info_done( struct super_block *sb )
+ {
++ struct proc_dir_entry *de = REISERFS_SB(sb)->procdir;
++ if (de) {
++ remove_proc_entry("journal", de);
++ remove_proc_entry("oidmap", de);
++ remove_proc_entry("on-disk-super", de);
++ remove_proc_entry("bitmap", de);
++ remove_proc_entry("per-level", de);
++ remove_proc_entry("super", de);
++ remove_proc_entry("version", de);
++ }
+ spin_lock( & __PINFO( sb ).lock );
+ __PINFO( sb ).exiting = 1;
+ spin_unlock( & __PINFO( sb ).lock );
+@@ -602,23 +577,6 @@
+ return 0;
+ }
+
+-/* Create /proc/fs/reiserfs/DEV/name and attach read procedure @func
+- to it. Other parts of reiserfs use this function to make their
+- per-device statistics available via /proc */
+-
+-struct proc_dir_entry *reiserfs_proc_register( struct super_block *sb,
+- char *name, read_proc_t *func )
+-{
+- return ( REISERFS_SB(sb)->procdir ) ? create_proc_read_entry
+- ( name, 0, REISERFS_SB(sb)->procdir, func,
+- ( void * )(int) sb->s_bdev->bd_dev) : NULL;
+-}
+-
+-void reiserfs_proc_unregister( struct super_block *sb, const char *name )
+-{
+- remove_proc_entry( name, REISERFS_SB(sb)->procdir );
+-}
+-
+ struct proc_dir_entry *reiserfs_proc_register_global( char *name,
+ read_proc_t *func )
+ {
+@@ -662,14 +620,6 @@
+ int reiserfs_proc_info_init( struct super_block *sb ) { return 0; }
+ int reiserfs_proc_info_done( struct super_block *sb ) { return 0; }
+
+-struct proc_dir_entry *reiserfs_proc_register( struct super_block *sb,
+- char *name,
+- read_proc_t *func )
+-{ return NULL; }
+-
+-void reiserfs_proc_unregister( struct super_block *sb, const char *name )
+-{;}
+-
+ struct proc_dir_entry *reiserfs_proc_register_global( char *name,
+ read_proc_t *func )
+ { return NULL; }
+@@ -684,34 +634,6 @@
+ int count, int *eof, void *data )
+ { return 0; }
+
+-int reiserfs_version_in_proc( char *buffer, char **start, off_t offset,
+- int count, int *eof, void *data )
+-{ return 0; }
+-
+-int reiserfs_super_in_proc( char *buffer, char **start, off_t offset,
+- int count, int *eof, void *data )
+-{ return 0; }
+-
+-int reiserfs_per_level_in_proc( char *buffer, char **start, off_t offset,
+- int count, int *eof, void *data )
+-{ return 0; }
+-
+-int reiserfs_bitmap_in_proc( char *buffer, char **start, off_t offset,
+- int count, int *eof, void *data )
+-{ return 0; }
+-
+-int reiserfs_on_disk_super_in_proc( char *buffer, char **start, off_t offset,
+- int count, int *eof, void *data )
+-{ return 0; }
+-
+-int reiserfs_oidmap_in_proc( char *buffer, char **start, off_t offset,
+- int count, int *eof, void *data )
+-{ return 0; }
+-
+-int reiserfs_journal_in_proc( char *buffer, char **start, off_t offset,
+- int count, int *eof, void *data )
+-{ return 0; }
+-
+ /* REISERFS_PROC_INFO */
+ #endif
+
+Index: linux-2.6.0-test5/fs/reiserfs/super.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/reiserfs/super.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/reiserfs/super.c 2003-09-27 11:38:39.314551664 +0800
+@@ -23,7 +23,7 @@
+ #include <linux/buffer_head.h>
+ #include <linux/vfs.h>
+
+-static struct file_system_type reiserfs_fs_type;
++struct file_system_type reiserfs_fs_type;
+
+ const char reiserfs_3_5_magic_string[] = REISERFS_SUPER_MAGIC_STRING;
+ const char reiserfs_3_6_magic_string[] = REISER2FS_SUPER_MAGIC_STRING;
+@@ -56,11 +56,6 @@
+ is_reiserfs_jr (rs));
+ }
+
+-int is_reiserfs_super (struct super_block *s)
+-{
+- return s -> s_type == & reiserfs_fs_type ;
+-}
+-
+ static int reiserfs_remount (struct super_block * s, int * flags, char * data);
+ static int reiserfs_statfs (struct super_block * s, struct kstatfs * buf);
+
+@@ -391,13 +386,6 @@
+ REISERFS_SB(s)->reserved_blocks);
+ }
+
+- reiserfs_proc_unregister( s, "journal" );
+- reiserfs_proc_unregister( s, "oidmap" );
+- reiserfs_proc_unregister( s, "on-disk-super" );
+- reiserfs_proc_unregister( s, "bitmap" );
+- reiserfs_proc_unregister( s, "per-level" );
+- reiserfs_proc_unregister( s, "super" );
+- reiserfs_proc_unregister( s, "version" );
+ reiserfs_proc_info_done( s );
+
+ kfree(s->s_fs_info);
+@@ -1264,6 +1252,18 @@
+ printk("sh-2021: reiserfs_fill_super: can not find reiserfs on %s\n", reiserfs_bdevname (s));
+ goto error;
+ }
++
++ rs = SB_DISK_SUPER_BLOCK (s);
++ /* Let's do basic sanity check to verify that underlying device is not
++ smaller than the filesystem. If the check fails then abort and scream,
++ because bad stuff will happen otherwise. */
++ if ( s->s_bdev && s->s_bdev->bd_inode && i_size_read(s->s_bdev->bd_inode) < sb_block_count(rs)*sb_blocksize(rs) ) {
++ printk("Filesystem on %s cannot be mounted because it is bigger than the device\n", reiserfs_bdevname(s));
++ printk("You may need to run fsck or increase size of your LVM partition\n");
++ printk("Or may be you forgot to reboot after fdisk when it told you to\n");
++ goto error;
++ }
++
+ sbi->s_mount_state = SB_REISERFS_STATE(s);
+ sbi->s_mount_state = REISERFS_VALID_FS ;
+
+@@ -1324,7 +1324,6 @@
+ goto error ;
+ }
+
+- rs = SB_DISK_SUPER_BLOCK (s);
+ if (is_reiserfs_3_5 (rs) || (is_reiserfs_jr (rs) && SB_VERSION (s) == REISERFS_VERSION_1))
+ set_bit(REISERFS_3_5, &(sbi->s_properties));
+ else
+@@ -1378,13 +1377,7 @@
+ handle_attrs( s );
+
+ reiserfs_proc_info_init( s );
+- reiserfs_proc_register( s, "version", reiserfs_version_in_proc );
+- reiserfs_proc_register( s, "super", reiserfs_super_in_proc );
+- reiserfs_proc_register( s, "per-level", reiserfs_per_level_in_proc );
+- reiserfs_proc_register( s, "bitmap", reiserfs_bitmap_in_proc );
+- reiserfs_proc_register( s, "on-disk-super", reiserfs_on_disk_super_in_proc );
+- reiserfs_proc_register( s, "oidmap", reiserfs_oidmap_in_proc );
+- reiserfs_proc_register( s, "journal", reiserfs_journal_in_proc );
++
+ init_waitqueue_head (&(sbi->s_wait));
+ sbi->bitmap_lock = SPIN_LOCK_UNLOCKED;
+
+@@ -1469,7 +1462,7 @@
+ destroy_inodecache ();
+ }
+
+-static struct file_system_type reiserfs_fs_type = {
++struct file_system_type reiserfs_fs_type = {
+ .owner = THIS_MODULE,
+ .name = "reiserfs",
+ .get_sb = get_super_block,
+Index: linux-2.6.0-test5/fs/reiserfs/tail_conversion.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/reiserfs/tail_conversion.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/reiserfs/tail_conversion.c 2003-09-27 11:38:39.317551208 +0800
+@@ -104,8 +104,10 @@
+ /* we only send the unbh pointer if the buffer is not up to date.
+ ** this avoids overwriting good data from writepage() with old data
+ ** from the disk or buffer cache
++ ** Special case: unbh->b_page will be NULL if we are coming through
++ ** DIRECT_IO handler here.
+ */
+- if (buffer_uptodate(unbh) || PageUptodate(unbh->b_page)) {
++ if (!unbh->b_page || buffer_uptodate(unbh) || PageUptodate(unbh->b_page)) {
+ up_to_date_bh = NULL ;
+ } else {
+ up_to_date_bh = unbh ;
+Index: linux-2.6.0-test5/fs/smbfs/dir.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/smbfs/dir.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/smbfs/dir.c 2003-09-27 11:38:39.321550600 +0800
+@@ -661,7 +661,7 @@
+ attr.ia_uid = current->euid;
+ attr.ia_gid = current->egid;
+
+- if (!old_valid_dev(dev))
++ if (!new_valid_dev(dev))
+ return -EINVAL;
+
+ smb_invalid_dir_cache(dir);
+Index: linux-2.6.0-test5/fs/smbfs/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/smbfs/inode.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/smbfs/inode.c 2003-09-27 11:38:39.327549688 +0800
+@@ -25,6 +25,7 @@
+ #include <linux/mount.h>
+ #include <linux/net.h>
+ #include <linux/vfs.h>
++#include <linux/highuid.h>
+ #include <linux/smb_fs.h>
+ #include <linux/smbno.h>
+ #include <linux/smb_mount.h>
+@@ -447,6 +448,19 @@
+ }
+
+ static void
++smb_unload_nls(struct smb_sb_info *server)
++{
++ if (server->remote_nls) {
++ unload_nls(server->remote_nls);
++ server->remote_nls = NULL;
++ }
++ if (server->local_nls) {
++ unload_nls(server->local_nls);
++ server->local_nls = NULL;
++ }
++}
++
++static void
+ smb_put_super(struct super_block *sb)
+ {
+ struct smb_sb_info *server = SMB_SB(sb);
+@@ -461,15 +475,7 @@
+ kill_proc(server->conn_pid, SIGTERM, 1);
+
+ smb_kfree(server->ops);
+-
+- if (server->remote_nls) {
+- unload_nls(server->remote_nls);
+- server->remote_nls = NULL;
+- }
+- if (server->local_nls) {
+- unload_nls(server->local_nls);
+- server->local_nls = NULL;
+- }
++ smb_unload_nls(server);
+ sb->s_fs_info = NULL;
+ smb_unlock_server(server);
+ smb_kfree(server);
+@@ -545,10 +551,8 @@
+ if (ver == SMB_MOUNT_OLDVERSION) {
+ mnt->version = oldmnt->version;
+
+- /* FIXME: is this enough to convert uid/gid's ? */
+- mnt->mounted_uid = oldmnt->mounted_uid;
+- mnt->uid = oldmnt->uid;
+- mnt->gid = oldmnt->gid;
++ mnt->uid = low2highuid(oldmnt->uid);
++ mnt->gid = low2highuid(oldmnt->gid);
+
+ mnt->file_mode = (oldmnt->file_mode & S_IRWXUGO) | S_IFREG;
+ mnt->dir_mode = (oldmnt->dir_mode & S_IRWXUGO) | S_IFDIR;
+@@ -557,9 +561,8 @@
+ } else {
+ if (parse_options(mnt, raw_data))
+ goto out_bad_option;
+-
+- mnt->mounted_uid = current->uid;
+ }
++ mnt->mounted_uid = current->uid;
+ smb_setcodepage(server, &mnt->codepage);
+
+ /*
+@@ -571,6 +574,11 @@
+ else if (mnt->flags & SMB_MOUNT_DIRATTR)
+ printk("SMBFS: Using dir ff getattr\n");
+
++ if (smbiod_register_server(server) < 0) {
++ printk(KERN_ERR "smbfs: failed to start smbiod\n");
++ goto out_no_smbiod;
++ }
++
+ /*
+ * Keep the super block locked while we get the root inode.
+ */
+@@ -584,12 +592,12 @@
+ goto out_no_root;
+ smb_new_dentry(sb->s_root);
+
+- smbiod_register_server(server);
+-
+ return 0;
+
+ out_no_root:
+ iput(root_inode);
++out_no_smbiod:
++ smb_unload_nls(server);
+ out_bad_option:
+ smb_kfree(mem);
+ out_no_mem:
+Index: linux-2.6.0-test5/fs/smbfs/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/fs/smbfs/Makefile 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/smbfs/Makefile 2003-09-27 11:38:39.328549536 +0800
+@@ -32,6 +32,8 @@
+ @echo >> proto2.h " */"
+ @echo >> proto2.h ""
+ @echo >> proto2.h "struct smb_request;"
++ @echo >> proto2.h "struct sock;"
++ @echo >> proto2.h "struct statfs;"
+ @echo >> proto2.h ""
+ cproto -E "gcc -E" -e -v -I $(TOPDIR)/include -DMAKING_PROTO -D__KERNEL__ $(SRC) >> proto2.h
+ mv proto2.h proto.h
+Index: linux-2.6.0-test5/fs/smbfs/proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/smbfs/proc.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/smbfs/proc.c 2003-09-27 11:38:39.350546192 +0800
+@@ -212,12 +212,9 @@
+ }
+
+ static struct nls_table unicode_table = {
+- "unicode",
+- uni2char,
+- char2uni,
+- NULL, /* not used by smbfs */
+- NULL,
+- NULL, /* not a module */
++ .charset = "unicode",
++ .uni2char = uni2char,
++ .char2uni = char2uni,
+ };
+
+ /* ----------------------------------------------------------- */
+@@ -2115,6 +2112,9 @@
+ __u64 minor = LVAL(p, 68);
+
+ fattr->f_rdev = MKDEV(major & 0xffffffff, minor & 0xffffffff);
++ if (MAJOR(fattr->f_rdev) != (major & 0xffffffff) ||
++ MINOR(fattr->f_rdev) != (minor & 0xffffffff))
++ fattr->f_rdev = 0;
+ }
+ fattr->f_mode |= LVAL(p, 84);
+ }
+Index: linux-2.6.0-test5/fs/smbfs/proto.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/smbfs/proto.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/smbfs/proto.h 2003-09-27 11:38:39.353545736 +0800
+@@ -1,5 +1,5 @@
+ /*
+- * Autogenerated with cproto on: Sun Sep 29 21:48:59 CEST 2002
++ * Autogenerated with cproto on: Sat Sep 13 17:18:51 CEST 2003
+ */
+
+ struct smb_request;
+@@ -34,6 +34,7 @@
+ extern int smb_proc_symlink(struct smb_sb_info *server, struct dentry *d, const char *oldpath);
+ extern int smb_proc_link(struct smb_sb_info *server, struct dentry *dentry, struct dentry *new_dentry);
+ extern int smb_proc_query_cifsunix(struct smb_sb_info *server);
++extern void smb_install_null_ops(struct smb_ops *ops);
+ /* dir.c */
+ extern struct file_operations smb_dir_operations;
+ extern struct inode_operations smb_dir_inode_operations;
+@@ -71,7 +72,7 @@
+ extern int smb_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
+ /* smbiod.c */
+ extern void smbiod_wake_up(void);
+-extern void smbiod_register_server(struct smb_sb_info *server);
++extern int smbiod_register_server(struct smb_sb_info *server);
+ extern void smbiod_unregister_server(struct smb_sb_info *server);
+ extern void smbiod_flush(struct smb_sb_info *server);
+ extern int smbiod_retry(struct smb_sb_info *server);
+Index: linux-2.6.0-test5/fs/smbfs/smbiod.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/smbfs/smbiod.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/smbfs/smbiod.c 2003-09-27 11:38:39.355545432 +0800
+@@ -49,7 +49,7 @@
+ static long smbiod_flags;
+
+ static int smbiod(void *);
+-static void smbiod_start(void);
++static int smbiod_start(void);
+
+ /*
+ * called when there's work for us to do
+@@ -65,30 +65,36 @@
+ /*
+ * start smbiod if none is running
+ */
+-static void smbiod_start()
++static int smbiod_start()
+ {
+ pid_t pid;
+ if (smbiod_state != SMBIOD_DEAD)
+- return;
++ return 0;
+ smbiod_state = SMBIOD_STARTING;
++ __module_get(THIS_MODULE);
+ spin_unlock(&servers_lock);
+ pid = kernel_thread(smbiod, NULL, 0);
++ if (pid < 0)
++ module_put(THIS_MODULE);
+
+ spin_lock(&servers_lock);
+- smbiod_state = SMBIOD_RUNNING;
++ smbiod_state = pid < 0 ? SMBIOD_DEAD : SMBIOD_RUNNING;
+ smbiod_pid = pid;
++ return pid;
+ }
+
+ /*
+ * register a server & start smbiod if necessary
+ */
+-void smbiod_register_server(struct smb_sb_info *server)
++int smbiod_register_server(struct smb_sb_info *server)
+ {
++ int ret;
+ spin_lock(&servers_lock);
+ list_add(&server->entry, &smb_servers);
+ VERBOSE("%p\n", server);
+- smbiod_start();
++ ret = smbiod_start();
+ spin_unlock(&servers_lock);
++ return ret;
+ }
+
+ /*
+@@ -282,7 +288,6 @@
+ */
+ static int smbiod(void *unused)
+ {
+- MOD_INC_USE_COUNT;
+ daemonize("smbiod");
+
+ allow_signal(SIGKILL);
+@@ -330,6 +335,5 @@
+ }
+
+ VERBOSE("SMB Kernel thread exiting (%d) ...\n", current->pid);
+- MOD_DEC_USE_COUNT;
+- return 0;
++ module_put_and_exit(0);
+ }
+Index: linux-2.6.0-test5/fs/stat.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/stat.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/stat.c 2003-09-27 11:38:39.359544824 +0800
+@@ -117,13 +117,13 @@
+ }
+
+ memset(&tmp, 0, sizeof(struct __old_kernel_stat));
+- tmp.st_dev = stat->dev;
++ tmp.st_dev = old_encode_dev(stat->dev);
+ tmp.st_ino = stat->ino;
+ tmp.st_mode = stat->mode;
+ tmp.st_nlink = stat->nlink;
+ SET_OLDSTAT_UID(tmp, stat->uid);
+ SET_OLDSTAT_GID(tmp, stat->gid);
+- tmp.st_rdev = stat->rdev;
++ tmp.st_rdev = old_encode_dev(stat->rdev);
+ #if BITS_PER_LONG == 32
+ if (stat->size > MAX_NON_LFS)
+ return -EOVERFLOW;
+@@ -172,14 +172,30 @@
+ {
+ struct stat tmp;
+
++#if BITS_PER_LONG == 32
++ if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev))
++ return -EOVERFLOW;
++#else
++ if (!new_valid_dev(stat->dev) || !new_valid_dev(stat->rdev))
++ return -EOVERFLOW;
++#endif
++
+ memset(&tmp, 0, sizeof(tmp));
+- tmp.st_dev = stat->dev;
++#if BITS_PER_LONG == 32
++ tmp.st_dev = old_encode_dev(stat->dev);
++#else
++ tmp.st_dev = new_encode_dev(stat->dev);
++#endif
+ tmp.st_ino = stat->ino;
+ tmp.st_mode = stat->mode;
+ tmp.st_nlink = stat->nlink;
+ SET_STAT_UID(tmp, stat->uid);
+ SET_STAT_GID(tmp, stat->gid);
+- tmp.st_rdev = stat->rdev;
++#if BITS_PER_LONG == 32
++ tmp.st_rdev = old_encode_dev(stat->rdev);
++#else
++ tmp.st_rdev = new_encode_dev(stat->rdev);
++#endif
+ #if BITS_PER_LONG == 32
+ if (stat->size > MAX_NON_LFS)
+ return -EOVERFLOW;
+@@ -263,7 +279,16 @@
+ struct stat64 tmp;
+
+ memset(&tmp, 0, sizeof(struct stat64));
+- tmp.st_dev = stat->dev;
++#ifdef CONFIG_MIPS
++ /* mips has weird padding, so we don't get 64 bits there */
++ if (!new_valid_dev(stat->dev) || !new_valid_dev(stat->rdev))
++ return -EOVERFLOW;
++ tmp.st_dev = new_encode_dev(stat->dev);
++ tmp.st_rdev = new_encode_dev(stat->rdev);
++#else
++ tmp.st_dev = huge_encode_dev(stat->dev);
++ tmp.st_rdev = huge_encode_dev(stat->rdev);
++#endif
+ tmp.st_ino = stat->ino;
+ #ifdef STAT64_HAS_BROKEN_ST_INO
+ tmp.__st_ino = stat->ino;
+@@ -272,7 +297,6 @@
+ tmp.st_nlink = stat->nlink;
+ tmp.st_uid = stat->uid;
+ tmp.st_gid = stat->gid;
+- tmp.st_rdev = stat->rdev;
+ tmp.st_atime = stat->atime.tv_sec;
+ tmp.st_atime_nsec = stat->atime.tv_nsec;
+ tmp.st_mtime = stat->mtime.tv_sec;
+Index: linux-2.6.0-test5/fs/super.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/super.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/super.c 2003-09-27 11:38:39.364544064 +0800
+@@ -405,14 +405,14 @@
+ return NULL;
+ }
+
+-asmlinkage long sys_ustat(dev_t dev, struct ustat __user * ubuf)
++asmlinkage long sys_ustat(unsigned dev, struct ustat __user * ubuf)
+ {
+ struct super_block *s;
+ struct ustat tmp;
+ struct kstatfs sbuf;
+ int err = -EINVAL;
+
+- s = user_get_super(dev);
++ s = user_get_super(new_decode_dev(dev));
+ if (s == NULL)
+ goto out;
+ err = vfs_statfs(s, &sbuf);
+Index: linux-2.6.0-test5/fs/sysfs/dir.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/sysfs/dir.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/sysfs/dir.c 2003-09-27 11:38:39.366543760 +0800
+@@ -21,32 +21,32 @@
+ }
+
+
+-static struct dentry *
+-create_dir(struct kobject * k, struct dentry * p, const char * n)
++static int create_dir(struct kobject * k, struct dentry * p,
++ const char * n, struct dentry ** d)
+ {
+- struct dentry * dentry;
++ int error;
+
+ down(&p->d_inode->i_sem);
+- dentry = sysfs_get_dentry(p,n);
+- if (!IS_ERR(dentry)) {
+- int error = sysfs_create(dentry,
++ *d = sysfs_get_dentry(p,n);
++ if (!IS_ERR(*d)) {
++ error = sysfs_create(*d,
+ S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO,
+ init_dir);
+ if (!error) {
+- dentry->d_fsdata = k;
++ (*d)->d_fsdata = k;
+ p->d_inode->i_nlink++;
+- } else
+- dentry = ERR_PTR(error);
+- dput(dentry);
+- }
++ }
++ dput(*d);
++ } else
++ error = PTR_ERR(*d);
+ up(&p->d_inode->i_sem);
+- return dentry;
++ return error;
+ }
+
+
+-struct dentry * sysfs_create_subdir(struct kobject * k, const char * n)
++int sysfs_create_subdir(struct kobject * k, const char * n, struct dentry ** d)
+ {
+- return create_dir(k,k->dentry,n);
++ return create_dir(k,k->dentry,n,d);
+ }
+
+ /**
+@@ -71,11 +71,9 @@
+ else
+ return -EFAULT;
+
+- dentry = create_dir(kobj,parent,kobject_name(kobj));
+- if (!IS_ERR(dentry))
++ error = create_dir(kobj,parent,kobject_name(kobj),&dentry);
++ if (!error)
+ kobj->dentry = dentry;
+- else
+- error = PTR_ERR(dentry);
+ return error;
+ }
+
+@@ -84,8 +82,16 @@
+ {
+ struct dentry * parent = dget(d->d_parent);
+ down(&parent->d_inode->i_sem);
+- d_delete(d);
+- simple_rmdir(parent->d_inode,d);
++ /*
++ * It is possible that parent has already been removed, in which
++ * case directory is already unhashed and dput.
++ * Note that this won't update parent->d_inode->i_nlink; OTOH
++ * parent should already be dead
++ */
++ if (!d_unhashed(d)) {
++ d_delete(d);
++ simple_rmdir(parent->d_inode,d);
++ }
+
+ pr_debug(" o %s removing done (%d)\n",d->d_name.name,
+ atomic_read(&d->d_count));
+Index: linux-2.6.0-test5/fs/sysfs/file.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/sysfs/file.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/sysfs/file.c 2003-09-27 11:38:39.369543304 +0800
+@@ -353,11 +353,11 @@
+ down(&dir->d_inode->i_sem);
+ dentry = sysfs_get_dentry(dir,attr->name);
+ if (!IS_ERR(dentry)) {
+- error = sysfs_create(dentry,(attr->mode & S_IALLUGO) | S_IFREG,init_file);
++ error = sysfs_create(dentry,
++ (attr->mode & S_IALLUGO) | S_IFREG,
++ init_file);
+ if (!error)
+ dentry->d_fsdata = (void *)attr;
+- else
+- dentry = ERR_PTR(error);
+ dput(dentry);
+ } else
+ error = PTR_ERR(dentry);
+Index: linux-2.6.0-test5/fs/sysfs/group.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/sysfs/group.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/sysfs/group.c 2003-09-27 11:38:39.371543000 +0800
+@@ -46,9 +46,9 @@
+ int error;
+
+ if (grp->name) {
+- dir = sysfs_create_subdir(kobj,grp->name);
+- if (IS_ERR(dir))
+- return PTR_ERR(dir);
++ error = sysfs_create_subdir(kobj,grp->name,&dir);
++ if (error)
++ return error;
+ } else
+ dir = kobj->dentry;
+ dir = dget(dir);
+Index: linux-2.6.0-test5/fs/sysfs/sysfs.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/sysfs/sysfs.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/sysfs/sysfs.h 2003-09-27 11:38:39.372542848 +0800
+@@ -9,5 +9,5 @@
+ extern int sysfs_add_file(struct dentry * dir, const struct attribute * attr);
+ extern void sysfs_hash_and_remove(struct dentry * dir, const char * name);
+
+-extern struct dentry * sysfs_create_subdir(struct kobject *, const char *);
++extern int sysfs_create_subdir(struct kobject *, const char *, struct dentry **);
+ extern void sysfs_remove_subdir(struct dentry *);
+Index: linux-2.6.0-test5/fs/udf/super.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/udf/super.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/udf/super.c 2003-09-27 11:38:39.386540720 +0800
+@@ -50,6 +50,7 @@
+ #include <linux/slab.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
++#include <linux/parser.h>
+ #include <linux/stat.h>
+ #include <linux/cdrom.h>
+ #include <linux/nls.h>
+@@ -225,7 +226,7 @@
+ * gid= Set the default group.
+ * umask= Set the default umask.
+ * uid= Set the default user.
+- * bs= Set the block size.
++ * bs= Set the block size.
+ * unhide Show otherwise hidden files.
+ * undelete Show deleted files in lists.
+ * adinicb Embed data in the inode (default)
+@@ -259,18 +260,53 @@
+ * uopts Pointer to mount options variable.
+ *
+ * POST-CONDITIONS
+- * <return> 0 Mount options parsed okay.
+- * <return> -1 Error parsing mount options.
++ * <return> 1 Mount options parsed okay.
++ * <return> 0 Error parsing mount options.
+ *
+ * HISTORY
+ * July 1, 1997 - Andrew E. Mileski
+ * Written, tested, and released.
+ */
+
++enum {
++ Opt_novrs, Opt_nostrict, Opt_bs, Opt_unhide, Opt_undelete,
++ Opt_noadinicb, Opt_adinicb, Opt_shortad, Opt_longad,
++ Opt_gid, Opt_uid, Opt_umask, Opt_session, Opt_lastblock,
++ Opt_anchor, Opt_volume, Opt_partition, Opt_fileset,
++ Opt_rootdir, Opt_utf8, Opt_iocharset,
++ Opt_err
++};
++
++static match_table_t tokens = {
++ {Opt_novrs, "novrs"},
++ {Opt_nostrict, "nostrict"},
++ {Opt_bs, "bs=%u"},
++ {Opt_unhide, "unhide"},
++ {Opt_undelete, "undelete"},
++ {Opt_noadinicb, "noadinicb"},
++ {Opt_adinicb, "adinicb"},
++ {Opt_shortad, "shortad"},
++ {Opt_longad, "longad"},
++ {Opt_gid, "gid=%u"},
++ {Opt_uid, "uid=%u"},
++ {Opt_umask, "umask=%o"},
++ {Opt_session, "session=%u"},
++ {Opt_lastblock, "lastblock=%u"},
++ {Opt_anchor, "anchor=%u"},
++ {Opt_volume, "volume=%u"},
++ {Opt_partition, "partition=%u"},
++ {Opt_fileset, "fileset=%u"},
++ {Opt_rootdir, "rootdir=%u"},
++ {Opt_utf8, "utf8"},
++ {Opt_iocharset, "iocharset=%s"},
++ {Opt_err, NULL}
++};
++
+ static int
+ udf_parse_options(char *options, struct udf_options *uopt)
+ {
+- char *opt, *val;
++ char *p;
++ int option;
+
+ uopt->novrs = 0;
+ uopt->blocksize = 2048;
+@@ -286,71 +322,106 @@
+ if (!options)
+ return 1;
+
+- while ((opt = strsep(&options, ",")) != NULL)
+- {
+- if (!*opt)
++ while ((p = strsep(&options, ",")) != NULL) {
++ substring_t args[MAX_OPT_ARGS];
++ int token;
++ if (!*p)
+ continue;
+- /* Make "opt=val" into two strings */
+- val = strchr(opt, '=');
+- if (val)
+- *(val++) = 0;
+- if (!strcmp(opt, "novrs") && !val)
++
++ token = match_token(p, tokens, args);
++ switch (token) {
++ case Opt_novrs:
+ uopt->novrs = 1;
+- else if (!strcmp(opt, "bs") && val)
+- uopt->blocksize = simple_strtoul(val, NULL, 0);
+- else if (!strcmp(opt, "unhide") && !val)
++ break;
++ case Opt_bs:
++ if (match_int(&args[0], &option))
++ return 0;
++ uopt->blocksize = option;
++ break;
++ case Opt_unhide:
+ uopt->flags |= (1 << UDF_FLAG_UNHIDE);
+- else if (!strcmp(opt, "undelete") && !val)
++ break;
++ case Opt_undelete:
+ uopt->flags |= (1 << UDF_FLAG_UNDELETE);
+- else if (!strcmp(opt, "noadinicb") && !val)
++ break;
++ case Opt_noadinicb:
+ uopt->flags &= ~(1 << UDF_FLAG_USE_AD_IN_ICB);
+- else if (!strcmp(opt, "adinicb") && !val)
++ break;
++ case Opt_adinicb:
+ uopt->flags |= (1 << UDF_FLAG_USE_AD_IN_ICB);
+- else if (!strcmp(opt, "shortad") && !val)
++ break;
++ case Opt_shortad:
+ uopt->flags |= (1 << UDF_FLAG_USE_SHORT_AD);
+- else if (!strcmp(opt, "longad") && !val)
++ break;
++ case Opt_longad:
+ uopt->flags &= ~(1 << UDF_FLAG_USE_SHORT_AD);
+- else if (!strcmp(opt, "gid") && val)
+- uopt->gid = simple_strtoul(val, NULL, 0);
+- else if (!strcmp(opt, "umask") && val)
+- uopt->umask = simple_strtoul(val, NULL, 0);
+- else if (!strcmp(opt, "nostrict") && !val)
++ break;
++ case Opt_gid:
++ if (match_int(args, &option))
++ return 0;
++ uopt->gid = option;
++ break;
++ case Opt_uid:
++ if (match_int(args, &option))
++ return 0;
++ uopt->uid = option;
++ break;
++ case Opt_umask:
++ if (match_octal(args, &option))
++ return 0;
++ uopt->umask = option;
++ break;
++ case Opt_nostrict:
+ uopt->flags &= ~(1 << UDF_FLAG_STRICT);
+- else if (!strcmp(opt, "uid") && val)
+- uopt->uid = simple_strtoul(val, NULL, 0);
+- else if (!strcmp(opt, "session") && val)
+- uopt->session = simple_strtoul(val, NULL, 0);
+- else if (!strcmp(opt, "lastblock") && val)
+- uopt->lastblock = simple_strtoul(val, NULL, 0);
+- else if (!strcmp(opt, "anchor") && val)
+- uopt->anchor = simple_strtoul(val, NULL, 0);
+- else if (!strcmp(opt, "volume") && val)
+- uopt->volume = simple_strtoul(val, NULL, 0);
+- else if (!strcmp(opt, "partition") && val)
+- uopt->partition = simple_strtoul(val, NULL, 0);
+- else if (!strcmp(opt, "fileset") && val)
+- uopt->fileset = simple_strtoul(val, NULL, 0);
+- else if (!strcmp(opt, "rootdir") && val)
+- uopt->rootdir = simple_strtoul(val, NULL, 0);
++ break;
++ case Opt_session:
++ if (match_int(args, &option))
++ return 0;
++ uopt->session = option;
++ break;
++ case Opt_lastblock:
++ if (match_int(args, &option))
++ return 0;
++ uopt->lastblock = option;
++ break;
++ case Opt_anchor:
++ if (match_int(args, &option))
++ return 0;
++ uopt->anchor = option;
++ break;
++ case Opt_volume:
++ if (match_int(args, &option))
++ return 0;
++ uopt->volume = option;
++ break;
++ case Opt_partition:
++ if (match_int(args, &option))
++ return 0;
++ uopt->partition = option;
++ break;
++ case Opt_fileset:
++ if (match_int(args, &option))
++ return 0;
++ uopt->fileset = option;
++ break;
++ case Opt_rootdir:
++ if (match_int(args, &option))
++ return 0;
++ uopt->rootdir = option;
++ break;
++ case Opt_utf8:
++ uopt->flags |= (1 << UDF_FLAG_UTF8);
++ break;
+ #ifdef CONFIG_NLS
+- else if (!strcmp(opt, "iocharset") && val)
+- {
+- uopt->nls_map = load_nls(val);
++ case Opt_iocharset:
++ uopt->nls_map = load_nls(args[0].from);
+ uopt->flags |= (1 << UDF_FLAG_NLS_MAP);
+- }
++ break;
+ #endif
+- else if (!strcmp(opt, "utf8") && !val)
+- uopt->flags |= (1 << UDF_FLAG_UTF8);
+- else if (val)
+- {
+- printk(KERN_ERR "udf: bad mount option \"%s=%s\"\n",
+- opt, val);
+- return 0;
+- }
+- else
+- {
+- printk(KERN_ERR "udf: bad mount option \"%s\"\n",
+- opt);
++ default:
++ printk(KERN_ERR "udf: bad mount option \"%s\" "
++ "or missing value\n",
++ p);
+ return 0;
+ }
+ }
+Index: linux-2.6.0-test5/fs/ufs/namei.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/ufs/namei.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/ufs/namei.c 2003-09-27 11:38:39.389540264 +0800
+@@ -112,11 +112,13 @@
+
+ static int ufs_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_t rdev)
+ {
+- struct inode * inode;
++ struct inode *inode;
++ int err;
++
+ if (!old_valid_dev(rdev))
+ return -EINVAL;
+ inode = ufs_new_inode(dir, mode);
+- int err = PTR_ERR(inode);
++ err = PTR_ERR(inode);
+ if (!IS_ERR(inode)) {
+ init_special_inode(inode, mode, rdev);
+ /* NOTE: that'll go when we get wide dev_t */
+Index: linux-2.6.0-test5/fs/ufs/super.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/ufs/super.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/ufs/super.c 2003-09-27 11:38:39.397539048 +0800
+@@ -79,6 +79,7 @@
+ #include <linux/string.h>
+ #include <linux/blkdev.h>
+ #include <linux/init.h>
++#include <linux/parser.h>
+ #include <linux/smp_lock.h>
+ #include <linux/buffer_head.h>
+ #include <linux/vfs.h>
+@@ -250,64 +251,99 @@
+ sb->s_id, function, error_buf);
+ }
+
++enum {
++ Opt_type_old, Opt_type_sunx86, Opt_type_sun, Opt_type_44bsd,
++ Opt_type_hp, Opt_type_nextstepcd, Opt_type_nextstep,
++ Opt_type_openstep, Opt_onerror_panic, Opt_onerror_lock,
++ Opt_onerror_umount, Opt_onerror_repair, Opt_err
++};
++
++static match_table_t tokens = {
++ {Opt_type_old, "ufstype=old"},
++ {Opt_type_sunx86, "ufstype=sunx86"},
++ {Opt_type_sun, "ufstype=sun"},
++ {Opt_type_44bsd, "ufstype=44bsd"},
++ {Opt_type_hp, "ufstype=hp"},
++ {Opt_type_nextstepcd, "ufstype=nextstep-cd"},
++ {Opt_type_nextstep, "ufstype=nextstep"},
++ {Opt_type_openstep, "ufstype=openstep"},
++ {Opt_onerror_panic, "onerror=panic"},
++ {Opt_onerror_lock, "onerror=lock"},
++ {Opt_onerror_umount, "onerror=umount"},
++ {Opt_onerror_repair, "onerror=repair"},
++ {Opt_err, NULL}
++};
++
+ static int ufs_parse_options (char * options, unsigned * mount_options)
+ {
+- char * this_char;
+- char * value;
++ char * p;
+
+ UFSD(("ENTER\n"))
+
+ if (!options)
+ return 1;
+
+- while ((this_char = strsep (&options, ",")) != NULL) {
+- if (!*this_char)
++ while ((p = strsep(&options, ",")) != NULL) {
++ substring_t args[MAX_OPT_ARGS];
++ int token;
++ if (!*p)
+ continue;
+- if ((value = strchr (this_char, '=')) != NULL)
+- *value++ = 0;
+- if (!strcmp (this_char, "ufstype")) {
++
++ token = match_token(p, tokens, args);
++ switch (token) {
++ case Opt_type_old:
+ ufs_clear_opt (*mount_options, UFSTYPE);
+- if (!strcmp (value, "old"))
+- ufs_set_opt (*mount_options, UFSTYPE_OLD);
+- else if (!strcmp (value, "sun"))
+- ufs_set_opt (*mount_options, UFSTYPE_SUN);
+- else if (!strcmp (value, "44bsd"))
+- ufs_set_opt (*mount_options, UFSTYPE_44BSD);
+- else if (!strcmp (value, "nextstep"))
+- ufs_set_opt (*mount_options, UFSTYPE_NEXTSTEP);
+- else if (!strcmp (value, "nextstep-cd"))
+- ufs_set_opt (*mount_options, UFSTYPE_NEXTSTEP_CD);
+- else if (!strcmp (value, "openstep"))
+- ufs_set_opt (*mount_options, UFSTYPE_OPENSTEP);
+- else if (!strcmp (value, "sunx86"))
+- ufs_set_opt (*mount_options, UFSTYPE_SUNx86);
+- else if (!strcmp (value, "hp"))
+- ufs_set_opt (*mount_options, UFSTYPE_HP);
+- else {
+- printk ("UFS-fs: Invalid type option: %s\n", value);
+- return 0;
+- }
+- }
+- else if (!strcmp (this_char, "onerror")) {
++ ufs_set_opt (*mount_options, UFSTYPE_OLD);
++ break;
++ case Opt_type_sunx86:
++ ufs_clear_opt (*mount_options, UFSTYPE);
++ ufs_set_opt (*mount_options, UFSTYPE_SUNx86);
++ break;
++ case Opt_type_sun:
++ ufs_clear_opt (*mount_options, UFSTYPE);
++ ufs_set_opt (*mount_options, UFSTYPE_SUN);
++ break;
++ case Opt_type_44bsd:
++ ufs_clear_opt (*mount_options, UFSTYPE);
++ ufs_set_opt (*mount_options, UFSTYPE_44BSD);
++ break;
++ case Opt_type_hp:
++ ufs_clear_opt (*mount_options, UFSTYPE);
++ ufs_set_opt (*mount_options, UFSTYPE_HP);
++ break;
++ case Opt_type_nextstepcd:
++ ufs_clear_opt (*mount_options, UFSTYPE);
++ ufs_set_opt (*mount_options, UFSTYPE_NEXTSTEP_CD);
++ break;
++ case Opt_type_nextstep:
++ ufs_clear_opt (*mount_options, UFSTYPE);
++ ufs_set_opt (*mount_options, UFSTYPE_NEXTSTEP);
++ break;
++ case Opt_type_openstep:
++ ufs_clear_opt (*mount_options, UFSTYPE);
++ ufs_set_opt (*mount_options, UFSTYPE_OPENSTEP);
++ break;
++ case Opt_onerror_panic:
+ ufs_clear_opt (*mount_options, ONERROR);
+- if (!strcmp (value, "panic"))
+- ufs_set_opt (*mount_options, ONERROR_PANIC);
+- else if (!strcmp (value, "lock"))
+- ufs_set_opt (*mount_options, ONERROR_LOCK);
+- else if (!strcmp (value, "umount"))
+- ufs_set_opt (*mount_options, ONERROR_UMOUNT);
+- else if (!strcmp (value, "repair")) {
+- printk("UFS-fs: Unable to do repair on error, "
+- "will lock lock instead \n");
+- ufs_set_opt (*mount_options, ONERROR_REPAIR);
+- }
+- else {
+- printk ("UFS-fs: Invalid action onerror: %s\n", value);
+- return 0;
+- }
+- }
+- else {
+- printk("UFS-fs: Invalid option: %s\n", this_char);
++ ufs_set_opt (*mount_options, ONERROR_PANIC);
++ break;
++ case Opt_onerror_lock:
++ ufs_clear_opt (*mount_options, ONERROR);
++ ufs_set_opt (*mount_options, ONERROR_LOCK);
++ break;
++ case Opt_onerror_umount:
++ ufs_clear_opt (*mount_options, ONERROR);
++ ufs_set_opt (*mount_options, ONERROR_UMOUNT);
++ break;
++ case Opt_onerror_repair:
++ printk("UFS-fs: Unable to do repair on error, "
++ "will lock lock instead\n");
++ ufs_clear_opt (*mount_options, ONERROR);
++ ufs_set_opt (*mount_options, ONERROR_REPAIR);
++ break;
++ default:
++ printk("UFS-fs: Invalid option: \"%s\" "
++ "or missing value\n", p);
+ return 0;
+ }
+ }
+Index: linux-2.6.0-test5/fs/xattr.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xattr.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xattr.c 2003-09-27 11:38:39.400538592 +0800
+@@ -53,7 +53,8 @@
+ * Extended attribute SET operations
+ */
+ static long
+-setxattr(struct dentry *d, char *name, void *value, size_t size, int flags)
++setxattr(struct dentry *d, char __user *name, void __user *value,
++ size_t size, int flags)
+ {
+ int error;
+ void *kvalue;
+@@ -94,7 +95,8 @@
+ }
+
+ asmlinkage long
+-sys_setxattr(char *path, char *name, void *value, size_t size, int flags)
++sys_setxattr(char __user *path, char __user *name, void __user *value,
++ size_t size, int flags)
+ {
+ struct nameidata nd;
+ int error;
+@@ -108,7 +110,8 @@
+ }
+
+ asmlinkage long
+-sys_lsetxattr(char *path, char *name, void *value, size_t size, int flags)
++sys_lsetxattr(char __user *path, char __user *name, void __user *value,
++ size_t size, int flags)
+ {
+ struct nameidata nd;
+ int error;
+@@ -122,7 +125,8 @@
+ }
+
+ asmlinkage long
+-sys_fsetxattr(int fd, char *name, void *value, size_t size, int flags)
++sys_fsetxattr(int fd, char __user *name, void __user *value,
++ size_t size, int flags)
+ {
+ struct file *f;
+ int error = -EBADF;
+@@ -139,7 +143,7 @@
+ * Extended attribute GET operations
+ */
+ static ssize_t
+-getxattr(struct dentry *d, char *name, void *value, size_t size)
++getxattr(struct dentry *d, char __user *name, void __user *value, size_t size)
+ {
+ ssize_t error;
+ void *kvalue;
+@@ -172,7 +176,8 @@
+ }
+
+ asmlinkage ssize_t
+-sys_getxattr(char *path, char *name, void *value, size_t size)
++sys_getxattr(char __user *path, char __user *name, void __user *value,
++ size_t size)
+ {
+ struct nameidata nd;
+ ssize_t error;
+@@ -186,7 +191,8 @@
+ }
+
+ asmlinkage ssize_t
+-sys_lgetxattr(char *path, char *name, void *value, size_t size)
++sys_lgetxattr(char __user *path, char __user *name, void __user *value,
++ size_t size)
+ {
+ struct nameidata nd;
+ ssize_t error;
+@@ -200,7 +206,7 @@
+ }
+
+ asmlinkage ssize_t
+-sys_fgetxattr(int fd, char *name, void *value, size_t size)
++sys_fgetxattr(int fd, char __user *name, void __user *value, size_t size)
+ {
+ struct file *f;
+ ssize_t error = -EBADF;
+@@ -217,7 +223,7 @@
+ * Extended attribute LIST operations
+ */
+ static ssize_t
+-listxattr(struct dentry *d, char *list, size_t size)
++listxattr(struct dentry *d, char __user *list, size_t size)
+ {
+ ssize_t error;
+ char *klist;
+@@ -243,7 +249,7 @@
+ }
+
+ asmlinkage ssize_t
+-sys_listxattr(char *path, char *list, size_t size)
++sys_listxattr(char __user *path, char __user *list, size_t size)
+ {
+ struct nameidata nd;
+ ssize_t error;
+@@ -257,7 +263,7 @@
+ }
+
+ asmlinkage ssize_t
+-sys_llistxattr(char *path, char *list, size_t size)
++sys_llistxattr(char __user *path, char __user *list, size_t size)
+ {
+ struct nameidata nd;
+ ssize_t error;
+@@ -271,7 +277,7 @@
+ }
+
+ asmlinkage ssize_t
+-sys_flistxattr(int fd, char *list, size_t size)
++sys_flistxattr(int fd, char __user *list, size_t size)
+ {
+ struct file *f;
+ ssize_t error = -EBADF;
+@@ -288,7 +294,7 @@
+ * Extended attribute REMOVE operations
+ */
+ static long
+-removexattr(struct dentry *d, char *name)
++removexattr(struct dentry *d, char __user *name)
+ {
+ int error;
+ char kname[XATTR_NAME_MAX + 1];
+@@ -313,7 +319,7 @@
+ }
+
+ asmlinkage long
+-sys_removexattr(char *path, char *name)
++sys_removexattr(char __user *path, char __user *name)
+ {
+ struct nameidata nd;
+ int error;
+@@ -327,7 +333,7 @@
+ }
+
+ asmlinkage long
+-sys_lremovexattr(char *path, char *name)
++sys_lremovexattr(char __user *path, char __user *name)
+ {
+ struct nameidata nd;
+ int error;
+@@ -341,7 +347,7 @@
+ }
+
+ asmlinkage long
+-sys_fremovexattr(int fd, char *name)
++sys_fremovexattr(int fd, char __user *name)
+ {
+ struct file *f;
+ int error = -EBADF;
+Index: linux-2.6.0-test5/fs/xfs/linux/xfs_aops.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/linux/xfs_aops.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/linux/xfs_aops.c 2003-09-27 11:38:39.409537224 +0800
+@@ -225,7 +225,8 @@
+ page_buf_bmap_t *mp,
+ page_buf_t *pb,
+ unsigned long max_offset,
+- unsigned long *fsbs)
++ unsigned long *fsbs,
++ unsigned int bbits)
+ {
+ struct page *page;
+
+@@ -248,6 +249,7 @@
+ break;
+ if (p_offset >= max_offset)
+ break;
++ map_buffer_at_offset(page, bh, p_offset, bbits, mp);
+ set_buffer_unwritten_io(bh);
+ bh->b_private = pb;
+ p_offset += bh->b_size;
+@@ -455,13 +457,14 @@
+ if (bh == head) {
+ struct address_space *mapping = inode->i_mapping;
+ unsigned long tindex, tloff, tlast, bs;
++ unsigned int bbits = inode->i_blkbits;
+ struct page *page;
+
+ tlast = i_size_read(inode) >> PAGE_CACHE_SHIFT;
+ tloff = min(tlast, start_page->index + pb->pb_page_count - 1);
+ for (tindex = start_page->index + 1; tindex < tloff; tindex++) {
+ page = probe_unwritten_page(mapping, tindex, mp, pb,
+- PAGE_CACHE_SIZE, &bs);
++ PAGE_CACHE_SIZE, &bs, bbits);
+ if (!page)
+ break;
+ nblocks += bs;
+@@ -472,7 +475,7 @@
+ if (tindex == tlast &&
+ (tloff = (i_size_read(inode) & (PAGE_CACHE_SIZE - 1)))) {
+ page = probe_unwritten_page(mapping, tindex, mp, pb,
+- tloff, &bs);
++ tloff, &bs, bbits);
+ if (page) {
+ nblocks += bs;
+ atomic_add(bs, &pb->pb_io_remaining);
+@@ -560,7 +563,8 @@
+ offset = i << bbits;
+ if (!(PageUptodate(page) || buffer_uptodate(bh)))
+ continue;
+- if (buffer_mapped(bh) && !buffer_delay(bh) && all_bh) {
++ if (buffer_mapped(bh) && all_bh &&
++ !buffer_unwritten(bh) && !buffer_delay(bh)) {
+ if (startio && (offset < end)) {
+ lock_buffer(bh);
+ bh_arr[index++] = bh;
+@@ -581,7 +585,7 @@
+ ASSERT(tmp->pbm_flags & PBMF_UNWRITTEN);
+ map_unwritten(inode, page, head, bh,
+ offset, bbits, tmp, all_bh);
+- } else {
++ } else if (! (buffer_unwritten(bh) && buffer_locked(bh))) {
+ map_buffer_at_offset(page, bh, offset, bbits, tmp);
+ if (buffer_unwritten(bh)) {
+ set_buffer_unwritten_io(bh);
+Index: linux-2.6.0-test5/fs/xfs/linux/xfs_file.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/linux/xfs_file.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/linux/xfs_file.c 2003-09-27 11:38:39.412536768 +0800
+@@ -94,6 +94,8 @@
+ BUG_ON(iocb->ki_pos != pos);
+
+ if (direct) {
++ down_read(&inode->i_alloc_sem);
++ down(&inode->i_sem);
+ VOP_WRITE(vp, iocb, &iov, 1, &iocb->ki_pos, NULL, error);
+ } else {
+ down(&inode->i_sem);
+Index: linux-2.6.0-test5/fs/xfs/linux/xfs_globals.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/linux/xfs_globals.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/linux/xfs_globals.c 2003-09-27 11:38:39.413536616 +0800
+@@ -59,6 +59,9 @@
+ .error_level = { 0, 3, 11 },
+ .sync_interval = { HZ, 30*HZ, 60*HZ },
+ .stats_clear = { 0, 0, 1 },
++ .inherit_sync = { 0, 1, 1 },
++ .inherit_nodump = { 0, 1, 1 },
++ .inherit_noatim = { 0, 1, 1 },
+ };
+
+ /*
+Index: linux-2.6.0-test5/fs/xfs/linux/xfs_ioctl.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/linux/xfs_ioctl.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/linux/xfs_ioctl.c 2003-09-27 11:38:39.420535552 +0800
+@@ -72,6 +72,13 @@
+ #include <linux/namei.h>
+ #include <linux/pagemap.h>
+
++/*
++ * ioctl commands that are used by Linux filesystems
++ */
++#define XFS_IOC_GETXFLAGS _IOR('f', 1, long)
++#define XFS_IOC_SETXFLAGS _IOW('f', 2, long)
++#define XFS_IOC_GETVERSION _IOR('v', 1, long)
++
+
+ /*
+ * xfs_find_handle maps from userspace xfs_fsop_handlereq structure to
+@@ -328,6 +335,17 @@
+ if (permflag & O_TRUNC)
+ permflag |= 2;
+
++ if ((!(permflag & O_APPEND) || (permflag & O_TRUNC)) &&
++ (permflag & FMODE_WRITE) && IS_APPEND(inode)) {
++ iput(inode);
++ return -XFS_ERROR(EPERM);
++ }
++
++ if ((permflag & FMODE_WRITE) && IS_IMMUTABLE(inode)) {
++ iput(inode);
++ return -XFS_ERROR(EACCES);
++ }
++
+ /* Can't write directories. */
+ if ( S_ISDIR(inode->i_mode) && (permflag & FMODE_WRITE)) {
+ iput(inode);
+@@ -429,6 +447,11 @@
+ if (error)
+ return -error;
+
++ if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
++ VN_RELE(vp);
++ return -XFS_ERROR(EPERM);
++ }
++
+ if (copy_from_user(&fsd, dmhreq.data, sizeof(fsd))) {
+ VN_RELE(vp);
+ return -XFS_ERROR(EFAULT);
+@@ -514,11 +537,19 @@
+ NULL, ops[i].am_error);
+ break;
+ case ATTR_OP_SET:
++ if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
++ ops[i].am_error = EPERM;
++ break;
++ }
+ VOP_ATTR_SET(vp,ops[i].am_attrname, ops[i].am_attrvalue,
+ ops[i].am_length, ops[i].am_flags,
+ NULL, ops[i].am_error);
+ break;
+ case ATTR_OP_REMOVE:
++ if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
++ ops[i].am_error = EPERM;
++ break;
++ }
+ VOP_ATTR_REMOVE(vp, ops[i].am_attrname, ops[i].am_flags,
+ NULL, ops[i].am_error);
+ break;
+@@ -566,6 +597,7 @@
+ STATIC int
+ xfs_ioc_xattr(
+ vnode_t *vp,
++ xfs_inode_t *ip,
+ struct file *filp,
+ unsigned int cmd,
+ unsigned long arg);
+@@ -648,10 +680,13 @@
+ case XFS_IOC_FSGEOMETRY:
+ return xfs_ioc_fsgeometry(mp, arg);
+
++ case XFS_IOC_GETVERSION:
++ case XFS_IOC_GETXFLAGS:
++ case XFS_IOC_SETXFLAGS:
+ case XFS_IOC_FSGETXATTR:
+ case XFS_IOC_FSSETXATTR:
+ case XFS_IOC_FSGETXATTRA:
+- return xfs_ioc_xattr(vp, filp, cmd, arg);
++ return xfs_ioc_xattr(vp, ip, filp, cmd, arg);
+
+ case XFS_IOC_FSSETDM: {
+ struct fsdmidata dmi;
+@@ -837,6 +872,9 @@
+ int attr_flags = 0;
+ int error;
+
++ if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND))
++ return -XFS_ERROR(EPERM);
++
+ if (filp->f_flags & O_RDONLY)
+ return -XFS_ERROR(EBADF);
+
+@@ -957,9 +995,50 @@
+ return 0;
+ }
+
++/*
++ * Linux extended inode flags interface.
++ */
++#define LINUX_XFLAG_SYNC 0x00000008 /* Synchronous updates */
++#define LINUX_XFLAG_IMMUTABLE 0x00000010 /* Immutable file */
++#define LINUX_XFLAG_APPEND 0x00000020 /* writes to file may only append */
++#define LINUX_XFLAG_NODUMP 0x00000040 /* do not dump file */
++#define LINUX_XFLAG_NOATIME 0x00000080 /* do not update atime */
++
++STATIC unsigned int
++xfs_merge_ioc_xflags(
++ unsigned int flags,
++ unsigned int start)
++{
++ unsigned int xflags = start;
++
++ if (flags & LINUX_XFLAG_IMMUTABLE)
++ xflags |= XFS_XFLAG_IMMUTABLE;
++ else
++ xflags &= ~XFS_XFLAG_IMMUTABLE;
++ if (flags & LINUX_XFLAG_APPEND)
++ xflags |= XFS_XFLAG_APPEND;
++ else
++ xflags &= ~XFS_XFLAG_APPEND;
++ if (flags & LINUX_XFLAG_SYNC)
++ xflags |= XFS_XFLAG_SYNC;
++ else
++ xflags &= ~XFS_XFLAG_SYNC;
++ if (flags & LINUX_XFLAG_NOATIME)
++ xflags |= XFS_XFLAG_NOATIME;
++ else
++ xflags &= ~XFS_XFLAG_NOATIME;
++ if (flags & LINUX_XFLAG_NODUMP)
++ xflags |= XFS_XFLAG_NODUMP;
++ else
++ xflags &= ~XFS_XFLAG_NODUMP;
++
++ return xflags;
++}
++
+ STATIC int
+ xfs_ioc_xattr(
+ vnode_t *vp,
++ xfs_inode_t *ip,
+ struct file *filp,
+ unsigned int cmd,
+ unsigned long arg)
+@@ -967,6 +1046,8 @@
+ struct fsxattr fa;
+ vattr_t va;
+ int error;
++ int attr_flags;
++ unsigned int flags;
+
+ switch (cmd) {
+ case XFS_IOC_FSGETXATTR: {
+@@ -985,24 +1066,24 @@
+ }
+
+ case XFS_IOC_FSSETXATTR: {
+- int attr_flags = 0;
+-
+ if (copy_from_user(&fa, (struct fsxattr *)arg, sizeof(fa)))
+ return -XFS_ERROR(EFAULT);
+
++ attr_flags = 0;
++ if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
++ attr_flags |= ATTR_NONBLOCK;
++
+ va.va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE;
+ va.va_xflags = fa.fsx_xflags;
+ va.va_extsize = fa.fsx_extsize;
+
+- if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
+- attr_flags |= ATTR_NONBLOCK;
+-
+ VOP_SETATTR(vp, &va, attr_flags, NULL, error);
++ if (!error)
++ vn_revalidate(vp); /* update Linux inode flags */
+ return -error;
+ }
+
+ case XFS_IOC_FSGETXATTRA: {
+-
+ va.va_mask = XFS_AT_XFLAGS|XFS_AT_EXTSIZE|XFS_AT_ANEXTENTS;
+ VOP_GETATTR(vp, &va, 0, NULL, error);
+ if (error)
+@@ -1017,9 +1098,54 @@
+ return 0;
+ }
+
++ case XFS_IOC_GETXFLAGS: {
++ flags = 0;
++ if (ip->i_d.di_flags & XFS_XFLAG_IMMUTABLE)
++ flags |= LINUX_XFLAG_IMMUTABLE;
++ if (ip->i_d.di_flags & XFS_XFLAG_APPEND)
++ flags |= LINUX_XFLAG_APPEND;
++ if (ip->i_d.di_flags & XFS_XFLAG_SYNC)
++ flags |= LINUX_XFLAG_SYNC;
++ if (ip->i_d.di_flags & XFS_XFLAG_NOATIME)
++ flags |= LINUX_XFLAG_NOATIME;
++ if (ip->i_d.di_flags & XFS_XFLAG_NODUMP)
++ flags |= LINUX_XFLAG_NODUMP;
++ if (copy_to_user((unsigned int *)arg, &flags, sizeof(flags)))
++ return -XFS_ERROR(EFAULT);
++ return 0;
++ }
++
++ case XFS_IOC_SETXFLAGS: {
++ if (copy_from_user(&flags, (unsigned int *)arg, sizeof(flags)))
++ return -XFS_ERROR(EFAULT);
++
++ if (flags & ~(LINUX_XFLAG_IMMUTABLE | LINUX_XFLAG_APPEND | \
++ LINUX_XFLAG_NOATIME | LINUX_XFLAG_NODUMP | \
++ LINUX_XFLAG_SYNC))
++ return -XFS_ERROR(EOPNOTSUPP);
++
++ attr_flags = 0;
++ if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
++ attr_flags |= ATTR_NONBLOCK;
++
++ va.va_mask = XFS_AT_XFLAGS;
++ va.va_xflags = xfs_merge_ioc_xflags(flags, ip->i_d.di_flags);
++
++ VOP_SETATTR(vp, &va, attr_flags, NULL, error);
++ if (!error)
++ vn_revalidate(vp); /* update Linux inode flags */
++ return -error;
++ }
++
++ case XFS_IOC_GETVERSION: {
++ flags = LINVFS_GET_IP(vp)->i_generation;
++ if (copy_to_user((unsigned int *)arg, &flags, sizeof(flags)))
++ return -XFS_ERROR(EFAULT);
++ return 0;
++ }
++
+ default:
+ return -ENOTTY;
+-
+ }
+ }
+
+Index: linux-2.6.0-test5/fs/xfs/linux/xfs_iomap.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/linux/xfs_iomap.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/linux/xfs_iomap.c 2003-09-27 11:38:39.426534640 +0800
+@@ -156,7 +156,7 @@
+ if (flags & BMAP_IGNSTATE)
+ bmap_flags |= XFS_BMAPI_IGSTATE;
+ break;
+- case PBF_WRITE:
++ case BMAP_WRITE:
+ lockmode = XFS_ILOCK_EXCL|XFS_EXTSIZE_WR;
+ bmap_flags = 0;
+ XFS_ILOCK(mp, io, lockmode);
+@@ -598,7 +598,7 @@
+ count_fsb = map->br_blockcount;
+ map_start_fsb = offset_fsb;
+
+- XFS_STATS_ADD(xfsstats.xs_xstrat_bytes, XFS_FSB_TO_B(mp, count_fsb));
++ XFS_STATS_ADD(xs_xstrat_bytes, XFS_FSB_TO_B(mp, count_fsb));
+
+ while (count_fsb != 0) {
+ /*
+@@ -689,7 +689,7 @@
+ imap[i].br_blockcount))) {
+ *map = imap[i];
+ *retmap = 1;
+- XFS_STATS_INC(xfsstats.xs_xstrat_quick);
++ XFS_STATS_INC(xs_xstrat_quick);
+ return 0;
+ }
+ count_fsb -= imap[i].br_blockcount;
+Index: linux-2.6.0-test5/fs/xfs/linux/xfs_iops.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/linux/xfs_iops.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/linux/xfs_iops.c 2003-09-27 11:38:39.431533880 +0800
+@@ -113,7 +113,11 @@
+ xattr_exists_t test_default_acl = _ACL_DEFAULT_EXISTS;
+ int error;
+
+- if (!old_valid_dev(rdev))
++ /*
++ * Irix uses Missed'em'V split, but doesn't want to see
++ * the upper 5 bits of (14bit) major.
++ */
++ if (!sysv_valid_dev(rdev) || MAJOR(rdev) & ~0x1ff)
+ return -EINVAL;
+
+ if (test_default_acl && test_default_acl(dvp)) {
+@@ -135,7 +139,7 @@
+
+ switch (mode & S_IFMT) {
+ case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK:
+- va.va_rdev = XFS_MKDEV(MAJOR(rdev), MINOR(rdev));
++ va.va_rdev = sysv_encode_dev(rdev);
+ va.va_mask |= XFS_AT_RDEV;
+ /*FALLTHROUGH*/
+ case S_IFREG:
+@@ -638,6 +642,9 @@
+ return error;
+ }
+
++ if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
++ return -EPERM;
++
+ /* Convert Linux syscall to XFS internal ATTR flags */
+ if (flags & XATTR_CREATE)
+ xflags |= ATTR_CREATE;
+@@ -787,6 +794,9 @@
+ return error;
+ }
+
++ if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
++ return -EPERM;
++
+ if (strncmp(name, xfs_namespaces[ROOT_NAMES].name,
+ xfs_namespaces[ROOT_NAMES].namelen) == 0) {
+ if (!capable(CAP_SYS_ADMIN))
+Index: linux-2.6.0-test5/fs/xfs/linux/xfs_linux.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/linux/xfs_linux.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/linux/xfs_linux.h 2003-09-27 11:38:39.435533272 +0800
+@@ -96,6 +96,9 @@
+ #define xfs_error_level xfs_params.error_level.val
+ #define xfs_syncd_interval xfs_params.sync_interval.val
+ #define xfs_stats_clear xfs_params.stats_clear.val
++#define xfs_inherit_sync xfs_params.inherit_sync.val
++#define xfs_inherit_nodump xfs_params.inherit_nodump.val
++#define xfs_inherit_noatime xfs_params.inherit_noatim.val
+
+ #define NBPP PAGE_SIZE
+ #define DPPSHFT (PAGE_SHIFT - 9)
+Index: linux-2.6.0-test5/fs/xfs/linux/xfs_lrw.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/linux/xfs_lrw.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/linux/xfs_lrw.c 2003-09-27 11:38:39.441532360 +0800
+@@ -167,7 +167,7 @@
+ mp = ip->i_mount;
+ vn_trace_entry(vp, "xfs_read", (inst_t *)__return_address);
+
+- XFS_STATS_INC(xfsstats.xs_read_calls);
++ XFS_STATS_INC(xs_read_calls);
+
+ /* START copy & waste from filemap.c */
+ for (seg = 0; seg < segs; seg++) {
+@@ -231,7 +231,7 @@
+ xfs_iunlock(ip, XFS_IOLOCK_SHARED);
+
+ if (ret > 0)
+- XFS_STATS_ADD(xfsstats.xs_read_bytes, ret);
++ XFS_STATS_ADD(xs_read_bytes, ret);
+
+ if (!invisible)
+ xfs_ichgtime(ip, XFS_ICHGTIME_ACC);
+@@ -261,7 +261,7 @@
+ mp = ip->i_mount;
+ vn_trace_entry(vp, "xfs_sendfile", (inst_t *)__return_address);
+
+- XFS_STATS_INC(xfsstats.xs_read_calls);
++ XFS_STATS_INC(xs_read_calls);
+
+ n = XFS_MAXIOFFSET(mp) - *offset;
+ if ((n <= 0) || (count == 0))
+@@ -288,7 +288,7 @@
+ ret = generic_file_sendfile(filp, offset, count, actor, target);
+ xfs_iunlock(ip, XFS_IOLOCK_SHARED);
+
+- XFS_STATS_ADD(xfsstats.xs_read_bytes, ret);
++ XFS_STATS_ADD(xs_read_bytes, ret);
+ if (!invisible)
+ xfs_ichgtime(ip, XFS_ICHGTIME_ACC);
+ return ret;
+@@ -537,7 +537,7 @@
+ int eventsent = 0;
+ vrwlock_t locktype;
+
+- XFS_STATS_INC(xfsstats.xs_write_calls);
++ XFS_STATS_INC(xs_write_calls);
+
+ vp = BHV_TO_VNODE(bdp);
+ vn_trace_entry(vp, "xfs_write", (inst_t *)__return_address);
+@@ -693,8 +693,8 @@
+ DM_EVENT_ENABLED(vp->v_vfsp, xip, DM_EVENT_NOSPACE) && !invisible) {
+
+ xfs_rwunlock(bdp, locktype);
+- error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, bdp,
+- DM_RIGHT_NULL, bdp, DM_RIGHT_NULL, NULL, NULL,
++ error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, vp,
++ DM_RIGHT_NULL, vp, DM_RIGHT_NULL, NULL, NULL,
+ 0, 0, 0); /* Delay flag intentionally unused */
+ if (error)
+ return -error;
+@@ -722,7 +722,7 @@
+ return ret;
+ }
+
+- XFS_STATS_ADD(xfsstats.xs_write_bytes, ret);
++ XFS_STATS_ADD(xs_write_bytes, ret);
+
+ /* Handle various SYNC-type writes */
+ if ((file->f_flags & O_SYNC) || IS_SYNC(file->f_dentry->d_inode)) {
+Index: linux-2.6.0-test5/fs/xfs/linux/xfs_stats.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/linux/xfs_stats.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/linux/xfs_stats.c 2003-09-27 11:38:39.442532208 +0800
+@@ -80,6 +80,12 @@
+ xfsstats.xs_xstrat_bytes,
+ xfsstats.xs_write_bytes,
+ xfsstats.xs_read_bytes);
++ len += sprintf(buffer + len, "debug %u\n",
++#if defined(XFSDEBUG)
++ 1);
++#else
++ 0);
++#endif
+
+ if (offset >= len) {
+ *start = buffer;
+Index: linux-2.6.0-test5/fs/xfs/linux/xfs_stats.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/linux/xfs_stats.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/linux/xfs_stats.h 2003-09-27 11:38:39.445531752 +0800
+@@ -128,9 +128,9 @@
+
+ extern struct xfsstats xfsstats;
+
+-# define XFS_STATS_INC(count) ( (count)++ )
+-# define XFS_STATS_DEC(count) ( (count)-- )
+-# define XFS_STATS_ADD(count, inc) ( (count) += (inc) )
++# define XFS_STATS_INC(count) ( xfsstats.count++ )
++# define XFS_STATS_DEC(count) ( xfsstats.count-- )
++# define XFS_STATS_ADD(count, inc) ( xfsstats.count += (inc) )
+
+ extern void xfs_init_procfs(void);
+ extern void xfs_cleanup_procfs(void);
+Index: linux-2.6.0-test5/fs/xfs/linux/xfs_super.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/linux/xfs_super.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/linux/xfs_super.c 2003-09-27 11:38:39.450530992 +0800
+@@ -174,7 +174,7 @@
+ inode->i_rdev = 0;
+ } else {
+ xfs_dev_t dev = ip->i_df.if_u2.if_rdev;
+- inode->i_rdev = XFS_DEV_TO_KDEVT(dev);
++ inode->i_rdev = MKDEV(sysv_major(dev) & 0x1ff, sysv_minor(dev));
+ }
+ inode->i_blksize = PAGE_CACHE_SIZE;
+ inode->i_generation = ip->i_d.di_gen;
+@@ -187,7 +187,22 @@
+ inode->i_mtime.tv_nsec = ip->i_d.di_mtime.t_nsec;
+ inode->i_ctime.tv_sec = ip->i_d.di_ctime.t_sec;
+ inode->i_ctime.tv_nsec = ip->i_d.di_ctime.t_nsec;
+-
++ if (ip->i_d.di_flags & XFS_DIFLAG_IMMUTABLE)
++ inode->i_flags |= S_IMMUTABLE;
++ else
++ inode->i_flags &= ~S_IMMUTABLE;
++ if (ip->i_d.di_flags & XFS_DIFLAG_APPEND)
++ inode->i_flags |= S_APPEND;
++ else
++ inode->i_flags &= ~S_APPEND;
++ if (ip->i_d.di_flags & XFS_DIFLAG_SYNC)
++ inode->i_flags |= S_SYNC;
++ else
++ inode->i_flags &= ~S_SYNC;
++ if (ip->i_d.di_flags & XFS_DIFLAG_NOATIME)
++ inode->i_flags |= S_NOATIME;
++ else
++ inode->i_flags &= ~S_NOATIME;
+ vp->v_flag &= ~VMODIFIED;
+ }
+
+@@ -300,8 +315,8 @@
+
+ if (set_blocksize(btp->pbr_bdev, sectorsize)) {
+ printk(KERN_WARNING
+- "XFS: Cannot set_blocksize to %u on device 0x%lx\n",
+- sectorsize, (unsigned long)btp->pbr_dev);
++ "XFS: Cannot set_blocksize to %u on device %u:%u\n",
++ sectorsize, MAJOR(btp->pbr_dev), MINOR(btp->pbr_dev));
+ }
+ }
+
+Index: linux-2.6.0-test5/fs/xfs/linux/xfs_super.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/linux/xfs_super.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/linux/xfs_super.h 2003-09-27 11:38:39.452530688 +0800
+@@ -66,8 +66,12 @@
+ # define XFS_REALTIME_STRING
+ #endif
+
+-#if XFS_BIG_FILESYSTEMS
+-# define XFS_BIGFS_STRING "big filesystems, "
++#if XFS_BIG_BLKNOS
++# if XFS_BIG_INUMS
++# define XFS_BIGFS_STRING "large block/inode numbers, "
++# else
++# define XFS_BIGFS_STRING "large block numbers, "
++# endif
+ #else
+ # define XFS_BIGFS_STRING
+ #endif
+Index: linux-2.6.0-test5/fs/xfs/linux/xfs_sysctl.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/linux/xfs_sysctl.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/linux/xfs_sysctl.c 2003-09-27 11:38:39.454530384 +0800
+@@ -68,39 +68,54 @@
+
+ STATIC ctl_table xfs_table[] = {
+ {XFS_RESTRICT_CHOWN, "restrict_chown", &xfs_params.restrict_chown.val,
+- sizeof(ulong), 0644, NULL, &proc_doulongvec_minmax,
++ sizeof(int), 0644, NULL, &proc_dointvec_minmax,
+ &sysctl_intvec, NULL,
+ &xfs_params.restrict_chown.min, &xfs_params.restrict_chown.max},
+
+ {XFS_SGID_INHERIT, "irix_sgid_inherit", &xfs_params.sgid_inherit.val,
+- sizeof(ulong), 0644, NULL, &proc_doulongvec_minmax,
++ sizeof(int), 0644, NULL, &proc_dointvec_minmax,
+ &sysctl_intvec, NULL,
+ &xfs_params.sgid_inherit.min, &xfs_params.sgid_inherit.max},
+
+ {XFS_SYMLINK_MODE, "irix_symlink_mode", &xfs_params.symlink_mode.val,
+- sizeof(ulong), 0644, NULL, &proc_doulongvec_minmax,
++ sizeof(int), 0644, NULL, &proc_dointvec_minmax,
+ &sysctl_intvec, NULL,
+ &xfs_params.symlink_mode.min, &xfs_params.symlink_mode.max},
+
+ {XFS_PANIC_MASK, "panic_mask", &xfs_params.panic_mask.val,
+- sizeof(ulong), 0644, NULL, &proc_doulongvec_minmax,
++ sizeof(int), 0644, NULL, &proc_dointvec_minmax,
+ &sysctl_intvec, NULL,
+ &xfs_params.panic_mask.min, &xfs_params.panic_mask.max},
+
+ {XFS_ERRLEVEL, "error_level", &xfs_params.error_level.val,
+- sizeof(ulong), 0644, NULL, &proc_doulongvec_minmax,
++ sizeof(int), 0644, NULL, &proc_dointvec_minmax,
+ &sysctl_intvec, NULL,
+ &xfs_params.error_level.min, &xfs_params.error_level.max},
+
+ {XFS_SYNC_INTERVAL, "sync_interval", &xfs_params.sync_interval.val,
+- sizeof(ulong), 0644, NULL, &proc_doulongvec_minmax,
++ sizeof(int), 0644, NULL, &proc_dointvec_minmax,
+ &sysctl_intvec, NULL,
+ &xfs_params.sync_interval.min, &xfs_params.sync_interval.max},
+
++ {XFS_INHERIT_SYNC, "inherit_sync", &xfs_params.inherit_sync.val,
++ sizeof(int), 0644, NULL, &proc_dointvec_minmax,
++ &sysctl_intvec, NULL,
++ &xfs_params.inherit_sync.min, &xfs_params.inherit_sync.max},
++
++ {XFS_INHERIT_NODUMP, "inherit_nodump", &xfs_params.inherit_nodump.val,
++ sizeof(int), 0644, NULL, &proc_dointvec_minmax,
++ &sysctl_intvec, NULL,
++ &xfs_params.inherit_nodump.min, &xfs_params.inherit_nodump.max},
++
++ {XFS_INHERIT_NOATIME, "inherit_noatime", &xfs_params.inherit_noatim.val,
++ sizeof(int), 0644, NULL, &proc_dointvec_minmax,
++ &sysctl_intvec, NULL,
++ &xfs_params.inherit_noatim.min, &xfs_params.inherit_noatim.max},
++
+ /* please keep this the last entry */
+ #ifdef CONFIG_PROC_FS
+ {XFS_STATS_CLEAR, "stats_clear", &xfs_params.stats_clear.val,
+- sizeof(ulong), 0644, NULL, &xfs_stats_clear_proc_handler,
++ sizeof(int), 0644, NULL, &xfs_stats_clear_proc_handler,
+ &sysctl_intvec, NULL,
+ &xfs_params.stats_clear.min, &xfs_params.stats_clear.max},
+ #endif /* CONFIG_PROC_FS */
+Index: linux-2.6.0-test5/fs/xfs/linux/xfs_sysctl.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/linux/xfs_sysctl.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/linux/xfs_sysctl.h 2003-09-27 11:38:39.455530232 +0800
+@@ -40,9 +40,9 @@
+ */
+
+ typedef struct xfs_sysctl_val {
+- ulong min;
+- ulong val;
+- ulong max;
++ int min;
++ int val;
++ int max;
+ } xfs_sysctl_val_t;
+
+ typedef struct xfs_param {
+@@ -55,6 +55,9 @@
+ xfs_sysctl_val_t error_level; /* Degree of reporting for problems */
+ xfs_sysctl_val_t sync_interval; /* time between sync calls */
+ xfs_sysctl_val_t stats_clear; /* Reset all XFS statistics to zero. */
++ xfs_sysctl_val_t inherit_sync; /* Inherit the "sync" inode flag. */
++ xfs_sysctl_val_t inherit_nodump;/* Inherit the "nodump" inode flag. */
++ xfs_sysctl_val_t inherit_noatim;/* Inherit the "noatime" inode flag. */
+ } xfs_param_t;
+
+ /*
+@@ -73,13 +76,16 @@
+ */
+
+ enum {
+- XFS_RESTRICT_CHOWN = 1,
+- XFS_SGID_INHERIT = 2,
+- XFS_SYMLINK_MODE = 3,
+- XFS_PANIC_MASK = 4,
+- XFS_ERRLEVEL = 5,
+- XFS_SYNC_INTERVAL = 6,
+- XFS_STATS_CLEAR = 7,
++ XFS_RESTRICT_CHOWN = 3,
++ XFS_SGID_INHERIT = 4,
++ XFS_SYMLINK_MODE = 5,
++ XFS_PANIC_MASK = 6,
++ XFS_ERRLEVEL = 7,
++ XFS_SYNC_INTERVAL = 8,
++ XFS_STATS_CLEAR = 12,
++ XFS_INHERIT_SYNC = 13,
++ XFS_INHERIT_NODUMP = 14,
++ XFS_INHERIT_NOATIME = 15,
+ };
+
+ extern xfs_param_t xfs_params;
+Index: linux-2.6.0-test5/fs/xfs/linux/xfs_vnode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/linux/xfs_vnode.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/linux/xfs_vnode.c 2003-09-27 11:38:39.459529624 +0800
+@@ -77,7 +77,7 @@
+ {
+ int error;
+
+- XFS_STATS_INC(xfsstats.vn_reclaim);
++ XFS_STATS_INC(vn_reclaim);
+ vn_trace_entry(vp, "vn_reclaim", (inst_t *)__return_address);
+
+ /*
+@@ -137,8 +137,8 @@
+ {
+ struct vnode *vp = LINVFS_GET_VP(inode);
+
+- XFS_STATS_INC(xfsstats.vn_active);
+- XFS_STATS_INC(xfsstats.vn_alloc);
++ XFS_STATS_INC(vn_active);
++ XFS_STATS_INC(vn_alloc);
+
+ vp->v_flag = VMODIFIED;
+ spinlock_init(&vp->v_lock, "v_lock");
+@@ -172,7 +172,7 @@
+ {
+ struct inode *inode;
+
+- XFS_STATS_INC(xfsstats.vn_get);
++ XFS_STATS_INC(vn_get);
+ inode = LINVFS_GET_IP(vp);
+ if (inode->i_state & I_FREEING)
+ return NULL;
+@@ -200,7 +200,7 @@
+ vn_trace_entry(vp, "vn_revalidate", (inst_t *)__return_address);
+ ASSERT(vp->v_fbhv != NULL);
+
+- va.va_mask = XFS_AT_STAT;
++ va.va_mask = XFS_AT_STAT|XFS_AT_GENCOUNT;
+ VOP_GETATTR(vp, &va, 0, NULL, error);
+ if (!error) {
+ inode = LINVFS_GET_IP(vp);
+@@ -213,6 +213,22 @@
+ inode->i_ctime = va.va_ctime;
+ inode->i_atime = va.va_atime;
+ i_size_write(inode, va.va_size);
++ if (va.va_xflags & XFS_XFLAG_IMMUTABLE)
++ inode->i_flags |= S_IMMUTABLE;
++ else
++ inode->i_flags &= ~S_IMMUTABLE;
++ if (va.va_xflags & XFS_XFLAG_APPEND)
++ inode->i_flags |= S_APPEND;
++ else
++ inode->i_flags &= ~S_APPEND;
++ if (va.va_xflags & XFS_XFLAG_SYNC)
++ inode->i_flags |= S_SYNC;
++ else
++ inode->i_flags &= ~S_SYNC;
++ if (va.va_xflags & XFS_XFLAG_NOATIME)
++ inode->i_flags |= S_NOATIME;
++ else
++ inode->i_flags &= ~S_NOATIME;
+ VUNMODIFY(vp);
+ }
+ return -error;
+@@ -264,7 +280,7 @@
+ return;
+ }
+
+- XFS_STATS_DEC(xfsstats.vn_active);
++ XFS_STATS_DEC(vn_active);
+ vp->v_flag |= VRECLM;
+ VN_UNLOCK(vp, 0);
+
+@@ -292,7 +308,7 @@
+ {
+ struct inode *inode;
+
+- XFS_STATS_INC(xfsstats.vn_hold);
++ XFS_STATS_INC(vn_hold);
+
+ VN_LOCK(vp);
+ inode = igrab(LINVFS_GET_IP(vp));
+@@ -312,7 +328,7 @@
+ int vcnt;
+ int cache;
+
+- XFS_STATS_INC(xfsstats.vn_rele);
++ XFS_STATS_INC(vn_rele);
+
+ VN_LOCK(vp);
+
+@@ -364,7 +380,7 @@
+ if (!(vp->v_fbhv))
+ return;
+
+- XFS_STATS_INC(xfsstats.vn_remove);
++ XFS_STATS_INC(vn_remove);
+ vn_trace_exit(vp, "vn_remove", (inst_t *)__return_address);
+
+ /*
+Index: linux-2.6.0-test5/fs/xfs/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/Makefile 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/Makefile 2003-09-27 11:38:39.461529320 +0800
+@@ -65,7 +65,6 @@
+ xfs-y += xfs_alloc.o \
+ xfs_alloc_btree.o \
+ xfs_attr.o \
+- xfs_attr_fetch.o \
+ xfs_attr_leaf.o \
+ xfs_bit.o \
+ xfs_bmap.o \
+Index: linux-2.6.0-test5/fs/xfs/pagebuf/page_buf.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/pagebuf/page_buf.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/pagebuf/page_buf.c 2003-09-27 11:38:39.473527496 +0800
+@@ -174,16 +174,13 @@
+
+ STATIC int
+ _bhash(
+- dev_t dev,
++ struct block_device *bdev,
+ loff_t base)
+ {
+ int bit, hval;
+
+ base >>= 9;
+- /*
+- * dev_t is 16 bits, loff_t is always 64 bits
+- */
+- base ^= dev;
++ base ^= (unsigned long)bdev / L1_CACHE_BYTES;
+ for (bit = hval = 0; base && bit < sizeof(base) * 8; bit += NBITS) {
+ hval ^= (int)base & (NHASH-1);
+ base >>= NBITS;
+@@ -619,7 +616,7 @@
+ /* Ensure we never do IOs that are not sector aligned */
+ BUG_ON(range_base & (loff_t)target->pbr_smask);
+
+- hval = _bhash(target->pbr_bdev->bd_dev, range_base);
++ hval = _bhash(target->pbr_bdev, range_base);
+ h = &pbhash[hval];
+
+ spin_lock(&h->pb_hash_lock);
+@@ -1867,23 +1864,23 @@
+
+ STATIC ctl_table pagebuf_table[] = {
+ {PB_FLUSH_INT, "flush_int", &pb_params.flush_interval.val,
+- sizeof(ulong), 0644, NULL, &proc_doulongvec_ms_jiffies_minmax,
++ sizeof(int), 0644, NULL, &proc_dointvec_minmax,
+ &sysctl_intvec, NULL,
+ &pb_params.flush_interval.min, &pb_params.flush_interval.max},
+
+ {PB_FLUSH_AGE, "flush_age", &pb_params.age_buffer.val,
+- sizeof(ulong), 0644, NULL, &proc_doulongvec_ms_jiffies_minmax,
++ sizeof(int), 0644, NULL, &proc_dointvec_minmax,
+ &sysctl_intvec, NULL,
+ &pb_params.age_buffer.min, &pb_params.age_buffer.max},
+
+ {PB_STATS_CLEAR, "stats_clear", &pb_params.stats_clear.val,
+- sizeof(ulong), 0644, NULL, &pb_stats_clear_handler,
++ sizeof(int), 0644, NULL, &pb_stats_clear_handler,
+ &sysctl_intvec, NULL,
+ &pb_params.stats_clear.min, &pb_params.stats_clear.max},
+
+ #ifdef PAGEBUF_TRACE
+ {PB_DEBUG, "debug", &pb_params.debug.val,
+- sizeof(ulong), 0644, NULL, &proc_doulongvec_minmax,
++ sizeof(int), 0644, NULL, &proc_dointvec_minmax,
+ &sysctl_intvec, NULL,
+ &pb_params.debug.min, &pb_params.debug.max},
+ #endif
+Index: linux-2.6.0-test5/fs/xfs/pagebuf/page_buf_internal.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/pagebuf/page_buf_internal.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/pagebuf/page_buf_internal.h 2003-09-27 11:38:39.475527192 +0800
+@@ -81,9 +81,9 @@
+ */
+
+ typedef struct pb_sysctl_val {
+- ulong min;
+- ulong val;
+- ulong max;
++ int min;
++ int val;
++ int max;
+ } pb_sysctl_val_t;
+
+ typedef struct pagebuf_param {
+Index: linux-2.6.0-test5/fs/xfs/xfs_acl.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_acl.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_acl.c 2003-09-27 11:38:39.481526280 +0800
+@@ -388,6 +388,8 @@
+ vattr_t va;
+ int error;
+
++ if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND))
++ return EPERM;
+ if (kind == _ACL_TYPE_DEFAULT && vp->v_type != VDIR)
+ return ENOTDIR;
+ if (vp->v_vfsp->vfs_flag & VFS_RDONLY)
+Index: linux-2.6.0-test5/fs/xfs/xfs_alloc_btree.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_alloc_btree.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_alloc_btree.c 2003-09-27 11:38:39.499523544 +0800
+@@ -133,7 +133,7 @@
+ *stat = 0;
+ return 0;
+ }
+- XFS_STATS_INC(xfsstats.xs_abt_delrec);
++ XFS_STATS_INC(xs_abt_delrec);
+ /*
+ * It's a nonleaf. Excise the key and ptr being deleted, by
+ * sliding the entries past them down one.
+@@ -631,7 +631,7 @@
+ * and we're done.
+ */
+ if (level >= cur->bc_nlevels) {
+- XFS_STATS_INC(xfsstats.xs_abt_insrec);
++ XFS_STATS_INC(xs_abt_insrec);
+ if ((error = xfs_alloc_newroot(cur, &i)))
+ return error;
+ *bnop = NULLAGBLOCK;
+@@ -651,7 +651,7 @@
+ *stat = 0;
+ return 0;
+ }
+- XFS_STATS_INC(xfsstats.xs_abt_insrec);
++ XFS_STATS_INC(xs_abt_insrec);
+ /*
+ * Get pointers to the btree buffer and block.
+ */
+@@ -951,7 +951,7 @@
+ int level; /* level in the btree */
+ xfs_mount_t *mp; /* file system mount point */
+
+- XFS_STATS_INC(xfsstats.xs_abt_lookup);
++ XFS_STATS_INC(xs_abt_lookup);
+ /*
+ * Get the allocation group header, and the root block number.
+ */
+@@ -1046,7 +1046,7 @@
+ xfs_extlen_t blockcount; /* key value */
+ xfs_agblock_t startblock; /* key value */
+
+- XFS_STATS_INC(xfsstats.xs_abt_compare);
++ XFS_STATS_INC(xs_abt_compare);
+ /*
+ * keyno is average of low and high.
+ */
+Index: linux-2.6.0-test5/fs/xfs/xfs_alloc.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_alloc.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_alloc.c 2003-09-27 11:38:39.518520656 +0800
+@@ -636,8 +636,8 @@
+ xfs_trans_mod_sb(args->tp,
+ args->wasdel ? XFS_TRANS_SB_RES_FDBLOCKS :
+ XFS_TRANS_SB_FDBLOCKS, -slen);
+- XFS_STATS_INC(xfsstats.xs_allocx);
+- XFS_STATS_ADD(xfsstats.xs_allocb, args->len);
++ XFS_STATS_INC(xs_allocx);
++ XFS_STATS_ADD(xs_allocb, args->len);
+ }
+ return 0;
+ }
+@@ -1781,8 +1781,8 @@
+ xfs_alloc_log_agf(tp, agbp, XFS_AGF_FREEBLKS);
+ if (!isfl)
+ xfs_trans_mod_sb(tp, XFS_TRANS_SB_FDBLOCKS, (long)len);
+- XFS_STATS_INC(xfsstats.xs_freex);
+- XFS_STATS_ADD(xfsstats.xs_freeb, len);
++ XFS_STATS_INC(xs_freex);
++ XFS_STATS_ADD(xs_freeb, len);
+ }
+ TRACE_FREE(haveleft ?
+ (haveright ? "both" : "left") :
+Index: linux-2.6.0-test5/fs/xfs/xfs_arch.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_arch.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_arch.h 2003-09-27 11:38:39.522520048 +0800
+@@ -32,8 +32,8 @@
+ #ifndef __XFS_ARCH_H__
+ #define __XFS_ARCH_H__
+
+-#ifndef XFS_BIG_FILESYSTEMS
+-#error XFS_BIG_FILESYSTEMS must be defined true or false
++#ifndef XFS_BIG_INUMS
++# error XFS_BIG_INUMS must be defined true or false
+ #endif
+
+ #ifdef __KERNEL__
+@@ -239,7 +239,7 @@
+ (INT_GET_UNALIGNED_32_BE(pointer)) \
+ )
+
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+ #define DIRINO_GET_ARCH(pointer,arch) \
+ ( ((arch) == ARCH_NOCONVERT) \
+ ? \
+Index: linux-2.6.0-test5/fs/xfs/xfs_attr.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_attr.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_attr.c 2003-09-27 11:38:39.539517464 +0800
+@@ -116,37 +116,37 @@
+ *========================================================================*/
+
+ /*ARGSUSED*/
+-int /* error */
+-xfs_attr_get(bhv_desc_t *bdp, char *name, char *value, int *valuelenp,
+- int flags, struct cred *cred)
++STATIC int
++xfs_attr_get_int(xfs_inode_t *ip, char *name, char *value, int *valuelenp,
++ int flags, int lock, struct cred *cred)
+ {
+ xfs_da_args_t args;
+ int error;
+ int namelen;
+- xfs_inode_t *ip = XFS_BHVTOI(bdp);
+
+- if (!name)
+- return EINVAL;
+ ASSERT(MAXNAMELEN-1 <= 0xff); /* length is stored in uint8 */
+ namelen = strlen(name);
+ if (namelen >= MAXNAMELEN)
+- return EFAULT; /* match IRIX behaviour */
+- XFS_STATS_INC(xfsstats.xs_attr_get);
+-
+- if (XFS_IFORK_Q(ip) == 0)
+- return ENOATTR;
+-
++ return(EFAULT); /* match IRIX behaviour */
++ XFS_STATS_INC(xs_attr_get);
+
+ if (XFS_FORCED_SHUTDOWN(ip->i_mount))
+- return (EIO);
++ return(EIO);
+
+- /*
+- * Do we answer them, or ignore them?
+- */
+- xfs_ilock(ip, XFS_ILOCK_SHARED);
+- if ((error = xfs_iaccess(XFS_BHVTOI(bdp), IREAD, cred))) {
+- xfs_iunlock(ip, XFS_ILOCK_SHARED);
+- return(XFS_ERROR(error));
++ if ((XFS_IFORK_Q(ip) == 0) ||
++ (ip->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
++ ip->i_d.di_anextents == 0))
++ return(ENOATTR);
++
++ if (lock) {
++ xfs_ilock(ip, XFS_ILOCK_SHARED);
++ /*
++ * Do we answer them, or ignore them?
++ */
++ if ((error = xfs_iaccess(ip, IREAD, cred))) {
++ xfs_iunlock(ip, XFS_ILOCK_SHARED);
++ return(XFS_ERROR(error));
++ }
+ }
+
+ /*
+@@ -177,7 +177,9 @@
+ } else {
+ error = xfs_attr_node_get(&args);
+ }
+- xfs_iunlock(ip, XFS_ILOCK_SHARED);
++
++ if (lock)
++ xfs_iunlock(ip, XFS_ILOCK_SHARED);
+
+ /*
+ * Return the number of bytes in the value to the caller.
+@@ -189,6 +191,23 @@
+ return(error);
+ }
+
++int
++xfs_attr_fetch(xfs_inode_t *ip, char *name, char *value, int valuelen)
++{
++ return xfs_attr_get_int(ip, name, value, &valuelen, ATTR_ROOT, 0, NULL);
++}
++
++int
++xfs_attr_get(bhv_desc_t *bdp, char *name, char *value, int *valuelenp,
++ int flags, struct cred *cred)
++{
++ xfs_inode_t *ip = XFS_BHVTOI(bdp);
++
++ if (!name)
++ return(EINVAL);
++ return xfs_attr_get_int(ip, name, value, valuelenp, flags, 1, cred);
++}
++
+ /*ARGSUSED*/
+ int /* error */
+ xfs_attr_set(bhv_desc_t *bdp, char *name, char *value, int valuelen, int flags,
+@@ -210,7 +229,7 @@
+ if (namelen >= MAXNAMELEN)
+ return EFAULT; /* match irix behaviour */
+
+- XFS_STATS_INC(xfsstats.xs_attr_set);
++ XFS_STATS_INC(xs_attr_set);
+ /*
+ * Do we answer them, or ignore them?
+ */
+@@ -468,7 +487,7 @@
+ if (namelen>=MAXNAMELEN)
+ return EFAULT; /* match irix behaviour */
+
+- XFS_STATS_INC(xfsstats.xs_attr_remove);
++ XFS_STATS_INC(xs_attr_remove);
+
+ /*
+ * Do we answer them, or ignore them?
+@@ -620,7 +639,7 @@
+ xfs_inode_t *dp;
+ int error;
+
+- XFS_STATS_INC(xfsstats.xs_attr_list);
++ XFS_STATS_INC(xs_attr_list);
+
+ /*
+ * Validate the cursor.
+@@ -1718,7 +1737,6 @@
+ int i;
+
+ state = xfs_da_state_alloc();
+- state->holeok = 1;
+ state->args = args;
+ state->mp = args->dp->i_mount;
+ state->blocksize = state->mp->m_sb.sb_blocksize;
+Index: linux-2.6.0-test5/fs/xfs/xfs_bit.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_bit.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_bit.c 2003-09-27 11:38:39.542517008 +0800
+@@ -156,12 +156,12 @@
+ {
+ int n;
+ n = ffs((unsigned)v);
+- if (n == 0) {
++ if (n <= 0) {
+ n = ffs(v >> 32);
+ if (n >= 0)
+ n+=32;
+ }
+- return n-1;
++ return (n <= 0) ? n : n-1;
+ }
+
+ /*
+Index: linux-2.6.0-test5/fs/xfs/xfs_bmap_btree.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_bmap_btree.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_bmap_btree.c 2003-09-27 11:38:39.564513664 +0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
++ * Copyright (c) 2000-2003 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
+@@ -392,7 +392,7 @@
+ *stat = 0;
+ return 0;
+ }
+- XFS_STATS_INC(xfsstats.xs_bmbt_delrec);
++ XFS_STATS_INC(xs_bmbt_delrec);
+ if (level > 0) {
+ kp = XFS_BMAP_KEY_IADDR(block, 1, cur);
+ pp = XFS_BMAP_PTR_IADDR(block, 1, cur);
+@@ -784,7 +784,7 @@
+ *stat = 0;
+ return 0;
+ }
+- XFS_STATS_INC(xfsstats.xs_bmbt_insrec);
++ XFS_STATS_INC(xs_bmbt_insrec);
+ block = xfs_bmbt_get_block(cur, level, &bp);
+ numrecs = INT_GET(block->bb_numrecs, ARCH_CONVERT);
+ #ifdef DEBUG
+@@ -1137,7 +1137,7 @@
+ xfs_fileoff_t startoff;
+ xfs_trans_t *tp;
+
+- XFS_STATS_INC(xfsstats.xs_bmbt_lookup);
++ XFS_STATS_INC(xs_bmbt_lookup);
+ XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
+ XFS_BMBT_TRACE_ARGI(cur, (int)dir);
+ tp = cur->bc_tp;
+@@ -1182,7 +1182,7 @@
+ return 0;
+ }
+ while (low <= high) {
+- XFS_STATS_INC(xfsstats.xs_bmbt_compare);
++ XFS_STATS_INC(xs_bmbt_compare);
+ keyno = (low + high) >> 1;
+ if (level > 0) {
+ kkp = kkbase + keyno - 1;
+@@ -1899,7 +1899,7 @@
+ ext_flag = (int)(l0 >> (64 - BMBT_EXNTFLAG_BITLEN));
+ s->br_startoff = ((xfs_fileoff_t)l0 &
+ XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN)) >> 9;
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_BLKNOS
+ s->br_startblock = (((xfs_fsblock_t)l0 & XFS_MASK64LO(9)) << 43) |
+ (((xfs_fsblock_t)l1) >> 21);
+ #else
+@@ -1915,7 +1915,7 @@
+ #else /* !DEBUG */
+ s->br_startblock = (xfs_fsblock_t)(((xfs_dfsbno_t)l1) >> 21);
+ #endif /* DEBUG */
+-#endif /* XFS_BIG_FILESYSTEMS */
++#endif /* XFS_BIG_BLKNOS */
+ s->br_blockcount = (xfs_filblks_t)(l1 & XFS_MASK64LO(21));
+ /* This is xfs_extent_state() in-line */
+ if (ext_flag) {
+@@ -1976,7 +1976,7 @@
+ xfs_bmbt_get_startblock(
+ xfs_bmbt_rec_t *r)
+ {
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_BLKNOS
+ return (((xfs_fsblock_t)r->l0 & XFS_MASK64LO(9)) << 43) |
+ (((xfs_fsblock_t)r->l1) >> 21);
+ #else
+@@ -1990,7 +1990,7 @@
+ #else /* !DEBUG */
+ return (xfs_fsblock_t)(((xfs_dfsbno_t)r->l1) >> 21);
+ #endif /* DEBUG */
+-#endif /* XFS_BIG_FILESYSTEMS */
++#endif /* XFS_BIG_BLKNOS */
+ }
+
+ /*
+@@ -2047,7 +2047,7 @@
+ xfs_bmbt_disk_get_startblock(
+ xfs_bmbt_rec_t *r)
+ {
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_BLKNOS
+ return (((xfs_fsblock_t)INT_GET(r->l0, ARCH_CONVERT) & XFS_MASK64LO(9)) << 43) |
+ (((xfs_fsblock_t)INT_GET(r->l1, ARCH_CONVERT)) >> 21);
+ #else
+@@ -2061,7 +2061,7 @@
+ #else /* !DEBUG */
+ return (xfs_fsblock_t)(((xfs_dfsbno_t)INT_GET(r->l1, ARCH_CONVERT)) >> 21);
+ #endif /* DEBUG */
+-#endif /* XFS_BIG_FILESYSTEMS */
++#endif /* XFS_BIG_BLKNOS */
+ }
+
+ /*
+@@ -2472,17 +2472,15 @@
+ extent_flag = (s->br_state == XFS_EXT_NORM) ? 0 : 1;
+ ASSERT((s->br_startoff & XFS_MASK64HI(9)) == 0);
+ ASSERT((s->br_blockcount & XFS_MASK64HI(43)) == 0);
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_BLKNOS
+ ASSERT((s->br_startblock & XFS_MASK64HI(12)) == 0);
+-#endif /* XFS_BIG_FILESYSTEMS */
+-#if XFS_BIG_FILESYSTEMS
+ r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
+ ((xfs_bmbt_rec_base_t)s->br_startoff << 9) |
+ ((xfs_bmbt_rec_base_t)s->br_startblock >> 43);
+ r->l1 = ((xfs_bmbt_rec_base_t)s->br_startblock << 21) |
+ ((xfs_bmbt_rec_base_t)s->br_blockcount &
+ (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
+-#else /* !XFS_BIG_FILESYSTEMS */
++#else /* !XFS_BIG_BLKNOS */
+ if (ISNULLSTARTBLOCK(s->br_startblock)) {
+ r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
+ ((xfs_bmbt_rec_base_t)s->br_startoff << 9) |
+@@ -2498,7 +2496,7 @@
+ ((xfs_bmbt_rec_base_t)s->br_blockcount &
+ (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
+ }
+-#endif /* XFS_BIG_FILESYSTEMS */
++#endif /* XFS_BIG_BLKNOS */
+ }
+
+ /*
+@@ -2518,17 +2516,15 @@
+ extent_flag = (v == XFS_EXT_NORM) ? 0 : 1;
+ ASSERT((o & XFS_MASK64HI(64-BMBT_STARTOFF_BITLEN)) == 0);
+ ASSERT((c & XFS_MASK64HI(64-BMBT_BLOCKCOUNT_BITLEN)) == 0);
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_BLKNOS
+ ASSERT((b & XFS_MASK64HI(64-BMBT_STARTBLOCK_BITLEN)) == 0);
+-#endif /* XFS_BIG_FILESYSTEMS */
+-#if XFS_BIG_FILESYSTEMS
+ r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
+ ((xfs_bmbt_rec_base_t)o << 9) |
+ ((xfs_bmbt_rec_base_t)b >> 43);
+ r->l1 = ((xfs_bmbt_rec_base_t)b << 21) |
+ ((xfs_bmbt_rec_base_t)c &
+ (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
+-#else /* !XFS_BIG_FILESYSTEMS */
++#else /* !XFS_BIG_BLKNOS */
+ if (ISNULLSTARTBLOCK(b)) {
+ r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
+ ((xfs_bmbt_rec_base_t)o << 9) |
+@@ -2544,7 +2540,7 @@
+ ((xfs_bmbt_rec_base_t)c &
+ (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
+ }
+-#endif /* XFS_BIG_FILESYSTEMS */
++#endif /* XFS_BIG_BLKNOS */
+ }
+
+ #if ARCH_CONVERT != ARCH_NOCONVERT
+@@ -2563,17 +2559,15 @@
+ extent_flag = (s->br_state == XFS_EXT_NORM) ? 0 : 1;
+ ASSERT((s->br_startoff & XFS_MASK64HI(9)) == 0);
+ ASSERT((s->br_blockcount & XFS_MASK64HI(43)) == 0);
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_BLKNOS
+ ASSERT((s->br_startblock & XFS_MASK64HI(12)) == 0);
+-#endif /* XFS_BIG_FILESYSTEMS */
+-#if XFS_BIG_FILESYSTEMS
+ INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) |
+ ((xfs_bmbt_rec_base_t)s->br_startoff << 9) |
+ ((xfs_bmbt_rec_base_t)s->br_startblock >> 43));
+ INT_SET(r->l1, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)s->br_startblock << 21) |
+ ((xfs_bmbt_rec_base_t)s->br_blockcount &
+ (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
+-#else /* !XFS_BIG_FILESYSTEMS */
++#else /* !XFS_BIG_BLKNOS */
+ if (ISNULLSTARTBLOCK(s->br_startblock)) {
+ INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) |
+ ((xfs_bmbt_rec_base_t)s->br_startoff << 9) |
+@@ -2589,7 +2583,7 @@
+ ((xfs_bmbt_rec_base_t)s->br_blockcount &
+ (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
+ }
+-#endif /* XFS_BIG_FILESYSTEMS */
++#endif /* XFS_BIG_BLKNOS */
+ }
+
+ /*
+@@ -2609,17 +2603,15 @@
+ extent_flag = (v == XFS_EXT_NORM) ? 0 : 1;
+ ASSERT((o & XFS_MASK64HI(64-BMBT_STARTOFF_BITLEN)) == 0);
+ ASSERT((c & XFS_MASK64HI(64-BMBT_BLOCKCOUNT_BITLEN)) == 0);
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_BLKNOS
+ ASSERT((b & XFS_MASK64HI(64-BMBT_STARTBLOCK_BITLEN)) == 0);
+-#endif /* XFS_BIG_FILESYSTEMS */
+-#if XFS_BIG_FILESYSTEMS
+ INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) |
+ ((xfs_bmbt_rec_base_t)o << 9) |
+ ((xfs_bmbt_rec_base_t)b >> 43));
+ INT_SET(r->l1, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)b << 21) |
+ ((xfs_bmbt_rec_base_t)c &
+ (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
+-#else /* !XFS_BIG_FILESYSTEMS */
++#else /* !XFS_BIG_BLKNOS */
+ if (ISNULLSTARTBLOCK(b)) {
+ INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) |
+ ((xfs_bmbt_rec_base_t)o << 9) |
+@@ -2635,7 +2627,7 @@
+ ((xfs_bmbt_rec_base_t)c &
+ (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
+ }
+-#endif /* XFS_BIG_FILESYSTEMS */
++#endif /* XFS_BIG_BLKNOS */
+ }
+ #endif
+
+@@ -2660,15 +2652,13 @@
+ xfs_bmbt_rec_t *r,
+ xfs_fsblock_t v)
+ {
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_BLKNOS
+ ASSERT((v & XFS_MASK64HI(12)) == 0);
+-#endif /* XFS_BIG_FILESYSTEMS */
+-#if XFS_BIG_FILESYSTEMS
+ r->l0 = (r->l0 & (xfs_bmbt_rec_base_t)XFS_MASK64HI(55)) |
+ (xfs_bmbt_rec_base_t)(v >> 43);
+ r->l1 = (r->l1 & (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)) |
+ (xfs_bmbt_rec_base_t)(v << 21);
+-#else /* !XFS_BIG_FILESYSTEMS */
++#else /* !XFS_BIG_BLKNOS */
+ if (ISNULLSTARTBLOCK(v)) {
+ r->l0 |= (xfs_bmbt_rec_base_t)XFS_MASK64LO(9);
+ r->l1 = (xfs_bmbt_rec_base_t)XFS_MASK64HI(11) |
+@@ -2679,7 +2669,7 @@
+ r->l1 = ((xfs_bmbt_rec_base_t)v << 21) |
+ (r->l1 & (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
+ }
+-#endif /* XFS_BIG_FILESYSTEMS */
++#endif /* XFS_BIG_BLKNOS */
+ }
+
+ /*
+Index: linux-2.6.0-test5/fs/xfs/xfs_bmap_btree.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_bmap_btree.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_bmap_btree.h 2003-09-27 11:38:39.570512752 +0800
+@@ -108,7 +108,7 @@
+ * Values and macros for delayed-allocation startblock fields.
+ */
+ #define STARTBLOCKVALBITS 17
+-#define STARTBLOCKMASKBITS (15 + XFS_BIG_FILESYSTEMS * 20)
++#define STARTBLOCKMASKBITS (15 + XFS_BIG_BLKNOS * 20)
+ #define DSTARTBLOCKMASKBITS (15 + 20)
+ #define STARTBLOCKMASK \
+ (((((xfs_fsblock_t)1) << STARTBLOCKMASKBITS) - 1) << STARTBLOCKVALBITS)
+Index: linux-2.6.0-test5/fs/xfs/xfs_bmap.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_bmap.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_bmap.c 2003-09-27 11:38:39.617505608 +0800
+@@ -52,7 +52,6 @@
+ #include "xfs_dir_sf.h"
+ #include "xfs_dir2_sf.h"
+ #include "xfs_dinode.h"
+-#include "xfs_dmapi.h"
+ #include "xfs_inode_item.h"
+ #include "xfs_inode.h"
+ #include "xfs_itable.h"
+@@ -565,7 +564,7 @@
+ int logflags; /* returned value */
+ xfs_extnum_t nextents; /* number of extents in file now */
+
+- XFS_STATS_INC(xfsstats.xs_add_exlist);
++ XFS_STATS_INC(xs_add_exlist);
+ cur = *curp;
+ ifp = XFS_IFORK_PTR(ip, whichfork);
+ nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+@@ -2837,7 +2836,7 @@
+ xfs_filblks_t temp; /* for indirect length calculations */
+ xfs_filblks_t temp2; /* for indirect length calculations */
+
+- XFS_STATS_INC(xfsstats.xs_del_exlist);
++ XFS_STATS_INC(xs_del_exlist);
+ mp = ip->i_mount;
+ ifp = XFS_IFORK_PTR(ip, whichfork);
+ nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+@@ -3462,7 +3461,7 @@
+ low = 0;
+ high = nextents - 1;
+ while (low <= high) {
+- XFS_STATS_INC(xfsstats.xs_cmp_exlist);
++ XFS_STATS_INC(xs_cmp_exlist);
+ lastx = (low + high) >> 1;
+ ep = base + lastx;
+ got.br_startoff = xfs_bmbt_get_startoff(ep);
+@@ -3532,7 +3531,7 @@
+ xfs_extnum_t lastx; /* last extent index used */
+ xfs_extnum_t nextents; /* extent list size */
+
+- XFS_STATS_INC(xfsstats.xs_look_exlist);
++ XFS_STATS_INC(xs_look_exlist);
+ ifp = XFS_IFORK_PTR(ip, whichfork);
+ lastx = ifp->if_lastex;
+ nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+@@ -4630,9 +4629,9 @@
+ ASSERT(ifp->if_ext_max ==
+ XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
+ if ((wr = (flags & XFS_BMAPI_WRITE)) != 0)
+- XFS_STATS_INC(xfsstats.xs_blk_mapw);
++ XFS_STATS_INC(xs_blk_mapw);
+ else
+- XFS_STATS_INC(xfsstats.xs_blk_mapr);
++ XFS_STATS_INC(xs_blk_mapr);
+ delay = (flags & XFS_BMAPI_DELAY) != 0;
+ trim = (flags & XFS_BMAPI_ENTIRE) == 0;
+ userdata = (flags & XFS_BMAPI_METADATA) == 0;
+@@ -5116,7 +5115,7 @@
+ }
+ if (XFS_FORCED_SHUTDOWN(ip->i_mount))
+ return XFS_ERROR(EIO);
+- XFS_STATS_INC(xfsstats.xs_blk_mapr);
++ XFS_STATS_INC(xs_blk_mapr);
+ if (!(ifp->if_flags & XFS_IFEXTENTS) &&
+ (error = xfs_iread_extents(tp, ip, whichfork)))
+ return error;
+@@ -5205,7 +5204,7 @@
+ *done = 1;
+ return 0;
+ }
+- XFS_STATS_INC(xfsstats.xs_blk_unmap);
++ XFS_STATS_INC(xs_blk_unmap);
+ isrt = (whichfork == XFS_DATA_FORK) &&
+ (ip->i_d.di_flags & XFS_DIFLAG_REALTIME);
+ start = bno;
+Index: linux-2.6.0-test5/fs/xfs/xfs_cap.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_cap.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_cap.c 2003-09-27 11:38:39.622504848 +0800
+@@ -192,6 +192,8 @@
+
+ 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;
+Index: linux-2.6.0-test5/fs/xfs/xfs_da_btree.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_da_btree.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_da_btree.c 2003-09-27 11:38:39.642501808 +0800
+@@ -1141,12 +1141,10 @@
+ xfs_da_node_entry_t *btree;
+ xfs_dablk_t blkno;
+ int probe, span, max, error, retval;
+- xfs_daddr_t mappedbno;
+ xfs_dahash_t hashval;
+ xfs_da_args_t *args;
+
+ args = state->args;
+- mappedbno = state->holeok ? -2 : -1;
+
+ /*
+ * Descend thru the B-tree searching each level for the right
+@@ -1164,9 +1162,7 @@
+ */
+ blk->blkno = blkno;
+ error = xfs_da_read_buf(args->trans, args->dp, blkno,
+- mappedbno, &blk->bp, args->whichfork);
+- if (!error && unlikely(state->holeok && !blk->bp))
+- error = XFS_ERROR(ENOATTR); /* always attr here */
++ -1, &blk->bp, args->whichfork);
+ if (error) {
+ blk->blkno = 0;
+ state->path.active--;
+@@ -2170,9 +2166,9 @@
+ if (xfs_error_level >= XFS_ERRLEVEL_LOW) {
+ int i;
+ cmn_err(CE_ALERT, "xfs_da_do_buf: bno %lld\n",
+- bno);
++ (long long)bno);
+ cmn_err(CE_ALERT, "dir: inode %lld\n",
+- dp->i_ino);
++ (long long)dp->i_ino);
+ for (i = 0; i < nmap; i++) {
+ cmn_err(CE_ALERT,
+ "[%02d] br_startoff %lld br_startblock %lld br_blockcount %lld br_state %d\n",
+Index: linux-2.6.0-test5/fs/xfs/xfs_da_btree.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_da_btree.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_da_btree.h 2003-09-27 11:38:39.653500136 +0800
+@@ -189,10 +189,10 @@
+ int index2; /* index of 2nd attr in blk */
+ xfs_dablk_t rmtblkno2; /* remote attr value starting blkno */
+ int rmtblkcnt2; /* remote attr value block count */
+- int justcheck : 1; /* T/F: check for ok with no space */
+- int rename : 1; /* T/F: this is an atomic rename op */
+- int addname : 1; /* T/F: this is an add operation */
+- int oknoent : 1; /* T/F: ok to return ENOENT, else die */
++ unsigned char justcheck; /* T/F: check for ok with no space */
++ unsigned char rename; /* T/F: this is an atomic rename op */
++ unsigned char addname; /* T/F: this is an add operation */
++ unsigned char oknoent; /* T/F: ok to return ENOENT, else die */
+ } xfs_da_args_t;
+
+ /*
+@@ -252,10 +252,9 @@
+ unsigned int node_ents; /* how many entries in danode */
+ xfs_da_state_path_t path; /* search/split paths */
+ xfs_da_state_path_t altpath; /* alternate path for join */
+- unsigned int inleaf : 1; /* insert into 1->lf, 0->splf */
+- unsigned int holeok : 1; /* T/F: can deal with a hole */
+- unsigned int extravalid : 1; /* T/F: extrablk is in use */
+- unsigned int extraafter : 1; /* T/F: extrablk is after new */
++ unsigned char inleaf; /* insert into 1->lf, 0->splf */
++ unsigned char extravalid; /* T/F: extrablk is in use */
++ unsigned char extraafter; /* T/F: extrablk is after new */
+ xfs_da_state_blk_t extrablk; /* for double-splits on leafs */
+ /* for dirv2 extrablk is data */
+ } xfs_da_state_t;
+Index: linux-2.6.0-test5/fs/xfs/xfs_dinode.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_dinode.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_dinode.h 2003-09-27 11:38:39.658499376 +0800
+@@ -471,13 +471,21 @@
+ * There should be a one-to-one correspondence between these flags and the
+ * XFS_XFLAG_s.
+ */
+-#define XFS_DIFLAG_REALTIME_BIT 0 /* file's blocks come from rt area */
+-#define XFS_DIFLAG_PREALLOC_BIT 1 /* file space has been preallocated */
+-#define XFS_DIFLAG_NEWRTBM_BIT 2 /* for rtbitmap inode, new format */
+-#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)
+-#define XFS_DIFLAG_ALL \
+- (XFS_DIFLAG_REALTIME|XFS_DIFLAG_PREALLOC|XFS_DIFLAG_NEWRTBM)
++#define XFS_DIFLAG_REALTIME_BIT 0 /* file's blocks come from rt area */
++#define XFS_DIFLAG_PREALLOC_BIT 1 /* file space has been preallocated */
++#define XFS_DIFLAG_NEWRTBM_BIT 2 /* for rtbitmap inode, new format */
++#define XFS_DIFLAG_IMMUTABLE_BIT 3 /* inode is immutable */
++#define XFS_DIFLAG_APPEND_BIT 4 /* inode is append-only */
++#define XFS_DIFLAG_SYNC_BIT 5 /* inode is written synchronously */
++#define XFS_DIFLAG_NOATIME_BIT 6 /* do not update atime */
++#define XFS_DIFLAG_NODUMP_BIT 7 /* do not dump */
++#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)
++#define XFS_DIFLAG_IMMUTABLE (1 << XFS_DIFLAG_IMMUTABLE_BIT)
++#define XFS_DIFLAG_APPEND (1 << XFS_DIFLAG_APPEND_BIT)
++#define XFS_DIFLAG_SYNC (1 << XFS_DIFLAG_SYNC_BIT)
++#define XFS_DIFLAG_NOATIME (1 << XFS_DIFLAG_NOATIME_BIT)
++#define XFS_DIFLAG_NODUMP (1 << XFS_DIFLAG_NODUMP_BIT)
+
+ #endif /* __XFS_DINODE_H__ */
+Index: linux-2.6.0-test5/fs/xfs/xfs_dir2_block.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_dir2_block.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_dir2_block.c 2003-09-27 11:38:39.668497856 +0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
++ * Copyright (c) 2000-2003 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
+@@ -530,10 +530,9 @@
+
+ p.cook = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk,
+ ptr - (char *)block);
+-#if XFS_BIG_FILESYSTEMS
+- p.ino = INT_GET(dep->inumber, ARCH_CONVERT) + mp->m_inoadd;
+-#else
+ p.ino = INT_GET(dep->inumber, ARCH_CONVERT);
++#if XFS_BIG_INUMS
++ p.ino += mp->m_inoadd;
+ #endif
+ p.name = (char *)dep->name;
+
+Index: linux-2.6.0-test5/fs/xfs/xfs_dir2.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_dir2.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_dir2.c 2003-09-27 11:38:39.674496944 +0800
+@@ -63,7 +63,6 @@
+ #include "xfs_dir2_leaf.h"
+ #include "xfs_dir2_block.h"
+ #include "xfs_dir2_node.h"
+-#include "xfs_dir2_sf.h"
+ #include "xfs_dir2_trace.h"
+ #include "xfs_error.h"
+ #include "xfs_bit.h"
+@@ -213,7 +212,7 @@
+ if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) {
+ return rval;
+ }
+- XFS_STATS_INC(xfsstats.xs_dir_create);
++ XFS_STATS_INC(xs_dir_create);
+ /*
+ * Fill in the arg structure for this request.
+ */
+@@ -263,7 +262,7 @@
+ int v; /* type-checking value */
+
+ ASSERT((dp->i_d.di_mode & IFMT) == IFDIR);
+- XFS_STATS_INC(xfsstats.xs_dir_lookup);
++ XFS_STATS_INC(xs_dir_lookup);
+
+ /*
+ * Fill in the arg structure for this request.
+@@ -321,7 +320,7 @@
+ int v; /* type-checking value */
+
+ ASSERT((dp->i_d.di_mode & IFMT) == IFDIR);
+- XFS_STATS_INC(xfsstats.xs_dir_remove);
++ XFS_STATS_INC(xs_dir_remove);
+ /*
+ * Fill in the arg structure for this request.
+ */
+@@ -371,7 +370,7 @@
+ int v; /* type-checking value */
+
+ ASSERT((dp->i_d.di_mode & IFMT) == IFDIR);
+- XFS_STATS_INC(xfsstats.xs_dir_getdents);
++ XFS_STATS_INC(xs_dir_getdents);
+ /*
+ * If our caller has given us a single contiguous aligned memory buffer,
+ * just work directly within that buffer. If it's in user memory,
+Index: linux-2.6.0-test5/fs/xfs/xfs_dir2_leaf.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_dir2_leaf.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_dir2_leaf.c 2003-09-27 11:38:39.689494664 +0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
++ * Copyright (c) 2000-2003 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
+@@ -1118,10 +1118,9 @@
+
+ p.cook = XFS_DIR2_BYTE_TO_DATAPTR(mp, curoff + length);
+
+-#if XFS_BIG_FILESYSTEMS
+- p.ino = INT_GET(dep->inumber, ARCH_CONVERT) + mp->m_inoadd;
+-#else
+ p.ino = INT_GET(dep->inumber, ARCH_CONVERT);
++#if XFS_BIG_INUMS
++ p.ino += mp->m_inoadd;
+ #endif
+ p.name = (char *)dep->name;
+
+Index: linux-2.6.0-test5/fs/xfs/xfs_dir2_node.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_dir2_node.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_dir2_node.c 2003-09-27 11:38:39.705492232 +0800
+@@ -1612,7 +1612,8 @@
+ if (XFS_DIR2_DB_TO_FDB(mp, dbno) != fbno) {
+ cmn_err(CE_ALERT,
+ "xfs_dir2_node_addname_int: needed block %lld, got %lld\n",
+- XFS_DIR2_DB_TO_FDB(mp, dbno), fbno);
++ (long long)XFS_DIR2_DB_TO_FDB(mp, dbno),
++ (long long)fbno);
+ XFS_ERROR_REPORT("xfs_dir2_node_addname_int",
+ XFS_ERRLEVEL_LOW, mp);
+ return XFS_ERROR(EFSCORRUPTED);
+Index: linux-2.6.0-test5/fs/xfs/xfs_dir2_sf.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_dir2_sf.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_dir2_sf.c 2003-09-27 11:38:39.716490560 +0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
++ * Copyright (c) 2000-2003 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
+@@ -79,10 +79,10 @@
+ #else
+ #define xfs_dir2_sf_check(args)
+ #endif /* DEBUG */
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+ static void xfs_dir2_sf_toino4(xfs_da_args_t *args);
+ static void xfs_dir2_sf_toino8(xfs_da_args_t *args);
+-#endif /* XFS_BIG_FILESYSTEMS */
++#endif /* XFS_BIG_INUMS */
+
+ /*
+ * Given a block directory (dp/block), calculate its size as a shortform (sf)
+@@ -136,7 +136,7 @@
+ isdotdot =
+ dep->namelen == 2 &&
+ dep->name[0] == '.' && dep->name[1] == '.';
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+ if (!isdot)
+ i8count += INT_GET(dep->inumber, ARCH_CONVERT) > XFS_DIR2_MAX_SHORT_INUM;
+ #endif
+@@ -324,7 +324,8 @@
+ */
+ add_entsize = XFS_DIR2_SF_ENTSIZE_BYNAME(sfp, args->namelen);
+ incr_isize = add_entsize;
+-#if XFS_BIG_FILESYSTEMS
++ objchange = 0;
++#if XFS_BIG_INUMS
+ /*
+ * Do we have to change to 8 byte inodes?
+ */
+@@ -340,10 +341,7 @@
+ ((uint)sizeof(xfs_dir2_ino8_t) -
+ (uint)sizeof(xfs_dir2_ino4_t));
+ objchange = 1;
+- } else
+- objchange = 0;
+-#else
+- objchange = 0;
++ }
+ #endif
+ old_isize = (int)dp->i_d.di_size;
+ new_isize = old_isize + incr_isize;
+@@ -383,7 +381,7 @@
+ */
+ else {
+ ASSERT(pick == 2);
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+ if (objchange)
+ xfs_dir2_sf_toino8(args);
+ #endif
+@@ -437,7 +435,7 @@
+ * Update the header and inode.
+ */
+ sfp->hdr.count++;
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+ if (args->inumber > XFS_DIR2_MAX_SHORT_INUM)
+ sfp->hdr.i8count++;
+ #endif
+@@ -526,7 +524,7 @@
+ XFS_DIR2_SF_PUT_INUMBER_ARCH(sfp, &args->inumber,
+ XFS_DIR2_SF_INUMBERP(sfep), ARCH_CONVERT);
+ sfp->hdr.count++;
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+ if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && !objchange)
+ sfp->hdr.i8count++;
+ #endif
+@@ -603,7 +601,7 @@
+ /*
+ * If changing the inode number size, do it the hard way.
+ */
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+ if (objchange) {
+ return 2;
+ }
+@@ -657,9 +655,7 @@
+ XFS_DIR2_DATA_ENTSIZE(sfep->namelen);
+ }
+ ASSERT(i8count == sfp->hdr.i8count);
+-#if !XFS_BIG_FILESYSTEMS
+- ASSERT(i8count == 0);
+-#endif
++ ASSERT(XFS_BIG_INUMS || i8count == 0);
+ ASSERT((char *)sfep - (char *)sfp == dp->i_d.di_size);
+ ASSERT(offset +
+ (sfp->hdr.count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t) +
+@@ -779,10 +775,9 @@
+ XFS_DIR2_DATA_DOT_OFFSET)) {
+ p.cook = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, 0,
+ XFS_DIR2_DATA_DOTDOT_OFFSET);
+-#if XFS_BIG_FILESYSTEMS
+- p.ino = dp->i_ino + mp->m_inoadd;
+-#else
+ p.ino = dp->i_ino;
++#if XFS_BIG_INUMS
++ p.ino += mp->m_inoadd;
+ #endif
+ p.name = ".";
+ p.namelen = 1;
+@@ -805,11 +800,10 @@
+ XFS_DIR2_DATA_DOTDOT_OFFSET)) {
+ p.cook = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk,
+ XFS_DIR2_DATA_FIRST_OFFSET);
+-#if XFS_BIG_FILESYSTEMS
+- p.ino = XFS_DIR2_SF_GET_INUMBER_ARCH(sfp, &sfp->hdr.parent, ARCH_CONVERT) +
+- mp->m_inoadd;
+-#else
+- p.ino = XFS_DIR2_SF_GET_INUMBER_ARCH(sfp, &sfp->hdr.parent, ARCH_CONVERT);
++ p.ino = XFS_DIR2_SF_GET_INUMBER_ARCH(sfp, &sfp->hdr.parent,
++ ARCH_CONVERT);
++#if XFS_BIG_INUMS
++ p.ino += mp->m_inoadd;
+ #endif
+ p.name = "..";
+ p.namelen = 2;
+@@ -843,13 +837,10 @@
+ XFS_DIR2_SF_GET_OFFSET_ARCH(sfep, ARCH_CONVERT) +
+ XFS_DIR2_DATA_ENTSIZE(p.namelen));
+
+-#if XFS_BIG_FILESYSTEMS
+- p.ino = XFS_DIR2_SF_GET_INUMBER_ARCH(sfp,
+- XFS_DIR2_SF_INUMBERP(sfep), ARCH_CONVERT) +
+- mp->m_inoadd;
+-#else
+ p.ino = XFS_DIR2_SF_GET_INUMBER_ARCH(sfp,
+ XFS_DIR2_SF_INUMBERP(sfep), ARCH_CONVERT);
++#if XFS_BIG_INUMS
++ p.ino += mp->m_inoadd;
+ #endif
+ p.name = (char *)sfep->name;
+
+@@ -1014,7 +1005,7 @@
+ */
+ xfs_idata_realloc(dp, newsize - oldsize, XFS_DATA_FORK);
+ sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data;
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+ /*
+ * Are we changing inode number size?
+ */
+@@ -1039,10 +1030,10 @@
+ {
+ xfs_inode_t *dp; /* incore directory inode */
+ int i; /* entry index */
+-#if XFS_BIG_FILESYSTEMS || defined(DEBUG)
++#if XFS_BIG_INUMS || defined(DEBUG)
+ xfs_ino_t ino=0; /* entry old inode number */
+ #endif
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+ int i8elevated; /* sf_toino8 set i8count=1 */
+ #endif
+ xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */
+@@ -1063,7 +1054,7 @@
+ ASSERT(dp->i_df.if_u1.if_data != NULL);
+ sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data;
+ ASSERT(dp->i_d.di_size >= XFS_DIR2_SF_HDR_SIZE(sfp->hdr.i8count));
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+ /*
+ * New inode number is large, and need to convert to 8-byte inodes.
+ */
+@@ -1101,7 +1092,7 @@
+ */
+ if (args->namelen == 2 &&
+ args->name[0] == '.' && args->name[1] == '.') {
+-#if XFS_BIG_FILESYSTEMS || defined(DEBUG)
++#if XFS_BIG_INUMS || defined(DEBUG)
+ ino = XFS_DIR2_SF_GET_INUMBER_ARCH(sfp, &sfp->hdr.parent, ARCH_CONVERT);
+ ASSERT(args->inumber != ino);
+ #endif
+@@ -1117,7 +1108,7 @@
+ if (sfep->namelen == args->namelen &&
+ sfep->name[0] == args->name[0] &&
+ memcmp(args->name, sfep->name, args->namelen) == 0) {
+-#if XFS_BIG_FILESYSTEMS || defined(DEBUG)
++#if XFS_BIG_INUMS || defined(DEBUG)
+ ino = XFS_DIR2_SF_GET_INUMBER_ARCH(sfp,
+ XFS_DIR2_SF_INUMBERP(sfep), ARCH_CONVERT);
+ ASSERT(args->inumber != ino);
+@@ -1132,14 +1123,14 @@
+ */
+ if (i == sfp->hdr.count) {
+ ASSERT(args->oknoent);
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+ if (i8elevated)
+ xfs_dir2_sf_toino4(args);
+ #endif
+ return XFS_ERROR(ENOENT);
+ }
+ }
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+ /*
+ * See if the old number was large, the new number is small.
+ */
+@@ -1172,7 +1163,7 @@
+ return 0;
+ }
+
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+ /*
+ * Convert from 8-byte inode numbers to 4-byte inode numbers.
+ * The last 8-byte inode number is gone, but the count is still 1.
+@@ -1325,4 +1316,4 @@
+ dp->i_d.di_size = newsize;
+ xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA);
+ }
+-#endif /* XFS_BIG_FILESYSTEMS */
++#endif /* XFS_BIG_INUMS */
+Index: linux-2.6.0-test5/fs/xfs/xfs_dir.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_dir.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_dir.c 2003-09-27 11:38:39.725489192 +0800
+@@ -262,7 +262,7 @@
+ if ((retval = xfs_dir_ino_validate(trans->t_mountp, inum)))
+ return (retval);
+
+- XFS_STATS_INC(xfsstats.xs_dir_create);
++ XFS_STATS_INC(xs_dir_create);
+ /*
+ * Fill in the arg structure for this request.
+ */
+@@ -367,7 +367,7 @@
+ int count, totallen, newsize, retval;
+
+ ASSERT((dp->i_d.di_mode & IFMT) == IFDIR);
+- XFS_STATS_INC(xfsstats.xs_dir_remove);
++ XFS_STATS_INC(xs_dir_remove);
+ /*
+ * Fill in the arg structure for this request.
+ */
+@@ -411,7 +411,7 @@
+
+ ASSERT((dp->i_d.di_mode & IFMT) == IFDIR);
+
+- XFS_STATS_INC(xfsstats.xs_dir_lookup);
++ XFS_STATS_INC(xs_dir_lookup);
+ /*
+ * Fill in the arg structure for this request.
+ */
+@@ -454,7 +454,7 @@
+ int alignment, retval;
+ xfs_dir_put_t put;
+
+- XFS_STATS_INC(xfsstats.xs_dir_getdents);
++ XFS_STATS_INC(xs_dir_getdents);
+ ASSERT((dp->i_d.di_mode & IFMT) == IFDIR);
+
+ /*
+Index: linux-2.6.0-test5/fs/xfs/xfs_dir_leaf.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_dir_leaf.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_dir_leaf.c 2003-09-27 11:38:39.743486456 +0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
++ * Copyright (c) 2000-2003 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
+@@ -561,10 +561,9 @@
+ if (sbp->seqno == 0 || sbp == sbuf)
+ lastresid = uio->uio_resid;
+ XFS_PUT_COOKIE(p.cook, mp, 0, sbp[1].seqno, sbp[1].hash);
+-#if XFS_BIG_FILESYSTEMS
+- p.ino = sbp->ino + mp->m_inoadd;
+-#else
+ p.ino = sbp->ino;
++#if XFS_BIG_INUMS
++ p.ino += mp->m_inoadd;
+ #endif
+ p.name = sbp->name;
+ p.namelen = sbp->namelen;
+@@ -1835,7 +1834,6 @@
+ entry_d = &leaf_d->entries[start_d];
+ for (i = 0; i < count; entry_s++, entry_d++, i++) {
+ ASSERT(INT_GET(entry_s->nameidx, ARCH_CONVERT) >= INT_GET(hdr_s->firstused, ARCH_CONVERT));
+- ASSERT(entry_s->namelen < MAXNAMELEN);
+ tmp = XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry_s);
+ INT_MOD(hdr_d->firstused, ARCH_CONVERT, -(tmp));
+ entry_d->hashval = entry_s->hashval; /* INT_: direct copy */
+@@ -2142,10 +2140,9 @@
+ * then restore the UIO to the first entry in the current
+ * run of equal-hashval entries (probably one 1 entry long).
+ */
+-#if XFS_BIG_FILESYSTEMS
+- p.ino = XFS_GET_DIR_INO_ARCH(mp, namest->inumber, ARCH_CONVERT) + mp->m_inoadd;
+-#else
+ p.ino = XFS_GET_DIR_INO_ARCH(mp, namest->inumber, ARCH_CONVERT);
++#if XFS_BIG_INUMS
++ p.ino += mp->m_inoadd;
+ #endif
+ p.name = (char *)namest->name;
+ p.namelen = entry->namelen;
+Index: linux-2.6.0-test5/fs/xfs/xfs_error.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_error.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_error.c 2003-09-27 11:38:39.745486152 +0800
+@@ -238,7 +238,7 @@
+ }
+
+ void
+-xfs_cmn_err(uint64_t panic_tag, int level, xfs_mount_t *mp, char *fmt, ...)
++xfs_cmn_err(int panic_tag, int level, xfs_mount_t *mp, char *fmt, ...)
+ {
+ va_list ap;
+
+Index: linux-2.6.0-test5/fs/xfs/xfs_error.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_error.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_error.h 2003-09-27 11:38:39.748485696 +0800
+@@ -33,7 +33,7 @@
+ #define __XFS_ERROR_H__
+
+ #define prdev(fmt,dev,args...) \
+- printk("XFS: device 0x%x- " fmt "\n", (unsigned)dev, ## args)
++ printk("XFS: device %u:%u- " fmt "\n", MAJOR(dev), MINOR(dev), ## args)
+
+ #define XFS_ERECOVER 1 /* Failure to recover log */
+ #define XFS_ELOGSTAT 2 /* Failure to stat log in user space */
+@@ -177,18 +177,18 @@
+ * sysctl. update xfs_max[XFS_PARAM] if
+ * more are added.
+ */
+-#define XFS_NO_PTAG 0LL
+-#define XFS_PTAG_IFLUSH 0x0000000000000001LL
+-#define XFS_PTAG_LOGRES 0x0000000000000002LL
+-#define XFS_PTAG_AILDELETE 0x0000000000000004LL
+-#define XFS_PTAG_ERROR_REPORT 0x0000000000000008LL
+-#define XFS_PTAG_SHUTDOWN_CORRUPT 0x0000000000000010LL
+-#define XFS_PTAG_SHUTDOWN_IOERROR 0x0000000000000020LL
+-#define XFS_PTAG_SHUTDOWN_LOGERROR 0x0000000000000040LL
++#define XFS_NO_PTAG 0
++#define XFS_PTAG_IFLUSH 0x00000001
++#define XFS_PTAG_LOGRES 0x00000002
++#define XFS_PTAG_AILDELETE 0x00000004
++#define XFS_PTAG_ERROR_REPORT 0x00000008
++#define XFS_PTAG_SHUTDOWN_CORRUPT 0x00000010
++#define XFS_PTAG_SHUTDOWN_IOERROR 0x00000020
++#define XFS_PTAG_SHUTDOWN_LOGERROR 0x00000040
+
+ struct xfs_mount;
+ /* PRINTFLIKE4 */
+-void xfs_cmn_err(uint64_t panic_tag, int level, struct xfs_mount *mp,
++void xfs_cmn_err(int panic_tag, int level, struct xfs_mount *mp,
+ char *fmt, ...);
+ /* PRINTFLIKE3 */
+ void xfs_fs_cmn_err(int level, struct xfs_mount *mp, char *fmt, ...);
+Index: linux-2.6.0-test5/fs/xfs/xfs_fs.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_fs.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_fs.h 2003-09-27 11:38:39.753484936 +0800
+@@ -69,12 +69,14 @@
+ * There should be a one-to-one correspondence between these flags and the
+ * XFS_DIFLAG_s.
+ */
+-#define XFS_XFLAG_REALTIME 0x00000001
+-#define XFS_XFLAG_PREALLOC 0x00000002
++#define XFS_XFLAG_REALTIME 0x00000001 /* data in realtime volume */
++#define XFS_XFLAG_PREALLOC 0x00000002 /* preallocated file extents */
++#define XFS_XFLAG_IMMUTABLE 0x00000008 /* file cannot be modified */
++#define XFS_XFLAG_APPEND 0x00000010 /* all writes append */
++#define XFS_XFLAG_SYNC 0x00000020 /* all writes synchronous */
++#define XFS_XFLAG_NOATIME 0x00000040 /* do not update access time */
++#define XFS_XFLAG_NODUMP 0x00000080 /* do not include in backups */
+ #define XFS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */
+-#define XFS_XFLAG_ALL \
+- ( XFS_XFLAG_REALTIME|XFS_XFLAG_PREALLOC|XFS_XFLAG_HASATTR )
+-
+
+ /*
+ * Structure for XFS_IOC_GETBMAP.
+Index: linux-2.6.0-test5/fs/xfs/xfs_fsops.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_fsops.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_fsops.c 2003-09-27 11:38:39.758484176 +0800
+@@ -53,7 +53,6 @@
+ #include "xfs_rw.h"
+ #include "xfs_trans_space.h"
+ #include "xfs_rtalloc.h"
+-#include "xfs_dir.h"
+ #include "xfs_dir2.h"
+ #include "xfs_attr_sf.h"
+ #include "xfs_dir_sf.h"
+@@ -172,7 +171,7 @@
+ if (nb < mp->m_sb.sb_dblocks)
+ return XFS_ERROR(EINVAL);
+ }
+- new = in->newblocks - mp->m_sb.sb_dblocks;
++ new = nb - mp->m_sb.sb_dblocks;
+ oagcount = mp->m_sb.sb_agcount;
+ if (nagcount > oagcount) {
+ down_write(&mp->m_peraglock);
+Index: linux-2.6.0-test5/fs/xfs/xfs_ialloc.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_ialloc.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_ialloc.c 2003-09-27 11:38:39.768482656 +0800
+@@ -1114,7 +1114,7 @@
+ agbno = XFS_AGINO_TO_AGBNO(mp, agino);
+ if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks ||
+ ino != XFS_AGINO_TO_INO(mp, agno, agino)) {
+-#ifdef DEBUG
++#if 0
+ if (agno >= mp->m_sb.sb_agcount) {
+ xfs_fs_cmn_err(CE_ALERT, mp,
+ "xfs_dilocate: agno (%d) >= "
+Index: linux-2.6.0-test5/fs/xfs/xfsidbg.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfsidbg.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfsidbg.c 2003-09-27 11:38:39.804477184 +0800
+@@ -78,7 +78,6 @@
+ #include "xfs_rw.h"
+ #include "xfs_bit.h"
+ #include "xfs_quota.h"
+-#include "xfs_log_recover.h"
+ #include "quota/xfs_qm.h"
+
+ MODULE_AUTHOR("Silicon Graphics, Inc.");
+@@ -1685,9 +1684,11 @@
+ ip->i_size);
+
+ kdb_printf(
+- " i_mode = 0x%x i_nlink = %d i_rdev = 0x%x i_state = 0x%lx\n",
++ " i_mode = 0x%x i_nlink = %d i_rdev = %u:%u i_state = 0x%lx\n",
+ ip->i_mode, ip->i_nlink,
+- ip->i_rdev, ip->i_state);
++ MAJOR(ip->i_rdev),
++ MINOR(ip->i_rdev),
++ ip->i_state);
+
+ kdb_printf(" i_hash.nxt = 0x%p i_hash.prv = 0x%p\n",
+ ip->i_hash.next, ip->i_hash.prev);
+@@ -3022,6 +3023,12 @@
+ static char *diflags[] = {
+ "realtime", /* XFS_DIFLAG_REALTIME */
+ "prealloc", /* XFS_DIFLAG_PREALLOC */
++ "newrtbm", /* XFS_DIFLAG_NEWRTBM */
++ "immutable", /* XFS_DIFLAG_IMMUTABLE */
++ "append", /* XFS_DIFLAG_APPEND */
++ "sync", /* XFS_DIFLAG_SYNC */
++ "noatime", /* XFS_DIFLAG_NOATIME */
++ "nodump", /* XFS_DIFLAG_NODUMP */
+ NULL
+ };
+
+@@ -3732,8 +3739,9 @@
+ kdb_printf(" %d:0x%p", i, dabuf->bps[i]);
+ kdb_printf("\n");
+ #ifdef XFS_DABUF_DEBUG
+- kdb_printf(" ra 0x%x prev 0x%x next 0x%x dev 0x%x blkno 0x%x\n",
+- dabuf->ra, dabuf->prev, dabuf->next, dabuf->dev, dabuf->blkno);
++ kdb_printf(" ra 0x%x prev 0x%x next 0x%x dev %u:%u blkno 0x%x\n",
++ dabuf->ra, dabuf->prev, dabuf->next,
++ MAJOR(dabuf->dev), MINOR(dabuf->dev), dabuf->blkno);
+ #endif
+ }
+
+@@ -4261,8 +4269,9 @@
+ xfsidbg_get_cstate(log->l_covered_state));
+ kdb_printf("flags: ");
+ printflags(log->l_flags, t_flags,"log");
+- kdb_printf(" dev: 0x%x logBBstart: %lld logsize: %d logBBsize: %d\n",
+- log->l_dev, (long long) log->l_logBBstart,
++ kdb_printf(" dev: %u:%u logBBstart: %lld logsize: %d logBBsize: %d\n",
++ MAJOR(log->l_dev), MINOR(log->l_dev),
++ (long long) log->l_logBBstart,
+ log->l_logsize,log->l_logBBsize);
+ kdb_printf("curr_cycle: %d prev_cycle: %d curr_block: %d prev_block: %d\n",
+ log->l_curr_cycle, log->l_prev_cycle, log->l_curr_block,
+@@ -4637,11 +4646,14 @@
+ XFS_MTOVFS(mp), mp->m_tid, &mp->m_ail_lock, &mp->m_ail);
+ kdb_printf("ail_gen 0x%x &sb 0x%p\n",
+ mp->m_ail_gen, &mp->m_sb);
+- kdb_printf("sb_lock 0x%p sb_bp 0x%p dev 0x%x logdev 0x%x rtdev 0x%x\n",
++ kdb_printf("sb_lock 0x%p sb_bp 0x%p dev %u:%u logdev %u:%u rtdev %u:%u\n",
+ &mp->m_sb_lock, mp->m_sb_bp,
+- mp->m_ddev_targp ? mp->m_ddev_targp->pbr_dev : 0,
+- mp->m_logdev_targp ? mp->m_logdev_targp->pbr_dev : 0,
+- mp->m_rtdev_targp ? mp->m_rtdev_targp->pbr_dev : 0);
++ mp->m_ddev_targp ? MAJOR(mp->m_ddev_targp->pbr_dev) : 0,
++ mp->m_ddev_targp ? MINOR(mp->m_ddev_targp->pbr_dev) : 0,
++ mp->m_logdev_targp ? MAJOR(mp->m_logdev_targp->pbr_dev) : 0,
++ mp->m_logdev_targp ? MINOR(mp->m_logdev_targp->pbr_dev) : 0,
++ mp->m_rtdev_targp ? MAJOR(mp->m_rtdev_targp->pbr_dev) : 0,
++ mp->m_rtdev_targp ? MINOR(mp->m_rtdev_targp->pbr_dev) : 0);
+ kdb_printf("bsize %d agfrotor %d agirotor %d ihash 0x%p ihsize %d\n",
+ mp->m_bsize, mp->m_agfrotor, mp->m_agirotor,
+ mp->m_ihash, mp->m_ihsize);
+@@ -4687,7 +4699,7 @@
+ mp->m_attroffset, mp->m_maxicount, mp->m_inoalign_mask);
+ kdb_printf("resblks %Ld resblks_avail %Ld\n", mp->m_resblks,
+ mp->m_resblks_avail);
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+ kdb_printf(" inoadd %llx\n", (unsigned long long) mp->m_inoadd);
+ #else
+ kdb_printf("\n");
+@@ -4812,8 +4824,9 @@
+ ip->i_mnext,
+ ip->i_mprev,
+ XFS_ITOV_NULL(ip));
+- kdb_printf("dev %x ino %s\n",
+- ip->i_mount->m_dev,
++ kdb_printf("dev %u:%u ino %s\n",
++ MAJOR(ip->i_mount->m_dev),
++ MINOR(ip->i_mount->m_dev),
+ xfs_fmtino(ip->i_ino, ip->i_mount));
+ kdb_printf("blkno 0x%llx len 0x%x boffset 0x%x\n",
+ (long long) ip->i_blkno,
+Index: linux-2.6.0-test5/fs/xfs/xfs_iget.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_iget.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_iget.c 2003-09-27 11:38:39.811476120 +0800
+@@ -204,7 +204,7 @@
+ if (ip->i_flags & XFS_IRECLAIM) {
+ read_unlock(&ih->ih_lock);
+ delay(1);
+- XFS_STATS_INC(xfsstats.xs_ig_frecycle);
++ XFS_STATS_INC(xs_ig_frecycle);
+
+ goto again;
+ }
+@@ -212,7 +212,7 @@
+ vn_trace_exit(vp, "xfs_iget.alloc",
+ (inst_t *)__return_address);
+
+- XFS_STATS_INC(xfsstats.xs_ig_found);
++ XFS_STATS_INC(xs_ig_found);
+
+ ip->i_flags &= ~XFS_IRECLAIMABLE;
+ read_unlock(&ih->ih_lock);
+@@ -232,7 +232,7 @@
+ if (inode->i_state & (I_FREEING | I_CLEAR)) {
+ read_unlock(&ih->ih_lock);
+ delay(1);
+- XFS_STATS_INC(xfsstats.xs_ig_frecycle);
++ XFS_STATS_INC(xs_ig_frecycle);
+
+ goto again;
+ }
+@@ -247,7 +247,7 @@
+
+ read_unlock(&ih->ih_lock);
+
+- XFS_STATS_INC(xfsstats.xs_ig_found);
++ XFS_STATS_INC(xs_ig_found);
+
+ finish_inode:
+ if (lock_flags != 0) {
+@@ -269,7 +269,7 @@
+ * Inode cache miss: save the hash chain version stamp and unlock
+ * the chain, so we don't deadlock in vn_alloc.
+ */
+- XFS_STATS_INC(xfsstats.xs_ig_missed);
++ XFS_STATS_INC(xs_ig_missed);
+
+ version = ih->ih_version;
+
+@@ -305,7 +305,7 @@
+ write_unlock(&ih->ih_lock);
+ xfs_idestroy(ip);
+
+- XFS_STATS_INC(xfsstats.xs_ig_dup);
++ XFS_STATS_INC(xs_ig_dup);
+ goto again;
+ }
+ }
+@@ -442,7 +442,7 @@
+ int error;
+
+ retry:
+- XFS_STATS_INC(xfsstats.xs_ig_attempts);
++ XFS_STATS_INC(xs_ig_attempts);
+
+ if ((inode = iget_locked(XFS_MTOVFS(mp)->vfs_super, ino))) {
+ bhv_desc_t *bdp;
+@@ -475,7 +475,7 @@
+
+ bdp = vn_bhv_lookup(VN_BHV_HEAD(vp), &xfs_vnodeops);
+ if (bdp == NULL) {
+- XFS_STATS_INC(xfsstats.xs_ig_dup);
++ XFS_STATS_INC(xs_ig_dup);
+ goto inode_allocate;
+ }
+ ip = XFS_BHVTOI(bdp);
+@@ -484,7 +484,7 @@
+ newnode = (ip->i_d.di_mode == 0);
+ if (newnode)
+ xfs_iocore_inode_reinit(ip);
+- XFS_STATS_INC(xfsstats.xs_ig_found);
++ XFS_STATS_INC(xs_ig_found);
+ *ipp = ip;
+ error = 0;
+ }
+@@ -604,7 +604,7 @@
+ /*
+ * Remove from old hash list and mount list.
+ */
+- XFS_STATS_INC(xfsstats.xs_ig_reclaims);
++ XFS_STATS_INC(xs_ig_reclaims);
+
+ xfs_iextract(ip);
+
+Index: linux-2.6.0-test5/fs/xfs/xfs_inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_inode.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_inode.c 2003-09-27 11:38:39.838472016 +0800
+@@ -1210,6 +1210,18 @@
+ break;
+ case IFREG:
+ case IFDIR:
++ if (pip->i_d.di_flags &
++ (XFS_DIFLAG_NOATIME|XFS_DIFLAG_NODUMP|XFS_DIFLAG_SYNC)) {
++ if ((pip->i_d.di_flags & XFS_DIFLAG_NOATIME) &&
++ xfs_inherit_noatime)
++ ip->i_d.di_flags |= XFS_DIFLAG_NOATIME;
++ if ((pip->i_d.di_flags & XFS_DIFLAG_NODUMP) &&
++ xfs_inherit_nodump)
++ ip->i_d.di_flags |= XFS_DIFLAG_NODUMP;
++ if ((pip->i_d.di_flags & XFS_DIFLAG_SYNC) &&
++ xfs_inherit_sync)
++ ip->i_d.di_flags |= XFS_DIFLAG_SYNC;
++ }
+ case IFLNK:
+ ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS;
+ ip->i_df.if_flags = XFS_IFEXTENTS;
+@@ -2884,7 +2896,7 @@
+ enum { INT_DELWRI = (1 << 0), INT_ASYNC = (1 << 1) };
+ SPLDECL(s);
+
+- XFS_STATS_INC(xfsstats.xs_iflush_count);
++ XFS_STATS_INC(xs_iflush_count);
+
+ ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE|MR_ACCESS));
+ ASSERT(valusema(&ip->i_flock) <= 0);
+@@ -3057,8 +3069,8 @@
+ mutex_spinunlock(&ch->ch_lock, s);
+
+ if (clcount) {
+- XFS_STATS_INC(xfsstats.xs_icluster_flushcnt);
+- XFS_STATS_ADD(xfsstats.xs_icluster_flushinode, clcount);
++ XFS_STATS_INC(xs_icluster_flushcnt);
++ XFS_STATS_ADD(xs_icluster_flushinode, clcount);
+ }
+
+ /*
+@@ -3500,6 +3512,9 @@
+ if (IS_RDONLY(inode) &&
+ (S_ISREG(imode) || S_ISDIR(imode) || S_ISLNK(imode)))
+ return XFS_ERROR(EROFS);
++
++ if (IS_IMMUTABLE(inode))
++ return XFS_ERROR(EACCES);
+ }
+
+ /*
+@@ -3623,7 +3638,7 @@
+ * Don't update access timestamps on reads if mounted "noatime"
+ * Throw it away if anyone asks us.
+ */
+- if (ip->i_mount->m_flags & XFS_MOUNT_NOATIME &&
++ if ((ip->i_mount->m_flags & XFS_MOUNT_NOATIME || IS_NOATIME(inode)) &&
+ ((flags & (XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD|XFS_ICHGTIME_CHG))
+ == XFS_ICHGTIME_ACC))
+ return;
+@@ -3657,7 +3672,7 @@
+ SYNCHRONIZE();
+ ip->i_update_core = 1;
+ if (!(inode->i_state & I_LOCK))
+- mark_inode_dirty(inode);
++ mark_inode_dirty_sync(inode);
+ }
+
+ #ifdef XFS_ILOCK_TRACE
+Index: linux-2.6.0-test5/fs/xfs/xfs_inum.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_inum.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_inum.h 2003-09-27 11:38:39.841471560 +0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
++ * Copyright (c) 2000-2003 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
+@@ -47,7 +47,7 @@
+ * Used in some places where having 64-bits in the 32-bit kernels
+ * costs too much.
+ */
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+ typedef xfs_ino_t xfs_intino_t;
+ #else
+ typedef __uint32_t xfs_intino_t;
+@@ -162,7 +162,7 @@
+ ((xfs_agino_t)(((b) << XFS_INO_OFFSET_BITS(mp)) | (o)))
+ #endif
+
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+ #define XFS_MAXINUMBER ((xfs_ino_t)((1ULL << 56) - 1ULL))
+ #define XFS_INO64_OFFSET ((xfs_ino_t)(1ULL << 32))
+ #else
+Index: linux-2.6.0-test5/fs/xfs/xfs_iocore.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_iocore.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_iocore.c 2003-09-27 11:38:39.843471256 +0800
+@@ -61,7 +61,6 @@
+ #include "xfs_rw.h"
+ #include "xfs_quota.h"
+ #include "xfs_trans_space.h"
+-#include "xfs_dmapi.h"
+
+
+ STATIC xfs_fsize_t
+Index: linux-2.6.0-test5/fs/xfs/xfs_itable.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_itable.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_itable.c 2003-09-27 11:38:39.849470344 +0800
+@@ -156,13 +156,23 @@
+ /*
+ * convert di_flags to bs_xflags.
+ */
+- di_flags=INT_GET(dic->di_flags, arch);
++ di_flags = INT_GET(dic->di_flags, arch);
+
+ buf->bs_xflags =
+ ((di_flags & XFS_DIFLAG_REALTIME) ?
+ XFS_XFLAG_REALTIME : 0) |
+ ((di_flags & XFS_DIFLAG_PREALLOC) ?
+ XFS_XFLAG_PREALLOC : 0) |
++ ((di_flags & XFS_DIFLAG_IMMUTABLE) ?
++ XFS_XFLAG_IMMUTABLE : 0) |
++ ((di_flags & XFS_DIFLAG_APPEND) ?
++ XFS_XFLAG_APPEND : 0) |
++ ((di_flags & XFS_DIFLAG_SYNC) ?
++ XFS_XFLAG_SYNC : 0) |
++ ((di_flags & XFS_DIFLAG_NOATIME) ?
++ XFS_XFLAG_NOATIME : 0) |
++ ((di_flags & XFS_DIFLAG_NODUMP) ?
++ XFS_XFLAG_NODUMP : 0) |
+ (XFS_CFORK_Q_ARCH(dic, arch) ?
+ XFS_XFLAG_HASATTR : 0);
+
+Index: linux-2.6.0-test5/fs/xfs/xfs_log.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_log.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_log.c 2003-09-27 11:38:39.876466240 +0800
+@@ -345,7 +345,7 @@
+
+ ASSERT(flags & XFS_LOG_FORCE);
+
+- XFS_STATS_INC(xfsstats.xs_log_force);
++ XFS_STATS_INC(xs_log_force);
+
+ if ((log->l_flags & XLOG_IO_ERROR) == 0) {
+ if (lsn == 0)
+@@ -446,7 +446,7 @@
+ if (XLOG_FORCED_SHUTDOWN(log))
+ return XFS_ERROR(EIO);
+
+- XFS_STATS_INC(xfsstats.xs_try_logspace);
++ XFS_STATS_INC(xs_try_logspace);
+
+ if (*ticket != NULL) {
+ ASSERT(flags & XFS_LOG_PERM_RESERV);
+@@ -497,7 +497,8 @@
+
+ #if defined(DEBUG) || defined(XLOG_NOLOG)
+ if (! xlog_debug) {
+- cmn_err(CE_NOTE, "log dev: 0x%x", log_dev);
++ cmn_err(CE_NOTE, "log dev: %u:%u",
++ MAJOR(log_dev), MINOR(log_dev));
+ return 0;
+ }
+ #endif
+@@ -1428,7 +1429,7 @@
+ int split = 0; /* split write into two regions */
+ int error;
+
+- XFS_STATS_INC(xfsstats.xs_log_writes);
++ XFS_STATS_INC(xs_log_writes);
+ ASSERT(iclog->ic_refcnt == 0);
+
+ /* Round out the log write size */
+@@ -1477,7 +1478,7 @@
+
+ /* Add for LR header */
+ count += log->l_iclog_hsize;
+- XFS_STATS_ADD(xfsstats.xs_log_blocks, BTOBB(count));
++ XFS_STATS_ADD(xs_log_blocks, BTOBB(count));
+
+ /* Do we need to split this write into 2 parts? */
+ if (XFS_BUF_ADDR(bp) + BTOBB(count) > log->l_logBBsize) {
+@@ -2308,7 +2309,7 @@
+ log->l_flushcnt++;
+ LOG_UNLOCK(log, s);
+ xlog_trace_iclog(iclog, XLOG_TRACE_SLEEP_FLUSH);
+- XFS_STATS_INC(xfsstats.xs_log_noiclogs);
++ XFS_STATS_INC(xs_log_noiclogs);
+ /* Ensure that log writes happen */
+ psema(&log->l_flushsema, PINOD);
+ goto restart;
+@@ -2421,7 +2422,7 @@
+ if (XLOG_FORCED_SHUTDOWN(log))
+ goto error_return;
+
+- XFS_STATS_INC(xfsstats.xs_sleep_logspace);
++ XFS_STATS_INC(xs_sleep_logspace);
+ sv_wait(&tic->t_sema, PINOD|PLTWAIT, &log->l_grant_lock, s);
+ /*
+ * If we got an error, and the filesystem is shutting down,
+@@ -2447,7 +2448,7 @@
+ XLOG_INS_TICKETQ(log->l_reserve_headq, tic);
+ xlog_trace_loggrant(log, tic,
+ "xlog_grant_log_space: sleep 2");
+- XFS_STATS_INC(xfsstats.xs_sleep_logspace);
++ XFS_STATS_INC(xs_sleep_logspace);
+ sv_wait(&tic->t_sema, PINOD|PLTWAIT, &log->l_grant_lock, s);
+
+ if (XLOG_FORCED_SHUTDOWN(log)) {
+@@ -2558,7 +2559,7 @@
+
+ xlog_trace_loggrant(log, tic,
+ "xlog_regrant_write_log_space: sleep 1");
+- XFS_STATS_INC(xfsstats.xs_sleep_logspace);
++ XFS_STATS_INC(xs_sleep_logspace);
+ sv_wait(&tic->t_sema, PINOD|PLTWAIT,
+ &log->l_grant_lock, s);
+
+@@ -2587,7 +2588,7 @@
+ if (free_bytes < need_bytes) {
+ if ((tic->t_flags & XLOG_TIC_IN_Q) == 0)
+ XLOG_INS_TICKETQ(log->l_write_headq, tic);
+- XFS_STATS_INC(xfsstats.xs_sleep_logspace);
++ XFS_STATS_INC(xs_sleep_logspace);
+ sv_wait(&tic->t_sema, PINOD|PLTWAIT, &log->l_grant_lock, s);
+
+ /* If we're shutting down, this tic is already off the queue */
+@@ -2952,7 +2953,7 @@
+ LOG_UNLOCK(log, s);
+ return XFS_ERROR(EIO);
+ }
+- XFS_STATS_INC(xfsstats.xs_log_force_sleep);
++ XFS_STATS_INC(xs_log_force_sleep);
+ sv_wait(&iclog->ic_forcesema, PINOD, &log->l_icloglock, s);
+ /*
+ * No need to grab the log lock here since we're
+@@ -3035,7 +3036,7 @@
+ (iclog->ic_prev->ic_state & (XLOG_STATE_WANT_SYNC |
+ XLOG_STATE_SYNCING))) {
+ ASSERT(!(iclog->ic_state & XLOG_STATE_IOERROR));
+- XFS_STATS_INC(xfsstats.xs_log_force_sleep);
++ XFS_STATS_INC(xs_log_force_sleep);
+ sv_wait(&iclog->ic_prev->ic_writesema, PSWP,
+ &log->l_icloglock, s);
+ already_slept = 1;
+@@ -3061,7 +3062,7 @@
+ LOG_UNLOCK(log, s);
+ return XFS_ERROR(EIO);
+ }
+- XFS_STATS_INC(xfsstats.xs_log_force_sleep);
++ XFS_STATS_INC(xs_log_force_sleep);
+ sv_wait(&iclog->ic_forcesema, PSWP, &log->l_icloglock, s);
+ /*
+ * No need to grab the log lock here since we're
+@@ -3128,7 +3129,7 @@
+ * The kmem_zalloc may sleep, so we shouldn't be holding the
+ * global lock. XXXmiken: may want to use zone allocator.
+ */
+- buf = (xfs_caddr_t) kmem_zalloc(NBPP, 0);
++ buf = (xfs_caddr_t) kmem_zalloc(NBPP, KM_SLEEP);
+
+ s = LOG_LOCK(log);
+
+@@ -3427,8 +3428,8 @@
+ if (syncing == B_FALSE || (field_offset & 0x1ff)) {
+ clientid = ophead->oh_clientid;
+ } else {
+- idx = BTOBB((xfs_caddr_t)&(ophead->oh_clientid) - iclog->ic_datap);
+- if (idx > (XLOG_HEADER_CYCLE_SIZE / BBSIZE)) {
++ idx = BTOBBT((xfs_caddr_t)&(ophead->oh_clientid) - iclog->ic_datap);
++ if (idx >= (XLOG_HEADER_CYCLE_SIZE / BBSIZE)) {
+ j = idx / (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
+ k = idx % (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
+ clientid = GET_CLIENT_ID(xhdr[j].hic_xheader.xh_cycle_data[k], ARCH_CONVERT);
+@@ -3445,9 +3446,9 @@
+ if (syncing == B_FALSE || (field_offset & 0x1ff)) {
+ op_len = INT_GET(ophead->oh_len, ARCH_CONVERT);
+ } else {
+- idx = BTOBB((__psint_t)&ophead->oh_len -
++ idx = BTOBBT((__psint_t)&ophead->oh_len -
+ (__psint_t)iclog->ic_datap);
+- if (idx > (XLOG_HEADER_CYCLE_SIZE / BBSIZE)) {
++ if (idx >= (XLOG_HEADER_CYCLE_SIZE / BBSIZE)) {
+ j = idx / (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
+ k = idx % (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
+ op_len = INT_GET(xhdr[j].hic_xheader.xh_cycle_data[k], ARCH_CONVERT);
+Index: linux-2.6.0-test5/fs/xfs/xfs_log_recover.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_log_recover.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_log_recover.c 2003-09-27 11:38:39.905461832 +0800
+@@ -54,7 +54,6 @@
+ #include "xfs_inode.h"
+ #include "xfs_ialloc_btree.h"
+ #include "xfs_ialloc.h"
+-#include "xfs_error.h"
+ #include "xfs_log_priv.h"
+ #include "xfs_buf_item.h"
+ #include "xfs_alloc_btree.h"
+@@ -1360,7 +1359,7 @@
+ {
+ xlog_recover_item_t *item;
+
+- item = kmem_zalloc(sizeof(xlog_recover_item_t), 0);
++ item = kmem_zalloc(sizeof(xlog_recover_item_t), KM_SLEEP);
+ xlog_recover_insert_item_backq(itemq, item);
+ }
+
+@@ -1444,7 +1443,7 @@
+ item->ri_total = in_f->ilf_size;
+ ASSERT(item->ri_total <= XLOG_MAX_REGIONS_IN_ITEM);
+ item->ri_buf = kmem_zalloc((item->ri_total *
+- sizeof(xfs_log_iovec_t)), 0);
++ sizeof(xfs_log_iovec_t)), KM_SLEEP);
+ }
+ ASSERT(item->ri_total > item->ri_cnt);
+ /* Description region is ri_buf[0] */
+@@ -2180,8 +2179,8 @@
+ break;
+ default:
+ xfs_fs_cmn_err(CE_ALERT, log->l_mp,
+- "xfs_log_recover: unknown buffer type 0x%x, dev 0x%x",
+- buf_f->blf_type, log->l_dev);
++ "xfs_log_recover: unknown buffer type 0x%x, dev %u:%u",
++ buf_f->blf_type, MAJOR(log->l_dev), MINOR(log->l_dev));
+ XFS_ERROR_REPORT("xlog_recover_do_buffer_trans",
+ XFS_ERRLEVEL_LOW, log->l_mp);
+ return XFS_ERROR(EFSCORRUPTED);
+Index: linux-2.6.0-test5/fs/xfs/xfs_mount.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_mount.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_mount.c 2003-09-27 11:38:39.941456360 +0800
+@@ -222,15 +222,21 @@
+ return XFS_ERROR(EWRONGFS);
+ }
+
+- if (unlikely(sbp->sb_logstart == 0 && mp->m_logdev_targp == mp->m_ddev_targp)) {
+- cmn_err(CE_WARN, "XFS: filesystem is marked as having an external log; specify logdev on the\nmount command line.");
++ if (unlikely(
++ sbp->sb_logstart == 0 && mp->m_logdev_targp == mp->m_ddev_targp)) {
++ cmn_err(CE_WARN,
++ "XFS: filesystem is marked as having an external log; "
++ "specify logdev on the\nmount command line.");
+ XFS_CORRUPTION_ERROR("xfs_mount_validate_sb(1)",
+ XFS_ERRLEVEL_HIGH, mp, sbp);
+ return XFS_ERROR(EFSCORRUPTED);
+ }
+
+- if (unlikely(sbp->sb_logstart != 0 && mp->m_logdev_targp != mp->m_ddev_targp)) {
+- cmn_err(CE_WARN, "XFS: filesystem is marked as having an internal log; don't specify logdev on\nthe mount command line.");
++ if (unlikely(
++ sbp->sb_logstart != 0 && mp->m_logdev_targp != mp->m_ddev_targp)) {
++ cmn_err(CE_WARN,
++ "XFS: filesystem is marked as having an internal log; "
++ "don't specify logdev on\nthe mount command line.");
+ XFS_CORRUPTION_ERROR("xfs_mount_validate_sb(2)",
+ XFS_ERRLEVEL_HIGH, mp, sbp);
+ return XFS_ERROR(EFSCORRUPTED);
+@@ -276,10 +282,14 @@
+ return XFS_ERROR(EFSCORRUPTED);
+ }
+
+-#if !XFS_BIG_FILESYSTEMS
+- if (sbp->sb_dblocks > INT_MAX || sbp->sb_rblocks > INT_MAX) {
++#if !XFS_BIG_BLKNOS
++ if (unlikely(
++ (sbp->sb_dblocks << (__uint64_t)(sbp->sb_blocklog - BBSHIFT))
++ > INT_MAX ||
++ (sbp->sb_rblocks << (__uint64_t)(sbp->sb_blocklog - BBSHIFT))
++ > INT_MAX)) {
+ cmn_err(CE_WARN,
+-"XFS: File systems greater than 1TB not supported on this system.");
++ "XFS: File system is too large to be mounted on this system.");
+ return XFS_ERROR(E2BIG);
+ }
+ #endif
+@@ -294,7 +304,7 @@
+ /*
+ * Until this is fixed only page-sized or smaller data blocks work.
+ */
+- if (sbp->sb_blocksize > PAGE_SIZE) {
++ if (unlikely(sbp->sb_blocksize > PAGE_SIZE)) {
+ cmn_err(CE_WARN,
+ "XFS: Attempted to mount file system with blocksize %d bytes",
+ sbp->sb_blocksize);
+@@ -322,9 +332,11 @@
+ ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino);
+
+ /* Clear the mount flag if no inode can overflow 32 bits
+- * on this filesystem.
++ * on this filesystem, or if specifically requested..
+ */
+- if (ino <= max_inum) {
++ if ((mp->m_flags & XFS_MOUNT_32BITINOOPT) && ino > max_inum) {
++ mp->m_flags |= XFS_MOUNT_32BITINODES;
++ } else {
+ mp->m_flags &= ~XFS_MOUNT_32BITINODES;
+ }
+
+Index: linux-2.6.0-test5/fs/xfs/xfs_mount.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_mount.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_mount.h 2003-09-27 11:38:39.951454840 +0800
+@@ -95,8 +95,8 @@
+ xfs_off_t, size_t, int, vrwlock_t *);
+ typedef int (*xfs_send_mmap_t)(struct vm_area_struct *, uint);
+ typedef int (*xfs_send_destroy_t)(struct bhv_desc *, dm_right_t);
+-typedef int (*xfs_send_namesp_t)(dm_eventtype_t, struct bhv_desc *,
+- dm_right_t, struct bhv_desc *, dm_right_t,
++typedef int (*xfs_send_namesp_t)(dm_eventtype_t, struct vnode *,
++ dm_right_t, struct vnode *, dm_right_t,
+ char *, char *, mode_t, int, int);
+ typedef void (*xfs_send_unmount_t)(struct vfs *, struct vnode *,
+ dm_right_t, mode_t, int, int);
+@@ -354,7 +354,7 @@
+ __uint64_t m_maxioffset; /* maximum inode offset */
+ __uint64_t m_resblks; /* total reserved blocks */
+ __uint64_t m_resblks_avail;/* available reserved blocks */
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+ xfs_ino_t m_inoadd; /* add value for ino64_offset */
+ #endif
+ int m_dalign; /* stripe unit */
+@@ -392,9 +392,7 @@
+ #define XFS_MOUNT_WSYNC 0x00000001 /* for nfs - all metadata ops
+ must be synchronous except
+ for space allocations */
+-#if XFS_BIG_FILESYSTEMS
+ #define XFS_MOUNT_INO64 0x00000002
+-#endif
+ /* 0x00000004 -- currently unused */
+ /* 0x00000008 -- currently unused */
+ #define XFS_MOUNT_FS_SHUTDOWN 0x00000010 /* atomic stop of all filesystem
+@@ -413,10 +411,11 @@
+ #define XFS_MOUNT_DFLT_IOSIZE 0x00001000 /* set default i/o size */
+ #define XFS_MOUNT_OSYNCISOSYNC 0x00002000 /* o_sync is REALLY o_sync */
+ /* osyncisdsync is now default*/
+-#define XFS_MOUNT_NOUUID 0x00004000 /* ignore uuid during mount */
+-#define XFS_MOUNT_32BITINODES 0x00008000 /* do not create inodes above
++#define XFS_MOUNT_32BITINODES 0x00004000 /* do not create inodes above
+ * 32 bits in size */
+-#define XFS_MOUNT_NOLOGFLUSH 0x00010000
++#define XFS_MOUNT_32BITINOOPT 0x00008000 /* saved mount option state */
++#define XFS_MOUNT_NOUUID 0x00010000 /* ignore uuid during mount */
++#define XFS_MOUNT_NOLOGFLUSH 0x00020000
+
+ /*
+ * Default minimum read and write sizes.
+Index: linux-2.6.0-test5/fs/xfs/xfs_rename.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_rename.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_rename.c 2003-09-27 11:38:39.966452560 +0800
+@@ -56,7 +56,6 @@
+ #include "xfs_trans_space.h"
+ #include "xfs_da_btree.h"
+ #include "xfs_dir_leaf.h"
+-#include "xfs_dmapi.h"
+
+
+ /*
+@@ -293,8 +292,8 @@
+ DM_EVENT_ENABLED(target_dir_vp->v_vfsp,
+ target_dp, DM_EVENT_RENAME)) {
+ error = XFS_SEND_NAMESP(mp, DM_EVENT_RENAME,
+- src_dir_bdp, DM_RIGHT_NULL,
+- target_dir_bdp, DM_RIGHT_NULL,
++ src_dir_vp, DM_RIGHT_NULL,
++ target_dir_vp, DM_RIGHT_NULL,
+ src_name, target_name,
+ 0, 0, 0);
+ if (error) {
+@@ -650,8 +649,8 @@
+ DM_EVENT_ENABLED(target_dir_vp->v_vfsp,
+ target_dp, DM_EVENT_POSTRENAME)) {
+ (void) XFS_SEND_NAMESP (mp, DM_EVENT_POSTRENAME,
+- src_dir_bdp, DM_RIGHT_NULL,
+- target_dir_bdp, DM_RIGHT_NULL,
++ src_dir_vp, DM_RIGHT_NULL,
++ target_dir_vp, DM_RIGHT_NULL,
+ src_name, target_name,
+ 0, error, 0);
+ }
+Index: linux-2.6.0-test5/fs/xfs/xfs_rtalloc.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_rtalloc.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_rtalloc.h 2003-09-27 11:38:39.968452256 +0800
+@@ -77,7 +77,7 @@
+ #define XFS_RTLOBIT(w) xfs_lowbit32(w)
+ #define XFS_RTHIBIT(w) xfs_highbit32(w)
+
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_BLKNOS
+ #define XFS_RTBLOCKLOG(b) xfs_highbit64(b)
+ #else
+ #define XFS_RTBLOCKLOG(b) xfs_highbit32(b)
+Index: linux-2.6.0-test5/fs/xfs/xfs_rw.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_rw.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_rw.c 2003-09-27 11:38:39.971451800 +0800
+@@ -59,7 +59,6 @@
+ #include "xfs_bmap.h"
+ #include "xfs_acl.h"
+ #include "xfs_mac.h"
+-#include "xfs_attr.h"
+ #include "xfs_error.h"
+ #include "xfs_buf_item.h"
+ #include "xfs_rw.h"
+@@ -261,10 +260,11 @@
+ xfs_daddr_t blkno)
+ {
+ cmn_err(CE_ALERT,
+- "I/O error in filesystem (\"%s\") meta-data dev 0x%x block 0x%llx"
++ "I/O error in filesystem (\"%s\") meta-data dev %u:%u block 0x%llx"
+ " (\"%s\") error %d buf count %u",
+ (!mp || !mp->m_fsname) ? "(fs name not set)" : mp->m_fsname,
+- XFS_BUF_TARGET_DEV(bp),
++ MAJOR(XFS_BUF_TARGET_DEV(bp)),
++ MINOR(XFS_BUF_TARGET_DEV(bp)),
+ (__uint64_t)blkno,
+ func,
+ XFS_BUF_GETERROR(bp),
+Index: linux-2.6.0-test5/fs/xfs/xfs_trans_ail.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_trans_ail.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_trans_ail.c 2003-09-27 11:38:39.976451040 +0800
+@@ -40,7 +40,6 @@
+ #include "xfs_dir.h"
+ #include "xfs_dmapi.h"
+ #include "xfs_mount.h"
+-#include "xfs_log.h"
+ #include "xfs_trans_priv.h"
+ #include "xfs_error.h"
+
+@@ -119,7 +118,7 @@
+ return (xfs_lsn_t)0;
+ }
+
+- XFS_STATS_INC(xfsstats.xs_push_ail);
++ XFS_STATS_INC(xs_push_ail);
+
+ /*
+ * While the item we are looking at is below the given threshold
+@@ -153,14 +152,14 @@
+ switch (lock_result) {
+ case XFS_ITEM_SUCCESS:
+ AIL_UNLOCK(mp, s);
+- XFS_STATS_INC(xfsstats.xs_push_ail_success);
++ XFS_STATS_INC(xs_push_ail_success);
+ IOP_PUSH(lip);
+ AIL_LOCK(mp,s);
+ break;
+
+ case XFS_ITEM_PUSHBUF:
+ AIL_UNLOCK(mp, s);
+- XFS_STATS_INC(xfsstats.xs_push_ail_pushbuf);
++ XFS_STATS_INC(xs_push_ail_pushbuf);
+ #ifdef XFSRACEDEBUG
+ delay_for_intr();
+ delay(300);
+@@ -172,16 +171,16 @@
+ break;
+
+ case XFS_ITEM_PINNED:
+- XFS_STATS_INC(xfsstats.xs_push_ail_pinned);
++ XFS_STATS_INC(xs_push_ail_pinned);
+ flush_log = 1;
+ break;
+
+ case XFS_ITEM_LOCKED:
+- XFS_STATS_INC(xfsstats.xs_push_ail_locked);
++ XFS_STATS_INC(xs_push_ail_locked);
+ break;
+
+ case XFS_ITEM_FLUSHING:
+- XFS_STATS_INC(xfsstats.xs_push_ail_flushing);
++ XFS_STATS_INC(xs_push_ail_flushing);
+ break;
+
+ default:
+@@ -210,7 +209,7 @@
+ * move forward in the AIL.
+ */
+ AIL_UNLOCK(mp, s);
+- XFS_STATS_INC(xfsstats.xs_push_ail_flush);
++ XFS_STATS_INC(xs_push_ail_flush);
+ xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE);
+ AIL_LOCK(mp, s);
+ }
+@@ -429,7 +428,7 @@
+ nlip = xfs_ail_min(&(mp->m_ail));
+ *gen = (int)mp->m_ail_gen;
+ if (restarts != NULL) {
+- XFS_STATS_INC(xfsstats.xs_push_ail_restarts);
++ XFS_STATS_INC(xs_push_ail_restarts);
+ (*restarts)++;
+ }
+ }
+Index: linux-2.6.0-test5/fs/xfs/xfs_trans.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_trans.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_trans.c 2003-09-27 11:38:39.985449672 +0800
+@@ -739,7 +739,7 @@
+ xfs_trans_free_items(tp, shutdown? XFS_TRANS_ABORT : 0);
+ xfs_trans_free_busy(tp);
+ xfs_trans_free(tp);
+- XFS_STATS_INC(xfsstats.xs_trans_empty);
++ XFS_STATS_INC(xs_trans_empty);
+ if (commit_lsn_p)
+ *commit_lsn_p = commit_lsn;
+ return (shutdown);
+@@ -895,9 +895,9 @@
+ if (!error)
+ error = xfs_log_force(mp, commit_lsn,
+ XFS_LOG_FORCE | XFS_LOG_SYNC);
+- XFS_STATS_INC(xfsstats.xs_trans_sync);
++ XFS_STATS_INC(xs_trans_sync);
+ } else {
+- XFS_STATS_INC(xfsstats.xs_trans_async);
++ XFS_STATS_INC(xs_trans_async);
+ }
+
+ return (error);
+Index: linux-2.6.0-test5/fs/xfs/xfs_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_types.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_types.h 2003-09-27 11:38:39.988449216 +0800
+@@ -78,20 +78,21 @@
+ #endif /* __KERNEL__ */
+
+ /*
+- * Some types are conditional based on the selected configuration.
+- * Set XFS_BIG_FILESYSTEMS=1 or 0 depending on the desired configuration.
+- * XFS_BIG_FILESYSTEMS needs daddr_t to be 64 bits
+- *
+- * On linux right now we are limited to 2^32 512 byte blocks in a
+- * filesystem, Once this limit is changed, setting this to 1
+- * will allow XFS to go larger. With BIG_FILESYSTEMS set to 0
+- * a 4K block filesystem could still theoretically be 16Gbytes
+- * long, so on an ia32 box the 32 bit page index will then be
+- * the limiting factor.
+- */
+-
+-#ifndef XFS_BIG_FILESYSTEMS
+-#define XFS_BIG_FILESYSTEMS 0
++ * Some types are conditional depending on the target system.
++ * XFS_BIG_BLKNOS needs block layer disk addresses to be 64 bits.
++ * XFS_BIG_INUMS needs the VFS inode number to be 64 bits, as well
++ * as requiring XFS_BIG_BLKNOS to be set.
++ */
++#if defined(CONFIG_LBD) || (defined(HAVE_SECTOR_T) && (BITS_PER_LONG == 64))
++# define XFS_BIG_BLKNOS 1
++# if BITS_PER_LONG == 64
++# define XFS_BIG_INUMS 1
++# else
++# define XFS_BIG_INUMS 0
++# endif
++#else
++# define XFS_BIG_BLKNOS 0
++# define XFS_BIG_INUMS 0
+ #endif
+
+ typedef __uint32_t xfs_agblock_t; /* blockno in alloc. group */
+@@ -126,7 +127,7 @@
+ /*
+ * Memory based types are conditional.
+ */
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_BLKNOS
+ typedef __uint64_t xfs_fsblock_t; /* blockno in filesystem (agno|agbno) */
+ typedef __uint64_t xfs_rfsblock_t; /* blockno in filesystem (raw) */
+ typedef __uint64_t xfs_rtblock_t; /* extent (block) in realtime area */
+@@ -196,20 +197,4 @@
+ XFS_BTNUM_MAX
+ } xfs_btnum_t;
+
+-
+-/*
+- * Juggle IRIX device numbers - still used in ondisk structures
+- */
+-#define XFS_DEV_BITSMAJOR 14
+-#define XFS_DEV_BITSMINOR 18
+-#define XFS_DEV_MAXMAJ 0x1ff
+-#define XFS_DEV_MAXMIN 0x3ffff
+-#define XFS_DEV_MAJOR(dev) ((int)(((unsigned)(dev)>>XFS_DEV_BITSMINOR) \
+- & XFS_DEV_MAXMAJ))
+-#define XFS_DEV_MINOR(dev) ((int)((dev)&XFS_DEV_MAXMIN))
+-#define XFS_MKDEV(major,minor) ((xfs_dev_t)(((major)<<XFS_DEV_BITSMINOR) \
+- | (minor&XFS_DEV_MAXMIN)))
+-
+-#define XFS_DEV_TO_KDEVT(dev) MKDEV(XFS_DEV_MAJOR(dev),XFS_DEV_MINOR(dev))
+-
+ #endif /* !__XFS_TYPES_H */
+Index: linux-2.6.0-test5/fs/xfs/xfs_vfsops.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_vfsops.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_vfsops.c 2003-09-27 11:38:40.000447392 +0800
+@@ -49,7 +49,6 @@
+ #include "xfs_btree.h"
+ #include "xfs_alloc.h"
+ #include "xfs_ialloc.h"
+-#include "xfs_alloc.h"
+ #include "xfs_attr_sf.h"
+ #include "xfs_dir_sf.h"
+ #include "xfs_dir2_sf.h"
+@@ -64,7 +63,6 @@
+ #include "xfs_buf_item.h"
+ #include "xfs_extfree_item.h"
+ #include "xfs_quota.h"
+-#include "xfs_dmapi.h"
+ #include "xfs_dir2_trace.h"
+ #include "xfs_acl.h"
+ #include "xfs_attr.h"
+@@ -266,7 +264,7 @@
+ */
+ if (ap->flags & XFSMNT_WSYNC)
+ mp->m_flags |= XFS_MOUNT_WSYNC;
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+ if (ap->flags & XFSMNT_INO64) {
+ mp->m_flags |= XFS_MOUNT_INO64;
+ mp->m_inoadd = XFS_INO64_OFFSET;
+@@ -285,7 +283,7 @@
+ mp->m_flags |= XFS_MOUNT_OSYNCISOSYNC;
+
+ if (ap->flags & XFSMNT_32BITINODES)
+- mp->m_flags |= XFS_MOUNT_32BITINODES;
++ mp->m_flags |= (XFS_MOUNT_32BITINODES | XFS_MOUNT_32BITINOOPT);
+
+ if (ap->flags & XFSMNT_IOSIZE) {
+ if (ap->iosizelog > XFS_MAX_IO_LOG ||
+@@ -333,9 +331,10 @@
+ {
+ /* Fail a mount where the logbuf is smaller then the log stripe */
+ if (XFS_SB_VERSION_HASLOGV2(&mp->m_sb)) {
+- if (((ap->logbufsize == -1) &&
+- (mp->m_sb.sb_logsunit > XLOG_BIG_RECORD_BSIZE)) ||
+- (ap->logbufsize < mp->m_sb.sb_logsunit)) {
++ if ((ap->logbufsize == -1) &&
++ (mp->m_sb.sb_logsunit > XLOG_BIG_RECORD_BSIZE)) {
++ mp->m_logbsize = mp->m_sb.sb_logsunit;
++ } else if (ap->logbufsize < mp->m_sb.sb_logsunit) {
+ cmn_err(CE_WARN,
+ "XFS: logbuf size must be greater than or equal to log stripe size");
+ return XFS_ERROR(EINVAL);
+@@ -534,11 +533,8 @@
+ rvp = XFS_ITOV(rip);
+
+ if (vfsp->vfs_flag & VFS_DMI) {
+- bhv_desc_t *rbdp;
+-
+- rbdp = vn_bhv_lookup_unlocked(VN_BHV_HEAD(rvp), &xfs_vnodeops);
+ error = XFS_SEND_NAMESP(mp, DM_EVENT_PREUNMOUNT,
+- rbdp, DM_RIGHT_NULL, rbdp, DM_RIGHT_NULL,
++ rvp, DM_RIGHT_NULL, rvp, DM_RIGHT_NULL,
+ NULL, NULL, 0, 0,
+ (mp->m_dmevmask & (1<<DM_EVENT_PREUNMOUNT))?
+ 0:DM_FLAGS_UNWANTED);
+@@ -759,6 +755,7 @@
+ xfs_mount_t *mp;
+ xfs_sb_t *sbp;
+ unsigned long s;
++ u64 id;
+
+ mp = XFS_BHVTOM(bdp);
+ sbp = &(mp->m_sb);
+@@ -771,13 +768,13 @@
+ statp->f_blocks = sbp->sb_dblocks - lsize;
+ statp->f_bfree = statp->f_bavail = sbp->sb_fdblocks;
+ fakeinos = statp->f_bfree << sbp->sb_inopblog;
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+ fakeinos += mp->m_inoadd;
+ #endif
+ statp->f_files =
+ MIN(sbp->sb_icount + fakeinos, (__uint64_t)XFS_MAXINUMBER);
+ if (mp->m_maxicount)
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+ if (!mp->m_inoadd)
+ #endif
+ statp->f_files =
+@@ -785,8 +782,9 @@
+ statp->f_ffree = statp->f_files - (sbp->sb_icount - sbp->sb_ifree);
+ XFS_SB_UNLOCK(mp, s);
+
+- statp->f_fsid.val[0] = mp->m_dev;
+- statp->f_fsid.val[1] = 0;
++ id = huge_encode_dev(mp->m_dev);
++ statp->f_fsid.val[0] = (u32)id;
++ statp->f_fsid.val[1] = (u32)(id >> 32);
+ statp->f_namelen = MAXNAMELEN - 1;
+
+ return 0;
+@@ -1589,6 +1587,7 @@
+ #define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */
+ #define MNTOPT_NOLOGFLUSH "nologflush" /* don't hard flush on log writes */
+ #define MNTOPT_OSYNCISOSYNC "osyncisosync" /* o_sync is REALLY o_sync */
++#define MNTOPT_64BITINODE "inode64" /* inodes can be allocated anywhere */
+
+
+ int
+@@ -1675,7 +1674,7 @@
+ args->flags |= XFSMNT_NORECOVERY;
+ } else if (!strcmp(this_char, MNTOPT_INO64)) {
+ args->flags |= XFSMNT_INO64;
+-#ifndef XFS_BIG_FILESYSTEMS
++#if !XFS_BIG_INUMS
+ printk("XFS: %s option not allowed on this system\n",
+ MNTOPT_INO64);
+ return EINVAL;
+@@ -1696,6 +1695,13 @@
+ return EINVAL;
+ }
+ dswidth = simple_strtoul(value, &eov, 10);
++ } else if (!strcmp(this_char, MNTOPT_64BITINODE)) {
++ args->flags &= ~XFSMNT_32BITINODES;
++#if !XFS_BIG_INUMS
++ printk("XFS: %s option not allowed on this system\n",
++ MNTOPT_64BITINODE);
++ return EINVAL;
++#endif
+ } else if (!strcmp(this_char, MNTOPT_NOUUID)) {
+ args->flags |= XFSMNT_NOUUID;
+ } else if (!strcmp(this_char, MNTOPT_NOLOGFLUSH)) {
+Index: linux-2.6.0-test5/fs/xfs/xfs_vnodeops.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_vnodeops.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_vnodeops.c 2003-09-27 11:38:40.030442832 +0800
+@@ -66,7 +66,6 @@
+ #include "xfs_utils.h"
+ #include "xfs_trans_space.h"
+ #include "xfs_dir_leaf.h"
+-#include "xfs_dmapi.h"
+ #include "xfs_mac.h"
+ #include "xfs_log_priv.h"
+
+@@ -153,10 +152,9 @@
+ vap->va_nblocks =
+ XFS_FSB_TO_BB(mp, ip->i_d.di_nblocks + ip->i_delayed_blks);
+ vap->va_fsid = mp->m_dev;
+-#if XFS_BIG_FILESYSTEMS
+- vap->va_nodeid = ip->i_ino + mp->m_inoadd;
+-#else
+ vap->va_nodeid = ip->i_ino;
++#if XFS_BIG_INUMS
++ vap->va_nodeid += mp->m_inoadd;
+ #endif
+ vap->va_nlink = ip->i_d.di_nlink;
+
+@@ -266,6 +264,16 @@
+ XFS_XFLAG_REALTIME : 0) |
+ ((ip->i_d.di_flags & XFS_DIFLAG_PREALLOC) ?
+ XFS_XFLAG_PREALLOC : 0) |
++ ((ip->i_d.di_flags & XFS_DIFLAG_IMMUTABLE) ?
++ XFS_XFLAG_IMMUTABLE : 0) |
++ ((ip->i_d.di_flags & XFS_DIFLAG_APPEND) ?
++ XFS_XFLAG_APPEND : 0) |
++ ((ip->i_d.di_flags & XFS_DIFLAG_SYNC) ?
++ XFS_XFLAG_SYNC : 0) |
++ ((ip->i_d.di_flags & XFS_DIFLAG_NOATIME) ?
++ XFS_XFLAG_NOATIME : 0) |
++ ((ip->i_d.di_flags & XFS_DIFLAG_NODUMP) ?
++ XFS_XFLAG_NODUMP: 0) |
+ (XFS_IFORK_Q(ip) ?
+ XFS_XFLAG_HASATTR : 0);
+ vap->va_extsize = ip->i_d.di_extsize << mp->m_sb.sb_blocklog;
+@@ -648,6 +656,20 @@
+ goto error_return;
+ }
+ }
++
++ /*
++ * Can't modify an immutable/append-only file unless
++ * we have appropriate permission.
++ */
++ if ((mask & XFS_AT_XFLAGS) &&
++ (ip->i_d.di_flags &
++ (XFS_DIFLAG_IMMUTABLE|XFS_DIFLAG_APPEND) ||
++ (vap->va_xflags &
++ (XFS_XFLAG_IMMUTABLE | XFS_XFLAG_APPEND))) &&
++ !capable(CAP_LINUX_IMMUTABLE)) {
++ code = XFS_ERROR(EPERM);
++ goto error_return;
++ }
+ }
+
+ /*
+@@ -833,6 +855,16 @@
+ ip->i_d.di_flags |= XFS_DIFLAG_REALTIME;
+ ip->i_iocore.io_flags |= XFS_IOCORE_RT;
+ }
++ if (vap->va_xflags & XFS_XFLAG_IMMUTABLE)
++ ip->i_d.di_flags |= XFS_DIFLAG_IMMUTABLE;
++ if (vap->va_xflags & XFS_XFLAG_APPEND)
++ ip->i_d.di_flags |= XFS_DIFLAG_APPEND;
++ if (vap->va_xflags & XFS_XFLAG_SYNC)
++ ip->i_d.di_flags |= XFS_DIFLAG_SYNC;
++ if (vap->va_xflags & XFS_XFLAG_NOATIME)
++ ip->i_d.di_flags |= XFS_DIFLAG_NOATIME;
++ if (vap->va_xflags & XFS_XFLAG_NODUMP)
++ ip->i_d.di_flags |= XFS_DIFLAG_NODUMP;
+ /* can't set PREALLOC this way, just ignore it */
+ }
+ xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+@@ -858,7 +890,7 @@
+ if (timeflags && !(flags & ATTR_DMI))
+ xfs_ichgtime(ip, timeflags);
+
+- XFS_STATS_INC(xfsstats.xs_ig_attrchg);
++ XFS_STATS_INC(xs_ig_attrchg);
+
+ /*
+ * If this is a synchronous mount, make sure that the
+@@ -905,7 +937,7 @@
+
+ if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_ATTRIBUTE) &&
+ !(flags & ATTR_DMI)) {
+- (void) XFS_SEND_NAMESP(mp, DM_EVENT_ATTRIBUTE, bdp, DM_RIGHT_NULL,
++ (void) XFS_SEND_NAMESP(mp, DM_EVENT_ATTRIBUTE, vp, DM_RIGHT_NULL,
+ NULL, DM_RIGHT_NULL, NULL, NULL,
+ 0, 0, AT_DELAY_FLAG(flags));
+ }
+@@ -1635,7 +1667,7 @@
+ if ((((ip->i_d.di_mode & IFMT) == IFREG) &&
+ ((ip->i_d.di_size > 0) || (VN_CACHED(vp) > 0)) &&
+ (ip->i_df.if_flags & XFS_IFEXTENTS)) &&
+- (!(ip->i_d.di_flags & XFS_DIFLAG_PREALLOC))) {
++ (!(ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC|XFS_DIFLAG_APPEND)))) {
+ if ((error = xfs_inactive_free_eofblocks(mp, ip)))
+ return (error);
+ /* Update linux inode block count after free above */
+@@ -1710,7 +1742,7 @@
+ if ((((ip->i_d.di_mode & IFMT) == IFREG) &&
+ ((ip->i_d.di_size > 0) || (VN_CACHED(vp) > 0)) &&
+ (ip->i_df.if_flags & XFS_IFEXTENTS)) &&
+- (!(ip->i_d.di_flags & XFS_DIFLAG_PREALLOC) ||
++ (!(ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC|XFS_DIFLAG_APPEND)) ||
+ (ip->i_delayed_blks != 0))) {
+ if ((error = xfs_inactive_free_eofblocks(mp, ip)))
+ return (VN_INACTIVE_CACHE);
+@@ -1948,7 +1980,7 @@
+
+ if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_CREATE)) {
+ error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE,
+- dir_bdp, DM_RIGHT_NULL, NULL,
++ dir_vp, DM_RIGHT_NULL, NULL,
+ DM_RIGHT_NULL, name, NULL,
+ dm_di_mode, 0, 0);
+
+@@ -2114,8 +2146,8 @@
+ DM_EVENT_ENABLED(dir_vp->v_vfsp, XFS_BHVTOI(dir_bdp),
+ DM_EVENT_POSTCREATE)) {
+ (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE,
+- dir_bdp, DM_RIGHT_NULL,
+- *vpp ? vn_bhv_lookup_unlocked(VN_BHV_HEAD(vp), &xfs_vnodeops):NULL,
++ dir_vp, DM_RIGHT_NULL,
++ *vpp ? vp:NULL,
+ DM_RIGHT_NULL, name, NULL,
+ dm_di_mode, error, 0);
+ }
+@@ -2428,7 +2460,7 @@
+ namelen = VNAMELEN(dentry);
+
+ if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) {
+- error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, dir_bdp,
++ error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, dir_vp,
+ DM_RIGHT_NULL, NULL, DM_RIGHT_NULL,
+ name, NULL, 0, 0, 0);
+ if (error)
+@@ -2594,7 +2626,7 @@
+ if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp,
+ DM_EVENT_POSTREMOVE)) {
+ (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE,
+- dir_bdp, DM_RIGHT_NULL,
++ dir_vp, DM_RIGHT_NULL,
+ NULL, DM_RIGHT_NULL,
+ name, NULL, dm_di_mode, error, 0);
+ }
+@@ -2678,8 +2710,8 @@
+
+ if (DM_EVENT_ENABLED(src_vp->v_vfsp, tdp, DM_EVENT_LINK)) {
+ error = XFS_SEND_NAMESP(mp, DM_EVENT_LINK,
+- target_dir_bdp, DM_RIGHT_NULL,
+- src_bdp, DM_RIGHT_NULL,
++ target_dir_vp, DM_RIGHT_NULL,
++ src_vp, DM_RIGHT_NULL,
+ target_name, NULL, 0, 0, 0);
+ if (error)
+ return error;
+@@ -2782,8 +2814,8 @@
+ if (DM_EVENT_ENABLED(src_vp->v_vfsp, sip,
+ DM_EVENT_POSTLINK)) {
+ (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTLINK,
+- target_dir_bdp, DM_RIGHT_NULL,
+- src_bdp, DM_RIGHT_NULL,
++ target_dir_vp, DM_RIGHT_NULL,
++ src_vp, DM_RIGHT_NULL,
+ target_name, NULL, 0, error, 0);
+ }
+ return error;
+@@ -2844,7 +2876,7 @@
+
+ if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_CREATE)) {
+ error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE,
+- dir_bdp, DM_RIGHT_NULL, NULL,
++ dir_vp, DM_RIGHT_NULL, NULL,
+ DM_RIGHT_NULL, dir_name, NULL,
+ dm_di_mode, 0, 0);
+ if (error)
+@@ -3003,8 +3035,8 @@
+ DM_EVENT_ENABLED(dir_vp->v_vfsp, XFS_BHVTOI(dir_bdp),
+ DM_EVENT_POSTCREATE)) {
+ (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE,
+- dir_bdp, DM_RIGHT_NULL,
+- created ? XFS_ITOBHV(cdp):NULL,
++ dir_vp, DM_RIGHT_NULL,
++ created ? XFS_ITOV(cdp):NULL,
+ DM_RIGHT_NULL,
+ dir_name, NULL,
+ dm_di_mode, error, 0);
+@@ -3067,7 +3099,7 @@
+
+ if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) {
+ error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE,
+- dir_bdp, DM_RIGHT_NULL,
++ dir_vp, DM_RIGHT_NULL,
+ NULL, DM_RIGHT_NULL,
+ name, NULL, 0, 0, 0);
+ if (error)
+@@ -3261,7 +3293,7 @@
+ std_return:
+ if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_POSTREMOVE)) {
+ (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE,
+- dir_bdp, DM_RIGHT_NULL,
++ dir_vp, DM_RIGHT_NULL,
+ NULL, DM_RIGHT_NULL,
+ name, NULL, dm_di_mode,
+ error, 0);
+@@ -3405,7 +3437,7 @@
+ }
+
+ if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_SYMLINK)) {
+- error = XFS_SEND_NAMESP(mp, DM_EVENT_SYMLINK, dir_bdp,
++ error = XFS_SEND_NAMESP(mp, DM_EVENT_SYMLINK, dir_vp,
+ DM_RIGHT_NULL, NULL, DM_RIGHT_NULL,
+ link_name, target_path, 0, 0, 0);
+ if (error)
+@@ -3597,8 +3629,8 @@
+ if (DM_EVENT_ENABLED(dir_vp->v_vfsp, XFS_BHVTOI(dir_bdp),
+ DM_EVENT_POSTSYMLINK)) {
+ (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTSYMLINK,
+- dir_bdp, DM_RIGHT_NULL,
+- error ? NULL : XFS_ITOBHV(ip),
++ dir_vp, DM_RIGHT_NULL,
++ error ? NULL : XFS_ITOV(ip),
+ DM_RIGHT_NULL, link_name, target_path,
+ 0, error, 0);
+ }
+@@ -4236,8 +4268,8 @@
+ DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_NOSPACE)) {
+
+ error = XFS_SEND_NAMESP(mp, DM_EVENT_NOSPACE,
+- XFS_ITOBHV(ip), DM_RIGHT_NULL,
+- XFS_ITOBHV(ip), DM_RIGHT_NULL,
++ XFS_ITOV(ip), DM_RIGHT_NULL,
++ XFS_ITOV(ip), DM_RIGHT_NULL,
+ NULL, NULL, 0, 0, 0); /* Delay flag intentionally unused */
+ if (error == 0)
+ goto retry; /* Maybe DMAPI app. has made space */
+Index: linux-2.6.0-test5/include/acpi/acconfig.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/acpi/acconfig.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/acpi/acconfig.h 2003-09-27 11:38:40.032442528 +0800
+@@ -64,7 +64,7 @@
+
+ /* Version string */
+
+-#define ACPI_CA_VERSION 0x20030813
++#define ACPI_CA_VERSION 0x20030916
+
+ /* Maximum objects in the various object caches */
+
+Index: linux-2.6.0-test5/include/asm-alpha/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-alpha/cacheflush.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-alpha/cacheflush.h 2003-09-27 11:38:40.034442224 +0800
+@@ -10,6 +10,8 @@
+ #define flush_cache_range(vma, start, end) do { } while (0)
+ #define flush_cache_page(vma, vmaddr) do { } while (0)
+ #define flush_dcache_page(page) do { } while (0)
++#define flush_cache_vmap(start, end) do { } while (0)
++#define flush_cache_vunmap(start, end) do { } while (0)
+
+ /* Note that the following two definitions are _highly_ dependent
+ on the contexts in which they are used in the kernel. I personally
+@@ -60,4 +62,11 @@
+ #define flush_icache_page(vma, page) \
+ flush_icache_user_range((vma), (page), 0, 0)
+
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++do { memcpy(dst, src, len); \
++ flush_icache_user_range(vma, page, vaddr, len); \
++} while (0)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++ memcpy(dst, src, len)
++
+ #endif /* _ALPHA_CACHEFLUSH_H */
+Index: linux-2.6.0-test5/include/asm-alpha/lockmeter.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-alpha/lockmeter.h 2003-09-27 11:38:18.474719800 +0800
++++ linux-2.6.0-test5/include/asm-alpha/lockmeter.h 2003-09-27 11:38:40.034442224 +0800
+@@ -0,0 +1,90 @@
++/*
++ * Written by John Hawkes (hawkes@sgi.com)
++ * Based on klstat.h by Jack Steiner (steiner@sgi.com)
++ *
++ * Modified by Peter Rival (frival@zk3.dec.com)
++ */
++
++#ifndef _ALPHA_LOCKMETER_H
++#define _ALPHA_LOCKMETER_H
++
++#include <asm/hwrpb.h>
++#define CPU_CYCLE_FREQUENCY hwrpb->cycle_freq
++
++#define get_cycles64() get_cycles()
++
++#define THIS_CPU_NUMBER smp_processor_id()
++
++#include <linux/version.h>
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
++#define local_irq_save(x) \
++ __save_and_cli(x)
++#define local_irq_restore(x) \
++ __restore_flags(x)
++#endif /* Linux version 2.2.x */
++
++#define SPINLOCK_MAGIC_INIT /**/
++
++/*
++ * Macros to cache and retrieve an index value inside of a lock
++ * these macros assume that there are less than 65536 simultaneous
++ * (read mode) holders of a rwlock.
++ * We also assume that the hash table has less than 32767 entries.
++ * the high order bit is used for write locking a rw_lock
++ * Note: although these defines and macros are the same as what is being used
++ * in include/asm-i386/lockmeter.h, they are present here to easily
++ * allow an alternate Alpha implementation.
++ */
++/*
++ * instrumented spinlock structure -- never used to allocate storage
++ * only used in macros below to overlay a spinlock_t
++ */
++typedef struct inst_spinlock_s {
++ /* remember, Alpha is little endian */
++ unsigned short lock;
++ unsigned short index;
++} inst_spinlock_t;
++#define PUT_INDEX(lock_ptr,indexv) ((inst_spinlock_t *)(lock_ptr))->index = indexv
++#define GET_INDEX(lock_ptr) ((inst_spinlock_t *)(lock_ptr))->index
++
++/*
++ * macros to cache and retrieve an index value in a read/write lock
++ * as well as the cpu where a reader busy period started
++ * we use the 2nd word (the debug word) for this, so require the
++ * debug word to be present
++ */
++/*
++ * instrumented rwlock structure -- never used to allocate storage
++ * only used in macros below to overlay a rwlock_t
++ */
++typedef struct inst_rwlock_s {
++ volatile int lock;
++ unsigned short index;
++ unsigned short cpu;
++} inst_rwlock_t;
++#define PUT_RWINDEX(rwlock_ptr,indexv) ((inst_rwlock_t *)(rwlock_ptr))->index = indexv
++#define GET_RWINDEX(rwlock_ptr) ((inst_rwlock_t *)(rwlock_ptr))->index
++#define PUT_RW_CPU(rwlock_ptr,cpuv) ((inst_rwlock_t *)(rwlock_ptr))->cpu = cpuv
++#define GET_RW_CPU(rwlock_ptr) ((inst_rwlock_t *)(rwlock_ptr))->cpu
++
++/*
++ * return true if rwlock is write locked
++ * (note that other lock attempts can cause the lock value to be negative)
++ */
++#define RWLOCK_IS_WRITE_LOCKED(rwlock_ptr) (((inst_rwlock_t *)rwlock_ptr)->lock & 1)
++#define IABS(x) ((x) > 0 ? (x) : -(x))
++
++#define RWLOCK_READERS(rwlock_ptr) rwlock_readers(rwlock_ptr)
++extern inline int rwlock_readers(rwlock_t *rwlock_ptr)
++{
++ int tmp = (int) ((inst_rwlock_t *)rwlock_ptr)->lock;
++ /* readers subtract 2, so we have to: */
++ /* - andnot off a possible writer (bit 0) */
++ /* - get the absolute value */
++ /* - divide by 2 (right shift by one) */
++ /* to find the number of readers */
++ if (tmp == 0) return(0);
++ else return(IABS(tmp & ~1)>>1);
++}
++
++#endif /* _ALPHA_LOCKMETER_H */
+Index: linux-2.6.0-test5/include/asm-alpha/numnodes.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-alpha/numnodes.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-alpha/numnodes.h 2003-09-27 11:38:40.036441920 +0800
+@@ -1,6 +1,7 @@
+ #ifndef _ASM_MAX_NUMNODES_H
+ #define _ASM_MAX_NUMNODES_H
+
+-#define MAX_NUMNODES 128 /* Marvel */
++/* Max 128 Nodes - Marvel */
++#define NODES_SHIFT 7
+
+ #endif /* _ASM_MAX_NUMNODES_H */
+Index: linux-2.6.0-test5/include/asm-alpha/pgtable.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-alpha/pgtable.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-alpha/pgtable.h 2003-09-27 11:38:40.040441312 +0800
+@@ -49,7 +49,6 @@
+ #else
+ #define VMALLOC_START (-2*PGDIR_SIZE)
+ #endif
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END (-PGDIR_SIZE)
+
+ /*
+Index: linux-2.6.0-test5/include/asm-alpha/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-alpha/posix_types.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-alpha/posix_types.h 2003-09-27 11:38:40.042441008 +0800
+@@ -7,7 +7,6 @@
+ * assume GCC is being used.
+ */
+
+-typedef unsigned int __kernel_dev_t;
+ typedef unsigned int __kernel_ino_t;
+ typedef unsigned int __kernel_mode_t;
+ typedef unsigned int __kernel_nlink_t;
+Index: linux-2.6.0-test5/include/asm-alpha/processor.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-alpha/processor.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-alpha/processor.h 2003-09-27 11:38:40.043440856 +0800
+@@ -29,7 +29,6 @@
+ /*
+ * Bus types
+ */
+-#define EISA_bus 1
+ #define MCA_bus 0
+ #define MCA_bus__is_a_macro /* for versions in ksyms.c */
+
+Index: linux-2.6.0-test5/include/asm-alpha/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-alpha/signal.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-alpha/signal.h 2003-09-27 11:38:40.045440552 +0800
+@@ -71,7 +71,7 @@
+
+ /* These should not be considered constants from userland. */
+ #define SIGRTMIN 32
+-#define SIGRTMAX (_NSIG-1)
++#define SIGRTMAX _NSIG
+
+ /*
+ * SA_FLAGS values:
+Index: linux-2.6.0-test5/include/asm-alpha/smp.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-alpha/smp.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-alpha/smp.h 2003-09-27 11:38:40.047440248 +0800
+@@ -46,7 +46,7 @@
+ #define smp_processor_id() (current_thread_info()->cpu)
+
+ extern cpumask_t cpu_present_mask;
+-extern cpumask_t long cpu_online_map;
++extern cpumask_t cpu_online_map;
+ extern int smp_num_cpus;
+
+ #define cpu_possible(cpu) cpu_isset(cpu, cpu_present_mask)
+Index: linux-2.6.0-test5/include/asm-alpha/spinlock.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-alpha/spinlock.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-alpha/spinlock.h 2003-09-27 11:38:40.048440096 +0800
+@@ -6,6 +6,10 @@
+ #include <linux/kernel.h>
+ #include <asm/current.h>
+
++#ifdef CONFIG_LOCKMETER
++#undef DEBUG_SPINLOCK
++#undef DEBUG_RWLOCK
++#endif
+
+ /*
+ * Simple spin lock operations. There are two variants, one clears IRQ's
+@@ -95,9 +99,18 @@
+
+ typedef struct {
+ volatile int write_lock:1, read_counter:31;
++#ifdef CONFIG_LOCKMETER
++ /* required for LOCKMETER since all bits in lock are used */
++ /* need this storage for CPU and lock INDEX ............. */
++ unsigned magic;
++#endif
+ } /*__attribute__((aligned(32)))*/ rwlock_t;
+
++#ifdef CONFIG_LOCKMETER
++#define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0, 0 }
++#else
+ #define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 }
++#endif
+
+ #define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0)
+ #define rwlock_is_locked(x) (*(volatile int *)(x) != 0)
+@@ -169,4 +182,41 @@
+ : "m" (*lock) : "memory");
+ }
+
++#ifdef CONFIG_LOCKMETER
++static inline int _raw_write_trylock(rwlock_t *lock)
++{
++ long temp,result;
++
++ __asm__ __volatile__(
++ " ldl_l %1,%0\n"
++ " mov $31,%2\n"
++ " bne %1,1f\n"
++ " or $31,1,%2\n"
++ " stl_c %2,%0\n"
++ "1: mb\n"
++ : "=m" (*(volatile int *)lock), "=&r" (temp), "=&r" (result)
++ : "m" (*(volatile int *)lock)
++ );
++
++ return (result);
++}
++
++static inline int _raw_read_trylock(rwlock_t *lock)
++{
++ unsigned long temp,result;
++
++ __asm__ __volatile__(
++ " ldl_l %1,%0\n"
++ " mov $31,%2\n"
++ " blbs %1,1f\n"
++ " subl %1,2,%2\n"
++ " stl_c %2,%0\n"
++ "1: mb\n"
++ : "=m" (*(volatile int *)lock), "=&r" (temp), "=&r" (result)
++ : "m" (*(volatile int *)lock)
++ );
++ return (result);
++}
++#endif /* CONFIG_LOCKMETER */
++
+ #endif /* _ALPHA_SPINLOCK_H */
+Index: linux-2.6.0-test5/include/asm-arm26/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm26/cacheflush.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm26/cacheflush.h 2003-09-27 11:38:40.050439792 +0800
+@@ -25,6 +25,8 @@
+ #define flush_cache_range(vma,start,end) do { } while (0)
+ #define flush_cache_page(vma,vmaddr) do { } while (0)
+ #define flush_page_to_ram(page) do { } while (0)
++#define flush_cache_vmap(start, end) do { } while (0)
++#define flush_cache_vunmap(start, end) do { } while (0)
+
+ #define invalidate_dcache_range(start,end) do { } while (0)
+ #define clean_dcache_range(start,end) do { } while (0)
+@@ -37,6 +39,11 @@
+ #define flush_icache_range(start,end) do { } while (0)
+ #define flush_icache_page(vma,page) do { } while (0)
+
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++ memcpy(dst, src, len)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++ memcpy(dst, src, len)
++
+ /* DAG: ARM3 will flush cache on MEMC updates anyway? so don't bother */
+ /* IM : Yes, it will, but only if setup to do so (we do this). */
+ #define clean_cache_area(_start,_size) do { } while (0)
+Index: linux-2.6.0-test5/include/asm-arm26/pgtable.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm26/pgtable.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm26/pgtable.h 2003-09-27 11:38:40.053439336 +0800
+@@ -173,7 +173,6 @@
+ * area for the same reason. ;) FIXME: surely 1 page not 4k ?
+ */
+ #define VMALLOC_START 0x01a00000
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END 0x01c00000
+
+ /* Is pmd_page supposed to return a pointer to a page in some arches? ours seems to
+Index: linux-2.6.0-test5/include/asm-arm26/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm26/posix_types.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm26/posix_types.h 2003-09-27 11:38:40.055439032 +0800
+@@ -19,7 +19,6 @@
+ * assume GCC is being used.
+ */
+
+-typedef unsigned short __kernel_dev_t;
+ typedef unsigned long __kernel_ino_t;
+ typedef unsigned short __kernel_mode_t;
+ typedef unsigned short __kernel_nlink_t;
+Index: linux-2.6.0-test5/include/asm-arm26/processor.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm26/processor.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm26/processor.h 2003-09-27 11:38:40.056438880 +0800
+@@ -20,7 +20,6 @@
+
+ #ifdef __KERNEL__
+
+-#define EISA_bus 0
+ #define MCA_bus 0
+ #define MCA_bus__is_a_macro
+
+Index: linux-2.6.0-test5/include/asm-arm26/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm26/signal.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm26/signal.h 2003-09-27 11:38:40.059438424 +0800
+@@ -68,7 +68,7 @@
+
+ /* These should not be considered constants from userland. */
+ #define SIGRTMIN 32
+-#define SIGRTMAX (_NSIG-1)
++#define SIGRTMAX _NSIG
+
+ #define SIGSWI 32
+
+Index: linux-2.6.0-test5/include/asm-arm26/stat.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm26/stat.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm26/stat.h 2003-09-27 11:38:40.060438272 +0800
+@@ -42,8 +42,7 @@
+ * insane amounts of padding around dev_t's.
+ */
+ struct stat64 {
+- unsigned short st_dev;
+- unsigned char __pad0b[6];
++ unsigned long long st_dev;
+ unsigned char __pad0[4];
+
+ #define STAT64_HAS_BROKEN_ST_INO 1
+@@ -54,8 +53,7 @@
+ unsigned long st_uid;
+ unsigned long st_gid;
+
+- unsigned short st_rdev;
+- unsigned char __pad3b[6];
++ unsigned long long st_rdev;
+ unsigned char __pad3[4];
+
+ long long st_size;
+Index: linux-2.6.0-test5/include/asm-arm/arch-adifcc/vmalloc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-adifcc/vmalloc.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-adifcc/vmalloc.h 2003-09-27 11:38:40.062437968 +0800
+@@ -12,7 +12,6 @@
+ */
+ #define VMALLOC_OFFSET (8*1024*1024)
+ #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END (0xe8000000)
+
+ #define MODULE_START (PAGE_OFFSET - 16*1048576)
+Index: linux-2.6.0-test5/include/asm-arm/arch-anakin/vmalloc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-anakin/vmalloc.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-anakin/vmalloc.h 2003-09-27 11:38:40.063437816 +0800
+@@ -19,8 +19,7 @@
+ * linux/arch/arm/kernel/traps.c)
+ */
+ #define VMALLOC_ARCH_OFFSET (8 * 1024 * 1024)
+-#define VMALLOC_VMADDR(a) ((unsigned int) (a))
+-#define VMALLOC_START ((VMALLOC_VMADDR(high_memory) + VMALLOC_ARCH_OFFSET) & ~(VMALLOC_ARCH_OFFSET - 1))
++#define VMALLOC_START (((unsigned long) (high_memory) + VMALLOC_ARCH_OFFSET) & ~(VMALLOC_ARCH_OFFSET - 1))
+ #define VMALLOC_END (PAGE_OFFSET + 0x10000000)
+
+ #define MODULE_START (PAGE_OFFSET - 16*1048576)
+Index: linux-2.6.0-test5/include/asm-arm/arch-cl7500/vmalloc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-cl7500/vmalloc.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-cl7500/vmalloc.h 2003-09-27 11:38:40.064437664 +0800
+@@ -12,7 +12,6 @@
+ */
+ #define VMALLOC_OFFSET (8*1024*1024)
+ #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END (PAGE_OFFSET + 0x1c000000)
+
+ #define MODULE_START (PAGE_OFFSET - 16*1048576)
+Index: linux-2.6.0-test5/include/asm-arm/arch-clps711x/memory.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-clps711x/memory.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-clps711x/memory.h 2003-09-27 11:38:40.067437208 +0800
+@@ -109,8 +109,6 @@
+ * node 3: 0xd8000000 - 0xdfffffff
+ */
+
+-#define NR_NODES 4
+-
+ /*
+ * Given a kernel address, find the home node of the underlying memory.
+ */
+Index: linux-2.6.0-test5/include/asm-arm/arch-clps711x/system.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-clps711x/system.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-clps711x/system.h 2003-09-27 11:38:40.068437056 +0800
+@@ -26,7 +26,7 @@
+ {
+ clps_writel(1, HALT);
+ __asm__ __volatile__(
+- "mov r0, r0
++ "mov r0, r0\n\
+ mov r0, r0");
+ }
+
+Index: linux-2.6.0-test5/include/asm-arm/arch-clps711x/vmalloc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-clps711x/vmalloc.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-clps711x/vmalloc.h 2003-09-27 11:38:40.070436752 +0800
+@@ -28,7 +28,6 @@
+ */
+ #define VMALLOC_OFFSET (8*1024*1024)
+ #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END (PAGE_OFFSET + 0x10000000)
+
+ #define MODULE_START (PAGE_OFFSET - 16*1048576)
+Index: linux-2.6.0-test5/include/asm-arm/arch-ebsa110/vmalloc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-ebsa110/vmalloc.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-ebsa110/vmalloc.h 2003-09-27 11:38:40.071436600 +0800
+@@ -18,7 +18,6 @@
+ */
+ #define VMALLOC_OFFSET (8*1024*1024)
+ #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END (PAGE_OFFSET + 0x1f000000)
+
+ #define MODULE_START (PAGE_OFFSET - 16*1048576)
+Index: linux-2.6.0-test5/include/asm-arm/arch-ebsa285/vmalloc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-ebsa285/vmalloc.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-ebsa285/vmalloc.h 2003-09-27 11:38:40.072436448 +0800
+@@ -18,7 +18,6 @@
+ */
+ #define VMALLOC_OFFSET (8*1024*1024)
+ #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+
+ #ifdef CONFIG_ARCH_FOOTBRIDGE
+ #define VMALLOC_END (PAGE_OFFSET + 0x30000000)
+Index: linux-2.6.0-test5/include/asm-arm/arch-epxa10db/vmalloc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-epxa10db/vmalloc.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-epxa10db/vmalloc.h 2003-09-27 11:38:40.074436144 +0800
+@@ -28,7 +28,6 @@
+ */
+ #define VMALLOC_OFFSET (8*1024*1024)
+ #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END (PAGE_OFFSET + 0x10000000)
+
+ #define MODULE_START (PAGE_OFFSET - 16*1048576)
+Index: linux-2.6.0-test5/include/asm-arm/arch-integrator/lm.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-integrator/lm.h 2003-09-27 11:38:18.475719648 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-integrator/lm.h 2003-09-27 11:38:40.074436144 +0800
+@@ -0,0 +1,23 @@
++
++struct lm_device {
++ struct device dev;
++ struct resource resource;
++ unsigned int irq;
++ unsigned int id;
++};
++
++struct lm_driver {
++ struct device_driver drv;
++ int (*probe)(struct lm_device *);
++ void (*remove)(struct lm_device *);
++ int (*suspend)(struct lm_device *, u32);
++ int (*resume)(struct lm_device *);
++};
++
++int lm_driver_register(struct lm_driver *drv);
++void lm_driver_unregister(struct lm_driver *drv);
++
++int lm_device_register(struct lm_device *dev);
++
++#define lm_get_drvdata(lm) dev_get_drvdata(&(lm)->dev)
++#define lm_set_drvdata(lm,d) dev_set_drvdata(&(lm)->dev, d)
+Index: linux-2.6.0-test5/include/asm-arm/arch-integrator/vmalloc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-integrator/vmalloc.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-integrator/vmalloc.h 2003-09-27 11:38:40.076435840 +0800
+@@ -28,7 +28,6 @@
+ */
+ #define VMALLOC_OFFSET (8*1024*1024)
+ #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END (PAGE_OFFSET + 0x10000000)
+
+ #define MODULE_START (PAGE_OFFSET - 16*1048576)
+Index: linux-2.6.0-test5/include/asm-arm/arch-iop3xx/iop321-irqs.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-iop3xx/iop321-irqs.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-iop3xx/iop321-irqs.h 2003-09-27 11:38:40.077435688 +0800
+@@ -10,6 +10,7 @@
+ *
+ */
+
++#include <linux/config.h>
+
+ /*
+ * IOP80321 chipset interrupts
+Index: linux-2.6.0-test5/include/asm-arm/arch-iop3xx/irqs.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-iop3xx/irqs.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-iop3xx/irqs.h 2003-09-27 11:38:40.079435384 +0800
+@@ -10,6 +10,8 @@
+ *
+ */
+
++#include <linux/config.h>
++
+ /*
+ * Whic iop3xx implementation is this?
+ */
+Index: linux-2.6.0-test5/include/asm-arm/arch-iop3xx/vmalloc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-iop3xx/vmalloc.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-iop3xx/vmalloc.h 2003-09-27 11:38:40.080435232 +0800
+@@ -12,7 +12,6 @@
+ */
+ #define VMALLOC_OFFSET (8*1024*1024)
+ #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END (0xe8000000)
+
+ #define MODULE_START (PAGE_OFFSET - 16*1048576)
+Index: linux-2.6.0-test5/include/asm-arm/arch-l7200/vmalloc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-l7200/vmalloc.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-l7200/vmalloc.h 2003-09-27 11:38:40.081435080 +0800
+@@ -12,7 +12,6 @@
+ */
+ #define VMALLOC_OFFSET (8*1024*1024)
+ #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END (PAGE_OFFSET + 0x10000000)
+
+ #define MODULE_START (PAGE_OFFSET - 16*1048576)
+Index: linux-2.6.0-test5/include/asm-arm/arch-nexuspci/vmalloc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-nexuspci/vmalloc.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-nexuspci/vmalloc.h 2003-09-27 11:38:40.083434776 +0800
+@@ -12,7 +12,6 @@
+ */
+ #define VMALLOC_OFFSET (8*1024*1024)
+ #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END (PAGE_OFFSET + 0x20000000)
+
+ #define MODULE_START (PAGE_OFFSET - 16*1048576)
+Index: linux-2.6.0-test5/include/asm-arm/arch-pxa/hardware.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-pxa/hardware.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-pxa/hardware.h 2003-09-27 11:38:40.084434624 +0800
+@@ -13,7 +13,6 @@
+ #ifndef __ASM_ARCH_HARDWARE_H
+ #define __ASM_ARCH_HARDWARE_H
+
+-#include <linux/config.h>
+ #include <asm/mach-types.h>
+
+
+Index: linux-2.6.0-test5/include/asm-arm/arch-pxa/ide.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-pxa/ide.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-pxa/ide.h 2003-09-27 11:38:40.086434320 +0800
+@@ -14,7 +14,6 @@
+ *
+ */
+
+-#include <linux/config.h>
+ #include <asm/irq.h>
+ #include <asm/hardware.h>
+ #include <asm/mach-types.h>
+Index: linux-2.6.0-test5/include/asm-arm/arch-pxa/idp.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-pxa/idp.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-pxa/idp.h 2003-09-27 11:38:40.090433712 +0800
+@@ -12,6 +12,7 @@
+ *
+ */
+
++#include <linux/config.h>
+
+ /*
+ * Note: this file must be safe to include in assembly files
+Index: linux-2.6.0-test5/include/asm-arm/arch-pxa/irqs.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-pxa/irqs.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-pxa/irqs.h 2003-09-27 11:38:40.092433408 +0800
+@@ -10,6 +10,8 @@
+ * published by the Free Software Foundation.
+ */
+
++#include <linux/config.h>
++
+ #define PXA_IRQ_SKIP 7 /* The first 7 IRQs are not yet used */
+ #define PXA_IRQ(x) ((x) - PXA_IRQ_SKIP)
+
+Index: linux-2.6.0-test5/include/asm-arm/arch-pxa/keyboard.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-pxa/keyboard.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-pxa/keyboard.h 2003-09-27 11:38:40.094433104 +0800
+@@ -7,7 +7,6 @@
+ #ifndef _PXA_KEYBOARD_H
+ #define _PXA_KEYBOARD_H
+
+-#include <linux/config.h>
+ #include <asm/mach-types.h>
+ #include <asm/hardware.h>
+
+Index: linux-2.6.0-test5/include/asm-arm/arch-pxa/pxa-regs.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-pxa/pxa-regs.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-pxa/pxa-regs.h 2003-09-27 11:38:40.111430520 +0800
+@@ -10,6 +10,7 @@
+ * published by the Free Software Foundation.
+ */
+
++#include <linux/config.h>
+
+ // FIXME hack so that SA-1111.h will work [cb]
+
+Index: linux-2.6.0-test5/include/asm-arm/arch-pxa/vmalloc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-pxa/vmalloc.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-pxa/vmalloc.h 2003-09-27 11:38:40.113430216 +0800
+@@ -19,7 +19,6 @@
+ */
+ #define VMALLOC_OFFSET (8*1024*1024)
+ #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END (0xe8000000)
+
+ #define MODULE_START (PAGE_OFFSET - 16*1048576)
+Index: linux-2.6.0-test5/include/asm-arm/arch-rpc/vmalloc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-rpc/vmalloc.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-rpc/vmalloc.h 2003-09-27 11:38:40.114430064 +0800
+@@ -18,7 +18,6 @@
+ */
+ #define VMALLOC_OFFSET (8*1024*1024)
+ #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END (PAGE_OFFSET + 0x1c000000)
+
+ #define MODULE_START (PAGE_OFFSET - 16*1048576)
+Index: linux-2.6.0-test5/include/asm-arm/arch-sa1100/memory.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-sa1100/memory.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-sa1100/memory.h 2003-09-27 11:38:40.116429760 +0800
+@@ -74,8 +74,6 @@
+ * node 3: 0xd8000000 - 0xdfffffff
+ */
+
+-#define NR_NODES 4
+-
+ /*
+ * Given a kernel address, find the home node of the underlying memory.
+ */
+Index: linux-2.6.0-test5/include/asm-arm/arch-sa1100/serial.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-sa1100/serial.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-sa1100/serial.h 2003-09-27 11:38:40.117429608 +0800
+@@ -7,6 +7,8 @@
+ * This is included by serial.c -- serial_sa1100.c makes no use of it.
+ */
+
++#include <linux/config.h>
++
+ /* Standard COM flags */
+ #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+
+Index: linux-2.6.0-test5/include/asm-arm/arch-sa1100/trizeps.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-sa1100/trizeps.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-sa1100/trizeps.h 2003-09-27 11:38:40.119429304 +0800
+@@ -13,6 +13,8 @@
+ #ifndef _ASM_ARCH_TRIZEPS_H_
+ #define _ASM_ARCH_TRIZEPS_H_
+
++#include <linux/config.h>
++
+ #ifdef CONFIG_TRIZEPS_MFTB2
+ #include "mftb2.h"
+ #endif
+Index: linux-2.6.0-test5/include/asm-arm/arch-sa1100/vmalloc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-sa1100/vmalloc.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-sa1100/vmalloc.h 2003-09-27 11:38:40.120429152 +0800
+@@ -12,7 +12,6 @@
+ */
+ #define VMALLOC_OFFSET (8*1024*1024)
+ #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END (0xe8000000)
+
+ #define MODULE_START (PAGE_OFFSET - 16*1048576)
+Index: linux-2.6.0-test5/include/asm-arm/arch-shark/vmalloc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-shark/vmalloc.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-shark/vmalloc.h 2003-09-27 11:38:40.121429000 +0800
+@@ -12,7 +12,6 @@
+ */
+ #define VMALLOC_OFFSET (8*1024*1024)
+ #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END (PAGE_OFFSET + 0x10000000)
+
+ #define MODULE_START (PAGE_OFFSET - 16*1048576)
+Index: linux-2.6.0-test5/include/asm-arm/arch-tbox/vmalloc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-tbox/vmalloc.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-tbox/vmalloc.h 2003-09-27 11:38:40.123428696 +0800
+@@ -12,7 +12,6 @@
+ */
+ #define VMALLOC_OFFSET (8*1024*1024)
+ #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END (PAGE_OFFSET + 0x10000000)
+
+ #define MODULE_START (PAGE_OFFSET - 16*1048576)
+Index: linux-2.6.0-test5/include/asm-arm/bugs.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/bugs.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/bugs.h 2003-09-27 11:38:40.124428544 +0800
+@@ -10,6 +10,8 @@
+ #ifndef __ASM_BUGS_H
+ #define __ASM_BUGS_H
+
+-#define check_bugs() do { } while (0)
++extern void check_writebuffer_bugs(void);
++
++#define check_bugs() check_writebuffer_bugs()
+
+ #endif
+Index: linux-2.6.0-test5/include/asm-arm/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/cacheflush.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/cacheflush.h 2003-09-27 11:38:40.128427936 +0800
+@@ -10,6 +10,7 @@
+ #ifndef _ASMARM_CACHEFLUSH_H
+ #define _ASMARM_CACHEFLUSH_H
+
++#include <linux/config.h>
+ #include <linux/sched.h>
+ #include <linux/mm.h>
+
+@@ -206,6 +207,15 @@
+ extern void dmac_clean_range(unsigned long, unsigned long);
+ extern void dmac_flush_range(unsigned long, unsigned long);
+
++#define flush_cache_vmap(start, end) flush_cache_all()
++#define flush_cache_vunmap(start, end) flush_cache_all()
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++do { memcpy(dst, src, len); \
++ flush_icache_user_range(vma, page, vaddr, len); \
++} while (0)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++ memcpy(dst, src, len)
++
+ #endif
+
+ /*
+Index: linux-2.6.0-test5/include/asm-arm/glue.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/glue.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/glue.h 2003-09-27 11:38:40.129427784 +0800
+@@ -58,7 +58,7 @@
+ # endif
+ #endif
+
+-#if defined(CONFIG_CPU_ARM720T)
++#ifdef CONFIG_CPU_ABRT_LV4T
+ # ifdef CPU_ABORT_HANDLER
+ # define MULTI_ABORT 1
+ # else
+@@ -66,7 +66,7 @@
+ # endif
+ #endif
+
+-#if defined(CONFIG_CPU_SA110) || defined(CONFIG_CPU_SA1100)
++#ifdef CONFIG_CPU_ABRT_EV4
+ # ifdef CPU_ABORT_HANDLER
+ # define MULTI_ABORT 1
+ # else
+@@ -74,8 +74,7 @@
+ # endif
+ #endif
+
+-#if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \
+- defined(CONFIG_CPU_ARM1020)
++#ifdef CONFIG_CPU_ABRT_EV4T
+ # ifdef CPU_ABORT_HANDLER
+ # define MULTI_ABORT 1
+ # else
+@@ -83,19 +82,19 @@
+ # endif
+ #endif
+
+-#if defined(CONFIG_CPU_ARM926T)
++#ifdef CONFIG_CPU_ABRT_EV5TJ
+ # ifdef CPU_ABORT_HANDLER
+ # define MULTI_ABORT 1
+ # else
+-# define CPU_ABORT_HANDLER v5tej_early_abort
++# define CPU_ABORT_HANDLER v5tj_early_abort
+ # endif
+ #endif
+
+-#if defined(CONFIG_CPU_XSCALE)
++#ifdef CONFIG_CPU_ABRT_EV5T
+ # ifdef CPU_ABORT_HANDLER
+ # define MULTI_ABORT 1
+ # else
+-# define CPU_ABORT_HANDLER xscale_abort
++# define CPU_ABORT_HANDLER v5t_early_abort
+ # endif
+ #endif
+
+Index: linux-2.6.0-test5/include/asm-arm/hardware/sa1111.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/hardware/sa1111.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/hardware/sa1111.h 2003-09-27 11:38:40.135426872 +0800
+@@ -543,7 +543,7 @@
+ #define SA1111_DEV(_d) container_of((_d), struct sa1111_dev, dev)
+
+ #define sa1111_get_drvdata(d) dev_get_drvdata(&(d)->dev)
+-#define sa1111_set_drvdata(d,p) dev_get_drvdata(&(d)->dev, p)
++#define sa1111_set_drvdata(d,p) dev_set_drvdata(&(d)->dev, p)
+
+ struct sa1111_driver {
+ struct device_driver drv;
+@@ -559,11 +559,6 @@
+ #define SA1111_DRIVER_NAME(_sadev) ((_sadev)->dev.driver->name)
+
+ /*
+- * Probe for a SA1111 chip.
+- */
+-extern int sa1111_init(unsigned long phys, unsigned int irq);
+-
+-/*
+ * These frob the SKPCR register.
+ */
+ void sa1111_enable_device(struct sa1111_dev *);
+Index: linux-2.6.0-test5/include/asm-arm/memory.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/memory.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/memory.h 2003-09-27 11:38:40.136426720 +0800
+@@ -84,24 +84,24 @@
+
+ #define PHYS_TO_NID(addr) (0)
+
+-#else
++#else /* CONFIG_DISCONTIGMEM */
++
+ /*
+ * This is more complex. We have a set of mem_map arrays spread
+ * around in memory.
+ */
++#include <linux/numa.h>
++
+ #define page_to_pfn(page) \
+ (( (page) - page_zone(page)->zone_mem_map) \
+ + page_zone(page)->zone_start_pfn)
+-
+ #define pfn_to_page(pfn) \
+ (PFN_TO_MAPBASE(pfn) + LOCAL_MAP_NR((pfn) << PAGE_SHIFT))
+-
+-#define pfn_valid(pfn) (PFN_TO_NID(pfn) < NR_NODES)
++#define pfn_valid(pfn) (PFN_TO_NID(pfn) < MAX_NUMNODES)
+
+ #define virt_to_page(kaddr) \
+ (ADDR_TO_MAPBASE(kaddr) + LOCAL_MAP_NR(kaddr))
+-
+-#define virt_addr_valid(kaddr) (KVADDR_TO_NID(kaddr) < NR_NODES)
++#define virt_addr_valid(kaddr) (KVADDR_TO_NID(kaddr) < MAX_NUMNODES)
+
+ /*
+ * Common discontigmem stuff.
+@@ -109,7 +109,7 @@
+ */
+ #define PHYS_TO_NID(addr) PFN_TO_NID((addr) >> PAGE_SHIFT)
+
+-#endif
++#endif /* !CONFIG_DISCONTIGMEM */
+
+ /*
+ * For BIO. "will die". Kill me when bio_to_phys() and bvec_to_phys() die.
+Index: linux-2.6.0-test5/include/asm-arm/mmu.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/mmu.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/mmu.h 2003-09-27 11:38:40.138426416 +0800
+@@ -1,8 +1,6 @@
+ #ifndef __ARM_MMU_H
+ #define __ARM_MMU_H
+
+-#include <linux/config.h>
+-
+ typedef struct {
+ #if __LINUX_ARM_ARCH__ >= 6
+ unsigned int id;
+Index: linux-2.6.0-test5/include/asm-arm/numnodes.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/numnodes.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/numnodes.h 2003-09-27 11:38:40.139426264 +0800
+@@ -10,8 +10,7 @@
+ #ifndef __ASM_ARM_NUMNODES_H
+ #define __ASM_ARM_NUMNODES_H
+
+-#include <asm/memory.h>
+-
+-#define MAX_NUMNODES NR_NODES
++/* Max 4 Nodes */
++#define NODES_SHIFT 2
+
+ #endif
+Index: linux-2.6.0-test5/include/asm-arm/page.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/page.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/page.h 2003-09-27 11:38:40.141425960 +0800
+@@ -44,7 +44,7 @@
+ #undef _USER
+ #undef MULTI_USER
+
+-#if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710)
++#ifdef CONFIG_CPU_COPY_V3
+ # ifdef _USER
+ # define MULTI_USER 1
+ # else
+@@ -52,7 +52,7 @@
+ # endif
+ #endif
+
+-#if defined(CONFIG_CPU_ARM720T)
++#ifdef CONFIG_CPU_COPY_V4WT
+ # ifdef _USER
+ # define MULTI_USER 1
+ # else
+@@ -60,9 +60,7 @@
+ # endif
+ #endif
+
+-#if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \
+- defined(CONFIG_CPU_ARM926T) || defined(CONFIG_CPU_SA110) || \
+- defined(CONFIG_CPU_ARM1020)
++#ifdef CONFIG_CPU_COPY_V4WB
+ # ifdef _USER
+ # define MULTI_USER 1
+ # else
+@@ -70,7 +68,7 @@
+ # endif
+ #endif
+
+-#if defined(CONFIG_CPU_SA1100)
++#ifdef CONFIG_CPU_SA1100
+ # ifdef _USER
+ # define MULTI_USER 1
+ # else
+@@ -78,7 +76,7 @@
+ # endif
+ #endif
+
+-#if defined(CONFIG_CPU_XSCALE)
++#ifdef CONFIG_CPU_XSCALE
+ # ifdef _USER
+ # define MULTI_USER 1
+ # else
+Index: linux-2.6.0-test5/include/asm-arm/pgtable.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/pgtable.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/pgtable.h 2003-09-27 11:38:40.145425352 +0800
+@@ -10,7 +10,6 @@
+ #ifndef _ASMARM_PGTABLE_H
+ #define _ASMARM_PGTABLE_H
+
+-#include <linux/config.h>
+ #include <asm/memory.h>
+ #include <asm/proc-fns.h>
+ #include <asm/arch/vmalloc.h>
+@@ -106,6 +105,7 @@
+ /*
+ * - extended small page/tiny page
+ */
++#define PTE_EXT_AP_MASK (3 << 4)
+ #define PTE_EXT_AP_UNO_SRO (0 << 4)
+ #define PTE_EXT_AP_UNO_SRW (1 << 4)
+ #define PTE_EXT_AP_URO_SRW (2 << 4)
+@@ -115,12 +115,11 @@
+ /*
+ * - small page
+ */
++#define PTE_SMALL_AP_MASK (0xff << 4)
+ #define PTE_SMALL_AP_UNO_SRO (0x00 << 4)
+ #define PTE_SMALL_AP_UNO_SRW (0x55 << 4)
+ #define PTE_SMALL_AP_URO_SRW (0xaa << 4)
+ #define PTE_SMALL_AP_URW_SRW (0xff << 4)
+-#define PTE_AP_READ PTE_SMALL_AP_URO_SRW
+-#define PTE_AP_WRITE PTE_SMALL_AP_UNO_SRW
+
+ /*
+ * "Linux" PTE definitions.
+Index: linux-2.6.0-test5/include/asm-arm/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/posix_types.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/posix_types.h 2003-09-27 11:38:40.146425200 +0800
+@@ -19,7 +19,6 @@
+ * assume GCC is being used.
+ */
+
+-typedef unsigned short __kernel_dev_t;
+ typedef unsigned long __kernel_ino_t;
+ typedef unsigned short __kernel_mode_t;
+ typedef unsigned short __kernel_nlink_t;
+Index: linux-2.6.0-test5/include/asm-arm/processor.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/processor.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/processor.h 2003-09-27 11:38:40.148424896 +0800
+@@ -19,7 +19,6 @@
+
+ #ifdef __KERNEL__
+
+-#define EISA_bus 0
+ #define MCA_bus 0
+ #define MCA_bus__is_a_macro
+
+Index: linux-2.6.0-test5/include/asm-arm/proc-fns.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/proc-fns.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/proc-fns.h 2003-09-27 11:38:40.150424592 +0800
+@@ -26,7 +26,6 @@
+ */
+
+ #ifdef CONFIG_CPU_32
+-# define CPU_INCLUDE_NAME "asm/cpu-multi32.h"
+ # ifdef CONFIG_CPU_ARM610
+ # ifdef CPU_NAME
+ # undef MULTI_CPU
+@@ -99,6 +98,30 @@
+ # define CPU_NAME cpu_arm1020
+ # endif
+ # endif
++# ifdef CONFIG_CPU_ARM1020E
++# ifdef CPU_NAME
++# undef MULTI_CPU
++# define MULTI_CPU
++# else
++# define CPU_NAME cpu_arm1020e
++# endif
++# endif
++# ifdef CONFIG_CPU_ARM1022
++# ifdef CPU_NAME
++# undef MULTI_CPU
++# define MULTI_CPU
++# else
++# define CPU_NAME cpu_arm1022
++# endif
++# endif
++# ifdef CONFIG_CPU_ARM1026
++# ifdef CPU_NAME
++# undef MULTI_CPU
++# define MULTI_CPU
++# else
++# define CPU_NAME cpu_arm1026
++# endif
++# endif
+ # ifdef CONFIG_CPU_XSCALE
+ # ifdef CPU_NAME
+ # undef MULTI_CPU
+@@ -110,11 +133,10 @@
+ #endif
+
+ #ifndef MULTI_CPU
+-#undef CPU_INCLUDE_NAME
+-#define CPU_INCLUDE_NAME "asm/cpu-single.h"
++#include "asm/cpu-single.h"
++#else
++#include "asm/cpu-multi32.h"
+ #endif
+
+-#include CPU_INCLUDE_NAME
+-
+ #endif /* __KERNEL__ */
+ #endif /* __ASM_PROCFNS_H */
+Index: linux-2.6.0-test5/include/asm-arm/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/signal.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/signal.h 2003-09-27 11:38:40.152424288 +0800
+@@ -68,7 +68,7 @@
+
+ /* These should not be considered constants from userland. */
+ #define SIGRTMIN 32
+-#define SIGRTMAX (_NSIG-1)
++#define SIGRTMAX _NSIG
+
+ #define SIGSWI 32
+
+Index: linux-2.6.0-test5/include/asm-arm/string.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/string.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/string.h 2003-09-27 11:38:40.153424136 +0800
+@@ -25,6 +25,8 @@
+ #define __HAVE_ARCH_MEMSET
+ extern void * memset(void *, int, __kernel_size_t);
+
++#define __HAVE_ARCH_BCOPY
++
+ extern void __memzero(void *ptr, __kernel_size_t n);
+
+ #define memset(p,v,n) \
+Index: linux-2.6.0-test5/include/asm-arm/system.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/system.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/system.h 2003-09-27 11:38:40.156423680 +0800
+@@ -36,7 +36,7 @@
+ #define CR_DT (1 << 16)
+ #define CR_IT (1 << 18)
+ #define CR_ST (1 << 19)
+-#define CR_FI (1 << 21)
++#define CR_FI (1 << 21) /* Fast interrupt (lower latency mode) */
+ #define CR_U (1 << 22) /* Unaligned access operation */
+ #define CR_XP (1 << 23) /* Extended page tables */
+ #define CR_VE (1 << 24) /* Vectored interrupts */
+Index: linux-2.6.0-test5/include/asm-arm/tlbflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/tlbflush.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/tlbflush.h 2003-09-27 11:38:40.159423224 +0800
+@@ -52,7 +52,7 @@
+
+ #define v3_tlb_flags (TLB_V3_FULL | TLB_V3_PAGE)
+
+-#if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710)
++#ifdef CONFIG_CPU_TLB_V3
+ # define v3_possible_flags v3_tlb_flags
+ # define v3_always_flags v3_tlb_flags
+ # ifdef _TLB
+@@ -67,7 +67,7 @@
+
+ #define v4_tlb_flags (TLB_V4_U_FULL | TLB_V4_U_PAGE)
+
+-#if defined(CONFIG_CPU_ARM720T)
++#ifdef CONFIG_CPU_TLB_V4WT
+ # define v4_possible_flags v4_tlb_flags
+ # define v4_always_flags v4_tlb_flags
+ # ifdef _TLB
+@@ -84,9 +84,7 @@
+ TLB_V4_I_FULL | TLB_V4_D_FULL | \
+ TLB_V4_I_PAGE | TLB_V4_D_PAGE)
+
+-#if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \
+- defined(CONFIG_CPU_ARM926T) || defined(CONFIG_CPU_ARM1020) || \
+- defined(CONFIG_CPU_XSCALE)
++#ifdef CONFIG_CPU_TLB_V4WBI
+ # define v4wbi_possible_flags v4wbi_tlb_flags
+ # define v4wbi_always_flags v4wbi_tlb_flags
+ # ifdef _TLB
+@@ -103,7 +101,7 @@
+ TLB_V4_I_FULL | TLB_V4_D_FULL | \
+ TLB_V4_D_PAGE)
+
+-#if defined(CONFIG_CPU_SA110) || defined(CONFIG_CPU_SA1100)
++#ifdef CONFIG_CPU_TLB_V4WB
+ # define v4wb_possible_flags v4wb_tlb_flags
+ # define v4wb_always_flags v4wb_tlb_flags
+ # ifdef _TLB
+@@ -121,7 +119,7 @@
+ TLB_V6_I_PAGE | TLB_V6_D_PAGE | \
+ TLB_V6_I_ASID | TLB_V6_D_ASID)
+
+-#if defined(CONFIG_CPU_V6)
++#ifdef CONFIG_CPU_TLB_V6
+ # define v6wbi_possible_flags v6wbi_tlb_flags
+ # define v6wbi_always_flags v6wbi_tlb_flags
+ # ifdef _TLB
+Index: linux-2.6.0-test5/include/asm-cris/arch-v10/pgtable.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-cris/arch-v10/pgtable.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-cris/arch-v10/pgtable.h 2003-09-27 11:38:40.161422920 +0800
+@@ -7,11 +7,9 @@
+
+ #ifdef CONFIG_CRIS_LOW_MAP
+ #define VMALLOC_START KSEG_7
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END KSEG_8
+ #else
+ #define VMALLOC_START KSEG_D
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END KSEG_E
+ #endif
+
+Index: linux-2.6.0-test5/include/asm-cris/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-cris/cacheflush.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-cris/cacheflush.h 2003-09-27 11:38:40.162422768 +0800
+@@ -16,6 +16,13 @@
+ #define flush_icache_range(start, end) do { } while (0)
+ #define flush_icache_page(vma,pg) do { } while (0)
+ #define flush_icache_user_range(vma,pg,adr,len) do { } while (0)
++#define flush_cache_vmap(start, end) do { } while (0)
++#define flush_cache_vunmap(start, end) do { } while (0)
++
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++ memcpy(dst, src, len)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++ memcpy(dst, src, len)
+
+ void global_flush_tlb(void);
+ int change_page_attr(struct page *page, int numpages, pgprot_t prot);
+Index: linux-2.6.0-test5/include/asm-cris/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-cris/posix_types.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-cris/posix_types.h 2003-09-27 11:38:40.164422464 +0800
+@@ -14,7 +14,6 @@
+ * assume GCC is being used.
+ */
+
+-typedef unsigned short __kernel_dev_t;
+ typedef unsigned long __kernel_ino_t;
+ typedef unsigned short __kernel_mode_t;
+ typedef unsigned short __kernel_nlink_t;
+Index: linux-2.6.0-test5/include/asm-cris/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-cris/signal.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-cris/signal.h 2003-09-27 11:38:40.166422160 +0800
+@@ -68,7 +68,7 @@
+
+ /* These should not be considered constants from userland. */
+ #define SIGRTMIN 32
+-#define SIGRTMAX (_NSIG-1)
++#define SIGRTMAX _NSIG
+
+ /*
+ * SA_FLAGS values:
+Index: linux-2.6.0-test5/include/asm-generic/cpumask_arith.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-generic/cpumask_arith.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-generic/cpumask_arith.h 2003-09-27 11:38:40.168421856 +0800
+@@ -27,7 +27,12 @@
+ #define cpus_shift_right(dst, src, n) do { dst = (src) >> (n); } while (0)
+ #define cpus_shift_left(dst, src, n) do { dst = (src) << (n); } while (0)
+
+-#define any_online_cpu(map) ({ (map) ? first_cpu(map) : NR_CPUS; })
++#define any_online_cpu(map) \
++({ \
++ cpumask_t __tmp__; \
++ cpus_and(__tmp__, map, cpu_online_map); \
++ __tmp__ ? first_cpu(__tmp__) : NR_CPUS; \
++})
+
+ #define CPU_MASK_ALL (~((cpumask_t)0) >> (8*sizeof(cpumask_t) - NR_CPUS))
+ #define CPU_MASK_NONE ((cpumask_t)0)
+Index: linux-2.6.0-test5/include/asm-generic/cpumask_array.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-generic/cpumask_array.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-generic/cpumask_array.h 2003-09-27 11:38:40.169421704 +0800
+@@ -36,7 +36,13 @@
+ cpu_set(cpu, __cpu_mask); \
+ __cpu_mask; \
+ })
+-#define any_online_cpu(map) find_first_bit((map).mask, NR_CPUS)
++#define any_online_cpu(map) \
++({ \
++ cpumask_t __tmp__; \
++ cpus_and(__tmp__, map, cpu_online_map); \
++ find_first_bit(__tmp__.mask, NR_CPUS); \
++})
++
+
+ /*
+ * um, these need to be usable as static initializers
+Index: linux-2.6.0-test5/include/asm-generic/cpumask_up.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-generic/cpumask_up.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-generic/cpumask_up.h 2003-09-27 11:38:40.170421552 +0800
+@@ -6,7 +6,7 @@
+ #define cpu_set(cpu, map) do { (void)(cpu); cpus_coerce(map) = 1UL; } while (0)
+ #define cpu_clear(cpu, map) do { (void)(cpu); cpus_coerce(map) = 0UL; } while (0)
+ #define cpu_isset(cpu, map) ((void)(cpu), cpus_coerce(map) != 0UL)
+-#define cpu_test_and_set(cpu, map) ((void)(cpu), test_and_set_bit(0, (map).mask))
++#define cpu_test_and_set(cpu, map) ((void)(cpu), test_and_set_bit(0, &(map)))
+
+ #define cpus_and(dst, src1, src2) \
+ do { \
+Index: linux-2.6.0-test5/include/asm-h8300/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-h8300/cacheflush.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-h8300/cacheflush.h 2003-09-27 11:38:40.172421248 +0800
+@@ -11,7 +11,6 @@
+ */
+
+ #define flush_cache_all()
+-#define flush_cache_all()
+ #define flush_cache_mm(mm)
+ #define flush_cache_range(vma,a,b)
+ #define flush_cache_page(vma,p)
+@@ -20,6 +19,8 @@
+ #define flush_icache()
+ #define flush_icache_page(vma,page)
+ #define flush_icache_range(start,len)
++#define flush_cache_vmap(start, end)
++#define flush_cache_vunmap(start, end)
+ #define cache_push_v(vaddr,len)
+ #define cache_push(paddr,len)
+ #define cache_clear(paddr,len)
+@@ -28,4 +29,9 @@
+
+ #define flush_icache_user_range(vma,page,addr,len)
+
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++ memcpy(dst, src, len)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++ memcpy(dst, src, len)
++
+ #endif /* _ASM_H8300_CACHEFLUSH_H */
+Index: linux-2.6.0-test5/include/asm-h8300/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-h8300/posix_types.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-h8300/posix_types.h 2003-09-27 11:38:40.173421096 +0800
+@@ -7,7 +7,6 @@
+ * assume GCC is being used.
+ */
+
+-typedef unsigned short __kernel_dev_t;
+ typedef unsigned long __kernel_ino_t;
+ typedef unsigned short __kernel_mode_t;
+ typedef unsigned short __kernel_nlink_t;
+Index: linux-2.6.0-test5/include/asm-h8300/processor.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-h8300/processor.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-h8300/processor.h 2003-09-27 11:38:40.175420792 +0800
+@@ -48,7 +48,6 @@
+ /*
+ * Bus types
+ */
+-#define EISA_bus 0
+ #define MCA_bus 0
+
+ struct thread_struct {
+Index: linux-2.6.0-test5/include/asm-h8300/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-h8300/signal.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-h8300/signal.h 2003-09-27 11:38:40.177420488 +0800
+@@ -68,7 +68,7 @@
+
+ /* These should not be considered constants from userland. */
+ #define SIGRTMIN 32
+-#define SIGRTMAX (_NSIG-1)
++#define SIGRTMAX _NSIG
+
+ /*
+ * SA_FLAGS values:
+Index: linux-2.6.0-test5/include/asm-h8300/stat.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-h8300/stat.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-h8300/stat.h 2003-09-27 11:38:40.179420184 +0800
+@@ -42,8 +42,7 @@
+ * insane amounts of padding around dev_t's.
+ */
+ struct stat64 {
+- unsigned char __pad0[6];
+- unsigned short st_dev;
++ unsigned long long st_dev;
+ unsigned char __pad1[2];
+
+ #define STAT64_HAS_BROKEN_ST_INO 1
+@@ -55,8 +54,7 @@
+ unsigned long st_uid;
+ unsigned long st_gid;
+
+- unsigned char __pad2[6];
+- unsigned short st_rdev;
++ unsigned long long st_rdev;
+ unsigned char __pad3[2];
+
+ long long st_size;
+Index: linux-2.6.0-test5/include/asm-i386/atomic_kmap.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/atomic_kmap.h 2003-09-27 11:38:18.477719344 +0800
++++ linux-2.6.0-test5/include/asm-i386/atomic_kmap.h 2003-09-27 11:38:40.179420184 +0800
+@@ -0,0 +1,95 @@
++/*
++ * atomic_kmap.h: temporary virtual kernel memory mappings
++ *
++ * Copyright (C) 2003 Ingo Molnar <mingo@redhat.com>
++ */
++
++#ifndef _ASM_ATOMIC_KMAP_H
++#define _ASM_ATOMIC_KMAP_H
++
++#ifdef __KERNEL__
++
++#include <linux/config.h>
++#include <asm/tlbflush.h>
++
++#ifdef CONFIG_DEBUG_HIGHMEM
++#define HIGHMEM_DEBUG 1
++#else
++#define HIGHMEM_DEBUG 0
++#endif
++
++extern pte_t *kmap_pte;
++#define kmap_prot PAGE_KERNEL
++
++#define PKMAP_BASE (0xff000000UL)
++#define NR_SHARED_PMDS ((0xffffffff-PKMAP_BASE+1)/PMD_SIZE)
++
++static inline unsigned long __kmap_atomic_vaddr(enum km_type type)
++{
++ enum fixed_addresses idx;
++
++ idx = type + KM_TYPE_NR*smp_processor_id();
++ return __fix_to_virt(FIX_KMAP_BEGIN + idx);
++}
++
++static inline void *__kmap_atomic_noflush(struct page *page, enum km_type type)
++{
++ enum fixed_addresses idx;
++ unsigned long vaddr;
++
++ idx = type + KM_TYPE_NR*smp_processor_id();
++ vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
++ /*
++ * NOTE: entries that rely on some secondary TLB-flush
++ * effect must not be global:
++ */
++ set_pte(kmap_pte-idx, mk_pte(page, PAGE_KERNEL));
++
++ return (void*) vaddr;
++}
++
++static inline void *__kmap_atomic(struct page *page, enum km_type type)
++{
++ enum fixed_addresses idx;
++ unsigned long vaddr;
++
++ idx = type + KM_TYPE_NR*smp_processor_id();
++ vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
++#if HIGHMEM_DEBUG
++ BUG_ON(!pte_none(*(kmap_pte-idx)));
++#else
++ /*
++ * Performance optimization - do not flush if the new
++ * pte is the same as the old one:
++ */
++ if (pte_val(*(kmap_pte-idx)) == pte_val(mk_pte(page, kmap_prot)))
++ return (void *) vaddr;
++#endif
++ set_pte(kmap_pte-idx, mk_pte(page, kmap_prot));
++ __flush_tlb_one(vaddr);
++
++ return (void*) vaddr;
++}
++
++static inline void __kunmap_atomic(void *kvaddr, enum km_type type)
++{
++#if HIGHMEM_DEBUG
++ unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
++ enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
++
++ BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx));
++ /*
++ * force other mappings to Oops if they'll try to access
++ * this pte without first remap it
++ */
++ pte_clear(kmap_pte-idx);
++ __flush_tlb_one(vaddr);
++#endif
++}
++
++#define __kunmap_atomic_type(type) \
++ __kunmap_atomic((void *)__kmap_atomic_vaddr(type), (type))
++
++#endif /* __KERNEL__ */
++
++#endif /* _ASM_ATOMIC_KMAP_H */
+Index: linux-2.6.0-test5/include/asm-i386/bugs.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/bugs.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/bugs.h 2003-09-27 11:38:40.182419728 +0800
+@@ -1,11 +1,11 @@
+ /*
+ * include/asm-i386/bugs.h
+ *
+- * Copyright (C) 1994 Linus Torvalds
++ * Copyright (C) 1994 Linus Torvalds
+ *
+ * Cyrix stuff, June 1998 by:
+ * - Rafael R. Reilova (moved everything from head.S),
+- * <rreilova@ececs.uc.edu>
++ * <rreilova@ececs.uc.edu>
+ * - Channing Corn (tests & fixes),
+ * - Andrew D. Balsa (code cleanup).
+ *
+@@ -25,7 +25,20 @@
+ #include <asm/processor.h>
+ #include <asm/i387.h>
+ #include <asm/msr.h>
+-
++#ifdef CONFIG_KGDB
++/*
++ * Provied the command line "gdb" initial break
++ */
++int __init kgdb_initial_break(char * str)
++{
++ if (*str == '\0'){
++ breakpoint();
++ return 1;
++ }
++ return 0;
++}
++__setup("gdb",kgdb_initial_break);
++#endif
+ static int __init no_halt(char *s)
+ {
+ boot_cpu_data.hlt_works_ok = 0;
+@@ -140,7 +153,7 @@
+ : "ecx", "edi" );
+ /* If this fails, it means that any user program may lock the CPU hard. Too bad. */
+ if (res != 12345678) printk( "Buggy.\n" );
+- else printk( "OK.\n" );
++ else printk( "OK.\n" );
+ #endif
+ }
+
+Index: linux-2.6.0-test5/include/asm-i386/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/cacheflush.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/cacheflush.h 2003-09-27 11:38:40.183419576 +0800
+@@ -13,6 +13,13 @@
+ #define flush_icache_range(start, end) do { } while (0)
+ #define flush_icache_page(vma,pg) do { } while (0)
+ #define flush_icache_user_range(vma,pg,adr,len) do { } while (0)
++#define flush_cache_vmap(start, end) do { } while (0)
++#define flush_cache_vunmap(start, end) do { } while (0)
++
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++ memcpy(dst, src, len)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++ memcpy(dst, src, len)
+
+ void global_flush_tlb(void);
+ int change_page_attr(struct page *page, int numpages, pgprot_t prot);
+Index: linux-2.6.0-test5/include/asm-i386/checksum.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/checksum.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/checksum.h 2003-09-27 11:38:40.186419120 +0800
+@@ -25,7 +25,7 @@
+ * better 64-bit) boundary
+ */
+
+-asmlinkage unsigned int csum_partial_copy_generic( const char *src, char *dst, int len, int sum,
++asmlinkage unsigned int direct_csum_partial_copy_generic( const char *src, char *dst, int len, int sum,
+ int *src_err_ptr, int *dst_err_ptr);
+
+ /*
+@@ -39,14 +39,19 @@
+ unsigned int csum_partial_copy_nocheck ( const char *src, char *dst,
+ int len, int sum)
+ {
+- return csum_partial_copy_generic ( src, dst, len, sum, NULL, NULL);
++ /*
++ * The direct function is OK for kernel-space => kernel-space copies:
++ */
++ return direct_csum_partial_copy_generic ( src, dst, len, sum, NULL, NULL);
+ }
+
+ static __inline__
+ unsigned int csum_partial_copy_from_user ( const char *src, char *dst,
+ int len, int sum, int *err_ptr)
+ {
+- return csum_partial_copy_generic ( src, dst, len, sum, err_ptr, NULL);
++ if (copy_from_user(dst, src, len))
++ *err_ptr = -EFAULT;
++ return csum_partial(dst, len, sum);
+ }
+
+ /*
+@@ -171,11 +176,26 @@
+ * Copy and checksum to user
+ */
+ #define HAVE_CSUM_COPY_USER
+-static __inline__ unsigned int csum_and_copy_to_user(const char *src, char *dst,
++static __inline__ unsigned int direct_csum_and_copy_to_user(const char *src, char *dst,
+ int len, int sum, int *err_ptr)
+ {
+ if (access_ok(VERIFY_WRITE, dst, len))
+- return csum_partial_copy_generic(src, dst, len, sum, NULL, err_ptr);
++ return direct_csum_partial_copy_generic(src, dst, len, sum, NULL, err_ptr);
++
++ if (len)
++ *err_ptr = -EFAULT;
++
++ return -1; /* invalid checksum */
++}
++
++static __inline__ unsigned int csum_and_copy_to_user(const char *src, char *dst,
++ int len, int sum, int *err_ptr)
++{
++ if (access_ok(VERIFY_WRITE, dst, len)) {
++ if (copy_to_user(dst, src, len))
++ *err_ptr = -EFAULT;
++ return csum_partial(src, len, sum);
++ }
+
+ if (len)
+ *err_ptr = -EFAULT;
+Index: linux-2.6.0-test5/include/asm-i386/cpufeature.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/cpufeature.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/cpufeature.h 2003-09-27 11:38:40.188418816 +0800
+@@ -71,6 +71,8 @@
+
+ /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
+ #define X86_FEATURE_EST (4*32+ 7) /* Enhanced SpeedStep */
++#define X86_FEATURE_MWAIT (4*32+ 3) /* Monitor/Mwait support */
++
+
+ /* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
+ #define X86_FEATURE_XSTORE (5*32+ 2) /* on-CPU RNG present (xstore insn) */
+Index: linux-2.6.0-test5/include/asm-i386/desc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/desc.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/desc.h 2003-09-27 11:38:40.190418512 +0800
+@@ -21,6 +21,13 @@
+
+ extern struct Xgt_desc_struct idt_descr, cpu_gdt_descr[NR_CPUS];
+
++extern void trap_init_virtual_IDT(void);
++extern void trap_init_virtual_GDT(void);
++
++asmlinkage int system_call(void);
++asmlinkage void lcall7(void);
++asmlinkage void lcall27(void);
++
+ #define load_TR_desc() __asm__ __volatile__("ltr %%ax"::"a" (GDT_ENTRY_TSS*8))
+ #define load_LDT_desc() __asm__ __volatile__("lldt %%ax"::"a" (GDT_ENTRY_LDT*8))
+
+@@ -30,6 +37,7 @@
+ */
+ extern struct desc_struct default_ldt[];
+ extern void set_intr_gate(unsigned int irq, void * addr);
++extern void set_trap_gate(unsigned int n, void *addr);
+
+ #define _set_tssldt_desc(n,addr,limit,type) \
+ __asm__ __volatile__ ("movw %w3,0(%2)\n\t" \
+@@ -90,31 +98,8 @@
+ #undef C
+ }
+
+-static inline void clear_LDT(void)
+-{
+- int cpu = get_cpu();
+-
+- set_ldt_desc(cpu, &default_ldt[0], 5);
+- load_LDT_desc();
+- put_cpu();
+-}
+-
+-/*
+- * load one particular LDT into the current CPU
+- */
+-static inline void load_LDT_nolock(mm_context_t *pc, int cpu)
+-{
+- void *segments = pc->ldt;
+- int count = pc->size;
+-
+- if (likely(!count)) {
+- segments = &default_ldt[0];
+- count = 5;
+- }
+-
+- set_ldt_desc(cpu, segments, count);
+- load_LDT_desc();
+-}
++extern struct page *default_ldt_page;
++extern void load_LDT_nolock(mm_context_t *pc, int cpu);
+
+ static inline void load_LDT(mm_context_t *pc)
+ {
+@@ -123,6 +108,6 @@
+ put_cpu();
+ }
+
+-#endif /* !__ASSEMBLY__ */
+
++#endif /* !__ASSEMBLY__ */
+ #endif
+Index: linux-2.6.0-test5/include/asm-i386/fixmap.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/fixmap.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/fixmap.h 2003-09-27 11:38:40.192418208 +0800
+@@ -18,17 +18,15 @@
+ #include <asm/acpi.h>
+ #include <asm/apicdef.h>
+ #include <asm/page.h>
+-#ifdef CONFIG_HIGHMEM
+ #include <linux/threads.h>
+ #include <asm/kmap_types.h>
+-#endif
+
+ /*
+ * Here we define all the compile-time 'special' virtual
+ * addresses. The point is to have a constant address at
+ * compile time, but to set the physical address only
+- * in the boot process. We allocate these special addresses
+- * from the end of virtual memory (0xfffff000) backwards.
++ * in the boot process. We allocate these special addresses
++ * from the end of virtual memory (0xffffe000) backwards.
+ * Also this lets us do fail-safe vmalloc(), we
+ * can guarantee that these special addresses and
+ * vmalloc()-ed addresses never overlap.
+@@ -41,11 +39,20 @@
+ * TLB entries of such buffers will not be flushed across
+ * task switches.
+ */
++
++/*
++ * on UP currently we will have no trace of the fixmap mechanizm,
++ * no page table allocations, etc. This might change in the
++ * future, say framebuffers for the console driver(s) could be
++ * fix-mapped?
++ */
+ enum fixed_addresses {
+ FIX_HOLE,
+ FIX_VSYSCALL,
+ #ifdef CONFIG_X86_LOCAL_APIC
+ FIX_APIC_BASE, /* local (CPU) APIC) -- required for SMP or not */
++#else
++ FIX_VSTACK_HOLE_1,
+ #endif
+ #ifdef CONFIG_X86_IO_APIC
+ FIX_IO_APIC_BASE_0,
+@@ -57,16 +64,21 @@
+ FIX_LI_PCIA, /* Lithium PCI Bridge A */
+ FIX_LI_PCIB, /* Lithium PCI Bridge B */
+ #endif
+-#ifdef CONFIG_X86_F00F_BUG
+- FIX_F00F_IDT, /* Virtual mapping for IDT */
+-#endif
++ FIX_IDT,
++ FIX_GDT_1,
++ FIX_GDT_0,
++ FIX_TSS_3,
++ FIX_TSS_2,
++ FIX_TSS_1,
++ FIX_TSS_0,
++ FIX_ENTRY_TRAMPOLINE_1,
++ FIX_ENTRY_TRAMPOLINE_0,
+ #ifdef CONFIG_X86_CYCLONE_TIMER
+ FIX_CYCLONE_TIMER, /*cyclone timer register*/
++ FIX_VSTACK_HOLE_2,
+ #endif
+-#ifdef CONFIG_HIGHMEM
+ FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
+ FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
+-#endif
+ #ifdef CONFIG_ACPI_BOOT
+ FIX_ACPI_BEGIN,
+ FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1,
+@@ -95,12 +107,15 @@
+ __set_fixmap(idx, 0, __pgprot(0))
+
+ /*
+- * used by vmalloc.c.
++ * used by vmalloc.c and various other places.
+ *
+ * Leave one empty page between vmalloc'ed areas and
+ * the start of the fixmap.
++ *
++ * IMPORTANT: dont change FIXADDR_TOP without adjusting KM_VSTACK0
++ * and KM_VSTACK1 so that the virtual stack is 8K aligned.
+ */
+-#define FIXADDR_TOP (0xfffff000UL)
++#define FIXADDR_TOP (0xffffe000UL)
+ #define __FIXADDR_SIZE (__end_of_permanent_fixed_addresses << PAGE_SHIFT)
+ #define FIXADDR_START (FIXADDR_TOP - __FIXADDR_SIZE)
+
+Index: linux-2.6.0-test5/include/asm-i386/genapic.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/genapic.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/genapic.h 2003-09-27 11:38:40.194417904 +0800
+@@ -30,6 +30,7 @@
+ unsigned long (*check_apicid_used)(physid_mask_t bitmap, int apicid);
+ unsigned long (*check_apicid_present)(int apicid);
+ int no_balance_irq;
++ int no_ioapic_check;
+ void (*init_apic_ldr)(void);
+ physid_mask_t (*ioapic_phys_id_map)(physid_mask_t map);
+
+@@ -77,6 +78,7 @@
+ .int_dest_mode = INT_DEST_MODE, \
+ .apic_broadcast_id = APIC_BROADCAST_ID, \
+ .no_balance_irq = NO_BALANCE_IRQ, \
++ .no_ioapic_check = NO_IOAPIC_CHECK, \
+ APICFUNC(apic_id_registered), \
+ APICFUNC(target_cpus), \
+ APICFUNC(check_apicid_used), \
+Index: linux-2.6.0-test5/include/asm-i386/highmem.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/highmem.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/highmem.h 2003-09-27 11:38:40.195417752 +0800
+@@ -25,26 +25,19 @@
+ #include <linux/threads.h>
+ #include <asm/kmap_types.h>
+ #include <asm/tlbflush.h>
++#include <asm/atomic_kmap.h>
+
+ /* declarations for highmem.c */
+ extern unsigned long highstart_pfn, highend_pfn;
+
+-extern pte_t *kmap_pte;
+-extern pgprot_t kmap_prot;
+ extern pte_t *pkmap_page_table;
+-
+-extern void kmap_init(void);
++extern void kmap_init(void) __init;
+
+ /*
+ * Right now we initialize only a single pte table. It can be extended
+ * easily, subsequent pte tables have to be allocated in one physical
+ * chunk of RAM.
+ */
+-#if NR_CPUS <= 32
+-#define PKMAP_BASE (0xff800000UL)
+-#else
+-#define PKMAP_BASE (0xff600000UL)
+-#endif
+ #ifdef CONFIG_X86_PAE
+ #define LAST_PKMAP 512
+ #else
+@@ -63,6 +56,8 @@
+ void kunmap_atomic(void *kvaddr, enum km_type type);
+ struct page *kmap_atomic_to_page(void *ptr);
+
++#define flush_cache_kmaps() do { } while (0)
++
+ #endif /* __KERNEL__ */
+
+ #endif /* _ASM_HIGHMEM_H */
+Index: linux-2.6.0-test5/include/asm-i386/ist.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/ist.h 2003-09-27 11:38:18.477719344 +0800
++++ linux-2.6.0-test5/include/asm-i386/ist.h 2003-09-27 11:38:40.196417600 +0800
+@@ -0,0 +1,32 @@
++#ifndef _ASM_IST_H
++#define _ASM_IST_H
++
++/*
++ * Include file for the interface to IST BIOS
++ * Copyright 2002 Andy Grover <andrew.grover@intel.com>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2, or (at your option) any
++ * later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * General Public License for more details.
++ */
++
++
++#ifdef __KERNEL__
++
++struct ist_info {
++ unsigned long signature;
++ unsigned long command;
++ unsigned long event;
++ unsigned long perf_level;
++};
++
++extern struct ist_info ist_info;
++
++#endif /* __KERNEL__ */
++#endif /* _ASM_IST_H */
+Index: linux-2.6.0-test5/include/asm-i386/kgdb.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/kgdb.h 2003-09-27 11:38:18.477719344 +0800
++++ linux-2.6.0-test5/include/asm-i386/kgdb.h 2003-09-27 11:38:40.196417600 +0800
+@@ -0,0 +1,74 @@
++#ifndef __KGDB
++#define __KGDB
++
++/*
++ * This file should not include ANY others. This makes it usable
++ * most anywhere without the fear of include order or inclusion.
++ * Make it so!
++ *
++ * This file may be included all the time. It is only active if
++ * CONFIG_KGDB is defined, otherwise it stubs out all the macros
++ * and entry points.
++ */
++#if defined(CONFIG_KGDB) && !defined(__ASSEMBLY__)
++
++extern void breakpoint(void);
++#define INIT_KGDB_INTS kgdb_enable_ints()
++
++#ifndef BREAKPOINT
++#define BREAKPOINT asm(" int $3")
++#endif
++
++struct sk_buff;
++
++extern int kgdb_eth;
++extern unsigned kgdb_remoteip;
++extern unsigned short kgdb_listenport;
++extern unsigned short kgdb_sendport;
++extern unsigned char kgdb_remotemac[6];
++extern unsigned char kgdb_localmac[6];
++extern int kgdb_eth_need_breakpoint[];
++
++extern int kgdb_tty_hook(void);
++extern int kgdb_eth_hook(void);
++extern int gdb_net_interrupt(struct sk_buff *skb);
++
++/*
++ * GDB debug stub (or any debug stub) can point the 'linux_debug_hook'
++ * pointer to its routine and it will be entered as the first thing
++ * when a trap occurs.
++ *
++ * Return values are, at present, undefined.
++ *
++ * The debug hook routine does not necessarily return to its caller.
++ * It has the register image and thus may choose to resume execution
++ * anywhere it pleases.
++ */
++struct pt_regs;
++
++extern int kgdb_handle_exception(int trapno,
++ int signo, int err_code, struct pt_regs *regs);
++extern int in_kgdb(struct pt_regs *regs);
++
++#ifdef CONFIG_KGDB_TS
++void kgdb_tstamp(int line, char *source, int data0, int data1);
++/*
++ * This is the time stamp function. The macro adds the source info and
++ * does a cast on the data to allow most any 32-bit value.
++ */
++
++#define kgdb_ts(data0,data1) kgdb_tstamp(__LINE__,__FILE__,(int)data0,(int)data1)
++#else
++#define kgdb_ts(data0,data1)
++#endif
++#else /* CONFIG_KGDB && ! __ASSEMBLY__ ,stubs follow... */
++#ifndef BREAKPOINT
++#define BREAKPOINT
++#endif
++#define kgdb_ts(data0,data1)
++#define in_kgdb
++#define kgdb_handle_exception
++#define breakpoint
++#define INIT_KGDB_INTS
++#endif
++#endif /* __KGDB */
+Index: linux-2.6.0-test5/include/asm-i386/kgdb_local.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/kgdb_local.h 2003-09-27 11:38:18.477719344 +0800
++++ linux-2.6.0-test5/include/asm-i386/kgdb_local.h 2003-09-27 11:38:40.196417600 +0800
+@@ -0,0 +1,102 @@
++#ifndef __KGDB_LOCAL
++#define ___KGDB_LOCAL
++#include <linux/config.h>
++#include <linux/types.h>
++#include <linux/serial.h>
++#include <linux/serialP.h>
++#include <linux/spinlock.h>
++#include <asm/processor.h>
++#include <asm/msr.h>
++#include <asm/kgdb.h>
++
++#define PORT 0x3f8
++#ifdef CONFIG_KGDB_PORT
++#undef PORT
++#define PORT CONFIG_KGDB_PORT
++#endif
++#define IRQ 4
++#ifdef CONFIG_KGDB_IRQ
++#undef IRQ
++#define IRQ CONFIG_KGDB_IRQ
++#endif
++#define SB_CLOCK 1843200
++#define SB_BASE (SB_CLOCK/16)
++#define SB_BAUD9600 SB_BASE/9600
++#define SB_BAUD192 SB_BASE/19200
++#define SB_BAUD384 SB_BASE/38400
++#define SB_BAUD576 SB_BASE/57600
++#define SB_BAUD1152 SB_BASE/115200
++#ifdef CONFIG_KGDB_9600BAUD
++#define SB_BAUD SB_BAUD9600
++#endif
++#ifdef CONFIG_KGDB_19200BAUD
++#define SB_BAUD SB_BAUD192
++#endif
++#ifdef CONFIG_KGDB_38400BAUD
++#define SB_BAUD SB_BAUD384
++#endif
++#ifdef CONFIG_KGDB_57600BAUD
++#define SB_BAUD SB_BAUD576
++#endif
++#ifdef CONFIG_KGDB_115200BAUD
++#define SB_BAUD SB_BAUD1152
++#endif
++#ifndef SB_BAUD
++#define SB_BAUD SB_BAUD1152 /* Start with this if not given */
++#endif
++
++#ifndef CONFIG_X86_TSC
++#undef rdtsc
++#define rdtsc(a,b) if (a++ > 10000){a = 0; b++;}
++#undef rdtscll
++#define rdtscll(s) s++
++#endif
++
++#ifdef _raw_read_unlock /* must use a name that is "define"ed, not an inline */
++#undef spin_lock
++#undef spin_trylock
++#undef spin_unlock
++#define spin_lock _raw_spin_lock
++#define spin_trylock _raw_spin_trylock
++#define spin_unlock _raw_spin_unlock
++#else
++#endif
++#undef spin_unlock_wait
++#define spin_unlock_wait(x) do { cpu_relax(); barrier();} \
++ while(spin_is_locked(x))
++
++#define SB_IER 1
++#define SB_MCR UART_MCR_OUT2 | UART_MCR_DTR | UART_MCR_RTS
++
++#define FLAGS 0
++#define SB_STATE { \
++ magic: SSTATE_MAGIC, \
++ baud_base: SB_BASE, \
++ port: PORT, \
++ irq: IRQ, \
++ flags: FLAGS, \
++ custom_divisor:SB_BAUD}
++#define SB_INFO { \
++ magic: SERIAL_MAGIC, \
++ port: PORT,0,FLAGS, \
++ state: &state, \
++ tty: (struct tty_struct *)&state, \
++ IER: SB_IER, \
++ MCR: SB_MCR}
++extern void putDebugChar(int);
++/* RTAI support needs us to really stop/start interrupts */
++
++#define kgdb_sti() __asm__ __volatile__("sti": : :"memory")
++#define kgdb_cli() __asm__ __volatile__("cli": : :"memory")
++#define kgdb_local_save_flags(x) __asm__ __volatile__(\
++ "pushfl ; popl %0":"=g" (x): /* no input */)
++#define kgdb_local_irq_restore(x) __asm__ __volatile__(\
++ "pushl %0 ; popfl": \
++ /* no output */ :"g" (x):"memory", "cc")
++#define kgdb_local_irq_save(x) kgdb_local_save_flags(x); kgdb_cli()
++
++#ifdef CONFIG_SERIAL
++extern void shutdown_for_kgdb(struct async_struct *info);
++#endif
++#define INIT_KDEBUG putDebugChar("+");
++#endif /* __KGDB_LOCAL */
+Index: linux-2.6.0-test5/include/asm-i386/kmap_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/kmap_types.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/kmap_types.h 2003-09-27 11:38:40.198417296 +0800
+@@ -3,30 +3,36 @@
+
+ #include <linux/config.h>
+
+-#ifdef CONFIG_DEBUG_HIGHMEM
+-# define D(n) __KM_FENCE_##n ,
+-#else
+-# define D(n)
+-#endif
+-
+ enum km_type {
+-D(0) KM_BOUNCE_READ,
+-D(1) KM_SKB_SUNRPC_DATA,
+-D(2) KM_SKB_DATA_SOFTIRQ,
+-D(3) KM_USER0,
+-D(4) KM_USER1,
+-D(5) KM_BIO_SRC_IRQ,
+-D(6) KM_BIO_DST_IRQ,
+-D(7) KM_PTE0,
+-D(8) KM_PTE1,
+-D(9) KM_PTE2,
+-D(10) KM_IRQ0,
+-D(11) KM_IRQ1,
+-D(12) KM_SOFTIRQ0,
+-D(13) KM_SOFTIRQ1,
+-D(14) KM_TYPE_NR
+-};
+-
+-#undef D
++ /*
++ * IMPORTANT: don't move these 3 entries, and only add entries in
++ * pairs: the 4G/4G virtual stack must be 8K aligned on each cpu.
++ */
++ KM_BOUNCE_READ,
++ KM_VSTACK1,
++ KM_VSTACK0,
+
++ KM_LDT_PAGE15,
++ KM_LDT_PAGE0 = KM_LDT_PAGE15 + 16-1,
++ KM_USER_COPY,
++ KM_VSTACK_HOLE,
++ KM_SKB_SUNRPC_DATA,
++ KM_SKB_DATA_SOFTIRQ,
++ KM_USER0,
++ KM_USER1,
++ KM_BIO_SRC_IRQ,
++ KM_BIO_DST_IRQ,
++ KM_PTE0,
++ KM_PTE1,
++ KM_PTE2,
++ KM_IRQ0,
++ KM_IRQ1,
++ KM_SOFTIRQ0,
++ KM_SOFTIRQ1,
++ /*
++ * Add new entries in pairs:
++ * the 4G/4G virtual stack must be 8K aligned on each cpu.
++ */
++ KM_TYPE_NR
++};
+ #endif
+Index: linux-2.6.0-test5/include/asm-i386/lockmeter.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/lockmeter.h 2003-09-27 11:38:18.477719344 +0800
++++ linux-2.6.0-test5/include/asm-i386/lockmeter.h 2003-09-27 11:38:40.199417144 +0800
+@@ -0,0 +1,127 @@
++/*
++ * Copyright (C) 1999,2000 Silicon Graphics, Inc.
++ *
++ * Written by John Hawkes (hawkes@sgi.com)
++ * Based on klstat.h by Jack Steiner (steiner@sgi.com)
++ *
++ * Modified by Ray Bryant (raybry@us.ibm.com)
++ * Changes Copyright (C) 2000 IBM, Inc.
++ * Added save of index in spinlock_t to improve efficiency
++ * of "hold" time reporting for spinlocks.
++ * Added support for hold time statistics for read and write
++ * locks.
++ * Moved machine dependent code here from include/lockmeter.h.
++ *
++ */
++
++#ifndef _I386_LOCKMETER_H
++#define _I386_LOCKMETER_H
++
++#include <asm/spinlock.h>
++#include <asm/rwlock.h>
++
++#include <linux/version.h>
++
++#ifdef __KERNEL__
++extern unsigned long cpu_khz;
++#define CPU_CYCLE_FREQUENCY (cpu_khz * 1000)
++#else
++#define CPU_CYCLE_FREQUENCY 450000000
++#endif
++
++#define THIS_CPU_NUMBER smp_processor_id()
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
++#define local_irq_save(x) \
++ __asm__ __volatile__("pushfl ; popl %0 ; cli":"=g" (x): /* no input */ :"memory")
++
++#define local_irq_restore(x) \
++ __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory")
++#endif /* Linux version 2.2.x */
++
++/*
++ * macros to cache and retrieve an index value inside of a spin lock
++ * these macros assume that there are less than 65536 simultaneous
++ * (read mode) holders of a rwlock. Not normally a problem!!
++ * we also assume that the hash table has less than 65535 entries.
++ */
++/*
++ * instrumented spinlock structure -- never used to allocate storage
++ * only used in macros below to overlay a spinlock_t
++ */
++typedef struct inst_spinlock_s {
++ /* remember, Intel is little endian */
++ unsigned short lock;
++ unsigned short index;
++} inst_spinlock_t;
++#define PUT_INDEX(lock_ptr,indexv) ((inst_spinlock_t *)(lock_ptr))->index = indexv
++#define GET_INDEX(lock_ptr) ((inst_spinlock_t *)(lock_ptr))->index
++
++/*
++ * macros to cache and retrieve an index value in a read/write lock
++ * as well as the cpu where a reader busy period started
++ * we use the 2nd word (the debug word) for this, so require the
++ * debug word to be present
++ */
++/*
++ * instrumented rwlock structure -- never used to allocate storage
++ * only used in macros below to overlay a rwlock_t
++ */
++typedef struct inst_rwlock_s {
++ volatile int lock;
++ unsigned short index;
++ unsigned short cpu;
++} inst_rwlock_t;
++#define PUT_RWINDEX(rwlock_ptr,indexv) ((inst_rwlock_t *)(rwlock_ptr))->index = indexv
++#define GET_RWINDEX(rwlock_ptr) ((inst_rwlock_t *)(rwlock_ptr))->index
++#define PUT_RW_CPU(rwlock_ptr,cpuv) ((inst_rwlock_t *)(rwlock_ptr))->cpu = cpuv
++#define GET_RW_CPU(rwlock_ptr) ((inst_rwlock_t *)(rwlock_ptr))->cpu
++
++/*
++ * return the number of readers for a rwlock_t
++ */
++#define RWLOCK_READERS(rwlock_ptr) rwlock_readers(rwlock_ptr)
++
++extern inline int rwlock_readers(rwlock_t *rwlock_ptr)
++{
++ int tmp = (int) rwlock_ptr->lock;
++ /* read and write lock attempts may cause the lock value to temporarily */
++ /* be negative. Until it is >= 0 we know nothing (i. e. can't tell if */
++ /* is -1 because it was write locked and somebody tried to read lock it */
++ /* or if it is -1 because it was read locked and somebody tried to write*/
++ /* lock it. ........................................................... */
++ do {
++ tmp = (int) rwlock_ptr->lock;
++ } while (tmp < 0);
++ if (tmp == 0) return(0);
++ else return(RW_LOCK_BIAS-tmp);
++}
++
++/*
++ * return true if rwlock is write locked
++ * (note that other lock attempts can cause the lock value to be negative)
++ */
++#define RWLOCK_IS_WRITE_LOCKED(rwlock_ptr) ((rwlock_ptr)->lock <= 0)
++#define IABS(x) ((x) > 0 ? (x) : -(x))
++#define RWLOCK_IS_READ_LOCKED(rwlock_ptr) ((IABS((rwlock_ptr)->lock) % RW_LOCK_BIAS) != 0)
++
++/* this is a lot of typing just to get gcc to emit "rdtsc" */
++static inline long long get_cycles64 (void)
++{
++#ifndef CONFIG_X86_TSC
++ #error this code requires CONFIG_X86_TSC
++#else
++ union longlong_u {
++ long long intlong;
++ struct intint_s {
++ uint32_t eax;
++ uint32_t edx;
++ } intint;
++ } longlong;
++
++ rdtsc(longlong.intint.eax,longlong.intint.edx);
++ return longlong.intlong;
++#endif
++}
++
++#endif /* _I386_LOCKMETER_H */
+Index: linux-2.6.0-test5/include/asm-i386/mach-bigsmp/mach_apic.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/mach-bigsmp/mach_apic.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/mach-bigsmp/mach_apic.h 2003-09-27 11:38:40.200416992 +0800
+@@ -14,6 +14,8 @@
+ #define NO_BALANCE_IRQ (1)
+ #define esr_disable (1)
+
++#define NO_IOAPIC_CHECK (0)
++
+ static inline int apic_id_registered(void)
+ {
+ return (1);
+Index: linux-2.6.0-test5/include/asm-i386/mach-default/mach_apic.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/mach-default/mach_apic.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/mach-default/mach_apic.h 2003-09-27 11:38:40.202416688 +0800
+@@ -18,6 +18,8 @@
+ #define NO_BALANCE_IRQ (0)
+ #define esr_disable (0)
+
++#define NO_IOAPIC_CHECK (0)
++
+ #define INT_DELIVERY_MODE dest_LowestPrio
+ #define INT_DEST_MODE 1 /* logical delivery broadcast to all procs */
+
+Index: linux-2.6.0-test5/include/asm-i386/mach-generic/mach_apic.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/mach-generic/mach_apic.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/mach-generic/mach_apic.h 2003-09-27 11:38:40.203416536 +0800
+@@ -5,6 +5,7 @@
+
+ #define esr_disable (genapic->esr_disable)
+ #define NO_BALANCE_IRQ (genapic->no_balance_irq)
++#define NO_IOAPIC_CHECK (genapic->no_ioapic_check)
+ #define APIC_BROADCAST_ID (genapic->apic_broadcast_id)
+ #define INT_DELIVERY_MODE (genapic->int_delivery_mode)
+ #define INT_DEST_MODE (genapic->int_dest_mode)
+Index: linux-2.6.0-test5/include/asm-i386/mach-numaq/mach_apic.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/mach-numaq/mach_apic.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/mach-numaq/mach_apic.h 2003-09-27 11:38:40.205416232 +0800
+@@ -17,6 +17,8 @@
+ #define NO_BALANCE_IRQ (1)
+ #define esr_disable (1)
+
++#define NO_IOAPIC_CHECK (0)
++
+ #define INT_DELIVERY_MODE dest_LowestPrio
+ #define INT_DEST_MODE 0 /* physical delivery on LOCAL quad */
+
+Index: linux-2.6.0-test5/include/asm-i386/mach-summit/mach_apic.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/mach-summit/mach_apic.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/mach-summit/mach_apic.h 2003-09-27 11:38:40.206416080 +0800
+@@ -7,14 +7,13 @@
+ #define esr_disable (1)
+ #define NO_BALANCE_IRQ (0)
+
+-#define XAPIC_DEST_CPUS_MASK 0x0Fu
+-#define XAPIC_DEST_CLUSTER_MASK 0xF0u
++#define NO_IOAPIC_CHECK (1) /* Don't check I/O APIC ID for xAPIC */
+
+-static inline unsigned long xapic_phys_to_log_apicid(int phys_apic)
+-{
+- return ( (1ul << ((phys_apic) & 0x3)) |
+- ((phys_apic) & XAPIC_DEST_CLUSTER_MASK) );
+-}
++/* In clustered mode, the high nibble of APIC ID is a cluster number.
++ * The low nibble is a 4-bit bitmap. */
++#define XAPIC_DEST_CPUS_SHIFT 4
++#define XAPIC_DEST_CPUS_MASK ((1u << XAPIC_DEST_CPUS_SHIFT) - 1)
++#define XAPIC_DEST_CLUSTER_MASK (XAPIC_DEST_CPUS_MASK << XAPIC_DEST_CPUS_SHIFT)
+
+ #define APIC_DFR_VALUE (APIC_DFR_CLUSTER)
+
+@@ -40,15 +39,29 @@
+ return 1;
+ }
+
+-#define apicid_cluster(apicid) (apicid & 0xF0)
++#define apicid_cluster(apicid) ((apicid) & XAPIC_DEST_CLUSTER_MASK)
+
+ extern u8 bios_cpu_apicid[];
++extern u8 cpu_2_logical_apicid[];
+
+ static inline void init_apic_ldr(void)
+ {
+ unsigned long val, id;
+-
+- id = xapic_phys_to_log_apicid(hard_smp_processor_id());
++ int i, count;
++ u8 lid;
++ u8 my_id = (u8)hard_smp_processor_id();
++ u8 my_cluster = (u8)apicid_cluster(my_id);
++
++ /* Create logical APIC IDs by counting CPUs already in cluster. */
++ for (count = 0, i = NR_CPUS; --i >= 0; ) {
++ lid = cpu_2_logical_apicid[i];
++ if (lid != BAD_APICID && apicid_cluster(lid) == my_cluster)
++ ++count;
++ }
++ /* We only have a 4 wide bitmap in cluster mode. If a deranged
++ * BIOS puts 5 CPUs in one APIC cluster, we're hosed. */
++ BUG_ON(count >= XAPIC_DEST_CPUS_SHIFT);
++ id = my_cluster | (1UL << count);
+ apic_write_around(APIC_DFR, APIC_DFR_VALUE);
+ val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
+ val |= SET_APIC_LOGICAL_ID(id);
+@@ -77,7 +90,6 @@
+ }
+
+ /* Mapping from cpu number to logical apicid */
+-extern u8 cpu_2_logical_apicid[];
+ static inline int cpu_to_logical_apicid(int cpu)
+ {
+ if (cpu >= NR_CPUS)
+Index: linux-2.6.0-test5/include/asm-i386/mach-visws/mach_apic.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/mach-visws/mach_apic.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/mach-visws/mach_apic.h 2003-09-27 11:38:40.208415776 +0800
+@@ -8,6 +8,8 @@
+ #define no_balance_irq (0)
+ #define esr_disable (0)
+
++#define NO_IOAPIC_CHECK (0)
++
+ #define INT_DELIVERY_MODE dest_LowestPrio
+ #define INT_DEST_MODE 1 /* logical delivery broadcast to all procs */
+
+Index: linux-2.6.0-test5/include/asm-i386/mmu_context.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/mmu_context.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/mmu_context.h 2003-09-27 11:38:40.209415624 +0800
+@@ -29,6 +29,10 @@
+ {
+ int cpu = smp_processor_id();
+
++#ifdef CONFIG_X86_SWITCH_PAGETABLES
++ if (tsk->mm)
++ tsk->thread_info->user_pgd = (void *)__pa(tsk->mm->pgd);
++#endif
+ if (likely(prev != next)) {
+ /* stop flush ipis for the previous mm */
+ cpu_clear(cpu, prev->cpu_vm_mask);
+@@ -39,12 +43,14 @@
+ cpu_set(cpu, next->cpu_vm_mask);
+
+ /* Re-load page tables */
++#if !defined(CONFIG_X86_SWITCH_PAGETABLES)
+ load_cr3(next->pgd);
++#endif
+
+ /*
+ * load the LDT, if the LDT is different:
+ */
+- if (unlikely(prev->context.ldt != next->context.ldt))
++ if (unlikely(prev->context.size + next->context.size))
+ load_LDT_nolock(&next->context, cpu);
+ }
+ #ifdef CONFIG_SMP
+@@ -56,7 +62,9 @@
+ /* We were in lazy tlb mode and leave_mm disabled
+ * tlb flush IPI delivery. We must reload %cr3.
+ */
++#if !defined(CONFIG_X86_SWITCH_PAGETABLES)
+ load_cr3(next->pgd);
++#endif
+ load_LDT_nolock(&next->context, cpu);
+ }
+ }
+@@ -67,6 +75,6 @@
+ asm("movl %0,%%fs ; movl %0,%%gs": :"r" (0))
+
+ #define activate_mm(prev, next) \
+- switch_mm((prev),(next),NULL)
++ switch_mm((prev),(next),current)
+
+ #endif
+Index: linux-2.6.0-test5/include/asm-i386/mmu.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/mmu.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/mmu.h 2003-09-27 11:38:40.210415472 +0800
+@@ -8,10 +8,13 @@
+ *
+ * cpu_vm_mask is used to optimize ldt flushing.
+ */
++
++#define MAX_LDT_PAGES 16
++
+ typedef struct {
+ int size;
+ struct semaphore sem;
+- void *ldt;
++ struct page *ldt_pages[MAX_LDT_PAGES];
+ } mm_context_t;
+
+ #endif
+Index: linux-2.6.0-test5/include/asm-i386/mmzone.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/mmzone.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/mmzone.h 2003-09-27 11:38:40.212415168 +0800
+@@ -119,14 +119,32 @@
+
+ #ifdef CONFIG_X86_NUMAQ
+ #include <asm/numaq.h>
+-#elif CONFIG_NUMA /* summit or generic arch */
++#elif CONFIG_ACPI_SRAT
+ #include <asm/srat.h>
+ #elif CONFIG_X86_PC
+-#define get_memcfg_numa get_memcfg_numa_flat
+ #define get_zholes_size(n) (0)
+ #else
+ #define pfn_to_nid(pfn) (0)
+ #endif /* CONFIG_X86_NUMAQ */
+
++extern int get_memcfg_numa_flat(void );
++/*
++ * This allows any one NUMA architecture to be compiled
++ * for, and still fall back to the flat function if it
++ * fails.
++ */
++static inline void get_memcfg_numa(void)
++{
++#ifdef CONFIG_X86_NUMAQ
++ if (get_memcfg_numaq())
++ return;
++#elif CONFIG_ACPI_SRAT
++ if (get_memcfg_from_srat())
++ return;
++#endif
++
++ get_memcfg_numa_flat();
++}
++
+ #endif /* CONFIG_DISCONTIGMEM */
+ #endif /* _ASM_MMZONE_H_ */
+Index: linux-2.6.0-test5/include/asm-i386/numaq.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/numaq.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/numaq.h 2003-09-27 11:38:40.214414864 +0800
+@@ -28,9 +28,7 @@
+
+ #ifdef CONFIG_X86_NUMAQ
+
+-#define MAX_NUMNODES 16
+-extern void get_memcfg_numaq(void);
+-#define get_memcfg_numa() get_memcfg_numaq()
++extern int get_memcfg_numaq(void);
+
+ /*
+ * SYS_CFG_DATA_PRIV_ADDR, struct eachquadmem, and struct sys_cfg_data are the
+Index: linux-2.6.0-test5/include/asm-i386/numnodes.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/numnodes.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/numnodes.h 2003-09-27 11:38:40.215414712 +0800
+@@ -4,11 +4,15 @@
+ #include <linux/config.h>
+
+ #ifdef CONFIG_X86_NUMAQ
+-#include <asm/numaq.h>
+-#elif CONFIG_NUMA
+-#include <asm/srat.h>
+-#else
+-#define MAX_NUMNODES 1
++
++/* Max 16 Nodes */
++#define NODES_SHIFT 4
++
++#elif defined(CONFIG_ACPI_SRAT)
++
++/* Max 8 Nodes */
++#define NODES_SHIFT 3
++
+ #endif /* CONFIG_X86_NUMAQ */
+
+ #endif /* _ASM_MAX_NUMNODES_H */
+Index: linux-2.6.0-test5/include/asm-i386/page.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/page.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/page.h 2003-09-27 11:38:40.217414408 +0800
+@@ -1,6 +1,8 @@
+ #ifndef _I386_PAGE_H
+ #define _I386_PAGE_H
+
++#include <linux/config.h>
++
+ /* PAGE_SHIFT determines the page size */
+ #define PAGE_SHIFT 12
+ #define PAGE_SIZE (1UL << PAGE_SHIFT)
+@@ -9,11 +11,10 @@
+ #define LARGE_PAGE_MASK (~(LARGE_PAGE_SIZE-1))
+ #define LARGE_PAGE_SIZE (1UL << PMD_SHIFT)
+
+-#ifdef __KERNEL__
+-#ifndef __ASSEMBLY__
+-
+ #include <linux/config.h>
+
++#ifdef __KERNEL__
++#ifndef __ASSEMBLY__
+ #ifdef CONFIG_X86_USE_3DNOW
+
+ #include <asm/mmx.h>
+@@ -88,8 +89,19 @@
+ *
+ * If you want more physical memory than this then see the CONFIG_HIGHMEM4G
+ * and CONFIG_HIGHMEM64G options in the kernel configuration.
++ *
++ * Note: on PAE the kernel must never go below 32 MB, we use the
++ * first 8 entries of the 2-level boot pgd for PAE magic.
+ */
+
++#ifdef CONFIG_X86_4G_VM_LAYOUT
++#define __PAGE_OFFSET (0x02000000)
++#define TASK_SIZE (0xff000000)
++#else
++#define __PAGE_OFFSET (0xc0000000)
++#define TASK_SIZE (0xc0000000)
++#endif
++
+ /*
+ * This much address space is reserved for vmalloc() and iomap()
+ * as well as fixmap mappings.
+@@ -114,16 +126,10 @@
+
+ #endif /* __ASSEMBLY__ */
+
+-#ifdef __ASSEMBLY__
+-#define __PAGE_OFFSET (0xC0000000)
+-#else
+-#define __PAGE_OFFSET (0xC0000000UL)
+-#endif
+-
+-
+ #define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET)
+ #define VMALLOC_RESERVE ((unsigned long)__VMALLOC_RESERVE)
+-#define MAXMEM (-__PAGE_OFFSET-__VMALLOC_RESERVE)
++#define __MAXMEM (-__PAGE_OFFSET-__VMALLOC_RESERVE)
++#define MAXMEM ((unsigned long)(-PAGE_OFFSET-VMALLOC_RESERVE))
+ #define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)
+ #define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET))
+ #define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
+Index: linux-2.6.0-test5/include/asm-i386/pgtable.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/pgtable.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/pgtable.h 2003-09-27 11:38:40.220413952 +0800
+@@ -32,16 +32,17 @@
+ #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
+ extern unsigned long empty_zero_page[1024];
+ extern pgd_t swapper_pg_dir[1024];
+-extern kmem_cache_t *pgd_cache;
+-extern kmem_cache_t *pmd_cache;
++extern kmem_cache_t *pgd_cache, *pmd_cache, *kpmd_cache;
+ extern spinlock_t pgd_lock;
+ extern struct list_head pgd_list;
+
+ void pmd_ctor(void *, kmem_cache_t *, unsigned long);
++void kpmd_ctor(void *, kmem_cache_t *, unsigned long);
+ void pgd_ctor(void *, kmem_cache_t *, unsigned long);
+ void pgd_dtor(void *, kmem_cache_t *, unsigned long);
+ void pgtable_cache_init(void);
+ void paging_init(void);
++void setup_identity_mappings(pgd_t *pgd_base, unsigned long start, unsigned long end);
+
+ #endif /* !__ASSEMBLY__ */
+
+@@ -51,6 +52,11 @@
+ * newer 3-level PAE-mode page tables.
+ */
+ #ifndef __ASSEMBLY__
++
++extern void set_system_gate(unsigned int n, void *addr);
++extern void init_entry_mappings(void);
++extern void entry_trampoline_setup(void);
++
+ #ifdef CONFIG_X86_PAE
+ # include <asm/pgtable-3level.h>
+ #else
+@@ -63,7 +69,12 @@
+ #define PGDIR_SIZE (1UL << PGDIR_SHIFT)
+ #define PGDIR_MASK (~(PGDIR_SIZE-1))
+
+-#define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE)
++#if defined(CONFIG_X86_PAE) && defined(CONFIG_X86_4G_VM_LAYOUT)
++# define USER_PTRS_PER_PGD 4
++#else
++# define USER_PTRS_PER_PGD ((TASK_SIZE/PGDIR_SIZE) + ((TASK_SIZE % PGDIR_SIZE) + PGDIR_SIZE-1)/PGDIR_SIZE)
++#endif
++
+ #define FIRST_USER_PGD_NR 0
+
+ #define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
+@@ -85,7 +96,6 @@
+ #define VMALLOC_OFFSET (8*1024*1024)
+ #define VMALLOC_START (((unsigned long) high_memory + 2*VMALLOC_OFFSET-1) & \
+ ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #ifdef CONFIG_HIGHMEM
+ # define VMALLOC_END (PKMAP_BASE-2*PAGE_SIZE)
+ #else
+@@ -234,6 +244,7 @@
+
+ #define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
+ #define mk_pte_huge(entry) ((entry).pte_low |= _PAGE_PRESENT | _PAGE_PSE)
++#define mk_pte_phys(physpage, pgprot) pfn_pte((physpage) >> PAGE_SHIFT, pgprot)
+
+ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+ {
+Index: linux-2.6.0-test5/include/asm-i386/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/posix_types.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/posix_types.h 2003-09-27 11:38:40.222413648 +0800
+@@ -7,7 +7,6 @@
+ * assume GCC is being used.
+ */
+
+-typedef unsigned short __kernel_dev_t;
+ typedef unsigned long __kernel_ino_t;
+ typedef unsigned short __kernel_mode_t;
+ typedef unsigned short __kernel_nlink_t;
+Index: linux-2.6.0-test5/include/asm-i386/processor.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/processor.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/processor.h 2003-09-27 11:38:40.226413040 +0800
+@@ -260,11 +260,6 @@
+ * Bus types (default is ISA, but people can check others with these..)
+ * pc98 indicates PC98 systems (CBUS)
+ */
+-#ifdef CONFIG_EISA
+-extern int EISA_bus;
+-#else
+-#define EISA_bus (0)
+-#endif
+ extern int MCA_bus;
+ #ifdef CONFIG_X86_PC9800
+ #define pc98 1
+@@ -272,6 +267,22 @@
+ #define pc98 0
+ #endif
+
++static inline void __monitor(const void *eax, unsigned long ecx,
++ unsigned long edx)
++{
++ /* "monitor %eax,%ecx,%edx;" */
++ asm volatile(
++ ".byte 0x0f,0x01,0xc8;"
++ : :"a" (eax), "c" (ecx), "d"(edx));
++}
++
++static inline void __mwait(unsigned long eax, unsigned long ecx)
++{
++ /* "mwait %eax,%ecx;" */
++ asm volatile(
++ ".byte 0x0f,0x01,0xc9;"
++ : :"a" (eax), "c" (ecx));
++}
+
+ /* from system description table in BIOS. Mostly for MCA use, but
+ others may find it useful. */
+@@ -280,11 +291,6 @@
+ extern unsigned int BIOS_revision;
+ extern unsigned int mca_pentium_flag;
+
+-/*
+- * User space process size: 3GB (default).
+- */
+-#define TASK_SIZE (PAGE_OFFSET)
+-
+ /* This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+@@ -395,6 +401,7 @@
+ struct thread_struct {
+ /* cached TLS descriptors. */
+ struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
++ void *stack_page0, *stack_page1;
+ unsigned long esp0;
+ unsigned long eip;
+ unsigned long esp;
+@@ -480,6 +487,13 @@
+ */
+ extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+
++#ifdef CONFIG_X86_HIGH_ENTRY
++#define virtual_esp0(tsk) \
++ ((unsigned long)(tsk)->thread_info->virtual_stack + ((tsk)->thread.esp0 - (unsigned long)(tsk)->thread_info->real_stack))
++#else
++# define virtual_esp0(tsk) ((tsk)->thread.esp0)
++#endif
++
+ extern unsigned long thread_saved_pc(struct task_struct *tsk);
+ void show_trace(struct task_struct *task, unsigned long *stack);
+
+@@ -578,8 +592,6 @@
+ #define ARCH_HAS_PREFETCH
+ extern inline void prefetch(const void *x)
+ {
+- if (cpu_data[0].x86_vendor == X86_VENDOR_AMD)
+- return; /* Some athlons fault if the address is bad */
+ alternative_input(ASM_NOP4,
+ "prefetchnta (%1)",
+ X86_FEATURE_XMM,
+@@ -601,4 +613,6 @@
+ }
+ #define spin_lock_prefetch(x) prefetchw(x)
+
++extern void select_idle_routine(const struct cpuinfo_x86 *c);
++
+ #endif /* __ASM_I386_PROCESSOR_H */
+Index: linux-2.6.0-test5/include/asm-i386/rwlock.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/rwlock.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/rwlock.h 2003-09-27 11:38:40.228412736 +0800
+@@ -20,28 +20,52 @@
+ #define RW_LOCK_BIAS 0x01000000
+ #define RW_LOCK_BIAS_STR "0x01000000"
+
+-#define __build_read_lock_ptr(rw, helper) \
+- asm volatile(LOCK "subl $1,(%0)\n\t" \
+- "js 2f\n" \
+- "1:\n" \
+- LOCK_SECTION_START("") \
+- "2:\tcall " helper "\n\t" \
+- "jmp 1b\n" \
+- LOCK_SECTION_END \
+- ::"a" (rw) : "memory")
+-
+-#define __build_read_lock_const(rw, helper) \
+- asm volatile(LOCK "subl $1,%0\n\t" \
+- "js 2f\n" \
+- "1:\n" \
+- LOCK_SECTION_START("") \
+- "2:\tpushl %%eax\n\t" \
+- "leal %0,%%eax\n\t" \
+- "call " helper "\n\t" \
+- "popl %%eax\n\t" \
+- "jmp 1b\n" \
+- LOCK_SECTION_END \
+- :"=m" (*(volatile int *)rw) : : "memory")
++#ifdef CONFIG_SPINLINE
++
++ #define __build_read_lock_ptr(rw, helper) \
++ asm volatile(LOCK "subl $1,(%0)\n\t" \
++ "jns 1f\n\t" \
++ "call " helper "\n\t" \
++ "1:\t" \
++ ::"a" (rw) : "memory")
++
++ #define __build_read_lock_const(rw, helper) \
++ asm volatile(LOCK "subl $1,%0\n\t" \
++ "jns 1f\n\t" \
++ "pushl %%eax\n\t" \
++ "leal %0,%%eax\n\t" \
++ "call " helper "\n\t" \
++ "popl %%eax\n\t" \
++ "1:\t" \
++ :"=m" (*(volatile int *)rw) : : "memory")
++
++#else /* !CONFIG_SPINLINE */
++
++ #define __build_read_lock_ptr(rw, helper) \
++ asm volatile(LOCK "subl $1,(%0)\n\t" \
++ "js 2f\n" \
++ "1:\n" \
++ LOCK_SECTION_START("") \
++ "2:\tcall " helper "\n\t" \
++ "jmp 1b\n" \
++ LOCK_SECTION_END \
++ ::"a" (rw) : "memory")
++
++ #define __build_read_lock_const(rw, helper) \
++ asm volatile(LOCK "subl $1,%0\n\t" \
++ "js 2f\n" \
++ "1:\n" \
++ LOCK_SECTION_START("") \
++ "2:\tpushl %%eax\n\t" \
++ "leal %0,%%eax\n\t" \
++ "call " helper "\n\t" \
++ "popl %%eax\n\t" \
++ "jmp 1b\n" \
++ LOCK_SECTION_END \
++ :"=m" (*(volatile int *)rw) : : "memory")
++
++#endif /* CONFIG_SPINLINE */
++
+
+ #define __build_read_lock(rw, helper) do { \
+ if (__builtin_constant_p(rw)) \
+@@ -50,28 +74,51 @@
+ __build_read_lock_ptr(rw, helper); \
+ } while (0)
+
+-#define __build_write_lock_ptr(rw, helper) \
+- asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \
+- "jnz 2f\n" \
+- "1:\n" \
+- LOCK_SECTION_START("") \
+- "2:\tcall " helper "\n\t" \
+- "jmp 1b\n" \
+- LOCK_SECTION_END \
+- ::"a" (rw) : "memory")
+-
+-#define __build_write_lock_const(rw, helper) \
+- asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",%0\n\t" \
+- "jnz 2f\n" \
+- "1:\n" \
+- LOCK_SECTION_START("") \
+- "2:\tpushl %%eax\n\t" \
+- "leal %0,%%eax\n\t" \
+- "call " helper "\n\t" \
+- "popl %%eax\n\t" \
+- "jmp 1b\n" \
+- LOCK_SECTION_END \
+- :"=m" (*(volatile int *)rw) : : "memory")
++#ifdef CONFIG_SPINLINE
++
++ #define __build_write_lock_ptr(rw, helper) \
++ asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \
++ "jz 1f\n\t" \
++ "call " helper "\n\t" \
++ "1:\n" \
++ ::"a" (rw) : "memory")
++
++ #define __build_write_lock_const(rw, helper) \
++ asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",%0\n\t" \
++ "jz 1f\n\t" \
++ "pushl %%eax\n\t" \
++ "leal %0,%%eax\n\t" \
++ "call " helper "\n\t" \
++ "popl %%eax\n\t" \
++ "1:\n" \
++ :"=m" (*(volatile int *)rw) : : "memory")
++
++#else /* !CONFIG_SPINLINE */
++
++ #define __build_write_lock_ptr(rw, helper) \
++ asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \
++ "jnz 2f\n" \
++ "1:\n" \
++ LOCK_SECTION_START("") \
++ "2:\tcall " helper "\n\t" \
++ "jmp 1b\n" \
++ LOCK_SECTION_END \
++ ::"a" (rw) : "memory")
++
++ #define __build_write_lock_const(rw, helper) \
++ asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",%0\n\t" \
++ "jnz 2f\n" \
++ "1:\n" \
++ LOCK_SECTION_START("") \
++ "2:\tpushl %%eax\n\t" \
++ "leal %0,%%eax\n\t" \
++ "call " helper "\n\t" \
++ "popl %%eax\n\t" \
++ "jmp 1b\n" \
++ LOCK_SECTION_END \
++ :"=m" (*(volatile int *)rw) : : "memory")
++
++#endif /* CONFIG_SPINLINE */
+
+ #define __build_write_lock(rw, helper) do { \
+ if (__builtin_constant_p(rw)) \
+Index: linux-2.6.0-test5/include/asm-i386/setup.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/setup.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/setup.h 2003-09-27 11:38:40.229412584 +0800
+@@ -26,6 +26,7 @@
+ #define E820_MAP_NR (*(char*) (PARAM+E820NR))
+ #define E820_MAP ((struct e820entry *) (PARAM+E820MAP))
+ #define APM_BIOS_INFO (*(struct apm_bios_info *) (PARAM+0x40))
++#define IST_INFO (*(struct ist_info *) (PARAM+0x60))
+ #define DRIVE_INFO (*(struct drive_info_struct *) (PARAM+0x80))
+ #define SYS_DESC_TABLE (*(struct sys_desc_table_struct*)(PARAM+0xa0))
+ #define MOUNT_ROOT_RDONLY (*(unsigned short *) (PARAM+0x1F2))
+Index: linux-2.6.0-test5/include/asm-i386/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/signal.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/signal.h 2003-09-27 11:38:40.232412128 +0800
+@@ -70,7 +70,7 @@
+
+ /* These should not be considered constants from userland. */
+ #define SIGRTMIN 32
+-#define SIGRTMAX (_NSIG-1)
++#define SIGRTMAX _NSIG
+
+ /*
+ * SA_FLAGS values:
+Index: linux-2.6.0-test5/include/asm-i386/spinlock.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/spinlock.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/spinlock.h 2003-09-27 11:38:40.234411824 +0800
+@@ -43,18 +43,35 @@
+ #define spin_is_locked(x) (*(volatile signed char *)(&(x)->lock) <= 0)
+ #define spin_unlock_wait(x) do { barrier(); } while(spin_is_locked(x))
+
+-#define spin_lock_string \
+- "\n1:\t" \
+- "lock ; decb %0\n\t" \
+- "js 2f\n" \
+- LOCK_SECTION_START("") \
+- "2:\t" \
+- "rep;nop\n\t" \
+- "cmpb $0,%0\n\t" \
+- "jle 2b\n\t" \
+- "jmp 1b\n" \
+- LOCK_SECTION_END
++#ifdef CONFIG_SPINLINE
+
++ #define spin_lock_string \
++ "\n1:\t" \
++ "lock ; decb %0\n\t" \
++ "js 2f\n" \
++ "jmp 3f\n" \
++ "2:\t" \
++ "rep;nop\n\t" \
++ "cmpb $0,%0\n\t" \
++ "jle 2b\n\t" \
++ "jmp 1b\n" \
++ "3:\t"
++
++#else /* !CONFIG_SPINLINE */
++
++ #define spin_lock_string \
++ "\n1:\t" \
++ "lock ; decb %0\n\t" \
++ "js 2f\n" \
++ LOCK_SECTION_START("") \
++ "2:\t" \
++ "rep;nop\n\t" \
++ "cmpb $0,%0\n\t" \
++ "jle 2b\n\t" \
++ "jmp 1b\n" \
++ LOCK_SECTION_END
++
++#endif /* CONFIG_SPINLINE */
+ /*
+ * This works. Despite all the confusion.
+ * (except on PPro SMP or if we are using OOSTORE)
+@@ -138,6 +155,11 @@
+ */
+ typedef struct {
+ volatile unsigned int lock;
++#ifdef CONFIG_LOCKMETER
++ /* required for LOCKMETER since all bits in lock are used */
++ /* and we need this storage for CPU and lock INDEX */
++ unsigned lockmeter_magic;
++#endif
+ #ifdef CONFIG_DEBUG_SPINLOCK
+ unsigned magic;
+ #endif
+@@ -145,11 +167,19 @@
+
+ #define RWLOCK_MAGIC 0xdeaf1eed
+
++#ifdef CONFIG_LOCKMETER
++#ifdef CONFIG_DEBUG_SPINLOCK
++#define RWLOCK_MAGIC_INIT , 0, RWLOCK_MAGIC
++#else
++#define RWLOCK_MAGIC_INIT , 0
++#endif
++#else /* !CONFIG_LOCKMETER */
+ #ifdef CONFIG_DEBUG_SPINLOCK
+ #define RWLOCK_MAGIC_INIT , RWLOCK_MAGIC
+ #else
+ #define RWLOCK_MAGIC_INIT /* */
+ #endif
++#endif /* !CONFIG_LOCKMETER */
+
+ #define RW_LOCK_UNLOCKED (rwlock_t) { RW_LOCK_BIAS RWLOCK_MAGIC_INIT }
+
+@@ -196,4 +226,58 @@
+ return 0;
+ }
+
++#ifdef CONFIG_LOCKMETER
++static inline int _raw_read_trylock(rwlock_t *lock)
++{
++/* FIXME -- replace with assembler */
++ atomic_t *count = (atomic_t *)lock;
++ atomic_dec(count);
++ if (count->counter > 0)
++ return 1;
++ atomic_inc(count);
++ return 0;
++}
++#endif
++
++#if defined(CONFIG_LOCKMETER) && defined(CONFIG_HAVE_DEC_LOCK)
++extern void _metered_spin_lock (spinlock_t *lock);
++extern void _metered_spin_unlock(spinlock_t *lock);
++
++/*
++ * Matches what is in arch/i386/lib/dec_and_lock.c, except this one is
++ * "static inline" so that the spin_lock(), if actually invoked, is charged
++ * against the real caller, not against the catch-all atomic_dec_and_lock
++ */
++static inline int atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
++{
++ int counter;
++ int newcount;
++
++repeat:
++ counter = atomic_read(atomic);
++ newcount = counter-1;
++
++ if (!newcount)
++ goto slow_path;
++
++ asm volatile("lock; cmpxchgl %1,%2"
++ :"=a" (newcount)
++ :"r" (newcount), "m" (atomic->counter), "0" (counter));
++
++ /* If the above failed, "eax" will have changed */
++ if (newcount != counter)
++ goto repeat;
++ return 0;
++
++slow_path:
++ _metered_spin_lock(lock);
++ if (atomic_dec_and_test(atomic))
++ return 1;
++ _metered_spin_unlock(lock);
++ return 0;
++}
++
++#define ATOMIC_DEC_AND_LOCK
++#endif
++
+ #endif /* __ASM_SPINLOCK_H */
+Index: linux-2.6.0-test5/include/asm-i386/srat.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/srat.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/srat.h 2003-09-27 11:38:40.236411520 +0800
+@@ -27,9 +27,11 @@
+ #ifndef _ASM_SRAT_H_
+ #define _ASM_SRAT_H_
+
+-#define MAX_NUMNODES 8
+-extern void get_memcfg_from_srat(void);
++#ifndef CONFIG_ACPI_SRAT
++#error CONFIG_ACPI_SRAT not defined, and srat.h header has been included
++#endif
++
++extern int get_memcfg_from_srat(void);
+ extern unsigned long *get_zholes_size(int);
+-#define get_memcfg_numa() get_memcfg_from_srat()
+
+ #endif /* _ASM_SRAT_H_ */
+Index: linux-2.6.0-test5/include/asm-i386/string.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/string.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/string.h 2003-09-27 11:38:40.239411064 +0800
+@@ -56,6 +56,29 @@
+ return dest;
+ }
+
++/*
++ * This is a more generic variant of strncpy_count() suitable for
++ * implementing string-access routines with all sorts of return
++ * code semantics. It's used by mm/usercopy.c.
++ */
++static inline size_t strncpy_count(char * dest,const char *src,size_t count)
++{
++ __asm__ __volatile__(
++
++ "1:\tdecl %0\n\t"
++ "js 2f\n\t"
++ "lodsb\n\t"
++ "stosb\n\t"
++ "testb %%al,%%al\n\t"
++ "jne 1b\n\t"
++ "2:"
++ "incl %0"
++ : "=c" (count)
++ :"S" (src),"D" (dest),"0" (count) : "memory");
++
++ return count;
++}
++
+ #define __HAVE_ARCH_STRCAT
+ static inline char * strcat(char * dest,const char * src)
+ {
+Index: linux-2.6.0-test5/include/asm-i386/suspend.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/suspend.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/suspend.h 2003-09-27 11:38:40.241410760 +0800
+@@ -6,11 +6,12 @@
+ #include <asm/desc.h>
+ #include <asm/i387.h>
+
+-static inline void
++static inline int
+ arch_prepare_suspend(void)
+ {
+ if (!cpu_has_pse)
+- panic("pse required");
++ return -EPERM;
++ return 0;
+ }
+
+ /* image of the saved processor state */
+@@ -38,8 +39,6 @@
+ extern void save_processor_state(void);
+ extern void restore_processor_state(void);
+
+-extern int do_magic(int resume);
+-
+ #ifdef CONFIG_ACPI_SLEEP
+ extern unsigned long saved_eip;
+ extern unsigned long saved_esp;
+Index: linux-2.6.0-test5/include/asm-i386/thread_info.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/thread_info.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/thread_info.h 2003-09-27 11:38:40.243410456 +0800
+@@ -33,23 +33,12 @@
+ 0-0xBFFFFFFF for user-thead
+ 0-0xFFFFFFFF for kernel-thread
+ */
+- struct restart_block restart_block;
++ void *real_stack, *virtual_stack, *user_pgd;
+
++ struct restart_block restart_block;
+ __u8 supervisor_stack[0];
+ };
+
+-#else /* !__ASSEMBLY__ */
+-
+-/* offsets into the thread_info struct for assembly code access */
+-#define TI_TASK 0x00000000
+-#define TI_EXEC_DOMAIN 0x00000004
+-#define TI_FLAGS 0x00000008
+-#define TI_STATUS 0x0000000C
+-#define TI_CPU 0x00000010
+-#define TI_PRE_COUNT 0x00000014
+-#define TI_ADDR_LIMIT 0x00000018
+-#define TI_RESTART_BLOCK 0x000001C
+-
+ #endif
+
+ #define PREEMPT_ACTIVE 0x4000000
+@@ -61,7 +50,7 @@
+ */
+ #ifndef __ASSEMBLY__
+
+-#define INIT_THREAD_INFO(tsk) \
++#define INIT_THREAD_INFO(tsk, thread_info) \
+ { \
+ .task = &tsk, \
+ .exec_domain = &default_exec_domain, \
+@@ -72,6 +61,7 @@
+ .restart_block = { \
+ .fn = do_no_restart_syscall, \
+ }, \
++ .real_stack = &thread_info, \
+ }
+
+ #define init_thread_info (init_thread_union.thread_info)
+@@ -113,6 +103,7 @@
+ #define TIF_NEED_RESCHED 3 /* rescheduling necessary */
+ #define TIF_SINGLESTEP 4 /* restore singlestep on return to user mode */
+ #define TIF_IRET 5 /* return with iret */
++#define TIF_DB7 6 /* has debug registers */
+ #define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */
+
+ #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
+@@ -121,6 +112,7 @@
+ #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
+ #define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
+ #define _TIF_IRET (1<<TIF_IRET)
++#define _TIF_DB7 (1<<TIF_DB7)
+ #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
+
+ #define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */
+Index: linux-2.6.0-test5/include/asm-i386/timer.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/timer.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/timer.h 2003-09-27 11:38:40.244410304 +0800
+@@ -38,8 +38,10 @@
+ extern struct timer_opts timer_cyclone;
+ #endif
+
++extern unsigned long calibrate_tsc(void);
+ #ifdef CONFIG_HPET_TIMER
+ extern struct timer_opts timer_hpet;
++extern unsigned long calibrate_tsc_hpet(unsigned long *tsc_hpet_quotient_ptr);
+ #endif
+
+ #endif
+Index: linux-2.6.0-test5/include/asm-i386/tlbflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/tlbflush.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/tlbflush.h 2003-09-27 11:38:40.246410000 +0800
+@@ -85,22 +85,28 @@
+
+ static inline void flush_tlb_mm(struct mm_struct *mm)
+ {
++#ifndef CONFIG_X86_SWITCH_PAGETABLES
+ if (mm == current->active_mm)
+ __flush_tlb();
++#endif
+ }
+
+ static inline void flush_tlb_page(struct vm_area_struct *vma,
+ unsigned long addr)
+ {
++#ifndef CONFIG_X86_SWITCH_PAGETABLES
+ if (vma->vm_mm == current->active_mm)
+ __flush_tlb_one(addr);
++#endif
+ }
+
+ static inline void flush_tlb_range(struct vm_area_struct *vma,
+ unsigned long start, unsigned long end)
+ {
++#ifndef CONFIG_X86_SWITCH_PAGETABLES
+ if (vma->vm_mm == current->active_mm)
+ __flush_tlb();
++#endif
+ }
+
+ #else
+@@ -111,11 +117,10 @@
+ __flush_tlb()
+
+ extern void flush_tlb_all(void);
+-extern void flush_tlb_current_task(void);
+ extern void flush_tlb_mm(struct mm_struct *);
+ extern void flush_tlb_page(struct vm_area_struct *, unsigned long);
+
+-#define flush_tlb() flush_tlb_current_task()
++#define flush_tlb() flush_tlb_all()
+
+ static inline void flush_tlb_range(struct vm_area_struct * vma, unsigned long start, unsigned long end)
+ {
+Index: linux-2.6.0-test5/include/asm-i386/uaccess.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/uaccess.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/uaccess.h 2003-09-27 11:38:40.251409240 +0800
+@@ -26,7 +26,7 @@
+
+
+ #define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFFUL)
+-#define USER_DS MAKE_MM_SEG(PAGE_OFFSET)
++#define USER_DS MAKE_MM_SEG(TASK_SIZE)
+
+ #define get_ds() (KERNEL_DS)
+ #define get_fs() (current_thread_info()->addr_limit)
+@@ -80,7 +80,7 @@
+ * checks that the pointer is in the user space range - after calling
+ * this function, memory access functions may still return -EFAULT.
+ */
+-#define access_ok(type,addr,size) (__range_ok(addr,size) == 0)
++#define access_ok(type,addr,size) (likely(__range_ok(addr,size) == 0))
+
+ /**
+ * verify_area: - Obsolete, use access_ok()
+@@ -149,6 +149,45 @@
+ :"=a" (ret),"=d" (x) \
+ :"0" (ptr))
+
++extern int get_user_size(unsigned int size, void *val, const void *ptr);
++extern int put_user_size(unsigned int size, const void *val, void *ptr);
++extern int zero_user_size(unsigned int size, void *ptr);
++extern int copy_str_fromuser_size(unsigned int size, void *val, const void *ptr);
++extern int strlen_fromuser_size(unsigned int size, const void *ptr);
++
++
++# define indirect_get_user(x,ptr) \
++({ int __ret_gu,__val_gu; \
++ __typeof__(ptr) __ptr_gu = (ptr); \
++ __ret_gu = get_user_size(sizeof(*__ptr_gu), &__val_gu,__ptr_gu) ? -EFAULT : 0;\
++ (x) = (__typeof__(*__ptr_gu))__val_gu; \
++ __ret_gu; \
++})
++#define indirect_put_user(x,ptr) \
++({ \
++ __typeof__(*(ptr)) *__ptr_pu = (ptr), __x_pu = (x); \
++ put_user_size(sizeof(*__ptr_pu), &__x_pu, __ptr_pu) ? -EFAULT : 0; \
++})
++#define __indirect_put_user indirect_put_user
++#define __indirect_get_user indirect_get_user
++
++#define indirect_copy_from_user(to,from,n) get_user_size(n,to,from)
++#define indirect_copy_to_user(to,from,n) put_user_size(n,from,to)
++
++#define __indirect_copy_from_user indirect_copy_from_user
++#define __indirect_copy_to_user indirect_copy_to_user
++
++#define indirect_strncpy_from_user(dst, src, count) \
++ copy_str_fromuser_size(count, dst, src)
++
++extern int strlen_fromuser_size(unsigned int size, const void *ptr);
++#define indirect_strnlen_user(str, n) strlen_fromuser_size(n, str)
++#define indirect_strlen_user(str) indirect_strnlen_user(str, ~0UL >> 1)
++
++extern int zero_user_size(unsigned int size, void *ptr);
++
++#define indirect_clear_user(mem, len) zero_user_size(len, mem)
++#define __indirect_clear_user clear_user
+
+ /* Careful: we have to cast the result to the type of the pointer for sign reasons */
+ /**
+@@ -168,7 +207,7 @@
+ * Returns zero on success, or -EFAULT on error.
+ * On error, the variable @x is set to zero.
+ */
+-#define get_user(x,ptr) \
++#define direct_get_user(x,ptr) \
+ ({ int __ret_gu,__val_gu; \
+ switch(sizeof (*(ptr))) { \
+ case 1: __get_user_x(1,__ret_gu,__val_gu,ptr); break; \
+@@ -198,7 +237,7 @@
+ *
+ * Returns zero on success, or -EFAULT on error.
+ */
+-#define put_user(x,ptr) \
++#define direct_put_user(x,ptr) \
+ __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+
+
+@@ -222,7 +261,7 @@
+ * Returns zero on success, or -EFAULT on error.
+ * On error, the variable @x is set to zero.
+ */
+-#define __get_user(x,ptr) \
++#define __direct_get_user(x,ptr) \
+ __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
+
+
+@@ -245,7 +284,7 @@
+ *
+ * Returns zero on success, or -EFAULT on error.
+ */
+-#define __put_user(x,ptr) \
++#define __direct_put_user(x,ptr) \
+ __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+
+ #define __put_user_nocheck(x,ptr,size) \
+@@ -396,7 +435,7 @@
+ * On success, this will be zero.
+ */
+ static inline unsigned long
+-__copy_to_user(void __user *to, const void *from, unsigned long n)
++__direct_copy_to_user(void __user *to, const void *from, unsigned long n)
+ {
+ if (__builtin_constant_p(n)) {
+ unsigned long ret;
+@@ -434,7 +473,7 @@
+ * data to the requested size using zero bytes.
+ */
+ static inline unsigned long
+-__copy_from_user(void *to, const void __user *from, unsigned long n)
++__direct_copy_from_user(void *to, const void __user *from, unsigned long n)
+ {
+ if (__builtin_constant_p(n)) {
+ unsigned long ret;
+@@ -468,11 +507,11 @@
+ * On success, this will be zero.
+ */
+ static inline unsigned long
+-copy_to_user(void __user *to, const void *from, unsigned long n)
++direct_copy_to_user(void __user *to, const void *from, unsigned long n)
+ {
+ might_sleep();
+ if (access_ok(VERIFY_WRITE, to, n))
+- n = __copy_to_user(to, from, n);
++ n = __direct_copy_to_user(to, from, n);
+ return n;
+ }
+
+@@ -493,11 +532,11 @@
+ * data to the requested size using zero bytes.
+ */
+ static inline unsigned long
+-copy_from_user(void *to, const void __user *from, unsigned long n)
++direct_copy_from_user(void *to, const void __user *from, unsigned long n)
+ {
+ might_sleep();
+ if (access_ok(VERIFY_READ, from, n))
+- n = __copy_from_user(to, from, n);
++ n = __direct_copy_from_user(to, from, n);
+ else
+ memset(to, 0, n);
+ return n;
+@@ -520,10 +559,68 @@
+ * If there is a limit on the length of a valid string, you may wish to
+ * consider using strnlen_user() instead.
+ */
+-#define strlen_user(str) strnlen_user(str, ~0UL >> 1)
+
+-long strnlen_user(const char __user *str, long n);
+-unsigned long clear_user(void __user *mem, unsigned long len);
+-unsigned long __clear_user(void __user *mem, unsigned long len);
++long direct_strncpy_from_user(char *dst, const char *src, long count);
++long __direct_strncpy_from_user(char *dst, const char *src, long count);
++#define direct_strlen_user(str) direct_strnlen_user(str, ~0UL >> 1)
++long direct_strnlen_user(const char *str, long n);
++unsigned long direct_clear_user(void *mem, unsigned long len);
++unsigned long __direct_clear_user(void *mem, unsigned long len);
++
++extern int indirect_uaccess;
++
++#ifdef CONFIG_X86_UACCESS_INDIRECT
++
++/*
++ * Return code and zeroing semantics:
++
++ __clear_user 0 <-> bytes not done
++ clear_user 0 <-> bytes not done
++ __copy_to_user 0 <-> bytes not done
++ copy_to_user 0 <-> bytes not done
++ __copy_from_user 0 <-> bytes not done, zero rest
++ copy_from_user 0 <-> bytes not done, zero rest
++ __get_user 0 <-> -EFAULT
++ get_user 0 <-> -EFAULT
++ __put_user 0 <-> -EFAULT
++ put_user 0 <-> -EFAULT
++ strlen_user strlen + 1 <-> 0
++ strnlen_user strlen + 1 (or n+1) <-> 0
++ strncpy_from_user strlen (or n) <-> -EFAULT
++
++ */
++
++#define __clear_user(mem,len) __indirect_clear_user(mem,len)
++#define clear_user(mem,len) indirect_clear_user(mem,len)
++#define __copy_to_user(to,from,n) __indirect_copy_to_user(to,from,n)
++#define copy_to_user(to,from,n) indirect_copy_to_user(to,from,n)
++#define __copy_from_user(to,from,n) __indirect_copy_from_user(to,from,n)
++#define copy_from_user(to,from,n) indirect_copy_from_user(to,from,n)
++#define __get_user(val,ptr) __indirect_get_user(val,ptr)
++#define get_user(val,ptr) indirect_get_user(val,ptr)
++#define __put_user(val,ptr) __indirect_put_user(val,ptr)
++#define put_user(val,ptr) indirect_put_user(val,ptr)
++#define strlen_user(str) indirect_strlen_user(str)
++#define strnlen_user(src,count) indirect_strnlen_user(src,count)
++#define strncpy_from_user(dst,src,count) \
++ indirect_strncpy_from_user(dst,src,count)
++
++#else
++
++#define __clear_user __direct_clear_user
++#define clear_user direct_clear_user
++#define __copy_to_user __direct_copy_to_user
++#define copy_to_user direct_copy_to_user
++#define __copy_from_user __direct_copy_from_user
++#define copy_from_user direct_copy_from_user
++#define __get_user __direct_get_user
++#define get_user direct_get_user
++#define __put_user __direct_put_user
++#define put_user direct_put_user
++#define strlen_user direct_strlen_user
++#define strnlen_user direct_strnlen_user
++#define strncpy_from_user direct_strncpy_from_user
++
++#endif /* CONFIG_X86_UACCESS_INDIRECT */
+
+ #endif /* __i386_UACCESS_H */
+Index: linux-2.6.0-test5/include/asm-ia64/acpi.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/acpi.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/acpi.h 2003-09-27 11:38:40.253408936 +0800
+@@ -30,6 +30,8 @@
+
+ #ifdef __KERNEL__
+
++#include <asm/system.h>
++
+ #define COMPILER_DEPENDENT_INT64 long
+ #define COMPILER_DEPENDENT_UINT64 unsigned long
+
+@@ -54,47 +56,35 @@
+ #define ACPI_ENABLE_IRQS() local_irq_enable()
+ #define ACPI_FLUSH_CPU_CACHE()
+
+-#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \
+- do { \
+- __asm__ volatile ("1: ld4 r29=[%1]\n" \
+- ";;\n" \
+- "mov ar.ccv=r29\n" \
+- "mov r2=r29\n" \
+- "shr.u r30=r29,1\n" \
+- "and r29=-4,r29\n" \
+- ";;\n" \
+- "add r29=2,r29\n" \
+- "and r30=1,r30\n" \
+- ";;\n" \
+- "add r29=r29,r30\n" \
+- ";;\n" \
+- "cmpxchg4.acq r30=[%1],r29,ar.ccv\n" \
+- ";;\n" \
+- "cmp.eq p6,p7=r2,r30\n" \
+- "(p7) br.dpnt.few 1b\n" \
+- "cmp.gt p8,p9=3,r29\n" \
+- ";;\n" \
+- "(p8) mov %0=-1\n" \
+- "(p9) mov %0=r0\n" \
+- :"=r"(Acq):"r"(GLptr):"r2","r29","r30","memory"); \
+- } while (0)
+-
+-#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \
+- do { \
+- __asm__ volatile ("1: ld4 r29=[%1]\n" \
+- ";;\n" \
+- "mov ar.ccv=r29\n" \
+- "mov r2=r29\n" \
+- "and r29=-4,r29\n" \
+- ";;\n" \
+- "cmpxchg4.acq r30=[%1],r29,ar.ccv\n" \
+- ";;\n" \
+- "cmp.eq p6,p7=r2,r30\n" \
+- "(p7) br.dpnt.few 1b\n" \
+- "and %0=1,r2\n" \
+- ";;\n" \
+- :"=r"(Acq):"r"(GLptr):"r2","r29","r30","memory"); \
+- } while (0)
++static inline int
++ia64_acpi_acquire_global_lock (unsigned int *lock)
++{
++ unsigned int old, new, val;
++ do {
++ old = *lock;
++ new = (((old & ~0x3) + 2) + ((old >> 1) & 0x1));
++ val = ia64_cmpxchg4_acq(lock, new, old);
++ } while (unlikely (val != old));
++ return (new < 3) ? -1 : 0;
++}
++
++static inline int
++ia64_acpi_release_global_lock (unsigned int *lock)
++{
++ unsigned int old, new, val;
++ do {
++ old = *lock;
++ new = old & ~0x3;
++ val = ia64_cmpxchg4_acq(lock, new, old);
++ } while (unlikely (val != old));
++ return old & 0x1;
++}
++
++#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \
++ ((Acq) = ia64_acpi_acquire_global_lock((unsigned int *) GLptr))
++
++#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \
++ ((Acq) = ia64_acpi_release_global_lock((unsigned int *) GLptr))
+
+ const char *acpi_get_sysname (void);
+ int acpi_request_vector (u32 int_type);
+@@ -109,7 +99,7 @@
+ /* Proximity bitmap length; _PXM is at most 255 (8 bit)*/
+ #define MAX_PXM_DOMAINS (256)
+ extern int __initdata pxm_to_nid_map[MAX_PXM_DOMAINS];
+-extern int __initdata nid_to_pxm_map[NR_NODES];
++extern int __initdata nid_to_pxm_map[MAX_NUMNODES];
+ #endif
+
+ #endif /*__KERNEL__*/
+Index: linux-2.6.0-test5/include/asm-ia64/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/cacheflush.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/cacheflush.h 2003-09-27 11:38:40.254408784 +0800
+@@ -21,6 +21,8 @@
+ #define flush_cache_range(vma, start, end) do { } while (0)
+ #define flush_cache_page(vma, vmaddr) do { } while (0)
+ #define flush_icache_page(vma,page) do { } while (0)
++#define flush_cache_vmap(start, end) do { } while (0)
++#define flush_cache_vunmap(start, end) do { } while (0)
+
+ #define flush_dcache_page(page) \
+ do { \
+@@ -35,4 +37,11 @@
+ flush_icache_range(_addr, _addr + (len)); \
+ } while (0)
+
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++do { memcpy(dst, src, len); \
++ flush_icache_user_range(vma, page, vaddr, len); \
++} while (0)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++ memcpy(dst, src, len)
++
+ #endif /* _ASM_IA64_CACHEFLUSH_H */
+Index: linux-2.6.0-test5/include/asm-ia64/hw_irq.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/hw_irq.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/hw_irq.h 2003-09-27 11:38:40.257408328 +0800
+@@ -9,6 +9,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/sched.h>
+ #include <linux/types.h>
++#include <linux/profile.h>
+
+ #include <asm/machvec.h>
+ #include <asm/ptrace.h>
+Index: linux-2.6.0-test5/include/asm-ia64/intel_intrin.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/intel_intrin.h 2003-09-27 11:38:18.478719192 +0800
++++ linux-2.6.0-test5/include/asm-ia64/intel_intrin.h 2003-09-27 11:38:40.258408176 +0800
+@@ -0,0 +1,254 @@
++#ifndef _ASM_IA64_INTEL_INTRIN_H
++#define _ASM_IA64_INTEL_INTRIN_H
++/*
++ * Intel Compiler Intrinsics
++ *
++ * Copyright (C) 2002,2003 Jun Nakajima <jun.nakajima@intel.com>
++ * Copyright (C) 2002,2003 Suresh Siddha <suresh.b.siddha@intel.com>
++ *
++ */
++#include <asm/types.h>
++
++void __lfetch(int lfhint, void *y);
++void __lfetch_excl(int lfhint, void *y);
++void __lfetch_fault(int lfhint, void *y);
++void __lfetch_fault_excl(int lfhint, void *y);
++
++/* In the following, whichFloatReg should be an integer from 0-127 */
++void __ldfs(const int whichFloatReg, void *src);
++void __ldfd(const int whichFloatReg, void *src);
++void __ldfe(const int whichFloatReg, void *src);
++void __ldf8(const int whichFloatReg, void *src);
++void __ldf_fill(const int whichFloatReg, void *src);
++void __stfs(void *dst, const int whichFloatReg);
++void __stfd(void *dst, const int whichFloatReg);
++void __stfe(void *dst, const int whichFloatReg);
++void __stf8(void *dst, const int whichFloatReg);
++void __stf_spill(void *dst, const int whichFloatReg);
++
++void __st1_rel(void *dst, const __s8 value);
++void __st2_rel(void *dst, const __s16 value);
++void __st4_rel(void *dst, const __s32 value);
++void __st8_rel(void *dst, const __s64 value);
++__u8 __ld1_acq(void *src);
++__u16 __ld2_acq(void *src);
++__u32 __ld4_acq(void *src);
++__u64 __ld8_acq(void *src);
++
++__u64 __fetchadd4_acq(__u32 *addend, const int increment);
++__u64 __fetchadd4_rel(__u32 *addend, const int increment);
++__u64 __fetchadd8_acq(__u64 *addend, const int increment);
++__u64 __fetchadd8_rel(__u64 *addend, const int increment);
++
++__u64 __getf_exp(double d);
++
++/* OS Related Itanium(R) Intrinsics */
++
++/* The names to use for whichReg and whichIndReg below come from
++ the include file asm/ia64regs.h */
++
++__u64 __getIndReg(const int whichIndReg, __s64 index);
++__u64 __getReg(const int whichReg);
++
++void __setIndReg(const int whichIndReg, __s64 index, __u64 value);
++void __setReg(const int whichReg, __u64 value);
++
++void __mf(void);
++void __mfa(void);
++void __synci(void);
++void __itcd(__s64 pa);
++void __itci(__s64 pa);
++void __itrd(__s64 whichTransReg, __s64 pa);
++void __itri(__s64 whichTransReg, __s64 pa);
++void __ptce(__s64 va);
++void __ptcl(__s64 va, __s64 pagesz);
++void __ptcg(__s64 va, __s64 pagesz);
++void __ptcga(__s64 va, __s64 pagesz);
++void __ptri(__s64 va, __s64 pagesz);
++void __ptrd(__s64 va, __s64 pagesz);
++void __invala (void);
++void __invala_gr(const int whichGeneralReg /* 0-127 */ );
++void __invala_fr(const int whichFloatReg /* 0-127 */ );
++void __nop(const int);
++void __fc(__u64 *addr);
++void __sum(int mask);
++void __rum(int mask);
++void __ssm(int mask);
++void __rsm(int mask);
++__u64 __thash(__s64);
++__u64 __ttag(__s64);
++__s64 __tpa(__s64);
++
++/* Intrinsics for implementing get/put_user macros */
++void __st_user(const char *tableName, __u64 addr, char size, char relocType, __u64 val);
++void __ld_user(const char *tableName, __u64 addr, char size, char relocType);
++
++/* This intrinsic does not generate code, it creates a barrier across which
++ * the compiler will not schedule data access instructions.
++ */
++void __memory_barrier(void);
++
++void __isrlz(void);
++void __dsrlz(void);
++
++__u64 _m64_mux1(__u64 a, const int n);
++__u64 __thash(__u64);
++
++/* Lock and Atomic Operation Related Intrinsics */
++__u64 _InterlockedExchange8(volatile __u8 *trgt, __u8 value);
++__u64 _InterlockedExchange16(volatile __u16 *trgt, __u16 value);
++__s64 _InterlockedExchange(volatile __u32 *trgt, __u32 value);
++__s64 _InterlockedExchange64(volatile __u64 *trgt, __u64 value);
++
++__u64 _InterlockedCompareExchange8_rel(volatile __u8 *dest, __u64 xchg, __u64 comp);
++__u64 _InterlockedCompareExchange8_acq(volatile __u8 *dest, __u64 xchg, __u64 comp);
++__u64 _InterlockedCompareExchange16_rel(volatile __u16 *dest, __u64 xchg, __u64 comp);
++__u64 _InterlockedCompareExchange16_acq(volatile __u16 *dest, __u64 xchg, __u64 comp);
++__u64 _InterlockedCompareExchange_rel(volatile __u32 *dest, __u64 xchg, __u64 comp);
++__u64 _InterlockedCompareExchange_acq(volatile __u32 *dest, __u64 xchg, __u64 comp);
++__u64 _InterlockedCompareExchange64_rel(volatile __u64 *dest, __u64 xchg, __u64 comp);
++__u64 _InterlockedCompareExchange64_acq(volatile __u64 *dest, __u64 xchg, __u64 comp);
++
++__s64 _m64_dep_mi(const int v, __s64 s, const int p, const int len);
++__s64 _m64_shrp(__s64 a, __s64 b, const int count);
++__s64 _m64_popcnt(__s64 a);
++
++#define ia64_barrier() __memory_barrier()
++
++#define ia64_stop() /* Nothing: As of now stop bit is generated for each
++ * intrinsic
++ */
++
++#define ia64_getreg __getReg
++#define ia64_setreg __setReg
++
++#define ia64_hint(x)
++
++#define ia64_mux1_brcst 0
++#define ia64_mux1_mix 8
++#define ia64_mux1_shuf 9
++#define ia64_mux1_alt 10
++#define ia64_mux1_rev 11
++
++#define ia64_mux1 _m64_mux1
++#define ia64_popcnt _m64_popcnt
++#define ia64_getf_exp __getf_exp
++#define ia64_shrp _m64_shrp
++
++#define ia64_tpa __tpa
++#define ia64_invala __invala
++#define ia64_invala_gr __invala_gr
++#define ia64_invala_fr __invala_fr
++#define ia64_nop __nop
++#define ia64_sum __sum
++#define ia64_ssm __ssm
++#define ia64_rum __rum
++#define ia64_rsm __rsm
++#define ia64_fc __fc
++
++#define ia64_ldfs __ldfs
++#define ia64_ldfd __ldfd
++#define ia64_ldfe __ldfe
++#define ia64_ldf8 __ldf8
++#define ia64_ldf_fill __ldf_fill
++
++#define ia64_stfs __stfs
++#define ia64_stfd __stfd
++#define ia64_stfe __stfe
++#define ia64_stf8 __stf8
++#define ia64_stf_spill __stf_spill
++
++#define ia64_mf __mf
++#define ia64_mfa __mfa
++
++#define ia64_fetchadd4_acq __fetchadd4_acq
++#define ia64_fetchadd4_rel __fetchadd4_rel
++#define ia64_fetchadd8_acq __fetchadd8_acq
++#define ia64_fetchadd8_rel __fetchadd8_rel
++
++#define ia64_xchg1 _InterlockedExchange8
++#define ia64_xchg2 _InterlockedExchange16
++#define ia64_xchg4 _InterlockedExchange
++#define ia64_xchg8 _InterlockedExchange64
++
++#define ia64_cmpxchg1_rel _InterlockedCompareExchange8_rel
++#define ia64_cmpxchg1_acq _InterlockedCompareExchange8_acq
++#define ia64_cmpxchg2_rel _InterlockedCompareExchange16_rel
++#define ia64_cmpxchg2_acq _InterlockedCompareExchange16_acq
++#define ia64_cmpxchg4_rel _InterlockedCompareExchange_rel
++#define ia64_cmpxchg4_acq _InterlockedCompareExchange_acq
++#define ia64_cmpxchg8_rel _InterlockedCompareExchange64_rel
++#define ia64_cmpxchg8_acq _InterlockedCompareExchange64_acq
++
++#define __ia64_set_dbr(index, val) \
++ __setIndReg(_IA64_REG_INDR_DBR, index, val)
++#define ia64_set_ibr(index, val) \
++ __setIndReg(_IA64_REG_INDR_IBR, index, val)
++#define ia64_set_pkr(index, val) \
++ __setIndReg(_IA64_REG_INDR_PKR, index, val)
++#define ia64_set_pmc(index, val) \
++ __setIndReg(_IA64_REG_INDR_PMC, index, val)
++#define ia64_set_pmd(index, val) \
++ __setIndReg(_IA64_REG_INDR_PMD, index, val)
++#define ia64_set_rr(index, val) \
++ __setIndReg(_IA64_REG_INDR_RR, index, val)
++
++#define ia64_get_cpuid(index) __getIndReg(_IA64_REG_INDR_CPUID, index)
++#define __ia64_get_dbr(index) __getIndReg(_IA64_REG_INDR_DBR, index)
++#define ia64_get_ibr(index) __getIndReg(_IA64_REG_INDR_IBR, index)
++#define ia64_get_pkr(index) __getIndReg(_IA64_REG_INDR_PKR, index)
++#define ia64_get_pmc(index) __getIndReg(_IA64_REG_INDR_PMC, index)
++#define ia64_get_pmd(index) __getIndReg(_IA64_REG_INDR_PMD, index)
++#define ia64_get_rr(index) __getIndReg(_IA64_REG_INDR_RR, index)
++
++#define ia64_srlz_d __dsrlz
++#define ia64_srlz_i __isrlz
++
++#define ia64_st1_rel __st1_rel
++#define ia64_st2_rel __st2_rel
++#define ia64_st4_rel __st4_rel
++#define ia64_st8_rel __st8_rel
++
++#define ia64_ld1_acq __ld1_acq
++#define ia64_ld2_acq __ld2_acq
++#define ia64_ld4_acq __ld4_acq
++#define ia64_ld8_acq __ld8_acq
++
++#define ia64_sync_i __synci
++#define ia64_thash __thash
++#define ia64_ttag __ttag
++#define ia64_itcd __itcd
++#define ia64_itci __itci
++#define ia64_itrd __itrd
++#define ia64_itri __itri
++#define ia64_ptce __ptce
++#define ia64_ptcl __ptcl
++#define ia64_ptcg __ptcg
++#define ia64_ptcga __ptcga
++#define ia64_ptri __ptri
++#define ia64_ptrd __ptrd
++#define ia64_dep_mi _m64_dep_mi
++
++/* Values for lfhint in __lfetch and __lfetch_fault */
++
++#define ia64_lfhint_none 0
++#define ia64_lfhint_nt1 1
++#define ia64_lfhint_nt2 2
++#define ia64_lfhint_nta 3
++
++#define ia64_lfetch __lfetch
++#define ia64_lfetch_excl __lfetch_excl
++#define ia64_lfetch_fault __lfetch_fault
++#define ia64_lfetch_fault_excl __lfetch_fault_excl
++
++#define ia64_intrin_local_irq_restore(x) \
++do { \
++ if ((x) != 0) { \
++ ia64_ssm(IA64_PSR_I); \
++ ia64_srlz_d(); \
++ } else { \
++ ia64_rsm(IA64_PSR_I); \
++ } \
++} while (0)
++
++#endif /* _ASM_IA64_INTEL_INTRIN_H */
+Index: linux-2.6.0-test5/include/asm-ia64/lockmeter.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/lockmeter.h 2003-09-27 11:38:18.478719192 +0800
++++ linux-2.6.0-test5/include/asm-ia64/lockmeter.h 2003-09-27 11:38:40.258408176 +0800
+@@ -0,0 +1,72 @@
++/*
++ * Copyright (C) 1999,2000 Silicon Graphics, Inc.
++ *
++ * Written by John Hawkes (hawkes@sgi.com)
++ * Based on klstat.h by Jack Steiner (steiner@sgi.com)
++ */
++
++#ifndef _IA64_LOCKMETER_H
++#define _IA64_LOCKMETER_H
++
++#ifdef local_cpu_data
++#define CPU_CYCLE_FREQUENCY local_cpu_data->itc_freq
++#else
++#define CPU_CYCLE_FREQUENCY my_cpu_data.itc_freq
++#endif
++#define get_cycles64() get_cycles()
++
++#define THIS_CPU_NUMBER smp_processor_id()
++
++/*
++ * macros to cache and retrieve an index value inside of a lock
++ * these macros assume that there are less than 65536 simultaneous
++ * (read mode) holders of a rwlock.
++ * we also assume that the hash table has less than 32767 entries.
++ */
++/*
++ * instrumented spinlock structure -- never used to allocate storage
++ * only used in macros below to overlay a spinlock_t
++ */
++typedef struct inst_spinlock_s {
++ /* remember, Intel is little endian */
++ volatile unsigned short lock;
++ volatile unsigned short index;
++} inst_spinlock_t;
++#define PUT_INDEX(lock_ptr,indexv) ((inst_spinlock_t *)(lock_ptr))->index = indexv
++#define GET_INDEX(lock_ptr) ((inst_spinlock_t *)(lock_ptr))->index
++
++/*
++ * macros to cache and retrieve an index value in a read/write lock
++ * as well as the cpu where a reader busy period started
++ * we use the 2nd word (the debug word) for this, so require the
++ * debug word to be present
++ */
++/*
++ * instrumented rwlock structure -- never used to allocate storage
++ * only used in macros below to overlay a rwlock_t
++ */
++typedef struct inst_rwlock_s {
++ volatile int read_counter:31;
++ volatile int write_lock:1;
++ volatile unsigned short index;
++ volatile unsigned short cpu;
++} inst_rwlock_t;
++#define PUT_RWINDEX(rwlock_ptr,indexv) ((inst_rwlock_t *)(rwlock_ptr))->index = indexv
++#define GET_RWINDEX(rwlock_ptr) ((inst_rwlock_t *)(rwlock_ptr))->index
++#define PUT_RW_CPU(rwlock_ptr,cpuv) ((inst_rwlock_t *)(rwlock_ptr))->cpu = cpuv
++#define GET_RW_CPU(rwlock_ptr) ((inst_rwlock_t *)(rwlock_ptr))->cpu
++
++/*
++ * return the number of readers for a rwlock_t
++ */
++#define RWLOCK_READERS(rwlock_ptr) ((rwlock_ptr)->read_counter)
++
++/*
++ * return true if rwlock is write locked
++ * (note that other lock attempts can cause the lock value to be negative)
++ */
++#define RWLOCK_IS_WRITE_LOCKED(rwlock_ptr) ((rwlock_ptr)->write_lock)
++#define RWLOCK_IS_READ_LOCKED(rwlock_ptr) ((rwlock_ptr)->read_counter)
++
++#endif /* _IA64_LOCKMETER_H */
++
+Index: linux-2.6.0-test5/include/asm-ia64/mmzone.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/mmzone.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/mmzone.h 2003-09-27 11:38:40.261407720 +0800
+@@ -92,14 +92,12 @@
+ extern unsigned long max_low_pfn;
+
+
+-#ifdef CONFIG_IA64_DIG
++#if defined(CONFIG_IA64_DIG)
+
+ /*
+ * Platform definitions for DIG platform with contiguous memory.
+ */
+-#define MAX_PHYSNODE_ID 8 /* Maximum node number +1 */
+-#define NR_NODES 8 /* Maximum number of nodes in SSI */
+-
++#define MAX_PHYSNODE_ID 8 /* Maximum node number +1 */
+ #define MAX_PHYS_MEMORY (1UL << 40) /* 1 TB */
+
+ /*
+@@ -119,37 +117,34 @@
+ # error Unsupported bank and nodesize!
+ #endif
+ #define BANKSIZE (1UL << BANKSHIFT)
+-#define BANK_OFFSET(addr) ((unsigned long)(addr) & (BANKSIZE-1))
+-#define NR_BANKS (NR_BANKS_PER_NODE * NR_NODES)
+-
+-/*
+- * VALID_MEM_KADDR returns a boolean to indicate if a kaddr is
+- * potentially a valid cacheable identity mapped RAM memory address.
+- * Note that the RAM may or may not actually be present!!
+- */
+-#define VALID_MEM_KADDR(kaddr) 1
+-
+-/*
+- * Given a nodeid & a bank number, find the address of the mem_map
+- * entry for the first page of the bank.
+- */
+-#define BANK_MEM_MAP_INDEX(kaddr) \
+- (((unsigned long)(kaddr) & (MAX_PHYS_MEMORY-1)) >> BANKSHIFT)
+
+ #elif defined(CONFIG_IA64_SGI_SN2)
++
+ /*
+ * SGI SN2 discontig definitions
+ */
+ #define MAX_PHYSNODE_ID 2048 /* 2048 node ids (also called nasid) */
+-#define NR_NODES 128 /* Maximum number of nodes in SSI */
+ #define MAX_PHYS_MEMORY (1UL << 49)
+
+-#define BANKSHIFT 38
+ #define NR_BANKS_PER_NODE 4
++#define BANKSHIFT 38
+ #define SN2_NODE_SIZE (64UL*1024*1024*1024) /* 64GB per node */
+ #define BANKSIZE (SN2_NODE_SIZE/NR_BANKS_PER_NODE)
++
++#endif /* CONFIG_IA64_DIG */
++
++#if defined(CONFIG_IA64_DIG) || defined (CONFIG_IA64_SGI_SN2)
++/* Common defines for both platforms */
++#include <asm/numnodes.h>
+ #define BANK_OFFSET(addr) ((unsigned long)(addr) & (BANKSIZE-1))
+-#define NR_BANKS (NR_BANKS_PER_NODE * NR_NODES)
++#define NR_BANKS (NR_BANKS_PER_NODE * (1 << NODES_SHIFT))
++#define NR_MEMBLKS (NR_BANKS)
++
++/*
++ * VALID_MEM_KADDR returns a boolean to indicate if a kaddr is
++ * potentially a valid cacheable identity mapped RAM memory address.
++ * Note that the RAM may or may not actually be present!!
++ */
+ #define VALID_MEM_KADDR(kaddr) 1
+
+ /*
+@@ -159,5 +154,6 @@
+ #define BANK_MEM_MAP_INDEX(kaddr) \
+ (((unsigned long)(kaddr) & (MAX_PHYS_MEMORY-1)) >> BANKSHIFT)
+
+-#endif /* CONFIG_IA64_DIG */
++#endif /* CONFIG_IA64_DIG || CONFIG_IA64_SGI_SN2 */
++
+ #endif /* _ASM_IA64_MMZONE_H */
+Index: linux-2.6.0-test5/include/asm-ia64/nodedata.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/nodedata.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/nodedata.h 2003-09-27 11:38:40.262407568 +0800
+@@ -8,12 +8,10 @@
+ * Copyright (c) 2002 Erich Focht <efocht@ess.nec.de>
+ * Copyright (c) 2002 Kimio Suganuma <k-suganuma@da.jp.nec.com>
+ */
+-
+-
+ #ifndef _ASM_IA64_NODEDATA_H
+ #define _ASM_IA64_NODEDATA_H
+
+-
++#include <linux/numa.h>
+ #include <asm/mmzone.h>
+
+ /*
+@@ -24,9 +22,9 @@
+ struct ia64_node_data {
+ short active_cpu_count;
+ short node;
+- struct pglist_data *pg_data_ptrs[NR_NODES];
++ struct pglist_data *pg_data_ptrs[MAX_NUMNODES];
+ struct page *bank_mem_map_base[NR_BANKS];
+- struct ia64_node_data *node_data_ptrs[NR_NODES];
++ struct ia64_node_data *node_data_ptrs[MAX_NUMNODES];
+ short node_id_map[NR_BANKS];
+ };
+
+Index: linux-2.6.0-test5/include/asm-ia64/numa.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/numa.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/numa.h 2003-09-27 11:38:40.264407264 +0800
+@@ -13,17 +13,11 @@
+
+ #ifdef CONFIG_NUMA
+
+-#ifdef CONFIG_DISCONTIGMEM
+-# include <asm/mmzone.h>
+-# define NR_MEMBLKS (NR_BANKS)
+-#else
+-# define NR_NODES (8)
+-# define NR_MEMBLKS (NR_NODES * 8)
+-#endif
+-
++#include <linux/numa.h>
+ #include <linux/cache.h>
++
+ extern volatile char cpu_to_node_map[NR_CPUS] __cacheline_aligned;
+-extern volatile unsigned long node_to_cpu_mask[NR_NODES] __cacheline_aligned;
++extern volatile cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned;
+
+ /* Stuff below this line could be architecture independent */
+
+@@ -57,7 +51,7 @@
+ * proportional to the memory access latency ratios.
+ */
+
+-extern u8 numa_slit[NR_NODES * NR_NODES];
++extern u8 numa_slit[MAX_NUMNODES * MAX_NUMNODES];
+ #define node_distance(from,to) (numa_slit[from * numnodes + to])
+
+ extern int paddr_to_nid(unsigned long paddr);
+Index: linux-2.6.0-test5/include/asm-ia64/numnodes.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/numnodes.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/numnodes.h 2003-09-27 11:38:40.265407112 +0800
+@@ -1,7 +1,12 @@
+ #ifndef _ASM_MAX_NUMNODES_H
+ #define _ASM_MAX_NUMNODES_H
+
+-#include <asm/mmzone.h>
+-#define MAX_NUMNODES NR_NODES
++#ifdef CONFIG_IA64_DIG
++/* Max 8 Nodes */
++#define NODES_SHIFT 3
++#elif defined(CONFIG_IA64_SGI_SN2)
++/* Max 128 Nodes */
++#define NODES_SHIFT 7
++#endif
+
+ #endif /* _ASM_MAX_NUMNODES_H */
+Index: linux-2.6.0-test5/include/asm-ia64/param.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/param.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/param.h 2003-09-27 11:38:40.267406808 +0800
+@@ -4,22 +4,10 @@
+ /*
+ * Fundamental kernel parameters.
+ *
+- * Copyright (C) 1998, 1999, 2002 Hewlett-Packard Co
++ * Copyright (C) 1998, 1999, 2002-2003 Hewlett-Packard Co
+ * David Mosberger-Tang <davidm@hpl.hp.com>
+ */
+
+-#include <linux/config.h>
+-
+-#ifdef CONFIG_IA64_HP_SIM
+-/*
+- * Yeah, simulating stuff is slow, so let us catch some breath between
+- * timer interrupts...
+- */
+-# define HZ 32
+-#else
+-# define HZ 1024
+-#endif
+-
+ #define EXEC_PAGESIZE 65536
+
+ #ifndef NGROUPS
+@@ -33,8 +21,24 @@
+ #define MAXHOSTNAMELEN 64 /* max length of hostname */
+
+ #ifdef __KERNEL__
++# include <linux/config.h> /* mustn't include <linux/config.h> outside of #ifdef __KERNEL__ */
++# ifdef CONFIG_IA64_HP_SIM
++ /*
++ * Yeah, simulating stuff is slow, so let us catch some breath between
++ * timer interrupts...
++ */
++# define HZ 32
++# else
++# define HZ 1024
++# endif
+ # define USER_HZ HZ
+ # define CLOCKS_PER_SEC HZ /* frequency at which times() counts */
++#else
++ /*
++ * Technically, this is wrong, but some old apps still refer to it. The proper way to
++ * get the HZ value is via sysconf(_SC_CLK_TCK).
++ */
++# define HZ 1024
+ #endif
+
+ #endif /* _ASM_IA64_PARAM_H */
+Index: linux-2.6.0-test5/include/asm-ia64/pgtable.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/pgtable.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/pgtable.h 2003-09-27 11:38:40.272406048 +0800
+@@ -207,7 +207,6 @@
+ #define RGN_KERNEL 7
+
+ #define VMALLOC_START 0xa000000200000000
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #ifdef CONFIG_VIRTUAL_MEM_MAP
+ # define VMALLOC_END_INIT (0xa000000000000000 + (1UL << (4*PAGE_SHIFT - 9)))
+ # define VMALLOC_END vmalloc_end
+Index: linux-2.6.0-test5/include/asm-ia64/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/posix_types.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/posix_types.h 2003-09-27 11:38:40.273405896 +0800
+@@ -10,7 +10,6 @@
+ * David Mosberger-Tang <davidm@hpl.hp.com>
+ */
+
+-typedef unsigned int __kernel_dev_t;
+ typedef unsigned int __kernel_ino_t;
+ typedef unsigned int __kernel_mode_t;
+ typedef unsigned int __kernel_nlink_t;
+Index: linux-2.6.0-test5/include/asm-ia64/processor.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/processor.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/processor.h 2003-09-27 11:38:40.279404984 +0800
+@@ -56,7 +56,6 @@
+ /*
+ * Bus types
+ */
+-#define EISA_bus 0
+ #define MCA_bus 0
+ #define MCA_bus__is_a_macro /* for versions in ksyms.c */
+
+Index: linux-2.6.0-test5/include/asm-ia64/ptrace.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/ptrace.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/ptrace.h 2003-09-27 11:38:40.282404528 +0800
+@@ -223,6 +223,12 @@
+ };
+
+ #ifdef __KERNEL__
++/*
++ * We use the ia64_psr(regs)->ri to determine which of the three
++ * instructions in bundle (16 bytes) took the sample. Generate
++ * the canonical representation by adding to instruction pointer.
++ */
++# define instruction_pointer(regs) ((regs)->cr_iip + ia64_psr(regs)->ri)
+ /* given a pointer to a task_struct, return the user's pt_regs */
+ # define ia64_task_regs(t) (((struct pt_regs *) ((char *) (t) + IA64_STK_OFFSET)) - 1)
+ # define ia64_psr(regs) ((struct ia64_psr *) &(regs)->cr_ipsr)
+Index: linux-2.6.0-test5/include/asm-ia64/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/signal.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/signal.h 2003-09-27 11:38:40.284404224 +0800
+@@ -2,7 +2,7 @@
+ #define _ASM_IA64_SIGNAL_H
+
+ /*
+- * Copyright (C) 1998-2001 Hewlett-Packard Co
++ * Copyright (C) 1998-2001, 2003 Hewlett-Packard Co
+ * David Mosberger-Tang <davidm@hpl.hp.com>
+ *
+ * Unfortunately, this file is being included by bits/signal.h in
+@@ -50,7 +50,7 @@
+
+ /* These should not be considered constants from userland. */
+ #define SIGRTMIN 32
+-#define SIGRTMAX (_NSIG-1)
++#define SIGRTMAX _NSIG
+
+ /*
+ * SA_FLAGS values:
+@@ -96,7 +96,16 @@
+ * ar.rsc.loadrs is 14 bits, we can assume that they'll never take up
+ * more than 16KB of space.
+ */
+-#define MINSIGSTKSZ 131027 /* min. stack size for sigaltstack() */
++#if 1
++ /*
++ * This is a stupid typo: the value was _meant_ to be 131072 (0x20000), but I typed it
++ * in wrong. ;-( To preserve backwards compatibility, we leave the kernel at the
++ * incorrect value and fix libc only.
++ */
++# define MINSIGSTKSZ 131027 /* min. stack size for sigaltstack() */
++#else
++# define MINSIGSTKSZ 131072 /* min. stack size for sigaltstack() */
++#endif
+ #define SIGSTKSZ 262144 /* default stack size for sigaltstack() */
+
+ #ifdef __KERNEL__
+Index: linux-2.6.0-test5/include/asm-ia64/sn/hcl.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/sn/hcl.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/sn/hcl.h 2003-09-27 11:38:40.287403768 +0800
+@@ -10,6 +10,7 @@
+ #define _ASM_IA64_SN_HCL_H
+
+ #include <asm/sn/sgi.h>
++#include <asm/sn/invent.h>
+
+ extern vertex_hdl_t hwgraph_root;
+ extern vertex_hdl_t linux_busnum;
+Index: linux-2.6.0-test5/include/asm-ia64/sn/ksys/elsc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/sn/ksys/elsc.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/sn/ksys/elsc.h 2003-09-27 11:38:40.288403616 +0800
+@@ -9,9 +9,6 @@
+ #ifndef _ASM_SN_KSYS_ELSC_H
+ #define _ASM_SN_KSYS_ELSC_H
+
+-#include <linux/config.h>
+-#include <asm/sn/ksys/l1.h>
+-
+ /*
+ * Error codes
+ *
+Index: linux-2.6.0-test5/include/asm-ia64/sn/ksys/l1.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/sn/ksys/l1.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/sn/ksys/l1.h 2003-09-27 11:38:40.291403160 +0800
+@@ -10,10 +10,7 @@
+ #ifndef _ASM_SN_KSYS_L1_H
+ #define _ASM_SN_KSYS_L1_H
+
+-#include <linux/config.h>
+-#include <asm/sn/vector.h>
+-#include <asm/sn/addrs.h>
+-#include <asm/atomic.h>
++#include <asm/sn/types.h>
+
+ /* L1 Target Addresses */
+ /*
+@@ -39,18 +36,6 @@
+ #define L1_ADDR_TASK_BEDROCK 0x05 /* bedrock */
+ #define L1_ADDR_TASK_GENERAL 0x06 /* general requests */
+
+-#define L1_ADDR_LOCAL \
+- (L1_ADDR_TYPE_L1 << L1_ADDR_TYPE_SHFT) | \
+- (L1_ADDR_RACK_LOCAL << L1_ADDR_RACK_SHFT) | \
+- (L1_ADDR_BAY_LOCAL << L1_ADDR_BAY_SHFT)
+-
+-#define L1_ADDR_LOCALIO \
+- (L1_ADDR_TYPE_IOBRICK << L1_ADDR_TYPE_SHFT) | \
+- (L1_ADDR_RACK_LOCAL << L1_ADDR_RACK_SHFT) | \
+- (L1_ADDR_BAY_LOCAL << L1_ADDR_BAY_SHFT)
+-
+-#define L1_ADDR_LOCAL_SHFT L1_ADDR_BAY_SHFT
+-
+ /* response argument types */
+ #define L1_ARG_INT 0x00 /* 4-byte integer (big-endian) */
+ #define L1_ARG_ASCII 0x01 /* null-terminated ASCII string */
+@@ -133,18 +118,6 @@
+ #define L1_EEP_IUSE 3 /* internal use area */
+ #define L1_EEP_SPD 4 /* serial presence detect record */
+
+-typedef uint32_t l1addr_t;
+-
+-#define L1_BUILD_ADDR(addr,at,r,s,t) \
+- (*(l1addr_t *)(addr) = ((l1addr_t)(at) << L1_ADDR_TYPE_SHFT) | \
+- ((l1addr_t)(r) << L1_ADDR_RACK_SHFT) | \
+- ((l1addr_t)(s) << L1_ADDR_BAY_SHFT) | \
+- ((l1addr_t)(t) << L1_ADDR_TASK_SHFT))
+-
+-#define L1_ADDRESS_TO_TASK(addr,trb,tsk) \
+- (*(l1addr_t *)(addr) = (l1addr_t)(trb) | \
+- ((l1addr_t)(tsk) << L1_ADDR_TASK_SHFT))
+-
+ #define L1_DISPLAY_LINE_LENGTH 12 /* L1 display characters/line */
+
+ #ifdef L1_DISP_2LINES
+@@ -154,11 +127,9 @@
+ * to system software */
+ #endif
+
+-#define bzero(d, n) memset((d), 0, (n))
+-
+ int elsc_display_line(nasid_t nasid, char *line, int lnum);
+-int iobrick_rack_bay_type_get( nasid_t nasid, uint *rack,
+- uint *bay, uint *brick_type );
++int iobrick_rack_bay_type_get( nasid_t nasid, unsigned int *rack,
++ unsigned int *bay, unsigned int *brick_type );
+ int iobrick_module_get( nasid_t nasid );
+
+
+Index: linux-2.6.0-test5/include/asm-ia64/sn/nodepda.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/sn/nodepda.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/sn/nodepda.h 2003-09-27 11:38:40.292403008 +0800
+@@ -87,7 +87,7 @@
+ char irq_flags[NR_IRQS];
+ struct pci_dev *device_dev[NR_IRQS];
+ char share_count[NR_IRQS];
+- struct pci_dev *current;
++ struct pci_dev *curr;
+ };
+
+ typedef struct irqpda_s irqpda_t;
+@@ -128,7 +128,7 @@
+ * Check if given a compact node id the corresponding node has all the
+ * cpus disabled.
+ */
+-#define is_headless_node(cnode) (!node_to_cpumask(cnode))
++#define is_headless_node(cnode) (!any_online_cpu(node_to_cpumask(cnode)))
+
+ /*
+ * Check if given a node vertex handle the corresponding node has all the
+Index: linux-2.6.0-test5/include/asm-ia64/sn/pci/pcibr_private.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/sn/pci/pcibr_private.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/sn/pci/pcibr_private.h 2003-09-27 11:38:40.300401792 +0800
+@@ -15,11 +15,9 @@
+ * should ever peek into this file.
+ */
+
+-#include <linux/config.h>
+ #include <linux/pci.h>
+ #include <asm/sn/pci/pcibr.h>
+ #include <asm/sn/pci/pciio_private.h>
+-#include <asm/sn/ksys/l1.h>
+
+ /*
+ * convenience typedefs
+Index: linux-2.6.0-test5/include/asm-ia64/sn/pci/pciio.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/sn/pci/pciio.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/sn/pci/pciio.h 2003-09-27 11:38:40.308400576 +0800
+@@ -695,5 +695,39 @@
+ extern int pciio_error_handler(vertex_hdl_t, int, ioerror_mode_t, ioerror_t *);
+ extern int pciio_dma_enabled(vertex_hdl_t);
+
++/**
++ * sn_pci_set_vchan - Set the requested Virtual Channel bits into the mapped DMA
++ * address.
++ * @pci_dev: pci device pointer
++ * @addr: mapped dma address
++ * @vchan: Virtual Channel to use 0 or 1.
++ *
++ * Set the Virtual Channel bit in the mapped dma address.
++ */
++
++static inline int
++sn_pci_set_vchan(struct pci_dev *pci_dev,
++ dma_addr_t *addr,
++ int vchan)
++{
++ if (vchan > 1) {
++ return -1;
++ }
++
++ if (!(*addr >> 32)) /* Using a mask here would be cleaner */
++ return 0; /* but this generates better code */
++
++ if (vchan == 1) {
++ /* Set Bit 57 */
++ *addr |= (1UL << 57);
++ }
++ else {
++ /* Clear Bit 57 */
++ *addr &= ~(1UL << 57);
++ }
++
++ return 0;
++}
++
+ #endif /* C or C++ */
+ #endif /* _ASM_SN_PCI_PCIIO_H */
+Index: linux-2.6.0-test5/include/asm-ia64/sn/pda.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/sn/pda.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/sn/pda.h 2003-09-27 11:38:40.309400424 +0800
+@@ -10,6 +10,7 @@
+
+ #include <linux/config.h>
+ #include <linux/cache.h>
++#include <linux/numa.h>
+ #include <asm/percpu.h>
+ #include <asm/system.h>
+ #include <asm/processor.h>
+@@ -56,7 +57,7 @@
+
+ unsigned long sn_soft_irr[4];
+ unsigned long sn_in_service_ivecs[4];
+- short cnodeid_to_nasid_table[NR_NODES];
++ short cnodeid_to_nasid_table[MAX_NUMNODES];
+ int sn_lb_int_war_ticks;
+ int sn_last_irq;
+ int sn_first_irq;
+Index: linux-2.6.0-test5/include/asm-ia64/sn/router.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/sn/router.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/sn/router.h 2003-09-27 11:38:40.316399360 +0800
+@@ -1,5 +1,4 @@
+-
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++/* $id$
+ *
+ * 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
+@@ -19,7 +18,6 @@
+
+ #ifndef __ASSEMBLY__
+
+-#include <linux/devfs_fs_kernel.h>
+ #include <asm/sn/vector.h>
+ #include <asm/sn/slotnum.h>
+ #include <asm/sn/arch.h>
+@@ -31,23 +29,19 @@
+ #define MAX_ROUTER_PATH 80
+
+ #define ROUTER_REG_CAST (volatile router_reg_t *)
+-#define PS_UINT_CAST (__psunsigned_t)
+-#define UINT64_CAST (uint64_t)
+ typedef signed char port_no_t; /* Type for router port number */
+
+ #else
+
+ #define ROUTERREG_CAST
+-#define PS_UINT_CAST
+-#define UINT64_CAST
+
+ #endif /* __ASSEMBLY__ */
+
+-#define MAX_ROUTER_PORTS (8) /* Max. number of ports on a router */
++#define MAX_ROUTER_PORTS 8 /* Max. number of ports on a router */
+
+ #define ALL_PORTS ((1 << MAX_ROUTER_PORTS) - 1) /* for 0 based references */
+
+-#define PORT_INVALID (-1) /* Invalid port number */
++#define PORT_INVALID -1 /* Invalid port number */
+
+ #define IS_META(_rp) ((_rp)->flags & PCFG_ROUTER_META)
+
+@@ -126,24 +120,24 @@
+ */
+
+ #define RSRI_INPORT_SHFT 52
+-#define RSRI_INPORT_MASK (UINT64_CAST 0xf << 52)
++#define RSRI_INPORT_MASK (0xfUL << 52)
+ #define RSRI_LINKWORKING_BIT(_L) (35 + 2 * (_L))
+-#define RSRI_LINKWORKING(_L) (UINT64_CAST 1 << (35 + 2 * (_L)))
+-#define RSRI_LINKRESETFAIL(_L) (UINT64_CAST 1 << (34 + 2 * (_L)))
++#define RSRI_LINKWORKING(_L) (1UL << (35 + 2 * (_L)))
++#define RSRI_LINKRESETFAIL(_L) (1UL << (34 + 2 * (_L)))
+ #define RSRI_LSTAT_SHFT(_L) (34 + 2 * (_L))
+-#define RSRI_LSTAT_MASK(_L) (UINT64_CAST 0x3 << 34 + 2 * (_L))
+-#define RSRI_LOCALSBERROR (UINT64_CAST 1 << 35)
+-#define RSRI_LOCALSTUCK (UINT64_CAST 1 << 34)
+-#define RSRI_LOCALBADVEC (UINT64_CAST 1 << 33)
+-#define RSRI_LOCALTAILERR (UINT64_CAST 1 << 32)
++#define RSRI_LSTAT_MASK(_L) (0x3UL << 34 + 2 * (_L))
++#define RSRI_LOCALSBERROR (1UL << 35)
++#define RSRI_LOCALSTUCK (1UL << 34)
++#define RSRI_LOCALBADVEC (1UL << 33)
++#define RSRI_LOCALTAILERR (1UL << 32)
+ #define RSRI_LOCAL_SHFT 32
+-#define RSRI_LOCAL_MASK (UINT64_CAST 0xf << 32)
++#define RSRI_LOCAL_MASK (0xfUL << 32)
+ #define RSRI_CHIPREV_SHFT 28
+-#define RSRI_CHIPREV_MASK (UINT64_CAST 0xf << 28)
++#define RSRI_CHIPREV_MASK (0xfUL << 28)
+ #define RSRI_CHIPID_SHFT 12
+-#define RSRI_CHIPID_MASK (UINT64_CAST 0xffff << 12)
++#define RSRI_CHIPID_MASK (0xffffUL << 12)
+ #define RSRI_MFGID_SHFT 1
+-#define RSRI_MFGID_MASK (UINT64_CAST 0x7ff << 1)
++#define RSRI_MFGID_MASK (0x7ffUL << 1)
+
+ #define RSRI_LSTAT_WENTDOWN 0
+ #define RSRI_LSTAT_RESETFAIL 1
+@@ -154,38 +148,38 @@
+ * RR_PORT_RESET mask definitions
+ */
+
+-#define RPRESET_WARM (UINT64_CAST 1 << 9)
+-#define RPRESET_LINK(_L) (UINT64_CAST 1 << (_L))
+-#define RPRESET_LOCAL (UINT64_CAST 1)
++#define RPRESET_WARM (1UL << 9)
++#define RPRESET_LINK(_L) (1UL << (_L))
++#define RPRESET_LOCAL 1UL
+
+ /*
+ * RR_PROT_CONF mask and shift definitions
+ */
+
+ #define RPCONF_DIRCMPDIS_SHFT 13
+-#define RPCONF_DIRCMPDIS_MASK (UINT64_CAST 1 << 13)
+-#define RPCONF_FORCELOCAL (UINT64_CAST 1 << 12)
++#define RPCONF_DIRCMPDIS_MASK (1UL << 13)
++#define RPCONF_FORCELOCAL (1UL << 12)
+ #define RPCONF_FLOCAL_SHFT 12
+ #define RPCONF_METAID_SHFT 8
+-#define RPCONF_METAID_MASK (UINT64_CAST 0xf << 8)
+-#define RPCONF_RESETOK(_L) (UINT64_CAST 1 << ((_L) - 1))
++#define RPCONF_METAID_MASK (0xfUL << 8)
++#define RPCONF_RESETOK(_L) (1UL << ((_L) - 1))
+
+ /*
+ * RR_GLOBAL_PORT_DEF mask and shift definitions
+ */
+
+ #define RGPD_MGLBLNHBR_ID_SHFT 12 /* -global neighbor ID */
+-#define RGPD_MGLBLNHBR_ID_MASK (UINT64_CAST 0xf << 12)
++#define RGPD_MGLBLNHBR_ID_MASK (0xfUL << 12)
+ #define RGPD_MGLBLNHBR_VLD_SHFT 11 /* -global neighbor Valid */
+-#define RGPD_MGLBLNHBR_VLD_MASK (UINT64_CAST 0x1 << 11)
++#define RGPD_MGLBLNHBR_VLD_MASK (0x1UL << 11)
+ #define RGPD_MGLBLPORT_SHFT 8 /* -global neighbor Port */
+-#define RGPD_MGLBLPORT_MASK (UINT64_CAST 0x7 << 8)
++#define RGPD_MGLBLPORT_MASK (0x7UL << 8)
+ #define RGPD_PGLBLNHBR_ID_SHFT 4 /* +global neighbor ID */
+-#define RGPD_PGLBLNHBR_ID_MASK (UINT64_CAST 0xf << 4)
++#define RGPD_PGLBLNHBR_ID_MASK (0xfUL << 4)
+ #define RGPD_PGLBLNHBR_VLD_SHFT 3 /* +global neighbor Valid */
+-#define RGPD_PGLBLNHBR_VLD_MASK (UINT64_CAST 0x1 << 3)
++#define RGPD_PGLBLNHBR_VLD_MASK (0x1UL << 3)
+ #define RGPD_PGLBLPORT_SHFT 0 /* +global neighbor Port */
+-#define RGPD_PGLBLPORT_MASK (UINT64_CAST 0x7 << 0)
++#define RGPD_PGLBLPORT_MASK (0x7UL << 0)
+
+ #define GLBL_PARMS_REGS 2 /* Two Global Parms registers */
+
+@@ -194,95 +188,95 @@
+ */
+
+ #define RGPARM0_ARB_VALUE_SHFT 54 /* Local Block Arbitration State */
+-#define RGPARM0_ARB_VALUE_MASK (UINT64_CAST 0x7 << 54)
++#define RGPARM0_ARB_VALUE_MASK (0x7UL << 54)
+ #define RGPARM0_ROTATEARB_SHFT 53 /* Rotate Local Block Arbitration */
+-#define RGPARM0_ROTATEARB_MASK (UINT64_CAST 0x1 << 53)
++#define RGPARM0_ROTATEARB_MASK (1UL << 53)
+ #define RGPARM0_FAIREN_SHFT 52 /* Fairness logic Enable */
+-#define RGPARM0_FAIREN_MASK (UINT64_CAST 0x1 << 52)
++#define RGPARM0_FAIREN_MASK (1UL << 52)
+ #define RGPARM0_LOCGNTTO_SHFT 40 /* Local grant timeout */
+-#define RGPARM0_LOCGNTTO_MASK (UINT64_CAST 0xfff << 40)
++#define RGPARM0_LOCGNTTO_MASK (0xfffUL << 40)
+ #define RGPARM0_DATELINE_SHFT 38 /* Dateline crossing router */
+-#define RGPARM0_DATELINE_MASK (UINT64_CAST 0x1 << 38)
++#define RGPARM0_DATELINE_MASK (1UL << 38)
+ #define RGPARM0_MAXRETRY_SHFT 28 /* Max retry count */
+-#define RGPARM0_MAXRETRY_MASK (UINT64_CAST 0x3ff << 28)
++#define RGPARM0_MAXRETRY_MASK (0x3ffUL << 28)
+ #define RGPARM0_URGWRAP_SHFT 20 /* Urgent wrap */
+-#define RGPARM0_URGWRAP_MASK (UINT64_CAST 0xff << 20)
++#define RGPARM0_URGWRAP_MASK (0xffUL << 20)
+ #define RGPARM0_DEADLKTO_SHFT 16 /* Deadlock timeout */
+-#define RGPARM0_DEADLKTO_MASK (UINT64_CAST 0xf << 16)
++#define RGPARM0_DEADLKTO_MASK (0xfUL << 16)
+ #define RGPARM0_URGVAL_SHFT 12 /* Urgent value */
+-#define RGPARM0_URGVAL_MASK (UINT64_CAST 0xf << 12)
++#define RGPARM0_URGVAL_MASK (0xfUL << 12)
+ #define RGPARM0_VCHSELEN_SHFT 11 /* VCH_SEL_EN */
+-#define RGPARM0_VCHSELEN_MASK (UINT64_CAST 0x1 << 11)
++#define RGPARM0_VCHSELEN_MASK (1UL << 11)
+ #define RGPARM0_LOCURGTO_SHFT 9 /* Local urgent timeout */
+-#define RGPARM0_LOCURGTO_MASK (UINT64_CAST 0x3 << 9)
++#define RGPARM0_LOCURGTO_MASK (0x3UL << 9)
+ #define RGPARM0_TAILVAL_SHFT 5 /* Tail value */
+-#define RGPARM0_TAILVAL_MASK (UINT64_CAST 0xf << 5)
++#define RGPARM0_TAILVAL_MASK (0xfUL << 5)
+ #define RGPARM0_CLOCK_SHFT 1 /* Global clock select */
+-#define RGPARM0_CLOCK_MASK (UINT64_CAST 0xf << 1)
++#define RGPARM0_CLOCK_MASK (0xfUL << 1)
+ #define RGPARM0_BYPEN_SHFT 0
+-#define RGPARM0_BYPEN_MASK (UINT64_CAST 1) /* Bypass enable */
++#define RGPARM0_BYPEN_MASK 1UL /* Bypass enable */
+
+ /*
+ * RR_GLOBAL_PARMS1 shift and mask definitions
+ */
+
+ #define RGPARM1_TTOWRAP_SHFT 12 /* Tail timeout wrap */
+-#define RGPARM1_TTOWRAP_MASK (UINT64_CAST 0xfffff << 12)
++#define RGPARM1_TTOWRAP_MASK (0xfffffUL << 12)
+ #define RGPARM1_AGERATE_SHFT 8 /* Age rate */
+-#define RGPARM1_AGERATE_MASK (UINT64_CAST 0xf << 8)
++#define RGPARM1_AGERATE_MASK (0xfUL << 8)
+ #define RGPARM1_JSWSTAT_SHFT 0 /* JTAG Sw Register bits */
+-#define RGPARM1_JSWSTAT_MASK (UINT64_CAST 0xff << 0)
++#define RGPARM1_JSWSTAT_MASK (0xffUL << 0)
+
+ /*
+ * RR_DIAG_PARMS mask and shift definitions
+ */
+
+-#define RDPARM_ABSHISTOGRAM (UINT64_CAST 1 << 17) /* Absolute histgrm */
+-#define RDPARM_DEADLOCKRESET (UINT64_CAST 1 << 16) /* Reset on deadlck */
+-#define RDPARM_DISABLE(_L) (UINT64_CAST 1 << ((_L) + 7))
+-#define RDPARM_SENDERROR(_L) (UINT64_CAST 1 << ((_L) - 1))
++#define RDPARM_ABSHISTOGRAM (1UL << 17) /* Absolute histgrm */
++#define RDPARM_DEADLOCKRESET (1UL << 16) /* Reset on deadlck */
++#define RDPARM_DISABLE(_L) (1UL << ((_L) + 7))
++#define RDPARM_SENDERROR(_L) (1UL << ((_L) - 1))
+
+ /*
+ * RR_DEBUG_ADDR mask and shift definitions
+ */
+
+ #define RDA_DATA_SHFT 10 /* Observed debug data */
+-#define RDA_DATA_MASK (UINT64_CAST 0xffff << 10)
++#define RDA_DATA_MASK (0xffffUL << 10)
+ #define RDA_ADDR_SHFT 0 /* debug address for data */
+-#define RDA_ADDR_MASK (UINT64_CAST 0x3ff << 0)
++#define RDA_ADDR_MASK (0x3ffUL << 0)
+
+ /*
+ * RR_LB_TO_L2 mask and shift definitions
+ */
+
+ #define RLBTOL2_DATA_VLD_SHFT 32 /* data is valid for JTAG controller */
+-#define RLBTOL2_DATA_VLD_MASK (UINT64_CAST 0x1 << 32)
++#define RLBTOL2_DATA_VLD_MASK (1UL << 32)
+ #define RLBTOL2_DATA_SHFT 0 /* data bits for JTAG controller */
+-#define RLBTOL2_DATA_MASK (UINT64_CAST 0xffffffff)
++#define RLBTOL2_DATA_MASK 0xffffffffUL
+
+ /*
+ * RR_L2_TO_LB mask and shift definitions
+ */
+
+ #define RL2TOLB_DATA_VLD_SHFT 33 /* data is valid from JTAG controller */
+-#define RL2TOLB_DATA_VLD_MASK (UINT64_CAST 0x1 << 33)
++#define RL2TOLB_DATA_VLD_MASK (1UL << 33)
+ #define RL2TOLB_PARITY_SHFT 32 /* sw implemented parity for data */
+-#define RL2TOLB_PARITY_MASK (UINT64_CAST 0x1 << 32)
++#define RL2TOLB_PARITY_MASK (1UL << 32)
+ #define RL2TOLB_DATA_SHFT 0 /* data bits from JTAG controller */
+-#define RL2TOLB_DATA_MASK (UINT64_CAST 0xffffffff)
++#define RL2TOLB_DATA_MASK 0xffffffffUL
+
+ /*
+ * RR_JBUS_CONTROL mask and shift definitions
+ */
+
+ #define RJC_POS_BITS_SHFT 20 /* Router position bits */
+-#define RJC_POS_BITS_MASK (UINT64_CAST 0xf << 20)
++#define RJC_POS_BITS_MASK (0xfUL << 20)
+ #define RJC_RD_DATA_STROBE_SHFT 16 /* count when read data is strobed in */
+-#define RJC_RD_DATA_STROBE_MASK (UINT64_CAST 0xf << 16)
++#define RJC_RD_DATA_STROBE_MASK (0xfUL << 16)
+ #define RJC_WE_OE_HOLD_SHFT 8 /* time OE or WE is held */
+-#define RJC_WE_OE_HOLD_MASK (UINT64_CAST 0xff << 8)
++#define RJC_WE_OE_HOLD_MASK (0xffUL << 8)
+ #define RJC_ADDR_SET_HLD_SHFT 0 /* time address driven around OE/WE */
+-#define RJC_ADDR_SET_HLD_MASK (UINT64_CAST 0xff)
++#define RJC_ADDR_SET_HLD_MASK 0xffUL
+
+ /*
+ * RR_SCRATCH_REGx mask and shift definitions
+@@ -291,58 +285,58 @@
+ */
+
+ #define RSCR0_BOOTED_SHFT 63
+-#define RSCR0_BOOTED_MASK (UINT64_CAST 0x1 << RSCR0_BOOTED_SHFT)
++#define RSCR0_BOOTED_MASK (0x1UL << RSCR0_BOOTED_SHFT)
+ #define RSCR0_LOCALID_SHFT 56
+-#define RSCR0_LOCALID_MASK (UINT64_CAST 0x7f << RSCR0_LOCALID_SHFT)
++#define RSCR0_LOCALID_MASK (0x7fUL << RSCR0_LOCALID_SHFT)
+ #define RSCR0_UNUSED_SHFT 48
+-#define RSCR0_UNUSED_MASK (UINT64_CAST 0xff << RSCR0_UNUSED_SHFT)
++#define RSCR0_UNUSED_MASK (0xffUL << RSCR0_UNUSED_SHFT)
+ #define RSCR0_NIC_SHFT 0
+-#define RSCR0_NIC_MASK (UINT64_CAST 0xffffffffffff)
++#define RSCR0_NIC_MASK 0xffffffffffffUL
+
+ #define RSCR1_MODID_SHFT 0
+-#define RSCR1_MODID_MASK (UINT64_CAST 0xffff)
++#define RSCR1_MODID_MASK 0xffffUL
+
+ /*
+ * RR_VECTOR_HW_BAR mask and shift definitions
+ */
+
+ #define BAR_TX_SHFT 27 /* Barrier in trans(m)it when read */
+-#define BAR_TX_MASK (UINT64_CAST 1 << BAR_TX_SHFT)
++#define BAR_TX_MASK (1UL << BAR_TX_SHFT)
+ #define BAR_VLD_SHFT 26 /* Valid Configuration */
+-#define BAR_VLD_MASK (UINT64_CAST 1 << BAR_VLD_SHFT)
++#define BAR_VLD_MASK (1UL << BAR_VLD_SHFT)
+ #define BAR_SEQ_SHFT 24 /* Sequence number */
+-#define BAR_SEQ_MASK (UINT64_CAST 3 << BAR_SEQ_SHFT)
++#define BAR_SEQ_MASK (3UL << BAR_SEQ_SHFT)
+ #define BAR_LEAFSTATE_SHFT 18 /* Leaf State */
+-#define BAR_LEAFSTATE_MASK (UINT64_CAST 0x3f << BAR_LEAFSTATE_SHFT)
++#define BAR_LEAFSTATE_MASK (0x3fUL << BAR_LEAFSTATE_SHFT)
+ #define BAR_PARENT_SHFT 14 /* Parent Port */
+-#define BAR_PARENT_MASK (UINT64_CAST 0xf << BAR_PARENT_SHFT)
++#define BAR_PARENT_MASK (0xfUL << BAR_PARENT_SHFT)
+ #define BAR_CHILDREN_SHFT 6 /* Child Select port bits */
+-#define BAR_CHILDREN_MASK (UINT64_CAST 0xff << BAR_CHILDREN_SHFT)
++#define BAR_CHILDREN_MASK (0xffUL << BAR_CHILDREN_SHFT)
+ #define BAR_LEAFCOUNT_SHFT 0 /* Leaf Count to trigger parent */
+-#define BAR_LEAFCOUNT_MASK (UINT64_CAST 0x3f)
++#define BAR_LEAFCOUNT_MASK 0x3fUL
+
+ /*
+ * RR_PORT_PARMS(_L) mask and shift definitions
+ */
+
+ #define RPPARM_MIPRESETEN_SHFT 29 /* Message In Progress reset enable */
+-#define RPPARM_MIPRESETEN_MASK (UINT64_CAST 0x1 << 29)
++#define RPPARM_MIPRESETEN_MASK (0x1UL << 29)
+ #define RPPARM_UBAREN_SHFT 28 /* Enable user barrier requests */
+-#define RPPARM_UBAREN_MASK (UINT64_CAST 0x1 << 28)
++#define RPPARM_UBAREN_MASK (0x1UL << 28)
+ #define RPPARM_OUTPDTO_SHFT 24 /* Output Port Deadlock TO value */
+-#define RPPARM_OUTPDTO_MASK (UINT64_CAST 0xf << 24)
++#define RPPARM_OUTPDTO_MASK (0xfUL << 24)
+ #define RPPARM_PORTMATE_SHFT 21 /* Port Mate for the port */
+-#define RPPARM_PORTMATE_MASK (UINT64_CAST 0x7 << 21)
++#define RPPARM_PORTMATE_MASK (0x7UL << 21)
+ #define RPPARM_HISTEN_SHFT 20 /* Histogram counter enable */
+-#define RPPARM_HISTEN_MASK (UINT64_CAST 0x1 << 20)
++#define RPPARM_HISTEN_MASK (0x1UL << 20)
+ #define RPPARM_HISTSEL_SHFT 18
+-#define RPPARM_HISTSEL_MASK (UINT64_CAST 0x3 << 18)
++#define RPPARM_HISTSEL_MASK (0x3UL << 18)
+ #define RPPARM_DAMQHS_SHFT 16
+-#define RPPARM_DAMQHS_MASK (UINT64_CAST 0x3 << 16)
++#define RPPARM_DAMQHS_MASK (0x3UL << 16)
+ #define RPPARM_NULLTO_SHFT 10
+-#define RPPARM_NULLTO_MASK (UINT64_CAST 0x3f << 10)
++#define RPPARM_NULLTO_MASK (0x3fUL << 10)
+ #define RPPARM_MAXBURST_SHFT 0
+-#define RPPARM_MAXBURST_MASK (UINT64_CAST 0x3ff)
++#define RPPARM_MAXBURST_MASK 0x3ffUL
+
+ /*
+ * NOTE: Normally the kernel tracks only UTILIZATION statistics.
+@@ -356,23 +350,23 @@
+ /*
+ * RR_STATUS_ERROR(_L) and RR_ERROR_CLEAR(_L) mask and shift definitions
+ */
+-#define RSERR_POWERNOK (UINT64_CAST 1 << 38)
+-#define RSERR_PORT_DEADLOCK (UINT64_CAST 1 << 37)
+-#define RSERR_WARMRESET (UINT64_CAST 1 << 36)
+-#define RSERR_LINKRESET (UINT64_CAST 1 << 35)
+-#define RSERR_RETRYTIMEOUT (UINT64_CAST 1 << 34)
+-#define RSERR_FIFOOVERFLOW (UINT64_CAST 1 << 33)
+-#define RSERR_ILLEGALPORT (UINT64_CAST 1 << 32)
++#define RSERR_POWERNOK (1UL << 38)
++#define RSERR_PORT_DEADLOCK (1UL << 37)
++#define RSERR_WARMRESET (1UL << 36)
++#define RSERR_LINKRESET (1UL << 35)
++#define RSERR_RETRYTIMEOUT (1UL << 34)
++#define RSERR_FIFOOVERFLOW (1UL << 33)
++#define RSERR_ILLEGALPORT (1UL << 32)
+ #define RSERR_DEADLOCKTO_SHFT 28
+-#define RSERR_DEADLOCKTO_MASK (UINT64_CAST 0xf << 28)
++#define RSERR_DEADLOCKTO_MASK (0xfUL << 28)
+ #define RSERR_RECVTAILTO_SHFT 24
+-#define RSERR_RECVTAILTO_MASK (UINT64_CAST 0xf << 24)
++#define RSERR_RECVTAILTO_MASK (0xfUL << 24)
+ #define RSERR_RETRYCNT_SHFT 16
+-#define RSERR_RETRYCNT_MASK (UINT64_CAST 0xff << 16)
++#define RSERR_RETRYCNT_MASK (0xffUL << 16)
+ #define RSERR_CBERRCNT_SHFT 8
+-#define RSERR_CBERRCNT_MASK (UINT64_CAST 0xff << 8)
++#define RSERR_CBERRCNT_MASK (0xffUL << 8)
+ #define RSERR_SNERRCNT_SHFT 0
+-#define RSERR_SNERRCNT_MASK (UINT64_CAST 0xff << 0)
++#define RSERR_SNERRCNT_MASK (0xffUL << 0)
+
+
+ #define PORT_STATUS_UP (1 << 0) /* Router link up */
+@@ -393,10 +387,10 @@
+ * why the router link
+ * went down
+ */
+-#define PROBE_RESULT_BAD (-1) /* Set if any of the router
++#define PROBE_RESULT_BAD -1 /* Set if any of the router
+ * links failed after reset
+ */
+-#define PROBE_RESULT_GOOD (0) /* Set if all the router links
++#define PROBE_RESULT_GOOD 0 /* Set if all the router links
+ * which came out of reset
+ * are up
+ */
+@@ -528,23 +522,6 @@
+ #define RIP_PROMLOG 2 /* Router info in promlog */
+ #define RIP_CONSOLE 4 /* Router info on console */
+
+-#define ROUTER_INFO_PRINT(_rip,_where) (_rip->ri_print |= _where)
+- /* Set the field used to check if a
+- * router info can be printed
+- */
+-#define IS_ROUTER_INFO_PRINTED(_rip,_where) \
+- (_rip->ri_print & _where)
+- /* Was the router info printed to
+- * the given location (_where) ?
+- * Mainly used to prevent duplicate
+- * router error states.
+- */
+-#define ROUTER_INFO_LOCK(_rip,_s) _s = mutex_spinlock(&(_rip->ri_lock))
+- /* Take the lock on router info
+- * to gain exclusive access
+- */
+-#define ROUTER_INFO_UNLOCK(_rip,_s) mutex_spinunlock(&(_rip->ri_lock),_s)
+- /* Release the lock on router info */
+ /*
+ * Router info hanging in the nodepda
+ */
+@@ -623,7 +600,7 @@
+ */
+
+ #define RHIST_BUCKET_SHFT(_x) (32 * ((_x) & 0x1))
+-#define RHIST_BUCKET_MASK(_x) (UINT64_CAST 0xffffffff << RHIST_BUCKET_SHFT((_x) & 0x1))
++#define RHIST_BUCKET_MASK(_x) (0xffffffffUL << RHIST_BUCKET_SHFT((_x) & 0x1))
+ #define RHIST_GET_BUCKET(_x, _reg) \
+ ((RHIST_BUCKET_MASK(_x) & ((_reg)[(_x) >> 1])) >> RHIST_BUCKET_SHFT(_x))
+
+@@ -631,7 +608,7 @@
+ * RR_RESET_MASK(_L) mask and shift definitions
+ */
+
+-#define RRM_RESETOK(_L) (UINT64_CAST 1 << ((_L) - 1))
++#define RRM_RESETOK(_L) (1UL << ((_L) - 1))
+ #define RRM_RESETOK_ALL ALL_PORTS
+
+ /*
+@@ -639,7 +616,7 @@
+ */
+
+ #define RTABLE_SHFT(_L) (4 * ((_L) - 1))
+-#define RTABLE_MASK(_L) (UINT64_CAST 0x7 << RTABLE_SHFT(_L))
++#define RTABLE_MASK(_L) (0x7UL << RTABLE_SHFT(_L))
+
+
+ #define ROUTERINFO_STKSZ 4096
+Index: linux-2.6.0-test5/include/asm-ia64/sn/sn2/intr.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/sn/sn2/intr.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/sn/sn2/intr.h 2003-09-27 11:38:40.318399056 +0800
+@@ -17,10 +17,11 @@
+ #define SGI_II_ERROR (0x31)
+ #define SGI_XBOW_ERROR (0x32)
+ #define SGI_PCIBR_ERROR (0x33)
++#define SGI_ACPI_SCI_INT (0x34)
+ #define SGI_XPC_NOTIFY (0xe7)
+
+ #define IA64_SN2_FIRST_DEVICE_VECTOR (0x34)
+-#define IA64_SN2_LAST_DEVICE_VECTOR (0xe6)
++#define IA64_SN2_LAST_DEVICE_VECTOR (0xe7)
+
+ #define SN2_IRQ_RESERVED (0x1)
+ #define SN2_IRQ_CONNECTED (0x2)
+Index: linux-2.6.0-test5/include/asm-ia64/sn/sn2/shub.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/sn/sn2/shub.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/sn/sn2/shub.h 2003-09-27 11:38:40.319398904 +0800
+@@ -11,13 +11,6 @@
+ #ifndef _ASM_IA64_SN_SN2_SHUB_H
+ #define _ASM_IA64_SN_SN2_SHUB_H
+
+-#include <asm/sn/sn2/shub_mmr.h> /* shub mmr addresses and formats */
+-#include <asm/sn/sn2/shub_md.h>
+-#include <asm/sn/sn2/shubio.h>
+-#ifndef __ASSEMBLY__
+-#include <asm/sn/sn2/shub_mmr_t.h> /* shub mmr struct defines */
+-#endif
+-
+ /*
+ * Junk Bus Address Space
+ * The junk bus is used to access the PROM, LED's, and UART. It's
+Index: linux-2.6.0-test5/include/asm-ia64/sn/sn2/shub_mmr_t.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/sn/sn2/shub_mmr_t.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/sn/sn2/shub_mmr_t.h 2003-09-27 11:38:40.579359384 +0800
+@@ -7,8 +7,6 @@
+ * Copyright (c) 2001-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+
+-
+-
+ #ifndef _ASM_IA64_SN_SN2_SHUB_MMR_T_H
+ #define _ASM_IA64_SN_SN2_SHUB_MMR_T_H
+
+@@ -19,7 +17,6 @@
+ /* FSB BINIT# Control */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_fsb_binit_control_u {
+ mmr_t sh_fsb_binit_control_regval;
+ struct {
+@@ -27,22 +24,12 @@
+ mmr_t reserved_0 : 63;
+ } sh_fsb_binit_control_s;
+ } sh_fsb_binit_control_u_t;
+-#else
+-typedef union sh_fsb_binit_control_u {
+- mmr_t sh_fsb_binit_control_regval;
+- struct {
+- mmr_t reserved_0 : 63;
+- mmr_t binit : 1;
+- } sh_fsb_binit_control_s;
+-} sh_fsb_binit_control_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_FSB_RESET_CONTROL" */
+ /* FSB Reset Control */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_fsb_reset_control_u {
+ mmr_t sh_fsb_reset_control_regval;
+ struct {
+@@ -50,22 +37,12 @@
+ mmr_t reserved_0 : 63;
+ } sh_fsb_reset_control_s;
+ } sh_fsb_reset_control_u_t;
+-#else
+-typedef union sh_fsb_reset_control_u {
+- mmr_t sh_fsb_reset_control_regval;
+- struct {
+- mmr_t reserved_0 : 63;
+- mmr_t reset : 1;
+- } sh_fsb_reset_control_s;
+-} sh_fsb_reset_control_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_FSB_SYSTEM_AGENT_CONFIG" */
+ /* FSB System Agent Configuration */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_fsb_system_agent_config_u {
+ mmr_t sh_fsb_system_agent_config_regval;
+ struct {
+@@ -88,37 +65,12 @@
+ mmr_t reserved_3 : 18;
+ } sh_fsb_system_agent_config_s;
+ } sh_fsb_system_agent_config_u_t;
+-#else
+-typedef union sh_fsb_system_agent_config_u {
+- mmr_t sh_fsb_system_agent_config_regval;
+- struct {
+- mmr_t reserved_3 : 18;
+- mmr_t binit_event_enables : 14;
+- mmr_t reserved_2 : 7;
+- mmr_t serialize_fsb_en : 1;
+- mmr_t tdot : 1;
+- mmr_t reserved_1 : 4;
+- mmr_t inta_trans_rsp : 1;
+- mmr_t xtpr_trans_rsp : 1;
+- mmr_t io_trans_rsp : 1;
+- mmr_t inta_rsp_data : 8;
+- mmr_t short_hang_en : 1;
+- mmr_t bnr_throttling_en : 1;
+- mmr_t binit_assert_en : 1;
+- mmr_t berr_sampling_en : 1;
+- mmr_t berr_assert_en : 1;
+- mmr_t reserved_0 : 2;
+- mmr_t rcnt_scnt_en : 1;
+- } sh_fsb_system_agent_config_s;
+-} sh_fsb_system_agent_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_FSB_VGA_REMAP" */
+ /* FSB VGA Address Space Remap */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_fsb_vga_remap_u {
+ mmr_t sh_fsb_vga_remap_regval;
+ struct {
+@@ -131,27 +83,12 @@
+ mmr_t reserved_2 : 1;
+ } sh_fsb_vga_remap_s;
+ } sh_fsb_vga_remap_u_t;
+-#else
+-typedef union sh_fsb_vga_remap_u {
+- mmr_t sh_fsb_vga_remap_regval;
+- struct {
+- mmr_t reserved_2 : 1;
+- mmr_t vga_remapping_enabled : 1;
+- mmr_t reserved_1 : 13;
+- mmr_t nid : 11;
+- mmr_t asid : 2;
+- mmr_t offset : 19;
+- mmr_t reserved_0 : 17;
+- } sh_fsb_vga_remap_s;
+-} sh_fsb_vga_remap_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_FSB_RESET_STATUS" */
+ /* FSB Reset Status */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_fsb_reset_status_u {
+ mmr_t sh_fsb_reset_status_regval;
+ struct {
+@@ -159,22 +96,12 @@
+ mmr_t reserved_0 : 63;
+ } sh_fsb_reset_status_s;
+ } sh_fsb_reset_status_u_t;
+-#else
+-typedef union sh_fsb_reset_status_u {
+- mmr_t sh_fsb_reset_status_regval;
+- struct {
+- mmr_t reserved_0 : 63;
+- mmr_t reset_in_progress : 1;
+- } sh_fsb_reset_status_s;
+-} sh_fsb_reset_status_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_FSB_SYMMETRIC_AGENT_STATUS" */
+ /* FSB Symmetric Agent Status */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_fsb_symmetric_agent_status_u {
+ mmr_t sh_fsb_symmetric_agent_status_regval;
+ struct {
+@@ -184,24 +111,12 @@
+ mmr_t reserved_0 : 61;
+ } sh_fsb_symmetric_agent_status_s;
+ } sh_fsb_symmetric_agent_status_u_t;
+-#else
+-typedef union sh_fsb_symmetric_agent_status_u {
+- mmr_t sh_fsb_symmetric_agent_status_regval;
+- struct {
+- mmr_t reserved_0 : 61;
+- mmr_t cpus_ready : 1;
+- mmr_t cpu_1_active : 1;
+- mmr_t cpu_0_active : 1;
+- } sh_fsb_symmetric_agent_status_s;
+-} sh_fsb_symmetric_agent_status_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_GFX_CREDIT_COUNT_0" */
+ /* Graphics-write Credit Count for CPU 0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gfx_credit_count_0_u {
+ mmr_t sh_gfx_credit_count_0_regval;
+ struct {
+@@ -210,23 +125,12 @@
+ mmr_t reset_gfx_state : 1;
+ } sh_gfx_credit_count_0_s;
+ } sh_gfx_credit_count_0_u_t;
+-#else
+-typedef union sh_gfx_credit_count_0_u {
+- mmr_t sh_gfx_credit_count_0_regval;
+- struct {
+- mmr_t reset_gfx_state : 1;
+- mmr_t reserved_0 : 43;
+- mmr_t count : 20;
+- } sh_gfx_credit_count_0_s;
+-} sh_gfx_credit_count_0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_GFX_CREDIT_COUNT_1" */
+ /* Graphics-write Credit Count for CPU 1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gfx_credit_count_1_u {
+ mmr_t sh_gfx_credit_count_1_regval;
+ struct {
+@@ -235,23 +139,12 @@
+ mmr_t reset_gfx_state : 1;
+ } sh_gfx_credit_count_1_s;
+ } sh_gfx_credit_count_1_u_t;
+-#else
+-typedef union sh_gfx_credit_count_1_u {
+- mmr_t sh_gfx_credit_count_1_regval;
+- struct {
+- mmr_t reset_gfx_state : 1;
+- mmr_t reserved_0 : 43;
+- mmr_t count : 20;
+- } sh_gfx_credit_count_1_s;
+-} sh_gfx_credit_count_1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_GFX_MODE_CNTRL_0" */
+ /* Graphics credit mode amd message ordering for CPU 0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gfx_mode_cntrl_0_u {
+ mmr_t sh_gfx_mode_cntrl_0_regval;
+ struct {
+@@ -261,24 +154,12 @@
+ mmr_t reserved_0 : 61;
+ } sh_gfx_mode_cntrl_0_s;
+ } sh_gfx_mode_cntrl_0_u_t;
+-#else
+-typedef union sh_gfx_mode_cntrl_0_u {
+- mmr_t sh_gfx_mode_cntrl_0_regval;
+- struct {
+- mmr_t reserved_0 : 61;
+- mmr_t relaxed_ordering : 1;
+- mmr_t mixed_mode_credits : 1;
+- mmr_t dword_credits : 1;
+- } sh_gfx_mode_cntrl_0_s;
+-} sh_gfx_mode_cntrl_0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_GFX_MODE_CNTRL_1" */
+ /* Graphics credit mode amd message ordering for CPU 1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gfx_mode_cntrl_1_u {
+ mmr_t sh_gfx_mode_cntrl_1_regval;
+ struct {
+@@ -288,24 +169,12 @@
+ mmr_t reserved_0 : 61;
+ } sh_gfx_mode_cntrl_1_s;
+ } sh_gfx_mode_cntrl_1_u_t;
+-#else
+-typedef union sh_gfx_mode_cntrl_1_u {
+- mmr_t sh_gfx_mode_cntrl_1_regval;
+- struct {
+- mmr_t reserved_0 : 61;
+- mmr_t relaxed_ordering : 1;
+- mmr_t mixed_mode_credits : 1;
+- mmr_t dword_credits : 1;
+- } sh_gfx_mode_cntrl_1_s;
+-} sh_gfx_mode_cntrl_1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_GFX_SKID_CREDIT_COUNT_0" */
+ /* Graphics-write Skid Credit Count for CPU 0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gfx_skid_credit_count_0_u {
+ mmr_t sh_gfx_skid_credit_count_0_regval;
+ struct {
+@@ -313,22 +182,12 @@
+ mmr_t reserved_0 : 44;
+ } sh_gfx_skid_credit_count_0_s;
+ } sh_gfx_skid_credit_count_0_u_t;
+-#else
+-typedef union sh_gfx_skid_credit_count_0_u {
+- mmr_t sh_gfx_skid_credit_count_0_regval;
+- struct {
+- mmr_t reserved_0 : 44;
+- mmr_t skid : 20;
+- } sh_gfx_skid_credit_count_0_s;
+-} sh_gfx_skid_credit_count_0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_GFX_SKID_CREDIT_COUNT_1" */
+ /* Graphics-write Skid Credit Count for CPU 1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gfx_skid_credit_count_1_u {
+ mmr_t sh_gfx_skid_credit_count_1_regval;
+ struct {
+@@ -336,22 +195,12 @@
+ mmr_t reserved_0 : 44;
+ } sh_gfx_skid_credit_count_1_s;
+ } sh_gfx_skid_credit_count_1_u_t;
+-#else
+-typedef union sh_gfx_skid_credit_count_1_u {
+- mmr_t sh_gfx_skid_credit_count_1_regval;
+- struct {
+- mmr_t reserved_0 : 44;
+- mmr_t skid : 20;
+- } sh_gfx_skid_credit_count_1_s;
+-} sh_gfx_skid_credit_count_1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_GFX_STALL_LIMIT_0" */
+ /* Graphics-write Stall Limit for CPU 0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gfx_stall_limit_0_u {
+ mmr_t sh_gfx_stall_limit_0_regval;
+ struct {
+@@ -359,22 +208,12 @@
+ mmr_t reserved_0 : 38;
+ } sh_gfx_stall_limit_0_s;
+ } sh_gfx_stall_limit_0_u_t;
+-#else
+-typedef union sh_gfx_stall_limit_0_u {
+- mmr_t sh_gfx_stall_limit_0_regval;
+- struct {
+- mmr_t reserved_0 : 38;
+- mmr_t limit : 26;
+- } sh_gfx_stall_limit_0_s;
+-} sh_gfx_stall_limit_0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_GFX_STALL_LIMIT_1" */
+ /* Graphics-write Stall Limit for CPU 1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gfx_stall_limit_1_u {
+ mmr_t sh_gfx_stall_limit_1_regval;
+ struct {
+@@ -382,22 +221,12 @@
+ mmr_t reserved_0 : 38;
+ } sh_gfx_stall_limit_1_s;
+ } sh_gfx_stall_limit_1_u_t;
+-#else
+-typedef union sh_gfx_stall_limit_1_u {
+- mmr_t sh_gfx_stall_limit_1_regval;
+- struct {
+- mmr_t reserved_0 : 38;
+- mmr_t limit : 26;
+- } sh_gfx_stall_limit_1_s;
+-} sh_gfx_stall_limit_1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_GFX_STALL_TIMER_0" */
+ /* Graphics-write Stall Timer for CPU 0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gfx_stall_timer_0_u {
+ mmr_t sh_gfx_stall_timer_0_regval;
+ struct {
+@@ -405,22 +234,12 @@
+ mmr_t reserved_0 : 38;
+ } sh_gfx_stall_timer_0_s;
+ } sh_gfx_stall_timer_0_u_t;
+-#else
+-typedef union sh_gfx_stall_timer_0_u {
+- mmr_t sh_gfx_stall_timer_0_regval;
+- struct {
+- mmr_t reserved_0 : 38;
+- mmr_t timer_value : 26;
+- } sh_gfx_stall_timer_0_s;
+-} sh_gfx_stall_timer_0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_GFX_STALL_TIMER_1" */
+ /* Graphics-write Stall Timer for CPU 1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gfx_stall_timer_1_u {
+ mmr_t sh_gfx_stall_timer_1_regval;
+ struct {
+@@ -428,22 +247,12 @@
+ mmr_t reserved_0 : 38;
+ } sh_gfx_stall_timer_1_s;
+ } sh_gfx_stall_timer_1_u_t;
+-#else
+-typedef union sh_gfx_stall_timer_1_u {
+- mmr_t sh_gfx_stall_timer_1_regval;
+- struct {
+- mmr_t reserved_0 : 38;
+- mmr_t timer_value : 26;
+- } sh_gfx_stall_timer_1_s;
+-} sh_gfx_stall_timer_1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_GFX_WINDOW_0" */
+ /* Graphics-write Window for CPU 0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gfx_window_0_u {
+ mmr_t sh_gfx_window_0_regval;
+ struct {
+@@ -453,24 +262,12 @@
+ mmr_t gfx_window_en : 1;
+ } sh_gfx_window_0_s;
+ } sh_gfx_window_0_u_t;
+-#else
+-typedef union sh_gfx_window_0_u {
+- mmr_t sh_gfx_window_0_regval;
+- struct {
+- mmr_t gfx_window_en : 1;
+- mmr_t reserved_1 : 27;
+- mmr_t base_addr : 12;
+- mmr_t reserved_0 : 24;
+- } sh_gfx_window_0_s;
+-} sh_gfx_window_0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_GFX_WINDOW_1" */
+ /* Graphics-write Window for CPU 1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gfx_window_1_u {
+ mmr_t sh_gfx_window_1_regval;
+ struct {
+@@ -480,24 +277,12 @@
+ mmr_t gfx_window_en : 1;
+ } sh_gfx_window_1_s;
+ } sh_gfx_window_1_u_t;
+-#else
+-typedef union sh_gfx_window_1_u {
+- mmr_t sh_gfx_window_1_regval;
+- struct {
+- mmr_t gfx_window_en : 1;
+- mmr_t reserved_1 : 27;
+- mmr_t base_addr : 12;
+- mmr_t reserved_0 : 24;
+- } sh_gfx_window_1_s;
+-} sh_gfx_window_1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_GFX_INTERRUPT_TIMER_LIMIT_0" */
+ /* Graphics-write Interrupt Limit for CPU 0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gfx_interrupt_timer_limit_0_u {
+ mmr_t sh_gfx_interrupt_timer_limit_0_regval;
+ struct {
+@@ -505,22 +290,12 @@
+ mmr_t reserved_0 : 56;
+ } sh_gfx_interrupt_timer_limit_0_s;
+ } sh_gfx_interrupt_timer_limit_0_u_t;
+-#else
+-typedef union sh_gfx_interrupt_timer_limit_0_u {
+- mmr_t sh_gfx_interrupt_timer_limit_0_regval;
+- struct {
+- mmr_t reserved_0 : 56;
+- mmr_t interrupt_timer_limit : 8;
+- } sh_gfx_interrupt_timer_limit_0_s;
+-} sh_gfx_interrupt_timer_limit_0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_GFX_INTERRUPT_TIMER_LIMIT_1" */
+ /* Graphics-write Interrupt Limit for CPU 1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gfx_interrupt_timer_limit_1_u {
+ mmr_t sh_gfx_interrupt_timer_limit_1_regval;
+ struct {
+@@ -528,22 +303,12 @@
+ mmr_t reserved_0 : 56;
+ } sh_gfx_interrupt_timer_limit_1_s;
+ } sh_gfx_interrupt_timer_limit_1_u_t;
+-#else
+-typedef union sh_gfx_interrupt_timer_limit_1_u {
+- mmr_t sh_gfx_interrupt_timer_limit_1_regval;
+- struct {
+- mmr_t reserved_0 : 56;
+- mmr_t interrupt_timer_limit : 8;
+- } sh_gfx_interrupt_timer_limit_1_s;
+-} sh_gfx_interrupt_timer_limit_1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_GFX_WRITE_STATUS_0" */
+ /* Graphics Write Status for CPU 0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gfx_write_status_0_u {
+ mmr_t sh_gfx_write_status_0_regval;
+ struct {
+@@ -552,23 +317,12 @@
+ mmr_t re_enable_gfx_stall : 1;
+ } sh_gfx_write_status_0_s;
+ } sh_gfx_write_status_0_u_t;
+-#else
+-typedef union sh_gfx_write_status_0_u {
+- mmr_t sh_gfx_write_status_0_regval;
+- struct {
+- mmr_t re_enable_gfx_stall : 1;
+- mmr_t reserved_0 : 62;
+- mmr_t busy : 1;
+- } sh_gfx_write_status_0_s;
+-} sh_gfx_write_status_0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_GFX_WRITE_STATUS_1" */
+ /* Graphics Write Status for CPU 1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gfx_write_status_1_u {
+ mmr_t sh_gfx_write_status_1_regval;
+ struct {
+@@ -577,23 +331,12 @@
+ mmr_t re_enable_gfx_stall : 1;
+ } sh_gfx_write_status_1_s;
+ } sh_gfx_write_status_1_u_t;
+-#else
+-typedef union sh_gfx_write_status_1_u {
+- mmr_t sh_gfx_write_status_1_regval;
+- struct {
+- mmr_t re_enable_gfx_stall : 1;
+- mmr_t reserved_0 : 62;
+- mmr_t busy : 1;
+- } sh_gfx_write_status_1_s;
+-} sh_gfx_write_status_1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_II_INT0" */
+ /* SHub II Interrupt 0 Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ii_int0_u {
+ mmr_t sh_ii_int0_regval;
+ struct {
+@@ -602,23 +345,12 @@
+ mmr_t reserved_0 : 55;
+ } sh_ii_int0_s;
+ } sh_ii_int0_u_t;
+-#else
+-typedef union sh_ii_int0_u {
+- mmr_t sh_ii_int0_regval;
+- struct {
+- mmr_t reserved_0 : 55;
+- mmr_t send : 1;
+- mmr_t idx : 8;
+- } sh_ii_int0_s;
+-} sh_ii_int0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_II_INT0_CONFIG" */
+ /* SHub II Interrupt 0 Config Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ii_int0_config_u {
+ mmr_t sh_ii_int0_config_regval;
+ struct {
+@@ -630,26 +362,12 @@
+ mmr_t reserved_1 : 14;
+ } sh_ii_int0_config_s;
+ } sh_ii_int0_config_u_t;
+-#else
+-typedef union sh_ii_int0_config_u {
+- mmr_t sh_ii_int0_config_regval;
+- struct {
+- mmr_t reserved_1 : 14;
+- mmr_t base : 29;
+- mmr_t reserved_0 : 1;
+- mmr_t pid : 16;
+- mmr_t agt : 1;
+- mmr_t type : 3;
+- } sh_ii_int0_config_s;
+-} sh_ii_int0_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_II_INT0_ENABLE" */
+ /* SHub II Interrupt 0 Enable Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ii_int0_enable_u {
+ mmr_t sh_ii_int0_enable_regval;
+ struct {
+@@ -657,22 +375,12 @@
+ mmr_t reserved_0 : 63;
+ } sh_ii_int0_enable_s;
+ } sh_ii_int0_enable_u_t;
+-#else
+-typedef union sh_ii_int0_enable_u {
+- mmr_t sh_ii_int0_enable_regval;
+- struct {
+- mmr_t reserved_0 : 63;
+- mmr_t ii_enable : 1;
+- } sh_ii_int0_enable_s;
+-} sh_ii_int0_enable_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_II_INT1" */
+ /* SHub II Interrupt 1 Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ii_int1_u {
+ mmr_t sh_ii_int1_regval;
+ struct {
+@@ -681,23 +389,12 @@
+ mmr_t reserved_0 : 55;
+ } sh_ii_int1_s;
+ } sh_ii_int1_u_t;
+-#else
+-typedef union sh_ii_int1_u {
+- mmr_t sh_ii_int1_regval;
+- struct {
+- mmr_t reserved_0 : 55;
+- mmr_t send : 1;
+- mmr_t idx : 8;
+- } sh_ii_int1_s;
+-} sh_ii_int1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_II_INT1_CONFIG" */
+ /* SHub II Interrupt 1 Config Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ii_int1_config_u {
+ mmr_t sh_ii_int1_config_regval;
+ struct {
+@@ -709,26 +406,12 @@
+ mmr_t reserved_1 : 14;
+ } sh_ii_int1_config_s;
+ } sh_ii_int1_config_u_t;
+-#else
+-typedef union sh_ii_int1_config_u {
+- mmr_t sh_ii_int1_config_regval;
+- struct {
+- mmr_t reserved_1 : 14;
+- mmr_t base : 29;
+- mmr_t reserved_0 : 1;
+- mmr_t pid : 16;
+- mmr_t agt : 1;
+- mmr_t type : 3;
+- } sh_ii_int1_config_s;
+-} sh_ii_int1_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_II_INT1_ENABLE" */
+ /* SHub II Interrupt 1 Enable Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ii_int1_enable_u {
+ mmr_t sh_ii_int1_enable_regval;
+ struct {
+@@ -736,22 +419,12 @@
+ mmr_t reserved_0 : 63;
+ } sh_ii_int1_enable_s;
+ } sh_ii_int1_enable_u_t;
+-#else
+-typedef union sh_ii_int1_enable_u {
+- mmr_t sh_ii_int1_enable_regval;
+- struct {
+- mmr_t reserved_0 : 63;
+- mmr_t ii_enable : 1;
+- } sh_ii_int1_enable_s;
+-} sh_ii_int1_enable_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_INT_NODE_ID_CONFIG" */
+ /* SHub Interrupt Node ID Configuration */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_int_node_id_config_u {
+ mmr_t sh_int_node_id_config_regval;
+ struct {
+@@ -760,23 +433,12 @@
+ mmr_t reserved_0 : 52;
+ } sh_int_node_id_config_s;
+ } sh_int_node_id_config_u_t;
+-#else
+-typedef union sh_int_node_id_config_u {
+- mmr_t sh_int_node_id_config_regval;
+- struct {
+- mmr_t reserved_0 : 52;
+- mmr_t id_sel : 1;
+- mmr_t node_id : 11;
+- } sh_int_node_id_config_s;
+-} sh_int_node_id_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_IPI_INT" */
+ /* SHub Inter-Processor Interrupt Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ipi_int_u {
+ mmr_t sh_ipi_int_regval;
+ struct {
+@@ -791,29 +453,12 @@
+ mmr_t send : 1;
+ } sh_ipi_int_s;
+ } sh_ipi_int_u_t;
+-#else
+-typedef union sh_ipi_int_u {
+- mmr_t sh_ipi_int_regval;
+- struct {
+- mmr_t send : 1;
+- mmr_t reserved_2 : 3;
+- mmr_t idx : 8;
+- mmr_t reserved_1 : 2;
+- mmr_t base : 29;
+- mmr_t reserved_0 : 1;
+- mmr_t pid : 16;
+- mmr_t agt : 1;
+- mmr_t type : 3;
+- } sh_ipi_int_s;
+-} sh_ipi_int_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_IPI_INT_ENABLE" */
+ /* SHub Inter-Processor Interrupt Enable Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ipi_int_enable_u {
+ mmr_t sh_ipi_int_enable_regval;
+ struct {
+@@ -821,22 +466,12 @@
+ mmr_t reserved_0 : 63;
+ } sh_ipi_int_enable_s;
+ } sh_ipi_int_enable_u_t;
+-#else
+-typedef union sh_ipi_int_enable_u {
+- mmr_t sh_ipi_int_enable_regval;
+- struct {
+- mmr_t reserved_0 : 63;
+- mmr_t pio_enable : 1;
+- } sh_ipi_int_enable_s;
+-} sh_ipi_int_enable_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LOCAL_INT0_CONFIG" */
+ /* SHub Local Interrupt 0 Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_local_int0_config_u {
+ mmr_t sh_local_int0_config_regval;
+ struct {
+@@ -850,28 +485,12 @@
+ mmr_t reserved_2 : 4;
+ } sh_local_int0_config_s;
+ } sh_local_int0_config_u_t;
+-#else
+-typedef union sh_local_int0_config_u {
+- mmr_t sh_local_int0_config_regval;
+- struct {
+- mmr_t reserved_2 : 4;
+- mmr_t idx : 8;
+- mmr_t reserved_1 : 2;
+- mmr_t base : 29;
+- mmr_t reserved_0 : 1;
+- mmr_t pid : 16;
+- mmr_t agt : 1;
+- mmr_t type : 3;
+- } sh_local_int0_config_s;
+-} sh_local_int0_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LOCAL_INT0_ENABLE" */
+ /* SHub Local Interrupt 0 Enable */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_local_int0_enable_u {
+ mmr_t sh_local_int0_enable_regval;
+ struct {
+@@ -894,37 +513,12 @@
+ mmr_t reserved_1 : 48;
+ } sh_local_int0_enable_s;
+ } sh_local_int0_enable_u_t;
+-#else
+-typedef union sh_local_int0_enable_u {
+- mmr_t sh_local_int0_enable_regval;
+- struct {
+- mmr_t reserved_1 : 48;
+- mmr_t stop_clock : 1;
+- mmr_t l1_nmi_int : 1;
+- mmr_t uart_int : 1;
+- mmr_t system_shutdown_int : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t xn_uce_int : 1;
+- mmr_t md_uce_int : 1;
+- mmr_t pi_uce_int : 1;
+- mmr_t xn_ce_int : 1;
+- mmr_t md_ce_int : 1;
+- mmr_t pi_ce_int : 1;
+- mmr_t ii_hw_int : 1;
+- mmr_t lb_hw_int : 1;
+- mmr_t xn_hw_int : 1;
+- mmr_t md_hw_int : 1;
+- mmr_t pi_hw_int : 1;
+- } sh_local_int0_enable_s;
+-} sh_local_int0_enable_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LOCAL_INT1_CONFIG" */
+ /* SHub Local Interrupt 1 Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_local_int1_config_u {
+ mmr_t sh_local_int1_config_regval;
+ struct {
+@@ -938,28 +532,12 @@
+ mmr_t reserved_2 : 4;
+ } sh_local_int1_config_s;
+ } sh_local_int1_config_u_t;
+-#else
+-typedef union sh_local_int1_config_u {
+- mmr_t sh_local_int1_config_regval;
+- struct {
+- mmr_t reserved_2 : 4;
+- mmr_t idx : 8;
+- mmr_t reserved_1 : 2;
+- mmr_t base : 29;
+- mmr_t reserved_0 : 1;
+- mmr_t pid : 16;
+- mmr_t agt : 1;
+- mmr_t type : 3;
+- } sh_local_int1_config_s;
+-} sh_local_int1_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LOCAL_INT1_ENABLE" */
+ /* SHub Local Interrupt 1 Enable */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_local_int1_enable_u {
+ mmr_t sh_local_int1_enable_regval;
+ struct {
+@@ -982,37 +560,12 @@
+ mmr_t reserved_1 : 48;
+ } sh_local_int1_enable_s;
+ } sh_local_int1_enable_u_t;
+-#else
+-typedef union sh_local_int1_enable_u {
+- mmr_t sh_local_int1_enable_regval;
+- struct {
+- mmr_t reserved_1 : 48;
+- mmr_t stop_clock : 1;
+- mmr_t l1_nmi_int : 1;
+- mmr_t uart_int : 1;
+- mmr_t system_shutdown_int : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t xn_uce_int : 1;
+- mmr_t md_uce_int : 1;
+- mmr_t pi_uce_int : 1;
+- mmr_t xn_ce_int : 1;
+- mmr_t md_ce_int : 1;
+- mmr_t pi_ce_int : 1;
+- mmr_t ii_hw_int : 1;
+- mmr_t lb_hw_int : 1;
+- mmr_t xn_hw_int : 1;
+- mmr_t md_hw_int : 1;
+- mmr_t pi_hw_int : 1;
+- } sh_local_int1_enable_s;
+-} sh_local_int1_enable_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LOCAL_INT2_CONFIG" */
+ /* SHub Local Interrupt 2 Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_local_int2_config_u {
+ mmr_t sh_local_int2_config_regval;
+ struct {
+@@ -1026,28 +579,12 @@
+ mmr_t reserved_2 : 4;
+ } sh_local_int2_config_s;
+ } sh_local_int2_config_u_t;
+-#else
+-typedef union sh_local_int2_config_u {
+- mmr_t sh_local_int2_config_regval;
+- struct {
+- mmr_t reserved_2 : 4;
+- mmr_t idx : 8;
+- mmr_t reserved_1 : 2;
+- mmr_t base : 29;
+- mmr_t reserved_0 : 1;
+- mmr_t pid : 16;
+- mmr_t agt : 1;
+- mmr_t type : 3;
+- } sh_local_int2_config_s;
+-} sh_local_int2_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LOCAL_INT2_ENABLE" */
+ /* SHub Local Interrupt 2 Enable */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_local_int2_enable_u {
+ mmr_t sh_local_int2_enable_regval;
+ struct {
+@@ -1070,37 +607,12 @@
+ mmr_t reserved_1 : 48;
+ } sh_local_int2_enable_s;
+ } sh_local_int2_enable_u_t;
+-#else
+-typedef union sh_local_int2_enable_u {
+- mmr_t sh_local_int2_enable_regval;
+- struct {
+- mmr_t reserved_1 : 48;
+- mmr_t stop_clock : 1;
+- mmr_t l1_nmi_int : 1;
+- mmr_t uart_int : 1;
+- mmr_t system_shutdown_int : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t xn_uce_int : 1;
+- mmr_t md_uce_int : 1;
+- mmr_t pi_uce_int : 1;
+- mmr_t xn_ce_int : 1;
+- mmr_t md_ce_int : 1;
+- mmr_t pi_ce_int : 1;
+- mmr_t ii_hw_int : 1;
+- mmr_t lb_hw_int : 1;
+- mmr_t xn_hw_int : 1;
+- mmr_t md_hw_int : 1;
+- mmr_t pi_hw_int : 1;
+- } sh_local_int2_enable_s;
+-} sh_local_int2_enable_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LOCAL_INT3_CONFIG" */
+ /* SHub Local Interrupt 3 Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_local_int3_config_u {
+ mmr_t sh_local_int3_config_regval;
+ struct {
+@@ -1114,28 +626,12 @@
+ mmr_t reserved_2 : 4;
+ } sh_local_int3_config_s;
+ } sh_local_int3_config_u_t;
+-#else
+-typedef union sh_local_int3_config_u {
+- mmr_t sh_local_int3_config_regval;
+- struct {
+- mmr_t reserved_2 : 4;
+- mmr_t idx : 8;
+- mmr_t reserved_1 : 2;
+- mmr_t base : 29;
+- mmr_t reserved_0 : 1;
+- mmr_t pid : 16;
+- mmr_t agt : 1;
+- mmr_t type : 3;
+- } sh_local_int3_config_s;
+-} sh_local_int3_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LOCAL_INT3_ENABLE" */
+ /* SHub Local Interrupt 3 Enable */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_local_int3_enable_u {
+ mmr_t sh_local_int3_enable_regval;
+ struct {
+@@ -1158,37 +654,12 @@
+ mmr_t reserved_1 : 48;
+ } sh_local_int3_enable_s;
+ } sh_local_int3_enable_u_t;
+-#else
+-typedef union sh_local_int3_enable_u {
+- mmr_t sh_local_int3_enable_regval;
+- struct {
+- mmr_t reserved_1 : 48;
+- mmr_t stop_clock : 1;
+- mmr_t l1_nmi_int : 1;
+- mmr_t uart_int : 1;
+- mmr_t system_shutdown_int : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t xn_uce_int : 1;
+- mmr_t md_uce_int : 1;
+- mmr_t pi_uce_int : 1;
+- mmr_t xn_ce_int : 1;
+- mmr_t md_ce_int : 1;
+- mmr_t pi_ce_int : 1;
+- mmr_t ii_hw_int : 1;
+- mmr_t lb_hw_int : 1;
+- mmr_t xn_hw_int : 1;
+- mmr_t md_hw_int : 1;
+- mmr_t pi_hw_int : 1;
+- } sh_local_int3_enable_s;
+-} sh_local_int3_enable_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LOCAL_INT4_CONFIG" */
+ /* SHub Local Interrupt 4 Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_local_int4_config_u {
+ mmr_t sh_local_int4_config_regval;
+ struct {
+@@ -1202,28 +673,12 @@
+ mmr_t reserved_2 : 4;
+ } sh_local_int4_config_s;
+ } sh_local_int4_config_u_t;
+-#else
+-typedef union sh_local_int4_config_u {
+- mmr_t sh_local_int4_config_regval;
+- struct {
+- mmr_t reserved_2 : 4;
+- mmr_t idx : 8;
+- mmr_t reserved_1 : 2;
+- mmr_t base : 29;
+- mmr_t reserved_0 : 1;
+- mmr_t pid : 16;
+- mmr_t agt : 1;
+- mmr_t type : 3;
+- } sh_local_int4_config_s;
+-} sh_local_int4_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LOCAL_INT4_ENABLE" */
+ /* SHub Local Interrupt 4 Enable */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_local_int4_enable_u {
+ mmr_t sh_local_int4_enable_regval;
+ struct {
+@@ -1246,37 +701,12 @@
+ mmr_t reserved_1 : 48;
+ } sh_local_int4_enable_s;
+ } sh_local_int4_enable_u_t;
+-#else
+-typedef union sh_local_int4_enable_u {
+- mmr_t sh_local_int4_enable_regval;
+- struct {
+- mmr_t reserved_1 : 48;
+- mmr_t stop_clock : 1;
+- mmr_t l1_nmi_int : 1;
+- mmr_t uart_int : 1;
+- mmr_t system_shutdown_int : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t xn_uce_int : 1;
+- mmr_t md_uce_int : 1;
+- mmr_t pi_uce_int : 1;
+- mmr_t xn_ce_int : 1;
+- mmr_t md_ce_int : 1;
+- mmr_t pi_ce_int : 1;
+- mmr_t ii_hw_int : 1;
+- mmr_t lb_hw_int : 1;
+- mmr_t xn_hw_int : 1;
+- mmr_t md_hw_int : 1;
+- mmr_t pi_hw_int : 1;
+- } sh_local_int4_enable_s;
+-} sh_local_int4_enable_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LOCAL_INT5_CONFIG" */
+ /* SHub Local Interrupt 5 Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_local_int5_config_u {
+ mmr_t sh_local_int5_config_regval;
+ struct {
+@@ -1290,28 +720,12 @@
+ mmr_t reserved_2 : 4;
+ } sh_local_int5_config_s;
+ } sh_local_int5_config_u_t;
+-#else
+-typedef union sh_local_int5_config_u {
+- mmr_t sh_local_int5_config_regval;
+- struct {
+- mmr_t reserved_2 : 4;
+- mmr_t idx : 8;
+- mmr_t reserved_1 : 2;
+- mmr_t base : 29;
+- mmr_t reserved_0 : 1;
+- mmr_t pid : 16;
+- mmr_t agt : 1;
+- mmr_t type : 3;
+- } sh_local_int5_config_s;
+-} sh_local_int5_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LOCAL_INT5_ENABLE" */
+ /* SHub Local Interrupt 5 Enable */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_local_int5_enable_u {
+ mmr_t sh_local_int5_enable_regval;
+ struct {
+@@ -1334,37 +748,12 @@
+ mmr_t reserved_1 : 48;
+ } sh_local_int5_enable_s;
+ } sh_local_int5_enable_u_t;
+-#else
+-typedef union sh_local_int5_enable_u {
+- mmr_t sh_local_int5_enable_regval;
+- struct {
+- mmr_t reserved_1 : 48;
+- mmr_t stop_clock : 1;
+- mmr_t l1_nmi_int : 1;
+- mmr_t uart_int : 1;
+- mmr_t system_shutdown_int : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t xn_uce_int : 1;
+- mmr_t md_uce_int : 1;
+- mmr_t pi_uce_int : 1;
+- mmr_t xn_ce_int : 1;
+- mmr_t md_ce_int : 1;
+- mmr_t pi_ce_int : 1;
+- mmr_t ii_hw_int : 1;
+- mmr_t lb_hw_int : 1;
+- mmr_t xn_hw_int : 1;
+- mmr_t md_hw_int : 1;
+- mmr_t pi_hw_int : 1;
+- } sh_local_int5_enable_s;
+-} sh_local_int5_enable_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PROC0_ERR_INT_CONFIG" */
+ /* SHub Processor 0 Error Interrupt Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc0_err_int_config_u {
+ mmr_t sh_proc0_err_int_config_regval;
+ struct {
+@@ -1378,28 +767,12 @@
+ mmr_t reserved_2 : 4;
+ } sh_proc0_err_int_config_s;
+ } sh_proc0_err_int_config_u_t;
+-#else
+-typedef union sh_proc0_err_int_config_u {
+- mmr_t sh_proc0_err_int_config_regval;
+- struct {
+- mmr_t reserved_2 : 4;
+- mmr_t idx : 8;
+- mmr_t reserved_1 : 2;
+- mmr_t base : 29;
+- mmr_t reserved_0 : 1;
+- mmr_t pid : 16;
+- mmr_t agt : 1;
+- mmr_t type : 3;
+- } sh_proc0_err_int_config_s;
+-} sh_proc0_err_int_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PROC1_ERR_INT_CONFIG" */
+ /* SHub Processor 1 Error Interrupt Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc1_err_int_config_u {
+ mmr_t sh_proc1_err_int_config_regval;
+ struct {
+@@ -1413,28 +786,12 @@
+ mmr_t reserved_2 : 4;
+ } sh_proc1_err_int_config_s;
+ } sh_proc1_err_int_config_u_t;
+-#else
+-typedef union sh_proc1_err_int_config_u {
+- mmr_t sh_proc1_err_int_config_regval;
+- struct {
+- mmr_t reserved_2 : 4;
+- mmr_t idx : 8;
+- mmr_t reserved_1 : 2;
+- mmr_t base : 29;
+- mmr_t reserved_0 : 1;
+- mmr_t pid : 16;
+- mmr_t agt : 1;
+- mmr_t type : 3;
+- } sh_proc1_err_int_config_s;
+-} sh_proc1_err_int_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PROC2_ERR_INT_CONFIG" */
+ /* SHub Processor 2 Error Interrupt Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc2_err_int_config_u {
+ mmr_t sh_proc2_err_int_config_regval;
+ struct {
+@@ -1448,28 +805,12 @@
+ mmr_t reserved_2 : 4;
+ } sh_proc2_err_int_config_s;
+ } sh_proc2_err_int_config_u_t;
+-#else
+-typedef union sh_proc2_err_int_config_u {
+- mmr_t sh_proc2_err_int_config_regval;
+- struct {
+- mmr_t reserved_2 : 4;
+- mmr_t idx : 8;
+- mmr_t reserved_1 : 2;
+- mmr_t base : 29;
+- mmr_t reserved_0 : 1;
+- mmr_t pid : 16;
+- mmr_t agt : 1;
+- mmr_t type : 3;
+- } sh_proc2_err_int_config_s;
+-} sh_proc2_err_int_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PROC3_ERR_INT_CONFIG" */
+ /* SHub Processor 3 Error Interrupt Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc3_err_int_config_u {
+ mmr_t sh_proc3_err_int_config_regval;
+ struct {
+@@ -1483,28 +824,12 @@
+ mmr_t reserved_2 : 4;
+ } sh_proc3_err_int_config_s;
+ } sh_proc3_err_int_config_u_t;
+-#else
+-typedef union sh_proc3_err_int_config_u {
+- mmr_t sh_proc3_err_int_config_regval;
+- struct {
+- mmr_t reserved_2 : 4;
+- mmr_t idx : 8;
+- mmr_t reserved_1 : 2;
+- mmr_t base : 29;
+- mmr_t reserved_0 : 1;
+- mmr_t pid : 16;
+- mmr_t agt : 1;
+- mmr_t type : 3;
+- } sh_proc3_err_int_config_s;
+-} sh_proc3_err_int_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PROC0_ADV_INT_CONFIG" */
+ /* SHub Processor 0 Advisory Interrupt Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc0_adv_int_config_u {
+ mmr_t sh_proc0_adv_int_config_regval;
+ struct {
+@@ -1518,28 +843,12 @@
+ mmr_t reserved_2 : 4;
+ } sh_proc0_adv_int_config_s;
+ } sh_proc0_adv_int_config_u_t;
+-#else
+-typedef union sh_proc0_adv_int_config_u {
+- mmr_t sh_proc0_adv_int_config_regval;
+- struct {
+- mmr_t reserved_2 : 4;
+- mmr_t idx : 8;
+- mmr_t reserved_1 : 2;
+- mmr_t base : 29;
+- mmr_t reserved_0 : 1;
+- mmr_t pid : 16;
+- mmr_t agt : 1;
+- mmr_t type : 3;
+- } sh_proc0_adv_int_config_s;
+-} sh_proc0_adv_int_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PROC1_ADV_INT_CONFIG" */
+ /* SHub Processor 1 Advisory Interrupt Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc1_adv_int_config_u {
+ mmr_t sh_proc1_adv_int_config_regval;
+ struct {
+@@ -1553,28 +862,12 @@
+ mmr_t reserved_2 : 4;
+ } sh_proc1_adv_int_config_s;
+ } sh_proc1_adv_int_config_u_t;
+-#else
+-typedef union sh_proc1_adv_int_config_u {
+- mmr_t sh_proc1_adv_int_config_regval;
+- struct {
+- mmr_t reserved_2 : 4;
+- mmr_t idx : 8;
+- mmr_t reserved_1 : 2;
+- mmr_t base : 29;
+- mmr_t reserved_0 : 1;
+- mmr_t pid : 16;
+- mmr_t agt : 1;
+- mmr_t type : 3;
+- } sh_proc1_adv_int_config_s;
+-} sh_proc1_adv_int_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PROC2_ADV_INT_CONFIG" */
+ /* SHub Processor 2 Advisory Interrupt Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc2_adv_int_config_u {
+ mmr_t sh_proc2_adv_int_config_regval;
+ struct {
+@@ -1588,28 +881,12 @@
+ mmr_t reserved_2 : 4;
+ } sh_proc2_adv_int_config_s;
+ } sh_proc2_adv_int_config_u_t;
+-#else
+-typedef union sh_proc2_adv_int_config_u {
+- mmr_t sh_proc2_adv_int_config_regval;
+- struct {
+- mmr_t reserved_2 : 4;
+- mmr_t idx : 8;
+- mmr_t reserved_1 : 2;
+- mmr_t base : 29;
+- mmr_t reserved_0 : 1;
+- mmr_t pid : 16;
+- mmr_t agt : 1;
+- mmr_t type : 3;
+- } sh_proc2_adv_int_config_s;
+-} sh_proc2_adv_int_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PROC3_ADV_INT_CONFIG" */
+ /* SHub Processor 3 Advisory Interrupt Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc3_adv_int_config_u {
+ mmr_t sh_proc3_adv_int_config_regval;
+ struct {
+@@ -1623,28 +900,12 @@
+ mmr_t reserved_2 : 4;
+ } sh_proc3_adv_int_config_s;
+ } sh_proc3_adv_int_config_u_t;
+-#else
+-typedef union sh_proc3_adv_int_config_u {
+- mmr_t sh_proc3_adv_int_config_regval;
+- struct {
+- mmr_t reserved_2 : 4;
+- mmr_t idx : 8;
+- mmr_t reserved_1 : 2;
+- mmr_t base : 29;
+- mmr_t reserved_0 : 1;
+- mmr_t pid : 16;
+- mmr_t agt : 1;
+- mmr_t type : 3;
+- } sh_proc3_adv_int_config_s;
+-} sh_proc3_adv_int_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PROC0_ERR_INT_ENABLE" */
+ /* SHub Processor 0 Error Interrupt Enable Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc0_err_int_enable_u {
+ mmr_t sh_proc0_err_int_enable_regval;
+ struct {
+@@ -1652,22 +913,12 @@
+ mmr_t reserved_0 : 63;
+ } sh_proc0_err_int_enable_s;
+ } sh_proc0_err_int_enable_u_t;
+-#else
+-typedef union sh_proc0_err_int_enable_u {
+- mmr_t sh_proc0_err_int_enable_regval;
+- struct {
+- mmr_t reserved_0 : 63;
+- mmr_t proc0_err_enable : 1;
+- } sh_proc0_err_int_enable_s;
+-} sh_proc0_err_int_enable_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PROC1_ERR_INT_ENABLE" */
+ /* SHub Processor 1 Error Interrupt Enable Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc1_err_int_enable_u {
+ mmr_t sh_proc1_err_int_enable_regval;
+ struct {
+@@ -1675,22 +926,12 @@
+ mmr_t reserved_0 : 63;
+ } sh_proc1_err_int_enable_s;
+ } sh_proc1_err_int_enable_u_t;
+-#else
+-typedef union sh_proc1_err_int_enable_u {
+- mmr_t sh_proc1_err_int_enable_regval;
+- struct {
+- mmr_t reserved_0 : 63;
+- mmr_t proc1_err_enable : 1;
+- } sh_proc1_err_int_enable_s;
+-} sh_proc1_err_int_enable_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PROC2_ERR_INT_ENABLE" */
+ /* SHub Processor 2 Error Interrupt Enable Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc2_err_int_enable_u {
+ mmr_t sh_proc2_err_int_enable_regval;
+ struct {
+@@ -1698,22 +939,12 @@
+ mmr_t reserved_0 : 63;
+ } sh_proc2_err_int_enable_s;
+ } sh_proc2_err_int_enable_u_t;
+-#else
+-typedef union sh_proc2_err_int_enable_u {
+- mmr_t sh_proc2_err_int_enable_regval;
+- struct {
+- mmr_t reserved_0 : 63;
+- mmr_t proc2_err_enable : 1;
+- } sh_proc2_err_int_enable_s;
+-} sh_proc2_err_int_enable_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PROC3_ERR_INT_ENABLE" */
+ /* SHub Processor 3 Error Interrupt Enable Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc3_err_int_enable_u {
+ mmr_t sh_proc3_err_int_enable_regval;
+ struct {
+@@ -1721,22 +952,12 @@
+ mmr_t reserved_0 : 63;
+ } sh_proc3_err_int_enable_s;
+ } sh_proc3_err_int_enable_u_t;
+-#else
+-typedef union sh_proc3_err_int_enable_u {
+- mmr_t sh_proc3_err_int_enable_regval;
+- struct {
+- mmr_t reserved_0 : 63;
+- mmr_t proc3_err_enable : 1;
+- } sh_proc3_err_int_enable_s;
+-} sh_proc3_err_int_enable_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PROC0_ADV_INT_ENABLE" */
+ /* SHub Processor 0 Advisory Interrupt Enable Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc0_adv_int_enable_u {
+ mmr_t sh_proc0_adv_int_enable_regval;
+ struct {
+@@ -1744,22 +965,12 @@
+ mmr_t reserved_0 : 63;
+ } sh_proc0_adv_int_enable_s;
+ } sh_proc0_adv_int_enable_u_t;
+-#else
+-typedef union sh_proc0_adv_int_enable_u {
+- mmr_t sh_proc0_adv_int_enable_regval;
+- struct {
+- mmr_t reserved_0 : 63;
+- mmr_t proc0_adv_enable : 1;
+- } sh_proc0_adv_int_enable_s;
+-} sh_proc0_adv_int_enable_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PROC1_ADV_INT_ENABLE" */
+ /* SHub Processor 1 Advisory Interrupt Enable Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc1_adv_int_enable_u {
+ mmr_t sh_proc1_adv_int_enable_regval;
+ struct {
+@@ -1767,22 +978,12 @@
+ mmr_t reserved_0 : 63;
+ } sh_proc1_adv_int_enable_s;
+ } sh_proc1_adv_int_enable_u_t;
+-#else
+-typedef union sh_proc1_adv_int_enable_u {
+- mmr_t sh_proc1_adv_int_enable_regval;
+- struct {
+- mmr_t reserved_0 : 63;
+- mmr_t proc1_adv_enable : 1;
+- } sh_proc1_adv_int_enable_s;
+-} sh_proc1_adv_int_enable_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PROC2_ADV_INT_ENABLE" */
+ /* SHub Processor 2 Advisory Interrupt Enable Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc2_adv_int_enable_u {
+ mmr_t sh_proc2_adv_int_enable_regval;
+ struct {
+@@ -1790,22 +991,12 @@
+ mmr_t reserved_0 : 63;
+ } sh_proc2_adv_int_enable_s;
+ } sh_proc2_adv_int_enable_u_t;
+-#else
+-typedef union sh_proc2_adv_int_enable_u {
+- mmr_t sh_proc2_adv_int_enable_regval;
+- struct {
+- mmr_t reserved_0 : 63;
+- mmr_t proc2_adv_enable : 1;
+- } sh_proc2_adv_int_enable_s;
+-} sh_proc2_adv_int_enable_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PROC3_ADV_INT_ENABLE" */
+ /* SHub Processor 3 Advisory Interrupt Enable Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc3_adv_int_enable_u {
+ mmr_t sh_proc3_adv_int_enable_regval;
+ struct {
+@@ -1813,22 +1004,12 @@
+ mmr_t reserved_0 : 63;
+ } sh_proc3_adv_int_enable_s;
+ } sh_proc3_adv_int_enable_u_t;
+-#else
+-typedef union sh_proc3_adv_int_enable_u {
+- mmr_t sh_proc3_adv_int_enable_regval;
+- struct {
+- mmr_t reserved_0 : 63;
+- mmr_t proc3_adv_enable : 1;
+- } sh_proc3_adv_int_enable_s;
+-} sh_proc3_adv_int_enable_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PROFILE_INT_CONFIG" */
+ /* SHub Profile Interrupt Configuration Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_profile_int_config_u {
+ mmr_t sh_profile_int_config_regval;
+ struct {
+@@ -1842,28 +1023,12 @@
+ mmr_t reserved_2 : 4;
+ } sh_profile_int_config_s;
+ } sh_profile_int_config_u_t;
+-#else
+-typedef union sh_profile_int_config_u {
+- mmr_t sh_profile_int_config_regval;
+- struct {
+- mmr_t reserved_2 : 4;
+- mmr_t idx : 8;
+- mmr_t reserved_1 : 2;
+- mmr_t base : 29;
+- mmr_t reserved_0 : 1;
+- mmr_t pid : 16;
+- mmr_t agt : 1;
+- mmr_t type : 3;
+- } sh_profile_int_config_s;
+-} sh_profile_int_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PROFILE_INT_ENABLE" */
+ /* SHub Profile Interrupt Enable Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_profile_int_enable_u {
+ mmr_t sh_profile_int_enable_regval;
+ struct {
+@@ -1871,22 +1036,12 @@
+ mmr_t reserved_0 : 63;
+ } sh_profile_int_enable_s;
+ } sh_profile_int_enable_u_t;
+-#else
+-typedef union sh_profile_int_enable_u {
+- mmr_t sh_profile_int_enable_regval;
+- struct {
+- mmr_t reserved_0 : 63;
+- mmr_t profile_enable : 1;
+- } sh_profile_int_enable_s;
+-} sh_profile_int_enable_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_RTC0_INT_CONFIG" */
+ /* SHub RTC 0 Interrupt Config Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_rtc0_int_config_u {
+ mmr_t sh_rtc0_int_config_regval;
+ struct {
+@@ -1900,28 +1055,12 @@
+ mmr_t reserved_2 : 4;
+ } sh_rtc0_int_config_s;
+ } sh_rtc0_int_config_u_t;
+-#else
+-typedef union sh_rtc0_int_config_u {
+- mmr_t sh_rtc0_int_config_regval;
+- struct {
+- mmr_t reserved_2 : 4;
+- mmr_t idx : 8;
+- mmr_t reserved_1 : 2;
+- mmr_t base : 29;
+- mmr_t reserved_0 : 1;
+- mmr_t pid : 16;
+- mmr_t agt : 1;
+- mmr_t type : 3;
+- } sh_rtc0_int_config_s;
+-} sh_rtc0_int_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_RTC0_INT_ENABLE" */
+ /* SHub RTC 0 Interrupt Enable Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_rtc0_int_enable_u {
+ mmr_t sh_rtc0_int_enable_regval;
+ struct {
+@@ -1929,22 +1068,12 @@
+ mmr_t reserved_0 : 63;
+ } sh_rtc0_int_enable_s;
+ } sh_rtc0_int_enable_u_t;
+-#else
+-typedef union sh_rtc0_int_enable_u {
+- mmr_t sh_rtc0_int_enable_regval;
+- struct {
+- mmr_t reserved_0 : 63;
+- mmr_t rtc0_enable : 1;
+- } sh_rtc0_int_enable_s;
+-} sh_rtc0_int_enable_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_RTC1_INT_CONFIG" */
+ /* SHub RTC 1 Interrupt Config Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_rtc1_int_config_u {
+ mmr_t sh_rtc1_int_config_regval;
+ struct {
+@@ -1958,28 +1087,12 @@
+ mmr_t reserved_2 : 4;
+ } sh_rtc1_int_config_s;
+ } sh_rtc1_int_config_u_t;
+-#else
+-typedef union sh_rtc1_int_config_u {
+- mmr_t sh_rtc1_int_config_regval;
+- struct {
+- mmr_t reserved_2 : 4;
+- mmr_t idx : 8;
+- mmr_t reserved_1 : 2;
+- mmr_t base : 29;
+- mmr_t reserved_0 : 1;
+- mmr_t pid : 16;
+- mmr_t agt : 1;
+- mmr_t type : 3;
+- } sh_rtc1_int_config_s;
+-} sh_rtc1_int_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_RTC1_INT_ENABLE" */
+ /* SHub RTC 1 Interrupt Enable Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_rtc1_int_enable_u {
+ mmr_t sh_rtc1_int_enable_regval;
+ struct {
+@@ -1987,22 +1100,12 @@
+ mmr_t reserved_0 : 63;
+ } sh_rtc1_int_enable_s;
+ } sh_rtc1_int_enable_u_t;
+-#else
+-typedef union sh_rtc1_int_enable_u {
+- mmr_t sh_rtc1_int_enable_regval;
+- struct {
+- mmr_t reserved_0 : 63;
+- mmr_t rtc1_enable : 1;
+- } sh_rtc1_int_enable_s;
+-} sh_rtc1_int_enable_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_RTC2_INT_CONFIG" */
+ /* SHub RTC 2 Interrupt Config Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_rtc2_int_config_u {
+ mmr_t sh_rtc2_int_config_regval;
+ struct {
+@@ -2016,28 +1119,12 @@
+ mmr_t reserved_2 : 4;
+ } sh_rtc2_int_config_s;
+ } sh_rtc2_int_config_u_t;
+-#else
+-typedef union sh_rtc2_int_config_u {
+- mmr_t sh_rtc2_int_config_regval;
+- struct {
+- mmr_t reserved_2 : 4;
+- mmr_t idx : 8;
+- mmr_t reserved_1 : 2;
+- mmr_t base : 29;
+- mmr_t reserved_0 : 1;
+- mmr_t pid : 16;
+- mmr_t agt : 1;
+- mmr_t type : 3;
+- } sh_rtc2_int_config_s;
+-} sh_rtc2_int_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_RTC2_INT_ENABLE" */
+ /* SHub RTC 2 Interrupt Enable Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_rtc2_int_enable_u {
+ mmr_t sh_rtc2_int_enable_regval;
+ struct {
+@@ -2045,22 +1132,12 @@
+ mmr_t reserved_0 : 63;
+ } sh_rtc2_int_enable_s;
+ } sh_rtc2_int_enable_u_t;
+-#else
+-typedef union sh_rtc2_int_enable_u {
+- mmr_t sh_rtc2_int_enable_regval;
+- struct {
+- mmr_t reserved_0 : 63;
+- mmr_t rtc2_enable : 1;
+- } sh_rtc2_int_enable_s;
+-} sh_rtc2_int_enable_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_RTC3_INT_CONFIG" */
+ /* SHub RTC 3 Interrupt Config Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_rtc3_int_config_u {
+ mmr_t sh_rtc3_int_config_regval;
+ struct {
+@@ -2074,28 +1151,12 @@
+ mmr_t reserved_2 : 4;
+ } sh_rtc3_int_config_s;
+ } sh_rtc3_int_config_u_t;
+-#else
+-typedef union sh_rtc3_int_config_u {
+- mmr_t sh_rtc3_int_config_regval;
+- struct {
+- mmr_t reserved_2 : 4;
+- mmr_t idx : 8;
+- mmr_t reserved_1 : 2;
+- mmr_t base : 29;
+- mmr_t reserved_0 : 1;
+- mmr_t pid : 16;
+- mmr_t agt : 1;
+- mmr_t type : 3;
+- } sh_rtc3_int_config_s;
+-} sh_rtc3_int_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_RTC3_INT_ENABLE" */
+ /* SHub RTC 3 Interrupt Enable Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_rtc3_int_enable_u {
+ mmr_t sh_rtc3_int_enable_regval;
+ struct {
+@@ -2103,22 +1164,12 @@
+ mmr_t reserved_0 : 63;
+ } sh_rtc3_int_enable_s;
+ } sh_rtc3_int_enable_u_t;
+-#else
+-typedef union sh_rtc3_int_enable_u {
+- mmr_t sh_rtc3_int_enable_regval;
+- struct {
+- mmr_t reserved_0 : 63;
+- mmr_t rtc3_enable : 1;
+- } sh_rtc3_int_enable_s;
+-} sh_rtc3_int_enable_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_EVENT_OCCURRED" */
+ /* SHub Interrupt Event Occurred */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_event_occurred_u {
+ mmr_t sh_event_occurred_regval;
+ struct {
+@@ -2156,54 +1207,14 @@
+ mmr_t reserved_0 : 33;
+ } sh_event_occurred_s;
+ } sh_event_occurred_u_t;
+-#else
+-typedef union sh_event_occurred_u {
+- mmr_t sh_event_occurred_regval;
+- struct {
+- mmr_t reserved_0 : 33;
+- mmr_t ii_int1 : 1;
+- mmr_t ii_int0 : 1;
+- mmr_t ipi_int : 1;
+- mmr_t profile_int : 1;
+- mmr_t rtc3_int : 1;
+- mmr_t rtc2_int : 1;
+- mmr_t rtc1_int : 1;
+- mmr_t rtc0_int : 1;
+- mmr_t stop_clock : 1;
+- mmr_t l1_nmi_int : 1;
+- mmr_t uart_int : 1;
+- mmr_t system_shutdown_int : 1;
+- mmr_t proc3_err_int : 1;
+- mmr_t proc2_err_int : 1;
+- mmr_t proc1_err_int : 1;
+- mmr_t proc0_err_int : 1;
+- mmr_t proc3_adv_int : 1;
+- mmr_t proc2_adv_int : 1;
+- mmr_t proc1_adv_int : 1;
+- mmr_t proc0_adv_int : 1;
+- mmr_t xn_uce_int : 1;
+- mmr_t md_uce_int : 1;
+- mmr_t pi_uce_int : 1;
+- mmr_t xn_ce_int : 1;
+- mmr_t md_ce_int : 1;
+- mmr_t pi_ce_int : 1;
+- mmr_t ii_hw_int : 1;
+- mmr_t lb_hw_int : 1;
+- mmr_t xn_hw_int : 1;
+- mmr_t md_hw_int : 1;
+- mmr_t pi_hw_int : 1;
+- } sh_event_occurred_s;
+-} sh_event_occurred_u_t;
+-#endif
+-
+-/* ==================================================================== */
+-/* Register "SH_EVENT_OVERFLOW" */
+-/* SHub Interrupt Event Occurred Overflow */
+-/* ==================================================================== */
+-
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_event_overflow_u {
+- mmr_t sh_event_overflow_regval;
++
++/* ==================================================================== */
++/* Register "SH_EVENT_OVERFLOW" */
++/* SHub Interrupt Event Occurred Overflow */
++/* ==================================================================== */
++
++typedef union sh_event_overflow_u {
++ mmr_t sh_event_overflow_regval;
+ struct {
+ mmr_t pi_hw_int : 1;
+ mmr_t md_hw_int : 1;
+@@ -2236,49 +1247,12 @@
+ mmr_t reserved_0 : 36;
+ } sh_event_overflow_s;
+ } sh_event_overflow_u_t;
+-#else
+-typedef union sh_event_overflow_u {
+- mmr_t sh_event_overflow_regval;
+- struct {
+- mmr_t reserved_0 : 36;
+- mmr_t profile_int : 1;
+- mmr_t rtc3_int : 1;
+- mmr_t rtc2_int : 1;
+- mmr_t rtc1_int : 1;
+- mmr_t rtc0_int : 1;
+- mmr_t stop_clock : 1;
+- mmr_t l1_nmi_int : 1;
+- mmr_t uart_int : 1;
+- mmr_t system_shutdown_int : 1;
+- mmr_t proc3_err_int : 1;
+- mmr_t proc2_err_int : 1;
+- mmr_t proc1_err_int : 1;
+- mmr_t proc0_err_int : 1;
+- mmr_t proc3_adv_int : 1;
+- mmr_t proc2_adv_int : 1;
+- mmr_t proc1_adv_int : 1;
+- mmr_t proc0_adv_int : 1;
+- mmr_t xn_uce_int : 1;
+- mmr_t md_uce_int : 1;
+- mmr_t pi_uce_int : 1;
+- mmr_t xn_ce_int : 1;
+- mmr_t md_ce_int : 1;
+- mmr_t pi_ce_int : 1;
+- mmr_t ii_hw_int : 1;
+- mmr_t lb_hw_int : 1;
+- mmr_t xn_hw_int : 1;
+- mmr_t md_hw_int : 1;
+- mmr_t pi_hw_int : 1;
+- } sh_event_overflow_s;
+-} sh_event_overflow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_JUNK_BUS_TIME" */
+ /* Junk Bus Timing */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_junk_bus_time_u {
+ mmr_t sh_junk_bus_time_regval;
+ struct {
+@@ -2289,25 +1263,12 @@
+ mmr_t reserved_0 : 32;
+ } sh_junk_bus_time_s;
+ } sh_junk_bus_time_u_t;
+-#else
+-typedef union sh_junk_bus_time_u {
+- mmr_t sh_junk_bus_time_regval;
+- struct {
+- mmr_t reserved_0 : 32;
+- mmr_t uart_enable : 8;
+- mmr_t uart_setup_hold : 8;
+- mmr_t fprom_enable : 8;
+- mmr_t fprom_setup_hold : 8;
+- } sh_junk_bus_time_s;
+-} sh_junk_bus_time_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_JUNK_LATCH_TIME" */
+ /* Junk Bus Latch Timing */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_junk_latch_time_u {
+ mmr_t sh_junk_latch_time_regval;
+ struct {
+@@ -2315,22 +1276,12 @@
+ mmr_t reserved_0 : 61;
+ } sh_junk_latch_time_s;
+ } sh_junk_latch_time_u_t;
+-#else
+-typedef union sh_junk_latch_time_u {
+- mmr_t sh_junk_latch_time_regval;
+- struct {
+- mmr_t reserved_0 : 61;
+- mmr_t setup_hold : 3;
+- } sh_junk_latch_time_s;
+-} sh_junk_latch_time_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_JUNK_NACK_RESET" */
+ /* Junk Bus Nack Counter Reset */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_junk_nack_reset_u {
+ mmr_t sh_junk_nack_reset_regval;
+ struct {
+@@ -2338,22 +1289,12 @@
+ mmr_t reserved_0 : 63;
+ } sh_junk_nack_reset_s;
+ } sh_junk_nack_reset_u_t;
+-#else
+-typedef union sh_junk_nack_reset_u {
+- mmr_t sh_junk_nack_reset_regval;
+- struct {
+- mmr_t reserved_0 : 63;
+- mmr_t pulse : 1;
+- } sh_junk_nack_reset_s;
+-} sh_junk_nack_reset_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_JUNK_BUS_LED0" */
+ /* Junk Bus LED0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_junk_bus_led0_u {
+ mmr_t sh_junk_bus_led0_regval;
+ struct {
+@@ -2361,22 +1302,12 @@
+ mmr_t reserved_0 : 56;
+ } sh_junk_bus_led0_s;
+ } sh_junk_bus_led0_u_t;
+-#else
+-typedef union sh_junk_bus_led0_u {
+- mmr_t sh_junk_bus_led0_regval;
+- struct {
+- mmr_t reserved_0 : 56;
+- mmr_t led0_data : 8;
+- } sh_junk_bus_led0_s;
+-} sh_junk_bus_led0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_JUNK_BUS_LED1" */
+ /* Junk Bus LED1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_junk_bus_led1_u {
+ mmr_t sh_junk_bus_led1_regval;
+ struct {
+@@ -2384,22 +1315,12 @@
+ mmr_t reserved_0 : 56;
+ } sh_junk_bus_led1_s;
+ } sh_junk_bus_led1_u_t;
+-#else
+-typedef union sh_junk_bus_led1_u {
+- mmr_t sh_junk_bus_led1_regval;
+- struct {
+- mmr_t reserved_0 : 56;
+- mmr_t led1_data : 8;
+- } sh_junk_bus_led1_s;
+-} sh_junk_bus_led1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_JUNK_BUS_LED2" */
+ /* Junk Bus LED2 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_junk_bus_led2_u {
+ mmr_t sh_junk_bus_led2_regval;
+ struct {
+@@ -2407,22 +1328,12 @@
+ mmr_t reserved_0 : 56;
+ } sh_junk_bus_led2_s;
+ } sh_junk_bus_led2_u_t;
+-#else
+-typedef union sh_junk_bus_led2_u {
+- mmr_t sh_junk_bus_led2_regval;
+- struct {
+- mmr_t reserved_0 : 56;
+- mmr_t led2_data : 8;
+- } sh_junk_bus_led2_s;
+-} sh_junk_bus_led2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_JUNK_BUS_LED3" */
+ /* Junk Bus LED3 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_junk_bus_led3_u {
+ mmr_t sh_junk_bus_led3_regval;
+ struct {
+@@ -2430,22 +1341,12 @@
+ mmr_t reserved_0 : 56;
+ } sh_junk_bus_led3_s;
+ } sh_junk_bus_led3_u_t;
+-#else
+-typedef union sh_junk_bus_led3_u {
+- mmr_t sh_junk_bus_led3_regval;
+- struct {
+- mmr_t reserved_0 : 56;
+- mmr_t led3_data : 8;
+- } sh_junk_bus_led3_s;
+-} sh_junk_bus_led3_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_JUNK_ERROR_STATUS" */
+ /* Junk Bus Error Status */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_junk_error_status_u {
+ mmr_t sh_junk_error_status_regval;
+ struct {
+@@ -2457,26 +1358,12 @@
+ mmr_t reserved_1 : 3;
+ } sh_junk_error_status_s;
+ } sh_junk_error_status_u_t;
+-#else
+-typedef union sh_junk_error_status_u {
+- mmr_t sh_junk_error_status_regval;
+- struct {
+- mmr_t reserved_1 : 3;
+- mmr_t status : 4;
+- mmr_t mode : 1;
+- mmr_t cmd : 8;
+- mmr_t reserved_0 : 1;
+- mmr_t address : 47;
+- } sh_junk_error_status_s;
+-} sh_junk_error_status_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI0_LLP_STAT" */
+ /* This register describes the LLP status. */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_llp_stat_u {
+ mmr_t sh_ni0_llp_stat_regval;
+ struct {
+@@ -2484,22 +1371,12 @@
+ mmr_t reserved_0 : 60;
+ } sh_ni0_llp_stat_s;
+ } sh_ni0_llp_stat_u_t;
+-#else
+-typedef union sh_ni0_llp_stat_u {
+- mmr_t sh_ni0_llp_stat_regval;
+- struct {
+- mmr_t reserved_0 : 60;
+- mmr_t link_reset_state : 4;
+- } sh_ni0_llp_stat_s;
+-} sh_ni0_llp_stat_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI0_LLP_RESET" */
+ /* Writing issues a reset to the network interface */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_llp_reset_u {
+ mmr_t sh_ni0_llp_reset_regval;
+ struct {
+@@ -2508,23 +1385,12 @@
+ mmr_t reserved_0 : 62;
+ } sh_ni0_llp_reset_s;
+ } sh_ni0_llp_reset_u_t;
+-#else
+-typedef union sh_ni0_llp_reset_u {
+- mmr_t sh_ni0_llp_reset_regval;
+- struct {
+- mmr_t reserved_0 : 62;
+- mmr_t warm : 1;
+- mmr_t link : 1;
+- } sh_ni0_llp_reset_s;
+-} sh_ni0_llp_reset_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI0_LLP_RESET_EN" */
+ /* Controls LLP warm reset propagation */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_llp_reset_en_u {
+ mmr_t sh_ni0_llp_reset_en_regval;
+ struct {
+@@ -2532,22 +1398,12 @@
+ mmr_t reserved_0 : 63;
+ } sh_ni0_llp_reset_en_s;
+ } sh_ni0_llp_reset_en_u_t;
+-#else
+-typedef union sh_ni0_llp_reset_en_u {
+- mmr_t sh_ni0_llp_reset_en_regval;
+- struct {
+- mmr_t reserved_0 : 63;
+- mmr_t ok : 1;
+- } sh_ni0_llp_reset_en_s;
+-} sh_ni0_llp_reset_en_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI0_LLP_CHAN_MODE" */
+ /* Sets the signaling mode of LLP and channel */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_llp_chan_mode_u {
+ mmr_t sh_ni0_llp_chan_mode_regval;
+ struct {
+@@ -2559,26 +1415,12 @@
+ mmr_t reserved_0 : 59;
+ } sh_ni0_llp_chan_mode_s;
+ } sh_ni0_llp_chan_mode_u_t;
+-#else
+-typedef union sh_ni0_llp_chan_mode_u {
+- mmr_t sh_ni0_llp_chan_mode_regval;
+- struct {
+- mmr_t reserved_0 : 59;
+- mmr_t enable_clkquad : 1;
+- mmr_t enable_rmt_ft_upd : 1;
+- mmr_t enable_tuning : 1;
+- mmr_t ac_encode : 1;
+- mmr_t bitmode32 : 1;
+- } sh_ni0_llp_chan_mode_s;
+-} sh_ni0_llp_chan_mode_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI0_LLP_CONFIG" */
+ /* Sets the configuration of LLP and channel */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_llp_config_u {
+ mmr_t sh_ni0_llp_config_regval;
+ struct {
+@@ -2589,24 +1431,11 @@
+ mmr_t reserved_0 : 26;
+ } sh_ni0_llp_config_s;
+ } sh_ni0_llp_config_u_t;
+-#else
+-typedef union sh_ni0_llp_config_u {
+- mmr_t sh_ni0_llp_config_regval;
+- struct {
+- mmr_t reserved_0 : 26;
+- mmr_t ftu_time : 12;
+- mmr_t nulltimeout : 6;
+- mmr_t maxretry : 10;
+- mmr_t maxburst : 10;
+- } sh_ni0_llp_config_s;
+-} sh_ni0_llp_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI0_LLP_TEST_CTL" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_llp_test_ctl_u {
+ mmr_t sh_ni0_llp_test_ctl_regval;
+ struct {
+@@ -2627,77 +1456,36 @@
+ mmr_t reserved_2 : 1;
+ } sh_ni0_llp_test_ctl_s;
+ } sh_ni0_llp_test_ctl_u_t;
+-#else
+-typedef union sh_ni0_llp_test_ctl_u {
+- mmr_t sh_ni0_llp_test_ctl_regval;
+- struct {
+- mmr_t reserved_2 : 1;
+- mmr_t cberror : 1;
+- mmr_t captured : 1;
+- mmr_t fakesnerror : 1;
+- mmr_t sendsnerror : 1;
+- mmr_t sendcberror : 1;
+- mmr_t capturecbonly : 1;
+- mmr_t armcapture : 1;
+- mmr_t noise_mode : 2;
+- mmr_t lfsr_mode : 2;
+- mmr_t reserved_1 : 2;
+- mmr_t wire_sel : 6;
+- mmr_t reserved_0 : 2;
+- mmr_t send_test_mode : 2;
+- mmr_t pattern : 40;
+- } sh_ni0_llp_test_ctl_s;
+-} sh_ni0_llp_test_ctl_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI0_LLP_CAPT_WD1" */
+ /* low order 64-bit captured word */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_ni0_llp_capt_wd1_u {
+- mmr_t sh_ni0_llp_capt_wd1_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_ni0_llp_capt_wd1_s;
+-} sh_ni0_llp_capt_wd1_u_t;
+-#else
+ typedef union sh_ni0_llp_capt_wd1_u {
+ mmr_t sh_ni0_llp_capt_wd1_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_ni0_llp_capt_wd1_s;
+ } sh_ni0_llp_capt_wd1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI0_LLP_CAPT_WD2" */
+ /* high order 64-bit captured word */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_llp_capt_wd2_u {
+ mmr_t sh_ni0_llp_capt_wd2_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_ni0_llp_capt_wd2_s;
+ } sh_ni0_llp_capt_wd2_u_t;
+-#else
+-typedef union sh_ni0_llp_capt_wd2_u {
+- mmr_t sh_ni0_llp_capt_wd2_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_ni0_llp_capt_wd2_s;
+-} sh_ni0_llp_capt_wd2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI0_LLP_CAPT_SBCB" */
+ /* captured sideband, sequence, and CRC */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_llp_capt_sbcb_u {
+ mmr_t sh_ni0_llp_capt_sbcb_regval;
+ struct {
+@@ -2711,27 +1499,11 @@
+ mmr_t reserved_0 : 27;
+ } sh_ni0_llp_capt_sbcb_s;
+ } sh_ni0_llp_capt_sbcb_u_t;
+-#else
+-typedef union sh_ni0_llp_capt_sbcb_u {
+- mmr_t sh_ni0_llp_capt_sbcb_regval;
+- struct {
+- mmr_t reserved_0 : 27;
+- mmr_t chargeunderflow : 1;
+- mmr_t chargeoverflow : 1;
+- mmr_t fakedallsnerrors : 1;
+- mmr_t sentallsnerrors : 1;
+- mmr_t sentallcberrors : 1;
+- mmr_t capturedrcvcrc : 16;
+- mmr_t capturedrcvsbsn : 16;
+- } sh_ni0_llp_capt_sbcb_s;
+-} sh_ni0_llp_capt_sbcb_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI0_LLP_ERR" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_llp_err_u {
+ mmr_t sh_ni0_llp_err_regval;
+ struct {
+@@ -2747,30 +1519,12 @@
+ mmr_t reserved_0 : 11;
+ } sh_ni0_llp_err_s;
+ } sh_ni0_llp_err_u_t;
+-#else
+-typedef union sh_ni0_llp_err_u {
+- mmr_t sh_ni0_llp_err_regval;
+- struct {
+- mmr_t reserved_0 : 11;
+- mmr_t wire_overflow : 1;
+- mmr_t wire_cnt : 24;
+- mmr_t power_not_ok : 1;
+- mmr_t squash : 1;
+- mmr_t rcv_link_reset : 1;
+- mmr_t retry_timeout : 1;
+- mmr_t retry_count : 8;
+- mmr_t rx_cb_err_count : 8;
+- mmr_t rx_sn_err_count : 8;
+- } sh_ni0_llp_err_s;
+-} sh_ni0_llp_err_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI1_LLP_STAT" */
+ /* This register describes the LLP status. */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_llp_stat_u {
+ mmr_t sh_ni1_llp_stat_regval;
+ struct {
+@@ -2778,22 +1532,12 @@
+ mmr_t reserved_0 : 60;
+ } sh_ni1_llp_stat_s;
+ } sh_ni1_llp_stat_u_t;
+-#else
+-typedef union sh_ni1_llp_stat_u {
+- mmr_t sh_ni1_llp_stat_regval;
+- struct {
+- mmr_t reserved_0 : 60;
+- mmr_t link_reset_state : 4;
+- } sh_ni1_llp_stat_s;
+-} sh_ni1_llp_stat_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI1_LLP_RESET" */
+ /* Writing issues a reset to the network interface */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_llp_reset_u {
+ mmr_t sh_ni1_llp_reset_regval;
+ struct {
+@@ -2802,23 +1546,12 @@
+ mmr_t reserved_0 : 62;
+ } sh_ni1_llp_reset_s;
+ } sh_ni1_llp_reset_u_t;
+-#else
+-typedef union sh_ni1_llp_reset_u {
+- mmr_t sh_ni1_llp_reset_regval;
+- struct {
+- mmr_t reserved_0 : 62;
+- mmr_t warm : 1;
+- mmr_t link : 1;
+- } sh_ni1_llp_reset_s;
+-} sh_ni1_llp_reset_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI1_LLP_RESET_EN" */
+ /* Controls LLP warm reset propagation */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_llp_reset_en_u {
+ mmr_t sh_ni1_llp_reset_en_regval;
+ struct {
+@@ -2826,22 +1559,12 @@
+ mmr_t reserved_0 : 63;
+ } sh_ni1_llp_reset_en_s;
+ } sh_ni1_llp_reset_en_u_t;
+-#else
+-typedef union sh_ni1_llp_reset_en_u {
+- mmr_t sh_ni1_llp_reset_en_regval;
+- struct {
+- mmr_t reserved_0 : 63;
+- mmr_t ok : 1;
+- } sh_ni1_llp_reset_en_s;
+-} sh_ni1_llp_reset_en_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI1_LLP_CHAN_MODE" */
+ /* Sets the signaling mode of LLP and channel */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_llp_chan_mode_u {
+ mmr_t sh_ni1_llp_chan_mode_regval;
+ struct {
+@@ -2853,26 +1576,12 @@
+ mmr_t reserved_0 : 59;
+ } sh_ni1_llp_chan_mode_s;
+ } sh_ni1_llp_chan_mode_u_t;
+-#else
+-typedef union sh_ni1_llp_chan_mode_u {
+- mmr_t sh_ni1_llp_chan_mode_regval;
+- struct {
+- mmr_t reserved_0 : 59;
+- mmr_t enable_clkquad : 1;
+- mmr_t enable_rmt_ft_upd : 1;
+- mmr_t enable_tuning : 1;
+- mmr_t ac_encode : 1;
+- mmr_t bitmode32 : 1;
+- } sh_ni1_llp_chan_mode_s;
+-} sh_ni1_llp_chan_mode_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI1_LLP_CONFIG" */
+ /* Sets the configuration of LLP and channel */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_llp_config_u {
+ mmr_t sh_ni1_llp_config_regval;
+ struct {
+@@ -2883,24 +1592,11 @@
+ mmr_t reserved_0 : 26;
+ } sh_ni1_llp_config_s;
+ } sh_ni1_llp_config_u_t;
+-#else
+-typedef union sh_ni1_llp_config_u {
+- mmr_t sh_ni1_llp_config_regval;
+- struct {
+- mmr_t reserved_0 : 26;
+- mmr_t ftu_time : 12;
+- mmr_t nulltimeout : 6;
+- mmr_t maxretry : 10;
+- mmr_t maxburst : 10;
+- } sh_ni1_llp_config_s;
+-} sh_ni1_llp_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI1_LLP_TEST_CTL" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_llp_test_ctl_u {
+ mmr_t sh_ni1_llp_test_ctl_regval;
+ struct {
+@@ -2921,77 +1617,36 @@
+ mmr_t reserved_2 : 1;
+ } sh_ni1_llp_test_ctl_s;
+ } sh_ni1_llp_test_ctl_u_t;
+-#else
+-typedef union sh_ni1_llp_test_ctl_u {
+- mmr_t sh_ni1_llp_test_ctl_regval;
+- struct {
+- mmr_t reserved_2 : 1;
+- mmr_t cberror : 1;
+- mmr_t captured : 1;
+- mmr_t fakesnerror : 1;
+- mmr_t sendsnerror : 1;
+- mmr_t sendcberror : 1;
+- mmr_t capturecbonly : 1;
+- mmr_t armcapture : 1;
+- mmr_t noise_mode : 2;
+- mmr_t lfsr_mode : 2;
+- mmr_t reserved_1 : 2;
+- mmr_t wire_sel : 6;
+- mmr_t reserved_0 : 2;
+- mmr_t send_test_mode : 2;
+- mmr_t pattern : 40;
+- } sh_ni1_llp_test_ctl_s;
+-} sh_ni1_llp_test_ctl_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI1_LLP_CAPT_WD1" */
+ /* low order 64-bit captured word */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_ni1_llp_capt_wd1_u {
+- mmr_t sh_ni1_llp_capt_wd1_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_ni1_llp_capt_wd1_s;
+-} sh_ni1_llp_capt_wd1_u_t;
+-#else
+ typedef union sh_ni1_llp_capt_wd1_u {
+ mmr_t sh_ni1_llp_capt_wd1_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_ni1_llp_capt_wd1_s;
+ } sh_ni1_llp_capt_wd1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI1_LLP_CAPT_WD2" */
+ /* high order 64-bit captured word */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_ni1_llp_capt_wd2_u {
+- mmr_t sh_ni1_llp_capt_wd2_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_ni1_llp_capt_wd2_s;
+-} sh_ni1_llp_capt_wd2_u_t;
+-#else
+ typedef union sh_ni1_llp_capt_wd2_u {
+ mmr_t sh_ni1_llp_capt_wd2_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_ni1_llp_capt_wd2_s;
+ } sh_ni1_llp_capt_wd2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI1_LLP_CAPT_SBCB" */
+ /* captured sideband, sequence, and CRC */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_llp_capt_sbcb_u {
+ mmr_t sh_ni1_llp_capt_sbcb_regval;
+ struct {
+@@ -3005,27 +1660,11 @@
+ mmr_t reserved_0 : 27;
+ } sh_ni1_llp_capt_sbcb_s;
+ } sh_ni1_llp_capt_sbcb_u_t;
+-#else
+-typedef union sh_ni1_llp_capt_sbcb_u {
+- mmr_t sh_ni1_llp_capt_sbcb_regval;
+- struct {
+- mmr_t reserved_0 : 27;
+- mmr_t chargeunderflow : 1;
+- mmr_t chargeoverflow : 1;
+- mmr_t fakedallsnerrors : 1;
+- mmr_t sentallsnerrors : 1;
+- mmr_t sentallcberrors : 1;
+- mmr_t capturedrcvcrc : 16;
+- mmr_t capturedrcvsbsn : 16;
+- } sh_ni1_llp_capt_sbcb_s;
+-} sh_ni1_llp_capt_sbcb_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI1_LLP_ERR" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_llp_err_u {
+ mmr_t sh_ni1_llp_err_regval;
+ struct {
+@@ -3041,29 +1680,11 @@
+ mmr_t reserved_0 : 11;
+ } sh_ni1_llp_err_s;
+ } sh_ni1_llp_err_u_t;
+-#else
+-typedef union sh_ni1_llp_err_u {
+- mmr_t sh_ni1_llp_err_regval;
+- struct {
+- mmr_t reserved_0 : 11;
+- mmr_t wire_overflow : 1;
+- mmr_t wire_cnt : 24;
+- mmr_t power_not_ok : 1;
+- mmr_t squash : 1;
+- mmr_t rcv_link_reset : 1;
+- mmr_t retry_timeout : 1;
+- mmr_t retry_count : 8;
+- mmr_t rx_cb_err_count : 8;
+- mmr_t rx_sn_err_count : 8;
+- } sh_ni1_llp_err_s;
+-} sh_ni1_llp_err_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI0_LLP_TO_FIFO02_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_llp_to_fifo02_flow_u {
+ mmr_t sh_xnni0_llp_to_fifo02_flow_regval;
+ struct {
+@@ -3084,34 +1705,11 @@
+ mmr_t reserved_6 : 2;
+ } sh_xnni0_llp_to_fifo02_flow_s;
+ } sh_xnni0_llp_to_fifo02_flow_u_t;
+-#else
+-typedef union sh_xnni0_llp_to_fifo02_flow_u {
+- mmr_t sh_xnni0_llp_to_fifo02_flow_regval;
+- struct {
+- mmr_t reserved_6 : 2;
+- mmr_t credit_vc2_cap : 6;
+- mmr_t reserved_5 : 2;
+- mmr_t credit_vc2_dyn : 6;
+- mmr_t reserved_4 : 10;
+- mmr_t credit_vc0_cap : 6;
+- mmr_t reserved_3 : 2;
+- mmr_t credit_vc0_dyn : 6;
+- mmr_t reserved_2 : 8;
+- mmr_t debit_vc2_force_cred : 1;
+- mmr_t reserved_1 : 1;
+- mmr_t debit_vc2_withhold : 6;
+- mmr_t debit_vc0_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t debit_vc0_withhold : 6;
+- } sh_xnni0_llp_to_fifo02_flow_s;
+-} sh_xnni0_llp_to_fifo02_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI0_LLP_TO_FIFO13_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_llp_to_fifo13_flow_u {
+ mmr_t sh_xnni0_llp_to_fifo13_flow_regval;
+ struct {
+@@ -3132,34 +1730,11 @@
+ mmr_t reserved_6 : 2;
+ } sh_xnni0_llp_to_fifo13_flow_s;
+ } sh_xnni0_llp_to_fifo13_flow_u_t;
+-#else
+-typedef union sh_xnni0_llp_to_fifo13_flow_u {
+- mmr_t sh_xnni0_llp_to_fifo13_flow_regval;
+- struct {
+- mmr_t reserved_6 : 2;
+- mmr_t credit_vc2_cap : 6;
+- mmr_t reserved_5 : 2;
+- mmr_t credit_vc2_dyn : 6;
+- mmr_t reserved_4 : 10;
+- mmr_t credit_vc0_cap : 6;
+- mmr_t reserved_3 : 2;
+- mmr_t credit_vc0_dyn : 6;
+- mmr_t reserved_2 : 8;
+- mmr_t debit_vc2_force_cred : 1;
+- mmr_t reserved_1 : 1;
+- mmr_t debit_vc2_withhold : 6;
+- mmr_t debit_vc0_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t debit_vc0_withhold : 6;
+- } sh_xnni0_llp_to_fifo13_flow_s;
+-} sh_xnni0_llp_to_fifo13_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI0_LLP_DEBIT_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_llp_debit_flow_u {
+ mmr_t sh_xnni0_llp_debit_flow_regval;
+ struct {
+@@ -3181,35 +1756,11 @@
+ mmr_t reserved_7 : 3;
+ } sh_xnni0_llp_debit_flow_s;
+ } sh_xnni0_llp_debit_flow_u_t;
+-#else
+-typedef union sh_xnni0_llp_debit_flow_u {
+- mmr_t sh_xnni0_llp_debit_flow_regval;
+- struct {
+- mmr_t reserved_7 : 3;
+- mmr_t debit_vc3_cap : 5;
+- mmr_t reserved_6 : 3;
+- mmr_t debit_vc3_dyn : 5;
+- mmr_t reserved_5 : 3;
+- mmr_t debit_vc2_cap : 5;
+- mmr_t reserved_4 : 3;
+- mmr_t debit_vc2_dyn : 5;
+- mmr_t reserved_3 : 3;
+- mmr_t debit_vc1_cap : 5;
+- mmr_t reserved_2 : 3;
+- mmr_t debit_vc1_dyn : 5;
+- mmr_t reserved_1 : 3;
+- mmr_t debit_vc0_cap : 5;
+- mmr_t reserved_0 : 3;
+- mmr_t debit_vc0_dyn : 5;
+- } sh_xnni0_llp_debit_flow_s;
+-} sh_xnni0_llp_debit_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI0_LINK_0_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_link_0_flow_u {
+ mmr_t sh_xnni0_link_0_flow_regval;
+ struct {
+@@ -3224,28 +1775,11 @@
+ mmr_t reserved_3 : 33;
+ } sh_xnni0_link_0_flow_s;
+ } sh_xnni0_link_0_flow_u_t;
+-#else
+-typedef union sh_xnni0_link_0_flow_u {
+- mmr_t sh_xnni0_link_0_flow_regval;
+- struct {
+- mmr_t reserved_3 : 33;
+- mmr_t credit_vc0_cap : 7;
+- mmr_t reserved_2 : 1;
+- mmr_t credit_vc0_dyn : 7;
+- mmr_t reserved_1 : 1;
+- mmr_t credit_vc0_test : 7;
+- mmr_t debit_vc0_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t debit_vc0_withhold : 6;
+- } sh_xnni0_link_0_flow_s;
+-} sh_xnni0_link_0_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI0_LINK_1_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_link_1_flow_u {
+ mmr_t sh_xnni0_link_1_flow_regval;
+ struct {
+@@ -3260,28 +1794,11 @@
+ mmr_t reserved_3 : 33;
+ } sh_xnni0_link_1_flow_s;
+ } sh_xnni0_link_1_flow_u_t;
+-#else
+-typedef union sh_xnni0_link_1_flow_u {
+- mmr_t sh_xnni0_link_1_flow_regval;
+- struct {
+- mmr_t reserved_3 : 33;
+- mmr_t credit_vc1_cap : 7;
+- mmr_t reserved_2 : 1;
+- mmr_t credit_vc1_dyn : 7;
+- mmr_t reserved_1 : 1;
+- mmr_t credit_vc1_test : 7;
+- mmr_t debit_vc1_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t debit_vc1_withhold : 6;
+- } sh_xnni0_link_1_flow_s;
+-} sh_xnni0_link_1_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI0_LINK_2_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_link_2_flow_u {
+ mmr_t sh_xnni0_link_2_flow_regval;
+ struct {
+@@ -3296,28 +1813,11 @@
+ mmr_t reserved_3 : 33;
+ } sh_xnni0_link_2_flow_s;
+ } sh_xnni0_link_2_flow_u_t;
+-#else
+-typedef union sh_xnni0_link_2_flow_u {
+- mmr_t sh_xnni0_link_2_flow_regval;
+- struct {
+- mmr_t reserved_3 : 33;
+- mmr_t credit_vc2_cap : 7;
+- mmr_t reserved_2 : 1;
+- mmr_t credit_vc2_dyn : 7;
+- mmr_t reserved_1 : 1;
+- mmr_t credit_vc2_test : 7;
+- mmr_t debit_vc2_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t debit_vc2_withhold : 6;
+- } sh_xnni0_link_2_flow_s;
+-} sh_xnni0_link_2_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI0_LINK_3_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_link_3_flow_u {
+ mmr_t sh_xnni0_link_3_flow_regval;
+ struct {
+@@ -3332,28 +1832,11 @@
+ mmr_t reserved_3 : 33;
+ } sh_xnni0_link_3_flow_s;
+ } sh_xnni0_link_3_flow_u_t;
+-#else
+-typedef union sh_xnni0_link_3_flow_u {
+- mmr_t sh_xnni0_link_3_flow_regval;
+- struct {
+- mmr_t reserved_3 : 33;
+- mmr_t credit_vc3_cap : 7;
+- mmr_t reserved_2 : 1;
+- mmr_t credit_vc3_dyn : 7;
+- mmr_t reserved_1 : 1;
+- mmr_t credit_vc3_test : 7;
+- mmr_t debit_vc3_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t debit_vc3_withhold : 6;
+- } sh_xnni0_link_3_flow_s;
+-} sh_xnni0_link_3_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI1_LLP_TO_FIFO02_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_llp_to_fifo02_flow_u {
+ mmr_t sh_xnni1_llp_to_fifo02_flow_regval;
+ struct {
+@@ -3374,34 +1857,11 @@
+ mmr_t reserved_6 : 2;
+ } sh_xnni1_llp_to_fifo02_flow_s;
+ } sh_xnni1_llp_to_fifo02_flow_u_t;
+-#else
+-typedef union sh_xnni1_llp_to_fifo02_flow_u {
+- mmr_t sh_xnni1_llp_to_fifo02_flow_regval;
+- struct {
+- mmr_t reserved_6 : 2;
+- mmr_t credit_vc2_cap : 6;
+- mmr_t reserved_5 : 2;
+- mmr_t credit_vc2_dyn : 6;
+- mmr_t reserved_4 : 10;
+- mmr_t credit_vc0_cap : 6;
+- mmr_t reserved_3 : 2;
+- mmr_t credit_vc0_dyn : 6;
+- mmr_t reserved_2 : 8;
+- mmr_t debit_vc2_force_cred : 1;
+- mmr_t reserved_1 : 1;
+- mmr_t debit_vc2_withhold : 6;
+- mmr_t debit_vc0_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t debit_vc0_withhold : 6;
+- } sh_xnni1_llp_to_fifo02_flow_s;
+-} sh_xnni1_llp_to_fifo02_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI1_LLP_TO_FIFO13_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_llp_to_fifo13_flow_u {
+ mmr_t sh_xnni1_llp_to_fifo13_flow_regval;
+ struct {
+@@ -3422,34 +1882,11 @@
+ mmr_t reserved_6 : 2;
+ } sh_xnni1_llp_to_fifo13_flow_s;
+ } sh_xnni1_llp_to_fifo13_flow_u_t;
+-#else
+-typedef union sh_xnni1_llp_to_fifo13_flow_u {
+- mmr_t sh_xnni1_llp_to_fifo13_flow_regval;
+- struct {
+- mmr_t reserved_6 : 2;
+- mmr_t credit_vc2_cap : 6;
+- mmr_t reserved_5 : 2;
+- mmr_t credit_vc2_dyn : 6;
+- mmr_t reserved_4 : 10;
+- mmr_t credit_vc0_cap : 6;
+- mmr_t reserved_3 : 2;
+- mmr_t credit_vc0_dyn : 6;
+- mmr_t reserved_2 : 8;
+- mmr_t debit_vc2_force_cred : 1;
+- mmr_t reserved_1 : 1;
+- mmr_t debit_vc2_withhold : 6;
+- mmr_t debit_vc0_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t debit_vc0_withhold : 6;
+- } sh_xnni1_llp_to_fifo13_flow_s;
+-} sh_xnni1_llp_to_fifo13_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI1_LLP_DEBIT_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_llp_debit_flow_u {
+ mmr_t sh_xnni1_llp_debit_flow_regval;
+ struct {
+@@ -3471,35 +1908,11 @@
+ mmr_t reserved_7 : 3;
+ } sh_xnni1_llp_debit_flow_s;
+ } sh_xnni1_llp_debit_flow_u_t;
+-#else
+-typedef union sh_xnni1_llp_debit_flow_u {
+- mmr_t sh_xnni1_llp_debit_flow_regval;
+- struct {
+- mmr_t reserved_7 : 3;
+- mmr_t debit_vc3_cap : 5;
+- mmr_t reserved_6 : 3;
+- mmr_t debit_vc3_dyn : 5;
+- mmr_t reserved_5 : 3;
+- mmr_t debit_vc2_cap : 5;
+- mmr_t reserved_4 : 3;
+- mmr_t debit_vc2_dyn : 5;
+- mmr_t reserved_3 : 3;
+- mmr_t debit_vc1_cap : 5;
+- mmr_t reserved_2 : 3;
+- mmr_t debit_vc1_dyn : 5;
+- mmr_t reserved_1 : 3;
+- mmr_t debit_vc0_cap : 5;
+- mmr_t reserved_0 : 3;
+- mmr_t debit_vc0_dyn : 5;
+- } sh_xnni1_llp_debit_flow_s;
+-} sh_xnni1_llp_debit_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI1_LINK_0_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_link_0_flow_u {
+ mmr_t sh_xnni1_link_0_flow_regval;
+ struct {
+@@ -3514,28 +1927,11 @@
+ mmr_t reserved_3 : 33;
+ } sh_xnni1_link_0_flow_s;
+ } sh_xnni1_link_0_flow_u_t;
+-#else
+-typedef union sh_xnni1_link_0_flow_u {
+- mmr_t sh_xnni1_link_0_flow_regval;
+- struct {
+- mmr_t reserved_3 : 33;
+- mmr_t credit_vc0_cap : 7;
+- mmr_t reserved_2 : 1;
+- mmr_t credit_vc0_dyn : 7;
+- mmr_t reserved_1 : 1;
+- mmr_t credit_vc0_test : 7;
+- mmr_t debit_vc0_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t debit_vc0_withhold : 6;
+- } sh_xnni1_link_0_flow_s;
+-} sh_xnni1_link_0_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI1_LINK_1_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_link_1_flow_u {
+ mmr_t sh_xnni1_link_1_flow_regval;
+ struct {
+@@ -3550,28 +1946,11 @@
+ mmr_t reserved_3 : 33;
+ } sh_xnni1_link_1_flow_s;
+ } sh_xnni1_link_1_flow_u_t;
+-#else
+-typedef union sh_xnni1_link_1_flow_u {
+- mmr_t sh_xnni1_link_1_flow_regval;
+- struct {
+- mmr_t reserved_3 : 33;
+- mmr_t credit_vc1_cap : 7;
+- mmr_t reserved_2 : 1;
+- mmr_t credit_vc1_dyn : 7;
+- mmr_t reserved_1 : 1;
+- mmr_t credit_vc1_test : 7;
+- mmr_t debit_vc1_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t debit_vc1_withhold : 6;
+- } sh_xnni1_link_1_flow_s;
+-} sh_xnni1_link_1_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI1_LINK_2_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_link_2_flow_u {
+ mmr_t sh_xnni1_link_2_flow_regval;
+ struct {
+@@ -3586,28 +1965,11 @@
+ mmr_t reserved_3 : 33;
+ } sh_xnni1_link_2_flow_s;
+ } sh_xnni1_link_2_flow_u_t;
+-#else
+-typedef union sh_xnni1_link_2_flow_u {
+- mmr_t sh_xnni1_link_2_flow_regval;
+- struct {
+- mmr_t reserved_3 : 33;
+- mmr_t credit_vc2_cap : 7;
+- mmr_t reserved_2 : 1;
+- mmr_t credit_vc2_dyn : 7;
+- mmr_t reserved_1 : 1;
+- mmr_t credit_vc2_test : 7;
+- mmr_t debit_vc2_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t debit_vc2_withhold : 6;
+- } sh_xnni1_link_2_flow_s;
+-} sh_xnni1_link_2_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI1_LINK_3_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_link_3_flow_u {
+ mmr_t sh_xnni1_link_3_flow_regval;
+ struct {
+@@ -3622,29 +1984,12 @@
+ mmr_t reserved_3 : 33;
+ } sh_xnni1_link_3_flow_s;
+ } sh_xnni1_link_3_flow_u_t;
+-#else
+-typedef union sh_xnni1_link_3_flow_u {
+- mmr_t sh_xnni1_link_3_flow_regval;
+- struct {
+- mmr_t reserved_3 : 33;
+- mmr_t credit_vc3_cap : 7;
+- mmr_t reserved_2 : 1;
+- mmr_t credit_vc3_dyn : 7;
+- mmr_t reserved_1 : 1;
+- mmr_t credit_vc3_test : 7;
+- mmr_t debit_vc3_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t debit_vc3_withhold : 6;
+- } sh_xnni1_link_3_flow_s;
+-} sh_xnni1_link_3_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_IILB_LOCAL_TABLE" */
+ /* local lookup table */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_iilb_local_table_u {
+ mmr_t sh_iilb_local_table_regval;
+ struct {
+@@ -3655,25 +2000,12 @@
+ mmr_t valid : 1;
+ } sh_iilb_local_table_s;
+ } sh_iilb_local_table_u_t;
+-#else
+-typedef union sh_iilb_local_table_u {
+- mmr_t sh_iilb_local_table_regval;
+- struct {
+- mmr_t valid : 1;
+- mmr_t reserved_0 : 57;
+- mmr_t ni_sel0 : 1;
+- mmr_t v0 : 1;
+- mmr_t dir0 : 4;
+- } sh_iilb_local_table_s;
+-} sh_iilb_local_table_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_IILB_GLOBAL_TABLE" */
+ /* global lookup table */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_iilb_global_table_u {
+ mmr_t sh_iilb_global_table_regval;
+ struct {
+@@ -3684,25 +2016,12 @@
+ mmr_t valid : 1;
+ } sh_iilb_global_table_s;
+ } sh_iilb_global_table_u_t;
+-#else
+-typedef union sh_iilb_global_table_u {
+- mmr_t sh_iilb_global_table_regval;
+- struct {
+- mmr_t valid : 1;
+- mmr_t reserved_0 : 57;
+- mmr_t ni_sel0 : 1;
+- mmr_t v0 : 1;
+- mmr_t dir0 : 4;
+- } sh_iilb_global_table_s;
+-} sh_iilb_global_table_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_IILB_OVER_RIDE_TABLE" */
+ /* If enabled, bypass the Global/Local tables */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_iilb_over_ride_table_u {
+ mmr_t sh_iilb_over_ride_table_regval;
+ struct {
+@@ -3713,46 +2032,24 @@
+ mmr_t enable : 1;
+ } sh_iilb_over_ride_table_s;
+ } sh_iilb_over_ride_table_u_t;
+-#else
+-typedef union sh_iilb_over_ride_table_u {
+- mmr_t sh_iilb_over_ride_table_regval;
+- struct {
+- mmr_t enable : 1;
+- mmr_t reserved_0 : 57;
+- mmr_t ni_sel0 : 1;
+- mmr_t v0 : 1;
+- mmr_t dir0 : 4;
+- } sh_iilb_over_ride_table_s;
+-} sh_iilb_over_ride_table_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_IILB_RSP_PLANE_HINT" */
+ /* If enabled, invert incoming response only plane hint bit before lo */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_iilb_rsp_plane_hint_u {
+- mmr_t sh_iilb_rsp_plane_hint_regval;
+- struct {
+- mmr_t reserved_0 : 64;
+- } sh_iilb_rsp_plane_hint_s;
+-} sh_iilb_rsp_plane_hint_u_t;
+-#else
+ typedef union sh_iilb_rsp_plane_hint_u {
+ mmr_t sh_iilb_rsp_plane_hint_regval;
+ struct {
+ mmr_t reserved_0 : 64;
+ } sh_iilb_rsp_plane_hint_s;
+ } sh_iilb_rsp_plane_hint_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_LOCAL_TABLE" */
+ /* local lookup table */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_local_table_u {
+ mmr_t sh_pi_local_table_regval;
+ struct {
+@@ -3767,29 +2064,12 @@
+ mmr_t valid : 1;
+ } sh_pi_local_table_s;
+ } sh_pi_local_table_u_t;
+-#else
+-typedef union sh_pi_local_table_u {
+- mmr_t sh_pi_local_table_regval;
+- struct {
+- mmr_t valid : 1;
+- mmr_t reserved_1 : 49;
+- mmr_t ni_sel1 : 1;
+- mmr_t v1 : 1;
+- mmr_t dir1 : 4;
+- mmr_t reserved_0 : 2;
+- mmr_t ni_sel0 : 1;
+- mmr_t v0 : 1;
+- mmr_t dir0 : 4;
+- } sh_pi_local_table_s;
+-} sh_pi_local_table_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_GLOBAL_TABLE" */
+ /* global lookup table */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_global_table_u {
+ mmr_t sh_pi_global_table_regval;
+ struct {
+@@ -3804,29 +2084,12 @@
+ mmr_t valid : 1;
+ } sh_pi_global_table_s;
+ } sh_pi_global_table_u_t;
+-#else
+-typedef union sh_pi_global_table_u {
+- mmr_t sh_pi_global_table_regval;
+- struct {
+- mmr_t valid : 1;
+- mmr_t reserved_1 : 49;
+- mmr_t ni_sel1 : 1;
+- mmr_t v1 : 1;
+- mmr_t dir1 : 4;
+- mmr_t reserved_0 : 2;
+- mmr_t ni_sel0 : 1;
+- mmr_t v0 : 1;
+- mmr_t dir0 : 4;
+- } sh_pi_global_table_s;
+-} sh_pi_global_table_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_OVER_RIDE_TABLE" */
+ /* If enabled, bypass the Global/Local tables */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_over_ride_table_u {
+ mmr_t sh_pi_over_ride_table_regval;
+ struct {
+@@ -3841,29 +2104,12 @@
+ mmr_t enable : 1;
+ } sh_pi_over_ride_table_s;
+ } sh_pi_over_ride_table_u_t;
+-#else
+-typedef union sh_pi_over_ride_table_u {
+- mmr_t sh_pi_over_ride_table_regval;
+- struct {
+- mmr_t enable : 1;
+- mmr_t reserved_1 : 49;
+- mmr_t ni_sel1 : 1;
+- mmr_t v1 : 1;
+- mmr_t dir1 : 4;
+- mmr_t reserved_0 : 2;
+- mmr_t ni_sel0 : 1;
+- mmr_t v0 : 1;
+- mmr_t dir0 : 4;
+- } sh_pi_over_ride_table_s;
+-} sh_pi_over_ride_table_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_RSP_PLANE_HINT" */
+ /* If enabled, invert incoming response only plane hint bit before lo */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_rsp_plane_hint_u {
+ mmr_t sh_pi_rsp_plane_hint_regval;
+ struct {
+@@ -3871,22 +2117,12 @@
+ mmr_t reserved_0 : 63;
+ } sh_pi_rsp_plane_hint_s;
+ } sh_pi_rsp_plane_hint_u_t;
+-#else
+-typedef union sh_pi_rsp_plane_hint_u {
+- mmr_t sh_pi_rsp_plane_hint_regval;
+- struct {
+- mmr_t reserved_0 : 63;
+- mmr_t invert : 1;
+- } sh_pi_rsp_plane_hint_s;
+-} sh_pi_rsp_plane_hint_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI0_LOCAL_TABLE" */
+ /* local lookup table */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_local_table_u {
+ mmr_t sh_ni0_local_table_regval;
+ struct {
+@@ -3896,24 +2132,12 @@
+ mmr_t valid : 1;
+ } sh_ni0_local_table_s;
+ } sh_ni0_local_table_u_t;
+-#else
+-typedef union sh_ni0_local_table_u {
+- mmr_t sh_ni0_local_table_regval;
+- struct {
+- mmr_t valid : 1;
+- mmr_t reserved_0 : 58;
+- mmr_t v0 : 1;
+- mmr_t dir0 : 4;
+- } sh_ni0_local_table_s;
+-} sh_ni0_local_table_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI0_GLOBAL_TABLE" */
+ /* global lookup table */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_global_table_u {
+ mmr_t sh_ni0_global_table_regval;
+ struct {
+@@ -3923,24 +2147,12 @@
+ mmr_t valid : 1;
+ } sh_ni0_global_table_s;
+ } sh_ni0_global_table_u_t;
+-#else
+-typedef union sh_ni0_global_table_u {
+- mmr_t sh_ni0_global_table_regval;
+- struct {
+- mmr_t valid : 1;
+- mmr_t reserved_0 : 58;
+- mmr_t v0 : 1;
+- mmr_t dir0 : 4;
+- } sh_ni0_global_table_s;
+-} sh_ni0_global_table_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI0_OVER_RIDE_TABLE" */
+ /* If enabled, bypass the Global/Local tables */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_over_ride_table_u {
+ mmr_t sh_ni0_over_ride_table_regval;
+ struct {
+@@ -3950,45 +2162,24 @@
+ mmr_t enable : 1;
+ } sh_ni0_over_ride_table_s;
+ } sh_ni0_over_ride_table_u_t;
+-#else
+-typedef union sh_ni0_over_ride_table_u {
+- mmr_t sh_ni0_over_ride_table_regval;
+- struct {
+- mmr_t enable : 1;
+- mmr_t reserved_0 : 58;
+- mmr_t v0 : 1;
+- mmr_t dir0 : 4;
+- } sh_ni0_over_ride_table_s;
+-} sh_ni0_over_ride_table_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI0_RSP_PLANE_HINT" */
+ /* If enabled, invert incoming response only plane hint bit before lo */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_ni0_rsp_plane_hint_u {
+- mmr_t sh_ni0_rsp_plane_hint_regval;
+- struct {
+- mmr_t reserved_0 : 64;
+- } sh_ni0_rsp_plane_hint_s;
+-} sh_ni0_rsp_plane_hint_u_t;
+-#else
+ typedef union sh_ni0_rsp_plane_hint_u {
+ mmr_t sh_ni0_rsp_plane_hint_regval;
+ struct {
+ mmr_t reserved_0 : 64;
+ } sh_ni0_rsp_plane_hint_s;
+ } sh_ni0_rsp_plane_hint_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI1_LOCAL_TABLE" */
+ /* local lookup table */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_local_table_u {
+ mmr_t sh_ni1_local_table_regval;
+ struct {
+@@ -3998,24 +2189,12 @@
+ mmr_t valid : 1;
+ } sh_ni1_local_table_s;
+ } sh_ni1_local_table_u_t;
+-#else
+-typedef union sh_ni1_local_table_u {
+- mmr_t sh_ni1_local_table_regval;
+- struct {
+- mmr_t valid : 1;
+- mmr_t reserved_0 : 58;
+- mmr_t v0 : 1;
+- mmr_t dir0 : 4;
+- } sh_ni1_local_table_s;
+-} sh_ni1_local_table_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI1_GLOBAL_TABLE" */
+ /* global lookup table */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_global_table_u {
+ mmr_t sh_ni1_global_table_regval;
+ struct {
+@@ -4025,24 +2204,12 @@
+ mmr_t valid : 1;
+ } sh_ni1_global_table_s;
+ } sh_ni1_global_table_u_t;
+-#else
+-typedef union sh_ni1_global_table_u {
+- mmr_t sh_ni1_global_table_regval;
+- struct {
+- mmr_t valid : 1;
+- mmr_t reserved_0 : 58;
+- mmr_t v0 : 1;
+- mmr_t dir0 : 4;
+- } sh_ni1_global_table_s;
+-} sh_ni1_global_table_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI1_OVER_RIDE_TABLE" */
+ /* If enabled, bypass the Global/Local tables */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_over_ride_table_u {
+ mmr_t sh_ni1_over_ride_table_regval;
+ struct {
+@@ -4052,45 +2219,24 @@
+ mmr_t enable : 1;
+ } sh_ni1_over_ride_table_s;
+ } sh_ni1_over_ride_table_u_t;
+-#else
+-typedef union sh_ni1_over_ride_table_u {
+- mmr_t sh_ni1_over_ride_table_regval;
+- struct {
+- mmr_t enable : 1;
+- mmr_t reserved_0 : 58;
+- mmr_t v0 : 1;
+- mmr_t dir0 : 4;
+- } sh_ni1_over_ride_table_s;
+-} sh_ni1_over_ride_table_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI1_RSP_PLANE_HINT" */
+ /* If enabled, invert incoming response only plane hint bit before lo */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_ni1_rsp_plane_hint_u {
+- mmr_t sh_ni1_rsp_plane_hint_regval;
+- struct {
+- mmr_t reserved_0 : 64;
+- } sh_ni1_rsp_plane_hint_s;
+-} sh_ni1_rsp_plane_hint_u_t;
+-#else
+ typedef union sh_ni1_rsp_plane_hint_u {
+ mmr_t sh_ni1_rsp_plane_hint_regval;
+ struct {
+ mmr_t reserved_0 : 64;
+ } sh_ni1_rsp_plane_hint_s;
+ } sh_ni1_rsp_plane_hint_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_LOCAL_TABLE" */
+ /* local lookup table */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_local_table_u {
+ mmr_t sh_md_local_table_regval;
+ struct {
+@@ -4105,29 +2251,12 @@
+ mmr_t valid : 1;
+ } sh_md_local_table_s;
+ } sh_md_local_table_u_t;
+-#else
+-typedef union sh_md_local_table_u {
+- mmr_t sh_md_local_table_regval;
+- struct {
+- mmr_t valid : 1;
+- mmr_t reserved_1 : 49;
+- mmr_t ni_sel1 : 1;
+- mmr_t v1 : 1;
+- mmr_t dir1 : 4;
+- mmr_t reserved_0 : 2;
+- mmr_t ni_sel0 : 1;
+- mmr_t v0 : 1;
+- mmr_t dir0 : 4;
+- } sh_md_local_table_s;
+-} sh_md_local_table_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_GLOBAL_TABLE" */
+ /* global lookup table */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_global_table_u {
+ mmr_t sh_md_global_table_regval;
+ struct {
+@@ -4142,29 +2271,12 @@
+ mmr_t valid : 1;
+ } sh_md_global_table_s;
+ } sh_md_global_table_u_t;
+-#else
+-typedef union sh_md_global_table_u {
+- mmr_t sh_md_global_table_regval;
+- struct {
+- mmr_t valid : 1;
+- mmr_t reserved_1 : 49;
+- mmr_t ni_sel1 : 1;
+- mmr_t v1 : 1;
+- mmr_t dir1 : 4;
+- mmr_t reserved_0 : 2;
+- mmr_t ni_sel0 : 1;
+- mmr_t v0 : 1;
+- mmr_t dir0 : 4;
+- } sh_md_global_table_s;
+-} sh_md_global_table_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_OVER_RIDE_TABLE" */
+ /* If enabled, bypass the Global/Local tables */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_over_ride_table_u {
+ mmr_t sh_md_over_ride_table_regval;
+ struct {
+@@ -4179,29 +2291,12 @@
+ mmr_t enable : 1;
+ } sh_md_over_ride_table_s;
+ } sh_md_over_ride_table_u_t;
+-#else
+-typedef union sh_md_over_ride_table_u {
+- mmr_t sh_md_over_ride_table_regval;
+- struct {
+- mmr_t enable : 1;
+- mmr_t reserved_1 : 49;
+- mmr_t ni_sel1 : 1;
+- mmr_t v1 : 1;
+- mmr_t dir1 : 4;
+- mmr_t reserved_0 : 2;
+- mmr_t ni_sel0 : 1;
+- mmr_t v0 : 1;
+- mmr_t dir0 : 4;
+- } sh_md_over_ride_table_s;
+-} sh_md_over_ride_table_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_RSP_PLANE_HINT" */
+ /* If enabled, invert incoming response only plane hint bit before lo */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_rsp_plane_hint_u {
+ mmr_t sh_md_rsp_plane_hint_regval;
+ struct {
+@@ -4209,22 +2304,12 @@
+ mmr_t reserved_0 : 63;
+ } sh_md_rsp_plane_hint_s;
+ } sh_md_rsp_plane_hint_u_t;
+-#else
+-typedef union sh_md_rsp_plane_hint_u {
+- mmr_t sh_md_rsp_plane_hint_regval;
+- struct {
+- mmr_t reserved_0 : 63;
+- mmr_t invert : 1;
+- } sh_md_rsp_plane_hint_s;
+-} sh_md_rsp_plane_hint_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LB_LIQ_CTL" */
+ /* Local Block LIQ Control */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_liq_ctl_u {
+ mmr_t sh_lb_liq_ctl_regval;
+ struct {
+@@ -4238,28 +2323,12 @@
+ mmr_t reserved_2 : 45;
+ } sh_lb_liq_ctl_s;
+ } sh_lb_liq_ctl_u_t;
+-#else
+-typedef union sh_lb_liq_ctl_u {
+- mmr_t sh_lb_liq_ctl_regval;
+- struct {
+- mmr_t reserved_2 : 45;
+- mmr_t force_linvv_credit : 1;
+- mmr_t force_rp_credit : 1;
+- mmr_t force_rq_credit : 1;
+- mmr_t reserved_1 : 4;
+- mmr_t liq_rpl_ctl : 4;
+- mmr_t reserved_0 : 3;
+- mmr_t liq_req_ctl : 5;
+- } sh_lb_liq_ctl_s;
+-} sh_lb_liq_ctl_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LB_LOQ_CTL" */
+ /* Local Block LOQ Control */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_loq_ctl_u {
+ mmr_t sh_lb_loq_ctl_regval;
+ struct {
+@@ -4268,23 +2337,12 @@
+ mmr_t reserved_0 : 62;
+ } sh_lb_loq_ctl_s;
+ } sh_lb_loq_ctl_u_t;
+-#else
+-typedef union sh_lb_loq_ctl_u {
+- mmr_t sh_lb_loq_ctl_regval;
+- struct {
+- mmr_t reserved_0 : 62;
+- mmr_t loq_rpl_ctl : 1;
+- mmr_t loq_req_ctl : 1;
+- } sh_lb_loq_ctl_s;
+-} sh_lb_loq_ctl_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LB_MAX_REP_CREDIT_CNT" */
+ /* Maximum number of reply credits from XN */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_max_rep_credit_cnt_u {
+ mmr_t sh_lb_max_rep_credit_cnt_regval;
+ struct {
+@@ -4292,22 +2350,12 @@
+ mmr_t reserved_0 : 59;
+ } sh_lb_max_rep_credit_cnt_s;
+ } sh_lb_max_rep_credit_cnt_u_t;
+-#else
+-typedef union sh_lb_max_rep_credit_cnt_u {
+- mmr_t sh_lb_max_rep_credit_cnt_regval;
+- struct {
+- mmr_t reserved_0 : 59;
+- mmr_t max_cnt : 5;
+- } sh_lb_max_rep_credit_cnt_s;
+-} sh_lb_max_rep_credit_cnt_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LB_MAX_REQ_CREDIT_CNT" */
+ /* Maximum number of request credits from XN */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_max_req_credit_cnt_u {
+ mmr_t sh_lb_max_req_credit_cnt_regval;
+ struct {
+@@ -4315,22 +2363,12 @@
+ mmr_t reserved_0 : 59;
+ } sh_lb_max_req_credit_cnt_s;
+ } sh_lb_max_req_credit_cnt_u_t;
+-#else
+-typedef union sh_lb_max_req_credit_cnt_u {
+- mmr_t sh_lb_max_req_credit_cnt_regval;
+- struct {
+- mmr_t reserved_0 : 59;
+- mmr_t max_cnt : 5;
+- } sh_lb_max_req_credit_cnt_s;
+-} sh_lb_max_req_credit_cnt_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PIO_TIME_OUT" */
+ /* Local Block PIO time out value */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pio_time_out_u {
+ mmr_t sh_pio_time_out_regval;
+ struct {
+@@ -4338,22 +2376,12 @@
+ mmr_t reserved_0 : 48;
+ } sh_pio_time_out_s;
+ } sh_pio_time_out_u_t;
+-#else
+-typedef union sh_pio_time_out_u {
+- mmr_t sh_pio_time_out_regval;
+- struct {
+- mmr_t reserved_0 : 48;
+- mmr_t value : 16;
+- } sh_pio_time_out_s;
+-} sh_pio_time_out_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PIO_NACK_RESET" */
+ /* Local Block PIO Reset for nack counters */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pio_nack_reset_u {
+ mmr_t sh_pio_nack_reset_regval;
+ struct {
+@@ -4361,22 +2389,12 @@
+ mmr_t reserved_0 : 63;
+ } sh_pio_nack_reset_s;
+ } sh_pio_nack_reset_u_t;
+-#else
+-typedef union sh_pio_nack_reset_u {
+- mmr_t sh_pio_nack_reset_regval;
+- struct {
+- mmr_t reserved_0 : 63;
+- mmr_t pulse : 1;
+- } sh_pio_nack_reset_s;
+-} sh_pio_nack_reset_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_CONVEYOR_BELT_TIME_OUT" */
+ /* Local Block conveyor belt time out value */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_conveyor_belt_time_out_u {
+ mmr_t sh_conveyor_belt_time_out_regval;
+ struct {
+@@ -4384,22 +2402,12 @@
+ mmr_t reserved_0 : 52;
+ } sh_conveyor_belt_time_out_s;
+ } sh_conveyor_belt_time_out_u_t;
+-#else
+-typedef union sh_conveyor_belt_time_out_u {
+- mmr_t sh_conveyor_belt_time_out_regval;
+- struct {
+- mmr_t reserved_0 : 52;
+- mmr_t value : 12;
+- } sh_conveyor_belt_time_out_s;
+-} sh_conveyor_belt_time_out_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LB_CREDIT_STATUS" */
+ /* Credit Counter Status Register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_credit_status_u {
+ mmr_t sh_lb_credit_status_regval;
+ struct {
+@@ -4413,28 +2421,12 @@
+ mmr_t reserved_2 : 36;
+ } sh_lb_credit_status_s;
+ } sh_lb_credit_status_u_t;
+-#else
+-typedef union sh_lb_credit_status_u {
+- mmr_t sh_lb_credit_status_regval;
+- struct {
+- mmr_t reserved_2 : 36;
+- mmr_t loq_rp_credit : 5;
+- mmr_t loq_rq_credit : 5;
+- mmr_t linvv_credit : 6;
+- mmr_t reserved_1 : 2;
+- mmr_t liq_rp_credit : 4;
+- mmr_t reserved_0 : 1;
+- mmr_t liq_rq_credit : 5;
+- } sh_lb_credit_status_s;
+-} sh_lb_credit_status_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LB_DEBUG_LOCAL_SEL" */
+ /* LB Debug Port Select */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_debug_local_sel_u {
+ mmr_t sh_lb_debug_local_sel_regval;
+ struct {
+@@ -4472,52 +2464,12 @@
+ mmr_t trigger_enable : 1;
+ } sh_lb_debug_local_sel_s;
+ } sh_lb_debug_local_sel_u_t;
+-#else
+-typedef union sh_lb_debug_local_sel_u {
+- mmr_t sh_lb_debug_local_sel_regval;
+- struct {
+- mmr_t trigger_enable : 1;
+- mmr_t nibble7_nibble_sel : 3;
+- mmr_t reserved_14 : 1;
+- mmr_t nibble7_chiplet_sel : 3;
+- mmr_t reserved_13 : 1;
+- mmr_t nibble6_nibble_sel : 3;
+- mmr_t reserved_12 : 1;
+- mmr_t nibble6_chiplet_sel : 3;
+- mmr_t reserved_11 : 1;
+- mmr_t nibble5_nibble_sel : 3;
+- mmr_t reserved_10 : 1;
+- mmr_t nibble5_chiplet_sel : 3;
+- mmr_t reserved_9 : 1;
+- mmr_t nibble4_nibble_sel : 3;
+- mmr_t reserved_8 : 1;
+- mmr_t nibble4_chiplet_sel : 3;
+- mmr_t reserved_7 : 1;
+- mmr_t nibble3_nibble_sel : 3;
+- mmr_t reserved_6 : 1;
+- mmr_t nibble3_chiplet_sel : 3;
+- mmr_t reserved_5 : 1;
+- mmr_t nibble2_nibble_sel : 3;
+- mmr_t reserved_4 : 1;
+- mmr_t nibble2_chiplet_sel : 3;
+- mmr_t reserved_3 : 1;
+- mmr_t nibble1_nibble_sel : 3;
+- mmr_t reserved_2 : 1;
+- mmr_t nibble1_chiplet_sel : 3;
+- mmr_t reserved_1 : 1;
+- mmr_t nibble0_nibble_sel : 3;
+- mmr_t reserved_0 : 1;
+- mmr_t nibble0_chiplet_sel : 3;
+- } sh_lb_debug_local_sel_s;
+-} sh_lb_debug_local_sel_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LB_DEBUG_PERF_SEL" */
+ /* LB Debug Port Performance Select */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_debug_perf_sel_u {
+ mmr_t sh_lb_debug_perf_sel_regval;
+ struct {
+@@ -4555,52 +2507,12 @@
+ mmr_t reserved_15 : 1;
+ } sh_lb_debug_perf_sel_s;
+ } sh_lb_debug_perf_sel_u_t;
+-#else
+-typedef union sh_lb_debug_perf_sel_u {
+- mmr_t sh_lb_debug_perf_sel_regval;
+- struct {
+- mmr_t reserved_15 : 1;
+- mmr_t nibble7_nibble_sel : 3;
+- mmr_t reserved_14 : 1;
+- mmr_t nibble7_chiplet_sel : 3;
+- mmr_t reserved_13 : 1;
+- mmr_t nibble6_nibble_sel : 3;
+- mmr_t reserved_12 : 1;
+- mmr_t nibble6_chiplet_sel : 3;
+- mmr_t reserved_11 : 1;
+- mmr_t nibble5_nibble_sel : 3;
+- mmr_t reserved_10 : 1;
+- mmr_t nibble5_chiplet_sel : 3;
+- mmr_t reserved_9 : 1;
+- mmr_t nibble4_nibble_sel : 3;
+- mmr_t reserved_8 : 1;
+- mmr_t nibble4_chiplet_sel : 3;
+- mmr_t reserved_7 : 1;
+- mmr_t nibble3_nibble_sel : 3;
+- mmr_t reserved_6 : 1;
+- mmr_t nibble3_chiplet_sel : 3;
+- mmr_t reserved_5 : 1;
+- mmr_t nibble2_nibble_sel : 3;
+- mmr_t reserved_4 : 1;
+- mmr_t nibble2_chiplet_sel : 3;
+- mmr_t reserved_3 : 1;
+- mmr_t nibble1_nibble_sel : 3;
+- mmr_t reserved_2 : 1;
+- mmr_t nibble1_chiplet_sel : 3;
+- mmr_t reserved_1 : 1;
+- mmr_t nibble0_nibble_sel : 3;
+- mmr_t reserved_0 : 1;
+- mmr_t nibble0_chiplet_sel : 3;
+- } sh_lb_debug_perf_sel_s;
+-} sh_lb_debug_perf_sel_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LB_DEBUG_TRIG_SEL" */
+ /* LB Debug Trigger Select */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_debug_trig_sel_u {
+ mmr_t sh_lb_debug_trig_sel_regval;
+ struct {
+@@ -4638,52 +2550,12 @@
+ mmr_t reserved_15 : 1;
+ } sh_lb_debug_trig_sel_s;
+ } sh_lb_debug_trig_sel_u_t;
+-#else
+-typedef union sh_lb_debug_trig_sel_u {
+- mmr_t sh_lb_debug_trig_sel_regval;
+- struct {
+- mmr_t reserved_15 : 1;
+- mmr_t trigger7_nibble_sel : 3;
+- mmr_t reserved_14 : 1;
+- mmr_t trigger7_chiplet_sel : 3;
+- mmr_t reserved_13 : 1;
+- mmr_t trigger6_nibble_sel : 3;
+- mmr_t reserved_12 : 1;
+- mmr_t trigger6_chiplet_sel : 3;
+- mmr_t reserved_11 : 1;
+- mmr_t trigger5_nibble_sel : 3;
+- mmr_t reserved_10 : 1;
+- mmr_t trigger5_chiplet_sel : 3;
+- mmr_t reserved_9 : 1;
+- mmr_t trigger4_nibble_sel : 3;
+- mmr_t reserved_8 : 1;
+- mmr_t trigger4_chiplet_sel : 3;
+- mmr_t reserved_7 : 1;
+- mmr_t trigger3_nibble_sel : 3;
+- mmr_t reserved_6 : 1;
+- mmr_t trigger3_chiplet_sel : 3;
+- mmr_t reserved_5 : 1;
+- mmr_t trigger2_nibble_sel : 3;
+- mmr_t reserved_4 : 1;
+- mmr_t trigger2_chiplet_sel : 3;
+- mmr_t reserved_3 : 1;
+- mmr_t trigger1_nibble_sel : 3;
+- mmr_t reserved_2 : 1;
+- mmr_t trigger1_chiplet_sel : 3;
+- mmr_t reserved_1 : 1;
+- mmr_t trigger0_nibble_sel : 3;
+- mmr_t reserved_0 : 1;
+- mmr_t trigger0_chiplet_sel : 3;
+- } sh_lb_debug_trig_sel_s;
+-} sh_lb_debug_trig_sel_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LB_ERROR_DETAIL_1" */
+ /* LB Error capture information: HDR1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_error_detail_1_u {
+ mmr_t sh_lb_error_detail_1_regval;
+ struct {
+@@ -4700,31 +2572,12 @@
+ mmr_t valid : 1;
+ } sh_lb_error_detail_1_s;
+ } sh_lb_error_detail_1_u_t;
+-#else
+-typedef union sh_lb_error_detail_1_u {
+- mmr_t sh_lb_error_detail_1_regval;
+- struct {
+- mmr_t valid : 1;
+- mmr_t reserved_3 : 13;
+- mmr_t data_err : 1;
+- mmr_t hdr_err : 1;
+- mmr_t reserved_2 : 5;
+- mmr_t dest : 3;
+- mmr_t reserved_1 : 2;
+- mmr_t source : 14;
+- mmr_t reserved_0 : 2;
+- mmr_t suppl : 14;
+- mmr_t command : 8;
+- } sh_lb_error_detail_1_s;
+-} sh_lb_error_detail_1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LB_ERROR_DETAIL_2" */
+ /* LB Error Bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_error_detail_2_u {
+ mmr_t sh_lb_error_detail_2_regval;
+ struct {
+@@ -4732,64 +2585,36 @@
+ mmr_t reserved_0 : 17;
+ } sh_lb_error_detail_2_s;
+ } sh_lb_error_detail_2_u_t;
+-#else
+-typedef union sh_lb_error_detail_2_u {
+- mmr_t sh_lb_error_detail_2_regval;
+- struct {
+- mmr_t reserved_0 : 17;
+- mmr_t address : 47;
+- } sh_lb_error_detail_2_s;
+-} sh_lb_error_detail_2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LB_ERROR_DETAIL_3" */
+ /* LB Error Bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_lb_error_detail_3_u {
+- mmr_t sh_lb_error_detail_3_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_lb_error_detail_3_s;
+-} sh_lb_error_detail_3_u_t;
+-#else
+ typedef union sh_lb_error_detail_3_u {
+ mmr_t sh_lb_error_detail_3_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_lb_error_detail_3_s;
+ } sh_lb_error_detail_3_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LB_ERROR_DETAIL_4" */
+ /* LB Error Bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_lb_error_detail_4_u {
+- mmr_t sh_lb_error_detail_4_regval;
+- struct {
+- mmr_t route : 64;
+- } sh_lb_error_detail_4_s;
+-} sh_lb_error_detail_4_u_t;
+-#else
+ typedef union sh_lb_error_detail_4_u {
+ mmr_t sh_lb_error_detail_4_regval;
+ struct {
+ mmr_t route : 64;
+ } sh_lb_error_detail_4_s;
+ } sh_lb_error_detail_4_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LB_ERROR_DETAIL_5" */
+ /* LB Error Bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_error_detail_5_u {
+ mmr_t sh_lb_error_detail_5_regval;
+ struct {
+@@ -4803,28 +2628,12 @@
+ mmr_t reserved_0 : 57;
+ } sh_lb_error_detail_5_s;
+ } sh_lb_error_detail_5_u_t;
+-#else
+-typedef union sh_lb_error_detail_5_u {
+- mmr_t sh_lb_error_detail_5_regval;
+- struct {
+- mmr_t reserved_0 : 57;
+- mmr_t nack_b_timeout : 1;
+- mmr_t nack_a_timeout : 1;
+- mmr_t count_b_overflow : 1;
+- mmr_t count_a_overflow : 1;
+- mmr_t write_retry : 1;
+- mmr_t ptc1_write : 1;
+- mmr_t read_retry : 1;
+- } sh_lb_error_detail_5_s;
+-} sh_lb_error_detail_5_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LB_ERROR_MASK" */
+ /* LB Error Mask */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_error_mask_u {
+ mmr_t sh_lb_error_mask_regval;
+ struct {
+@@ -4854,44 +2663,12 @@
+ mmr_t reserved_0 : 41;
+ } sh_lb_error_mask_s;
+ } sh_lb_error_mask_u_t;
+-#else
+-typedef union sh_lb_error_mask_u {
+- mmr_t sh_lb_error_mask_regval;
+- struct {
+- mmr_t reserved_0 : 41;
+- mmr_t rp_credit_overflow : 1;
+- mmr_t rq_credit_overflow : 1;
+- mmr_t unexp_valid : 1;
+- mmr_t rp_fifo_error : 1;
+- mmr_t rq_fifo_error : 1;
+- mmr_t gclk_drop : 1;
+- mmr_t vector_rp_route_error : 1;
+- mmr_t vector_rq_route_error : 1;
+- mmr_t pio_cb_err : 1;
+- mmr_t junk_bus_err : 1;
+- mmr_t ptc_1_timeout : 1;
+- mmr_t unexpected_linv : 1;
+- mmr_t linvv_overflow : 1;
+- mmr_t rq_time_out : 1;
+- mmr_t rq_bad_addr : 1;
+- mmr_t rp_bad_data : 1;
+- mmr_t rq_bad_data : 1;
+- mmr_t rp_long : 1;
+- mmr_t rq_long : 1;
+- mmr_t rp_short : 1;
+- mmr_t rq_short : 1;
+- mmr_t rp_bad_cmd : 1;
+- mmr_t rq_bad_cmd : 1;
+- } sh_lb_error_mask_s;
+-} sh_lb_error_mask_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LB_ERROR_OVERFLOW" */
+ /* LB Error Overflow */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_error_overflow_u {
+ mmr_t sh_lb_error_overflow_regval;
+ struct {
+@@ -4921,44 +2698,12 @@
+ mmr_t reserved_0 : 41;
+ } sh_lb_error_overflow_s;
+ } sh_lb_error_overflow_u_t;
+-#else
+-typedef union sh_lb_error_overflow_u {
+- mmr_t sh_lb_error_overflow_regval;
+- struct {
+- mmr_t reserved_0 : 41;
+- mmr_t rp_credit_overflow_ovrfl : 1;
+- mmr_t rq_credit_overflow_ovrfl : 1;
+- mmr_t unexp_valid_ovrfl : 1;
+- mmr_t rp_fifo_error_ovrfl : 1;
+- mmr_t rq_fifo_error_ovrfl : 1;
+- mmr_t gclk_drop_ovrfl : 1;
+- mmr_t vector_rp_route_error_ovrfl : 1;
+- mmr_t vector_rq_route_error_ovrfl : 1;
+- mmr_t pio_cb_err_ovrfl : 1;
+- mmr_t junk_bus_err_ovrfl : 1;
+- mmr_t ptc_1_timeout_ovrfl : 1;
+- mmr_t unexpected_linv_ovrfl : 1;
+- mmr_t linvv_overflow_ovrfl : 1;
+- mmr_t rq_time_out_ovrfl : 1;
+- mmr_t rq_bad_addr_ovrfl : 1;
+- mmr_t rp_bad_data_ovrfl : 1;
+- mmr_t rq_bad_data_ovrfl : 1;
+- mmr_t rp_long_ovrfl : 1;
+- mmr_t rq_long_ovrfl : 1;
+- mmr_t rp_short_ovrfl : 1;
+- mmr_t rq_short_ovrfl : 1;
+- mmr_t rp_bad_cmd_ovrfl : 1;
+- mmr_t rq_bad_cmd_ovrfl : 1;
+- } sh_lb_error_overflow_s;
+-} sh_lb_error_overflow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LB_ERROR_SUMMARY" */
+ /* LB Error Bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_error_summary_u {
+ mmr_t sh_lb_error_summary_regval;
+ struct {
+@@ -4988,44 +2733,12 @@
+ mmr_t reserved_0 : 41;
+ } sh_lb_error_summary_s;
+ } sh_lb_error_summary_u_t;
+-#else
+-typedef union sh_lb_error_summary_u {
+- mmr_t sh_lb_error_summary_regval;
+- struct {
+- mmr_t reserved_0 : 41;
+- mmr_t rp_credit_overflow : 1;
+- mmr_t rq_credit_overflow : 1;
+- mmr_t unexp_valid : 1;
+- mmr_t rp_fifo_error : 1;
+- mmr_t rq_fifo_error : 1;
+- mmr_t gclk_drop : 1;
+- mmr_t vector_rp_route_error : 1;
+- mmr_t vector_rq_route_error : 1;
+- mmr_t pio_cb_err : 1;
+- mmr_t junk_bus_err : 1;
+- mmr_t ptc_1_timeout : 1;
+- mmr_t unexpected_linv : 1;
+- mmr_t linvv_overflow : 1;
+- mmr_t rq_time_out : 1;
+- mmr_t rq_bad_addr : 1;
+- mmr_t rp_bad_data : 1;
+- mmr_t rq_bad_data : 1;
+- mmr_t rp_long : 1;
+- mmr_t rq_long : 1;
+- mmr_t rp_short : 1;
+- mmr_t rq_short : 1;
+- mmr_t rp_bad_cmd : 1;
+- mmr_t rq_bad_cmd : 1;
+- } sh_lb_error_summary_s;
+-} sh_lb_error_summary_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LB_FIRST_ERROR" */
+ /* LB First Error */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_first_error_u {
+ mmr_t sh_lb_first_error_regval;
+ struct {
+@@ -5055,44 +2768,12 @@
+ mmr_t reserved_0 : 41;
+ } sh_lb_first_error_s;
+ } sh_lb_first_error_u_t;
+-#else
+-typedef union sh_lb_first_error_u {
+- mmr_t sh_lb_first_error_regval;
+- struct {
+- mmr_t reserved_0 : 41;
+- mmr_t rp_credit_overflow : 1;
+- mmr_t rq_credit_overflow : 1;
+- mmr_t unexp_valid : 1;
+- mmr_t rp_fifo_error : 1;
+- mmr_t rq_fifo_error : 1;
+- mmr_t gclk_drop : 1;
+- mmr_t vector_rp_route_error : 1;
+- mmr_t vector_rq_route_error : 1;
+- mmr_t pio_cb_err : 1;
+- mmr_t junk_bus_err : 1;
+- mmr_t ptc_1_timeout : 1;
+- mmr_t unexpected_linv : 1;
+- mmr_t linvv_overflow : 1;
+- mmr_t rq_time_out : 1;
+- mmr_t rq_bad_addr : 1;
+- mmr_t rp_bad_data : 1;
+- mmr_t rq_bad_data : 1;
+- mmr_t rp_long : 1;
+- mmr_t rq_long : 1;
+- mmr_t rp_short : 1;
+- mmr_t rq_short : 1;
+- mmr_t rp_bad_cmd : 1;
+- mmr_t rq_bad_cmd : 1;
+- } sh_lb_first_error_s;
+-} sh_lb_first_error_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LB_LAST_CREDIT" */
+ /* Credit counter status register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_last_credit_u {
+ mmr_t sh_lb_last_credit_regval;
+ struct {
+@@ -5106,28 +2787,12 @@
+ mmr_t reserved_2 : 36;
+ } sh_lb_last_credit_s;
+ } sh_lb_last_credit_u_t;
+-#else
+-typedef union sh_lb_last_credit_u {
+- mmr_t sh_lb_last_credit_regval;
+- struct {
+- mmr_t reserved_2 : 36;
+- mmr_t loq_rp_credit : 5;
+- mmr_t loq_rq_credit : 5;
+- mmr_t linvv_credit : 6;
+- mmr_t reserved_1 : 2;
+- mmr_t liq_rp_credit : 4;
+- mmr_t reserved_0 : 1;
+- mmr_t liq_rq_credit : 5;
+- } sh_lb_last_credit_s;
+-} sh_lb_last_credit_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LB_NACK_STATUS" */
+ /* Nack Counter Status Register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_nack_status_u {
+ mmr_t sh_lb_nack_status_regval;
+ struct {
+@@ -5141,28 +2806,12 @@
+ mmr_t reserved_2 : 2;
+ } sh_lb_nack_status_s;
+ } sh_lb_nack_status_u_t;
+-#else
+-typedef union sh_lb_nack_status_u {
+- mmr_t sh_lb_nack_status_regval;
+- struct {
+- mmr_t reserved_2 : 2;
+- mmr_t cb_state : 2;
+- mmr_t cb_timeout_count : 12;
+- mmr_t junk_nack : 16;
+- mmr_t reserved_1 : 4;
+- mmr_t pio_nack_b : 12;
+- mmr_t reserved_0 : 4;
+- mmr_t pio_nack_a : 12;
+- } sh_lb_nack_status_s;
+-} sh_lb_nack_status_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LB_TRIGGER_COMPARE" */
+ /* LB Test-point Trigger Compare */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_trigger_compare_u {
+ mmr_t sh_lb_trigger_compare_regval;
+ struct {
+@@ -5170,22 +2819,12 @@
+ mmr_t reserved_0 : 32;
+ } sh_lb_trigger_compare_s;
+ } sh_lb_trigger_compare_u_t;
+-#else
+-typedef union sh_lb_trigger_compare_u {
+- mmr_t sh_lb_trigger_compare_regval;
+- struct {
+- mmr_t reserved_0 : 32;
+- mmr_t mask : 32;
+- } sh_lb_trigger_compare_s;
+-} sh_lb_trigger_compare_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LB_TRIGGER_DATA" */
+ /* LB Test-point Trigger Compare Data */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_trigger_data_u {
+ mmr_t sh_lb_trigger_data_regval;
+ struct {
+@@ -5193,22 +2832,12 @@
+ mmr_t reserved_0 : 32;
+ } sh_lb_trigger_data_s;
+ } sh_lb_trigger_data_u_t;
+-#else
+-typedef union sh_lb_trigger_data_u {
+- mmr_t sh_lb_trigger_data_regval;
+- struct {
+- mmr_t reserved_0 : 32;
+- mmr_t compare_pattern : 32;
+- } sh_lb_trigger_data_s;
+-} sh_lb_trigger_data_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_AEC_CONFIG" */
+ /* PI Adaptive Error Correction Configuration */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_aec_config_u {
+ mmr_t sh_pi_aec_config_regval;
+ struct {
+@@ -5216,22 +2845,12 @@
+ mmr_t reserved_0 : 61;
+ } sh_pi_aec_config_s;
+ } sh_pi_aec_config_u_t;
+-#else
+-typedef union sh_pi_aec_config_u {
+- mmr_t sh_pi_aec_config_regval;
+- struct {
+- mmr_t reserved_0 : 61;
+- mmr_t mode : 3;
+- } sh_pi_aec_config_s;
+-} sh_pi_aec_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_AFI_ERROR_MASK" */
+ /* PI AFI Error Mask */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_afi_error_mask_u {
+ mmr_t sh_pi_afi_error_mask_regval;
+ struct {
+@@ -5253,36 +2872,12 @@
+ mmr_t reserved_1 : 29;
+ } sh_pi_afi_error_mask_s;
+ } sh_pi_afi_error_mask_u_t;
+-#else
+-typedef union sh_pi_afi_error_mask_u {
+- mmr_t sh_pi_afi_error_mask_regval;
+- struct {
+- mmr_t reserved_1 : 29;
+- mmr_t msg_len : 1;
+- mmr_t fsb_tbl_miss : 1;
+- mmr_t bad_snoop : 1;
+- mmr_t livelock : 1;
+- mmr_t shub_fsb_ce : 1;
+- mmr_t shub_fsb_uce : 1;
+- mmr_t shub_fsb_dqe : 1;
+- mmr_t addr_parity : 1;
+- mmr_t req_parity : 1;
+- mmr_t addr_access : 1;
+- mmr_t req_format : 1;
+- mmr_t ioq_overrun : 1;
+- mmr_t rsp_parity : 1;
+- mmr_t hung_bus : 1;
+- mmr_t reserved_0 : 21;
+- } sh_pi_afi_error_mask_s;
+-} sh_pi_afi_error_mask_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_AFI_TEST_POINT_COMPARE" */
+ /* PI AFI Test Point Compare */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_afi_test_point_compare_u {
+ mmr_t sh_pi_afi_test_point_compare_regval;
+ struct {
+@@ -5290,22 +2885,12 @@
+ mmr_t compare_pattern : 32;
+ } sh_pi_afi_test_point_compare_s;
+ } sh_pi_afi_test_point_compare_u_t;
+-#else
+-typedef union sh_pi_afi_test_point_compare_u {
+- mmr_t sh_pi_afi_test_point_compare_regval;
+- struct {
+- mmr_t compare_pattern : 32;
+- mmr_t compare_mask : 32;
+- } sh_pi_afi_test_point_compare_s;
+-} sh_pi_afi_test_point_compare_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_AFI_TEST_POINT_SELECT" */
+ /* PI AFI Test Point Select */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_afi_test_point_select_u {
+ mmr_t sh_pi_afi_test_point_select_regval;
+ struct {
+@@ -5335,44 +2920,12 @@
+ mmr_t trigger_enable : 1;
+ } sh_pi_afi_test_point_select_s;
+ } sh_pi_afi_test_point_select_u_t;
+-#else
+-typedef union sh_pi_afi_test_point_select_u {
+- mmr_t sh_pi_afi_test_point_select_regval;
+- struct {
+- mmr_t trigger_enable : 1;
+- mmr_t nibble7_nibble_sel : 3;
+- mmr_t nibble7_chiplet_sel : 4;
+- mmr_t reserved_6 : 1;
+- mmr_t nibble6_nibble_sel : 3;
+- mmr_t nibble6_chiplet_sel : 4;
+- mmr_t reserved_5 : 1;
+- mmr_t nibble5_nibble_sel : 3;
+- mmr_t nibble5_chiplet_sel : 4;
+- mmr_t reserved_4 : 1;
+- mmr_t nibble4_nibble_sel : 3;
+- mmr_t nibble4_chiplet_sel : 4;
+- mmr_t reserved_3 : 1;
+- mmr_t nibble3_nibble_sel : 3;
+- mmr_t nibble3_chiplet_sel : 4;
+- mmr_t reserved_2 : 1;
+- mmr_t nibble2_nibble_sel : 3;
+- mmr_t nibble2_chiplet_sel : 4;
+- mmr_t reserved_1 : 1;
+- mmr_t nibble1_nibble_sel : 3;
+- mmr_t nibble1_chiplet_sel : 4;
+- mmr_t reserved_0 : 1;
+- mmr_t nibble0_nibble_sel : 3;
+- mmr_t nibble0_chiplet_sel : 4;
+- } sh_pi_afi_test_point_select_s;
+-} sh_pi_afi_test_point_select_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_AFI_TEST_POINT_TRIGGER_SELECT" */
+ /* PI CRBC Test Point Trigger Select */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_afi_test_point_trigger_select_u {
+ mmr_t sh_pi_afi_test_point_trigger_select_regval;
+ struct {
+@@ -5402,44 +2955,12 @@
+ mmr_t reserved_7 : 1;
+ } sh_pi_afi_test_point_trigger_select_s;
+ } sh_pi_afi_test_point_trigger_select_u_t;
+-#else
+-typedef union sh_pi_afi_test_point_trigger_select_u {
+- mmr_t sh_pi_afi_test_point_trigger_select_regval;
+- struct {
+- mmr_t reserved_7 : 1;
+- mmr_t trigger7_nibble_sel : 3;
+- mmr_t trigger7_chiplet_sel : 4;
+- mmr_t reserved_6 : 1;
+- mmr_t trigger6_nibble_sel : 3;
+- mmr_t trigger6_chiplet_sel : 4;
+- mmr_t reserved_5 : 1;
+- mmr_t trigger5_nibble_sel : 3;
+- mmr_t trigger5_chiplet_sel : 4;
+- mmr_t reserved_4 : 1;
+- mmr_t trigger4_nibble_sel : 3;
+- mmr_t trigger4_chiplet_sel : 4;
+- mmr_t reserved_3 : 1;
+- mmr_t trigger3_nibble_sel : 3;
+- mmr_t trigger3_chiplet_sel : 4;
+- mmr_t reserved_2 : 1;
+- mmr_t trigger2_nibble_sel : 3;
+- mmr_t trigger2_chiplet_sel : 4;
+- mmr_t reserved_1 : 1;
+- mmr_t trigger1_nibble_sel : 3;
+- mmr_t trigger1_chiplet_sel : 4;
+- mmr_t reserved_0 : 1;
+- mmr_t trigger0_nibble_sel : 3;
+- mmr_t trigger0_chiplet_sel : 4;
+- } sh_pi_afi_test_point_trigger_select_s;
+-} sh_pi_afi_test_point_trigger_select_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_AUTO_REPLY_ENABLE" */
+ /* PI Auto Reply Enable */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_auto_reply_enable_u {
+ mmr_t sh_pi_auto_reply_enable_regval;
+ struct {
+@@ -5447,22 +2968,12 @@
+ mmr_t reserved_0 : 63;
+ } sh_pi_auto_reply_enable_s;
+ } sh_pi_auto_reply_enable_u_t;
+-#else
+-typedef union sh_pi_auto_reply_enable_u {
+- mmr_t sh_pi_auto_reply_enable_regval;
+- struct {
+- mmr_t reserved_0 : 63;
+- mmr_t auto_reply_enable : 1;
+- } sh_pi_auto_reply_enable_s;
+-} sh_pi_auto_reply_enable_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_CAM_CONTROL" */
+ /* CRB CAM MMR Access Control */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_cam_control_u {
+ mmr_t sh_pi_cam_control_regval;
+ struct {
+@@ -5474,26 +2985,12 @@
+ mmr_t start : 1;
+ } sh_pi_cam_control_s;
+ } sh_pi_cam_control_u_t;
+-#else
+-typedef union sh_pi_cam_control_u {
+- mmr_t sh_pi_cam_control_regval;
+- struct {
+- mmr_t start : 1;
+- mmr_t reserved_1 : 53;
+- mmr_t rrb_rd_xfer_clear : 1;
+- mmr_t cam_write : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t cam_indx : 7;
+- } sh_pi_cam_control_s;
+-} sh_pi_cam_control_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_CRBC_TEST_POINT_COMPARE" */
+ /* PI CRBC Test Point Compare */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_crbc_test_point_compare_u {
+ mmr_t sh_pi_crbc_test_point_compare_regval;
+ struct {
+@@ -5501,22 +2998,12 @@
+ mmr_t compare_pattern : 32;
+ } sh_pi_crbc_test_point_compare_s;
+ } sh_pi_crbc_test_point_compare_u_t;
+-#else
+-typedef union sh_pi_crbc_test_point_compare_u {
+- mmr_t sh_pi_crbc_test_point_compare_regval;
+- struct {
+- mmr_t compare_pattern : 32;
+- mmr_t compare_mask : 32;
+- } sh_pi_crbc_test_point_compare_s;
+-} sh_pi_crbc_test_point_compare_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_CRBC_TEST_POINT_SELECT" */
+ /* PI CRBC Test Point Select */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_crbc_test_point_select_u {
+ mmr_t sh_pi_crbc_test_point_select_regval;
+ struct {
+@@ -5554,54 +3041,14 @@
+ mmr_t trigger_enable : 1;
+ } sh_pi_crbc_test_point_select_s;
+ } sh_pi_crbc_test_point_select_u_t;
+-#else
+-typedef union sh_pi_crbc_test_point_select_u {
+- mmr_t sh_pi_crbc_test_point_select_regval;
+- struct {
+- mmr_t trigger_enable : 1;
+- mmr_t nibble7_nibble_sel : 3;
+- mmr_t reserved_14 : 1;
+- mmr_t nibble7_chiplet_sel : 3;
+- mmr_t reserved_13 : 1;
+- mmr_t nibble6_nibble_sel : 3;
+- mmr_t reserved_12 : 1;
+- mmr_t nibble6_chiplet_sel : 3;
+- mmr_t reserved_11 : 1;
+- mmr_t nibble5_nibble_sel : 3;
+- mmr_t reserved_10 : 1;
+- mmr_t nibble5_chiplet_sel : 3;
+- mmr_t reserved_9 : 1;
+- mmr_t nibble4_nibble_sel : 3;
+- mmr_t reserved_8 : 1;
+- mmr_t nibble4_chiplet_sel : 3;
+- mmr_t reserved_7 : 1;
+- mmr_t nibble3_nibble_sel : 3;
+- mmr_t reserved_6 : 1;
+- mmr_t nibble3_chiplet_sel : 3;
+- mmr_t reserved_5 : 1;
+- mmr_t nibble2_nibble_sel : 3;
+- mmr_t reserved_4 : 1;
+- mmr_t nibble2_chiplet_sel : 3;
+- mmr_t reserved_3 : 1;
+- mmr_t nibble1_nibble_sel : 3;
+- mmr_t reserved_2 : 1;
+- mmr_t nibble1_chiplet_sel : 3;
+- mmr_t reserved_1 : 1;
+- mmr_t nibble0_nibble_sel : 3;
+- mmr_t reserved_0 : 1;
+- mmr_t nibble0_chiplet_sel : 3;
+- } sh_pi_crbc_test_point_select_s;
+-} sh_pi_crbc_test_point_select_u_t;
+-#endif
+-
+-/* ==================================================================== */
+-/* Register "SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT" */
+-/* PI CRBC Test Point Trigger Select */
+-/* ==================================================================== */
+-
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_pi_crbc_test_point_trigger_select_u {
+- mmr_t sh_pi_crbc_test_point_trigger_select_regval;
++
++/* ==================================================================== */
++/* Register "SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT" */
++/* PI CRBC Test Point Trigger Select */
++/* ==================================================================== */
++
++typedef union sh_pi_crbc_test_point_trigger_select_u {
++ mmr_t sh_pi_crbc_test_point_trigger_select_regval;
+ struct {
+ mmr_t trigger0_chiplet_sel : 3;
+ mmr_t reserved_0 : 1;
+@@ -5637,52 +3084,12 @@
+ mmr_t reserved_15 : 1;
+ } sh_pi_crbc_test_point_trigger_select_s;
+ } sh_pi_crbc_test_point_trigger_select_u_t;
+-#else
+-typedef union sh_pi_crbc_test_point_trigger_select_u {
+- mmr_t sh_pi_crbc_test_point_trigger_select_regval;
+- struct {
+- mmr_t reserved_15 : 1;
+- mmr_t trigger7_nibble_sel : 3;
+- mmr_t reserved_14 : 1;
+- mmr_t trigger7_chiplet_sel : 3;
+- mmr_t reserved_13 : 1;
+- mmr_t trigger6_nibble_sel : 3;
+- mmr_t reserved_12 : 1;
+- mmr_t trigger6_chiplet_sel : 3;
+- mmr_t reserved_11 : 1;
+- mmr_t trigger5_nibble_sel : 3;
+- mmr_t reserved_10 : 1;
+- mmr_t trigger5_chiplet_sel : 3;
+- mmr_t reserved_9 : 1;
+- mmr_t trigger4_nibble_sel : 3;
+- mmr_t reserved_8 : 1;
+- mmr_t trigger4_chiplet_sel : 3;
+- mmr_t reserved_7 : 1;
+- mmr_t trigger3_nibble_sel : 3;
+- mmr_t reserved_6 : 1;
+- mmr_t trigger3_chiplet_sel : 3;
+- mmr_t reserved_5 : 1;
+- mmr_t trigger2_nibble_sel : 3;
+- mmr_t reserved_4 : 1;
+- mmr_t trigger2_chiplet_sel : 3;
+- mmr_t reserved_3 : 1;
+- mmr_t trigger1_nibble_sel : 3;
+- mmr_t reserved_2 : 1;
+- mmr_t trigger1_chiplet_sel : 3;
+- mmr_t reserved_1 : 1;
+- mmr_t trigger0_nibble_sel : 3;
+- mmr_t reserved_0 : 1;
+- mmr_t trigger0_chiplet_sel : 3;
+- } sh_pi_crbc_test_point_trigger_select_s;
+-} sh_pi_crbc_test_point_trigger_select_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_CRBP_ERROR_MASK" */
+ /* PI CRBP Error Mask */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_crbp_error_mask_u {
+ mmr_t sh_pi_crbp_error_mask_regval;
+ struct {
+@@ -5710,42 +3117,12 @@
+ mmr_t reserved_0 : 43;
+ } sh_pi_crbp_error_mask_s;
+ } sh_pi_crbp_error_mask_u_t;
+-#else
+-typedef union sh_pi_crbp_error_mask_u {
+- mmr_t sh_pi_crbp_error_mask_regval;
+- struct {
+- mmr_t reserved_0 : 43;
+- mmr_t xn_rp_crd_oflow : 1;
+- mmr_t xn_rq_crd_oflow : 1;
+- mmr_t md_rp_crd_oflow : 1;
+- mmr_t md_rq_crd_oflow : 1;
+- mmr_t gfx_int_1 : 1;
+- mmr_t gfx_int_0 : 1;
+- mmr_t nack_oflow : 1;
+- mmr_t xn_rp_q_oflow : 1;
+- mmr_t xn_rq_q_oflow : 1;
+- mmr_t md_rp_q_oflow : 1;
+- mmr_t md_rq_q_oflow : 1;
+- mmr_t msg_color_err : 1;
+- mmr_t fsb_shub_ce : 1;
+- mmr_t fsb_shub_uce : 1;
+- mmr_t pio_to_err : 1;
+- mmr_t mem_to_err : 1;
+- mmr_t pio_rp_err : 1;
+- mmr_t mem_rp_err : 1;
+- mmr_t xb_proto_err : 1;
+- mmr_t gfx_rp_err : 1;
+- mmr_t fsb_proto_err : 1;
+- } sh_pi_crbp_error_mask_s;
+-} sh_pi_crbp_error_mask_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_CRBP_FSB_PIPE_COMPARE" */
+ /* CRBP FSB Pipe Compare */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_crbp_fsb_pipe_compare_u {
+ mmr_t sh_pi_crbp_fsb_pipe_compare_regval;
+ struct {
+@@ -5754,23 +3131,12 @@
+ mmr_t reserved_0 : 11;
+ } sh_pi_crbp_fsb_pipe_compare_s;
+ } sh_pi_crbp_fsb_pipe_compare_u_t;
+-#else
+-typedef union sh_pi_crbp_fsb_pipe_compare_u {
+- mmr_t sh_pi_crbp_fsb_pipe_compare_regval;
+- struct {
+- mmr_t reserved_0 : 11;
+- mmr_t compare_req : 6;
+- mmr_t compare_address : 47;
+- } sh_pi_crbp_fsb_pipe_compare_s;
+-} sh_pi_crbp_fsb_pipe_compare_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_CRBP_FSB_PIPE_MASK" */
+ /* CRBP Compare Mask */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_crbp_fsb_pipe_mask_u {
+ mmr_t sh_pi_crbp_fsb_pipe_mask_regval;
+ struct {
+@@ -5779,23 +3145,12 @@
+ mmr_t reserved_0 : 11;
+ } sh_pi_crbp_fsb_pipe_mask_s;
+ } sh_pi_crbp_fsb_pipe_mask_u_t;
+-#else
+-typedef union sh_pi_crbp_fsb_pipe_mask_u {
+- mmr_t sh_pi_crbp_fsb_pipe_mask_regval;
+- struct {
+- mmr_t reserved_0 : 11;
+- mmr_t compare_req_mask : 6;
+- mmr_t compare_address_mask : 47;
+- } sh_pi_crbp_fsb_pipe_mask_s;
+-} sh_pi_crbp_fsb_pipe_mask_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_CRBP_TEST_POINT_COMPARE" */
+ /* PI CRBP Test Point Compare */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_crbp_test_point_compare_u {
+ mmr_t sh_pi_crbp_test_point_compare_regval;
+ struct {
+@@ -5803,22 +3158,12 @@
+ mmr_t compare_pattern : 32;
+ } sh_pi_crbp_test_point_compare_s;
+ } sh_pi_crbp_test_point_compare_u_t;
+-#else
+-typedef union sh_pi_crbp_test_point_compare_u {
+- mmr_t sh_pi_crbp_test_point_compare_regval;
+- struct {
+- mmr_t compare_pattern : 32;
+- mmr_t compare_mask : 32;
+- } sh_pi_crbp_test_point_compare_s;
+-} sh_pi_crbp_test_point_compare_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_CRBP_TEST_POINT_SELECT" */
+ /* PI CRBP Test Point Select */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_crbp_test_point_select_u {
+ mmr_t sh_pi_crbp_test_point_select_regval;
+ struct {
+@@ -5856,52 +3201,12 @@
+ mmr_t trigger_enable : 1;
+ } sh_pi_crbp_test_point_select_s;
+ } sh_pi_crbp_test_point_select_u_t;
+-#else
+-typedef union sh_pi_crbp_test_point_select_u {
+- mmr_t sh_pi_crbp_test_point_select_regval;
+- struct {
+- mmr_t trigger_enable : 1;
+- mmr_t nibble7_nibble_sel : 3;
+- mmr_t reserved_14 : 1;
+- mmr_t nibble7_chiplet_sel : 3;
+- mmr_t reserved_13 : 1;
+- mmr_t nibble6_nibble_sel : 3;
+- mmr_t reserved_12 : 1;
+- mmr_t nibble6_chiplet_sel : 3;
+- mmr_t reserved_11 : 1;
+- mmr_t nibble5_nibble_sel : 3;
+- mmr_t reserved_10 : 1;
+- mmr_t nibble5_chiplet_sel : 3;
+- mmr_t reserved_9 : 1;
+- mmr_t nibble4_nibble_sel : 3;
+- mmr_t reserved_8 : 1;
+- mmr_t nibble4_chiplet_sel : 3;
+- mmr_t reserved_7 : 1;
+- mmr_t nibble3_nibble_sel : 3;
+- mmr_t reserved_6 : 1;
+- mmr_t nibble3_chiplet_sel : 3;
+- mmr_t reserved_5 : 1;
+- mmr_t nibble2_nibble_sel : 3;
+- mmr_t reserved_4 : 1;
+- mmr_t nibble2_chiplet_sel : 3;
+- mmr_t reserved_3 : 1;
+- mmr_t nibble1_nibble_sel : 3;
+- mmr_t reserved_2 : 1;
+- mmr_t nibble1_chiplet_sel : 3;
+- mmr_t reserved_1 : 1;
+- mmr_t nibble0_nibble_sel : 3;
+- mmr_t reserved_0 : 1;
+- mmr_t nibble0_chiplet_sel : 3;
+- } sh_pi_crbp_test_point_select_s;
+-} sh_pi_crbp_test_point_select_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT" */
+ /* PI CRBP Test Point Trigger Select */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_crbp_test_point_trigger_select_u {
+ mmr_t sh_pi_crbp_test_point_trigger_select_regval;
+ struct {
+@@ -5939,52 +3244,12 @@
+ mmr_t reserved_15 : 1;
+ } sh_pi_crbp_test_point_trigger_select_s;
+ } sh_pi_crbp_test_point_trigger_select_u_t;
+-#else
+-typedef union sh_pi_crbp_test_point_trigger_select_u {
+- mmr_t sh_pi_crbp_test_point_trigger_select_regval;
+- struct {
+- mmr_t reserved_15 : 1;
+- mmr_t trigger7_nibble_sel : 3;
+- mmr_t reserved_14 : 1;
+- mmr_t trigger7_chiplet_sel : 3;
+- mmr_t reserved_13 : 1;
+- mmr_t trigger6_nibble_sel : 3;
+- mmr_t reserved_12 : 1;
+- mmr_t trigger6_chiplet_sel : 3;
+- mmr_t reserved_11 : 1;
+- mmr_t trigger5_nibble_sel : 3;
+- mmr_t reserved_10 : 1;
+- mmr_t trigger5_chiplet_sel : 3;
+- mmr_t reserved_9 : 1;
+- mmr_t trigger4_nibble_sel : 3;
+- mmr_t reserved_8 : 1;
+- mmr_t trigger4_chiplet_sel : 3;
+- mmr_t reserved_7 : 1;
+- mmr_t trigger3_nibble_sel : 3;
+- mmr_t reserved_6 : 1;
+- mmr_t trigger3_chiplet_sel : 3;
+- mmr_t reserved_5 : 1;
+- mmr_t trigger2_nibble_sel : 3;
+- mmr_t reserved_4 : 1;
+- mmr_t trigger2_chiplet_sel : 3;
+- mmr_t reserved_3 : 1;
+- mmr_t trigger1_nibble_sel : 3;
+- mmr_t reserved_2 : 1;
+- mmr_t trigger1_chiplet_sel : 3;
+- mmr_t reserved_1 : 1;
+- mmr_t trigger0_nibble_sel : 3;
+- mmr_t reserved_0 : 1;
+- mmr_t trigger0_chiplet_sel : 3;
+- } sh_pi_crbp_test_point_trigger_select_s;
+-} sh_pi_crbp_test_point_trigger_select_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_CRBP_XB_PIPE_COMPARE_0" */
+ /* CRBP XB Pipe Compare */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_crbp_xb_pipe_compare_0_u {
+ mmr_t sh_pi_crbp_xb_pipe_compare_0_regval;
+ struct {
+@@ -5993,23 +3258,12 @@
+ mmr_t reserved_0 : 9;
+ } sh_pi_crbp_xb_pipe_compare_0_s;
+ } sh_pi_crbp_xb_pipe_compare_0_u_t;
+-#else
+-typedef union sh_pi_crbp_xb_pipe_compare_0_u {
+- mmr_t sh_pi_crbp_xb_pipe_compare_0_regval;
+- struct {
+- mmr_t reserved_0 : 9;
+- mmr_t compare_command : 8;
+- mmr_t compare_address : 47;
+- } sh_pi_crbp_xb_pipe_compare_0_s;
+-} sh_pi_crbp_xb_pipe_compare_0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_CRBP_XB_PIPE_COMPARE_1" */
+ /* CRBP XB Pipe Compare */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_crbp_xb_pipe_compare_1_u {
+ mmr_t sh_pi_crbp_xb_pipe_compare_1_regval;
+ struct {
+@@ -6021,26 +3275,12 @@
+ mmr_t reserved_2 : 23;
+ } sh_pi_crbp_xb_pipe_compare_1_s;
+ } sh_pi_crbp_xb_pipe_compare_1_u_t;
+-#else
+-typedef union sh_pi_crbp_xb_pipe_compare_1_u {
+- mmr_t sh_pi_crbp_xb_pipe_compare_1_regval;
+- struct {
+- mmr_t reserved_2 : 23;
+- mmr_t compare_echo : 9;
+- mmr_t reserved_1 : 2;
+- mmr_t compare_supplemental : 14;
+- mmr_t reserved_0 : 2;
+- mmr_t compare_source : 14;
+- } sh_pi_crbp_xb_pipe_compare_1_s;
+-} sh_pi_crbp_xb_pipe_compare_1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_CRBP_XB_PIPE_MASK_0" */
+ /* CRBP Compare Mask Register 1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_crbp_xb_pipe_mask_0_u {
+ mmr_t sh_pi_crbp_xb_pipe_mask_0_regval;
+ struct {
+@@ -6049,23 +3289,12 @@
+ mmr_t reserved_0 : 9;
+ } sh_pi_crbp_xb_pipe_mask_0_s;
+ } sh_pi_crbp_xb_pipe_mask_0_u_t;
+-#else
+-typedef union sh_pi_crbp_xb_pipe_mask_0_u {
+- mmr_t sh_pi_crbp_xb_pipe_mask_0_regval;
+- struct {
+- mmr_t reserved_0 : 9;
+- mmr_t compare_command_mask : 8;
+- mmr_t compare_address_mask : 47;
+- } sh_pi_crbp_xb_pipe_mask_0_s;
+-} sh_pi_crbp_xb_pipe_mask_0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_CRBP_XB_PIPE_MASK_1" */
+ /* CRBP XB Pipe Compare Mask Register 1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_crbp_xb_pipe_mask_1_u {
+ mmr_t sh_pi_crbp_xb_pipe_mask_1_regval;
+ struct {
+@@ -6077,26 +3306,12 @@
+ mmr_t reserved_2 : 23;
+ } sh_pi_crbp_xb_pipe_mask_1_s;
+ } sh_pi_crbp_xb_pipe_mask_1_u_t;
+-#else
+-typedef union sh_pi_crbp_xb_pipe_mask_1_u {
+- mmr_t sh_pi_crbp_xb_pipe_mask_1_regval;
+- struct {
+- mmr_t reserved_2 : 23;
+- mmr_t compare_echo_mask : 9;
+- mmr_t reserved_1 : 2;
+- mmr_t compare_supplemental_mask : 14;
+- mmr_t reserved_0 : 2;
+- mmr_t compare_source_mask : 14;
+- } sh_pi_crbp_xb_pipe_mask_1_s;
+-} sh_pi_crbp_xb_pipe_mask_1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_DPC_QUEUE_CONFIG" */
+ /* DPC Queue Configuration */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_dpc_queue_config_u {
+ mmr_t sh_pi_dpc_queue_config_regval;
+ struct {
+@@ -6110,28 +3325,12 @@
+ mmr_t reserved_3 : 35;
+ } sh_pi_dpc_queue_config_s;
+ } sh_pi_dpc_queue_config_u_t;
+-#else
+-typedef union sh_pi_dpc_queue_config_u {
+- mmr_t sh_pi_dpc_queue_config_regval;
+- struct {
+- mmr_t reserved_3 : 35;
+- mmr_t fwcq_af_thresh : 5;
+- mmr_t reserved_2 : 3;
+- mmr_t fwcq_ae_level : 5;
+- mmr_t reserved_1 : 3;
+- mmr_t dwcq_af_thresh : 5;
+- mmr_t reserved_0 : 3;
+- mmr_t dwcq_ae_level : 5;
+- } sh_pi_dpc_queue_config_s;
+-} sh_pi_dpc_queue_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_ERROR_MASK" */
+ /* PI Error Mask */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_error_mask_u {
+ mmr_t sh_pi_error_mask_regval;
+ struct {
+@@ -6173,56 +3372,12 @@
+ mmr_t reserved_0 : 29;
+ } sh_pi_error_mask_s;
+ } sh_pi_error_mask_u_t;
+-#else
+-typedef union sh_pi_error_mask_u {
+- mmr_t sh_pi_error_mask_regval;
+- struct {
+- mmr_t reserved_0 : 29;
+- mmr_t msg_length : 1;
+- mmr_t fsb_tbl_miss : 1;
+- mmr_t bad_snoop : 1;
+- mmr_t livelock : 1;
+- mmr_t shub_fsb_ce : 1;
+- mmr_t shub_fsb_uce : 1;
+- mmr_t shub_fsb_dqe : 1;
+- mmr_t addr_parity : 1;
+- mmr_t req_parity : 1;
+- mmr_t addr_access : 1;
+- mmr_t req_format : 1;
+- mmr_t ioq_overrun : 1;
+- mmr_t rsp_parity : 1;
+- mmr_t hung_bus : 1;
+- mmr_t xn_rp_crd_oflow : 1;
+- mmr_t xn_rq_crd_oflow : 1;
+- mmr_t md_rp_crd_oflow : 1;
+- mmr_t md_rq_crd_oflow : 1;
+- mmr_t gfx_int_1 : 1;
+- mmr_t gfx_int_0 : 1;
+- mmr_t nack_oflow : 1;
+- mmr_t xn_rp_q_oflow : 1;
+- mmr_t xn_rq_q_oflow : 1;
+- mmr_t md_rp_q_oflow : 1;
+- mmr_t md_rq_q_oflow : 1;
+- mmr_t msg_color_err : 1;
+- mmr_t fsb_shub_ce : 1;
+- mmr_t fsb_shub_uce : 1;
+- mmr_t pio_to_err : 1;
+- mmr_t mem_to_err : 1;
+- mmr_t pio_rp_err : 1;
+- mmr_t mem_rp_err : 1;
+- mmr_t xb_proto_err : 1;
+- mmr_t gfx_rp_err : 1;
+- mmr_t fsb_proto_err : 1;
+- } sh_pi_error_mask_s;
+-} sh_pi_error_mask_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_EXPRESS_REPLY_CONFIG" */
+ /* PI Express Reply Configuration */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_express_reply_config_u {
+ mmr_t sh_pi_express_reply_config_regval;
+ struct {
+@@ -6230,64 +3385,36 @@
+ mmr_t reserved_0 : 61;
+ } sh_pi_express_reply_config_s;
+ } sh_pi_express_reply_config_u_t;
+-#else
+-typedef union sh_pi_express_reply_config_u {
+- mmr_t sh_pi_express_reply_config_regval;
+- struct {
+- mmr_t reserved_0 : 61;
+- mmr_t mode : 3;
+- } sh_pi_express_reply_config_s;
+-} sh_pi_express_reply_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_FSB_COMPARE_VALUE" */
+ /* FSB Compare Value */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_pi_fsb_compare_value_u {
+- mmr_t sh_pi_fsb_compare_value_regval;
+- struct {
+- mmr_t compare_value : 64;
+- } sh_pi_fsb_compare_value_s;
+-} sh_pi_fsb_compare_value_u_t;
+-#else
+ typedef union sh_pi_fsb_compare_value_u {
+ mmr_t sh_pi_fsb_compare_value_regval;
+ struct {
+ mmr_t compare_value : 64;
+ } sh_pi_fsb_compare_value_s;
+ } sh_pi_fsb_compare_value_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_FSB_COMPARE_MASK" */
+ /* FSB Compare Mask */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_fsb_compare_mask_u {
+ mmr_t sh_pi_fsb_compare_mask_regval;
+ struct {
+ mmr_t mask_value : 64;
+ } sh_pi_fsb_compare_mask_s;
+ } sh_pi_fsb_compare_mask_u_t;
+-#else
+-typedef union sh_pi_fsb_compare_mask_u {
+- mmr_t sh_pi_fsb_compare_mask_regval;
+- struct {
+- mmr_t mask_value : 64;
+- } sh_pi_fsb_compare_mask_s;
+-} sh_pi_fsb_compare_mask_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_FSB_ERROR_INJECTION" */
+ /* Inject an Error onto the FSB */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_fsb_error_injection_u {
+ mmr_t sh_pi_fsb_error_injection_regval;
+ struct {
+@@ -6321,48 +3448,12 @@
+ mmr_t reserved_2 : 29;
+ } sh_pi_fsb_error_injection_s;
+ } sh_pi_fsb_error_injection_u_t;
+-#else
+-typedef union sh_pi_fsb_error_injection_u {
+- mmr_t sh_pi_fsb_error_injection_regval;
+- struct {
+- mmr_t reserved_2 : 29;
+- mmr_t bus_hang : 1;
+- mmr_t livelock : 1;
+- mmr_t ioq_overrun : 1;
+- mmr_t reserved_1 : 4;
+- mmr_t dw3_uce_from_fsb : 1;
+- mmr_t dw3_ce_from_fsb : 1;
+- mmr_t dw2_uce_from_fsb : 1;
+- mmr_t dw2_ce_from_fsb : 1;
+- mmr_t dw1_uce_from_fsb : 1;
+- mmr_t dw1_ce_from_fsb : 1;
+- mmr_t dw0_uce_from_fsb : 1;
+- mmr_t dw0_ce_from_fsb : 1;
+- mmr_t rsp_pe_from_fsb : 1;
+- mmr_t ap1_pe_from_fsb : 1;
+- mmr_t ap0_pe_from_fsb : 1;
+- mmr_t rp_pe_from_fsb : 1;
+- mmr_t reserved_0 : 6;
+- mmr_t ip1_pe_to_fsb : 1;
+- mmr_t ip0_pe_to_fsb : 1;
+- mmr_t dw1_uce_to_fsb : 1;
+- mmr_t dw1_ce_to_fsb : 1;
+- mmr_t dw0_uce_to_fsb : 1;
+- mmr_t dw0_ce_to_fsb : 1;
+- mmr_t rsp_pe_to_fsb : 1;
+- mmr_t ap1_pe_to_fsb : 1;
+- mmr_t ap0_pe_to_fsb : 1;
+- mmr_t rp_pe_to_fsb : 1;
+- } sh_pi_fsb_error_injection_s;
+-} sh_pi_fsb_error_injection_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_MD2PI_REPLY_VC_CONFIG" */
+ /* MD-to-PI Reply Virtual Channel Configuration */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_md2pi_reply_vc_config_u {
+ mmr_t sh_pi_md2pi_reply_vc_config_regval;
+ struct {
+@@ -6374,26 +3465,12 @@
+ mmr_t capture_credit_status : 1;
+ } sh_pi_md2pi_reply_vc_config_s;
+ } sh_pi_md2pi_reply_vc_config_u_t;
+-#else
+-typedef union sh_pi_md2pi_reply_vc_config_u {
+- mmr_t sh_pi_md2pi_reply_vc_config_regval;
+- struct {
+- mmr_t capture_credit_status : 1;
+- mmr_t force_credit : 1;
+- mmr_t reserved_0 : 48;
+- mmr_t max_credits : 6;
+- mmr_t data_depth : 4;
+- mmr_t hdr_depth : 4;
+- } sh_pi_md2pi_reply_vc_config_s;
+-} sh_pi_md2pi_reply_vc_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_MD2PI_REQUEST_VC_CONFIG" */
+ /* MD-to-PI Request Virtual Channel Configuration */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_md2pi_request_vc_config_u {
+ mmr_t sh_pi_md2pi_request_vc_config_regval;
+ struct {
+@@ -6405,26 +3482,12 @@
+ mmr_t capture_credit_status : 1;
+ } sh_pi_md2pi_request_vc_config_s;
+ } sh_pi_md2pi_request_vc_config_u_t;
+-#else
+-typedef union sh_pi_md2pi_request_vc_config_u {
+- mmr_t sh_pi_md2pi_request_vc_config_regval;
+- struct {
+- mmr_t capture_credit_status : 1;
+- mmr_t force_credit : 1;
+- mmr_t reserved_0 : 48;
+- mmr_t max_credits : 6;
+- mmr_t data_depth : 4;
+- mmr_t hdr_depth : 4;
+- } sh_pi_md2pi_request_vc_config_s;
+-} sh_pi_md2pi_request_vc_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_QUEUE_ERROR_INJECTION" */
+ /* PI Queue Error Injection */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_queue_error_injection_u {
+ mmr_t sh_pi_queue_error_injection_regval;
+ struct {
+@@ -6439,29 +3502,12 @@
+ mmr_t reserved_0 : 56;
+ } sh_pi_queue_error_injection_s;
+ } sh_pi_queue_error_injection_u_t;
+-#else
+-typedef union sh_pi_queue_error_injection_u {
+- mmr_t sh_pi_queue_error_injection_regval;
+- struct {
+- mmr_t reserved_0 : 56;
+- mmr_t xnpi_rpy_bfr : 1;
+- mmr_t rxl_rdy_q : 1;
+- mmr_t rxl_kill_q : 1;
+- mmr_t ptc_intr : 1;
+- mmr_t mdpi_rpy_bfr : 1;
+- mmr_t fsb_wtl_cmnd_q : 1;
+- mmr_t dxb_wtl_cmnd_q : 1;
+- mmr_t dat_dfr_q : 1;
+- } sh_pi_queue_error_injection_s;
+-} sh_pi_queue_error_injection_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_TEST_POINT_COMPARE" */
+ /* PI Test Point Compare */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_test_point_compare_u {
+ mmr_t sh_pi_test_point_compare_regval;
+ struct {
+@@ -6469,22 +3515,12 @@
+ mmr_t compare_pattern : 32;
+ } sh_pi_test_point_compare_s;
+ } sh_pi_test_point_compare_u_t;
+-#else
+-typedef union sh_pi_test_point_compare_u {
+- mmr_t sh_pi_test_point_compare_regval;
+- struct {
+- mmr_t compare_pattern : 32;
+- mmr_t compare_mask : 32;
+- } sh_pi_test_point_compare_s;
+-} sh_pi_test_point_compare_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_TEST_POINT_SELECT" */
+ /* PI Test Point Select */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_test_point_select_u {
+ mmr_t sh_pi_test_point_select_regval;
+ struct {
+@@ -6522,52 +3558,12 @@
+ mmr_t trigger_enable : 1;
+ } sh_pi_test_point_select_s;
+ } sh_pi_test_point_select_u_t;
+-#else
+-typedef union sh_pi_test_point_select_u {
+- mmr_t sh_pi_test_point_select_regval;
+- struct {
+- mmr_t trigger_enable : 1;
+- mmr_t nibble7_nibble_sel : 3;
+- mmr_t reserved_14 : 1;
+- mmr_t nibble7_chiplet_sel : 3;
+- mmr_t reserved_13 : 1;
+- mmr_t nibble6_nibble_sel : 3;
+- mmr_t reserved_12 : 1;
+- mmr_t nibble6_chiplet_sel : 3;
+- mmr_t reserved_11 : 1;
+- mmr_t nibble5_nibble_sel : 3;
+- mmr_t reserved_10 : 1;
+- mmr_t nibble5_chiplet_sel : 3;
+- mmr_t reserved_9 : 1;
+- mmr_t nibble4_nibble_sel : 3;
+- mmr_t reserved_8 : 1;
+- mmr_t nibble4_chiplet_sel : 3;
+- mmr_t reserved_7 : 1;
+- mmr_t nibble3_nibble_sel : 3;
+- mmr_t reserved_6 : 1;
+- mmr_t nibble3_chiplet_sel : 3;
+- mmr_t reserved_5 : 1;
+- mmr_t nibble2_nibble_sel : 3;
+- mmr_t reserved_4 : 1;
+- mmr_t nibble2_chiplet_sel : 3;
+- mmr_t reserved_3 : 1;
+- mmr_t nibble1_nibble_sel : 3;
+- mmr_t reserved_2 : 1;
+- mmr_t nibble1_chiplet_sel : 3;
+- mmr_t reserved_1 : 1;
+- mmr_t nibble0_nibble_sel : 3;
+- mmr_t reserved_0 : 1;
+- mmr_t nibble0_chiplet_sel : 3;
+- } sh_pi_test_point_select_s;
+-} sh_pi_test_point_select_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_TEST_POINT_TRIGGER_SELECT" */
+ /* PI Test Point Trigger Select */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_test_point_trigger_select_u {
+ mmr_t sh_pi_test_point_trigger_select_regval;
+ struct {
+@@ -6605,52 +3601,12 @@
+ mmr_t reserved_15 : 1;
+ } sh_pi_test_point_trigger_select_s;
+ } sh_pi_test_point_trigger_select_u_t;
+-#else
+-typedef union sh_pi_test_point_trigger_select_u {
+- mmr_t sh_pi_test_point_trigger_select_regval;
+- struct {
+- mmr_t reserved_15 : 1;
+- mmr_t trigger7_nibble_sel : 3;
+- mmr_t reserved_14 : 1;
+- mmr_t trigger7_chiplet_sel : 3;
+- mmr_t reserved_13 : 1;
+- mmr_t trigger6_nibble_sel : 3;
+- mmr_t reserved_12 : 1;
+- mmr_t trigger6_chiplet_sel : 3;
+- mmr_t reserved_11 : 1;
+- mmr_t trigger5_nibble_sel : 3;
+- mmr_t reserved_10 : 1;
+- mmr_t trigger5_chiplet_sel : 3;
+- mmr_t reserved_9 : 1;
+- mmr_t trigger4_nibble_sel : 3;
+- mmr_t reserved_8 : 1;
+- mmr_t trigger4_chiplet_sel : 3;
+- mmr_t reserved_7 : 1;
+- mmr_t trigger3_nibble_sel : 3;
+- mmr_t reserved_6 : 1;
+- mmr_t trigger3_chiplet_sel : 3;
+- mmr_t reserved_5 : 1;
+- mmr_t trigger2_nibble_sel : 3;
+- mmr_t reserved_4 : 1;
+- mmr_t trigger2_chiplet_sel : 3;
+- mmr_t reserved_3 : 1;
+- mmr_t trigger1_nibble_sel : 3;
+- mmr_t reserved_2 : 1;
+- mmr_t trigger1_chiplet_sel : 3;
+- mmr_t reserved_1 : 1;
+- mmr_t trigger0_nibble_sel : 3;
+- mmr_t reserved_0 : 1;
+- mmr_t trigger0_chiplet_sel : 3;
+- } sh_pi_test_point_trigger_select_s;
+-} sh_pi_test_point_trigger_select_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_XN2PI_REPLY_VC_CONFIG" */
+ /* XN-to-PI Reply Virtual Channel Configuration */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_xn2pi_reply_vc_config_u {
+ mmr_t sh_pi_xn2pi_reply_vc_config_regval;
+ struct {
+@@ -6662,26 +3618,12 @@
+ mmr_t capture_credit_status : 1;
+ } sh_pi_xn2pi_reply_vc_config_s;
+ } sh_pi_xn2pi_reply_vc_config_u_t;
+-#else
+-typedef union sh_pi_xn2pi_reply_vc_config_u {
+- mmr_t sh_pi_xn2pi_reply_vc_config_regval;
+- struct {
+- mmr_t capture_credit_status : 1;
+- mmr_t force_credit : 1;
+- mmr_t reserved_0 : 48;
+- mmr_t max_credits : 6;
+- mmr_t data_depth : 4;
+- mmr_t hdr_depth : 4;
+- } sh_pi_xn2pi_reply_vc_config_s;
+-} sh_pi_xn2pi_reply_vc_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_XN2PI_REQUEST_VC_CONFIG" */
+ /* XN-to-PI Request Virtual Channel Configuration */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_xn2pi_request_vc_config_u {
+ mmr_t sh_pi_xn2pi_request_vc_config_regval;
+ struct {
+@@ -6693,26 +3635,12 @@
+ mmr_t capture_credit_status : 1;
+ } sh_pi_xn2pi_request_vc_config_s;
+ } sh_pi_xn2pi_request_vc_config_u_t;
+-#else
+-typedef union sh_pi_xn2pi_request_vc_config_u {
+- mmr_t sh_pi_xn2pi_request_vc_config_regval;
+- struct {
+- mmr_t capture_credit_status : 1;
+- mmr_t force_credit : 1;
+- mmr_t reserved_0 : 48;
+- mmr_t max_credits : 6;
+- mmr_t data_depth : 4;
+- mmr_t hdr_depth : 4;
+- } sh_pi_xn2pi_request_vc_config_s;
+-} sh_pi_xn2pi_request_vc_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_AEC_STATUS" */
+ /* PI Adaptive Error Correction Status */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_aec_status_u {
+ mmr_t sh_pi_aec_status_regval;
+ struct {
+@@ -6720,22 +3648,12 @@
+ mmr_t reserved_0 : 61;
+ } sh_pi_aec_status_s;
+ } sh_pi_aec_status_u_t;
+-#else
+-typedef union sh_pi_aec_status_u {
+- mmr_t sh_pi_aec_status_regval;
+- struct {
+- mmr_t reserved_0 : 61;
+- mmr_t state : 3;
+- } sh_pi_aec_status_s;
+-} sh_pi_aec_status_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_AFI_FIRST_ERROR" */
+ /* PI AFI First Error */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_afi_first_error_u {
+ mmr_t sh_pi_afi_first_error_regval;
+ struct {
+@@ -6760,85 +3678,38 @@
+ mmr_t reserved_2 : 29;
+ } sh_pi_afi_first_error_s;
+ } sh_pi_afi_first_error_u_t;
+-#else
+-typedef union sh_pi_afi_first_error_u {
+- mmr_t sh_pi_afi_first_error_regval;
+- struct {
+- mmr_t reserved_2 : 29;
+- mmr_t msg_len : 1;
+- mmr_t fsb_tbl_miss : 1;
+- mmr_t bad_snoop : 1;
+- mmr_t livelock : 1;
+- mmr_t shub_fsb_ce : 1;
+- mmr_t shub_fsb_uce : 1;
+- mmr_t shub_fsb_dqe : 1;
+- mmr_t addr_parity : 1;
+- mmr_t req_parity : 1;
+- mmr_t addr_access : 1;
+- mmr_t req_format : 1;
+- mmr_t ioq_overrun : 1;
+- mmr_t rsp_parity : 1;
+- mmr_t hung_bus : 1;
+- mmr_t reserved_1 : 12;
+- mmr_t fsb_shub_ce : 1;
+- mmr_t fsb_shub_uce : 1;
+- mmr_t reserved_0 : 7;
+- } sh_pi_afi_first_error_s;
+-} sh_pi_afi_first_error_u_t;
+-#endif
+-
+-/* ==================================================================== */
+-/* Register "SH_PI_CAM_ADDRESS_READ_DATA" */
+-/* CRB CAM MMR Address Read Data */
+-/* ==================================================================== */
+-
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_pi_cam_address_read_data_u {
+- mmr_t sh_pi_cam_address_read_data_regval;
++
++/* ==================================================================== */
++/* Register "SH_PI_CAM_ADDRESS_READ_DATA" */
++/* CRB CAM MMR Address Read Data */
++/* ==================================================================== */
++
++typedef union sh_pi_cam_address_read_data_u {
++ mmr_t sh_pi_cam_address_read_data_regval;
+ struct {
+ mmr_t cam_addr : 48;
+ mmr_t reserved_0 : 15;
+ mmr_t cam_addr_val : 1;
+ } sh_pi_cam_address_read_data_s;
+ } sh_pi_cam_address_read_data_u_t;
+-#else
+-typedef union sh_pi_cam_address_read_data_u {
+- mmr_t sh_pi_cam_address_read_data_regval;
+- struct {
+- mmr_t cam_addr_val : 1;
+- mmr_t reserved_0 : 15;
+- mmr_t cam_addr : 48;
+- } sh_pi_cam_address_read_data_s;
+-} sh_pi_cam_address_read_data_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_CAM_LPRA_READ_DATA" */
+ /* CRB CAM MMR LPRA Read Data */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_pi_cam_lpra_read_data_u {
+- mmr_t sh_pi_cam_lpra_read_data_regval;
+- struct {
+- mmr_t cam_lpra : 64;
+- } sh_pi_cam_lpra_read_data_s;
+-} sh_pi_cam_lpra_read_data_u_t;
+-#else
+ typedef union sh_pi_cam_lpra_read_data_u {
+ mmr_t sh_pi_cam_lpra_read_data_regval;
+ struct {
+ mmr_t cam_lpra : 64;
+ } sh_pi_cam_lpra_read_data_s;
+ } sh_pi_cam_lpra_read_data_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_CAM_STATE_READ_DATA" */
+ /* CRB CAM MMR State Read Data */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_cam_state_read_data_u {
+ mmr_t sh_pi_cam_state_read_data_regval;
+ struct {
+@@ -6851,27 +3722,12 @@
+ mmr_t cam_rd_data_val : 1;
+ } sh_pi_cam_state_read_data_s;
+ } sh_pi_cam_state_read_data_u_t;
+-#else
+-typedef union sh_pi_cam_state_read_data_u {
+- mmr_t sh_pi_cam_state_read_data_regval;
+- struct {
+- mmr_t cam_rd_data_val : 1;
+- mmr_t reserved_1 : 13;
+- mmr_t cam_lpra : 18;
+- mmr_t reserved_0 : 26;
+- mmr_t cam_state_rd_pend : 1;
+- mmr_t cam_to : 1;
+- mmr_t cam_state : 4;
+- } sh_pi_cam_state_read_data_s;
+-} sh_pi_cam_state_read_data_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_CORRECTED_DETAIL_1" */
+ /* PI Corrected Error Detail */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_corrected_detail_1_u {
+ mmr_t sh_pi_corrected_detail_1_regval;
+ struct {
+@@ -6880,44 +3736,24 @@
+ mmr_t dep : 8;
+ } sh_pi_corrected_detail_1_s;
+ } sh_pi_corrected_detail_1_u_t;
+-#else
+-typedef union sh_pi_corrected_detail_1_u {
+- mmr_t sh_pi_corrected_detail_1_regval;
+- struct {
+- mmr_t dep : 8;
+- mmr_t syndrome : 8;
+- mmr_t address : 48;
+- } sh_pi_corrected_detail_1_s;
+-} sh_pi_corrected_detail_1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_CORRECTED_DETAIL_2" */
+ /* PI Corrected Error Detail 2 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_pi_corrected_detail_2_u {
+- mmr_t sh_pi_corrected_detail_2_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_pi_corrected_detail_2_s;
+-} sh_pi_corrected_detail_2_u_t;
+-#else
+ typedef union sh_pi_corrected_detail_2_u {
+ mmr_t sh_pi_corrected_detail_2_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_pi_corrected_detail_2_s;
+ } sh_pi_corrected_detail_2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_CORRECTED_DETAIL_3" */
+ /* PI Corrected Error Detail 3 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_corrected_detail_3_u {
+ mmr_t sh_pi_corrected_detail_3_regval;
+ struct {
+@@ -6926,44 +3762,24 @@
+ mmr_t dep : 8;
+ } sh_pi_corrected_detail_3_s;
+ } sh_pi_corrected_detail_3_u_t;
+-#else
+-typedef union sh_pi_corrected_detail_3_u {
+- mmr_t sh_pi_corrected_detail_3_regval;
+- struct {
+- mmr_t dep : 8;
+- mmr_t syndrome : 8;
+- mmr_t address : 48;
+- } sh_pi_corrected_detail_3_s;
+-} sh_pi_corrected_detail_3_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_CORRECTED_DETAIL_4" */
+ /* PI Corrected Error Detail 4 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_pi_corrected_detail_4_u {
+- mmr_t sh_pi_corrected_detail_4_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_pi_corrected_detail_4_s;
+-} sh_pi_corrected_detail_4_u_t;
+-#else
+ typedef union sh_pi_corrected_detail_4_u {
+ mmr_t sh_pi_corrected_detail_4_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_pi_corrected_detail_4_s;
+ } sh_pi_corrected_detail_4_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_CRBP_FIRST_ERROR" */
+ /* PI CRBP First Error */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_crbp_first_error_u {
+ mmr_t sh_pi_crbp_first_error_regval;
+ struct {
+@@ -6991,84 +3807,36 @@
+ mmr_t reserved_0 : 43;
+ } sh_pi_crbp_first_error_s;
+ } sh_pi_crbp_first_error_u_t;
+-#else
+-typedef union sh_pi_crbp_first_error_u {
+- mmr_t sh_pi_crbp_first_error_regval;
+- struct {
+- mmr_t reserved_0 : 43;
+- mmr_t xn_rp_crd_oflow : 1;
+- mmr_t xn_rq_crd_oflow : 1;
+- mmr_t md_rp_crd_oflow : 1;
+- mmr_t md_rq_crd_oflow : 1;
+- mmr_t gfx_int_1 : 1;
+- mmr_t gfx_int_0 : 1;
+- mmr_t nack_oflow : 1;
+- mmr_t xn_rp_q_oflow : 1;
+- mmr_t xn_rq_q_oflow : 1;
+- mmr_t md_rp_q_oflow : 1;
+- mmr_t md_rq_q_oflow : 1;
+- mmr_t msg_color_err : 1;
+- mmr_t fsb_shub_ce : 1;
+- mmr_t fsb_shub_uce : 1;
+- mmr_t pio_to_err : 1;
+- mmr_t mem_to_err : 1;
+- mmr_t pio_rp_err : 1;
+- mmr_t mem_rp_err : 1;
+- mmr_t xb_proto_err : 1;
+- mmr_t gfx_rp_err : 1;
+- mmr_t fsb_proto_err : 1;
+- } sh_pi_crbp_first_error_s;
+-} sh_pi_crbp_first_error_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_ERROR_DETAIL_1" */
+ /* PI Error Detail 1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_pi_error_detail_1_u {
+- mmr_t sh_pi_error_detail_1_regval;
+- struct {
+- mmr_t status : 64;
+- } sh_pi_error_detail_1_s;
+-} sh_pi_error_detail_1_u_t;
+-#else
+ typedef union sh_pi_error_detail_1_u {
+ mmr_t sh_pi_error_detail_1_regval;
+ struct {
+ mmr_t status : 64;
+ } sh_pi_error_detail_1_s;
+ } sh_pi_error_detail_1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_ERROR_DETAIL_2" */
+ /* PI Error Detail 2 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_error_detail_2_u {
+ mmr_t sh_pi_error_detail_2_regval;
+ struct {
+ mmr_t status : 64;
+ } sh_pi_error_detail_2_s;
+ } sh_pi_error_detail_2_u_t;
+-#else
+-typedef union sh_pi_error_detail_2_u {
+- mmr_t sh_pi_error_detail_2_regval;
+- struct {
+- mmr_t status : 64;
+- } sh_pi_error_detail_2_s;
+-} sh_pi_error_detail_2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_ERROR_OVERFLOW" */
+ /* PI Error Overflow */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_error_overflow_u {
+ mmr_t sh_pi_error_overflow_regval;
+ struct {
+@@ -7110,56 +3878,12 @@
+ mmr_t reserved_0 : 29;
+ } sh_pi_error_overflow_s;
+ } sh_pi_error_overflow_u_t;
+-#else
+-typedef union sh_pi_error_overflow_u {
+- mmr_t sh_pi_error_overflow_regval;
+- struct {
+- mmr_t reserved_0 : 29;
+- mmr_t msg_length : 1;
+- mmr_t fsb_tbl_miss : 1;
+- mmr_t bad_snoop : 1;
+- mmr_t livelock : 1;
+- mmr_t shub_fsb_ce : 1;
+- mmr_t shub_fsb_uce : 1;
+- mmr_t shub_fsb_dqe : 1;
+- mmr_t addr_parity : 1;
+- mmr_t req_parity : 1;
+- mmr_t addr_access : 1;
+- mmr_t req_format : 1;
+- mmr_t ioq_overrun : 1;
+- mmr_t rsp_parity : 1;
+- mmr_t hung_bus : 1;
+- mmr_t xn_rp_crd_oflow : 1;
+- mmr_t xn_rq_crd_oflow : 1;
+- mmr_t md_rp_crd_oflow : 1;
+- mmr_t md_rq_crd_oflow : 1;
+- mmr_t gfx_int_1 : 1;
+- mmr_t gfx_int_0 : 1;
+- mmr_t nack_oflow : 1;
+- mmr_t xn_rp_q_oflow : 1;
+- mmr_t xn_rq_q_oflow : 1;
+- mmr_t md_rp_q_oflow : 1;
+- mmr_t md_rq_q_oflow : 1;
+- mmr_t msg_color_err : 1;
+- mmr_t fsb_shub_ce : 1;
+- mmr_t fsb_shub_uce : 1;
+- mmr_t pio_to_err : 1;
+- mmr_t mem_to_err : 1;
+- mmr_t pio_rp_err : 1;
+- mmr_t mem_rp_err : 1;
+- mmr_t xb_proto_err : 1;
+- mmr_t gfx_rp_err : 1;
+- mmr_t fsb_proto_err : 1;
+- } sh_pi_error_overflow_s;
+-} sh_pi_error_overflow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_ERROR_SUMMARY" */
+ /* PI Error Summary */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_error_summary_u {
+ mmr_t sh_pi_error_summary_regval;
+ struct {
+@@ -7201,56 +3925,12 @@
+ mmr_t reserved_0 : 29;
+ } sh_pi_error_summary_s;
+ } sh_pi_error_summary_u_t;
+-#else
+-typedef union sh_pi_error_summary_u {
+- mmr_t sh_pi_error_summary_regval;
+- struct {
+- mmr_t reserved_0 : 29;
+- mmr_t msg_length : 1;
+- mmr_t fsb_tbl_miss : 1;
+- mmr_t bad_snoop : 1;
+- mmr_t livelock : 1;
+- mmr_t shub_fsb_ce : 1;
+- mmr_t shub_fsb_uce : 1;
+- mmr_t shub_fsb_dqe : 1;
+- mmr_t addr_parity : 1;
+- mmr_t req_parity : 1;
+- mmr_t addr_access : 1;
+- mmr_t req_format : 1;
+- mmr_t ioq_overrun : 1;
+- mmr_t rsp_parity : 1;
+- mmr_t hung_bus : 1;
+- mmr_t xn_rp_crd_oflow : 1;
+- mmr_t xn_rq_crd_oflow : 1;
+- mmr_t md_rp_crd_oflow : 1;
+- mmr_t md_rq_crd_oflow : 1;
+- mmr_t gfx_int_1 : 1;
+- mmr_t gfx_int_0 : 1;
+- mmr_t nack_oflow : 1;
+- mmr_t xn_rp_q_oflow : 1;
+- mmr_t xn_rq_q_oflow : 1;
+- mmr_t md_rp_q_oflow : 1;
+- mmr_t md_rq_q_oflow : 1;
+- mmr_t msg_color_err : 1;
+- mmr_t fsb_shub_ce : 1;
+- mmr_t fsb_shub_uce : 1;
+- mmr_t pio_to_err : 1;
+- mmr_t mem_to_err : 1;
+- mmr_t pio_rp_err : 1;
+- mmr_t mem_rp_err : 1;
+- mmr_t xb_proto_err : 1;
+- mmr_t gfx_rp_err : 1;
+- mmr_t fsb_proto_err : 1;
+- } sh_pi_error_summary_s;
+-} sh_pi_error_summary_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_EXPRESS_REPLY_STATUS" */
+ /* PI Express Reply Status */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_express_reply_status_u {
+ mmr_t sh_pi_express_reply_status_regval;
+ struct {
+@@ -7258,22 +3938,12 @@
+ mmr_t reserved_0 : 61;
+ } sh_pi_express_reply_status_s;
+ } sh_pi_express_reply_status_u_t;
+-#else
+-typedef union sh_pi_express_reply_status_u {
+- mmr_t sh_pi_express_reply_status_regval;
+- struct {
+- mmr_t reserved_0 : 61;
+- mmr_t state : 3;
+- } sh_pi_express_reply_status_s;
+-} sh_pi_express_reply_status_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_FIRST_ERROR" */
+ /* PI First Error */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_first_error_u {
+ mmr_t sh_pi_first_error_regval;
+ struct {
+@@ -7315,56 +3985,12 @@
+ mmr_t reserved_0 : 29;
+ } sh_pi_first_error_s;
+ } sh_pi_first_error_u_t;
+-#else
+-typedef union sh_pi_first_error_u {
+- mmr_t sh_pi_first_error_regval;
+- struct {
+- mmr_t reserved_0 : 29;
+- mmr_t msg_length : 1;
+- mmr_t fsb_tbl_miss : 1;
+- mmr_t bad_snoop : 1;
+- mmr_t livelock : 1;
+- mmr_t shub_fsb_ce : 1;
+- mmr_t shub_fsb_uce : 1;
+- mmr_t shub_fsb_dqe : 1;
+- mmr_t addr_parity : 1;
+- mmr_t req_parity : 1;
+- mmr_t addr_access : 1;
+- mmr_t req_format : 1;
+- mmr_t ioq_overrun : 1;
+- mmr_t rsp_parity : 1;
+- mmr_t hung_bus : 1;
+- mmr_t xn_rp_crd_oflow : 1;
+- mmr_t xn_rq_crd_oflow : 1;
+- mmr_t md_rp_crd_oflow : 1;
+- mmr_t md_rq_crd_oflow : 1;
+- mmr_t gfx_int_1 : 1;
+- mmr_t gfx_int_0 : 1;
+- mmr_t nack_oflow : 1;
+- mmr_t xn_rp_q_oflow : 1;
+- mmr_t xn_rq_q_oflow : 1;
+- mmr_t md_rp_q_oflow : 1;
+- mmr_t md_rq_q_oflow : 1;
+- mmr_t msg_color_err : 1;
+- mmr_t fsb_shub_ce : 1;
+- mmr_t fsb_shub_uce : 1;
+- mmr_t pio_to_err : 1;
+- mmr_t mem_to_err : 1;
+- mmr_t pio_rp_err : 1;
+- mmr_t mem_rp_err : 1;
+- mmr_t xb_proto_err : 1;
+- mmr_t gfx_rp_err : 1;
+- mmr_t fsb_proto_err : 1;
+- } sh_pi_first_error_s;
+-} sh_pi_first_error_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_PI2MD_REPLY_VC_STATUS" */
+ /* PI-to-MD Reply Virtual Channel Status */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_pi2md_reply_vc_status_u {
+ mmr_t sh_pi_pi2md_reply_vc_status_regval;
+ struct {
+@@ -7372,22 +3998,12 @@
+ mmr_t reserved_0 : 58;
+ } sh_pi_pi2md_reply_vc_status_s;
+ } sh_pi_pi2md_reply_vc_status_u_t;
+-#else
+-typedef union sh_pi_pi2md_reply_vc_status_u {
+- mmr_t sh_pi_pi2md_reply_vc_status_regval;
+- struct {
+- mmr_t reserved_0 : 58;
+- mmr_t output_crd_stat : 6;
+- } sh_pi_pi2md_reply_vc_status_s;
+-} sh_pi_pi2md_reply_vc_status_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_PI2MD_REQUEST_VC_STATUS" */
+ /* PI-to-MD Request Virtual Channel Status */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_pi2md_request_vc_status_u {
+ mmr_t sh_pi_pi2md_request_vc_status_regval;
+ struct {
+@@ -7395,22 +4011,12 @@
+ mmr_t reserved_0 : 58;
+ } sh_pi_pi2md_request_vc_status_s;
+ } sh_pi_pi2md_request_vc_status_u_t;
+-#else
+-typedef union sh_pi_pi2md_request_vc_status_u {
+- mmr_t sh_pi_pi2md_request_vc_status_regval;
+- struct {
+- mmr_t reserved_0 : 58;
+- mmr_t output_crd_stat : 6;
+- } sh_pi_pi2md_request_vc_status_s;
+-} sh_pi_pi2md_request_vc_status_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_PI2XN_REPLY_VC_STATUS" */
+ /* PI-to-XN Reply Virtual Channel Status */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_pi2xn_reply_vc_status_u {
+ mmr_t sh_pi_pi2xn_reply_vc_status_regval;
+ struct {
+@@ -7418,22 +4024,12 @@
+ mmr_t reserved_0 : 58;
+ } sh_pi_pi2xn_reply_vc_status_s;
+ } sh_pi_pi2xn_reply_vc_status_u_t;
+-#else
+-typedef union sh_pi_pi2xn_reply_vc_status_u {
+- mmr_t sh_pi_pi2xn_reply_vc_status_regval;
+- struct {
+- mmr_t reserved_0 : 58;
+- mmr_t output_crd_stat : 6;
+- } sh_pi_pi2xn_reply_vc_status_s;
+-} sh_pi_pi2xn_reply_vc_status_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_PI2XN_REQUEST_VC_STATUS" */
+ /* PI-to-XN Request Virtual Channel Status */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_pi2xn_request_vc_status_u {
+ mmr_t sh_pi_pi2xn_request_vc_status_regval;
+ struct {
+@@ -7441,22 +4037,12 @@
+ mmr_t reserved_0 : 58;
+ } sh_pi_pi2xn_request_vc_status_s;
+ } sh_pi_pi2xn_request_vc_status_u_t;
+-#else
+-typedef union sh_pi_pi2xn_request_vc_status_u {
+- mmr_t sh_pi_pi2xn_request_vc_status_regval;
+- struct {
+- mmr_t reserved_0 : 58;
+- mmr_t output_crd_stat : 6;
+- } sh_pi_pi2xn_request_vc_status_s;
+-} sh_pi_pi2xn_request_vc_status_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_UNCORRECTED_DETAIL_1" */
+ /* PI Uncorrected Error Detail 1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_uncorrected_detail_1_u {
+ mmr_t sh_pi_uncorrected_detail_1_regval;
+ struct {
+@@ -7465,44 +4051,24 @@
+ mmr_t dep : 8;
+ } sh_pi_uncorrected_detail_1_s;
+ } sh_pi_uncorrected_detail_1_u_t;
+-#else
+-typedef union sh_pi_uncorrected_detail_1_u {
+- mmr_t sh_pi_uncorrected_detail_1_regval;
+- struct {
+- mmr_t dep : 8;
+- mmr_t syndrome : 8;
+- mmr_t address : 48;
+- } sh_pi_uncorrected_detail_1_s;
+-} sh_pi_uncorrected_detail_1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_UNCORRECTED_DETAIL_2" */
+ /* PI Uncorrected Error Detail 2 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_pi_uncorrected_detail_2_u {
+- mmr_t sh_pi_uncorrected_detail_2_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_pi_uncorrected_detail_2_s;
+-} sh_pi_uncorrected_detail_2_u_t;
+-#else
+ typedef union sh_pi_uncorrected_detail_2_u {
+ mmr_t sh_pi_uncorrected_detail_2_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_pi_uncorrected_detail_2_s;
+ } sh_pi_uncorrected_detail_2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_UNCORRECTED_DETAIL_3" */
+ /* PI Uncorrected Error Detail 3 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_uncorrected_detail_3_u {
+ mmr_t sh_pi_uncorrected_detail_3_regval;
+ struct {
+@@ -7511,44 +4077,24 @@
+ mmr_t dep : 8;
+ } sh_pi_uncorrected_detail_3_s;
+ } sh_pi_uncorrected_detail_3_u_t;
+-#else
+-typedef union sh_pi_uncorrected_detail_3_u {
+- mmr_t sh_pi_uncorrected_detail_3_regval;
+- struct {
+- mmr_t dep : 8;
+- mmr_t syndrome : 8;
+- mmr_t address : 48;
+- } sh_pi_uncorrected_detail_3_s;
+-} sh_pi_uncorrected_detail_3_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_UNCORRECTED_DETAIL_4" */
+ /* PI Uncorrected Error Detail 4 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_pi_uncorrected_detail_4_u {
+- mmr_t sh_pi_uncorrected_detail_4_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_pi_uncorrected_detail_4_s;
+-} sh_pi_uncorrected_detail_4_u_t;
+-#else
+ typedef union sh_pi_uncorrected_detail_4_u {
+ mmr_t sh_pi_uncorrected_detail_4_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_pi_uncorrected_detail_4_s;
+ } sh_pi_uncorrected_detail_4_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_MD2PI_REPLY_VC_STATUS" */
+ /* MD-to-PI Reply Virtual Channel Status */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_md2pi_reply_vc_status_u {
+ mmr_t sh_pi_md2pi_reply_vc_status_regval;
+ struct {
+@@ -7558,24 +4104,12 @@
+ mmr_t reserved_0 : 52;
+ } sh_pi_md2pi_reply_vc_status_s;
+ } sh_pi_md2pi_reply_vc_status_u_t;
+-#else
+-typedef union sh_pi_md2pi_reply_vc_status_u {
+- mmr_t sh_pi_md2pi_reply_vc_status_regval;
+- struct {
+- mmr_t reserved_0 : 52;
+- mmr_t input_queue_stat : 4;
+- mmr_t input_dat_crd_stat : 4;
+- mmr_t input_hdr_crd_stat : 4;
+- } sh_pi_md2pi_reply_vc_status_s;
+-} sh_pi_md2pi_reply_vc_status_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_MD2PI_REQUEST_VC_STATUS" */
+ /* MD-to-PI Request Virtual Channel Status */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_md2pi_request_vc_status_u {
+ mmr_t sh_pi_md2pi_request_vc_status_regval;
+ struct {
+@@ -7585,24 +4119,12 @@
+ mmr_t reserved_0 : 52;
+ } sh_pi_md2pi_request_vc_status_s;
+ } sh_pi_md2pi_request_vc_status_u_t;
+-#else
+-typedef union sh_pi_md2pi_request_vc_status_u {
+- mmr_t sh_pi_md2pi_request_vc_status_regval;
+- struct {
+- mmr_t reserved_0 : 52;
+- mmr_t input_queue_stat : 4;
+- mmr_t input_dat_crd_stat : 4;
+- mmr_t input_hdr_crd_stat : 4;
+- } sh_pi_md2pi_request_vc_status_s;
+-} sh_pi_md2pi_request_vc_status_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_XN2PI_REPLY_VC_STATUS" */
+ /* XN-to-PI Reply Virtual Channel Status */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_xn2pi_reply_vc_status_u {
+ mmr_t sh_pi_xn2pi_reply_vc_status_regval;
+ struct {
+@@ -7612,24 +4134,12 @@
+ mmr_t reserved_0 : 52;
+ } sh_pi_xn2pi_reply_vc_status_s;
+ } sh_pi_xn2pi_reply_vc_status_u_t;
+-#else
+-typedef union sh_pi_xn2pi_reply_vc_status_u {
+- mmr_t sh_pi_xn2pi_reply_vc_status_regval;
+- struct {
+- mmr_t reserved_0 : 52;
+- mmr_t input_queue_stat : 4;
+- mmr_t input_dat_crd_stat : 4;
+- mmr_t input_hdr_crd_stat : 4;
+- } sh_pi_xn2pi_reply_vc_status_s;
+-} sh_pi_xn2pi_reply_vc_status_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_XN2PI_REQUEST_VC_STATUS" */
+ /* XN-to-PI Request Virtual Channel Status */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_xn2pi_request_vc_status_u {
+ mmr_t sh_pi_xn2pi_request_vc_status_regval;
+ struct {
+@@ -7639,23 +4149,11 @@
+ mmr_t reserved_0 : 52;
+ } sh_pi_xn2pi_request_vc_status_s;
+ } sh_pi_xn2pi_request_vc_status_u_t;
+-#else
+-typedef union sh_pi_xn2pi_request_vc_status_u {
+- mmr_t sh_pi_xn2pi_request_vc_status_regval;
+- struct {
+- mmr_t reserved_0 : 52;
+- mmr_t input_queue_stat : 4;
+- mmr_t input_dat_crd_stat : 4;
+- mmr_t input_hdr_crd_stat : 4;
+- } sh_pi_xn2pi_request_vc_status_s;
+-} sh_pi_xn2pi_request_vc_status_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNPI_SIC_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnpi_sic_flow_u {
+ mmr_t sh_xnpi_sic_flow_regval;
+ struct {
+@@ -7680,38 +4178,11 @@
+ mmr_t disable_bypass_out : 1;
+ } sh_xnpi_sic_flow_s;
+ } sh_xnpi_sic_flow_u_t;
+-#else
+-typedef union sh_xnpi_sic_flow_u {
+- mmr_t sh_xnpi_sic_flow_regval;
+- struct {
+- mmr_t disable_bypass_out : 1;
+- mmr_t reserved_7 : 2;
+- mmr_t credit_vc2_cap : 5;
+- mmr_t reserved_6 : 3;
+- mmr_t credit_vc2_dyn : 5;
+- mmr_t reserved_5 : 3;
+- mmr_t credit_vc2_test : 5;
+- mmr_t reserved_4 : 3;
+- mmr_t credit_vc0_cap : 5;
+- mmr_t reserved_3 : 3;
+- mmr_t credit_vc0_dyn : 5;
+- mmr_t reserved_2 : 3;
+- mmr_t credit_vc0_test : 5;
+- mmr_t debit_vc2_force_cred : 1;
+- mmr_t reserved_1 : 2;
+- mmr_t debit_vc2_withhold : 5;
+- mmr_t debit_vc0_force_cred : 1;
+- mmr_t reserved_0 : 2;
+- mmr_t debit_vc0_withhold : 5;
+- } sh_xnpi_sic_flow_s;
+-} sh_xnpi_sic_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNPI_TO_NI0_PORT_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnpi_to_ni0_port_flow_u {
+ mmr_t sh_xnpi_to_ni0_port_flow_regval;
+ struct {
+@@ -7732,34 +4203,11 @@
+ mmr_t reserved_6 : 2;
+ } sh_xnpi_to_ni0_port_flow_s;
+ } sh_xnpi_to_ni0_port_flow_u_t;
+-#else
+-typedef union sh_xnpi_to_ni0_port_flow_u {
+- mmr_t sh_xnpi_to_ni0_port_flow_regval;
+- struct {
+- mmr_t reserved_6 : 2;
+- mmr_t credit_vc2_cap : 6;
+- mmr_t reserved_5 : 2;
+- mmr_t credit_vc2_dyn : 6;
+- mmr_t reserved_4 : 10;
+- mmr_t credit_vc0_cap : 6;
+- mmr_t reserved_3 : 2;
+- mmr_t credit_vc0_dyn : 6;
+- mmr_t reserved_2 : 8;
+- mmr_t debit_vc2_force_cred : 1;
+- mmr_t reserved_1 : 1;
+- mmr_t debit_vc2_withhold : 6;
+- mmr_t debit_vc0_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t debit_vc0_withhold : 6;
+- } sh_xnpi_to_ni0_port_flow_s;
+-} sh_xnpi_to_ni0_port_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNPI_TO_NI1_PORT_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnpi_to_ni1_port_flow_u {
+ mmr_t sh_xnpi_to_ni1_port_flow_regval;
+ struct {
+@@ -7780,34 +4228,11 @@
+ mmr_t reserved_6 : 2;
+ } sh_xnpi_to_ni1_port_flow_s;
+ } sh_xnpi_to_ni1_port_flow_u_t;
+-#else
+-typedef union sh_xnpi_to_ni1_port_flow_u {
+- mmr_t sh_xnpi_to_ni1_port_flow_regval;
+- struct {
+- mmr_t reserved_6 : 2;
+- mmr_t credit_vc2_cap : 6;
+- mmr_t reserved_5 : 2;
+- mmr_t credit_vc2_dyn : 6;
+- mmr_t reserved_4 : 10;
+- mmr_t credit_vc0_cap : 6;
+- mmr_t reserved_3 : 2;
+- mmr_t credit_vc0_dyn : 6;
+- mmr_t reserved_2 : 8;
+- mmr_t debit_vc2_force_cred : 1;
+- mmr_t reserved_1 : 1;
+- mmr_t debit_vc2_withhold : 6;
+- mmr_t debit_vc0_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t debit_vc0_withhold : 6;
+- } sh_xnpi_to_ni1_port_flow_s;
+-} sh_xnpi_to_ni1_port_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNPI_TO_IILB_PORT_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnpi_to_iilb_port_flow_u {
+ mmr_t sh_xnpi_to_iilb_port_flow_regval;
+ struct {
+@@ -7828,34 +4253,11 @@
+ mmr_t reserved_6 : 2;
+ } sh_xnpi_to_iilb_port_flow_s;
+ } sh_xnpi_to_iilb_port_flow_u_t;
+-#else
+-typedef union sh_xnpi_to_iilb_port_flow_u {
+- mmr_t sh_xnpi_to_iilb_port_flow_regval;
+- struct {
+- mmr_t reserved_6 : 2;
+- mmr_t credit_vc2_cap : 6;
+- mmr_t reserved_5 : 2;
+- mmr_t credit_vc2_dyn : 6;
+- mmr_t reserved_4 : 10;
+- mmr_t credit_vc0_cap : 6;
+- mmr_t reserved_3 : 2;
+- mmr_t credit_vc0_dyn : 6;
+- mmr_t reserved_2 : 8;
+- mmr_t debit_vc2_force_cred : 1;
+- mmr_t reserved_1 : 1;
+- mmr_t debit_vc2_withhold : 6;
+- mmr_t debit_vc0_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t debit_vc0_withhold : 6;
+- } sh_xnpi_to_iilb_port_flow_s;
+-} sh_xnpi_to_iilb_port_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNPI_FR_NI0_PORT_FLOW_FIFO" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnpi_fr_ni0_port_flow_fifo_u {
+ mmr_t sh_xnpi_fr_ni0_port_flow_fifo_regval;
+ struct {
+@@ -7873,31 +4275,11 @@
+ mmr_t reserved_5 : 19;
+ } sh_xnpi_fr_ni0_port_flow_fifo_s;
+ } sh_xnpi_fr_ni0_port_flow_fifo_u_t;
+-#else
+-typedef union sh_xnpi_fr_ni0_port_flow_fifo_u {
+- mmr_t sh_xnpi_fr_ni0_port_flow_fifo_regval;
+- struct {
+- mmr_t reserved_5 : 19;
+- mmr_t entry_vc2_test : 5;
+- mmr_t reserved_4 : 3;
+- mmr_t entry_vc0_test : 5;
+- mmr_t reserved_3 : 2;
+- mmr_t entry_vc2_cap : 6;
+- mmr_t reserved_2 : 2;
+- mmr_t entry_vc2_dyn : 6;
+- mmr_t reserved_1 : 2;
+- mmr_t entry_vc0_cap : 6;
+- mmr_t reserved_0 : 2;
+- mmr_t entry_vc0_dyn : 6;
+- } sh_xnpi_fr_ni0_port_flow_fifo_s;
+-} sh_xnpi_fr_ni0_port_flow_fifo_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNPI_FR_NI1_PORT_FLOW_FIFO" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnpi_fr_ni1_port_flow_fifo_u {
+ mmr_t sh_xnpi_fr_ni1_port_flow_fifo_regval;
+ struct {
+@@ -7915,31 +4297,11 @@
+ mmr_t reserved_5 : 19;
+ } sh_xnpi_fr_ni1_port_flow_fifo_s;
+ } sh_xnpi_fr_ni1_port_flow_fifo_u_t;
+-#else
+-typedef union sh_xnpi_fr_ni1_port_flow_fifo_u {
+- mmr_t sh_xnpi_fr_ni1_port_flow_fifo_regval;
+- struct {
+- mmr_t reserved_5 : 19;
+- mmr_t entry_vc2_test : 5;
+- mmr_t reserved_4 : 3;
+- mmr_t entry_vc0_test : 5;
+- mmr_t reserved_3 : 2;
+- mmr_t entry_vc2_cap : 6;
+- mmr_t reserved_2 : 2;
+- mmr_t entry_vc2_dyn : 6;
+- mmr_t reserved_1 : 2;
+- mmr_t entry_vc0_cap : 6;
+- mmr_t reserved_0 : 2;
+- mmr_t entry_vc0_dyn : 6;
+- } sh_xnpi_fr_ni1_port_flow_fifo_s;
+-} sh_xnpi_fr_ni1_port_flow_fifo_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNPI_FR_IILB_PORT_FLOW_FIFO" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnpi_fr_iilb_port_flow_fifo_u {
+ mmr_t sh_xnpi_fr_iilb_port_flow_fifo_regval;
+ struct {
+@@ -7957,31 +4319,11 @@
+ mmr_t reserved_5 : 19;
+ } sh_xnpi_fr_iilb_port_flow_fifo_s;
+ } sh_xnpi_fr_iilb_port_flow_fifo_u_t;
+-#else
+-typedef union sh_xnpi_fr_iilb_port_flow_fifo_u {
+- mmr_t sh_xnpi_fr_iilb_port_flow_fifo_regval;
+- struct {
+- mmr_t reserved_5 : 19;
+- mmr_t entry_vc2_test : 5;
+- mmr_t reserved_4 : 3;
+- mmr_t entry_vc0_test : 5;
+- mmr_t reserved_3 : 2;
+- mmr_t entry_vc2_cap : 6;
+- mmr_t reserved_2 : 2;
+- mmr_t entry_vc2_dyn : 6;
+- mmr_t reserved_1 : 2;
+- mmr_t entry_vc0_cap : 6;
+- mmr_t reserved_0 : 2;
+- mmr_t entry_vc0_dyn : 6;
+- } sh_xnpi_fr_iilb_port_flow_fifo_s;
+-} sh_xnpi_fr_iilb_port_flow_fifo_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNMD_SIC_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnmd_sic_flow_u {
+ mmr_t sh_xnmd_sic_flow_regval;
+ struct {
+@@ -8006,38 +4348,11 @@
+ mmr_t disable_bypass_out : 1;
+ } sh_xnmd_sic_flow_s;
+ } sh_xnmd_sic_flow_u_t;
+-#else
+-typedef union sh_xnmd_sic_flow_u {
+- mmr_t sh_xnmd_sic_flow_regval;
+- struct {
+- mmr_t disable_bypass_out : 1;
+- mmr_t reserved_7 : 2;
+- mmr_t credit_vc2_cap : 5;
+- mmr_t reserved_6 : 3;
+- mmr_t credit_vc2_dyn : 5;
+- mmr_t reserved_5 : 3;
+- mmr_t credit_vc2_test : 5;
+- mmr_t reserved_4 : 3;
+- mmr_t credit_vc0_cap : 5;
+- mmr_t reserved_3 : 3;
+- mmr_t credit_vc0_dyn : 5;
+- mmr_t reserved_2 : 3;
+- mmr_t credit_vc0_test : 5;
+- mmr_t debit_vc2_force_cred : 1;
+- mmr_t reserved_1 : 2;
+- mmr_t debit_vc2_withhold : 5;
+- mmr_t debit_vc0_force_cred : 1;
+- mmr_t reserved_0 : 2;
+- mmr_t debit_vc0_withhold : 5;
+- } sh_xnmd_sic_flow_s;
+-} sh_xnmd_sic_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNMD_TO_NI0_PORT_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnmd_to_ni0_port_flow_u {
+ mmr_t sh_xnmd_to_ni0_port_flow_regval;
+ struct {
+@@ -8058,34 +4373,11 @@
+ mmr_t reserved_6 : 2;
+ } sh_xnmd_to_ni0_port_flow_s;
+ } sh_xnmd_to_ni0_port_flow_u_t;
+-#else
+-typedef union sh_xnmd_to_ni0_port_flow_u {
+- mmr_t sh_xnmd_to_ni0_port_flow_regval;
+- struct {
+- mmr_t reserved_6 : 2;
+- mmr_t credit_vc2_cap : 6;
+- mmr_t reserved_5 : 2;
+- mmr_t credit_vc2_dyn : 6;
+- mmr_t reserved_4 : 10;
+- mmr_t credit_vc0_cap : 6;
+- mmr_t reserved_3 : 2;
+- mmr_t credit_vc0_dyn : 6;
+- mmr_t reserved_2 : 8;
+- mmr_t debit_vc2_force_cred : 1;
+- mmr_t reserved_1 : 1;
+- mmr_t debit_vc2_withhold : 6;
+- mmr_t debit_vc0_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t debit_vc0_withhold : 6;
+- } sh_xnmd_to_ni0_port_flow_s;
+-} sh_xnmd_to_ni0_port_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNMD_TO_NI1_PORT_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnmd_to_ni1_port_flow_u {
+ mmr_t sh_xnmd_to_ni1_port_flow_regval;
+ struct {
+@@ -8106,34 +4398,11 @@
+ mmr_t reserved_6 : 2;
+ } sh_xnmd_to_ni1_port_flow_s;
+ } sh_xnmd_to_ni1_port_flow_u_t;
+-#else
+-typedef union sh_xnmd_to_ni1_port_flow_u {
+- mmr_t sh_xnmd_to_ni1_port_flow_regval;
+- struct {
+- mmr_t reserved_6 : 2;
+- mmr_t credit_vc2_cap : 6;
+- mmr_t reserved_5 : 2;
+- mmr_t credit_vc2_dyn : 6;
+- mmr_t reserved_4 : 10;
+- mmr_t credit_vc0_cap : 6;
+- mmr_t reserved_3 : 2;
+- mmr_t credit_vc0_dyn : 6;
+- mmr_t reserved_2 : 8;
+- mmr_t debit_vc2_force_cred : 1;
+- mmr_t reserved_1 : 1;
+- mmr_t debit_vc2_withhold : 6;
+- mmr_t debit_vc0_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t debit_vc0_withhold : 6;
+- } sh_xnmd_to_ni1_port_flow_s;
+-} sh_xnmd_to_ni1_port_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNMD_TO_IILB_PORT_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnmd_to_iilb_port_flow_u {
+ mmr_t sh_xnmd_to_iilb_port_flow_regval;
+ struct {
+@@ -8154,34 +4423,11 @@
+ mmr_t reserved_6 : 2;
+ } sh_xnmd_to_iilb_port_flow_s;
+ } sh_xnmd_to_iilb_port_flow_u_t;
+-#else
+-typedef union sh_xnmd_to_iilb_port_flow_u {
+- mmr_t sh_xnmd_to_iilb_port_flow_regval;
+- struct {
+- mmr_t reserved_6 : 2;
+- mmr_t credit_vc2_cap : 6;
+- mmr_t reserved_5 : 2;
+- mmr_t credit_vc2_dyn : 6;
+- mmr_t reserved_4 : 10;
+- mmr_t credit_vc0_cap : 6;
+- mmr_t reserved_3 : 2;
+- mmr_t credit_vc0_dyn : 6;
+- mmr_t reserved_2 : 8;
+- mmr_t debit_vc2_force_cred : 1;
+- mmr_t reserved_1 : 1;
+- mmr_t debit_vc2_withhold : 6;
+- mmr_t debit_vc0_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t debit_vc0_withhold : 6;
+- } sh_xnmd_to_iilb_port_flow_s;
+-} sh_xnmd_to_iilb_port_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNMD_FR_NI0_PORT_FLOW_FIFO" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnmd_fr_ni0_port_flow_fifo_u {
+ mmr_t sh_xnmd_fr_ni0_port_flow_fifo_regval;
+ struct {
+@@ -8199,31 +4445,11 @@
+ mmr_t reserved_5 : 19;
+ } sh_xnmd_fr_ni0_port_flow_fifo_s;
+ } sh_xnmd_fr_ni0_port_flow_fifo_u_t;
+-#else
+-typedef union sh_xnmd_fr_ni0_port_flow_fifo_u {
+- mmr_t sh_xnmd_fr_ni0_port_flow_fifo_regval;
+- struct {
+- mmr_t reserved_5 : 19;
+- mmr_t entry_vc2_test : 5;
+- mmr_t reserved_4 : 3;
+- mmr_t entry_vc0_test : 5;
+- mmr_t reserved_3 : 2;
+- mmr_t entry_vc2_cap : 6;
+- mmr_t reserved_2 : 2;
+- mmr_t entry_vc2_dyn : 6;
+- mmr_t reserved_1 : 2;
+- mmr_t entry_vc0_cap : 6;
+- mmr_t reserved_0 : 2;
+- mmr_t entry_vc0_dyn : 6;
+- } sh_xnmd_fr_ni0_port_flow_fifo_s;
+-} sh_xnmd_fr_ni0_port_flow_fifo_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNMD_FR_NI1_PORT_FLOW_FIFO" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnmd_fr_ni1_port_flow_fifo_u {
+ mmr_t sh_xnmd_fr_ni1_port_flow_fifo_regval;
+ struct {
+@@ -8241,31 +4467,11 @@
+ mmr_t reserved_5 : 19;
+ } sh_xnmd_fr_ni1_port_flow_fifo_s;
+ } sh_xnmd_fr_ni1_port_flow_fifo_u_t;
+-#else
+-typedef union sh_xnmd_fr_ni1_port_flow_fifo_u {
+- mmr_t sh_xnmd_fr_ni1_port_flow_fifo_regval;
+- struct {
+- mmr_t reserved_5 : 19;
+- mmr_t entry_vc2_test : 5;
+- mmr_t reserved_4 : 3;
+- mmr_t entry_vc0_test : 5;
+- mmr_t reserved_3 : 2;
+- mmr_t entry_vc2_cap : 6;
+- mmr_t reserved_2 : 2;
+- mmr_t entry_vc2_dyn : 6;
+- mmr_t reserved_1 : 2;
+- mmr_t entry_vc0_cap : 6;
+- mmr_t reserved_0 : 2;
+- mmr_t entry_vc0_dyn : 6;
+- } sh_xnmd_fr_ni1_port_flow_fifo_s;
+-} sh_xnmd_fr_ni1_port_flow_fifo_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNMD_FR_IILB_PORT_FLOW_FIFO" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnmd_fr_iilb_port_flow_fifo_u {
+ mmr_t sh_xnmd_fr_iilb_port_flow_fifo_regval;
+ struct {
+@@ -8283,31 +4489,11 @@
+ mmr_t reserved_5 : 19;
+ } sh_xnmd_fr_iilb_port_flow_fifo_s;
+ } sh_xnmd_fr_iilb_port_flow_fifo_u_t;
+-#else
+-typedef union sh_xnmd_fr_iilb_port_flow_fifo_u {
+- mmr_t sh_xnmd_fr_iilb_port_flow_fifo_regval;
+- struct {
+- mmr_t reserved_5 : 19;
+- mmr_t entry_vc2_test : 5;
+- mmr_t reserved_4 : 3;
+- mmr_t entry_vc0_test : 5;
+- mmr_t reserved_3 : 2;
+- mmr_t entry_vc2_cap : 6;
+- mmr_t reserved_2 : 2;
+- mmr_t entry_vc2_dyn : 6;
+- mmr_t reserved_1 : 2;
+- mmr_t entry_vc0_cap : 6;
+- mmr_t reserved_0 : 2;
+- mmr_t entry_vc0_dyn : 6;
+- } sh_xnmd_fr_iilb_port_flow_fifo_s;
+-} sh_xnmd_fr_iilb_port_flow_fifo_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNII_INTRA_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnii_intra_flow_u {
+ mmr_t sh_xnii_intra_flow_regval;
+ struct {
+@@ -8331,37 +4517,11 @@
+ mmr_t reserved_7 : 1;
+ } sh_xnii_intra_flow_s;
+ } sh_xnii_intra_flow_u_t;
+-#else
+-typedef union sh_xnii_intra_flow_u {
+- mmr_t sh_xnii_intra_flow_regval;
+- struct {
+- mmr_t reserved_7 : 1;
+- mmr_t credit_vc2_cap : 7;
+- mmr_t reserved_6 : 1;
+- mmr_t credit_vc2_dyn : 7;
+- mmr_t reserved_5 : 1;
+- mmr_t credit_vc2_test : 7;
+- mmr_t reserved_4 : 1;
+- mmr_t credit_vc0_cap : 7;
+- mmr_t reserved_3 : 1;
+- mmr_t credit_vc0_dyn : 7;
+- mmr_t reserved_2 : 1;
+- mmr_t credit_vc0_test : 7;
+- mmr_t debit_vc2_force_cred : 1;
+- mmr_t reserved_1 : 1;
+- mmr_t debit_vc2_withhold : 6;
+- mmr_t debit_vc0_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t debit_vc0_withhold : 6;
+- } sh_xnii_intra_flow_s;
+-} sh_xnii_intra_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNLB_INTRA_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnlb_intra_flow_u {
+ mmr_t sh_xnlb_intra_flow_regval;
+ struct {
+@@ -8385,37 +4545,11 @@
+ mmr_t disable_bypass_in : 1;
+ } sh_xnlb_intra_flow_s;
+ } sh_xnlb_intra_flow_u_t;
+-#else
+-typedef union sh_xnlb_intra_flow_u {
+- mmr_t sh_xnlb_intra_flow_regval;
+- struct {
+- mmr_t disable_bypass_in : 1;
+- mmr_t credit_vc2_cap : 7;
+- mmr_t reserved_6 : 1;
+- mmr_t credit_vc2_dyn : 7;
+- mmr_t reserved_5 : 1;
+- mmr_t credit_vc2_test : 7;
+- mmr_t reserved_4 : 1;
+- mmr_t credit_vc0_cap : 7;
+- mmr_t reserved_3 : 1;
+- mmr_t credit_vc0_dyn : 7;
+- mmr_t reserved_2 : 1;
+- mmr_t credit_vc0_test : 7;
+- mmr_t debit_vc2_force_cred : 1;
+- mmr_t reserved_1 : 1;
+- mmr_t debit_vc2_withhold : 6;
+- mmr_t debit_vc0_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t debit_vc0_withhold : 6;
+- } sh_xnlb_intra_flow_s;
+-} sh_xnlb_intra_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNIILB_TO_NI0_INTRA_FLOW_DEBIT" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xniilb_to_ni0_intra_flow_debit_u {
+ mmr_t sh_xniilb_to_ni0_intra_flow_debit_regval;
+ struct {
+@@ -8436,34 +4570,11 @@
+ mmr_t reserved_6 : 1;
+ } sh_xniilb_to_ni0_intra_flow_debit_s;
+ } sh_xniilb_to_ni0_intra_flow_debit_u_t;
+-#else
+-typedef union sh_xniilb_to_ni0_intra_flow_debit_u {
+- mmr_t sh_xniilb_to_ni0_intra_flow_debit_regval;
+- struct {
+- mmr_t reserved_6 : 1;
+- mmr_t vc2_cap : 7;
+- mmr_t reserved_5 : 1;
+- mmr_t vc2_dyn : 7;
+- mmr_t reserved_4 : 9;
+- mmr_t vc0_cap : 7;
+- mmr_t reserved_3 : 1;
+- mmr_t vc0_dyn : 7;
+- mmr_t reserved_2 : 8;
+- mmr_t vc2_force_cred : 1;
+- mmr_t reserved_1 : 1;
+- mmr_t vc2_withhold : 6;
+- mmr_t vc0_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t vc0_withhold : 6;
+- } sh_xniilb_to_ni0_intra_flow_debit_s;
+-} sh_xniilb_to_ni0_intra_flow_debit_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNIILB_TO_NI1_INTRA_FLOW_DEBIT" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xniilb_to_ni1_intra_flow_debit_u {
+ mmr_t sh_xniilb_to_ni1_intra_flow_debit_regval;
+ struct {
+@@ -8484,34 +4595,11 @@
+ mmr_t reserved_6 : 1;
+ } sh_xniilb_to_ni1_intra_flow_debit_s;
+ } sh_xniilb_to_ni1_intra_flow_debit_u_t;
+-#else
+-typedef union sh_xniilb_to_ni1_intra_flow_debit_u {
+- mmr_t sh_xniilb_to_ni1_intra_flow_debit_regval;
+- struct {
+- mmr_t reserved_6 : 1;
+- mmr_t vc2_cap : 7;
+- mmr_t reserved_5 : 1;
+- mmr_t vc2_dyn : 7;
+- mmr_t reserved_4 : 9;
+- mmr_t vc0_cap : 7;
+- mmr_t reserved_3 : 1;
+- mmr_t vc0_dyn : 7;
+- mmr_t reserved_2 : 8;
+- mmr_t vc2_force_cred : 1;
+- mmr_t reserved_1 : 1;
+- mmr_t vc2_withhold : 6;
+- mmr_t vc0_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t vc0_withhold : 6;
+- } sh_xniilb_to_ni1_intra_flow_debit_s;
+-} sh_xniilb_to_ni1_intra_flow_debit_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNIILB_TO_MD_INTRA_FLOW_DEBIT" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xniilb_to_md_intra_flow_debit_u {
+ mmr_t sh_xniilb_to_md_intra_flow_debit_regval;
+ struct {
+@@ -8532,34 +4620,11 @@
+ mmr_t reserved_6 : 1;
+ } sh_xniilb_to_md_intra_flow_debit_s;
+ } sh_xniilb_to_md_intra_flow_debit_u_t;
+-#else
+-typedef union sh_xniilb_to_md_intra_flow_debit_u {
+- mmr_t sh_xniilb_to_md_intra_flow_debit_regval;
+- struct {
+- mmr_t reserved_6 : 1;
+- mmr_t vc2_cap : 7;
+- mmr_t reserved_5 : 1;
+- mmr_t vc2_dyn : 7;
+- mmr_t reserved_4 : 9;
+- mmr_t vc0_cap : 7;
+- mmr_t reserved_3 : 1;
+- mmr_t vc0_dyn : 7;
+- mmr_t reserved_2 : 8;
+- mmr_t vc2_force_cred : 1;
+- mmr_t reserved_1 : 1;
+- mmr_t vc2_withhold : 6;
+- mmr_t vc0_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t vc0_withhold : 6;
+- } sh_xniilb_to_md_intra_flow_debit_s;
+-} sh_xniilb_to_md_intra_flow_debit_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNIILB_TO_IILB_INTRA_FLOW_DEBIT" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xniilb_to_iilb_intra_flow_debit_u {
+ mmr_t sh_xniilb_to_iilb_intra_flow_debit_regval;
+ struct {
+@@ -8580,34 +4645,11 @@
+ mmr_t reserved_6 : 1;
+ } sh_xniilb_to_iilb_intra_flow_debit_s;
+ } sh_xniilb_to_iilb_intra_flow_debit_u_t;
+-#else
+-typedef union sh_xniilb_to_iilb_intra_flow_debit_u {
+- mmr_t sh_xniilb_to_iilb_intra_flow_debit_regval;
+- struct {
+- mmr_t reserved_6 : 1;
+- mmr_t vc2_cap : 7;
+- mmr_t reserved_5 : 1;
+- mmr_t vc2_dyn : 7;
+- mmr_t reserved_4 : 9;
+- mmr_t vc0_cap : 7;
+- mmr_t reserved_3 : 1;
+- mmr_t vc0_dyn : 7;
+- mmr_t reserved_2 : 8;
+- mmr_t vc2_force_cred : 1;
+- mmr_t reserved_1 : 1;
+- mmr_t vc2_withhold : 6;
+- mmr_t vc0_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t vc0_withhold : 6;
+- } sh_xniilb_to_iilb_intra_flow_debit_s;
+-} sh_xniilb_to_iilb_intra_flow_debit_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNIILB_TO_PI_INTRA_FLOW_DEBIT" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xniilb_to_pi_intra_flow_debit_u {
+ mmr_t sh_xniilb_to_pi_intra_flow_debit_regval;
+ struct {
+@@ -8628,34 +4670,11 @@
+ mmr_t reserved_6 : 1;
+ } sh_xniilb_to_pi_intra_flow_debit_s;
+ } sh_xniilb_to_pi_intra_flow_debit_u_t;
+-#else
+-typedef union sh_xniilb_to_pi_intra_flow_debit_u {
+- mmr_t sh_xniilb_to_pi_intra_flow_debit_regval;
+- struct {
+- mmr_t reserved_6 : 1;
+- mmr_t vc2_cap : 7;
+- mmr_t reserved_5 : 1;
+- mmr_t vc2_dyn : 7;
+- mmr_t reserved_4 : 9;
+- mmr_t vc0_cap : 7;
+- mmr_t reserved_3 : 1;
+- mmr_t vc0_dyn : 7;
+- mmr_t reserved_2 : 8;
+- mmr_t vc2_force_cred : 1;
+- mmr_t reserved_1 : 1;
+- mmr_t vc2_withhold : 6;
+- mmr_t vc0_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t vc0_withhold : 6;
+- } sh_xniilb_to_pi_intra_flow_debit_s;
+-} sh_xniilb_to_pi_intra_flow_debit_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNIILB_FR_NI0_INTRA_FLOW_CREDIT" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xniilb_fr_ni0_intra_flow_credit_u {
+ mmr_t sh_xniilb_fr_ni0_intra_flow_credit_regval;
+ struct {
+@@ -8673,31 +4692,11 @@
+ mmr_t reserved_5 : 17;
+ } sh_xniilb_fr_ni0_intra_flow_credit_s;
+ } sh_xniilb_fr_ni0_intra_flow_credit_u_t;
+-#else
+-typedef union sh_xniilb_fr_ni0_intra_flow_credit_u {
+- mmr_t sh_xniilb_fr_ni0_intra_flow_credit_regval;
+- struct {
+- mmr_t reserved_5 : 17;
+- mmr_t vc2_cap : 7;
+- mmr_t reserved_4 : 1;
+- mmr_t vc2_dyn : 7;
+- mmr_t reserved_3 : 1;
+- mmr_t vc2_test : 7;
+- mmr_t reserved_2 : 1;
+- mmr_t vc0_cap : 7;
+- mmr_t reserved_1 : 1;
+- mmr_t vc0_dyn : 7;
+- mmr_t reserved_0 : 1;
+- mmr_t vc0_test : 7;
+- } sh_xniilb_fr_ni0_intra_flow_credit_s;
+-} sh_xniilb_fr_ni0_intra_flow_credit_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNIILB_FR_NI1_INTRA_FLOW_CREDIT" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xniilb_fr_ni1_intra_flow_credit_u {
+ mmr_t sh_xniilb_fr_ni1_intra_flow_credit_regval;
+ struct {
+@@ -8715,31 +4714,11 @@
+ mmr_t reserved_5 : 17;
+ } sh_xniilb_fr_ni1_intra_flow_credit_s;
+ } sh_xniilb_fr_ni1_intra_flow_credit_u_t;
+-#else
+-typedef union sh_xniilb_fr_ni1_intra_flow_credit_u {
+- mmr_t sh_xniilb_fr_ni1_intra_flow_credit_regval;
+- struct {
+- mmr_t reserved_5 : 17;
+- mmr_t vc2_cap : 7;
+- mmr_t reserved_4 : 1;
+- mmr_t vc2_dyn : 7;
+- mmr_t reserved_3 : 1;
+- mmr_t vc2_test : 7;
+- mmr_t reserved_2 : 1;
+- mmr_t vc0_cap : 7;
+- mmr_t reserved_1 : 1;
+- mmr_t vc0_dyn : 7;
+- mmr_t reserved_0 : 1;
+- mmr_t vc0_test : 7;
+- } sh_xniilb_fr_ni1_intra_flow_credit_s;
+-} sh_xniilb_fr_ni1_intra_flow_credit_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNIILB_FR_MD_INTRA_FLOW_CREDIT" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xniilb_fr_md_intra_flow_credit_u {
+ mmr_t sh_xniilb_fr_md_intra_flow_credit_regval;
+ struct {
+@@ -8757,31 +4736,11 @@
+ mmr_t reserved_5 : 17;
+ } sh_xniilb_fr_md_intra_flow_credit_s;
+ } sh_xniilb_fr_md_intra_flow_credit_u_t;
+-#else
+-typedef union sh_xniilb_fr_md_intra_flow_credit_u {
+- mmr_t sh_xniilb_fr_md_intra_flow_credit_regval;
+- struct {
+- mmr_t reserved_5 : 17;
+- mmr_t vc2_cap : 7;
+- mmr_t reserved_4 : 1;
+- mmr_t vc2_dyn : 7;
+- mmr_t reserved_3 : 1;
+- mmr_t vc2_test : 7;
+- mmr_t reserved_2 : 1;
+- mmr_t vc0_cap : 7;
+- mmr_t reserved_1 : 1;
+- mmr_t vc0_dyn : 7;
+- mmr_t reserved_0 : 1;
+- mmr_t vc0_test : 7;
+- } sh_xniilb_fr_md_intra_flow_credit_s;
+-} sh_xniilb_fr_md_intra_flow_credit_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNIILB_FR_IILB_INTRA_FLOW_CREDIT" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xniilb_fr_iilb_intra_flow_credit_u {
+ mmr_t sh_xniilb_fr_iilb_intra_flow_credit_regval;
+ struct {
+@@ -8799,31 +4758,11 @@
+ mmr_t reserved_5 : 17;
+ } sh_xniilb_fr_iilb_intra_flow_credit_s;
+ } sh_xniilb_fr_iilb_intra_flow_credit_u_t;
+-#else
+-typedef union sh_xniilb_fr_iilb_intra_flow_credit_u {
+- mmr_t sh_xniilb_fr_iilb_intra_flow_credit_regval;
+- struct {
+- mmr_t reserved_5 : 17;
+- mmr_t vc2_cap : 7;
+- mmr_t reserved_4 : 1;
+- mmr_t vc2_dyn : 7;
+- mmr_t reserved_3 : 1;
+- mmr_t vc2_test : 7;
+- mmr_t reserved_2 : 1;
+- mmr_t vc0_cap : 7;
+- mmr_t reserved_1 : 1;
+- mmr_t vc0_dyn : 7;
+- mmr_t reserved_0 : 1;
+- mmr_t vc0_test : 7;
+- } sh_xniilb_fr_iilb_intra_flow_credit_s;
+-} sh_xniilb_fr_iilb_intra_flow_credit_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNIILB_FR_PI_INTRA_FLOW_CREDIT" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xniilb_fr_pi_intra_flow_credit_u {
+ mmr_t sh_xniilb_fr_pi_intra_flow_credit_regval;
+ struct {
+@@ -8841,31 +4780,11 @@
+ mmr_t reserved_5 : 17;
+ } sh_xniilb_fr_pi_intra_flow_credit_s;
+ } sh_xniilb_fr_pi_intra_flow_credit_u_t;
+-#else
+-typedef union sh_xniilb_fr_pi_intra_flow_credit_u {
+- mmr_t sh_xniilb_fr_pi_intra_flow_credit_regval;
+- struct {
+- mmr_t reserved_5 : 17;
+- mmr_t vc2_cap : 7;
+- mmr_t reserved_4 : 1;
+- mmr_t vc2_dyn : 7;
+- mmr_t reserved_3 : 1;
+- mmr_t vc2_test : 7;
+- mmr_t reserved_2 : 1;
+- mmr_t vc0_cap : 7;
+- mmr_t reserved_1 : 1;
+- mmr_t vc0_dyn : 7;
+- mmr_t reserved_0 : 1;
+- mmr_t vc0_test : 7;
+- } sh_xniilb_fr_pi_intra_flow_credit_s;
+-} sh_xniilb_fr_pi_intra_flow_credit_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI0_TO_PI_INTRA_FLOW_DEBIT" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_to_pi_intra_flow_debit_u {
+ mmr_t sh_xnni0_to_pi_intra_flow_debit_regval;
+ struct {
+@@ -8886,34 +4805,11 @@
+ mmr_t reserved_6 : 1;
+ } sh_xnni0_to_pi_intra_flow_debit_s;
+ } sh_xnni0_to_pi_intra_flow_debit_u_t;
+-#else
+-typedef union sh_xnni0_to_pi_intra_flow_debit_u {
+- mmr_t sh_xnni0_to_pi_intra_flow_debit_regval;
+- struct {
+- mmr_t reserved_6 : 1;
+- mmr_t vc2_cap : 7;
+- mmr_t reserved_5 : 1;
+- mmr_t vc2_dyn : 7;
+- mmr_t reserved_4 : 9;
+- mmr_t vc0_cap : 7;
+- mmr_t reserved_3 : 1;
+- mmr_t vc0_dyn : 7;
+- mmr_t reserved_2 : 8;
+- mmr_t vc2_force_cred : 1;
+- mmr_t reserved_1 : 1;
+- mmr_t vc2_withhold : 6;
+- mmr_t vc0_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t vc0_withhold : 6;
+- } sh_xnni0_to_pi_intra_flow_debit_s;
+-} sh_xnni0_to_pi_intra_flow_debit_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI0_TO_MD_INTRA_FLOW_DEBIT" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_to_md_intra_flow_debit_u {
+ mmr_t sh_xnni0_to_md_intra_flow_debit_regval;
+ struct {
+@@ -8934,34 +4830,11 @@
+ mmr_t reserved_6 : 1;
+ } sh_xnni0_to_md_intra_flow_debit_s;
+ } sh_xnni0_to_md_intra_flow_debit_u_t;
+-#else
+-typedef union sh_xnni0_to_md_intra_flow_debit_u {
+- mmr_t sh_xnni0_to_md_intra_flow_debit_regval;
+- struct {
+- mmr_t reserved_6 : 1;
+- mmr_t vc2_cap : 7;
+- mmr_t reserved_5 : 1;
+- mmr_t vc2_dyn : 7;
+- mmr_t reserved_4 : 9;
+- mmr_t vc0_cap : 7;
+- mmr_t reserved_3 : 1;
+- mmr_t vc0_dyn : 7;
+- mmr_t reserved_2 : 8;
+- mmr_t vc2_force_cred : 1;
+- mmr_t reserved_1 : 1;
+- mmr_t vc2_withhold : 6;
+- mmr_t vc0_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t vc0_withhold : 6;
+- } sh_xnni0_to_md_intra_flow_debit_s;
+-} sh_xnni0_to_md_intra_flow_debit_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI0_TO_IILB_INTRA_FLOW_DEBIT" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_to_iilb_intra_flow_debit_u {
+ mmr_t sh_xnni0_to_iilb_intra_flow_debit_regval;
+ struct {
+@@ -8982,34 +4855,11 @@
+ mmr_t reserved_6 : 1;
+ } sh_xnni0_to_iilb_intra_flow_debit_s;
+ } sh_xnni0_to_iilb_intra_flow_debit_u_t;
+-#else
+-typedef union sh_xnni0_to_iilb_intra_flow_debit_u {
+- mmr_t sh_xnni0_to_iilb_intra_flow_debit_regval;
+- struct {
+- mmr_t reserved_6 : 1;
+- mmr_t vc2_cap : 7;
+- mmr_t reserved_5 : 1;
+- mmr_t vc2_dyn : 7;
+- mmr_t reserved_4 : 9;
+- mmr_t vc0_cap : 7;
+- mmr_t reserved_3 : 1;
+- mmr_t vc0_dyn : 7;
+- mmr_t reserved_2 : 8;
+- mmr_t vc2_force_cred : 1;
+- mmr_t reserved_1 : 1;
+- mmr_t vc2_withhold : 6;
+- mmr_t vc0_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t vc0_withhold : 6;
+- } sh_xnni0_to_iilb_intra_flow_debit_s;
+-} sh_xnni0_to_iilb_intra_flow_debit_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI0_FR_PI_INTRA_FLOW_CREDIT" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_fr_pi_intra_flow_credit_u {
+ mmr_t sh_xnni0_fr_pi_intra_flow_credit_regval;
+ struct {
+@@ -9027,31 +4877,11 @@
+ mmr_t reserved_5 : 17;
+ } sh_xnni0_fr_pi_intra_flow_credit_s;
+ } sh_xnni0_fr_pi_intra_flow_credit_u_t;
+-#else
+-typedef union sh_xnni0_fr_pi_intra_flow_credit_u {
+- mmr_t sh_xnni0_fr_pi_intra_flow_credit_regval;
+- struct {
+- mmr_t reserved_5 : 17;
+- mmr_t vc2_cap : 7;
+- mmr_t reserved_4 : 1;
+- mmr_t vc2_dyn : 7;
+- mmr_t reserved_3 : 1;
+- mmr_t vc2_test : 7;
+- mmr_t reserved_2 : 1;
+- mmr_t vc0_cap : 7;
+- mmr_t reserved_1 : 1;
+- mmr_t vc0_dyn : 7;
+- mmr_t reserved_0 : 1;
+- mmr_t vc0_test : 7;
+- } sh_xnni0_fr_pi_intra_flow_credit_s;
+-} sh_xnni0_fr_pi_intra_flow_credit_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI0_FR_MD_INTRA_FLOW_CREDIT" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_fr_md_intra_flow_credit_u {
+ mmr_t sh_xnni0_fr_md_intra_flow_credit_regval;
+ struct {
+@@ -9069,31 +4899,11 @@
+ mmr_t reserved_5 : 17;
+ } sh_xnni0_fr_md_intra_flow_credit_s;
+ } sh_xnni0_fr_md_intra_flow_credit_u_t;
+-#else
+-typedef union sh_xnni0_fr_md_intra_flow_credit_u {
+- mmr_t sh_xnni0_fr_md_intra_flow_credit_regval;
+- struct {
+- mmr_t reserved_5 : 17;
+- mmr_t vc2_cap : 7;
+- mmr_t reserved_4 : 1;
+- mmr_t vc2_dyn : 7;
+- mmr_t reserved_3 : 1;
+- mmr_t vc2_test : 7;
+- mmr_t reserved_2 : 1;
+- mmr_t vc0_cap : 7;
+- mmr_t reserved_1 : 1;
+- mmr_t vc0_dyn : 7;
+- mmr_t reserved_0 : 1;
+- mmr_t vc0_test : 7;
+- } sh_xnni0_fr_md_intra_flow_credit_s;
+-} sh_xnni0_fr_md_intra_flow_credit_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI0_FR_IILB_INTRA_FLOW_CREDIT" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_fr_iilb_intra_flow_credit_u {
+ mmr_t sh_xnni0_fr_iilb_intra_flow_credit_regval;
+ struct {
+@@ -9111,31 +4921,11 @@
+ mmr_t reserved_5 : 17;
+ } sh_xnni0_fr_iilb_intra_flow_credit_s;
+ } sh_xnni0_fr_iilb_intra_flow_credit_u_t;
+-#else
+-typedef union sh_xnni0_fr_iilb_intra_flow_credit_u {
+- mmr_t sh_xnni0_fr_iilb_intra_flow_credit_regval;
+- struct {
+- mmr_t reserved_5 : 17;
+- mmr_t vc2_cap : 7;
+- mmr_t reserved_4 : 1;
+- mmr_t vc2_dyn : 7;
+- mmr_t reserved_3 : 1;
+- mmr_t vc2_test : 7;
+- mmr_t reserved_2 : 1;
+- mmr_t vc0_cap : 7;
+- mmr_t reserved_1 : 1;
+- mmr_t vc0_dyn : 7;
+- mmr_t reserved_0 : 1;
+- mmr_t vc0_test : 7;
+- } sh_xnni0_fr_iilb_intra_flow_credit_s;
+-} sh_xnni0_fr_iilb_intra_flow_credit_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI0_0_INTRANI_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_0_intrani_flow_u {
+ mmr_t sh_xnni0_0_intrani_flow_regval;
+ struct {
+@@ -9145,23 +4935,11 @@
+ mmr_t reserved_1 : 56;
+ } sh_xnni0_0_intrani_flow_s;
+ } sh_xnni0_0_intrani_flow_u_t;
+-#else
+-typedef union sh_xnni0_0_intrani_flow_u {
+- mmr_t sh_xnni0_0_intrani_flow_regval;
+- struct {
+- mmr_t reserved_1 : 56;
+- mmr_t debit_vc0_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t debit_vc0_withhold : 6;
+- } sh_xnni0_0_intrani_flow_s;
+-} sh_xnni0_0_intrani_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI0_1_INTRANI_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_1_intrani_flow_u {
+ mmr_t sh_xnni0_1_intrani_flow_regval;
+ struct {
+@@ -9171,23 +4949,11 @@
+ mmr_t reserved_1 : 56;
+ } sh_xnni0_1_intrani_flow_s;
+ } sh_xnni0_1_intrani_flow_u_t;
+-#else
+-typedef union sh_xnni0_1_intrani_flow_u {
+- mmr_t sh_xnni0_1_intrani_flow_regval;
+- struct {
+- mmr_t reserved_1 : 56;
+- mmr_t debit_vc1_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t debit_vc1_withhold : 6;
+- } sh_xnni0_1_intrani_flow_s;
+-} sh_xnni0_1_intrani_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI0_2_INTRANI_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_2_intrani_flow_u {
+ mmr_t sh_xnni0_2_intrani_flow_regval;
+ struct {
+@@ -9197,23 +4963,11 @@
+ mmr_t reserved_1 : 56;
+ } sh_xnni0_2_intrani_flow_s;
+ } sh_xnni0_2_intrani_flow_u_t;
+-#else
+-typedef union sh_xnni0_2_intrani_flow_u {
+- mmr_t sh_xnni0_2_intrani_flow_regval;
+- struct {
+- mmr_t reserved_1 : 56;
+- mmr_t debit_vc2_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t debit_vc2_withhold : 6;
+- } sh_xnni0_2_intrani_flow_s;
+-} sh_xnni0_2_intrani_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI0_3_INTRANI_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_3_intrani_flow_u {
+ mmr_t sh_xnni0_3_intrani_flow_regval;
+ struct {
+@@ -9223,23 +4977,11 @@
+ mmr_t reserved_1 : 56;
+ } sh_xnni0_3_intrani_flow_s;
+ } sh_xnni0_3_intrani_flow_u_t;
+-#else
+-typedef union sh_xnni0_3_intrani_flow_u {
+- mmr_t sh_xnni0_3_intrani_flow_regval;
+- struct {
+- mmr_t reserved_1 : 56;
+- mmr_t debit_vc3_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t debit_vc3_withhold : 6;
+- } sh_xnni0_3_intrani_flow_s;
+-} sh_xnni0_3_intrani_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI0_VCSWITCH_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_vcswitch_flow_u {
+ mmr_t sh_xnni0_vcswitch_flow_regval;
+ struct {
+@@ -9257,31 +4999,11 @@
+ mmr_t reserved_4 : 29;
+ } sh_xnni0_vcswitch_flow_s;
+ } sh_xnni0_vcswitch_flow_u_t;
+-#else
+-typedef union sh_xnni0_vcswitch_flow_u {
+- mmr_t sh_xnni0_vcswitch_flow_regval;
+- struct {
+- mmr_t reserved_4 : 29;
+- mmr_t async_fifoes : 1;
+- mmr_t disable_sync_bypass_out : 1;
+- mmr_t disable_sync_bypass_in : 1;
+- mmr_t reserved_3 : 7;
+- mmr_t iilb_vcfifo_switch : 1;
+- mmr_t reserved_2 : 7;
+- mmr_t md_vcfifo_switch : 1;
+- mmr_t reserved_1 : 7;
+- mmr_t pi_vcfifo_switch : 1;
+- mmr_t reserved_0 : 7;
+- mmr_t ni_vcfifo_dateline_switch : 1;
+- } sh_xnni0_vcswitch_flow_s;
+-} sh_xnni0_vcswitch_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI0_TIMER_REG" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_timer_reg_u {
+ mmr_t sh_xnni0_timer_reg_regval;
+ struct {
+@@ -9291,23 +5013,11 @@
+ mmr_t reserved_1 : 31;
+ } sh_xnni0_timer_reg_s;
+ } sh_xnni0_timer_reg_u_t;
+-#else
+-typedef union sh_xnni0_timer_reg_u {
+- mmr_t sh_xnni0_timer_reg_regval;
+- struct {
+- mmr_t reserved_1 : 31;
+- mmr_t linkcleanup_reg : 1;
+- mmr_t reserved_0 : 8;
+- mmr_t timeout_reg : 24;
+- } sh_xnni0_timer_reg_s;
+-} sh_xnni0_timer_reg_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI0_FIFO02_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_fifo02_flow_u {
+ mmr_t sh_xnni0_fifo02_flow_regval;
+ struct {
+@@ -9325,31 +5035,11 @@
+ mmr_t reserved_5 : 20;
+ } sh_xnni0_fifo02_flow_s;
+ } sh_xnni0_fifo02_flow_u_t;
+-#else
+-typedef union sh_xnni0_fifo02_flow_u {
+- mmr_t sh_xnni0_fifo02_flow_regval;
+- struct {
+- mmr_t reserved_5 : 20;
+- mmr_t count_vc2_cap : 4;
+- mmr_t reserved_4 : 4;
+- mmr_t count_vc2_dyn : 4;
+- mmr_t reserved_3 : 4;
+- mmr_t count_vc2_limit : 4;
+- mmr_t reserved_2 : 4;
+- mmr_t count_vc0_cap : 4;
+- mmr_t reserved_1 : 4;
+- mmr_t count_vc0_dyn : 4;
+- mmr_t reserved_0 : 4;
+- mmr_t count_vc0_limit : 4;
+- } sh_xnni0_fifo02_flow_s;
+-} sh_xnni0_fifo02_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI0_FIFO13_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_fifo13_flow_u {
+ mmr_t sh_xnni0_fifo13_flow_regval;
+ struct {
+@@ -9367,31 +5057,11 @@
+ mmr_t reserved_5 : 20;
+ } sh_xnni0_fifo13_flow_s;
+ } sh_xnni0_fifo13_flow_u_t;
+-#else
+-typedef union sh_xnni0_fifo13_flow_u {
+- mmr_t sh_xnni0_fifo13_flow_regval;
+- struct {
+- mmr_t reserved_5 : 20;
+- mmr_t count_vc3_cap : 4;
+- mmr_t reserved_4 : 4;
+- mmr_t count_vc3_dyn : 4;
+- mmr_t reserved_3 : 4;
+- mmr_t count_vc3_limit : 4;
+- mmr_t reserved_2 : 4;
+- mmr_t count_vc1_cap : 4;
+- mmr_t reserved_1 : 4;
+- mmr_t count_vc1_dyn : 4;
+- mmr_t reserved_0 : 4;
+- mmr_t count_vc1_limit : 4;
+- } sh_xnni0_fifo13_flow_s;
+-} sh_xnni0_fifo13_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI0_NI_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_ni_flow_u {
+ mmr_t sh_xnni0_ni_flow_regval;
+ struct {
+@@ -9413,35 +5083,11 @@
+ mmr_t vc3_cap : 4;
+ } sh_xnni0_ni_flow_s;
+ } sh_xnni0_ni_flow_u_t;
+-#else
+-typedef union sh_xnni0_ni_flow_u {
+- mmr_t sh_xnni0_ni_flow_regval;
+- struct {
+- mmr_t vc3_cap : 4;
+- mmr_t vc3_dyn : 4;
+- mmr_t reserved_3 : 4;
+- mmr_t vc3_limit : 4;
+- mmr_t vc2_cap : 4;
+- mmr_t vc2_dyn : 4;
+- mmr_t reserved_2 : 4;
+- mmr_t vc2_limit : 4;
+- mmr_t vc1_cap : 4;
+- mmr_t vc1_dyn : 4;
+- mmr_t reserved_1 : 4;
+- mmr_t vc1_limit : 4;
+- mmr_t vc0_cap : 4;
+- mmr_t vc0_dyn : 4;
+- mmr_t reserved_0 : 4;
+- mmr_t vc0_limit : 4;
+- } sh_xnni0_ni_flow_s;
+-} sh_xnni0_ni_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI0_DEAD_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_dead_flow_u {
+ mmr_t sh_xnni0_dead_flow_regval;
+ struct {
+@@ -9463,35 +5109,11 @@
+ mmr_t vc3_cap : 4;
+ } sh_xnni0_dead_flow_s;
+ } sh_xnni0_dead_flow_u_t;
+-#else
+-typedef union sh_xnni0_dead_flow_u {
+- mmr_t sh_xnni0_dead_flow_regval;
+- struct {
+- mmr_t vc3_cap : 4;
+- mmr_t vc3_dyn : 4;
+- mmr_t reserved_3 : 4;
+- mmr_t vc3_limit : 4;
+- mmr_t vc2_cap : 4;
+- mmr_t vc2_dyn : 4;
+- mmr_t reserved_2 : 4;
+- mmr_t vc2_limit : 4;
+- mmr_t vc1_cap : 4;
+- mmr_t vc1_dyn : 4;
+- mmr_t reserved_1 : 4;
+- mmr_t vc1_limit : 4;
+- mmr_t vc0_cap : 4;
+- mmr_t vc0_dyn : 4;
+- mmr_t reserved_0 : 4;
+- mmr_t vc0_limit : 4;
+- } sh_xnni0_dead_flow_s;
+-} sh_xnni0_dead_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI0_INJECT_AGE" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_inject_age_u {
+ mmr_t sh_xnni0_inject_age_regval;
+ struct {
+@@ -9500,22 +5122,11 @@
+ mmr_t reserved_0 : 48;
+ } sh_xnni0_inject_age_s;
+ } sh_xnni0_inject_age_u_t;
+-#else
+-typedef union sh_xnni0_inject_age_u {
+- mmr_t sh_xnni0_inject_age_regval;
+- struct {
+- mmr_t reserved_0 : 48;
+- mmr_t reply_inject : 8;
+- mmr_t request_inject : 8;
+- } sh_xnni0_inject_age_s;
+-} sh_xnni0_inject_age_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI1_TO_PI_INTRA_FLOW_DEBIT" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_to_pi_intra_flow_debit_u {
+ mmr_t sh_xnni1_to_pi_intra_flow_debit_regval;
+ struct {
+@@ -9536,34 +5147,11 @@
+ mmr_t reserved_6 : 1;
+ } sh_xnni1_to_pi_intra_flow_debit_s;
+ } sh_xnni1_to_pi_intra_flow_debit_u_t;
+-#else
+-typedef union sh_xnni1_to_pi_intra_flow_debit_u {
+- mmr_t sh_xnni1_to_pi_intra_flow_debit_regval;
+- struct {
+- mmr_t reserved_6 : 1;
+- mmr_t vc2_cap : 7;
+- mmr_t reserved_5 : 1;
+- mmr_t vc2_dyn : 7;
+- mmr_t reserved_4 : 9;
+- mmr_t vc0_cap : 7;
+- mmr_t reserved_3 : 1;
+- mmr_t vc0_dyn : 7;
+- mmr_t reserved_2 : 8;
+- mmr_t vc2_force_cred : 1;
+- mmr_t reserved_1 : 1;
+- mmr_t vc2_withhold : 6;
+- mmr_t vc0_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t vc0_withhold : 6;
+- } sh_xnni1_to_pi_intra_flow_debit_s;
+-} sh_xnni1_to_pi_intra_flow_debit_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI1_TO_MD_INTRA_FLOW_DEBIT" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_to_md_intra_flow_debit_u {
+ mmr_t sh_xnni1_to_md_intra_flow_debit_regval;
+ struct {
+@@ -9584,34 +5172,11 @@
+ mmr_t reserved_6 : 1;
+ } sh_xnni1_to_md_intra_flow_debit_s;
+ } sh_xnni1_to_md_intra_flow_debit_u_t;
+-#else
+-typedef union sh_xnni1_to_md_intra_flow_debit_u {
+- mmr_t sh_xnni1_to_md_intra_flow_debit_regval;
+- struct {
+- mmr_t reserved_6 : 1;
+- mmr_t vc2_cap : 7;
+- mmr_t reserved_5 : 1;
+- mmr_t vc2_dyn : 7;
+- mmr_t reserved_4 : 9;
+- mmr_t vc0_cap : 7;
+- mmr_t reserved_3 : 1;
+- mmr_t vc0_dyn : 7;
+- mmr_t reserved_2 : 8;
+- mmr_t vc2_force_cred : 1;
+- mmr_t reserved_1 : 1;
+- mmr_t vc2_withhold : 6;
+- mmr_t vc0_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t vc0_withhold : 6;
+- } sh_xnni1_to_md_intra_flow_debit_s;
+-} sh_xnni1_to_md_intra_flow_debit_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI1_TO_IILB_INTRA_FLOW_DEBIT" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_to_iilb_intra_flow_debit_u {
+ mmr_t sh_xnni1_to_iilb_intra_flow_debit_regval;
+ struct {
+@@ -9632,34 +5197,11 @@
+ mmr_t reserved_6 : 1;
+ } sh_xnni1_to_iilb_intra_flow_debit_s;
+ } sh_xnni1_to_iilb_intra_flow_debit_u_t;
+-#else
+-typedef union sh_xnni1_to_iilb_intra_flow_debit_u {
+- mmr_t sh_xnni1_to_iilb_intra_flow_debit_regval;
+- struct {
+- mmr_t reserved_6 : 1;
+- mmr_t vc2_cap : 7;
+- mmr_t reserved_5 : 1;
+- mmr_t vc2_dyn : 7;
+- mmr_t reserved_4 : 9;
+- mmr_t vc0_cap : 7;
+- mmr_t reserved_3 : 1;
+- mmr_t vc0_dyn : 7;
+- mmr_t reserved_2 : 8;
+- mmr_t vc2_force_cred : 1;
+- mmr_t reserved_1 : 1;
+- mmr_t vc2_withhold : 6;
+- mmr_t vc0_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t vc0_withhold : 6;
+- } sh_xnni1_to_iilb_intra_flow_debit_s;
+-} sh_xnni1_to_iilb_intra_flow_debit_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI1_FR_PI_INTRA_FLOW_CREDIT" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_fr_pi_intra_flow_credit_u {
+ mmr_t sh_xnni1_fr_pi_intra_flow_credit_regval;
+ struct {
+@@ -9677,31 +5219,11 @@
+ mmr_t reserved_5 : 17;
+ } sh_xnni1_fr_pi_intra_flow_credit_s;
+ } sh_xnni1_fr_pi_intra_flow_credit_u_t;
+-#else
+-typedef union sh_xnni1_fr_pi_intra_flow_credit_u {
+- mmr_t sh_xnni1_fr_pi_intra_flow_credit_regval;
+- struct {
+- mmr_t reserved_5 : 17;
+- mmr_t vc2_cap : 7;
+- mmr_t reserved_4 : 1;
+- mmr_t vc2_dyn : 7;
+- mmr_t reserved_3 : 1;
+- mmr_t vc2_test : 7;
+- mmr_t reserved_2 : 1;
+- mmr_t vc0_cap : 7;
+- mmr_t reserved_1 : 1;
+- mmr_t vc0_dyn : 7;
+- mmr_t reserved_0 : 1;
+- mmr_t vc0_test : 7;
+- } sh_xnni1_fr_pi_intra_flow_credit_s;
+-} sh_xnni1_fr_pi_intra_flow_credit_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI1_FR_MD_INTRA_FLOW_CREDIT" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_fr_md_intra_flow_credit_u {
+ mmr_t sh_xnni1_fr_md_intra_flow_credit_regval;
+ struct {
+@@ -9719,31 +5241,11 @@
+ mmr_t reserved_5 : 17;
+ } sh_xnni1_fr_md_intra_flow_credit_s;
+ } sh_xnni1_fr_md_intra_flow_credit_u_t;
+-#else
+-typedef union sh_xnni1_fr_md_intra_flow_credit_u {
+- mmr_t sh_xnni1_fr_md_intra_flow_credit_regval;
+- struct {
+- mmr_t reserved_5 : 17;
+- mmr_t vc2_cap : 7;
+- mmr_t reserved_4 : 1;
+- mmr_t vc2_dyn : 7;
+- mmr_t reserved_3 : 1;
+- mmr_t vc2_test : 7;
+- mmr_t reserved_2 : 1;
+- mmr_t vc0_cap : 7;
+- mmr_t reserved_1 : 1;
+- mmr_t vc0_dyn : 7;
+- mmr_t reserved_0 : 1;
+- mmr_t vc0_test : 7;
+- } sh_xnni1_fr_md_intra_flow_credit_s;
+-} sh_xnni1_fr_md_intra_flow_credit_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI1_FR_IILB_INTRA_FLOW_CREDIT" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_fr_iilb_intra_flow_credit_u {
+ mmr_t sh_xnni1_fr_iilb_intra_flow_credit_regval;
+ struct {
+@@ -9761,31 +5263,11 @@
+ mmr_t reserved_5 : 17;
+ } sh_xnni1_fr_iilb_intra_flow_credit_s;
+ } sh_xnni1_fr_iilb_intra_flow_credit_u_t;
+-#else
+-typedef union sh_xnni1_fr_iilb_intra_flow_credit_u {
+- mmr_t sh_xnni1_fr_iilb_intra_flow_credit_regval;
+- struct {
+- mmr_t reserved_5 : 17;
+- mmr_t vc2_cap : 7;
+- mmr_t reserved_4 : 1;
+- mmr_t vc2_dyn : 7;
+- mmr_t reserved_3 : 1;
+- mmr_t vc2_test : 7;
+- mmr_t reserved_2 : 1;
+- mmr_t vc0_cap : 7;
+- mmr_t reserved_1 : 1;
+- mmr_t vc0_dyn : 7;
+- mmr_t reserved_0 : 1;
+- mmr_t vc0_test : 7;
+- } sh_xnni1_fr_iilb_intra_flow_credit_s;
+-} sh_xnni1_fr_iilb_intra_flow_credit_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI1_0_INTRANI_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_0_intrani_flow_u {
+ mmr_t sh_xnni1_0_intrani_flow_regval;
+ struct {
+@@ -9795,23 +5277,11 @@
+ mmr_t reserved_1 : 56;
+ } sh_xnni1_0_intrani_flow_s;
+ } sh_xnni1_0_intrani_flow_u_t;
+-#else
+-typedef union sh_xnni1_0_intrani_flow_u {
+- mmr_t sh_xnni1_0_intrani_flow_regval;
+- struct {
+- mmr_t reserved_1 : 56;
+- mmr_t debit_vc0_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t debit_vc0_withhold : 6;
+- } sh_xnni1_0_intrani_flow_s;
+-} sh_xnni1_0_intrani_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI1_1_INTRANI_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_1_intrani_flow_u {
+ mmr_t sh_xnni1_1_intrani_flow_regval;
+ struct {
+@@ -9821,23 +5291,11 @@
+ mmr_t reserved_1 : 56;
+ } sh_xnni1_1_intrani_flow_s;
+ } sh_xnni1_1_intrani_flow_u_t;
+-#else
+-typedef union sh_xnni1_1_intrani_flow_u {
+- mmr_t sh_xnni1_1_intrani_flow_regval;
+- struct {
+- mmr_t reserved_1 : 56;
+- mmr_t debit_vc1_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t debit_vc1_withhold : 6;
+- } sh_xnni1_1_intrani_flow_s;
+-} sh_xnni1_1_intrani_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI1_2_INTRANI_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_2_intrani_flow_u {
+ mmr_t sh_xnni1_2_intrani_flow_regval;
+ struct {
+@@ -9847,23 +5305,11 @@
+ mmr_t reserved_1 : 56;
+ } sh_xnni1_2_intrani_flow_s;
+ } sh_xnni1_2_intrani_flow_u_t;
+-#else
+-typedef union sh_xnni1_2_intrani_flow_u {
+- mmr_t sh_xnni1_2_intrani_flow_regval;
+- struct {
+- mmr_t reserved_1 : 56;
+- mmr_t debit_vc2_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t debit_vc2_withhold : 6;
+- } sh_xnni1_2_intrani_flow_s;
+-} sh_xnni1_2_intrani_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI1_3_INTRANI_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_3_intrani_flow_u {
+ mmr_t sh_xnni1_3_intrani_flow_regval;
+ struct {
+@@ -9873,23 +5319,11 @@
+ mmr_t reserved_1 : 56;
+ } sh_xnni1_3_intrani_flow_s;
+ } sh_xnni1_3_intrani_flow_u_t;
+-#else
+-typedef union sh_xnni1_3_intrani_flow_u {
+- mmr_t sh_xnni1_3_intrani_flow_regval;
+- struct {
+- mmr_t reserved_1 : 56;
+- mmr_t debit_vc3_force_cred : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t debit_vc3_withhold : 6;
+- } sh_xnni1_3_intrani_flow_s;
+-} sh_xnni1_3_intrani_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI1_VCSWITCH_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_vcswitch_flow_u {
+ mmr_t sh_xnni1_vcswitch_flow_regval;
+ struct {
+@@ -9907,31 +5341,11 @@
+ mmr_t reserved_4 : 29;
+ } sh_xnni1_vcswitch_flow_s;
+ } sh_xnni1_vcswitch_flow_u_t;
+-#else
+-typedef union sh_xnni1_vcswitch_flow_u {
+- mmr_t sh_xnni1_vcswitch_flow_regval;
+- struct {
+- mmr_t reserved_4 : 29;
+- mmr_t async_fifoes : 1;
+- mmr_t disable_sync_bypass_out : 1;
+- mmr_t disable_sync_bypass_in : 1;
+- mmr_t reserved_3 : 7;
+- mmr_t iilb_vcfifo_switch : 1;
+- mmr_t reserved_2 : 7;
+- mmr_t md_vcfifo_switch : 1;
+- mmr_t reserved_1 : 7;
+- mmr_t pi_vcfifo_switch : 1;
+- mmr_t reserved_0 : 7;
+- mmr_t ni_vcfifo_dateline_switch : 1;
+- } sh_xnni1_vcswitch_flow_s;
+-} sh_xnni1_vcswitch_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI1_TIMER_REG" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_timer_reg_u {
+ mmr_t sh_xnni1_timer_reg_regval;
+ struct {
+@@ -9941,23 +5355,11 @@
+ mmr_t reserved_1 : 31;
+ } sh_xnni1_timer_reg_s;
+ } sh_xnni1_timer_reg_u_t;
+-#else
+-typedef union sh_xnni1_timer_reg_u {
+- mmr_t sh_xnni1_timer_reg_regval;
+- struct {
+- mmr_t reserved_1 : 31;
+- mmr_t linkcleanup_reg : 1;
+- mmr_t reserved_0 : 8;
+- mmr_t timeout_reg : 24;
+- } sh_xnni1_timer_reg_s;
+-} sh_xnni1_timer_reg_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI1_FIFO02_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_fifo02_flow_u {
+ mmr_t sh_xnni1_fifo02_flow_regval;
+ struct {
+@@ -9975,31 +5377,11 @@
+ mmr_t reserved_5 : 20;
+ } sh_xnni1_fifo02_flow_s;
+ } sh_xnni1_fifo02_flow_u_t;
+-#else
+-typedef union sh_xnni1_fifo02_flow_u {
+- mmr_t sh_xnni1_fifo02_flow_regval;
+- struct {
+- mmr_t reserved_5 : 20;
+- mmr_t count_vc2_cap : 4;
+- mmr_t reserved_4 : 4;
+- mmr_t count_vc2_dyn : 4;
+- mmr_t reserved_3 : 4;
+- mmr_t count_vc2_limit : 4;
+- mmr_t reserved_2 : 4;
+- mmr_t count_vc0_cap : 4;
+- mmr_t reserved_1 : 4;
+- mmr_t count_vc0_dyn : 4;
+- mmr_t reserved_0 : 4;
+- mmr_t count_vc0_limit : 4;
+- } sh_xnni1_fifo02_flow_s;
+-} sh_xnni1_fifo02_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI1_FIFO13_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_fifo13_flow_u {
+ mmr_t sh_xnni1_fifo13_flow_regval;
+ struct {
+@@ -10017,31 +5399,11 @@
+ mmr_t reserved_5 : 20;
+ } sh_xnni1_fifo13_flow_s;
+ } sh_xnni1_fifo13_flow_u_t;
+-#else
+-typedef union sh_xnni1_fifo13_flow_u {
+- mmr_t sh_xnni1_fifo13_flow_regval;
+- struct {
+- mmr_t reserved_5 : 20;
+- mmr_t count_vc3_cap : 4;
+- mmr_t reserved_4 : 4;
+- mmr_t count_vc3_dyn : 4;
+- mmr_t reserved_3 : 4;
+- mmr_t count_vc3_limit : 4;
+- mmr_t reserved_2 : 4;
+- mmr_t count_vc1_cap : 4;
+- mmr_t reserved_1 : 4;
+- mmr_t count_vc1_dyn : 4;
+- mmr_t reserved_0 : 4;
+- mmr_t count_vc1_limit : 4;
+- } sh_xnni1_fifo13_flow_s;
+-} sh_xnni1_fifo13_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI1_NI_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_ni_flow_u {
+ mmr_t sh_xnni1_ni_flow_regval;
+ struct {
+@@ -10063,35 +5425,11 @@
+ mmr_t vc3_cap : 4;
+ } sh_xnni1_ni_flow_s;
+ } sh_xnni1_ni_flow_u_t;
+-#else
+-typedef union sh_xnni1_ni_flow_u {
+- mmr_t sh_xnni1_ni_flow_regval;
+- struct {
+- mmr_t vc3_cap : 4;
+- mmr_t vc3_dyn : 4;
+- mmr_t reserved_3 : 4;
+- mmr_t vc3_limit : 4;
+- mmr_t vc2_cap : 4;
+- mmr_t vc2_dyn : 4;
+- mmr_t reserved_2 : 4;
+- mmr_t vc2_limit : 4;
+- mmr_t vc1_cap : 4;
+- mmr_t vc1_dyn : 4;
+- mmr_t reserved_1 : 4;
+- mmr_t vc1_limit : 4;
+- mmr_t vc0_cap : 4;
+- mmr_t vc0_dyn : 4;
+- mmr_t reserved_0 : 4;
+- mmr_t vc0_limit : 4;
+- } sh_xnni1_ni_flow_s;
+-} sh_xnni1_ni_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI1_DEAD_FLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_dead_flow_u {
+ mmr_t sh_xnni1_dead_flow_regval;
+ struct {
+@@ -10113,35 +5451,11 @@
+ mmr_t vc3_cap : 4;
+ } sh_xnni1_dead_flow_s;
+ } sh_xnni1_dead_flow_u_t;
+-#else
+-typedef union sh_xnni1_dead_flow_u {
+- mmr_t sh_xnni1_dead_flow_regval;
+- struct {
+- mmr_t vc3_cap : 4;
+- mmr_t vc3_dyn : 4;
+- mmr_t reserved_3 : 4;
+- mmr_t vc3_limit : 4;
+- mmr_t vc2_cap : 4;
+- mmr_t vc2_dyn : 4;
+- mmr_t reserved_2 : 4;
+- mmr_t vc2_limit : 4;
+- mmr_t vc1_cap : 4;
+- mmr_t vc1_dyn : 4;
+- mmr_t reserved_1 : 4;
+- mmr_t vc1_limit : 4;
+- mmr_t vc0_cap : 4;
+- mmr_t vc0_dyn : 4;
+- mmr_t reserved_0 : 4;
+- mmr_t vc0_limit : 4;
+- } sh_xnni1_dead_flow_s;
+-} sh_xnni1_dead_flow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNNI1_INJECT_AGE" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_inject_age_u {
+ mmr_t sh_xnni1_inject_age_regval;
+ struct {
+@@ -10150,23 +5464,12 @@
+ mmr_t reserved_0 : 48;
+ } sh_xnni1_inject_age_s;
+ } sh_xnni1_inject_age_u_t;
+-#else
+-typedef union sh_xnni1_inject_age_u {
+- mmr_t sh_xnni1_inject_age_regval;
+- struct {
+- mmr_t reserved_0 : 48;
+- mmr_t reply_inject : 8;
+- mmr_t request_inject : 8;
+- } sh_xnni1_inject_age_s;
+-} sh_xnni1_inject_age_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_DEBUG_SEL" */
+ /* XN Debug Port Select */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_debug_sel_u {
+ mmr_t sh_xn_debug_sel_regval;
+ struct {
+@@ -10204,52 +5507,12 @@
+ mmr_t trigger_enable : 1;
+ } sh_xn_debug_sel_s;
+ } sh_xn_debug_sel_u_t;
+-#else
+-typedef union sh_xn_debug_sel_u {
+- mmr_t sh_xn_debug_sel_regval;
+- struct {
+- mmr_t trigger_enable : 1;
+- mmr_t nibble7_nibble_sel : 3;
+- mmr_t reserved_14 : 1;
+- mmr_t nibble7_rlm_sel : 3;
+- mmr_t reserved_13 : 1;
+- mmr_t nibble6_nibble_sel : 3;
+- mmr_t reserved_12 : 1;
+- mmr_t nibble6_rlm_sel : 3;
+- mmr_t reserved_11 : 1;
+- mmr_t nibble5_nibble_sel : 3;
+- mmr_t reserved_10 : 1;
+- mmr_t nibble5_rlm_sel : 3;
+- mmr_t reserved_9 : 1;
+- mmr_t nibble4_nibble_sel : 3;
+- mmr_t reserved_8 : 1;
+- mmr_t nibble4_rlm_sel : 3;
+- mmr_t reserved_7 : 1;
+- mmr_t nibble3_nibble_sel : 3;
+- mmr_t reserved_6 : 1;
+- mmr_t nibble3_rlm_sel : 3;
+- mmr_t reserved_5 : 1;
+- mmr_t nibble2_nibble_sel : 3;
+- mmr_t reserved_4 : 1;
+- mmr_t nibble2_rlm_sel : 3;
+- mmr_t reserved_3 : 1;
+- mmr_t nibble1_nibble_sel : 3;
+- mmr_t reserved_2 : 1;
+- mmr_t nibble1_rlm_sel : 3;
+- mmr_t reserved_1 : 1;
+- mmr_t nibble0_nibble_sel : 3;
+- mmr_t reserved_0 : 1;
+- mmr_t nibble0_rlm_sel : 3;
+- } sh_xn_debug_sel_s;
+-} sh_xn_debug_sel_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_DEBUG_TRIG_SEL" */
+ /* XN Debug trigger Select */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_debug_trig_sel_u {
+ mmr_t sh_xn_debug_trig_sel_regval;
+ struct {
+@@ -10287,52 +5550,12 @@
+ mmr_t reserved_15 : 1;
+ } sh_xn_debug_trig_sel_s;
+ } sh_xn_debug_trig_sel_u_t;
+-#else
+-typedef union sh_xn_debug_trig_sel_u {
+- mmr_t sh_xn_debug_trig_sel_regval;
+- struct {
+- mmr_t reserved_15 : 1;
+- mmr_t trigger7_nibble_sel : 3;
+- mmr_t reserved_14 : 1;
+- mmr_t trigger7_rlm_sel : 3;
+- mmr_t reserved_13 : 1;
+- mmr_t trigger6_nibble_sel : 3;
+- mmr_t reserved_12 : 1;
+- mmr_t trigger6_rlm_sel : 3;
+- mmr_t reserved_11 : 1;
+- mmr_t trigger5_nibble_sel : 3;
+- mmr_t reserved_10 : 1;
+- mmr_t trigger5_rlm_sel : 3;
+- mmr_t reserved_9 : 1;
+- mmr_t trigger4_nibble_sel : 3;
+- mmr_t reserved_8 : 1;
+- mmr_t trigger4_rlm_sel : 3;
+- mmr_t reserved_7 : 1;
+- mmr_t trigger3_nibble_sel : 3;
+- mmr_t reserved_6 : 1;
+- mmr_t trigger3_rlm_sel : 3;
+- mmr_t reserved_5 : 1;
+- mmr_t trigger2_nibble_sel : 3;
+- mmr_t reserved_4 : 1;
+- mmr_t trigger2_rlm_sel : 3;
+- mmr_t reserved_3 : 1;
+- mmr_t trigger1_nibble_sel : 3;
+- mmr_t reserved_2 : 1;
+- mmr_t trigger1_rlm_sel : 3;
+- mmr_t reserved_1 : 1;
+- mmr_t trigger0_nibble_sel : 3;
+- mmr_t reserved_0 : 1;
+- mmr_t trigger0_rlm_sel : 3;
+- } sh_xn_debug_trig_sel_s;
+-} sh_xn_debug_trig_sel_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_TRIGGER_COMPARE" */
+ /* XN Debug Compare */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_trigger_compare_u {
+ mmr_t sh_xn_trigger_compare_regval;
+ struct {
+@@ -10340,22 +5563,12 @@
+ mmr_t reserved_0 : 32;
+ } sh_xn_trigger_compare_s;
+ } sh_xn_trigger_compare_u_t;
+-#else
+-typedef union sh_xn_trigger_compare_u {
+- mmr_t sh_xn_trigger_compare_regval;
+- struct {
+- mmr_t reserved_0 : 32;
+- mmr_t mask : 32;
+- } sh_xn_trigger_compare_s;
+-} sh_xn_trigger_compare_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_TRIGGER_DATA" */
+ /* XN Debug Compare Data */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_trigger_data_u {
+ mmr_t sh_xn_trigger_data_regval;
+ struct {
+@@ -10363,22 +5576,12 @@
+ mmr_t reserved_0 : 32;
+ } sh_xn_trigger_data_s;
+ } sh_xn_trigger_data_u_t;
+-#else
+-typedef union sh_xn_trigger_data_u {
+- mmr_t sh_xn_trigger_data_regval;
+- struct {
+- mmr_t reserved_0 : 32;
+- mmr_t compare_pattern : 32;
+- } sh_xn_trigger_data_s;
+-} sh_xn_trigger_data_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_IILB_DEBUG_SEL" */
+ /* XN IILB Debug Port Select */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_iilb_debug_sel_u {
+ mmr_t sh_xn_iilb_debug_sel_regval;
+ struct {
+@@ -10416,52 +5619,12 @@
+ mmr_t reserved_15 : 1;
+ } sh_xn_iilb_debug_sel_s;
+ } sh_xn_iilb_debug_sel_u_t;
+-#else
+-typedef union sh_xn_iilb_debug_sel_u {
+- mmr_t sh_xn_iilb_debug_sel_regval;
+- struct {
+- mmr_t reserved_15 : 1;
+- mmr_t nibble7_nibble_sel : 3;
+- mmr_t reserved_14 : 1;
+- mmr_t nibble7_input_sel : 3;
+- mmr_t reserved_13 : 1;
+- mmr_t nibble6_nibble_sel : 3;
+- mmr_t reserved_12 : 1;
+- mmr_t nibble6_input_sel : 3;
+- mmr_t reserved_11 : 1;
+- mmr_t nibble5_nibble_sel : 3;
+- mmr_t reserved_10 : 1;
+- mmr_t nibble5_input_sel : 3;
+- mmr_t reserved_9 : 1;
+- mmr_t nibble4_nibble_sel : 3;
+- mmr_t reserved_8 : 1;
+- mmr_t nibble4_input_sel : 3;
+- mmr_t reserved_7 : 1;
+- mmr_t nibble3_nibble_sel : 3;
+- mmr_t reserved_6 : 1;
+- mmr_t nibble3_input_sel : 3;
+- mmr_t reserved_5 : 1;
+- mmr_t nibble2_nibble_sel : 3;
+- mmr_t reserved_4 : 1;
+- mmr_t nibble2_input_sel : 3;
+- mmr_t reserved_3 : 1;
+- mmr_t nibble1_nibble_sel : 3;
+- mmr_t reserved_2 : 1;
+- mmr_t nibble1_input_sel : 3;
+- mmr_t reserved_1 : 1;
+- mmr_t nibble0_nibble_sel : 3;
+- mmr_t reserved_0 : 1;
+- mmr_t nibble0_input_sel : 3;
+- } sh_xn_iilb_debug_sel_s;
+-} sh_xn_iilb_debug_sel_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_PI_DEBUG_SEL" */
+ /* XN PI Debug Port Select */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_pi_debug_sel_u {
+ mmr_t sh_xn_pi_debug_sel_regval;
+ struct {
+@@ -10499,52 +5662,12 @@
+ mmr_t reserved_15 : 1;
+ } sh_xn_pi_debug_sel_s;
+ } sh_xn_pi_debug_sel_u_t;
+-#else
+-typedef union sh_xn_pi_debug_sel_u {
+- mmr_t sh_xn_pi_debug_sel_regval;
+- struct {
+- mmr_t reserved_15 : 1;
+- mmr_t nibble7_nibble_sel : 3;
+- mmr_t reserved_14 : 1;
+- mmr_t nibble7_input_sel : 3;
+- mmr_t reserved_13 : 1;
+- mmr_t nibble6_nibble_sel : 3;
+- mmr_t reserved_12 : 1;
+- mmr_t nibble6_input_sel : 3;
+- mmr_t reserved_11 : 1;
+- mmr_t nibble5_nibble_sel : 3;
+- mmr_t reserved_10 : 1;
+- mmr_t nibble5_input_sel : 3;
+- mmr_t reserved_9 : 1;
+- mmr_t nibble4_nibble_sel : 3;
+- mmr_t reserved_8 : 1;
+- mmr_t nibble4_input_sel : 3;
+- mmr_t reserved_7 : 1;
+- mmr_t nibble3_nibble_sel : 3;
+- mmr_t reserved_6 : 1;
+- mmr_t nibble3_input_sel : 3;
+- mmr_t reserved_5 : 1;
+- mmr_t nibble2_nibble_sel : 3;
+- mmr_t reserved_4 : 1;
+- mmr_t nibble2_input_sel : 3;
+- mmr_t reserved_3 : 1;
+- mmr_t nibble1_nibble_sel : 3;
+- mmr_t reserved_2 : 1;
+- mmr_t nibble1_input_sel : 3;
+- mmr_t reserved_1 : 1;
+- mmr_t nibble0_nibble_sel : 3;
+- mmr_t reserved_0 : 1;
+- mmr_t nibble0_input_sel : 3;
+- } sh_xn_pi_debug_sel_s;
+-} sh_xn_pi_debug_sel_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_MD_DEBUG_SEL" */
+ /* XN MD Debug Port Select */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_md_debug_sel_u {
+ mmr_t sh_xn_md_debug_sel_regval;
+ struct {
+@@ -10582,54 +5705,14 @@
+ mmr_t reserved_15 : 1;
+ } sh_xn_md_debug_sel_s;
+ } sh_xn_md_debug_sel_u_t;
+-#else
+-typedef union sh_xn_md_debug_sel_u {
+- mmr_t sh_xn_md_debug_sel_regval;
+- struct {
+- mmr_t reserved_15 : 1;
+- mmr_t nibble7_nibble_sel : 3;
+- mmr_t reserved_14 : 1;
+- mmr_t nibble7_input_sel : 3;
+- mmr_t reserved_13 : 1;
+- mmr_t nibble6_nibble_sel : 3;
+- mmr_t reserved_12 : 1;
+- mmr_t nibble6_input_sel : 3;
+- mmr_t reserved_11 : 1;
+- mmr_t nibble5_nibble_sel : 3;
+- mmr_t reserved_10 : 1;
+- mmr_t nibble5_input_sel : 3;
+- mmr_t reserved_9 : 1;
+- mmr_t nibble4_nibble_sel : 3;
+- mmr_t reserved_8 : 1;
+- mmr_t nibble4_input_sel : 3;
+- mmr_t reserved_7 : 1;
+- mmr_t nibble3_nibble_sel : 3;
+- mmr_t reserved_6 : 1;
+- mmr_t nibble3_input_sel : 3;
+- mmr_t reserved_5 : 1;
+- mmr_t nibble2_nibble_sel : 3;
+- mmr_t reserved_4 : 1;
+- mmr_t nibble2_input_sel : 3;
+- mmr_t reserved_3 : 1;
+- mmr_t nibble1_nibble_sel : 3;
+- mmr_t reserved_2 : 1;
+- mmr_t nibble1_input_sel : 3;
+- mmr_t reserved_1 : 1;
+- mmr_t nibble0_nibble_sel : 3;
+- mmr_t reserved_0 : 1;
+- mmr_t nibble0_input_sel : 3;
+- } sh_xn_md_debug_sel_s;
+-} sh_xn_md_debug_sel_u_t;
+-#endif
+-
+-/* ==================================================================== */
+-/* Register "SH_XN_NI0_DEBUG_SEL" */
+-/* XN NI0 Debug Port Select */
+-/* ==================================================================== */
+-
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni0_debug_sel_u {
+- mmr_t sh_xn_ni0_debug_sel_regval;
++
++/* ==================================================================== */
++/* Register "SH_XN_NI0_DEBUG_SEL" */
++/* XN NI0 Debug Port Select */
++/* ==================================================================== */
++
++typedef union sh_xn_ni0_debug_sel_u {
++ mmr_t sh_xn_ni0_debug_sel_regval;
+ struct {
+ mmr_t nibble0_input_sel : 3;
+ mmr_t reserved_0 : 1;
+@@ -10665,52 +5748,12 @@
+ mmr_t reserved_15 : 1;
+ } sh_xn_ni0_debug_sel_s;
+ } sh_xn_ni0_debug_sel_u_t;
+-#else
+-typedef union sh_xn_ni0_debug_sel_u {
+- mmr_t sh_xn_ni0_debug_sel_regval;
+- struct {
+- mmr_t reserved_15 : 1;
+- mmr_t nibble7_nibble_sel : 3;
+- mmr_t reserved_14 : 1;
+- mmr_t nibble7_input_sel : 3;
+- mmr_t reserved_13 : 1;
+- mmr_t nibble6_nibble_sel : 3;
+- mmr_t reserved_12 : 1;
+- mmr_t nibble6_input_sel : 3;
+- mmr_t reserved_11 : 1;
+- mmr_t nibble5_nibble_sel : 3;
+- mmr_t reserved_10 : 1;
+- mmr_t nibble5_input_sel : 3;
+- mmr_t reserved_9 : 1;
+- mmr_t nibble4_nibble_sel : 3;
+- mmr_t reserved_8 : 1;
+- mmr_t nibble4_input_sel : 3;
+- mmr_t reserved_7 : 1;
+- mmr_t nibble3_nibble_sel : 3;
+- mmr_t reserved_6 : 1;
+- mmr_t nibble3_input_sel : 3;
+- mmr_t reserved_5 : 1;
+- mmr_t nibble2_nibble_sel : 3;
+- mmr_t reserved_4 : 1;
+- mmr_t nibble2_input_sel : 3;
+- mmr_t reserved_3 : 1;
+- mmr_t nibble1_nibble_sel : 3;
+- mmr_t reserved_2 : 1;
+- mmr_t nibble1_input_sel : 3;
+- mmr_t reserved_1 : 1;
+- mmr_t nibble0_nibble_sel : 3;
+- mmr_t reserved_0 : 1;
+- mmr_t nibble0_input_sel : 3;
+- } sh_xn_ni0_debug_sel_s;
+-} sh_xn_ni0_debug_sel_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI1_DEBUG_SEL" */
+ /* XN NI1 Debug Port Select */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_ni1_debug_sel_u {
+ mmr_t sh_xn_ni1_debug_sel_regval;
+ struct {
+@@ -10748,829 +5791,456 @@
+ mmr_t reserved_15 : 1;
+ } sh_xn_ni1_debug_sel_s;
+ } sh_xn_ni1_debug_sel_u_t;
+-#else
+-typedef union sh_xn_ni1_debug_sel_u {
+- mmr_t sh_xn_ni1_debug_sel_regval;
+- struct {
+- mmr_t reserved_15 : 1;
+- mmr_t nibble7_nibble_sel : 3;
+- mmr_t reserved_14 : 1;
+- mmr_t nibble7_input_sel : 3;
+- mmr_t reserved_13 : 1;
+- mmr_t nibble6_nibble_sel : 3;
+- mmr_t reserved_12 : 1;
+- mmr_t nibble6_input_sel : 3;
+- mmr_t reserved_11 : 1;
+- mmr_t nibble5_nibble_sel : 3;
+- mmr_t reserved_10 : 1;
+- mmr_t nibble5_input_sel : 3;
+- mmr_t reserved_9 : 1;
+- mmr_t nibble4_nibble_sel : 3;
+- mmr_t reserved_8 : 1;
+- mmr_t nibble4_input_sel : 3;
+- mmr_t reserved_7 : 1;
+- mmr_t nibble3_nibble_sel : 3;
+- mmr_t reserved_6 : 1;
+- mmr_t nibble3_input_sel : 3;
+- mmr_t reserved_5 : 1;
+- mmr_t nibble2_nibble_sel : 3;
+- mmr_t reserved_4 : 1;
+- mmr_t nibble2_input_sel : 3;
+- mmr_t reserved_3 : 1;
+- mmr_t nibble1_nibble_sel : 3;
+- mmr_t reserved_2 : 1;
+- mmr_t nibble1_input_sel : 3;
+- mmr_t reserved_1 : 1;
+- mmr_t nibble0_nibble_sel : 3;
+- mmr_t reserved_0 : 1;
+- mmr_t nibble0_input_sel : 3;
+- } sh_xn_ni1_debug_sel_s;
+-} sh_xn_ni1_debug_sel_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_IILB_LB_CMP_EXP_DATA0" */
+ /* IILB compare LB input expected data0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_lb_cmp_exp_data0_u {
+- mmr_t sh_xn_iilb_lb_cmp_exp_data0_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_iilb_lb_cmp_exp_data0_s;
+-} sh_xn_iilb_lb_cmp_exp_data0_u_t;
+-#else
+ typedef union sh_xn_iilb_lb_cmp_exp_data0_u {
+ mmr_t sh_xn_iilb_lb_cmp_exp_data0_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_iilb_lb_cmp_exp_data0_s;
+ } sh_xn_iilb_lb_cmp_exp_data0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_IILB_LB_CMP_EXP_DATA1" */
+ /* IILB compare LB input expected data1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_lb_cmp_exp_data1_u {
+- mmr_t sh_xn_iilb_lb_cmp_exp_data1_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_iilb_lb_cmp_exp_data1_s;
+-} sh_xn_iilb_lb_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_iilb_lb_cmp_exp_data1_u {
+ mmr_t sh_xn_iilb_lb_cmp_exp_data1_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_iilb_lb_cmp_exp_data1_s;
+ } sh_xn_iilb_lb_cmp_exp_data1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_IILB_LB_CMP_ENABLE0" */
+ /* IILB compare LB input enable0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_iilb_lb_cmp_enable0_u {
+ mmr_t sh_xn_iilb_lb_cmp_enable0_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_iilb_lb_cmp_enable0_s;
+ } sh_xn_iilb_lb_cmp_enable0_u_t;
+-#else
+-typedef union sh_xn_iilb_lb_cmp_enable0_u {
+- mmr_t sh_xn_iilb_lb_cmp_enable0_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_iilb_lb_cmp_enable0_s;
+-} sh_xn_iilb_lb_cmp_enable0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_IILB_LB_CMP_ENABLE1" */
+ /* IILB compare LB input enable1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_lb_cmp_enable1_u {
+- mmr_t sh_xn_iilb_lb_cmp_enable1_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_iilb_lb_cmp_enable1_s;
+-} sh_xn_iilb_lb_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_iilb_lb_cmp_enable1_u {
+ mmr_t sh_xn_iilb_lb_cmp_enable1_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_iilb_lb_cmp_enable1_s;
+ } sh_xn_iilb_lb_cmp_enable1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_IILB_II_CMP_EXP_DATA0" */
+ /* IILB compare II input expected data0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_ii_cmp_exp_data0_u {
+- mmr_t sh_xn_iilb_ii_cmp_exp_data0_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_iilb_ii_cmp_exp_data0_s;
+-} sh_xn_iilb_ii_cmp_exp_data0_u_t;
+-#else
+ typedef union sh_xn_iilb_ii_cmp_exp_data0_u {
+ mmr_t sh_xn_iilb_ii_cmp_exp_data0_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_iilb_ii_cmp_exp_data0_s;
+ } sh_xn_iilb_ii_cmp_exp_data0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_IILB_II_CMP_EXP_DATA1" */
+ /* IILB compare II input expected data1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_ii_cmp_exp_data1_u {
+- mmr_t sh_xn_iilb_ii_cmp_exp_data1_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_iilb_ii_cmp_exp_data1_s;
+-} sh_xn_iilb_ii_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_iilb_ii_cmp_exp_data1_u {
+ mmr_t sh_xn_iilb_ii_cmp_exp_data1_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_iilb_ii_cmp_exp_data1_s;
+ } sh_xn_iilb_ii_cmp_exp_data1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_IILB_II_CMP_ENABLE0" */
+ /* IILB compare II input enable0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_iilb_ii_cmp_enable0_u {
+ mmr_t sh_xn_iilb_ii_cmp_enable0_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_iilb_ii_cmp_enable0_s;
+ } sh_xn_iilb_ii_cmp_enable0_u_t;
+-#else
+-typedef union sh_xn_iilb_ii_cmp_enable0_u {
+- mmr_t sh_xn_iilb_ii_cmp_enable0_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_iilb_ii_cmp_enable0_s;
+-} sh_xn_iilb_ii_cmp_enable0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_IILB_II_CMP_ENABLE1" */
+ /* IILB compare II input enable1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_ii_cmp_enable1_u {
+- mmr_t sh_xn_iilb_ii_cmp_enable1_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_iilb_ii_cmp_enable1_s;
+-} sh_xn_iilb_ii_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_iilb_ii_cmp_enable1_u {
+ mmr_t sh_xn_iilb_ii_cmp_enable1_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_iilb_ii_cmp_enable1_s;
+ } sh_xn_iilb_ii_cmp_enable1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_IILB_MD_CMP_EXP_DATA0" */
+ /* IILB compare MD input expected data0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_md_cmp_exp_data0_u {
+- mmr_t sh_xn_iilb_md_cmp_exp_data0_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_iilb_md_cmp_exp_data0_s;
+-} sh_xn_iilb_md_cmp_exp_data0_u_t;
+-#else
+ typedef union sh_xn_iilb_md_cmp_exp_data0_u {
+ mmr_t sh_xn_iilb_md_cmp_exp_data0_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_iilb_md_cmp_exp_data0_s;
+ } sh_xn_iilb_md_cmp_exp_data0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_IILB_MD_CMP_EXP_DATA1" */
+ /* IILB compare MD input expected data1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_md_cmp_exp_data1_u {
+- mmr_t sh_xn_iilb_md_cmp_exp_data1_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_iilb_md_cmp_exp_data1_s;
+-} sh_xn_iilb_md_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_iilb_md_cmp_exp_data1_u {
+ mmr_t sh_xn_iilb_md_cmp_exp_data1_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_iilb_md_cmp_exp_data1_s;
+ } sh_xn_iilb_md_cmp_exp_data1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_IILB_MD_CMP_ENABLE0" */
+ /* IILB compare MD input enable0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_iilb_md_cmp_enable0_u {
+ mmr_t sh_xn_iilb_md_cmp_enable0_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_iilb_md_cmp_enable0_s;
+ } sh_xn_iilb_md_cmp_enable0_u_t;
+-#else
+-typedef union sh_xn_iilb_md_cmp_enable0_u {
+- mmr_t sh_xn_iilb_md_cmp_enable0_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_iilb_md_cmp_enable0_s;
+-} sh_xn_iilb_md_cmp_enable0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_IILB_MD_CMP_ENABLE1" */
+ /* IILB compare MD input enable1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_md_cmp_enable1_u {
+- mmr_t sh_xn_iilb_md_cmp_enable1_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_iilb_md_cmp_enable1_s;
+-} sh_xn_iilb_md_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_iilb_md_cmp_enable1_u {
+ mmr_t sh_xn_iilb_md_cmp_enable1_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_iilb_md_cmp_enable1_s;
+ } sh_xn_iilb_md_cmp_enable1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_IILB_PI_CMP_EXP_DATA0" */
+ /* IILB compare PI input expected data0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_pi_cmp_exp_data0_u {
+- mmr_t sh_xn_iilb_pi_cmp_exp_data0_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_iilb_pi_cmp_exp_data0_s;
+-} sh_xn_iilb_pi_cmp_exp_data0_u_t;
+-#else
+ typedef union sh_xn_iilb_pi_cmp_exp_data0_u {
+ mmr_t sh_xn_iilb_pi_cmp_exp_data0_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_iilb_pi_cmp_exp_data0_s;
+ } sh_xn_iilb_pi_cmp_exp_data0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_IILB_PI_CMP_EXP_DATA1" */
+ /* IILB compare PI input expected data1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_pi_cmp_exp_data1_u {
+- mmr_t sh_xn_iilb_pi_cmp_exp_data1_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_iilb_pi_cmp_exp_data1_s;
+-} sh_xn_iilb_pi_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_iilb_pi_cmp_exp_data1_u {
+ mmr_t sh_xn_iilb_pi_cmp_exp_data1_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_iilb_pi_cmp_exp_data1_s;
+ } sh_xn_iilb_pi_cmp_exp_data1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_IILB_PI_CMP_ENABLE0" */
+ /* IILB compare PI input enable0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_iilb_pi_cmp_enable0_u {
+ mmr_t sh_xn_iilb_pi_cmp_enable0_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_iilb_pi_cmp_enable0_s;
+ } sh_xn_iilb_pi_cmp_enable0_u_t;
+-#else
+-typedef union sh_xn_iilb_pi_cmp_enable0_u {
+- mmr_t sh_xn_iilb_pi_cmp_enable0_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_iilb_pi_cmp_enable0_s;
+-} sh_xn_iilb_pi_cmp_enable0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_IILB_PI_CMP_ENABLE1" */
+ /* IILB compare PI input enable1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_pi_cmp_enable1_u {
+- mmr_t sh_xn_iilb_pi_cmp_enable1_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_iilb_pi_cmp_enable1_s;
+-} sh_xn_iilb_pi_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_iilb_pi_cmp_enable1_u {
+ mmr_t sh_xn_iilb_pi_cmp_enable1_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_iilb_pi_cmp_enable1_s;
+ } sh_xn_iilb_pi_cmp_enable1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_IILB_NI0_CMP_EXP_DATA0" */
+ /* IILB compare NI0 input expected data0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_ni0_cmp_exp_data0_u {
+- mmr_t sh_xn_iilb_ni0_cmp_exp_data0_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_iilb_ni0_cmp_exp_data0_s;
+-} sh_xn_iilb_ni0_cmp_exp_data0_u_t;
+-#else
+ typedef union sh_xn_iilb_ni0_cmp_exp_data0_u {
+ mmr_t sh_xn_iilb_ni0_cmp_exp_data0_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_iilb_ni0_cmp_exp_data0_s;
+ } sh_xn_iilb_ni0_cmp_exp_data0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_IILB_NI0_CMP_EXP_DATA1" */
+ /* IILB compare NI0 input expected data1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_ni0_cmp_exp_data1_u {
+- mmr_t sh_xn_iilb_ni0_cmp_exp_data1_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_iilb_ni0_cmp_exp_data1_s;
+-} sh_xn_iilb_ni0_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_iilb_ni0_cmp_exp_data1_u {
+ mmr_t sh_xn_iilb_ni0_cmp_exp_data1_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_iilb_ni0_cmp_exp_data1_s;
+ } sh_xn_iilb_ni0_cmp_exp_data1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_IILB_NI0_CMP_ENABLE0" */
+ /* IILB compare NI0 input enable0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_iilb_ni0_cmp_enable0_u {
+ mmr_t sh_xn_iilb_ni0_cmp_enable0_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_iilb_ni0_cmp_enable0_s;
+ } sh_xn_iilb_ni0_cmp_enable0_u_t;
+-#else
+-typedef union sh_xn_iilb_ni0_cmp_enable0_u {
+- mmr_t sh_xn_iilb_ni0_cmp_enable0_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_iilb_ni0_cmp_enable0_s;
+-} sh_xn_iilb_ni0_cmp_enable0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_IILB_NI0_CMP_ENABLE1" */
+ /* IILB compare NI0 input enable1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_ni0_cmp_enable1_u {
+- mmr_t sh_xn_iilb_ni0_cmp_enable1_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_iilb_ni0_cmp_enable1_s;
+-} sh_xn_iilb_ni0_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_iilb_ni0_cmp_enable1_u {
+ mmr_t sh_xn_iilb_ni0_cmp_enable1_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_iilb_ni0_cmp_enable1_s;
+ } sh_xn_iilb_ni0_cmp_enable1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_IILB_NI1_CMP_EXP_DATA0" */
+ /* IILB compare NI1 input expected data0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_ni1_cmp_exp_data0_u {
+- mmr_t sh_xn_iilb_ni1_cmp_exp_data0_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_iilb_ni1_cmp_exp_data0_s;
+-} sh_xn_iilb_ni1_cmp_exp_data0_u_t;
+-#else
+ typedef union sh_xn_iilb_ni1_cmp_exp_data0_u {
+ mmr_t sh_xn_iilb_ni1_cmp_exp_data0_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_iilb_ni1_cmp_exp_data0_s;
+ } sh_xn_iilb_ni1_cmp_exp_data0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_IILB_NI1_CMP_EXP_DATA1" */
+ /* IILB compare NI1 input expected data1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_ni1_cmp_exp_data1_u {
+- mmr_t sh_xn_iilb_ni1_cmp_exp_data1_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_iilb_ni1_cmp_exp_data1_s;
+-} sh_xn_iilb_ni1_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_iilb_ni1_cmp_exp_data1_u {
+ mmr_t sh_xn_iilb_ni1_cmp_exp_data1_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_iilb_ni1_cmp_exp_data1_s;
+ } sh_xn_iilb_ni1_cmp_exp_data1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_IILB_NI1_CMP_ENABLE0" */
+ /* IILB compare NI1 input enable0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_iilb_ni1_cmp_enable0_u {
+ mmr_t sh_xn_iilb_ni1_cmp_enable0_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_iilb_ni1_cmp_enable0_s;
+ } sh_xn_iilb_ni1_cmp_enable0_u_t;
+-#else
+-typedef union sh_xn_iilb_ni1_cmp_enable0_u {
+- mmr_t sh_xn_iilb_ni1_cmp_enable0_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_iilb_ni1_cmp_enable0_s;
+-} sh_xn_iilb_ni1_cmp_enable0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_IILB_NI1_CMP_ENABLE1" */
+ /* IILB compare NI1 input enable1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_ni1_cmp_enable1_u {
+- mmr_t sh_xn_iilb_ni1_cmp_enable1_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_iilb_ni1_cmp_enable1_s;
+-} sh_xn_iilb_ni1_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_iilb_ni1_cmp_enable1_u {
+ mmr_t sh_xn_iilb_ni1_cmp_enable1_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_iilb_ni1_cmp_enable1_s;
+ } sh_xn_iilb_ni1_cmp_enable1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_MD_IILB_CMP_EXP_DATA0" */
+ /* MD compare IILB input expected data0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_md_iilb_cmp_exp_data0_u {
+- mmr_t sh_xn_md_iilb_cmp_exp_data0_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_md_iilb_cmp_exp_data0_s;
+-} sh_xn_md_iilb_cmp_exp_data0_u_t;
+-#else
+ typedef union sh_xn_md_iilb_cmp_exp_data0_u {
+ mmr_t sh_xn_md_iilb_cmp_exp_data0_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_md_iilb_cmp_exp_data0_s;
+ } sh_xn_md_iilb_cmp_exp_data0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_MD_IILB_CMP_EXP_DATA1" */
+ /* MD compare IILB input expected data1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_md_iilb_cmp_exp_data1_u {
+- mmr_t sh_xn_md_iilb_cmp_exp_data1_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_md_iilb_cmp_exp_data1_s;
+-} sh_xn_md_iilb_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_md_iilb_cmp_exp_data1_u {
+ mmr_t sh_xn_md_iilb_cmp_exp_data1_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_md_iilb_cmp_exp_data1_s;
+ } sh_xn_md_iilb_cmp_exp_data1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_MD_IILB_CMP_ENABLE0" */
+ /* MD compare IILB input enable0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_md_iilb_cmp_enable0_u {
+ mmr_t sh_xn_md_iilb_cmp_enable0_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_md_iilb_cmp_enable0_s;
+ } sh_xn_md_iilb_cmp_enable0_u_t;
+-#else
+-typedef union sh_xn_md_iilb_cmp_enable0_u {
+- mmr_t sh_xn_md_iilb_cmp_enable0_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_md_iilb_cmp_enable0_s;
+-} sh_xn_md_iilb_cmp_enable0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_MD_IILB_CMP_ENABLE1" */
+ /* MD compare IILB input enable1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_md_iilb_cmp_enable1_u {
+- mmr_t sh_xn_md_iilb_cmp_enable1_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_md_iilb_cmp_enable1_s;
+-} sh_xn_md_iilb_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_md_iilb_cmp_enable1_u {
+ mmr_t sh_xn_md_iilb_cmp_enable1_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_md_iilb_cmp_enable1_s;
+ } sh_xn_md_iilb_cmp_enable1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_MD_NI0_CMP_EXP_DATA0" */
+ /* MD compare NI0 input expected data0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_md_ni0_cmp_exp_data0_u {
+- mmr_t sh_xn_md_ni0_cmp_exp_data0_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_md_ni0_cmp_exp_data0_s;
+-} sh_xn_md_ni0_cmp_exp_data0_u_t;
+-#else
+ typedef union sh_xn_md_ni0_cmp_exp_data0_u {
+ mmr_t sh_xn_md_ni0_cmp_exp_data0_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_md_ni0_cmp_exp_data0_s;
+ } sh_xn_md_ni0_cmp_exp_data0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_MD_NI0_CMP_EXP_DATA1" */
+ /* MD compare NI0 input expected data1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_md_ni0_cmp_exp_data1_u {
+- mmr_t sh_xn_md_ni0_cmp_exp_data1_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_md_ni0_cmp_exp_data1_s;
+-} sh_xn_md_ni0_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_md_ni0_cmp_exp_data1_u {
+ mmr_t sh_xn_md_ni0_cmp_exp_data1_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_md_ni0_cmp_exp_data1_s;
+ } sh_xn_md_ni0_cmp_exp_data1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_MD_NI0_CMP_ENABLE0" */
+ /* MD compare NI0 input enable0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_md_ni0_cmp_enable0_u {
+ mmr_t sh_xn_md_ni0_cmp_enable0_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_md_ni0_cmp_enable0_s;
+ } sh_xn_md_ni0_cmp_enable0_u_t;
+-#else
+-typedef union sh_xn_md_ni0_cmp_enable0_u {
+- mmr_t sh_xn_md_ni0_cmp_enable0_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_md_ni0_cmp_enable0_s;
+-} sh_xn_md_ni0_cmp_enable0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_MD_NI0_CMP_ENABLE1" */
+ /* MD compare NI0 input enable1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_md_ni0_cmp_enable1_u {
+- mmr_t sh_xn_md_ni0_cmp_enable1_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_md_ni0_cmp_enable1_s;
+-} sh_xn_md_ni0_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_md_ni0_cmp_enable1_u {
+ mmr_t sh_xn_md_ni0_cmp_enable1_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_md_ni0_cmp_enable1_s;
+ } sh_xn_md_ni0_cmp_enable1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_MD_NI1_CMP_EXP_DATA0" */
+ /* MD compare NI1 input expected data0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_md_ni1_cmp_exp_data0_u {
+- mmr_t sh_xn_md_ni1_cmp_exp_data0_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_md_ni1_cmp_exp_data0_s;
+-} sh_xn_md_ni1_cmp_exp_data0_u_t;
+-#else
+ typedef union sh_xn_md_ni1_cmp_exp_data0_u {
+ mmr_t sh_xn_md_ni1_cmp_exp_data0_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_md_ni1_cmp_exp_data0_s;
+ } sh_xn_md_ni1_cmp_exp_data0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_MD_NI1_CMP_EXP_DATA1" */
+ /* MD compare NI1 input expected data1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_md_ni1_cmp_exp_data1_u {
+- mmr_t sh_xn_md_ni1_cmp_exp_data1_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_md_ni1_cmp_exp_data1_s;
+-} sh_xn_md_ni1_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_md_ni1_cmp_exp_data1_u {
+ mmr_t sh_xn_md_ni1_cmp_exp_data1_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_md_ni1_cmp_exp_data1_s;
+ } sh_xn_md_ni1_cmp_exp_data1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_MD_NI1_CMP_ENABLE0" */
+ /* MD compare NI1 input enable0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_md_ni1_cmp_enable0_u {
+ mmr_t sh_xn_md_ni1_cmp_enable0_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_md_ni1_cmp_enable0_s;
+ } sh_xn_md_ni1_cmp_enable0_u_t;
+-#else
+-typedef union sh_xn_md_ni1_cmp_enable0_u {
+- mmr_t sh_xn_md_ni1_cmp_enable0_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_md_ni1_cmp_enable0_s;
+-} sh_xn_md_ni1_cmp_enable0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_MD_NI1_CMP_ENABLE1" */
+ /* MD compare NI1 input enable1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_md_ni1_cmp_enable1_u {
+- mmr_t sh_xn_md_ni1_cmp_enable1_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_md_ni1_cmp_enable1_s;
+-} sh_xn_md_ni1_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_md_ni1_cmp_enable1_u {
+ mmr_t sh_xn_md_ni1_cmp_enable1_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_md_ni1_cmp_enable1_s;
+ } sh_xn_md_ni1_cmp_enable1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_MD_SIC_CMP_EXP_HDR0" */
+ /* MD compare SIC input expected header0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_md_sic_cmp_exp_hdr0_u {
+- mmr_t sh_xn_md_sic_cmp_exp_hdr0_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_md_sic_cmp_exp_hdr0_s;
+-} sh_xn_md_sic_cmp_exp_hdr0_u_t;
+-#else
+ typedef union sh_xn_md_sic_cmp_exp_hdr0_u {
+ mmr_t sh_xn_md_sic_cmp_exp_hdr0_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_md_sic_cmp_exp_hdr0_s;
+ } sh_xn_md_sic_cmp_exp_hdr0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_MD_SIC_CMP_EXP_HDR1" */
+ /* MD compare SIC input expected header1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_md_sic_cmp_exp_hdr1_u {
+ mmr_t sh_xn_md_sic_cmp_exp_hdr1_regval;
+ struct {
+@@ -11578,43 +6248,24 @@
+ mmr_t reserved_0 : 22;
+ } sh_xn_md_sic_cmp_exp_hdr1_s;
+ } sh_xn_md_sic_cmp_exp_hdr1_u_t;
+-#else
+-typedef union sh_xn_md_sic_cmp_exp_hdr1_u {
+- mmr_t sh_xn_md_sic_cmp_exp_hdr1_regval;
+- struct {
+- mmr_t reserved_0 : 22;
+- mmr_t data : 42;
+- } sh_xn_md_sic_cmp_exp_hdr1_s;
+-} sh_xn_md_sic_cmp_exp_hdr1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_MD_SIC_CMP_HDR_ENABLE0" */
+ /* MD compare SIC header enable0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_md_sic_cmp_hdr_enable0_u {
+- mmr_t sh_xn_md_sic_cmp_hdr_enable0_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_md_sic_cmp_hdr_enable0_s;
+-} sh_xn_md_sic_cmp_hdr_enable0_u_t;
+-#else
+ typedef union sh_xn_md_sic_cmp_hdr_enable0_u {
+ mmr_t sh_xn_md_sic_cmp_hdr_enable0_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_md_sic_cmp_hdr_enable0_s;
+ } sh_xn_md_sic_cmp_hdr_enable0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_MD_SIC_CMP_HDR_ENABLE1" */
+ /* MD compare SIC header enable1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_md_sic_cmp_hdr_enable1_u {
+ mmr_t sh_xn_md_sic_cmp_hdr_enable1_regval;
+ struct {
+@@ -11622,463 +6273,264 @@
+ mmr_t reserved_0 : 22;
+ } sh_xn_md_sic_cmp_hdr_enable1_s;
+ } sh_xn_md_sic_cmp_hdr_enable1_u_t;
+-#else
+-typedef union sh_xn_md_sic_cmp_hdr_enable1_u {
+- mmr_t sh_xn_md_sic_cmp_hdr_enable1_regval;
+- struct {
+- mmr_t reserved_0 : 22;
+- mmr_t enable : 42;
+- } sh_xn_md_sic_cmp_hdr_enable1_s;
+-} sh_xn_md_sic_cmp_hdr_enable1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_MD_SIC_CMP_DATA0" */
+ /* MD compare SIC data0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_md_sic_cmp_data0_u {
+- mmr_t sh_xn_md_sic_cmp_data0_regval;
+- struct {
+- mmr_t data0 : 64;
+- } sh_xn_md_sic_cmp_data0_s;
+-} sh_xn_md_sic_cmp_data0_u_t;
+-#else
+ typedef union sh_xn_md_sic_cmp_data0_u {
+ mmr_t sh_xn_md_sic_cmp_data0_regval;
+ struct {
+ mmr_t data0 : 64;
+ } sh_xn_md_sic_cmp_data0_s;
+ } sh_xn_md_sic_cmp_data0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_MD_SIC_CMP_DATA1" */
+ /* MD compare SIC data1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_md_sic_cmp_data1_u {
+- mmr_t sh_xn_md_sic_cmp_data1_regval;
+- struct {
+- mmr_t data1 : 64;
+- } sh_xn_md_sic_cmp_data1_s;
+-} sh_xn_md_sic_cmp_data1_u_t;
+-#else
+ typedef union sh_xn_md_sic_cmp_data1_u {
+ mmr_t sh_xn_md_sic_cmp_data1_regval;
+ struct {
+ mmr_t data1 : 64;
+ } sh_xn_md_sic_cmp_data1_s;
+ } sh_xn_md_sic_cmp_data1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_MD_SIC_CMP_DATA2" */
+ /* MD compare SIC data2 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_md_sic_cmp_data2_u {
+- mmr_t sh_xn_md_sic_cmp_data2_regval;
+- struct {
+- mmr_t data2 : 64;
+- } sh_xn_md_sic_cmp_data2_s;
+-} sh_xn_md_sic_cmp_data2_u_t;
+-#else
+ typedef union sh_xn_md_sic_cmp_data2_u {
+ mmr_t sh_xn_md_sic_cmp_data2_regval;
+ struct {
+ mmr_t data2 : 64;
+ } sh_xn_md_sic_cmp_data2_s;
+ } sh_xn_md_sic_cmp_data2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_MD_SIC_CMP_DATA3" */
+ /* MD compare SIC data3 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_md_sic_cmp_data3_u {
+ mmr_t sh_xn_md_sic_cmp_data3_regval;
+ struct {
+ mmr_t data3 : 64;
+ } sh_xn_md_sic_cmp_data3_s;
+ } sh_xn_md_sic_cmp_data3_u_t;
+-#else
+-typedef union sh_xn_md_sic_cmp_data3_u {
+- mmr_t sh_xn_md_sic_cmp_data3_regval;
+- struct {
+- mmr_t data3 : 64;
+- } sh_xn_md_sic_cmp_data3_s;
+-} sh_xn_md_sic_cmp_data3_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_MD_SIC_CMP_DATA_ENABLE0" */
+ /* MD enable compare SIC data0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_md_sic_cmp_data_enable0_u {
+- mmr_t sh_xn_md_sic_cmp_data_enable0_regval;
+- struct {
+- mmr_t data_enable0 : 64;
+- } sh_xn_md_sic_cmp_data_enable0_s;
+-} sh_xn_md_sic_cmp_data_enable0_u_t;
+-#else
+ typedef union sh_xn_md_sic_cmp_data_enable0_u {
+ mmr_t sh_xn_md_sic_cmp_data_enable0_regval;
+ struct {
+ mmr_t data_enable0 : 64;
+ } sh_xn_md_sic_cmp_data_enable0_s;
+ } sh_xn_md_sic_cmp_data_enable0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_MD_SIC_CMP_DATA_ENABLE1" */
+ /* MD enable compare SIC data1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_md_sic_cmp_data_enable1_u {
+- mmr_t sh_xn_md_sic_cmp_data_enable1_regval;
+- struct {
+- mmr_t data_enable1 : 64;
+- } sh_xn_md_sic_cmp_data_enable1_s;
+-} sh_xn_md_sic_cmp_data_enable1_u_t;
+-#else
+ typedef union sh_xn_md_sic_cmp_data_enable1_u {
+ mmr_t sh_xn_md_sic_cmp_data_enable1_regval;
+ struct {
+ mmr_t data_enable1 : 64;
+ } sh_xn_md_sic_cmp_data_enable1_s;
+ } sh_xn_md_sic_cmp_data_enable1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_MD_SIC_CMP_DATA_ENABLE2" */
+ /* MD enable compare SIC data2 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_md_sic_cmp_data_enable2_u {
+- mmr_t sh_xn_md_sic_cmp_data_enable2_regval;
+- struct {
+- mmr_t data_enable2 : 64;
+- } sh_xn_md_sic_cmp_data_enable2_s;
+-} sh_xn_md_sic_cmp_data_enable2_u_t;
+-#else
+ typedef union sh_xn_md_sic_cmp_data_enable2_u {
+ mmr_t sh_xn_md_sic_cmp_data_enable2_regval;
+ struct {
+ mmr_t data_enable2 : 64;
+ } sh_xn_md_sic_cmp_data_enable2_s;
+ } sh_xn_md_sic_cmp_data_enable2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_MD_SIC_CMP_DATA_ENABLE3" */
+ /* MD enable compare SIC data3 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_md_sic_cmp_data_enable3_u {
+ mmr_t sh_xn_md_sic_cmp_data_enable3_regval;
+ struct {
+ mmr_t data_enable3 : 64;
+ } sh_xn_md_sic_cmp_data_enable3_s;
+ } sh_xn_md_sic_cmp_data_enable3_u_t;
+-#else
+-typedef union sh_xn_md_sic_cmp_data_enable3_u {
+- mmr_t sh_xn_md_sic_cmp_data_enable3_regval;
+- struct {
+- mmr_t data_enable3 : 64;
+- } sh_xn_md_sic_cmp_data_enable3_s;
+-} sh_xn_md_sic_cmp_data_enable3_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_PI_IILB_CMP_EXP_DATA0" */
+ /* PI compare IILB input expected data0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_pi_iilb_cmp_exp_data0_u {
+- mmr_t sh_xn_pi_iilb_cmp_exp_data0_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_pi_iilb_cmp_exp_data0_s;
+-} sh_xn_pi_iilb_cmp_exp_data0_u_t;
+-#else
+ typedef union sh_xn_pi_iilb_cmp_exp_data0_u {
+ mmr_t sh_xn_pi_iilb_cmp_exp_data0_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_pi_iilb_cmp_exp_data0_s;
+ } sh_xn_pi_iilb_cmp_exp_data0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_PI_IILB_CMP_EXP_DATA1" */
+ /* PI compare IILB input expected data1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_pi_iilb_cmp_exp_data1_u {
+- mmr_t sh_xn_pi_iilb_cmp_exp_data1_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_pi_iilb_cmp_exp_data1_s;
+-} sh_xn_pi_iilb_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_pi_iilb_cmp_exp_data1_u {
+ mmr_t sh_xn_pi_iilb_cmp_exp_data1_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_pi_iilb_cmp_exp_data1_s;
+ } sh_xn_pi_iilb_cmp_exp_data1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_PI_IILB_CMP_ENABLE0" */
+ /* PI compare IILB input enable0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_pi_iilb_cmp_enable0_u {
+- mmr_t sh_xn_pi_iilb_cmp_enable0_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_pi_iilb_cmp_enable0_s;
+-} sh_xn_pi_iilb_cmp_enable0_u_t;
+-#else
+ typedef union sh_xn_pi_iilb_cmp_enable0_u {
+ mmr_t sh_xn_pi_iilb_cmp_enable0_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_pi_iilb_cmp_enable0_s;
+ } sh_xn_pi_iilb_cmp_enable0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_PI_IILB_CMP_ENABLE1" */
+ /* PI compare IILB input enable1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_pi_iilb_cmp_enable1_u {
+ mmr_t sh_xn_pi_iilb_cmp_enable1_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_pi_iilb_cmp_enable1_s;
+ } sh_xn_pi_iilb_cmp_enable1_u_t;
+-#else
+-typedef union sh_xn_pi_iilb_cmp_enable1_u {
+- mmr_t sh_xn_pi_iilb_cmp_enable1_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_pi_iilb_cmp_enable1_s;
+-} sh_xn_pi_iilb_cmp_enable1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_PI_NI0_CMP_EXP_DATA0" */
+ /* PI compare NI0 input expected data0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_pi_ni0_cmp_exp_data0_u {
+- mmr_t sh_xn_pi_ni0_cmp_exp_data0_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_pi_ni0_cmp_exp_data0_s;
+-} sh_xn_pi_ni0_cmp_exp_data0_u_t;
+-#else
+ typedef union sh_xn_pi_ni0_cmp_exp_data0_u {
+ mmr_t sh_xn_pi_ni0_cmp_exp_data0_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_pi_ni0_cmp_exp_data0_s;
+ } sh_xn_pi_ni0_cmp_exp_data0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_PI_NI0_CMP_EXP_DATA1" */
+ /* PI compare NI0 input expected data1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_pi_ni0_cmp_exp_data1_u {
+- mmr_t sh_xn_pi_ni0_cmp_exp_data1_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_pi_ni0_cmp_exp_data1_s;
+-} sh_xn_pi_ni0_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_pi_ni0_cmp_exp_data1_u {
+ mmr_t sh_xn_pi_ni0_cmp_exp_data1_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_pi_ni0_cmp_exp_data1_s;
+ } sh_xn_pi_ni0_cmp_exp_data1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_PI_NI0_CMP_ENABLE0" */
+ /* PI compare NI0 input enable0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_pi_ni0_cmp_enable0_u {
+- mmr_t sh_xn_pi_ni0_cmp_enable0_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_pi_ni0_cmp_enable0_s;
+-} sh_xn_pi_ni0_cmp_enable0_u_t;
+-#else
+ typedef union sh_xn_pi_ni0_cmp_enable0_u {
+ mmr_t sh_xn_pi_ni0_cmp_enable0_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_pi_ni0_cmp_enable0_s;
+ } sh_xn_pi_ni0_cmp_enable0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_PI_NI0_CMP_ENABLE1" */
+ /* PI compare NI0 input enable1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_pi_ni0_cmp_enable1_u {
+ mmr_t sh_xn_pi_ni0_cmp_enable1_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_pi_ni0_cmp_enable1_s;
+ } sh_xn_pi_ni0_cmp_enable1_u_t;
+-#else
+-typedef union sh_xn_pi_ni0_cmp_enable1_u {
+- mmr_t sh_xn_pi_ni0_cmp_enable1_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_pi_ni0_cmp_enable1_s;
+-} sh_xn_pi_ni0_cmp_enable1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_PI_NI1_CMP_EXP_DATA0" */
+ /* PI compare NI1 input expected data0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_pi_ni1_cmp_exp_data0_u {
+- mmr_t sh_xn_pi_ni1_cmp_exp_data0_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_pi_ni1_cmp_exp_data0_s;
+-} sh_xn_pi_ni1_cmp_exp_data0_u_t;
+-#else
+ typedef union sh_xn_pi_ni1_cmp_exp_data0_u {
+ mmr_t sh_xn_pi_ni1_cmp_exp_data0_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_pi_ni1_cmp_exp_data0_s;
+ } sh_xn_pi_ni1_cmp_exp_data0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_PI_NI1_CMP_EXP_DATA1" */
+ /* PI compare NI1 input expected data1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_pi_ni1_cmp_exp_data1_u {
+- mmr_t sh_xn_pi_ni1_cmp_exp_data1_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_pi_ni1_cmp_exp_data1_s;
+-} sh_xn_pi_ni1_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_pi_ni1_cmp_exp_data1_u {
+ mmr_t sh_xn_pi_ni1_cmp_exp_data1_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_pi_ni1_cmp_exp_data1_s;
+ } sh_xn_pi_ni1_cmp_exp_data1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_PI_NI1_CMP_ENABLE0" */
+ /* PI compare NI1 input enable0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_pi_ni1_cmp_enable0_u {
+- mmr_t sh_xn_pi_ni1_cmp_enable0_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_pi_ni1_cmp_enable0_s;
+-} sh_xn_pi_ni1_cmp_enable0_u_t;
+-#else
+ typedef union sh_xn_pi_ni1_cmp_enable0_u {
+ mmr_t sh_xn_pi_ni1_cmp_enable0_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_pi_ni1_cmp_enable0_s;
+ } sh_xn_pi_ni1_cmp_enable0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_PI_NI1_CMP_ENABLE1" */
+ /* PI compare NI1 input enable1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_pi_ni1_cmp_enable1_u {
+ mmr_t sh_xn_pi_ni1_cmp_enable1_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_pi_ni1_cmp_enable1_s;
+ } sh_xn_pi_ni1_cmp_enable1_u_t;
+-#else
+-typedef union sh_xn_pi_ni1_cmp_enable1_u {
+- mmr_t sh_xn_pi_ni1_cmp_enable1_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_pi_ni1_cmp_enable1_s;
+-} sh_xn_pi_ni1_cmp_enable1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_PI_SIC_CMP_EXP_HDR0" */
+ /* PI compare SIC input expected header0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_pi_sic_cmp_exp_hdr0_u {
+- mmr_t sh_xn_pi_sic_cmp_exp_hdr0_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_pi_sic_cmp_exp_hdr0_s;
+-} sh_xn_pi_sic_cmp_exp_hdr0_u_t;
+-#else
+ typedef union sh_xn_pi_sic_cmp_exp_hdr0_u {
+ mmr_t sh_xn_pi_sic_cmp_exp_hdr0_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_pi_sic_cmp_exp_hdr0_s;
+ } sh_xn_pi_sic_cmp_exp_hdr0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_PI_SIC_CMP_EXP_HDR1" */
+ /* PI compare SIC input expected header1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_pi_sic_cmp_exp_hdr1_u {
+ mmr_t sh_xn_pi_sic_cmp_exp_hdr1_regval;
+ struct {
+@@ -12086,43 +6538,24 @@
+ mmr_t reserved_0 : 22;
+ } sh_xn_pi_sic_cmp_exp_hdr1_s;
+ } sh_xn_pi_sic_cmp_exp_hdr1_u_t;
+-#else
+-typedef union sh_xn_pi_sic_cmp_exp_hdr1_u {
+- mmr_t sh_xn_pi_sic_cmp_exp_hdr1_regval;
+- struct {
+- mmr_t reserved_0 : 22;
+- mmr_t data : 42;
+- } sh_xn_pi_sic_cmp_exp_hdr1_s;
+-} sh_xn_pi_sic_cmp_exp_hdr1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_PI_SIC_CMP_HDR_ENABLE0" */
+ /* PI compare SIC header enable0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_pi_sic_cmp_hdr_enable0_u {
+- mmr_t sh_xn_pi_sic_cmp_hdr_enable0_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_pi_sic_cmp_hdr_enable0_s;
+-} sh_xn_pi_sic_cmp_hdr_enable0_u_t;
+-#else
+ typedef union sh_xn_pi_sic_cmp_hdr_enable0_u {
+ mmr_t sh_xn_pi_sic_cmp_hdr_enable0_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_pi_sic_cmp_hdr_enable0_s;
+ } sh_xn_pi_sic_cmp_hdr_enable0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_PI_SIC_CMP_HDR_ENABLE1" */
+ /* PI compare SIC header enable1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_pi_sic_cmp_hdr_enable1_u {
+ mmr_t sh_xn_pi_sic_cmp_hdr_enable1_regval;
+ struct {
+@@ -12130,1029 +6563,587 @@
+ mmr_t reserved_0 : 22;
+ } sh_xn_pi_sic_cmp_hdr_enable1_s;
+ } sh_xn_pi_sic_cmp_hdr_enable1_u_t;
+-#else
+-typedef union sh_xn_pi_sic_cmp_hdr_enable1_u {
+- mmr_t sh_xn_pi_sic_cmp_hdr_enable1_regval;
+- struct {
+- mmr_t reserved_0 : 22;
+- mmr_t enable : 42;
+- } sh_xn_pi_sic_cmp_hdr_enable1_s;
+-} sh_xn_pi_sic_cmp_hdr_enable1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_PI_SIC_CMP_DATA0" */
+ /* PI compare SIC data0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_pi_sic_cmp_data0_u {
+ mmr_t sh_xn_pi_sic_cmp_data0_regval;
+ struct {
+ mmr_t data0 : 64;
+ } sh_xn_pi_sic_cmp_data0_s;
+ } sh_xn_pi_sic_cmp_data0_u_t;
+-#else
+-typedef union sh_xn_pi_sic_cmp_data0_u {
+- mmr_t sh_xn_pi_sic_cmp_data0_regval;
+- struct {
+- mmr_t data0 : 64;
+- } sh_xn_pi_sic_cmp_data0_s;
+-} sh_xn_pi_sic_cmp_data0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_PI_SIC_CMP_DATA1" */
+ /* PI compare SIC data1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_pi_sic_cmp_data1_u {
+- mmr_t sh_xn_pi_sic_cmp_data1_regval;
+- struct {
+- mmr_t data1 : 64;
+- } sh_xn_pi_sic_cmp_data1_s;
+-} sh_xn_pi_sic_cmp_data1_u_t;
+-#else
+ typedef union sh_xn_pi_sic_cmp_data1_u {
+ mmr_t sh_xn_pi_sic_cmp_data1_regval;
+ struct {
+ mmr_t data1 : 64;
+ } sh_xn_pi_sic_cmp_data1_s;
+ } sh_xn_pi_sic_cmp_data1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_PI_SIC_CMP_DATA2" */
+ /* PI compare SIC data2 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_pi_sic_cmp_data2_u {
+- mmr_t sh_xn_pi_sic_cmp_data2_regval;
+- struct {
+- mmr_t data2 : 64;
+- } sh_xn_pi_sic_cmp_data2_s;
+-} sh_xn_pi_sic_cmp_data2_u_t;
+-#else
+ typedef union sh_xn_pi_sic_cmp_data2_u {
+ mmr_t sh_xn_pi_sic_cmp_data2_regval;
+ struct {
+ mmr_t data2 : 64;
+ } sh_xn_pi_sic_cmp_data2_s;
+ } sh_xn_pi_sic_cmp_data2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_PI_SIC_CMP_DATA3" */
+ /* PI compare SIC data3 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_pi_sic_cmp_data3_u {
+- mmr_t sh_xn_pi_sic_cmp_data3_regval;
+- struct {
+- mmr_t data3 : 64;
+- } sh_xn_pi_sic_cmp_data3_s;
+-} sh_xn_pi_sic_cmp_data3_u_t;
+-#else
+ typedef union sh_xn_pi_sic_cmp_data3_u {
+ mmr_t sh_xn_pi_sic_cmp_data3_regval;
+ struct {
+ mmr_t data3 : 64;
+ } sh_xn_pi_sic_cmp_data3_s;
+ } sh_xn_pi_sic_cmp_data3_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_PI_SIC_CMP_DATA_ENABLE0" */
+ /* PI enable compare SIC data0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_pi_sic_cmp_data_enable0_u {
+ mmr_t sh_xn_pi_sic_cmp_data_enable0_regval;
+ struct {
+ mmr_t data_enable0 : 64;
+ } sh_xn_pi_sic_cmp_data_enable0_s;
+ } sh_xn_pi_sic_cmp_data_enable0_u_t;
+-#else
+-typedef union sh_xn_pi_sic_cmp_data_enable0_u {
+- mmr_t sh_xn_pi_sic_cmp_data_enable0_regval;
+- struct {
+- mmr_t data_enable0 : 64;
+- } sh_xn_pi_sic_cmp_data_enable0_s;
+-} sh_xn_pi_sic_cmp_data_enable0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_PI_SIC_CMP_DATA_ENABLE1" */
+ /* PI enable compare SIC data1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_pi_sic_cmp_data_enable1_u {
+- mmr_t sh_xn_pi_sic_cmp_data_enable1_regval;
+- struct {
+- mmr_t data_enable1 : 64;
+- } sh_xn_pi_sic_cmp_data_enable1_s;
+-} sh_xn_pi_sic_cmp_data_enable1_u_t;
+-#else
+ typedef union sh_xn_pi_sic_cmp_data_enable1_u {
+ mmr_t sh_xn_pi_sic_cmp_data_enable1_regval;
+ struct {
+ mmr_t data_enable1 : 64;
+ } sh_xn_pi_sic_cmp_data_enable1_s;
+ } sh_xn_pi_sic_cmp_data_enable1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_PI_SIC_CMP_DATA_ENABLE2" */
+ /* PI enable compare SIC data2 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_pi_sic_cmp_data_enable2_u {
+- mmr_t sh_xn_pi_sic_cmp_data_enable2_regval;
+- struct {
+- mmr_t data_enable2 : 64;
+- } sh_xn_pi_sic_cmp_data_enable2_s;
+-} sh_xn_pi_sic_cmp_data_enable2_u_t;
+-#else
+ typedef union sh_xn_pi_sic_cmp_data_enable2_u {
+ mmr_t sh_xn_pi_sic_cmp_data_enable2_regval;
+ struct {
+ mmr_t data_enable2 : 64;
+ } sh_xn_pi_sic_cmp_data_enable2_s;
+ } sh_xn_pi_sic_cmp_data_enable2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_PI_SIC_CMP_DATA_ENABLE3" */
+ /* PI enable compare SIC data3 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_pi_sic_cmp_data_enable3_u {
+- mmr_t sh_xn_pi_sic_cmp_data_enable3_regval;
+- struct {
+- mmr_t data_enable3 : 64;
+- } sh_xn_pi_sic_cmp_data_enable3_s;
+-} sh_xn_pi_sic_cmp_data_enable3_u_t;
+-#else
+ typedef union sh_xn_pi_sic_cmp_data_enable3_u {
+ mmr_t sh_xn_pi_sic_cmp_data_enable3_regval;
+ struct {
+ mmr_t data_enable3 : 64;
+ } sh_xn_pi_sic_cmp_data_enable3_s;
+ } sh_xn_pi_sic_cmp_data_enable3_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI0_IILB_CMP_EXP_DATA0" */
+ /* NI0 compare IILB input expected data0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_ni0_iilb_cmp_exp_data0_u {
+ mmr_t sh_xn_ni0_iilb_cmp_exp_data0_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_ni0_iilb_cmp_exp_data0_s;
+ } sh_xn_ni0_iilb_cmp_exp_data0_u_t;
+-#else
+-typedef union sh_xn_ni0_iilb_cmp_exp_data0_u {
+- mmr_t sh_xn_ni0_iilb_cmp_exp_data0_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_ni0_iilb_cmp_exp_data0_s;
+-} sh_xn_ni0_iilb_cmp_exp_data0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI0_IILB_CMP_EXP_DATA1" */
+ /* NI0 compare IILB input expected data1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni0_iilb_cmp_exp_data1_u {
+- mmr_t sh_xn_ni0_iilb_cmp_exp_data1_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_ni0_iilb_cmp_exp_data1_s;
+-} sh_xn_ni0_iilb_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_ni0_iilb_cmp_exp_data1_u {
+ mmr_t sh_xn_ni0_iilb_cmp_exp_data1_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_ni0_iilb_cmp_exp_data1_s;
+ } sh_xn_ni0_iilb_cmp_exp_data1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI0_IILB_CMP_ENABLE0" */
+ /* NI0 compare IILB input enable0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni0_iilb_cmp_enable0_u {
+- mmr_t sh_xn_ni0_iilb_cmp_enable0_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_ni0_iilb_cmp_enable0_s;
+-} sh_xn_ni0_iilb_cmp_enable0_u_t;
+-#else
+ typedef union sh_xn_ni0_iilb_cmp_enable0_u {
+ mmr_t sh_xn_ni0_iilb_cmp_enable0_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_ni0_iilb_cmp_enable0_s;
+ } sh_xn_ni0_iilb_cmp_enable0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI0_IILB_CMP_ENABLE1" */
+ /* NI0 compare IILB input enable1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni0_iilb_cmp_enable1_u {
+- mmr_t sh_xn_ni0_iilb_cmp_enable1_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_ni0_iilb_cmp_enable1_s;
+-} sh_xn_ni0_iilb_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_ni0_iilb_cmp_enable1_u {
+ mmr_t sh_xn_ni0_iilb_cmp_enable1_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_ni0_iilb_cmp_enable1_s;
+ } sh_xn_ni0_iilb_cmp_enable1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI0_PI_CMP_EXP_DATA0" */
+ /* NI0 compare PI input expected data0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_ni0_pi_cmp_exp_data0_u {
+ mmr_t sh_xn_ni0_pi_cmp_exp_data0_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_ni0_pi_cmp_exp_data0_s;
+ } sh_xn_ni0_pi_cmp_exp_data0_u_t;
+-#else
+-typedef union sh_xn_ni0_pi_cmp_exp_data0_u {
+- mmr_t sh_xn_ni0_pi_cmp_exp_data0_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_ni0_pi_cmp_exp_data0_s;
+-} sh_xn_ni0_pi_cmp_exp_data0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI0_PI_CMP_EXP_DATA1" */
+ /* NI0 compare PI input expected data1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni0_pi_cmp_exp_data1_u {
+- mmr_t sh_xn_ni0_pi_cmp_exp_data1_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_ni0_pi_cmp_exp_data1_s;
+-} sh_xn_ni0_pi_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_ni0_pi_cmp_exp_data1_u {
+ mmr_t sh_xn_ni0_pi_cmp_exp_data1_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_ni0_pi_cmp_exp_data1_s;
+ } sh_xn_ni0_pi_cmp_exp_data1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI0_PI_CMP_ENABLE0" */
+ /* NI0 compare PI input enable0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni0_pi_cmp_enable0_u {
+- mmr_t sh_xn_ni0_pi_cmp_enable0_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_ni0_pi_cmp_enable0_s;
+-} sh_xn_ni0_pi_cmp_enable0_u_t;
+-#else
+ typedef union sh_xn_ni0_pi_cmp_enable0_u {
+ mmr_t sh_xn_ni0_pi_cmp_enable0_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_ni0_pi_cmp_enable0_s;
+ } sh_xn_ni0_pi_cmp_enable0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI0_PI_CMP_ENABLE1" */
+ /* NI0 compare PI input enable1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni0_pi_cmp_enable1_u {
+- mmr_t sh_xn_ni0_pi_cmp_enable1_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_ni0_pi_cmp_enable1_s;
+-} sh_xn_ni0_pi_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_ni0_pi_cmp_enable1_u {
+ mmr_t sh_xn_ni0_pi_cmp_enable1_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_ni0_pi_cmp_enable1_s;
+ } sh_xn_ni0_pi_cmp_enable1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI0_MD_CMP_EXP_DATA0" */
+ /* NI0 compare MD input expected data0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_ni0_md_cmp_exp_data0_u {
+ mmr_t sh_xn_ni0_md_cmp_exp_data0_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_ni0_md_cmp_exp_data0_s;
+ } sh_xn_ni0_md_cmp_exp_data0_u_t;
+-#else
+-typedef union sh_xn_ni0_md_cmp_exp_data0_u {
+- mmr_t sh_xn_ni0_md_cmp_exp_data0_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_ni0_md_cmp_exp_data0_s;
+-} sh_xn_ni0_md_cmp_exp_data0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI0_MD_CMP_EXP_DATA1" */
+ /* NI0 compare MD input expected data1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni0_md_cmp_exp_data1_u {
+- mmr_t sh_xn_ni0_md_cmp_exp_data1_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_ni0_md_cmp_exp_data1_s;
+-} sh_xn_ni0_md_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_ni0_md_cmp_exp_data1_u {
+ mmr_t sh_xn_ni0_md_cmp_exp_data1_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_ni0_md_cmp_exp_data1_s;
+ } sh_xn_ni0_md_cmp_exp_data1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI0_MD_CMP_ENABLE0" */
+ /* NI0 compare MD input enable0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni0_md_cmp_enable0_u {
+- mmr_t sh_xn_ni0_md_cmp_enable0_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_ni0_md_cmp_enable0_s;
+-} sh_xn_ni0_md_cmp_enable0_u_t;
+-#else
+ typedef union sh_xn_ni0_md_cmp_enable0_u {
+ mmr_t sh_xn_ni0_md_cmp_enable0_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_ni0_md_cmp_enable0_s;
+ } sh_xn_ni0_md_cmp_enable0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI0_MD_CMP_ENABLE1" */
+ /* NI0 compare MD input enable1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni0_md_cmp_enable1_u {
+- mmr_t sh_xn_ni0_md_cmp_enable1_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_ni0_md_cmp_enable1_s;
+-} sh_xn_ni0_md_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_ni0_md_cmp_enable1_u {
+ mmr_t sh_xn_ni0_md_cmp_enable1_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_ni0_md_cmp_enable1_s;
+ } sh_xn_ni0_md_cmp_enable1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI0_NI_CMP_EXP_DATA0" */
+ /* NI0 compare NI input expected data0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_ni0_ni_cmp_exp_data0_u {
+ mmr_t sh_xn_ni0_ni_cmp_exp_data0_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_ni0_ni_cmp_exp_data0_s;
+ } sh_xn_ni0_ni_cmp_exp_data0_u_t;
+-#else
+-typedef union sh_xn_ni0_ni_cmp_exp_data0_u {
+- mmr_t sh_xn_ni0_ni_cmp_exp_data0_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_ni0_ni_cmp_exp_data0_s;
+-} sh_xn_ni0_ni_cmp_exp_data0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI0_NI_CMP_EXP_DATA1" */
+ /* NI0 compare NI input expected data1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni0_ni_cmp_exp_data1_u {
+- mmr_t sh_xn_ni0_ni_cmp_exp_data1_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_ni0_ni_cmp_exp_data1_s;
+-} sh_xn_ni0_ni_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_ni0_ni_cmp_exp_data1_u {
+ mmr_t sh_xn_ni0_ni_cmp_exp_data1_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_ni0_ni_cmp_exp_data1_s;
+ } sh_xn_ni0_ni_cmp_exp_data1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI0_NI_CMP_ENABLE0" */
+ /* NI0 compare NI input enable0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni0_ni_cmp_enable0_u {
+- mmr_t sh_xn_ni0_ni_cmp_enable0_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_ni0_ni_cmp_enable0_s;
+-} sh_xn_ni0_ni_cmp_enable0_u_t;
+-#else
+ typedef union sh_xn_ni0_ni_cmp_enable0_u {
+ mmr_t sh_xn_ni0_ni_cmp_enable0_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_ni0_ni_cmp_enable0_s;
+ } sh_xn_ni0_ni_cmp_enable0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI0_NI_CMP_ENABLE1" */
+ /* NI0 compare NI input enable1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni0_ni_cmp_enable1_u {
+- mmr_t sh_xn_ni0_ni_cmp_enable1_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_ni0_ni_cmp_enable1_s;
+-} sh_xn_ni0_ni_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_ni0_ni_cmp_enable1_u {
+ mmr_t sh_xn_ni0_ni_cmp_enable1_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_ni0_ni_cmp_enable1_s;
+ } sh_xn_ni0_ni_cmp_enable1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI0_LLP_CMP_EXP_DATA0" */
+ /* NI0 compare LLP input expected data0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_ni0_llp_cmp_exp_data0_u {
+ mmr_t sh_xn_ni0_llp_cmp_exp_data0_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_ni0_llp_cmp_exp_data0_s;
+ } sh_xn_ni0_llp_cmp_exp_data0_u_t;
+-#else
+-typedef union sh_xn_ni0_llp_cmp_exp_data0_u {
+- mmr_t sh_xn_ni0_llp_cmp_exp_data0_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_ni0_llp_cmp_exp_data0_s;
+-} sh_xn_ni0_llp_cmp_exp_data0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI0_LLP_CMP_EXP_DATA1" */
+ /* NI0 compare LLP input expected data1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni0_llp_cmp_exp_data1_u {
+- mmr_t sh_xn_ni0_llp_cmp_exp_data1_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_ni0_llp_cmp_exp_data1_s;
+-} sh_xn_ni0_llp_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_ni0_llp_cmp_exp_data1_u {
+ mmr_t sh_xn_ni0_llp_cmp_exp_data1_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_ni0_llp_cmp_exp_data1_s;
+ } sh_xn_ni0_llp_cmp_exp_data1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI0_LLP_CMP_ENABLE0" */
+ /* NI0 compare LLP input enable0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni0_llp_cmp_enable0_u {
+- mmr_t sh_xn_ni0_llp_cmp_enable0_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_ni0_llp_cmp_enable0_s;
+-} sh_xn_ni0_llp_cmp_enable0_u_t;
+-#else
+ typedef union sh_xn_ni0_llp_cmp_enable0_u {
+ mmr_t sh_xn_ni0_llp_cmp_enable0_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_ni0_llp_cmp_enable0_s;
+ } sh_xn_ni0_llp_cmp_enable0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI0_LLP_CMP_ENABLE1" */
+ /* NI0 compare LLP input enable1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni0_llp_cmp_enable1_u {
+- mmr_t sh_xn_ni0_llp_cmp_enable1_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_ni0_llp_cmp_enable1_s;
+-} sh_xn_ni0_llp_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_ni0_llp_cmp_enable1_u {
+ mmr_t sh_xn_ni0_llp_cmp_enable1_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_ni0_llp_cmp_enable1_s;
+ } sh_xn_ni0_llp_cmp_enable1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI1_IILB_CMP_EXP_DATA0" */
+ /* NI1 compare IILB input expected data0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_ni1_iilb_cmp_exp_data0_u {
+ mmr_t sh_xn_ni1_iilb_cmp_exp_data0_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_ni1_iilb_cmp_exp_data0_s;
+ } sh_xn_ni1_iilb_cmp_exp_data0_u_t;
+-#else
+-typedef union sh_xn_ni1_iilb_cmp_exp_data0_u {
+- mmr_t sh_xn_ni1_iilb_cmp_exp_data0_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_ni1_iilb_cmp_exp_data0_s;
+-} sh_xn_ni1_iilb_cmp_exp_data0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI1_IILB_CMP_EXP_DATA1" */
+ /* NI1 compare IILB input expected data1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni1_iilb_cmp_exp_data1_u {
+- mmr_t sh_xn_ni1_iilb_cmp_exp_data1_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_ni1_iilb_cmp_exp_data1_s;
+-} sh_xn_ni1_iilb_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_ni1_iilb_cmp_exp_data1_u {
+ mmr_t sh_xn_ni1_iilb_cmp_exp_data1_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_ni1_iilb_cmp_exp_data1_s;
+ } sh_xn_ni1_iilb_cmp_exp_data1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI1_IILB_CMP_ENABLE0" */
+ /* NI1 compare IILB input enable0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni1_iilb_cmp_enable0_u {
+- mmr_t sh_xn_ni1_iilb_cmp_enable0_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_ni1_iilb_cmp_enable0_s;
+-} sh_xn_ni1_iilb_cmp_enable0_u_t;
+-#else
+ typedef union sh_xn_ni1_iilb_cmp_enable0_u {
+ mmr_t sh_xn_ni1_iilb_cmp_enable0_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_ni1_iilb_cmp_enable0_s;
+ } sh_xn_ni1_iilb_cmp_enable0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI1_IILB_CMP_ENABLE1" */
+ /* NI1 compare IILB input enable1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni1_iilb_cmp_enable1_u {
+- mmr_t sh_xn_ni1_iilb_cmp_enable1_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_ni1_iilb_cmp_enable1_s;
+-} sh_xn_ni1_iilb_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_ni1_iilb_cmp_enable1_u {
+ mmr_t sh_xn_ni1_iilb_cmp_enable1_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_ni1_iilb_cmp_enable1_s;
+ } sh_xn_ni1_iilb_cmp_enable1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI1_PI_CMP_EXP_DATA0" */
+ /* NI1 compare PI input expected data0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_ni1_pi_cmp_exp_data0_u {
+ mmr_t sh_xn_ni1_pi_cmp_exp_data0_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_ni1_pi_cmp_exp_data0_s;
+ } sh_xn_ni1_pi_cmp_exp_data0_u_t;
+-#else
+-typedef union sh_xn_ni1_pi_cmp_exp_data0_u {
+- mmr_t sh_xn_ni1_pi_cmp_exp_data0_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_ni1_pi_cmp_exp_data0_s;
+-} sh_xn_ni1_pi_cmp_exp_data0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI1_PI_CMP_EXP_DATA1" */
+ /* NI1 compare PI input expected data1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni1_pi_cmp_exp_data1_u {
+- mmr_t sh_xn_ni1_pi_cmp_exp_data1_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_ni1_pi_cmp_exp_data1_s;
+-} sh_xn_ni1_pi_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_ni1_pi_cmp_exp_data1_u {
+ mmr_t sh_xn_ni1_pi_cmp_exp_data1_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_ni1_pi_cmp_exp_data1_s;
+ } sh_xn_ni1_pi_cmp_exp_data1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI1_PI_CMP_ENABLE0" */
+ /* NI1 compare PI input enable0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni1_pi_cmp_enable0_u {
+- mmr_t sh_xn_ni1_pi_cmp_enable0_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_ni1_pi_cmp_enable0_s;
+-} sh_xn_ni1_pi_cmp_enable0_u_t;
+-#else
+ typedef union sh_xn_ni1_pi_cmp_enable0_u {
+ mmr_t sh_xn_ni1_pi_cmp_enable0_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_ni1_pi_cmp_enable0_s;
+ } sh_xn_ni1_pi_cmp_enable0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI1_PI_CMP_ENABLE1" */
+ /* NI1 compare PI input enable1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni1_pi_cmp_enable1_u {
+- mmr_t sh_xn_ni1_pi_cmp_enable1_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_ni1_pi_cmp_enable1_s;
+-} sh_xn_ni1_pi_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_ni1_pi_cmp_enable1_u {
+ mmr_t sh_xn_ni1_pi_cmp_enable1_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_ni1_pi_cmp_enable1_s;
+ } sh_xn_ni1_pi_cmp_enable1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI1_MD_CMP_EXP_DATA0" */
+ /* NI1 compare MD input expected data0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_ni1_md_cmp_exp_data0_u {
+ mmr_t sh_xn_ni1_md_cmp_exp_data0_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_ni1_md_cmp_exp_data0_s;
+ } sh_xn_ni1_md_cmp_exp_data0_u_t;
+-#else
+-typedef union sh_xn_ni1_md_cmp_exp_data0_u {
+- mmr_t sh_xn_ni1_md_cmp_exp_data0_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_ni1_md_cmp_exp_data0_s;
+-} sh_xn_ni1_md_cmp_exp_data0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI1_MD_CMP_EXP_DATA1" */
+ /* NI1 compare MD input expected data1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni1_md_cmp_exp_data1_u {
+- mmr_t sh_xn_ni1_md_cmp_exp_data1_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_ni1_md_cmp_exp_data1_s;
+-} sh_xn_ni1_md_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_ni1_md_cmp_exp_data1_u {
+ mmr_t sh_xn_ni1_md_cmp_exp_data1_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_ni1_md_cmp_exp_data1_s;
+ } sh_xn_ni1_md_cmp_exp_data1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI1_MD_CMP_ENABLE0" */
+ /* NI1 compare MD input enable0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni1_md_cmp_enable0_u {
+- mmr_t sh_xn_ni1_md_cmp_enable0_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_ni1_md_cmp_enable0_s;
+-} sh_xn_ni1_md_cmp_enable0_u_t;
+-#else
+ typedef union sh_xn_ni1_md_cmp_enable0_u {
+ mmr_t sh_xn_ni1_md_cmp_enable0_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_ni1_md_cmp_enable0_s;
+ } sh_xn_ni1_md_cmp_enable0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI1_MD_CMP_ENABLE1" */
+ /* NI1 compare MD input enable1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni1_md_cmp_enable1_u {
+- mmr_t sh_xn_ni1_md_cmp_enable1_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_ni1_md_cmp_enable1_s;
+-} sh_xn_ni1_md_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_ni1_md_cmp_enable1_u {
+ mmr_t sh_xn_ni1_md_cmp_enable1_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_ni1_md_cmp_enable1_s;
+ } sh_xn_ni1_md_cmp_enable1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI1_NI_CMP_EXP_DATA0" */
+ /* NI1 compare NI input expected data0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_ni1_ni_cmp_exp_data0_u {
+ mmr_t sh_xn_ni1_ni_cmp_exp_data0_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_ni1_ni_cmp_exp_data0_s;
+ } sh_xn_ni1_ni_cmp_exp_data0_u_t;
+-#else
+-typedef union sh_xn_ni1_ni_cmp_exp_data0_u {
+- mmr_t sh_xn_ni1_ni_cmp_exp_data0_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_ni1_ni_cmp_exp_data0_s;
+-} sh_xn_ni1_ni_cmp_exp_data0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI1_NI_CMP_EXP_DATA1" */
+ /* NI1 compare NI input expected data1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni1_ni_cmp_exp_data1_u {
+- mmr_t sh_xn_ni1_ni_cmp_exp_data1_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_ni1_ni_cmp_exp_data1_s;
+-} sh_xn_ni1_ni_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_ni1_ni_cmp_exp_data1_u {
+ mmr_t sh_xn_ni1_ni_cmp_exp_data1_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_ni1_ni_cmp_exp_data1_s;
+ } sh_xn_ni1_ni_cmp_exp_data1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI1_NI_CMP_ENABLE0" */
+ /* NI1 compare NI input enable0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni1_ni_cmp_enable0_u {
+- mmr_t sh_xn_ni1_ni_cmp_enable0_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_ni1_ni_cmp_enable0_s;
+-} sh_xn_ni1_ni_cmp_enable0_u_t;
+-#else
+ typedef union sh_xn_ni1_ni_cmp_enable0_u {
+ mmr_t sh_xn_ni1_ni_cmp_enable0_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_ni1_ni_cmp_enable0_s;
+ } sh_xn_ni1_ni_cmp_enable0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI1_NI_CMP_ENABLE1" */
+ /* NI1 compare NI input enable1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni1_ni_cmp_enable1_u {
+- mmr_t sh_xn_ni1_ni_cmp_enable1_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_ni1_ni_cmp_enable1_s;
+-} sh_xn_ni1_ni_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_ni1_ni_cmp_enable1_u {
+ mmr_t sh_xn_ni1_ni_cmp_enable1_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_ni1_ni_cmp_enable1_s;
+ } sh_xn_ni1_ni_cmp_enable1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI1_LLP_CMP_EXP_DATA0" */
+ /* NI1 compare LLP input expected data0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_ni1_llp_cmp_exp_data0_u {
+ mmr_t sh_xn_ni1_llp_cmp_exp_data0_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_ni1_llp_cmp_exp_data0_s;
+ } sh_xn_ni1_llp_cmp_exp_data0_u_t;
+-#else
+-typedef union sh_xn_ni1_llp_cmp_exp_data0_u {
+- mmr_t sh_xn_ni1_llp_cmp_exp_data0_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_ni1_llp_cmp_exp_data0_s;
+-} sh_xn_ni1_llp_cmp_exp_data0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI1_LLP_CMP_EXP_DATA1" */
+ /* NI1 compare LLP input expected data1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni1_llp_cmp_exp_data1_u {
+- mmr_t sh_xn_ni1_llp_cmp_exp_data1_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_ni1_llp_cmp_exp_data1_s;
+-} sh_xn_ni1_llp_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_ni1_llp_cmp_exp_data1_u {
+ mmr_t sh_xn_ni1_llp_cmp_exp_data1_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_ni1_llp_cmp_exp_data1_s;
+ } sh_xn_ni1_llp_cmp_exp_data1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI1_LLP_CMP_ENABLE0" */
+ /* NI1 compare LLP input enable0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_ni1_llp_cmp_enable0_u {
+ mmr_t sh_xn_ni1_llp_cmp_enable0_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_ni1_llp_cmp_enable0_s;
+ } sh_xn_ni1_llp_cmp_enable0_u_t;
+-#else
+-typedef union sh_xn_ni1_llp_cmp_enable0_u {
+- mmr_t sh_xn_ni1_llp_cmp_enable0_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_ni1_llp_cmp_enable0_s;
+-} sh_xn_ni1_llp_cmp_enable0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_NI1_LLP_CMP_ENABLE1" */
+ /* NI1 compare LLP input enable1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni1_llp_cmp_enable1_u {
+- mmr_t sh_xn_ni1_llp_cmp_enable1_regval;
+- struct {
+- mmr_t enable : 64;
+- } sh_xn_ni1_llp_cmp_enable1_s;
+-} sh_xn_ni1_llp_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_ni1_llp_cmp_enable1_u {
+ mmr_t sh_xn_ni1_llp_cmp_enable1_regval;
+ struct {
+ mmr_t enable : 64;
+ } sh_xn_ni1_llp_cmp_enable1_s;
+ } sh_xn_ni1_llp_cmp_enable1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNPI_ECC_INJ_REG" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnpi_ecc_inj_reg_u {
+ mmr_t sh_xnpi_ecc_inj_reg_regval;
+ struct {
+@@ -13182,123 +7173,55 @@
+ mmr_t data_cb_cont3 : 1;
+ } sh_xnpi_ecc_inj_reg_s;
+ } sh_xnpi_ecc_inj_reg_u_t;
+-#else
+-typedef union sh_xnpi_ecc_inj_reg_u {
+- mmr_t sh_xnpi_ecc_inj_reg_regval;
+- struct {
+- mmr_t data_cb_cont3 : 1;
+- mmr_t data_cb_1shot3 : 1;
+- mmr_t data_cont3 : 1;
+- mmr_t data_1shot3 : 1;
+- mmr_t reserved_3 : 4;
+- mmr_t byte3 : 8;
+- mmr_t data_cb_cont2 : 1;
+- mmr_t data_cb_1shot2 : 1;
+- mmr_t data_cont2 : 1;
+- mmr_t data_1shot2 : 1;
+- mmr_t reserved_2 : 4;
+- mmr_t byte2 : 8;
+- mmr_t data_cb_cont1 : 1;
+- mmr_t data_cb_1shot1 : 1;
+- mmr_t data_cont1 : 1;
+- mmr_t data_1shot1 : 1;
+- mmr_t reserved_1 : 4;
+- mmr_t byte1 : 8;
+- mmr_t data_cb_cont0 : 1;
+- mmr_t data_cb_1shot0 : 1;
+- mmr_t data_cont0 : 1;
+- mmr_t data_1shot0 : 1;
+- mmr_t reserved_0 : 4;
+- mmr_t byte0 : 8;
+- } sh_xnpi_ecc_inj_reg_s;
+-} sh_xnpi_ecc_inj_reg_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNPI_ECC0_INJ_MASK_REG" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xnpi_ecc0_inj_mask_reg_u {
+- mmr_t sh_xnpi_ecc0_inj_mask_reg_regval;
+- struct {
+- mmr_t mask_ecc0 : 64;
+- } sh_xnpi_ecc0_inj_mask_reg_s;
+-} sh_xnpi_ecc0_inj_mask_reg_u_t;
+-#else
+ typedef union sh_xnpi_ecc0_inj_mask_reg_u {
+ mmr_t sh_xnpi_ecc0_inj_mask_reg_regval;
+ struct {
+ mmr_t mask_ecc0 : 64;
+ } sh_xnpi_ecc0_inj_mask_reg_s;
+ } sh_xnpi_ecc0_inj_mask_reg_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNPI_ECC1_INJ_MASK_REG" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xnpi_ecc1_inj_mask_reg_u {
+- mmr_t sh_xnpi_ecc1_inj_mask_reg_regval;
+- struct {
+- mmr_t mask_ecc1 : 64;
+- } sh_xnpi_ecc1_inj_mask_reg_s;
+-} sh_xnpi_ecc1_inj_mask_reg_u_t;
+-#else
+ typedef union sh_xnpi_ecc1_inj_mask_reg_u {
+ mmr_t sh_xnpi_ecc1_inj_mask_reg_regval;
+ struct {
+ mmr_t mask_ecc1 : 64;
+ } sh_xnpi_ecc1_inj_mask_reg_s;
+ } sh_xnpi_ecc1_inj_mask_reg_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNPI_ECC2_INJ_MASK_REG" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xnpi_ecc2_inj_mask_reg_u {
+- mmr_t sh_xnpi_ecc2_inj_mask_reg_regval;
+- struct {
+- mmr_t mask_ecc2 : 64;
+- } sh_xnpi_ecc2_inj_mask_reg_s;
+-} sh_xnpi_ecc2_inj_mask_reg_u_t;
+-#else
+ typedef union sh_xnpi_ecc2_inj_mask_reg_u {
+ mmr_t sh_xnpi_ecc2_inj_mask_reg_regval;
+ struct {
+ mmr_t mask_ecc2 : 64;
+ } sh_xnpi_ecc2_inj_mask_reg_s;
+ } sh_xnpi_ecc2_inj_mask_reg_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNPI_ECC3_INJ_MASK_REG" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xnpi_ecc3_inj_mask_reg_u {
+- mmr_t sh_xnpi_ecc3_inj_mask_reg_regval;
+- struct {
+- mmr_t mask_ecc3 : 64;
+- } sh_xnpi_ecc3_inj_mask_reg_s;
+-} sh_xnpi_ecc3_inj_mask_reg_u_t;
+-#else
+ typedef union sh_xnpi_ecc3_inj_mask_reg_u {
+ mmr_t sh_xnpi_ecc3_inj_mask_reg_regval;
+ struct {
+ mmr_t mask_ecc3 : 64;
+ } sh_xnpi_ecc3_inj_mask_reg_s;
+ } sh_xnpi_ecc3_inj_mask_reg_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNMD_ECC_INJ_REG" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnmd_ecc_inj_reg_u {
+ mmr_t sh_xnmd_ecc_inj_reg_regval;
+ struct {
+@@ -13328,123 +7251,55 @@
+ mmr_t data_cb_cont3 : 1;
+ } sh_xnmd_ecc_inj_reg_s;
+ } sh_xnmd_ecc_inj_reg_u_t;
+-#else
+-typedef union sh_xnmd_ecc_inj_reg_u {
+- mmr_t sh_xnmd_ecc_inj_reg_regval;
+- struct {
+- mmr_t data_cb_cont3 : 1;
+- mmr_t data_cb_1shot3 : 1;
+- mmr_t data_cont3 : 1;
+- mmr_t data_1shot3 : 1;
+- mmr_t reserved_3 : 4;
+- mmr_t byte3 : 8;
+- mmr_t data_cb_cont2 : 1;
+- mmr_t data_cb_1shot2 : 1;
+- mmr_t data_cont2 : 1;
+- mmr_t data_1shot2 : 1;
+- mmr_t reserved_2 : 4;
+- mmr_t byte2 : 8;
+- mmr_t data_cb_cont1 : 1;
+- mmr_t data_cb_1shot1 : 1;
+- mmr_t data_cont1 : 1;
+- mmr_t data_1shot1 : 1;
+- mmr_t reserved_1 : 4;
+- mmr_t byte1 : 8;
+- mmr_t data_cb_cont0 : 1;
+- mmr_t data_cb_1shot0 : 1;
+- mmr_t data_cont0 : 1;
+- mmr_t data_1shot0 : 1;
+- mmr_t reserved_0 : 4;
+- mmr_t byte0 : 8;
+- } sh_xnmd_ecc_inj_reg_s;
+-} sh_xnmd_ecc_inj_reg_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNMD_ECC0_INJ_MASK_REG" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xnmd_ecc0_inj_mask_reg_u {
+- mmr_t sh_xnmd_ecc0_inj_mask_reg_regval;
+- struct {
+- mmr_t mask_ecc0 : 64;
+- } sh_xnmd_ecc0_inj_mask_reg_s;
+-} sh_xnmd_ecc0_inj_mask_reg_u_t;
+-#else
+ typedef union sh_xnmd_ecc0_inj_mask_reg_u {
+ mmr_t sh_xnmd_ecc0_inj_mask_reg_regval;
+ struct {
+ mmr_t mask_ecc0 : 64;
+ } sh_xnmd_ecc0_inj_mask_reg_s;
+ } sh_xnmd_ecc0_inj_mask_reg_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNMD_ECC1_INJ_MASK_REG" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnmd_ecc1_inj_mask_reg_u {
+ mmr_t sh_xnmd_ecc1_inj_mask_reg_regval;
+ struct {
+ mmr_t mask_ecc1 : 64;
+ } sh_xnmd_ecc1_inj_mask_reg_s;
+ } sh_xnmd_ecc1_inj_mask_reg_u_t;
+-#else
+-typedef union sh_xnmd_ecc1_inj_mask_reg_u {
+- mmr_t sh_xnmd_ecc1_inj_mask_reg_regval;
+- struct {
+- mmr_t mask_ecc1 : 64;
+- } sh_xnmd_ecc1_inj_mask_reg_s;
+-} sh_xnmd_ecc1_inj_mask_reg_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNMD_ECC2_INJ_MASK_REG" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xnmd_ecc2_inj_mask_reg_u {
+- mmr_t sh_xnmd_ecc2_inj_mask_reg_regval;
+- struct {
+- mmr_t mask_ecc2 : 64;
+- } sh_xnmd_ecc2_inj_mask_reg_s;
+-} sh_xnmd_ecc2_inj_mask_reg_u_t;
+-#else
+ typedef union sh_xnmd_ecc2_inj_mask_reg_u {
+ mmr_t sh_xnmd_ecc2_inj_mask_reg_regval;
+ struct {
+ mmr_t mask_ecc2 : 64;
+ } sh_xnmd_ecc2_inj_mask_reg_s;
+ } sh_xnmd_ecc2_inj_mask_reg_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNMD_ECC3_INJ_MASK_REG" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xnmd_ecc3_inj_mask_reg_u {
+- mmr_t sh_xnmd_ecc3_inj_mask_reg_regval;
+- struct {
+- mmr_t mask_ecc3 : 64;
+- } sh_xnmd_ecc3_inj_mask_reg_s;
+-} sh_xnmd_ecc3_inj_mask_reg_u_t;
+-#else
+ typedef union sh_xnmd_ecc3_inj_mask_reg_u {
+ mmr_t sh_xnmd_ecc3_inj_mask_reg_regval;
+ struct {
+ mmr_t mask_ecc3 : 64;
+ } sh_xnmd_ecc3_inj_mask_reg_s;
+ } sh_xnmd_ecc3_inj_mask_reg_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNMD_ECC_ERR_REPORT" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnmd_ecc_err_report_u {
+ mmr_t sh_xnmd_ecc_err_report_regval;
+ struct {
+@@ -13458,28 +7313,12 @@
+ mmr_t reserved_3 : 15;
+ } sh_xnmd_ecc_err_report_s;
+ } sh_xnmd_ecc_err_report_u_t;
+-#else
+-typedef union sh_xnmd_ecc_err_report_u {
+- mmr_t sh_xnmd_ecc_err_report_regval;
+- struct {
+- mmr_t reserved_3 : 15;
+- mmr_t ecc_disable3 : 1;
+- mmr_t reserved_2 : 15;
+- mmr_t ecc_disable2 : 1;
+- mmr_t reserved_1 : 15;
+- mmr_t ecc_disable1 : 1;
+- mmr_t reserved_0 : 15;
+- mmr_t ecc_disable0 : 1;
+- } sh_xnmd_ecc_err_report_s;
+-} sh_xnmd_ecc_err_report_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI0_ERROR_SUMMARY_1" */
+ /* ni0 Error Summary Bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_error_summary_1_u {
+ mmr_t sh_ni0_error_summary_1_regval;
+ struct {
+@@ -13549,84 +7388,12 @@
+ mmr_t tail_timeout_ni_vc3 : 1;
+ } sh_ni0_error_summary_1_s;
+ } sh_ni0_error_summary_1_u_t;
+-#else
+-typedef union sh_ni0_error_summary_1_u {
+- mmr_t sh_ni0_error_summary_1_regval;
+- struct {
+- mmr_t tail_timeout_ni_vc3 : 1;
+- mmr_t tail_timeout_ni_vc2 : 1;
+- mmr_t tail_timeout_ni_vc1 : 1;
+- mmr_t tail_timeout_ni_vc0 : 1;
+- mmr_t tail_timeout_fifo13_vc3 : 1;
+- mmr_t tail_timeout_fifo13_vc1 : 1;
+- mmr_t tail_timeout_fifo02_vc2 : 1;
+- mmr_t tail_timeout_fifo02_vc0 : 1;
+- mmr_t overflow_ni_fifo_vc3_credit : 1;
+- mmr_t overflow_ni_fifo_vc2_credit : 1;
+- mmr_t overflow_ni_fifo_vc1_credit : 1;
+- mmr_t overflow_ni_fifo_vc0_credit : 1;
+- mmr_t overflow_md_fifo_vc2_credit : 1;
+- mmr_t overflow_md_fifo_vc0_credit : 1;
+- mmr_t overflow_iilb_fifo_vc2_credit : 1;
+- mmr_t overflow_iilb_fifo_vc0_credit : 1;
+- mmr_t overflow_pi_fifo_vc2_credit : 1;
+- mmr_t overflow_pi_fifo_vc0_credit : 1;
+- mmr_t overflow_md_fifo_vc2_push : 1;
+- mmr_t overflow_md_fifo_vc0_push : 1;
+- mmr_t overflow_iilb_fifo_vc2_push : 1;
+- mmr_t overflow_iilb_fifo_vc0_push : 1;
+- mmr_t overflow_pi_fifo_vc2_push : 1;
+- mmr_t overflow_pi_fifo_vc0_push : 1;
+- mmr_t overflow_ni_fifo_vc2_pop : 1;
+- mmr_t overflow_ni_fifo_vc0_pop : 1;
+- mmr_t overflow_md_fifo_vc2_pop : 1;
+- mmr_t overflow_md_fifo_vc0_pop : 1;
+- mmr_t overflow_iilb_fifo_vc2_pop : 1;
+- mmr_t overflow_iilb_fifo_vc0_pop : 1;
+- mmr_t overflow_pi_fifo_vc2_pop : 1;
+- mmr_t overflow_pi_fifo_vc0_pop : 1;
+- mmr_t overflow_ni_fifo_debit3 : 1;
+- mmr_t overflow_ni_fifo_debit2 : 1;
+- mmr_t overflow_ni_fifo_debit1 : 1;
+- mmr_t overflow_ni_fifo_debit0 : 1;
+- mmr_t overflow_md_fifo_debit2 : 1;
+- mmr_t overflow_md_fifo_debit0 : 1;
+- mmr_t overflow_iilb_fifo_debit2 : 1;
+- mmr_t overflow_iilb_fifo_debit0 : 1;
+- mmr_t overflow_pi_fifo_debit2 : 1;
+- mmr_t overflow_pi_fifo_debit0 : 1;
+- mmr_t overflow2_vc2_credit : 1;
+- mmr_t overflow1_vc2_credit : 1;
+- mmr_t overflow0_vc2_credit : 1;
+- mmr_t overflow2_vc0_credit : 1;
+- mmr_t overflow1_vc0_credit : 1;
+- mmr_t overflow0_vc0_credit : 1;
+- mmr_t overflow_fifo13_vc2_credit : 1;
+- mmr_t overflow_fifo13_vc0_credit : 1;
+- mmr_t overflow_fifo02_vc2_credit : 1;
+- mmr_t overflow_fifo02_vc0_credit : 1;
+- mmr_t overflow_fifo13_vc3_push : 1;
+- mmr_t overflow_fifo13_vc1_push : 1;
+- mmr_t overflow_fifo02_vc2_push : 1;
+- mmr_t overflow_fifo02_vc0_push : 1;
+- mmr_t overflow_fifo13_vc3_pop : 1;
+- mmr_t overflow_fifo13_vc1_pop : 1;
+- mmr_t overflow_fifo02_vc2_pop : 1;
+- mmr_t overflow_fifo02_vc0_pop : 1;
+- mmr_t overflow_fifo13_debit2 : 1;
+- mmr_t overflow_fifo13_debit0 : 1;
+- mmr_t overflow_fifo02_debit2 : 1;
+- mmr_t overflow_fifo02_debit0 : 1;
+- } sh_ni0_error_summary_1_s;
+-} sh_ni0_error_summary_1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI0_ERROR_SUMMARY_2" */
+ /* ni0 Error Summary Bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_error_summary_2_u {
+ mmr_t sh_ni0_error_summary_2_regval;
+ struct {
+@@ -13687,75 +7454,12 @@
+ mmr_t reserved_1 : 1;
+ } sh_ni0_error_summary_2_s;
+ } sh_ni0_error_summary_2_u_t;
+-#else
+-typedef union sh_ni0_error_summary_2_u {
+- mmr_t sh_ni0_error_summary_2_regval;
+- struct {
+- mmr_t reserved_1 : 1;
+- mmr_t retry_timeout_error : 1;
+- mmr_t lut_read_error : 1;
+- mmr_t chiplet_nomatch : 1;
+- mmr_t llp_deadlock_vc3 : 1;
+- mmr_t llp_deadlock_vc2 : 1;
+- mmr_t llp_deadlock_vc1 : 1;
+- mmr_t llp_deadlock_vc0 : 1;
+- mmr_t underflow_ni_fifo_vc3_credit : 1;
+- mmr_t underflow_ni_fifo_vc2_credit : 1;
+- mmr_t underflow_ni_fifo_vc1_credit : 1;
+- mmr_t underflow_ni_fifo_vc0_credit : 1;
+- mmr_t underflow_md_fifo_vc2_credit : 1;
+- mmr_t underflow_md_fifo_vc0_credit : 1;
+- mmr_t underflow_iilb_fifo_vc2_credit : 1;
+- mmr_t underflow_iilb_fifo_vc0_credit : 1;
+- mmr_t underflow_pi_fifo_vc2_credit : 1;
+- mmr_t underflow_pi_fifo_vc0_credit : 1;
+- mmr_t underflow_md_fifo_vc2_push : 1;
+- mmr_t underflow_md_fifo_vc0_push : 1;
+- mmr_t underflow_iilb_fifo_vc2_push : 1;
+- mmr_t underflow_iilb_fifo_vc0_push : 1;
+- mmr_t underflow_pi_fifo_vc2_push : 1;
+- mmr_t underflow_pi_fifo_vc0_push : 1;
+- mmr_t underflow_ni_fifo_vc2_pop : 1;
+- mmr_t underflow_ni_fifo_vc0_pop : 1;
+- mmr_t underflow_md_fifo_vc2_pop : 1;
+- mmr_t underflow_md_fifo_vc0_pop : 1;
+- mmr_t underflow_iilb_fifo_vc2_pop : 1;
+- mmr_t underflow_iilb_fifo_vc0_pop : 1;
+- mmr_t underflow_pi_fifo_vc2_pop : 1;
+- mmr_t underflow_pi_fifo_vc0_pop : 1;
+- mmr_t reserved_0 : 10;
+- mmr_t underflow2_vc2_credit : 1;
+- mmr_t underflow1_vc2_credit : 1;
+- mmr_t underflow0_vc2_credit : 1;
+- mmr_t underflow2_vc0_credit : 1;
+- mmr_t underflow1_vc0_credit : 1;
+- mmr_t underflow0_vc0_credit : 1;
+- mmr_t underflow_fifo13_vc2_credit : 1;
+- mmr_t underflow_fifo13_vc0_credit : 1;
+- mmr_t underflow_fifo02_vc2_credit : 1;
+- mmr_t underflow_fifo02_vc0_credit : 1;
+- mmr_t underflow_fifo13_vc3_push : 1;
+- mmr_t underflow_fifo13_vc1_push : 1;
+- mmr_t underflow_fifo02_vc2_push : 1;
+- mmr_t underflow_fifo02_vc0_push : 1;
+- mmr_t underflow_fifo13_vc3_pop : 1;
+- mmr_t underflow_fifo13_vc1_pop : 1;
+- mmr_t underflow_fifo02_vc2_pop : 1;
+- mmr_t underflow_fifo02_vc0_pop : 1;
+- mmr_t illegal_vciilb : 1;
+- mmr_t illegal_vcmd : 1;
+- mmr_t illegal_vcpi : 1;
+- mmr_t illegal_vcni : 1;
+- } sh_ni0_error_summary_2_s;
+-} sh_ni0_error_summary_2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI0_ERROR_OVERFLOW_1" */
+ /* ni0 Error Overflow Bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_error_overflow_1_u {
+ mmr_t sh_ni0_error_overflow_1_regval;
+ struct {
+@@ -13825,84 +7529,12 @@
+ mmr_t tail_timeout_ni_vc3 : 1;
+ } sh_ni0_error_overflow_1_s;
+ } sh_ni0_error_overflow_1_u_t;
+-#else
+-typedef union sh_ni0_error_overflow_1_u {
+- mmr_t sh_ni0_error_overflow_1_regval;
+- struct {
+- mmr_t tail_timeout_ni_vc3 : 1;
+- mmr_t tail_timeout_ni_vc2 : 1;
+- mmr_t tail_timeout_ni_vc1 : 1;
+- mmr_t tail_timeout_ni_vc0 : 1;
+- mmr_t tail_timeout_fifo13_vc3 : 1;
+- mmr_t tail_timeout_fifo13_vc1 : 1;
+- mmr_t tail_timeout_fifo02_vc2 : 1;
+- mmr_t tail_timeout_fifo02_vc0 : 1;
+- mmr_t overflow_ni_fifo_vc3_credit : 1;
+- mmr_t overflow_ni_fifo_vc2_credit : 1;
+- mmr_t overflow_ni_fifo_vc1_credit : 1;
+- mmr_t overflow_ni_fifo_vc0_credit : 1;
+- mmr_t overflow_md_fifo_vc2_credit : 1;
+- mmr_t overflow_md_fifo_vc0_credit : 1;
+- mmr_t overflow_iilb_fifo_vc2_credit : 1;
+- mmr_t overflow_iilb_fifo_vc0_credit : 1;
+- mmr_t overflow_pi_fifo_vc2_credit : 1;
+- mmr_t overflow_pi_fifo_vc0_credit : 1;
+- mmr_t overflow_md_fifo_vc2_push : 1;
+- mmr_t overflow_md_fifo_vc0_push : 1;
+- mmr_t overflow_iilb_fifo_vc2_push : 1;
+- mmr_t overflow_iilb_fifo_vc0_push : 1;
+- mmr_t overflow_pi_fifo_vc2_push : 1;
+- mmr_t overflow_pi_fifo_vc0_push : 1;
+- mmr_t overflow_ni_fifo_vc2_pop : 1;
+- mmr_t overflow_ni_fifo_vc0_pop : 1;
+- mmr_t overflow_md_fifo_vc2_pop : 1;
+- mmr_t overflow_md_fifo_vc0_pop : 1;
+- mmr_t overflow_iilb_fifo_vc2_pop : 1;
+- mmr_t overflow_iilb_fifo_vc0_pop : 1;
+- mmr_t overflow_pi_fifo_vc2_pop : 1;
+- mmr_t overflow_pi_fifo_vc0_pop : 1;
+- mmr_t overflow_ni_fifo_debit3 : 1;
+- mmr_t overflow_ni_fifo_debit2 : 1;
+- mmr_t overflow_ni_fifo_debit1 : 1;
+- mmr_t overflow_ni_fifo_debit0 : 1;
+- mmr_t overflow_md_fifo_debit2 : 1;
+- mmr_t overflow_md_fifo_debit0 : 1;
+- mmr_t overflow_iilb_fifo_debit2 : 1;
+- mmr_t overflow_iilb_fifo_debit0 : 1;
+- mmr_t overflow_pi_fifo_debit2 : 1;
+- mmr_t overflow_pi_fifo_debit0 : 1;
+- mmr_t overflow2_vc2_credit : 1;
+- mmr_t overflow1_vc2_credit : 1;
+- mmr_t overflow0_vc2_credit : 1;
+- mmr_t overflow2_vc0_credit : 1;
+- mmr_t overflow1_vc0_credit : 1;
+- mmr_t overflow0_vc0_credit : 1;
+- mmr_t overflow_fifo13_vc2_credit : 1;
+- mmr_t overflow_fifo13_vc0_credit : 1;
+- mmr_t overflow_fifo02_vc2_credit : 1;
+- mmr_t overflow_fifo02_vc0_credit : 1;
+- mmr_t overflow_fifo13_vc3_push : 1;
+- mmr_t overflow_fifo13_vc1_push : 1;
+- mmr_t overflow_fifo02_vc2_push : 1;
+- mmr_t overflow_fifo02_vc0_push : 1;
+- mmr_t overflow_fifo13_vc3_pop : 1;
+- mmr_t overflow_fifo13_vc1_pop : 1;
+- mmr_t overflow_fifo02_vc2_pop : 1;
+- mmr_t overflow_fifo02_vc0_pop : 1;
+- mmr_t overflow_fifo13_debit2 : 1;
+- mmr_t overflow_fifo13_debit0 : 1;
+- mmr_t overflow_fifo02_debit2 : 1;
+- mmr_t overflow_fifo02_debit0 : 1;
+- } sh_ni0_error_overflow_1_s;
+-} sh_ni0_error_overflow_1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI0_ERROR_OVERFLOW_2" */
+ /* ni0 Error Overflow Bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_error_overflow_2_u {
+ mmr_t sh_ni0_error_overflow_2_regval;
+ struct {
+@@ -13963,75 +7595,12 @@
+ mmr_t reserved_1 : 1;
+ } sh_ni0_error_overflow_2_s;
+ } sh_ni0_error_overflow_2_u_t;
+-#else
+-typedef union sh_ni0_error_overflow_2_u {
+- mmr_t sh_ni0_error_overflow_2_regval;
+- struct {
+- mmr_t reserved_1 : 1;
+- mmr_t retry_timeout_error : 1;
+- mmr_t lut_read_error : 1;
+- mmr_t chiplet_nomatch : 1;
+- mmr_t llp_deadlock_vc3 : 1;
+- mmr_t llp_deadlock_vc2 : 1;
+- mmr_t llp_deadlock_vc1 : 1;
+- mmr_t llp_deadlock_vc0 : 1;
+- mmr_t underflow_ni_fifo_vc3_credit : 1;
+- mmr_t underflow_ni_fifo_vc2_credit : 1;
+- mmr_t underflow_ni_fifo_vc1_credit : 1;
+- mmr_t underflow_ni_fifo_vc0_credit : 1;
+- mmr_t underflow_md_fifo_vc2_credit : 1;
+- mmr_t underflow_md_fifo_vc0_credit : 1;
+- mmr_t underflow_iilb_fifo_vc2_credit : 1;
+- mmr_t underflow_iilb_fifo_vc0_credit : 1;
+- mmr_t underflow_pi_fifo_vc2_credit : 1;
+- mmr_t underflow_pi_fifo_vc0_credit : 1;
+- mmr_t underflow_md_fifo_vc2_push : 1;
+- mmr_t underflow_md_fifo_vc0_push : 1;
+- mmr_t underflow_iilb_fifo_vc2_push : 1;
+- mmr_t underflow_iilb_fifo_vc0_push : 1;
+- mmr_t underflow_pi_fifo_vc2_push : 1;
+- mmr_t underflow_pi_fifo_vc0_push : 1;
+- mmr_t underflow_ni_fifo_vc2_pop : 1;
+- mmr_t underflow_ni_fifo_vc0_pop : 1;
+- mmr_t underflow_md_fifo_vc2_pop : 1;
+- mmr_t underflow_md_fifo_vc0_pop : 1;
+- mmr_t underflow_iilb_fifo_vc2_pop : 1;
+- mmr_t underflow_iilb_fifo_vc0_pop : 1;
+- mmr_t underflow_pi_fifo_vc2_pop : 1;
+- mmr_t underflow_pi_fifo_vc0_pop : 1;
+- mmr_t reserved_0 : 10;
+- mmr_t underflow2_vc2_credit : 1;
+- mmr_t underflow1_vc2_credit : 1;
+- mmr_t underflow0_vc2_credit : 1;
+- mmr_t underflow2_vc0_credit : 1;
+- mmr_t underflow1_vc0_credit : 1;
+- mmr_t underflow0_vc0_credit : 1;
+- mmr_t underflow_fifo13_vc2_credit : 1;
+- mmr_t underflow_fifo13_vc0_credit : 1;
+- mmr_t underflow_fifo02_vc2_credit : 1;
+- mmr_t underflow_fifo02_vc0_credit : 1;
+- mmr_t underflow_fifo13_vc3_push : 1;
+- mmr_t underflow_fifo13_vc1_push : 1;
+- mmr_t underflow_fifo02_vc2_push : 1;
+- mmr_t underflow_fifo02_vc0_push : 1;
+- mmr_t underflow_fifo13_vc3_pop : 1;
+- mmr_t underflow_fifo13_vc1_pop : 1;
+- mmr_t underflow_fifo02_vc2_pop : 1;
+- mmr_t underflow_fifo02_vc0_pop : 1;
+- mmr_t illegal_vciilb : 1;
+- mmr_t illegal_vcmd : 1;
+- mmr_t illegal_vcpi : 1;
+- mmr_t illegal_vcni : 1;
+- } sh_ni0_error_overflow_2_s;
+-} sh_ni0_error_overflow_2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI0_ERROR_MASK_1" */
+ /* ni0 Error Mask Bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_error_mask_1_u {
+ mmr_t sh_ni0_error_mask_1_regval;
+ struct {
+@@ -14101,84 +7670,12 @@
+ mmr_t tail_timeout_ni_vc3 : 1;
+ } sh_ni0_error_mask_1_s;
+ } sh_ni0_error_mask_1_u_t;
+-#else
+-typedef union sh_ni0_error_mask_1_u {
+- mmr_t sh_ni0_error_mask_1_regval;
+- struct {
+- mmr_t tail_timeout_ni_vc3 : 1;
+- mmr_t tail_timeout_ni_vc2 : 1;
+- mmr_t tail_timeout_ni_vc1 : 1;
+- mmr_t tail_timeout_ni_vc0 : 1;
+- mmr_t tail_timeout_fifo13_vc3 : 1;
+- mmr_t tail_timeout_fifo13_vc1 : 1;
+- mmr_t tail_timeout_fifo02_vc2 : 1;
+- mmr_t tail_timeout_fifo02_vc0 : 1;
+- mmr_t overflow_ni_fifo_vc3_credit : 1;
+- mmr_t overflow_ni_fifo_vc2_credit : 1;
+- mmr_t overflow_ni_fifo_vc1_credit : 1;
+- mmr_t overflow_ni_fifo_vc0_credit : 1;
+- mmr_t overflow_md_fifo_vc2_credit : 1;
+- mmr_t overflow_md_fifo_vc0_credit : 1;
+- mmr_t overflow_iilb_fifo_vc2_credit : 1;
+- mmr_t overflow_iilb_fifo_vc0_credit : 1;
+- mmr_t overflow_pi_fifo_vc2_credit : 1;
+- mmr_t overflow_pi_fifo_vc0_credit : 1;
+- mmr_t overflow_md_fifo_vc2_push : 1;
+- mmr_t overflow_md_fifo_vc0_push : 1;
+- mmr_t overflow_iilb_fifo_vc2_push : 1;
+- mmr_t overflow_iilb_fifo_vc0_push : 1;
+- mmr_t overflow_pi_fifo_vc2_push : 1;
+- mmr_t overflow_pi_fifo_vc0_push : 1;
+- mmr_t overflow_ni_fifo_vc2_pop : 1;
+- mmr_t overflow_ni_fifo_vc0_pop : 1;
+- mmr_t overflow_md_fifo_vc2_pop : 1;
+- mmr_t overflow_md_fifo_vc0_pop : 1;
+- mmr_t overflow_iilb_fifo_vc2_pop : 1;
+- mmr_t overflow_iilb_fifo_vc0_pop : 1;
+- mmr_t overflow_pi_fifo_vc2_pop : 1;
+- mmr_t overflow_pi_fifo_vc0_pop : 1;
+- mmr_t overflow_ni_fifo_debit3 : 1;
+- mmr_t overflow_ni_fifo_debit2 : 1;
+- mmr_t overflow_ni_fifo_debit1 : 1;
+- mmr_t overflow_ni_fifo_debit0 : 1;
+- mmr_t overflow_md_fifo_debit2 : 1;
+- mmr_t overflow_md_fifo_debit0 : 1;
+- mmr_t overflow_iilb_fifo_debit2 : 1;
+- mmr_t overflow_iilb_fifo_debit0 : 1;
+- mmr_t overflow_pi_fifo_debit2 : 1;
+- mmr_t overflow_pi_fifo_debit0 : 1;
+- mmr_t overflow2_vc2_credit : 1;
+- mmr_t overflow1_vc2_credit : 1;
+- mmr_t overflow0_vc2_credit : 1;
+- mmr_t overflow2_vc0_credit : 1;
+- mmr_t overflow1_vc0_credit : 1;
+- mmr_t overflow0_vc0_credit : 1;
+- mmr_t overflow_fifo13_vc2_credit : 1;
+- mmr_t overflow_fifo13_vc0_credit : 1;
+- mmr_t overflow_fifo02_vc2_credit : 1;
+- mmr_t overflow_fifo02_vc0_credit : 1;
+- mmr_t overflow_fifo13_vc3_push : 1;
+- mmr_t overflow_fifo13_vc1_push : 1;
+- mmr_t overflow_fifo02_vc2_push : 1;
+- mmr_t overflow_fifo02_vc0_push : 1;
+- mmr_t overflow_fifo13_vc3_pop : 1;
+- mmr_t overflow_fifo13_vc1_pop : 1;
+- mmr_t overflow_fifo02_vc2_pop : 1;
+- mmr_t overflow_fifo02_vc0_pop : 1;
+- mmr_t overflow_fifo13_debit2 : 1;
+- mmr_t overflow_fifo13_debit0 : 1;
+- mmr_t overflow_fifo02_debit2 : 1;
+- mmr_t overflow_fifo02_debit0 : 1;
+- } sh_ni0_error_mask_1_s;
+-} sh_ni0_error_mask_1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI0_ERROR_MASK_2" */
+ /* ni0 Error Mask Bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_error_mask_2_u {
+ mmr_t sh_ni0_error_mask_2_regval;
+ struct {
+@@ -14239,77 +7736,14 @@
+ mmr_t reserved_1 : 1;
+ } sh_ni0_error_mask_2_s;
+ } sh_ni0_error_mask_2_u_t;
+-#else
+-typedef union sh_ni0_error_mask_2_u {
+- mmr_t sh_ni0_error_mask_2_regval;
+- struct {
+- mmr_t reserved_1 : 1;
+- mmr_t retry_timeout_error : 1;
+- mmr_t lut_read_error : 1;
+- mmr_t chiplet_nomatch : 1;
+- mmr_t llp_deadlock_vc3 : 1;
+- mmr_t llp_deadlock_vc2 : 1;
+- mmr_t llp_deadlock_vc1 : 1;
+- mmr_t llp_deadlock_vc0 : 1;
+- mmr_t underflow_ni_fifo_vc3_credit : 1;
+- mmr_t underflow_ni_fifo_vc2_credit : 1;
+- mmr_t underflow_ni_fifo_vc1_credit : 1;
+- mmr_t underflow_ni_fifo_vc0_credit : 1;
+- mmr_t underflow_md_fifo_vc2_credit : 1;
+- mmr_t underflow_md_fifo_vc0_credit : 1;
+- mmr_t underflow_iilb_fifo_vc2_credit : 1;
+- mmr_t underflow_iilb_fifo_vc0_credit : 1;
+- mmr_t underflow_pi_fifo_vc2_credit : 1;
+- mmr_t underflow_pi_fifo_vc0_credit : 1;
+- mmr_t underflow_md_fifo_vc2_push : 1;
+- mmr_t underflow_md_fifo_vc0_push : 1;
+- mmr_t underflow_iilb_fifo_vc2_push : 1;
+- mmr_t underflow_iilb_fifo_vc0_push : 1;
+- mmr_t underflow_pi_fifo_vc2_push : 1;
+- mmr_t underflow_pi_fifo_vc0_push : 1;
+- mmr_t underflow_ni_fifo_vc2_pop : 1;
+- mmr_t underflow_ni_fifo_vc0_pop : 1;
+- mmr_t underflow_md_fifo_vc2_pop : 1;
+- mmr_t underflow_md_fifo_vc0_pop : 1;
+- mmr_t underflow_iilb_fifo_vc2_pop : 1;
+- mmr_t underflow_iilb_fifo_vc0_pop : 1;
+- mmr_t underflow_pi_fifo_vc2_pop : 1;
+- mmr_t underflow_pi_fifo_vc0_pop : 1;
+- mmr_t reserved_0 : 10;
+- mmr_t underflow2_vc2_credit : 1;
+- mmr_t underflow1_vc2_credit : 1;
+- mmr_t underflow0_vc2_credit : 1;
+- mmr_t underflow2_vc0_credit : 1;
+- mmr_t underflow1_vc0_credit : 1;
+- mmr_t underflow0_vc0_credit : 1;
+- mmr_t underflow_fifo13_vc2_credit : 1;
+- mmr_t underflow_fifo13_vc0_credit : 1;
+- mmr_t underflow_fifo02_vc2_credit : 1;
+- mmr_t underflow_fifo02_vc0_credit : 1;
+- mmr_t underflow_fifo13_vc3_push : 1;
+- mmr_t underflow_fifo13_vc1_push : 1;
+- mmr_t underflow_fifo02_vc2_push : 1;
+- mmr_t underflow_fifo02_vc0_push : 1;
+- mmr_t underflow_fifo13_vc3_pop : 1;
+- mmr_t underflow_fifo13_vc1_pop : 1;
+- mmr_t underflow_fifo02_vc2_pop : 1;
+- mmr_t underflow_fifo02_vc0_pop : 1;
+- mmr_t illegal_vciilb : 1;
+- mmr_t illegal_vcmd : 1;
+- mmr_t illegal_vcpi : 1;
+- mmr_t illegal_vcni : 1;
+- } sh_ni0_error_mask_2_s;
+-} sh_ni0_error_mask_2_u_t;
+-#endif
+-
+-/* ==================================================================== */
+-/* Register "SH_NI0_FIRST_ERROR_1" */
+-/* ni0 First Error Bits */
+-/* ==================================================================== */
+-
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_ni0_first_error_1_u {
+- mmr_t sh_ni0_first_error_1_regval;
++
++/* ==================================================================== */
++/* Register "SH_NI0_FIRST_ERROR_1" */
++/* ni0 First Error Bits */
++/* ==================================================================== */
++
++typedef union sh_ni0_first_error_1_u {
++ mmr_t sh_ni0_first_error_1_regval;
+ struct {
+ mmr_t overflow_fifo02_debit0 : 1;
+ mmr_t overflow_fifo02_debit2 : 1;
+@@ -14377,84 +7811,12 @@
+ mmr_t tail_timeout_ni_vc3 : 1;
+ } sh_ni0_first_error_1_s;
+ } sh_ni0_first_error_1_u_t;
+-#else
+-typedef union sh_ni0_first_error_1_u {
+- mmr_t sh_ni0_first_error_1_regval;
+- struct {
+- mmr_t tail_timeout_ni_vc3 : 1;
+- mmr_t tail_timeout_ni_vc2 : 1;
+- mmr_t tail_timeout_ni_vc1 : 1;
+- mmr_t tail_timeout_ni_vc0 : 1;
+- mmr_t tail_timeout_fifo13_vc3 : 1;
+- mmr_t tail_timeout_fifo13_vc1 : 1;
+- mmr_t tail_timeout_fifo02_vc2 : 1;
+- mmr_t tail_timeout_fifo02_vc0 : 1;
+- mmr_t overflow_ni_fifo_vc3_credit : 1;
+- mmr_t overflow_ni_fifo_vc2_credit : 1;
+- mmr_t overflow_ni_fifo_vc1_credit : 1;
+- mmr_t overflow_ni_fifo_vc0_credit : 1;
+- mmr_t overflow_md_fifo_vc2_credit : 1;
+- mmr_t overflow_md_fifo_vc0_credit : 1;
+- mmr_t overflow_iilb_fifo_vc2_credit : 1;
+- mmr_t overflow_iilb_fifo_vc0_credit : 1;
+- mmr_t overflow_pi_fifo_vc2_credit : 1;
+- mmr_t overflow_pi_fifo_vc0_credit : 1;
+- mmr_t overflow_md_fifo_vc2_push : 1;
+- mmr_t overflow_md_fifo_vc0_push : 1;
+- mmr_t overflow_iilb_fifo_vc2_push : 1;
+- mmr_t overflow_iilb_fifo_vc0_push : 1;
+- mmr_t overflow_pi_fifo_vc2_push : 1;
+- mmr_t overflow_pi_fifo_vc0_push : 1;
+- mmr_t overflow_ni_fifo_vc2_pop : 1;
+- mmr_t overflow_ni_fifo_vc0_pop : 1;
+- mmr_t overflow_md_fifo_vc2_pop : 1;
+- mmr_t overflow_md_fifo_vc0_pop : 1;
+- mmr_t overflow_iilb_fifo_vc2_pop : 1;
+- mmr_t overflow_iilb_fifo_vc0_pop : 1;
+- mmr_t overflow_pi_fifo_vc2_pop : 1;
+- mmr_t overflow_pi_fifo_vc0_pop : 1;
+- mmr_t overflow_ni_fifo_debit3 : 1;
+- mmr_t overflow_ni_fifo_debit2 : 1;
+- mmr_t overflow_ni_fifo_debit1 : 1;
+- mmr_t overflow_ni_fifo_debit0 : 1;
+- mmr_t overflow_md_fifo_debit2 : 1;
+- mmr_t overflow_md_fifo_debit0 : 1;
+- mmr_t overflow_iilb_fifo_debit2 : 1;
+- mmr_t overflow_iilb_fifo_debit0 : 1;
+- mmr_t overflow_pi_fifo_debit2 : 1;
+- mmr_t overflow_pi_fifo_debit0 : 1;
+- mmr_t overflow2_vc2_credit : 1;
+- mmr_t overflow1_vc2_credit : 1;
+- mmr_t overflow0_vc2_credit : 1;
+- mmr_t overflow2_vc0_credit : 1;
+- mmr_t overflow1_vc0_credit : 1;
+- mmr_t overflow0_vc0_credit : 1;
+- mmr_t overflow_fifo13_vc2_credit : 1;
+- mmr_t overflow_fifo13_vc0_credit : 1;
+- mmr_t overflow_fifo02_vc2_credit : 1;
+- mmr_t overflow_fifo02_vc0_credit : 1;
+- mmr_t overflow_fifo13_vc3_push : 1;
+- mmr_t overflow_fifo13_vc1_push : 1;
+- mmr_t overflow_fifo02_vc2_push : 1;
+- mmr_t overflow_fifo02_vc0_push : 1;
+- mmr_t overflow_fifo13_vc3_pop : 1;
+- mmr_t overflow_fifo13_vc1_pop : 1;
+- mmr_t overflow_fifo02_vc2_pop : 1;
+- mmr_t overflow_fifo02_vc0_pop : 1;
+- mmr_t overflow_fifo13_debit2 : 1;
+- mmr_t overflow_fifo13_debit0 : 1;
+- mmr_t overflow_fifo02_debit2 : 1;
+- mmr_t overflow_fifo02_debit0 : 1;
+- } sh_ni0_first_error_1_s;
+-} sh_ni0_first_error_1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI0_FIRST_ERROR_2" */
+ /* ni0 First Error Bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_first_error_2_u {
+ mmr_t sh_ni0_first_error_2_regval;
+ struct {
+@@ -14515,117 +7877,36 @@
+ mmr_t reserved_1 : 1;
+ } sh_ni0_first_error_2_s;
+ } sh_ni0_first_error_2_u_t;
+-#else
+-typedef union sh_ni0_first_error_2_u {
+- mmr_t sh_ni0_first_error_2_regval;
+- struct {
+- mmr_t reserved_1 : 1;
+- mmr_t retry_timeout_error : 1;
+- mmr_t lut_read_error : 1;
+- mmr_t chiplet_nomatch : 1;
+- mmr_t llp_deadlock_vc3 : 1;
+- mmr_t llp_deadlock_vc2 : 1;
+- mmr_t llp_deadlock_vc1 : 1;
+- mmr_t llp_deadlock_vc0 : 1;
+- mmr_t underflow_ni_fifo_vc3_credit : 1;
+- mmr_t underflow_ni_fifo_vc2_credit : 1;
+- mmr_t underflow_ni_fifo_vc1_credit : 1;
+- mmr_t underflow_ni_fifo_vc0_credit : 1;
+- mmr_t underflow_md_fifo_vc2_credit : 1;
+- mmr_t underflow_md_fifo_vc0_credit : 1;
+- mmr_t underflow_iilb_fifo_vc2_credit : 1;
+- mmr_t underflow_iilb_fifo_vc0_credit : 1;
+- mmr_t underflow_pi_fifo_vc2_credit : 1;
+- mmr_t underflow_pi_fifo_vc0_credit : 1;
+- mmr_t underflow_md_fifo_vc2_push : 1;
+- mmr_t underflow_md_fifo_vc0_push : 1;
+- mmr_t underflow_iilb_fifo_vc2_push : 1;
+- mmr_t underflow_iilb_fifo_vc0_push : 1;
+- mmr_t underflow_pi_fifo_vc2_push : 1;
+- mmr_t underflow_pi_fifo_vc0_push : 1;
+- mmr_t underflow_ni_fifo_vc2_pop : 1;
+- mmr_t underflow_ni_fifo_vc0_pop : 1;
+- mmr_t underflow_md_fifo_vc2_pop : 1;
+- mmr_t underflow_md_fifo_vc0_pop : 1;
+- mmr_t underflow_iilb_fifo_vc2_pop : 1;
+- mmr_t underflow_iilb_fifo_vc0_pop : 1;
+- mmr_t underflow_pi_fifo_vc2_pop : 1;
+- mmr_t underflow_pi_fifo_vc0_pop : 1;
+- mmr_t reserved_0 : 10;
+- mmr_t underflow2_vc2_credit : 1;
+- mmr_t underflow1_vc2_credit : 1;
+- mmr_t underflow0_vc2_credit : 1;
+- mmr_t underflow2_vc0_credit : 1;
+- mmr_t underflow1_vc0_credit : 1;
+- mmr_t underflow0_vc0_credit : 1;
+- mmr_t underflow_fifo13_vc2_credit : 1;
+- mmr_t underflow_fifo13_vc0_credit : 1;
+- mmr_t underflow_fifo02_vc2_credit : 1;
+- mmr_t underflow_fifo02_vc0_credit : 1;
+- mmr_t underflow_fifo13_vc3_push : 1;
+- mmr_t underflow_fifo13_vc1_push : 1;
+- mmr_t underflow_fifo02_vc2_push : 1;
+- mmr_t underflow_fifo02_vc0_push : 1;
+- mmr_t underflow_fifo13_vc3_pop : 1;
+- mmr_t underflow_fifo13_vc1_pop : 1;
+- mmr_t underflow_fifo02_vc2_pop : 1;
+- mmr_t underflow_fifo02_vc0_pop : 1;
+- mmr_t illegal_vciilb : 1;
+- mmr_t illegal_vcmd : 1;
+- mmr_t illegal_vcpi : 1;
+- mmr_t illegal_vcni : 1;
+- } sh_ni0_first_error_2_s;
+-} sh_ni0_first_error_2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI0_ERROR_DETAIL_1" */
+ /* ni0 Chiplet no match header bits 63:0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_ni0_error_detail_1_u {
+- mmr_t sh_ni0_error_detail_1_regval;
+- struct {
+- mmr_t header : 64;
+- } sh_ni0_error_detail_1_s;
+-} sh_ni0_error_detail_1_u_t;
+-#else
+ typedef union sh_ni0_error_detail_1_u {
+ mmr_t sh_ni0_error_detail_1_regval;
+ struct {
+ mmr_t header : 64;
+ } sh_ni0_error_detail_1_s;
+ } sh_ni0_error_detail_1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI0_ERROR_DETAIL_2" */
+ /* ni0 Chiplet no match header bits 127:64 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_ni0_error_detail_2_u {
+- mmr_t sh_ni0_error_detail_2_regval;
+- struct {
+- mmr_t header : 64;
+- } sh_ni0_error_detail_2_s;
+-} sh_ni0_error_detail_2_u_t;
+-#else
+ typedef union sh_ni0_error_detail_2_u {
+ mmr_t sh_ni0_error_detail_2_regval;
+ struct {
+ mmr_t header : 64;
+ } sh_ni0_error_detail_2_s;
+ } sh_ni0_error_detail_2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI1_ERROR_SUMMARY_1" */
+ /* ni1 Error Summary Bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_error_summary_1_u {
+ mmr_t sh_ni1_error_summary_1_regval;
+ struct {
+@@ -14695,84 +7976,12 @@
+ mmr_t tail_timeout_ni_vc3 : 1;
+ } sh_ni1_error_summary_1_s;
+ } sh_ni1_error_summary_1_u_t;
+-#else
+-typedef union sh_ni1_error_summary_1_u {
+- mmr_t sh_ni1_error_summary_1_regval;
+- struct {
+- mmr_t tail_timeout_ni_vc3 : 1;
+- mmr_t tail_timeout_ni_vc2 : 1;
+- mmr_t tail_timeout_ni_vc1 : 1;
+- mmr_t tail_timeout_ni_vc0 : 1;
+- mmr_t tail_timeout_fifo13_vc3 : 1;
+- mmr_t tail_timeout_fifo13_vc1 : 1;
+- mmr_t tail_timeout_fifo02_vc2 : 1;
+- mmr_t tail_timeout_fifo02_vc0 : 1;
+- mmr_t overflow_ni_fifo_vc3_credit : 1;
+- mmr_t overflow_ni_fifo_vc2_credit : 1;
+- mmr_t overflow_ni_fifo_vc1_credit : 1;
+- mmr_t overflow_ni_fifo_vc0_credit : 1;
+- mmr_t overflow_md_fifo_vc2_credit : 1;
+- mmr_t overflow_md_fifo_vc0_credit : 1;
+- mmr_t overflow_iilb_fifo_vc2_credit : 1;
+- mmr_t overflow_iilb_fifo_vc0_credit : 1;
+- mmr_t overflow_pi_fifo_vc2_credit : 1;
+- mmr_t overflow_pi_fifo_vc0_credit : 1;
+- mmr_t overflow_md_fifo_vc2_push : 1;
+- mmr_t overflow_md_fifo_vc0_push : 1;
+- mmr_t overflow_iilb_fifo_vc2_push : 1;
+- mmr_t overflow_iilb_fifo_vc0_push : 1;
+- mmr_t overflow_pi_fifo_vc2_push : 1;
+- mmr_t overflow_pi_fifo_vc0_push : 1;
+- mmr_t overflow_ni_fifo_vc2_pop : 1;
+- mmr_t overflow_ni_fifo_vc0_pop : 1;
+- mmr_t overflow_md_fifo_vc2_pop : 1;
+- mmr_t overflow_md_fifo_vc0_pop : 1;
+- mmr_t overflow_iilb_fifo_vc2_pop : 1;
+- mmr_t overflow_iilb_fifo_vc0_pop : 1;
+- mmr_t overflow_pi_fifo_vc2_pop : 1;
+- mmr_t overflow_pi_fifo_vc0_pop : 1;
+- mmr_t overflow_ni_fifo_debit3 : 1;
+- mmr_t overflow_ni_fifo_debit2 : 1;
+- mmr_t overflow_ni_fifo_debit1 : 1;
+- mmr_t overflow_ni_fifo_debit0 : 1;
+- mmr_t overflow_md_fifo_debit2 : 1;
+- mmr_t overflow_md_fifo_debit0 : 1;
+- mmr_t overflow_iilb_fifo_debit2 : 1;
+- mmr_t overflow_iilb_fifo_debit0 : 1;
+- mmr_t overflow_pi_fifo_debit2 : 1;
+- mmr_t overflow_pi_fifo_debit0 : 1;
+- mmr_t overflow2_vc2_credit : 1;
+- mmr_t overflow1_vc2_credit : 1;
+- mmr_t overflow0_vc2_credit : 1;
+- mmr_t overflow2_vc0_credit : 1;
+- mmr_t overflow1_vc0_credit : 1;
+- mmr_t overflow0_vc0_credit : 1;
+- mmr_t overflow_fifo13_vc2_credit : 1;
+- mmr_t overflow_fifo13_vc0_credit : 1;
+- mmr_t overflow_fifo02_vc2_credit : 1;
+- mmr_t overflow_fifo02_vc0_credit : 1;
+- mmr_t overflow_fifo13_vc3_push : 1;
+- mmr_t overflow_fifo13_vc1_push : 1;
+- mmr_t overflow_fifo02_vc2_push : 1;
+- mmr_t overflow_fifo02_vc0_push : 1;
+- mmr_t overflow_fifo13_vc3_pop : 1;
+- mmr_t overflow_fifo13_vc1_pop : 1;
+- mmr_t overflow_fifo02_vc2_pop : 1;
+- mmr_t overflow_fifo02_vc0_pop : 1;
+- mmr_t overflow_fifo13_debit2 : 1;
+- mmr_t overflow_fifo13_debit0 : 1;
+- mmr_t overflow_fifo02_debit2 : 1;
+- mmr_t overflow_fifo02_debit0 : 1;
+- } sh_ni1_error_summary_1_s;
+-} sh_ni1_error_summary_1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI1_ERROR_SUMMARY_2" */
+ /* ni1 Error Summary Bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_error_summary_2_u {
+ mmr_t sh_ni1_error_summary_2_regval;
+ struct {
+@@ -14833,77 +8042,14 @@
+ mmr_t reserved_1 : 1;
+ } sh_ni1_error_summary_2_s;
+ } sh_ni1_error_summary_2_u_t;
+-#else
+-typedef union sh_ni1_error_summary_2_u {
+- mmr_t sh_ni1_error_summary_2_regval;
+- struct {
+- mmr_t reserved_1 : 1;
+- mmr_t retry_timeout_error : 1;
+- mmr_t lut_read_error : 1;
+- mmr_t chiplet_nomatch : 1;
+- mmr_t llp_deadlock_vc3 : 1;
+- mmr_t llp_deadlock_vc2 : 1;
+- mmr_t llp_deadlock_vc1 : 1;
+- mmr_t llp_deadlock_vc0 : 1;
+- mmr_t underflow_ni_fifo_vc3_credit : 1;
+- mmr_t underflow_ni_fifo_vc2_credit : 1;
+- mmr_t underflow_ni_fifo_vc1_credit : 1;
+- mmr_t underflow_ni_fifo_vc0_credit : 1;
+- mmr_t underflow_md_fifo_vc2_credit : 1;
+- mmr_t underflow_md_fifo_vc0_credit : 1;
+- mmr_t underflow_iilb_fifo_vc2_credit : 1;
+- mmr_t underflow_iilb_fifo_vc0_credit : 1;
+- mmr_t underflow_pi_fifo_vc2_credit : 1;
+- mmr_t underflow_pi_fifo_vc0_credit : 1;
+- mmr_t underflow_md_fifo_vc2_push : 1;
+- mmr_t underflow_md_fifo_vc0_push : 1;
+- mmr_t underflow_iilb_fifo_vc2_push : 1;
+- mmr_t underflow_iilb_fifo_vc0_push : 1;
+- mmr_t underflow_pi_fifo_vc2_push : 1;
+- mmr_t underflow_pi_fifo_vc0_push : 1;
+- mmr_t underflow_ni_fifo_vc2_pop : 1;
+- mmr_t underflow_ni_fifo_vc0_pop : 1;
+- mmr_t underflow_md_fifo_vc2_pop : 1;
+- mmr_t underflow_md_fifo_vc0_pop : 1;
+- mmr_t underflow_iilb_fifo_vc2_pop : 1;
+- mmr_t underflow_iilb_fifo_vc0_pop : 1;
+- mmr_t underflow_pi_fifo_vc2_pop : 1;
+- mmr_t underflow_pi_fifo_vc0_pop : 1;
+- mmr_t reserved_0 : 10;
+- mmr_t underflow2_vc2_credit : 1;
+- mmr_t underflow1_vc2_credit : 1;
+- mmr_t underflow0_vc2_credit : 1;
+- mmr_t underflow2_vc0_credit : 1;
+- mmr_t underflow1_vc0_credit : 1;
+- mmr_t underflow0_vc0_credit : 1;
+- mmr_t underflow_fifo13_vc2_credit : 1;
+- mmr_t underflow_fifo13_vc0_credit : 1;
+- mmr_t underflow_fifo02_vc2_credit : 1;
+- mmr_t underflow_fifo02_vc0_credit : 1;
+- mmr_t underflow_fifo13_vc3_push : 1;
+- mmr_t underflow_fifo13_vc1_push : 1;
+- mmr_t underflow_fifo02_vc2_push : 1;
+- mmr_t underflow_fifo02_vc0_push : 1;
+- mmr_t underflow_fifo13_vc3_pop : 1;
+- mmr_t underflow_fifo13_vc1_pop : 1;
+- mmr_t underflow_fifo02_vc2_pop : 1;
+- mmr_t underflow_fifo02_vc0_pop : 1;
+- mmr_t illegal_vciilb : 1;
+- mmr_t illegal_vcmd : 1;
+- mmr_t illegal_vcpi : 1;
+- mmr_t illegal_vcni : 1;
+- } sh_ni1_error_summary_2_s;
+-} sh_ni1_error_summary_2_u_t;
+-#endif
+-
+-/* ==================================================================== */
+-/* Register "SH_NI1_ERROR_OVERFLOW_1" */
+-/* ni1 Error Overflow Bits */
+-/* ==================================================================== */
+-
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_ni1_error_overflow_1_u {
+- mmr_t sh_ni1_error_overflow_1_regval;
++
++/* ==================================================================== */
++/* Register "SH_NI1_ERROR_OVERFLOW_1" */
++/* ni1 Error Overflow Bits */
++/* ==================================================================== */
++
++typedef union sh_ni1_error_overflow_1_u {
++ mmr_t sh_ni1_error_overflow_1_regval;
+ struct {
+ mmr_t overflow_fifo02_debit0 : 1;
+ mmr_t overflow_fifo02_debit2 : 1;
+@@ -14971,84 +8117,12 @@
+ mmr_t tail_timeout_ni_vc3 : 1;
+ } sh_ni1_error_overflow_1_s;
+ } sh_ni1_error_overflow_1_u_t;
+-#else
+-typedef union sh_ni1_error_overflow_1_u {
+- mmr_t sh_ni1_error_overflow_1_regval;
+- struct {
+- mmr_t tail_timeout_ni_vc3 : 1;
+- mmr_t tail_timeout_ni_vc2 : 1;
+- mmr_t tail_timeout_ni_vc1 : 1;
+- mmr_t tail_timeout_ni_vc0 : 1;
+- mmr_t tail_timeout_fifo13_vc3 : 1;
+- mmr_t tail_timeout_fifo13_vc1 : 1;
+- mmr_t tail_timeout_fifo02_vc2 : 1;
+- mmr_t tail_timeout_fifo02_vc0 : 1;
+- mmr_t overflow_ni_fifo_vc3_credit : 1;
+- mmr_t overflow_ni_fifo_vc2_credit : 1;
+- mmr_t overflow_ni_fifo_vc1_credit : 1;
+- mmr_t overflow_ni_fifo_vc0_credit : 1;
+- mmr_t overflow_md_fifo_vc2_credit : 1;
+- mmr_t overflow_md_fifo_vc0_credit : 1;
+- mmr_t overflow_iilb_fifo_vc2_credit : 1;
+- mmr_t overflow_iilb_fifo_vc0_credit : 1;
+- mmr_t overflow_pi_fifo_vc2_credit : 1;
+- mmr_t overflow_pi_fifo_vc0_credit : 1;
+- mmr_t overflow_md_fifo_vc2_push : 1;
+- mmr_t overflow_md_fifo_vc0_push : 1;
+- mmr_t overflow_iilb_fifo_vc2_push : 1;
+- mmr_t overflow_iilb_fifo_vc0_push : 1;
+- mmr_t overflow_pi_fifo_vc2_push : 1;
+- mmr_t overflow_pi_fifo_vc0_push : 1;
+- mmr_t overflow_ni_fifo_vc2_pop : 1;
+- mmr_t overflow_ni_fifo_vc0_pop : 1;
+- mmr_t overflow_md_fifo_vc2_pop : 1;
+- mmr_t overflow_md_fifo_vc0_pop : 1;
+- mmr_t overflow_iilb_fifo_vc2_pop : 1;
+- mmr_t overflow_iilb_fifo_vc0_pop : 1;
+- mmr_t overflow_pi_fifo_vc2_pop : 1;
+- mmr_t overflow_pi_fifo_vc0_pop : 1;
+- mmr_t overflow_ni_fifo_debit3 : 1;
+- mmr_t overflow_ni_fifo_debit2 : 1;
+- mmr_t overflow_ni_fifo_debit1 : 1;
+- mmr_t overflow_ni_fifo_debit0 : 1;
+- mmr_t overflow_md_fifo_debit2 : 1;
+- mmr_t overflow_md_fifo_debit0 : 1;
+- mmr_t overflow_iilb_fifo_debit2 : 1;
+- mmr_t overflow_iilb_fifo_debit0 : 1;
+- mmr_t overflow_pi_fifo_debit2 : 1;
+- mmr_t overflow_pi_fifo_debit0 : 1;
+- mmr_t overflow2_vc2_credit : 1;
+- mmr_t overflow1_vc2_credit : 1;
+- mmr_t overflow0_vc2_credit : 1;
+- mmr_t overflow2_vc0_credit : 1;
+- mmr_t overflow1_vc0_credit : 1;
+- mmr_t overflow0_vc0_credit : 1;
+- mmr_t overflow_fifo13_vc2_credit : 1;
+- mmr_t overflow_fifo13_vc0_credit : 1;
+- mmr_t overflow_fifo02_vc2_credit : 1;
+- mmr_t overflow_fifo02_vc0_credit : 1;
+- mmr_t overflow_fifo13_vc3_push : 1;
+- mmr_t overflow_fifo13_vc1_push : 1;
+- mmr_t overflow_fifo02_vc2_push : 1;
+- mmr_t overflow_fifo02_vc0_push : 1;
+- mmr_t overflow_fifo13_vc3_pop : 1;
+- mmr_t overflow_fifo13_vc1_pop : 1;
+- mmr_t overflow_fifo02_vc2_pop : 1;
+- mmr_t overflow_fifo02_vc0_pop : 1;
+- mmr_t overflow_fifo13_debit2 : 1;
+- mmr_t overflow_fifo13_debit0 : 1;
+- mmr_t overflow_fifo02_debit2 : 1;
+- mmr_t overflow_fifo02_debit0 : 1;
+- } sh_ni1_error_overflow_1_s;
+-} sh_ni1_error_overflow_1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI1_ERROR_OVERFLOW_2" */
+ /* ni1 Error Overflow Bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_error_overflow_2_u {
+ mmr_t sh_ni1_error_overflow_2_regval;
+ struct {
+@@ -15109,75 +8183,12 @@
+ mmr_t reserved_1 : 1;
+ } sh_ni1_error_overflow_2_s;
+ } sh_ni1_error_overflow_2_u_t;
+-#else
+-typedef union sh_ni1_error_overflow_2_u {
+- mmr_t sh_ni1_error_overflow_2_regval;
+- struct {
+- mmr_t reserved_1 : 1;
+- mmr_t retry_timeout_error : 1;
+- mmr_t lut_read_error : 1;
+- mmr_t chiplet_nomatch : 1;
+- mmr_t llp_deadlock_vc3 : 1;
+- mmr_t llp_deadlock_vc2 : 1;
+- mmr_t llp_deadlock_vc1 : 1;
+- mmr_t llp_deadlock_vc0 : 1;
+- mmr_t underflow_ni_fifo_vc3_credit : 1;
+- mmr_t underflow_ni_fifo_vc2_credit : 1;
+- mmr_t underflow_ni_fifo_vc1_credit : 1;
+- mmr_t underflow_ni_fifo_vc0_credit : 1;
+- mmr_t underflow_md_fifo_vc2_credit : 1;
+- mmr_t underflow_md_fifo_vc0_credit : 1;
+- mmr_t underflow_iilb_fifo_vc2_credit : 1;
+- mmr_t underflow_iilb_fifo_vc0_credit : 1;
+- mmr_t underflow_pi_fifo_vc2_credit : 1;
+- mmr_t underflow_pi_fifo_vc0_credit : 1;
+- mmr_t underflow_md_fifo_vc2_push : 1;
+- mmr_t underflow_md_fifo_vc0_push : 1;
+- mmr_t underflow_iilb_fifo_vc2_push : 1;
+- mmr_t underflow_iilb_fifo_vc0_push : 1;
+- mmr_t underflow_pi_fifo_vc2_push : 1;
+- mmr_t underflow_pi_fifo_vc0_push : 1;
+- mmr_t underflow_ni_fifo_vc2_pop : 1;
+- mmr_t underflow_ni_fifo_vc0_pop : 1;
+- mmr_t underflow_md_fifo_vc2_pop : 1;
+- mmr_t underflow_md_fifo_vc0_pop : 1;
+- mmr_t underflow_iilb_fifo_vc2_pop : 1;
+- mmr_t underflow_iilb_fifo_vc0_pop : 1;
+- mmr_t underflow_pi_fifo_vc2_pop : 1;
+- mmr_t underflow_pi_fifo_vc0_pop : 1;
+- mmr_t reserved_0 : 10;
+- mmr_t underflow2_vc2_credit : 1;
+- mmr_t underflow1_vc2_credit : 1;
+- mmr_t underflow0_vc2_credit : 1;
+- mmr_t underflow2_vc0_credit : 1;
+- mmr_t underflow1_vc0_credit : 1;
+- mmr_t underflow0_vc0_credit : 1;
+- mmr_t underflow_fifo13_vc2_credit : 1;
+- mmr_t underflow_fifo13_vc0_credit : 1;
+- mmr_t underflow_fifo02_vc2_credit : 1;
+- mmr_t underflow_fifo02_vc0_credit : 1;
+- mmr_t underflow_fifo13_vc3_push : 1;
+- mmr_t underflow_fifo13_vc1_push : 1;
+- mmr_t underflow_fifo02_vc2_push : 1;
+- mmr_t underflow_fifo02_vc0_push : 1;
+- mmr_t underflow_fifo13_vc3_pop : 1;
+- mmr_t underflow_fifo13_vc1_pop : 1;
+- mmr_t underflow_fifo02_vc2_pop : 1;
+- mmr_t underflow_fifo02_vc0_pop : 1;
+- mmr_t illegal_vciilb : 1;
+- mmr_t illegal_vcmd : 1;
+- mmr_t illegal_vcpi : 1;
+- mmr_t illegal_vcni : 1;
+- } sh_ni1_error_overflow_2_s;
+-} sh_ni1_error_overflow_2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI1_ERROR_MASK_1" */
+ /* ni1 Error Mask Bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_error_mask_1_u {
+ mmr_t sh_ni1_error_mask_1_regval;
+ struct {
+@@ -15247,84 +8258,12 @@
+ mmr_t tail_timeout_ni_vc3 : 1;
+ } sh_ni1_error_mask_1_s;
+ } sh_ni1_error_mask_1_u_t;
+-#else
+-typedef union sh_ni1_error_mask_1_u {
+- mmr_t sh_ni1_error_mask_1_regval;
+- struct {
+- mmr_t tail_timeout_ni_vc3 : 1;
+- mmr_t tail_timeout_ni_vc2 : 1;
+- mmr_t tail_timeout_ni_vc1 : 1;
+- mmr_t tail_timeout_ni_vc0 : 1;
+- mmr_t tail_timeout_fifo13_vc3 : 1;
+- mmr_t tail_timeout_fifo13_vc1 : 1;
+- mmr_t tail_timeout_fifo02_vc2 : 1;
+- mmr_t tail_timeout_fifo02_vc0 : 1;
+- mmr_t overflow_ni_fifo_vc3_credit : 1;
+- mmr_t overflow_ni_fifo_vc2_credit : 1;
+- mmr_t overflow_ni_fifo_vc1_credit : 1;
+- mmr_t overflow_ni_fifo_vc0_credit : 1;
+- mmr_t overflow_md_fifo_vc2_credit : 1;
+- mmr_t overflow_md_fifo_vc0_credit : 1;
+- mmr_t overflow_iilb_fifo_vc2_credit : 1;
+- mmr_t overflow_iilb_fifo_vc0_credit : 1;
+- mmr_t overflow_pi_fifo_vc2_credit : 1;
+- mmr_t overflow_pi_fifo_vc0_credit : 1;
+- mmr_t overflow_md_fifo_vc2_push : 1;
+- mmr_t overflow_md_fifo_vc0_push : 1;
+- mmr_t overflow_iilb_fifo_vc2_push : 1;
+- mmr_t overflow_iilb_fifo_vc0_push : 1;
+- mmr_t overflow_pi_fifo_vc2_push : 1;
+- mmr_t overflow_pi_fifo_vc0_push : 1;
+- mmr_t overflow_ni_fifo_vc2_pop : 1;
+- mmr_t overflow_ni_fifo_vc0_pop : 1;
+- mmr_t overflow_md_fifo_vc2_pop : 1;
+- mmr_t overflow_md_fifo_vc0_pop : 1;
+- mmr_t overflow_iilb_fifo_vc2_pop : 1;
+- mmr_t overflow_iilb_fifo_vc0_pop : 1;
+- mmr_t overflow_pi_fifo_vc2_pop : 1;
+- mmr_t overflow_pi_fifo_vc0_pop : 1;
+- mmr_t overflow_ni_fifo_debit3 : 1;
+- mmr_t overflow_ni_fifo_debit2 : 1;
+- mmr_t overflow_ni_fifo_debit1 : 1;
+- mmr_t overflow_ni_fifo_debit0 : 1;
+- mmr_t overflow_md_fifo_debit2 : 1;
+- mmr_t overflow_md_fifo_debit0 : 1;
+- mmr_t overflow_iilb_fifo_debit2 : 1;
+- mmr_t overflow_iilb_fifo_debit0 : 1;
+- mmr_t overflow_pi_fifo_debit2 : 1;
+- mmr_t overflow_pi_fifo_debit0 : 1;
+- mmr_t overflow2_vc2_credit : 1;
+- mmr_t overflow1_vc2_credit : 1;
+- mmr_t overflow0_vc2_credit : 1;
+- mmr_t overflow2_vc0_credit : 1;
+- mmr_t overflow1_vc0_credit : 1;
+- mmr_t overflow0_vc0_credit : 1;
+- mmr_t overflow_fifo13_vc2_credit : 1;
+- mmr_t overflow_fifo13_vc0_credit : 1;
+- mmr_t overflow_fifo02_vc2_credit : 1;
+- mmr_t overflow_fifo02_vc0_credit : 1;
+- mmr_t overflow_fifo13_vc3_push : 1;
+- mmr_t overflow_fifo13_vc1_push : 1;
+- mmr_t overflow_fifo02_vc2_push : 1;
+- mmr_t overflow_fifo02_vc0_push : 1;
+- mmr_t overflow_fifo13_vc3_pop : 1;
+- mmr_t overflow_fifo13_vc1_pop : 1;
+- mmr_t overflow_fifo02_vc2_pop : 1;
+- mmr_t overflow_fifo02_vc0_pop : 1;
+- mmr_t overflow_fifo13_debit2 : 1;
+- mmr_t overflow_fifo13_debit0 : 1;
+- mmr_t overflow_fifo02_debit2 : 1;
+- mmr_t overflow_fifo02_debit0 : 1;
+- } sh_ni1_error_mask_1_s;
+-} sh_ni1_error_mask_1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI1_ERROR_MASK_2" */
+ /* ni1 Error Mask Bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_error_mask_2_u {
+ mmr_t sh_ni1_error_mask_2_regval;
+ struct {
+@@ -15385,77 +8324,14 @@
+ mmr_t reserved_1 : 1;
+ } sh_ni1_error_mask_2_s;
+ } sh_ni1_error_mask_2_u_t;
+-#else
+-typedef union sh_ni1_error_mask_2_u {
+- mmr_t sh_ni1_error_mask_2_regval;
+- struct {
+- mmr_t reserved_1 : 1;
+- mmr_t retry_timeout_error : 1;
+- mmr_t lut_read_error : 1;
+- mmr_t chiplet_nomatch : 1;
+- mmr_t llp_deadlock_vc3 : 1;
+- mmr_t llp_deadlock_vc2 : 1;
+- mmr_t llp_deadlock_vc1 : 1;
+- mmr_t llp_deadlock_vc0 : 1;
+- mmr_t underflow_ni_fifo_vc3_credit : 1;
+- mmr_t underflow_ni_fifo_vc2_credit : 1;
+- mmr_t underflow_ni_fifo_vc1_credit : 1;
+- mmr_t underflow_ni_fifo_vc0_credit : 1;
+- mmr_t underflow_md_fifo_vc2_credit : 1;
+- mmr_t underflow_md_fifo_vc0_credit : 1;
+- mmr_t underflow_iilb_fifo_vc2_credit : 1;
+- mmr_t underflow_iilb_fifo_vc0_credit : 1;
+- mmr_t underflow_pi_fifo_vc2_credit : 1;
+- mmr_t underflow_pi_fifo_vc0_credit : 1;
+- mmr_t underflow_md_fifo_vc2_push : 1;
+- mmr_t underflow_md_fifo_vc0_push : 1;
+- mmr_t underflow_iilb_fifo_vc2_push : 1;
+- mmr_t underflow_iilb_fifo_vc0_push : 1;
+- mmr_t underflow_pi_fifo_vc2_push : 1;
+- mmr_t underflow_pi_fifo_vc0_push : 1;
+- mmr_t underflow_ni_fifo_vc2_pop : 1;
+- mmr_t underflow_ni_fifo_vc0_pop : 1;
+- mmr_t underflow_md_fifo_vc2_pop : 1;
+- mmr_t underflow_md_fifo_vc0_pop : 1;
+- mmr_t underflow_iilb_fifo_vc2_pop : 1;
+- mmr_t underflow_iilb_fifo_vc0_pop : 1;
+- mmr_t underflow_pi_fifo_vc2_pop : 1;
+- mmr_t underflow_pi_fifo_vc0_pop : 1;
+- mmr_t reserved_0 : 10;
+- mmr_t underflow2_vc2_credit : 1;
+- mmr_t underflow1_vc2_credit : 1;
+- mmr_t underflow0_vc2_credit : 1;
+- mmr_t underflow2_vc0_credit : 1;
+- mmr_t underflow1_vc0_credit : 1;
+- mmr_t underflow0_vc0_credit : 1;
+- mmr_t underflow_fifo13_vc2_credit : 1;
+- mmr_t underflow_fifo13_vc0_credit : 1;
+- mmr_t underflow_fifo02_vc2_credit : 1;
+- mmr_t underflow_fifo02_vc0_credit : 1;
+- mmr_t underflow_fifo13_vc3_push : 1;
+- mmr_t underflow_fifo13_vc1_push : 1;
+- mmr_t underflow_fifo02_vc2_push : 1;
+- mmr_t underflow_fifo02_vc0_push : 1;
+- mmr_t underflow_fifo13_vc3_pop : 1;
+- mmr_t underflow_fifo13_vc1_pop : 1;
+- mmr_t underflow_fifo02_vc2_pop : 1;
+- mmr_t underflow_fifo02_vc0_pop : 1;
+- mmr_t illegal_vciilb : 1;
+- mmr_t illegal_vcmd : 1;
+- mmr_t illegal_vcpi : 1;
+- mmr_t illegal_vcni : 1;
+- } sh_ni1_error_mask_2_s;
+-} sh_ni1_error_mask_2_u_t;
+-#endif
+-
+-/* ==================================================================== */
+-/* Register "SH_NI1_FIRST_ERROR_1" */
+-/* ni1 First Error Bits */
+-/* ==================================================================== */
+-
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_ni1_first_error_1_u {
+- mmr_t sh_ni1_first_error_1_regval;
++
++/* ==================================================================== */
++/* Register "SH_NI1_FIRST_ERROR_1" */
++/* ni1 First Error Bits */
++/* ==================================================================== */
++
++typedef union sh_ni1_first_error_1_u {
++ mmr_t sh_ni1_first_error_1_regval;
+ struct {
+ mmr_t overflow_fifo02_debit0 : 1;
+ mmr_t overflow_fifo02_debit2 : 1;
+@@ -15523,84 +8399,12 @@
+ mmr_t tail_timeout_ni_vc3 : 1;
+ } sh_ni1_first_error_1_s;
+ } sh_ni1_first_error_1_u_t;
+-#else
+-typedef union sh_ni1_first_error_1_u {
+- mmr_t sh_ni1_first_error_1_regval;
+- struct {
+- mmr_t tail_timeout_ni_vc3 : 1;
+- mmr_t tail_timeout_ni_vc2 : 1;
+- mmr_t tail_timeout_ni_vc1 : 1;
+- mmr_t tail_timeout_ni_vc0 : 1;
+- mmr_t tail_timeout_fifo13_vc3 : 1;
+- mmr_t tail_timeout_fifo13_vc1 : 1;
+- mmr_t tail_timeout_fifo02_vc2 : 1;
+- mmr_t tail_timeout_fifo02_vc0 : 1;
+- mmr_t overflow_ni_fifo_vc3_credit : 1;
+- mmr_t overflow_ni_fifo_vc2_credit : 1;
+- mmr_t overflow_ni_fifo_vc1_credit : 1;
+- mmr_t overflow_ni_fifo_vc0_credit : 1;
+- mmr_t overflow_md_fifo_vc2_credit : 1;
+- mmr_t overflow_md_fifo_vc0_credit : 1;
+- mmr_t overflow_iilb_fifo_vc2_credit : 1;
+- mmr_t overflow_iilb_fifo_vc0_credit : 1;
+- mmr_t overflow_pi_fifo_vc2_credit : 1;
+- mmr_t overflow_pi_fifo_vc0_credit : 1;
+- mmr_t overflow_md_fifo_vc2_push : 1;
+- mmr_t overflow_md_fifo_vc0_push : 1;
+- mmr_t overflow_iilb_fifo_vc2_push : 1;
+- mmr_t overflow_iilb_fifo_vc0_push : 1;
+- mmr_t overflow_pi_fifo_vc2_push : 1;
+- mmr_t overflow_pi_fifo_vc0_push : 1;
+- mmr_t overflow_ni_fifo_vc2_pop : 1;
+- mmr_t overflow_ni_fifo_vc0_pop : 1;
+- mmr_t overflow_md_fifo_vc2_pop : 1;
+- mmr_t overflow_md_fifo_vc0_pop : 1;
+- mmr_t overflow_iilb_fifo_vc2_pop : 1;
+- mmr_t overflow_iilb_fifo_vc0_pop : 1;
+- mmr_t overflow_pi_fifo_vc2_pop : 1;
+- mmr_t overflow_pi_fifo_vc0_pop : 1;
+- mmr_t overflow_ni_fifo_debit3 : 1;
+- mmr_t overflow_ni_fifo_debit2 : 1;
+- mmr_t overflow_ni_fifo_debit1 : 1;
+- mmr_t overflow_ni_fifo_debit0 : 1;
+- mmr_t overflow_md_fifo_debit2 : 1;
+- mmr_t overflow_md_fifo_debit0 : 1;
+- mmr_t overflow_iilb_fifo_debit2 : 1;
+- mmr_t overflow_iilb_fifo_debit0 : 1;
+- mmr_t overflow_pi_fifo_debit2 : 1;
+- mmr_t overflow_pi_fifo_debit0 : 1;
+- mmr_t overflow2_vc2_credit : 1;
+- mmr_t overflow1_vc2_credit : 1;
+- mmr_t overflow0_vc2_credit : 1;
+- mmr_t overflow2_vc0_credit : 1;
+- mmr_t overflow1_vc0_credit : 1;
+- mmr_t overflow0_vc0_credit : 1;
+- mmr_t overflow_fifo13_vc2_credit : 1;
+- mmr_t overflow_fifo13_vc0_credit : 1;
+- mmr_t overflow_fifo02_vc2_credit : 1;
+- mmr_t overflow_fifo02_vc0_credit : 1;
+- mmr_t overflow_fifo13_vc3_push : 1;
+- mmr_t overflow_fifo13_vc1_push : 1;
+- mmr_t overflow_fifo02_vc2_push : 1;
+- mmr_t overflow_fifo02_vc0_push : 1;
+- mmr_t overflow_fifo13_vc3_pop : 1;
+- mmr_t overflow_fifo13_vc1_pop : 1;
+- mmr_t overflow_fifo02_vc2_pop : 1;
+- mmr_t overflow_fifo02_vc0_pop : 1;
+- mmr_t overflow_fifo13_debit2 : 1;
+- mmr_t overflow_fifo13_debit0 : 1;
+- mmr_t overflow_fifo02_debit2 : 1;
+- mmr_t overflow_fifo02_debit0 : 1;
+- } sh_ni1_first_error_1_s;
+-} sh_ni1_first_error_1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI1_FIRST_ERROR_2" */
+ /* ni1 First Error Bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_first_error_2_u {
+ mmr_t sh_ni1_first_error_2_regval;
+ struct {
+@@ -15661,117 +8465,36 @@
+ mmr_t reserved_1 : 1;
+ } sh_ni1_first_error_2_s;
+ } sh_ni1_first_error_2_u_t;
+-#else
+-typedef union sh_ni1_first_error_2_u {
+- mmr_t sh_ni1_first_error_2_regval;
+- struct {
+- mmr_t reserved_1 : 1;
+- mmr_t retry_timeout_error : 1;
+- mmr_t lut_read_error : 1;
+- mmr_t chiplet_nomatch : 1;
+- mmr_t llp_deadlock_vc3 : 1;
+- mmr_t llp_deadlock_vc2 : 1;
+- mmr_t llp_deadlock_vc1 : 1;
+- mmr_t llp_deadlock_vc0 : 1;
+- mmr_t underflow_ni_fifo_vc3_credit : 1;
+- mmr_t underflow_ni_fifo_vc2_credit : 1;
+- mmr_t underflow_ni_fifo_vc1_credit : 1;
+- mmr_t underflow_ni_fifo_vc0_credit : 1;
+- mmr_t underflow_md_fifo_vc2_credit : 1;
+- mmr_t underflow_md_fifo_vc0_credit : 1;
+- mmr_t underflow_iilb_fifo_vc2_credit : 1;
+- mmr_t underflow_iilb_fifo_vc0_credit : 1;
+- mmr_t underflow_pi_fifo_vc2_credit : 1;
+- mmr_t underflow_pi_fifo_vc0_credit : 1;
+- mmr_t underflow_md_fifo_vc2_push : 1;
+- mmr_t underflow_md_fifo_vc0_push : 1;
+- mmr_t underflow_iilb_fifo_vc2_push : 1;
+- mmr_t underflow_iilb_fifo_vc0_push : 1;
+- mmr_t underflow_pi_fifo_vc2_push : 1;
+- mmr_t underflow_pi_fifo_vc0_push : 1;
+- mmr_t underflow_ni_fifo_vc2_pop : 1;
+- mmr_t underflow_ni_fifo_vc0_pop : 1;
+- mmr_t underflow_md_fifo_vc2_pop : 1;
+- mmr_t underflow_md_fifo_vc0_pop : 1;
+- mmr_t underflow_iilb_fifo_vc2_pop : 1;
+- mmr_t underflow_iilb_fifo_vc0_pop : 1;
+- mmr_t underflow_pi_fifo_vc2_pop : 1;
+- mmr_t underflow_pi_fifo_vc0_pop : 1;
+- mmr_t reserved_0 : 10;
+- mmr_t underflow2_vc2_credit : 1;
+- mmr_t underflow1_vc2_credit : 1;
+- mmr_t underflow0_vc2_credit : 1;
+- mmr_t underflow2_vc0_credit : 1;
+- mmr_t underflow1_vc0_credit : 1;
+- mmr_t underflow0_vc0_credit : 1;
+- mmr_t underflow_fifo13_vc2_credit : 1;
+- mmr_t underflow_fifo13_vc0_credit : 1;
+- mmr_t underflow_fifo02_vc2_credit : 1;
+- mmr_t underflow_fifo02_vc0_credit : 1;
+- mmr_t underflow_fifo13_vc3_push : 1;
+- mmr_t underflow_fifo13_vc1_push : 1;
+- mmr_t underflow_fifo02_vc2_push : 1;
+- mmr_t underflow_fifo02_vc0_push : 1;
+- mmr_t underflow_fifo13_vc3_pop : 1;
+- mmr_t underflow_fifo13_vc1_pop : 1;
+- mmr_t underflow_fifo02_vc2_pop : 1;
+- mmr_t underflow_fifo02_vc0_pop : 1;
+- mmr_t illegal_vciilb : 1;
+- mmr_t illegal_vcmd : 1;
+- mmr_t illegal_vcpi : 1;
+- mmr_t illegal_vcni : 1;
+- } sh_ni1_first_error_2_s;
+-} sh_ni1_first_error_2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI1_ERROR_DETAIL_1" */
+ /* ni1 Chiplet no match header bits 63:0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_ni1_error_detail_1_u {
+- mmr_t sh_ni1_error_detail_1_regval;
+- struct {
+- mmr_t header : 64;
+- } sh_ni1_error_detail_1_s;
+-} sh_ni1_error_detail_1_u_t;
+-#else
+ typedef union sh_ni1_error_detail_1_u {
+ mmr_t sh_ni1_error_detail_1_regval;
+ struct {
+ mmr_t header : 64;
+ } sh_ni1_error_detail_1_s;
+ } sh_ni1_error_detail_1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI1_ERROR_DETAIL_2" */
+ /* ni1 Chiplet no match header bits 127:64 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_ni1_error_detail_2_u {
+- mmr_t sh_ni1_error_detail_2_regval;
+- struct {
+- mmr_t header : 64;
+- } sh_ni1_error_detail_2_s;
+-} sh_ni1_error_detail_2_u_t;
+-#else
+ typedef union sh_ni1_error_detail_2_u {
+ mmr_t sh_ni1_error_detail_2_regval;
+ struct {
+ mmr_t header : 64;
+ } sh_ni1_error_detail_2_s;
+ } sh_ni1_error_detail_2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_CORRECTED_DETAIL_1" */
+ /* Corrected error details */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_corrected_detail_1_u {
+ mmr_t sh_xn_corrected_detail_1_regval;
+ struct {
+@@ -15793,78 +8516,36 @@
+ mmr_t reserved_3 : 4;
+ } sh_xn_corrected_detail_1_s;
+ } sh_xn_corrected_detail_1_u_t;
+-#else
+-typedef union sh_xn_corrected_detail_1_u {
+- mmr_t sh_xn_corrected_detail_1_regval;
+- struct {
+- mmr_t reserved_3 : 4;
+- mmr_t ecc3_vc : 2;
+- mmr_t ecc3_wc : 2;
+- mmr_t ecc3_syndrome : 8;
+- mmr_t reserved_2 : 4;
+- mmr_t ecc2_vc : 2;
+- mmr_t ecc2_wc : 2;
+- mmr_t ecc2_syndrome : 8;
+- mmr_t reserved_1 : 4;
+- mmr_t ecc1_vc : 2;
+- mmr_t ecc1_wc : 2;
+- mmr_t ecc1_syndrome : 8;
+- mmr_t reserved_0 : 4;
+- mmr_t ecc0_vc : 2;
+- mmr_t ecc0_wc : 2;
+- mmr_t ecc0_syndrome : 8;
+- } sh_xn_corrected_detail_1_s;
+-} sh_xn_corrected_detail_1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_CORRECTED_DETAIL_2" */
+ /* Corrected error data */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_corrected_detail_2_u {
+- mmr_t sh_xn_corrected_detail_2_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_corrected_detail_2_s;
+-} sh_xn_corrected_detail_2_u_t;
+-#else
+ typedef union sh_xn_corrected_detail_2_u {
+ mmr_t sh_xn_corrected_detail_2_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_corrected_detail_2_s;
+ } sh_xn_corrected_detail_2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_CORRECTED_DETAIL_3" */
+ /* Corrected error header0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_corrected_detail_3_u {
+- mmr_t sh_xn_corrected_detail_3_regval;
+- struct {
+- mmr_t header0 : 64;
+- } sh_xn_corrected_detail_3_s;
+-} sh_xn_corrected_detail_3_u_t;
+-#else
+ typedef union sh_xn_corrected_detail_3_u {
+ mmr_t sh_xn_corrected_detail_3_regval;
+ struct {
+ mmr_t header0 : 64;
+ } sh_xn_corrected_detail_3_s;
+ } sh_xn_corrected_detail_3_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_CORRECTED_DETAIL_4" */
+ /* Corrected error header1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_corrected_detail_4_u {
+ mmr_t sh_xn_corrected_detail_4_regval;
+ struct {
+@@ -15873,23 +8554,12 @@
+ mmr_t err_group : 2;
+ } sh_xn_corrected_detail_4_s;
+ } sh_xn_corrected_detail_4_u_t;
+-#else
+-typedef union sh_xn_corrected_detail_4_u {
+- mmr_t sh_xn_corrected_detail_4_regval;
+- struct {
+- mmr_t err_group : 2;
+- mmr_t reserved_0 : 20;
+- mmr_t header1 : 42;
+- } sh_xn_corrected_detail_4_s;
+-} sh_xn_corrected_detail_4_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_UNCORRECTED_DETAIL_1" */
+ /* Uncorrected error details */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_uncorrected_detail_1_u {
+ mmr_t sh_xn_uncorrected_detail_1_regval;
+ struct {
+@@ -15911,78 +8581,36 @@
+ mmr_t reserved_3 : 4;
+ } sh_xn_uncorrected_detail_1_s;
+ } sh_xn_uncorrected_detail_1_u_t;
+-#else
+-typedef union sh_xn_uncorrected_detail_1_u {
+- mmr_t sh_xn_uncorrected_detail_1_regval;
+- struct {
+- mmr_t reserved_3 : 4;
+- mmr_t ecc3_vc : 2;
+- mmr_t ecc3_wc : 2;
+- mmr_t ecc3_syndrome : 8;
+- mmr_t reserved_2 : 4;
+- mmr_t ecc2_vc : 2;
+- mmr_t ecc2_wc : 2;
+- mmr_t ecc2_syndrome : 8;
+- mmr_t reserved_1 : 4;
+- mmr_t ecc1_vc : 2;
+- mmr_t ecc1_wc : 2;
+- mmr_t ecc1_syndrome : 8;
+- mmr_t reserved_0 : 4;
+- mmr_t ecc0_vc : 2;
+- mmr_t ecc0_wc : 2;
+- mmr_t ecc0_syndrome : 8;
+- } sh_xn_uncorrected_detail_1_s;
+-} sh_xn_uncorrected_detail_1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_UNCORRECTED_DETAIL_2" */
+ /* Uncorrected error data */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_uncorrected_detail_2_u {
+- mmr_t sh_xn_uncorrected_detail_2_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_xn_uncorrected_detail_2_s;
+-} sh_xn_uncorrected_detail_2_u_t;
+-#else
+ typedef union sh_xn_uncorrected_detail_2_u {
+ mmr_t sh_xn_uncorrected_detail_2_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_xn_uncorrected_detail_2_s;
+ } sh_xn_uncorrected_detail_2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_UNCORRECTED_DETAIL_3" */
+ /* Uncorrected error header0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_uncorrected_detail_3_u {
+- mmr_t sh_xn_uncorrected_detail_3_regval;
+- struct {
+- mmr_t header0 : 64;
+- } sh_xn_uncorrected_detail_3_s;
+-} sh_xn_uncorrected_detail_3_u_t;
+-#else
+ typedef union sh_xn_uncorrected_detail_3_u {
+ mmr_t sh_xn_uncorrected_detail_3_regval;
+ struct {
+ mmr_t header0 : 64;
+ } sh_xn_uncorrected_detail_3_s;
+ } sh_xn_uncorrected_detail_3_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_UNCORRECTED_DETAIL_4" */
+ /* Uncorrected error header1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_uncorrected_detail_4_u {
+ mmr_t sh_xn_uncorrected_detail_4_regval;
+ struct {
+@@ -15991,23 +8619,12 @@
+ mmr_t err_group : 2;
+ } sh_xn_uncorrected_detail_4_s;
+ } sh_xn_uncorrected_detail_4_u_t;
+-#else
+-typedef union sh_xn_uncorrected_detail_4_u {
+- mmr_t sh_xn_uncorrected_detail_4_regval;
+- struct {
+- mmr_t err_group : 2;
+- mmr_t reserved_0 : 20;
+- mmr_t header1 : 42;
+- } sh_xn_uncorrected_detail_4_s;
+-} sh_xn_uncorrected_detail_4_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNMD_ERROR_DETAIL_1" */
+ /* Look Up Table Address (md) */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnmd_error_detail_1_u {
+ mmr_t sh_xnmd_error_detail_1_regval;
+ struct {
+@@ -16015,22 +8632,12 @@
+ mmr_t reserved_0 : 53;
+ } sh_xnmd_error_detail_1_s;
+ } sh_xnmd_error_detail_1_u_t;
+-#else
+-typedef union sh_xnmd_error_detail_1_u {
+- mmr_t sh_xnmd_error_detail_1_regval;
+- struct {
+- mmr_t reserved_0 : 53;
+- mmr_t lut_addr : 11;
+- } sh_xnmd_error_detail_1_s;
+-} sh_xnmd_error_detail_1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNPI_ERROR_DETAIL_1" */
+ /* Look Up Table Address (pi) */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnpi_error_detail_1_u {
+ mmr_t sh_xnpi_error_detail_1_regval;
+ struct {
+@@ -16038,64 +8645,36 @@
+ mmr_t reserved_0 : 53;
+ } sh_xnpi_error_detail_1_s;
+ } sh_xnpi_error_detail_1_u_t;
+-#else
+-typedef union sh_xnpi_error_detail_1_u {
+- mmr_t sh_xnpi_error_detail_1_regval;
+- struct {
+- mmr_t reserved_0 : 53;
+- mmr_t lut_addr : 11;
+- } sh_xnpi_error_detail_1_s;
+-} sh_xnpi_error_detail_1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNIILB_ERROR_DETAIL_1" */
+ /* Chiplet NoMatch header [63:0] */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xniilb_error_detail_1_u {
+- mmr_t sh_xniilb_error_detail_1_regval;
+- struct {
+- mmr_t header : 64;
+- } sh_xniilb_error_detail_1_s;
+-} sh_xniilb_error_detail_1_u_t;
+-#else
+ typedef union sh_xniilb_error_detail_1_u {
+ mmr_t sh_xniilb_error_detail_1_regval;
+ struct {
+ mmr_t header : 64;
+ } sh_xniilb_error_detail_1_s;
+ } sh_xniilb_error_detail_1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNIILB_ERROR_DETAIL_2" */
+ /* Chiplet NoMatch header [127:64] */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xniilb_error_detail_2_u {
+- mmr_t sh_xniilb_error_detail_2_regval;
+- struct {
+- mmr_t header : 64;
+- } sh_xniilb_error_detail_2_s;
+-} sh_xniilb_error_detail_2_u_t;
+-#else
+ typedef union sh_xniilb_error_detail_2_u {
+ mmr_t sh_xniilb_error_detail_2_regval;
+ struct {
+ mmr_t header : 64;
+ } sh_xniilb_error_detail_2_s;
+ } sh_xniilb_error_detail_2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNIILB_ERROR_DETAIL_3" */
+ /* Look Up Table Address (iilb) */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xniilb_error_detail_3_u {
+ mmr_t sh_xniilb_error_detail_3_regval;
+ struct {
+@@ -16103,22 +8682,12 @@
+ mmr_t reserved_0 : 53;
+ } sh_xniilb_error_detail_3_s;
+ } sh_xniilb_error_detail_3_u_t;
+-#else
+-typedef union sh_xniilb_error_detail_3_u {
+- mmr_t sh_xniilb_error_detail_3_regval;
+- struct {
+- mmr_t reserved_0 : 53;
+- mmr_t lut_addr : 11;
+- } sh_xniilb_error_detail_3_s;
+-} sh_xniilb_error_detail_3_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI0_ERROR_DETAIL_3" */
+ /* Look Up Table Address (ni0) */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_error_detail_3_u {
+ mmr_t sh_ni0_error_detail_3_regval;
+ struct {
+@@ -16126,22 +8695,12 @@
+ mmr_t reserved_0 : 53;
+ } sh_ni0_error_detail_3_s;
+ } sh_ni0_error_detail_3_u_t;
+-#else
+-typedef union sh_ni0_error_detail_3_u {
+- mmr_t sh_ni0_error_detail_3_regval;
+- struct {
+- mmr_t reserved_0 : 53;
+- mmr_t lut_addr : 11;
+- } sh_ni0_error_detail_3_s;
+-} sh_ni0_error_detail_3_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_NI1_ERROR_DETAIL_3" */
+ /* Look Up Table Address (ni1) */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_error_detail_3_u {
+ mmr_t sh_ni1_error_detail_3_regval;
+ struct {
+@@ -16149,21 +8708,11 @@
+ mmr_t reserved_0 : 53;
+ } sh_ni1_error_detail_3_s;
+ } sh_ni1_error_detail_3_u_t;
+-#else
+-typedef union sh_ni1_error_detail_3_u {
+- mmr_t sh_ni1_error_detail_3_regval;
+- struct {
+- mmr_t reserved_0 : 53;
+- mmr_t lut_addr : 11;
+- } sh_ni1_error_detail_3_s;
+-} sh_ni1_error_detail_3_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_ERROR_SUMMARY" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_error_summary_u {
+ mmr_t sh_xn_error_summary_regval;
+ struct {
+@@ -16208,58 +8757,11 @@
+ mmr_t reserved_0 : 26;
+ } sh_xn_error_summary_s;
+ } sh_xn_error_summary_u_t;
+-#else
+-typedef union sh_xn_error_summary_u {
+- mmr_t sh_xn_error_summary_regval;
+- struct {
+- mmr_t reserved_0 : 26;
+- mmr_t iilb_chiplet_or_lut : 1;
+- mmr_t iilb_fifo_underflow : 1;
+- mmr_t iilb_credit_underflow : 1;
+- mmr_t iilb_fifo_overflow : 1;
+- mmr_t iilb_credit_overflow : 1;
+- mmr_t iilb_debit_overflow : 1;
+- mmr_t xnpi_lut_error : 1;
+- mmr_t xnpi_uce_error : 1;
+- mmr_t xnpi_sbe_error : 1;
+- mmr_t xnpi_credit_underflow : 1;
+- mmr_t xnpi_data_buff_overflow : 1;
+- mmr_t xnpi_debit_overflow : 1;
+- mmr_t xnpi_credit_overflow : 1;
+- mmr_t xnmd_lut_error : 1;
+- mmr_t xnmd_uce_error : 1;
+- mmr_t xnmd_sbe_error : 1;
+- mmr_t xnmd_credit_underflow : 1;
+- mmr_t xnmd_data_buff_overflow : 1;
+- mmr_t xnmd_debit_overflow : 1;
+- mmr_t xnmd_credit_overflow : 1;
+- mmr_t ni1_pipe_error : 1;
+- mmr_t ni1_llp_error : 1;
+- mmr_t ni1_credit_underflow : 1;
+- mmr_t ni1_push_underflow : 1;
+- mmr_t ni1_pop_underflow : 1;
+- mmr_t ni1_debit_overflow : 1;
+- mmr_t ni1_credit_overflow : 1;
+- mmr_t ni1_push_overflow : 1;
+- mmr_t ni1_pop_overflow : 1;
+- mmr_t ni0_pipe_error : 1;
+- mmr_t ni0_llp_error : 1;
+- mmr_t ni0_credit_underflow : 1;
+- mmr_t ni0_push_underflow : 1;
+- mmr_t ni0_pop_underflow : 1;
+- mmr_t ni0_debit_overflow : 1;
+- mmr_t ni0_credit_overflow : 1;
+- mmr_t ni0_push_overflow : 1;
+- mmr_t ni0_pop_overflow : 1;
+- } sh_xn_error_summary_s;
+-} sh_xn_error_summary_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_ERROR_OVERFLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_error_overflow_u {
+ mmr_t sh_xn_error_overflow_regval;
+ struct {
+@@ -16304,58 +8806,11 @@
+ mmr_t reserved_0 : 26;
+ } sh_xn_error_overflow_s;
+ } sh_xn_error_overflow_u_t;
+-#else
+-typedef union sh_xn_error_overflow_u {
+- mmr_t sh_xn_error_overflow_regval;
+- struct {
+- mmr_t reserved_0 : 26;
+- mmr_t iilb_chiplet_or_lut : 1;
+- mmr_t iilb_fifo_underflow : 1;
+- mmr_t iilb_credit_underflow : 1;
+- mmr_t iilb_fifo_overflow : 1;
+- mmr_t iilb_credit_overflow : 1;
+- mmr_t iilb_debit_overflow : 1;
+- mmr_t xnpi_lut_error : 1;
+- mmr_t xnpi_uce_error : 1;
+- mmr_t xnpi_sbe_error : 1;
+- mmr_t xnpi_credit_underflow : 1;
+- mmr_t xnpi_data_buff_overflow : 1;
+- mmr_t xnpi_debit_overflow : 1;
+- mmr_t xnpi_credit_overflow : 1;
+- mmr_t xnmd_lut_error : 1;
+- mmr_t xnmd_uce_error : 1;
+- mmr_t xnmd_sbe_error : 1;
+- mmr_t xnmd_credit_underflow : 1;
+- mmr_t xnmd_data_buff_overflow : 1;
+- mmr_t xnmd_debit_overflow : 1;
+- mmr_t xnmd_credit_overflow : 1;
+- mmr_t ni1_pipe_error : 1;
+- mmr_t ni1_llp_error : 1;
+- mmr_t ni1_credit_underflow : 1;
+- mmr_t ni1_push_underflow : 1;
+- mmr_t ni1_pop_underflow : 1;
+- mmr_t ni1_debit_overflow : 1;
+- mmr_t ni1_credit_overflow : 1;
+- mmr_t ni1_push_overflow : 1;
+- mmr_t ni1_pop_overflow : 1;
+- mmr_t ni0_pipe_error : 1;
+- mmr_t ni0_llp_error : 1;
+- mmr_t ni0_credit_underflow : 1;
+- mmr_t ni0_push_underflow : 1;
+- mmr_t ni0_pop_underflow : 1;
+- mmr_t ni0_debit_overflow : 1;
+- mmr_t ni0_credit_overflow : 1;
+- mmr_t ni0_push_overflow : 1;
+- mmr_t ni0_pop_overflow : 1;
+- } sh_xn_error_overflow_s;
+-} sh_xn_error_overflow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_ERROR_MASK" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_error_mask_u {
+ mmr_t sh_xn_error_mask_regval;
+ struct {
+@@ -16400,58 +8855,11 @@
+ mmr_t reserved_0 : 26;
+ } sh_xn_error_mask_s;
+ } sh_xn_error_mask_u_t;
+-#else
+-typedef union sh_xn_error_mask_u {
+- mmr_t sh_xn_error_mask_regval;
+- struct {
+- mmr_t reserved_0 : 26;
+- mmr_t iilb_chiplet_or_lut : 1;
+- mmr_t iilb_fifo_underflow : 1;
+- mmr_t iilb_credit_underflow : 1;
+- mmr_t iilb_fifo_overflow : 1;
+- mmr_t iilb_credit_overflow : 1;
+- mmr_t iilb_debit_overflow : 1;
+- mmr_t xnpi_lut_error : 1;
+- mmr_t xnpi_uce_error : 1;
+- mmr_t xnpi_sbe_error : 1;
+- mmr_t xnpi_credit_underflow : 1;
+- mmr_t xnpi_data_buff_overflow : 1;
+- mmr_t xnpi_debit_overflow : 1;
+- mmr_t xnpi_credit_overflow : 1;
+- mmr_t xnmd_lut_error : 1;
+- mmr_t xnmd_uce_error : 1;
+- mmr_t xnmd_sbe_error : 1;
+- mmr_t xnmd_credit_underflow : 1;
+- mmr_t xnmd_data_buff_overflow : 1;
+- mmr_t xnmd_debit_overflow : 1;
+- mmr_t xnmd_credit_overflow : 1;
+- mmr_t ni1_pipe_error : 1;
+- mmr_t ni1_llp_error : 1;
+- mmr_t ni1_credit_underflow : 1;
+- mmr_t ni1_push_underflow : 1;
+- mmr_t ni1_pop_underflow : 1;
+- mmr_t ni1_debit_overflow : 1;
+- mmr_t ni1_credit_overflow : 1;
+- mmr_t ni1_push_overflow : 1;
+- mmr_t ni1_pop_overflow : 1;
+- mmr_t ni0_pipe_error : 1;
+- mmr_t ni0_llp_error : 1;
+- mmr_t ni0_credit_underflow : 1;
+- mmr_t ni0_push_underflow : 1;
+- mmr_t ni0_pop_underflow : 1;
+- mmr_t ni0_debit_overflow : 1;
+- mmr_t ni0_credit_overflow : 1;
+- mmr_t ni0_push_overflow : 1;
+- mmr_t ni0_pop_overflow : 1;
+- } sh_xn_error_mask_s;
+-} sh_xn_error_mask_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_FIRST_ERROR" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_first_error_u {
+ mmr_t sh_xn_first_error_regval;
+ struct {
+@@ -16496,58 +8904,11 @@
+ mmr_t reserved_0 : 26;
+ } sh_xn_first_error_s;
+ } sh_xn_first_error_u_t;
+-#else
+-typedef union sh_xn_first_error_u {
+- mmr_t sh_xn_first_error_regval;
+- struct {
+- mmr_t reserved_0 : 26;
+- mmr_t iilb_chiplet_or_lut : 1;
+- mmr_t iilb_fifo_underflow : 1;
+- mmr_t iilb_credit_underflow : 1;
+- mmr_t iilb_fifo_overflow : 1;
+- mmr_t iilb_credit_overflow : 1;
+- mmr_t iilb_debit_overflow : 1;
+- mmr_t xnpi_lut_error : 1;
+- mmr_t xnpi_uce_error : 1;
+- mmr_t xnpi_sbe_error : 1;
+- mmr_t xnpi_credit_underflow : 1;
+- mmr_t xnpi_data_buff_overflow : 1;
+- mmr_t xnpi_debit_overflow : 1;
+- mmr_t xnpi_credit_overflow : 1;
+- mmr_t xnmd_lut_error : 1;
+- mmr_t xnmd_uce_error : 1;
+- mmr_t xnmd_sbe_error : 1;
+- mmr_t xnmd_credit_underflow : 1;
+- mmr_t xnmd_data_buff_overflow : 1;
+- mmr_t xnmd_debit_overflow : 1;
+- mmr_t xnmd_credit_overflow : 1;
+- mmr_t ni1_pipe_error : 1;
+- mmr_t ni1_llp_error : 1;
+- mmr_t ni1_credit_underflow : 1;
+- mmr_t ni1_push_underflow : 1;
+- mmr_t ni1_pop_underflow : 1;
+- mmr_t ni1_debit_overflow : 1;
+- mmr_t ni1_credit_overflow : 1;
+- mmr_t ni1_push_overflow : 1;
+- mmr_t ni1_pop_overflow : 1;
+- mmr_t ni0_pipe_error : 1;
+- mmr_t ni0_llp_error : 1;
+- mmr_t ni0_credit_underflow : 1;
+- mmr_t ni0_push_underflow : 1;
+- mmr_t ni0_pop_underflow : 1;
+- mmr_t ni0_debit_overflow : 1;
+- mmr_t ni0_credit_overflow : 1;
+- mmr_t ni0_push_overflow : 1;
+- mmr_t ni0_pop_overflow : 1;
+- } sh_xn_first_error_s;
+-} sh_xn_first_error_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNIILB_ERROR_SUMMARY" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xniilb_error_summary_u {
+ mmr_t sh_xniilb_error_summary_regval;
+ struct {
+@@ -16617,83 +8978,11 @@
+ mmr_t lut_read_error : 1;
+ } sh_xniilb_error_summary_s;
+ } sh_xniilb_error_summary_u_t;
+-#else
+-typedef union sh_xniilb_error_summary_u {
+- mmr_t sh_xniilb_error_summary_regval;
+- struct {
+- mmr_t lut_read_error : 1;
+- mmr_t chiplet_nomatch : 1;
+- mmr_t underflow_ni1_vc2_credit_out : 1;
+- mmr_t underflow_ni1_vc0_credit_out : 1;
+- mmr_t underflow_ni0_vc2_credit_out : 1;
+- mmr_t underflow_ni0_vc0_credit_out : 1;
+- mmr_t underflow_iilb_vc2_credit_out : 1;
+- mmr_t underflow_iilb_vc0_credit_out : 1;
+- mmr_t underflow_md_vc2_credit_out : 1;
+- mmr_t underflow_md_vc0_credit_out : 1;
+- mmr_t underflow_pi_vc2_credit_out : 1;
+- mmr_t underflow_pi_vc0_credit_out : 1;
+- mmr_t overflow_ni1_vc2_credit_out : 1;
+- mmr_t overflow_ni1_vc0_credit_out : 1;
+- mmr_t overflow_ni0_vc2_credit_out : 1;
+- mmr_t overflow_ni0_vc0_credit_out : 1;
+- mmr_t overflow_iilb_vc2_credit_out : 1;
+- mmr_t overflow_iilb_vc0_credit_out : 1;
+- mmr_t overflow_md_vc2_credit_out : 1;
+- mmr_t overflow_md_vc0_credit_out : 1;
+- mmr_t overflow_pi_vc2_credit_out : 1;
+- mmr_t overflow_pi_vc0_credit_out : 1;
+- mmr_t overflow_ni1_debit2 : 1;
+- mmr_t overflow_ni1_debit0 : 1;
+- mmr_t overflow_ni0_debit2 : 1;
+- mmr_t overflow_ni0_debit0 : 1;
+- mmr_t overflow_md_debit2 : 1;
+- mmr_t overflow_md_debit0 : 1;
+- mmr_t overflow_iilb_debit2 : 1;
+- mmr_t overflow_iilb_debit0 : 1;
+- mmr_t overflow_pi_debit2 : 1;
+- mmr_t overflow_pi_debit0 : 1;
+- mmr_t underflow_ni1_vc2_credit_in : 1;
+- mmr_t underflow_ni0_vc2_credit_in : 1;
+- mmr_t underflow_md_vc2_credit_in : 1;
+- mmr_t underflow_iilb_vc2_credit_in : 1;
+- mmr_t underflow_pi_vc2_credit_in : 1;
+- mmr_t underflow_ni1_vc0_credit_in : 1;
+- mmr_t underflow_ni0_vc0_credit_in : 1;
+- mmr_t underflow_md_vc0_credit_in : 1;
+- mmr_t underflow_iilb_vc0_credit_in : 1;
+- mmr_t underflow_pi_vc0_credit_in : 1;
+- mmr_t overflow_ni1_vc2_credit_in : 1;
+- mmr_t overflow_ni0_vc2_credit_in : 1;
+- mmr_t overflow_md_vc2_credit_in : 1;
+- mmr_t overflow_iilb_vc2_credit_in : 1;
+- mmr_t overflow_pi_vc2_credit_in : 1;
+- mmr_t overflow_ni1_vc0_credit_in : 1;
+- mmr_t overflow_ni0_vc0_credit_in : 1;
+- mmr_t overflow_md_vc0_credit_in : 1;
+- mmr_t overflow_iilb_vc0_credit_in : 1;
+- mmr_t overflow_pi_vc0_credit_in : 1;
+- mmr_t underflow_lb_vc2 : 1;
+- mmr_t underflow_lb_vc0 : 1;
+- mmr_t overflow_lb_vc2 : 1;
+- mmr_t overflow_lb_vc0 : 1;
+- mmr_t underflow_ii_vc2 : 1;
+- mmr_t underflow_ii_vc0 : 1;
+- mmr_t overflow_ii_vc2 : 1;
+- mmr_t overflow_ii_vc0 : 1;
+- mmr_t overflow_lb_debit2 : 1;
+- mmr_t overflow_lb_debit0 : 1;
+- mmr_t overflow_ii_debit2 : 1;
+- mmr_t overflow_ii_debit0 : 1;
+- } sh_xniilb_error_summary_s;
+-} sh_xniilb_error_summary_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNIILB_ERROR_OVERFLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xniilb_error_overflow_u {
+ mmr_t sh_xniilb_error_overflow_regval;
+ struct {
+@@ -16763,83 +9052,11 @@
+ mmr_t lut_read_error : 1;
+ } sh_xniilb_error_overflow_s;
+ } sh_xniilb_error_overflow_u_t;
+-#else
+-typedef union sh_xniilb_error_overflow_u {
+- mmr_t sh_xniilb_error_overflow_regval;
+- struct {
+- mmr_t lut_read_error : 1;
+- mmr_t chiplet_nomatch : 1;
+- mmr_t underflow_ni1_vc2_credit_out : 1;
+- mmr_t underflow_ni1_vc0_credit_out : 1;
+- mmr_t underflow_ni0_vc2_credit_out : 1;
+- mmr_t underflow_ni0_vc0_credit_out : 1;
+- mmr_t underflow_iilb_vc2_credit_out : 1;
+- mmr_t underflow_iilb_vc0_credit_out : 1;
+- mmr_t underflow_md_vc2_credit_out : 1;
+- mmr_t underflow_md_vc0_credit_out : 1;
+- mmr_t underflow_pi_vc2_credit_out : 1;
+- mmr_t underflow_pi_vc0_credit_out : 1;
+- mmr_t overflow_ni1_vc2_credit_out : 1;
+- mmr_t overflow_ni1_vc0_credit_out : 1;
+- mmr_t overflow_ni0_vc2_credit_out : 1;
+- mmr_t overflow_ni0_vc0_credit_out : 1;
+- mmr_t overflow_iilb_vc2_credit_out : 1;
+- mmr_t overflow_iilb_vc0_credit_out : 1;
+- mmr_t overflow_md_vc2_credit_out : 1;
+- mmr_t overflow_md_vc0_credit_out : 1;
+- mmr_t overflow_pi_vc2_credit_out : 1;
+- mmr_t overflow_pi_vc0_credit_out : 1;
+- mmr_t overflow_ni1_debit2 : 1;
+- mmr_t overflow_ni1_debit0 : 1;
+- mmr_t overflow_ni0_debit2 : 1;
+- mmr_t overflow_ni0_debit0 : 1;
+- mmr_t overflow_md_debit2 : 1;
+- mmr_t overflow_md_debit0 : 1;
+- mmr_t overflow_iilb_debit2 : 1;
+- mmr_t overflow_iilb_debit0 : 1;
+- mmr_t overflow_pi_debit2 : 1;
+- mmr_t overflow_pi_debit0 : 1;
+- mmr_t underflow_ni1_vc2_credit_in : 1;
+- mmr_t underflow_ni0_vc2_credit_in : 1;
+- mmr_t underflow_md_vc2_credit_in : 1;
+- mmr_t underflow_iilb_vc2_credit_in : 1;
+- mmr_t underflow_pi_vc2_credit_in : 1;
+- mmr_t underflow_ni1_vc0_credit_in : 1;
+- mmr_t underflow_ni0_vc0_credit_in : 1;
+- mmr_t underflow_md_vc0_credit_in : 1;
+- mmr_t underflow_iilb_vc0_credit_in : 1;
+- mmr_t underflow_pi_vc0_credit_in : 1;
+- mmr_t overflow_ni1_vc2_credit_in : 1;
+- mmr_t overflow_ni0_vc2_credit_in : 1;
+- mmr_t overflow_md_vc2_credit_in : 1;
+- mmr_t overflow_iilb_vc2_credit_in : 1;
+- mmr_t overflow_pi_vc2_credit_in : 1;
+- mmr_t overflow_ni1_vc0_credit_in : 1;
+- mmr_t overflow_ni0_vc0_credit_in : 1;
+- mmr_t overflow_md_vc0_credit_in : 1;
+- mmr_t overflow_iilb_vc0_credit_in : 1;
+- mmr_t overflow_pi_vc0_credit_in : 1;
+- mmr_t underflow_lb_vc2 : 1;
+- mmr_t underflow_lb_vc0 : 1;
+- mmr_t overflow_lb_vc2 : 1;
+- mmr_t overflow_lb_vc0 : 1;
+- mmr_t underflow_ii_vc2 : 1;
+- mmr_t underflow_ii_vc0 : 1;
+- mmr_t overflow_ii_vc2 : 1;
+- mmr_t overflow_ii_vc0 : 1;
+- mmr_t overflow_lb_debit2 : 1;
+- mmr_t overflow_lb_debit0 : 1;
+- mmr_t overflow_ii_debit2 : 1;
+- mmr_t overflow_ii_debit0 : 1;
+- } sh_xniilb_error_overflow_s;
+-} sh_xniilb_error_overflow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNIILB_ERROR_MASK" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xniilb_error_mask_u {
+ mmr_t sh_xniilb_error_mask_regval;
+ struct {
+@@ -16909,83 +9126,11 @@
+ mmr_t lut_read_error : 1;
+ } sh_xniilb_error_mask_s;
+ } sh_xniilb_error_mask_u_t;
+-#else
+-typedef union sh_xniilb_error_mask_u {
+- mmr_t sh_xniilb_error_mask_regval;
+- struct {
+- mmr_t lut_read_error : 1;
+- mmr_t chiplet_nomatch : 1;
+- mmr_t underflow_ni1_vc2_credit_out : 1;
+- mmr_t underflow_ni1_vc0_credit_out : 1;
+- mmr_t underflow_ni0_vc2_credit_out : 1;
+- mmr_t underflow_ni0_vc0_credit_out : 1;
+- mmr_t underflow_iilb_vc2_credit_out : 1;
+- mmr_t underflow_iilb_vc0_credit_out : 1;
+- mmr_t underflow_md_vc2_credit_out : 1;
+- mmr_t underflow_md_vc0_credit_out : 1;
+- mmr_t underflow_pi_vc2_credit_out : 1;
+- mmr_t underflow_pi_vc0_credit_out : 1;
+- mmr_t overflow_ni1_vc2_credit_out : 1;
+- mmr_t overflow_ni1_vc0_credit_out : 1;
+- mmr_t overflow_ni0_vc2_credit_out : 1;
+- mmr_t overflow_ni0_vc0_credit_out : 1;
+- mmr_t overflow_iilb_vc2_credit_out : 1;
+- mmr_t overflow_iilb_vc0_credit_out : 1;
+- mmr_t overflow_md_vc2_credit_out : 1;
+- mmr_t overflow_md_vc0_credit_out : 1;
+- mmr_t overflow_pi_vc2_credit_out : 1;
+- mmr_t overflow_pi_vc0_credit_out : 1;
+- mmr_t overflow_ni1_debit2 : 1;
+- mmr_t overflow_ni1_debit0 : 1;
+- mmr_t overflow_ni0_debit2 : 1;
+- mmr_t overflow_ni0_debit0 : 1;
+- mmr_t overflow_md_debit2 : 1;
+- mmr_t overflow_md_debit0 : 1;
+- mmr_t overflow_iilb_debit2 : 1;
+- mmr_t overflow_iilb_debit0 : 1;
+- mmr_t overflow_pi_debit2 : 1;
+- mmr_t overflow_pi_debit0 : 1;
+- mmr_t underflow_ni1_vc2_credit_in : 1;
+- mmr_t underflow_ni0_vc2_credit_in : 1;
+- mmr_t underflow_md_vc2_credit_in : 1;
+- mmr_t underflow_iilb_vc2_credit_in : 1;
+- mmr_t underflow_pi_vc2_credit_in : 1;
+- mmr_t underflow_ni1_vc0_credit_in : 1;
+- mmr_t underflow_ni0_vc0_credit_in : 1;
+- mmr_t underflow_md_vc0_credit_in : 1;
+- mmr_t underflow_iilb_vc0_credit_in : 1;
+- mmr_t underflow_pi_vc0_credit_in : 1;
+- mmr_t overflow_ni1_vc2_credit_in : 1;
+- mmr_t overflow_ni0_vc2_credit_in : 1;
+- mmr_t overflow_md_vc2_credit_in : 1;
+- mmr_t overflow_iilb_vc2_credit_in : 1;
+- mmr_t overflow_pi_vc2_credit_in : 1;
+- mmr_t overflow_ni1_vc0_credit_in : 1;
+- mmr_t overflow_ni0_vc0_credit_in : 1;
+- mmr_t overflow_md_vc0_credit_in : 1;
+- mmr_t overflow_iilb_vc0_credit_in : 1;
+- mmr_t overflow_pi_vc0_credit_in : 1;
+- mmr_t underflow_lb_vc2 : 1;
+- mmr_t underflow_lb_vc0 : 1;
+- mmr_t overflow_lb_vc2 : 1;
+- mmr_t overflow_lb_vc0 : 1;
+- mmr_t underflow_ii_vc2 : 1;
+- mmr_t underflow_ii_vc0 : 1;
+- mmr_t overflow_ii_vc2 : 1;
+- mmr_t overflow_ii_vc0 : 1;
+- mmr_t overflow_lb_debit2 : 1;
+- mmr_t overflow_lb_debit0 : 1;
+- mmr_t overflow_ii_debit2 : 1;
+- mmr_t overflow_ii_debit0 : 1;
+- } sh_xniilb_error_mask_s;
+-} sh_xniilb_error_mask_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNIILB_FIRST_ERROR" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xniilb_first_error_u {
+ mmr_t sh_xniilb_first_error_regval;
+ struct {
+@@ -17055,85 +9200,13 @@
+ mmr_t lut_read_error : 1;
+ } sh_xniilb_first_error_s;
+ } sh_xniilb_first_error_u_t;
+-#else
+-typedef union sh_xniilb_first_error_u {
+- mmr_t sh_xniilb_first_error_regval;
+- struct {
+- mmr_t lut_read_error : 1;
+- mmr_t chiplet_nomatch : 1;
+- mmr_t underflow_ni1_vc2_credit_out : 1;
+- mmr_t underflow_ni1_vc0_credit_out : 1;
+- mmr_t underflow_ni0_vc2_credit_out : 1;
+- mmr_t underflow_ni0_vc0_credit_out : 1;
+- mmr_t underflow_iilb_vc2_credit_out : 1;
+- mmr_t underflow_iilb_vc0_credit_out : 1;
+- mmr_t underflow_md_vc2_credit_out : 1;
+- mmr_t underflow_md_vc0_credit_out : 1;
+- mmr_t underflow_pi_vc2_credit_out : 1;
+- mmr_t underflow_pi_vc0_credit_out : 1;
+- mmr_t overflow_ni1_vc2_credit_out : 1;
+- mmr_t overflow_ni1_vc0_credit_out : 1;
+- mmr_t overflow_ni0_vc2_credit_out : 1;
+- mmr_t overflow_ni0_vc0_credit_out : 1;
+- mmr_t overflow_iilb_vc2_credit_out : 1;
+- mmr_t overflow_iilb_vc0_credit_out : 1;
+- mmr_t overflow_md_vc2_credit_out : 1;
+- mmr_t overflow_md_vc0_credit_out : 1;
+- mmr_t overflow_pi_vc2_credit_out : 1;
+- mmr_t overflow_pi_vc0_credit_out : 1;
+- mmr_t overflow_ni1_debit2 : 1;
+- mmr_t overflow_ni1_debit0 : 1;
+- mmr_t overflow_ni0_debit2 : 1;
+- mmr_t overflow_ni0_debit0 : 1;
+- mmr_t overflow_md_debit2 : 1;
+- mmr_t overflow_md_debit0 : 1;
+- mmr_t overflow_iilb_debit2 : 1;
+- mmr_t overflow_iilb_debit0 : 1;
+- mmr_t overflow_pi_debit2 : 1;
+- mmr_t overflow_pi_debit0 : 1;
+- mmr_t underflow_ni1_vc2_credit_in : 1;
+- mmr_t underflow_ni0_vc2_credit_in : 1;
+- mmr_t underflow_md_vc2_credit_in : 1;
+- mmr_t underflow_iilb_vc2_credit_in : 1;
+- mmr_t underflow_pi_vc2_credit_in : 1;
+- mmr_t underflow_ni1_vc0_credit_in : 1;
+- mmr_t underflow_ni0_vc0_credit_in : 1;
+- mmr_t underflow_md_vc0_credit_in : 1;
+- mmr_t underflow_iilb_vc0_credit_in : 1;
+- mmr_t underflow_pi_vc0_credit_in : 1;
+- mmr_t overflow_ni1_vc2_credit_in : 1;
+- mmr_t overflow_ni0_vc2_credit_in : 1;
+- mmr_t overflow_md_vc2_credit_in : 1;
+- mmr_t overflow_iilb_vc2_credit_in : 1;
+- mmr_t overflow_pi_vc2_credit_in : 1;
+- mmr_t overflow_ni1_vc0_credit_in : 1;
+- mmr_t overflow_ni0_vc0_credit_in : 1;
+- mmr_t overflow_md_vc0_credit_in : 1;
+- mmr_t overflow_iilb_vc0_credit_in : 1;
+- mmr_t overflow_pi_vc0_credit_in : 1;
+- mmr_t underflow_lb_vc2 : 1;
+- mmr_t underflow_lb_vc0 : 1;
+- mmr_t overflow_lb_vc2 : 1;
+- mmr_t overflow_lb_vc0 : 1;
+- mmr_t underflow_ii_vc2 : 1;
+- mmr_t underflow_ii_vc0 : 1;
+- mmr_t overflow_ii_vc2 : 1;
+- mmr_t overflow_ii_vc0 : 1;
+- mmr_t overflow_lb_debit2 : 1;
+- mmr_t overflow_lb_debit0 : 1;
+- mmr_t overflow_ii_debit2 : 1;
+- mmr_t overflow_ii_debit0 : 1;
+- } sh_xniilb_first_error_s;
+-} sh_xniilb_first_error_u_t;
+-#endif
+-
+-/* ==================================================================== */
+-/* Register "SH_XNPI_ERROR_SUMMARY" */
+-/* ==================================================================== */
+-
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xnpi_error_summary_u {
+- mmr_t sh_xnpi_error_summary_regval;
++
++/* ==================================================================== */
++/* Register "SH_XNPI_ERROR_SUMMARY" */
++/* ==================================================================== */
++
++typedef union sh_xnpi_error_summary_u {
++ mmr_t sh_xnpi_error_summary_regval;
+ struct {
+ mmr_t underflow_ni0_vc0 : 1;
+ mmr_t overflow_ni0_vc0 : 1;
+@@ -17188,70 +9261,11 @@
+ mmr_t reserved_0 : 14;
+ } sh_xnpi_error_summary_s;
+ } sh_xnpi_error_summary_u_t;
+-#else
+-typedef union sh_xnpi_error_summary_u {
+- mmr_t sh_xnpi_error_summary_regval;
+- struct {
+- mmr_t reserved_0 : 14;
+- mmr_t overflow_header_cancel_fifo : 1;
+- mmr_t overflow_iilb_vc2_credit : 1;
+- mmr_t underflow_iilb_vc2_credit : 1;
+- mmr_t overflow_iilb_vc0_credit : 1;
+- mmr_t underflow_iilb_vc0_credit : 1;
+- mmr_t overflow_ni1_vc2_credit : 1;
+- mmr_t underflow_ni1_vc2_credit : 1;
+- mmr_t overflow_ni1_vc0_credit : 1;
+- mmr_t underflow_ni1_vc0_credit : 1;
+- mmr_t overflow_ni0_vc2_credit : 1;
+- mmr_t underflow_ni0_vc2_credit : 1;
+- mmr_t overflow_ni0_vc0_credit : 1;
+- mmr_t underflow_ni0_vc0_credit : 1;
+- mmr_t overflow_iilb_debit2 : 1;
+- mmr_t overflow_iilb_debit0 : 1;
+- mmr_t overflow_ni1_debit2 : 1;
+- mmr_t overflow_ni1_debit0 : 1;
+- mmr_t overflow_ni0_debit2 : 1;
+- mmr_t overflow_ni0_debit0 : 1;
+- mmr_t overflow_sic_cntr2 : 1;
+- mmr_t underflow_sic_cntr2 : 1;
+- mmr_t overflow_sic_cntr0 : 1;
+- mmr_t underflow_sic_cntr0 : 1;
+- mmr_t uncor_error3 : 1;
+- mmr_t uncor_error2 : 1;
+- mmr_t uncor_error1 : 1;
+- mmr_t uncor_error0 : 1;
+- mmr_t single_bit_error3 : 1;
+- mmr_t single_bit_error2 : 1;
+- mmr_t single_bit_error1 : 1;
+- mmr_t single_bit_error0 : 1;
+- mmr_t lut_read_error : 1;
+- mmr_t overflow_databuff_vc2 : 1;
+- mmr_t overflow_databuff_vc0 : 1;
+- mmr_t overflow_vc2_credit : 1;
+- mmr_t underflow_vc2_credit : 1;
+- mmr_t overflow_vc0_credit : 1;
+- mmr_t underflow_vc0_credit : 1;
+- mmr_t overflow_iilb_vc2 : 1;
+- mmr_t underflow_iilb_vc2 : 1;
+- mmr_t overflow_iilb_vc0 : 1;
+- mmr_t underflow_iilb_vc0 : 1;
+- mmr_t overflow_ni1_vc2 : 1;
+- mmr_t underflow_ni1_vc2 : 1;
+- mmr_t overflow_ni1_vc0 : 1;
+- mmr_t underflow_ni1_vc0 : 1;
+- mmr_t overflow_ni0_vc2 : 1;
+- mmr_t underflow_ni0_vc2 : 1;
+- mmr_t overflow_ni0_vc0 : 1;
+- mmr_t underflow_ni0_vc0 : 1;
+- } sh_xnpi_error_summary_s;
+-} sh_xnpi_error_summary_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNPI_ERROR_OVERFLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnpi_error_overflow_u {
+ mmr_t sh_xnpi_error_overflow_regval;
+ struct {
+@@ -17308,70 +9322,11 @@
+ mmr_t reserved_0 : 14;
+ } sh_xnpi_error_overflow_s;
+ } sh_xnpi_error_overflow_u_t;
+-#else
+-typedef union sh_xnpi_error_overflow_u {
+- mmr_t sh_xnpi_error_overflow_regval;
+- struct {
+- mmr_t reserved_0 : 14;
+- mmr_t overflow_header_cancel_fifo : 1;
+- mmr_t overflow_iilb_vc2_credit : 1;
+- mmr_t underflow_iilb_vc2_credit : 1;
+- mmr_t overflow_iilb_vc0_credit : 1;
+- mmr_t underflow_iilb_vc0_credit : 1;
+- mmr_t overflow_ni1_vc2_credit : 1;
+- mmr_t underflow_ni1_vc2_credit : 1;
+- mmr_t overflow_ni1_vc0_credit : 1;
+- mmr_t underflow_ni1_vc0_credit : 1;
+- mmr_t overflow_ni0_vc2_credit : 1;
+- mmr_t underflow_ni0_vc2_credit : 1;
+- mmr_t overflow_ni0_vc0_credit : 1;
+- mmr_t underflow_ni0_vc0_credit : 1;
+- mmr_t overflow_iilb_debit2 : 1;
+- mmr_t overflow_iilb_debit0 : 1;
+- mmr_t overflow_ni1_debit2 : 1;
+- mmr_t overflow_ni1_debit0 : 1;
+- mmr_t overflow_ni0_debit2 : 1;
+- mmr_t overflow_ni0_debit0 : 1;
+- mmr_t overflow_sic_cntr2 : 1;
+- mmr_t underflow_sic_cntr2 : 1;
+- mmr_t overflow_sic_cntr0 : 1;
+- mmr_t underflow_sic_cntr0 : 1;
+- mmr_t uncor_error3 : 1;
+- mmr_t uncor_error2 : 1;
+- mmr_t uncor_error1 : 1;
+- mmr_t uncor_error0 : 1;
+- mmr_t single_bit_error3 : 1;
+- mmr_t single_bit_error2 : 1;
+- mmr_t single_bit_error1 : 1;
+- mmr_t single_bit_error0 : 1;
+- mmr_t lut_read_error : 1;
+- mmr_t overflow_databuff_vc2 : 1;
+- mmr_t overflow_databuff_vc0 : 1;
+- mmr_t overflow_vc2_credit : 1;
+- mmr_t underflow_vc2_credit : 1;
+- mmr_t overflow_vc0_credit : 1;
+- mmr_t underflow_vc0_credit : 1;
+- mmr_t overflow_iilb_vc2 : 1;
+- mmr_t underflow_iilb_vc2 : 1;
+- mmr_t overflow_iilb_vc0 : 1;
+- mmr_t underflow_iilb_vc0 : 1;
+- mmr_t overflow_ni1_vc2 : 1;
+- mmr_t underflow_ni1_vc2 : 1;
+- mmr_t overflow_ni1_vc0 : 1;
+- mmr_t underflow_ni1_vc0 : 1;
+- mmr_t overflow_ni0_vc2 : 1;
+- mmr_t underflow_ni0_vc2 : 1;
+- mmr_t overflow_ni0_vc0 : 1;
+- mmr_t underflow_ni0_vc0 : 1;
+- } sh_xnpi_error_overflow_s;
+-} sh_xnpi_error_overflow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNPI_ERROR_MASK" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnpi_error_mask_u {
+ mmr_t sh_xnpi_error_mask_regval;
+ struct {
+@@ -17428,70 +9383,11 @@
+ mmr_t reserved_0 : 14;
+ } sh_xnpi_error_mask_s;
+ } sh_xnpi_error_mask_u_t;
+-#else
+-typedef union sh_xnpi_error_mask_u {
+- mmr_t sh_xnpi_error_mask_regval;
+- struct {
+- mmr_t reserved_0 : 14;
+- mmr_t overflow_header_cancel_fifo : 1;
+- mmr_t overflow_iilb_vc2_credit : 1;
+- mmr_t underflow_iilb_vc2_credit : 1;
+- mmr_t overflow_iilb_vc0_credit : 1;
+- mmr_t underflow_iilb_vc0_credit : 1;
+- mmr_t overflow_ni1_vc2_credit : 1;
+- mmr_t underflow_ni1_vc2_credit : 1;
+- mmr_t overflow_ni1_vc0_credit : 1;
+- mmr_t underflow_ni1_vc0_credit : 1;
+- mmr_t overflow_ni0_vc2_credit : 1;
+- mmr_t underflow_ni0_vc2_credit : 1;
+- mmr_t overflow_ni0_vc0_credit : 1;
+- mmr_t underflow_ni0_vc0_credit : 1;
+- mmr_t overflow_iilb_debit2 : 1;
+- mmr_t overflow_iilb_debit0 : 1;
+- mmr_t overflow_ni1_debit2 : 1;
+- mmr_t overflow_ni1_debit0 : 1;
+- mmr_t overflow_ni0_debit2 : 1;
+- mmr_t overflow_ni0_debit0 : 1;
+- mmr_t overflow_sic_cntr2 : 1;
+- mmr_t underflow_sic_cntr2 : 1;
+- mmr_t overflow_sic_cntr0 : 1;
+- mmr_t underflow_sic_cntr0 : 1;
+- mmr_t uncor_error3 : 1;
+- mmr_t uncor_error2 : 1;
+- mmr_t uncor_error1 : 1;
+- mmr_t uncor_error0 : 1;
+- mmr_t single_bit_error3 : 1;
+- mmr_t single_bit_error2 : 1;
+- mmr_t single_bit_error1 : 1;
+- mmr_t single_bit_error0 : 1;
+- mmr_t lut_read_error : 1;
+- mmr_t overflow_databuff_vc2 : 1;
+- mmr_t overflow_databuff_vc0 : 1;
+- mmr_t overflow_vc2_credit : 1;
+- mmr_t underflow_vc2_credit : 1;
+- mmr_t overflow_vc0_credit : 1;
+- mmr_t underflow_vc0_credit : 1;
+- mmr_t overflow_iilb_vc2 : 1;
+- mmr_t underflow_iilb_vc2 : 1;
+- mmr_t overflow_iilb_vc0 : 1;
+- mmr_t underflow_iilb_vc0 : 1;
+- mmr_t overflow_ni1_vc2 : 1;
+- mmr_t underflow_ni1_vc2 : 1;
+- mmr_t overflow_ni1_vc0 : 1;
+- mmr_t underflow_ni1_vc0 : 1;
+- mmr_t overflow_ni0_vc2 : 1;
+- mmr_t underflow_ni0_vc2 : 1;
+- mmr_t overflow_ni0_vc0 : 1;
+- mmr_t underflow_ni0_vc0 : 1;
+- } sh_xnpi_error_mask_s;
+-} sh_xnpi_error_mask_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNPI_FIRST_ERROR" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnpi_first_error_u {
+ mmr_t sh_xnpi_first_error_regval;
+ struct {
+@@ -17548,72 +9444,13 @@
+ mmr_t reserved_0 : 14;
+ } sh_xnpi_first_error_s;
+ } sh_xnpi_first_error_u_t;
+-#else
+-typedef union sh_xnpi_first_error_u {
+- mmr_t sh_xnpi_first_error_regval;
+- struct {
+- mmr_t reserved_0 : 14;
+- mmr_t overflow_header_cancel_fifo : 1;
+- mmr_t overflow_iilb_vc2_credit : 1;
+- mmr_t underflow_iilb_vc2_credit : 1;
+- mmr_t overflow_iilb_vc0_credit : 1;
+- mmr_t underflow_iilb_vc0_credit : 1;
+- mmr_t overflow_ni1_vc2_credit : 1;
+- mmr_t underflow_ni1_vc2_credit : 1;
+- mmr_t overflow_ni1_vc0_credit : 1;
+- mmr_t underflow_ni1_vc0_credit : 1;
+- mmr_t overflow_ni0_vc2_credit : 1;
+- mmr_t underflow_ni0_vc2_credit : 1;
+- mmr_t overflow_ni0_vc0_credit : 1;
+- mmr_t underflow_ni0_vc0_credit : 1;
+- mmr_t overflow_iilb_debit2 : 1;
+- mmr_t overflow_iilb_debit0 : 1;
+- mmr_t overflow_ni1_debit2 : 1;
+- mmr_t overflow_ni1_debit0 : 1;
+- mmr_t overflow_ni0_debit2 : 1;
+- mmr_t overflow_ni0_debit0 : 1;
+- mmr_t overflow_sic_cntr2 : 1;
+- mmr_t underflow_sic_cntr2 : 1;
+- mmr_t overflow_sic_cntr0 : 1;
+- mmr_t underflow_sic_cntr0 : 1;
+- mmr_t uncor_error3 : 1;
+- mmr_t uncor_error2 : 1;
+- mmr_t uncor_error1 : 1;
+- mmr_t uncor_error0 : 1;
+- mmr_t single_bit_error3 : 1;
+- mmr_t single_bit_error2 : 1;
+- mmr_t single_bit_error1 : 1;
+- mmr_t single_bit_error0 : 1;
+- mmr_t lut_read_error : 1;
+- mmr_t overflow_databuff_vc2 : 1;
+- mmr_t overflow_databuff_vc0 : 1;
+- mmr_t overflow_vc2_credit : 1;
+- mmr_t underflow_vc2_credit : 1;
+- mmr_t overflow_vc0_credit : 1;
+- mmr_t underflow_vc0_credit : 1;
+- mmr_t overflow_iilb_vc2 : 1;
+- mmr_t underflow_iilb_vc2 : 1;
+- mmr_t overflow_iilb_vc0 : 1;
+- mmr_t underflow_iilb_vc0 : 1;
+- mmr_t overflow_ni1_vc2 : 1;
+- mmr_t underflow_ni1_vc2 : 1;
+- mmr_t overflow_ni1_vc0 : 1;
+- mmr_t underflow_ni1_vc0 : 1;
+- mmr_t overflow_ni0_vc2 : 1;
+- mmr_t underflow_ni0_vc2 : 1;
+- mmr_t overflow_ni0_vc0 : 1;
+- mmr_t underflow_ni0_vc0 : 1;
+- } sh_xnpi_first_error_s;
+-} sh_xnpi_first_error_u_t;
+-#endif
+-
+-/* ==================================================================== */
+-/* Register "SH_XNMD_ERROR_SUMMARY" */
+-/* ==================================================================== */
+-
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xnmd_error_summary_u {
+- mmr_t sh_xnmd_error_summary_regval;
++
++/* ==================================================================== */
++/* Register "SH_XNMD_ERROR_SUMMARY" */
++/* ==================================================================== */
++
++typedef union sh_xnmd_error_summary_u {
++ mmr_t sh_xnmd_error_summary_regval;
+ struct {
+ mmr_t underflow_ni0_vc0 : 1;
+ mmr_t overflow_ni0_vc0 : 1;
+@@ -17668,70 +9505,11 @@
+ mmr_t reserved_0 : 14;
+ } sh_xnmd_error_summary_s;
+ } sh_xnmd_error_summary_u_t;
+-#else
+-typedef union sh_xnmd_error_summary_u {
+- mmr_t sh_xnmd_error_summary_regval;
+- struct {
+- mmr_t reserved_0 : 14;
+- mmr_t overflow_header_cancel_fifo : 1;
+- mmr_t overflow_iilb_vc2_credit : 1;
+- mmr_t underflow_iilb_vc2_credit : 1;
+- mmr_t overflow_iilb_vc0_credit : 1;
+- mmr_t underflow_iilb_vc0_credit : 1;
+- mmr_t overflow_ni1_vc2_credit : 1;
+- mmr_t underflow_ni1_vc2_credit : 1;
+- mmr_t overflow_ni1_vc0_credit : 1;
+- mmr_t underflow_ni1_vc0_credit : 1;
+- mmr_t overflow_ni0_vc2_credit : 1;
+- mmr_t underflow_ni0_vc2_credit : 1;
+- mmr_t overflow_ni0_vc0_credit : 1;
+- mmr_t underflow_ni0_vc0_credit : 1;
+- mmr_t overflow_iilb_debit2 : 1;
+- mmr_t overflow_iilb_debit0 : 1;
+- mmr_t overflow_ni1_debit2 : 1;
+- mmr_t overflow_ni1_debit0 : 1;
+- mmr_t overflow_ni0_debit2 : 1;
+- mmr_t overflow_ni0_debit0 : 1;
+- mmr_t overflow_sic_cntr2 : 1;
+- mmr_t underflow_sic_cntr2 : 1;
+- mmr_t overflow_sic_cntr0 : 1;
+- mmr_t underflow_sic_cntr0 : 1;
+- mmr_t uncor_error3 : 1;
+- mmr_t uncor_error2 : 1;
+- mmr_t uncor_error1 : 1;
+- mmr_t uncor_error0 : 1;
+- mmr_t single_bit_error3 : 1;
+- mmr_t single_bit_error2 : 1;
+- mmr_t single_bit_error1 : 1;
+- mmr_t single_bit_error0 : 1;
+- mmr_t lut_read_error : 1;
+- mmr_t overflow_databuff_vc2 : 1;
+- mmr_t overflow_databuff_vc0 : 1;
+- mmr_t overflow_vc2_credit : 1;
+- mmr_t underflow_vc2_credit : 1;
+- mmr_t overflow_vc0_credit : 1;
+- mmr_t underflow_vc0_credit : 1;
+- mmr_t overflow_iilb_vc2 : 1;
+- mmr_t underflow_iilb_vc2 : 1;
+- mmr_t overflow_iilb_vc0 : 1;
+- mmr_t underflow_iilb_vc0 : 1;
+- mmr_t overflow_ni1_vc2 : 1;
+- mmr_t underflow_ni1_vc2 : 1;
+- mmr_t overflow_ni1_vc0 : 1;
+- mmr_t underflow_ni1_vc0 : 1;
+- mmr_t overflow_ni0_vc2 : 1;
+- mmr_t underflow_ni0_vc2 : 1;
+- mmr_t overflow_ni0_vc0 : 1;
+- mmr_t underflow_ni0_vc0 : 1;
+- } sh_xnmd_error_summary_s;
+-} sh_xnmd_error_summary_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNMD_ERROR_OVERFLOW" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnmd_error_overflow_u {
+ mmr_t sh_xnmd_error_overflow_regval;
+ struct {
+@@ -17788,70 +9566,11 @@
+ mmr_t reserved_0 : 14;
+ } sh_xnmd_error_overflow_s;
+ } sh_xnmd_error_overflow_u_t;
+-#else
+-typedef union sh_xnmd_error_overflow_u {
+- mmr_t sh_xnmd_error_overflow_regval;
+- struct {
+- mmr_t reserved_0 : 14;
+- mmr_t overflow_header_cancel_fifo : 1;
+- mmr_t overflow_iilb_vc2_credit : 1;
+- mmr_t underflow_iilb_vc2_credit : 1;
+- mmr_t overflow_iilb_vc0_credit : 1;
+- mmr_t underflow_iilb_vc0_credit : 1;
+- mmr_t overflow_ni1_vc2_credit : 1;
+- mmr_t underflow_ni1_vc2_credit : 1;
+- mmr_t overflow_ni1_vc0_credit : 1;
+- mmr_t underflow_ni1_vc0_credit : 1;
+- mmr_t overflow_ni0_vc2_credit : 1;
+- mmr_t underflow_ni0_vc2_credit : 1;
+- mmr_t overflow_ni0_vc0_credit : 1;
+- mmr_t underflow_ni0_vc0_credit : 1;
+- mmr_t overflow_iilb_debit2 : 1;
+- mmr_t overflow_iilb_debit0 : 1;
+- mmr_t overflow_ni1_debit2 : 1;
+- mmr_t overflow_ni1_debit0 : 1;
+- mmr_t overflow_ni0_debit2 : 1;
+- mmr_t overflow_ni0_debit0 : 1;
+- mmr_t overflow_sic_cntr2 : 1;
+- mmr_t underflow_sic_cntr2 : 1;
+- mmr_t overflow_sic_cntr0 : 1;
+- mmr_t underflow_sic_cntr0 : 1;
+- mmr_t uncor_error3 : 1;
+- mmr_t uncor_error2 : 1;
+- mmr_t uncor_error1 : 1;
+- mmr_t uncor_error0 : 1;
+- mmr_t single_bit_error3 : 1;
+- mmr_t single_bit_error2 : 1;
+- mmr_t single_bit_error1 : 1;
+- mmr_t single_bit_error0 : 1;
+- mmr_t lut_read_error : 1;
+- mmr_t overflow_databuff_vc2 : 1;
+- mmr_t overflow_databuff_vc0 : 1;
+- mmr_t overflow_vc2_credit : 1;
+- mmr_t underflow_vc2_credit : 1;
+- mmr_t overflow_vc0_credit : 1;
+- mmr_t underflow_vc0_credit : 1;
+- mmr_t overflow_iilb_vc2 : 1;
+- mmr_t underflow_iilb_vc2 : 1;
+- mmr_t overflow_iilb_vc0 : 1;
+- mmr_t underflow_iilb_vc0 : 1;
+- mmr_t overflow_ni1_vc2 : 1;
+- mmr_t underflow_ni1_vc2 : 1;
+- mmr_t overflow_ni1_vc0 : 1;
+- mmr_t underflow_ni1_vc0 : 1;
+- mmr_t overflow_ni0_vc2 : 1;
+- mmr_t underflow_ni0_vc2 : 1;
+- mmr_t overflow_ni0_vc0 : 1;
+- mmr_t underflow_ni0_vc0 : 1;
+- } sh_xnmd_error_overflow_s;
+-} sh_xnmd_error_overflow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNMD_ERROR_MASK" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnmd_error_mask_u {
+ mmr_t sh_xnmd_error_mask_regval;
+ struct {
+@@ -17908,70 +9627,11 @@
+ mmr_t reserved_0 : 14;
+ } sh_xnmd_error_mask_s;
+ } sh_xnmd_error_mask_u_t;
+-#else
+-typedef union sh_xnmd_error_mask_u {
+- mmr_t sh_xnmd_error_mask_regval;
+- struct {
+- mmr_t reserved_0 : 14;
+- mmr_t overflow_header_cancel_fifo : 1;
+- mmr_t overflow_iilb_vc2_credit : 1;
+- mmr_t underflow_iilb_vc2_credit : 1;
+- mmr_t overflow_iilb_vc0_credit : 1;
+- mmr_t underflow_iilb_vc0_credit : 1;
+- mmr_t overflow_ni1_vc2_credit : 1;
+- mmr_t underflow_ni1_vc2_credit : 1;
+- mmr_t overflow_ni1_vc0_credit : 1;
+- mmr_t underflow_ni1_vc0_credit : 1;
+- mmr_t overflow_ni0_vc2_credit : 1;
+- mmr_t underflow_ni0_vc2_credit : 1;
+- mmr_t overflow_ni0_vc0_credit : 1;
+- mmr_t underflow_ni0_vc0_credit : 1;
+- mmr_t overflow_iilb_debit2 : 1;
+- mmr_t overflow_iilb_debit0 : 1;
+- mmr_t overflow_ni1_debit2 : 1;
+- mmr_t overflow_ni1_debit0 : 1;
+- mmr_t overflow_ni0_debit2 : 1;
+- mmr_t overflow_ni0_debit0 : 1;
+- mmr_t overflow_sic_cntr2 : 1;
+- mmr_t underflow_sic_cntr2 : 1;
+- mmr_t overflow_sic_cntr0 : 1;
+- mmr_t underflow_sic_cntr0 : 1;
+- mmr_t uncor_error3 : 1;
+- mmr_t uncor_error2 : 1;
+- mmr_t uncor_error1 : 1;
+- mmr_t uncor_error0 : 1;
+- mmr_t single_bit_error3 : 1;
+- mmr_t single_bit_error2 : 1;
+- mmr_t single_bit_error1 : 1;
+- mmr_t single_bit_error0 : 1;
+- mmr_t lut_read_error : 1;
+- mmr_t overflow_databuff_vc2 : 1;
+- mmr_t overflow_databuff_vc0 : 1;
+- mmr_t overflow_vc2_credit : 1;
+- mmr_t underflow_vc2_credit : 1;
+- mmr_t overflow_vc0_credit : 1;
+- mmr_t underflow_vc0_credit : 1;
+- mmr_t overflow_iilb_vc2 : 1;
+- mmr_t underflow_iilb_vc2 : 1;
+- mmr_t overflow_iilb_vc0 : 1;
+- mmr_t underflow_iilb_vc0 : 1;
+- mmr_t overflow_ni1_vc2 : 1;
+- mmr_t underflow_ni1_vc2 : 1;
+- mmr_t overflow_ni1_vc0 : 1;
+- mmr_t underflow_ni1_vc0 : 1;
+- mmr_t overflow_ni0_vc2 : 1;
+- mmr_t underflow_ni0_vc2 : 1;
+- mmr_t overflow_ni0_vc0 : 1;
+- mmr_t underflow_ni0_vc0 : 1;
+- } sh_xnmd_error_mask_s;
+-} sh_xnmd_error_mask_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XNMD_FIRST_ERROR" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnmd_first_error_u {
+ mmr_t sh_xnmd_first_error_regval;
+ struct {
+@@ -17981,202 +9641,107 @@
+ mmr_t overflow_ni0_vc2 : 1;
+ mmr_t underflow_ni1_vc0 : 1;
+ mmr_t overflow_ni1_vc0 : 1;
+- mmr_t underflow_ni1_vc2 : 1;
+- mmr_t overflow_ni1_vc2 : 1;
+- mmr_t underflow_iilb_vc0 : 1;
+- mmr_t overflow_iilb_vc0 : 1;
+- mmr_t underflow_iilb_vc2 : 1;
+- mmr_t overflow_iilb_vc2 : 1;
+- mmr_t underflow_vc0_credit : 1;
+- mmr_t overflow_vc0_credit : 1;
+- mmr_t underflow_vc2_credit : 1;
+- mmr_t overflow_vc2_credit : 1;
+- mmr_t overflow_databuff_vc0 : 1;
+- mmr_t overflow_databuff_vc2 : 1;
+- mmr_t lut_read_error : 1;
+- mmr_t single_bit_error0 : 1;
+- mmr_t single_bit_error1 : 1;
+- mmr_t single_bit_error2 : 1;
+- mmr_t single_bit_error3 : 1;
+- mmr_t uncor_error0 : 1;
+- mmr_t uncor_error1 : 1;
+- mmr_t uncor_error2 : 1;
+- mmr_t uncor_error3 : 1;
+- mmr_t underflow_sic_cntr0 : 1;
+- mmr_t overflow_sic_cntr0 : 1;
+- mmr_t underflow_sic_cntr2 : 1;
+- mmr_t overflow_sic_cntr2 : 1;
+- mmr_t overflow_ni0_debit0 : 1;
+- mmr_t overflow_ni0_debit2 : 1;
+- mmr_t overflow_ni1_debit0 : 1;
+- mmr_t overflow_ni1_debit2 : 1;
+- mmr_t overflow_iilb_debit0 : 1;
+- mmr_t overflow_iilb_debit2 : 1;
+- mmr_t underflow_ni0_vc0_credit : 1;
+- mmr_t overflow_ni0_vc0_credit : 1;
+- mmr_t underflow_ni0_vc2_credit : 1;
+- mmr_t overflow_ni0_vc2_credit : 1;
+- mmr_t underflow_ni1_vc0_credit : 1;
+- mmr_t overflow_ni1_vc0_credit : 1;
+- mmr_t underflow_ni1_vc2_credit : 1;
+- mmr_t overflow_ni1_vc2_credit : 1;
+- mmr_t underflow_iilb_vc0_credit : 1;
+- mmr_t overflow_iilb_vc0_credit : 1;
+- mmr_t underflow_iilb_vc2_credit : 1;
+- mmr_t overflow_iilb_vc2_credit : 1;
+- mmr_t overflow_header_cancel_fifo : 1;
+- mmr_t reserved_0 : 14;
+- } sh_xnmd_first_error_s;
+-} sh_xnmd_first_error_u_t;
+-#else
+-typedef union sh_xnmd_first_error_u {
+- mmr_t sh_xnmd_first_error_regval;
+- struct {
+- mmr_t reserved_0 : 14;
+- mmr_t overflow_header_cancel_fifo : 1;
+- mmr_t overflow_iilb_vc2_credit : 1;
+- mmr_t underflow_iilb_vc2_credit : 1;
+- mmr_t overflow_iilb_vc0_credit : 1;
+- mmr_t underflow_iilb_vc0_credit : 1;
+- mmr_t overflow_ni1_vc2_credit : 1;
+- mmr_t underflow_ni1_vc2_credit : 1;
+- mmr_t overflow_ni1_vc0_credit : 1;
+- mmr_t underflow_ni1_vc0_credit : 1;
+- mmr_t overflow_ni0_vc2_credit : 1;
+- mmr_t underflow_ni0_vc2_credit : 1;
+- mmr_t overflow_ni0_vc0_credit : 1;
+- mmr_t underflow_ni0_vc0_credit : 1;
+- mmr_t overflow_iilb_debit2 : 1;
+- mmr_t overflow_iilb_debit0 : 1;
+- mmr_t overflow_ni1_debit2 : 1;
+- mmr_t overflow_ni1_debit0 : 1;
+- mmr_t overflow_ni0_debit2 : 1;
+- mmr_t overflow_ni0_debit0 : 1;
+- mmr_t overflow_sic_cntr2 : 1;
+- mmr_t underflow_sic_cntr2 : 1;
+- mmr_t overflow_sic_cntr0 : 1;
+- mmr_t underflow_sic_cntr0 : 1;
+- mmr_t uncor_error3 : 1;
+- mmr_t uncor_error2 : 1;
+- mmr_t uncor_error1 : 1;
+- mmr_t uncor_error0 : 1;
+- mmr_t single_bit_error3 : 1;
+- mmr_t single_bit_error2 : 1;
+- mmr_t single_bit_error1 : 1;
+- mmr_t single_bit_error0 : 1;
+- mmr_t lut_read_error : 1;
+- mmr_t overflow_databuff_vc2 : 1;
+- mmr_t overflow_databuff_vc0 : 1;
+- mmr_t overflow_vc2_credit : 1;
+- mmr_t underflow_vc2_credit : 1;
+- mmr_t overflow_vc0_credit : 1;
+- mmr_t underflow_vc0_credit : 1;
+- mmr_t overflow_iilb_vc2 : 1;
+- mmr_t underflow_iilb_vc2 : 1;
+- mmr_t overflow_iilb_vc0 : 1;
+- mmr_t underflow_iilb_vc0 : 1;
+- mmr_t overflow_ni1_vc2 : 1;
+- mmr_t underflow_ni1_vc2 : 1;
+- mmr_t overflow_ni1_vc0 : 1;
+- mmr_t underflow_ni1_vc0 : 1;
+- mmr_t overflow_ni0_vc2 : 1;
+- mmr_t underflow_ni0_vc2 : 1;
+- mmr_t overflow_ni0_vc0 : 1;
+- mmr_t underflow_ni0_vc0 : 1;
++ mmr_t underflow_ni1_vc2 : 1;
++ mmr_t overflow_ni1_vc2 : 1;
++ mmr_t underflow_iilb_vc0 : 1;
++ mmr_t overflow_iilb_vc0 : 1;
++ mmr_t underflow_iilb_vc2 : 1;
++ mmr_t overflow_iilb_vc2 : 1;
++ mmr_t underflow_vc0_credit : 1;
++ mmr_t overflow_vc0_credit : 1;
++ mmr_t underflow_vc2_credit : 1;
++ mmr_t overflow_vc2_credit : 1;
++ mmr_t overflow_databuff_vc0 : 1;
++ mmr_t overflow_databuff_vc2 : 1;
++ mmr_t lut_read_error : 1;
++ mmr_t single_bit_error0 : 1;
++ mmr_t single_bit_error1 : 1;
++ mmr_t single_bit_error2 : 1;
++ mmr_t single_bit_error3 : 1;
++ mmr_t uncor_error0 : 1;
++ mmr_t uncor_error1 : 1;
++ mmr_t uncor_error2 : 1;
++ mmr_t uncor_error3 : 1;
++ mmr_t underflow_sic_cntr0 : 1;
++ mmr_t overflow_sic_cntr0 : 1;
++ mmr_t underflow_sic_cntr2 : 1;
++ mmr_t overflow_sic_cntr2 : 1;
++ mmr_t overflow_ni0_debit0 : 1;
++ mmr_t overflow_ni0_debit2 : 1;
++ mmr_t overflow_ni1_debit0 : 1;
++ mmr_t overflow_ni1_debit2 : 1;
++ mmr_t overflow_iilb_debit0 : 1;
++ mmr_t overflow_iilb_debit2 : 1;
++ mmr_t underflow_ni0_vc0_credit : 1;
++ mmr_t overflow_ni0_vc0_credit : 1;
++ mmr_t underflow_ni0_vc2_credit : 1;
++ mmr_t overflow_ni0_vc2_credit : 1;
++ mmr_t underflow_ni1_vc0_credit : 1;
++ mmr_t overflow_ni1_vc0_credit : 1;
++ mmr_t underflow_ni1_vc2_credit : 1;
++ mmr_t overflow_ni1_vc2_credit : 1;
++ mmr_t underflow_iilb_vc0_credit : 1;
++ mmr_t overflow_iilb_vc0_credit : 1;
++ mmr_t underflow_iilb_vc2_credit : 1;
++ mmr_t overflow_iilb_vc2_credit : 1;
++ mmr_t overflow_header_cancel_fifo : 1;
++ mmr_t reserved_0 : 14;
+ } sh_xnmd_first_error_s;
+ } sh_xnmd_first_error_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_AUTO_REPLY_ENABLE0" */
+ /* Automatic Maintenance Reply Enable 0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_auto_reply_enable0_u {
+- mmr_t sh_auto_reply_enable0_regval;
+- struct {
+- mmr_t enable0 : 64;
+- } sh_auto_reply_enable0_s;
+-} sh_auto_reply_enable0_u_t;
+-#else
+ typedef union sh_auto_reply_enable0_u {
+ mmr_t sh_auto_reply_enable0_regval;
+ struct {
+ mmr_t enable0 : 64;
+ } sh_auto_reply_enable0_s;
+ } sh_auto_reply_enable0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_AUTO_REPLY_ENABLE1" */
+ /* Automatic Maintenance Reply Enable 1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_auto_reply_enable1_u {
+- mmr_t sh_auto_reply_enable1_regval;
+- struct {
+- mmr_t enable1 : 64;
+- } sh_auto_reply_enable1_s;
+-} sh_auto_reply_enable1_u_t;
+-#else
+ typedef union sh_auto_reply_enable1_u {
+ mmr_t sh_auto_reply_enable1_regval;
+ struct {
+ mmr_t enable1 : 64;
+ } sh_auto_reply_enable1_s;
+ } sh_auto_reply_enable1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_AUTO_REPLY_HEADER0" */
+ /* Automatic Maintenance Reply Header 0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_auto_reply_header0_u {
+- mmr_t sh_auto_reply_header0_regval;
+- struct {
+- mmr_t header0 : 64;
+- } sh_auto_reply_header0_s;
+-} sh_auto_reply_header0_u_t;
+-#else
+ typedef union sh_auto_reply_header0_u {
+ mmr_t sh_auto_reply_header0_regval;
+ struct {
+ mmr_t header0 : 64;
+ } sh_auto_reply_header0_s;
+ } sh_auto_reply_header0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_AUTO_REPLY_HEADER1" */
+ /* Automatic Maintenance Reply Header 1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_auto_reply_header1_u {
+- mmr_t sh_auto_reply_header1_regval;
+- struct {
+- mmr_t header1 : 64;
+- } sh_auto_reply_header1_s;
+-} sh_auto_reply_header1_u_t;
+-#else
+ typedef union sh_auto_reply_header1_u {
+ mmr_t sh_auto_reply_header1_regval;
+ struct {
+ mmr_t header1 : 64;
+ } sh_auto_reply_header1_s;
+ } sh_auto_reply_header1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_ENABLE_RP_AUTO_REPLY" */
+ /* Enable Automatic Maintenance Reply From Reply Queue */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_enable_rp_auto_reply_u {
+ mmr_t sh_enable_rp_auto_reply_regval;
+ struct {
+@@ -18184,22 +9749,12 @@
+ mmr_t reserved_0 : 63;
+ } sh_enable_rp_auto_reply_s;
+ } sh_enable_rp_auto_reply_u_t;
+-#else
+-typedef union sh_enable_rp_auto_reply_u {
+- mmr_t sh_enable_rp_auto_reply_regval;
+- struct {
+- mmr_t reserved_0 : 63;
+- mmr_t enable : 1;
+- } sh_enable_rp_auto_reply_s;
+-} sh_enable_rp_auto_reply_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_ENABLE_RQ_AUTO_REPLY" */
+ /* Enable Automatic Maintenance Reply From Request Queue */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_enable_rq_auto_reply_u {
+ mmr_t sh_enable_rq_auto_reply_regval;
+ struct {
+@@ -18207,22 +9762,12 @@
+ mmr_t reserved_0 : 63;
+ } sh_enable_rq_auto_reply_s;
+ } sh_enable_rq_auto_reply_u_t;
+-#else
+-typedef union sh_enable_rq_auto_reply_u {
+- mmr_t sh_enable_rq_auto_reply_regval;
+- struct {
+- mmr_t reserved_0 : 63;
+- mmr_t enable : 1;
+- } sh_enable_rq_auto_reply_s;
+-} sh_enable_rq_auto_reply_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_REDIRECT_INVAL" */
+ /* Redirect invalidate to LB instead of PI */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_redirect_inval_u {
+ mmr_t sh_redirect_inval_regval;
+ struct {
+@@ -18230,22 +9775,12 @@
+ mmr_t reserved_0 : 63;
+ } sh_redirect_inval_s;
+ } sh_redirect_inval_u_t;
+-#else
+-typedef union sh_redirect_inval_u {
+- mmr_t sh_redirect_inval_regval;
+- struct {
+- mmr_t reserved_0 : 63;
+- mmr_t redirect : 1;
+- } sh_redirect_inval_s;
+-} sh_redirect_inval_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_DIAG_MSG_CNTRL" */
+ /* Diagnostic Message Control Register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_diag_msg_cntrl_u {
+ mmr_t sh_diag_msg_cntrl_regval;
+ struct {
+@@ -18258,447 +9793,252 @@
+ mmr_t busy : 1;
+ } sh_diag_msg_cntrl_s;
+ } sh_diag_msg_cntrl_u_t;
+-#else
+-typedef union sh_diag_msg_cntrl_u {
+- mmr_t sh_diag_msg_cntrl_regval;
+- struct {
+- mmr_t busy : 1;
+- mmr_t start : 1;
+- mmr_t reserved_0 : 48;
+- mmr_t port : 1;
+- mmr_t error_inject_enable : 1;
+- mmr_t error_inject_point : 6;
+- mmr_t msg_length : 6;
+- } sh_diag_msg_cntrl_s;
+-} sh_diag_msg_cntrl_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_DIAG_MSG_DATA0L" */
+ /* Diagnostic Data, lower 64 bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_diag_msg_data0l_u {
+- mmr_t sh_diag_msg_data0l_regval;
+- struct {
+- mmr_t data_lower : 64;
+- } sh_diag_msg_data0l_s;
+-} sh_diag_msg_data0l_u_t;
+-#else
+ typedef union sh_diag_msg_data0l_u {
+ mmr_t sh_diag_msg_data0l_regval;
+ struct {
+ mmr_t data_lower : 64;
+ } sh_diag_msg_data0l_s;
+ } sh_diag_msg_data0l_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_DIAG_MSG_DATA0U" */
+ /* Diagnostice Data, upper 64 bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_diag_msg_data0u_u {
+- mmr_t sh_diag_msg_data0u_regval;
+- struct {
+- mmr_t data_upper : 64;
+- } sh_diag_msg_data0u_s;
+-} sh_diag_msg_data0u_u_t;
+-#else
+ typedef union sh_diag_msg_data0u_u {
+ mmr_t sh_diag_msg_data0u_regval;
+ struct {
+ mmr_t data_upper : 64;
+ } sh_diag_msg_data0u_s;
+ } sh_diag_msg_data0u_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_DIAG_MSG_DATA1L" */
+ /* Diagnostic Data, lower 64 bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_diag_msg_data1l_u {
+- mmr_t sh_diag_msg_data1l_regval;
+- struct {
+- mmr_t data_lower : 64;
+- } sh_diag_msg_data1l_s;
+-} sh_diag_msg_data1l_u_t;
+-#else
+ typedef union sh_diag_msg_data1l_u {
+ mmr_t sh_diag_msg_data1l_regval;
+ struct {
+ mmr_t data_lower : 64;
+ } sh_diag_msg_data1l_s;
+ } sh_diag_msg_data1l_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_DIAG_MSG_DATA1U" */
+ /* Diagnostice Data, upper 64 bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_diag_msg_data1u_u {
+ mmr_t sh_diag_msg_data1u_regval;
+ struct {
+ mmr_t data_upper : 64;
+ } sh_diag_msg_data1u_s;
+ } sh_diag_msg_data1u_u_t;
+-#else
+-typedef union sh_diag_msg_data1u_u {
+- mmr_t sh_diag_msg_data1u_regval;
+- struct {
+- mmr_t data_upper : 64;
+- } sh_diag_msg_data1u_s;
+-} sh_diag_msg_data1u_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_DIAG_MSG_DATA2L" */
+ /* Diagnostic Data, lower 64 bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_diag_msg_data2l_u {
+- mmr_t sh_diag_msg_data2l_regval;
+- struct {
+- mmr_t data_lower : 64;
+- } sh_diag_msg_data2l_s;
+-} sh_diag_msg_data2l_u_t;
+-#else
+ typedef union sh_diag_msg_data2l_u {
+ mmr_t sh_diag_msg_data2l_regval;
+ struct {
+ mmr_t data_lower : 64;
+ } sh_diag_msg_data2l_s;
+ } sh_diag_msg_data2l_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_DIAG_MSG_DATA2U" */
+ /* Diagnostice Data, upper 64 bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_diag_msg_data2u_u {
+- mmr_t sh_diag_msg_data2u_regval;
+- struct {
+- mmr_t data_upper : 64;
+- } sh_diag_msg_data2u_s;
+-} sh_diag_msg_data2u_u_t;
+-#else
+ typedef union sh_diag_msg_data2u_u {
+ mmr_t sh_diag_msg_data2u_regval;
+ struct {
+ mmr_t data_upper : 64;
+ } sh_diag_msg_data2u_s;
+ } sh_diag_msg_data2u_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_DIAG_MSG_DATA3L" */
+ /* Diagnostic Data, lower 64 bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_diag_msg_data3l_u {
+- mmr_t sh_diag_msg_data3l_regval;
+- struct {
+- mmr_t data_lower : 64;
+- } sh_diag_msg_data3l_s;
+-} sh_diag_msg_data3l_u_t;
+-#else
+ typedef union sh_diag_msg_data3l_u {
+ mmr_t sh_diag_msg_data3l_regval;
+ struct {
+ mmr_t data_lower : 64;
+ } sh_diag_msg_data3l_s;
+ } sh_diag_msg_data3l_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_DIAG_MSG_DATA3U" */
+ /* Diagnostice Data, upper 64 bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_diag_msg_data3u_u {
+ mmr_t sh_diag_msg_data3u_regval;
+ struct {
+ mmr_t data_upper : 64;
+ } sh_diag_msg_data3u_s;
+ } sh_diag_msg_data3u_u_t;
+-#else
+-typedef union sh_diag_msg_data3u_u {
+- mmr_t sh_diag_msg_data3u_regval;
+- struct {
+- mmr_t data_upper : 64;
+- } sh_diag_msg_data3u_s;
+-} sh_diag_msg_data3u_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_DIAG_MSG_DATA4L" */
+ /* Diagnostic Data, lower 64 bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_diag_msg_data4l_u {
+- mmr_t sh_diag_msg_data4l_regval;
+- struct {
+- mmr_t data_lower : 64;
+- } sh_diag_msg_data4l_s;
+-} sh_diag_msg_data4l_u_t;
+-#else
+ typedef union sh_diag_msg_data4l_u {
+ mmr_t sh_diag_msg_data4l_regval;
+ struct {
+ mmr_t data_lower : 64;
+ } sh_diag_msg_data4l_s;
+ } sh_diag_msg_data4l_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_DIAG_MSG_DATA4U" */
+ /* Diagnostice Data, upper 64 bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_diag_msg_data4u_u {
+- mmr_t sh_diag_msg_data4u_regval;
+- struct {
+- mmr_t data_upper : 64;
+- } sh_diag_msg_data4u_s;
+-} sh_diag_msg_data4u_u_t;
+-#else
+ typedef union sh_diag_msg_data4u_u {
+ mmr_t sh_diag_msg_data4u_regval;
+ struct {
+ mmr_t data_upper : 64;
+ } sh_diag_msg_data4u_s;
+ } sh_diag_msg_data4u_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_DIAG_MSG_DATA5L" */
+ /* Diagnostic Data, lower 64 bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_diag_msg_data5l_u {
+- mmr_t sh_diag_msg_data5l_regval;
+- struct {
+- mmr_t data_lower : 64;
+- } sh_diag_msg_data5l_s;
+-} sh_diag_msg_data5l_u_t;
+-#else
+ typedef union sh_diag_msg_data5l_u {
+ mmr_t sh_diag_msg_data5l_regval;
+ struct {
+ mmr_t data_lower : 64;
+ } sh_diag_msg_data5l_s;
+ } sh_diag_msg_data5l_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_DIAG_MSG_DATA5U" */
+ /* Diagnostice Data, upper 64 bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_diag_msg_data5u_u {
+ mmr_t sh_diag_msg_data5u_regval;
+ struct {
+ mmr_t data_upper : 64;
+ } sh_diag_msg_data5u_s;
+ } sh_diag_msg_data5u_u_t;
+-#else
+-typedef union sh_diag_msg_data5u_u {
+- mmr_t sh_diag_msg_data5u_regval;
+- struct {
+- mmr_t data_upper : 64;
+- } sh_diag_msg_data5u_s;
+-} sh_diag_msg_data5u_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_DIAG_MSG_DATA6L" */
+ /* Diagnostic Data, lower 64 bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_diag_msg_data6l_u {
+- mmr_t sh_diag_msg_data6l_regval;
+- struct {
+- mmr_t data_lower : 64;
+- } sh_diag_msg_data6l_s;
+-} sh_diag_msg_data6l_u_t;
+-#else
+ typedef union sh_diag_msg_data6l_u {
+ mmr_t sh_diag_msg_data6l_regval;
+ struct {
+ mmr_t data_lower : 64;
+ } sh_diag_msg_data6l_s;
+ } sh_diag_msg_data6l_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_DIAG_MSG_DATA6U" */
+ /* Diagnostice Data, upper 64 bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_diag_msg_data6u_u {
+- mmr_t sh_diag_msg_data6u_regval;
+- struct {
+- mmr_t data_upper : 64;
+- } sh_diag_msg_data6u_s;
+-} sh_diag_msg_data6u_u_t;
+-#else
+ typedef union sh_diag_msg_data6u_u {
+ mmr_t sh_diag_msg_data6u_regval;
+ struct {
+ mmr_t data_upper : 64;
+ } sh_diag_msg_data6u_s;
+ } sh_diag_msg_data6u_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_DIAG_MSG_DATA7L" */
+ /* Diagnostic Data, lower 64 bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_diag_msg_data7l_u {
+- mmr_t sh_diag_msg_data7l_regval;
+- struct {
+- mmr_t data_lower : 64;
+- } sh_diag_msg_data7l_s;
+-} sh_diag_msg_data7l_u_t;
+-#else
+ typedef union sh_diag_msg_data7l_u {
+ mmr_t sh_diag_msg_data7l_regval;
+ struct {
+ mmr_t data_lower : 64;
+ } sh_diag_msg_data7l_s;
+ } sh_diag_msg_data7l_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_DIAG_MSG_DATA7U" */
+ /* Diagnostice Data, upper 64 bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_diag_msg_data7u_u {
+ mmr_t sh_diag_msg_data7u_regval;
+ struct {
+ mmr_t data_upper : 64;
+ } sh_diag_msg_data7u_s;
+ } sh_diag_msg_data7u_u_t;
+-#else
+-typedef union sh_diag_msg_data7u_u {
+- mmr_t sh_diag_msg_data7u_regval;
+- struct {
+- mmr_t data_upper : 64;
+- } sh_diag_msg_data7u_s;
+-} sh_diag_msg_data7u_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_DIAG_MSG_DATA8L" */
+ /* Diagnostic Data, lower 64 bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_diag_msg_data8l_u {
+- mmr_t sh_diag_msg_data8l_regval;
+- struct {
+- mmr_t data_lower : 64;
+- } sh_diag_msg_data8l_s;
+-} sh_diag_msg_data8l_u_t;
+-#else
+ typedef union sh_diag_msg_data8l_u {
+ mmr_t sh_diag_msg_data8l_regval;
+ struct {
+ mmr_t data_lower : 64;
+ } sh_diag_msg_data8l_s;
+ } sh_diag_msg_data8l_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_DIAG_MSG_DATA8U" */
+ /* Diagnostice Data, upper 64 bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_diag_msg_data8u_u {
+- mmr_t sh_diag_msg_data8u_regval;
+- struct {
+- mmr_t data_upper : 64;
+- } sh_diag_msg_data8u_s;
+-} sh_diag_msg_data8u_u_t;
+-#else
+ typedef union sh_diag_msg_data8u_u {
+ mmr_t sh_diag_msg_data8u_regval;
+ struct {
+ mmr_t data_upper : 64;
+ } sh_diag_msg_data8u_s;
+ } sh_diag_msg_data8u_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_DIAG_MSG_HDR0" */
+ /* Diagnostice Data, lower 64 bits of header */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_diag_msg_hdr0_u {
+- mmr_t sh_diag_msg_hdr0_regval;
+- struct {
+- mmr_t header0 : 64;
+- } sh_diag_msg_hdr0_s;
+-} sh_diag_msg_hdr0_u_t;
+-#else
+ typedef union sh_diag_msg_hdr0_u {
+ mmr_t sh_diag_msg_hdr0_regval;
+ struct {
+ mmr_t header0 : 64;
+ } sh_diag_msg_hdr0_s;
+ } sh_diag_msg_hdr0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_DIAG_MSG_HDR1" */
+ /* Diagnostice Data, upper 64 bits of header */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_diag_msg_hdr1_u {
+ mmr_t sh_diag_msg_hdr1_regval;
+ struct {
+ mmr_t header1 : 64;
+ } sh_diag_msg_hdr1_s;
+ } sh_diag_msg_hdr1_u_t;
+-#else
+-typedef union sh_diag_msg_hdr1_u {
+- mmr_t sh_diag_msg_hdr1_regval;
+- struct {
+- mmr_t header1 : 64;
+- } sh_diag_msg_hdr1_s;
+-} sh_diag_msg_hdr1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_DEBUG_SELECT" */
+ /* SHub Debug Port Select */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_debug_select_u {
+ mmr_t sh_debug_select_regval;
+ struct {
+@@ -18713,51 +10053,23 @@
+ mmr_t nibble4_nibble_sel : 3;
+ mmr_t nibble4_chiplet_sel : 3;
+ mmr_t nibble5_nibble_sel : 3;
+- mmr_t nibble5_chiplet_sel : 3;
+- mmr_t nibble6_nibble_sel : 3;
+- mmr_t nibble6_chiplet_sel : 3;
+- mmr_t nibble7_nibble_sel : 3;
+- mmr_t nibble7_chiplet_sel : 3;
+- mmr_t debug_ii_sel : 3;
+- mmr_t sel_ii : 9;
+- mmr_t reserved_0 : 3;
+- mmr_t trigger_enable : 1;
+- } sh_debug_select_s;
+-} sh_debug_select_u_t;
+-#else
+-typedef union sh_debug_select_u {
+- mmr_t sh_debug_select_regval;
+- struct {
+- mmr_t trigger_enable : 1;
+- mmr_t reserved_0 : 3;
+- mmr_t sel_ii : 9;
+- mmr_t debug_ii_sel : 3;
+- mmr_t nibble7_chiplet_sel : 3;
+- mmr_t nibble7_nibble_sel : 3;
+- mmr_t nibble6_chiplet_sel : 3;
+- mmr_t nibble6_nibble_sel : 3;
+- mmr_t nibble5_chiplet_sel : 3;
+- mmr_t nibble5_nibble_sel : 3;
+- mmr_t nibble4_chiplet_sel : 3;
+- mmr_t nibble4_nibble_sel : 3;
+- mmr_t nibble3_chiplet_sel : 3;
+- mmr_t nibble3_nibble_sel : 3;
+- mmr_t nibble2_chiplet_sel : 3;
+- mmr_t nibble2_nibble_sel : 3;
+- mmr_t nibble1_chiplet_sel : 3;
+- mmr_t nibble1_nibble_sel : 3;
+- mmr_t nibble0_chiplet_sel : 3;
+- mmr_t nibble0_nibble_sel : 3;
++ mmr_t nibble5_chiplet_sel : 3;
++ mmr_t nibble6_nibble_sel : 3;
++ mmr_t nibble6_chiplet_sel : 3;
++ mmr_t nibble7_nibble_sel : 3;
++ mmr_t nibble7_chiplet_sel : 3;
++ mmr_t debug_ii_sel : 3;
++ mmr_t sel_ii : 9;
++ mmr_t reserved_0 : 3;
++ mmr_t trigger_enable : 1;
+ } sh_debug_select_s;
+ } sh_debug_select_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_TRIGGER_COMPARE_MASK" */
+ /* SHub Trigger Compare Mask */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_trigger_compare_mask_u {
+ mmr_t sh_trigger_compare_mask_regval;
+ struct {
+@@ -18765,22 +10077,12 @@
+ mmr_t reserved_0 : 32;
+ } sh_trigger_compare_mask_s;
+ } sh_trigger_compare_mask_u_t;
+-#else
+-typedef union sh_trigger_compare_mask_u {
+- mmr_t sh_trigger_compare_mask_regval;
+- struct {
+- mmr_t reserved_0 : 32;
+- mmr_t mask : 32;
+- } sh_trigger_compare_mask_s;
+-} sh_trigger_compare_mask_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_TRIGGER_COMPARE_PATTERN" */
+ /* SHub Trigger Compare Pattern */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_trigger_compare_pattern_u {
+ mmr_t sh_trigger_compare_pattern_regval;
+ struct {
+@@ -18788,22 +10090,12 @@
+ mmr_t reserved_0 : 32;
+ } sh_trigger_compare_pattern_s;
+ } sh_trigger_compare_pattern_u_t;
+-#else
+-typedef union sh_trigger_compare_pattern_u {
+- mmr_t sh_trigger_compare_pattern_regval;
+- struct {
+- mmr_t reserved_0 : 32;
+- mmr_t data : 32;
+- } sh_trigger_compare_pattern_s;
+-} sh_trigger_compare_pattern_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_TRIGGER_SEL" */
+ /* Trigger select for SHUB debug port */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_trigger_sel_u {
+ mmr_t sh_trigger_sel_regval;
+ struct {
+@@ -18841,52 +10133,12 @@
+ mmr_t reserved_15 : 1;
+ } sh_trigger_sel_s;
+ } sh_trigger_sel_u_t;
+-#else
+-typedef union sh_trigger_sel_u {
+- mmr_t sh_trigger_sel_regval;
+- struct {
+- mmr_t reserved_15 : 1;
+- mmr_t nibble7_nibble_sel : 3;
+- mmr_t reserved_14 : 1;
+- mmr_t nibble7_input_sel : 3;
+- mmr_t reserved_13 : 1;
+- mmr_t nibble6_nibble_sel : 3;
+- mmr_t reserved_12 : 1;
+- mmr_t nibble6_input_sel : 3;
+- mmr_t reserved_11 : 1;
+- mmr_t nibble5_nibble_sel : 3;
+- mmr_t reserved_10 : 1;
+- mmr_t nibble5_input_sel : 3;
+- mmr_t reserved_9 : 1;
+- mmr_t nibble4_nibble_sel : 3;
+- mmr_t reserved_8 : 1;
+- mmr_t nibble4_input_sel : 3;
+- mmr_t reserved_7 : 1;
+- mmr_t nibble3_nibble_sel : 3;
+- mmr_t reserved_6 : 1;
+- mmr_t nibble3_input_sel : 3;
+- mmr_t reserved_5 : 1;
+- mmr_t nibble2_nibble_sel : 3;
+- mmr_t reserved_4 : 1;
+- mmr_t nibble2_input_sel : 3;
+- mmr_t reserved_3 : 1;
+- mmr_t nibble1_nibble_sel : 3;
+- mmr_t reserved_2 : 1;
+- mmr_t nibble1_input_sel : 3;
+- mmr_t reserved_1 : 1;
+- mmr_t nibble0_nibble_sel : 3;
+- mmr_t reserved_0 : 1;
+- mmr_t nibble0_input_sel : 3;
+- } sh_trigger_sel_s;
+-} sh_trigger_sel_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_STOP_CLK_CONTROL" */
+ /* Stop Clock Control */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_stop_clk_control_u {
+ mmr_t sh_stop_clk_control_regval;
+ struct {
+@@ -18897,25 +10149,12 @@
+ mmr_t reserved_0 : 56;
+ } sh_stop_clk_control_s;
+ } sh_stop_clk_control_u_t;
+-#else
+-typedef union sh_stop_clk_control_u {
+- mmr_t sh_stop_clk_control_regval;
+- struct {
+- mmr_t reserved_0 : 56;
+- mmr_t mode : 1;
+- mmr_t polarity : 1;
+- mmr_t event : 1;
+- mmr_t stimulus : 5;
+- } sh_stop_clk_control_s;
+-} sh_stop_clk_control_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_STOP_CLK_DELAY_PHASE" */
+ /* Stop Clock Delay Phase */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_stop_clk_delay_phase_u {
+ mmr_t sh_stop_clk_delay_phase_regval;
+ struct {
+@@ -18923,43 +10162,24 @@
+ mmr_t reserved_0 : 56;
+ } sh_stop_clk_delay_phase_s;
+ } sh_stop_clk_delay_phase_u_t;
+-#else
+-typedef union sh_stop_clk_delay_phase_u {
+- mmr_t sh_stop_clk_delay_phase_regval;
+- struct {
+- mmr_t reserved_0 : 56;
+- mmr_t delay : 8;
+- } sh_stop_clk_delay_phase_s;
+-} sh_stop_clk_delay_phase_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_TSF_ARM_MASK" */
+ /* Trigger sequencing facility arm mask */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_tsf_arm_mask_u {
+- mmr_t sh_tsf_arm_mask_regval;
+- struct {
+- mmr_t mask : 64;
+- } sh_tsf_arm_mask_s;
+-} sh_tsf_arm_mask_u_t;
+-#else
+ typedef union sh_tsf_arm_mask_u {
+ mmr_t sh_tsf_arm_mask_regval;
+ struct {
+ mmr_t mask : 64;
+ } sh_tsf_arm_mask_s;
+ } sh_tsf_arm_mask_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_TSF_COUNTER_PRESETS" */
+ /* Trigger sequencing facility counter presets */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_tsf_counter_presets_u {
+ mmr_t sh_tsf_counter_presets_regval;
+ struct {
+@@ -18969,24 +10189,12 @@
+ mmr_t count_8a : 8;
+ } sh_tsf_counter_presets_s;
+ } sh_tsf_counter_presets_u_t;
+-#else
+-typedef union sh_tsf_counter_presets_u {
+- mmr_t sh_tsf_counter_presets_regval;
+- struct {
+- mmr_t count_8a : 8;
+- mmr_t count_8b : 8;
+- mmr_t count_16 : 16;
+- mmr_t count_32 : 32;
+- } sh_tsf_counter_presets_s;
+-} sh_tsf_counter_presets_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_TSF_DECREMENT_CTL" */
+ /* Trigger sequencing facility counter decrement control */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_tsf_decrement_ctl_u {
+ mmr_t sh_tsf_decrement_ctl_regval;
+ struct {
+@@ -18994,22 +10202,12 @@
+ mmr_t reserved_0 : 48;
+ } sh_tsf_decrement_ctl_s;
+ } sh_tsf_decrement_ctl_u_t;
+-#else
+-typedef union sh_tsf_decrement_ctl_u {
+- mmr_t sh_tsf_decrement_ctl_regval;
+- struct {
+- mmr_t reserved_0 : 48;
+- mmr_t ctl : 16;
+- } sh_tsf_decrement_ctl_s;
+-} sh_tsf_decrement_ctl_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_TSF_DIAG_MSG_CTL" */
+ /* Trigger sequencing facility diagnostic message control */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_tsf_diag_msg_ctl_u {
+ mmr_t sh_tsf_diag_msg_ctl_regval;
+ struct {
+@@ -19017,43 +10215,24 @@
+ mmr_t reserved_0 : 56;
+ } sh_tsf_diag_msg_ctl_s;
+ } sh_tsf_diag_msg_ctl_u_t;
+-#else
+-typedef union sh_tsf_diag_msg_ctl_u {
+- mmr_t sh_tsf_diag_msg_ctl_regval;
+- struct {
+- mmr_t reserved_0 : 56;
+- mmr_t enable : 8;
+- } sh_tsf_diag_msg_ctl_s;
+-} sh_tsf_diag_msg_ctl_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_TSF_DISARM_MASK" */
+ /* Trigger sequencing facility disarm mask */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_tsf_disarm_mask_u {
+- mmr_t sh_tsf_disarm_mask_regval;
+- struct {
+- mmr_t mask : 64;
+- } sh_tsf_disarm_mask_s;
+-} sh_tsf_disarm_mask_u_t;
+-#else
+ typedef union sh_tsf_disarm_mask_u {
+ mmr_t sh_tsf_disarm_mask_regval;
+ struct {
+ mmr_t mask : 64;
+ } sh_tsf_disarm_mask_s;
+ } sh_tsf_disarm_mask_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_TSF_ENABLE_CTL" */
+ /* Trigger sequencing facility counter enable control */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_tsf_enable_ctl_u {
+ mmr_t sh_tsf_enable_ctl_regval;
+ struct {
+@@ -19061,22 +10240,12 @@
+ mmr_t reserved_0 : 48;
+ } sh_tsf_enable_ctl_s;
+ } sh_tsf_enable_ctl_u_t;
+-#else
+-typedef union sh_tsf_enable_ctl_u {
+- mmr_t sh_tsf_enable_ctl_regval;
+- struct {
+- mmr_t reserved_0 : 48;
+- mmr_t ctl : 16;
+- } sh_tsf_enable_ctl_s;
+-} sh_tsf_enable_ctl_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_TSF_SOFTWARE_ARM" */
+ /* Trigger sequencing facility software arm */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_tsf_software_arm_u {
+ mmr_t sh_tsf_software_arm_regval;
+ struct {
+@@ -19091,29 +10260,12 @@
+ mmr_t reserved_0 : 56;
+ } sh_tsf_software_arm_s;
+ } sh_tsf_software_arm_u_t;
+-#else
+-typedef union sh_tsf_software_arm_u {
+- mmr_t sh_tsf_software_arm_regval;
+- struct {
+- mmr_t reserved_0 : 56;
+- mmr_t bit7 : 1;
+- mmr_t bit6 : 1;
+- mmr_t bit5 : 1;
+- mmr_t bit4 : 1;
+- mmr_t bit3 : 1;
+- mmr_t bit2 : 1;
+- mmr_t bit1 : 1;
+- mmr_t bit0 : 1;
+- } sh_tsf_software_arm_s;
+-} sh_tsf_software_arm_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_TSF_SOFTWARE_DISARM" */
+ /* Trigger sequencing facility software disarm */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_tsf_software_disarm_u {
+ mmr_t sh_tsf_software_disarm_regval;
+ struct {
+@@ -19128,29 +10280,12 @@
+ mmr_t reserved_0 : 56;
+ } sh_tsf_software_disarm_s;
+ } sh_tsf_software_disarm_u_t;
+-#else
+-typedef union sh_tsf_software_disarm_u {
+- mmr_t sh_tsf_software_disarm_regval;
+- struct {
+- mmr_t reserved_0 : 56;
+- mmr_t bit7 : 1;
+- mmr_t bit6 : 1;
+- mmr_t bit5 : 1;
+- mmr_t bit4 : 1;
+- mmr_t bit3 : 1;
+- mmr_t bit2 : 1;
+- mmr_t bit1 : 1;
+- mmr_t bit0 : 1;
+- } sh_tsf_software_disarm_s;
+-} sh_tsf_software_disarm_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_TSF_SOFTWARE_TRIGGERED" */
+ /* Trigger sequencing facility software triggered */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_tsf_software_triggered_u {
+ mmr_t sh_tsf_software_triggered_regval;
+ struct {
+@@ -19165,71 +10300,36 @@
+ mmr_t reserved_0 : 56;
+ } sh_tsf_software_triggered_s;
+ } sh_tsf_software_triggered_u_t;
+-#else
+-typedef union sh_tsf_software_triggered_u {
+- mmr_t sh_tsf_software_triggered_regval;
+- struct {
+- mmr_t reserved_0 : 56;
+- mmr_t bit7 : 1;
+- mmr_t bit6 : 1;
+- mmr_t bit5 : 1;
+- mmr_t bit4 : 1;
+- mmr_t bit3 : 1;
+- mmr_t bit2 : 1;
+- mmr_t bit1 : 1;
+- mmr_t bit0 : 1;
+- } sh_tsf_software_triggered_s;
+-} sh_tsf_software_triggered_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_TSF_TRIGGER_MASK" */
+ /* Trigger sequencing facility trigger mask */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_tsf_trigger_mask_u {
+- mmr_t sh_tsf_trigger_mask_regval;
+- struct {
+- mmr_t mask : 64;
+- } sh_tsf_trigger_mask_s;
+-} sh_tsf_trigger_mask_u_t;
+-#else
+ typedef union sh_tsf_trigger_mask_u {
+ mmr_t sh_tsf_trigger_mask_regval;
+ struct {
+ mmr_t mask : 64;
+ } sh_tsf_trigger_mask_s;
+ } sh_tsf_trigger_mask_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_VEC_DATA" */
+ /* Vector Write Request Message Data */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_vec_data_u {
+- mmr_t sh_vec_data_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_vec_data_s;
+-} sh_vec_data_u_t;
+-#else
+ typedef union sh_vec_data_u {
+ mmr_t sh_vec_data_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_vec_data_s;
+ } sh_vec_data_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_VEC_PARMS" */
+ /* Vector Message Parameters Register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_vec_parms_u {
+ mmr_t sh_vec_parms_regval;
+ struct {
+@@ -19243,133 +10343,72 @@
+ mmr_t busy : 1;
+ } sh_vec_parms_s;
+ } sh_vec_parms_u_t;
+-#else
+-typedef union sh_vec_parms_u {
+- mmr_t sh_vec_parms_regval;
+- struct {
+- mmr_t busy : 1;
+- mmr_t start : 1;
+- mmr_t reserved_1 : 16;
+- mmr_t pio_id : 11;
+- mmr_t address : 32;
+- mmr_t reserved_0 : 1;
+- mmr_t ni_port : 1;
+- mmr_t type : 1;
+- } sh_vec_parms_s;
+-} sh_vec_parms_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_VEC_ROUTE" */
+ /* Vector Request Message Route */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_vec_route_u {
+- mmr_t sh_vec_route_regval;
+- struct {
+- mmr_t route : 64;
+- } sh_vec_route_s;
+-} sh_vec_route_u_t;
+-#else
+ typedef union sh_vec_route_u {
+ mmr_t sh_vec_route_regval;
+ struct {
+ mmr_t route : 64;
+ } sh_vec_route_s;
+ } sh_vec_route_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_CPU_PERM" */
+ /* CPU MMR Access Permission Bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_cpu_perm_u {
+ mmr_t sh_cpu_perm_regval;
+ struct {
+ mmr_t access_bits : 64;
+ } sh_cpu_perm_s;
+ } sh_cpu_perm_u_t;
+-#else
+-typedef union sh_cpu_perm_u {
+- mmr_t sh_cpu_perm_regval;
+- struct {
+- mmr_t access_bits : 64;
+- } sh_cpu_perm_s;
+-} sh_cpu_perm_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_CPU_PERM_OVR" */
+ /* CPU MMR Access Permission Override */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_cpu_perm_ovr_u {
+- mmr_t sh_cpu_perm_ovr_regval;
+- struct {
+- mmr_t override : 64;
+- } sh_cpu_perm_ovr_s;
+-} sh_cpu_perm_ovr_u_t;
+-#else
+ typedef union sh_cpu_perm_ovr_u {
+ mmr_t sh_cpu_perm_ovr_regval;
+ struct {
+ mmr_t override : 64;
+ } sh_cpu_perm_ovr_s;
+ } sh_cpu_perm_ovr_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_EXT_IO_PERM" */
+ /* External IO MMR Access Permission Bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_ext_io_perm_u {
+- mmr_t sh_ext_io_perm_regval;
+- struct {
+- mmr_t access_bits : 64;
+- } sh_ext_io_perm_s;
+-} sh_ext_io_perm_u_t;
+-#else
+ typedef union sh_ext_io_perm_u {
+ mmr_t sh_ext_io_perm_regval;
+ struct {
+ mmr_t access_bits : 64;
+ } sh_ext_io_perm_s;
+ } sh_ext_io_perm_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_EXT_IOI_ACCESS" */
+ /* External IO Interrupt Access Permission Bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_ext_ioi_access_u {
+- mmr_t sh_ext_ioi_access_regval;
+- struct {
+- mmr_t access_bits : 64;
+- } sh_ext_ioi_access_s;
+-} sh_ext_ioi_access_u_t;
+-#else
+ typedef union sh_ext_ioi_access_u {
+ mmr_t sh_ext_ioi_access_regval;
+ struct {
+ mmr_t access_bits : 64;
+ } sh_ext_ioi_access_s;
+ } sh_ext_ioi_access_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_GC_FIL_CTRL" */
+ /* SHub Global Clock Filter Control */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gc_fil_ctrl_u {
+ mmr_t sh_gc_fil_ctrl_regval;
+ struct {
+@@ -19386,31 +10425,12 @@
+ mmr_t reserved_4 : 6;
+ } sh_gc_fil_ctrl_s;
+ } sh_gc_fil_ctrl_u_t;
+-#else
+-typedef union sh_gc_fil_ctrl_u {
+- mmr_t sh_gc_fil_ctrl_regval;
+- struct {
+- mmr_t reserved_4 : 6;
+- mmr_t error_counter : 10;
+- mmr_t reserved_3 : 2;
+- mmr_t dropout_thresh : 10;
+- mmr_t reserved_2 : 2;
+- mmr_t dropout_counter : 10;
+- mmr_t reserved_1 : 3;
+- mmr_t mask_enable : 1;
+- mmr_t mask_counter : 12;
+- mmr_t reserved_0 : 3;
+- mmr_t offset : 5;
+- } sh_gc_fil_ctrl_s;
+-} sh_gc_fil_ctrl_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_GC_SRC_CTRL" */
+ /* SHub Global Clock Control */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gc_src_ctrl_u {
+ mmr_t sh_gc_src_ctrl_regval;
+ struct {
+@@ -19426,116 +10446,61 @@
+ mmr_t reserved_4 : 30;
+ } sh_gc_src_ctrl_s;
+ } sh_gc_src_ctrl_u_t;
+-#else
+-typedef union sh_gc_src_ctrl_u {
+- mmr_t sh_gc_src_ctrl_regval;
+- struct {
+- mmr_t reserved_4 : 30;
+- mmr_t source_sel : 2;
+- mmr_t reserved_3 : 3;
+- mmr_t toggle_bit : 1;
+- mmr_t reserved_2 : 2;
+- mmr_t counter : 10;
+- mmr_t reserved_1 : 2;
+- mmr_t max_count : 10;
+- mmr_t reserved_0 : 3;
+- mmr_t enable_counter : 1;
+- } sh_gc_src_ctrl_s;
+-} sh_gc_src_ctrl_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_HARD_RESET" */
+ /* SHub Hard Reset */
+-/* ==================================================================== */
+-
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_hard_reset_u {
+- mmr_t sh_hard_reset_regval;
+- struct {
+- mmr_t hard_reset : 1;
+- mmr_t reserved_0 : 63;
+- } sh_hard_reset_s;
+-} sh_hard_reset_u_t;
+-#else
++/* ==================================================================== */
++
+ typedef union sh_hard_reset_u {
+ mmr_t sh_hard_reset_regval;
+ struct {
+- mmr_t reserved_0 : 63;
+ mmr_t hard_reset : 1;
++ mmr_t reserved_0 : 63;
+ } sh_hard_reset_s;
+ } sh_hard_reset_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_IO_PERM" */
+ /* II MMR Access Permission Bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_io_perm_u {
+- mmr_t sh_io_perm_regval;
+- struct {
+- mmr_t access_bits : 64;
+- } sh_io_perm_s;
+-} sh_io_perm_u_t;
+-#else
+ typedef union sh_io_perm_u {
+ mmr_t sh_io_perm_regval;
+ struct {
+ mmr_t access_bits : 64;
+ } sh_io_perm_s;
+ } sh_io_perm_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_IOI_ACCESS" */
+ /* II Interrupt Access Permission Bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_ioi_access_u {
+- mmr_t sh_ioi_access_regval;
+- struct {
+- mmr_t access_bits : 64;
+- } sh_ioi_access_s;
+-} sh_ioi_access_u_t;
+-#else
+ typedef union sh_ioi_access_u {
+ mmr_t sh_ioi_access_regval;
+ struct {
+ mmr_t access_bits : 64;
+ } sh_ioi_access_s;
+ } sh_ioi_access_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_IPI_ACCESS" */
+ /* CPU interrupt Access Permission Bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ipi_access_u {
+ mmr_t sh_ipi_access_regval;
+ struct {
+ mmr_t access_bits : 64;
+ } sh_ipi_access_s;
+ } sh_ipi_access_u_t;
+-#else
+-typedef union sh_ipi_access_u {
+- mmr_t sh_ipi_access_regval;
+- struct {
+- mmr_t access_bits : 64;
+- } sh_ipi_access_s;
+-} sh_ipi_access_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_JTAG_CONFIG" */
+ /* SHub JTAG configuration */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_jtag_config_u {
+ mmr_t sh_jtag_config_regval;
+ struct {
+@@ -19559,38 +10524,12 @@
+ mmr_t reserved_0 : 8;
+ } sh_jtag_config_s;
+ } sh_jtag_config_u_t;
+-#else
+-typedef union sh_jtag_config_u {
+- mmr_t sh_jtag_config_regval;
+- struct {
+- mmr_t reserved_0 : 8;
+- mmr_t gtl_config_re : 1;
+- mmr_t fsb_config_aux : 2;
+- mmr_t fsb_config_enable_bist : 1;
+- mmr_t fsb_config_output_tristate : 4;
+- mmr_t fsb_config_clock_ratio : 5;
+- mmr_t fsb_config_enable_bus_parking : 1;
+- mmr_t fsb_config_sample_binit : 1;
+- mmr_t fsb_config_ioq_depth : 1;
+- mmr_t jtag_mci_override : 1;
+- mmr_t jtag_mci_target : 14;
+- mmr_t jtag_mci_reset_delay : 4;
+- mmr_t wrt90_override : 1;
+- mmr_t wrt90_overrider : 1;
+- mmr_t wrt90_target : 14;
+- mmr_t ii_clk_sel : 2;
+- mmr_t ni_clk_sel : 1;
+- mmr_t md_clk_sel : 2;
+- } sh_jtag_config_s;
+-} sh_jtag_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_SHUB_ID" */
+ /* SHub ID Number */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_shub_id_u {
+ mmr_t sh_shub_id_regval;
+ struct {
+@@ -19608,116 +10547,60 @@
+ mmr_t reserved_3 : 7;
+ } sh_shub_id_s;
+ } sh_shub_id_u_t;
+-#else
+-typedef union sh_shub_id_u {
+- mmr_t sh_shub_id_regval;
+- struct {
+- mmr_t reserved_3 : 7;
+- mmr_t ni_port : 1;
+- mmr_t reserved_2 : 3;
+- mmr_t nodes_per_bit : 5;
+- mmr_t reserved_1 : 2;
+- mmr_t sharing_mode : 2;
+- mmr_t reserved_0 : 1;
+- mmr_t node_id : 11;
+- mmr_t revision : 4;
+- mmr_t part_number : 16;
+- mmr_t manufacturer : 11;
+- mmr_t force1 : 1;
+- } sh_shub_id_s;
+-} sh_shub_id_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_SHUBS_PRESENT0" */
+ /* Shubs 0 - 63 Present. Used for invalidate generation */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_shubs_present0_u {
+- mmr_t sh_shubs_present0_regval;
+- struct {
+- mmr_t shubs_present0 : 64;
+- } sh_shubs_present0_s;
+-} sh_shubs_present0_u_t;
+-#else
+ typedef union sh_shubs_present0_u {
+ mmr_t sh_shubs_present0_regval;
+ struct {
+ mmr_t shubs_present0 : 64;
+ } sh_shubs_present0_s;
+ } sh_shubs_present0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_SHUBS_PRESENT1" */
+ /* Shubs 64 - 127 Present. Used for invalidate generation */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_shubs_present1_u {
+- mmr_t sh_shubs_present1_regval;
+- struct {
+- mmr_t shubs_present1 : 64;
+- } sh_shubs_present1_s;
+-} sh_shubs_present1_u_t;
+-#else
+ typedef union sh_shubs_present1_u {
+ mmr_t sh_shubs_present1_regval;
+ struct {
+ mmr_t shubs_present1 : 64;
+ } sh_shubs_present1_s;
+ } sh_shubs_present1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_SHUBS_PRESENT2" */
+ /* Shubs 128 - 191 Present. Used for invalidate generation */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_shubs_present2_u {
+- mmr_t sh_shubs_present2_regval;
+- struct {
+- mmr_t shubs_present2 : 64;
+- } sh_shubs_present2_s;
+-} sh_shubs_present2_u_t;
+-#else
+ typedef union sh_shubs_present2_u {
+ mmr_t sh_shubs_present2_regval;
+ struct {
+ mmr_t shubs_present2 : 64;
+ } sh_shubs_present2_s;
+ } sh_shubs_present2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_SHUBS_PRESENT3" */
+ /* Shubs 192 - 255 Present. Used for invalidate generation */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_shubs_present3_u {
+ mmr_t sh_shubs_present3_regval;
+ struct {
+ mmr_t shubs_present3 : 64;
+ } sh_shubs_present3_s;
+ } sh_shubs_present3_u_t;
+-#else
+-typedef union sh_shubs_present3_u {
+- mmr_t sh_shubs_present3_regval;
+- struct {
+- mmr_t shubs_present3 : 64;
+- } sh_shubs_present3_s;
+-} sh_shubs_present3_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_SOFT_RESET" */
+ /* SHub Soft Reset */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_soft_reset_u {
+ mmr_t sh_soft_reset_regval;
+ struct {
+@@ -19725,22 +10608,12 @@
+ mmr_t reserved_0 : 63;
+ } sh_soft_reset_s;
+ } sh_soft_reset_u_t;
+-#else
+-typedef union sh_soft_reset_u {
+- mmr_t sh_soft_reset_regval;
+- struct {
+- mmr_t reserved_0 : 63;
+- mmr_t soft_reset : 1;
+- } sh_soft_reset_s;
+-} sh_soft_reset_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_FIRST_ERROR" */
+ /* Shub Global First Error Flags */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_first_error_u {
+ mmr_t sh_first_error_regval;
+ struct {
+@@ -19748,22 +10621,12 @@
+ mmr_t reserved_0 : 45;
+ } sh_first_error_s;
+ } sh_first_error_u_t;
+-#else
+-typedef union sh_first_error_u {
+- mmr_t sh_first_error_regval;
+- struct {
+- mmr_t reserved_0 : 45;
+- mmr_t first_error : 19;
+- } sh_first_error_s;
+-} sh_first_error_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_II_HW_TIME_STAMP" */
+ /* II hardware error time stamp */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ii_hw_time_stamp_u {
+ mmr_t sh_ii_hw_time_stamp_regval;
+ struct {
+@@ -19771,22 +10634,12 @@
+ mmr_t valid : 1;
+ } sh_ii_hw_time_stamp_s;
+ } sh_ii_hw_time_stamp_u_t;
+-#else
+-typedef union sh_ii_hw_time_stamp_u {
+- mmr_t sh_ii_hw_time_stamp_regval;
+- struct {
+- mmr_t valid : 1;
+- mmr_t time : 63;
+- } sh_ii_hw_time_stamp_s;
+-} sh_ii_hw_time_stamp_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LB_HW_TIME_STAMP" */
+ /* LB hardware error time stamp */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_hw_time_stamp_u {
+ mmr_t sh_lb_hw_time_stamp_regval;
+ struct {
+@@ -19794,22 +10647,12 @@
+ mmr_t valid : 1;
+ } sh_lb_hw_time_stamp_s;
+ } sh_lb_hw_time_stamp_u_t;
+-#else
+-typedef union sh_lb_hw_time_stamp_u {
+- mmr_t sh_lb_hw_time_stamp_regval;
+- struct {
+- mmr_t valid : 1;
+- mmr_t time : 63;
+- } sh_lb_hw_time_stamp_s;
+-} sh_lb_hw_time_stamp_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_COR_TIME_STAMP" */
+ /* MD correctable error time stamp */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_cor_time_stamp_u {
+ mmr_t sh_md_cor_time_stamp_regval;
+ struct {
+@@ -19817,22 +10660,12 @@
+ mmr_t valid : 1;
+ } sh_md_cor_time_stamp_s;
+ } sh_md_cor_time_stamp_u_t;
+-#else
+-typedef union sh_md_cor_time_stamp_u {
+- mmr_t sh_md_cor_time_stamp_regval;
+- struct {
+- mmr_t valid : 1;
+- mmr_t time : 63;
+- } sh_md_cor_time_stamp_s;
+-} sh_md_cor_time_stamp_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_HW_TIME_STAMP" */
+ /* MD hardware error time stamp */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_hw_time_stamp_u {
+ mmr_t sh_md_hw_time_stamp_regval;
+ struct {
+@@ -19840,22 +10673,12 @@
+ mmr_t valid : 1;
+ } sh_md_hw_time_stamp_s;
+ } sh_md_hw_time_stamp_u_t;
+-#else
+-typedef union sh_md_hw_time_stamp_u {
+- mmr_t sh_md_hw_time_stamp_regval;
+- struct {
+- mmr_t valid : 1;
+- mmr_t time : 63;
+- } sh_md_hw_time_stamp_s;
+-} sh_md_hw_time_stamp_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_UNCOR_TIME_STAMP" */
+ /* MD uncorrectable error time stamp */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_uncor_time_stamp_u {
+ mmr_t sh_md_uncor_time_stamp_regval;
+ struct {
+@@ -19863,22 +10686,12 @@
+ mmr_t valid : 1;
+ } sh_md_uncor_time_stamp_s;
+ } sh_md_uncor_time_stamp_u_t;
+-#else
+-typedef union sh_md_uncor_time_stamp_u {
+- mmr_t sh_md_uncor_time_stamp_regval;
+- struct {
+- mmr_t valid : 1;
+- mmr_t time : 63;
+- } sh_md_uncor_time_stamp_s;
+-} sh_md_uncor_time_stamp_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_COR_TIME_STAMP" */
+ /* PI correctable error time stamp */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_cor_time_stamp_u {
+ mmr_t sh_pi_cor_time_stamp_regval;
+ struct {
+@@ -19886,22 +10699,12 @@
+ mmr_t valid : 1;
+ } sh_pi_cor_time_stamp_s;
+ } sh_pi_cor_time_stamp_u_t;
+-#else
+-typedef union sh_pi_cor_time_stamp_u {
+- mmr_t sh_pi_cor_time_stamp_regval;
+- struct {
+- mmr_t valid : 1;
+- mmr_t time : 63;
+- } sh_pi_cor_time_stamp_s;
+-} sh_pi_cor_time_stamp_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_HW_TIME_STAMP" */
+ /* PI hardware error time stamp */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_hw_time_stamp_u {
+ mmr_t sh_pi_hw_time_stamp_regval;
+ struct {
+@@ -19909,22 +10712,12 @@
+ mmr_t valid : 1;
+ } sh_pi_hw_time_stamp_s;
+ } sh_pi_hw_time_stamp_u_t;
+-#else
+-typedef union sh_pi_hw_time_stamp_u {
+- mmr_t sh_pi_hw_time_stamp_regval;
+- struct {
+- mmr_t valid : 1;
+- mmr_t time : 63;
+- } sh_pi_hw_time_stamp_s;
+-} sh_pi_hw_time_stamp_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_UNCOR_TIME_STAMP" */
+ /* PI uncorrectable error time stamp */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_uncor_time_stamp_u {
+ mmr_t sh_pi_uncor_time_stamp_regval;
+ struct {
+@@ -19932,22 +10725,12 @@
+ mmr_t valid : 1;
+ } sh_pi_uncor_time_stamp_s;
+ } sh_pi_uncor_time_stamp_u_t;
+-#else
+-typedef union sh_pi_uncor_time_stamp_u {
+- mmr_t sh_pi_uncor_time_stamp_regval;
+- struct {
+- mmr_t valid : 1;
+- mmr_t time : 63;
+- } sh_pi_uncor_time_stamp_s;
+-} sh_pi_uncor_time_stamp_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PROC0_ADV_TIME_STAMP" */
+ /* Proc 0 advisory time stamp */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc0_adv_time_stamp_u {
+ mmr_t sh_proc0_adv_time_stamp_regval;
+ struct {
+@@ -19955,22 +10738,12 @@
+ mmr_t valid : 1;
+ } sh_proc0_adv_time_stamp_s;
+ } sh_proc0_adv_time_stamp_u_t;
+-#else
+-typedef union sh_proc0_adv_time_stamp_u {
+- mmr_t sh_proc0_adv_time_stamp_regval;
+- struct {
+- mmr_t valid : 1;
+- mmr_t time : 63;
+- } sh_proc0_adv_time_stamp_s;
+-} sh_proc0_adv_time_stamp_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PROC0_ERR_TIME_STAMP" */
+ /* Proc 0 error time stamp */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc0_err_time_stamp_u {
+ mmr_t sh_proc0_err_time_stamp_regval;
+ struct {
+@@ -19978,22 +10751,12 @@
+ mmr_t valid : 1;
+ } sh_proc0_err_time_stamp_s;
+ } sh_proc0_err_time_stamp_u_t;
+-#else
+-typedef union sh_proc0_err_time_stamp_u {
+- mmr_t sh_proc0_err_time_stamp_regval;
+- struct {
+- mmr_t valid : 1;
+- mmr_t time : 63;
+- } sh_proc0_err_time_stamp_s;
+-} sh_proc0_err_time_stamp_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PROC1_ADV_TIME_STAMP" */
+ /* Proc 1 advisory time stamp */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc1_adv_time_stamp_u {
+ mmr_t sh_proc1_adv_time_stamp_regval;
+ struct {
+@@ -20001,22 +10764,12 @@
+ mmr_t valid : 1;
+ } sh_proc1_adv_time_stamp_s;
+ } sh_proc1_adv_time_stamp_u_t;
+-#else
+-typedef union sh_proc1_adv_time_stamp_u {
+- mmr_t sh_proc1_adv_time_stamp_regval;
+- struct {
+- mmr_t valid : 1;
+- mmr_t time : 63;
+- } sh_proc1_adv_time_stamp_s;
+-} sh_proc1_adv_time_stamp_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PROC1_ERR_TIME_STAMP" */
+ /* Proc 1 error time stamp */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc1_err_time_stamp_u {
+ mmr_t sh_proc1_err_time_stamp_regval;
+ struct {
+@@ -20024,22 +10777,12 @@
+ mmr_t valid : 1;
+ } sh_proc1_err_time_stamp_s;
+ } sh_proc1_err_time_stamp_u_t;
+-#else
+-typedef union sh_proc1_err_time_stamp_u {
+- mmr_t sh_proc1_err_time_stamp_regval;
+- struct {
+- mmr_t valid : 1;
+- mmr_t time : 63;
+- } sh_proc1_err_time_stamp_s;
+-} sh_proc1_err_time_stamp_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PROC2_ADV_TIME_STAMP" */
+ /* Proc 2 advisory time stamp */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc2_adv_time_stamp_u {
+ mmr_t sh_proc2_adv_time_stamp_regval;
+ struct {
+@@ -20047,22 +10790,12 @@
+ mmr_t valid : 1;
+ } sh_proc2_adv_time_stamp_s;
+ } sh_proc2_adv_time_stamp_u_t;
+-#else
+-typedef union sh_proc2_adv_time_stamp_u {
+- mmr_t sh_proc2_adv_time_stamp_regval;
+- struct {
+- mmr_t valid : 1;
+- mmr_t time : 63;
+- } sh_proc2_adv_time_stamp_s;
+-} sh_proc2_adv_time_stamp_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PROC2_ERR_TIME_STAMP" */
+ /* Proc 2 error time stamp */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc2_err_time_stamp_u {
+ mmr_t sh_proc2_err_time_stamp_regval;
+ struct {
+@@ -20070,22 +10803,12 @@
+ mmr_t valid : 1;
+ } sh_proc2_err_time_stamp_s;
+ } sh_proc2_err_time_stamp_u_t;
+-#else
+-typedef union sh_proc2_err_time_stamp_u {
+- mmr_t sh_proc2_err_time_stamp_regval;
+- struct {
+- mmr_t valid : 1;
+- mmr_t time : 63;
+- } sh_proc2_err_time_stamp_s;
+-} sh_proc2_err_time_stamp_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PROC3_ADV_TIME_STAMP" */
+ /* Proc 3 advisory time stamp */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc3_adv_time_stamp_u {
+ mmr_t sh_proc3_adv_time_stamp_regval;
+ struct {
+@@ -20093,22 +10816,12 @@
+ mmr_t valid : 1;
+ } sh_proc3_adv_time_stamp_s;
+ } sh_proc3_adv_time_stamp_u_t;
+-#else
+-typedef union sh_proc3_adv_time_stamp_u {
+- mmr_t sh_proc3_adv_time_stamp_regval;
+- struct {
+- mmr_t valid : 1;
+- mmr_t time : 63;
+- } sh_proc3_adv_time_stamp_s;
+-} sh_proc3_adv_time_stamp_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PROC3_ERR_TIME_STAMP" */
+ /* Proc 3 error time stamp */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc3_err_time_stamp_u {
+ mmr_t sh_proc3_err_time_stamp_regval;
+ struct {
+@@ -20116,22 +10829,12 @@
+ mmr_t valid : 1;
+ } sh_proc3_err_time_stamp_s;
+ } sh_proc3_err_time_stamp_u_t;
+-#else
+-typedef union sh_proc3_err_time_stamp_u {
+- mmr_t sh_proc3_err_time_stamp_regval;
+- struct {
+- mmr_t valid : 1;
+- mmr_t time : 63;
+- } sh_proc3_err_time_stamp_s;
+-} sh_proc3_err_time_stamp_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_COR_TIME_STAMP" */
+ /* XN correctable error time stamp */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_cor_time_stamp_u {
+ mmr_t sh_xn_cor_time_stamp_regval;
+ struct {
+@@ -20139,22 +10842,12 @@
+ mmr_t valid : 1;
+ } sh_xn_cor_time_stamp_s;
+ } sh_xn_cor_time_stamp_u_t;
+-#else
+-typedef union sh_xn_cor_time_stamp_u {
+- mmr_t sh_xn_cor_time_stamp_regval;
+- struct {
+- mmr_t valid : 1;
+- mmr_t time : 63;
+- } sh_xn_cor_time_stamp_s;
+-} sh_xn_cor_time_stamp_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_HW_TIME_STAMP" */
+ /* XN hardware error time stamp */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_hw_time_stamp_u {
+ mmr_t sh_xn_hw_time_stamp_regval;
+ struct {
+@@ -20162,22 +10855,12 @@
+ mmr_t valid : 1;
+ } sh_xn_hw_time_stamp_s;
+ } sh_xn_hw_time_stamp_u_t;
+-#else
+-typedef union sh_xn_hw_time_stamp_u {
+- mmr_t sh_xn_hw_time_stamp_regval;
+- struct {
+- mmr_t valid : 1;
+- mmr_t time : 63;
+- } sh_xn_hw_time_stamp_s;
+-} sh_xn_hw_time_stamp_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_UNCOR_TIME_STAMP" */
+ /* XN uncorrectable error time stamp */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_uncor_time_stamp_u {
+ mmr_t sh_xn_uncor_time_stamp_regval;
+ struct {
+@@ -20185,22 +10868,12 @@
+ mmr_t valid : 1;
+ } sh_xn_uncor_time_stamp_s;
+ } sh_xn_uncor_time_stamp_u_t;
+-#else
+-typedef union sh_xn_uncor_time_stamp_u {
+- mmr_t sh_xn_uncor_time_stamp_regval;
+- struct {
+- mmr_t valid : 1;
+- mmr_t time : 63;
+- } sh_xn_uncor_time_stamp_s;
+-} sh_xn_uncor_time_stamp_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_DEBUG_PORT" */
+ /* SHub Debug Port */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_debug_port_u {
+ mmr_t sh_debug_port_regval;
+ struct {
+@@ -20215,52 +10888,25 @@
+ mmr_t reserved_0 : 32;
+ } sh_debug_port_s;
+ } sh_debug_port_u_t;
+-#else
+-typedef union sh_debug_port_u {
+- mmr_t sh_debug_port_regval;
+- struct {
+- mmr_t reserved_0 : 32;
+- mmr_t debug_nibble7 : 4;
+- mmr_t debug_nibble6 : 4;
+- mmr_t debug_nibble5 : 4;
+- mmr_t debug_nibble4 : 4;
+- mmr_t debug_nibble3 : 4;
+- mmr_t debug_nibble2 : 4;
+- mmr_t debug_nibble1 : 4;
+- mmr_t debug_nibble0 : 4;
+- } sh_debug_port_s;
+-} sh_debug_port_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_II_DEBUG_DATA" */
+ /* II Debug Data */
+-/* ==================================================================== */
+-
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_ii_debug_data_u {
+- mmr_t sh_ii_debug_data_regval;
+- struct {
+- mmr_t ii_data : 32;
+- mmr_t reserved_0 : 32;
+- } sh_ii_debug_data_s;
+-} sh_ii_debug_data_u_t;
+-#else
++/* ==================================================================== */
++
+ typedef union sh_ii_debug_data_u {
+ mmr_t sh_ii_debug_data_regval;
+ struct {
+- mmr_t reserved_0 : 32;
+ mmr_t ii_data : 32;
++ mmr_t reserved_0 : 32;
+ } sh_ii_debug_data_s;
+ } sh_ii_debug_data_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_II_WRAP_DEBUG_DATA" */
+ /* SHub II Wrapper Debug Data */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ii_wrap_debug_data_u {
+ mmr_t sh_ii_wrap_debug_data_regval;
+ struct {
+@@ -20268,22 +10914,12 @@
+ mmr_t reserved_0 : 32;
+ } sh_ii_wrap_debug_data_s;
+ } sh_ii_wrap_debug_data_u_t;
+-#else
+-typedef union sh_ii_wrap_debug_data_u {
+- mmr_t sh_ii_wrap_debug_data_regval;
+- struct {
+- mmr_t reserved_0 : 32;
+- mmr_t ii_wrap_data : 32;
+- } sh_ii_wrap_debug_data_s;
+-} sh_ii_wrap_debug_data_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_LB_DEBUG_DATA" */
+ /* SHub LB Debug Data */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_debug_data_u {
+ mmr_t sh_lb_debug_data_regval;
+ struct {
+@@ -20291,22 +10927,12 @@
+ mmr_t reserved_0 : 32;
+ } sh_lb_debug_data_s;
+ } sh_lb_debug_data_u_t;
+-#else
+-typedef union sh_lb_debug_data_u {
+- mmr_t sh_lb_debug_data_regval;
+- struct {
+- mmr_t reserved_0 : 32;
+- mmr_t lb_data : 32;
+- } sh_lb_debug_data_s;
+-} sh_lb_debug_data_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DEBUG_DATA" */
+ /* SHub MD Debug Data */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_debug_data_u {
+ mmr_t sh_md_debug_data_regval;
+ struct {
+@@ -20314,22 +10940,12 @@
+ mmr_t reserved_0 : 32;
+ } sh_md_debug_data_s;
+ } sh_md_debug_data_u_t;
+-#else
+-typedef union sh_md_debug_data_u {
+- mmr_t sh_md_debug_data_regval;
+- struct {
+- mmr_t reserved_0 : 32;
+- mmr_t md_data : 32;
+- } sh_md_debug_data_s;
+-} sh_md_debug_data_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_DEBUG_DATA" */
+ /* SHub PI Debug Data */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_debug_data_u {
+ mmr_t sh_pi_debug_data_regval;
+ struct {
+@@ -20337,22 +10953,12 @@
+ mmr_t reserved_0 : 32;
+ } sh_pi_debug_data_s;
+ } sh_pi_debug_data_u_t;
+-#else
+-typedef union sh_pi_debug_data_u {
+- mmr_t sh_pi_debug_data_regval;
+- struct {
+- mmr_t reserved_0 : 32;
+- mmr_t pi_data : 32;
+- } sh_pi_debug_data_s;
+-} sh_pi_debug_data_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_DEBUG_DATA" */
+ /* SHub XN Debug Data */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_debug_data_u {
+ mmr_t sh_xn_debug_data_regval;
+ struct {
+@@ -20360,22 +10966,12 @@
+ mmr_t reserved_0 : 32;
+ } sh_xn_debug_data_s;
+ } sh_xn_debug_data_u_t;
+-#else
+-typedef union sh_xn_debug_data_u {
+- mmr_t sh_xn_debug_data_regval;
+- struct {
+- mmr_t reserved_0 : 32;
+- mmr_t xn_data : 32;
+- } sh_xn_debug_data_s;
+-} sh_xn_debug_data_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_TSF_ARMED_STATE" */
+ /* Trigger sequencing facility arm state */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_tsf_armed_state_u {
+ mmr_t sh_tsf_armed_state_regval;
+ struct {
+@@ -20383,22 +10979,12 @@
+ mmr_t reserved_0 : 56;
+ } sh_tsf_armed_state_s;
+ } sh_tsf_armed_state_u_t;
+-#else
+-typedef union sh_tsf_armed_state_u {
+- mmr_t sh_tsf_armed_state_regval;
+- struct {
+- mmr_t reserved_0 : 56;
+- mmr_t state : 8;
+- } sh_tsf_armed_state_s;
+-} sh_tsf_armed_state_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_TSF_COUNTER_VALUE" */
+ /* Trigger sequencing facility counter value */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_tsf_counter_value_u {
+ mmr_t sh_tsf_counter_value_regval;
+ struct {
+@@ -20408,24 +10994,12 @@
+ mmr_t count_8a : 8;
+ } sh_tsf_counter_value_s;
+ } sh_tsf_counter_value_u_t;
+-#else
+-typedef union sh_tsf_counter_value_u {
+- mmr_t sh_tsf_counter_value_regval;
+- struct {
+- mmr_t count_8a : 8;
+- mmr_t count_8b : 8;
+- mmr_t count_16 : 16;
+- mmr_t count_32 : 32;
+- } sh_tsf_counter_value_s;
+-} sh_tsf_counter_value_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_TSF_TRIGGERED_STATE" */
+ /* Trigger sequencing facility triggered state */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_tsf_triggered_state_u {
+ mmr_t sh_tsf_triggered_state_regval;
+ struct {
+@@ -20433,64 +11007,36 @@
+ mmr_t reserved_0 : 56;
+ } sh_tsf_triggered_state_s;
+ } sh_tsf_triggered_state_u_t;
+-#else
+-typedef union sh_tsf_triggered_state_u {
+- mmr_t sh_tsf_triggered_state_regval;
+- struct {
+- mmr_t reserved_0 : 56;
+- mmr_t state : 8;
+- } sh_tsf_triggered_state_s;
+-} sh_tsf_triggered_state_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_VEC_RDDATA" */
+ /* Vector Reply Message Data */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_vec_rddata_u {
+- mmr_t sh_vec_rddata_regval;
+- struct {
+- mmr_t data : 64;
+- } sh_vec_rddata_s;
+-} sh_vec_rddata_u_t;
+-#else
+ typedef union sh_vec_rddata_u {
+ mmr_t sh_vec_rddata_regval;
+ struct {
+ mmr_t data : 64;
+ } sh_vec_rddata_s;
+ } sh_vec_rddata_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_VEC_RETURN" */
+ /* Vector Reply Message Return Route */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_vec_return_u {
+- mmr_t sh_vec_return_regval;
+- struct {
+- mmr_t route : 64;
+- } sh_vec_return_s;
+-} sh_vec_return_u_t;
+-#else
+ typedef union sh_vec_return_u {
+ mmr_t sh_vec_return_regval;
+ struct {
+ mmr_t route : 64;
+ } sh_vec_return_s;
+ } sh_vec_return_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_VEC_STATUS" */
+ /* Vector Reply Message Status */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_vec_status_u {
+ mmr_t sh_vec_status_regval;
+ struct {
+@@ -20503,27 +11049,12 @@
+ mmr_t status_valid : 1;
+ } sh_vec_status_s;
+ } sh_vec_status_u_t;
+-#else
+-typedef union sh_vec_status_u {
+- mmr_t sh_vec_status_regval;
+- struct {
+- mmr_t status_valid : 1;
+- mmr_t overrun : 1;
+- mmr_t reserved_0 : 2;
+- mmr_t source : 14;
+- mmr_t pio_id : 11;
+- mmr_t address : 32;
+- mmr_t type : 3;
+- } sh_vec_status_s;
+-} sh_vec_status_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PERFORMANCE_COUNT0_CONTROL" */
+ /* Performance Counter 0 Control */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_performance_count0_control_u {
+ mmr_t sh_performance_count0_control_regval;
+ struct {
+@@ -20541,32 +11072,12 @@
+ mmr_t reserved_0 : 45;
+ } sh_performance_count0_control_s;
+ } sh_performance_count0_control_u_t;
+-#else
+-typedef union sh_performance_count0_control_u {
+- mmr_t sh_performance_count0_control_regval;
+- struct {
+- mmr_t reserved_0 : 45;
+- mmr_t peak_det_enable : 1;
+- mmr_t dec_enable : 1;
+- mmr_t inc_enable : 1;
+- mmr_t dn_mode : 1;
+- mmr_t dn_polarity : 1;
+- mmr_t dn_event : 1;
+- mmr_t dn_stimulus : 5;
+- mmr_t up_mode : 1;
+- mmr_t up_polarity : 1;
+- mmr_t up_event : 1;
+- mmr_t up_stimulus : 5;
+- } sh_performance_count0_control_s;
+-} sh_performance_count0_control_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PERFORMANCE_COUNT1_CONTROL" */
+ /* Performance Counter 1 Control */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_performance_count1_control_u {
+ mmr_t sh_performance_count1_control_regval;
+ struct {
+@@ -20584,32 +11095,12 @@
+ mmr_t reserved_0 : 45;
+ } sh_performance_count1_control_s;
+ } sh_performance_count1_control_u_t;
+-#else
+-typedef union sh_performance_count1_control_u {
+- mmr_t sh_performance_count1_control_regval;
+- struct {
+- mmr_t reserved_0 : 45;
+- mmr_t peak_det_enable : 1;
+- mmr_t dec_enable : 1;
+- mmr_t inc_enable : 1;
+- mmr_t dn_mode : 1;
+- mmr_t dn_polarity : 1;
+- mmr_t dn_event : 1;
+- mmr_t dn_stimulus : 5;
+- mmr_t up_mode : 1;
+- mmr_t up_polarity : 1;
+- mmr_t up_event : 1;
+- mmr_t up_stimulus : 5;
+- } sh_performance_count1_control_s;
+-} sh_performance_count1_control_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PERFORMANCE_COUNT2_CONTROL" */
+ /* Performance Counter 2 Control */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_performance_count2_control_u {
+ mmr_t sh_performance_count2_control_regval;
+ struct {
+@@ -20627,32 +11118,12 @@
+ mmr_t reserved_0 : 45;
+ } sh_performance_count2_control_s;
+ } sh_performance_count2_control_u_t;
+-#else
+-typedef union sh_performance_count2_control_u {
+- mmr_t sh_performance_count2_control_regval;
+- struct {
+- mmr_t reserved_0 : 45;
+- mmr_t peak_det_enable : 1;
+- mmr_t dec_enable : 1;
+- mmr_t inc_enable : 1;
+- mmr_t dn_mode : 1;
+- mmr_t dn_polarity : 1;
+- mmr_t dn_event : 1;
+- mmr_t dn_stimulus : 5;
+- mmr_t up_mode : 1;
+- mmr_t up_polarity : 1;
+- mmr_t up_event : 1;
+- mmr_t up_stimulus : 5;
+- } sh_performance_count2_control_s;
+-} sh_performance_count2_control_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PERFORMANCE_COUNT3_CONTROL" */
+ /* Performance Counter 3 Control */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_performance_count3_control_u {
+ mmr_t sh_performance_count3_control_regval;
+ struct {
+@@ -20670,32 +11141,12 @@
+ mmr_t reserved_0 : 45;
+ } sh_performance_count3_control_s;
+ } sh_performance_count3_control_u_t;
+-#else
+-typedef union sh_performance_count3_control_u {
+- mmr_t sh_performance_count3_control_regval;
+- struct {
+- mmr_t reserved_0 : 45;
+- mmr_t peak_det_enable : 1;
+- mmr_t dec_enable : 1;
+- mmr_t inc_enable : 1;
+- mmr_t dn_mode : 1;
+- mmr_t dn_polarity : 1;
+- mmr_t dn_event : 1;
+- mmr_t dn_stimulus : 5;
+- mmr_t up_mode : 1;
+- mmr_t up_polarity : 1;
+- mmr_t up_event : 1;
+- mmr_t up_stimulus : 5;
+- } sh_performance_count3_control_s;
+-} sh_performance_count3_control_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PERFORMANCE_COUNT4_CONTROL" */
+ /* Performance Counter 4 Control */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_performance_count4_control_u {
+ mmr_t sh_performance_count4_control_regval;
+ struct {
+@@ -20713,32 +11164,12 @@
+ mmr_t reserved_0 : 45;
+ } sh_performance_count4_control_s;
+ } sh_performance_count4_control_u_t;
+-#else
+-typedef union sh_performance_count4_control_u {
+- mmr_t sh_performance_count4_control_regval;
+- struct {
+- mmr_t reserved_0 : 45;
+- mmr_t peak_det_enable : 1;
+- mmr_t dec_enable : 1;
+- mmr_t inc_enable : 1;
+- mmr_t dn_mode : 1;
+- mmr_t dn_polarity : 1;
+- mmr_t dn_event : 1;
+- mmr_t dn_stimulus : 5;
+- mmr_t up_mode : 1;
+- mmr_t up_polarity : 1;
+- mmr_t up_event : 1;
+- mmr_t up_stimulus : 5;
+- } sh_performance_count4_control_s;
+-} sh_performance_count4_control_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PERFORMANCE_COUNT5_CONTROL" */
+ /* Performance Counter 5 Control */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_performance_count5_control_u {
+ mmr_t sh_performance_count5_control_regval;
+ struct {
+@@ -20756,32 +11187,12 @@
+ mmr_t reserved_0 : 45;
+ } sh_performance_count5_control_s;
+ } sh_performance_count5_control_u_t;
+-#else
+-typedef union sh_performance_count5_control_u {
+- mmr_t sh_performance_count5_control_regval;
+- struct {
+- mmr_t reserved_0 : 45;
+- mmr_t peak_det_enable : 1;
+- mmr_t dec_enable : 1;
+- mmr_t inc_enable : 1;
+- mmr_t dn_mode : 1;
+- mmr_t dn_polarity : 1;
+- mmr_t dn_event : 1;
+- mmr_t dn_stimulus : 5;
+- mmr_t up_mode : 1;
+- mmr_t up_polarity : 1;
+- mmr_t up_event : 1;
+- mmr_t up_stimulus : 5;
+- } sh_performance_count5_control_s;
+-} sh_performance_count5_control_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PERFORMANCE_COUNT6_CONTROL" */
+ /* Performance Counter 6 Control */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_performance_count6_control_u {
+ mmr_t sh_performance_count6_control_regval;
+ struct {
+@@ -20799,32 +11210,12 @@
+ mmr_t reserved_0 : 45;
+ } sh_performance_count6_control_s;
+ } sh_performance_count6_control_u_t;
+-#else
+-typedef union sh_performance_count6_control_u {
+- mmr_t sh_performance_count6_control_regval;
+- struct {
+- mmr_t reserved_0 : 45;
+- mmr_t peak_det_enable : 1;
+- mmr_t dec_enable : 1;
+- mmr_t inc_enable : 1;
+- mmr_t dn_mode : 1;
+- mmr_t dn_polarity : 1;
+- mmr_t dn_event : 1;
+- mmr_t dn_stimulus : 5;
+- mmr_t up_mode : 1;
+- mmr_t up_polarity : 1;
+- mmr_t up_event : 1;
+- mmr_t up_stimulus : 5;
+- } sh_performance_count6_control_s;
+-} sh_performance_count6_control_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PERFORMANCE_COUNT7_CONTROL" */
+ /* Performance Counter 7 Control */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_performance_count7_control_u {
+ mmr_t sh_performance_count7_control_regval;
+ struct {
+@@ -20842,32 +11233,12 @@
+ mmr_t reserved_0 : 45;
+ } sh_performance_count7_control_s;
+ } sh_performance_count7_control_u_t;
+-#else
+-typedef union sh_performance_count7_control_u {
+- mmr_t sh_performance_count7_control_regval;
+- struct {
+- mmr_t reserved_0 : 45;
+- mmr_t peak_det_enable : 1;
+- mmr_t dec_enable : 1;
+- mmr_t inc_enable : 1;
+- mmr_t dn_mode : 1;
+- mmr_t dn_polarity : 1;
+- mmr_t dn_event : 1;
+- mmr_t dn_stimulus : 5;
+- mmr_t up_mode : 1;
+- mmr_t up_polarity : 1;
+- mmr_t up_event : 1;
+- mmr_t up_stimulus : 5;
+- } sh_performance_count7_control_s;
+-} sh_performance_count7_control_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PROFILE_DN_CONTROL" */
+ /* Profile Counter Down Control */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_profile_dn_control_u {
+ mmr_t sh_profile_dn_control_regval;
+ struct {
+@@ -20878,25 +11249,12 @@
+ mmr_t reserved_0 : 56;
+ } sh_profile_dn_control_s;
+ } sh_profile_dn_control_u_t;
+-#else
+-typedef union sh_profile_dn_control_u {
+- mmr_t sh_profile_dn_control_regval;
+- struct {
+- mmr_t reserved_0 : 56;
+- mmr_t mode : 1;
+- mmr_t polarity : 1;
+- mmr_t event : 1;
+- mmr_t stimulus : 5;
+- } sh_profile_dn_control_s;
+-} sh_profile_dn_control_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PROFILE_PEAK_CONTROL" */
+ /* Profile Counter Peak Control */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_profile_peak_control_u {
+ mmr_t sh_profile_peak_control_regval;
+ struct {
+@@ -20908,26 +11266,12 @@
+ mmr_t reserved_2 : 57;
+ } sh_profile_peak_control_s;
+ } sh_profile_peak_control_u_t;
+-#else
+-typedef union sh_profile_peak_control_u {
+- mmr_t sh_profile_peak_control_regval;
+- struct {
+- mmr_t reserved_2 : 57;
+- mmr_t polarity : 1;
+- mmr_t event : 1;
+- mmr_t reserved_1 : 1;
+- mmr_t stimulus : 1;
+- mmr_t reserved_0 : 3;
+- } sh_profile_peak_control_s;
+-} sh_profile_peak_control_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PROFILE_RANGE" */
+ /* Profile Counter Range */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_profile_range_u {
+ mmr_t sh_profile_range_regval;
+ struct {
+@@ -20941,28 +11285,12 @@
+ mmr_t range7 : 8;
+ } sh_profile_range_s;
+ } sh_profile_range_u_t;
+-#else
+-typedef union sh_profile_range_u {
+- mmr_t sh_profile_range_regval;
+- struct {
+- mmr_t range7 : 8;
+- mmr_t range6 : 8;
+- mmr_t range5 : 8;
+- mmr_t range4 : 8;
+- mmr_t range3 : 8;
+- mmr_t range2 : 8;
+- mmr_t range1 : 8;
+- mmr_t range0 : 8;
+- } sh_profile_range_s;
+-} sh_profile_range_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PROFILE_UP_CONTROL" */
+ /* Profile Counter Up Control */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_profile_up_control_u {
+ mmr_t sh_profile_up_control_regval;
+ struct {
+@@ -20973,25 +11301,12 @@
+ mmr_t reserved_0 : 56;
+ } sh_profile_up_control_s;
+ } sh_profile_up_control_u_t;
+-#else
+-typedef union sh_profile_up_control_u {
+- mmr_t sh_profile_up_control_regval;
+- struct {
+- mmr_t reserved_0 : 56;
+- mmr_t mode : 1;
+- mmr_t polarity : 1;
+- mmr_t event : 1;
+- mmr_t stimulus : 5;
+- } sh_profile_up_control_s;
+-} sh_profile_up_control_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PERFORMANCE_COUNTER0" */
+ /* Performance Counter 0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_performance_counter0_u {
+ mmr_t sh_performance_counter0_regval;
+ struct {
+@@ -20999,22 +11314,12 @@
+ mmr_t reserved_0 : 32;
+ } sh_performance_counter0_s;
+ } sh_performance_counter0_u_t;
+-#else
+-typedef union sh_performance_counter0_u {
+- mmr_t sh_performance_counter0_regval;
+- struct {
+- mmr_t reserved_0 : 32;
+- mmr_t count : 32;
+- } sh_performance_counter0_s;
+-} sh_performance_counter0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PERFORMANCE_COUNTER1" */
+ /* Performance Counter 1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_performance_counter1_u {
+ mmr_t sh_performance_counter1_regval;
+ struct {
+@@ -21022,22 +11327,12 @@
+ mmr_t reserved_0 : 32;
+ } sh_performance_counter1_s;
+ } sh_performance_counter1_u_t;
+-#else
+-typedef union sh_performance_counter1_u {
+- mmr_t sh_performance_counter1_regval;
+- struct {
+- mmr_t reserved_0 : 32;
+- mmr_t count : 32;
+- } sh_performance_counter1_s;
+-} sh_performance_counter1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PERFORMANCE_COUNTER2" */
+ /* Performance Counter 2 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_performance_counter2_u {
+ mmr_t sh_performance_counter2_regval;
+ struct {
+@@ -21045,22 +11340,12 @@
+ mmr_t reserved_0 : 32;
+ } sh_performance_counter2_s;
+ } sh_performance_counter2_u_t;
+-#else
+-typedef union sh_performance_counter2_u {
+- mmr_t sh_performance_counter2_regval;
+- struct {
+- mmr_t reserved_0 : 32;
+- mmr_t count : 32;
+- } sh_performance_counter2_s;
+-} sh_performance_counter2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PERFORMANCE_COUNTER3" */
+ /* Performance Counter 3 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_performance_counter3_u {
+ mmr_t sh_performance_counter3_regval;
+ struct {
+@@ -21068,22 +11353,12 @@
+ mmr_t reserved_0 : 32;
+ } sh_performance_counter3_s;
+ } sh_performance_counter3_u_t;
+-#else
+-typedef union sh_performance_counter3_u {
+- mmr_t sh_performance_counter3_regval;
+- struct {
+- mmr_t reserved_0 : 32;
+- mmr_t count : 32;
+- } sh_performance_counter3_s;
+-} sh_performance_counter3_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PERFORMANCE_COUNTER4" */
+ /* Performance Counter 4 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_performance_counter4_u {
+ mmr_t sh_performance_counter4_regval;
+ struct {
+@@ -21091,22 +11366,12 @@
+ mmr_t reserved_0 : 32;
+ } sh_performance_counter4_s;
+ } sh_performance_counter4_u_t;
+-#else
+-typedef union sh_performance_counter4_u {
+- mmr_t sh_performance_counter4_regval;
+- struct {
+- mmr_t reserved_0 : 32;
+- mmr_t count : 32;
+- } sh_performance_counter4_s;
+-} sh_performance_counter4_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PERFORMANCE_COUNTER5" */
+ /* Performance Counter 5 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_performance_counter5_u {
+ mmr_t sh_performance_counter5_regval;
+ struct {
+@@ -21114,22 +11379,12 @@
+ mmr_t reserved_0 : 32;
+ } sh_performance_counter5_s;
+ } sh_performance_counter5_u_t;
+-#else
+-typedef union sh_performance_counter5_u {
+- mmr_t sh_performance_counter5_regval;
+- struct {
+- mmr_t reserved_0 : 32;
+- mmr_t count : 32;
+- } sh_performance_counter5_s;
+-} sh_performance_counter5_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PERFORMANCE_COUNTER6" */
+ /* Performance Counter 6 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_performance_counter6_u {
+ mmr_t sh_performance_counter6_regval;
+ struct {
+@@ -21137,22 +11392,12 @@
+ mmr_t reserved_0 : 32;
+ } sh_performance_counter6_s;
+ } sh_performance_counter6_u_t;
+-#else
+-typedef union sh_performance_counter6_u {
+- mmr_t sh_performance_counter6_regval;
+- struct {
+- mmr_t reserved_0 : 32;
+- mmr_t count : 32;
+- } sh_performance_counter6_s;
+-} sh_performance_counter6_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PERFORMANCE_COUNTER7" */
+ /* Performance Counter 7 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_performance_counter7_u {
+ mmr_t sh_performance_counter7_regval;
+ struct {
+@@ -21160,22 +11405,12 @@
+ mmr_t reserved_0 : 32;
+ } sh_performance_counter7_s;
+ } sh_performance_counter7_u_t;
+-#else
+-typedef union sh_performance_counter7_u {
+- mmr_t sh_performance_counter7_regval;
+- struct {
+- mmr_t reserved_0 : 32;
+- mmr_t count : 32;
+- } sh_performance_counter7_s;
+-} sh_performance_counter7_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PROFILE_COUNTER" */
+ /* Profile Counter */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_profile_counter_u {
+ mmr_t sh_profile_counter_regval;
+ struct {
+@@ -21183,22 +11418,12 @@
+ mmr_t reserved_0 : 56;
+ } sh_profile_counter_s;
+ } sh_profile_counter_u_t;
+-#else
+-typedef union sh_profile_counter_u {
+- mmr_t sh_profile_counter_regval;
+- struct {
+- mmr_t reserved_0 : 56;
+- mmr_t counter : 8;
+- } sh_profile_counter_s;
+-} sh_profile_counter_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PROFILE_PEAK" */
+ /* Profile Peak Counter */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_profile_peak_u {
+ mmr_t sh_profile_peak_regval;
+ struct {
+@@ -21206,22 +11431,12 @@
+ mmr_t reserved_0 : 56;
+ } sh_profile_peak_s;
+ } sh_profile_peak_u_t;
+-#else
+-typedef union sh_profile_peak_u {
+- mmr_t sh_profile_peak_regval;
+- struct {
+- mmr_t reserved_0 : 56;
+- mmr_t counter : 8;
+- } sh_profile_peak_s;
+-} sh_profile_peak_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PTC_0" */
+ /* Puge Translation Cache Message Configuration Information */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ptc_0_u {
+ mmr_t sh_ptc_0_regval;
+ struct {
+@@ -21233,26 +11448,12 @@
+ mmr_t start : 1;
+ } sh_ptc_0_s;
+ } sh_ptc_0_u_t;
+-#else
+-typedef union sh_ptc_0_u {
+- mmr_t sh_ptc_0_regval;
+- struct {
+- mmr_t start : 1;
+- mmr_t reserved_1 : 31;
+- mmr_t rid : 24;
+- mmr_t ps : 6;
+- mmr_t reserved_0 : 1;
+- mmr_t a : 1;
+- } sh_ptc_0_s;
+-} sh_ptc_0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PTC_1" */
+ /* Puge Translation Cache Message Configuration Information */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ptc_1_u {
+ mmr_t sh_ptc_1_regval;
+ struct {
+@@ -21262,24 +11463,12 @@
+ mmr_t start : 1;
+ } sh_ptc_1_s;
+ } sh_ptc_1_u_t;
+-#else
+-typedef union sh_ptc_1_u {
+- mmr_t sh_ptc_1_regval;
+- struct {
+- mmr_t start : 1;
+- mmr_t reserved_1 : 2;
+- mmr_t vpn : 49;
+- mmr_t reserved_0 : 12;
+- } sh_ptc_1_s;
+-} sh_ptc_1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PTC_PARMS" */
+ /* PTC Time-out parmaeters */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ptc_parms_u {
+ mmr_t sh_ptc_parms_regval;
+ struct {
+@@ -21288,23 +11477,12 @@
+ mmr_t reserved_0 : 28;
+ } sh_ptc_parms_s;
+ } sh_ptc_parms_u_t;
+-#else
+-typedef union sh_ptc_parms_u {
+- mmr_t sh_ptc_parms_regval;
+- struct {
+- mmr_t reserved_0 : 28;
+- mmr_t ptc_to_val : 12;
+- mmr_t ptc_to_wrap : 24;
+- } sh_ptc_parms_s;
+-} sh_ptc_parms_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_INT_CMPA" */
+ /* RTC Compare Value for Processor A */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_int_cmpa_u {
+ mmr_t sh_int_cmpa_regval;
+ struct {
+@@ -21312,22 +11490,12 @@
+ mmr_t reserved_0 : 9;
+ } sh_int_cmpa_s;
+ } sh_int_cmpa_u_t;
+-#else
+-typedef union sh_int_cmpa_u {
+- mmr_t sh_int_cmpa_regval;
+- struct {
+- mmr_t reserved_0 : 9;
+- mmr_t real_time_cmpa : 55;
+- } sh_int_cmpa_s;
+-} sh_int_cmpa_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_INT_CMPB" */
+ /* RTC Compare Value for Processor B */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_int_cmpb_u {
+ mmr_t sh_int_cmpb_regval;
+ struct {
+@@ -21335,22 +11503,12 @@
+ mmr_t reserved_0 : 9;
+ } sh_int_cmpb_s;
+ } sh_int_cmpb_u_t;
+-#else
+-typedef union sh_int_cmpb_u {
+- mmr_t sh_int_cmpb_regval;
+- struct {
+- mmr_t reserved_0 : 9;
+- mmr_t real_time_cmpb : 55;
+- } sh_int_cmpb_s;
+-} sh_int_cmpb_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_INT_CMPC" */
+ /* RTC Compare Value for Processor C */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_int_cmpc_u {
+ mmr_t sh_int_cmpc_regval;
+ struct {
+@@ -21358,22 +11516,12 @@
+ mmr_t reserved_0 : 9;
+ } sh_int_cmpc_s;
+ } sh_int_cmpc_u_t;
+-#else
+-typedef union sh_int_cmpc_u {
+- mmr_t sh_int_cmpc_regval;
+- struct {
+- mmr_t reserved_0 : 9;
+- mmr_t real_time_cmpc : 55;
+- } sh_int_cmpc_s;
+-} sh_int_cmpc_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_INT_CMPD" */
+ /* RTC Compare Value for Processor D */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_int_cmpd_u {
+ mmr_t sh_int_cmpd_regval;
+ struct {
+@@ -21381,22 +11529,12 @@
+ mmr_t reserved_0 : 9;
+ } sh_int_cmpd_s;
+ } sh_int_cmpd_u_t;
+-#else
+-typedef union sh_int_cmpd_u {
+- mmr_t sh_int_cmpd_regval;
+- struct {
+- mmr_t reserved_0 : 9;
+- mmr_t real_time_cmpd : 55;
+- } sh_int_cmpd_s;
+-} sh_int_cmpd_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_INT_PROF" */
+ /* Profile Compare Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_int_prof_u {
+ mmr_t sh_int_prof_regval;
+ struct {
+@@ -21404,22 +11542,12 @@
+ mmr_t reserved_0 : 32;
+ } sh_int_prof_s;
+ } sh_int_prof_u_t;
+-#else
+-typedef union sh_int_prof_u {
+- mmr_t sh_int_prof_regval;
+- struct {
+- mmr_t reserved_0 : 32;
+- mmr_t profile_compare : 32;
+- } sh_int_prof_s;
+-} sh_int_prof_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_RTC" */
+ /* Real-time Clock */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_rtc_u {
+ mmr_t sh_rtc_regval;
+ struct {
+@@ -21427,85 +11555,48 @@
+ mmr_t reserved_0 : 9;
+ } sh_rtc_s;
+ } sh_rtc_u_t;
+-#else
+-typedef union sh_rtc_u {
+- mmr_t sh_rtc_regval;
+- struct {
+- mmr_t reserved_0 : 9;
+- mmr_t real_time_clock : 55;
+- } sh_rtc_s;
+-} sh_rtc_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_SCRATCH0" */
+ /* Scratch Register 0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_scratch0_u {
+- mmr_t sh_scratch0_regval;
+- struct {
+- mmr_t scratch0 : 64;
+- } sh_scratch0_s;
+-} sh_scratch0_u_t;
+-#else
+ typedef union sh_scratch0_u {
+ mmr_t sh_scratch0_regval;
+ struct {
+ mmr_t scratch0 : 64;
+ } sh_scratch0_s;
+ } sh_scratch0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_SCRATCH1" */
+ /* Scratch Register 1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_scratch1_u {
+- mmr_t sh_scratch1_regval;
+- struct {
+- mmr_t scratch1 : 64;
+- } sh_scratch1_s;
+-} sh_scratch1_u_t;
+-#else
+ typedef union sh_scratch1_u {
+ mmr_t sh_scratch1_regval;
+ struct {
+ mmr_t scratch1 : 64;
+ } sh_scratch1_s;
+ } sh_scratch1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_SCRATCH2" */
+ /* Scratch Register 2 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_scratch2_u {
+- mmr_t sh_scratch2_regval;
+- struct {
+- mmr_t scratch2 : 64;
+- } sh_scratch2_s;
+-} sh_scratch2_u_t;
+-#else
+ typedef union sh_scratch2_u {
+ mmr_t sh_scratch2_regval;
+ struct {
+ mmr_t scratch2 : 64;
+ } sh_scratch2_s;
+ } sh_scratch2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_SCRATCH3" */
+ /* Scratch Register 3 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_scratch3_u {
+ mmr_t sh_scratch3_regval;
+ struct {
+@@ -21513,22 +11604,12 @@
+ mmr_t reserved_0 : 63;
+ } sh_scratch3_s;
+ } sh_scratch3_u_t;
+-#else
+-typedef union sh_scratch3_u {
+- mmr_t sh_scratch3_regval;
+- struct {
+- mmr_t reserved_0 : 63;
+- mmr_t scratch3 : 1;
+- } sh_scratch3_s;
+-} sh_scratch3_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_SCRATCH4" */
+ /* Scratch Register 4 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_scratch4_u {
+ mmr_t sh_scratch4_regval;
+ struct {
+@@ -21536,22 +11617,12 @@
+ mmr_t reserved_0 : 63;
+ } sh_scratch4_s;
+ } sh_scratch4_u_t;
+-#else
+-typedef union sh_scratch4_u {
+- mmr_t sh_scratch4_regval;
+- struct {
+- mmr_t reserved_0 : 63;
+- mmr_t scratch4 : 1;
+- } sh_scratch4_s;
+-} sh_scratch4_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_CRB_MESSAGE_CONTROL" */
+ /* Coherent Request Buffer Message Control */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_crb_message_control_u {
+ mmr_t sh_crb_message_control_regval;
+ struct {
+@@ -21572,35 +11643,12 @@
+ mmr_t ivack_throttle_control : 16;
+ } sh_crb_message_control_s;
+ } sh_crb_message_control_u_t;
+-#else
+-typedef union sh_crb_message_control_u {
+- mmr_t sh_crb_message_control_regval;
+- struct {
+- mmr_t ivack_throttle_control : 16;
+- mmr_t ivack_stall_count : 16;
+- mmr_t reserved_0 : 20;
+- mmr_t enable_ivack_consolidation : 1;
+- mmr_t suppress_bogus_writes : 1;
+- mmr_t wrb_attribute_mismatch_xb_enable : 1;
+- mmr_t rrb_attribute_mismatch_xb_enable : 1;
+- mmr_t irb_attribute_mismatch_fsb_enable : 1;
+- mmr_t wrb_attribute_mismatch_fsb_enable : 1;
+- mmr_t rrb_attribute_mismatch_fsb_enable : 1;
+- mmr_t message_color_enable : 1;
+- mmr_t message_color : 1;
+- mmr_t remote_speculative_message_enable : 1;
+- mmr_t local_speculative_message_enable : 1;
+- mmr_t system_coherence_enable : 1;
+- } sh_crb_message_control_s;
+-} sh_crb_message_control_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_CRB_NACK_LIMIT" */
+ /* CRB Nack Limit */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_crb_nack_limit_u {
+ mmr_t sh_crb_nack_limit_regval;
+ struct {
+@@ -21610,24 +11658,12 @@
+ mmr_t enable : 1;
+ } sh_crb_nack_limit_s;
+ } sh_crb_nack_limit_u_t;
+-#else
+-typedef union sh_crb_nack_limit_u {
+- mmr_t sh_crb_nack_limit_regval;
+- struct {
+- mmr_t enable : 1;
+- mmr_t reserved_0 : 47;
+- mmr_t pri_freq : 4;
+- mmr_t limit : 12;
+- } sh_crb_nack_limit_s;
+-} sh_crb_nack_limit_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_CRB_TIMEOUT_PRESCALE" */
+ /* Coherent Request Buffer Timeout Prescale */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_crb_timeout_prescale_u {
+ mmr_t sh_crb_timeout_prescale_regval;
+ struct {
+@@ -21635,22 +11671,12 @@
+ mmr_t reserved_0 : 32;
+ } sh_crb_timeout_prescale_s;
+ } sh_crb_timeout_prescale_u_t;
+-#else
+-typedef union sh_crb_timeout_prescale_u {
+- mmr_t sh_crb_timeout_prescale_regval;
+- struct {
+- mmr_t reserved_0 : 32;
+- mmr_t scaling_factor : 32;
+- } sh_crb_timeout_prescale_s;
+-} sh_crb_timeout_prescale_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_CRB_TIMEOUT_SKID" */
+ /* Coherent Request Buffer Timeout Skid Limit */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_crb_timeout_skid_u {
+ mmr_t sh_crb_timeout_skid_regval;
+ struct {
+@@ -21659,23 +11685,12 @@
+ mmr_t reset_skid_count : 1;
+ } sh_crb_timeout_skid_s;
+ } sh_crb_timeout_skid_u_t;
+-#else
+-typedef union sh_crb_timeout_skid_u {
+- mmr_t sh_crb_timeout_skid_regval;
+- struct {
+- mmr_t reset_skid_count : 1;
+- mmr_t reserved_0 : 57;
+- mmr_t skid : 6;
+- } sh_crb_timeout_skid_s;
+-} sh_crb_timeout_skid_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MEMORY_WRITE_STATUS_0" */
+ /* Memory Write Status for CPU 0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_memory_write_status_0_u {
+ mmr_t sh_memory_write_status_0_regval;
+ struct {
+@@ -21683,22 +11698,12 @@
+ mmr_t reserved_0 : 58;
+ } sh_memory_write_status_0_s;
+ } sh_memory_write_status_0_u_t;
+-#else
+-typedef union sh_memory_write_status_0_u {
+- mmr_t sh_memory_write_status_0_regval;
+- struct {
+- mmr_t reserved_0 : 58;
+- mmr_t pending_write_count : 6;
+- } sh_memory_write_status_0_s;
+-} sh_memory_write_status_0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MEMORY_WRITE_STATUS_1" */
+ /* Memory Write Status for CPU 1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_memory_write_status_1_u {
+ mmr_t sh_memory_write_status_1_regval;
+ struct {
+@@ -21706,22 +11711,12 @@
+ mmr_t reserved_0 : 58;
+ } sh_memory_write_status_1_s;
+ } sh_memory_write_status_1_u_t;
+-#else
+-typedef union sh_memory_write_status_1_u {
+- mmr_t sh_memory_write_status_1_regval;
+- struct {
+- mmr_t reserved_0 : 58;
+- mmr_t pending_write_count : 6;
+- } sh_memory_write_status_1_s;
+-} sh_memory_write_status_1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PIO_WRITE_STATUS_0" */
+ /* PIO Write Status for CPU 0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pio_write_status_0_u {
+ mmr_t sh_pio_write_status_0_regval;
+ struct {
+@@ -21730,33 +11725,17 @@
+ mmr_t write_error : 1;
+ mmr_t write_error_address : 47;
+ mmr_t reserved_0 : 6;
+- mmr_t pending_write_count : 6;
+- mmr_t reserved_1 : 1;
+- mmr_t writes_ok : 1;
+- } sh_pio_write_status_0_s;
+-} sh_pio_write_status_0_u_t;
+-#else
+-typedef union sh_pio_write_status_0_u {
+- mmr_t sh_pio_write_status_0_regval;
+- struct {
+- mmr_t writes_ok : 1;
+- mmr_t reserved_1 : 1;
+- mmr_t pending_write_count : 6;
+- mmr_t reserved_0 : 6;
+- mmr_t write_error_address : 47;
+- mmr_t write_error : 1;
+- mmr_t write_deadlock : 1;
+- mmr_t multi_write_error : 1;
++ mmr_t pending_write_count : 6;
++ mmr_t reserved_1 : 1;
++ mmr_t writes_ok : 1;
+ } sh_pio_write_status_0_s;
+ } sh_pio_write_status_0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PIO_WRITE_STATUS_1" */
+ /* PIO Write Status for CPU 1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pio_write_status_1_u {
+ mmr_t sh_pio_write_status_1_regval;
+ struct {
+@@ -21770,28 +11749,12 @@
+ mmr_t writes_ok : 1;
+ } sh_pio_write_status_1_s;
+ } sh_pio_write_status_1_u_t;
+-#else
+-typedef union sh_pio_write_status_1_u {
+- mmr_t sh_pio_write_status_1_regval;
+- struct {
+- mmr_t writes_ok : 1;
+- mmr_t reserved_1 : 1;
+- mmr_t pending_write_count : 6;
+- mmr_t reserved_0 : 6;
+- mmr_t write_error_address : 47;
+- mmr_t write_error : 1;
+- mmr_t write_deadlock : 1;
+- mmr_t multi_write_error : 1;
+- } sh_pio_write_status_1_s;
+-} sh_pio_write_status_1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MEMORY_WRITE_STATUS_NON_USER_0" */
+ /* Memory Write Status for CPU 0. OS access only */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_memory_write_status_non_user_0_u {
+ mmr_t sh_memory_write_status_non_user_0_regval;
+ struct {
+@@ -21800,23 +11763,12 @@
+ mmr_t clear : 1;
+ } sh_memory_write_status_non_user_0_s;
+ } sh_memory_write_status_non_user_0_u_t;
+-#else
+-typedef union sh_memory_write_status_non_user_0_u {
+- mmr_t sh_memory_write_status_non_user_0_regval;
+- struct {
+- mmr_t clear : 1;
+- mmr_t reserved_0 : 57;
+- mmr_t pending_write_count : 6;
+- } sh_memory_write_status_non_user_0_s;
+-} sh_memory_write_status_non_user_0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MEMORY_WRITE_STATUS_NON_USER_1" */
+ /* Memory Write Status for CPU 1. OS access only */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_memory_write_status_non_user_1_u {
+ mmr_t sh_memory_write_status_non_user_1_regval;
+ struct {
+@@ -21825,23 +11777,12 @@
+ mmr_t clear : 1;
+ } sh_memory_write_status_non_user_1_s;
+ } sh_memory_write_status_non_user_1_u_t;
+-#else
+-typedef union sh_memory_write_status_non_user_1_u {
+- mmr_t sh_memory_write_status_non_user_1_regval;
+- struct {
+- mmr_t clear : 1;
+- mmr_t reserved_0 : 57;
+- mmr_t pending_write_count : 6;
+- } sh_memory_write_status_non_user_1_s;
+-} sh_memory_write_status_non_user_1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MMRBIST_ERR" */
+ /* Error capture for bist read errors */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_mmrbist_err_u {
+ mmr_t sh_mmrbist_err_regval;
+ struct {
+@@ -21853,26 +11794,12 @@
+ mmr_t reserved_1 : 25;
+ } sh_mmrbist_err_s;
+ } sh_mmrbist_err_u_t;
+-#else
+-typedef union sh_mmrbist_err_u {
+- mmr_t sh_mmrbist_err_regval;
+- struct {
+- mmr_t reserved_1 : 25;
+- mmr_t cancelled : 1;
+- mmr_t multiple_detected : 1;
+- mmr_t detected : 1;
+- mmr_t reserved_0 : 3;
+- mmr_t addr : 33;
+- } sh_mmrbist_err_s;
+-} sh_mmrbist_err_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MISC_ERR_HDR_LOWER" */
+ /* Header capture register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_misc_err_hdr_lower_u {
+ mmr_t sh_misc_err_hdr_lower_regval;
+ struct {
+@@ -21886,28 +11813,12 @@
+ mmr_t valid : 1;
+ } sh_misc_err_hdr_lower_s;
+ } sh_misc_err_hdr_lower_u_t;
+-#else
+-typedef union sh_misc_err_hdr_lower_u {
+- mmr_t sh_misc_err_hdr_lower_regval;
+- struct {
+- mmr_t valid : 1;
+- mmr_t reserved_2 : 2;
+- mmr_t write : 1;
+- mmr_t reserved_1 : 2;
+- mmr_t src : 14;
+- mmr_t cmd : 8;
+- mmr_t addr : 33;
+- mmr_t reserved_0 : 3;
+- } sh_misc_err_hdr_lower_s;
+-} sh_misc_err_hdr_lower_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MISC_ERR_HDR_UPPER" */
+ /* Error header capture packet and protocol errors */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_misc_err_hdr_upper_u {
+ mmr_t sh_misc_err_hdr_upper_regval;
+ struct {
+@@ -21924,31 +11835,12 @@
+ mmr_t reserved_1 : 35;
+ } sh_misc_err_hdr_upper_s;
+ } sh_misc_err_hdr_upper_u_t;
+-#else
+-typedef union sh_misc_err_hdr_upper_u {
+- mmr_t sh_misc_err_hdr_upper_regval;
+- struct {
+- mmr_t reserved_1 : 35;
+- mmr_t echo : 9;
+- mmr_t reserved_0 : 12;
+- mmr_t xn_pkt_size : 1;
+- mmr_t pi_pkt_size : 1;
+- mmr_t dir_acc : 1;
+- mmr_t rmw_cor : 1;
+- mmr_t rmw_uc : 1;
+- mmr_t nonexist_addr : 1;
+- mmr_t illegal_cmd : 1;
+- mmr_t dir_protocol : 1;
+- } sh_misc_err_hdr_upper_s;
+-} sh_misc_err_hdr_upper_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_DIR_UC_ERR_HDR_LOWER" */
+ /* Header capture register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_dir_uc_err_hdr_lower_u {
+ mmr_t sh_dir_uc_err_hdr_lower_regval;
+ struct {
+@@ -21962,28 +11854,12 @@
+ mmr_t valid : 1;
+ } sh_dir_uc_err_hdr_lower_s;
+ } sh_dir_uc_err_hdr_lower_u_t;
+-#else
+-typedef union sh_dir_uc_err_hdr_lower_u {
+- mmr_t sh_dir_uc_err_hdr_lower_regval;
+- struct {
+- mmr_t valid : 1;
+- mmr_t reserved_2 : 2;
+- mmr_t write : 1;
+- mmr_t reserved_1 : 2;
+- mmr_t src : 14;
+- mmr_t cmd : 8;
+- mmr_t addr : 33;
+- mmr_t reserved_0 : 3;
+- } sh_dir_uc_err_hdr_lower_s;
+-} sh_dir_uc_err_hdr_lower_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_DIR_UC_ERR_HDR_UPPER" */
+ /* Error header capture packet and protocol errors */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_dir_uc_err_hdr_upper_u {
+ mmr_t sh_dir_uc_err_hdr_upper_regval;
+ struct {
+@@ -21994,25 +11870,12 @@
+ mmr_t reserved_2 : 35;
+ } sh_dir_uc_err_hdr_upper_s;
+ } sh_dir_uc_err_hdr_upper_u_t;
+-#else
+-typedef union sh_dir_uc_err_hdr_upper_u {
+- mmr_t sh_dir_uc_err_hdr_upper_regval;
+- struct {
+- mmr_t reserved_2 : 35;
+- mmr_t echo : 9;
+- mmr_t reserved_1 : 16;
+- mmr_t dir_uc : 1;
+- mmr_t reserved_0 : 3;
+- } sh_dir_uc_err_hdr_upper_s;
+-} sh_dir_uc_err_hdr_upper_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_DIR_COR_ERR_HDR_LOWER" */
+ /* Header capture register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_dir_cor_err_hdr_lower_u {
+ mmr_t sh_dir_cor_err_hdr_lower_regval;
+ struct {
+@@ -22026,28 +11889,12 @@
+ mmr_t valid : 1;
+ } sh_dir_cor_err_hdr_lower_s;
+ } sh_dir_cor_err_hdr_lower_u_t;
+-#else
+-typedef union sh_dir_cor_err_hdr_lower_u {
+- mmr_t sh_dir_cor_err_hdr_lower_regval;
+- struct {
+- mmr_t valid : 1;
+- mmr_t reserved_2 : 2;
+- mmr_t write : 1;
+- mmr_t reserved_1 : 2;
+- mmr_t src : 14;
+- mmr_t cmd : 8;
+- mmr_t addr : 33;
+- mmr_t reserved_0 : 3;
+- } sh_dir_cor_err_hdr_lower_s;
+-} sh_dir_cor_err_hdr_lower_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_DIR_COR_ERR_HDR_UPPER" */
+ /* Error header capture packet and protocol errors */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_dir_cor_err_hdr_upper_u {
+ mmr_t sh_dir_cor_err_hdr_upper_regval;
+ struct {
+@@ -22058,25 +11905,12 @@
+ mmr_t reserved_2 : 35;
+ } sh_dir_cor_err_hdr_upper_s;
+ } sh_dir_cor_err_hdr_upper_u_t;
+-#else
+-typedef union sh_dir_cor_err_hdr_upper_u {
+- mmr_t sh_dir_cor_err_hdr_upper_regval;
+- struct {
+- mmr_t reserved_2 : 35;
+- mmr_t echo : 9;
+- mmr_t reserved_1 : 11;
+- mmr_t dir_cor : 1;
+- mmr_t reserved_0 : 8;
+- } sh_dir_cor_err_hdr_upper_s;
+-} sh_dir_cor_err_hdr_upper_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MEM_ERROR_SUMMARY" */
+ /* Memory error flags */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_mem_error_summary_u {
+ mmr_t sh_mem_error_summary_regval;
+ struct {
+@@ -22118,56 +11952,12 @@
+ mmr_t reserved_5 : 29;
+ } sh_mem_error_summary_s;
+ } sh_mem_error_summary_u_t;
+-#else
+-typedef union sh_mem_error_summary_u {
+- mmr_t sh_mem_error_summary_regval;
+- struct {
+- mmr_t reserved_5 : 29;
+- mmr_t xn_pkt_size : 1;
+- mmr_t pi_pkt_size : 1;
+- mmr_t red_black_err_timeout : 1;
+- mmr_t xn_request_overflow : 1;
+- mmr_t pi_request_overflow : 1;
+- mmr_t xn_reply_overflow : 1;
+- mmr_t pi_reply_overflow : 1;
+- mmr_t reserved_4 : 1;
+- mmr_t dqrs_int_hw : 1;
+- mmr_t dqrs_int_cor : 1;
+- mmr_t dqrs_int_uc : 1;
+- mmr_t reserved_3 : 1;
+- mmr_t dqrp_int_hw : 1;
+- mmr_t dqrp_int_cor : 1;
+- mmr_t dqrp_int_uc : 1;
+- mmr_t reserved_2 : 1;
+- mmr_t dqls_int_hw : 1;
+- mmr_t dqls_int_cor : 1;
+- mmr_t dqls_int_uc : 1;
+- mmr_t reserved_1 : 1;
+- mmr_t dqlp_int_hw : 1;
+- mmr_t dqlp_int_cor : 1;
+- mmr_t dqlp_int_uc : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t dir_acc : 1;
+- mmr_t acy_int_hw : 1;
+- mmr_t acx_int_hw : 1;
+- mmr_t dqrp_dir_cor : 1;
+- mmr_t dqrp_dir_uc : 1;
+- mmr_t dqlp_dir_cor : 1;
+- mmr_t dqlp_dir_uc : 1;
+- mmr_t dqrp_dir_perr : 1;
+- mmr_t dqlp_dir_perr : 1;
+- mmr_t nonexist_addr : 1;
+- mmr_t illegal_cmd : 1;
+- } sh_mem_error_summary_s;
+-} sh_mem_error_summary_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MEM_ERROR_OVERFLOW" */
+ /* Memory error flags */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_mem_error_overflow_u {
+ mmr_t sh_mem_error_overflow_regval;
+ struct {
+@@ -22209,56 +11999,12 @@
+ mmr_t reserved_5 : 29;
+ } sh_mem_error_overflow_s;
+ } sh_mem_error_overflow_u_t;
+-#else
+-typedef union sh_mem_error_overflow_u {
+- mmr_t sh_mem_error_overflow_regval;
+- struct {
+- mmr_t reserved_5 : 29;
+- mmr_t xn_pkt_size : 1;
+- mmr_t pi_pkt_size : 1;
+- mmr_t red_black_err_timeout : 1;
+- mmr_t xn_request_overflow : 1;
+- mmr_t pi_request_overflow : 1;
+- mmr_t xn_reply_overflow : 1;
+- mmr_t pi_reply_overflow : 1;
+- mmr_t reserved_4 : 1;
+- mmr_t dqrs_int_hw : 1;
+- mmr_t dqrs_int_cor : 1;
+- mmr_t dqrs_int_uc : 1;
+- mmr_t reserved_3 : 1;
+- mmr_t dqrp_int_hw : 1;
+- mmr_t dqrp_int_cor : 1;
+- mmr_t dqrp_int_uc : 1;
+- mmr_t reserved_2 : 1;
+- mmr_t dqls_int_hw : 1;
+- mmr_t dqls_int_cor : 1;
+- mmr_t dqls_int_uc : 1;
+- mmr_t reserved_1 : 1;
+- mmr_t dqlp_int_hw : 1;
+- mmr_t dqlp_int_cor : 1;
+- mmr_t dqlp_int_uc : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t dir_acc : 1;
+- mmr_t acy_int_hw : 1;
+- mmr_t acx_int_hw : 1;
+- mmr_t dqrp_dir_cor : 1;
+- mmr_t dqrp_dir_uc : 1;
+- mmr_t dqlp_dir_cor : 1;
+- mmr_t dqlp_dir_uc : 1;
+- mmr_t dqrp_dir_perr : 1;
+- mmr_t dqlp_dir_perr : 1;
+- mmr_t nonexist_addr : 1;
+- mmr_t illegal_cmd : 1;
+- } sh_mem_error_overflow_s;
+-} sh_mem_error_overflow_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MEM_ERROR_MASK" */
+ /* Memory error flags */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_mem_error_mask_u {
+ mmr_t sh_mem_error_mask_regval;
+ struct {
+@@ -22283,73 +12029,29 @@
+ mmr_t dqls_int_hw : 1;
+ mmr_t reserved_2 : 1;
+ mmr_t dqrp_int_uc : 1;
+- mmr_t dqrp_int_cor : 1;
+- mmr_t dqrp_int_hw : 1;
+- mmr_t reserved_3 : 1;
+- mmr_t dqrs_int_uc : 1;
+- mmr_t dqrs_int_cor : 1;
+- mmr_t dqrs_int_hw : 1;
+- mmr_t reserved_4 : 1;
+- mmr_t pi_reply_overflow : 1;
+- mmr_t xn_reply_overflow : 1;
+- mmr_t pi_request_overflow : 1;
+- mmr_t xn_request_overflow : 1;
+- mmr_t red_black_err_timeout : 1;
+- mmr_t pi_pkt_size : 1;
+- mmr_t xn_pkt_size : 1;
+- mmr_t reserved_5 : 29;
+- } sh_mem_error_mask_s;
+-} sh_mem_error_mask_u_t;
+-#else
+-typedef union sh_mem_error_mask_u {
+- mmr_t sh_mem_error_mask_regval;
+- struct {
+- mmr_t reserved_5 : 29;
+- mmr_t xn_pkt_size : 1;
+- mmr_t pi_pkt_size : 1;
+- mmr_t red_black_err_timeout : 1;
+- mmr_t xn_request_overflow : 1;
+- mmr_t pi_request_overflow : 1;
+- mmr_t xn_reply_overflow : 1;
+- mmr_t pi_reply_overflow : 1;
+- mmr_t reserved_4 : 1;
+- mmr_t dqrs_int_hw : 1;
+- mmr_t dqrs_int_cor : 1;
+- mmr_t dqrs_int_uc : 1;
+- mmr_t reserved_3 : 1;
+- mmr_t dqrp_int_hw : 1;
+- mmr_t dqrp_int_cor : 1;
+- mmr_t dqrp_int_uc : 1;
+- mmr_t reserved_2 : 1;
+- mmr_t dqls_int_hw : 1;
+- mmr_t dqls_int_cor : 1;
+- mmr_t dqls_int_uc : 1;
+- mmr_t reserved_1 : 1;
+- mmr_t dqlp_int_hw : 1;
+- mmr_t dqlp_int_cor : 1;
+- mmr_t dqlp_int_uc : 1;
+- mmr_t reserved_0 : 1;
+- mmr_t dir_acc : 1;
+- mmr_t acy_int_hw : 1;
+- mmr_t acx_int_hw : 1;
+- mmr_t dqrp_dir_cor : 1;
+- mmr_t dqrp_dir_uc : 1;
+- mmr_t dqlp_dir_cor : 1;
+- mmr_t dqlp_dir_uc : 1;
+- mmr_t dqrp_dir_perr : 1;
+- mmr_t dqlp_dir_perr : 1;
+- mmr_t nonexist_addr : 1;
+- mmr_t illegal_cmd : 1;
++ mmr_t dqrp_int_cor : 1;
++ mmr_t dqrp_int_hw : 1;
++ mmr_t reserved_3 : 1;
++ mmr_t dqrs_int_uc : 1;
++ mmr_t dqrs_int_cor : 1;
++ mmr_t dqrs_int_hw : 1;
++ mmr_t reserved_4 : 1;
++ mmr_t pi_reply_overflow : 1;
++ mmr_t xn_reply_overflow : 1;
++ mmr_t pi_request_overflow : 1;
++ mmr_t xn_request_overflow : 1;
++ mmr_t red_black_err_timeout : 1;
++ mmr_t pi_pkt_size : 1;
++ mmr_t xn_pkt_size : 1;
++ mmr_t reserved_5 : 29;
+ } sh_mem_error_mask_s;
+ } sh_mem_error_mask_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_X_DIMM_CFG" */
+ /* AC Mem Config Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_dimm_cfg_u {
+ mmr_t sh_x_dimm_cfg_regval;
+ struct {
+@@ -22377,42 +12079,12 @@
+ mmr_t reserved_4 : 28;
+ } sh_x_dimm_cfg_s;
+ } sh_x_dimm_cfg_u_t;
+-#else
+-typedef union sh_x_dimm_cfg_u {
+- mmr_t sh_x_dimm_cfg_regval;
+- struct {
+- mmr_t reserved_4 : 28;
+- mmr_t freq : 4;
+- mmr_t reserved_3 : 1;
+- mmr_t dimm3_cs : 2;
+- mmr_t dimm3_rev : 1;
+- mmr_t dimm3_2bk : 1;
+- mmr_t dimm3_size : 3;
+- mmr_t reserved_2 : 1;
+- mmr_t dimm2_cs : 2;
+- mmr_t dimm2_rev : 1;
+- mmr_t dimm2_2bk : 1;
+- mmr_t dimm2_size : 3;
+- mmr_t reserved_1 : 1;
+- mmr_t dimm1_cs : 2;
+- mmr_t dimm1_rev : 1;
+- mmr_t dimm1_2bk : 1;
+- mmr_t dimm1_size : 3;
+- mmr_t reserved_0 : 1;
+- mmr_t dimm0_cs : 2;
+- mmr_t dimm0_rev : 1;
+- mmr_t dimm0_2bk : 1;
+- mmr_t dimm0_size : 3;
+- } sh_x_dimm_cfg_s;
+-} sh_x_dimm_cfg_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_Y_DIMM_CFG" */
+ /* AC Mem Config Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_dimm_cfg_u {
+ mmr_t sh_y_dimm_cfg_regval;
+ struct {
+@@ -22440,42 +12112,12 @@
+ mmr_t reserved_4 : 28;
+ } sh_y_dimm_cfg_s;
+ } sh_y_dimm_cfg_u_t;
+-#else
+-typedef union sh_y_dimm_cfg_u {
+- mmr_t sh_y_dimm_cfg_regval;
+- struct {
+- mmr_t reserved_4 : 28;
+- mmr_t freq : 4;
+- mmr_t reserved_3 : 1;
+- mmr_t dimm3_cs : 2;
+- mmr_t dimm3_rev : 1;
+- mmr_t dimm3_2bk : 1;
+- mmr_t dimm3_size : 3;
+- mmr_t reserved_2 : 1;
+- mmr_t dimm2_cs : 2;
+- mmr_t dimm2_rev : 1;
+- mmr_t dimm2_2bk : 1;
+- mmr_t dimm2_size : 3;
+- mmr_t reserved_1 : 1;
+- mmr_t dimm1_cs : 2;
+- mmr_t dimm1_rev : 1;
+- mmr_t dimm1_2bk : 1;
+- mmr_t dimm1_size : 3;
+- mmr_t reserved_0 : 1;
+- mmr_t dimm0_cs : 2;
+- mmr_t dimm0_rev : 1;
+- mmr_t dimm0_2bk : 1;
+- mmr_t dimm0_size : 3;
+- } sh_y_dimm_cfg_s;
+-} sh_y_dimm_cfg_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_JNR_DIMM_CFG" */
+ /* AC Mem Config Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_jnr_dimm_cfg_u {
+ mmr_t sh_jnr_dimm_cfg_regval;
+ struct {
+@@ -22503,42 +12145,12 @@
+ mmr_t reserved_4 : 28;
+ } sh_jnr_dimm_cfg_s;
+ } sh_jnr_dimm_cfg_u_t;
+-#else
+-typedef union sh_jnr_dimm_cfg_u {
+- mmr_t sh_jnr_dimm_cfg_regval;
+- struct {
+- mmr_t reserved_4 : 28;
+- mmr_t freq : 4;
+- mmr_t reserved_3 : 1;
+- mmr_t dimm3_cs : 2;
+- mmr_t dimm3_rev : 1;
+- mmr_t dimm3_2bk : 1;
+- mmr_t dimm3_size : 3;
+- mmr_t reserved_2 : 1;
+- mmr_t dimm2_cs : 2;
+- mmr_t dimm2_rev : 1;
+- mmr_t dimm2_2bk : 1;
+- mmr_t dimm2_size : 3;
+- mmr_t reserved_1 : 1;
+- mmr_t dimm1_cs : 2;
+- mmr_t dimm1_rev : 1;
+- mmr_t dimm1_2bk : 1;
+- mmr_t dimm1_size : 3;
+- mmr_t reserved_0 : 1;
+- mmr_t dimm0_cs : 2;
+- mmr_t dimm0_rev : 1;
+- mmr_t dimm0_2bk : 1;
+- mmr_t dimm0_size : 3;
+- } sh_jnr_dimm_cfg_s;
+-} sh_jnr_dimm_cfg_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_X_PHASE_CFG" */
+ /* AC Phase Config Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_phase_cfg_u {
+ mmr_t sh_x_phase_cfg_regval;
+ struct {
+@@ -22560,36 +12172,12 @@
+ mmr_t reserved_0 : 1;
+ } sh_x_phase_cfg_s;
+ } sh_x_phase_cfg_u_t;
+-#else
+-typedef union sh_x_phase_cfg_u {
+- mmr_t sh_x_phase_cfg_regval;
+- struct {
+- mmr_t reserved_0 : 1;
+- mmr_t dq_sel_a : 4;
+- mmr_t sel_a : 4;
+- mmr_t phe_bubble : 3;
+- mmr_t phd_bubble : 3;
+- mmr_t phc_bubble : 3;
+- mmr_t phb_bubble : 3;
+- mmr_t pha_bubble : 3;
+- mmr_t bubble_en : 5;
+- mmr_t add_cp : 5;
+- mmr_t hold_req : 5;
+- mmr_t hold : 5;
+- mmr_t dq_ld_b : 5;
+- mmr_t dq_ld_a : 5;
+- mmr_t ld_b : 5;
+- mmr_t ld_a : 5;
+- } sh_x_phase_cfg_s;
+-} sh_x_phase_cfg_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_X_CFG" */
+ /* AC Config Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_cfg_u {
+ mmr_t sh_x_cfg_regval;
+ struct {
+@@ -22609,34 +12197,12 @@
+ mmr_t clr_dir_cache : 1;
+ } sh_x_cfg_s;
+ } sh_x_cfg_u_t;
+-#else
+-typedef union sh_x_cfg_u {
+- mmr_t sh_x_cfg_regval;
+- struct {
+- mmr_t clr_dir_cache : 1;
+- mmr_t inv_cas_addr : 1;
+- mmr_t req_cntr_val : 6;
+- mmr_t req_cntr_dis : 1;
+- mmr_t trcd4_en : 1;
+- mmr_t trcd2_en : 1;
+- mmr_t sso_wt_en : 1;
+- mmr_t wt_bb_clr : 4;
+- mmr_t dc_bb_clr : 4;
+- mmr_t da_bb_clr : 4;
+- mmr_t ta_dlys : 32;
+- mmr_t dir_counter_init : 6;
+- mmr_t dirc_random_replacement : 1;
+- mmr_t mode_serial : 1;
+- } sh_x_cfg_s;
+-} sh_x_cfg_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_X_DQCT_CFG" */
+ /* AC Config Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_dqct_cfg_u {
+ mmr_t sh_x_dqct_cfg_regval;
+ struct {
+@@ -22649,27 +12215,12 @@
+ mmr_t reserved_0 : 40;
+ } sh_x_dqct_cfg_s;
+ } sh_x_dqct_cfg_u_t;
+-#else
+-typedef union sh_x_dqct_cfg_u {
+- mmr_t sh_x_dqct_cfg_regval;
+- struct {
+- mmr_t reserved_0 : 40;
+- mmr_t mdir_rd_sel : 4;
+- mmr_t dir_rd_sel : 4;
+- mmr_t dta_wt_sel : 4;
+- mmr_t dta_rd_sel : 4;
+- mmr_t wt_sel : 4;
+- mmr_t rd_sel : 4;
+- } sh_x_dqct_cfg_s;
+-} sh_x_dqct_cfg_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_X_REFRESH_CONTROL" */
+ /* Refresh Control Register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_refresh_control_u {
+ mmr_t sh_x_refresh_control_regval;
+ struct {
+@@ -22681,26 +12232,12 @@
+ mmr_t reserved_0 : 36;
+ } sh_x_refresh_control_s;
+ } sh_x_refresh_control_u_t;
+-#else
+-typedef union sh_x_refresh_control_u {
+- mmr_t sh_x_refresh_control_regval;
+- struct {
+- mmr_t reserved_0 : 36;
+- mmr_t half_rate : 4;
+- mmr_t interleave : 1;
+- mmr_t hold : 6;
+- mmr_t interval : 9;
+- mmr_t enable : 8;
+- } sh_x_refresh_control_s;
+-} sh_x_refresh_control_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_Y_PHASE_CFG" */
+ /* AC Phase Config Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_phase_cfg_u {
+ mmr_t sh_y_phase_cfg_regval;
+ struct {
+@@ -22722,36 +12259,12 @@
+ mmr_t reserved_0 : 1;
+ } sh_y_phase_cfg_s;
+ } sh_y_phase_cfg_u_t;
+-#else
+-typedef union sh_y_phase_cfg_u {
+- mmr_t sh_y_phase_cfg_regval;
+- struct {
+- mmr_t reserved_0 : 1;
+- mmr_t dq_sel_a : 4;
+- mmr_t sel_a : 4;
+- mmr_t phe_bubble : 3;
+- mmr_t phd_bubble : 3;
+- mmr_t phc_bubble : 3;
+- mmr_t phb_bubble : 3;
+- mmr_t pha_bubble : 3;
+- mmr_t bubble_en : 5;
+- mmr_t add_cp : 5;
+- mmr_t hold_req : 5;
+- mmr_t hold : 5;
+- mmr_t dq_ld_b : 5;
+- mmr_t dq_ld_a : 5;
+- mmr_t ld_b : 5;
+- mmr_t ld_a : 5;
+- } sh_y_phase_cfg_s;
+-} sh_y_phase_cfg_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_Y_CFG" */
+ /* AC Config Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_cfg_u {
+ mmr_t sh_y_cfg_regval;
+ struct {
+@@ -22771,34 +12284,12 @@
+ mmr_t clr_dir_cache : 1;
+ } sh_y_cfg_s;
+ } sh_y_cfg_u_t;
+-#else
+-typedef union sh_y_cfg_u {
+- mmr_t sh_y_cfg_regval;
+- struct {
+- mmr_t clr_dir_cache : 1;
+- mmr_t inv_cas_addr : 1;
+- mmr_t req_cntr_val : 6;
+- mmr_t req_cntr_dis : 1;
+- mmr_t trcd4_en : 1;
+- mmr_t trcd2_en : 1;
+- mmr_t sso_wt_en : 1;
+- mmr_t wt_bb_clr : 4;
+- mmr_t dc_bb_clr : 4;
+- mmr_t da_bb_clr : 4;
+- mmr_t ta_dlys : 32;
+- mmr_t dir_counter_init : 6;
+- mmr_t dirc_random_replacement : 1;
+- mmr_t mode_serial : 1;
+- } sh_y_cfg_s;
+-} sh_y_cfg_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_Y_DQCT_CFG" */
+ /* AC Config Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_dqct_cfg_u {
+ mmr_t sh_y_dqct_cfg_regval;
+ struct {
+@@ -22811,27 +12302,12 @@
+ mmr_t reserved_0 : 40;
+ } sh_y_dqct_cfg_s;
+ } sh_y_dqct_cfg_u_t;
+-#else
+-typedef union sh_y_dqct_cfg_u {
+- mmr_t sh_y_dqct_cfg_regval;
+- struct {
+- mmr_t reserved_0 : 40;
+- mmr_t mdir_rd_sel : 4;
+- mmr_t dir_rd_sel : 4;
+- mmr_t dta_wt_sel : 4;
+- mmr_t dta_rd_sel : 4;
+- mmr_t wt_sel : 4;
+- mmr_t rd_sel : 4;
+- } sh_y_dqct_cfg_s;
+-} sh_y_dqct_cfg_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_Y_REFRESH_CONTROL" */
+ /* Refresh Control Register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_refresh_control_u {
+ mmr_t sh_y_refresh_control_regval;
+ struct {
+@@ -22843,26 +12319,12 @@
+ mmr_t reserved_0 : 36;
+ } sh_y_refresh_control_s;
+ } sh_y_refresh_control_u_t;
+-#else
+-typedef union sh_y_refresh_control_u {
+- mmr_t sh_y_refresh_control_regval;
+- struct {
+- mmr_t reserved_0 : 36;
+- mmr_t half_rate : 4;
+- mmr_t interleave : 1;
+- mmr_t hold : 6;
+- mmr_t interval : 9;
+- mmr_t enable : 8;
+- } sh_y_refresh_control_s;
+-} sh_y_refresh_control_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MEM_RED_BLACK" */
+ /* MD fairness watchdog timers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_mem_red_black_u {
+ mmr_t sh_mem_red_black_regval;
+ struct {
+@@ -22871,22 +12333,11 @@
+ mmr_t reserved_0 : 12;
+ } sh_mem_red_black_s;
+ } sh_mem_red_black_u_t;
+-#else
+-typedef union sh_mem_red_black_u {
+- mmr_t sh_mem_red_black_regval;
+- struct {
+- mmr_t reserved_0 : 12;
+- mmr_t err_time : 36;
+- mmr_t time : 16;
+- } sh_mem_red_black_s;
+-} sh_mem_red_black_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MISC_MEM_CFG" */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_misc_mem_cfg_u {
+ mmr_t sh_misc_mem_cfg_regval;
+ struct {
+@@ -22903,43 +12354,18 @@
+ mmr_t reserved_2 : 3;
+ mmr_t disabled_write_tnums : 5;
+ mmr_t reserved_3 : 3;
+- mmr_t disabled_victims : 6;
+- mmr_t reserved_4 : 2;
+- mmr_t alternate_xn_rp_plane : 1;
+- mmr_t reserved_5 : 11;
+- } sh_misc_mem_cfg_s;
+-} sh_misc_mem_cfg_u_t;
+-#else
+-typedef union sh_misc_mem_cfg_u {
+- mmr_t sh_misc_mem_cfg_regval;
+- struct {
+- mmr_t reserved_5 : 11;
+- mmr_t alternate_xn_rp_plane : 1;
+- mmr_t reserved_4 : 2;
+- mmr_t disabled_victims : 6;
+- mmr_t reserved_3 : 3;
+- mmr_t disabled_write_tnums : 5;
+- mmr_t reserved_2 : 3;
+- mmr_t disabled_read_tnums : 5;
+- mmr_t throttle_cnt : 8;
+- mmr_t reserved_1 : 2;
+- mmr_t low_victim_buffer_threshold : 6;
+- mmr_t reserved_0 : 2;
+- mmr_t low_write_buffer_threshold : 6;
+- mmr_t xn_rd_same_as_pi : 1;
+- mmr_t jnr_bypass_enable : 1;
+- mmr_t spec_header_enable : 1;
+- mmr_t express_header_enable : 1;
++ mmr_t disabled_victims : 6;
++ mmr_t reserved_4 : 2;
++ mmr_t alternate_xn_rp_plane : 1;
++ mmr_t reserved_5 : 11;
+ } sh_misc_mem_cfg_s;
+ } sh_misc_mem_cfg_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PIO_RQ_CRD_CTL" */
+ /* pio_rq Credit Circulation Control */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pio_rq_crd_ctl_u {
+ mmr_t sh_pio_rq_crd_ctl_regval;
+ struct {
+@@ -22947,22 +12373,12 @@
+ mmr_t reserved_0 : 58;
+ } sh_pio_rq_crd_ctl_s;
+ } sh_pio_rq_crd_ctl_u_t;
+-#else
+-typedef union sh_pio_rq_crd_ctl_u {
+- mmr_t sh_pio_rq_crd_ctl_regval;
+- struct {
+- mmr_t reserved_0 : 58;
+- mmr_t depth : 6;
+- } sh_pio_rq_crd_ctl_s;
+-} sh_pio_rq_crd_ctl_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_MD_RQ_CRD_CTL" */
+ /* pi_md_rq Credit Circulation Control */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_md_rq_crd_ctl_u {
+ mmr_t sh_pi_md_rq_crd_ctl_regval;
+ struct {
+@@ -22970,22 +12386,12 @@
+ mmr_t reserved_0 : 58;
+ } sh_pi_md_rq_crd_ctl_s;
+ } sh_pi_md_rq_crd_ctl_u_t;
+-#else
+-typedef union sh_pi_md_rq_crd_ctl_u {
+- mmr_t sh_pi_md_rq_crd_ctl_regval;
+- struct {
+- mmr_t reserved_0 : 58;
+- mmr_t depth : 6;
+- } sh_pi_md_rq_crd_ctl_s;
+-} sh_pi_md_rq_crd_ctl_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_PI_MD_RP_CRD_CTL" */
+ /* pi_md_rp Credit Circulation Control */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_md_rp_crd_ctl_u {
+ mmr_t sh_pi_md_rp_crd_ctl_regval;
+ struct {
+@@ -22993,22 +12399,12 @@
+ mmr_t reserved_0 : 58;
+ } sh_pi_md_rp_crd_ctl_s;
+ } sh_pi_md_rp_crd_ctl_u_t;
+-#else
+-typedef union sh_pi_md_rp_crd_ctl_u {
+- mmr_t sh_pi_md_rp_crd_ctl_regval;
+- struct {
+- mmr_t reserved_0 : 58;
+- mmr_t depth : 6;
+- } sh_pi_md_rp_crd_ctl_s;
+-} sh_pi_md_rp_crd_ctl_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_MD_RQ_CRD_CTL" */
+ /* xn_md_rq Credit Circulation Control */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_md_rq_crd_ctl_u {
+ mmr_t sh_xn_md_rq_crd_ctl_regval;
+ struct {
+@@ -23016,22 +12412,12 @@
+ mmr_t reserved_0 : 58;
+ } sh_xn_md_rq_crd_ctl_s;
+ } sh_xn_md_rq_crd_ctl_u_t;
+-#else
+-typedef union sh_xn_md_rq_crd_ctl_u {
+- mmr_t sh_xn_md_rq_crd_ctl_regval;
+- struct {
+- mmr_t reserved_0 : 58;
+- mmr_t depth : 6;
+- } sh_xn_md_rq_crd_ctl_s;
+-} sh_xn_md_rq_crd_ctl_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_XN_MD_RP_CRD_CTL" */
+ /* xn_md_rp Credit Circulation Control */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_md_rp_crd_ctl_u {
+ mmr_t sh_xn_md_rp_crd_ctl_regval;
+ struct {
+@@ -23039,22 +12425,12 @@
+ mmr_t reserved_0 : 58;
+ } sh_xn_md_rp_crd_ctl_s;
+ } sh_xn_md_rp_crd_ctl_u_t;
+-#else
+-typedef union sh_xn_md_rp_crd_ctl_u {
+- mmr_t sh_xn_md_rp_crd_ctl_regval;
+- struct {
+- mmr_t reserved_0 : 58;
+- mmr_t depth : 6;
+- } sh_xn_md_rp_crd_ctl_s;
+-} sh_xn_md_rp_crd_ctl_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_X_TAG0" */
+ /* AC tag Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_tag0_u {
+ mmr_t sh_x_tag0_regval;
+ struct {
+@@ -23062,22 +12438,12 @@
+ mmr_t reserved_0 : 44;
+ } sh_x_tag0_s;
+ } sh_x_tag0_u_t;
+-#else
+-typedef union sh_x_tag0_u {
+- mmr_t sh_x_tag0_regval;
+- struct {
+- mmr_t reserved_0 : 44;
+- mmr_t tag : 20;
+- } sh_x_tag0_s;
+-} sh_x_tag0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_X_TAG1" */
+ /* AC tag Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_tag1_u {
+ mmr_t sh_x_tag1_regval;
+ struct {
+@@ -23085,22 +12451,12 @@
+ mmr_t reserved_0 : 44;
+ } sh_x_tag1_s;
+ } sh_x_tag1_u_t;
+-#else
+-typedef union sh_x_tag1_u {
+- mmr_t sh_x_tag1_regval;
+- struct {
+- mmr_t reserved_0 : 44;
+- mmr_t tag : 20;
+- } sh_x_tag1_s;
+-} sh_x_tag1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_X_TAG2" */
+ /* AC tag Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_tag2_u {
+ mmr_t sh_x_tag2_regval;
+ struct {
+@@ -23108,22 +12464,12 @@
+ mmr_t reserved_0 : 44;
+ } sh_x_tag2_s;
+ } sh_x_tag2_u_t;
+-#else
+-typedef union sh_x_tag2_u {
+- mmr_t sh_x_tag2_regval;
+- struct {
+- mmr_t reserved_0 : 44;
+- mmr_t tag : 20;
+- } sh_x_tag2_s;
+-} sh_x_tag2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_X_TAG3" */
+ /* AC tag Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_tag3_u {
+ mmr_t sh_x_tag3_regval;
+ struct {
+@@ -23131,22 +12477,12 @@
+ mmr_t reserved_0 : 44;
+ } sh_x_tag3_s;
+ } sh_x_tag3_u_t;
+-#else
+-typedef union sh_x_tag3_u {
+- mmr_t sh_x_tag3_regval;
+- struct {
+- mmr_t reserved_0 : 44;
+- mmr_t tag : 20;
+- } sh_x_tag3_s;
+-} sh_x_tag3_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_X_TAG4" */
+ /* AC tag Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_tag4_u {
+ mmr_t sh_x_tag4_regval;
+ struct {
+@@ -23154,22 +12490,12 @@
+ mmr_t reserved_0 : 44;
+ } sh_x_tag4_s;
+ } sh_x_tag4_u_t;
+-#else
+-typedef union sh_x_tag4_u {
+- mmr_t sh_x_tag4_regval;
+- struct {
+- mmr_t reserved_0 : 44;
+- mmr_t tag : 20;
+- } sh_x_tag4_s;
+-} sh_x_tag4_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_X_TAG5" */
+ /* AC tag Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_tag5_u {
+ mmr_t sh_x_tag5_regval;
+ struct {
+@@ -23177,22 +12503,12 @@
+ mmr_t reserved_0 : 44;
+ } sh_x_tag5_s;
+ } sh_x_tag5_u_t;
+-#else
+-typedef union sh_x_tag5_u {
+- mmr_t sh_x_tag5_regval;
+- struct {
+- mmr_t reserved_0 : 44;
+- mmr_t tag : 20;
+- } sh_x_tag5_s;
+-} sh_x_tag5_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_X_TAG6" */
+ /* AC tag Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_tag6_u {
+ mmr_t sh_x_tag6_regval;
+ struct {
+@@ -23200,22 +12516,12 @@
+ mmr_t reserved_0 : 44;
+ } sh_x_tag6_s;
+ } sh_x_tag6_u_t;
+-#else
+-typedef union sh_x_tag6_u {
+- mmr_t sh_x_tag6_regval;
+- struct {
+- mmr_t reserved_0 : 44;
+- mmr_t tag : 20;
+- } sh_x_tag6_s;
+-} sh_x_tag6_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_X_TAG7" */
+ /* AC tag Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_tag7_u {
+ mmr_t sh_x_tag7_regval;
+ struct {
+@@ -23223,22 +12529,12 @@
+ mmr_t reserved_0 : 44;
+ } sh_x_tag7_s;
+ } sh_x_tag7_u_t;
+-#else
+-typedef union sh_x_tag7_u {
+- mmr_t sh_x_tag7_regval;
+- struct {
+- mmr_t reserved_0 : 44;
+- mmr_t tag : 20;
+- } sh_x_tag7_s;
+-} sh_x_tag7_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_Y_TAG0" */
+ /* AC tag Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_tag0_u {
+ mmr_t sh_y_tag0_regval;
+ struct {
+@@ -23246,22 +12542,12 @@
+ mmr_t reserved_0 : 44;
+ } sh_y_tag0_s;
+ } sh_y_tag0_u_t;
+-#else
+-typedef union sh_y_tag0_u {
+- mmr_t sh_y_tag0_regval;
+- struct {
+- mmr_t reserved_0 : 44;
+- mmr_t tag : 20;
+- } sh_y_tag0_s;
+-} sh_y_tag0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_Y_TAG1" */
+ /* AC tag Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_tag1_u {
+ mmr_t sh_y_tag1_regval;
+ struct {
+@@ -23269,22 +12555,12 @@
+ mmr_t reserved_0 : 44;
+ } sh_y_tag1_s;
+ } sh_y_tag1_u_t;
+-#else
+-typedef union sh_y_tag1_u {
+- mmr_t sh_y_tag1_regval;
+- struct {
+- mmr_t reserved_0 : 44;
+- mmr_t tag : 20;
+- } sh_y_tag1_s;
+-} sh_y_tag1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_Y_TAG2" */
+ /* AC tag Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_tag2_u {
+ mmr_t sh_y_tag2_regval;
+ struct {
+@@ -23292,22 +12568,12 @@
+ mmr_t reserved_0 : 44;
+ } sh_y_tag2_s;
+ } sh_y_tag2_u_t;
+-#else
+-typedef union sh_y_tag2_u {
+- mmr_t sh_y_tag2_regval;
+- struct {
+- mmr_t reserved_0 : 44;
+- mmr_t tag : 20;
+- } sh_y_tag2_s;
+-} sh_y_tag2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_Y_TAG3" */
+ /* AC tag Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_tag3_u {
+ mmr_t sh_y_tag3_regval;
+ struct {
+@@ -23315,22 +12581,12 @@
+ mmr_t reserved_0 : 44;
+ } sh_y_tag3_s;
+ } sh_y_tag3_u_t;
+-#else
+-typedef union sh_y_tag3_u {
+- mmr_t sh_y_tag3_regval;
+- struct {
+- mmr_t reserved_0 : 44;
+- mmr_t tag : 20;
+- } sh_y_tag3_s;
+-} sh_y_tag3_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_Y_TAG4" */
+ /* AC tag Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_tag4_u {
+ mmr_t sh_y_tag4_regval;
+ struct {
+@@ -23338,22 +12594,12 @@
+ mmr_t reserved_0 : 44;
+ } sh_y_tag4_s;
+ } sh_y_tag4_u_t;
+-#else
+-typedef union sh_y_tag4_u {
+- mmr_t sh_y_tag4_regval;
+- struct {
+- mmr_t reserved_0 : 44;
+- mmr_t tag : 20;
+- } sh_y_tag4_s;
+-} sh_y_tag4_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_Y_TAG5" */
+ /* AC tag Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_tag5_u {
+ mmr_t sh_y_tag5_regval;
+ struct {
+@@ -23361,22 +12607,12 @@
+ mmr_t reserved_0 : 44;
+ } sh_y_tag5_s;
+ } sh_y_tag5_u_t;
+-#else
+-typedef union sh_y_tag5_u {
+- mmr_t sh_y_tag5_regval;
+- struct {
+- mmr_t reserved_0 : 44;
+- mmr_t tag : 20;
+- } sh_y_tag5_s;
+-} sh_y_tag5_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_Y_TAG6" */
+ /* AC tag Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_tag6_u {
+ mmr_t sh_y_tag6_regval;
+ struct {
+@@ -23384,22 +12620,12 @@
+ mmr_t reserved_0 : 44;
+ } sh_y_tag6_s;
+ } sh_y_tag6_u_t;
+-#else
+-typedef union sh_y_tag6_u {
+- mmr_t sh_y_tag6_regval;
+- struct {
+- mmr_t reserved_0 : 44;
+- mmr_t tag : 20;
+- } sh_y_tag6_s;
+-} sh_y_tag6_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_Y_TAG7" */
+ /* AC tag Registers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_tag7_u {
+ mmr_t sh_y_tag7_regval;
+ struct {
+@@ -23407,22 +12633,12 @@
+ mmr_t reserved_0 : 44;
+ } sh_y_tag7_s;
+ } sh_y_tag7_u_t;
+-#else
+-typedef union sh_y_tag7_u {
+- mmr_t sh_y_tag7_regval;
+- struct {
+- mmr_t reserved_0 : 44;
+- mmr_t tag : 20;
+- } sh_y_tag7_s;
+-} sh_y_tag7_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MMRBIST_BASE" */
+ /* mmr/bist base address */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_mmrbist_base_u {
+ mmr_t sh_mmrbist_base_regval;
+ struct {
+@@ -23431,23 +12647,12 @@
+ mmr_t reserved_1 : 14;
+ } sh_mmrbist_base_s;
+ } sh_mmrbist_base_u_t;
+-#else
+-typedef union sh_mmrbist_base_u {
+- mmr_t sh_mmrbist_base_regval;
+- struct {
+- mmr_t reserved_1 : 14;
+- mmr_t dword_addr : 47;
+- mmr_t reserved_0 : 3;
+- } sh_mmrbist_base_s;
+-} sh_mmrbist_base_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MMRBIST_CTL" */
+ /* Bist base address */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_mmrbist_ctl_u {
+ mmr_t sh_mmrbist_ctl_regval;
+ struct {
+@@ -23463,30 +12668,12 @@
+ mmr_t reserved_3 : 19;
+ } sh_mmrbist_ctl_s;
+ } sh_mmrbist_ctl_u_t;
+-#else
+-typedef union sh_mmrbist_ctl_u {
+- mmr_t sh_mmrbist_ctl_regval;
+- struct {
+- mmr_t reserved_3 : 19;
+- mmr_t reset_state : 1;
+- mmr_t reserved_2 : 1;
+- mmr_t mem_idle : 1;
+- mmr_t fail : 1;
+- mmr_t in_progress : 1;
+- mmr_t reserved_1 : 1;
+- mmr_t cmd : 7;
+- mmr_t reserved_0 : 1;
+- mmr_t block_length : 31;
+- } sh_mmrbist_ctl_s;
+-} sh_mmrbist_ctl_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DBUG_DATA_CFG" */
+ /* configuration for md debug data muxes */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dbug_data_cfg_u {
+ mmr_t sh_md_dbug_data_cfg_regval;
+ struct {
+@@ -23524,52 +12711,12 @@
+ mmr_t reserved_15 : 1;
+ } sh_md_dbug_data_cfg_s;
+ } sh_md_dbug_data_cfg_u_t;
+-#else
+-typedef union sh_md_dbug_data_cfg_u {
+- mmr_t sh_md_dbug_data_cfg_regval;
+- struct {
+- mmr_t reserved_15 : 1;
+- mmr_t nibble7_nibble : 3;
+- mmr_t reserved_14 : 1;
+- mmr_t nibble7_chiplet : 3;
+- mmr_t reserved_13 : 1;
+- mmr_t nibble6_nibble : 3;
+- mmr_t reserved_12 : 1;
+- mmr_t nibble6_chiplet : 3;
+- mmr_t reserved_11 : 1;
+- mmr_t nibble5_nibble : 3;
+- mmr_t reserved_10 : 1;
+- mmr_t nibble5_chiplet : 3;
+- mmr_t reserved_9 : 1;
+- mmr_t nibble4_nibble : 3;
+- mmr_t reserved_8 : 1;
+- mmr_t nibble4_chiplet : 3;
+- mmr_t reserved_7 : 1;
+- mmr_t nibble3_nibble : 3;
+- mmr_t reserved_6 : 1;
+- mmr_t nibble3_chiplet : 3;
+- mmr_t reserved_5 : 1;
+- mmr_t nibble2_nibble : 3;
+- mmr_t reserved_4 : 1;
+- mmr_t nibble2_chiplet : 3;
+- mmr_t reserved_3 : 1;
+- mmr_t nibble1_nibble : 3;
+- mmr_t reserved_2 : 1;
+- mmr_t nibble1_chiplet : 3;
+- mmr_t reserved_1 : 1;
+- mmr_t nibble0_nibble : 3;
+- mmr_t reserved_0 : 1;
+- mmr_t nibble0_chiplet : 3;
+- } sh_md_dbug_data_cfg_s;
+-} sh_md_dbug_data_cfg_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DBUG_TRIGGER_CFG" */
+ /* configuration for md debug triggers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dbug_trigger_cfg_u {
+ mmr_t sh_md_dbug_trigger_cfg_regval;
+ struct {
+@@ -23607,75 +12754,25 @@
+ mmr_t enable : 1;
+ } sh_md_dbug_trigger_cfg_s;
+ } sh_md_dbug_trigger_cfg_u_t;
+-#else
+-typedef union sh_md_dbug_trigger_cfg_u {
+- mmr_t sh_md_dbug_trigger_cfg_regval;
+- struct {
+- mmr_t enable : 1;
+- mmr_t nibble7_nibble : 3;
+- mmr_t reserved_14 : 1;
+- mmr_t nibble7_chiplet : 3;
+- mmr_t reserved_13 : 1;
+- mmr_t nibble6_nibble : 3;
+- mmr_t reserved_12 : 1;
+- mmr_t nibble6_chiplet : 3;
+- mmr_t reserved_11 : 1;
+- mmr_t nibble5_nibble : 3;
+- mmr_t reserved_10 : 1;
+- mmr_t nibble5_chiplet : 3;
+- mmr_t reserved_9 : 1;
+- mmr_t nibble4_nibble : 3;
+- mmr_t reserved_8 : 1;
+- mmr_t nibble4_chiplet : 3;
+- mmr_t reserved_7 : 1;
+- mmr_t nibble3_nibble : 3;
+- mmr_t reserved_6 : 1;
+- mmr_t nibble3_chiplet : 3;
+- mmr_t reserved_5 : 1;
+- mmr_t nibble2_nibble : 3;
+- mmr_t reserved_4 : 1;
+- mmr_t nibble2_chiplet : 3;
+- mmr_t reserved_3 : 1;
+- mmr_t nibble1_nibble : 3;
+- mmr_t reserved_2 : 1;
+- mmr_t nibble1_chiplet : 3;
+- mmr_t reserved_1 : 1;
+- mmr_t nibble0_nibble : 3;
+- mmr_t reserved_0 : 1;
+- mmr_t nibble0_chiplet : 3;
+- } sh_md_dbug_trigger_cfg_s;
+-} sh_md_dbug_trigger_cfg_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DBUG_COMPARE" */
+ /* md debug compare pattern and mask */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dbug_compare_u {
+ mmr_t sh_md_dbug_compare_regval;
+ struct {
+ mmr_t pattern : 32;
+- mmr_t mask : 32;
+- } sh_md_dbug_compare_s;
+-} sh_md_dbug_compare_u_t;
+-#else
+-typedef union sh_md_dbug_compare_u {
+- mmr_t sh_md_dbug_compare_regval;
+- struct {
+- mmr_t mask : 32;
+- mmr_t pattern : 32;
++ mmr_t mask : 32;
+ } sh_md_dbug_compare_s;
+ } sh_md_dbug_compare_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_X_MOD_DBUG_SEL" */
+ /* MD acx debug select */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_mod_dbug_sel_u {
+ mmr_t sh_x_mod_dbug_sel_regval;
+ struct {
+@@ -23689,28 +12786,12 @@
+ mmr_t reserved_0 : 6;
+ } sh_x_mod_dbug_sel_s;
+ } sh_x_mod_dbug_sel_u_t;
+-#else
+-typedef union sh_x_mod_dbug_sel_u {
+- mmr_t sh_x_mod_dbug_sel_regval;
+- struct {
+- mmr_t reserved_0 : 6;
+- mmr_t dqr_sel : 6;
+- mmr_t dql_sel : 6;
+- mmr_t atr_sel : 11;
+- mmr_t atl_sel : 11;
+- mmr_t arb_sel : 8;
+- mmr_t wbq_sel : 8;
+- mmr_t tag_sel : 8;
+- } sh_x_mod_dbug_sel_s;
+-} sh_x_mod_dbug_sel_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_X_DBUG_SEL" */
+ /* MD acx debug select */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_dbug_sel_u {
+ mmr_t sh_x_dbug_sel_regval;
+ struct {
+@@ -23718,22 +12799,12 @@
+ mmr_t reserved_0 : 40;
+ } sh_x_dbug_sel_s;
+ } sh_x_dbug_sel_u_t;
+-#else
+-typedef union sh_x_dbug_sel_u {
+- mmr_t sh_x_dbug_sel_regval;
+- struct {
+- mmr_t reserved_0 : 40;
+- mmr_t dbg_sel : 24;
+- } sh_x_dbug_sel_s;
+-} sh_x_dbug_sel_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_X_LADDR_CMP" */
+ /* MD acx address compare */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_laddr_cmp_u {
+ mmr_t sh_x_laddr_cmp_regval;
+ struct {
+@@ -23743,24 +12814,12 @@
+ mmr_t reserved_1 : 4;
+ } sh_x_laddr_cmp_s;
+ } sh_x_laddr_cmp_u_t;
+-#else
+-typedef union sh_x_laddr_cmp_u {
+- mmr_t sh_x_laddr_cmp_regval;
+- struct {
+- mmr_t reserved_1 : 4;
+- mmr_t mask_val : 28;
+- mmr_t reserved_0 : 4;
+- mmr_t cmp_val : 28;
+- } sh_x_laddr_cmp_s;
+-} sh_x_laddr_cmp_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_X_RADDR_CMP" */
+ /* MD acx address compare */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_raddr_cmp_u {
+ mmr_t sh_x_raddr_cmp_regval;
+ struct {
+@@ -23770,24 +12829,12 @@
+ mmr_t reserved_1 : 4;
+ } sh_x_raddr_cmp_s;
+ } sh_x_raddr_cmp_u_t;
+-#else
+-typedef union sh_x_raddr_cmp_u {
+- mmr_t sh_x_raddr_cmp_regval;
+- struct {
+- mmr_t reserved_1 : 4;
+- mmr_t mask_val : 28;
+- mmr_t reserved_0 : 4;
+- mmr_t cmp_val : 28;
+- } sh_x_raddr_cmp_s;
+-} sh_x_raddr_cmp_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_X_TAG_CMP" */
+ /* MD acx tagmgr compare */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_tag_cmp_u {
+ mmr_t sh_x_tag_cmp_regval;
+ struct {
+@@ -23797,24 +12844,12 @@
+ mmr_t reserved_0 : 9;
+ } sh_x_tag_cmp_s;
+ } sh_x_tag_cmp_u_t;
+-#else
+-typedef union sh_x_tag_cmp_u {
+- mmr_t sh_x_tag_cmp_regval;
+- struct {
+- mmr_t reserved_0 : 9;
+- mmr_t src : 14;
+- mmr_t addr : 33;
+- mmr_t cmd : 8;
+- } sh_x_tag_cmp_s;
+-} sh_x_tag_cmp_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_X_TAG_MASK" */
+ /* MD acx tagmgr mask */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_tag_mask_u {
+ mmr_t sh_x_tag_mask_regval;
+ struct {
+@@ -23824,24 +12859,12 @@
+ mmr_t reserved_0 : 9;
+ } sh_x_tag_mask_s;
+ } sh_x_tag_mask_u_t;
+-#else
+-typedef union sh_x_tag_mask_u {
+- mmr_t sh_x_tag_mask_regval;
+- struct {
+- mmr_t reserved_0 : 9;
+- mmr_t src : 14;
+- mmr_t addr : 33;
+- mmr_t cmd : 8;
+- } sh_x_tag_mask_s;
+-} sh_x_tag_mask_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_Y_MOD_DBUG_SEL" */
+ /* MD acy debug select */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_mod_dbug_sel_u {
+ mmr_t sh_y_mod_dbug_sel_regval;
+ struct {
+@@ -23855,28 +12878,12 @@
+ mmr_t reserved_0 : 6;
+ } sh_y_mod_dbug_sel_s;
+ } sh_y_mod_dbug_sel_u_t;
+-#else
+-typedef union sh_y_mod_dbug_sel_u {
+- mmr_t sh_y_mod_dbug_sel_regval;
+- struct {
+- mmr_t reserved_0 : 6;
+- mmr_t dqr_sel : 6;
+- mmr_t dql_sel : 6;
+- mmr_t atr_sel : 11;
+- mmr_t atl_sel : 11;
+- mmr_t arb_sel : 8;
+- mmr_t wbq_sel : 8;
+- mmr_t tag_sel : 8;
+- } sh_y_mod_dbug_sel_s;
+-} sh_y_mod_dbug_sel_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_Y_DBUG_SEL" */
+ /* MD acy debug select */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_dbug_sel_u {
+ mmr_t sh_y_dbug_sel_regval;
+ struct {
+@@ -23884,22 +12891,12 @@
+ mmr_t reserved_0 : 40;
+ } sh_y_dbug_sel_s;
+ } sh_y_dbug_sel_u_t;
+-#else
+-typedef union sh_y_dbug_sel_u {
+- mmr_t sh_y_dbug_sel_regval;
+- struct {
+- mmr_t reserved_0 : 40;
+- mmr_t dbg_sel : 24;
+- } sh_y_dbug_sel_s;
+-} sh_y_dbug_sel_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_Y_LADDR_CMP" */
+ /* MD acy address compare */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_laddr_cmp_u {
+ mmr_t sh_y_laddr_cmp_regval;
+ struct {
+@@ -23909,24 +12906,12 @@
+ mmr_t reserved_1 : 4;
+ } sh_y_laddr_cmp_s;
+ } sh_y_laddr_cmp_u_t;
+-#else
+-typedef union sh_y_laddr_cmp_u {
+- mmr_t sh_y_laddr_cmp_regval;
+- struct {
+- mmr_t reserved_1 : 4;
+- mmr_t mask_val : 28;
+- mmr_t reserved_0 : 4;
+- mmr_t cmp_val : 28;
+- } sh_y_laddr_cmp_s;
+-} sh_y_laddr_cmp_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_Y_RADDR_CMP" */
+ /* MD acy address compare */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_raddr_cmp_u {
+ mmr_t sh_y_raddr_cmp_regval;
+ struct {
+@@ -23936,24 +12921,12 @@
+ mmr_t reserved_1 : 4;
+ } sh_y_raddr_cmp_s;
+ } sh_y_raddr_cmp_u_t;
+-#else
+-typedef union sh_y_raddr_cmp_u {
+- mmr_t sh_y_raddr_cmp_regval;
+- struct {
+- mmr_t reserved_1 : 4;
+- mmr_t mask_val : 28;
+- mmr_t reserved_0 : 4;
+- mmr_t cmp_val : 28;
+- } sh_y_raddr_cmp_s;
+-} sh_y_raddr_cmp_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_Y_TAG_CMP" */
+ /* MD acy tagmgr compare */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_tag_cmp_u {
+ mmr_t sh_y_tag_cmp_regval;
+ struct {
+@@ -23963,24 +12936,12 @@
+ mmr_t reserved_0 : 9;
+ } sh_y_tag_cmp_s;
+ } sh_y_tag_cmp_u_t;
+-#else
+-typedef union sh_y_tag_cmp_u {
+- mmr_t sh_y_tag_cmp_regval;
+- struct {
+- mmr_t reserved_0 : 9;
+- mmr_t src : 14;
+- mmr_t addr : 33;
+- mmr_t cmd : 8;
+- } sh_y_tag_cmp_s;
+-} sh_y_tag_cmp_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_Y_TAG_MASK" */
+ /* MD acy tagmgr mask */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_tag_mask_u {
+ mmr_t sh_y_tag_mask_regval;
+ struct {
+@@ -23990,24 +12951,12 @@
+ mmr_t reserved_0 : 9;
+ } sh_y_tag_mask_s;
+ } sh_y_tag_mask_u_t;
+-#else
+-typedef union sh_y_tag_mask_u {
+- mmr_t sh_y_tag_mask_regval;
+- struct {
+- mmr_t reserved_0 : 9;
+- mmr_t src : 14;
+- mmr_t addr : 33;
+- mmr_t cmd : 8;
+- } sh_y_tag_mask_s;
+-} sh_y_tag_mask_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_JNR_DBUG_DATA_CFG" */
+ /* configuration for md jnr debug data muxes */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_jnr_dbug_data_cfg_u {
+ mmr_t sh_md_jnr_dbug_data_cfg_regval;
+ struct {
+@@ -24029,36 +12978,12 @@
+ mmr_t reserved_7 : 33;
+ } sh_md_jnr_dbug_data_cfg_s;
+ } sh_md_jnr_dbug_data_cfg_u_t;
+-#else
+-typedef union sh_md_jnr_dbug_data_cfg_u {
+- mmr_t sh_md_jnr_dbug_data_cfg_regval;
+- struct {
+- mmr_t reserved_7 : 33;
+- mmr_t nibble7_sel : 3;
+- mmr_t reserved_6 : 1;
+- mmr_t nibble6_sel : 3;
+- mmr_t reserved_5 : 1;
+- mmr_t nibble5_sel : 3;
+- mmr_t reserved_4 : 1;
+- mmr_t nibble4_sel : 3;
+- mmr_t reserved_3 : 1;
+- mmr_t nibble3_sel : 3;
+- mmr_t reserved_2 : 1;
+- mmr_t nibble2_sel : 3;
+- mmr_t reserved_1 : 1;
+- mmr_t nibble1_sel : 3;
+- mmr_t reserved_0 : 1;
+- mmr_t nibble0_sel : 3;
+- } sh_md_jnr_dbug_data_cfg_s;
+-} sh_md_jnr_dbug_data_cfg_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_LAST_CREDIT" */
+ /* captures last credit values on reset */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_last_credit_u {
+ mmr_t sh_md_last_credit_regval;
+ struct {
+@@ -24074,30 +12999,12 @@
+ mmr_t reserved_4 : 26;
+ } sh_md_last_credit_s;
+ } sh_md_last_credit_u_t;
+-#else
+-typedef union sh_md_last_credit_u {
+- mmr_t sh_md_last_credit_regval;
+- struct {
+- mmr_t reserved_4 : 26;
+- mmr_t to_lb : 6;
+- mmr_t reserved_3 : 2;
+- mmr_t rp_to_xn : 6;
+- mmr_t reserved_2 : 2;
+- mmr_t rq_to_xn : 6;
+- mmr_t reserved_1 : 2;
+- mmr_t rp_to_pi : 6;
+- mmr_t reserved_0 : 2;
+- mmr_t rq_to_pi : 6;
+- } sh_md_last_credit_s;
+-} sh_md_last_credit_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MEM_CAPTURE_ADDR" */
+ /* Address capture address register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_mem_capture_addr_u {
+ mmr_t sh_mem_capture_addr_regval;
+ struct {
+@@ -24107,24 +13014,12 @@
+ mmr_t reserved_1 : 20;
+ } sh_mem_capture_addr_s;
+ } sh_mem_capture_addr_u_t;
+-#else
+-typedef union sh_mem_capture_addr_u {
+- mmr_t sh_mem_capture_addr_regval;
+- struct {
+- mmr_t reserved_1 : 20;
+- mmr_t cmd : 8;
+- mmr_t addr : 33;
+- mmr_t reserved_0 : 3;
+- } sh_mem_capture_addr_s;
+-} sh_mem_capture_addr_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MEM_CAPTURE_MASK" */
+ /* Address capture mask register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_mem_capture_mask_u {
+ mmr_t sh_mem_capture_mask_regval;
+ struct {
+@@ -24136,26 +13031,12 @@
+ mmr_t reserved_1 : 18;
+ } sh_mem_capture_mask_s;
+ } sh_mem_capture_mask_u_t;
+-#else
+-typedef union sh_mem_capture_mask_u {
+- mmr_t sh_mem_capture_mask_regval;
+- struct {
+- mmr_t reserved_1 : 18;
+- mmr_t enable_remote : 1;
+- mmr_t enable_local : 1;
+- mmr_t cmd : 8;
+- mmr_t addr : 33;
+- mmr_t reserved_0 : 3;
+- } sh_mem_capture_mask_s;
+-} sh_mem_capture_mask_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MEM_CAPTURE_HDR" */
+ /* Address capture header register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_mem_capture_hdr_u {
+ mmr_t sh_mem_capture_hdr_regval;
+ struct {
+@@ -24166,25 +13047,12 @@
+ mmr_t cntr : 6;
+ } sh_mem_capture_hdr_s;
+ } sh_mem_capture_hdr_u_t;
+-#else
+-typedef union sh_mem_capture_hdr_u {
+- mmr_t sh_mem_capture_hdr_regval;
+- struct {
+- mmr_t cntr : 6;
+- mmr_t src : 14;
+- mmr_t cmd : 8;
+- mmr_t addr : 33;
+- mmr_t reserved_0 : 3;
+- } sh_mem_capture_hdr_s;
+-} sh_mem_capture_hdr_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_DIR_CONFIG" */
+ /* DQ directory config register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_dir_config_u {
+ mmr_t sh_md_dqlp_mmr_dir_config_regval;
+ struct {
+@@ -24194,276 +13062,156 @@
+ mmr_t reserved_0 : 59;
+ } sh_md_dqlp_mmr_dir_config_s;
+ } sh_md_dqlp_mmr_dir_config_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_dir_config_u {
+- mmr_t sh_md_dqlp_mmr_dir_config_regval;
+- struct {
+- mmr_t reserved_0 : 59;
+- mmr_t en_dirpois : 1;
+- mmr_t en_direcc : 1;
+- mmr_t sys_size : 3;
+- } sh_md_dqlp_mmr_dir_config_s;
+-} sh_md_dqlp_mmr_dir_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_DIR_PRESVEC0" */
+ /* node [63:0] presence bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqlp_mmr_dir_presvec0_u {
+- mmr_t sh_md_dqlp_mmr_dir_presvec0_regval;
+- struct {
+- mmr_t vec : 64;
+- } sh_md_dqlp_mmr_dir_presvec0_s;
+-} sh_md_dqlp_mmr_dir_presvec0_u_t;
+-#else
+ typedef union sh_md_dqlp_mmr_dir_presvec0_u {
+ mmr_t sh_md_dqlp_mmr_dir_presvec0_regval;
+ struct {
+ mmr_t vec : 64;
+ } sh_md_dqlp_mmr_dir_presvec0_s;
+ } sh_md_dqlp_mmr_dir_presvec0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_DIR_PRESVEC1" */
+ /* node [127:64] presence bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqlp_mmr_dir_presvec1_u {
+- mmr_t sh_md_dqlp_mmr_dir_presvec1_regval;
+- struct {
+- mmr_t vec : 64;
+- } sh_md_dqlp_mmr_dir_presvec1_s;
+-} sh_md_dqlp_mmr_dir_presvec1_u_t;
+-#else
+ typedef union sh_md_dqlp_mmr_dir_presvec1_u {
+ mmr_t sh_md_dqlp_mmr_dir_presvec1_regval;
+ struct {
+ mmr_t vec : 64;
+ } sh_md_dqlp_mmr_dir_presvec1_s;
+ } sh_md_dqlp_mmr_dir_presvec1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_DIR_PRESVEC2" */
+ /* node [191:128] presence bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_dir_presvec2_u {
+ mmr_t sh_md_dqlp_mmr_dir_presvec2_regval;
+ struct {
+ mmr_t vec : 64;
+ } sh_md_dqlp_mmr_dir_presvec2_s;
+ } sh_md_dqlp_mmr_dir_presvec2_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_dir_presvec2_u {
+- mmr_t sh_md_dqlp_mmr_dir_presvec2_regval;
+- struct {
+- mmr_t vec : 64;
+- } sh_md_dqlp_mmr_dir_presvec2_s;
+-} sh_md_dqlp_mmr_dir_presvec2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_DIR_PRESVEC3" */
+ /* node [255:192] presence bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqlp_mmr_dir_presvec3_u {
+- mmr_t sh_md_dqlp_mmr_dir_presvec3_regval;
+- struct {
+- mmr_t vec : 64;
+- } sh_md_dqlp_mmr_dir_presvec3_s;
+-} sh_md_dqlp_mmr_dir_presvec3_u_t;
+-#else
+ typedef union sh_md_dqlp_mmr_dir_presvec3_u {
+ mmr_t sh_md_dqlp_mmr_dir_presvec3_regval;
+ struct {
+ mmr_t vec : 64;
+ } sh_md_dqlp_mmr_dir_presvec3_s;
+ } sh_md_dqlp_mmr_dir_presvec3_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_DIR_LOCVEC0" */
+ /* local vector for acc=0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqlp_mmr_dir_locvec0_u {
+- mmr_t sh_md_dqlp_mmr_dir_locvec0_regval;
+- struct {
+- mmr_t vec : 64;
+- } sh_md_dqlp_mmr_dir_locvec0_s;
+-} sh_md_dqlp_mmr_dir_locvec0_u_t;
+-#else
+ typedef union sh_md_dqlp_mmr_dir_locvec0_u {
+ mmr_t sh_md_dqlp_mmr_dir_locvec0_regval;
+ struct {
+ mmr_t vec : 64;
+ } sh_md_dqlp_mmr_dir_locvec0_s;
+ } sh_md_dqlp_mmr_dir_locvec0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_DIR_LOCVEC1" */
+ /* local vector for acc=1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqlp_mmr_dir_locvec1_u {
+- mmr_t sh_md_dqlp_mmr_dir_locvec1_regval;
+- struct {
+- mmr_t vec : 64;
+- } sh_md_dqlp_mmr_dir_locvec1_s;
+-} sh_md_dqlp_mmr_dir_locvec1_u_t;
+-#else
+ typedef union sh_md_dqlp_mmr_dir_locvec1_u {
+ mmr_t sh_md_dqlp_mmr_dir_locvec1_regval;
+ struct {
+ mmr_t vec : 64;
+ } sh_md_dqlp_mmr_dir_locvec1_s;
+ } sh_md_dqlp_mmr_dir_locvec1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_DIR_LOCVEC2" */
+ /* local vector for acc=2 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_dir_locvec2_u {
+ mmr_t sh_md_dqlp_mmr_dir_locvec2_regval;
+ struct {
+ mmr_t vec : 64;
+ } sh_md_dqlp_mmr_dir_locvec2_s;
+ } sh_md_dqlp_mmr_dir_locvec2_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_dir_locvec2_u {
+- mmr_t sh_md_dqlp_mmr_dir_locvec2_regval;
+- struct {
+- mmr_t vec : 64;
+- } sh_md_dqlp_mmr_dir_locvec2_s;
+-} sh_md_dqlp_mmr_dir_locvec2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_DIR_LOCVEC3" */
+ /* local vector for acc=3 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqlp_mmr_dir_locvec3_u {
+- mmr_t sh_md_dqlp_mmr_dir_locvec3_regval;
+- struct {
+- mmr_t vec : 64;
+- } sh_md_dqlp_mmr_dir_locvec3_s;
+-} sh_md_dqlp_mmr_dir_locvec3_u_t;
+-#else
+ typedef union sh_md_dqlp_mmr_dir_locvec3_u {
+ mmr_t sh_md_dqlp_mmr_dir_locvec3_regval;
+ struct {
+ mmr_t vec : 64;
+ } sh_md_dqlp_mmr_dir_locvec3_s;
+ } sh_md_dqlp_mmr_dir_locvec3_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_DIR_LOCVEC4" */
+ /* local vector for acc=4 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqlp_mmr_dir_locvec4_u {
+- mmr_t sh_md_dqlp_mmr_dir_locvec4_regval;
+- struct {
+- mmr_t vec : 64;
+- } sh_md_dqlp_mmr_dir_locvec4_s;
+-} sh_md_dqlp_mmr_dir_locvec4_u_t;
+-#else
+ typedef union sh_md_dqlp_mmr_dir_locvec4_u {
+ mmr_t sh_md_dqlp_mmr_dir_locvec4_regval;
+ struct {
+ mmr_t vec : 64;
+ } sh_md_dqlp_mmr_dir_locvec4_s;
+ } sh_md_dqlp_mmr_dir_locvec4_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_DIR_LOCVEC5" */
+ /* local vector for acc=5 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqlp_mmr_dir_locvec5_u {
+- mmr_t sh_md_dqlp_mmr_dir_locvec5_regval;
+- struct {
+- mmr_t vec : 64;
+- } sh_md_dqlp_mmr_dir_locvec5_s;
+-} sh_md_dqlp_mmr_dir_locvec5_u_t;
+-#else
+ typedef union sh_md_dqlp_mmr_dir_locvec5_u {
+ mmr_t sh_md_dqlp_mmr_dir_locvec5_regval;
+ struct {
+ mmr_t vec : 64;
+ } sh_md_dqlp_mmr_dir_locvec5_s;
+ } sh_md_dqlp_mmr_dir_locvec5_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_DIR_LOCVEC6" */
+ /* local vector for acc=6 */
+-/* ==================================================================== */
+-
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqlp_mmr_dir_locvec6_u {
+- mmr_t sh_md_dqlp_mmr_dir_locvec6_regval;
+- struct {
+- mmr_t vec : 64;
+- } sh_md_dqlp_mmr_dir_locvec6_s;
+-} sh_md_dqlp_mmr_dir_locvec6_u_t;
+-#else
++/* ==================================================================== */
++
+ typedef union sh_md_dqlp_mmr_dir_locvec6_u {
+ mmr_t sh_md_dqlp_mmr_dir_locvec6_regval;
+ struct {
+ mmr_t vec : 64;
+ } sh_md_dqlp_mmr_dir_locvec6_s;
+ } sh_md_dqlp_mmr_dir_locvec6_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_DIR_LOCVEC7" */
+ /* local vector for acc=7 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqlp_mmr_dir_locvec7_u {
+- mmr_t sh_md_dqlp_mmr_dir_locvec7_regval;
+- struct {
+- mmr_t vec : 64;
+- } sh_md_dqlp_mmr_dir_locvec7_s;
+-} sh_md_dqlp_mmr_dir_locvec7_u_t;
+-#else
+ typedef union sh_md_dqlp_mmr_dir_locvec7_u {
+ mmr_t sh_md_dqlp_mmr_dir_locvec7_regval;
+ struct {
+ mmr_t vec : 64;
+ } sh_md_dqlp_mmr_dir_locvec7_s;
+ } sh_md_dqlp_mmr_dir_locvec7_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_DIR_PRIVEC0" */
+ /* privilege vector for acc=0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_dir_privec0_u {
+ mmr_t sh_md_dqlp_mmr_dir_privec0_regval;
+ struct {
+@@ -24472,23 +13220,12 @@
+ mmr_t reserved_0 : 36;
+ } sh_md_dqlp_mmr_dir_privec0_s;
+ } sh_md_dqlp_mmr_dir_privec0_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_dir_privec0_u {
+- mmr_t sh_md_dqlp_mmr_dir_privec0_regval;
+- struct {
+- mmr_t reserved_0 : 36;
+- mmr_t out : 14;
+- mmr_t in : 14;
+- } sh_md_dqlp_mmr_dir_privec0_s;
+-} sh_md_dqlp_mmr_dir_privec0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_DIR_PRIVEC1" */
+ /* privilege vector for acc=1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_dir_privec1_u {
+ mmr_t sh_md_dqlp_mmr_dir_privec1_regval;
+ struct {
+@@ -24497,23 +13234,12 @@
+ mmr_t reserved_0 : 36;
+ } sh_md_dqlp_mmr_dir_privec1_s;
+ } sh_md_dqlp_mmr_dir_privec1_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_dir_privec1_u {
+- mmr_t sh_md_dqlp_mmr_dir_privec1_regval;
+- struct {
+- mmr_t reserved_0 : 36;
+- mmr_t out : 14;
+- mmr_t in : 14;
+- } sh_md_dqlp_mmr_dir_privec1_s;
+-} sh_md_dqlp_mmr_dir_privec1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_DIR_PRIVEC2" */
+ /* privilege vector for acc=2 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_dir_privec2_u {
+ mmr_t sh_md_dqlp_mmr_dir_privec2_regval;
+ struct {
+@@ -24522,23 +13248,12 @@
+ mmr_t reserved_0 : 36;
+ } sh_md_dqlp_mmr_dir_privec2_s;
+ } sh_md_dqlp_mmr_dir_privec2_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_dir_privec2_u {
+- mmr_t sh_md_dqlp_mmr_dir_privec2_regval;
+- struct {
+- mmr_t reserved_0 : 36;
+- mmr_t out : 14;
+- mmr_t in : 14;
+- } sh_md_dqlp_mmr_dir_privec2_s;
+-} sh_md_dqlp_mmr_dir_privec2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_DIR_PRIVEC3" */
+ /* privilege vector for acc=3 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_dir_privec3_u {
+ mmr_t sh_md_dqlp_mmr_dir_privec3_regval;
+ struct {
+@@ -24547,23 +13262,12 @@
+ mmr_t reserved_0 : 36;
+ } sh_md_dqlp_mmr_dir_privec3_s;
+ } sh_md_dqlp_mmr_dir_privec3_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_dir_privec3_u {
+- mmr_t sh_md_dqlp_mmr_dir_privec3_regval;
+- struct {
+- mmr_t reserved_0 : 36;
+- mmr_t out : 14;
+- mmr_t in : 14;
+- } sh_md_dqlp_mmr_dir_privec3_s;
+-} sh_md_dqlp_mmr_dir_privec3_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_DIR_PRIVEC4" */
+ /* privilege vector for acc=4 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_dir_privec4_u {
+ mmr_t sh_md_dqlp_mmr_dir_privec4_regval;
+ struct {
+@@ -24572,23 +13276,12 @@
+ mmr_t reserved_0 : 36;
+ } sh_md_dqlp_mmr_dir_privec4_s;
+ } sh_md_dqlp_mmr_dir_privec4_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_dir_privec4_u {
+- mmr_t sh_md_dqlp_mmr_dir_privec4_regval;
+- struct {
+- mmr_t reserved_0 : 36;
+- mmr_t out : 14;
+- mmr_t in : 14;
+- } sh_md_dqlp_mmr_dir_privec4_s;
+-} sh_md_dqlp_mmr_dir_privec4_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_DIR_PRIVEC5" */
+ /* privilege vector for acc=5 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_dir_privec5_u {
+ mmr_t sh_md_dqlp_mmr_dir_privec5_regval;
+ struct {
+@@ -24597,23 +13290,12 @@
+ mmr_t reserved_0 : 36;
+ } sh_md_dqlp_mmr_dir_privec5_s;
+ } sh_md_dqlp_mmr_dir_privec5_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_dir_privec5_u {
+- mmr_t sh_md_dqlp_mmr_dir_privec5_regval;
+- struct {
+- mmr_t reserved_0 : 36;
+- mmr_t out : 14;
+- mmr_t in : 14;
+- } sh_md_dqlp_mmr_dir_privec5_s;
+-} sh_md_dqlp_mmr_dir_privec5_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_DIR_PRIVEC6" */
+ /* privilege vector for acc=6 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_dir_privec6_u {
+ mmr_t sh_md_dqlp_mmr_dir_privec6_regval;
+ struct {
+@@ -24622,23 +13304,12 @@
+ mmr_t reserved_0 : 36;
+ } sh_md_dqlp_mmr_dir_privec6_s;
+ } sh_md_dqlp_mmr_dir_privec6_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_dir_privec6_u {
+- mmr_t sh_md_dqlp_mmr_dir_privec6_regval;
+- struct {
+- mmr_t reserved_0 : 36;
+- mmr_t out : 14;
+- mmr_t in : 14;
+- } sh_md_dqlp_mmr_dir_privec6_s;
+-} sh_md_dqlp_mmr_dir_privec6_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_DIR_PRIVEC7" */
+ /* privilege vector for acc=7 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_dir_privec7_u {
+ mmr_t sh_md_dqlp_mmr_dir_privec7_regval;
+ struct {
+@@ -24647,23 +13318,12 @@
+ mmr_t reserved_0 : 36;
+ } sh_md_dqlp_mmr_dir_privec7_s;
+ } sh_md_dqlp_mmr_dir_privec7_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_dir_privec7_u {
+- mmr_t sh_md_dqlp_mmr_dir_privec7_regval;
+- struct {
+- mmr_t reserved_0 : 36;
+- mmr_t out : 14;
+- mmr_t in : 14;
+- } sh_md_dqlp_mmr_dir_privec7_s;
+-} sh_md_dqlp_mmr_dir_privec7_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_DIR_TIMER" */
+ /* MD SXRO timer */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_dir_timer_u {
+ mmr_t sh_md_dqlp_mmr_dir_timer_regval;
+ struct {
+@@ -24673,24 +13333,12 @@
+ mmr_t reserved_0 : 42;
+ } sh_md_dqlp_mmr_dir_timer_s;
+ } sh_md_dqlp_mmr_dir_timer_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_dir_timer_u {
+- mmr_t sh_md_dqlp_mmr_dir_timer_regval;
+- struct {
+- mmr_t reserved_0 : 42;
+- mmr_t timer_cur : 9;
+- mmr_t timer_en : 1;
+- mmr_t timer_div : 12;
+- } sh_md_dqlp_mmr_dir_timer_s;
+-} sh_md_dqlp_mmr_dir_timer_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_PIOWD_DIR_ENTRY" */
+ /* directory pio write data */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_piowd_dir_entry_u {
+ mmr_t sh_md_dqlp_mmr_piowd_dir_entry_regval;
+ struct {
+@@ -24701,25 +13349,12 @@
+ mmr_t reserved_0 : 6;
+ } sh_md_dqlp_mmr_piowd_dir_entry_s;
+ } sh_md_dqlp_mmr_piowd_dir_entry_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_piowd_dir_entry_u {
+- mmr_t sh_md_dqlp_mmr_piowd_dir_entry_regval;
+- struct {
+- mmr_t reserved_0 : 6;
+- mmr_t acc : 3;
+- mmr_t pri : 3;
+- mmr_t dirb : 26;
+- mmr_t dira : 26;
+- } sh_md_dqlp_mmr_piowd_dir_entry_s;
+-} sh_md_dqlp_mmr_piowd_dir_entry_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_PIOWD_DIR_ECC" */
+ /* directory ecc register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_piowd_dir_ecc_u {
+ mmr_t sh_md_dqlp_mmr_piowd_dir_ecc_regval;
+ struct {
+@@ -24728,23 +13363,12 @@
+ mmr_t reserved_0 : 50;
+ } sh_md_dqlp_mmr_piowd_dir_ecc_s;
+ } sh_md_dqlp_mmr_piowd_dir_ecc_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_piowd_dir_ecc_u {
+- mmr_t sh_md_dqlp_mmr_piowd_dir_ecc_regval;
+- struct {
+- mmr_t reserved_0 : 50;
+- mmr_t eccb : 7;
+- mmr_t ecca : 7;
+- } sh_md_dqlp_mmr_piowd_dir_ecc_s;
+-} sh_md_dqlp_mmr_piowd_dir_ecc_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_XPIORD_XDIR_ENTRY" */
+ /* x directory pio read data */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_xpiord_xdir_entry_u {
+ mmr_t sh_md_dqlp_mmr_xpiord_xdir_entry_regval;
+ struct {
+@@ -24757,27 +13381,12 @@
+ mmr_t reserved_0 : 4;
+ } sh_md_dqlp_mmr_xpiord_xdir_entry_s;
+ } sh_md_dqlp_mmr_xpiord_xdir_entry_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_xpiord_xdir_entry_u {
+- mmr_t sh_md_dqlp_mmr_xpiord_xdir_entry_regval;
+- struct {
+- mmr_t reserved_0 : 4;
+- mmr_t unc : 1;
+- mmr_t cor : 1;
+- mmr_t acc : 3;
+- mmr_t pri : 3;
+- mmr_t dirb : 26;
+- mmr_t dira : 26;
+- } sh_md_dqlp_mmr_xpiord_xdir_entry_s;
+-} sh_md_dqlp_mmr_xpiord_xdir_entry_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_XPIORD_XDIR_ECC" */
+ /* x directory ecc */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_xpiord_xdir_ecc_u {
+ mmr_t sh_md_dqlp_mmr_xpiord_xdir_ecc_regval;
+ struct {
+@@ -24786,23 +13395,12 @@
+ mmr_t reserved_0 : 50;
+ } sh_md_dqlp_mmr_xpiord_xdir_ecc_s;
+ } sh_md_dqlp_mmr_xpiord_xdir_ecc_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_xpiord_xdir_ecc_u {
+- mmr_t sh_md_dqlp_mmr_xpiord_xdir_ecc_regval;
+- struct {
+- mmr_t reserved_0 : 50;
+- mmr_t eccb : 7;
+- mmr_t ecca : 7;
+- } sh_md_dqlp_mmr_xpiord_xdir_ecc_s;
+-} sh_md_dqlp_mmr_xpiord_xdir_ecc_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_YPIORD_YDIR_ENTRY" */
+ /* y directory pio read data */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_ypiord_ydir_entry_u {
+ mmr_t sh_md_dqlp_mmr_ypiord_ydir_entry_regval;
+ struct {
+@@ -24815,27 +13413,12 @@
+ mmr_t reserved_0 : 4;
+ } sh_md_dqlp_mmr_ypiord_ydir_entry_s;
+ } sh_md_dqlp_mmr_ypiord_ydir_entry_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_ypiord_ydir_entry_u {
+- mmr_t sh_md_dqlp_mmr_ypiord_ydir_entry_regval;
+- struct {
+- mmr_t reserved_0 : 4;
+- mmr_t unc : 1;
+- mmr_t cor : 1;
+- mmr_t acc : 3;
+- mmr_t pri : 3;
+- mmr_t dirb : 26;
+- mmr_t dira : 26;
+- } sh_md_dqlp_mmr_ypiord_ydir_entry_s;
+-} sh_md_dqlp_mmr_ypiord_ydir_entry_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_YPIORD_YDIR_ECC" */
+ /* y directory ecc */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_ypiord_ydir_ecc_u {
+ mmr_t sh_md_dqlp_mmr_ypiord_ydir_ecc_regval;
+ struct {
+@@ -24844,23 +13427,12 @@
+ mmr_t reserved_0 : 50;
+ } sh_md_dqlp_mmr_ypiord_ydir_ecc_s;
+ } sh_md_dqlp_mmr_ypiord_ydir_ecc_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_ypiord_ydir_ecc_u {
+- mmr_t sh_md_dqlp_mmr_ypiord_ydir_ecc_regval;
+- struct {
+- mmr_t reserved_0 : 50;
+- mmr_t eccb : 7;
+- mmr_t ecca : 7;
+- } sh_md_dqlp_mmr_ypiord_ydir_ecc_s;
+-} sh_md_dqlp_mmr_ypiord_ydir_ecc_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_XCERR1" */
+ /* correctable dir ecc group 1 error register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_xcerr1_u {
+ mmr_t sh_md_dqlp_mmr_xcerr1_regval;
+ struct {
+@@ -24871,25 +13443,12 @@
+ mmr_t reserved_0 : 25;
+ } sh_md_dqlp_mmr_xcerr1_s;
+ } sh_md_dqlp_mmr_xcerr1_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_xcerr1_u {
+- mmr_t sh_md_dqlp_mmr_xcerr1_regval;
+- struct {
+- mmr_t reserved_0 : 25;
+- mmr_t arm : 1;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t grp1 : 36;
+- } sh_md_dqlp_mmr_xcerr1_s;
+-} sh_md_dqlp_mmr_xcerr1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_XCERR2" */
+ /* correctable dir ecc group 2 error register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_xcerr2_u {
+ mmr_t sh_md_dqlp_mmr_xcerr2_regval;
+ struct {
+@@ -24899,24 +13458,12 @@
+ mmr_t reserved_0 : 26;
+ } sh_md_dqlp_mmr_xcerr2_s;
+ } sh_md_dqlp_mmr_xcerr2_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_xcerr2_u {
+- mmr_t sh_md_dqlp_mmr_xcerr2_regval;
+- struct {
+- mmr_t reserved_0 : 26;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t grp2 : 36;
+- } sh_md_dqlp_mmr_xcerr2_s;
+-} sh_md_dqlp_mmr_xcerr2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_XUERR1" */
+ /* uncorrectable dir ecc group 1 error register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_xuerr1_u {
+ mmr_t sh_md_dqlp_mmr_xuerr1_regval;
+ struct {
+@@ -24927,25 +13474,12 @@
+ mmr_t reserved_0 : 25;
+ } sh_md_dqlp_mmr_xuerr1_s;
+ } sh_md_dqlp_mmr_xuerr1_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_xuerr1_u {
+- mmr_t sh_md_dqlp_mmr_xuerr1_regval;
+- struct {
+- mmr_t reserved_0 : 25;
+- mmr_t arm : 1;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t grp1 : 36;
+- } sh_md_dqlp_mmr_xuerr1_s;
+-} sh_md_dqlp_mmr_xuerr1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_XUERR2" */
+ /* uncorrectable dir ecc group 2 error register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_xuerr2_u {
+ mmr_t sh_md_dqlp_mmr_xuerr2_regval;
+ struct {
+@@ -24955,24 +13489,12 @@
+ mmr_t reserved_0 : 26;
+ } sh_md_dqlp_mmr_xuerr2_s;
+ } sh_md_dqlp_mmr_xuerr2_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_xuerr2_u {
+- mmr_t sh_md_dqlp_mmr_xuerr2_regval;
+- struct {
+- mmr_t reserved_0 : 26;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t grp2 : 36;
+- } sh_md_dqlp_mmr_xuerr2_s;
+-} sh_md_dqlp_mmr_xuerr2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_XPERR" */
+ /* protocol error register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_xperr_u {
+ mmr_t sh_md_dqlp_mmr_xperr_regval;
+ struct {
+@@ -24990,32 +13512,12 @@
+ mmr_t reserved_0 : 1;
+ } sh_md_dqlp_mmr_xperr_s;
+ } sh_md_dqlp_mmr_xperr_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_xperr_u {
+- mmr_t sh_md_dqlp_mmr_xperr_regval;
+- struct {
+- mmr_t reserved_0 : 1;
+- mmr_t arm : 1;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t mybit : 8;
+- mmr_t unc : 1;
+- mmr_t cor : 1;
+- mmr_t priv : 1;
+- mmr_t prige : 1;
+- mmr_t src : 14;
+- mmr_t cmd : 8;
+- mmr_t dir : 26;
+- } sh_md_dqlp_mmr_xperr_s;
+-} sh_md_dqlp_mmr_xperr_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_YCERR1" */
+ /* correctable dir ecc group 1 error register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_ycerr1_u {
+ mmr_t sh_md_dqlp_mmr_ycerr1_regval;
+ struct {
+@@ -25026,25 +13528,12 @@
+ mmr_t reserved_0 : 25;
+ } sh_md_dqlp_mmr_ycerr1_s;
+ } sh_md_dqlp_mmr_ycerr1_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_ycerr1_u {
+- mmr_t sh_md_dqlp_mmr_ycerr1_regval;
+- struct {
+- mmr_t reserved_0 : 25;
+- mmr_t arm : 1;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t grp1 : 36;
+- } sh_md_dqlp_mmr_ycerr1_s;
+-} sh_md_dqlp_mmr_ycerr1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_YCERR2" */
+ /* correctable dir ecc group 2 error register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_ycerr2_u {
+ mmr_t sh_md_dqlp_mmr_ycerr2_regval;
+ struct {
+@@ -25054,24 +13543,12 @@
+ mmr_t reserved_0 : 26;
+ } sh_md_dqlp_mmr_ycerr2_s;
+ } sh_md_dqlp_mmr_ycerr2_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_ycerr2_u {
+- mmr_t sh_md_dqlp_mmr_ycerr2_regval;
+- struct {
+- mmr_t reserved_0 : 26;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t grp2 : 36;
+- } sh_md_dqlp_mmr_ycerr2_s;
+-} sh_md_dqlp_mmr_ycerr2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_YUERR1" */
+ /* uncorrectable dir ecc group 1 error register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_yuerr1_u {
+ mmr_t sh_md_dqlp_mmr_yuerr1_regval;
+ struct {
+@@ -25082,25 +13559,12 @@
+ mmr_t reserved_0 : 25;
+ } sh_md_dqlp_mmr_yuerr1_s;
+ } sh_md_dqlp_mmr_yuerr1_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_yuerr1_u {
+- mmr_t sh_md_dqlp_mmr_yuerr1_regval;
+- struct {
+- mmr_t reserved_0 : 25;
+- mmr_t arm : 1;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t grp1 : 36;
+- } sh_md_dqlp_mmr_yuerr1_s;
+-} sh_md_dqlp_mmr_yuerr1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_YUERR2" */
+ /* uncorrectable dir ecc group 2 error register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_yuerr2_u {
+ mmr_t sh_md_dqlp_mmr_yuerr2_regval;
+ struct {
+@@ -25110,24 +13574,12 @@
+ mmr_t reserved_0 : 26;
+ } sh_md_dqlp_mmr_yuerr2_s;
+ } sh_md_dqlp_mmr_yuerr2_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_yuerr2_u {
+- mmr_t sh_md_dqlp_mmr_yuerr2_regval;
+- struct {
+- mmr_t reserved_0 : 26;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t grp2 : 36;
+- } sh_md_dqlp_mmr_yuerr2_s;
+-} sh_md_dqlp_mmr_yuerr2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_YPERR" */
+ /* protocol error register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_yperr_u {
+ mmr_t sh_md_dqlp_mmr_yperr_regval;
+ struct {
+@@ -25136,41 +13588,21 @@
+ mmr_t src : 14;
+ mmr_t prige : 1;
+ mmr_t priv : 1;
+- mmr_t cor : 1;
+- mmr_t unc : 1;
+- mmr_t mybit : 8;
+- mmr_t val : 1;
+- mmr_t more : 1;
+- mmr_t arm : 1;
+- mmr_t reserved_0 : 1;
+- } sh_md_dqlp_mmr_yperr_s;
+-} sh_md_dqlp_mmr_yperr_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_yperr_u {
+- mmr_t sh_md_dqlp_mmr_yperr_regval;
+- struct {
+- mmr_t reserved_0 : 1;
+- mmr_t arm : 1;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t mybit : 8;
+- mmr_t unc : 1;
+- mmr_t cor : 1;
+- mmr_t priv : 1;
+- mmr_t prige : 1;
+- mmr_t src : 14;
+- mmr_t cmd : 8;
+- mmr_t dir : 26;
++ mmr_t cor : 1;
++ mmr_t unc : 1;
++ mmr_t mybit : 8;
++ mmr_t val : 1;
++ mmr_t more : 1;
++ mmr_t arm : 1;
++ mmr_t reserved_0 : 1;
+ } sh_md_dqlp_mmr_yperr_s;
+ } sh_md_dqlp_mmr_yperr_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_DIR_CMDTRIG" */
+ /* cmd triggers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_dir_cmdtrig_u {
+ mmr_t sh_md_dqlp_mmr_dir_cmdtrig_regval;
+ struct {
+@@ -25181,25 +13613,12 @@
+ mmr_t reserved_0 : 32;
+ } sh_md_dqlp_mmr_dir_cmdtrig_s;
+ } sh_md_dqlp_mmr_dir_cmdtrig_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_dir_cmdtrig_u {
+- mmr_t sh_md_dqlp_mmr_dir_cmdtrig_regval;
+- struct {
+- mmr_t reserved_0 : 32;
+- mmr_t cmd3 : 8;
+- mmr_t cmd2 : 8;
+- mmr_t cmd1 : 8;
+- mmr_t cmd0 : 8;
+- } sh_md_dqlp_mmr_dir_cmdtrig_s;
+-} sh_md_dqlp_mmr_dir_cmdtrig_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_DIR_TBLTRIG" */
+ /* dir table trigger */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_dir_tbltrig_u {
+ mmr_t sh_md_dqlp_mmr_dir_tbltrig_regval;
+ struct {
+@@ -25212,27 +13631,12 @@
+ mmr_t reserved_0 : 22;
+ } sh_md_dqlp_mmr_dir_tbltrig_s;
+ } sh_md_dqlp_mmr_dir_tbltrig_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_dir_tbltrig_u {
+- mmr_t sh_md_dqlp_mmr_dir_tbltrig_regval;
+- struct {
+- mmr_t reserved_0 : 22;
+- mmr_t mybit : 8;
+- mmr_t dirst : 9;
+- mmr_t prige : 1;
+- mmr_t acc : 2;
+- mmr_t cmd : 8;
+- mmr_t src : 14;
+- } sh_md_dqlp_mmr_dir_tbltrig_s;
+-} sh_md_dqlp_mmr_dir_tbltrig_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_DIR_TBLMASK" */
+ /* dir table trigger mask */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_dir_tblmask_u {
+ mmr_t sh_md_dqlp_mmr_dir_tblmask_regval;
+ struct {
+@@ -25245,27 +13649,12 @@
+ mmr_t reserved_0 : 22;
+ } sh_md_dqlp_mmr_dir_tblmask_s;
+ } sh_md_dqlp_mmr_dir_tblmask_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_dir_tblmask_u {
+- mmr_t sh_md_dqlp_mmr_dir_tblmask_regval;
+- struct {
+- mmr_t reserved_0 : 22;
+- mmr_t mybit : 8;
+- mmr_t dirst : 9;
+- mmr_t prige : 1;
+- mmr_t acc : 2;
+- mmr_t cmd : 8;
+- mmr_t src : 14;
+- } sh_md_dqlp_mmr_dir_tblmask_s;
+-} sh_md_dqlp_mmr_dir_tblmask_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_XBIST_H" */
+ /* rising edge bist/fill pattern */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_xbist_h_u {
+ mmr_t sh_md_dqlp_mmr_xbist_h_regval;
+ struct {
+@@ -25277,26 +13666,12 @@
+ mmr_t reserved_1 : 21;
+ } sh_md_dqlp_mmr_xbist_h_s;
+ } sh_md_dqlp_mmr_xbist_h_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_xbist_h_u {
+- mmr_t sh_md_dqlp_mmr_xbist_h_regval;
+- struct {
+- mmr_t reserved_1 : 21;
+- mmr_t arm : 1;
+- mmr_t rot : 1;
+- mmr_t inv : 1;
+- mmr_t reserved_0 : 8;
+- mmr_t pat : 32;
+- } sh_md_dqlp_mmr_xbist_h_s;
+-} sh_md_dqlp_mmr_xbist_h_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_XBIST_L" */
+ /* falling edge bist/fill pattern */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_xbist_l_u {
+ mmr_t sh_md_dqlp_mmr_xbist_l_regval;
+ struct {
+@@ -25307,25 +13682,12 @@
+ mmr_t reserved_1 : 22;
+ } sh_md_dqlp_mmr_xbist_l_s;
+ } sh_md_dqlp_mmr_xbist_l_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_xbist_l_u {
+- mmr_t sh_md_dqlp_mmr_xbist_l_regval;
+- struct {
+- mmr_t reserved_1 : 22;
+- mmr_t rot : 1;
+- mmr_t inv : 1;
+- mmr_t reserved_0 : 8;
+- mmr_t pat : 32;
+- } sh_md_dqlp_mmr_xbist_l_s;
+-} sh_md_dqlp_mmr_xbist_l_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_XBIST_ERR_H" */
+ /* rising edge bist error pattern */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_xbist_err_h_u {
+ mmr_t sh_md_dqlp_mmr_xbist_err_h_regval;
+ struct {
+@@ -25336,25 +13698,12 @@
+ mmr_t reserved_1 : 22;
+ } sh_md_dqlp_mmr_xbist_err_h_s;
+ } sh_md_dqlp_mmr_xbist_err_h_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_xbist_err_h_u {
+- mmr_t sh_md_dqlp_mmr_xbist_err_h_regval;
+- struct {
+- mmr_t reserved_1 : 22;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t reserved_0 : 8;
+- mmr_t pat : 32;
+- } sh_md_dqlp_mmr_xbist_err_h_s;
+-} sh_md_dqlp_mmr_xbist_err_h_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_XBIST_ERR_L" */
+ /* falling edge bist error pattern */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_xbist_err_l_u {
+ mmr_t sh_md_dqlp_mmr_xbist_err_l_regval;
+ struct {
+@@ -25365,25 +13714,12 @@
+ mmr_t reserved_1 : 22;
+ } sh_md_dqlp_mmr_xbist_err_l_s;
+ } sh_md_dqlp_mmr_xbist_err_l_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_xbist_err_l_u {
+- mmr_t sh_md_dqlp_mmr_xbist_err_l_regval;
+- struct {
+- mmr_t reserved_1 : 22;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t reserved_0 : 8;
+- mmr_t pat : 32;
+- } sh_md_dqlp_mmr_xbist_err_l_s;
+-} sh_md_dqlp_mmr_xbist_err_l_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_YBIST_H" */
+ /* rising edge bist/fill pattern */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_ybist_h_u {
+ mmr_t sh_md_dqlp_mmr_ybist_h_regval;
+ struct {
+@@ -25395,26 +13731,12 @@
+ mmr_t reserved_1 : 21;
+ } sh_md_dqlp_mmr_ybist_h_s;
+ } sh_md_dqlp_mmr_ybist_h_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_ybist_h_u {
+- mmr_t sh_md_dqlp_mmr_ybist_h_regval;
+- struct {
+- mmr_t reserved_1 : 21;
+- mmr_t arm : 1;
+- mmr_t rot : 1;
+- mmr_t inv : 1;
+- mmr_t reserved_0 : 8;
+- mmr_t pat : 32;
+- } sh_md_dqlp_mmr_ybist_h_s;
+-} sh_md_dqlp_mmr_ybist_h_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_YBIST_L" */
+ /* falling edge bist/fill pattern */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_ybist_l_u {
+ mmr_t sh_md_dqlp_mmr_ybist_l_regval;
+ struct {
+@@ -25425,25 +13747,12 @@
+ mmr_t reserved_1 : 22;
+ } sh_md_dqlp_mmr_ybist_l_s;
+ } sh_md_dqlp_mmr_ybist_l_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_ybist_l_u {
+- mmr_t sh_md_dqlp_mmr_ybist_l_regval;
+- struct {
+- mmr_t reserved_1 : 22;
+- mmr_t rot : 1;
+- mmr_t inv : 1;
+- mmr_t reserved_0 : 8;
+- mmr_t pat : 32;
+- } sh_md_dqlp_mmr_ybist_l_s;
+-} sh_md_dqlp_mmr_ybist_l_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_YBIST_ERR_H" */
+ /* rising edge bist error pattern */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_ybist_err_h_u {
+ mmr_t sh_md_dqlp_mmr_ybist_err_h_regval;
+ struct {
+@@ -25454,25 +13763,12 @@
+ mmr_t reserved_1 : 22;
+ } sh_md_dqlp_mmr_ybist_err_h_s;
+ } sh_md_dqlp_mmr_ybist_err_h_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_ybist_err_h_u {
+- mmr_t sh_md_dqlp_mmr_ybist_err_h_regval;
+- struct {
+- mmr_t reserved_1 : 22;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t reserved_0 : 8;
+- mmr_t pat : 32;
+- } sh_md_dqlp_mmr_ybist_err_h_s;
+-} sh_md_dqlp_mmr_ybist_err_h_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLP_MMR_YBIST_ERR_L" */
+ /* falling edge bist error pattern */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_ybist_err_l_u {
+ mmr_t sh_md_dqlp_mmr_ybist_err_l_regval;
+ struct {
+@@ -25483,25 +13779,12 @@
+ mmr_t reserved_1 : 22;
+ } sh_md_dqlp_mmr_ybist_err_l_s;
+ } sh_md_dqlp_mmr_ybist_err_l_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_ybist_err_l_u {
+- mmr_t sh_md_dqlp_mmr_ybist_err_l_regval;
+- struct {
+- mmr_t reserved_1 : 22;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t reserved_0 : 8;
+- mmr_t pat : 32;
+- } sh_md_dqlp_mmr_ybist_err_l_s;
+-} sh_md_dqlp_mmr_ybist_err_l_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLS_MMR_XBIST_H" */
+ /* rising edge bist/fill pattern */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqls_mmr_xbist_h_u {
+ mmr_t sh_md_dqls_mmr_xbist_h_regval;
+ struct {
+@@ -25512,25 +13795,12 @@
+ mmr_t reserved_0 : 21;
+ } sh_md_dqls_mmr_xbist_h_s;
+ } sh_md_dqls_mmr_xbist_h_u_t;
+-#else
+-typedef union sh_md_dqls_mmr_xbist_h_u {
+- mmr_t sh_md_dqls_mmr_xbist_h_regval;
+- struct {
+- mmr_t reserved_0 : 21;
+- mmr_t arm : 1;
+- mmr_t rot : 1;
+- mmr_t inv : 1;
+- mmr_t pat : 40;
+- } sh_md_dqls_mmr_xbist_h_s;
+-} sh_md_dqls_mmr_xbist_h_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLS_MMR_XBIST_L" */
+ /* falling edge bist/fill pattern */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqls_mmr_xbist_l_u {
+ mmr_t sh_md_dqls_mmr_xbist_l_regval;
+ struct {
+@@ -25540,24 +13810,12 @@
+ mmr_t reserved_0 : 22;
+ } sh_md_dqls_mmr_xbist_l_s;
+ } sh_md_dqls_mmr_xbist_l_u_t;
+-#else
+-typedef union sh_md_dqls_mmr_xbist_l_u {
+- mmr_t sh_md_dqls_mmr_xbist_l_regval;
+- struct {
+- mmr_t reserved_0 : 22;
+- mmr_t rot : 1;
+- mmr_t inv : 1;
+- mmr_t pat : 40;
+- } sh_md_dqls_mmr_xbist_l_s;
+-} sh_md_dqls_mmr_xbist_l_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLS_MMR_XBIST_ERR_H" */
+ /* rising edge bist error pattern */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqls_mmr_xbist_err_h_u {
+ mmr_t sh_md_dqls_mmr_xbist_err_h_regval;
+ struct {
+@@ -25567,24 +13825,12 @@
+ mmr_t reserved_0 : 22;
+ } sh_md_dqls_mmr_xbist_err_h_s;
+ } sh_md_dqls_mmr_xbist_err_h_u_t;
+-#else
+-typedef union sh_md_dqls_mmr_xbist_err_h_u {
+- mmr_t sh_md_dqls_mmr_xbist_err_h_regval;
+- struct {
+- mmr_t reserved_0 : 22;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t pat : 40;
+- } sh_md_dqls_mmr_xbist_err_h_s;
+-} sh_md_dqls_mmr_xbist_err_h_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLS_MMR_XBIST_ERR_L" */
+ /* falling edge bist error pattern */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqls_mmr_xbist_err_l_u {
+ mmr_t sh_md_dqls_mmr_xbist_err_l_regval;
+ struct {
+@@ -25594,24 +13840,12 @@
+ mmr_t reserved_0 : 22;
+ } sh_md_dqls_mmr_xbist_err_l_s;
+ } sh_md_dqls_mmr_xbist_err_l_u_t;
+-#else
+-typedef union sh_md_dqls_mmr_xbist_err_l_u {
+- mmr_t sh_md_dqls_mmr_xbist_err_l_regval;
+- struct {
+- mmr_t reserved_0 : 22;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t pat : 40;
+- } sh_md_dqls_mmr_xbist_err_l_s;
+-} sh_md_dqls_mmr_xbist_err_l_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLS_MMR_YBIST_H" */
+ /* rising edge bist/fill pattern */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqls_mmr_ybist_h_u {
+ mmr_t sh_md_dqls_mmr_ybist_h_regval;
+ struct {
+@@ -25622,25 +13856,12 @@
+ mmr_t reserved_0 : 21;
+ } sh_md_dqls_mmr_ybist_h_s;
+ } sh_md_dqls_mmr_ybist_h_u_t;
+-#else
+-typedef union sh_md_dqls_mmr_ybist_h_u {
+- mmr_t sh_md_dqls_mmr_ybist_h_regval;
+- struct {
+- mmr_t reserved_0 : 21;
+- mmr_t arm : 1;
+- mmr_t rot : 1;
+- mmr_t inv : 1;
+- mmr_t pat : 40;
+- } sh_md_dqls_mmr_ybist_h_s;
+-} sh_md_dqls_mmr_ybist_h_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLS_MMR_YBIST_L" */
+ /* falling edge bist/fill pattern */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqls_mmr_ybist_l_u {
+ mmr_t sh_md_dqls_mmr_ybist_l_regval;
+ struct {
+@@ -25650,24 +13871,12 @@
+ mmr_t reserved_0 : 22;
+ } sh_md_dqls_mmr_ybist_l_s;
+ } sh_md_dqls_mmr_ybist_l_u_t;
+-#else
+-typedef union sh_md_dqls_mmr_ybist_l_u {
+- mmr_t sh_md_dqls_mmr_ybist_l_regval;
+- struct {
+- mmr_t reserved_0 : 22;
+- mmr_t rot : 1;
+- mmr_t inv : 1;
+- mmr_t pat : 40;
+- } sh_md_dqls_mmr_ybist_l_s;
+-} sh_md_dqls_mmr_ybist_l_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLS_MMR_YBIST_ERR_H" */
+ /* rising edge bist error pattern */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqls_mmr_ybist_err_h_u {
+ mmr_t sh_md_dqls_mmr_ybist_err_h_regval;
+ struct {
+@@ -25677,24 +13886,12 @@
+ mmr_t reserved_0 : 22;
+ } sh_md_dqls_mmr_ybist_err_h_s;
+ } sh_md_dqls_mmr_ybist_err_h_u_t;
+-#else
+-typedef union sh_md_dqls_mmr_ybist_err_h_u {
+- mmr_t sh_md_dqls_mmr_ybist_err_h_regval;
+- struct {
+- mmr_t reserved_0 : 22;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t pat : 40;
+- } sh_md_dqls_mmr_ybist_err_h_s;
+-} sh_md_dqls_mmr_ybist_err_h_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLS_MMR_YBIST_ERR_L" */
+ /* falling edge bist error pattern */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqls_mmr_ybist_err_l_u {
+ mmr_t sh_md_dqls_mmr_ybist_err_l_regval;
+ struct {
+@@ -25704,24 +13901,12 @@
+ mmr_t reserved_0 : 22;
+ } sh_md_dqls_mmr_ybist_err_l_s;
+ } sh_md_dqls_mmr_ybist_err_l_u_t;
+-#else
+-typedef union sh_md_dqls_mmr_ybist_err_l_u {
+- mmr_t sh_md_dqls_mmr_ybist_err_l_regval;
+- struct {
+- mmr_t reserved_0 : 22;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t pat : 40;
+- } sh_md_dqls_mmr_ybist_err_l_s;
+-} sh_md_dqls_mmr_ybist_err_l_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLS_MMR_JNR_DEBUG" */
+ /* joiner/fct debug configuration */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqls_mmr_jnr_debug_u {
+ mmr_t sh_md_dqls_mmr_jnr_debug_regval;
+ struct {
+@@ -25730,23 +13915,12 @@
+ mmr_t reserved_0 : 62;
+ } sh_md_dqls_mmr_jnr_debug_s;
+ } sh_md_dqls_mmr_jnr_debug_u_t;
+-#else
+-typedef union sh_md_dqls_mmr_jnr_debug_u {
+- mmr_t sh_md_dqls_mmr_jnr_debug_regval;
+- struct {
+- mmr_t reserved_0 : 62;
+- mmr_t rw : 1;
+- mmr_t px : 1;
+- } sh_md_dqls_mmr_jnr_debug_s;
+-} sh_md_dqls_mmr_jnr_debug_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQLS_MMR_XAMOPW_ERR" */
+ /* amo/partial rmw ecc error register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqls_mmr_xamopw_err_u {
+ mmr_t sh_md_dqls_mmr_xamopw_err_regval;
+ struct {
+@@ -25762,30 +13936,12 @@
+ mmr_t reserved_2 : 31;
+ } sh_md_dqls_mmr_xamopw_err_s;
+ } sh_md_dqls_mmr_xamopw_err_u_t;
+-#else
+-typedef union sh_md_dqls_mmr_xamopw_err_u {
+- mmr_t sh_md_dqls_mmr_xamopw_err_regval;
+- struct {
+- mmr_t reserved_2 : 31;
+- mmr_t arm : 1;
+- mmr_t reserved_1 : 6;
+- mmr_t runc : 1;
+- mmr_t rcor : 1;
+- mmr_t rsyn : 8;
+- mmr_t reserved_0 : 6;
+- mmr_t sunc : 1;
+- mmr_t scor : 1;
+- mmr_t ssyn : 8;
+- } sh_md_dqls_mmr_xamopw_err_s;
+-} sh_md_dqls_mmr_xamopw_err_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_DIR_CONFIG" */
+ /* DQ directory config register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_dir_config_u {
+ mmr_t sh_md_dqrp_mmr_dir_config_regval;
+ struct {
+@@ -25795,276 +13951,156 @@
+ mmr_t reserved_0 : 59;
+ } sh_md_dqrp_mmr_dir_config_s;
+ } sh_md_dqrp_mmr_dir_config_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_dir_config_u {
+- mmr_t sh_md_dqrp_mmr_dir_config_regval;
+- struct {
+- mmr_t reserved_0 : 59;
+- mmr_t en_dirpois : 1;
+- mmr_t en_direcc : 1;
+- mmr_t sys_size : 3;
+- } sh_md_dqrp_mmr_dir_config_s;
+-} sh_md_dqrp_mmr_dir_config_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_DIR_PRESVEC0" */
+ /* node [63:0] presence bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqrp_mmr_dir_presvec0_u {
+- mmr_t sh_md_dqrp_mmr_dir_presvec0_regval;
+- struct {
+- mmr_t vec : 64;
+- } sh_md_dqrp_mmr_dir_presvec0_s;
+-} sh_md_dqrp_mmr_dir_presvec0_u_t;
+-#else
+ typedef union sh_md_dqrp_mmr_dir_presvec0_u {
+ mmr_t sh_md_dqrp_mmr_dir_presvec0_regval;
+ struct {
+ mmr_t vec : 64;
+ } sh_md_dqrp_mmr_dir_presvec0_s;
+ } sh_md_dqrp_mmr_dir_presvec0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_DIR_PRESVEC1" */
+ /* node [127:64] presence bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqrp_mmr_dir_presvec1_u {
+- mmr_t sh_md_dqrp_mmr_dir_presvec1_regval;
+- struct {
+- mmr_t vec : 64;
+- } sh_md_dqrp_mmr_dir_presvec1_s;
+-} sh_md_dqrp_mmr_dir_presvec1_u_t;
+-#else
+ typedef union sh_md_dqrp_mmr_dir_presvec1_u {
+ mmr_t sh_md_dqrp_mmr_dir_presvec1_regval;
+ struct {
+ mmr_t vec : 64;
+ } sh_md_dqrp_mmr_dir_presvec1_s;
+ } sh_md_dqrp_mmr_dir_presvec1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_DIR_PRESVEC2" */
+ /* node [191:128] presence bits */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqrp_mmr_dir_presvec2_u {
+- mmr_t sh_md_dqrp_mmr_dir_presvec2_regval;
+- struct {
+- mmr_t vec : 64;
+- } sh_md_dqrp_mmr_dir_presvec2_s;
+-} sh_md_dqrp_mmr_dir_presvec2_u_t;
+-#else
+ typedef union sh_md_dqrp_mmr_dir_presvec2_u {
+ mmr_t sh_md_dqrp_mmr_dir_presvec2_regval;
+ struct {
+ mmr_t vec : 64;
+ } sh_md_dqrp_mmr_dir_presvec2_s;
+ } sh_md_dqrp_mmr_dir_presvec2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_DIR_PRESVEC3" */
+-/* node [255:192] presence bits */
+-/* ==================================================================== */
+-
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqrp_mmr_dir_presvec3_u {
+- mmr_t sh_md_dqrp_mmr_dir_presvec3_regval;
+- struct {
+- mmr_t vec : 64;
+- } sh_md_dqrp_mmr_dir_presvec3_s;
+-} sh_md_dqrp_mmr_dir_presvec3_u_t;
+-#else
++/* node [255:192] presence bits */
++/* ==================================================================== */
++
+ typedef union sh_md_dqrp_mmr_dir_presvec3_u {
+ mmr_t sh_md_dqrp_mmr_dir_presvec3_regval;
+ struct {
+ mmr_t vec : 64;
+ } sh_md_dqrp_mmr_dir_presvec3_s;
+ } sh_md_dqrp_mmr_dir_presvec3_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_DIR_LOCVEC0" */
+ /* local vector for acc=0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqrp_mmr_dir_locvec0_u {
+- mmr_t sh_md_dqrp_mmr_dir_locvec0_regval;
+- struct {
+- mmr_t vec : 64;
+- } sh_md_dqrp_mmr_dir_locvec0_s;
+-} sh_md_dqrp_mmr_dir_locvec0_u_t;
+-#else
+ typedef union sh_md_dqrp_mmr_dir_locvec0_u {
+ mmr_t sh_md_dqrp_mmr_dir_locvec0_regval;
+ struct {
+ mmr_t vec : 64;
+ } sh_md_dqrp_mmr_dir_locvec0_s;
+ } sh_md_dqrp_mmr_dir_locvec0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_DIR_LOCVEC1" */
+ /* local vector for acc=1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqrp_mmr_dir_locvec1_u {
+- mmr_t sh_md_dqrp_mmr_dir_locvec1_regval;
+- struct {
+- mmr_t vec : 64;
+- } sh_md_dqrp_mmr_dir_locvec1_s;
+-} sh_md_dqrp_mmr_dir_locvec1_u_t;
+-#else
+ typedef union sh_md_dqrp_mmr_dir_locvec1_u {
+ mmr_t sh_md_dqrp_mmr_dir_locvec1_regval;
+ struct {
+ mmr_t vec : 64;
+ } sh_md_dqrp_mmr_dir_locvec1_s;
+ } sh_md_dqrp_mmr_dir_locvec1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_DIR_LOCVEC2" */
+ /* local vector for acc=2 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqrp_mmr_dir_locvec2_u {
+- mmr_t sh_md_dqrp_mmr_dir_locvec2_regval;
+- struct {
+- mmr_t vec : 64;
+- } sh_md_dqrp_mmr_dir_locvec2_s;
+-} sh_md_dqrp_mmr_dir_locvec2_u_t;
+-#else
+ typedef union sh_md_dqrp_mmr_dir_locvec2_u {
+ mmr_t sh_md_dqrp_mmr_dir_locvec2_regval;
+ struct {
+ mmr_t vec : 64;
+ } sh_md_dqrp_mmr_dir_locvec2_s;
+ } sh_md_dqrp_mmr_dir_locvec2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_DIR_LOCVEC3" */
+ /* local vector for acc=3 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqrp_mmr_dir_locvec3_u {
+- mmr_t sh_md_dqrp_mmr_dir_locvec3_regval;
+- struct {
+- mmr_t vec : 64;
+- } sh_md_dqrp_mmr_dir_locvec3_s;
+-} sh_md_dqrp_mmr_dir_locvec3_u_t;
+-#else
+ typedef union sh_md_dqrp_mmr_dir_locvec3_u {
+ mmr_t sh_md_dqrp_mmr_dir_locvec3_regval;
+ struct {
+ mmr_t vec : 64;
+ } sh_md_dqrp_mmr_dir_locvec3_s;
+ } sh_md_dqrp_mmr_dir_locvec3_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_DIR_LOCVEC4" */
+ /* local vector for acc=4 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqrp_mmr_dir_locvec4_u {
+- mmr_t sh_md_dqrp_mmr_dir_locvec4_regval;
+- struct {
+- mmr_t vec : 64;
+- } sh_md_dqrp_mmr_dir_locvec4_s;
+-} sh_md_dqrp_mmr_dir_locvec4_u_t;
+-#else
+ typedef union sh_md_dqrp_mmr_dir_locvec4_u {
+ mmr_t sh_md_dqrp_mmr_dir_locvec4_regval;
+ struct {
+ mmr_t vec : 64;
+ } sh_md_dqrp_mmr_dir_locvec4_s;
+ } sh_md_dqrp_mmr_dir_locvec4_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_DIR_LOCVEC5" */
+ /* local vector for acc=5 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqrp_mmr_dir_locvec5_u {
+- mmr_t sh_md_dqrp_mmr_dir_locvec5_regval;
+- struct {
+- mmr_t vec : 64;
+- } sh_md_dqrp_mmr_dir_locvec5_s;
+-} sh_md_dqrp_mmr_dir_locvec5_u_t;
+-#else
+ typedef union sh_md_dqrp_mmr_dir_locvec5_u {
+ mmr_t sh_md_dqrp_mmr_dir_locvec5_regval;
+ struct {
+ mmr_t vec : 64;
+ } sh_md_dqrp_mmr_dir_locvec5_s;
+ } sh_md_dqrp_mmr_dir_locvec5_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_DIR_LOCVEC6" */
+ /* local vector for acc=6 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqrp_mmr_dir_locvec6_u {
+- mmr_t sh_md_dqrp_mmr_dir_locvec6_regval;
+- struct {
+- mmr_t vec : 64;
+- } sh_md_dqrp_mmr_dir_locvec6_s;
+-} sh_md_dqrp_mmr_dir_locvec6_u_t;
+-#else
+ typedef union sh_md_dqrp_mmr_dir_locvec6_u {
+ mmr_t sh_md_dqrp_mmr_dir_locvec6_regval;
+ struct {
+ mmr_t vec : 64;
+ } sh_md_dqrp_mmr_dir_locvec6_s;
+ } sh_md_dqrp_mmr_dir_locvec6_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_DIR_LOCVEC7" */
+ /* local vector for acc=7 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqrp_mmr_dir_locvec7_u {
+- mmr_t sh_md_dqrp_mmr_dir_locvec7_regval;
+- struct {
+- mmr_t vec : 64;
+- } sh_md_dqrp_mmr_dir_locvec7_s;
+-} sh_md_dqrp_mmr_dir_locvec7_u_t;
+-#else
+ typedef union sh_md_dqrp_mmr_dir_locvec7_u {
+ mmr_t sh_md_dqrp_mmr_dir_locvec7_regval;
+ struct {
+ mmr_t vec : 64;
+ } sh_md_dqrp_mmr_dir_locvec7_s;
+ } sh_md_dqrp_mmr_dir_locvec7_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_DIR_PRIVEC0" */
+ /* privilege vector for acc=0 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_dir_privec0_u {
+ mmr_t sh_md_dqrp_mmr_dir_privec0_regval;
+ struct {
+@@ -26073,23 +14109,12 @@
+ mmr_t reserved_0 : 36;
+ } sh_md_dqrp_mmr_dir_privec0_s;
+ } sh_md_dqrp_mmr_dir_privec0_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_dir_privec0_u {
+- mmr_t sh_md_dqrp_mmr_dir_privec0_regval;
+- struct {
+- mmr_t reserved_0 : 36;
+- mmr_t out : 14;
+- mmr_t in : 14;
+- } sh_md_dqrp_mmr_dir_privec0_s;
+-} sh_md_dqrp_mmr_dir_privec0_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_DIR_PRIVEC1" */
+ /* privilege vector for acc=1 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_dir_privec1_u {
+ mmr_t sh_md_dqrp_mmr_dir_privec1_regval;
+ struct {
+@@ -26098,23 +14123,12 @@
+ mmr_t reserved_0 : 36;
+ } sh_md_dqrp_mmr_dir_privec1_s;
+ } sh_md_dqrp_mmr_dir_privec1_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_dir_privec1_u {
+- mmr_t sh_md_dqrp_mmr_dir_privec1_regval;
+- struct {
+- mmr_t reserved_0 : 36;
+- mmr_t out : 14;
+- mmr_t in : 14;
+- } sh_md_dqrp_mmr_dir_privec1_s;
+-} sh_md_dqrp_mmr_dir_privec1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_DIR_PRIVEC2" */
+ /* privilege vector for acc=2 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_dir_privec2_u {
+ mmr_t sh_md_dqrp_mmr_dir_privec2_regval;
+ struct {
+@@ -26123,23 +14137,12 @@
+ mmr_t reserved_0 : 36;
+ } sh_md_dqrp_mmr_dir_privec2_s;
+ } sh_md_dqrp_mmr_dir_privec2_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_dir_privec2_u {
+- mmr_t sh_md_dqrp_mmr_dir_privec2_regval;
+- struct {
+- mmr_t reserved_0 : 36;
+- mmr_t out : 14;
+- mmr_t in : 14;
+- } sh_md_dqrp_mmr_dir_privec2_s;
+-} sh_md_dqrp_mmr_dir_privec2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_DIR_PRIVEC3" */
+ /* privilege vector for acc=3 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_dir_privec3_u {
+ mmr_t sh_md_dqrp_mmr_dir_privec3_regval;
+ struct {
+@@ -26148,23 +14151,12 @@
+ mmr_t reserved_0 : 36;
+ } sh_md_dqrp_mmr_dir_privec3_s;
+ } sh_md_dqrp_mmr_dir_privec3_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_dir_privec3_u {
+- mmr_t sh_md_dqrp_mmr_dir_privec3_regval;
+- struct {
+- mmr_t reserved_0 : 36;
+- mmr_t out : 14;
+- mmr_t in : 14;
+- } sh_md_dqrp_mmr_dir_privec3_s;
+-} sh_md_dqrp_mmr_dir_privec3_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_DIR_PRIVEC4" */
+ /* privilege vector for acc=4 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_dir_privec4_u {
+ mmr_t sh_md_dqrp_mmr_dir_privec4_regval;
+ struct {
+@@ -26173,23 +14165,12 @@
+ mmr_t reserved_0 : 36;
+ } sh_md_dqrp_mmr_dir_privec4_s;
+ } sh_md_dqrp_mmr_dir_privec4_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_dir_privec4_u {
+- mmr_t sh_md_dqrp_mmr_dir_privec4_regval;
+- struct {
+- mmr_t reserved_0 : 36;
+- mmr_t out : 14;
+- mmr_t in : 14;
+- } sh_md_dqrp_mmr_dir_privec4_s;
+-} sh_md_dqrp_mmr_dir_privec4_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_DIR_PRIVEC5" */
+ /* privilege vector for acc=5 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_dir_privec5_u {
+ mmr_t sh_md_dqrp_mmr_dir_privec5_regval;
+ struct {
+@@ -26198,23 +14179,12 @@
+ mmr_t reserved_0 : 36;
+ } sh_md_dqrp_mmr_dir_privec5_s;
+ } sh_md_dqrp_mmr_dir_privec5_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_dir_privec5_u {
+- mmr_t sh_md_dqrp_mmr_dir_privec5_regval;
+- struct {
+- mmr_t reserved_0 : 36;
+- mmr_t out : 14;
+- mmr_t in : 14;
+- } sh_md_dqrp_mmr_dir_privec5_s;
+-} sh_md_dqrp_mmr_dir_privec5_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_DIR_PRIVEC6" */
+ /* privilege vector for acc=6 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_dir_privec6_u {
+ mmr_t sh_md_dqrp_mmr_dir_privec6_regval;
+ struct {
+@@ -26223,23 +14193,12 @@
+ mmr_t reserved_0 : 36;
+ } sh_md_dqrp_mmr_dir_privec6_s;
+ } sh_md_dqrp_mmr_dir_privec6_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_dir_privec6_u {
+- mmr_t sh_md_dqrp_mmr_dir_privec6_regval;
+- struct {
+- mmr_t reserved_0 : 36;
+- mmr_t out : 14;
+- mmr_t in : 14;
+- } sh_md_dqrp_mmr_dir_privec6_s;
+-} sh_md_dqrp_mmr_dir_privec6_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_DIR_PRIVEC7" */
+ /* privilege vector for acc=7 */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_dir_privec7_u {
+ mmr_t sh_md_dqrp_mmr_dir_privec7_regval;
+ struct {
+@@ -26248,23 +14207,12 @@
+ mmr_t reserved_0 : 36;
+ } sh_md_dqrp_mmr_dir_privec7_s;
+ } sh_md_dqrp_mmr_dir_privec7_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_dir_privec7_u {
+- mmr_t sh_md_dqrp_mmr_dir_privec7_regval;
+- struct {
+- mmr_t reserved_0 : 36;
+- mmr_t out : 14;
+- mmr_t in : 14;
+- } sh_md_dqrp_mmr_dir_privec7_s;
+-} sh_md_dqrp_mmr_dir_privec7_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_DIR_TIMER" */
+ /* MD SXRO timer */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_dir_timer_u {
+ mmr_t sh_md_dqrp_mmr_dir_timer_regval;
+ struct {
+@@ -26274,24 +14222,12 @@
+ mmr_t reserved_0 : 42;
+ } sh_md_dqrp_mmr_dir_timer_s;
+ } sh_md_dqrp_mmr_dir_timer_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_dir_timer_u {
+- mmr_t sh_md_dqrp_mmr_dir_timer_regval;
+- struct {
+- mmr_t reserved_0 : 42;
+- mmr_t timer_cur : 9;
+- mmr_t timer_en : 1;
+- mmr_t timer_div : 12;
+- } sh_md_dqrp_mmr_dir_timer_s;
+-} sh_md_dqrp_mmr_dir_timer_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_PIOWD_DIR_ENTRY" */
+ /* directory pio write data */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_piowd_dir_entry_u {
+ mmr_t sh_md_dqrp_mmr_piowd_dir_entry_regval;
+ struct {
+@@ -26302,25 +14238,12 @@
+ mmr_t reserved_0 : 6;
+ } sh_md_dqrp_mmr_piowd_dir_entry_s;
+ } sh_md_dqrp_mmr_piowd_dir_entry_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_piowd_dir_entry_u {
+- mmr_t sh_md_dqrp_mmr_piowd_dir_entry_regval;
+- struct {
+- mmr_t reserved_0 : 6;
+- mmr_t acc : 3;
+- mmr_t pri : 3;
+- mmr_t dirb : 26;
+- mmr_t dira : 26;
+- } sh_md_dqrp_mmr_piowd_dir_entry_s;
+-} sh_md_dqrp_mmr_piowd_dir_entry_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_PIOWD_DIR_ECC" */
+ /* directory ecc register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_piowd_dir_ecc_u {
+ mmr_t sh_md_dqrp_mmr_piowd_dir_ecc_regval;
+ struct {
+@@ -26329,23 +14252,12 @@
+ mmr_t reserved_0 : 50;
+ } sh_md_dqrp_mmr_piowd_dir_ecc_s;
+ } sh_md_dqrp_mmr_piowd_dir_ecc_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_piowd_dir_ecc_u {
+- mmr_t sh_md_dqrp_mmr_piowd_dir_ecc_regval;
+- struct {
+- mmr_t reserved_0 : 50;
+- mmr_t eccb : 7;
+- mmr_t ecca : 7;
+- } sh_md_dqrp_mmr_piowd_dir_ecc_s;
+-} sh_md_dqrp_mmr_piowd_dir_ecc_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_XPIORD_XDIR_ENTRY" */
+ /* x directory pio read data */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_xpiord_xdir_entry_u {
+ mmr_t sh_md_dqrp_mmr_xpiord_xdir_entry_regval;
+ struct {
+@@ -26358,27 +14270,12 @@
+ mmr_t reserved_0 : 4;
+ } sh_md_dqrp_mmr_xpiord_xdir_entry_s;
+ } sh_md_dqrp_mmr_xpiord_xdir_entry_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_xpiord_xdir_entry_u {
+- mmr_t sh_md_dqrp_mmr_xpiord_xdir_entry_regval;
+- struct {
+- mmr_t reserved_0 : 4;
+- mmr_t unc : 1;
+- mmr_t cor : 1;
+- mmr_t acc : 3;
+- mmr_t pri : 3;
+- mmr_t dirb : 26;
+- mmr_t dira : 26;
+- } sh_md_dqrp_mmr_xpiord_xdir_entry_s;
+-} sh_md_dqrp_mmr_xpiord_xdir_entry_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_XPIORD_XDIR_ECC" */
+ /* x directory ecc */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_xpiord_xdir_ecc_u {
+ mmr_t sh_md_dqrp_mmr_xpiord_xdir_ecc_regval;
+ struct {
+@@ -26387,23 +14284,12 @@
+ mmr_t reserved_0 : 50;
+ } sh_md_dqrp_mmr_xpiord_xdir_ecc_s;
+ } sh_md_dqrp_mmr_xpiord_xdir_ecc_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_xpiord_xdir_ecc_u {
+- mmr_t sh_md_dqrp_mmr_xpiord_xdir_ecc_regval;
+- struct {
+- mmr_t reserved_0 : 50;
+- mmr_t eccb : 7;
+- mmr_t ecca : 7;
+- } sh_md_dqrp_mmr_xpiord_xdir_ecc_s;
+-} sh_md_dqrp_mmr_xpiord_xdir_ecc_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_YPIORD_YDIR_ENTRY" */
+ /* y directory pio read data */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_ypiord_ydir_entry_u {
+ mmr_t sh_md_dqrp_mmr_ypiord_ydir_entry_regval;
+ struct {
+@@ -26416,27 +14302,12 @@
+ mmr_t reserved_0 : 4;
+ } sh_md_dqrp_mmr_ypiord_ydir_entry_s;
+ } sh_md_dqrp_mmr_ypiord_ydir_entry_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_ypiord_ydir_entry_u {
+- mmr_t sh_md_dqrp_mmr_ypiord_ydir_entry_regval;
+- struct {
+- mmr_t reserved_0 : 4;
+- mmr_t unc : 1;
+- mmr_t cor : 1;
+- mmr_t acc : 3;
+- mmr_t pri : 3;
+- mmr_t dirb : 26;
+- mmr_t dira : 26;
+- } sh_md_dqrp_mmr_ypiord_ydir_entry_s;
+-} sh_md_dqrp_mmr_ypiord_ydir_entry_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_YPIORD_YDIR_ECC" */
+ /* y directory ecc */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_ypiord_ydir_ecc_u {
+ mmr_t sh_md_dqrp_mmr_ypiord_ydir_ecc_regval;
+ struct {
+@@ -26445,23 +14316,12 @@
+ mmr_t reserved_0 : 50;
+ } sh_md_dqrp_mmr_ypiord_ydir_ecc_s;
+ } sh_md_dqrp_mmr_ypiord_ydir_ecc_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_ypiord_ydir_ecc_u {
+- mmr_t sh_md_dqrp_mmr_ypiord_ydir_ecc_regval;
+- struct {
+- mmr_t reserved_0 : 50;
+- mmr_t eccb : 7;
+- mmr_t ecca : 7;
+- } sh_md_dqrp_mmr_ypiord_ydir_ecc_s;
+-} sh_md_dqrp_mmr_ypiord_ydir_ecc_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_XCERR1" */
+ /* correctable dir ecc group 1 error register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_xcerr1_u {
+ mmr_t sh_md_dqrp_mmr_xcerr1_regval;
+ struct {
+@@ -26472,25 +14332,12 @@
+ mmr_t reserved_0 : 25;
+ } sh_md_dqrp_mmr_xcerr1_s;
+ } sh_md_dqrp_mmr_xcerr1_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_xcerr1_u {
+- mmr_t sh_md_dqrp_mmr_xcerr1_regval;
+- struct {
+- mmr_t reserved_0 : 25;
+- mmr_t arm : 1;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t grp1 : 36;
+- } sh_md_dqrp_mmr_xcerr1_s;
+-} sh_md_dqrp_mmr_xcerr1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_XCERR2" */
+ /* correctable dir ecc group 2 error register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_xcerr2_u {
+ mmr_t sh_md_dqrp_mmr_xcerr2_regval;
+ struct {
+@@ -26500,24 +14347,12 @@
+ mmr_t reserved_0 : 26;
+ } sh_md_dqrp_mmr_xcerr2_s;
+ } sh_md_dqrp_mmr_xcerr2_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_xcerr2_u {
+- mmr_t sh_md_dqrp_mmr_xcerr2_regval;
+- struct {
+- mmr_t reserved_0 : 26;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t grp2 : 36;
+- } sh_md_dqrp_mmr_xcerr2_s;
+-} sh_md_dqrp_mmr_xcerr2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_XUERR1" */
+ /* uncorrectable dir ecc group 1 error register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_xuerr1_u {
+ mmr_t sh_md_dqrp_mmr_xuerr1_regval;
+ struct {
+@@ -26528,25 +14363,12 @@
+ mmr_t reserved_0 : 25;
+ } sh_md_dqrp_mmr_xuerr1_s;
+ } sh_md_dqrp_mmr_xuerr1_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_xuerr1_u {
+- mmr_t sh_md_dqrp_mmr_xuerr1_regval;
+- struct {
+- mmr_t reserved_0 : 25;
+- mmr_t arm : 1;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t grp1 : 36;
+- } sh_md_dqrp_mmr_xuerr1_s;
+-} sh_md_dqrp_mmr_xuerr1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_XUERR2" */
+ /* uncorrectable dir ecc group 2 error register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_xuerr2_u {
+ mmr_t sh_md_dqrp_mmr_xuerr2_regval;
+ struct {
+@@ -26556,24 +14378,12 @@
+ mmr_t reserved_0 : 26;
+ } sh_md_dqrp_mmr_xuerr2_s;
+ } sh_md_dqrp_mmr_xuerr2_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_xuerr2_u {
+- mmr_t sh_md_dqrp_mmr_xuerr2_regval;
+- struct {
+- mmr_t reserved_0 : 26;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t grp2 : 36;
+- } sh_md_dqrp_mmr_xuerr2_s;
+-} sh_md_dqrp_mmr_xuerr2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_XPERR" */
+ /* protocol error register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_xperr_u {
+ mmr_t sh_md_dqrp_mmr_xperr_regval;
+ struct {
+@@ -26591,32 +14401,12 @@
+ mmr_t reserved_0 : 1;
+ } sh_md_dqrp_mmr_xperr_s;
+ } sh_md_dqrp_mmr_xperr_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_xperr_u {
+- mmr_t sh_md_dqrp_mmr_xperr_regval;
+- struct {
+- mmr_t reserved_0 : 1;
+- mmr_t arm : 1;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t mybit : 8;
+- mmr_t unc : 1;
+- mmr_t cor : 1;
+- mmr_t priv : 1;
+- mmr_t prige : 1;
+- mmr_t src : 14;
+- mmr_t cmd : 8;
+- mmr_t dir : 26;
+- } sh_md_dqrp_mmr_xperr_s;
+-} sh_md_dqrp_mmr_xperr_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_YCERR1" */
+ /* correctable dir ecc group 1 error register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_ycerr1_u {
+ mmr_t sh_md_dqrp_mmr_ycerr1_regval;
+ struct {
+@@ -26627,52 +14417,27 @@
+ mmr_t reserved_0 : 25;
+ } sh_md_dqrp_mmr_ycerr1_s;
+ } sh_md_dqrp_mmr_ycerr1_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_ycerr1_u {
+- mmr_t sh_md_dqrp_mmr_ycerr1_regval;
+- struct {
+- mmr_t reserved_0 : 25;
+- mmr_t arm : 1;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t grp1 : 36;
+- } sh_md_dqrp_mmr_ycerr1_s;
+-} sh_md_dqrp_mmr_ycerr1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_YCERR2" */
+ /* correctable dir ecc group 2 error register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqrp_mmr_ycerr2_u {
+- mmr_t sh_md_dqrp_mmr_ycerr2_regval;
+- struct {
+- mmr_t grp2 : 36;
+- mmr_t val : 1;
+- mmr_t more : 1;
+- mmr_t reserved_0 : 26;
+- } sh_md_dqrp_mmr_ycerr2_s;
+-} sh_md_dqrp_mmr_ycerr2_u_t;
+-#else
+ typedef union sh_md_dqrp_mmr_ycerr2_u {
+ mmr_t sh_md_dqrp_mmr_ycerr2_regval;
+ struct {
+- mmr_t reserved_0 : 26;
+- mmr_t more : 1;
+- mmr_t val : 1;
+ mmr_t grp2 : 36;
++ mmr_t val : 1;
++ mmr_t more : 1;
++ mmr_t reserved_0 : 26;
+ } sh_md_dqrp_mmr_ycerr2_s;
+ } sh_md_dqrp_mmr_ycerr2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_YUERR1" */
+ /* uncorrectable dir ecc group 1 error register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_yuerr1_u {
+ mmr_t sh_md_dqrp_mmr_yuerr1_regval;
+ struct {
+@@ -26683,25 +14448,12 @@
+ mmr_t reserved_0 : 25;
+ } sh_md_dqrp_mmr_yuerr1_s;
+ } sh_md_dqrp_mmr_yuerr1_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_yuerr1_u {
+- mmr_t sh_md_dqrp_mmr_yuerr1_regval;
+- struct {
+- mmr_t reserved_0 : 25;
+- mmr_t arm : 1;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t grp1 : 36;
+- } sh_md_dqrp_mmr_yuerr1_s;
+-} sh_md_dqrp_mmr_yuerr1_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_YUERR2" */
+ /* uncorrectable dir ecc group 2 error register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_yuerr2_u {
+ mmr_t sh_md_dqrp_mmr_yuerr2_regval;
+ struct {
+@@ -26711,24 +14463,12 @@
+ mmr_t reserved_0 : 26;
+ } sh_md_dqrp_mmr_yuerr2_s;
+ } sh_md_dqrp_mmr_yuerr2_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_yuerr2_u {
+- mmr_t sh_md_dqrp_mmr_yuerr2_regval;
+- struct {
+- mmr_t reserved_0 : 26;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t grp2 : 36;
+- } sh_md_dqrp_mmr_yuerr2_s;
+-} sh_md_dqrp_mmr_yuerr2_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_YPERR" */
+ /* protocol error register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_yperr_u {
+ mmr_t sh_md_dqrp_mmr_yperr_regval;
+ struct {
+@@ -26746,32 +14486,12 @@
+ mmr_t reserved_0 : 1;
+ } sh_md_dqrp_mmr_yperr_s;
+ } sh_md_dqrp_mmr_yperr_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_yperr_u {
+- mmr_t sh_md_dqrp_mmr_yperr_regval;
+- struct {
+- mmr_t reserved_0 : 1;
+- mmr_t arm : 1;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t mybit : 8;
+- mmr_t unc : 1;
+- mmr_t cor : 1;
+- mmr_t priv : 1;
+- mmr_t prige : 1;
+- mmr_t src : 14;
+- mmr_t cmd : 8;
+- mmr_t dir : 26;
+- } sh_md_dqrp_mmr_yperr_s;
+-} sh_md_dqrp_mmr_yperr_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_DIR_CMDTRIG" */
+ /* cmd triggers */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_dir_cmdtrig_u {
+ mmr_t sh_md_dqrp_mmr_dir_cmdtrig_regval;
+ struct {
+@@ -26782,25 +14502,12 @@
+ mmr_t reserved_0 : 32;
+ } sh_md_dqrp_mmr_dir_cmdtrig_s;
+ } sh_md_dqrp_mmr_dir_cmdtrig_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_dir_cmdtrig_u {
+- mmr_t sh_md_dqrp_mmr_dir_cmdtrig_regval;
+- struct {
+- mmr_t reserved_0 : 32;
+- mmr_t cmd3 : 8;
+- mmr_t cmd2 : 8;
+- mmr_t cmd1 : 8;
+- mmr_t cmd0 : 8;
+- } sh_md_dqrp_mmr_dir_cmdtrig_s;
+-} sh_md_dqrp_mmr_dir_cmdtrig_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_DIR_TBLTRIG" */
+ /* dir table trigger */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_dir_tbltrig_u {
+ mmr_t sh_md_dqrp_mmr_dir_tbltrig_regval;
+ struct {
+@@ -26813,27 +14520,12 @@
+ mmr_t reserved_0 : 22;
+ } sh_md_dqrp_mmr_dir_tbltrig_s;
+ } sh_md_dqrp_mmr_dir_tbltrig_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_dir_tbltrig_u {
+- mmr_t sh_md_dqrp_mmr_dir_tbltrig_regval;
+- struct {
+- mmr_t reserved_0 : 22;
+- mmr_t mybit : 8;
+- mmr_t dirst : 9;
+- mmr_t prige : 1;
+- mmr_t acc : 2;
+- mmr_t cmd : 8;
+- mmr_t src : 14;
+- } sh_md_dqrp_mmr_dir_tbltrig_s;
+-} sh_md_dqrp_mmr_dir_tbltrig_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_DIR_TBLMASK" */
+ /* dir table trigger mask */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_dir_tblmask_u {
+ mmr_t sh_md_dqrp_mmr_dir_tblmask_regval;
+ struct {
+@@ -26846,27 +14538,12 @@
+ mmr_t reserved_0 : 22;
+ } sh_md_dqrp_mmr_dir_tblmask_s;
+ } sh_md_dqrp_mmr_dir_tblmask_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_dir_tblmask_u {
+- mmr_t sh_md_dqrp_mmr_dir_tblmask_regval;
+- struct {
+- mmr_t reserved_0 : 22;
+- mmr_t mybit : 8;
+- mmr_t dirst : 9;
+- mmr_t prige : 1;
+- mmr_t acc : 2;
+- mmr_t cmd : 8;
+- mmr_t src : 14;
+- } sh_md_dqrp_mmr_dir_tblmask_s;
+-} sh_md_dqrp_mmr_dir_tblmask_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_XBIST_H" */
+ /* rising edge bist/fill pattern */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_xbist_h_u {
+ mmr_t sh_md_dqrp_mmr_xbist_h_regval;
+ struct {
+@@ -26878,26 +14555,12 @@
+ mmr_t reserved_1 : 21;
+ } sh_md_dqrp_mmr_xbist_h_s;
+ } sh_md_dqrp_mmr_xbist_h_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_xbist_h_u {
+- mmr_t sh_md_dqrp_mmr_xbist_h_regval;
+- struct {
+- mmr_t reserved_1 : 21;
+- mmr_t arm : 1;
+- mmr_t rot : 1;
+- mmr_t inv : 1;
+- mmr_t reserved_0 : 8;
+- mmr_t pat : 32;
+- } sh_md_dqrp_mmr_xbist_h_s;
+-} sh_md_dqrp_mmr_xbist_h_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_XBIST_L" */
+ /* falling edge bist/fill pattern */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_xbist_l_u {
+ mmr_t sh_md_dqrp_mmr_xbist_l_regval;
+ struct {
+@@ -26908,25 +14571,12 @@
+ mmr_t reserved_1 : 22;
+ } sh_md_dqrp_mmr_xbist_l_s;
+ } sh_md_dqrp_mmr_xbist_l_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_xbist_l_u {
+- mmr_t sh_md_dqrp_mmr_xbist_l_regval;
+- struct {
+- mmr_t reserved_1 : 22;
+- mmr_t rot : 1;
+- mmr_t inv : 1;
+- mmr_t reserved_0 : 8;
+- mmr_t pat : 32;
+- } sh_md_dqrp_mmr_xbist_l_s;
+-} sh_md_dqrp_mmr_xbist_l_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_XBIST_ERR_H" */
+ /* rising edge bist error pattern */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_xbist_err_h_u {
+ mmr_t sh_md_dqrp_mmr_xbist_err_h_regval;
+ struct {
+@@ -26937,25 +14587,12 @@
+ mmr_t reserved_1 : 22;
+ } sh_md_dqrp_mmr_xbist_err_h_s;
+ } sh_md_dqrp_mmr_xbist_err_h_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_xbist_err_h_u {
+- mmr_t sh_md_dqrp_mmr_xbist_err_h_regval;
+- struct {
+- mmr_t reserved_1 : 22;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t reserved_0 : 8;
+- mmr_t pat : 32;
+- } sh_md_dqrp_mmr_xbist_err_h_s;
+-} sh_md_dqrp_mmr_xbist_err_h_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_XBIST_ERR_L" */
+ /* falling edge bist error pattern */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_xbist_err_l_u {
+ mmr_t sh_md_dqrp_mmr_xbist_err_l_regval;
+ struct {
+@@ -26966,25 +14603,12 @@
+ mmr_t reserved_1 : 22;
+ } sh_md_dqrp_mmr_xbist_err_l_s;
+ } sh_md_dqrp_mmr_xbist_err_l_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_xbist_err_l_u {
+- mmr_t sh_md_dqrp_mmr_xbist_err_l_regval;
+- struct {
+- mmr_t reserved_1 : 22;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t reserved_0 : 8;
+- mmr_t pat : 32;
+- } sh_md_dqrp_mmr_xbist_err_l_s;
+-} sh_md_dqrp_mmr_xbist_err_l_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_YBIST_H" */
+ /* rising edge bist/fill pattern */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_ybist_h_u {
+ mmr_t sh_md_dqrp_mmr_ybist_h_regval;
+ struct {
+@@ -26996,26 +14620,12 @@
+ mmr_t reserved_1 : 21;
+ } sh_md_dqrp_mmr_ybist_h_s;
+ } sh_md_dqrp_mmr_ybist_h_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_ybist_h_u {
+- mmr_t sh_md_dqrp_mmr_ybist_h_regval;
+- struct {
+- mmr_t reserved_1 : 21;
+- mmr_t arm : 1;
+- mmr_t rot : 1;
+- mmr_t inv : 1;
+- mmr_t reserved_0 : 8;
+- mmr_t pat : 32;
+- } sh_md_dqrp_mmr_ybist_h_s;
+-} sh_md_dqrp_mmr_ybist_h_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_YBIST_L" */
+ /* falling edge bist/fill pattern */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_ybist_l_u {
+ mmr_t sh_md_dqrp_mmr_ybist_l_regval;
+ struct {
+@@ -27026,25 +14636,12 @@
+ mmr_t reserved_1 : 22;
+ } sh_md_dqrp_mmr_ybist_l_s;
+ } sh_md_dqrp_mmr_ybist_l_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_ybist_l_u {
+- mmr_t sh_md_dqrp_mmr_ybist_l_regval;
+- struct {
+- mmr_t reserved_1 : 22;
+- mmr_t rot : 1;
+- mmr_t inv : 1;
+- mmr_t reserved_0 : 8;
+- mmr_t pat : 32;
+- } sh_md_dqrp_mmr_ybist_l_s;
+-} sh_md_dqrp_mmr_ybist_l_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_YBIST_ERR_H" */
+ /* rising edge bist error pattern */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_ybist_err_h_u {
+ mmr_t sh_md_dqrp_mmr_ybist_err_h_regval;
+ struct {
+@@ -27055,25 +14652,12 @@
+ mmr_t reserved_1 : 22;
+ } sh_md_dqrp_mmr_ybist_err_h_s;
+ } sh_md_dqrp_mmr_ybist_err_h_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_ybist_err_h_u {
+- mmr_t sh_md_dqrp_mmr_ybist_err_h_regval;
+- struct {
+- mmr_t reserved_1 : 22;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t reserved_0 : 8;
+- mmr_t pat : 32;
+- } sh_md_dqrp_mmr_ybist_err_h_s;
+-} sh_md_dqrp_mmr_ybist_err_h_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRP_MMR_YBIST_ERR_L" */
+ /* falling edge bist error pattern */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_ybist_err_l_u {
+ mmr_t sh_md_dqrp_mmr_ybist_err_l_regval;
+ struct {
+@@ -27084,25 +14668,12 @@
+ mmr_t reserved_1 : 22;
+ } sh_md_dqrp_mmr_ybist_err_l_s;
+ } sh_md_dqrp_mmr_ybist_err_l_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_ybist_err_l_u {
+- mmr_t sh_md_dqrp_mmr_ybist_err_l_regval;
+- struct {
+- mmr_t reserved_1 : 22;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t reserved_0 : 8;
+- mmr_t pat : 32;
+- } sh_md_dqrp_mmr_ybist_err_l_s;
+-} sh_md_dqrp_mmr_ybist_err_l_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRS_MMR_XBIST_H" */
+ /* rising edge bist/fill pattern */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrs_mmr_xbist_h_u {
+ mmr_t sh_md_dqrs_mmr_xbist_h_regval;
+ struct {
+@@ -27113,25 +14684,12 @@
+ mmr_t reserved_0 : 21;
+ } sh_md_dqrs_mmr_xbist_h_s;
+ } sh_md_dqrs_mmr_xbist_h_u_t;
+-#else
+-typedef union sh_md_dqrs_mmr_xbist_h_u {
+- mmr_t sh_md_dqrs_mmr_xbist_h_regval;
+- struct {
+- mmr_t reserved_0 : 21;
+- mmr_t arm : 1;
+- mmr_t rot : 1;
+- mmr_t inv : 1;
+- mmr_t pat : 40;
+- } sh_md_dqrs_mmr_xbist_h_s;
+-} sh_md_dqrs_mmr_xbist_h_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRS_MMR_XBIST_L" */
+ /* falling edge bist/fill pattern */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrs_mmr_xbist_l_u {
+ mmr_t sh_md_dqrs_mmr_xbist_l_regval;
+ struct {
+@@ -27141,24 +14699,12 @@
+ mmr_t reserved_0 : 22;
+ } sh_md_dqrs_mmr_xbist_l_s;
+ } sh_md_dqrs_mmr_xbist_l_u_t;
+-#else
+-typedef union sh_md_dqrs_mmr_xbist_l_u {
+- mmr_t sh_md_dqrs_mmr_xbist_l_regval;
+- struct {
+- mmr_t reserved_0 : 22;
+- mmr_t rot : 1;
+- mmr_t inv : 1;
+- mmr_t pat : 40;
+- } sh_md_dqrs_mmr_xbist_l_s;
+-} sh_md_dqrs_mmr_xbist_l_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRS_MMR_XBIST_ERR_H" */
+ /* rising edge bist error pattern */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrs_mmr_xbist_err_h_u {
+ mmr_t sh_md_dqrs_mmr_xbist_err_h_regval;
+ struct {
+@@ -27168,24 +14714,12 @@
+ mmr_t reserved_0 : 22;
+ } sh_md_dqrs_mmr_xbist_err_h_s;
+ } sh_md_dqrs_mmr_xbist_err_h_u_t;
+-#else
+-typedef union sh_md_dqrs_mmr_xbist_err_h_u {
+- mmr_t sh_md_dqrs_mmr_xbist_err_h_regval;
+- struct {
+- mmr_t reserved_0 : 22;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t pat : 40;
+- } sh_md_dqrs_mmr_xbist_err_h_s;
+-} sh_md_dqrs_mmr_xbist_err_h_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRS_MMR_XBIST_ERR_L" */
+ /* falling edge bist error pattern */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrs_mmr_xbist_err_l_u {
+ mmr_t sh_md_dqrs_mmr_xbist_err_l_regval;
+ struct {
+@@ -27195,24 +14729,12 @@
+ mmr_t reserved_0 : 22;
+ } sh_md_dqrs_mmr_xbist_err_l_s;
+ } sh_md_dqrs_mmr_xbist_err_l_u_t;
+-#else
+-typedef union sh_md_dqrs_mmr_xbist_err_l_u {
+- mmr_t sh_md_dqrs_mmr_xbist_err_l_regval;
+- struct {
+- mmr_t reserved_0 : 22;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t pat : 40;
+- } sh_md_dqrs_mmr_xbist_err_l_s;
+-} sh_md_dqrs_mmr_xbist_err_l_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRS_MMR_YBIST_H" */
+ /* rising edge bist/fill pattern */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrs_mmr_ybist_h_u {
+ mmr_t sh_md_dqrs_mmr_ybist_h_regval;
+ struct {
+@@ -27223,25 +14745,12 @@
+ mmr_t reserved_0 : 21;
+ } sh_md_dqrs_mmr_ybist_h_s;
+ } sh_md_dqrs_mmr_ybist_h_u_t;
+-#else
+-typedef union sh_md_dqrs_mmr_ybist_h_u {
+- mmr_t sh_md_dqrs_mmr_ybist_h_regval;
+- struct {
+- mmr_t reserved_0 : 21;
+- mmr_t arm : 1;
+- mmr_t rot : 1;
+- mmr_t inv : 1;
+- mmr_t pat : 40;
+- } sh_md_dqrs_mmr_ybist_h_s;
+-} sh_md_dqrs_mmr_ybist_h_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRS_MMR_YBIST_L" */
+ /* falling edge bist/fill pattern */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrs_mmr_ybist_l_u {
+ mmr_t sh_md_dqrs_mmr_ybist_l_regval;
+ struct {
+@@ -27251,24 +14760,12 @@
+ mmr_t reserved_0 : 22;
+ } sh_md_dqrs_mmr_ybist_l_s;
+ } sh_md_dqrs_mmr_ybist_l_u_t;
+-#else
+-typedef union sh_md_dqrs_mmr_ybist_l_u {
+- mmr_t sh_md_dqrs_mmr_ybist_l_regval;
+- struct {
+- mmr_t reserved_0 : 22;
+- mmr_t rot : 1;
+- mmr_t inv : 1;
+- mmr_t pat : 40;
+- } sh_md_dqrs_mmr_ybist_l_s;
+-} sh_md_dqrs_mmr_ybist_l_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRS_MMR_YBIST_ERR_H" */
+ /* rising edge bist error pattern */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrs_mmr_ybist_err_h_u {
+ mmr_t sh_md_dqrs_mmr_ybist_err_h_regval;
+ struct {
+@@ -27278,24 +14775,12 @@
+ mmr_t reserved_0 : 22;
+ } sh_md_dqrs_mmr_ybist_err_h_s;
+ } sh_md_dqrs_mmr_ybist_err_h_u_t;
+-#else
+-typedef union sh_md_dqrs_mmr_ybist_err_h_u {
+- mmr_t sh_md_dqrs_mmr_ybist_err_h_regval;
+- struct {
+- mmr_t reserved_0 : 22;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t pat : 40;
+- } sh_md_dqrs_mmr_ybist_err_h_s;
+-} sh_md_dqrs_mmr_ybist_err_h_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRS_MMR_YBIST_ERR_L" */
+ /* falling edge bist error pattern */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrs_mmr_ybist_err_l_u {
+ mmr_t sh_md_dqrs_mmr_ybist_err_l_regval;
+ struct {
+@@ -27305,24 +14790,12 @@
+ mmr_t reserved_0 : 22;
+ } sh_md_dqrs_mmr_ybist_err_l_s;
+ } sh_md_dqrs_mmr_ybist_err_l_u_t;
+-#else
+-typedef union sh_md_dqrs_mmr_ybist_err_l_u {
+- mmr_t sh_md_dqrs_mmr_ybist_err_l_regval;
+- struct {
+- mmr_t reserved_0 : 22;
+- mmr_t more : 1;
+- mmr_t val : 1;
+- mmr_t pat : 40;
+- } sh_md_dqrs_mmr_ybist_err_l_s;
+-} sh_md_dqrs_mmr_ybist_err_l_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRS_MMR_JNR_DEBUG" */
+ /* joiner/fct debug configuration */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrs_mmr_jnr_debug_u {
+ mmr_t sh_md_dqrs_mmr_jnr_debug_regval;
+ struct {
+@@ -27331,23 +14804,12 @@
+ mmr_t reserved_0 : 62;
+ } sh_md_dqrs_mmr_jnr_debug_s;
+ } sh_md_dqrs_mmr_jnr_debug_u_t;
+-#else
+-typedef union sh_md_dqrs_mmr_jnr_debug_u {
+- mmr_t sh_md_dqrs_mmr_jnr_debug_regval;
+- struct {
+- mmr_t reserved_0 : 62;
+- mmr_t rw : 1;
+- mmr_t px : 1;
+- } sh_md_dqrs_mmr_jnr_debug_s;
+-} sh_md_dqrs_mmr_jnr_debug_u_t;
+-#endif
+
+ /* ==================================================================== */
+ /* Register "SH_MD_DQRS_MMR_YAMOPW_ERR" */
+ /* amo/partial rmw ecc error register */
+ /* ==================================================================== */
+
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrs_mmr_yamopw_err_u {
+ mmr_t sh_md_dqrs_mmr_yamopw_err_regval;
+ struct {
+@@ -27363,23 +14825,5 @@
+ mmr_t reserved_2 : 31;
+ } sh_md_dqrs_mmr_yamopw_err_s;
+ } sh_md_dqrs_mmr_yamopw_err_u_t;
+-#else
+-typedef union sh_md_dqrs_mmr_yamopw_err_u {
+- mmr_t sh_md_dqrs_mmr_yamopw_err_regval;
+- struct {
+- mmr_t reserved_2 : 31;
+- mmr_t arm : 1;
+- mmr_t reserved_1 : 6;
+- mmr_t runc : 1;
+- mmr_t rcor : 1;
+- mmr_t rsyn : 8;
+- mmr_t reserved_0 : 6;
+- mmr_t sunc : 1;
+- mmr_t scor : 1;
+- mmr_t ssyn : 8;
+- } sh_md_dqrs_mmr_yamopw_err_s;
+-} sh_md_dqrs_mmr_yamopw_err_u_t;
+-#endif
+-
+
+ #endif /* _ASM_IA64_SN_SN2_SHUB_MMR_T_H */
+Index: linux-2.6.0-test5/include/asm-ia64/spinlock.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/spinlock.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/spinlock.h 2003-09-27 11:38:40.582358928 +0800
+@@ -24,6 +24,7 @@
+ #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
+ #define spin_lock_init(x) ((x)->lock = 0)
+
++#ifdef ASM_SUPPORTED
+ /*
+ * Try to get the lock. If we fail to get the lock, make a non-standard call to
+ * ia64_spinlock_contention(). We do not use a normal call because that would force all
+@@ -85,6 +86,21 @@
+ # endif /* CONFIG_MCKINLEY */
+ #endif
+ }
++#else /* !ASM_SUPPORTED */
++# define _raw_spin_lock(x) \
++do { \
++ __u32 *ia64_spinlock_ptr = (__u32 *) (x); \
++ __u64 ia64_spinlock_val; \
++ ia64_spinlock_val = ia64_cmpxchg4_acq(ia64_spinlock_ptr, 1, 0); \
++ if (unlikely(ia64_spinlock_val)) { \
++ do { \
++ while (*ia64_spinlock_ptr) \
++ ia64_barrier(); \
++ ia64_spinlock_val = ia64_cmpxchg4_acq(ia64_spinlock_ptr, 1, 0); \
++ } while (ia64_spinlock_val); \
++ } \
++} while (0)
++#endif /* !ASM_SUPPORTED */
+
+ #define spin_is_locked(x) ((x)->lock != 0)
+ #define _raw_spin_unlock(x) do { barrier(); ((spinlock_t *) x)->lock = 0; } while (0)
+@@ -94,8 +110,18 @@
+ typedef struct {
+ volatile int read_counter : 31;
+ volatile int write_lock : 1;
++#ifdef CONFIG_LOCKMETER
++ /* required for LOCKMETER since all bits in lock are used */
++ /* and we need this storage for CPU and lock INDEX */
++ unsigned lockmeter_magic;
++#endif
+ } rwlock_t;
++
++#ifdef CONFIG_LOCKMETER
++#define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0, 0 }
++#else
+ #define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 }
++#endif
+
+ #define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0)
+ #define rwlock_is_locked(x) (*(volatile int *) (x) != 0)
+@@ -111,28 +137,67 @@
+ } \
+ } while (0)
+
++#ifdef CONFIG_LOCKMETER
++/*
++ * HACK: This works, but still have a timing window that affects performance:
++ * we see that no one owns the Write lock, then someone * else grabs for Write
++ * lock before we do a read_lock().
++ * This means that on rare occasions our read_lock() will stall and spin-wait
++ * until we acquire for Read, instead of simply returning a trylock failure.
++ */
++static inline int _raw_read_trylock(rwlock_t *rw)
++{
++ if (rw->write_lock) {
++ return 0;
++ } else {
++ _raw_read_lock(rw);
++ return 1;
++ }
++}
++
++static inline int _raw_write_trylock(rwlock_t *rw)
++{
++ if (!(rw->write_lock)) {
++ /* isn't currently write-locked... that looks promising... */
++ if (test_and_set_bit(31, rw) == 0) {
++ /* now it is write-locked by me... */
++ if (rw->read_counter) {
++ /* really read-locked, so release write-lock and fail */
++ clear_bit(31, rw);
++ } else {
++ /* we've the the write-lock, no read-lockers... success! */
++ barrier();
++ return 1;
++ }
++
++ }
++ }
++
++ /* falls through ... fails to write-lock */
++ barrier();
++ return 0;
++}
++#endif
++
+ #define _raw_read_unlock(rw) \
+ do { \
+ rwlock_t *__read_lock_ptr = (rw); \
+ ia64_fetchadd(-1, (int *) __read_lock_ptr, rel); \
+ } while (0)
+
++#ifdef ASM_SUPPORTED
+ #define _raw_write_lock(rw) \
+ do { \
+ __asm__ __volatile__ ( \
+ "mov ar.ccv = r0\n" \
+- "dep r29 = -1, r0, 31, 1\n" \
+- ";;\n" \
++ "dep r29 = -1, r0, 31, 1;;\n" \
+ "1:\n" \
+- "ld4 r2 = [%0]\n" \
+- ";;\n" \
++ "ld4 r2 = [%0];;\n" \
+ "cmp4.eq p0,p7 = r0,r2\n" \
+ "(p7) br.cond.spnt.few 1b \n" \
+- "cmpxchg4.acq r2 = [%0], r29, ar.ccv\n" \
+- ";;\n" \
++ "cmpxchg4.acq r2 = [%0], r29, ar.ccv;;\n" \
+ "cmp4.eq p0,p7 = r0, r2\n" \
+- "(p7) br.cond.spnt.few 1b\n" \
+- ";;\n" \
++ "(p7) br.cond.spnt.few 1b;;\n" \
+ :: "r"(rw) : "ar.ccv", "p7", "r2", "r29", "memory"); \
+ } while(0)
+
+@@ -142,17 +207,60 @@
+ \
+ __asm__ __volatile__ ( \
+ "mov ar.ccv = r0\n" \
+- "dep r29 = -1, r0, 31, 1\n" \
+- ";;\n" \
++ "dep r29 = -1, r0, 31, 1;;\n" \
+ "cmpxchg4.acq %0 = [%1], r29, ar.ccv\n" \
+ : "=r"(result) : "r"(rw) : "ar.ccv", "r29", "memory"); \
+ (result == 0); \
+ })
+
++#else /* !ASM_SUPPORTED */
++
++#define _raw_write_lock(l) \
++({ \
++ __u64 ia64_val, ia64_set_val = ia64_dep_mi(-1, 0, 31, 1); \
++ __u32 *ia64_write_lock_ptr = (__u32 *) (l); \
++ do { \
++ while (*ia64_write_lock_ptr) \
++ ia64_barrier(); \
++ ia64_val = ia64_cmpxchg4_acq(ia64_write_lock_ptr, ia64_set_val, 0); \
++ } while (ia64_val); \
++})
++
++#define _raw_write_trylock(rw) \
++({ \
++ __u64 ia64_val; \
++ __u64 ia64_set_val = ia64_dep_mi(-1, 0, 31,1); \
++ ia64_val = ia64_cmpxchg4_acq((__u32 *)(rw), ia64_set_val, 0); \
++ (ia64_val == 0); \
++})
++
++#endif /* !ASM_SUPPORTED */
++
+ #define _raw_write_unlock(x) \
+ ({ \
+ smp_mb__before_clear_bit(); /* need barrier before releasing lock... */ \
+ clear_bit(31, (x)); \
+ })
+
++#ifdef CONFIG_LOCKMETER
++extern void _metered_spin_lock (spinlock_t *lock);
++extern void _metered_spin_unlock(spinlock_t *lock);
++
++/*
++ * Use a less efficient, and inline, atomic_dec_and_lock() if lockmetering
++ * so we can see the callerPC of who is actually doing the spin_lock().
++ * Otherwise, all we see is the generic rollup of all locks done by
++ * atomic_dec_and_lock().
++ */
++static inline int atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
++{
++ _metered_spin_lock(lock);
++ if (atomic_dec_and_test(atomic))
++ return 1;
++ _metered_spin_unlock(lock);
++ return 0;
++}
++#define ATOMIC_DEC_AND_LOCK
++#endif
++
+ #endif /* _ASM_IA64_SPINLOCK_H */
+Index: linux-2.6.0-test5/include/asm-ia64/uaccess.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/uaccess.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/uaccess.h 2003-09-27 11:38:40.586358320 +0800
+@@ -33,6 +33,7 @@
+ #include <linux/errno.h>
+ #include <linux/sched.h>
+
++#include <asm/intrinsics.h>
+ #include <asm/pgtable.h>
+
+ /*
+@@ -86,6 +87,8 @@
+ #define __put_user(x,ptr) __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+ #define __get_user(x,ptr) __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
+
++#ifdef ASM_SUPPORTED
++
+ extern void __get_user_unknown (void);
+
+ #define __get_user_nocheck(x,ptr,size) \
+@@ -217,6 +220,90 @@
+ "[1:]" \
+ : "=r"(__pu_err) : "m"(__m(addr)), "rO"(x), "0"(__pu_err))
+
++#else /* !ASM_SUPPORTED */
++
++#define RELOC_TYPE 2 /* ip-rel */
++
++#define __put_user_xx(val, addr, size, err) \
++ __st_user("__ex_table", (unsigned long) addr, size, RELOC_TYPE, (unsigned long) (val)); \
++ (err) = ia64_getreg(_IA64_REG_R8);
++
++#define __get_user_xx(val, addr, size, err) \
++ __ld_user("__ex_table", (unsigned long) addr, size, RELOC_TYPE); \
++ (err) = ia64_getreg(_IA64_REG_R8); \
++ (val) = ia64_getreg(_IA64_REG_R9);
++
++extern void __get_user_unknown (void);
++
++#define __get_user_nocheck(x, ptr, size) \
++({ \
++ register long __gu_err = 0; \
++ register long __gu_val = 0; \
++ const __typeof__(*(ptr)) *__gu_addr = (ptr); \
++ switch (size) { \
++ case 1: case 2: case 4: case 8: \
++ __get_user_xx(__gu_val, __gu_addr, size, __gu_err); \
++ break; \
++ default: \
++ __get_user_unknown(); \
++ break; \
++ } \
++ (x) = (__typeof__(*(ptr))) __gu_val; \
++ __gu_err; \
++})
++
++#define __get_user_check(x,ptr,size,segment) \
++({ \
++ register long __gu_err = -EFAULT; \
++ register long __gu_val = 0; \
++ const __typeof__(*(ptr)) *__gu_addr = (ptr); \
++ if (__access_ok((long) __gu_addr, size, segment)) { \
++ switch (size) { \
++ case 1: case 2: case 4: case 8: \
++ __get_user_xx(__gu_val, __gu_addr, size, __gu_err); \
++ break; \
++ default: \
++ __get_user_unknown(); break; \
++ } \
++ } \
++ (x) = (__typeof__(*(ptr))) __gu_val; \
++ __gu_err; \
++})
++
++extern void __put_user_unknown (void);
++
++#define __put_user_nocheck(x, ptr, size) \
++({ \
++ int __pu_err = 0; \
++ __typeof__(*(ptr)) *__pu_addr = (ptr); \
++ switch (size) { \
++ case 1: case 2: case 4: case 8: \
++ __put_user_xx(x, __pu_addr, size, __pu_err); \
++ break; \
++ default: \
++ __put_user_unknown(); break; \
++ } \
++ __pu_err; \
++})
++
++#define __put_user_check(x,ptr,size,segment) \
++({ \
++ register long __pu_err = -EFAULT; \
++ __typeof__(*(ptr)) *__pu_addr = (ptr); \
++ if (__access_ok((long)__pu_addr,size,segment)) { \
++ switch (size) { \
++ case 1: case 2: case 4: case 8: \
++ __put_user_xx(x,__pu_addr, size, __pu_err); \
++ break; \
++ default: \
++ __put_user_unknown(); break; \
++ } \
++ } \
++ __pu_err; \
++})
++
++#endif /* !ASM_SUPPORTED */
++
+ /*
+ * Complex access routines
+ */
+Index: linux-2.6.0-test5/include/asm-ia64/unistd.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/unistd.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/unistd.h 2003-09-27 11:38:40.589357864 +0800
+@@ -248,7 +248,6 @@
+ #define __NR_sys_clock_nanosleep 1256
+ #define __NR_sys_fstatfs64 1257
+ #define __NR_sys_statfs64 1258
+-#define __NR_fadvises64_64 1259
+
+ #ifdef __KERNEL__
+
+Index: linux-2.6.0-test5/include/asm-m68k/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-m68k/cacheflush.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-m68k/cacheflush.h 2003-09-27 11:38:40.591357560 +0800
+@@ -80,6 +80,9 @@
+
+ #define flush_cache_all() __flush_cache_all()
+
++#define flush_cache_vmap(start, end) flush_cache_all()
++#define flush_cache_vunmap(start, end) flush_cache_all()
++
+ extern inline void flush_cache_mm(struct mm_struct *mm)
+ {
+ if (mm == current->mm)
+@@ -127,6 +130,10 @@
+ #define flush_dcache_page(page) __flush_page_to_ram(page_address(page))
+ #define flush_icache_page(vma, page) __flush_page_to_ram(page_address(page))
+ #define flush_icache_user_range(vma,pg,adr,len) do { } while (0)
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++ memcpy(dst, src, len)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++ memcpy(dst, src, len)
+
+ extern void flush_icache_range(unsigned long address, unsigned long endaddr);
+
+Index: linux-2.6.0-test5/include/asm-m68knommu/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-m68knommu/cacheflush.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-m68knommu/cacheflush.h 2003-09-27 11:38:40.592357408 +0800
+@@ -15,7 +15,13 @@
+ #define flush_icache_range(start,len) __flush_cache_all()
+ #define flush_icache_page(vma,pg) do { } while (0)
+ #define flush_icache_user_range(vma,pg,adr,len) do { } while (0)
++#define flush_cache_vmap(start, end) flush_cache_all()
++#define flush_cache_vunmap(start, end) flush_cache_all()
+
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++ memcpy(dst, src, len)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++ memcpy(dst, src, len)
+
+ extern inline void __flush_cache_all(void)
+ {
+Index: linux-2.6.0-test5/include/asm-m68knommu/processor.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-m68knommu/processor.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-m68knommu/processor.h 2003-09-27 11:38:40.594357104 +0800
+@@ -58,7 +58,6 @@
+ /*
+ * Bus types
+ */
+-#define EISA_bus 0
+ #define MCA_bus 0
+
+ /*
+Index: linux-2.6.0-test5/include/asm-m68knommu/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-m68knommu/signal.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-m68knommu/signal.h 2003-09-27 11:38:40.596356800 +0800
+@@ -68,7 +68,7 @@
+
+ /* These should not be considered constants from userland. */
+ #define SIGRTMIN 32
+-#define SIGRTMAX (_NSIG-1)
++#define SIGRTMAX _NSIG
+
+ /*
+ * SA_FLAGS values:
+Index: linux-2.6.0-test5/include/asm-m68k/pgtable.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-m68k/pgtable.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-m68k/pgtable.h 2003-09-27 11:38:40.598356496 +0800
+@@ -79,12 +79,10 @@
+ */
+ #define VMALLOC_OFFSET (8*1024*1024)
+ #define VMALLOC_START (((unsigned long) high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END KMAP_START
+ #else
+ extern unsigned long vmalloc_end;
+ #define VMALLOC_START 0x0f800000
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END vmalloc_end
+ #endif /* CONFIG_SUN3 */
+
+Index: linux-2.6.0-test5/include/asm-m68k/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-m68k/posix_types.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-m68k/posix_types.h 2003-09-27 11:38:40.600356192 +0800
+@@ -7,7 +7,6 @@
+ * assume GCC is being used.
+ */
+
+-typedef unsigned short __kernel_dev_t;
+ typedef unsigned long __kernel_ino_t;
+ typedef unsigned short __kernel_mode_t;
+ typedef unsigned short __kernel_nlink_t;
+Index: linux-2.6.0-test5/include/asm-m68k/processor.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-m68k/processor.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-m68k/processor.h 2003-09-27 11:38:40.601356040 +0800
+@@ -56,7 +56,6 @@
+ /*
+ * Bus types
+ */
+-#define EISA_bus 0
+ #define MCA_bus 0
+
+ struct task_work {
+Index: linux-2.6.0-test5/include/asm-m68k/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-m68k/signal.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-m68k/signal.h 2003-09-27 11:38:40.604355584 +0800
+@@ -68,7 +68,7 @@
+
+ /* These should not be considered constants from userland. */
+ #define SIGRTMIN 32
+-#define SIGRTMAX (_NSIG-1)
++#define SIGRTMAX _NSIG
+
+ /*
+ * SA_FLAGS values:
+Index: linux-2.6.0-test5/include/asm-mips64/lockmeter.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-mips64/lockmeter.h 2003-09-27 11:38:18.480718888 +0800
++++ linux-2.6.0-test5/include/asm-mips64/lockmeter.h 2003-09-27 11:38:40.604355584 +0800
+@@ -0,0 +1,120 @@
++/*
++ * Copyright (C) 1999,2000 Silicon Graphics, Inc.
++ *
++ * Written by John Hawkes (hawkes@sgi.com)
++ * Based on klstat.h by Jack Steiner (steiner@sgi.com)
++ */
++
++#ifndef _ASM_LOCKMETER_H
++#define _ASM_LOCKMETER_H
++
++#include <linux/time.h>
++
++#define SPINLOCK_MAGIC_INIT /* */
++
++#define CPU_CYCLE_FREQUENCY get_cpu_cycle_frequency()
++
++#define THIS_CPU_NUMBER smp_processor_id()
++
++static uint32_t cpu_cycle_frequency = 0;
++
++static uint32_t get_cpu_cycle_frequency(void)
++{
++ /* a total hack, slow and invasive, but ... it works */
++ int sec;
++ uint32_t start_cycles;
++ struct timeval tv;
++
++ if (cpu_cycle_frequency == 0) { /* uninitialized */
++ do_gettimeofday(&tv);
++ sec = tv.tv_sec; /* set up to catch the tv_sec rollover */
++ while (sec == tv.tv_sec) { do_gettimeofday(&tv); }
++ sec = tv.tv_sec; /* rolled over to a new sec value */
++ start_cycles = get_cycles();
++ while (sec == tv.tv_sec) { do_gettimeofday(&tv); }
++ cpu_cycle_frequency = get_cycles() - start_cycles;
++ }
++
++ return cpu_cycle_frequency;
++}
++
++extern struct timeval xtime;
++extern long do_gettimeoffset(void);
++
++static uint64_t get_cycles64(void)
++{
++ static uint64_t last_get_cycles64 = 0;
++ uint64_t ret;
++ unsigned long sec;
++ unsigned long usec, usec_offset;
++
++again:
++ sec = xtime.tv_sec;
++ usec = xtime.tv_usec;
++ usec_offset = do_gettimeoffset();
++ if ((xtime.tv_sec != sec) ||
++ (xtime.tv_usec != usec)||
++ (usec_offset >= 20000))
++ goto again;
++
++ ret = ((uint64_t)sec * cpu_cycle_frequency)
++ + ( ((uint64_t)(usec + usec_offset) * cpu_cycle_frequency) / 1000000 );
++
++ /* XXX why does time go backwards? do_gettimeoffset? general time adj? */
++ if (ret <= last_get_cycles64)
++ ret = last_get_cycles64+1;
++ last_get_cycles64 = ret;
++
++ return ret;
++}
++
++/*
++ * macros to cache and retrieve an index value inside of a lock
++ * these macros assume that there are less than 65536 simultaneous
++ * (read mode) holders of a rwlock.
++ * we also assume that the hash table has less than 32767 entries.
++ * the high order bit is used for write locking a rw_lock
++ */
++#define INDEX_MASK 0x7FFF0000
++#define READERS_MASK 0x0000FFFF
++#define INDEX_SHIFT 16
++#define PUT_INDEX(lockp,index) \
++ lockp->lock = (((lockp->lock) & ~INDEX_MASK) | (index) << INDEX_SHIFT)
++#define GET_INDEX(lockp) \
++ (((lockp->lock) & INDEX_MASK) >> INDEX_SHIFT)
++
++/*
++ * macros to cache and retrieve an index value in a read/write lock
++ * as well as the cpu where a reader busy period started
++ * we use the 2nd word (the debug word) for this, so require the
++ * debug word to be present
++ */
++/*
++ * instrumented rwlock structure -- never used to allocate storage
++ * only used in macros below to overlay a rwlock_t
++ */
++typedef struct inst_rwlock_s {
++ volatile int lock;
++ unsigned short index;
++ unsigned short cpu;
++} inst_rwlock_t;
++#define PUT_RWINDEX(rwlock_ptr,indexv) ((inst_rwlock_t *)(rwlock_ptr))->index = indexv
++#define GET_RWINDEX(rwlock_ptr) ((inst_rwlock_t *)(rwlock_ptr))->index
++#define PUT_RW_CPU(rwlock_ptr,cpuv) ((inst_rwlock_t *)(rwlock_ptr))->cpu = cpuv
++#define GET_RW_CPU(rwlock_ptr) ((inst_rwlock_t *)(rwlock_ptr))->cpu
++
++/*
++ * return the number of readers for a rwlock_t
++ */
++#define RWLOCK_READERS(rwlock_ptr) rwlock_readers(rwlock_ptr)
++
++extern inline int rwlock_readers(rwlock_t *rwlock_ptr)
++{
++ int tmp = (int) rwlock_ptr->lock;
++ return (tmp >= 0) ? tmp : 0;
++}
++
++#define RWLOCK_IS_WRITE_LOCKED(rwlock_ptr) ((rwlock_ptr)->lock < 0)
++#define RWLOCK_IS_READ_LOCKED(rwlock_ptr) ((rwlock_ptr)->lock > 0)
++
++#endif /* _ASM_LOCKMETER_H */
+Index: linux-2.6.0-test5/include/asm-mips/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-mips/cacheflush.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-mips/cacheflush.h 2003-09-27 11:38:40.606355280 +0800
+@@ -43,7 +43,15 @@
+ extern void (*flush_icache_range)(unsigned long start, unsigned long end);
+ #define flush_icache_user_range(vma, page, addr, len) \
+ flush_icache_page(vma, page)
++#define flush_cache_vmap(start, end) flush_cache_all()
++#define flush_cache_vunmap(start, end) flush_cache_all()
+
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++do { memcpy(dst, src, len); \
++ flush_icache_user_range(vma, page, vaddr, len); \
++} while (0)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++ memcpy(dst, src, len)
+
+ extern void (*flush_cache_sigtramp)(unsigned long addr);
+ extern void (*flush_icache_all)(void);
+Index: linux-2.6.0-test5/include/asm-mips/highmem.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-mips/highmem.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-mips/highmem.h 2003-09-27 11:38:40.608354976 +0800
+@@ -54,6 +54,8 @@
+ extern void kunmap_atomic(void *kvaddr, enum km_type type);
+ extern struct page *kmap_atomic_to_page(void *ptr);
+
++#define flush_cache_kmaps() flush_cache_all()
++
+ #endif /* __KERNEL__ */
+
+ #endif /* _ASM_HIGHMEM_H */
+Index: linux-2.6.0-test5/include/asm-mips/lockmeter.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-mips/lockmeter.h 2003-09-27 11:38:18.480718888 +0800
++++ linux-2.6.0-test5/include/asm-mips/lockmeter.h 2003-09-27 11:38:40.608354976 +0800
+@@ -0,0 +1,126 @@
++/*
++ * Copyright (C) 1999,2000 Silicon Graphics, Inc.
++ *
++ * Written by John Hawkes (hawkes@sgi.com)
++ * Based on klstat.h by Jack Steiner (steiner@sgi.com)
++ * Ported to mips32 for Asita Technologies
++ * by D.J. Barrow ( dj.barrow@asitatechnologies.com )
++ */
++#ifndef _ASM_LOCKMETER_H
++#define _ASM_LOCKMETER_H
++
++/* do_gettimeoffset is a function pointer on mips */
++/* & it is not included by <linux/time.h> */
++#include <asm/time.h>
++#include <linux/time.h>
++#include <asm/div64.h>
++
++#define SPINLOCK_MAGIC_INIT /* */
++
++#define CPU_CYCLE_FREQUENCY get_cpu_cycle_frequency()
++
++#define THIS_CPU_NUMBER smp_processor_id()
++
++static uint32_t cpu_cycle_frequency = 0;
++
++static uint32_t get_cpu_cycle_frequency(void)
++{
++ /* a total hack, slow and invasive, but ... it works */
++ int sec;
++ uint32_t start_cycles;
++ struct timeval tv;
++
++ if (cpu_cycle_frequency == 0) { /* uninitialized */
++ do_gettimeofday(&tv);
++ sec = tv.tv_sec; /* set up to catch the tv_sec rollover */
++ while (sec == tv.tv_sec) { do_gettimeofday(&tv); }
++ sec = tv.tv_sec; /* rolled over to a new sec value */
++ start_cycles = get_cycles();
++ while (sec == tv.tv_sec) { do_gettimeofday(&tv); }
++ cpu_cycle_frequency = get_cycles() - start_cycles;
++ }
++
++ return cpu_cycle_frequency;
++}
++
++extern struct timeval xtime;
++
++static uint64_t get_cycles64(void)
++{
++ static uint64_t last_get_cycles64 = 0;
++ uint64_t ret;
++ unsigned long sec;
++ unsigned long usec, usec_offset;
++
++again:
++ sec = xtime.tv_sec;
++ usec = xtime.tv_usec;
++ usec_offset = do_gettimeoffset();
++ if ((xtime.tv_sec != sec) ||
++ (xtime.tv_usec != usec)||
++ (usec_offset >= 20000))
++ goto again;
++
++ ret = ((uint64_t)(usec + usec_offset) * cpu_cycle_frequency);
++ /* We can't do a normal 64 bit division on mips without libgcc.a */
++ do_div(ret,1000000);
++ ret += ((uint64_t)sec * cpu_cycle_frequency);
++
++ /* XXX why does time go backwards? do_gettimeoffset? general time adj? */
++ if (ret <= last_get_cycles64)
++ ret = last_get_cycles64+1;
++ last_get_cycles64 = ret;
++
++ return ret;
++}
++
++/*
++ * macros to cache and retrieve an index value inside of a lock
++ * these macros assume that there are less than 65536 simultaneous
++ * (read mode) holders of a rwlock.
++ * we also assume that the hash table has less than 32767 entries.
++ * the high order bit is used for write locking a rw_lock
++ */
++#define INDEX_MASK 0x7FFF0000
++#define READERS_MASK 0x0000FFFF
++#define INDEX_SHIFT 16
++#define PUT_INDEX(lockp,index) \
++ lockp->lock = (((lockp->lock) & ~INDEX_MASK) | (index) << INDEX_SHIFT)
++#define GET_INDEX(lockp) \
++ (((lockp->lock) & INDEX_MASK) >> INDEX_SHIFT)
++
++/*
++ * macros to cache and retrieve an index value in a read/write lock
++ * as well as the cpu where a reader busy period started
++ * we use the 2nd word (the debug word) for this, so require the
++ * debug word to be present
++ */
++/*
++ * instrumented rwlock structure -- never used to allocate storage
++ * only used in macros below to overlay a rwlock_t
++ */
++typedef struct inst_rwlock_s {
++ volatile int lock;
++ unsigned short index;
++ unsigned short cpu;
++} inst_rwlock_t;
++#define PUT_RWINDEX(rwlock_ptr,indexv) ((inst_rwlock_t *)(rwlock_ptr))->index = indexv
++#define GET_RWINDEX(rwlock_ptr) ((inst_rwlock_t *)(rwlock_ptr))->index
++#define PUT_RW_CPU(rwlock_ptr,cpuv) ((inst_rwlock_t *)(rwlock_ptr))->cpu = cpuv
++#define GET_RW_CPU(rwlock_ptr) ((inst_rwlock_t *)(rwlock_ptr))->cpu
++
++/*
++ * return the number of readers for a rwlock_t
++ */
++#define RWLOCK_READERS(rwlock_ptr) rwlock_readers(rwlock_ptr)
++
++extern inline int rwlock_readers(rwlock_t *rwlock_ptr)
++{
++ int tmp = (int) rwlock_ptr->lock;
++ return (tmp >= 0) ? tmp : 0;
++}
++
++#define RWLOCK_IS_WRITE_LOCKED(rwlock_ptr) ((rwlock_ptr)->lock < 0)
++#define RWLOCK_IS_READ_LOCKED(rwlock_ptr) ((rwlock_ptr)->lock > 0)
++
++#endif /* _ASM_LOCKMETER_H */
+Index: linux-2.6.0-test5/include/asm-mips/pgtable-32.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-mips/pgtable-32.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-mips/pgtable-32.h 2003-09-27 11:38:40.624352544 +0800
+@@ -79,7 +79,6 @@
+ #define FIRST_USER_PGD_NR 0
+
+ #define VMALLOC_START KSEG2
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+
+ #if CONFIG_HIGHMEM
+ # define VMALLOC_END (PKMAP_BASE-2*PAGE_SIZE)
+Index: linux-2.6.0-test5/include/asm-mips/pgtable-64.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-mips/pgtable-64.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-mips/pgtable-64.h 2003-09-27 11:38:40.626352240 +0800
+@@ -64,7 +64,6 @@
+ #define FIRST_USER_PGD_NR 0
+
+ #define VMALLOC_START XKSEG
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END \
+ (VMALLOC_START + ((1 << PGD_ORDER) * PTRS_PER_PTE * PAGE_SIZE))
+
+Index: linux-2.6.0-test5/include/asm-mips/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-mips/posix_types.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-mips/posix_types.h 2003-09-27 11:38:40.628351936 +0800
+@@ -17,7 +17,6 @@
+ * assume GCC is being used.
+ */
+
+-typedef unsigned int __kernel_dev_t;
+ typedef unsigned long __kernel_ino_t;
+ typedef unsigned int __kernel_mode_t;
+ #if (_MIPS_SZLONG == 32)
+Index: linux-2.6.0-test5/include/asm-mips/processor.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-mips/processor.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-mips/processor.h 2003-09-27 11:38:40.631351480 +0800
+@@ -135,12 +135,6 @@
+ /*
+ * Bus types (default is ISA, but people can check others with these..)
+ */
+-#ifdef CONFIG_EISA
+-extern int EISA_bus;
+-#else
+-#define EISA_bus (0)
+-#endif
+-
+ #define MCA_bus 0
+ #define MCA_bus__is_a_macro /* for versions in ksyms.c */
+
+Index: linux-2.6.0-test5/include/asm-mips/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-mips/signal.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-mips/signal.h 2003-09-27 11:38:40.634351024 +0800
+@@ -59,7 +59,7 @@
+
+ /* These should not be considered constants from userland. */
+ #define SIGRTMIN 32
+-#define SIGRTMAX (_NSIG-1)
++#define SIGRTMAX _NSIG
+
+ /*
+ * SA_FLAGS values:
+Index: linux-2.6.0-test5/include/asm-mips/spinlock.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-mips/spinlock.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-mips/spinlock.h 2003-09-27 11:38:40.635350872 +0800
+@@ -91,9 +91,18 @@
+
+ typedef struct {
+ volatile unsigned int lock;
++#ifdef CONFIG_LOCKMETER
++ /* required for LOCKMETER since all bits in lock are used */
++ /* and we need this storage for CPU and lock INDEX */
++ unsigned lockmeter_magic;
++#endif
+ } rwlock_t;
+
++#ifdef CONFIG_LOCKMETER
++#define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 }
++#else
+ #define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
++#endif
+
+ #define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0)
+
+Index: linux-2.6.0-test5/include/asm-mips/stat.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-mips/stat.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-mips/stat.h 2003-09-27 11:38:40.636350720 +0800
+@@ -16,14 +16,14 @@
+ #if (_MIPS_SIM == _MIPS_SIM_ABI32) || (_MIPS_SIM == _MIPS_SIM_NABI32)
+
+ struct stat {
+- dev_t st_dev;
++ unsigned st_dev;
+ long st_pad1[3]; /* Reserved for network id */
+ ino_t st_ino;
+ mode_t st_mode;
+ nlink_t st_nlink;
+ uid_t st_uid;
+ gid_t st_gid;
+- dev_t st_rdev;
++ unsigned st_rdev;
+ long st_pad2[2];
+ off_t st_size;
+ long st_pad3;
+@@ -90,7 +90,7 @@
+
+ /* The memory layout is the same as of struct stat64 of the 32-bit kernel. */
+ struct stat {
+- dev_t st_dev;
++ unsigned int st_dev;
+ unsigned int st_pad0[3]; /* Reserved for st_dev expansion */
+
+ unsigned long st_ino;
+@@ -101,7 +101,7 @@
+ uid_t st_uid;
+ gid_t st_gid;
+
+- dev_t st_rdev;
++ unsigned int st_rdev;
+ unsigned int st_pad1[3]; /* Reserved for st_rdev expansion */
+
+ off_t st_size;
+Index: linux-2.6.0-test5/include/asm-parisc/atomic.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-parisc/atomic.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-parisc/atomic.h 2003-09-27 11:38:40.639350264 +0800
+@@ -49,27 +49,14 @@
+ * Cache-line alignment would conflict with, for example, linux/module.h
+ */
+
+-typedef struct {
+- volatile int counter;
+-} atomic_t;
++typedef struct { volatile long counter; } atomic_t;
+
+
+-/*
+-** xchg/cmpxchg moved from asm/system.h - ggg
+-*/
+-
+-#if 1
+ /* This should get optimized out since it's never called.
+ ** Or get a link error if xchg is used "wrong".
+ */
+ extern void __xchg_called_with_bad_pointer(void);
+-#else
+-static inline void __xchg_called_with_bad_pointer(void)
+-{
+- extern void panic(const char * fmt, ...);
+- panic("xchg called with bad pointer");
+-}
+-#endif
++
+
+ /* __xchg32/64 defined in arch/parisc/lib/bitops.c */
+ extern unsigned long __xchg8(char, char *);
+Index: linux-2.6.0-test5/include/asm-parisc/bitops.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-parisc/bitops.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-parisc/bitops.h 2003-09-27 11:38:40.642349808 +0800
+@@ -203,55 +203,102 @@
+ return !!(*addr & mask);
+ }
+
+-extern __inline__ unsigned long ffz(unsigned long word)
+-{
+- unsigned long result;
+-
+- result = 0;
+- while (word & 1) {
+- result++;
+- word >>= 1;
+- }
+-
+- return result;
+-}
+-
+ #ifdef __KERNEL__
+
+ /**
+- * __ffs - find first bit in word.
++ * __ffs - find first bit in word. returns 0 to "BITS_PER_LONG-1".
+ * @word: The word to search
+ *
+- * Undefined if no bit exists, so code should check against 0 first.
++ * __ffs() return is undefined if no bit is set.
++ *
++ * 32-bit fast __ffs by LaMont Jones "lamont At hp com".
++ * 64-bit enhancement by Grant Grundler "grundler At parisc-linux org".
++ * (with help from willy/jejb to get the semantics right)
++ *
++ * This algorithm avoids branches by making use of nullification.
++ * One side effect of "extr" instructions is it sets PSW[N] bit.
++ * How PSW[N] (nullify next insn) gets set is determined by the
++ * "condition" field (eg "<>" or "TR" below) in the extr* insn.
++ * Only the 1st and one of either the 2cd or 3rd insn will get executed.
++ * Each set of 3 insn will get executed in 2 cycles on PA8x00 vs 16 or so
++ * cycles for each mispredicted branch.
+ */
+-static __inline__ unsigned long __ffs(unsigned long word)
++
++static __inline__ unsigned long __ffs(unsigned long x)
+ {
+- unsigned long result = 0;
++ unsigned long ret;
+
+- while (!(word & 1UL)) {
+- result++;
+- word >>= 1;
+- }
+- return result;
++ __asm__(
++#if BITS_PER_LONG > 32
++ " ldi 63,%1\n"
++ " extrd,u,*<> %0,63,32,%%r0\n"
++ " extrd,u,*TR %0,31,32,%0\n"
++ " addi -32,%1,%1\n"
++#else
++ " ldi 31,%1\n"
++#endif
++ " extru,<> %0,31,16,%%r0\n"
++ " extru,TR %0,15,16,%0\n"
++ " addi -16,%1,%1\n"
++ " extru,<> %0,31,8,%%r0\n"
++ " extru,TR %0,23,8,%0\n"
++ " addi -8,%1,%1\n"
++ " extru,<> %0,31,4,%%r0\n"
++ " extru,TR %0,27,4,%0\n"
++ " addi -4,%1,%1\n"
++ " extru,<> %0,31,2,%%r0\n"
++ " extru,TR %0,29,2,%0\n"
++ " addi -2,%1,%1\n"
++ " extru,= %0,31,1,%%r0\n"
++ " addi -1,%1,%1\n"
++ : "+r" (x), "=r" (ret) );
++ return ret;
+ }
+
++/* Undefined if no bit is zero. */
++#define ffz(x) __ffs(~x)
++
+ /*
+- * ffs: find first bit set. This is defined the same way as
+- * the libc and compiler builtin ffs routines, therefore
+- * differs in spirit from the above ffz (man ffs).
++ * ffs: find first bit set. returns 1 to BITS_PER_LONG or 0 (if none set)
++ * This is defined the same way as the libc and compiler builtin
++ * ffs routines, therefore differs in spirit from the above ffz (man ffs).
+ */
+ static __inline__ int ffs(int x)
+ {
+- if (!x)
+- return 0;
+- return __ffs((unsigned long)x);
++ return x ? (__ffs((unsigned long)x) + 1) : 0;
+ }
+
+ /*
+- * fls: find last bit set.
++ * fls: find last (most significant) bit set.
++ * fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
+ */
+
+-#define fls(x) generic_fls(x)
++static __inline__ int fls(int x)
++{
++ int ret;
++ if (!x)
++ return 0;
++
++ __asm__(
++ " ldi 1,%1\n"
++ " extru,<> %0,15,16,%%r0\n"
++ " zdep,TR %0,15,16,%0\n" /* xxxx0000 */
++ " addi 16,%1,%1\n"
++ " extru,<> %0,7,8,%%r0\n"
++ " zdep,TR %0,23,24,%0\n" /* xx000000 */
++ " addi 8,%1,%1\n"
++ " extru,<> %0,3,4,%%r0\n"
++ " zdep,TR %0,27,28,%0\n" /* x0000000 */
++ " addi 4,%1,%1\n"
++ " extru,<> %0,1,2,%%r0\n"
++ " zdep,TR %0,29,30,%0\n" /* y0000000 (y&3 = 0 */
++ " addi 2,%1,%1\n"
++ " extru,= %0,0,1,%%r0\n"
++ " addi 1,%1,%1\n" /* if y & 8, add 1 */
++ : "+r" (x), "=r" (ret) );
++
++ return ret;
++}
+
+ /*
+ * hweightN: returns the hamming weight (i.e. the number
+Index: linux-2.6.0-test5/include/asm-parisc/byteorder.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-parisc/byteorder.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-parisc/byteorder.h 2003-09-27 11:38:40.644349504 +0800
+@@ -5,6 +5,25 @@
+
+ #ifdef __GNUC__
+
++static __inline__ __const__ __u16 ___arch__swab16(__u16 x)
++{
++ __asm__("dep %0, 15, 8, %0\n\t" /* deposit 00ab -> 0bab */
++ "shd %%r0, %0, 8, %0" /* shift 000000ab -> 00ba */
++ : "=r" (x)
++ : "0" (x));
++ return x;
++}
++
++static __inline__ __const__ __u32 ___arch__swab24(__u32 x)
++{
++ __asm__("shd %0, %0, 8, %0\n\t" /* shift xabcxabc -> cxab */
++ "dep %0, 15, 8, %0\n\t" /* deposit cxab -> cbab */
++ "shd %%r0, %0, 8, %0" /* shift 0000cbab -> 0cba */
++ : "=r" (x)
++ : "0" (x));
++ return x;
++}
++
+ static __inline__ __const__ __u32 ___arch__swab32(__u32 x)
+ {
+ unsigned int temp;
+@@ -39,34 +58,21 @@
+ return x;
+ }
+ #define __arch__swab64(x) ___arch__swab64(x)
+-#else
++#define __BYTEORDER_HAS_U64__
++#elif !defined(__STRICT_ANSI__)
+ static __inline__ __const__ __u64 ___arch__swab64(__u64 x)
+ {
+- __u32 t1 = (__u32) x;
+- __u32 t2 = (__u32) ((x) >> 32);
+- ___arch__swab32(t1);
+- ___arch__swab32(t2);
+- return (((__u64) t1 << 32) + ((__u64) t2));
++ __u32 t1 = ___arch__swab32((__u32) x);
++ __u32 t2 = ___arch__swab32((__u32) (x >> 32));
++ return (((__u64) t1 << 32) | t2);
+ }
++#define __arch__swab64(x) ___arch__swab64(x)
++#define __BYTEORDER_HAS_U64__
+ #endif
+
+-
+-static __inline__ __const__ __u16 ___arch__swab16(__u16 x)
+-{
+- __asm__("dep %0, 15, 8, %0\n\t" /* deposit 00ab -> 0bab */
+- "shd %r0, %0, 8, %0" /* shift 000000ab -> 00ba */
+- : "=r" (x)
+- : "0" (x));
+- return x;
+-}
+-
+-#define __arch__swab32(x) ___arch__swab32(x)
+ #define __arch__swab16(x) ___arch__swab16(x)
+-
+-#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+-# define __BYTEORDER_HAS_U64__
+-# define __SWAB_64_THRU_32__
+-#endif
++#define __arch__swab24(x) ___arch__swab24(x)
++#define __arch__swab32(x) ___arch__swab32(x)
+
+ #endif /* __GNUC__ */
+
+Index: linux-2.6.0-test5/include/asm-parisc/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-parisc/cacheflush.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-parisc/cacheflush.h 2003-09-27 11:38:40.646349200 +0800
+@@ -30,6 +30,9 @@
+ on_each_cpu(cacheflush_h_tmp_function, NULL, 1, 1);
+ }
+
++#define flush_cache_vmap(start, end) flush_cache_all()
++#define flush_cache_vunmap(start, end) flush_cache_all()
++
+ /* The following value needs to be tuned and probably scaled with the
+ * cache size.
+ */
+@@ -78,8 +81,16 @@
+
+ #define flush_icache_range(s,e) do { flush_kernel_dcache_range_asm(s,e); flush_kernel_icache_range_asm(s,e); } while (0)
+
+-#define flush_icache_user_range(vma, page, addr, len) \
+- flush_icache_page((vma), (page))
++#define flush_icache_user_range(vma, page, addr, len) do { \
++ flush_user_dcache_range(addr, addr + len); \
++ flush_user_icache_range(addr, addr + len); } while (0)
++
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++do { memcpy(dst, src, len); \
++ flush_icache_user_range(vma, page, vaddr, len); \
++} while (0)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++ memcpy(dst, src, len)
+
+ static inline void flush_cache_range(struct vm_area_struct *vma,
+ unsigned long start, unsigned long end)
+Index: linux-2.6.0-test5/include/asm-parisc/elf.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-parisc/elf.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-parisc/elf.h 2003-09-27 11:38:40.650348592 +0800
+@@ -283,6 +283,7 @@
+ */
+ #define ELF_DATA ELFDATA2MSB
+ #define ELF_ARCH EM_PARISC
++#define ELF_OSABI ELFOSABI_LINUX
+
+ /* %r23 is set by ld.so to a pointer to a function which might be
+ registered using atexit. This provides a mean for the dynamic
+Index: linux-2.6.0-test5/include/asm-parisc/io.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-parisc/io.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-parisc/io.h 2003-09-27 11:38:40.653348136 +0800
+@@ -291,4 +291,11 @@
+ #define dma_cache_wback(_start,_size) do { flush_kernel_dcache_range(_start,_size); } while (0)
+ #define dma_cache_wback_inv(_start,_size) do { flush_kernel_dcache_range(_start,_size); } while (0)
+
++/* PA machines have an MM I/O space from 0xf0000000-0xffffffff in 32
++ * bit mode and from 0xfffffffff0000000-0xfffffffffffffff in 64 bit
++ * mode (essentially just sign extending. This macro takes in a 32
++ * bit I/O address (still with the leading f) and outputs the correct
++ * value for either 32 or 64 bit mode */
++#define F_EXTEND(x) ((unsigned long)((x) | (0xffffffff00000000ULL)))
++
+ #endif
+Index: linux-2.6.0-test5/include/asm-parisc/local.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-parisc/local.h 2003-09-27 11:38:18.480718888 +0800
++++ linux-2.6.0-test5/include/asm-parisc/local.h 2003-09-27 11:38:40.654347984 +0800
+@@ -0,0 +1,40 @@
++#ifndef _ARCH_PARISC_LOCAL_H
++#define _ARCH_PARISC_LOCAL_H
++
++#include <linux/percpu.h>
++#include <asm/atomic.h>
++
++typedef atomic_t local_t;
++
++#define LOCAL_INIT(i) ATOMIC_INIT(i)
++#define local_read(v) atomic_read(v)
++#define local_set(v,i) atomic_set(v,i)
++
++#define local_inc(v) atomic_inc(v)
++#define local_dec(v) atomic_dec(v)
++#define local_add(i, v) atomic_add(i, v)
++#define local_sub(i, v) atomic_sub(i, v)
++
++#define __local_inc(v) ((v)->counter++)
++#define __local_dec(v) ((v)->counter--)
++#define __local_add(i,v) ((v)->counter+=(i))
++#define __local_sub(i,v) ((v)->counter-=(i))
++
++/* Use these for per-cpu local_t variables: on some archs they are
++ * much more efficient than these naive implementations. Note they take
++ * a variable, not an address.
++ */
++#define cpu_local_read(v) local_read(&__get_cpu_var(v))
++#define cpu_local_set(v, i) local_set(&__get_cpu_var(v), (i))
++
++#define cpu_local_inc(v) local_inc(&__get_cpu_var(v))
++#define cpu_local_dec(v) local_dec(&__get_cpu_var(v))
++#define cpu_local_add(i, v) local_add((i), &__get_cpu_var(v))
++#define cpu_local_sub(i, v) local_sub((i), &__get_cpu_var(v))
++
++#define __cpu_local_inc(v) __local_inc(&__get_cpu_var(v))
++#define __cpu_local_dec(v) __local_dec(&__get_cpu_var(v))
++#define __cpu_local_add(i, v) __local_add((i), &__get_cpu_var(v))
++#define __cpu_local_sub(i, v) __local_sub((i), &__get_cpu_var(v))
++
++#endif /* _ARCH_PARISC_LOCAL_H */
+Index: linux-2.6.0-test5/include/asm-parisc/pgtable.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-parisc/pgtable.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-parisc/pgtable.h 2003-09-27 11:38:40.658347376 +0800
+@@ -108,7 +108,6 @@
+ extern void *vmalloc_start;
+ #define PCXL_DMA_MAP_SIZE (8*1024*1024)
+ #define VMALLOC_START ((unsigned long)vmalloc_start)
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ /* this is a fixmap remnant, see fixmap.h */
+ #define VMALLOC_END (TMPALIAS_MAP_START)
+ #endif
+Index: linux-2.6.0-test5/include/asm-parisc/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-parisc/posix_types.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-parisc/posix_types.h 2003-09-27 11:38:40.660347072 +0800
+@@ -6,7 +6,6 @@
+ * be a little careful about namespace pollution etc. Also, we cannot
+ * assume GCC is being used.
+ */
+-typedef unsigned int __kernel_dev_t;
+ typedef unsigned long __kernel_ino_t;
+ typedef unsigned short __kernel_mode_t;
+ typedef unsigned short __kernel_nlink_t;
+Index: linux-2.6.0-test5/include/asm-parisc/processor.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-parisc/processor.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-parisc/processor.h 2003-09-27 11:38:40.663346616 +0800
+@@ -101,12 +101,6 @@
+
+ #define CPU_HVERSION ((boot_cpu_data.hversion >> 4) & 0x0FFF)
+
+-#ifdef CONFIG_EISA
+-extern int EISA_bus;
+-#else
+-#define EISA_bus 0
+-#endif
+-
+ #define MCA_bus 0
+ #define MCA_bus__is_a_macro /* for versions in ksyms.c */
+
+Index: linux-2.6.0-test5/include/asm-parisc/sections.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-parisc/sections.h 2003-09-27 11:38:18.480718888 +0800
++++ linux-2.6.0-test5/include/asm-parisc/sections.h 2003-09-27 11:38:40.663346616 +0800
+@@ -0,0 +1,7 @@
++#ifndef _PARISC_SECTIONS_H
++#define _PARISC_SECTIONS_H
++
++/* nothing to see, move along */
++#include <asm-generic/sections.h>
++
++#endif
+Index: linux-2.6.0-test5/include/asm-parisc/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-parisc/signal.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-parisc/signal.h 2003-09-27 11:38:40.666346160 +0800
+@@ -42,7 +42,7 @@
+
+ /* These should not be considered constants from userland. */
+ #define SIGRTMIN 37
+-#define SIGRTMAX (_NSIG-1) /* it's 44 under HP/UX */
++#define SIGRTMAX _NSIG /* it's 44 under HP/UX */
+
+ /*
+ * SA_FLAGS values:
+Index: linux-2.6.0-test5/include/asm-parisc/stat.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-parisc/stat.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-parisc/stat.h 2003-09-27 11:38:40.667346008 +0800
+@@ -4,13 +4,13 @@
+ #include <linux/types.h>
+
+ struct stat {
+- dev_t st_dev; /* dev_t is 32 bits on parisc */
++ unsigned int st_dev; /* dev_t is 32 bits on parisc */
+ ino_t st_ino; /* 32 bits */
+ mode_t st_mode; /* 16 bits */
+ nlink_t st_nlink; /* 16 bits */
+ unsigned short st_reserved1; /* old st_uid */
+ unsigned short st_reserved2; /* old st_gid */
+- dev_t st_rdev;
++ unsigned int st_rdev;
+ off_t st_size;
+ time_t st_atime;
+ unsigned int st_atime_nsec;
+@@ -21,12 +21,12 @@
+ int st_blksize;
+ int st_blocks;
+ unsigned int __unused1; /* ACL stuff */
+- dev_t __unused2; /* network */
++ unsigned int __unused2; /* network */
+ ino_t __unused3; /* network */
+ unsigned int __unused4; /* cnodes */
+ unsigned short __unused5; /* netsite */
+ short st_fstype;
+- dev_t st_realdev;
++ unsigned int st_realdev;
+ unsigned short st_basemode;
+ unsigned short st_spareshort;
+ uid_t st_uid;
+@@ -39,13 +39,13 @@
+ typedef __kernel_off64_t off64_t;
+
+ struct hpux_stat64 {
+- dev_t st_dev; /* dev_t is 32 bits on parisc */
++ unsigned int st_dev; /* dev_t is 32 bits on parisc */
+ ino_t st_ino; /* 32 bits */
+ mode_t st_mode; /* 16 bits */
+ nlink_t st_nlink; /* 16 bits */
+ unsigned short st_reserved1; /* old st_uid */
+ unsigned short st_reserved2; /* old st_gid */
+- dev_t st_rdev;
++ unsigned int st_rdev;
+ off64_t st_size;
+ time_t st_atime;
+ unsigned int st_spare1;
+@@ -56,12 +56,12 @@
+ int st_blksize;
+ __u64 st_blocks;
+ unsigned int __unused1; /* ACL stuff */
+- dev_t __unused2; /* network */
++ unsigned int __unused2; /* network */
+ ino_t __unused3; /* network */
+ unsigned int __unused4; /* cnodes */
+ unsigned short __unused5; /* netsite */
+ short st_fstype;
+- dev_t st_realdev;
++ unsigned int st_realdev;
+ unsigned short st_basemode;
+ unsigned short st_spareshort;
+ uid_t st_uid;
+Index: linux-2.6.0-test5/include/asm-parisc/uaccess.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-parisc/uaccess.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-parisc/uaccess.h 2003-09-27 11:38:40.671345400 +0800
+@@ -28,6 +28,11 @@
+ * that put_user is the same as __put_user, etc.
+ */
+
++extern int __get_kernel_bad(void);
++extern int __get_user_bad(void);
++extern int __put_kernel_bad(void);
++extern int __put_user_bad(void);
++
+ #define access_ok(type,addr,size) (1)
+ #define verify_area(type,addr,size) (0)
+
+@@ -35,8 +40,8 @@
+ #define get_user __get_user
+
+ #if BITS_PER_LONG == 32
+-#define LDD_KERNEL(ptr) BUG()
+-#define LDD_USER(ptr) BUG()
++#define LDD_KERNEL(ptr) __get_kernel_bad();
++#define LDD_USER(ptr) __get_user_bad();
+ #define STD_KERNEL(x, ptr) __put_kernel_asm64((u32)x,ptr)
+ #define STD_USER(x, ptr) __put_user_asm64((u32)x,ptr)
+ #else
+@@ -72,7 +77,7 @@
+ case 2: __get_kernel_asm("ldh",ptr); break; \
+ case 4: __get_kernel_asm("ldw",ptr); break; \
+ case 8: LDD_KERNEL(ptr); break; \
+- default: BUG(); break; \
++ default: __get_kernel_bad(); break; \
+ } \
+ } \
+ else { \
+@@ -81,7 +86,7 @@
+ case 2: __get_user_asm("ldh",ptr); break; \
+ case 4: __get_user_asm("ldw",ptr); break; \
+ case 8: LDD_USER(ptr); break; \
+- default: BUG(); break; \
++ default: __get_user_bad(); break; \
+ } \
+ } \
+ \
+@@ -141,7 +146,7 @@
+ case 2: __put_kernel_asm("sth",x,ptr); break; \
+ case 4: __put_kernel_asm("stw",x,ptr); break; \
+ case 8: STD_KERNEL(x,ptr); break; \
+- default: BUG(); break; \
++ default: __put_kernel_bad(); break; \
+ } \
+ } \
+ else { \
+@@ -150,7 +155,7 @@
+ case 2: __put_user_asm("sth",x,ptr); break; \
+ case 4: __put_user_asm("stw",x,ptr); break; \
+ case 8: STD_USER(x,ptr); break; \
+- default: BUG(); break; \
++ default: __put_user_bad(); break; \
+ } \
+ } \
+ \
+Index: linux-2.6.0-test5/include/asm-ppc64/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/cacheflush.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/cacheflush.h 2003-09-27 11:38:40.672345248 +0800
+@@ -14,12 +14,22 @@
+ #define flush_cache_range(vma, start, end) do { } while (0)
+ #define flush_cache_page(vma, vmaddr) do { } while (0)
+ #define flush_icache_page(vma, page) do { } while (0)
++#define flush_cache_vmap(start, end) do { } while (0)
++#define flush_cache_vunmap(start, end) do { } while (0)
+
+ extern void flush_dcache_page(struct page *page);
+ extern void flush_icache_range(unsigned long, unsigned long);
+ extern void flush_icache_user_range(struct vm_area_struct *vma,
+ struct page *page, unsigned long addr,
+ int len);
++
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++do { memcpy(dst, src, len); \
++ flush_icache_user_range(vma, page, vaddr, len); \
++} while (0)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++ memcpy(dst, src, len)
++
+ extern void __flush_dcache_icache(void *page_va);
+
+ #endif /* _PPC64_CACHEFLUSH_H */
+Index: linux-2.6.0-test5/include/asm-ppc64/hvcall.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/hvcall.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/hvcall.h 2003-09-27 11:38:40.674344944 +0800
+@@ -59,9 +59,6 @@
+ #define H_XIRR 0x74
+ #define H_PERFMON 0x7c
+
+-#define HSC ".long 0x44000022\n"
+-#define H_ENTER_r3 "li 3, 0x08\n"
+-
+ /* plpar_hcall() -- Generic call interface using above opcodes
+ *
+ * The actual call interface is a hypervisor call instruction with
+Index: linux-2.6.0-test5/include/asm-ppc64/ioctl.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/ioctl.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/ioctl.h 2003-09-27 11:38:40.675344792 +0800
+@@ -42,11 +42,21 @@
+ ((nr) << _IOC_NRSHIFT) | \
+ ((size) << _IOC_SIZESHIFT))
+
++/* provoke compile error for invalid uses of size argument */
++extern int __invalid_size_argument_for_IOC;
++#define _IOC_TYPECHECK(t) \
++ ((sizeof(t) == sizeof(t[1]) && \
++ sizeof(t) < (1 << _IOC_SIZEBITS)) ? \
++ sizeof(t) : __invalid_size_argument_for_IOC)
++
+ /* used to create numbers */
+ #define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0)
+-#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size))
+-#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
+-#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
++#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size)))
++#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
++#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
++#define _IOR_BAD(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size))
++#define _IOW_BAD(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
++#define _IOWR_BAD(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
+
+ /* used to decode them.. */
+ #define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+Index: linux-2.6.0-test5/include/asm-ppc64/local.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/local.h 2003-09-27 11:38:18.481718736 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/local.h 2003-09-27 11:38:40.676344640 +0800
+@@ -0,0 +1 @@
++#include <asm-generic/local.h>
+Index: linux-2.6.0-test5/include/asm-ppc64/mmu_context.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/mmu_context.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/mmu_context.h 2003-09-27 11:38:40.678344336 +0800
+@@ -127,7 +127,8 @@
+ #endif
+
+ mmu_context_queue.size++;
+- mmu_context_queue.elements[index] = mm->context;
++ mmu_context_queue.elements[index] =
++ mm->context & ~CONTEXT_LOW_HPAGES;
+
+ spin_unlock_irqrestore(&mmu_context_queue.lock, flags);
+ }
+@@ -189,6 +190,8 @@
+ {
+ unsigned long ordinal, vsid;
+
++ context &= ~CONTEXT_LOW_HPAGES;
++
+ ordinal = (((ea >> 28) & 0x1fffff) * LAST_USER_CONTEXT) | context;
+ vsid = (ordinal * VSID_RANDOMIZER) & VSID_MASK;
+
+Index: linux-2.6.0-test5/include/asm-ppc64/mmu.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/mmu.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/mmu.h 2003-09-27 11:38:40.681343880 +0800
+@@ -18,6 +18,12 @@
+ /* Default "unsigned long" context */
+ typedef unsigned long mm_context_t;
+
++#ifdef CONFIG_HUGETLB_PAGE
++#define CONTEXT_LOW_HPAGES (1UL<<63)
++#else
++#define CONTEXT_LOW_HPAGES 0
++#endif
++
+ /*
+ * Define the size of the cache used for segment table entries. The first
+ * entry is used as a cache pointer, therefore the actual number of entries
+Index: linux-2.6.0-test5/include/asm-ppc64/mmzone.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/mmzone.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/mmzone.h 2003-09-27 11:38:40.683343576 +0800
+@@ -20,7 +20,7 @@
+
+ extern int numa_cpu_lookup_table[];
+ extern int numa_memory_lookup_table[];
+-extern unsigned long numa_cpumask_lookup_table[];
++extern cpumask_t numa_cpumask_lookup_table[];
+ extern int nr_cpus_in_node[];
+
+ #define MAX_MEMORY (1UL << 41)
+Index: linux-2.6.0-test5/include/asm-ppc64/numnodes.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/numnodes.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/numnodes.h 2003-09-27 11:38:40.684343424 +0800
+@@ -1,6 +1,7 @@
+ #ifndef _ASM_MAX_NUMNODES_H
+ #define _ASM_MAX_NUMNODES_H
+
+-#define MAX_NUMNODES 16
++/* Max 16 Nodes */
++#define NODES_SHIFT 4
+
+ #endif /* _ASM_MAX_NUMNODES_H */
+Index: linux-2.6.0-test5/include/asm-ppc64/paca.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/paca.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/paca.h 2003-09-27 11:38:40.687342968 +0800
+@@ -63,7 +63,7 @@
+ u16 xPacaIndex; /* Logical processor number 0x18 */
+ u16 active; /* Is this cpu active? 0x1a */
+ u32 default_decr; /* Default decrementer value 0x1c */
+- u64 xHrdIntStack; /* Stack for hardware interrupts 0x20 */
++ u64 unused1;
+ u64 xKsave; /* Saved Kernel stack addr or zero 0x28 */
+ u64 pvr; /* Processor version register 0x30 */
+ u8 *exception_sp; /* 0x38 */
+@@ -73,7 +73,7 @@
+ STAB xStab_data; /* Segment table information 0x50,0x58,0x60 */
+ u8 xSegments[STAB_CACHE_SIZE]; /* Cache of used stab entries 0x68,0x70 */
+ u8 xProcEnabled; /* 1=soft enabled 0x78 */
+- u8 xHrdIntCount; /* Count of active hardware interrupts 0x79 */
++ u8 unused2;
+ u8 prof_enabled; /* 1=iSeries profiling enabled 0x7A */
+ u8 stab_cache_pointer;
+ u8 resv1[4]; /* 0x7B-0x7F */
+Index: linux-2.6.0-test5/include/asm-ppc64/page.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/page.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/page.h 2003-09-27 11:38:40.689342664 +0800
+@@ -22,6 +22,39 @@
+ #define PAGE_MASK (~(PAGE_SIZE-1))
+ #define PAGE_OFFSET_MASK (PAGE_SIZE-1)
+
++#ifdef CONFIG_HUGETLB_PAGE
++
++#define HPAGE_SHIFT 24
++#define HPAGE_SIZE ((1UL) << HPAGE_SHIFT)
++#define HPAGE_MASK (~(HPAGE_SIZE - 1))
++#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)
++
++/* For 64-bit processes the hugepage range is 1T-1.5T */
++#define TASK_HPAGE_BASE (0x0000010000000000UL)
++#define TASK_HPAGE_END (0x0000018000000000UL)
++/* For 32-bit processes the hugepage range is 2-3G */
++#define TASK_HPAGE_BASE_32 (0x80000000UL)
++#define TASK_HPAGE_END_32 (0xc0000000UL)
++
++#define ARCH_HAS_HUGEPAGE_ONLY_RANGE
++#define is_hugepage_only_range(addr, len) \
++ ( ((addr > (TASK_HPAGE_BASE-len)) && (addr < TASK_HPAGE_END)) || \
++ ((current->mm->context & CONTEXT_LOW_HPAGES) && \
++ (addr > (TASK_HPAGE_BASE_32-len)) && (addr < TASK_HPAGE_END_32)) )
++#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
++
++#define in_hugepage_area(context, addr) \
++ ((cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE) && \
++ ((((addr) >= TASK_HPAGE_BASE) && ((addr) < TASK_HPAGE_END)) || \
++ (((context) & CONTEXT_LOW_HPAGES) && \
++ (((addr) >= TASK_HPAGE_BASE_32) && ((addr) < TASK_HPAGE_END_32)))))
++
++#else /* !CONFIG_HUGETLB_PAGE */
++
++#define in_hugepage_area(mm, addr) 0
++
++#endif /* !CONFIG_HUGETLB_PAGE */
++
+ #define SID_SHIFT 28
+ #define SID_MASK 0xfffffffff
+ #define GET_ESID(x) (((x) >> SID_SHIFT) & SID_MASK)
+Index: linux-2.6.0-test5/include/asm-ppc64/pgtable.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/pgtable.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/pgtable.h 2003-09-27 11:38:40.693342056 +0800
+@@ -45,7 +45,6 @@
+ * Define the address range of the vmalloc VM area.
+ */
+ #define VMALLOC_START (0xD000000000000000)
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END (VMALLOC_START + VALID_EA_BITS)
+
+ /*
+@@ -149,6 +148,25 @@
+ /* shift to put page number into pte */
+ #define PTE_SHIFT (16)
+
++/* We allow 2^41 bytes of real memory, so we need 29 bits in the PMD
++ * to give the PTE page number. The bottom two bits are for flags. */
++#define PMD_TO_PTEPAGE_SHIFT (2)
++
++#ifdef CONFIG_HUGETLB_PAGE
++#define _PMD_HUGEPAGE 0x00000001U
++#define HUGEPTE_BATCH_SIZE (1<<(HPAGE_SHIFT-PMD_SHIFT))
++
++int hash_huge_page(struct mm_struct *mm, unsigned long access,
++ unsigned long ea, unsigned long vsid, int local);
++
++#define HAVE_ARCH_UNMAPPED_AREA
++#else
++
++#define hash_huge_page(mm,a,ea,vsid,local) -1
++#define _PMD_HUGEPAGE 0
++
++#endif
++
+ #ifndef __ASSEMBLY__
+
+ /*
+@@ -178,12 +196,16 @@
+ #define pte_pfn(x) ((unsigned long)((pte_val(x) >> PTE_SHIFT)))
+ #define pte_page(x) pfn_to_page(pte_pfn(x))
+
+-#define pmd_set(pmdp, ptep) (pmd_val(*(pmdp)) = (__ba_to_bpn(ptep)))
++#define pmd_set(pmdp, ptep) \
++ (pmd_val(*(pmdp)) = (__ba_to_bpn(ptep) << PMD_TO_PTEPAGE_SHIFT))
+ #define pmd_none(pmd) (!pmd_val(pmd))
+-#define pmd_bad(pmd) ((pmd_val(pmd)) == 0)
+-#define pmd_present(pmd) ((pmd_val(pmd)) != 0)
++#define pmd_hugepage(pmd) (!!(pmd_val(pmd) & _PMD_HUGEPAGE))
++#define pmd_bad(pmd) (((pmd_val(pmd)) == 0) || pmd_hugepage(pmd))
++#define pmd_present(pmd) ((!pmd_hugepage(pmd)) \
++ && (pmd_val(pmd) & ~_PMD_HUGEPAGE) != 0)
+ #define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0)
+-#define pmd_page_kernel(pmd) (__bpn_to_ba(pmd_val(pmd)))
++#define pmd_page_kernel(pmd) \
++ (__bpn_to_ba(pmd_val(pmd) >> PMD_TO_PTEPAGE_SHIFT))
+ #define pmd_page(pmd) virt_to_page(pmd_page_kernel(pmd))
+ #define pgd_set(pgdp, pmdp) (pgd_val(*(pgdp)) = (__ba_to_bpn(pmdp)))
+ #define pgd_none(pgd) (!pgd_val(pgd))
+Index: linux-2.6.0-test5/include/asm-ppc64/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/posix_types.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/posix_types.h 2003-09-27 11:38:40.695341752 +0800
+@@ -12,7 +12,6 @@
+ * 2 of the License, or (at your option) any later version.
+ */
+
+-typedef unsigned long __kernel_dev_t;
+ typedef unsigned long __kernel_ino_t;
+ typedef unsigned long __kernel_nlink_t;
+ typedef unsigned int __kernel_mode_t;
+Index: linux-2.6.0-test5/include/asm-ppc64/processor.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/processor.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/processor.h 2003-09-27 11:38:40.703340536 +0800
+@@ -612,8 +612,6 @@
+ /*
+ * Bus types
+ */
+-#define EISA_bus 0
+-#define EISA_bus__is_a_macro /* for versions in ksyms.c */
+ #define MCA_bus 0
+ #define MCA_bus__is_a_macro /* for versions in ksyms.c */
+
+Index: linux-2.6.0-test5/include/asm-ppc64/prom.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/prom.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/prom.h 2003-09-27 11:38:40.705340232 +0800
+@@ -183,8 +183,6 @@
+ extern struct device_node *find_path_device(const char *path);
+ extern struct device_node *find_compatible_devices(const char *type,
+ const char *compat);
+-extern struct device_node *find_pci_device_OFnode(unsigned char bus,
+- unsigned char dev_fn);
+ extern struct device_node *find_all_nodes(void);
+ extern int device_is_compatible(struct device_node *device, const char *);
+ extern int machine_is_compatible(const char *compat);
+Index: linux-2.6.0-test5/include/asm-ppc64/rtas.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/rtas.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/rtas.h 2003-09-27 11:38:40.708339776 +0800
+@@ -166,6 +166,13 @@
+ extern void rtas_power_off(void);
+ extern void rtas_halt(void);
+
++/* Given an RTAS status code of 9900..9905 compute the hinted delay */
++unsigned int rtas_extended_busy_delay_time(int status);
++static inline int rtas_is_extended_busy(int status)
++{
++ return status >= 9900 && status <= 9909;
++}
++
+ /* Some RTAS ops require a data buffer and that buffer must be < 4G.
+ * Rather than having a memory allocator, just use this buffer
+ * (get the lock first), make the RTAS call. Copy the data instead
+Index: linux-2.6.0-test5/include/asm-ppc64/rwsem.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/rwsem.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/rwsem.h 2003-09-27 11:38:40.709339624 +0800
+@@ -1,5 +1,5 @@
+ /*
+- * include/asm-ppc/rwsem.h: R/W semaphores for PPC using the stuff
++ * include/asm-ppc64/rwsem.h: R/W semaphores for PPC using the stuff
+ * in lib/rwsem.c. Adapted largely from include/asm-i386/rwsem.h
+ * by Paul Mackerras <paulus@samba.org>.
+ *
+@@ -74,9 +74,7 @@
+ */
+ static inline void __down_read(struct rw_semaphore *sem)
+ {
+- if (atomic_inc_return((atomic_t *)(&sem->count)) > 0)
+- smp_wmb();
+- else
++ if (unlikely(atomic_inc_return((atomic_t *)(&sem->count)) <= 0))
+ rwsem_down_read_failed(sem);
+ }
+
+@@ -87,7 +85,6 @@
+ while ((tmp = sem->count) >= 0) {
+ if (tmp == cmpxchg(&sem->count, tmp,
+ tmp + RWSEM_ACTIVE_READ_BIAS)) {
+- smp_wmb();
+ return 1;
+ }
+ }
+@@ -103,9 +100,7 @@
+
+ tmp = atomic_add_return(RWSEM_ACTIVE_WRITE_BIAS,
+ (atomic_t *)(&sem->count));
+- if (tmp == RWSEM_ACTIVE_WRITE_BIAS)
+- smp_wmb();
+- else
++ if (unlikely(tmp != RWSEM_ACTIVE_WRITE_BIAS))
+ rwsem_down_write_failed(sem);
+ }
+
+@@ -115,7 +110,6 @@
+
+ tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE,
+ RWSEM_ACTIVE_WRITE_BIAS);
+- smp_wmb();
+ return tmp == RWSEM_UNLOCKED_VALUE;
+ }
+
+@@ -126,9 +120,8 @@
+ {
+ int tmp;
+
+- smp_wmb();
+ tmp = atomic_dec_return((atomic_t *)(&sem->count));
+- if (tmp < -1 && (tmp & RWSEM_ACTIVE_MASK) == 0)
++ if (unlikely(tmp < -1 && (tmp & RWSEM_ACTIVE_MASK) == 0))
+ rwsem_wake(sem);
+ }
+
+@@ -137,9 +130,8 @@
+ */
+ static inline void __up_write(struct rw_semaphore *sem)
+ {
+- smp_wmb();
+- if (atomic_sub_return(RWSEM_ACTIVE_WRITE_BIAS,
+- (atomic_t *)(&sem->count)) < 0)
++ if (unlikely(atomic_sub_return(RWSEM_ACTIVE_WRITE_BIAS,
++ (atomic_t *)(&sem->count)) < 0))
+ rwsem_wake(sem);
+ }
+
+@@ -158,7 +150,6 @@
+ {
+ int tmp;
+
+- smp_wmb();
+ tmp = atomic_add_return(-RWSEM_WAITING_BIAS, (atomic_t *)(&sem->count));
+ if (tmp < 0)
+ rwsem_downgrade_wake(sem);
+@@ -169,7 +160,6 @@
+ */
+ static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
+ {
+- smp_mb();
+ return atomic_add_return(delta, (atomic_t *)(&sem->count));
+ }
+
+Index: linux-2.6.0-test5/include/asm-ppc64/semaphore.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/semaphore.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/semaphore.h 2003-09-27 11:38:40.711339320 +0800
+@@ -22,6 +22,7 @@
+ * sleeping on `wait'.
+ */
+ atomic_t count;
++ int sleepers;
+ wait_queue_head_t wait;
+ #ifdef WAITQUEUE_DEBUG
+ long __magic;
+@@ -37,6 +38,7 @@
+
+ #define __SEMAPHORE_INITIALIZER(name, count) \
+ { ATOMIC_INIT(count), \
++ 0, \
+ __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
+ __SEM_DEBUG_INIT(name) }
+
+@@ -52,6 +54,7 @@
+ static inline void sema_init (struct semaphore *sem, int val)
+ {
+ atomic_set(&sem->count, val);
++ sem->sleepers = 0;
+ init_waitqueue_head(&sem->wait);
+ #ifdef WAITQUEUE_DEBUG
+ sem->__magic = (long)&sem->__magic;
+@@ -82,9 +85,8 @@
+ /*
+ * Try to get the semaphore, take the slow path if we fail.
+ */
+- if (atomic_dec_return(&sem->count) < 0)
++ if (unlikely(atomic_dec_return(&sem->count) < 0))
+ __down(sem);
+- smp_wmb();
+ }
+
+ static inline int down_interruptible(struct semaphore * sem)
+@@ -96,23 +98,18 @@
+ #endif
+ might_sleep();
+
+- if (atomic_dec_return(&sem->count) < 0)
++ if (unlikely(atomic_dec_return(&sem->count) < 0))
+ ret = __down_interruptible(sem);
+- smp_wmb();
+ return ret;
+ }
+
+ static inline int down_trylock(struct semaphore * sem)
+ {
+- int ret;
+-
+ #ifdef WAITQUEUE_DEBUG
+ CHECK_MAGIC(sem->__magic);
+ #endif
+
+- ret = atomic_dec_if_positive(&sem->count) < 0;
+- smp_wmb();
+- return ret;
++ return atomic_dec_if_positive(&sem->count) < 0;
+ }
+
+ static inline void up(struct semaphore * sem)
+@@ -121,8 +118,7 @@
+ CHECK_MAGIC(sem->__magic);
+ #endif
+
+- smp_wmb();
+- if (atomic_inc_return(&sem->count) <= 0)
++ if (unlikely(atomic_inc_return(&sem->count) <= 0))
+ __up(sem);
+ }
+
+Index: linux-2.6.0-test5/include/asm-ppc64/serial.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/serial.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/serial.h 2003-09-27 11:38:40.713339016 +0800
+@@ -26,11 +26,9 @@
+
+ /* Standard COM flags (except for COM4, because of the 8514 problem) */
+ #ifdef CONFIG_SERIAL_DETECT_IRQ
+-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ)
+-#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ)
++#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ)
+ #else
+-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+-#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
++#define STD_COM_FLAGS ASYNC_BOOT_AUTOCONF
+ #endif
+
+ #ifdef CONFIG_SERIAL_MANY_PORTS
+@@ -60,8 +58,8 @@
+ /* UART CLK PORT IRQ FLAGS */ \
+ { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \
+ { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \
+- { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \
+- { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */
++ { 0, BASE_BAUD, 0x890, 0xf, STD_COM_FLAGS }, /* ttyS2 */ \
++ { 0, BASE_BAUD, 0x898, 0xe, STD_COM_FLAGS }, /* ttyS3 */
+
+
+ #ifdef CONFIG_SERIAL_MANY_PORTS
+Index: linux-2.6.0-test5/include/asm-ppc64/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/signal.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/signal.h 2003-09-27 11:38:40.715338712 +0800
+@@ -57,7 +57,7 @@
+
+ /* These should not be considered constants from userland. */
+ #define SIGRTMIN 32
+-#define SIGRTMAX (_NSIG-1)
++#define SIGRTMAX _NSIG
+
+ /*
+ * SA_FLAGS values:
+Index: linux-2.6.0-test5/include/asm-ppc64/stat.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/stat.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/stat.h 2003-09-27 11:38:40.717338408 +0800
+@@ -11,13 +11,13 @@
+ #include <linux/types.h>
+
+ struct stat {
+- dev_t st_dev;
++ unsigned long st_dev;
+ ino_t st_ino;
+ nlink_t st_nlink;
+ mode_t st_mode;
+ uid_t st_uid;
+ gid_t st_gid;
+- dev_t st_rdev;
++ unsigned long st_rdev;
+ off_t st_size;
+ unsigned long st_blksize;
+ unsigned long st_blocks;
+Index: linux-2.6.0-test5/include/asm-ppc64/topology.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/topology.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/topology.h 2003-09-27 11:38:40.718338256 +0800
+@@ -24,14 +24,16 @@
+
+ #define parent_node(node) (node)
+
+-static inline unsigned long node_to_cpumask(int node)
++static inline cpumask_t node_to_cpumask(int node)
+ {
+ return numa_cpumask_lookup_table[node];
+ }
+
+ static inline int node_to_first_cpu(int node)
+ {
+- return __ffs(node_to_cpumask(node));
++ cpumask_t tmp;
++ tmp = node_to_cpumask(node);
++ return first_cpu(tmp);
+ }
+
+ #define node_to_memblk(node) (node)
+Index: linux-2.6.0-test5/include/asm-ppc64/uaccess.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/uaccess.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/uaccess.h 2003-09-27 11:38:40.722337648 +0800
+@@ -132,6 +132,7 @@
+
+ #define __put_user_size(x,ptr,size,retval,errret) \
+ do { \
++ might_sleep(); \
+ retval = 0; \
+ switch (size) { \
+ case 1: __put_user_asm(x,ptr,retval,"stb",errret); break; \
+@@ -185,6 +186,7 @@
+
+ #define __get_user_size(x,ptr,size,retval,errret) \
+ do { \
++ might_sleep(); \
+ retval = 0; \
+ switch (size) { \
+ case 1: __get_user_asm(x,ptr,retval,"lbz",errret); break; \
+@@ -220,6 +222,7 @@
+ static inline unsigned long
+ __copy_from_user(void *to, const void __user *from, unsigned long n)
+ {
++ might_sleep();
+ if (__builtin_constant_p(n)) {
+ unsigned long ret;
+
+@@ -244,6 +247,7 @@
+ static inline unsigned long
+ __copy_to_user(void __user *to, const void *from, unsigned long n)
+ {
++ might_sleep();
+ if (__builtin_constant_p(n)) {
+ unsigned long ret;
+
+@@ -289,6 +293,7 @@
+ static inline unsigned long
+ copy_in_user(void *to, const void *from, unsigned long n)
+ {
++ might_sleep();
+ if (likely(access_ok(VERIFY_READ, from, n) &&
+ access_ok(VERIFY_WRITE, to, n)))
+ n =__copy_tofrom_user(to, from, n);
+@@ -300,6 +305,7 @@
+ static inline unsigned long
+ clear_user(void *addr, unsigned long size)
+ {
++ might_sleep();
+ if (likely(access_ok(VERIFY_WRITE, addr, size)))
+ size = __clear_user(addr, size);
+ return size;
+@@ -310,6 +316,7 @@
+ static inline long
+ strncpy_from_user(char *dst, const char *src, long count)
+ {
++ might_sleep();
+ if (likely(access_ok(VERIFY_READ, src, 1)))
+ return __strncpy_from_user(dst, src, count);
+ return -EFAULT;
+@@ -329,6 +336,7 @@
+ */
+ static inline int strnlen_user(const char *str, long len)
+ {
++ might_sleep();
+ if (likely(access_ok(VERIFY_READ, str, 1)))
+ return __strnlen_user(str, len);
+ return 0;
+Index: linux-2.6.0-test5/include/asm-ppc/bitops.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc/bitops.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc/bitops.h 2003-09-27 11:38:40.725337192 +0800
+@@ -276,7 +276,7 @@
+ * Find the first bit set in a 140-bit bitmap.
+ * The first 100 bits are unlikely to be set.
+ */
+-static inline int sched_find_first_bit(unsigned long *b)
++static inline int sched_find_first_bit(const unsigned long *b)
+ {
+ if (unlikely(b[0]))
+ return __ffs(b[0]);
+@@ -295,7 +295,7 @@
+ * @offset: The bitnumber to start searching at
+ * @size: The maximum size to search
+ */
+-static __inline__ unsigned long find_next_bit(unsigned long *addr,
++static __inline__ unsigned long find_next_bit(const unsigned long *addr,
+ unsigned long size, unsigned long offset)
+ {
+ unsigned int *p = ((unsigned int *) addr) + (offset >> 5);
+@@ -352,7 +352,7 @@
+ #define find_first_zero_bit(addr, size) \
+ find_next_zero_bit((addr), (size), 0)
+
+-static __inline__ unsigned long find_next_zero_bit(unsigned long * addr,
++static __inline__ unsigned long find_next_zero_bit(const unsigned long *addr,
+ unsigned long size, unsigned long offset)
+ {
+ unsigned int * p = ((unsigned int *) addr) + (offset >> 5);
+@@ -411,7 +411,7 @@
+ #define ext2_find_first_zero_bit(addr, size) \
+ ext2_find_next_zero_bit((addr), (size), 0)
+
+-static __inline__ unsigned long ext2_find_next_zero_bit(void *addr,
++static __inline__ unsigned long ext2_find_next_zero_bit(const void *addr,
+ unsigned long size, unsigned long offset)
+ {
+ unsigned int *p = ((unsigned int *) addr) + (offset >> 5);
+Index: linux-2.6.0-test5/include/asm-ppc/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc/cacheflush.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc/cacheflush.h 2003-09-27 11:38:40.726337040 +0800
+@@ -24,12 +24,21 @@
+ #define flush_cache_range(vma, a, b) do { } while (0)
+ #define flush_cache_page(vma, p) do { } while (0)
+ #define flush_icache_page(vma, page) do { } while (0)
++#define flush_cache_vmap(start, end) do { } while (0)
++#define flush_cache_vunmap(start, end) do { } while (0)
+
+ extern void flush_dcache_page(struct page *page);
+ extern void flush_icache_range(unsigned long, unsigned long);
+ extern void flush_icache_user_range(struct vm_area_struct *vma,
+ struct page *page, unsigned long addr, int len);
+
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++do { memcpy(dst, src, len); \
++ flush_icache_user_range(vma, page, vaddr, len); \
++} while (0)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++ memcpy(dst, src, len)
++
+ extern void __flush_dcache_icache(void *page_va);
+ extern void __flush_dcache_icache_phys(unsigned long physaddr);
+
+Index: linux-2.6.0-test5/include/asm-ppc/highmem.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc/highmem.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc/highmem.h 2003-09-27 11:38:40.728336736 +0800
+@@ -26,6 +26,7 @@
+ #include <linux/interrupt.h>
+ #include <asm/kmap_types.h>
+ #include <asm/tlbflush.h>
++#include <asm/page.h>
+
+ /* undef for production */
+ #define HIGHMEM_DEBUG 1
+@@ -41,8 +42,8 @@
+ * easily, subsequent pte tables have to be allocated in one physical
+ * chunk of RAM.
+ */
+-#define PKMAP_BASE CONFIG_HIGHMEM_START
+-#define LAST_PKMAP 1024
++#define PKMAP_BASE CONFIG_HIGHMEM_START
++#define LAST_PKMAP (1 << PTE_SHIFT)
+ #define LAST_PKMAP_MASK (LAST_PKMAP-1)
+ #define PKMAP_NR(virt) ((virt-PKMAP_BASE) >> PAGE_SHIFT)
+ #define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT))
+@@ -131,6 +132,8 @@
+ return pte_page(kmap_pte[idx]);
+ }
+
++#define flush_cache_kmaps() flush_cache_all()
++
+ #endif /* __KERNEL__ */
+
+ #endif /* _ASM_HIGHMEM_H */
+Index: linux-2.6.0-test5/include/asm-ppc/ioctl.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc/ioctl.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc/ioctl.h 2003-09-27 11:38:40.729336584 +0800
+@@ -37,11 +37,21 @@
+ ((nr) << _IOC_NRSHIFT) | \
+ ((size) << _IOC_SIZESHIFT))
+
++/* provoke compile error for invalid uses of size argument */
++extern int __invalid_size_argument_for_IOC;
++#define _IOC_TYPECHECK(t) \
++ ((sizeof(t) == sizeof(t[1]) && \
++ sizeof(t) < (1 << _IOC_SIZEBITS)) ? \
++ sizeof(t) : __invalid_size_argument_for_IOC)
++
+ /* used to create numbers */
+ #define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0)
+-#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size))
+-#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
+-#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
++#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size)))
++#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
++#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
++#define _IOR_BAD(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size))
++#define _IOW_BAD(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
++#define _IOWR_BAD(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
+
+ /* used to decode them.. */
+ #define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+Index: linux-2.6.0-test5/include/asm-ppc/pgtable.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc/pgtable.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc/pgtable.h 2003-09-27 11:38:40.736335520 +0800
+@@ -129,7 +129,6 @@
+ #else
+ #define VMALLOC_START ((((long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
+ #endif
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END ioremap_bot
+
+ /*
+Index: linux-2.6.0-test5/include/asm-ppc/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc/posix_types.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc/posix_types.h 2003-09-27 11:38:40.738335216 +0800
+@@ -7,7 +7,6 @@
+ * assume GCC is being used.
+ */
+
+-typedef unsigned int __kernel_dev_t;
+ typedef unsigned long __kernel_ino_t;
+ typedef unsigned int __kernel_mode_t;
+ typedef unsigned short __kernel_nlink_t;
+Index: linux-2.6.0-test5/include/asm-ppc/processor.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc/processor.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc/processor.h 2003-09-27 11:38:40.749333544 +0800
+@@ -803,7 +803,6 @@
+ /*
+ * Bus types
+ */
+-#define EISA_bus 0
+ #define MCA_bus 0
+ #define MCA_bus__is_a_macro
+
+@@ -848,6 +847,7 @@
+ /* AltiVec status */
+ vector128 vscr __attribute((aligned(16)));
+ unsigned long vrsave;
++ int used_vr; /* set if process has used altivec */
+ #endif /* CONFIG_ALTIVEC */
+ };
+
+Index: linux-2.6.0-test5/include/asm-ppc/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc/signal.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc/signal.h 2003-09-27 11:38:40.750333392 +0800
+@@ -61,7 +61,7 @@
+
+ /* These should not be considered constants from userland. */
+ #define SIGRTMIN 32
+-#define SIGRTMAX (_NSIG-1)
++#define SIGRTMAX _NSIG
+
+ /*
+ * SA_FLAGS values:
+Index: linux-2.6.0-test5/include/asm-ppc/stat.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc/stat.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc/stat.h 2003-09-27 11:38:40.752333088 +0800
+@@ -22,13 +22,13 @@
+ #define STAT_HAVE_NSEC 1
+
+ struct stat {
+- dev_t st_dev;
++ unsigned st_dev;
+ ino_t st_ino;
+ mode_t st_mode;
+ nlink_t st_nlink;
+ uid_t st_uid;
+ gid_t st_gid;
+- dev_t st_rdev;
++ unsigned st_rdev;
+ off_t st_size;
+ unsigned long st_blksize;
+ unsigned long st_blocks;
+Index: linux-2.6.0-test5/include/asm-ppc/time.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc/time.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc/time.h 2003-09-27 11:38:40.753332936 +0800
+@@ -97,6 +97,13 @@
+ return rtcl;
+ }
+
++extern __inline__ unsigned long get_rtcu(void)
++{
++ unsigned long rtcu;
++ asm volatile("mfrtcu %0" : "=r" (rtcu));
++ return rtcu;
++}
++
+ extern __inline__ unsigned get_native_tbl(void) {
+ if (__USE_RTC())
+ return get_rtcl();
+@@ -140,6 +147,7 @@
+ #endif
+
+ /* Use mulhwu to scale processor timebase to timeval */
++/* Specifically, this computes (x * y) / 2^32. -- paulus */
+ #define mulhwu(x,y) \
+ ({unsigned z; asm ("mulhwu %0,%1,%2" : "=r" (z) : "r" (x), "r" (y)); z;})
+
+Index: linux-2.6.0-test5/include/asm-ppc/ucontext.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc/ucontext.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc/ucontext.h 2003-09-27 11:38:40.755332632 +0800
+@@ -1,14 +1,28 @@
+ #ifndef _ASMPPC_UCONTEXT_H
+ #define _ASMPPC_UCONTEXT_H
+
+-/* Copied from i386. */
++#include <asm/elf.h>
++#include <asm/signal.h>
++
++struct mcontext {
++ elf_gregset_t mc_gregs;
++ elf_fpregset_t mc_fregs;
++ unsigned long mc_pad[2];
++ elf_vrregset_t mc_vregs __attribute__((__aligned__(16)));
++};
+
+ struct ucontext {
+- unsigned long uc_flags;
+- struct ucontext *uc_link;
+- stack_t uc_stack;
+- struct sigcontext uc_mcontext;
+- sigset_t uc_sigmask; /* mask last for extensibility */
++ unsigned long uc_flags;
++ struct ucontext *uc_link;
++ stack_t uc_stack;
++ int uc_pad[7];
++ struct mcontext *uc_regs; /* backward compat */
++ sigset_t uc_oldsigmask; /* backward compat */
++ int uc_pad2;
++ sigset_t uc_sigmask;
++ /* glibc has 1024-bit signal masks, ours are 64-bit */
++ int uc_maskext[30];
++ struct mcontext uc_mcontext;
+ };
+
+ #endif /* !_ASMPPC_UCONTEXT_H */
+Index: linux-2.6.0-test5/include/asm-s390/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-s390/cacheflush.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-s390/cacheflush.h 2003-09-27 11:38:40.756332480 +0800
+@@ -13,5 +13,12 @@
+ #define flush_icache_range(start, end) do { } while (0)
+ #define flush_icache_page(vma,pg) do { } while (0)
+ #define flush_icache_user_range(vma,pg,adr,len) do { } while (0)
++#define flush_cache_vmap(start, end) do { } while (0)
++#define flush_cache_vunmap(start, end) do { } while (0)
++
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++ memcpy(dst, src, len)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++ memcpy(dst, src, len)
+
+ #endif /* _S390_CACHEFLUSH_H */
+Index: linux-2.6.0-test5/include/asm-s390/pgtable.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-s390/pgtable.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-s390/pgtable.h 2003-09-27 11:38:40.762331568 +0800
+@@ -117,7 +117,6 @@
+ #define VMALLOC_OFFSET (8*1024*1024)
+ #define VMALLOC_START (((unsigned long) high_memory + VMALLOC_OFFSET) \
+ & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #ifndef __s390x__
+ # define VMALLOC_END (0x7fffffffL)
+ #else /* __s390x__ */
+Index: linux-2.6.0-test5/include/asm-s390/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-s390/posix_types.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-s390/posix_types.h 2003-09-27 11:38:40.764331264 +0800
+@@ -34,7 +34,6 @@
+
+ #ifndef __s390x__
+
+-typedef unsigned short __kernel_dev_t;
+ typedef unsigned long __kernel_ino_t;
+ typedef unsigned short __kernel_mode_t;
+ typedef unsigned short __kernel_nlink_t;
+@@ -51,7 +50,6 @@
+
+ #else /* __s390x__ */
+
+-typedef unsigned int __kernel_dev_t;
+ typedef unsigned int __kernel_ino_t;
+ typedef unsigned int __kernel_mode_t;
+ typedef unsigned int __kernel_nlink_t;
+Index: linux-2.6.0-test5/include/asm-s390/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-s390/signal.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-s390/signal.h 2003-09-27 11:38:40.766330960 +0800
+@@ -78,7 +78,7 @@
+
+ /* These should not be considered constants from userland. */
+ #define SIGRTMIN 32
+-#define SIGRTMAX (_NSIG-1)
++#define SIGRTMAX _NSIG
+
+ /*
+ * SA_FLAGS values:
+Index: linux-2.6.0-test5/include/asm-sh/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sh/cacheflush.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sh/cacheflush.h 2003-09-27 11:38:40.768330656 +0800
+@@ -10,4 +10,14 @@
+ /* Flush (invalidate only) a region (smaller than a page) */
+ extern void __flush_invalidate_region(void *start, int size);
+
++#define flush_cache_vmap(start, end) flush_cache_all()
++#define flush_cache_vunmap(start, end) flush_cache_all()
++
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++do { memcpy(dst, src, len); \
++ flush_icache_user_range(vma, page, vaddr, len); \
++} while (0)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++ memcpy(dst, src, len)
++
+ #endif /* __ASM_SH_CACHEFLUSH_H */
+Index: linux-2.6.0-test5/include/asm-sh/mmzone.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sh/mmzone.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sh/mmzone.h 2003-09-27 11:38:40.769330504 +0800
+@@ -10,14 +10,14 @@
+
+ #include <linux/config.h>
+
++#ifdef CONFIG_DISCONTIGMEM
++
+ /* Currently, just for HP690 */
+ #define PHYSADDR_TO_NID(phys) ((((phys) - __MEMORY_START) >= 0x01000000)?1:0)
+-#define NR_NODES 2
+
+-extern pg_data_t discontig_page_data[NR_NODES];
+-extern bootmem_data_t discontig_node_bdata[NR_NODES];
++extern pg_data_t discontig_page_data[MAX_NUMNODES];
++extern bootmem_data_t discontig_node_bdata[MAX_NUMNODES];
+
+-#ifdef CONFIG_DISCONTIGMEM
+ /*
+ * Following are macros that each numa implmentation must define.
+ */
+@@ -46,7 +46,7 @@
+ {
+ unsigned int i;
+
+- for (i = 0; i < NR_NODES; i++) {
++ for (i = 0; i < MAX_NUMNODES; i++) {
+ if (page >= NODE_MEM_MAP(i) &&
+ page < NODE_MEM_MAP(i) + NODE_DATA(i)->node_size)
+ return 1;
+Index: linux-2.6.0-test5/include/asm-sh/numnodes.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sh/numnodes.h 2003-09-27 11:38:18.482718584 +0800
++++ linux-2.6.0-test5/include/asm-sh/numnodes.h 2003-09-27 11:38:40.769330504 +0800
+@@ -0,0 +1,7 @@
++#ifndef _ASM_MAX_NUMNODES_H
++#define _ASM_MAX_NUMNODES_H
++
++/* Max 2 Nodes */
++#define NODES_SHIFT 1
++
++#endif /* _ASM_MAX_NUMNODES_H */
+Index: linux-2.6.0-test5/include/asm-sh/pgtable.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sh/pgtable.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sh/pgtable.h 2003-09-27 11:38:40.773329896 +0800
+@@ -51,7 +51,6 @@
+ * Currently only 4-enty (16kB) is used (see arch/sh/mm/cache.c)
+ */
+ #define VMALLOC_START (P3SEG+0x00100000)
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END P4SEG
+
+ /* 0x001 WT-bit on SH-4, 0 on SH-3 */
+Index: linux-2.6.0-test5/include/asm-sh/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sh/posix_types.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sh/posix_types.h 2003-09-27 11:38:40.774329744 +0800
+@@ -7,7 +7,6 @@
+ * assume GCC is being used.
+ */
+
+-typedef unsigned short __kernel_dev_t;
+ typedef unsigned long __kernel_ino_t;
+ typedef unsigned short __kernel_mode_t;
+ typedef unsigned short __kernel_nlink_t;
+Index: linux-2.6.0-test5/include/asm-sh/processor.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sh/processor.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sh/processor.h 2003-09-27 11:38:40.777329288 +0800
+@@ -169,8 +169,6 @@
+ /*
+ * Bus types
+ */
+-#define EISA_bus 0
+-#define EISA_bus__is_a_macro /* for versions in ksyms.c */
+ #define MCA_bus 0
+ #define MCA_bus__is_a_macro /* for versions in ksyms.c */
+
+Index: linux-2.6.0-test5/include/asm-sh/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sh/signal.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sh/signal.h 2003-09-27 11:38:40.778329136 +0800
+@@ -57,7 +57,7 @@
+
+ /* These should not be considered constants from userland. */
+ #define SIGRTMIN 32
+-#define SIGRTMAX (_NSIG-1)
++#define SIGRTMAX _NSIG
+
+ /*
+ * SA_FLAGS values:
+Index: linux-2.6.0-test5/include/asm-sparc64/bugs.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc64/bugs.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sparc64/bugs.h 2003-09-27 11:38:40.779328984 +0800
+@@ -4,4 +4,13 @@
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+-static void check_bugs(void) { }
++#include <linux/config.h>
++
++extern unsigned long loops_per_jiffy;
++
++static void check_bugs(void)
++{
++#ifndef CONFIG_SMP
++ cpu_data(0).udelay_val = loops_per_jiffy;
++#endif
++}
+Index: linux-2.6.0-test5/include/asm-sparc64/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc64/cacheflush.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sparc64/cacheflush.h 2003-09-27 11:38:40.781328680 +0800
+@@ -48,6 +48,14 @@
+ #define flush_icache_page(vma, pg) do { } while(0)
+ #define flush_icache_user_range(vma,pg,adr,len) do { } while (0)
+
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++ memcpy(dst, src, len)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++ memcpy(dst, src, len)
++
+ extern void flush_dcache_page(struct page *page);
+
++#define flush_cache_vmap(start, end) flush_cache_all()
++#define flush_cache_vunmap(start, end) flush_cache_all()
++
+ #endif /* _SPARC64_CACHEFLUSH_H */
+Index: linux-2.6.0-test5/include/asm-sparc64/delay.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc64/delay.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sparc64/delay.h 2003-09-27 11:38:40.782328528 +0800
+@@ -13,12 +13,6 @@
+
+ #ifndef __ASSEMBLY__
+
+-#ifdef CONFIG_SMP
+-#include <asm/smp.h>
+-#else
+-extern unsigned long loops_per_jiffy;
+-#endif
+-
+ static __inline__ void __delay(unsigned long loops)
+ {
+ __asm__ __volatile__(
+Index: linux-2.6.0-test5/include/asm-sparc64/lockmeter.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc64/lockmeter.h 2003-09-27 11:38:18.482718584 +0800
++++ linux-2.6.0-test5/include/asm-sparc64/lockmeter.h 2003-09-27 11:38:40.782328528 +0800
+@@ -0,0 +1,45 @@
++/*
++ * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com)
++ * Copyright (C) 2003 David S. Miller (davem@redhat.com)
++ */
++
++#ifndef _SPARC64_LOCKMETER_H
++#define _SPARC64_LOCKMETER_H
++
++#include <linux/smp.h>
++#include <asm/spinlock.h>
++#include <asm/timer.h>
++#include <asm/timex.h>
++
++/* Actually, this is not the CPU frequency by the system tick
++ * frequency which is good enough for lock metering.
++ */
++#define CPU_CYCLE_FREQUENCY (timer_tick_offset * HZ)
++#define THIS_CPU_NUMBER smp_processor_id()
++
++#define PUT_INDEX(lock_ptr,indexv) (lock_ptr)->index = (indexv)
++#define GET_INDEX(lock_ptr) (lock_ptr)->index
++
++#define PUT_RWINDEX(rwlock_ptr,indexv) (rwlock_ptr)->index = (indexv)
++#define GET_RWINDEX(rwlock_ptr) (rwlock_ptr)->index
++#define PUT_RW_CPU(rwlock_ptr,cpuv) (rwlock_ptr)->cpu = (cpuv)
++#define GET_RW_CPU(rwlock_ptr) (rwlock_ptr)->cpu
++
++#define RWLOCK_READERS(rwlock_ptr) rwlock_readers(rwlock_ptr)
++
++extern inline int rwlock_readers(rwlock_t *rwlock_ptr)
++{
++ signed int tmp = rwlock_ptr->lock;
++
++ if (tmp > 0)
++ return tmp;
++ else
++ return 0;
++}
++
++#define RWLOCK_IS_WRITE_LOCKED(rwlock_ptr) ((signed int)((rwlock_ptr)->lock) < 0)
++#define RWLOCK_IS_READ_LOCKED(rwlock_ptr) ((signed int)((rwlock_ptr)->lock) > 0)
++
++#define get_cycles64() get_cycles()
++
++#endif /* _SPARC64_LOCKMETER_H */
+Index: linux-2.6.0-test5/include/asm-sparc64/pgtable.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc64/pgtable.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sparc64/pgtable.h 2003-09-27 11:38:40.787327768 +0800
+@@ -30,7 +30,6 @@
+ #define MODULES_LEN 0x000000007e000000
+ #define MODULES_END 0x0000000080000000
+ #define VMALLOC_START 0x0000000140000000
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END 0x0000000200000000
+ #define LOW_OBP_ADDRESS 0x00000000f0000000
+ #define HI_OBP_ADDRESS 0x0000000100000000
+Index: linux-2.6.0-test5/include/asm-sparc64/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc64/posix_types.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sparc64/posix_types.h 2003-09-27 11:38:40.789327464 +0800
+@@ -16,7 +16,6 @@
+ typedef int __kernel_ipc_pid_t;
+ typedef unsigned int __kernel_uid_t;
+ typedef unsigned int __kernel_gid_t;
+-typedef unsigned int __kernel_dev_t;
+ typedef unsigned long __kernel_ino_t;
+ typedef unsigned int __kernel_mode_t;
+ typedef unsigned short __kernel_umode_t;
+Index: linux-2.6.0-test5/include/asm-sparc64/processor.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc64/processor.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sparc64/processor.h 2003-09-27 11:38:40.791327160 +0800
+@@ -22,7 +22,6 @@
+ #include <asm/page.h>
+
+ /* Bus types */
+-#define EISA_bus 0
+ #define MCA_bus 0
+ #define MCA_bus__is_a_macro /* for versions in ksyms.c */
+
+Index: linux-2.6.0-test5/include/asm-sparc64/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc64/signal.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sparc64/signal.h 2003-09-27 11:38:40.794326704 +0800
+@@ -89,7 +89,7 @@
+ #define _NSIG_WORDS (__NEW_NSIG / _NSIG_BPW)
+
+ #define SIGRTMIN 32
+-#define SIGRTMAX (__NEW_NSIG - 1)
++#define SIGRTMAX __NEW_NSIG
+
+ #if defined(__KERNEL__) || defined(__WANT_POSIX1B_SIGNALS__)
+ #define _NSIG __NEW_NSIG
+Index: linux-2.6.0-test5/include/asm-sparc64/spinlock.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc64/spinlock.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sparc64/spinlock.h 2003-09-27 11:38:40.796326400 +0800
+@@ -30,15 +30,23 @@
+
+ #ifndef CONFIG_DEBUG_SPINLOCK
+
+-typedef unsigned char spinlock_t;
+-#define SPIN_LOCK_UNLOCKED 0
++typedef struct {
++ unsigned char lock;
++ unsigned int index;
++} spinlock_t;
+
+-#define spin_lock_init(lock) (*((unsigned char *)(lock)) = 0)
+-#define spin_is_locked(lock) (*((volatile unsigned char *)(lock)) != 0)
++#ifdef CONFIG_LOCKMETER
++#define SPIN_LOCK_UNLOCKED (spinlock_t) {0, 0}
++#else
++#define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
++#endif
+
+-#define spin_unlock_wait(lock) \
++#define spin_lock_init(__lock) do { *(__lock) = SPIN_LOCK_UNLOCKED; } while(0)
++#define spin_is_locked(__lock) (*((volatile unsigned char *)(&((__lock)->lock))) != 0)
++
++#define spin_unlock_wait(__lock) \
+ do { membar("#LoadLoad"); \
+-} while(*((volatile unsigned char *)lock))
++} while(*((volatile unsigned char *)(&(((spinlock_t *)__lock)->lock))))
+
+ static __inline__ void _raw_spin_lock(spinlock_t *lock)
+ {
+@@ -109,18 +117,34 @@
+
+ #ifndef CONFIG_DEBUG_SPINLOCK
+
+-typedef unsigned int rwlock_t;
+-#define RW_LOCK_UNLOCKED 0
+-#define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while(0)
+-#define rwlock_is_locked(x) (*(x) != RW_LOCK_UNLOCKED)
++#ifdef CONFIG_LOCKMETER
++typedef struct {
++ unsigned int lock;
++ unsigned int index;
++ unsigned int cpu;
++} rwlock_t;
++#define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0, 0xff }
++#else
++typedef struct {
++ unsigned int lock;
++} rwlock_t;
++#define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
++#endif
++
++#define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while(0)
++#define rwlock_is_locked(x) ((x)->lock != 0)
+
++extern int __read_trylock(rwlock_t *);
+ extern void __read_lock(rwlock_t *);
+ extern void __read_unlock(rwlock_t *);
++extern int __write_trylock(rwlock_t *);
+ extern void __write_lock(rwlock_t *);
+ extern void __write_unlock(rwlock_t *);
+
++#define _raw_read_trylock(p) __read_trylock(p)
+ #define _raw_read_lock(p) __read_lock(p)
+ #define _raw_read_unlock(p) __read_unlock(p)
++#define _raw_write_trylock(p) __write_trylock(p)
+ #define _raw_write_lock(p) __write_lock(p)
+ #define _raw_write_unlock(p) __write_unlock(p)
+
+Index: linux-2.6.0-test5/include/asm-sparc64/stat.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc64/stat.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sparc64/stat.h 2003-09-27 11:38:40.798326096 +0800
+@@ -5,13 +5,13 @@
+ #include <linux/types.h>
+
+ struct stat {
+- dev_t st_dev;
++ unsigned st_dev;
+ ino_t st_ino;
+ mode_t st_mode;
+ short st_nlink;
+ uid_t st_uid;
+ gid_t st_gid;
+- dev_t st_rdev;
++ unsigned st_rdev;
+ off_t st_size;
+ time_t st_atime;
+ time_t st_mtime;
+Index: linux-2.6.0-test5/include/asm-sparc64/vga.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc64/vga.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sparc64/vga.h 2003-09-27 11:38:40.799325944 +0800
+@@ -13,18 +13,16 @@
+
+ static inline void scr_writew(u16 val, u16 *addr)
+ {
+- if ((long) addr < 0)
+- *addr = val;
+- else
+- writew(val, (unsigned long) addr);
++ BUG_ON((long) addr >= 0);
++
++ *addr = val;
+ }
+
+ static inline u16 scr_readw(const u16 *addr)
+ {
+- if ((long) addr < 0)
+- return *addr;
+- else
+- return readw((unsigned long) addr);
++ BUG_ON((long) addr >= 0);
++
++ return *addr;
+ }
+
+ #define VGA_MAP_MEM(x) (x)
+Index: linux-2.6.0-test5/include/asm-sparc/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc/cacheflush.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sparc/cacheflush.h 2003-09-27 11:38:40.800325792 +0800
+@@ -56,6 +56,11 @@
+
+ #define flush_icache_user_range(vma,pg,adr,len) do { } while (0)
+
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++ memcpy(dst, src, len)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++ memcpy(dst, src, len)
++
+ BTFIXUPDEF_CALL(void, __flush_page_to_ram, unsigned long)
+ BTFIXUPDEF_CALL(void, flush_sig_insns, struct mm_struct *, unsigned long)
+
+@@ -66,4 +71,7 @@
+
+ #define flush_dcache_page(page) sparc_flush_page_to_ram(page)
+
++#define flush_cache_vmap(start, end) flush_cache_all()
++#define flush_cache_vunmap(start, end) flush_cache_all()
++
+ #endif /* _SPARC_CACHEFLUSH_H */
+Index: linux-2.6.0-test5/include/asm-sparc/highmem.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc/highmem.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sparc/highmem.h 2003-09-27 11:38:40.802325488 +0800
+@@ -89,6 +89,8 @@
+ return pte_page(*pte);
+ }
+
++#define flush_cache_kmaps() flush_cache_all()
++
+ #endif /* __KERNEL__ */
+
+ #endif /* _ASM_HIGHMEM_H */
+Index: linux-2.6.0-test5/include/asm-sparc/pgtable.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc/pgtable.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sparc/pgtable.h 2003-09-27 11:38:40.806324880 +0800
+@@ -101,8 +101,6 @@
+ BTFIXUPDEF_SIMM13(ptrs_per_pgd)
+ BTFIXUPDEF_SIMM13(user_ptrs_per_pgd)
+
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+-
+ #define pte_ERROR(e) __builtin_trap()
+ #define pmd_ERROR(e) __builtin_trap()
+ #define pgd_ERROR(e) __builtin_trap()
+Index: linux-2.6.0-test5/include/asm-sparc/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc/posix_types.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sparc/posix_types.h 2003-09-27 11:38:40.808324576 +0800
+@@ -17,7 +17,6 @@
+ typedef unsigned short __kernel_ipc_pid_t;
+ typedef unsigned short __kernel_uid_t;
+ typedef unsigned short __kernel_gid_t;
+-typedef unsigned short __kernel_dev_t;
+ typedef unsigned long __kernel_ino_t;
+ typedef unsigned short __kernel_mode_t;
+ typedef unsigned short __kernel_umode_t;
+Index: linux-2.6.0-test5/include/asm-sparc/processor.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc/processor.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sparc/processor.h 2003-09-27 11:38:40.810324272 +0800
+@@ -27,7 +27,6 @@
+ /*
+ * Bus types
+ */
+-#define EISA_bus 0
+ #define MCA_bus 0
+ #define MCA_bus__is_a_macro /* for versions in ksyms.c */
+
+Index: linux-2.6.0-test5/include/asm-sparc/sfp-machine.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc/sfp-machine.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sparc/sfp-machine.h 2003-09-27 11:38:40.813323816 +0800
+@@ -77,9 +77,9 @@
+
+ /* Some assembly to speed things up. */
+ #define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \
+- __asm__ ("addcc %r7,%8,%2
+- addxcc %r5,%6,%1
+- addx %r3,%4,%0" \
++ __asm__ ("addcc %r7,%8,%2\n\t" \
++ "addxcc %r5,%6,%1\n\t" \
++ "addx %r3,%4,%0\n" \
+ : "=r" ((USItype)(r2)), \
+ "=&r" ((USItype)(r1)), \
+ "=&r" ((USItype)(r0)) \
+@@ -92,9 +92,9 @@
+ : "cc")
+
+ #define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \
+- __asm__ ("subcc %r7,%8,%2
+- subxcc %r5,%6,%1
+- subx %r3,%4,%0" \
++ __asm__ ("subcc %r7,%8,%2\n\t" \
++ "subxcc %r5,%6,%1\n\t" \
++ "subx %r3,%4,%0\n" \
+ : "=r" ((USItype)(r2)), \
+ "=&r" ((USItype)(r1)), \
+ "=&r" ((USItype)(r0)) \
+@@ -111,11 +111,11 @@
+ /* We need to fool gcc, as we need to pass more than 10 \
+ input/outputs. */ \
+ register USItype _t1 __asm__ ("g1"), _t2 __asm__ ("g2"); \
+- __asm__ __volatile__ ("
+- addcc %r8,%9,%1
+- addxcc %r6,%7,%0
+- addxcc %r4,%5,%%g2
+- addx %r2,%3,%%g1" \
++ __asm__ __volatile__ ( \
++ "addcc %r8,%9,%1\n\t" \
++ "addxcc %r6,%7,%0\n\t" \
++ "addxcc %r4,%5,%%g2\n\t" \
++ "addx %r2,%3,%%g1\n\t" \
+ : "=&r" ((USItype)(r1)), \
+ "=&r" ((USItype)(r0)) \
+ : "%rJ" ((USItype)(x3)), \
+@@ -136,11 +136,11 @@
+ /* We need to fool gcc, as we need to pass more than 10 \
+ input/outputs. */ \
+ register USItype _t1 __asm__ ("g1"), _t2 __asm__ ("g2"); \
+- __asm__ __volatile__ ("
+- subcc %r8,%9,%1
+- subxcc %r6,%7,%0
+- subxcc %r4,%5,%%g2
+- subx %r2,%3,%%g1" \
++ __asm__ __volatile__ ( \
++ "subcc %r8,%9,%1\n\t" \
++ "subxcc %r6,%7,%0\n\t" \
++ "subxcc %r4,%5,%%g2\n\t" \
++ "subx %r2,%3,%%g1\n\t" \
+ : "=&r" ((USItype)(r1)), \
+ "=&r" ((USItype)(r0)) \
+ : "%rJ" ((USItype)(x3)), \
+@@ -161,10 +161,10 @@
+ #define __FP_FRAC_DEC_4(x3,x2,x1,x0,y3,y2,y1,y0) __FP_FRAC_SUB_4(x3,x2,x1,x0,x3,x2,x1,x0,y3,y2,y1,y0)
+
+ #define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i) \
+- __asm__ ("addcc %3,%4,%3
+- addxcc %2,%%g0,%2
+- addxcc %1,%%g0,%1
+- addx %0,%%g0,%0" \
++ __asm__ ("addcc %3,%4,%3\n\t" \
++ "addxcc %2,%%g0,%2\n\t" \
++ "addxcc %1,%%g0,%1\n\t" \
++ "addx %0,%%g0,%0\n\t" \
+ : "=&r" ((USItype)(x3)), \
+ "=&r" ((USItype)(x2)), \
+ "=&r" ((USItype)(x1)), \
+Index: linux-2.6.0-test5/include/asm-sparc/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc/signal.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sparc/signal.h 2003-09-27 11:38:40.815323512 +0800
+@@ -89,7 +89,7 @@
+ #define _NSIG_WORDS (__NEW_NSIG / _NSIG_BPW)
+
+ #define SIGRTMIN 32
+-#define SIGRTMAX (__NEW_NSIG - 1)
++#define SIGRTMAX __NEW_NSIG
+
+ #if defined(__KERNEL__) || defined(__WANT_POSIX1B_SIGNALS__)
+ #define _NSIG __NEW_NSIG
+Index: linux-2.6.0-test5/include/asm-um/archparam-i386.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/archparam-i386.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-um/archparam-i386.h 2003-09-27 11:38:40.816323360 +0800
+@@ -56,6 +56,65 @@
+ pr_reg[16] = PT_REGS_SS(regs); \
+ } while(0);
+
++#define VSYSCALL_BASE (__fix_to_virt(FIX_VSYSCALL))
++#define VSYSCALL_EHDR ((const struct elfhdr *) VSYSCALL_BASE)
++#define VSYSCALL_ENTRY ((unsigned long) &__kernel_vsyscall)
++extern void *__kernel_vsyscall;
++
++/*
++ * Architecture-neutral AT_ values in 0-17, leave some room
++ * for more of them, start the x86-specific ones at 32.
++ */
++#define AT_SYSINFO 32
++#define AT_SYSINFO_EHDR 33
++
++#define ARCH_DLINFO \
++do { \
++ NEW_AUX_ENT(AT_SYSINFO, VSYSCALL_ENTRY); \
++ NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL_BASE); \
++} while (0)
++
++/*
++ * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out
++ * extra segments containing the vsyscall DSO contents. Dumping its
++ * contents makes post-mortem fully interpretable later without matching up
++ * the same kernel and hardware config to see what PC values meant.
++ * Dumping its extra ELF program headers includes all the other information
++ * a debugger needs to easily find how the vsyscall DSO was being used.
++ */
++#define ELF_CORE_EXTRA_PHDRS (VSYSCALL_EHDR->e_phnum)
++#define ELF_CORE_WRITE_EXTRA_PHDRS \
++do { \
++ const struct elf_phdr *const vsyscall_phdrs = \
++ (const struct elf_phdr *) (VSYSCALL_BASE \
++ + VSYSCALL_EHDR->e_phoff); \
++ int i; \
++ Elf32_Off ofs = 0; \
++ for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) { \
++ struct elf_phdr phdr = vsyscall_phdrs[i]; \
++ if (phdr.p_type == PT_LOAD) { \
++ ofs = phdr.p_offset = offset; \
++ offset += phdr.p_filesz; \
++ } \
++ else \
++ phdr.p_offset += ofs; \
++ phdr.p_paddr = 0; /* match other core phdrs */ \
++ DUMP_WRITE(&phdr, sizeof(phdr)); \
++ } \
++} while (0)
++#define ELF_CORE_WRITE_EXTRA_DATA \
++do { \
++ const struct elf_phdr *const vsyscall_phdrs = \
++ (const struct elf_phdr *) (VSYSCALL_BASE \
++ + VSYSCALL_EHDR->e_phoff); \
++ int i; \
++ for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) { \
++ if (vsyscall_phdrs[i].p_type == PT_LOAD) \
++ DUMP_WRITE((void *) vsyscall_phdrs[i].p_vaddr, \
++ vsyscall_phdrs[i].p_filesz); \
++ } \
++} while (0)
++
+ /********* Bits for asm-um/delay.h **********/
+
+ typedef unsigned long um_udelay_t;
+Index: linux-2.6.0-test5/include/asm-um/common.lds.S
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/common.lds.S 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-um/common.lds.S 2003-09-27 11:38:40.818323056 +0800
+@@ -1,3 +1,5 @@
++#include <asm-generic/vmlinux.lds.h>
++
+ .fini : { *(.fini) } =0x9090
+ _etext = .;
+ PROVIDE (etext = .);
+@@ -67,6 +69,10 @@
+ }
+ __initcall_end = .;
+
++ __con_initcall_start = .;
++ .con_initcall.init : { *(.con_initcall.init) }
++ __con_initcall_end = .;
++
+ __uml_initcall_start = .;
+ .uml.initcall.init : { *(.uml.initcall.init) }
+ __uml_initcall_end = .;
+@@ -80,7 +86,33 @@
+ .uml.exitcall : { *(.uml.exitcall.exit) }
+ __uml_exitcall_end = .;
+
+- . = ALIGN(4096);
++ . = ALIGN(4);
++ __alt_instructions = .;
++ .altinstructions : { *(.altinstructions) }
++ __alt_instructions_end = .;
++ .altinstr_replacement : { *(.altinstr_replacement) }
++ /* .exit.text is discard at runtime, not link time, to deal with references
++ from .altinstructions and .eh_frame */
++ .exit.text : { *(.exit.text) }
++ .exit.data : { *(.exit.data) }
++
++ __preinit_array_start = .;
++ .preinit_array : { *(.preinit_array) }
++ __preinit_array_end = .;
++ __init_array_start = .;
++ .init_array : { *(.init_array) }
++ __init_array_end = .;
++ __fini_array_start = .;
++ .fini_array : { *(.fini_array) }
++ __fini_array_end = .;
++
++ . = ALIGN(4096);
+ __initramfs_start = .;
+ .init.ramfs : { *(.init.ramfs) }
+ __initramfs_end = .;
++
++ /* Sections to be discarded */
++ /DISCARD/ : {
++ *(.exitcall.exit)
++ }
++
+Index: linux-2.6.0-test5/include/asm-um/cpufeature.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/cpufeature.h 2003-09-27 11:38:18.483718432 +0800
++++ linux-2.6.0-test5/include/asm-um/cpufeature.h 2003-09-27 11:38:40.818323056 +0800
+@@ -0,0 +1,6 @@
++#ifndef __UM_CPUFEATURE_H
++#define __UM_CPUFEATURE_H
++
++#include "asm/arch/cpufeature.h"
++
++#endif
+Index: linux-2.6.0-test5/include/asm-um/current.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/current.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-um/current.h 2003-09-27 11:38:40.820322752 +0800
+@@ -16,8 +16,10 @@
+ #define CURRENT_THREAD(dummy) (((unsigned long) &dummy) & \
+ (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER))
+
+-#define current ({ int dummy; \
+- ((struct thread_info *) CURRENT_THREAD(dummy))->task; })
++#define current_thread \
++ ({ int dummy; ((struct thread_info *) CURRENT_THREAD(dummy)); })
++
++#define current (current_thread->task)
+
+ #endif /* __ASSEMBLY__ */
+
+Index: linux-2.6.0-test5/include/asm-um/fixmap.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/fixmap.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-um/fixmap.h 2003-09-27 11:38:40.821322600 +0800
+@@ -34,6 +34,7 @@
+ FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
+ FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
+ #endif
++ FIX_VSYSCALL,
+ __end_of_fixed_addresses
+ };
+
+@@ -63,6 +64,13 @@
+ #define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
+ #define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
+
++/*
++ * This is the range that is readable by user mode, and things
++ * acting like user mode such as get_user_pages.
++ */
++#define FIXADDR_USER_START (__fix_to_virt(FIX_VSYSCALL))
++#define FIXADDR_USER_END (FIXADDR_USER_START + PAGE_SIZE)
++
+ extern void __this_fixmap_does_not_exist(void);
+
+ /*
+Index: linux-2.6.0-test5/include/asm-um/irq.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/irq.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-um/irq.h 2003-09-27 11:38:40.823322296 +0800
+@@ -1,15 +1,6 @@
+ #ifndef __UM_IRQ_H
+ #define __UM_IRQ_H
+
+-/* The i386 irq.h has a struct task_struct in a prototype without including
+- * sched.h. This forward declaration kills the resulting warning.
+- */
+-struct task_struct;
+-
+-#include "asm/ptrace.h"
+-
+-#undef NR_IRQS
+-
+ #define TIMER_IRQ 0
+ #define UMN_IRQ 1
+ #define CONSOLE_IRQ 2
+@@ -28,8 +19,4 @@
+ #define LAST_IRQ XTERM_IRQ
+ #define NR_IRQS (LAST_IRQ + 1)
+
+-extern int um_request_irq(unsigned int irq, int fd, int type,
+- void (*handler)(int, void *, struct pt_regs *),
+- unsigned long irqflags, const char * devname,
+- void *dev_id);
+ #endif
+Index: linux-2.6.0-test5/include/asm-um/local.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/local.h 2003-09-27 11:38:18.483718432 +0800
++++ linux-2.6.0-test5/include/asm-um/local.h 2003-09-27 11:38:40.823322296 +0800
+@@ -0,0 +1,6 @@
++#ifndef __UM_LOCAL_H
++#define __UM_LOCAL_H
++
++#include "asm/arch/local.h"
++
++#endif
+Index: linux-2.6.0-test5/include/asm-um/module-generic.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/module-generic.h 2003-09-27 11:38:18.483718432 +0800
++++ linux-2.6.0-test5/include/asm-um/module-generic.h 2003-09-27 11:38:40.823322296 +0800
+@@ -0,0 +1,6 @@
++#ifndef __UM_MODULE_GENERIC_H
++#define __UM_MODULE_GENERIC_H
++
++#include "asm/arch/module.h"
++
++#endif
+Index: linux-2.6.0-test5/include/asm-um/module-i386.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/module-i386.h 2003-09-27 11:38:18.483718432 +0800
++++ linux-2.6.0-test5/include/asm-um/module-i386.h 2003-09-27 11:38:40.823322296 +0800
+@@ -0,0 +1,13 @@
++#ifndef __UM_MODULE_I386_H
++#define __UM_MODULE_I386_H
++
++/* UML is simple */
++struct mod_arch_specific
++{
++};
++
++#define Elf_Shdr Elf32_Shdr
++#define Elf_Sym Elf32_Sym
++#define Elf_Ehdr Elf32_Ehdr
++
++#endif
+Index: linux-2.6.0-test5/include/asm-um/page.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/page.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-um/page.h 2003-09-27 11:38:40.825321992 +0800
+@@ -4,7 +4,6 @@
+ struct page;
+
+ #include "asm/arch/page.h"
+-#include "asm/bug.h"
+
+ #undef __pa
+ #undef __va
+Index: linux-2.6.0-test5/include/asm-um/pgtable.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/pgtable.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-um/pgtable.h 2003-09-27 11:38:40.829321384 +0800
+@@ -69,7 +69,6 @@
+
+ #define VMALLOC_OFFSET (__va_space)
+ #define VMALLOC_START (((unsigned long) high_physmem + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+
+ #ifdef CONFIG_HIGHMEM
+ # define VMALLOC_END (PKMAP_BASE-2*PAGE_SIZE)
+@@ -79,12 +78,13 @@
+
+ #define _PAGE_PRESENT 0x001
+ #define _PAGE_NEWPAGE 0x002
+-#define _PAGE_PROTNONE 0x004 /* If not present */
+-#define _PAGE_RW 0x008
+-#define _PAGE_USER 0x010
+-#define _PAGE_ACCESSED 0x020
+-#define _PAGE_DIRTY 0x040
+-#define _PAGE_NEWPROT 0x080
++#define _PAGE_NEWPROT 0x004
++#define _PAGE_FILE 0x008 /* set:pagecache unset:swap */
++#define _PAGE_PROTNONE 0x010 /* If not present */
++#define _PAGE_RW 0x020
++#define _PAGE_USER 0x040
++#define _PAGE_ACCESSED 0x080
++#define _PAGE_DIRTY 0x100
+
+ #define REGION_MASK 0xf0000000
+ #define REGION_SHIFT 28
+@@ -203,6 +203,16 @@
+ #define pfn_pte(pfn, prot) __pte(pfn_to_phys(pfn) | pgprot_val(prot))
+ #define pfn_pmd(pfn, prot) __pmd(pfn_to_phys(pfn) | pgprot_val(prot))
+
++/*
++ * Bits 0 through 3 are taken
++ */
++#define PTE_FILE_MAX_BITS 28
++
++#define pte_to_pgoff(pte) ((pte).pte_low >> 4)
++
++#define pgoff_to_pte(off) \
++ ((pte_t) { ((off) << 4) + _PAGE_FILE })
++
+ static inline pte_t pte_mknewprot(pte_t pte)
+ {
+ pte_val(pte) |= _PAGE_NEWPROT;
+@@ -236,6 +246,12 @@
+ * The following only work if pte_present() is true.
+ * Undefined behaviour if not..
+ */
++static inline int pte_user(pte_t pte)
++{
++ return((pte_val(pte) & _PAGE_USER) &&
++ !(pte_val(pte) & _PAGE_PROTNONE));
++}
++
+ static inline int pte_read(pte_t pte)
+ {
+ return((pte_val(pte) & _PAGE_USER) &&
+@@ -253,6 +269,14 @@
+ !(pte_val(pte) & _PAGE_PROTNONE));
+ }
+
++/*
++ * The following only works if pte_present() is not true.
++ */
++static inline int pte_file(pte_t pte)
++{
++ return (pte).pte_low & _PAGE_FILE;
++}
++
+ static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
+ static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
+ static inline int pte_newpage(pte_t pte) { return pte_val(pte) & _PAGE_NEWPAGE; }
+@@ -355,14 +379,26 @@
+ #define pmd_page(pmd) (phys_mem_map(pmd_val(pmd) & PAGE_MASK) + \
+ ((phys_addr(pmd_val(pmd)) >> PAGE_SHIFT)))
+
+-/* to find an entry in a page-table-directory. */
++/*
++ * the pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD]
++ *
++ * this macro returns the index of the entry in the pgd page which would
++ * control the given virtual address
++ */
+ #define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
+
+-/* to find an entry in a page-table-directory */
++/*
++ * pgd_offset() returns a (pgd_t *)
++ * pgd_index() is used get the offset into the pgd page's array of pgd_t's;
++ */
+ #define pgd_offset(mm, address) \
+ ((mm)->pgd + ((address) >> PGDIR_SHIFT))
+
+-/* to find an entry in a kernel page-table-directory */
++
++/*
++ * a shortcut which implies the use of the kernel's pgd, instead
++ * of a process's
++ */
+ #define pgd_offset_k(address) pgd_offset(&init_mm, address)
+
+ #define pmd_index(address) \
+@@ -374,7 +410,12 @@
+ return (pmd_t *) dir;
+ }
+
+-/* Find an entry in the third-level page table.. */
++/*
++ * the pte page can be thought of an array like this: pte_t[PTRS_PER_PTE]
++ *
++ * this macro returns the index of the entry in the pte page which would
++ * control the given virtual address
++ */
+ #define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+ #define pte_offset_kernel(dir, address) \
+ ((pte_t *) pmd_page_kernel(*(dir)) + pte_index(address))
+@@ -400,11 +441,11 @@
+ #define update_mmu_cache(vma,address,pte) do ; while (0)
+
+ /* Encode and de-code a swap entry */
+-#define __swp_type(x) (((x).val >> 3) & 0x7f)
+-#define __swp_offset(x) ((x).val >> 10)
++#define __swp_type(x) (((x).val >> 4) & 0x3f)
++#define __swp_offset(x) ((x).val >> 11)
+
+ #define __swp_entry(type, offset) \
+- ((swp_entry_t) { ((type) << 3) | ((offset) << 10) })
++ ((swp_entry_t) { ((type) << 4) | ((offset) << 11) })
+ #define __pte_to_swp_entry(pte) \
+ ((swp_entry_t) { pte_val(pte_mkuptodate(pte)) })
+ #define __swp_entry_to_pte(x) ((pte_t) { (x).val })
+Index: linux-2.6.0-test5/include/asm-um/processor-generic.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/processor-generic.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-um/processor-generic.h 2003-09-27 11:38:40.831321080 +0800
+@@ -11,9 +11,7 @@
+ struct task_struct;
+
+ #include "linux/config.h"
+-#include "linux/signal.h"
+ #include "asm/ptrace.h"
+-#include "asm/siginfo.h"
+ #include "choose-mode.h"
+
+ struct mm_struct;
+@@ -101,14 +99,19 @@
+ } mm_segment_t;
+
+ extern struct task_struct *alloc_task_struct(void);
+-extern void free_task_struct(struct task_struct *task);
+
+ extern void release_thread(struct task_struct *);
+ extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+ extern void dump_thread(struct pt_regs *regs, struct user *u);
++extern void prepare_to_copy(struct task_struct *tsk);
+
+ extern unsigned long thread_saved_pc(struct task_struct *t);
+
++static inline void mm_copy_segments(struct mm_struct *from_mm,
++ struct mm_struct *new_mm)
++{
++}
++
+ #define init_stack (init_thread_union.stack)
+
+ /*
+Index: linux-2.6.0-test5/include/asm-um/processor-i386.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/processor-i386.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-um/processor-i386.h 2003-09-27 11:38:40.832320928 +0800
+@@ -6,8 +6,8 @@
+ #ifndef __UM_PROCESSOR_I386_H
+ #define __UM_PROCESSOR_I386_H
+
+-extern int cpu_has_xmm;
+-extern int cpu_has_cmov;
++extern int host_has_xmm;
++extern int host_has_cmov;
+
+ struct arch_thread {
+ unsigned long debugregs[8];
+Index: linux-2.6.0-test5/include/asm-um/sections.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/sections.h 2003-09-27 11:38:18.483718432 +0800
++++ linux-2.6.0-test5/include/asm-um/sections.h 2003-09-27 11:38:40.833320776 +0800
+@@ -0,0 +1,7 @@
++#ifndef _UM_SECTIONS_H
++#define _UM_SECTIONS_H
++
++/* nothing to see, move along */
++#include <asm-generic/sections.h>
++
++#endif
+Index: linux-2.6.0-test5/include/asm-um/smp.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/smp.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-um/smp.h 2003-09-27 11:38:40.834320624 +0800
+@@ -10,7 +10,7 @@
+
+ extern cpumask_t cpu_online_map;
+
+-#define smp_processor_id() (current->thread_info->cpu)
++#define smp_processor_id() (current_thread->cpu)
+ #define cpu_logical_map(n) (n)
+ #define cpu_number_map(n) (n)
+ #define PROC_CHANGE_PENALTY 15 /* Pick a number, any number */
+Index: linux-2.6.0-test5/include/asm-um/system-generic.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/system-generic.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-um/system-generic.h 2003-09-27 11:38:40.836320320 +0800
+@@ -23,8 +23,10 @@
+ extern void block_signals(void);
+ extern void unblock_signals(void);
+
+-#define local_save_flags(flags) do { (flags) = get_signals(); } while(0)
+-#define local_irq_restore(flags) do { set_signals(flags); } while(0)
++#define local_save_flags(flags) do { typecheck(unsigned long, flags); \
++ (flags) = get_signals(); } while(0)
++#define local_irq_restore(flags) do { typecheck(unsigned long, flags); \
++ set_signals(flags); } while(0)
+
+ #define local_irq_save(flags) do { local_save_flags(flags); \
+ local_irq_disable(); } while(0)
+@@ -39,4 +41,7 @@
+ (flags == 0); \
+ })
+
++extern void *_switch_to(void *prev, void *next, void *last);
++#define switch_to(prev, next, last) prev = _switch_to(prev, next, last)
++
+ #endif
+Index: linux-2.6.0-test5/include/asm-um/thread_info.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/thread_info.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-um/thread_info.h 2003-09-27 11:38:40.837320168 +0800
+@@ -9,6 +9,7 @@
+ #ifndef __ASSEMBLY__
+
+ #include <asm/processor.h>
++#include <asm/types.h>
+
+ struct thread_info {
+ struct task_struct *task; /* main task structure */
+@@ -43,15 +44,18 @@
+ static inline struct thread_info *current_thread_info(void)
+ {
+ struct thread_info *ti;
+- __asm__("andl %%esp,%0; ":"=r" (ti) : "0" (~16383UL));
++ unsigned long mask = PAGE_SIZE *
++ (1 << CONFIG_KERNEL_STACK_ORDER) - 1;
++ __asm__("andl %%esp,%0; ":"=r" (ti) : "0" (~mask));
+ return ti;
+ }
+
+ /* thread information allocation */
+-#define THREAD_SIZE (4*PAGE_SIZE)
+-#define alloc_thread_info(tsk) ((struct thread_info *) \
+- __get_free_pages(GFP_KERNEL,2))
+-#define free_thread_info(ti) free_pages((unsigned long) (ti), 2)
++#define THREAD_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE)
++#define alloc_thread_info(tsk) \
++ ((struct thread_info *) kmalloc(THREAD_SIZE, GFP_KERNEL))
++#define free_thread_info(ti) kfree(ti)
++
+ #define get_thread_info(ti) get_task_struct((ti)->task)
+ #define put_thread_info(ti) put_task_struct((ti)->task)
+
+@@ -65,11 +69,13 @@
+ #define TIF_POLLING_NRFLAG 3 /* true if poll_idle() is polling
+ * TIF_NEED_RESCHED
+ */
++#define TIF_RESTART_BLOCK 4
+
+ #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
+ #define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
+ #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
+ #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
++#define _TIF_RESTART_BLOCK (1 << TIF_RESTART_BLOCK)
+
+ #endif
+
+Index: linux-2.6.0-test5/include/asm-um/timex.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/timex.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-um/timex.h 2003-09-27 11:38:40.838320016 +0800
+@@ -1,8 +1,6 @@
+ #ifndef __UM_TIMEX_H
+ #define __UM_TIMEX_H
+
+-#include "linux/time.h"
+-
+ typedef unsigned long cycles_t;
+
+ #define cacheflush_time (0)
+Index: linux-2.6.0-test5/include/asm-v850/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-v850/cacheflush.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-v850/cacheflush.h 2003-09-27 11:38:40.840319712 +0800
+@@ -27,6 +27,8 @@
+ #define flush_cache_range(vma, start, end) ((void)0)
+ #define flush_cache_page(vma, vmaddr) ((void)0)
+ #define flush_dcache_page(page) ((void)0)
++#define flush_cache_vmap(start, end) ((void)0)
++#define flush_cache_vunmap(start, end) ((void)0)
+
+ #ifdef CONFIG_NO_CACHE
+
+@@ -55,5 +57,11 @@
+
+ #endif /* CONFIG_NO_CACHE */
+
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++do { memcpy(dst, src, len); \
++ flush_icache_user_range(vma, page, vaddr, len); \
++} while (0)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++ memcpy(dst, src, len)
+
+ #endif /* __V850_CACHEFLUSH_H__ */
+Index: linux-2.6.0-test5/include/asm-v850/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-v850/posix_types.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-v850/posix_types.h 2003-09-27 11:38:40.841319560 +0800
+@@ -14,7 +14,6 @@
+ #ifndef __V850_POSIX_TYPES_H__
+ #define __V850_POSIX_TYPES_H__
+
+-typedef unsigned int __kernel_dev_t;
+ typedef unsigned long __kernel_ino_t;
+ typedef unsigned long long __kernel_ino64_t;
+ typedef unsigned int __kernel_mode_t;
+Index: linux-2.6.0-test5/include/asm-v850/processor.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-v850/processor.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-v850/processor.h 2003-09-27 11:38:40.843319256 +0800
+@@ -52,8 +52,6 @@
+ /*
+ * Bus types
+ */
+-#define EISA_bus 0
+-#define EISA_bus__is_a_macro /* for versions in ksyms.c */
+ #define MCA_bus 0
+ #define MCA_bus__is_a_macro /* for versions in ksyms.c */
+
+Index: linux-2.6.0-test5/include/asm-v850/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-v850/signal.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-v850/signal.h 2003-09-27 11:38:40.845318952 +0800
+@@ -71,7 +71,7 @@
+
+ /* These should not be considered constants from userland. */
+ #define SIGRTMIN 32
+-#define SIGRTMAX (_NSIG-1)
++#define SIGRTMAX _NSIG
+
+ /*
+ * SA_FLAGS values:
+Index: linux-2.6.0-test5/include/asm-x86_64/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-x86_64/cacheflush.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-x86_64/cacheflush.h 2003-09-27 11:38:40.846318800 +0800
+@@ -13,6 +13,13 @@
+ #define flush_icache_range(start, end) do { } while (0)
+ #define flush_icache_page(vma,pg) do { } while (0)
+ #define flush_icache_user_range(vma,pg,adr,len) do { } while (0)
++#define flush_cache_vmap(start, end) do { } while (0)
++#define flush_cache_vunmap(start, end) do { } while (0)
++
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++ memcpy(dst, src, len)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++ memcpy(dst, src, len)
+
+ void global_flush_tlb(void);
+ int change_page_attr(struct page *page, int numpages, pgprot_t prot);
+Index: linux-2.6.0-test5/include/asm-x86_64/mmzone.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-x86_64/mmzone.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-x86_64/mmzone.h 2003-09-27 11:38:40.848318496 +0800
+@@ -10,7 +10,6 @@
+
+ #define VIRTUAL_BUG_ON(x)
+
+-#include <asm/numnodes.h>
+ #include <asm/smp.h>
+
+ #define MAXNODE 8
+Index: linux-2.6.0-test5/include/asm-x86_64/numnodes.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-x86_64/numnodes.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-x86_64/numnodes.h 2003-09-27 11:38:40.849318344 +0800
+@@ -3,10 +3,7 @@
+
+ #include <linux/config.h>
+
+-#ifdef CONFIG_DISCONTIGMEM
+-#define MAX_NUMNODES 8 /* APIC limit currently */
+-#else
+-#define MAX_NUMNODES 1
+-#endif
++/* Max 8 Nodes - APIC limit currently */
++#define NODES_SHIFT 3
+
+ #endif
+Index: linux-2.6.0-test5/include/asm-x86_64/pgtable.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-x86_64/pgtable.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-x86_64/pgtable.h 2003-09-27 11:38:40.853317736 +0800
+@@ -126,7 +126,6 @@
+ #ifndef __ASSEMBLY__
+ #define VMALLOC_START 0xffffff0000000000
+ #define VMALLOC_END 0xffffff7fffffffff
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define MODULES_VADDR 0xffffffffa0000000
+ #define MODULES_END 0xffffffffafffffff
+ #define MODULES_LEN (MODULES_END - MODULES_VADDR)
+Index: linux-2.6.0-test5/include/asm-x86_64/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-x86_64/posix_types.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-x86_64/posix_types.h 2003-09-27 11:38:40.855317432 +0800
+@@ -7,7 +7,6 @@
+ * assume GCC is being used.
+ */
+
+-typedef unsigned long __kernel_dev_t;
+ typedef unsigned long __kernel_ino_t;
+ typedef unsigned int __kernel_mode_t;
+ typedef unsigned long __kernel_nlink_t;
+Index: linux-2.6.0-test5/include/asm-x86_64/processor.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-x86_64/processor.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-x86_64/processor.h 2003-09-27 11:38:40.858316976 +0800
+@@ -160,7 +160,6 @@
+ /*
+ * Bus types
+ */
+-#define EISA_bus 0
+ #define MCA_bus 0
+ #define MCA_bus__is_a_macro
+
+Index: linux-2.6.0-test5/include/asm-x86_64/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-x86_64/signal.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-x86_64/signal.h 2003-09-27 11:38:40.861316520 +0800
+@@ -77,7 +77,7 @@
+
+ /* These should not be considered constants from userland. */
+ #define SIGRTMIN 32
+-#define SIGRTMAX (_NSIG-1)
++#define SIGRTMAX _NSIG
+
+ /*
+ * SA_FLAGS values:
+Index: linux-2.6.0-test5/include/linux/acpi.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/acpi.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/acpi.h 2003-09-27 11:38:40.864316064 +0800
+@@ -424,17 +424,17 @@
+
+ #endif /*CONFIG_ACPI_EC*/
+
+-#ifdef CONFIG_ACPI
++#ifdef CONFIG_ACPI_INTERPRETER
+
+ int acpi_blacklisted(void);
+
+-#else
++#else /*!CONFIG_ACPI_INTERPRETER*/
+
+ static inline int acpi_blacklisted(void)
+ {
+ return 0;
+ }
+
+-#endif /*CONFIG_ACPI*/
++#endif /*!CONFIG_ACPI_INTERPRETER*/
+
+ #endif /*_LINUX_ACPI_H*/
+Index: linux-2.6.0-test5/include/linux/aio.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/aio.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/aio.h 2003-09-27 11:38:40.867315608 +0800
+@@ -29,21 +29,26 @@
+ #define KIF_LOCKED 0
+ #define KIF_KICKED 1
+ #define KIF_CANCELLED 2
++#define KIF_SYNCED 3
+
+ #define kiocbTryLock(iocb) test_and_set_bit(KIF_LOCKED, &(iocb)->ki_flags)
+ #define kiocbTryKick(iocb) test_and_set_bit(KIF_KICKED, &(iocb)->ki_flags)
++#define kiocbTrySync(iocb) test_and_set_bit(KIF_SYNCED, &(iocb)->ki_flags)
+
+ #define kiocbSetLocked(iocb) set_bit(KIF_LOCKED, &(iocb)->ki_flags)
+ #define kiocbSetKicked(iocb) set_bit(KIF_KICKED, &(iocb)->ki_flags)
+ #define kiocbSetCancelled(iocb) set_bit(KIF_CANCELLED, &(iocb)->ki_flags)
++#define kiocbSetSynced(iocb) set_bit(KIF_SYNCED, &(iocb)->ki_flags)
+
+ #define kiocbClearLocked(iocb) clear_bit(KIF_LOCKED, &(iocb)->ki_flags)
+ #define kiocbClearKicked(iocb) clear_bit(KIF_KICKED, &(iocb)->ki_flags)
+ #define kiocbClearCancelled(iocb) clear_bit(KIF_CANCELLED, &(iocb)->ki_flags)
++#define kiocbClearSynced(iocb) clear_bit(KIF_SYNCED, &(iocb)->ki_flags)
+
+ #define kiocbIsLocked(iocb) test_bit(KIF_LOCKED, &(iocb)->ki_flags)
+ #define kiocbIsKicked(iocb) test_bit(KIF_KICKED, &(iocb)->ki_flags)
+ #define kiocbIsCancelled(iocb) test_bit(KIF_CANCELLED, &(iocb)->ki_flags)
++#define kiocbIsSynced(iocb) test_bit(KIF_SYNCED, &(iocb)->ki_flags)
+
+ struct kiocb {
+ struct list_head ki_run_list;
+@@ -54,7 +59,7 @@
+ struct file *ki_filp;
+ struct kioctx *ki_ctx; /* may be NULL for sync ops */
+ int (*ki_cancel)(struct kiocb *, struct io_event *);
+- long (*ki_retry)(struct kiocb *);
++ ssize_t (*ki_retry)(struct kiocb *);
+
+ struct list_head ki_list; /* the aio core uses this
+ * for cancellation */
+@@ -63,6 +68,16 @@
+ __u64 ki_user_data; /* user's data for completion */
+ loff_t ki_pos;
+
++ /* State that we remember to be able to restart/retry */
++ unsigned short ki_opcode;
++ size_t ki_nbytes; /* copy of iocb->aio_nbytes */
++ char *ki_buf; /* remaining iocb->aio_buf */
++ size_t ki_left; /* remaining bytes */
++ wait_queue_t ki_wait;
++ long ki_retried; /* just for testing */
++ long ki_kicked; /* just for testing */
++ long ki_queued; /* just for testing */
++
+ char private[KIOCB_PRIVATE_SIZE];
+ };
+
+@@ -77,6 +92,8 @@
+ (x)->ki_ctx = &tsk->active_mm->default_kioctx; \
+ (x)->ki_cancel = NULL; \
+ (x)->ki_user_obj = tsk; \
++ (x)->ki_user_data = 0; \
++ init_wait((&(x)->ki_wait)); \
+ } while (0)
+
+ #define AIO_RING_MAGIC 0xa10a10a1
+@@ -159,6 +176,17 @@
+ #define get_ioctx(kioctx) do { if (unlikely(atomic_read(&(kioctx)->users) <= 0)) BUG(); atomic_inc(&(kioctx)->users); } while (0)
+ #define put_ioctx(kioctx) do { if (unlikely(atomic_dec_and_test(&(kioctx)->users))) __put_ioctx(kioctx); else if (unlikely(atomic_read(&(kioctx)->users) < 0)) BUG(); } while (0)
+
++#define in_aio() !is_sync_wait(current->io_wait)
++/* may be used for debugging */
++#define warn_if_async() if (in_aio()) {\
++ printk(KERN_ERR "%s(%s:%d) called in async context!\n", \
++ __FUNCTION__, __FILE__, __LINE__); \
++ dump_stack(); \
++ }
++
++#define io_wait_to_kiocb(wait) container_of(wait, struct kiocb, ki_wait)
++#define is_retried_kiocb(iocb) ((iocb)->ki_retried > 1)
++
+ #include <linux/aio_abi.h>
+
+ static inline struct kiocb *list_kiocb(struct list_head *h)
+Index: linux-2.6.0-test5/include/linux/atmclip.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/atmclip.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/atmclip.h 2003-09-27 11:38:40.868315456 +0800
+@@ -18,8 +18,4 @@
+
+ #define SIOCMKCLIP _IO('a',ATMIOC_CLIP) /* create IP interface */
+
+-#ifdef __KERNEL__
+-extern const unsigned char llc_oui[6];
+-#endif
+-
+ #endif
+Index: linux-2.6.0-test5/include/linux/bio.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/bio.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/bio.h 2003-09-27 11:38:40.871315000 +0800
+@@ -20,7 +20,6 @@
+ #ifndef __LINUX_BIO_H
+ #define __LINUX_BIO_H
+
+-#include <linux/kdev_t.h>
+ #include <linux/highmem.h>
+ #include <linux/mempool.h>
+
+Index: linux-2.6.0-test5/include/linux/blkdev.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/blkdev.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/blkdev.h 2003-09-27 11:38:40.877314088 +0800
+@@ -262,6 +262,7 @@
+ int busy; /* current depth */
+ int max_depth; /* what we will send to device */
+ int real_max_depth; /* what the array can hold */
++ atomic_t refcnt; /* map can be shared */
+ };
+
+ struct request_queue
+@@ -579,11 +580,12 @@
+ extern int blk_queue_start_tag(request_queue_t *, struct request *);
+ extern struct request *blk_queue_find_tag(request_queue_t *, int);
+ extern void blk_queue_end_tag(request_queue_t *, struct request *);
+-extern int blk_queue_init_tags(request_queue_t *, int);
++extern int blk_queue_init_tags(request_queue_t *, int, struct blk_queue_tag *);
+ extern void blk_queue_free_tags(request_queue_t *);
+ extern int blk_queue_resize_tags(request_queue_t *, int);
+ extern void blk_queue_invalidate_tags(request_queue_t *);
+ extern void blk_congestion_wait(int rw, long timeout);
++extern int blk_congestion_wait_wq(int rw, long timeout, wait_queue_t *wait);
+
+ extern void blk_rq_bio_prep(request_queue_t *, struct request *, struct bio *);
+ extern void blk_rq_prep_restart(struct request *);
+Index: linux-2.6.0-test5/include/linux/buffer_head.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/buffer_head.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/buffer_head.h 2003-09-27 11:38:40.880313632 +0800
+@@ -162,6 +162,7 @@
+ void invalidate_bdev(struct block_device *, int);
+ int sync_blockdev(struct block_device *bdev);
+ void __wait_on_buffer(struct buffer_head *);
++int __wait_on_buffer_wq(struct buffer_head *, wait_queue_t *wait);
+ wait_queue_head_t *bh_waitq_head(struct buffer_head *bh);
+ void wake_up_buffer(struct buffer_head *bh);
+ int fsync_bdev(struct block_device *);
+@@ -173,6 +174,8 @@
+ void __bforget(struct buffer_head *);
+ void __breadahead(struct block_device *, sector_t block, int size);
+ struct buffer_head *__bread(struct block_device *, sector_t block, int size);
++struct buffer_head *__bread_wq(struct block_device *, sector_t block,
++ int size, wait_queue_t *wait);
+ struct buffer_head *alloc_buffer_head(int gfp_flags);
+ void free_buffer_head(struct buffer_head * bh);
+ void FASTCALL(unlock_buffer(struct buffer_head *bh));
+@@ -207,11 +210,6 @@
+ int nobh_commit_write(struct file *, struct page *, unsigned, unsigned);
+ int nobh_truncate_page(struct address_space *, loff_t);
+
+-#define OSYNC_METADATA (1<<0)
+-#define OSYNC_DATA (1<<1)
+-#define OSYNC_INODE (1<<2)
+-int generic_osync_inode(struct inode *, int);
+-
+
+ /*
+ * inline definitions
+@@ -230,13 +228,13 @@
+
+ static inline void brelse(struct buffer_head *bh)
+ {
+- if (bh)
++ if (bh && !IS_ERR(bh))
+ __brelse(bh);
+ }
+
+ static inline void bforget(struct buffer_head *bh)
+ {
+- if (bh)
++ if (bh && !IS_ERR(bh))
+ __bforget(bh);
+ }
+
+@@ -253,7 +251,12 @@
+ }
+
+ static inline struct buffer_head *
+-sb_getblk(struct super_block *sb, sector_t block)
++sb_bread_wq(struct super_block *sb, sector_t block, wait_queue_t *wait)
++{
++ return __bread_wq(sb->s_bdev, block, sb->s_blocksize, wait);
++}
++
++static inline struct buffer_head *sb_getblk(struct super_block *sb, sector_t block)
+ {
+ return __getblk(sb->s_bdev, block, sb->s_blocksize);
+ }
+@@ -277,16 +280,34 @@
+ * __wait_on_buffer() just to trip a debug check. Because debug code in inline
+ * functions is bloaty.
+ */
+-static inline void wait_on_buffer(struct buffer_head *bh)
++
++static inline int wait_on_buffer_wq(struct buffer_head *bh, wait_queue_t *wait)
+ {
+ if (buffer_locked(bh) || atomic_read(&bh->b_count) == 0)
+- __wait_on_buffer(bh);
++ return __wait_on_buffer_wq(bh, wait);
++
++ return 0;
++}
++
++static inline void wait_on_buffer(struct buffer_head *bh)
++{
++ wait_on_buffer_wq(bh, NULL);
++}
++
++static inline int lock_buffer_wq(struct buffer_head *bh, wait_queue_t *wait)
++{
++ while (test_set_buffer_locked(bh)) {
++ int ret = __wait_on_buffer_wq(bh, wait);
++ if (ret)
++ return ret;
++ }
++
++ return 0;
+ }
+
+ static inline void lock_buffer(struct buffer_head *bh)
+ {
+- while (test_set_buffer_locked(bh))
+- __wait_on_buffer(bh);
++ lock_buffer_wq(bh, NULL);
+ }
+
+ #endif /* _LINUX_BUFFER_HEAD_H */
+Index: linux-2.6.0-test5/include/linux/coda_cache.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/coda_cache.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/coda_cache.h 2003-09-27 11:38:40.882313328 +0800
+@@ -13,7 +13,7 @@
+ /* credential cache */
+ void coda_cache_enter(struct inode *inode, int mask);
+ void coda_cache_clear_inode(struct inode *);
+-void coda_cache_clear_all(struct super_block *sb, struct coda_cred *cred);
++void coda_cache_clear_all(struct super_block *sb);
+ int coda_cache_check(struct inode *inode, int mask);
+
+ /* for downcalls and attributes and lookups */
+Index: linux-2.6.0-test5/include/linux/coda_fs_i.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/coda_fs_i.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/coda_fs_i.h 2003-09-27 11:38:40.883313176 +0800
+@@ -17,11 +17,12 @@
+ * coda fs inode data
+ */
+ struct coda_inode_info {
+- struct ViceFid c_fid; /* Coda identifier */
++ struct CodaFid c_fid; /* Coda identifier */
+ u_short c_flags; /* flags (see below) */
+ struct list_head c_cilist; /* list of all coda inodes */
+ unsigned int c_mapcount; /* nr of times this inode is mapped */
+- struct coda_cred c_cached_cred; /* credentials of cached perms */
++ unsigned int c_cached_epoch; /* epoch for cached permissions */
++ vuid_t c_uid; /* fsuid for cached permissions */
+ unsigned int c_cached_perm; /* cached access permissions */
+ struct inode vfs_inode;
+ };
+@@ -34,7 +35,6 @@
+ int cfi_magic; /* magic number */
+ struct file *cfi_container; /* container file for this cnode */
+ unsigned int cfi_mapcount; /* nr of times this file is mapped */
+- struct coda_cred cfi_cred; /* credentials of opener */
+ };
+
+ #define CODA_FTOC(file) ((struct coda_file_info *)((file)->private_data))
+@@ -45,11 +45,11 @@
+ #define C_DYING 0x4 /* from venus (which died) */
+ #define C_PURGE 0x8
+
+-int coda_cnode_make(struct inode **, struct ViceFid *, struct super_block *);
+-struct inode *coda_iget(struct super_block *sb, struct ViceFid *fid, struct coda_vattr *attr);
++int coda_cnode_make(struct inode **, struct CodaFid *, struct super_block *);
++struct inode *coda_iget(struct super_block *sb, struct CodaFid *fid, struct coda_vattr *attr);
+ int coda_cnode_makectl(struct inode **inode, struct super_block *sb);
+-struct inode *coda_fid_to_inode(ViceFid *fid, struct super_block *sb);
+-void coda_replace_fid(struct inode *, ViceFid *, ViceFid *);
++struct inode *coda_fid_to_inode(struct CodaFid *fid, struct super_block *sb);
++void coda_replace_fid(struct inode *, struct CodaFid *, struct CodaFid *);
+
+ #endif
+ #endif
+Index: linux-2.6.0-test5/include/linux/coda.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/coda.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/coda.h 2003-09-27 11:38:40.889312264 +0800
+@@ -59,7 +59,7 @@
+ #ifndef _CODA_HEADER_
+ #define _CODA_HEADER_
+
+-
++#include <linux/config.h>
+
+ /* Catch new _KERNEL defn for NetBSD and DJGPP/__CYGWIN32__ */
+ #if defined(__NetBSD__) || \
+@@ -163,11 +163,11 @@
+ #ifndef _VENUS_DIRENT_T_
+ #define _VENUS_DIRENT_T_ 1
+ struct venus_dirent {
+- unsigned long d_fileno; /* file number of entry */
+- unsigned short d_reclen; /* length of this record */
+- unsigned char d_type; /* file type, see below */
+- unsigned char d_namlen; /* length of string in d_name */
+- char d_name[CODA_MAXNAMLEN + 1];/* name must be no longer than this */
++ u_int32_t d_fileno; /* file number of entry */
++ u_int16_t d_reclen; /* length of this record */
++ u_int8_t d_type; /* file type, see below */
++ u_int8_t d_namlen; /* length of string in d_name */
++ char d_name[CODA_MAXNAMLEN + 1];/* name must be no longer than this */
+ };
+ #undef DIRSIZ
+ #define DIRSIZ(dp) ((sizeof (struct venus_dirent) - (CODA_MAXNAMLEN+1)) + \
+@@ -194,54 +194,42 @@
+
+ #endif
+
+-#ifndef _FID_T_
+-#define _FID_T_ 1
+-typedef u_long VolumeId;
+-typedef u_long VnodeId;
+-typedef u_long Unique_t;
+-typedef u_long FileVersion;
+-#endif
+-
+-#ifndef _VICEFID_T_
+-#define _VICEFID_T_ 1
+-typedef struct ViceFid {
+- VolumeId Volume;
+- VnodeId Vnode;
+- Unique_t Unique;
+-} ViceFid;
+-#endif /* VICEFID */
++#ifndef _VUID_T_
++#define _VUID_T_
++typedef u_int32_t vuid_t;
++typedef u_int32_t vgid_t;
++#endif /*_VUID_T_ */
+
++#ifdef CODA_FS_OLD_API
++struct CodaFid {
++ u_int32_t opaque[3];
++};
+
+-#ifdef __linux__
+-static __inline__ ino_t coda_f2i(struct ViceFid *fid)
++static __inline__ ino_t coda_f2i(struct CodaFid *fid)
+ {
+ if ( ! fid )
+ return 0;
+- if (fid->Vnode == 0xfffffffe || fid->Vnode == 0xffffffff)
+- return ((fid->Volume << 20) | (fid->Unique & 0xfffff));
++ if (fid->opaque[1] == 0xfffffffe || fid->opaque[1] == 0xffffffff)
++ return ((fid->opaque[0] << 20) | (fid->opaque[2] & 0xfffff));
+ else
+- return (fid->Unique + (fid->Vnode<<10) + (fid->Volume<<20));
++ return (fid->opaque[2] + (fid->opaque[1]<<10) + (fid->opaque[0]<<20));
+ }
+-
+-#else
+-#define coda_f2i(fid)\
+- ((fid) ? ((fid)->Unique + ((fid)->Vnode<<10) + ((fid)->Volume<<20)) : 0)
+-#endif
+-
+-
+-#ifndef _VUID_T_
+-#define _VUID_T_
+-typedef u_int32_t vuid_t;
+-typedef u_int32_t vgid_t;
+-#endif /*_VUID_T_ */
+
+-#ifndef _CODACRED_T_
+-#define _CODACRED_T_
+ struct coda_cred {
+ vuid_t cr_uid, cr_euid, cr_suid, cr_fsuid; /* Real, efftve, set, fs uid*/
+- vgid_t cr_groupid, cr_egid, cr_sgid, cr_fsgid; /* same for groups */
++ vgid_t cr_groupid, cr_egid, cr_sgid, cr_fsgid; /* same for groups */
+ };
+-#endif
++
++#else /* not defined(CODA_FS_OLD_API) */
++
++struct CodaFid {
++ u_int32_t opaque[4];
++};
++
++#define coda_f2i(fid)\
++ (fid ? (fid->opaque[3] ^ (fid->opaque[2]<<10) ^ (fid->opaque[1]<<20) ^ fid->opaque[0]) : 0)
++
++#endif
+
+ #ifndef _VENUS_VATTR_T_
+ #define _VENUS_VATTR_T_
+@@ -330,31 +318,41 @@
+ #define CODA_KERNEL_VERSION 0 /* don't care about kernel version number */
+ #define CODA_KERNEL_VERSION 1 /* The old venus 4.6 compatible interface */
+ #endif
+-#define CODA_KERNEL_VERSION 2 /* venus_lookup gets an extra parameter */
++#ifdef CODA_FS_OLD_API
++#define CODA_KERNEL_VERSION 2 /* venus_lookup got an extra parameter */
++#else
++#define CODA_KERNEL_VERSION 3 /* 128-bit file identifiers */
++#endif
+
+ /*
+ * Venus <-> Coda RPC arguments
+ */
+ struct coda_in_hdr {
+- unsigned long opcode;
+- unsigned long unique; /* Keep multiple outstanding msgs distinct */
+- u_short pid; /* Common to all */
+- u_short pgid; /* Common to all */
+- u_short sid; /* Common to all */
+- struct coda_cred cred; /* Common to all */
++ u_int32_t opcode;
++ u_int32_t unique; /* Keep multiple outstanding msgs distinct */
++#ifdef CODA_FS_OLD_API
++ u_int16_t pid; /* Common to all */
++ u_int16_t pgid; /* Common to all */
++ u_int16_t sid; /* Common to all */
++ struct coda_cred cred; /* Common to all */
++#else
++ pid_t pid;
++ pid_t pgid;
++ vuid_t uid;
++#endif
+ };
+
+ /* Really important that opcode and unique are 1st two fields! */
+ struct coda_out_hdr {
+- unsigned long opcode;
+- unsigned long unique;
+- unsigned long result;
++ u_int32_t opcode;
++ u_int32_t unique;
++ u_int32_t result;
+ };
+
+ /* coda_root: NO_IN */
+ struct coda_root_out {
+ struct coda_out_hdr oh;
+- ViceFid VFid;
++ struct CodaFid VFid;
+ };
+
+ struct coda_root_in {
+@@ -364,7 +362,7 @@
+ /* coda_open: */
+ struct coda_open_in {
+ struct coda_in_hdr ih;
+- ViceFid VFid;
++ struct CodaFid VFid;
+ int flags;
+ };
+
+@@ -378,7 +376,7 @@
+ /* coda_store: */
+ struct coda_store_in {
+ struct coda_in_hdr ih;
+- ViceFid VFid;
++ struct CodaFid VFid;
+ int flags;
+ };
+
+@@ -389,7 +387,7 @@
+ /* coda_release: */
+ struct coda_release_in {
+ struct coda_in_hdr ih;
+- ViceFid VFid;
++ struct CodaFid VFid;
+ int flags;
+ };
+
+@@ -400,7 +398,7 @@
+ /* coda_close: */
+ struct coda_close_in {
+ struct coda_in_hdr ih;
+- ViceFid VFid;
++ struct CodaFid VFid;
+ int flags;
+ };
+
+@@ -411,7 +409,7 @@
+ /* coda_ioctl: */
+ struct coda_ioctl_in {
+ struct coda_in_hdr ih;
+- ViceFid VFid;
++ struct CodaFid VFid;
+ int cmd;
+ int len;
+ int rwflag;
+@@ -428,7 +426,7 @@
+ /* coda_getattr: */
+ struct coda_getattr_in {
+ struct coda_in_hdr ih;
+- ViceFid VFid;
++ struct CodaFid VFid;
+ };
+
+ struct coda_getattr_out {
+@@ -440,7 +438,7 @@
+ /* coda_setattr: NO_OUT */
+ struct coda_setattr_in {
+ struct coda_in_hdr ih;
+- ViceFid VFid;
++ struct CodaFid VFid;
+ struct coda_vattr attr;
+ };
+
+@@ -451,7 +449,7 @@
+ /* coda_access: NO_OUT */
+ struct coda_access_in {
+ struct coda_in_hdr ih;
+- ViceFid VFid;
++ struct CodaFid VFid;
+ int flags;
+ };
+
+@@ -467,14 +465,14 @@
+ /* coda_lookup: */
+ struct coda_lookup_in {
+ struct coda_in_hdr ih;
+- ViceFid VFid;
++ struct CodaFid VFid;
+ int name; /* Place holder for data. */
+ int flags;
+ };
+
+ struct coda_lookup_out {
+ struct coda_out_hdr oh;
+- ViceFid VFid;
++ struct CodaFid VFid;
+ int vtype;
+ };
+
+@@ -482,7 +480,7 @@
+ /* coda_create: */
+ struct coda_create_in {
+ struct coda_in_hdr ih;
+- ViceFid VFid;
++ struct CodaFid VFid;
+ struct coda_vattr attr;
+ int excl;
+ int mode;
+@@ -491,7 +489,7 @@
+
+ struct coda_create_out {
+ struct coda_out_hdr oh;
+- ViceFid VFid;
++ struct CodaFid VFid;
+ struct coda_vattr attr;
+ };
+
+@@ -499,7 +497,7 @@
+ /* coda_remove: NO_OUT */
+ struct coda_remove_in {
+ struct coda_in_hdr ih;
+- ViceFid VFid;
++ struct CodaFid VFid;
+ int name; /* Place holder for data. */
+ };
+
+@@ -510,8 +508,8 @@
+ /* coda_link: NO_OUT */
+ struct coda_link_in {
+ struct coda_in_hdr ih;
+- ViceFid sourceFid; /* cnode to link *to* */
+- ViceFid destFid; /* Directory in which to place link */
++ struct CodaFid sourceFid; /* cnode to link *to* */
++ struct CodaFid destFid; /* Directory in which to place link */
+ int tname; /* Place holder for data. */
+ };
+
+@@ -523,9 +521,9 @@
+ /* coda_rename: NO_OUT */
+ struct coda_rename_in {
+ struct coda_in_hdr ih;
+- ViceFid sourceFid;
++ struct CodaFid sourceFid;
+ int srcname;
+- ViceFid destFid;
++ struct CodaFid destFid;
+ int destname;
+ };
+
+@@ -536,14 +534,14 @@
+ /* coda_mkdir: */
+ struct coda_mkdir_in {
+ struct coda_in_hdr ih;
+- ViceFid VFid;
++ struct CodaFid VFid;
+ struct coda_vattr attr;
+ int name; /* Place holder for data. */
+ };
+
+ struct coda_mkdir_out {
+ struct coda_out_hdr oh;
+- ViceFid VFid;
++ struct CodaFid VFid;
+ struct coda_vattr attr;
+ };
+
+@@ -551,7 +549,7 @@
+ /* coda_rmdir: NO_OUT */
+ struct coda_rmdir_in {
+ struct coda_in_hdr ih;
+- ViceFid VFid;
++ struct CodaFid VFid;
+ int name; /* Place holder for data. */
+ };
+
+@@ -562,7 +560,7 @@
+ /* coda_symlink: NO_OUT */
+ struct coda_symlink_in {
+ struct coda_in_hdr ih;
+- ViceFid VFid; /* Directory to put symlink in */
++ struct CodaFid VFid; /* Directory to put symlink in */
+ int srcname;
+ struct coda_vattr attr;
+ int tname;
+@@ -575,7 +573,7 @@
+ /* coda_readlink: */
+ struct coda_readlink_in {
+ struct coda_in_hdr ih;
+- ViceFid VFid;
++ struct CodaFid VFid;
+ };
+
+ struct coda_readlink_out {
+@@ -588,7 +586,7 @@
+ /* coda_fsync: NO_OUT */
+ struct coda_fsync_in {
+ struct coda_in_hdr ih;
+- ViceFid VFid;
++ struct CodaFid VFid;
+ };
+
+ struct coda_fsync_out {
+@@ -598,12 +596,12 @@
+ /* coda_vget: */
+ struct coda_vget_in {
+ struct coda_in_hdr ih;
+- ViceFid VFid;
++ struct CodaFid VFid;
+ };
+
+ struct coda_vget_out {
+ struct coda_out_hdr oh;
+- ViceFid VFid;
++ struct CodaFid VFid;
+ int vtype;
+ };
+
+@@ -616,50 +614,46 @@
+ /* CODA_PURGEUSER is a venus->kernel call */
+ struct coda_purgeuser_out {
+ struct coda_out_hdr oh;
++#ifdef CODA_FS_OLD_API
+ struct coda_cred cred;
++#else
++ vuid_t uid;
++#endif
+ };
+
+ /* coda_zapfile: */
+ /* CODA_ZAPFILE is a venus->kernel call */
+ struct coda_zapfile_out {
+ struct coda_out_hdr oh;
+- ViceFid CodaFid;
++ struct CodaFid CodaFid;
+ };
+
+ /* coda_zapdir: */
+ /* CODA_ZAPDIR is a venus->kernel call */
+ struct coda_zapdir_out {
+ struct coda_out_hdr oh;
+- ViceFid CodaFid;
+-};
+-
+-/* coda_zapnode: */
+-/* CODA_ZAPVNODE is a venus->kernel call */
+-struct coda_zapvnode_out {
+- struct coda_out_hdr oh;
+- struct coda_cred cred;
+- ViceFid VFid;
++ struct CodaFid CodaFid;
+ };
+
+ /* coda_purgefid: */
+ /* CODA_PURGEFID is a venus->kernel call */
+ struct coda_purgefid_out {
+ struct coda_out_hdr oh;
+- ViceFid CodaFid;
++ struct CodaFid CodaFid;
+ };
+
+ /* coda_replace: */
+ /* CODA_REPLACE is a venus->kernel call */
+ struct coda_replace_out { /* coda_replace is a venus->kernel call */
+ struct coda_out_hdr oh;
+- ViceFid NewFid;
+- ViceFid OldFid;
++ struct CodaFid NewFid;
++ struct CodaFid OldFid;
+ };
+
+ /* coda_open_by_fd: */
+ struct coda_open_by_fd_in {
+ struct coda_in_hdr ih;
+- ViceFid VFid;
++ struct CodaFid VFid;
+ int flags;
+ };
+
+@@ -675,7 +669,7 @@
+ /* coda_open_by_path: */
+ struct coda_open_by_path_in {
+ struct coda_in_hdr ih;
+- ViceFid VFid;
++ struct CodaFid VFid;
+ int flags;
+ };
+
+@@ -741,7 +735,6 @@
+ struct coda_purgeuser_out coda_purgeuser;
+ struct coda_zapfile_out coda_zapfile;
+ struct coda_zapdir_out coda_zapdir;
+- struct coda_zapvnode_out coda_zapvnode;
+ struct coda_purgefid_out coda_purgefid;
+ struct coda_replace_out coda_replace;
+ struct coda_open_by_fd_out coda_open_by_fd;
+@@ -755,7 +748,6 @@
+ struct coda_purgeuser_out purgeuser;
+ struct coda_zapfile_out zapfile;
+ struct coda_zapdir_out zapdir;
+- struct coda_zapvnode_out zapvnode;
+ struct coda_purgefid_out purgefid;
+ struct coda_replace_out replace;
+ };
+@@ -778,18 +770,9 @@
+ struct ViceIoctl vi;
+ };
+
+-#define CODA_CONTROL ".CONTROL"
+-#define CODA_CONTROLLEN 8
+-#define CTL_VOL -1
+-#define CTL_VNO -1
+-#define CTL_UNI -1
+-#define CTL_INO -1
+-#define CTL_FILE "/coda/.CONTROL"
+-
+-
+-#define IS_CTL_FID(fidp) ((fidp)->Volume == CTL_VOL &&\
+- (fidp)->Vnode == CTL_VNO &&\
+- (fidp)->Unique == CTL_UNI)
++#define CODA_CONTROL ".CONTROL"
++#define CODA_CONTROLLEN 8
++#define CTL_INO -1
+
+ /* Data passed to mount */
+
+Index: linux-2.6.0-test5/include/linux/coda_linux.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/coda_linux.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/coda_linux.h 2003-09-27 11:38:40.891311960 +0800
+@@ -42,26 +42,21 @@
+ int coda_revalidate_inode(struct dentry *);
+ int coda_getattr(struct vfsmount *, struct dentry *, struct kstat *);
+ int coda_setattr(struct dentry *, struct iattr *);
+-int coda_isnullfid(ViceFid *fid);
+
+ /* global variables */
+ extern int coda_fake_statfs;
+
+ /* this file: heloers */
+-static __inline__ struct ViceFid *coda_i2f(struct inode *);
++static __inline__ struct CodaFid *coda_i2f(struct inode *);
+ static __inline__ char *coda_i2s(struct inode *);
+ static __inline__ void coda_flag_inode(struct inode *, int flag);
+-char *coda_f2s(ViceFid *f);
++char *coda_f2s(struct CodaFid *f);
+ int coda_isroot(struct inode *i);
+ int coda_iscontrol(const char *name, size_t length);
+
+-void coda_load_creds(struct coda_cred *cred);
+ void coda_vattr_to_iattr(struct inode *, struct coda_vattr *);
+ void coda_iattr_to_vattr(struct iattr *, struct coda_vattr *);
+ unsigned short coda_flags_to_cflags(unsigned short);
+-void print_vattr( struct coda_vattr *attr );
+-int coda_cred_ok(struct coda_cred *cred);
+-int coda_cred_eq(struct coda_cred *cred1, struct coda_cred *cred2);
+
+ /* sysctl.h */
+ void coda_sysctl_init(void);
+@@ -88,7 +83,7 @@
+ return list_entry(inode, struct coda_inode_info, vfs_inode);
+ }
+
+-static __inline__ struct ViceFid *coda_i2f(struct inode *inode)
++static __inline__ struct CodaFid *coda_i2f(struct inode *inode)
+ {
+ return &(ITOC(inode)->c_fid);
+ }
+Index: linux-2.6.0-test5/include/linux/coda_psdev.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/coda_psdev.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/coda_psdev.h 2003-09-27 11:38:40.893311656 +0800
+@@ -6,13 +6,11 @@
+
+ #define CODA_SUPER_MAGIC 0x73757245
+
+-struct statfs;
++struct kstatfs;
+
+ struct coda_sb_info
+ {
+- struct venus_comm * sbi_vcomm;
+- struct super_block *sbi_sb;
+- struct list_head sbi_cihead;
++ struct venus_comm *sbi_vcomm;
+ };
+
+ /* communication pending/processing queues */
+@@ -33,46 +31,45 @@
+
+
+ /* upcalls */
+-int venus_rootfid(struct super_block *sb, ViceFid *fidp);
+-int venus_getattr(struct super_block *sb, struct ViceFid *fid,
+- struct coda_vattr *attr);
+-int venus_setattr(struct super_block *, struct ViceFid *,
+- struct coda_vattr *);
+-int venus_lookup(struct super_block *sb, struct ViceFid *fid,
+- const char *name, int length, int *type,
+- struct ViceFid *resfid);
+-int venus_store(struct super_block *sb, struct ViceFid *fid, int flags,
+- struct coda_cred *);
+-int venus_release(struct super_block *sb, struct ViceFid *fid, int flags);
+-int venus_close(struct super_block *sb, struct ViceFid *fid, int flags,
+- struct coda_cred *);
+-int venus_open(struct super_block *sb, struct ViceFid *fid,
+- int flags, struct file **f);
+-int venus_mkdir(struct super_block *sb, struct ViceFid *dirfid,
++int venus_rootfid(struct super_block *sb, struct CodaFid *fidp);
++int venus_getattr(struct super_block *sb, struct CodaFid *fid,
++ struct coda_vattr *attr);
++int venus_setattr(struct super_block *, struct CodaFid *, struct coda_vattr *);
++int venus_lookup(struct super_block *sb, struct CodaFid *fid,
++ const char *name, int length, int *type,
++ struct CodaFid *resfid);
++int venus_store(struct super_block *sb, struct CodaFid *fid, int flags,
++ vuid_t uid);
++int venus_release(struct super_block *sb, struct CodaFid *fid, int flags);
++int venus_close(struct super_block *sb, struct CodaFid *fid, int flags,
++ vuid_t uid);
++int venus_open(struct super_block *sb, struct CodaFid *fid, int flags,
++ struct file **f);
++int venus_mkdir(struct super_block *sb, struct CodaFid *dirfid,
+ const char *name, int length,
+- struct ViceFid *newfid, struct coda_vattr *attrs);
+-int venus_create(struct super_block *sb, struct ViceFid *dirfid,
++ struct CodaFid *newfid, struct coda_vattr *attrs);
++int venus_create(struct super_block *sb, struct CodaFid *dirfid,
+ const char *name, int length, int excl, int mode, dev_t rdev,
+- struct ViceFid *newfid, struct coda_vattr *attrs) ;
+-int venus_rmdir(struct super_block *sb, struct ViceFid *dirfid,
++ struct CodaFid *newfid, struct coda_vattr *attrs) ;
++int venus_rmdir(struct super_block *sb, struct CodaFid *dirfid,
+ const char *name, int length);
+-int venus_remove(struct super_block *sb, struct ViceFid *dirfid,
++int venus_remove(struct super_block *sb, struct CodaFid *dirfid,
+ const char *name, int length);
+-int venus_readlink(struct super_block *sb, struct ViceFid *fid,
++int venus_readlink(struct super_block *sb, struct CodaFid *fid,
+ char *buffer, int *length);
+-int venus_rename(struct super_block *, struct ViceFid *new_fid,
+- struct ViceFid *old_fid, size_t old_length,
++int venus_rename(struct super_block *, struct CodaFid *new_fid,
++ struct CodaFid *old_fid, size_t old_length,
+ size_t new_length, const char *old_name,
+ const char *new_name);
+-int venus_link(struct super_block *sb, struct ViceFid *fid,
+- struct ViceFid *dirfid, const char *name, int len );
+-int venus_symlink(struct super_block *sb, struct ViceFid *fid,
++int venus_link(struct super_block *sb, struct CodaFid *fid,
++ struct CodaFid *dirfid, const char *name, int len );
++int venus_symlink(struct super_block *sb, struct CodaFid *fid,
+ const char *name, int len, const char *symname, int symlen);
+-int venus_access(struct super_block *sb, struct ViceFid *fid, int mask);
+-int venus_pioctl(struct super_block *sb, struct ViceFid *fid,
++int venus_access(struct super_block *sb, struct CodaFid *fid, int mask);
++int venus_pioctl(struct super_block *sb, struct CodaFid *fid,
+ unsigned int cmd, struct PioctlData *data);
+ int coda_downcall(int opcode, union outputArgs *out, struct super_block *sb);
+-int venus_fsync(struct super_block *sb, struct ViceFid *fid);
++int venus_fsync(struct super_block *sb, struct CodaFid *fid);
+ int venus_statfs(struct super_block *sb, struct kstatfs *sfs);
+
+
+Index: linux-2.6.0-test5/include/linux/compiler-gcc2.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/compiler-gcc2.h 2003-09-27 11:38:18.484718280 +0800
++++ linux-2.6.0-test5/include/linux/compiler-gcc2.h 2003-09-27 11:38:40.893311656 +0800
+@@ -0,0 +1,23 @@
++/* Never include this file directly. Include <linux/compiler.h> instead. */
++
++/* These definitions are for GCC v2.x. */
++
++/* Somewhere in the middle of the GCC 2.96 development cycle, we implemented
++ a mechanism by which the user can annotate likely branch directions and
++ expect the blocks to be reordered appropriately. Define __builtin_expect
++ to nothing for earlier compilers. */
++#include <linux/compiler-gcc.h>
++
++#if __GNUC_MINOR__ < 96
++# define __builtin_expect(x, expected_value) (x)
++#endif
++
++#define __attribute_used__ __attribute__((__unused__))
++
++/*
++ * The attribute `pure' is not implemented in GCC versions earlier
++ * than 2.96.
++ */
++#if __GNUC_MINOR__ >= 96
++# define __attribute_pure__ __attribute__((pure))
++#endif
+Index: linux-2.6.0-test5/include/linux/compiler-gcc3.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/compiler-gcc3.h 2003-09-27 11:38:18.484718280 +0800
++++ linux-2.6.0-test5/include/linux/compiler-gcc3.h 2003-09-27 11:38:40.894311504 +0800
+@@ -0,0 +1,22 @@
++/* Never include this file directly. Include <linux/compiler.h> instead. */
++
++/* These definitions are for GCC v3.x. */
++#include <linux/compiler-gcc.h>
++
++#if __GNUC_MINOR__ >= 1
++# define inline __inline__ __attribute__((always_inline))
++# define __inline__ __inline__ __attribute__((always_inline))
++# define __inline __inline__ __attribute__((always_inline))
++#endif
++
++#if __GNUC_MINOR__ > 0
++# define __deprecated __attribute__((deprecated))
++#endif
++
++#if __GNUC_MINOR__ >= 3
++# define __attribute_used__ __attribute__((__used__))
++#else
++# define __attribute_used__ __attribute__((__unused__))
++#endif
++
++#define __attribute_pure__ __attribute__((pure))
+Index: linux-2.6.0-test5/include/linux/compiler-gcc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/compiler-gcc.h 2003-09-27 11:38:18.484718280 +0800
++++ linux-2.6.0-test5/include/linux/compiler-gcc.h 2003-09-27 11:38:40.894311504 +0800
+@@ -0,0 +1,17 @@
++/* Never include this file directly. Include <linux/compiler.h> instead. */
++
++/*
++ * Common definitions for all gcc versions go here.
++ */
++
++
++/* Optimization barrier */
++/* The "volatile" is due to gcc bugs */
++#define barrier() __asm__ __volatile__("": : :"memory")
++
++/* This macro obfuscates arithmetic on a variable address so that gcc
++ shouldn't recognize the original var, and make assumptions about it */
++#define RELOC_HIDE(ptr, off) \
++ ({ unsigned long __ptr; \
++ __asm__ ("" : "=r"(__ptr) : "0"(ptr)); \
++ (typeof(ptr)) (__ptr + (off)); })
+Index: linux-2.6.0-test5/include/linux/compiler-gcc+.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/compiler-gcc+.h 2003-09-27 11:38:18.484718280 +0800
++++ linux-2.6.0-test5/include/linux/compiler-gcc+.h 2003-09-27 11:38:40.894311504 +0800
+@@ -0,0 +1,14 @@
++/* Never include this file directly. Include <linux/compiler.h> instead. */
++
++/*
++ * These definitions are for Ueber-GCC: always newer than the latest
++ * version and hence sporting everything plus a kitchen-sink.
++ */
++#include <linux/compiler-gcc.h>
++
++#define inline __inline__ __attribute__((always_inline))
++#define __inline__ __inline__ __attribute__((always_inline))
++#define __inline __inline__ __attribute__((always_inline))
++#define __deprecated __attribute__((deprecated))
++#define __attribute_used__ __attribute__((__used__))
++#define __attribute_pure__ __attribute__((pure))
+Index: linux-2.6.0-test5/include/linux/compiler.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/compiler.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/compiler.h 2003-09-27 11:38:40.896311200 +0800
+@@ -2,28 +2,36 @@
+ #define __LINUX_COMPILER_H
+
+ #ifdef __CHECKER__
+- #define __user __attribute__((noderef, address_space(1)))
+- #define __kernel /* default address space */
++# define __user __attribute__((noderef, address_space(1)))
++# define __kernel /* default address space */
+ #else
+- #define __user
+- #define __kernel
++# define __user
++# define __kernel
+ #endif
+
+-#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
+-#define inline __inline__ __attribute__((always_inline))
+-#define __inline__ __inline__ __attribute__((always_inline))
+-#define __inline __inline__ __attribute__((always_inline))
++#if __GNUC__ > 3
++# include <linux/compiler-gcc+.h> /* catch-all for GCC 4, 5, etc. */
++#elif __GNUC__ == 3
++# include <linux/compiler-gcc3.h>
++#elif __GNUC__ == 2
++# include <linux/compiler-gcc2.h>
++#else
++# error Sorry, your compiler is too old/not recognized.
+ #endif
+
+-/* Somewhere in the middle of the GCC 2.96 development cycle, we implemented
+- a mechanism by which the user can annotate likely branch directions and
+- expect the blocks to be reordered appropriately. Define __builtin_expect
+- to nothing for earlier compilers. */
+-
+-#if __GNUC__ == 2 && __GNUC_MINOR__ < 96
+-#define __builtin_expect(x, expected_value) (x)
++/* Intel compiler defines __GNUC__. So we will overwrite implementations
++ * coming from above header files here
++ */
++#ifdef __INTEL_COMPILER
++# include <linux/compiler-intel.h>
+ #endif
+
++/*
++ * Generic compiler-dependent macros required for kernel
++ * build go below this comment. Actual compiler/compiler version
++ * specific implementations come from the above header files
++ */
++
+ #define likely(x) __builtin_expect(!!(x), 1)
+ #define unlikely(x) __builtin_expect(!!(x), 0)
+
+@@ -33,10 +41,8 @@
+ * Usage is:
+ * int __deprecated foo(void)
+ */
+-#if ( __GNUC__ == 3 && __GNUC_MINOR__ > 0 ) || __GNUC__ > 3
+-#define __deprecated __attribute__((deprecated))
+-#else
+-#define __deprecated
++#ifndef __deprecated
++# define __deprecated /* unimplemented */
+ #endif
+
+ /*
+@@ -50,10 +56,8 @@
+ * In prior versions of gcc, such functions and data would be emitted, but
+ * would be warned about except with attribute((unused)).
+ */
+-#if __GNUC__ == 3 && __GNUC_MINOR__ >= 3 || __GNUC__ > 3
+-#define __attribute_used__ __attribute__((__used__))
+-#else
+-#define __attribute_used__ __attribute__((__unused__))
++#ifndef __attribute_used__
++# define __attribute_used__ /* unimplemented */
+ #endif
+
+ /*
+@@ -65,19 +69,21 @@
+ * elimination and loop optimization just as an arithmetic operator
+ * would be.
+ * [...]
+- * The attribute `pure' is not implemented in GCC versions earlier
+- * than 2.96.
+ */
+-#if (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || __GNUC__ > 2
+-#define __attribute_pure__ __attribute__((pure))
+-#else
+-#define __attribute_pure__ /* unimplemented */
++#ifndef __attribute_pure__
++# define __attribute_pure__ /* unimplemented */
++#endif
++
++/* Optimization barrier */
++#ifndef barrier
++# define barrier() __memory_barrier()
+ #endif
+
+-/* This macro obfuscates arithmetic on a variable address so that gcc
+- shouldn't recognize the original var, and make assumptions about it */
+-#define RELOC_HIDE(ptr, off) \
++#ifndef RELOC_HIDE
++# define RELOC_HIDE(ptr, off) \
+ ({ unsigned long __ptr; \
+- __asm__ ("" : "=g"(__ptr) : "0"(ptr)); \
++ __ptr = (unsigned long) (ptr); \
+ (typeof(ptr)) (__ptr + (off)); })
++#endif
++
+ #endif /* __LINUX_COMPILER_H */
+Index: linux-2.6.0-test5/include/linux/compiler-intel.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/compiler-intel.h 2003-09-27 11:38:18.484718280 +0800
++++ linux-2.6.0-test5/include/linux/compiler-intel.h 2003-09-27 11:38:40.897311048 +0800
+@@ -0,0 +1,24 @@
++/* Never include this file directly. Include <linux/compiler.h> instead. */
++
++#ifdef __ECC
++
++/* Some compiler specific definitions are overwritten here
++ * for Intel ECC compiler
++ */
++
++#include <asm/intrinsics.h>
++
++/* Intel ECC compiler doesn't support gcc specific asm stmts.
++ * It uses intrinsics to do the equivalent things.
++ */
++#undef barrier
++#undef RELOC_HIDE
++
++#define barrier() __memory_barrier()
++
++#define RELOC_HIDE(ptr, off) \
++ ({ unsigned long __ptr; \
++ __ptr = (unsigned long) (ptr); \
++ (typeof(ptr)) (__ptr + (off)); })
++
++#endif
+Index: linux-2.6.0-test5/include/linux/config.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/config.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/config.h 2003-09-27 11:38:40.898310896 +0800
+@@ -2,5 +2,8 @@
+ #define _LINUX_CONFIG_H
+
+ #include <linux/autoconf.h>
++#if defined(__i386__) && !defined(IN_BOOTLOADER)
++#include <asm/kgdb.h>
++#endif
+
+ #endif
+Index: linux-2.6.0-test5/include/linux/console.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/console.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/console.h 2003-09-27 11:38:40.899310744 +0800
+@@ -15,7 +15,6 @@
+ #define _LINUX_CONSOLE_H_ 1
+
+ #include <linux/types.h>
+-#include <linux/kdev_t.h>
+ #include <linux/spinlock.h>
+
+ struct vc_data;
+Index: linux-2.6.0-test5/include/linux/cpufreq.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/cpufreq.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/cpufreq.h 2003-09-27 11:38:40.903310136 +0800
+@@ -60,6 +60,13 @@
+ unsigned int transition_latency; /* in 10^(-9) s */
+ };
+
++struct cpufreq_real_policy {
++ unsigned int min; /* in kHz */
++ unsigned int max; /* in kHz */
++ unsigned int policy; /* see above */
++ struct cpufreq_governor *governor; /* see below */
++};
++
+ struct cpufreq_policy {
+ unsigned int cpu; /* cpu nr */
+ struct cpufreq_cpuinfo cpuinfo;/* see above */
+@@ -74,6 +81,8 @@
+ struct semaphore lock; /* CPU ->setpolicy or ->target may
+ only be called once a time */
+
++ struct cpufreq_real_policy user_policy;
++
+ struct kobject kobj;
+ struct completion kobj_unregister;
+ };
+@@ -217,6 +226,7 @@
+ *********************************************************************/
+ int cpufreq_set_policy(struct cpufreq_policy *policy);
+ int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu);
++int cpufreq_update_policy(unsigned int cpu);
+
+ /* the proc_intf.c needs this */
+ int cpufreq_parse_governor (char *str_governor, unsigned int *policy, struct cpufreq_governor **governor);
+@@ -290,7 +300,7 @@
+ #ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE
+ extern struct cpufreq_governor cpufreq_gov_performance;
+ #define CPUFREQ_DEFAULT_GOVERNOR &cpufreq_gov_performance
+-#elif CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE
++#elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE)
+ extern struct cpufreq_governor cpufreq_gov_userspace;
+ #define CPUFREQ_DEFAULT_GOVERNOR &cpufreq_gov_userspace
+ #endif
+Index: linux-2.6.0-test5/include/linux/devfs_fs_kernel.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/devfs_fs_kernel.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/devfs_fs_kernel.h 2003-09-27 11:38:40.904309984 +0800
+@@ -4,7 +4,6 @@
+ #include <linux/fs.h>
+ #include <linux/config.h>
+ #include <linux/spinlock.h>
+-#include <linux/kdev_t.h>
+ #include <linux/types.h>
+
+ #include <asm/semaphore.h>
+Index: linux-2.6.0-test5/include/linux/dm-ioctl-v1.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/dm-ioctl-v1.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/dm-ioctl-v1.h 2003-09-27 11:38:40.906309680 +0800
+@@ -50,7 +50,7 @@
+ uint32_t open_count; /* out */
+ uint32_t flags; /* in/out */
+
+- __kernel_dev_t dev; /* in/out */
++ __kernel_old_dev_t dev; /* in/out */
+
+ char name[DM_NAME_LEN]; /* device name */
+ char uuid[DM_UUID_LEN]; /* unique identifier for
+@@ -87,7 +87,7 @@
+ struct dm_target_deps {
+ uint32_t count;
+
+- __kernel_dev_t dev[0]; /* out */
++ __kernel_old_dev_t dev[0]; /* out */
+ };
+
+ /*
+Index: linux-2.6.0-test5/include/linux/dwarf2.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/dwarf2.h 2003-09-27 11:38:18.485718128 +0800
++++ linux-2.6.0-test5/include/linux/dwarf2.h 2003-09-27 11:38:40.908309376 +0800
+@@ -0,0 +1,738 @@
++/* Declarations and definitions of codes relating to the DWARF2 symbolic
++ debugging information format.
++ Copyright (C) 1992, 1993, 1995, 1996, 1997, 1999, 2000, 2001, 2002
++ Free Software Foundation, Inc.
++
++ Written by Gary Funck (gary@intrepid.com) The Ada Joint Program
++ Office (AJPO), Florida State Unviversity and Silicon Graphics Inc.
++ provided support for this effort -- June 21, 1995.
++
++ Derived from the DWARF 1 implementation written by Ron Guilmette
++ (rfg@netcom.com), November 1990.
++
++ This file is part of GCC.
++
++ GCC is free software; you can redistribute it and/or modify it under
++ the terms of the GNU General Public License as published by the Free
++ Software Foundation; either version 2, or (at your option) any later
++ version.
++
++ GCC 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 GCC; see the file COPYING. If not, write to the Free
++ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
++ 02111-1307, USA. */
++
++/* This file is derived from the DWARF specification (a public document)
++ Revision 2.0.0 (July 27, 1993) developed by the UNIX International
++ Programming Languages Special Interest Group (UI/PLSIG) and distributed
++ by UNIX International. Copies of this specification are available from
++ UNIX International, 20 Waterview Boulevard, Parsippany, NJ, 07054.
++
++ This file also now contains definitions from the DWARF 3 specification. */
++
++/* This file is shared between GCC and GDB, and should not contain
++ prototypes. */
++
++#ifndef _ELF_DWARF2_H
++#define _ELF_DWARF2_H
++
++/* Structure found in the .debug_line section. */
++#ifndef __ASSEMBLY__
++typedef struct
++{
++ unsigned char li_length [4];
++ unsigned char li_version [2];
++ unsigned char li_prologue_length [4];
++ unsigned char li_min_insn_length [1];
++ unsigned char li_default_is_stmt [1];
++ unsigned char li_line_base [1];
++ unsigned char li_line_range [1];
++ unsigned char li_opcode_base [1];
++}
++DWARF2_External_LineInfo;
++
++typedef struct
++{
++ unsigned long li_length;
++ unsigned short li_version;
++ unsigned int li_prologue_length;
++ unsigned char li_min_insn_length;
++ unsigned char li_default_is_stmt;
++ int li_line_base;
++ unsigned char li_line_range;
++ unsigned char li_opcode_base;
++}
++DWARF2_Internal_LineInfo;
++
++/* Structure found in .debug_pubnames section. */
++typedef struct
++{
++ unsigned char pn_length [4];
++ unsigned char pn_version [2];
++ unsigned char pn_offset [4];
++ unsigned char pn_size [4];
++}
++DWARF2_External_PubNames;
++
++typedef struct
++{
++ unsigned long pn_length;
++ unsigned short pn_version;
++ unsigned long pn_offset;
++ unsigned long pn_size;
++}
++DWARF2_Internal_PubNames;
++
++/* Structure found in .debug_info section. */
++typedef struct
++{
++ unsigned char cu_length [4];
++ unsigned char cu_version [2];
++ unsigned char cu_abbrev_offset [4];
++ unsigned char cu_pointer_size [1];
++}
++DWARF2_External_CompUnit;
++
++typedef struct
++{
++ unsigned long cu_length;
++ unsigned short cu_version;
++ unsigned long cu_abbrev_offset;
++ unsigned char cu_pointer_size;
++}
++DWARF2_Internal_CompUnit;
++
++typedef struct
++{
++ unsigned char ar_length [4];
++ unsigned char ar_version [2];
++ unsigned char ar_info_offset [4];
++ unsigned char ar_pointer_size [1];
++ unsigned char ar_segment_size [1];
++}
++DWARF2_External_ARange;
++
++typedef struct
++{
++ unsigned long ar_length;
++ unsigned short ar_version;
++ unsigned long ar_info_offset;
++ unsigned char ar_pointer_size;
++ unsigned char ar_segment_size;
++}
++DWARF2_Internal_ARange;
++
++#define ENUM(name) enum name {
++#define IF_NOT_ASM(a) a
++#define COMMA ,
++#else
++#define ENUM(name)
++#define IF_NOT_ASM(a)
++#define COMMA
++
++#endif
++
++/* Tag names and codes. */
++ENUM(dwarf_tag)
++
++ DW_TAG_padding = 0x00 COMMA
++ DW_TAG_array_type = 0x01 COMMA
++ DW_TAG_class_type = 0x02 COMMA
++ DW_TAG_entry_point = 0x03 COMMA
++ DW_TAG_enumeration_type = 0x04 COMMA
++ DW_TAG_formal_parameter = 0x05 COMMA
++ DW_TAG_imported_declaration = 0x08 COMMA
++ DW_TAG_label = 0x0a COMMA
++ DW_TAG_lexical_block = 0x0b COMMA
++ DW_TAG_member = 0x0d COMMA
++ DW_TAG_pointer_type = 0x0f COMMA
++ DW_TAG_reference_type = 0x10 COMMA
++ DW_TAG_compile_unit = 0x11 COMMA
++ DW_TAG_string_type = 0x12 COMMA
++ DW_TAG_structure_type = 0x13 COMMA
++ DW_TAG_subroutine_type = 0x15 COMMA
++ DW_TAG_typedef = 0x16 COMMA
++ DW_TAG_union_type = 0x17 COMMA
++ DW_TAG_unspecified_parameters = 0x18 COMMA
++ DW_TAG_variant = 0x19 COMMA
++ DW_TAG_common_block = 0x1a COMMA
++ DW_TAG_common_inclusion = 0x1b COMMA
++ DW_TAG_inheritance = 0x1c COMMA
++ DW_TAG_inlined_subroutine = 0x1d COMMA
++ DW_TAG_module = 0x1e COMMA
++ DW_TAG_ptr_to_member_type = 0x1f COMMA
++ DW_TAG_set_type = 0x20 COMMA
++ DW_TAG_subrange_type = 0x21 COMMA
++ DW_TAG_with_stmt = 0x22 COMMA
++ DW_TAG_access_declaration = 0x23 COMMA
++ DW_TAG_base_type = 0x24 COMMA
++ DW_TAG_catch_block = 0x25 COMMA
++ DW_TAG_const_type = 0x26 COMMA
++ DW_TAG_constant = 0x27 COMMA
++ DW_TAG_enumerator = 0x28 COMMA
++ DW_TAG_file_type = 0x29 COMMA
++ DW_TAG_friend = 0x2a COMMA
++ DW_TAG_namelist = 0x2b COMMA
++ DW_TAG_namelist_item = 0x2c COMMA
++ DW_TAG_packed_type = 0x2d COMMA
++ DW_TAG_subprogram = 0x2e COMMA
++ DW_TAG_template_type_param = 0x2f COMMA
++ DW_TAG_template_value_param = 0x30 COMMA
++ DW_TAG_thrown_type = 0x31 COMMA
++ DW_TAG_try_block = 0x32 COMMA
++ DW_TAG_variant_part = 0x33 COMMA
++ DW_TAG_variable = 0x34 COMMA
++ DW_TAG_volatile_type = 0x35 COMMA
++ /* DWARF 3. */
++ DW_TAG_dwarf_procedure = 0x36 COMMA
++ DW_TAG_restrict_type = 0x37 COMMA
++ DW_TAG_interface_type = 0x38 COMMA
++ DW_TAG_namespace = 0x39 COMMA
++ DW_TAG_imported_module = 0x3a COMMA
++ DW_TAG_unspecified_type = 0x3b COMMA
++ DW_TAG_partial_unit = 0x3c COMMA
++ DW_TAG_imported_unit = 0x3d COMMA
++ /* SGI/MIPS Extensions. */
++ DW_TAG_MIPS_loop = 0x4081 COMMA
++ /* GNU extensions. */
++ DW_TAG_format_label = 0x4101 COMMA /* For FORTRAN 77 and Fortran 90. */
++ DW_TAG_function_template = 0x4102 COMMA /* For C++. */
++ DW_TAG_class_template = 0x4103 COMMA /* For C++. */
++ DW_TAG_GNU_BINCL = 0x4104 COMMA
++ DW_TAG_GNU_EINCL = 0x4105 COMMA
++ /* Extensions for UPC. See: http://upc.gwu.edu/~upc. */
++ DW_TAG_upc_shared_type = 0x8765 COMMA
++ DW_TAG_upc_strict_type = 0x8766 COMMA
++ DW_TAG_upc_relaxed_type = 0x8767
++IF_NOT_ASM(};)
++
++#define DW_TAG_lo_user 0x4080
++#define DW_TAG_hi_user 0xffff
++
++/* Flag that tells whether entry has a child or not. */
++#define DW_children_no 0
++#define DW_children_yes 1
++
++/* Form names and codes. */
++ENUM(dwarf_form)
++
++ DW_FORM_addr = 0x01 COMMA
++ DW_FORM_block2 = 0x03 COMMA
++ DW_FORM_block4 = 0x04 COMMA
++ DW_FORM_data2 = 0x05 COMMA
++ DW_FORM_data4 = 0x06 COMMA
++ DW_FORM_data8 = 0x07 COMMA
++ DW_FORM_string = 0x08 COMMA
++ DW_FORM_block = 0x09 COMMA
++ DW_FORM_block1 = 0x0a COMMA
++ DW_FORM_data1 = 0x0b COMMA
++ DW_FORM_flag = 0x0c COMMA
++ DW_FORM_sdata = 0x0d COMMA
++ DW_FORM_strp = 0x0e COMMA
++ DW_FORM_udata = 0x0f COMMA
++ DW_FORM_ref_addr = 0x10 COMMA
++ DW_FORM_ref1 = 0x11 COMMA
++ DW_FORM_ref2 = 0x12 COMMA
++ DW_FORM_ref4 = 0x13 COMMA
++ DW_FORM_ref8 = 0x14 COMMA
++ DW_FORM_ref_udata = 0x15 COMMA
++ DW_FORM_indirect = 0x16
++IF_NOT_ASM(};)
++
++/* Attribute names and codes. */
++
++ENUM(dwarf_attribute)
++
++ DW_AT_sibling = 0x01 COMMA
++ DW_AT_location = 0x02 COMMA
++ DW_AT_name = 0x03 COMMA
++ DW_AT_ordering = 0x09 COMMA
++ DW_AT_subscr_data = 0x0a COMMA
++ DW_AT_byte_size = 0x0b COMMA
++ DW_AT_bit_offset = 0x0c COMMA
++ DW_AT_bit_size = 0x0d COMMA
++ DW_AT_element_list = 0x0f COMMA
++ DW_AT_stmt_list = 0x10 COMMA
++ DW_AT_low_pc = 0x11 COMMA
++ DW_AT_high_pc = 0x12 COMMA
++ DW_AT_language = 0x13 COMMA
++ DW_AT_member = 0x14 COMMA
++ DW_AT_discr = 0x15 COMMA
++ DW_AT_discr_value = 0x16 COMMA
++ DW_AT_visibility = 0x17 COMMA
++ DW_AT_import = 0x18 COMMA
++ DW_AT_string_length = 0x19 COMMA
++ DW_AT_common_reference = 0x1a COMMA
++ DW_AT_comp_dir = 0x1b COMMA
++ DW_AT_const_value = 0x1c COMMA
++ DW_AT_containing_type = 0x1d COMMA
++ DW_AT_default_value = 0x1e COMMA
++ DW_AT_inline = 0x20 COMMA
++ DW_AT_is_optional = 0x21 COMMA
++ DW_AT_lower_bound = 0x22 COMMA
++ DW_AT_producer = 0x25 COMMA
++ DW_AT_prototyped = 0x27 COMMA
++ DW_AT_return_addr = 0x2a COMMA
++ DW_AT_start_scope = 0x2c COMMA
++ DW_AT_stride_size = 0x2e COMMA
++ DW_AT_upper_bound = 0x2f COMMA
++ DW_AT_abstract_origin = 0x31 COMMA
++ DW_AT_accessibility = 0x32 COMMA
++ DW_AT_address_class = 0x33 COMMA
++ DW_AT_artificial = 0x34 COMMA
++ DW_AT_base_types = 0x35 COMMA
++ DW_AT_calling_convention = 0x36 COMMA
++ DW_AT_count = 0x37 COMMA
++ DW_AT_data_member_location = 0x38 COMMA
++ DW_AT_decl_column = 0x39 COMMA
++ DW_AT_decl_file = 0x3a COMMA
++ DW_AT_decl_line = 0x3b COMMA
++ DW_AT_declaration = 0x3c COMMA
++ DW_AT_discr_list = 0x3d COMMA
++ DW_AT_encoding = 0x3e COMMA
++ DW_AT_external = 0x3f COMMA
++ DW_AT_frame_base = 0x40 COMMA
++ DW_AT_friend = 0x41 COMMA
++ DW_AT_identifier_case = 0x42 COMMA
++ DW_AT_macro_info = 0x43 COMMA
++ DW_AT_namelist_items = 0x44 COMMA
++ DW_AT_priority = 0x45 COMMA
++ DW_AT_segment = 0x46 COMMA
++ DW_AT_specification = 0x47 COMMA
++ DW_AT_static_link = 0x48 COMMA
++ DW_AT_type = 0x49 COMMA
++ DW_AT_use_location = 0x4a COMMA
++ DW_AT_variable_parameter = 0x4b COMMA
++ DW_AT_virtuality = 0x4c COMMA
++ DW_AT_vtable_elem_location = 0x4d COMMA
++ /* DWARF 3 values. */
++ DW_AT_allocated = 0x4e COMMA
++ DW_AT_associated = 0x4f COMMA
++ DW_AT_data_location = 0x50 COMMA
++ DW_AT_stride = 0x51 COMMA
++ DW_AT_entry_pc = 0x52 COMMA
++ DW_AT_use_UTF8 = 0x53 COMMA
++ DW_AT_extension = 0x54 COMMA
++ DW_AT_ranges = 0x55 COMMA
++ DW_AT_trampoline = 0x56 COMMA
++ DW_AT_call_column = 0x57 COMMA
++ DW_AT_call_file = 0x58 COMMA
++ DW_AT_call_line = 0x59 COMMA
++ /* SGI/MIPS extensions. */
++ DW_AT_MIPS_fde = 0x2001 COMMA
++ DW_AT_MIPS_loop_begin = 0x2002 COMMA
++ DW_AT_MIPS_tail_loop_begin = 0x2003 COMMA
++ DW_AT_MIPS_epilog_begin = 0x2004 COMMA
++ DW_AT_MIPS_loop_unroll_factor = 0x2005 COMMA
++ DW_AT_MIPS_software_pipeline_depth = 0x2006 COMMA
++ DW_AT_MIPS_linkage_name = 0x2007 COMMA
++ DW_AT_MIPS_stride = 0x2008 COMMA
++ DW_AT_MIPS_abstract_name = 0x2009 COMMA
++ DW_AT_MIPS_clone_origin = 0x200a COMMA
++ DW_AT_MIPS_has_inlines = 0x200b COMMA
++ /* GNU extensions. */
++ DW_AT_sf_names = 0x2101 COMMA
++ DW_AT_src_info = 0x2102 COMMA
++ DW_AT_mac_info = 0x2103 COMMA
++ DW_AT_src_coords = 0x2104 COMMA
++ DW_AT_body_begin = 0x2105 COMMA
++ DW_AT_body_end = 0x2106 COMMA
++ DW_AT_GNU_vector = 0x2107 COMMA
++ /* VMS extensions. */
++ DW_AT_VMS_rtnbeg_pd_address = 0x2201 COMMA
++ /* UPC extension. */
++ DW_AT_upc_threads_scaled = 0x3210
++IF_NOT_ASM(};)
++
++#define DW_AT_lo_user 0x2000 /* Implementation-defined range start. */
++#define DW_AT_hi_user 0x3ff0 /* Implementation-defined range end. */
++
++/* Location atom names and codes. */
++ENUM(dwarf_location_atom)
++
++ DW_OP_addr = 0x03 COMMA
++ DW_OP_deref = 0x06 COMMA
++ DW_OP_const1u = 0x08 COMMA
++ DW_OP_const1s = 0x09 COMMA
++ DW_OP_const2u = 0x0a COMMA
++ DW_OP_const2s = 0x0b COMMA
++ DW_OP_const4u = 0x0c COMMA
++ DW_OP_const4s = 0x0d COMMA
++ DW_OP_const8u = 0x0e COMMA
++ DW_OP_const8s = 0x0f COMMA
++ DW_OP_constu = 0x10 COMMA
++ DW_OP_consts = 0x11 COMMA
++ DW_OP_dup = 0x12 COMMA
++ DW_OP_drop = 0x13 COMMA
++ DW_OP_over = 0x14 COMMA
++ DW_OP_pick = 0x15 COMMA
++ DW_OP_swap = 0x16 COMMA
++ DW_OP_rot = 0x17 COMMA
++ DW_OP_xderef = 0x18 COMMA
++ DW_OP_abs = 0x19 COMMA
++ DW_OP_and = 0x1a COMMA
++ DW_OP_div = 0x1b COMMA
++ DW_OP_minus = 0x1c COMMA
++ DW_OP_mod = 0x1d COMMA
++ DW_OP_mul = 0x1e COMMA
++ DW_OP_neg = 0x1f COMMA
++ DW_OP_not = 0x20 COMMA
++ DW_OP_or = 0x21 COMMA
++ DW_OP_plus = 0x22 COMMA
++ DW_OP_plus_uconst = 0x23 COMMA
++ DW_OP_shl = 0x24 COMMA
++ DW_OP_shr = 0x25 COMMA
++ DW_OP_shra = 0x26 COMMA
++ DW_OP_xor = 0x27 COMMA
++ DW_OP_bra = 0x28 COMMA
++ DW_OP_eq = 0x29 COMMA
++ DW_OP_ge = 0x2a COMMA
++ DW_OP_gt = 0x2b COMMA
++ DW_OP_le = 0x2c COMMA
++ DW_OP_lt = 0x2d COMMA
++ DW_OP_ne = 0x2e COMMA
++ DW_OP_skip = 0x2f COMMA
++ DW_OP_lit0 = 0x30 COMMA
++ DW_OP_lit1 = 0x31 COMMA
++ DW_OP_lit2 = 0x32 COMMA
++ DW_OP_lit3 = 0x33 COMMA
++ DW_OP_lit4 = 0x34 COMMA
++ DW_OP_lit5 = 0x35 COMMA
++ DW_OP_lit6 = 0x36 COMMA
++ DW_OP_lit7 = 0x37 COMMA
++ DW_OP_lit8 = 0x38 COMMA
++ DW_OP_lit9 = 0x39 COMMA
++ DW_OP_lit10 = 0x3a COMMA
++ DW_OP_lit11 = 0x3b COMMA
++ DW_OP_lit12 = 0x3c COMMA
++ DW_OP_lit13 = 0x3d COMMA
++ DW_OP_lit14 = 0x3e COMMA
++ DW_OP_lit15 = 0x3f COMMA
++ DW_OP_lit16 = 0x40 COMMA
++ DW_OP_lit17 = 0x41 COMMA
++ DW_OP_lit18 = 0x42 COMMA
++ DW_OP_lit19 = 0x43 COMMA
++ DW_OP_lit20 = 0x44 COMMA
++ DW_OP_lit21 = 0x45 COMMA
++ DW_OP_lit22 = 0x46 COMMA
++ DW_OP_lit23 = 0x47 COMMA
++ DW_OP_lit24 = 0x48 COMMA
++ DW_OP_lit25 = 0x49 COMMA
++ DW_OP_lit26 = 0x4a COMMA
++ DW_OP_lit27 = 0x4b COMMA
++ DW_OP_lit28 = 0x4c COMMA
++ DW_OP_lit29 = 0x4d COMMA
++ DW_OP_lit30 = 0x4e COMMA
++ DW_OP_lit31 = 0x4f COMMA
++ DW_OP_reg0 = 0x50 COMMA
++ DW_OP_reg1 = 0x51 COMMA
++ DW_OP_reg2 = 0x52 COMMA
++ DW_OP_reg3 = 0x53 COMMA
++ DW_OP_reg4 = 0x54 COMMA
++ DW_OP_reg5 = 0x55 COMMA
++ DW_OP_reg6 = 0x56 COMMA
++ DW_OP_reg7 = 0x57 COMMA
++ DW_OP_reg8 = 0x58 COMMA
++ DW_OP_reg9 = 0x59 COMMA
++ DW_OP_reg10 = 0x5a COMMA
++ DW_OP_reg11 = 0x5b COMMA
++ DW_OP_reg12 = 0x5c COMMA
++ DW_OP_reg13 = 0x5d COMMA
++ DW_OP_reg14 = 0x5e COMMA
++ DW_OP_reg15 = 0x5f COMMA
++ DW_OP_reg16 = 0x60 COMMA
++ DW_OP_reg17 = 0x61 COMMA
++ DW_OP_reg18 = 0x62 COMMA
++ DW_OP_reg19 = 0x63 COMMA
++ DW_OP_reg20 = 0x64 COMMA
++ DW_OP_reg21 = 0x65 COMMA
++ DW_OP_reg22 = 0x66 COMMA
++ DW_OP_reg23 = 0x67 COMMA
++ DW_OP_reg24 = 0x68 COMMA
++ DW_OP_reg25 = 0x69 COMMA
++ DW_OP_reg26 = 0x6a COMMA
++ DW_OP_reg27 = 0x6b COMMA
++ DW_OP_reg28 = 0x6c COMMA
++ DW_OP_reg29 = 0x6d COMMA
++ DW_OP_reg30 = 0x6e COMMA
++ DW_OP_reg31 = 0x6f COMMA
++ DW_OP_breg0 = 0x70 COMMA
++ DW_OP_breg1 = 0x71 COMMA
++ DW_OP_breg2 = 0x72 COMMA
++ DW_OP_breg3 = 0x73 COMMA
++ DW_OP_breg4 = 0x74 COMMA
++ DW_OP_breg5 = 0x75 COMMA
++ DW_OP_breg6 = 0x76 COMMA
++ DW_OP_breg7 = 0x77 COMMA
++ DW_OP_breg8 = 0x78 COMMA
++ DW_OP_breg9 = 0x79 COMMA
++ DW_OP_breg10 = 0x7a COMMA
++ DW_OP_breg11 = 0x7b COMMA
++ DW_OP_breg12 = 0x7c COMMA
++ DW_OP_breg13 = 0x7d COMMA
++ DW_OP_breg14 = 0x7e COMMA
++ DW_OP_breg15 = 0x7f COMMA
++ DW_OP_breg16 = 0x80 COMMA
++ DW_OP_breg17 = 0x81 COMMA
++ DW_OP_breg18 = 0x82 COMMA
++ DW_OP_breg19 = 0x83 COMMA
++ DW_OP_breg20 = 0x84 COMMA
++ DW_OP_breg21 = 0x85 COMMA
++ DW_OP_breg22 = 0x86 COMMA
++ DW_OP_breg23 = 0x87 COMMA
++ DW_OP_breg24 = 0x88 COMMA
++ DW_OP_breg25 = 0x89 COMMA
++ DW_OP_breg26 = 0x8a COMMA
++ DW_OP_breg27 = 0x8b COMMA
++ DW_OP_breg28 = 0x8c COMMA
++ DW_OP_breg29 = 0x8d COMMA
++ DW_OP_breg30 = 0x8e COMMA
++ DW_OP_breg31 = 0x8f COMMA
++ DW_OP_regx = 0x90 COMMA
++ DW_OP_fbreg = 0x91 COMMA
++ DW_OP_bregx = 0x92 COMMA
++ DW_OP_piece = 0x93 COMMA
++ DW_OP_deref_size = 0x94 COMMA
++ DW_OP_xderef_size = 0x95 COMMA
++ DW_OP_nop = 0x96 COMMA
++ /* DWARF 3 extensions. */
++ DW_OP_push_object_address = 0x97 COMMA
++ DW_OP_call2 = 0x98 COMMA
++ DW_OP_call4 = 0x99 COMMA
++ DW_OP_call_ref = 0x9a COMMA
++ /* GNU extensions. */
++ DW_OP_GNU_push_tls_address = 0xe0
++IF_NOT_ASM(};)
++
++#define DW_OP_lo_user 0xe0 /* Implementation-defined range start. */
++#define DW_OP_hi_user 0xff /* Implementation-defined range end. */
++
++/* Type encodings. */
++ENUM(dwarf_type)
++
++ DW_ATE_void = 0x0 COMMA
++ DW_ATE_address = 0x1 COMMA
++ DW_ATE_boolean = 0x2 COMMA
++ DW_ATE_complex_float = 0x3 COMMA
++ DW_ATE_float = 0x4 COMMA
++ DW_ATE_signed = 0x5 COMMA
++ DW_ATE_signed_char = 0x6 COMMA
++ DW_ATE_unsigned = 0x7 COMMA
++ DW_ATE_unsigned_char = 0x8 COMMA
++ /* DWARF 3. */
++ DW_ATE_imaginary_float = 0x9
++IF_NOT_ASM(};)
++
++#define DW_ATE_lo_user 0x80
++#define DW_ATE_hi_user 0xff
++
++/* Array ordering names and codes. */
++ENUM(dwarf_array_dim_ordering)
++
++ DW_ORD_row_major = 0 COMMA
++ DW_ORD_col_major = 1
++IF_NOT_ASM(};)
++
++/* Access attribute. */
++ENUM(dwarf_access_attribute)
++
++ DW_ACCESS_public = 1 COMMA
++ DW_ACCESS_protected = 2 COMMA
++ DW_ACCESS_private = 3
++IF_NOT_ASM(};)
++
++/* Visibility. */
++ENUM(dwarf_visibility_attribute)
++
++ DW_VIS_local = 1 COMMA
++ DW_VIS_exported = 2 COMMA
++ DW_VIS_qualified = 3
++IF_NOT_ASM(};)
++
++/* Virtuality. */
++ENUM(dwarf_virtuality_attribute)
++
++ DW_VIRTUALITY_none = 0 COMMA
++ DW_VIRTUALITY_virtual = 1 COMMA
++ DW_VIRTUALITY_pure_virtual = 2
++IF_NOT_ASM(};)
++
++/* Case sensitivity. */
++ENUM(dwarf_id_case)
++
++ DW_ID_case_sensitive = 0 COMMA
++ DW_ID_up_case = 1 COMMA
++ DW_ID_down_case = 2 COMMA
++ DW_ID_case_insensitive = 3
++IF_NOT_ASM(};)
++
++/* Calling convention. */
++ENUM(dwarf_calling_convention)
++
++ DW_CC_normal = 0x1 COMMA
++ DW_CC_program = 0x2 COMMA
++ DW_CC_nocall = 0x3
++IF_NOT_ASM(};)
++
++#define DW_CC_lo_user 0x40
++#define DW_CC_hi_user 0xff
++
++/* Inline attribute. */
++ENUM(dwarf_inline_attribute)
++
++ DW_INL_not_inlined = 0 COMMA
++ DW_INL_inlined = 1 COMMA
++ DW_INL_declared_not_inlined = 2 COMMA
++ DW_INL_declared_inlined = 3
++IF_NOT_ASM(};)
++
++/* Discriminant lists. */
++ENUM(dwarf_discrim_list)
++
++ DW_DSC_label = 0 COMMA
++ DW_DSC_range = 1
++IF_NOT_ASM(};)
++
++/* Line number opcodes. */
++ENUM(dwarf_line_number_ops)
++
++ DW_LNS_extended_op = 0 COMMA
++ DW_LNS_copy = 1 COMMA
++ DW_LNS_advance_pc = 2 COMMA
++ DW_LNS_advance_line = 3 COMMA
++ DW_LNS_set_file = 4 COMMA
++ DW_LNS_set_column = 5 COMMA
++ DW_LNS_negate_stmt = 6 COMMA
++ DW_LNS_set_basic_block = 7 COMMA
++ DW_LNS_const_add_pc = 8 COMMA
++ DW_LNS_fixed_advance_pc = 9 COMMA
++ /* DWARF 3. */
++ DW_LNS_set_prologue_end = 10 COMMA
++ DW_LNS_set_epilogue_begin = 11 COMMA
++ DW_LNS_set_isa = 12
++IF_NOT_ASM(};)
++
++/* Line number extended opcodes. */
++ENUM(dwarf_line_number_x_ops)
++
++ DW_LNE_end_sequence = 1 COMMA
++ DW_LNE_set_address = 2 COMMA
++ DW_LNE_define_file = 3
++IF_NOT_ASM(};)
++
++/* Call frame information. */
++ENUM(dwarf_call_frame_info)
++
++ DW_CFA_advance_loc = 0x40 COMMA
++ DW_CFA_offset = 0x80 COMMA
++ DW_CFA_restore = 0xc0 COMMA
++ DW_CFA_nop = 0x00 COMMA
++ DW_CFA_set_loc = 0x01 COMMA
++ DW_CFA_advance_loc1 = 0x02 COMMA
++ DW_CFA_advance_loc2 = 0x03 COMMA
++ DW_CFA_advance_loc4 = 0x04 COMMA
++ DW_CFA_offset_extended = 0x05 COMMA
++ DW_CFA_restore_extended = 0x06 COMMA
++ DW_CFA_undefined = 0x07 COMMA
++ DW_CFA_same_value = 0x08 COMMA
++ DW_CFA_register = 0x09 COMMA
++ DW_CFA_remember_state = 0x0a COMMA
++ DW_CFA_restore_state = 0x0b COMMA
++ DW_CFA_def_cfa = 0x0c COMMA
++ DW_CFA_def_cfa_register = 0x0d COMMA
++ DW_CFA_def_cfa_offset = 0x0e COMMA
++
++ /* DWARF 3. */
++ DW_CFA_def_cfa_expression = 0x0f COMMA
++ DW_CFA_expression = 0x10 COMMA
++ DW_CFA_offset_extended_sf = 0x11 COMMA
++ DW_CFA_def_cfa_sf = 0x12 COMMA
++ DW_CFA_def_cfa_offset_sf = 0x13 COMMA
++
++ /* SGI/MIPS specific. */
++ DW_CFA_MIPS_advance_loc8 = 0x1d COMMA
++
++ /* GNU extensions. */
++ DW_CFA_GNU_window_save = 0x2d COMMA
++ DW_CFA_GNU_args_size = 0x2e COMMA
++ DW_CFA_GNU_negative_offset_extended = 0x2f
++IF_NOT_ASM(};)
++
++#define DW_CIE_ID 0xffffffff
++#define DW_CIE_VERSION 1
++
++#define DW_CFA_extended 0
++#define DW_CFA_lo_user 0x1c
++#define DW_CFA_hi_user 0x3f
++
++#define DW_CHILDREN_no 0x00
++#define DW_CHILDREN_yes 0x01
++
++#define DW_ADDR_none 0
++
++/* Source language names and codes. */
++ENUM(dwarf_source_language)
++
++ DW_LANG_C89 = 0x0001 COMMA
++ DW_LANG_C = 0x0002 COMMA
++ DW_LANG_Ada83 = 0x0003 COMMA
++ DW_LANG_C_plus_plus = 0x0004 COMMA
++ DW_LANG_Cobol74 = 0x0005 COMMA
++ DW_LANG_Cobol85 = 0x0006 COMMA
++ DW_LANG_Fortran77 = 0x0007 COMMA
++ DW_LANG_Fortran90 = 0x0008 COMMA
++ DW_LANG_Pascal83 = 0x0009 COMMA
++ DW_LANG_Modula2 = 0x000a COMMA
++ DW_LANG_Java = 0x000b COMMA
++ /* DWARF 3. */
++ DW_LANG_C99 = 0x000c COMMA
++ DW_LANG_Ada95 = 0x000d COMMA
++ DW_LANG_Fortran95 = 0x000e COMMA
++ /* MIPS. */
++ DW_LANG_Mips_Assembler = 0x8001 COMMA
++ /* UPC. */
++ DW_LANG_Upc = 0x8765
++IF_NOT_ASM(};)
++
++#define DW_LANG_lo_user 0x8000 /* Implementation-defined range start. */
++#define DW_LANG_hi_user 0xffff /* Implementation-defined range start. */
++
++/* Names and codes for macro information. */
++ENUM(dwarf_macinfo_record_type)
++
++ DW_MACINFO_define = 1 COMMA
++ DW_MACINFO_undef = 2 COMMA
++ DW_MACINFO_start_file = 3 COMMA
++ DW_MACINFO_end_file = 4 COMMA
++ DW_MACINFO_vendor_ext = 255
++IF_NOT_ASM(};)
++\f
++/* @@@ For use with GNU frame unwind information. */
++
++#define DW_EH_PE_absptr 0x00
++#define DW_EH_PE_omit 0xff
++
++#define DW_EH_PE_uleb128 0x01
++#define DW_EH_PE_udata2 0x02
++#define DW_EH_PE_udata4 0x03
++#define DW_EH_PE_udata8 0x04
++#define DW_EH_PE_sleb128 0x09
++#define DW_EH_PE_sdata2 0x0A
++#define DW_EH_PE_sdata4 0x0B
++#define DW_EH_PE_sdata8 0x0C
++#define DW_EH_PE_signed 0x08
++
++#define DW_EH_PE_pcrel 0x10
++#define DW_EH_PE_textrel 0x20
++#define DW_EH_PE_datarel 0x30
++#define DW_EH_PE_funcrel 0x40
++#define DW_EH_PE_aligned 0x50
++
++#define DW_EH_PE_indirect 0x80
++
++#endif /* _ELF_DWARF2_H */
+Index: linux-2.6.0-test5/include/linux/dwarf2-lang.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/dwarf2-lang.h 2003-09-27 11:38:18.485718128 +0800
++++ linux-2.6.0-test5/include/linux/dwarf2-lang.h 2003-09-27 11:38:40.909309224 +0800
+@@ -0,0 +1,132 @@
++#ifndef DWARF2_LANG
++#define DWARF2_LANG
++#include <linux/dwarf2.h>
++
++/*
++ * This is free software; you can redistribute it and/or modify it under
++ * the terms of the GNU General Public License as published by the Free
++ * Software Foundation; either version 2, or (at your option) any later
++ * version.
++ */
++/*
++ * This file defines macros that allow generation of DWARF debug records
++ * for asm files. This file is platform independent. Register numbers
++ * (which are about the only thing that is platform dependent) are to be
++ * supplied by a platform defined file.
++ */
++#define DWARF_preamble() .section .debug_frame,"",@progbits
++/*
++ * This macro starts a debug frame section. The debug_frame describes
++ * where to find the registers that the enclosing function saved on
++ * entry.
++ *
++ * ORD is use by the label generator and should be the same as what is
++ * passed to CFI_postamble.
++ *
++ * pc, pc register gdb ordinal.
++ *
++ * code_align this is the factor used to define locations or regions
++ * where the given definitions apply. If you use labels to define these
++ * this should be 1.
++ *
++ * data_align this is the factor used to define register offsets. If
++ * you use struct offset, this should be the size of the register in
++ * bytes or the negative of that. This is how it is used: you will
++ * define a register as the reference register, say the stack pointer,
++ * then you will say where a register is located relative to this
++ * reference registers value, say 40 for register 3 (the gdb register
++ * number). The <40> will be multiplied by <data_align> to define the
++ * byte offset of the given register (3, in this example). So if your
++ * <40> is the byte offset and the reference register points at the
++ * begining, you would want 1 for the data_offset. If <40> was the 40th
++ * 4-byte element in that structure you would want 4. And if your
++ * reference register points at the end of the structure you would want
++ * a negative data_align value(and you would have to do other math as
++ * well).
++ */
++
++#define CFI_preamble(ORD, pc, code_align, data_align) \
++.section .debug_frame,"",@progbits ; \
++frame/**/_/**/ORD: \
++ .long end/**/_/**/ORD-start/**/_/**/ORD; \
++start/**/_/**/ORD: \
++ .long DW_CIE_ID; \
++ .byte DW_CIE_VERSION; \
++ .byte 0 ; \
++ .uleb128 code_align; \
++ .sleb128 data_align; \
++ .byte pc;
++
++/*
++ * After the above macro and prior to the CFI_postamble, you need to
++ * define the initial state. This starts with defining the reference
++ * register and, usually the pc. Here are some helper macros:
++ */
++
++#define CFA_define_reference(reg, offset) \
++ .byte DW_CFA_def_cfa; \
++ .uleb128 reg; \
++ .uleb128 (offset);
++
++#define CFA_define_offset(reg, offset) \
++ .byte (DW_CFA_offset + reg); \
++ .uleb128 (offset);
++
++#define CFI_postamble(ORD) \
++ .align 4; \
++end/**/_/**/ORD:
++/*
++ * So now your code pushs stuff on the stack, you need a new location
++ * and the rules for what to do. This starts a running description of
++ * the call frame. You need to describe what changes with respect to
++ * the call registers as the location of the pc moves through the code.
++ * The following builds an FDE (fram descriptor entry?). Like the
++ * above, it has a preamble and a postamble. It also is tied to the CFI
++ * above.
++ * The first entry after the preamble must be the location in the code
++ * that the call frame is being described for.
++ */
++#define FDE_preamble(ORD, fde_no, initial_address, length) \
++ .long FDE_end/**/_/**/fde_no-FDE_start/**/_/**/fde_no; \
++FDE_start/**/_/**/fde_no: \
++ .long frame/**/_/**/ORD; \
++ .long initial_address; \
++ .long length;
++
++#define FDE_postamble(fde_no) \
++ .align 4; \
++FDE_end/**/_/**/fde_no:
++/*
++ * That done, you can now add registers, subtract registers, move the
++ * reference and even change the reference. You can also define a new
++ * area of code the info applies to. For discontinuous bits you should
++ * start a new FDE. You may have as many as you like.
++ */
++
++/*
++ * To advance the address by <bytes>
++ */
++
++#define FDE_advance(bytes) \
++ .byte DW_CFA_advance_loc4 \
++ .long bytes
++
++
++
++/*
++ * With the above you can define all the register locations. But
++ * suppose the reference register moves... Takes the new offset NOT an
++ * increment. This is how esp is tracked if it is not saved.
++ */
++
++#define CFA_define_cfa_offset(offset) \
++ .byte $DW_CFA_def_cfa_offset; \
++ .uleb128 (offset);
++/*
++ * Or suppose you want to use a different reference register...
++ */
++#define CFA_define_cfa_register(reg) \
++ .byte DW_CFA_def_cfa_register; \
++ .uleb128 reg;
++
++#endif
+Index: linux-2.6.0-test5/include/linux/eisa.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/eisa.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/eisa.h 2003-09-27 11:38:40.910309072 +0800
+@@ -1,6 +1,19 @@
+ #ifndef _LINUX_EISA_H
+ #define _LINUX_EISA_H
+
++#include <linux/ioport.h>
++#include <linux/device.h>
++
++#ifdef CONFIG_EISA
++# ifdef CONFIG_EISA_ALWAYS
++# define EISA_bus 1
++# else
++ extern int EISA_bus;
++# endif
++#else
++# define EISA_bus 0
++#endif
++
+ #define EISA_SIG_LEN 8
+ #define EISA_MAX_SLOTS 8
+
+Index: linux-2.6.0-test5/include/linux/elevator.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/elevator.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/elevator.h 2003-09-27 11:38:40.913308616 +0800
+@@ -15,7 +15,6 @@
+ typedef void (elevator_remove_req_fn) (request_queue_t *, struct request *);
+ typedef void (elevator_requeue_req_fn) (request_queue_t *, struct request *);
+ typedef struct request *(elevator_request_list_fn) (request_queue_t *, struct request *);
+-typedef struct list_head *(elevator_get_sort_head_fn) (request_queue_t *, struct request *);
+ typedef void (elevator_completed_req_fn) (request_queue_t *, struct request *);
+ typedef int (elevator_may_queue_fn) (request_queue_t *, int);
+
+@@ -95,6 +94,11 @@
+ */
+ extern elevator_t iosched_as;
+
++/*
++ * completely fair queueing I/O scheduler
++ */
++extern elevator_t iosched_cfq;
++
+ extern int elevator_init(request_queue_t *, elevator_t *);
+ extern void elevator_exit(request_queue_t *);
+ extern inline int elv_rq_merge_ok(struct request *, struct bio *);
+Index: linux-2.6.0-test5/include/linux/elf.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/elf.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/elf.h 2003-09-27 11:38:40.916308160 +0800
+@@ -360,7 +360,8 @@
+ #define EI_CLASS 4
+ #define EI_DATA 5
+ #define EI_VERSION 6
+-#define EI_PAD 7
++#define EI_OSABI 7
++#define EI_PAD 8
+
+ #define ELFMAG0 0x7f /* EI_MAG */
+ #define ELFMAG1 'E'
+@@ -382,6 +383,13 @@
+ #define EV_CURRENT 1
+ #define EV_NUM 2
+
++#define ELFOSABI_NONE 0
++#define ELFOSABI_LINUX 3
++
++#ifndef ELF_OSABI
++#define ELF_OSABI ELFOSABI_NONE
++#endif
++
+ /* Notes used in ET_CORE */
+ #define NT_PRSTATUS 1
+ #define NT_PRFPREG 2
+Index: linux-2.6.0-test5/include/linux/errno.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/errno.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/errno.h 2003-09-27 11:38:40.917308008 +0800
+@@ -22,6 +22,7 @@
+ #define EBADTYPE 527 /* Type not supported by server */
+ #define EJUKEBOX 528 /* Request initiated, but will not complete before timeout */
+ #define EIOCBQUEUED 529 /* iocb queued, will get completion event */
++#define EIOCBRETRY 530 /* iocb queued, will trigger a retry */
+
+ #endif
+
+Index: linux-2.6.0-test5/include/linux/eventpoll.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/eventpoll.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/eventpoll.h 2003-09-27 11:38:40.919307704 +0800
+@@ -48,9 +48,10 @@
+
+ /* Kernel space functions implementing the user space "epoll" API */
+ asmlinkage long sys_epoll_create(int size);
+-asmlinkage long sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
+-asmlinkage long sys_epoll_wait(int epfd, struct epoll_event *events, int maxevents,
+- int timeout);
++asmlinkage long sys_epoll_ctl(int epfd, int op, int fd,
++ struct epoll_event __user *event);
++asmlinkage long sys_epoll_wait(int epfd, struct epoll_event __user *events,
++ int maxevents, int timeout);
+
+ #ifdef CONFIG_EPOLL
+
+Index: linux-2.6.0-test5/include/linux/fb.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/fb.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/fb.h 2003-09-27 11:38:40.925306792 +0800
+@@ -2,7 +2,6 @@
+ #define _LINUX_FB_H
+
+ #include <linux/tty.h>
+-#include <linux/workqueue.h>
+ #include <asm/types.h>
+ #include <asm/io.h>
+
+@@ -326,28 +325,38 @@
+ struct fb_image image; /* Cursor image */
+ };
+
++#ifdef __KERNEL__
++
++#include <linux/fs.h>
++#include <linux/init.h>
++#include <linux/workqueue.h>
++#include <linux/devfs_fs_kernel.h>
++
++/*
++ * The purpose of this structure is to translate data
++ * from the hardwre independent format of fbdev to what
++ * format the hardware needs.
++ */
++
+ #define FB_PIXMAP_DEFAULT 1 /* used internally by fbcon */
+ #define FB_PIXMAP_SYSTEM 2 /* memory is in system RAM */
+ #define FB_PIXMAP_IO 4 /* memory is iomapped */
+ #define FB_PIXMAP_SYNC 256 /* set if GPU can DMA */
+
+ struct fb_pixmap {
+- __u8 *addr; /* pointer to memory */
+- __u32 size; /* size of buffer in bytes */
+- __u32 offset; /* current offset to buffer */
+- __u32 buf_align; /* byte alignment of each bitmap */
+- __u32 scan_align; /* alignment per scanline */
+- __u32 flags; /* see FB_PIXMAP_* */
+- /* access methods */
+- void (*outbuf)(u8 *dst, u8 *addr, unsigned int size);
+- u8 (*inbuf) (u8 *addr);
+- spinlock_t lock; /* spinlock */
++ u8 *addr; /* pointer to memory */
++ u32 size; /* size of buffer in bytes */
++ u32 offset; /* current offset to buffer */
++ u32 buf_align; /* byte alignment of each bitmap */
++ u32 scan_align; /* alignment per scanline */
++ u32 access_align; /* alignment per read/write */
++ u32 flags; /* see FB_PIXMAP_* */
++ spinlock_t lock; /* spinlock */
+ atomic_t count;
++ /* access methods */
++ void (*outbuf)(u8 *addr, u8 *dst, unsigned int size);
++ u8 (*inbuf) (u8 *addr);
+ };
+-#ifdef __KERNEL__
+-
+-#include <linux/fs.h>
+-#include <linux/init.h>
+
+ struct fb_info;
+ struct vm_area_struct;
+@@ -396,24 +405,24 @@
+ };
+
+ struct fb_info {
+- int node;
+- int flags;
+- int open; /* Has this been open already ? */
++ int node;
++ int flags;
+ #define FBINFO_FLAG_MODULE 1 /* Low-level driver is a module */
+- struct fb_var_screeninfo var; /* Current var */
+- struct fb_fix_screeninfo fix; /* Current fix */
+- struct fb_monspecs monspecs; /* Current Monitor specs */
+- struct fb_cursor cursor; /* Current cursor */
+- struct work_struct queue; /* Framebuffer event queue */
+- struct fb_pixmap pixmap; /* Current pixmap */
+- struct fb_cmap cmap; /* Current cmap */
+- struct fb_ops *fbops;
+- char *screen_base; /* Virtual address */
+- struct vc_data *display_fg; /* Console visible on this display */
+- int currcon; /* Current VC. */
+- void *pseudo_palette; /* Fake palette of 16 colors */
+- /* From here on everything is device dependent */
+- void *par;
++ struct fb_var_screeninfo var; /* Current var */
++ struct fb_fix_screeninfo fix; /* Current fix */
++ struct fb_monspecs monspecs; /* Current Monitor specs */
++ struct fb_cursor cursor; /* Current cursor */
++ struct work_struct queue; /* Framebuffer event queue */
++ struct fb_pixmap pixmap; /* Image HW mapper */
++ struct fb_pixmap sprite; /* Cursor HW mapper */
++ struct fb_cmap cmap; /* Current cmap */
++ struct fb_ops *fbops;
++ char *screen_base; /* Virtual address */
++ struct vc_data *display_fg; /* Console visible on this display */
++ void *pseudo_palette; /* Fake palette of 16 colors */
++ int currcon; /* Current VC. */
++ /* From here on everything is device dependent */
++ void *par;
+ };
+
+ #ifdef MODULE
+@@ -481,12 +490,12 @@
+ extern int unregister_framebuffer(struct fb_info *fb_info);
+ extern int fb_prepare_logo(struct fb_info *fb_info);
+ extern int fb_show_logo(struct fb_info *fb_info);
+-extern u32 fb_get_buffer_offset(struct fb_info *info, u32 size);
+-extern void move_buf_unaligned(struct fb_info *info, u8 *dst, u8 *src, u32 d_pitch,
+- u32 height, u32 mask, u32 shift_high, u32 shift_low,
++extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size);
++extern void move_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf, u8 *dst, u8 *src,
++ u32 d_pitch, u32 height, u32 mask, u32 shift_high, u32 shift_low,
+ u32 mod, u32 idx);
+-extern void move_buf_aligned(struct fb_info *info, u8 *dst, u8 *src, u32 d_pitch,
+- u32 s_pitch, u32 height);
++extern void move_buf_aligned(struct fb_info *info, struct fb_pixmap *buf, u8 *dst, u8 *src,
++ u32 d_pitch, u32 s_pitch, u32 height);
+ extern struct fb_info *registered_fb[FB_MAX];
+ extern int num_registered_fb;
+
+Index: linux-2.6.0-test5/include/linux/fs.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/fs.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/fs.h 2003-09-27 11:38:40.939304664 +0800
+@@ -388,6 +388,7 @@
+ unsigned short i_bytes;
+ spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */
+ struct semaphore i_sem;
++ struct rw_semaphore i_alloc_sem;
+ struct inode_operations *i_op;
+ struct file_operations *i_fop; /* former ->i_op->default_file_ops */
+ struct super_block *i_sb;
+@@ -749,6 +750,11 @@
+ #define DT_SOCK 12
+ #define DT_WHT 14
+
++#define OSYNC_METADATA (1<<0)
++#define OSYNC_DATA (1<<1)
++#define OSYNC_INODE (1<<2)
++int generic_osync_inode(struct inode *, int);
++
+ /*
+ * This is the "filldir" function type, used by readdir() to let
+ * the kernel specify what kind of dirent layout it wants to have.
+@@ -1199,6 +1205,7 @@
+ }
+ extern void invalidate_inode_pages2(struct address_space *mapping);
+ extern void write_inode_now(struct inode *, int);
++extern int do_fdatasync(struct file *);
+ extern int filemap_fdatawrite(struct address_space *);
+ extern int filemap_flush(struct address_space *);
+ extern int filemap_fdatawait(struct address_space *);
+@@ -1392,9 +1399,6 @@
+ extern int simple_fill_super(struct super_block *, int, struct tree_descr *);
+ extern int simple_pin_fs(char *name, struct vfsmount **mount, int *count);
+ extern void simple_release_fs(struct vfsmount **mount, int *count);
+-extern int old_valid_dev(dev_t);
+-extern u16 old_encode_dev(dev_t);
+-extern dev_t old_decode_dev(u16);
+
+ extern int inode_change_ok(struct inode *, struct iattr *);
+ extern int inode_setattr(struct inode *, struct iattr *);
+Index: linux-2.6.0-test5/include/linux/ftape.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/ftape.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/ftape.h 2003-09-27 11:38:40.942304208 +0800
+@@ -199,8 +199,6 @@
+ #define ABS(a) ((a) < 0 ? -(a) : (a))
+ #define NR_ITEMS(x) (int)(sizeof(x)/ sizeof(*x))
+
+-extern int ftape_init(void);
+-
+ #endif /* __KERNEL__ */
+
+ #endif
+Index: linux-2.6.0-test5/include/linux/hugetlb.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/hugetlb.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/hugetlb.h 2003-09-27 11:38:40.943304056 +0800
+@@ -98,6 +98,8 @@
+ extern struct file_operations hugetlbfs_file_operations;
+ extern struct vm_operations_struct hugetlb_vm_ops;
+ struct file *hugetlb_zero_setup(size_t);
++int hugetlb_get_quota(struct address_space *mapping);
++void hugetlb_put_quota(struct address_space *mapping);
+
+ static inline int is_file_hugepages(struct file *file)
+ {
+Index: linux-2.6.0-test5/include/linux/if_frad.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/if_frad.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/if_frad.h 2003-09-27 11:38:40.946303600 +0800
+@@ -191,9 +191,6 @@
+ int buffer; /* current buffer for S508 firmware */
+ };
+
+-int register_frad(const char *name);
+-int unregister_frad(const char *name);
+-
+ extern void dlci_ioctl_set(int (*hook)(unsigned int, void *));
+
+ #endif /* __KERNEL__ */
+Index: linux-2.6.0-test5/include/linux/init_task.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/init_task.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/init_task.h 2003-09-27 11:38:40.947303448 +0800
+@@ -108,6 +108,7 @@
+ .proc_lock = SPIN_LOCK_UNLOCKED, \
+ .switch_lock = SPIN_LOCK_UNLOCKED, \
+ .journal_info = NULL, \
++ .io_wait = NULL, \
+ }
+
+
+Index: linux-2.6.0-test5/include/linux/input.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/input.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/input.h 2003-09-27 11:38:40.953302536 +0800
+@@ -751,7 +751,7 @@
+ #define LONG(x) ((x)/BITS_PER_LONG)
+
+ #define INPUT_KEYCODE(dev, scancode) ((dev->keycodesize == 1) ? ((u8*)dev->keycode)[scancode] : \
+- ((dev->keycodesize == 1) ? ((u16*)dev->keycode)[scancode] : (((u32*)dev->keycode)[scancode])))
++ ((dev->keycodesize == 2) ? ((u16*)dev->keycode)[scancode] : (((u32*)dev->keycode)[scancode])))
+
+ #define init_input_dev(dev) do { INIT_LIST_HEAD(&((dev)->h_list)); INIT_LIST_HEAD(&((dev)->node)); } while (0)
+
+Index: linux-2.6.0-test5/include/linux/interrupt.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/interrupt.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/interrupt.h 2003-09-27 11:38:40.956302080 +0800
+@@ -3,6 +3,7 @@
+ #define _LINUX_INTERRUPT_H
+
+ #include <linux/config.h>
++#include <linux/kernel.h>
+ #include <linux/linkage.h>
+ #include <linux/bitops.h>
+ #include <linux/preempt.h>
+Index: linux-2.6.0-test5/include/linux/ipv6.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/ipv6.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/ipv6.h 2003-09-27 11:38:40.958301776 +0800
+@@ -122,6 +122,52 @@
+ struct in6_addr daddr;
+ };
+
++/*
++ * This structure contains configuration options per IPv6 link.
++ */
++struct ipv6_devconf {
++ __s32 forwarding;
++ __s32 hop_limit;
++ __s32 mtu6;
++ __s32 accept_ra;
++ __s32 accept_redirects;
++ __s32 autoconf;
++ __s32 dad_transmits;
++ __s32 rtr_solicits;
++ __s32 rtr_solicit_interval;
++ __s32 rtr_solicit_delay;
++#ifdef CONFIG_IPV6_PRIVACY
++ __s32 use_tempaddr;
++ __s32 temp_valid_lft;
++ __s32 temp_prefered_lft;
++ __s32 regen_max_retry;
++ __s32 max_desync_factor;
++#endif
++ void *sysctl;
++};
++
++/* index values for the variables in ipv6_devconf */
++enum {
++ DEVCONF_FORWARDING = 0,
++ DEVCONF_HOPLIMIT,
++ DEVCONF_MTU6,
++ DEVCONF_ACCEPT_RA,
++ DEVCONF_ACCEPT_REDIRECTS,
++ DEVCONF_AUTOCONF,
++ DEVCONF_DAD_TRANSMITS,
++ DEVCONF_RTR_SOLICITS,
++ DEVCONF_RTR_SOLICIT_INTERVAL,
++ DEVCONF_RTR_SOLICIT_DELAY,
++#ifdef CONFIG_IPV6_PRIVACY
++ DEVCONF_USE_TEMPADDR,
++ DEVCONF_TEMP_VALID_LFT,
++ DEVCONF_TEMP_PREFERED_LFT,
++ DEVCONF_REGEN_MAX_RETRY,
++ DEVCONF_MAX_DESYNC_FACTOR,
++#endif
++ DEVCONF_MAX
++};
++
+ #ifdef __KERNEL__
+ #include <linux/in6.h> /* struct sockaddr_in6 */
+ #include <linux/icmpv6.h>
+Index: linux-2.6.0-test5/include/linux/kdev_t.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/kdev_t.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/kdev_t.h 2003-09-27 11:38:40.960301472 +0800
+@@ -1,8 +1,7 @@
+ #ifndef _LINUX_KDEV_T_H
+ #define _LINUX_KDEV_T_H
+ #ifdef __KERNEL__
+-/* These are for user-level "dev_t" */
+-#define MINORBITS 8
++#define MINORBITS 20
+ #define MINORMASK ((1U << MINORBITS) - 1)
+
+ #define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS))
+@@ -18,6 +17,77 @@
+ buffer; \
+ })
+
++/* acceptable for old filesystems */
++static inline int old_valid_dev(dev_t dev)
++{
++ return MAJOR(dev) < 256 && MINOR(dev) < 256;
++}
++
++static inline u16 old_encode_dev(dev_t dev)
++{
++ return (MAJOR(dev) << 8) | MINOR(dev);
++}
++
++static inline dev_t old_decode_dev(u16 val)
++{
++ return MKDEV((val >> 8) & 255, val & 255);
++}
++
++static inline int new_valid_dev(dev_t dev)
++{
++ return 1;
++}
++
++static inline u32 new_encode_dev(dev_t dev)
++{
++ unsigned major = MAJOR(dev);
++ unsigned minor = MINOR(dev);
++ return (minor & 0xff) | (major << 8) | ((minor & ~0xff) << 12);
++}
++
++static inline dev_t new_decode_dev(u32 dev)
++{
++ unsigned major = (dev & 0xfff00) >> 8;
++ unsigned minor = (dev & 0xff) | ((dev >> 12) & 0xfff00);
++ return MKDEV(major, minor);
++}
++
++static inline int huge_valid_dev(dev_t dev)
++{
++ return 1;
++}
++
++static inline u64 huge_encode_dev(dev_t dev)
++{
++ return new_encode_dev(dev);
++}
++
++static inline dev_t huge_decode_dev(u64 dev)
++{
++ return new_decode_dev(dev);
++}
++
++static inline int sysv_valid_dev(dev_t dev)
++{
++ return MAJOR(dev) < (1<<14) && MINOR(dev) < (1<<18);
++}
++
++static inline u32 sysv_encode_dev(dev_t dev)
++{
++ return MINOR(dev) | (MAJOR(dev) << 18);
++}
++
++static inline unsigned sysv_major(u32 dev)
++{
++ return (dev >> 18) & 0x3fff;
++}
++
++static inline unsigned sysv_minor(u32 dev)
++{
++ return dev & 0x3ffff;
++}
++
++
+ #else /* __KERNEL__ */
+
+ /*
+Index: linux-2.6.0-test5/include/linux/kernel.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/kernel.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/kernel.h 2003-09-27 11:38:40.962301168 +0800
+@@ -15,10 +15,6 @@
+ #include <asm/byteorder.h>
+ #include <asm/bug.h>
+
+-/* Optimization barrier */
+-/* The "volatile" is due to gcc bugs */
+-#define barrier() __asm__ __volatile__("": : :"memory")
+-
+ #define INT_MAX ((int)(~0U>>1))
+ #define INT_MIN (-INT_MAX - 1)
+ #define UINT_MAX (~0U)
+Index: linux-2.6.0-test5/include/linux/linux_logo.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/linux_logo.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/linux_logo.h 2003-09-27 11:38:40.964300864 +0800
+@@ -16,13 +16,11 @@
+
+ #include <linux/init.h>
+
+-
+ #define LINUX_LOGO_MONO 1 /* monochrome black/white */
+ #define LINUX_LOGO_VGA16 2 /* 16 colors VGA text palette */
+ #define LINUX_LOGO_CLUT224 3 /* 224 colors */
+ #define LINUX_LOGO_GRAY256 4 /* 256 levels grayscale */
+
+-
+ struct linux_logo {
+ int type; /* one of LINUX_LOGO_* */
+ unsigned int width;
+@@ -32,6 +30,6 @@
+ const unsigned char *data;
+ };
+
+-extern const struct linux_logo *fb_find_logo(int depth);
++extern const struct linux_logo *find_logo(int depth);
+
+ #endif /* _LINUX_LINUX_LOGO_H */
+Index: linux-2.6.0-test5/include/linux/list.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/list.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/list.h 2003-09-27 11:38:40.969300104 +0800
+@@ -142,8 +142,11 @@
+ * Note: list_empty on entry does not return true after this, the entry is
+ * in an undefined state.
+ */
++#include <linux/kernel.h> /* BUG_ON */
+ static inline void list_del(struct list_head *entry)
+ {
++ BUG_ON(entry->prev->next != entry);
++ BUG_ON(entry->next->prev != entry);
+ __list_del(entry->prev, entry->next);
+ entry->next = LIST_POISON1;
+ entry->prev = LIST_POISON2;
+Index: linux-2.6.0-test5/include/linux/llc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/llc.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/llc.h 2003-09-27 11:38:40.971299800 +0800
+@@ -79,13 +79,5 @@
+ #define LLC_SAP_DYN_TRIES 4
+
+ #define llc_ui_skb_cb(__skb) ((struct sockaddr_llc *)&((__skb)->cb[0]))
+-
+-#ifdef CONFIG_LLC_UI
+-extern int llc_ui_init(void);
+-extern void llc_ui_exit(void);
+-#else
+-#define llc_ui_init()
+-#define llc_ui_exit()
+-#endif
+ #endif /* __KERNEL__ */
+ #endif /* __LINUX_LLC_H */
+Index: linux-2.6.0-test5/include/linux/lockmeter.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/lockmeter.h 2003-09-27 11:38:18.485718128 +0800
++++ linux-2.6.0-test5/include/linux/lockmeter.h 2003-09-27 11:38:40.972299648 +0800
+@@ -0,0 +1,320 @@
++/*
++ * Copyright (C) 1999-2002 Silicon Graphics, Inc.
++ *
++ * Written by John Hawkes (hawkes@sgi.com)
++ * Based on klstat.h by Jack Steiner (steiner@sgi.com)
++ *
++ * Modified by Ray Bryant (raybry@us.ibm.com) Feb-Apr 2000
++ * Changes Copyright (C) 2000 IBM, Inc.
++ * Added save of index in spinlock_t to improve efficiency
++ * of "hold" time reporting for spinlocks
++ * Added support for hold time statistics for read and write
++ * locks.
++ * Moved machine dependent code to include/asm/lockmeter.h.
++ *
++ */
++
++#ifndef _LINUX_LOCKMETER_H
++#define _LINUX_LOCKMETER_H
++
++
++/*---------------------------------------------------
++ * architecture-independent lockmeter.h
++ *-------------------------------------------------*/
++
++/*
++ * raybry -- version 2: added efficient hold time statistics
++ * requires lstat recompile, so flagged as new version
++ * raybry -- version 3: added global reader lock data
++ * hawkes -- version 4: removed some unnecessary fields to simplify mips64 port
++ */
++#define LSTAT_VERSION 5
++
++int lstat_update(void*, void*, int);
++int lstat_update_time(void*, void*, int, uint32_t);
++
++/*
++ * Currently, the mips64 and sparc64 kernels talk to a 32-bit lockstat, so we
++ * need to force compatibility in the inter-communication data structure.
++ */
++
++#if defined(CONFIG_MIPS32_COMPAT)
++#define TIME_T uint32_t
++#elif defined(CONFIG_SPARC) || defined(CONFIG_SPARC64)
++#define TIME_T uint64_t
++#else
++#define TIME_T time_t
++#endif
++
++#if defined(__KERNEL__) || (!defined(CONFIG_MIPS32_COMPAT) && !defined(CONFIG_SPARC) && !defined(CONFIG_SPARC64)) || (_MIPS_SZLONG==32)
++#define POINTER void *
++#else
++#define POINTER int64_t
++#endif
++
++/*
++ * Values for the "action" parameter passed to lstat_update.
++ * ZZZ - do we want a try-success status here???
++ */
++#define LSTAT_ACT_NO_WAIT 0
++#define LSTAT_ACT_SPIN 1
++#define LSTAT_ACT_REJECT 2
++#define LSTAT_ACT_WW_SPIN 3
++#define LSTAT_ACT_SLEPT 4 /* UNUSED */
++
++#define LSTAT_ACT_MAX_VALUES 4 /* NOTE: Increase to 5 if use ACT_SLEPT */
++
++/*
++ * Special values for the low 2 bits of an RA passed to
++ * lstat_update.
++ */
++/* we use these values to figure out what kind of lock data */
++/* is stored in the statistics table entry at index ....... */
++#define LSTAT_RA_SPIN 0 /* spin lock data */
++#define LSTAT_RA_READ 1 /* read lock statistics */
++#define LSTAT_RA_SEMA 2 /* RESERVED */
++#define LSTAT_RA_WRITE 3 /* write lock statistics*/
++
++#define LSTAT_RA(n) \
++ ((void*)( ((unsigned long)__builtin_return_address(0) & ~3) | n) )
++
++/*
++ * Constants used for lock addresses in the lstat_directory
++ * to indicate special values of the lock address.
++ */
++#define LSTAT_MULTI_LOCK_ADDRESS NULL
++
++/*
++ * Maximum size of the lockstats tables. Increase this value
++ * if its not big enough. (Nothing bad happens if its not
++ * big enough although some locks will not be monitored.)
++ * We record overflows of this quantity in lstat_control.dir_overflows
++ *
++ * Note: The max value here must fit into the field set
++ * and obtained by the macro's PUT_INDEX() and GET_INDEX().
++ * This value depends on how many bits are available in the
++ * lock word in the particular machine implementation we are on.
++ */
++#define LSTAT_MAX_STAT_INDEX 2000
++
++/*
++ * Size and mask for the hash table into the directory.
++ */
++#define LSTAT_HASH_TABLE_SIZE 4096 /* must be 2**N */
++#define LSTAT_HASH_TABLE_MASK (LSTAT_HASH_TABLE_SIZE-1)
++
++#define DIRHASH(ra) ((unsigned long)(ra)>>2 & LSTAT_HASH_TABLE_MASK)
++
++/*
++ * This defines an entry in the lockstat directory. It contains
++ * information about a lock being monitored.
++ * A directory entry only contains the lock identification -
++ * counts on usage of the lock are kept elsewhere in a per-cpu
++ * data structure to minimize cache line pinging.
++ */
++typedef struct {
++ POINTER caller_ra; /* RA of code that set lock */
++ POINTER lock_ptr; /* lock address */
++ ushort next_stat_index; /* Used to link multiple locks that have the same hash table value */
++} lstat_directory_entry_t;
++
++/*
++ * A multi-dimensioned array used to contain counts for lock accesses.
++ * The array is 3-dimensional:
++ * - CPU number. Keep from thrashing cache lines between CPUs
++ * - Directory entry index. Identifies the lock
++ * - Action. Indicates what kind of contention occurred on an
++ * access to the lock.
++ *
++ * The index of an entry in the directory is the same as the 2nd index
++ * of the entry in the counts array.
++ */
++/*
++ * This table contains data for spin_locks, write locks, and read locks
++ * Not all data is used for all cases. In particular, the hold time
++ * information is not stored here for read locks since that is a global
++ * (e. g. cannot be separated out by return address) quantity.
++ * See the lstat_read_lock_counts_t structure for the global read lock
++ * hold time.
++ */
++typedef struct {
++ uint64_t cum_wait_ticks; /* sum of wait times */
++ /* for write locks, sum of time a */
++ /* writer is waiting for a reader */
++ int64_t cum_hold_ticks; /* cumulative sum of holds */
++ /* not used for read mode locks */
++ /* must be signed. ............... */
++ uint32_t max_wait_ticks; /* max waiting time */
++ uint32_t max_hold_ticks; /* max holding time */
++ uint64_t cum_wait_ww_ticks; /* sum times writer waits on writer*/
++ uint32_t max_wait_ww_ticks; /* max wait time writer vs writer */
++ /* prev 2 only used for write locks*/
++ uint32_t acquire_time; /* time lock acquired this CPU */
++ uint32_t count[LSTAT_ACT_MAX_VALUES];
++} lstat_lock_counts_t;
++
++typedef lstat_lock_counts_t lstat_cpu_counts_t[LSTAT_MAX_STAT_INDEX];
++
++/*
++ * User request to:
++ * - turn statistic collection on/off, or to reset
++ */
++#define LSTAT_OFF 0
++#define LSTAT_ON 1
++#define LSTAT_RESET 2
++#define LSTAT_RELEASE 3
++
++#define LSTAT_MAX_READ_LOCK_INDEX 1000
++typedef struct {
++ POINTER lock_ptr; /* address of lock for output stats */
++ uint32_t read_lock_count;
++ int64_t cum_hold_ticks; /* sum of read lock hold times over */
++ /* all callers. ....................*/
++ uint32_t write_index; /* last write lock hash table index */
++ uint32_t busy_periods; /* count of busy periods ended this */
++ uint64_t start_busy; /* time this busy period started. ..*/
++ uint64_t busy_ticks; /* sum of busy periods this lock. ..*/
++ uint64_t max_busy; /* longest busy period for this lock*/
++ uint32_t max_readers; /* maximum number of readers ...... */
++#ifdef USER_MODE_TESTING
++ rwlock_t entry_lock; /* lock for this read lock entry... */
++ /* avoid having more than one rdr at*/
++ /* needed for user space testing... */
++ /* not needed for kernel 'cause it */
++ /* is non-preemptive. ............. */
++#endif
++} lstat_read_lock_counts_t;
++typedef lstat_read_lock_counts_t lstat_read_lock_cpu_counts_t[LSTAT_MAX_READ_LOCK_INDEX];
++
++#if defined(__KERNEL__) || defined(USER_MODE_TESTING)
++
++#ifndef USER_MODE_TESTING
++#include <asm/lockmeter.h>
++#else
++#include "asm_newlockmeter.h"
++#endif
++
++/*
++ * Size and mask for the hash table into the directory.
++ */
++#define LSTAT_HASH_TABLE_SIZE 4096 /* must be 2**N */
++#define LSTAT_HASH_TABLE_MASK (LSTAT_HASH_TABLE_SIZE-1)
++
++#define DIRHASH(ra) ((unsigned long)(ra)>>2 & LSTAT_HASH_TABLE_MASK)
++
++/*
++ * This version eliminates the per processor lock stack. What we do is to
++ * store the index of the lock hash structure in unused bits in the lock
++ * itself. Then on unlock we can find the statistics record without doing
++ * any additional hash or lock stack lookup. This works for spin_locks.
++ * Hold time reporting is now basically as cheap as wait time reporting
++ * so we ignore the difference between LSTAT_ON_HOLD and LSTAT_ON_WAIT
++ * as in version 1.1.* of lockmeter.
++ *
++ * For rw_locks, we store the index of a global reader stats structure in
++ * the lock and the writer index is stored in the latter structure.
++ * For read mode locks we hash at the time of the lock to find an entry
++ * in the directory for reader wait time and the like.
++ * At unlock time for read mode locks, we update just the global structure
++ * so we don't need to know the reader directory index value at unlock time.
++ *
++ */
++
++/*
++ * Protocol to change lstat_control.state
++ * This is complicated because we don't want the cum_hold_time for
++ * a rw_lock to be decremented in _read_lock_ without making sure it
++ * is incremented in _read_lock_ and vice versa. So here is the
++ * way we change the state of lstat_control.state:
++ * I. To Turn Statistics On
++ * After allocating storage, set lstat_control.state non-zero.
++ * This works because we don't start updating statistics for in use
++ * locks until the reader lock count goes to zero.
++ * II. To Turn Statistics Off:
++ * (0) Disable interrupts on this CPU
++ * (1) Seize the lstat_control.directory_lock
++ * (2) Obtain the current value of lstat_control.next_free_read_lock_index
++ * (3) Store a zero in lstat_control.state.
++ * (4) Release the lstat_control.directory_lock
++ * (5) For each lock in the read lock list up to the saved value
++ * (well, -1) of the next_free_read_lock_index, do the following:
++ * (a) Check validity of the stored lock address
++ * by making sure that the word at the saved addr
++ * has an index that matches this entry. If not
++ * valid, then skip this entry.
++ * (b) If there is a write lock already set on this lock,
++ * skip to (d) below.
++ * (c) Set a non-metered write lock on the lock
++ * (d) set the cached INDEX in the lock to zero
++ * (e) Release the non-metered write lock.
++ * (6) Re-enable interrupts
++ *
++ * These rules ensure that a read lock will not have its statistics
++ * partially updated even though the global lock recording state has
++ * changed. See put_lockmeter_info() for implementation.
++ *
++ * The reason for (b) is that there may be write locks set on the
++ * syscall path to put_lockmeter_info() from user space. If we do
++ * not do this check, then we can deadlock. A similar problem would
++ * occur if the lock was read locked by the current CPU. At the
++ * moment this does not appear to happen.
++ */
++
++/*
++ * Main control structure for lockstat. Used to turn statistics on/off
++ * and to maintain directory info.
++ */
++typedef struct {
++ int state;
++ spinlock_t control_lock; /* used to serialize turning statistics on/off */
++ spinlock_t directory_lock; /* for serialize adding entries to directory */
++ volatile int next_free_dir_index;/* next free entry in the directory */
++ /* FIXME not all of these fields are used / needed .............. */
++ /* the following fields represent data since */
++ /* first "lstat on" or most recent "lstat reset" */
++ TIME_T first_started_time; /* time when measurement first enabled */
++ TIME_T started_time; /* time when measurement last started */
++ TIME_T ending_time; /* time when measurement last disabled */
++ uint64_t started_cycles64; /* cycles when measurement last started */
++ uint64_t ending_cycles64; /* cycles when measurement last disabled */
++ uint64_t enabled_cycles64; /* total cycles with measurement enabled */
++ int intervals; /* number of measurement intervals recorded */
++ /* i. e. number of times did lstat on;lstat off */
++ lstat_directory_entry_t *dir; /* directory */
++ int dir_overflow; /* count of times ran out of space in directory */
++ int rwlock_overflow; /* count of times we couldn't allocate a rw block*/
++ ushort *hashtab; /* hash table for quick dir scans */
++ lstat_cpu_counts_t *counts[NR_CPUS]; /* Array of pointers to per-cpu stats */
++ int next_free_read_lock_index; /* next rwlock reader (global) stats block */
++ lstat_read_lock_cpu_counts_t *read_lock_counts[NR_CPUS]; /* per cpu read lock stats */
++} lstat_control_t;
++
++#endif /* defined(__KERNEL__) || defined(USER_MODE_TESTING) */
++
++typedef struct {
++ short lstat_version; /* version of the data */
++ short state; /* the current state is returned */
++ int maxcpus; /* Number of cpus present */
++ int next_free_dir_index; /* index of the next free directory entry */
++ TIME_T first_started_time; /* when measurement enabled for first time */
++ TIME_T started_time; /* time in secs since 1969 when stats last turned on */
++ TIME_T ending_time; /* time in secs since 1969 when stats last turned off */
++ uint32_t cycleval; /* cycles per second */
++#ifdef notyet
++ void *kernel_magic_addr; /* address of kernel_magic */
++ void *kernel_end_addr; /* contents of kernel magic (points to "end") */
++#endif
++ int next_free_read_lock_index; /* index of next (global) read lock stats struct */
++ uint64_t started_cycles64; /* cycles when measurement last started */
++ uint64_t ending_cycles64; /* cycles when stats last turned off */
++ uint64_t enabled_cycles64; /* total cycles with measurement enabled */
++ int intervals; /* number of measurement intervals recorded */
++ /* i.e. number of times we did lstat on;lstat off*/
++ int dir_overflow; /* number of times we wanted more space in directory */
++ int rwlock_overflow; /* # of times we wanted more space in read_locks_count */
++ struct new_utsname uts; /* info about machine where stats are measured */
++ /* -T option of lockstat allows data to be */
++ /* moved to another machine. ................. */
++} lstat_user_request_t;
++
++#endif /* _LINUX_LOCKMETER_H */
+Index: linux-2.6.0-test5/include/linux/major.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/major.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/major.h 2003-09-27 11:38:40.974299344 +0800
+@@ -40,7 +40,7 @@
+ #define MFM_ACORN_MAJOR 21 /* ARM Linux /dev/mfm */
+ #define SCSI_GENERIC_MAJOR 21
+ #define IDE1_MAJOR 22
+-#define DIGICU_MAJOR 22
++#define DIGI_DGAP_MAJOR 22
+ #define DIGI_MAJOR 23
+ #define MITSUMI_CDROM_MAJOR 23
+ #define CDU535_CDROM_MAJOR 24
+@@ -160,34 +160,4 @@
+ #define IBM_TTY3270_MAJOR 227
+ #define IBM_FS3270_MAJOR 228
+
+-/*
+- * Tests for SCSI devices.
+- */
+-
+-#define SCSI_DISK_MAJOR(M) ((M) == SCSI_DISK0_MAJOR || \
+- ((M) >= SCSI_DISK1_MAJOR && (M) <= SCSI_DISK7_MAJOR) || \
+- ((M) >= SCSI_DISK8_MAJOR && (M) <= SCSI_DISK15_MAJOR))
+-
+-#define SCSI_BLK_MAJOR(M) \
+- (SCSI_DISK_MAJOR(M) \
+- || (M) == SCSI_CDROM_MAJOR)
+-
+-static __inline__ int scsi_blk_major(int m) {
+- return SCSI_BLK_MAJOR(m);
+-}
+-
+-/*
+- * Tests for IDE devices
+- */
+-#define IDE_DISK_MAJOR(M) ((M) == IDE0_MAJOR || (M) == IDE1_MAJOR || \
+- (M) == IDE2_MAJOR || (M) == IDE3_MAJOR || \
+- (M) == IDE4_MAJOR || (M) == IDE5_MAJOR || \
+- (M) == IDE6_MAJOR || (M) == IDE7_MAJOR || \
+- (M) == IDE8_MAJOR || (M) == IDE9_MAJOR)
+-
+-static __inline__ int ide_blk_major(int m)
+-{
+- return IDE_DISK_MAJOR(m);
+-}
+-
+ #endif
+Index: linux-2.6.0-test5/include/linux/miscdevice.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/miscdevice.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/miscdevice.h 2003-09-27 11:38:40.976299040 +0800
+@@ -36,14 +36,12 @@
+
+ #define TUN_MINOR 200
+
+-extern int misc_init(void);
+-
+ struct miscdevice
+ {
+ int minor;
+ const char *name;
+ struct file_operations *fops;
+- struct miscdevice * next, * prev;
++ struct list_head list;
+ char devfs_name[64];
+ };
+
+Index: linux-2.6.0-test5/include/linux/mm.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/mm.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/mm.h 2003-09-27 11:38:40.982298128 +0800
+@@ -323,7 +323,6 @@
+ * The zone field is never updated after free_area_init_core()
+ * sets it, so none of the operations on it need to be atomic.
+ */
+-#define NODE_SHIFT 4
+ #define ZONE_SHIFT (BITS_PER_LONG - 8)
+
+ struct zone;
+@@ -432,6 +431,7 @@
+ extern pte_t *FASTCALL(pte_alloc_kernel(struct mm_struct *mm, pmd_t *pmd, unsigned long address));
+ extern pte_t *FASTCALL(pte_alloc_map(struct mm_struct *mm, pmd_t *pmd, unsigned long address));
+ extern int install_page(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, struct page *page, pgprot_t prot);
++extern int install_file_pte(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, unsigned long pgoff, pgprot_t prot);
+ extern int handle_mm_fault(struct mm_struct *mm,struct vm_area_struct *vma, unsigned long address, int write_access);
+ extern int make_pages_present(unsigned long addr, unsigned long end);
+ extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
+Index: linux-2.6.0-test5/include/linux/mmzone.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/mmzone.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/mmzone.h 2003-09-27 11:38:40.986297520 +0800
+@@ -10,13 +10,8 @@
+ #include <linux/wait.h>
+ #include <linux/cache.h>
+ #include <linux/threads.h>
++#include <linux/numa.h>
+ #include <asm/atomic.h>
+-#ifdef CONFIG_DISCONTIGMEM
+-#include <asm/numnodes.h>
+-#endif
+-#ifndef MAX_NUMNODES
+-#define MAX_NUMNODES 1
+-#endif
+
+ /* Free memory management - zoned buddy allocator. */
+ #ifndef CONFIG_FORCE_MAX_ZONEORDER
+@@ -303,19 +298,34 @@
+ #define numa_node_id() (cpu_to_node(smp_processor_id()))
+
+ #ifndef CONFIG_DISCONTIGMEM
++
+ extern struct pglist_data contig_page_data;
+ #define NODE_DATA(nid) (&contig_page_data)
+ #define NODE_MEM_MAP(nid) mem_map
+-#define MAX_NR_NODES 1
++#define MAX_NODES_SHIFT 0
++
+ #else /* CONFIG_DISCONTIGMEM */
+
+ #include <asm/mmzone.h>
+
+-/* page->zone is currently 8 bits ... */
+-#define MAX_NR_NODES (255 / MAX_NR_ZONES)
++#if BITS_PER_LONG == 32
++/*
++ * with 32 bit flags field, page->zone is currently 8 bits.
++ * there are 3 zones (2 bits) and this leaves 8-2=6 bits for nodes.
++ */
++#define MAX_NODES_SHIFT 6
++#elif BITS_PER_LONG == 64
++/*
++ * with 64 bit flags field, there's plenty of room.
++ */
++#define MAX_NODES_SHIFT 10
++#endif
+
+ #endif /* !CONFIG_DISCONTIGMEM */
+
++#if NODES_SHIFT > MAX_NODES_SHIFT
++#error NODES_SHIFT > MAX_NODES_SHIFT
++#endif
+
+ extern DECLARE_BITMAP(node_online_map, MAX_NUMNODES);
+ extern DECLARE_BITMAP(memblk_online_map, MAX_NR_MEMBLKS);
+Index: linux-2.6.0-test5/include/linux/mount.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/mount.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/mount.h 2003-09-27 11:38:40.988297216 +0800
+@@ -14,9 +14,10 @@
+
+ #include <linux/list.h>
+
+-#define MNT_NOSUID 1
+-#define MNT_NODEV 2
+-#define MNT_NOEXEC 4
++#define MNT_RDONLY 1
++#define MNT_NOSUID 2
++#define MNT_NODEV 4
++#define MNT_NOEXEC 8
+
+ struct vfsmount
+ {
+@@ -33,6 +34,8 @@
+ struct list_head mnt_list;
+ };
+
++#define MNT_IS_RDONLY(m) ((m)->mnt_flags & MNT_RDONLY)
++
+ static inline struct vfsmount *mntget(struct vfsmount *mnt)
+ {
+ if (mnt)
+Index: linux-2.6.0-test5/include/linux/netdevice.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/netdevice.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/netdevice.h 2003-09-27 11:38:40.995296152 +0800
+@@ -28,8 +28,6 @@
+ #include <linux/if.h>
+ #include <linux/if_ether.h>
+ #include <linux/if_packet.h>
+-#include <linux/device.h>
+-#include <linux/percpu.h>
+
+ #include <asm/atomic.h>
+ #include <asm/cache.h>
+@@ -37,6 +35,8 @@
+
+ #ifdef __KERNEL__
+ #include <linux/config.h>
++#include <linux/device.h>
++#include <linux/percpu.h>
+
+ struct divert_blk;
+ struct vlan_group;
+@@ -456,6 +456,13 @@
+ /* bridge stuff */
+ struct net_bridge_port *br_port;
+
++#ifdef CONFIG_KGDB
++ int kgdb_is_trapped;
++#endif
++#ifdef CONFIG_NET_POLL_CONTROLLER
++ void (*poll_controller)(struct net_device *);
++#endif
++
+ #ifdef CONFIG_NET_FASTROUTE
+ #define NETDEV_FASTROUTE_HMASK 0xF
+ /* Semi-private data. Keep it at the end of device struct. */
+@@ -502,7 +509,11 @@
+ extern void dev_add_pack(struct packet_type *pt);
+ extern void dev_remove_pack(struct packet_type *pt);
+ extern void __dev_remove_pack(struct packet_type *pt);
+-extern int dev_get(const char *name);
++extern int __dev_get(const char *name);
++static inline int __deprecated dev_get(const char *name)
++{
++ return __dev_get(name);
++}
+ extern struct net_device *dev_get_by_flags(unsigned short flags,
+ unsigned short mask);
+ extern struct net_device *__dev_get_by_flags(unsigned short flags,
+@@ -525,6 +536,11 @@
+ extern struct net_device *dev_get_by_index(int ifindex);
+ extern struct net_device *__dev_get_by_index(int ifindex);
+ extern int dev_restart(struct net_device *dev);
++#ifdef CONFIG_KGDB
++extern int kgdb_eth_is_trapped(void);
++extern int kgdb_net_interrupt(struct sk_buff *skb);
++extern void kgdb_send_arp_request(void);
++#endif
+
+ typedef int gifconf_func_t(struct net_device * dev, char * bufptr, int len);
+ extern int register_gifconf(unsigned int family, gifconf_func_t * gifconf);
+@@ -583,12 +599,22 @@
+
+ static inline void netif_wake_queue(struct net_device *dev)
+ {
++#ifdef CONFIG_KGDB
++ if (kgdb_eth_is_trapped()) {
++ return;
++ }
++#endif
+ if (test_and_clear_bit(__LINK_STATE_XOFF, &dev->state))
+ __netif_schedule(dev);
+ }
+
+ static inline void netif_stop_queue(struct net_device *dev)
+ {
++#ifdef CONFIG_KGDB
++ if (kgdb_eth_is_trapped()) {
++ return;
++ }
++#endif
+ set_bit(__LINK_STATE_XOFF, &dev->state);
+ }
+
+Index: linux-2.6.0-test5/include/linux/netfilter_ipv4/ipt_physdev.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/netfilter_ipv4/ipt_physdev.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/netfilter_ipv4/ipt_physdev.h 2003-09-27 11:38:40.996296000 +0800
+@@ -13,12 +13,12 @@
+ #define IPT_PHYSDEV_OP_MASK (0x20 - 1)
+
+ struct ipt_physdev_info {
+- u_int8_t invert;
+- u_int8_t bitmask;
+ char physindev[IFNAMSIZ];
+ char in_mask[IFNAMSIZ];
+ char physoutdev[IFNAMSIZ];
+ char out_mask[IFNAMSIZ];
++ u_int8_t invert;
++ u_int8_t bitmask;
+ };
+
+ #endif /*_IPT_PHYSDEV_H*/
+Index: linux-2.6.0-test5/include/linux/nfsd/export.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/nfsd/export.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/nfsd/export.h 2003-09-27 11:38:40.998295696 +0800
+@@ -65,7 +65,7 @@
+
+ struct auth_domain * ek_client;
+ int ek_fsidtype;
+- u32 ek_fsid[2];
++ u32 ek_fsid[3];
+
+ struct svc_export * ek_export;
+ };
+Index: linux-2.6.0-test5/include/linux/nfsd/nfsd.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/nfsd/nfsd.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/nfsd/nfsd.h 2003-09-27 11:38:41.001295240 +0800
+@@ -15,6 +15,7 @@
+ #include <linux/unistd.h>
+ #include <linux/dirent.h>
+ #include <linux/fs.h>
++#include <linux/mount.h>
+
+ #include <linux/nfsd/debug.h>
+ #include <linux/nfsd/nfsfh.h>
+@@ -207,6 +208,17 @@
+ */
+ extern struct timeval nfssvc_boot;
+
++static inline int is_fsid(struct svc_fh *fh, struct knfsd_fh *reffh)
++{
++ if (fh->fh_export->ex_flags & NFSEXP_FSID) {
++ struct vfsmount *mnt = fh->fh_export->ex_mnt;
++ if (!old_valid_dev(mnt->mnt_sb->s_dev) ||
++ (reffh->fh_version == 1 && reffh->fh_fsid_type == 1))
++ return 1;
++ }
++ return 0;
++}
++
+
+ #ifdef CONFIG_NFSD_V4
+
+Index: linux-2.6.0-test5/include/linux/nfsd/nfsfh.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/nfsd/nfsfh.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/nfsd/nfsfh.h 2003-09-27 11:38:41.005294632 +0800
+@@ -117,26 +117,6 @@
+
+ #ifdef __KERNEL__
+
+-/*
+- * Conversion macros for the filehandle fields.
+- *
+- * Keep the device numbers in "backwards compatible
+- * format", ie the low 16 bits contain the low 8 bits
+- * of the 20-bit minor and the 12-bit major number.
+- *
+- * The high 16 bits contain the rest (4 bits major
+- * and 12 bits minor),
+- */
+-
+-static inline dev_t u32_to_dev_t(__u32 udev)
+-{
+- unsigned int minor, major;
+-
+- minor = (udev & 0xff) | ((udev >> 8) & 0xfff00);
+- major = ((udev >> 8) & 0xff) | ((udev >> 20) & 0xf00);
+- return MKDEV(major, minor);
+-}
+-
+ static inline __u32 ino_t_to_u32(ino_t ino)
+ {
+ return (__u32) ino;
+@@ -196,6 +176,12 @@
+ fsidv[0] = fsid;
+ }
+
++static inline void mk_fsid_v2(u32 *fsidv, dev_t dev, ino_t ino)
++{
++ fsidv[0] = htonl(MAJOR(dev));
++ fsidv[1] = htonl(MINOR(dev));
++ fsidv[2] = ino_t_to_u32(ino);
++}
+
+ /*
+ * Shorthand for dprintk()'s
+Index: linux-2.6.0-test5/include/linux/nfs_fs.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/nfs_fs.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/nfs_fs.h 2003-09-27 11:38:41.009294024 +0800
+@@ -271,7 +271,7 @@
+ /*
+ * linux/fs/nfs/direct.c
+ */
+-extern int nfs_direct_IO(int, struct file *, const struct iovec *, loff_t,
++extern int nfs_direct_IO(int, struct kiocb *, const struct iovec *, loff_t,
+ unsigned long);
+
+ /*
+Index: linux-2.6.0-test5/include/linux/nfs_page.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/nfs_page.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/nfs_page.h 2003-09-27 11:38:41.011293720 +0800
+@@ -46,7 +46,6 @@
+ unsigned int, unsigned int);
+ extern void nfs_clear_request(struct nfs_page *req);
+ extern void nfs_release_request(struct nfs_page *req);
+-extern void nfs_release_list(struct list_head *list);
+
+
+ extern void nfs_list_add_request(struct nfs_page *, struct list_head *);
+@@ -56,7 +55,6 @@
+ extern int nfs_coalesce_requests(struct list_head *, struct list_head *,
+ unsigned int);
+ extern int nfs_wait_on_request(struct nfs_page *);
+-extern int nfs_wait_for_reads(struct list_head *);
+
+ extern spinlock_t nfs_wreq_lock;
+
+Index: linux-2.6.0-test5/include/linux/nfs_xdr.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/nfs_xdr.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/nfs_xdr.h 2003-09-27 11:38:41.016292960 +0800
+@@ -591,6 +591,7 @@
+ #endif /* CONFIG_NFS_V4 */
+
+ struct nfs_read_data {
++ int flags;
+ struct rpc_task task;
+ struct inode *inode;
+ struct rpc_cred *cred;
+@@ -605,6 +606,7 @@
+ };
+
+ struct nfs_write_data {
++ int flags;
+ struct rpc_task task;
+ struct inode *inode;
+ struct rpc_cred *cred;
+@@ -634,16 +636,9 @@
+ struct nfs_fh *, struct nfs_fattr *);
+ int (*access) (struct inode *, struct rpc_cred *, int);
+ int (*readlink)(struct inode *, struct page *);
+- int (*read) (struct inode *, struct rpc_cred *,
+- struct nfs_fattr *,
+- int, unsigned int, unsigned int,
+- struct page *, int *eofp);
+- int (*write) (struct inode *, struct rpc_cred *,
+- struct nfs_fattr *,
+- int, unsigned int, unsigned int,
+- struct page *, struct nfs_writeverf *verfp);
+- int (*commit) (struct inode *, struct nfs_fattr *,
+- unsigned long, unsigned int);
++ int (*read) (struct nfs_read_data *);
++ int (*write) (struct nfs_write_data *);
++ int (*commit) (struct nfs_write_data *);
+ int (*create) (struct inode *, struct qstr *, struct iattr *,
+ int, struct nfs_fh *, struct nfs_fattr *);
+ int (*remove) (struct inode *, struct qstr *);
+Index: linux-2.6.0-test5/include/linux/nls.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/nls.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/nls.h 2003-09-27 11:38:41.017292808 +0800
+@@ -8,6 +8,7 @@
+
+ struct nls_table {
+ char *charset;
++ char *alias;
+ int (*uni2char) (wchar_t uni, unsigned char *out, int boundlen);
+ int (*char2uni) (const unsigned char *rawstring, int boundlen,
+ wchar_t *uni);
+@@ -32,5 +33,7 @@
+ extern int utf8_wctomb(__u8 *, wchar_t, int);
+ extern int utf8_wcstombs(__u8 *, const wchar_t *, int);
+
++#define MODULE_ALIAS_NLS(name) MODULE_ALIAS("nls_" __stringify(name))
++
+ #endif /* _LINUX_NLS_H */
+
+Index: linux-2.6.0-test5/include/linux/numa.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/numa.h 2003-09-27 11:38:18.486717976 +0800
++++ linux-2.6.0-test5/include/linux/numa.h 2003-09-27 11:38:41.018292656 +0800
+@@ -0,0 +1,16 @@
++#ifndef _LINUX_NUMA_H
++#define _LINUX_NUMA_H
++
++#include <linux/config.h>
++
++#ifdef CONFIG_DISCONTIGMEM
++#include <asm/numnodes.h>
++#endif
++
++#ifndef NODES_SHIFT
++#define NODES_SHIFT 0
++#endif
++
++#define MAX_NUMNODES (1 << NODES_SHIFT)
++
++#endif /* _LINUX_NUMA_H */
+Index: linux-2.6.0-test5/include/linux/pagemap.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/pagemap.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/pagemap.h 2003-09-27 11:38:41.020292352 +0800
+@@ -71,7 +71,7 @@
+ extern struct page * find_or_create_page(struct address_space *mapping,
+ unsigned long index, unsigned int gfp_mask);
+ extern unsigned int find_get_pages(struct address_space *mapping,
+- pgoff_t start, unsigned int nr_pages,
++ pgoff_t *next, unsigned int nr_pages,
+ struct page **pages);
+
+ /*
+@@ -153,17 +153,27 @@
+ extern void FASTCALL(__lock_page(struct page *page));
+ extern void FASTCALL(unlock_page(struct page *page));
+
+-static inline void lock_page(struct page *page)
++
++extern int FASTCALL(__lock_page_wq(struct page *page, wait_queue_t *wait));
++static inline int lock_page_wq(struct page *page, wait_queue_t *wait)
+ {
+ if (TestSetPageLocked(page))
+- __lock_page(page);
++ return __lock_page_wq(page, wait);
++ else
++ return 0;
++}
++
++static inline void lock_page(struct page *page)
++{
++ lock_page_wq(page, NULL);
+ }
+
+ /*
+ * This is exported only for wait_on_page_locked/wait_on_page_writeback.
+ * Never use this directly!
+ */
+-extern void FASTCALL(wait_on_page_bit(struct page *page, int bit_nr));
++extern int FASTCALL(wait_on_page_bit_wq(struct page *page, int bit_nr,
++ wait_queue_t *wait));
+
+ /*
+ * Wait for a page to be unlocked.
+@@ -172,19 +182,33 @@
+ * ie with increased "page->count" so that the page won't
+ * go away during the wait..
+ */
+-static inline void wait_on_page_locked(struct page *page)
++static inline int wait_on_page_locked_wq(struct page *page, wait_queue_t *wait)
+ {
+ if (PageLocked(page))
+- wait_on_page_bit(page, PG_locked);
++ return wait_on_page_bit_wq(page, PG_locked, wait);
++ return 0;
++}
++
++static inline void wait_on_page_locked(struct page *page)
++{
++ wait_on_page_locked_wq(page, NULL);
+ }
+
+ /*
+ * Wait for a page to complete writeback
+ */
+-static inline void wait_on_page_writeback(struct page *page)
++
++static inline int wait_on_page_writeback_wq(struct page *page,
++ wait_queue_t *wait)
+ {
+ if (PageWriteback(page))
+- wait_on_page_bit(page, PG_writeback);
++ return wait_on_page_bit_wq(page, PG_writeback, wait);
++ return 0;
++}
++
++static inline void wait_on_page_writeback(struct page *page)
++{
++ wait_on_page_writeback_wq(page, NULL);
+ }
+
+ extern void end_page_writeback(struct page *page);
+Index: linux-2.6.0-test5/include/linux/pagevec.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/pagevec.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/pagevec.h 2003-09-27 11:38:41.022292048 +0800
+@@ -23,7 +23,7 @@
+ void __pagevec_lru_add_active(struct pagevec *pvec);
+ void pagevec_strip(struct pagevec *pvec);
+ unsigned int pagevec_lookup(struct pagevec *pvec, struct address_space *mapping,
+- pgoff_t start, unsigned int nr_pages);
++ pgoff_t *next, unsigned int nr_pages);
+
+ static inline void pagevec_init(struct pagevec *pvec, int cold)
+ {
+Index: linux-2.6.0-test5/include/linux/parser.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/parser.h 2003-09-27 11:38:18.486717976 +0800
++++ linux-2.6.0-test5/include/linux/parser.h 2003-09-27 11:38:41.022292048 +0800
+@@ -0,0 +1,21 @@
++struct match_token {
++ int token;
++ char *pattern;
++};
++
++typedef struct match_token match_table_t[];
++
++enum {MAX_OPT_ARGS = 3};
++
++typedef struct {
++ char *from;
++ char *to;
++} substring_t;
++
++int match_token(char *s, match_table_t table, substring_t args[]);
++
++int match_int(substring_t *, int *result);
++int match_octal(substring_t *, int *result);
++int match_hex(substring_t *, int *result);
++void match_strcpy(char *, substring_t *);
++char *match_strdup(substring_t *);
+Index: linux-2.6.0-test5/include/linux/pci_ids.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/pci_ids.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/pci_ids.h 2003-09-27 11:38:41.043288856 +0800
+@@ -519,6 +519,7 @@
+ #define PCI_DEVICE_ID_CT_65550 0x00e0
+ #define PCI_DEVICE_ID_CT_65554 0x00e4
+ #define PCI_DEVICE_ID_CT_65555 0x00e5
++#define PCI_DEVICE_ID_CT_69000 0x00c0
+
+ #define PCI_VENDOR_ID_MIRO 0x1031
+ #define PCI_DEVICE_ID_MIRO_36050 0x5601
+@@ -1060,6 +1061,16 @@
+ #define PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL 0x0258
+ #define PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL 0x0259
+ #define PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL 0x025B
++#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800 0x0280
++#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4280 0x0281
++#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800_SE 0x0282
++#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_4200_GO 0x0286
++#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800_U 0x0301
++#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800 0x0302
++#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600_U 0x0311
++#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600 0x0312
++#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200_U 0x0321
++#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200 0x0322
+
+ #define PCI_VENDOR_ID_IMS 0x10e0
+ #define PCI_DEVICE_ID_IMS_8849 0x8849
+Index: linux-2.6.0-test5/include/linux/pnpbios.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/pnpbios.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/pnpbios.h 2003-09-27 11:38:41.045288552 +0800
+@@ -26,7 +26,7 @@
+ #ifdef __KERNEL__
+
+ #include <linux/types.h>
+-#include <linux/pci.h>
++#include <linux/pnp.h>
+
+ /*
+ * Return codes
+@@ -131,13 +131,7 @@
+ #ifdef CONFIG_PNPBIOS
+
+ /* non-exported */
+-extern int pnpbios_dont_use_current_config;
+ extern struct pnp_dev_node_info node_info;
+-extern void *pnpbios_kmalloc(size_t size, int f);
+-extern int pnpbios_init (void);
+-extern int pnpbios_interface_attach_device(struct pnp_bios_node * node);
+-extern int pnpbios_proc_init (void);
+-extern void pnpbios_proc_exit (void);
+
+ extern int pnp_bios_dev_node_info (struct pnp_dev_node_info *data);
+ extern int pnp_bios_get_dev_node (u8 *nodenum, char config, struct pnp_bios_node *data);
+Index: linux-2.6.0-test5/include/linux/proc_fs.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/proc_fs.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/proc_fs.h 2003-09-27 11:38:41.048288096 +0800
+@@ -185,9 +185,10 @@
+ #else
+
+ #define proc_root_driver NULL
+-#define proc_net_fops_create(name,mode,fops) do {} while(0)
+-static inline struct proc_dir_entry *proc_net_create(const char *name, mode_t mode,
+- get_info_t *get_info) {return NULL;}
++#define proc_net NULL
++
++#define proc_net_fops_create(name, mode, fops) ({ (void)(mode), NULL; })
++#define proc_net_create(name, mode, info) ({ (void)(mode), NULL; })
+ static inline void proc_net_remove(const char *name) {}
+
+ static inline struct dentry *proc_pid_unhash(struct task_struct *p) { return NULL; }
+Index: linux-2.6.0-test5/include/linux/raid/md_k.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/raid/md_k.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/raid/md_k.h 2003-09-27 11:38:41.051287640 +0800
+@@ -64,11 +64,7 @@
+ typedef struct mddev_s mddev_t;
+ typedef struct mdk_rdev_s mdk_rdev_t;
+
+-#if (MINORBITS != 8)
+-#error MD does not handle bigger kdev yet
+-#endif
+-
+-#define MAX_MD_DEVS (1<<MINORBITS) /* Max number of md dev */
++#define MAX_MD_DEVS 256 /* Max number of md dev */
+
+ /*
+ * options passed in raidrun:
+Index: linux-2.6.0-test5/include/linux/random.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/random.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/random.h 2003-09-27 11:38:41.053287336 +0800
+@@ -42,7 +42,6 @@
+
+ #ifdef __KERNEL__
+
+-extern void rand_initialize(void);
+ extern void rand_initialize_irq(int irq);
+
+ extern void batch_entropy_store(u32 a, u32 b, int num);
+Index: linux-2.6.0-test5/include/linux/reiserfs_fs.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/reiserfs_fs.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/reiserfs_fs.h 2003-09-27 11:38:41.076283840 +0800
+@@ -1931,32 +1931,13 @@
+
+ int reiserfs_proc_info_init( struct super_block *sb );
+ int reiserfs_proc_info_done( struct super_block *sb );
+-struct proc_dir_entry *reiserfs_proc_register( struct super_block *sb,
+- char *name, read_proc_t *func );
+-void reiserfs_proc_unregister( struct super_block *sb, const char *name );
+ struct proc_dir_entry *reiserfs_proc_register_global( char *name,
+ read_proc_t *func );
+ void reiserfs_proc_unregister_global( const char *name );
+ int reiserfs_proc_info_global_init( void );
+ int reiserfs_proc_info_global_done( void );
+-int reiserfs_proc_tail( int len, char *buffer, char **start,
+- off_t offset, int count, int *eof );
+ int reiserfs_global_version_in_proc( char *buffer, char **start, off_t offset,
+ int count, int *eof, void *data );
+-int reiserfs_version_in_proc( char *buffer, char **start, off_t offset,
+- int count, int *eof, void *data );
+-int reiserfs_super_in_proc( char *buffer, char **start, off_t offset,
+- int count, int *eof, void *data );
+-int reiserfs_per_level_in_proc( char *buffer, char **start, off_t offset,
+- int count, int *eof, void *data );
+-int reiserfs_bitmap_in_proc( char *buffer, char **start, off_t offset,
+- int count, int *eof, void *data );
+-int reiserfs_on_disk_super_in_proc( char *buffer, char **start, off_t offset,
+- int count, int *eof, void *data );
+-int reiserfs_oidmap_in_proc( char *buffer, char **start, off_t offset,
+- int count, int *eof, void *data );
+-int reiserfs_journal_in_proc( char *buffer, char **start, off_t offset,
+- int count, int *eof, void *data );
+
+ #if defined( REISERFS_PROC_INFO )
+
+Index: linux-2.6.0-test5/include/linux/reiserfs_fs_sb.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/reiserfs_fs_sb.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/reiserfs_fs_sb.h 2003-09-27 11:38:41.082282928 +0800
+@@ -468,7 +468,7 @@
+
+
+ void reiserfs_file_buffer (struct buffer_head * bh, int list);
+-int is_reiserfs_super(struct super_block *s) ;
++extern struct file_system_type reiserfs_fs_type;
+ int journal_mark_dirty(struct reiserfs_transaction_handle *, struct super_block *, struct buffer_head *bh) ;
+ int flush_old_commits(struct super_block *s, int) ;
+ int show_reiserfs_locks(void) ;
+Index: linux-2.6.0-test5/include/linux/rtnetlink.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/rtnetlink.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/rtnetlink.h 2003-09-27 11:38:41.088282016 +0800
+@@ -508,10 +508,12 @@
+ #define IFLA_MASTER IFLA_MASTER
+ IFLA_WIRELESS, /* Wireless Extension event - see wireless.h */
+ #define IFLA_WIRELESS IFLA_WIRELESS
++ IFLA_PROTINFO, /* Protocol specific information for a link */
++#define IFLA_PROTINFO IFLA_PROTINFO
+ };
+
+
+-#define IFLA_MAX IFLA_WIRELESS
++#define IFLA_MAX IFLA_PROTINFO
+
+ #define IFLA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
+ #define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg))
+@@ -545,6 +547,18 @@
+ for IPIP tunnels, when route to endpoint is allowed to change)
+ */
+
++/* Subtype attributes for IFLA_PROTINFO */
++enum
++{
++ IFLA_INET6_UNSPEC,
++ IFLA_INET6_FLAGS, /* link flags */
++ IFLA_INET6_CONF, /* sysctl parameters */
++ IFLA_INET6_STATS, /* statistics */
++ IFLA_INET6_MCAST, /* MC things. What of them? */
++};
++
++#define IFLA_INET6_MAX IFLA_INET6_MCAST
++
+ /*****************************************************************
+ * Traffic control messages.
+ ****/
+Index: linux-2.6.0-test5/include/linux/sched.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/sched.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/sched.h 2003-09-27 11:38:41.095280952 +0800
+@@ -151,6 +151,7 @@
+
+ extern void show_state(void);
+ extern void show_regs(struct pt_regs *);
++extern void show_trace_task(task_t *tsk);
+
+ /*
+ * TASK is a pointer to the task whose backtrace we want to see (or NULL for current
+@@ -281,7 +282,9 @@
+ #define MAX_RT_PRIO MAX_USER_RT_PRIO
+
+ #define MAX_PRIO (MAX_RT_PRIO + 40)
+-
++
++#define rt_task(p) ((p)->prio < MAX_RT_PRIO)
++
+ /*
+ * Some day this will be a full-fledged user tracking system..
+ */
+@@ -340,7 +343,9 @@
+ prio_array_t *array;
+
+ unsigned long sleep_avg;
+- unsigned long last_run;
++ long interactive_credit;
++ unsigned long long timestamp;
++ int activated;
+
+ unsigned long policy;
+ cpumask_t cpus_allowed;
+@@ -360,7 +365,7 @@
+ unsigned long personality;
+ int did_exec:1;
+ pid_t pid;
+- pid_t pgrp;
++ pid_t __pgrp; /* Accessed via process_group() */
+ pid_t tty_old_pgrp;
+ pid_t session;
+ pid_t tgid;
+@@ -375,7 +380,7 @@
+ struct task_struct *parent; /* parent process */
+ struct list_head children; /* list of my children */
+ struct list_head sibling; /* linkage in my parent's children list */
+- struct task_struct *group_leader;
++ struct task_struct *group_leader; /* threadgroup leader */
+
+ /* PID/PID hash table linkage. */
+ struct pid_link pids[PIDTYPE_MAX];
+@@ -459,8 +464,20 @@
+
+ unsigned long ptrace_message;
+ siginfo_t *last_siginfo; /* For ptrace use. */
++/*
++ * current io wait handle: wait queue entry to use for io waits
++ * If this thread is processing aio, this points at the waitqueue
++ * inside the currently handled kiocb. It may be NULL (i.e. default
++ * to a stack based synchronous wait) if its doing sync IO.
++ */
++ wait_queue_t *io_wait;
+ };
+
++static inline pid_t process_group(struct task_struct *tsk)
++{
++ return tsk->group_leader->__pgrp;
++}
++
+ extern void __put_task_struct(struct task_struct *tsk);
+ #define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0)
+ #define put_task_struct(tsk) \
+@@ -499,6 +516,8 @@
+ }
+ #endif
+
++extern unsigned long long sched_clock(void);
++
+ #ifdef CONFIG_NUMA
+ extern void sched_balance_exec(void);
+ extern void node_nr_running_init(void);
+Index: linux-2.6.0-test5/include/linux/seq_file.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/seq_file.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/seq_file.h 2003-09-27 11:38:41.097280648 +0800
+@@ -65,5 +65,8 @@
+ int single_open(struct file *, int (*)(struct seq_file *, void *), void *);
+ int single_release(struct inode *, struct file *);
+ int seq_release_private(struct inode *, struct file *);
++
++#define SEQ_START_TOKEN ((void *)1)
++
+ #endif
+ #endif
+Index: linux-2.6.0-test5/include/linux/serial_core.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/serial_core.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/serial_core.h 2003-09-27 11:38:41.100280192 +0800
+@@ -67,6 +67,12 @@
+ #define PORT_PC9861 45
+ #define PORT_PC9801_101 46
+
++/* DZ */
++#define PORT_DZ 47
++
++/* Parisc type numbers. */
++#define PORT_MUX 48
++
+ /* Macintosh Zilog type numbers */
+ #define PORT_MAC_ZILOG 50 /* m68k : not yet implemented */
+ #define PORT_PMAC_ZILOG 51
+@@ -152,7 +158,9 @@
+ unsigned char x_char; /* xon/xoff char */
+ unsigned char regshift; /* reg offset shift */
+ unsigned char iotype; /* io access style */
+-
++#ifdef CONFIG_KGDB
++ int kgdb; /* in use by kgdb */
++#endif
+ #define UPIO_PORT (0)
+ #define UPIO_HUB6 (1)
+ #define UPIO_MEM (2)
+@@ -319,8 +327,8 @@
+ /*
+ * Power Management
+ */
+-int uart_suspend_port(struct uart_driver *reg, struct uart_port *port, u32 level);
+-int uart_resume_port(struct uart_driver *reg, struct uart_port *port, u32 level);
++int uart_suspend_port(struct uart_driver *reg, struct uart_port *port);
++int uart_resume_port(struct uart_driver *reg, struct uart_port *port);
+
+ #define uart_circ_empty(circ) ((circ)->head == (circ)->tail)
+ #define uart_circ_clear(circ) ((circ)->head = (circ)->tail = 0)
+Index: linux-2.6.0-test5/include/linux/serio.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/serio.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/serio.h 2003-09-27 11:38:41.102279888 +0800
+@@ -65,7 +65,9 @@
+ irqreturn_t serio_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs);
+
+ void serio_register_port(struct serio *serio);
++void serio_register_slave_port(struct serio *serio);
+ void serio_unregister_port(struct serio *serio);
++void serio_unregister_slave_port(struct serio *serio);
+ void serio_register_device(struct serio_dev *dev);
+ void serio_unregister_device(struct serio_dev *dev);
+
+@@ -104,6 +106,7 @@
+ #define SERIO_RS232 0x02000000UL
+ #define SERIO_HIL_MLC 0x03000000UL
+ #define SERIO_PC9800 0x04000000UL
++#define SERIO_PS_PSTHRU 0x05000000UL
+
+ #define SERIO_PROTO 0xFFUL
+ #define SERIO_MSC 0x01
+Index: linux-2.6.0-test5/include/linux/skbuff.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/skbuff.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/skbuff.h 2003-09-27 11:38:41.111278520 +0800
+@@ -306,7 +306,7 @@
+ *
+ * Returns true if the queue is empty, false otherwise.
+ */
+-static inline int skb_queue_empty(struct sk_buff_head *list)
++static inline int skb_queue_empty(const struct sk_buff_head *list)
+ {
+ return list->next == (struct sk_buff *)list;
+ }
+@@ -357,7 +357,7 @@
+ * one of multiple shared copies of the buffer. Cloned buffers are
+ * shared data so must not be written to under normal circumstances.
+ */
+-static inline int skb_cloned(struct sk_buff *skb)
++static inline int skb_cloned(const struct sk_buff *skb)
+ {
+ return skb->cloned && atomic_read(&skb_shinfo(skb)->dataref) != 1;
+ }
+@@ -369,7 +369,7 @@
+ * Returns true if more than one person has a reference to this
+ * buffer.
+ */
+-static inline int skb_shared(struct sk_buff *skb)
++static inline int skb_shared(const struct sk_buff *skb)
+ {
+ return atomic_read(&skb->users) != 1;
+ }
+@@ -477,7 +477,7 @@
+ *
+ * Return the length of an &sk_buff queue.
+ */
+-static inline __u32 skb_queue_len(struct sk_buff_head *list_)
++static inline __u32 skb_queue_len(const struct sk_buff_head *list_)
+ {
+ return list_->qlen;
+ }
+Index: linux-2.6.0-test5/include/linux/smb_mount.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/smb_mount.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/smb_mount.h 2003-09-27 11:38:41.112278368 +0800
+@@ -43,11 +43,11 @@
+ struct smb_mount_data_kernel {
+ int version;
+
+- __kernel_uid_t mounted_uid; /* Who may umount() this filesystem? */
+- __kernel_uid_t uid;
+- __kernel_gid_t gid;
+- __kernel_mode_t file_mode;
+- __kernel_mode_t dir_mode;
++ uid_t mounted_uid; /* Who may umount() this filesystem? */
++ uid_t uid;
++ gid_t gid;
++ mode_t file_mode;
++ mode_t dir_mode;
+
+ u32 flags;
+
+Index: linux-2.6.0-test5/include/linux/spinlock.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/spinlock.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/spinlock.h 2003-09-27 11:38:41.116277760 +0800
+@@ -15,6 +15,12 @@
+
+ #include <asm/processor.h> /* for cpu relax */
+ #include <asm/system.h>
++#ifdef CONFIG_KGDB
++#include <asm/current.h>
++#define SET_WHO(x, him) (x)->who = him;
++#else
++#define SET_WHO(x, him)
++#endif
+
+ /*
+ * Must define these before including other files, inline functions need them
+@@ -55,6 +61,9 @@
+ const char *module;
+ char *owner;
+ int oline;
++#ifdef CONFIG_KGDB
++ struct task_struct *who;
++#endif
+ } spinlock_t;
+ #define SPIN_LOCK_UNLOCKED (spinlock_t) { SPINLOCK_MAGIC, 0, 10, __FILE__ , NULL, 0}
+
+@@ -66,6 +75,7 @@
+ (x)->module = __FILE__; \
+ (x)->owner = NULL; \
+ (x)->oline = 0; \
++ SET_WHO(x, NULL) \
+ } while (0)
+
+ #define CHECK_LOCK(x) \
+@@ -88,6 +98,7 @@
+ (x)->lock = 1; \
+ (x)->owner = __FILE__; \
+ (x)->oline = __LINE__; \
++ SET_WHO(x, current) \
+ } while (0)
+
+ /* without debugging, spin_is_locked on UP always says
+@@ -118,6 +129,7 @@
+ (x)->lock = 1; \
+ (x)->owner = __FILE__; \
+ (x)->oline = __LINE__; \
++ SET_WHO(x, current) \
+ 1; \
+ })
+
+@@ -184,6 +196,17 @@
+
+ #endif /* !SMP */
+
++#ifdef CONFIG_LOCKMETER
++extern void _metered_spin_lock (spinlock_t *lock);
++extern void _metered_spin_unlock (spinlock_t *lock);
++extern int _metered_spin_trylock(spinlock_t *lock);
++extern void _metered_read_lock (rwlock_t *lock);
++extern void _metered_read_unlock (rwlock_t *lock);
++extern void _metered_write_lock (rwlock_t *lock);
++extern void _metered_write_unlock (rwlock_t *lock);
++extern int _metered_write_trylock(rwlock_t *lock);
++#endif
++
+ /*
+ * Define the various spin_lock and rw_lock methods. Note we define these
+ * regardless of whether CONFIG_SMP or CONFIG_PREEMPT are set. The various
+@@ -389,6 +412,141 @@
+ _raw_spin_trylock(lock) ? 1 : \
+ ({preempt_enable(); local_bh_enable(); 0;});})
+
++#ifdef CONFIG_LOCKMETER
++#undef spin_lock
++#undef spin_trylock
++#undef spin_unlock
++#undef spin_lock_irqsave
++#undef spin_lock_irq
++#undef spin_lock_bh
++#undef read_lock
++#undef read_unlock
++#undef write_lock
++#undef write_unlock
++#undef write_trylock
++#undef spin_unlock_bh
++#undef read_lock_irqsave
++#undef read_lock_irq
++#undef read_lock_bh
++#undef read_unlock_bh
++#undef write_lock_irqsave
++#undef write_lock_irq
++#undef write_lock_bh
++#undef write_unlock_bh
++
++#define spin_lock(lock) \
++do { \
++ preempt_disable(); \
++ _metered_spin_lock(lock); \
++} while(0)
++
++#define spin_trylock(lock) ({preempt_disable(); _metered_spin_trylock(lock) ? \
++ 1 : ({preempt_enable(); 0;});})
++#define spin_unlock(lock) \
++do { \
++ _metered_spin_unlock(lock); \
++ preempt_enable(); \
++} while (0)
++
++#define spin_lock_irqsave(lock, flags) \
++do { \
++ local_irq_save(flags); \
++ preempt_disable(); \
++ _metered_spin_lock(lock); \
++} while (0)
++
++#define spin_lock_irq(lock) \
++do { \
++ local_irq_disable(); \
++ preempt_disable(); \
++ _metered_spin_lock(lock); \
++} while (0)
++
++#define spin_lock_bh(lock) \
++do { \
++ local_bh_disable(); \
++ preempt_disable(); \
++ _metered_spin_lock(lock); \
++} while (0)
++
++#define spin_unlock_bh(lock) \
++do { \
++ _metered_spin_unlock(lock); \
++ preempt_enable(); \
++ local_bh_enable(); \
++} while (0)
++
++
++#define read_lock(lock) ({preempt_disable(); _metered_read_lock(lock);})
++#define read_unlock(lock) ({_metered_read_unlock(lock); preempt_enable();})
++#define write_lock(lock) ({preempt_disable(); _metered_write_lock(lock);})
++#define write_unlock(lock) ({_metered_write_unlock(lock); preempt_enable();})
++#define write_trylock(lock) ({preempt_disable();_metered_write_trylock(lock) ? \
++ 1 : ({preempt_enable(); 0;});})
++#define spin_unlock_no_resched(lock) \
++do { \
++ _metered_spin_unlock(lock); \
++ preempt_enable_no_resched(); \
++} while (0)
++
++#define read_lock_irqsave(lock, flags) \
++do { \
++ local_irq_save(flags); \
++ preempt_disable(); \
++ _metered_read_lock(lock); \
++} while (0)
++
++#define read_lock_irq(lock) \
++do { \
++ local_irq_disable(); \
++ preempt_disable(); \
++ _metered_read_lock(lock); \
++} while (0)
++
++#define read_lock_bh(lock) \
++do { \
++ local_bh_disable(); \
++ preempt_disable(); \
++ _metered_read_lock(lock); \
++} while (0)
++
++#define read_unlock_bh(lock) \
++do { \
++ _metered_read_unlock(lock); \
++ preempt_enable(); \
++ local_bh_enable(); \
++} while (0)
++
++#define write_lock_irqsave(lock, flags) \
++do { \
++ local_irq_save(flags); \
++ preempt_disable(); \
++ _metered_write_lock(lock); \
++} while (0)
++
++#define write_lock_irq(lock) \
++do { \
++ local_irq_disable(); \
++ preempt_disable(); \
++ _metered_write_lock(lock); \
++} while (0)
++
++#define write_lock_bh(lock) \
++do { \
++ local_bh_disable(); \
++ preempt_disable(); \
++ _metered_write_lock(lock); \
++} while (0)
++
++#define write_unlock_bh(lock) \
++do { \
++ _metered_write_unlock(lock); \
++ preempt_enable(); \
++ local_bh_enable(); \
++} while (0)
++
++#endif /* !CONFIG_LOCKMETER */
++
+ /* "lock on reference count zero" */
+ #ifndef ATOMIC_DEC_AND_LOCK
+ #include <asm/atomic.h>
+Index: linux-2.6.0-test5/include/linux/suspend.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/suspend.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/suspend.h 2003-09-27 11:38:41.118277456 +0800
+@@ -10,7 +10,7 @@
+ #include <linux/init.h>
+ #include <linux/pm.h>
+
+-#ifdef CONFIG_SOFTWARE_SUSPEND
++#ifdef CONFIG_PM
+ /* page backup entry */
+ typedef struct pbe {
+ unsigned long address; /* address of the copy */
+@@ -53,10 +53,17 @@
+ extern void do_suspend_lowlevel(int resume);
+ extern void do_suspend_lowlevel_s4bios(int resume);
+
++#endif /* CONFIG_PM */
++
++#ifdef CONFIG_SOFTWARE_SUSPEND
++
++extern unsigned char software_suspend_enabled;
++
++extern void software_suspend(void);
+ #else /* CONFIG_SOFTWARE_SUSPEND */
+-static inline int software_suspend(void)
++static inline void software_suspend(void)
+ {
+- return -EPERM;
++ printk("Warning: fake suspend called\n");
+ }
+ #endif /* CONFIG_SOFTWARE_SUSPEND */
+
+Index: linux-2.6.0-test5/include/linux/swap.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/swap.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/swap.h 2003-09-27 11:38:41.121277000 +0800
+@@ -3,7 +3,6 @@
+
+ #include <linux/config.h>
+ #include <linux/spinlock.h>
+-#include <linux/kdev_t.h>
+ #include <linux/linkage.h>
+ #include <linux/mmzone.h>
+ #include <linux/list.h>
+Index: linux-2.6.0-test5/include/linux/tty.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/tty.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/tty.h 2003-09-27 11:38:41.125276392 +0800
+@@ -264,7 +264,6 @@
+ char name[64];
+ int pgrp;
+ int session;
+- dev_t device;
+ unsigned long flags;
+ int count;
+ struct winsize winsize;
+@@ -351,7 +350,6 @@
+
+ extern int lp_init(void);
+ extern int pty_init(void);
+-extern void tty_init(void);
+ extern int mxser_init(void);
+ extern int moxa_init(void);
+ extern int ip2_init(void);
+@@ -420,5 +418,10 @@
+ extern int vt_ioctl(struct tty_struct *tty, struct file * file,
+ unsigned int cmd, unsigned long arg);
+
++static inline dev_t tty_devnum(struct tty_struct *tty)
++{
++ return MKDEV(tty->driver->major, tty->driver->minor_start) + tty->index;
++}
++
+ #endif /* __KERNEL__ */
+ #endif
+Index: linux-2.6.0-test5/include/linux/types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/types.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/types.h 2003-09-27 11:38:41.127276088 +0800
+@@ -17,6 +17,8 @@
+
+ #ifndef __KERNEL_STRICT_NAMES
+
++typedef __u32 __kernel_dev_t;
++
+ typedef __kernel_fd_set fd_set;
+ typedef __kernel_dev_t dev_t;
+ typedef __kernel_ino_t ino_t;
+Index: linux-2.6.0-test5/include/linux/usb_gadget.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/usb_gadget.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/usb_gadget.h 2003-09-27 11:38:41.134275024 +0800
+@@ -72,9 +72,9 @@
+ unsigned length;
+ dma_addr_t dma;
+
+- unsigned no_interrupt : 1,
+- zero : 1,
+- short_not_ok : 1;
++ unsigned no_interrupt:1;
++ unsigned zero:1;
++ unsigned short_not_ok:1;
+
+ void (*complete)(struct usb_ep *ep,
+ struct usb_request *req);
+@@ -122,9 +122,11 @@
+ /**
+ * struct usb_ep - device side representation of USB endpoint
+ * @name:identifier for the endpoint, such as "ep-a" or "ep9in-bulk"
++ * @ops: Function pointers used to access hardware-specific operations.
+ * @ep_list:the gadget's ep_list holds all of its endpoints
+- * @maxpacket:the maximum packet size used on this endpoint, as
+- * configured when the endpoint was enabled.
++ * @maxpacket:The maximum packet size used on this endpoint. The initial
++ * value can sometimes be reduced (hardware allowing), according to
++ * the endpoint descriptor used to configure the endpoint.
+ * @driver_data:for use by the gadget driver. all other fields are
+ * read-only to gadget drivers.
+ *
+@@ -138,7 +140,7 @@
+ const char *name;
+ const struct usb_ep_ops *ops;
+ struct list_head ep_list;
+- unsigned maxpacket : 16;
++ unsigned maxpacket:16;
+ };
+
+ /*-------------------------------------------------------------------------*/
+@@ -443,18 +445,21 @@
+
+ /**
+ * struct usb_gadget - represents a usb slave device
++ * @ops: Function pointers used to access hardware-specific operations.
+ * @ep0: Endpoint zero, used when reading or writing responses to
+ * driver setup() requests
+ * @ep_list: List of other endpoints supported by the device.
+ * @speed: Speed of current connection to USB host.
+ * @name: Identifies the controller hardware type. Used in diagnostics
+ * and sometimes configuration.
++ * @dev: Driver model state for this abstract device.
+ *
+ * Gadgets have a mostly-portable "gadget driver" implementing device
+- * functions, handling all usb configurations and interfaces. They
+- * also have a hardware-specific driver (accessed through ops vectors),
+- * which insulates the gadget driver from hardware details and packages
+- * the hardware endpoints through generic i/o queues.
++ * functions, handling all usb configurations and interfaces. Gadget
++ * drivers talk to hardware-specific code indirectly, through ops vectors.
++ * That insulates the gadget driver from hardware details, and packages
++ * the hardware endpoints through generic i/o queues. The "usb_gadget"
++ * and "usb_ep" interfaces provide that insulation from the hardware.
+ *
+ * Except for the driver data, all fields in this structure are
+ * read-only to the gadget driver. That driver data is part of the
+@@ -469,10 +474,6 @@
+ struct list_head ep_list; /* of usb_ep */
+ enum usb_device_speed speed;
+ const char *name;
+-
+- /* use this to allocate dma-coherent buffers or set up
+- * dma mappings. or print diagnostics, etc.
+- */
+ struct device dev;
+ };
+
+@@ -576,6 +577,7 @@
+ * 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
+Index: linux-2.6.0-test5/include/linux/usb.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/usb.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/usb.h 2003-09-27 11:38:41.145273352 +0800
+@@ -80,7 +80,6 @@
+ * @act_altsetting: index of current altsetting. this number is always
+ * less than num_altsetting. after the device is configured, each
+ * interface uses its default setting of zero.
+- * @max_altsetting: the max number of altsettings for this interface.
+ * @driver: the USB driver that is bound to this interface.
+ * @minor: the minor number assigned to this interface, if this
+ * interface is bound to a driver that uses the USB major number.
+@@ -118,7 +117,6 @@
+
+ unsigned act_altsetting; /* active alternate setting */
+ unsigned num_altsetting; /* number of alternate settings */
+- unsigned max_altsetting; /* total memory allocated */
+
+ struct usb_driver *driver; /* driver */
+ int minor; /* minor number this interface is bound to */
+Index: linux-2.6.0-test5/include/linux/wait.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/wait.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/wait.h 2003-09-27 11:38:41.148272896 +0800
+@@ -80,6 +80,15 @@
+ return !list_empty(&q->task_list);
+ }
+
++/*
++ * Used to distinguish between sync and async io wait context:
++ * sync i/o typically specifies a NULL wait queue entry or a wait
++ * queue entry bound to a task (current task) to wake up.
++ * aio specifies a wait queue entry with an async notification
++ * callback routine, not associated with any task.
++ */
++#define is_sync_wait(wait) (!(wait) || ((wait)->task))
++
+ 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));
+Index: linux-2.6.0-test5/include/linux/writeback.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/writeback.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/writeback.h 2003-09-27 11:38:41.149272744 +0800
+@@ -80,14 +80,17 @@
+
+ struct ctl_table;
+ struct file;
+-int dirty_writeback_centisecs_handler(struct ctl_table *, int, struct file *,
+- void *, size_t *);
++int dirty_writeback_centisecs_handler(struct ctl_table *, int, struct file *,
++ void __user *, size_t *);
+
+ void page_writeback_init(void);
+-void balance_dirty_pages(struct address_space *mapping);
+-void balance_dirty_pages_ratelimited(struct address_space *mapping);
++int balance_dirty_pages_ratelimited(struct address_space *mapping);
+ int pdflush_operation(void (*fn)(unsigned long), unsigned long arg0);
+ int do_writepages(struct address_space *mapping, struct writeback_control *wbc);
++ssize_t sync_page_range(struct inode *inode, struct address_space *mapping,
++ loff_t pos, size_t count);
++ssize_t sync_page_range_nolock(struct inode *inode, struct address_space
++ *mapping, loff_t pos, size_t count);
+
+ /* pdflush.c */
+ extern int nr_pdflush_threads; /* Global so it can be exported to sysctl
+Index: linux-2.6.0-test5/include/net/bluetooth/bluetooth.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/net/bluetooth/bluetooth.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/net/bluetooth/bluetooth.h 2003-09-27 11:38:41.152272288 +0800
+@@ -131,7 +131,7 @@
+ void bt_sock_unlink(struct bt_sock_list *l, struct sock *s);
+ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, int len, int flags);
+ uint bt_sock_poll(struct file * file, struct socket *sock, poll_table *wait);
+-int bt_sock_w4_connect(struct sock *sk, int flags);
++int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo);
+
+ void bt_accept_enqueue(struct sock *parent, struct sock *sk);
+ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock);
+Index: linux-2.6.0-test5/include/net/bluetooth/hci.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/net/bluetooth/hci.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/net/bluetooth/hci.h 2003-09-27 11:38:41.156271680 +0800
+@@ -304,6 +304,8 @@
+ __u8 num_rsp;
+ } __attribute__ ((packed));
+
++#define OCF_INQUIRY_CANCEL 0x0002
++
+ #define OCF_LINK_KEY_REPLY 0x000B
+ #define OCF_LINK_KEY_NEG_REPLY 0x000C
+ struct hci_cp_link_key_reply {
+Index: linux-2.6.0-test5/include/net/bluetooth/l2cap.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/net/bluetooth/l2cap.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/net/bluetooth/l2cap.h 2003-09-27 11:38:41.159271224 +0800
+@@ -220,6 +220,7 @@
+ __u32 link_mode;
+
+ __u8 conf_state;
++ __u8 conf_retry;
+ __u16 conf_mtu;
+
+ __u8 ident;
+@@ -234,6 +235,7 @@
+ #define L2CAP_CONF_REQ_SENT 0x01
+ #define L2CAP_CONF_INPUT_DONE 0x02
+ #define L2CAP_CONF_OUTPUT_DONE 0x04
++#define L2CAP_CONF_MAX_RETRIES 2
+
+ void l2cap_load(void);
+
+Index: linux-2.6.0-test5/include/net/if_inet6.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/net/if_inet6.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/net/if_inet6.h 2003-09-27 11:38:41.161270920 +0800
+@@ -16,7 +16,12 @@
+ #define _NET_IF_INET6_H
+
+ #include <net/snmp.h>
++#include <linux/ipv6.h>
+
++/* inet6_dev.if_flags */
++
++#define IF_RA_OTHERCONF 0x80
++#define IF_RA_MANAGED 0x40
+ #define IF_RA_RCVD 0x20
+ #define IF_RS_SENT 0x10
+
+@@ -132,28 +137,6 @@
+ #define IFA_SITE IPV6_ADDR_SITELOCAL
+ #define IFA_GLOBAL 0x0000U
+
+-struct ipv6_devconf
+-{
+- int forwarding;
+- int hop_limit;
+- int mtu6;
+- int accept_ra;
+- int accept_redirects;
+- int autoconf;
+- int dad_transmits;
+- int rtr_solicits;
+- int rtr_solicit_interval;
+- int rtr_solicit_delay;
+-#ifdef CONFIG_IPV6_PRIVACY
+- int use_tempaddr;
+- int temp_valid_lft;
+- int temp_prefered_lft;
+- int regen_max_retry;
+- int max_desync_factor;
+-#endif
+- void *sysctl;
+-};
+-
+ struct ipv6_devstat {
+ struct proc_dir_entry *proc_dir_entry;
+ DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6);
+Index: linux-2.6.0-test5/include/net/llc_conn.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/net/llc_conn.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/net/llc_conn.h 2003-09-27 11:38:41.163270616 +0800
+@@ -15,6 +15,14 @@
+ #include <net/llc_if.h>
+ #include <linux/llc.h>
+
++#define LLC_EVENT 1
++#define LLC_PACKET 2
++
++#define LLC_P_TIME 2
++#define LLC_ACK_TIME 1
++#define LLC_REJ_TIME 3
++#define LLC_BUSY_TIME 3
++
+ struct llc_timer {
+ struct timer_list timer;
+ u16 expire; /* timer expire time */
+@@ -69,6 +77,16 @@
+
+ #define llc_sk(__sk) ((struct llc_opt *)(__sk)->sk_protinfo)
+
++static __inline__ void llc_set_backlog_type(struct sk_buff *skb, char type)
++{
++ skb->cb[sizeof(skb->cb) - 1] = type;
++}
++
++static __inline__ char llc_backlog_type(struct sk_buff *skb)
++{
++ return skb->cb[sizeof(skb->cb) - 1];
++}
++
+ extern struct sock *llc_sk_alloc(int family, int priority);
+ extern void llc_sk_free(struct sock *sk);
+
+@@ -90,9 +108,10 @@
+ struct llc_addr *laddr);
+ extern struct sock *llc_lookup_listener(struct llc_sap *sap,
+ struct llc_addr *laddr);
+-extern struct sock *llc_lookup_dgram(struct llc_sap *sap,
+- struct llc_addr *laddr);
+-extern void llc_save_primitive(struct sk_buff* skb, u8 prim);
++extern void llc_sap_add_socket(struct llc_sap *sap, struct sock *sk);
++extern void llc_sap_remove_socket(struct llc_sap *sap, struct sock *sk);
++
+ extern u8 llc_data_accept_state(u8 state);
+ extern void llc_build_offset_table(void);
++extern int llc_release_sockets(struct llc_sap *sap);
+ #endif /* LLC_CONN_H */
+Index: linux-2.6.0-test5/include/net/llc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/net/llc.h 2003-09-27 11:38:18.487717824 +0800
++++ linux-2.6.0-test5/include/net/llc.h 2003-09-27 11:38:41.163270616 +0800
+@@ -0,0 +1,91 @@
++#ifndef LLC_H
++#define LLC_H
++/*
++ * Copyright (c) 1997 by Procom Technology, Inc.
++ * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
++ *
++ * This program can be redistributed or modified under the terms of the
++ * GNU General Public License as published by the Free Software Foundation.
++ * This program is distributed without any warranty or implied warranty
++ * of merchantability or fitness for a particular purpose.
++ *
++ * See the GNU General Public License for more details.
++ */
++
++#include <linux/if.h>
++#include <linux/if_ether.h>
++#include <linux/list.h>
++#include <linux/spinlock.h>
++
++struct net_device;
++struct packet_type;
++struct sk_buff;
++
++struct llc_addr {
++ unsigned char lsap;
++ unsigned char mac[IFHWADDRLEN];
++};
++
++#define LLC_SAP_STATE_INACTIVE 1
++#define LLC_SAP_STATE_ACTIVE 2
++
++/**
++ * struct llc_sap - Defines the SAP component
++ *
++ * @station - station this sap belongs to
++ * @state - sap state
++ * @p_bit - only lowest-order bit used
++ * @f_bit - only lowest-order bit used
++ * @laddr - SAP value in this 'lsap'
++ * @node - entry in station sap_list
++ * @sk_list - LLC sockets this one manages
++ */
++struct llc_sap {
++ unsigned char state;
++ unsigned char p_bit;
++ unsigned char f_bit;
++ int (*rcv_func)(struct sk_buff *skb,
++ struct net_device *dev,
++ struct packet_type *pt);
++ struct llc_addr laddr;
++ struct list_head node;
++ struct {
++ rwlock_t lock;
++ struct hlist_head list;
++ } sk_list;
++};
++
++#define LLC_DEST_INVALID 0 /* Invalid LLC PDU type */
++#define LLC_DEST_SAP 1 /* Type 1 goes here */
++#define LLC_DEST_CONN 2 /* Type 2 goes here */
++
++extern struct list_head llc_sap_list;
++extern rwlock_t llc_sap_list_lock;
++extern unsigned char llc_station_mac_sa[ETH_ALEN];
++
++extern int llc_rcv(struct sk_buff *skb, struct net_device *dev,
++ struct packet_type *pt);
++
++extern int llc_mac_hdr_init(struct sk_buff *skb,
++ unsigned char *sa, unsigned char *da);
++
++extern void llc_add_pack(int type, void (*handler)(struct llc_sap *sap,
++ struct sk_buff *skb));
++extern void llc_remove_pack(int type);
++
++extern void llc_set_station_handler(void (*handler)(struct sk_buff *skb));
++
++extern struct llc_sap *llc_sap_open(unsigned char lsap,
++ int (*rcv)(struct sk_buff *skb,
++ struct net_device *dev,
++ struct packet_type *pt));
++extern void llc_sap_close(struct llc_sap *sap);
++
++extern struct llc_sap *llc_sap_find(unsigned char sap_value);
++
++extern int llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb,
++ unsigned char *dmac, unsigned char dsap);
++
++extern int llc_station_init(void);
++extern void llc_station_exit(void);
++#endif /* LLC_H */
+Index: linux-2.6.0-test5/include/net/llc_if.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/net/llc_if.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/net/llc_if.h 2003-09-27 11:38:41.165270312 +0800
+@@ -16,6 +16,7 @@
+ #include <linux/if.h>
+ #include <linux/if_arp.h>
+ #include <linux/llc.h>
++#include <net/llc.h>
+
+ #define LLC_DATAUNIT_PRIM 1
+ #define LLC_CONN_PRIM 2
+@@ -60,29 +61,41 @@
+ #define LLC_STATUS_CONFLICT 7 /* disconnect conn */
+ #define LLC_STATUS_RESET_DONE 8 /* */
+
+-/* Structures and types */
+-/* SAP/MAC Address pair */
+-struct llc_addr {
+- u8 lsap;
+- u8 mac[IFHWADDRLEN];
+-};
+-
+-struct llc_sap;
+-
+-extern struct llc_sap *llc_sap_open(u8 lsap,
+- int (*func)(struct sk_buff *skb,
+- struct net_device *dev,
+- struct packet_type *pt));
+-extern void llc_sap_close(struct llc_sap *sap);
++extern u8 llc_mac_null_var[IFHWADDRLEN];
++
++/**
++ * llc_mac_null - determines if a address is a null mac address
++ * @mac: Mac address to test if null.
++ *
++ * Determines if a given address is a null mac address. Returns 0 if the
++ * address is not a null mac, 1 if the address is a null mac.
++ */
++static __inline__ int llc_mac_null(u8 *mac)
++{
++ return !memcmp(mac, llc_mac_null_var, IFHWADDRLEN);
++}
++
++static __inline__ int llc_addrany(struct llc_addr *addr)
++{
++ return llc_mac_null(addr->mac) && !addr->lsap;
++}
++
++/**
++ * llc_mac_match - determines if two mac addresses are the same
++ * @mac1: First mac address to compare.
++ * @mac2: Second mac address to compare.
++ *
++ * Determines if two given mac address are the same. Returns 0 if there
++ * is not a complete match up to len, 1 if a complete match up to len is
++ * found.
++ */
++static __inline__ int llc_mac_match(u8 *mac1, u8 *mac2)
++{
++ return !memcmp(mac1, mac2, IFHWADDRLEN);
++}
+
+ extern int llc_establish_connection(struct sock *sk, u8 *lmac,
+ u8 *dmac, u8 dsap);
+ extern int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb);
+-extern void llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb,
+- u8 *dmac, u8 dsap);
+-extern void llc_build_and_send_xid_pkt(struct llc_sap *sap, struct sk_buff *skb,
+- u8 *dmac, u8 dsap);
+-extern void llc_build_and_send_test_pkt(struct llc_sap *sap, struct sk_buff *skb,
+- u8 *dmac, u8 dsap);
+ extern int llc_send_disc(struct sock *sk);
+ #endif /* LLC_IF_H */
+Index: linux-2.6.0-test5/include/net/llc_pdu.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/net/llc_pdu.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/net/llc_pdu.h 2003-09-27 11:38:41.169269704 +0800
+@@ -2,7 +2,7 @@
+ #define LLC_PDU_H
+ /*
+ * Copyright (c) 1997 by Procom Technology,Inc.
+- * 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
++ * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+@@ -11,7 +11,10 @@
+ *
+ * See the GNU General Public License for more details.
+ */
+-/* LLC PDU structure */
++
++#include <linux/if_ether.h>
++#include <linux/if_tr.h>
++
+ /* Lengths of frame formats */
+ #define LLC_PDU_LEN_I 4 /* header and 2 control bytes */
+ #define LLC_PDU_LEN_S 4
+@@ -198,7 +201,7 @@
+ u8 ctrl_2;
+ };
+
+-static __inline__ struct llc_pdu_sn *llc_pdu_sn_hdr(struct sk_buff *skb)
++static inline struct llc_pdu_sn *llc_pdu_sn_hdr(struct sk_buff *skb)
+ {
+ return (struct llc_pdu_sn *)skb->nh.raw;
+ }
+@@ -210,16 +213,146 @@
+ u8 ctrl_1;
+ };
+
+-static __inline__ struct llc_pdu_un *llc_pdu_un_hdr(struct sk_buff *skb)
++static inline struct llc_pdu_un *llc_pdu_un_hdr(struct sk_buff *skb)
+ {
+ return (struct llc_pdu_un *)skb->nh.raw;
+ }
+
+-static __inline__ void *llc_set_pdu_hdr(struct sk_buff *skb, void *ptr)
++static inline void *llc_set_pdu_hdr(struct sk_buff *skb, void *ptr)
+ {
+ return skb->nh.raw = ptr;
+ }
+
++/**
++ * llc_pdu_header_init - initializes pdu header
++ * @skb: input skb that header must be set into it.
++ * @type: type of PDU (U, I or S).
++ * @ssap: source sap.
++ * @dsap: destination sap.
++ * @cr: command/response bit (0 or 1).
++ *
++ * This function sets DSAP, SSAP and command/Response bit in LLC header.
++ */
++static inline void llc_pdu_header_init(struct sk_buff *skb, u8 type,
++ u8 ssap, u8 dsap, u8 cr)
++{
++ const int hlen = type == LLC_PDU_TYPE_U ? 3 : 4;
++ struct llc_pdu_un *pdu = llc_set_pdu_hdr(skb, skb_push(skb, hlen));
++ pdu->dsap = dsap;
++ pdu->ssap = ssap;
++ pdu->ssap |= cr;
++}
++
++/**
++ * llc_pdu_decode_sa - extracs source address (MAC) of input frame
++ * @skb: input skb that source address must be extracted from it.
++ * @sa: pointer to source address (6 byte array).
++ *
++ * This function extracts source address(MAC) of input frame.
++ */
++static inline void llc_pdu_decode_sa(struct sk_buff *skb, u8 *sa)
++{
++ if (skb->protocol == ntohs(ETH_P_802_2))
++ memcpy(sa, ((struct ethhdr *)skb->mac.raw)->h_source, ETH_ALEN);
++ else if (skb->protocol == ntohs(ETH_P_TR_802_2))
++ memcpy(sa, ((struct trh_hdr *)skb->mac.raw)->saddr, ETH_ALEN);
++}
++
++/**
++ * llc_pdu_decode_da - extracts dest address of input frame
++ * @skb: input skb that destination address must be extracted from it
++ * @sa: pointer to destination address (6 byte array).
++ *
++ * This function extracts destination address(MAC) of input frame.
++ */
++static inline void llc_pdu_decode_da(struct sk_buff *skb, u8 *da)
++{
++ if (skb->protocol == ntohs(ETH_P_802_2))
++ memcpy(da, ((struct ethhdr *)skb->mac.raw)->h_dest, ETH_ALEN);
++ else if (skb->protocol == ntohs(ETH_P_TR_802_2))
++ memcpy(da, ((struct trh_hdr *)skb->mac.raw)->daddr, ETH_ALEN);
++}
++
++/**
++ * llc_pdu_decode_ssap - extracts source SAP of input frame
++ * @skb: input skb that source SAP must be extracted from it.
++ * @ssap: source SAP (output argument).
++ *
++ * This function extracts source SAP of input frame. Right bit of SSAP is
++ * command/response bit.
++ */
++static inline void llc_pdu_decode_ssap(struct sk_buff *skb, u8 *ssap)
++{
++ *ssap = llc_pdu_un_hdr(skb)->ssap & 0xFE;
++}
++
++/**
++ * llc_pdu_decode_dsap - extracts dest SAP of input frame
++ * @skb: input skb that destination SAP must be extracted from it.
++ * @dsap: destination SAP (output argument).
++ *
++ * This function extracts destination SAP of input frame. right bit of
++ * DSAP designates individual/group SAP.
++ */
++static inline void llc_pdu_decode_dsap(struct sk_buff *skb, u8 *dsap)
++{
++ *dsap = llc_pdu_un_hdr(skb)->dsap & 0xFE;
++}
++
++/**
++ * llc_pdu_init_as_ui_cmd - sets LLC header as UI PDU
++ * @skb: input skb that header must be set into it.
++ *
++ * This function sets third byte of LLC header as a UI PDU.
++ */
++static inline void llc_pdu_init_as_ui_cmd(struct sk_buff *skb)
++{
++ struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
++
++ pdu->ctrl_1 = LLC_PDU_TYPE_U;
++ pdu->ctrl_1 |= LLC_1_PDU_CMD_UI;
++}
++
++/**
++ * llc_pdu_init_as_test_cmd - sets PDU as TEST
++ * @skb - Address of the skb to build
++ *
++ * Sets a PDU as TEST
++ */
++static inline void llc_pdu_init_as_test_cmd(struct sk_buff *skb)
++{
++ struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
++
++ pdu->ctrl_1 = LLC_PDU_TYPE_U;
++ pdu->ctrl_1 |= LLC_1_PDU_CMD_TEST;
++ pdu->ctrl_1 |= LLC_U_PF_BIT_MASK;
++}
++
++/**
++ * llc_pdu_init_as_test_rsp - build TEST response PDU
++ * @skb: Address of the skb to build
++ * @ev_skb: The received TEST command PDU frame
++ *
++ * Builds a pdu frame as a TEST response.
++ */
++static inline void llc_pdu_init_as_test_rsp(struct sk_buff *skb,
++ struct sk_buff *ev_skb)
++{
++ struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
++
++ pdu->ctrl_1 = LLC_PDU_TYPE_U;
++ pdu->ctrl_1 |= LLC_1_PDU_CMD_TEST;
++ pdu->ctrl_1 |= LLC_U_PF_BIT_MASK;
++ if (ev_skb->protocol == ntohs(ETH_P_802_2)) {
++ struct llc_pdu_un *ev_pdu = llc_pdu_un_hdr(ev_skb);
++ int dsize;
++
++ dsize = ntohs(((struct ethhdr *)ev_skb->mac.raw)->h_proto) - 3;
++ memcpy(((u8 *)pdu) + 3, ((u8 *)ev_pdu) + 3, dsize);
++ skb_put(skb, dsize);
++ }
++}
++
+ /* LLC Type 1 XID command/response information fields format */
+ struct llc_xid_info {
+ u8 fmt_id; /* always 0x18 for LLC */
+@@ -227,6 +360,54 @@
+ u8 rw; /* sender receive window */
+ };
+
++/**
++ * llc_pdu_init_as_xid_cmd - sets bytes 3, 4 & 5 of LLC header as XID
++ * @skb: input skb that header must be set into it.
++ *
++ * This function sets third,fourth,fifth and sixth bytes of LLC header as
++ * a XID PDU.
++ */
++static inline void llc_pdu_init_as_xid_cmd(struct sk_buff *skb,
++ u8 svcs_supported, u8 rx_window)
++{
++ struct llc_xid_info *xid_info;
++ struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
++
++ pdu->ctrl_1 = LLC_PDU_TYPE_U;
++ pdu->ctrl_1 |= LLC_1_PDU_CMD_XID;
++ pdu->ctrl_1 |= LLC_U_PF_BIT_MASK;
++ xid_info = (struct llc_xid_info *)(((u8 *)&pdu->ctrl_1) + 1);
++ xid_info->fmt_id = LLC_XID_FMT_ID; /* 0x81 */
++ xid_info->type = svcs_supported;
++ xid_info->rw = rx_window << 1; /* size of receive window */
++ skb_put(skb, 3);
++}
++
++/**
++ * llc_pdu_init_as_xid_rsp - builds XID response PDU
++ * @skb: Address of the skb to build
++ * @svcs_supported: The class of the LLC (I or II)
++ * @rx_window: The size of the receive window of the LLC
++ *
++ * Builds a pdu frame as an XID response.
++ */
++static inline void llc_pdu_init_as_xid_rsp(struct sk_buff *skb,
++ u8 svcs_supported, u8 rx_window)
++{
++ struct llc_xid_info *xid_info;
++ struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
++
++ pdu->ctrl_1 = LLC_PDU_TYPE_U;
++ pdu->ctrl_1 |= LLC_1_PDU_CMD_XID;
++ pdu->ctrl_1 |= LLC_U_PF_BIT_MASK;
++
++ xid_info = (struct llc_xid_info *)(((u8 *)&pdu->ctrl_1) + 1);
++ xid_info->fmt_id = LLC_XID_FMT_ID;
++ xid_info->type = svcs_supported;
++ xid_info->rw = rx_window << 1;
++ skb_put(skb, 3);
++}
++
+ /* LLC Type 2 FRMR response information field format */
+ struct llc_frmr_info {
+ u16 rej_pdu_ctrl; /* bits 1-8 if U-PDU */
+@@ -239,17 +420,6 @@
+ extern void llc_pdu_set_pf_bit(struct sk_buff *skb, u8 bit_value);
+ extern void llc_pdu_decode_pf_bit(struct sk_buff *skb, u8 *pf_bit);
+ extern void llc_pdu_decode_cr_bit(struct sk_buff *skb, u8 *cr_bit);
+-extern void llc_pdu_decode_sa(struct sk_buff *skb, u8 *sa);
+-extern void llc_pdu_decode_da(struct sk_buff *skb, u8 *ds);
+-extern void llc_pdu_decode_dsap(struct sk_buff *skb, u8 *dsap);
+-extern void llc_pdu_decode_ssap(struct sk_buff *skb, u8 *ssap);
+-extern void llc_decode_pdu_type(struct sk_buff *skb, u8 *destination);
+-extern void llc_pdu_header_init(struct sk_buff *skb, u8 pdu_type, u8 ssap,
+- u8 dsap, u8 cr);
+-extern void llc_pdu_init_as_ui_cmd(struct sk_buff *skb);
+-extern void llc_pdu_init_as_xid_cmd(struct sk_buff *skb, u8 svcs_supported,
+- u8 rx_window);
+-extern void llc_pdu_init_as_test_cmd(struct sk_buff *skb);
+ extern void llc_pdu_init_as_disc_cmd(struct sk_buff *skb, u8 p_bit);
+ extern void llc_pdu_init_as_i_cmd(struct sk_buff *skb, u8 p_bit, u8 ns, u8 nr);
+ extern void llc_pdu_init_as_rej_cmd(struct sk_buff *skb, u8 p_bit, u8 nr);
+@@ -257,10 +427,6 @@
+ extern void llc_pdu_init_as_rr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr);
+ extern void llc_pdu_init_as_sabme_cmd(struct sk_buff *skb, u8 p_bit);
+ extern void llc_pdu_init_as_dm_rsp(struct sk_buff *skb, u8 f_bit);
+-extern void llc_pdu_init_as_xid_rsp(struct sk_buff *skb, u8 svcs_supported,
+- u8 rx_window);
+-extern void llc_pdu_init_as_test_rsp(struct sk_buff *skb,
+- struct sk_buff *ev_skb);
+ extern void llc_pdu_init_as_frmr_rsp(struct sk_buff *skb,
+ struct llc_pdu_sn *prev_pdu,
+ u8 f_bit, u8 vs, u8 vr, u8 vzyxw);
+Index: linux-2.6.0-test5/include/net/llc_sap.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/net/llc_sap.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/net/llc_sap.h 2003-09-27 11:38:41.170269552 +0800
+@@ -2,7 +2,7 @@
+ #define LLC_SAP_H
+ /*
+ * Copyright (c) 1997 by Procom Technology,Inc.
+- * 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
++ * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+@@ -11,37 +11,20 @@
+ *
+ * See the GNU General Public License for more details.
+ */
+-#include <linux/skbuff.h>
+-#include <net/llc_if.h>
+-/**
+- * struct llc_sap - Defines the SAP component
+- *
+- * @station - station this sap belongs to
+- * @state - sap state
+- * @p_bit - only lowest-order bit used
+- * @f_bit - only lowest-order bit used
+- * @laddr - SAP value in this 'lsap'
+- * @node - entry in station sap_list
+- * @sk_list - LLC sockets this one manages
+- */
+-struct llc_sap {
+- struct llc_station *station;
+- u8 state;
+- u8 p_bit;
+- u8 f_bit;
+- int (*rcv_func)(struct sk_buff *skb,
+- struct net_device *dev,
+- struct packet_type *pt);
+- struct llc_addr laddr;
+- struct list_head node;
+- struct {
+- rwlock_t lock;
+- struct hlist_head list;
+- } sk_list;
+-};
++struct llc_sap;
++struct sk_buff;
+
+-extern void llc_sap_assign_sock(struct llc_sap *sap, struct sock *sk);
+-extern void llc_sap_unassign_sock(struct llc_sap *sap, struct sock *sk);
+ extern void llc_sap_state_process(struct llc_sap *sap, struct sk_buff *skb);
+ extern void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb);
++extern void llc_save_primitive(struct sk_buff* skb, unsigned char prim);
++extern struct sk_buff *llc_alloc_frame(void);
++
++extern void llc_build_and_send_test_pkt(struct llc_sap *sap,
++ struct sk_buff *skb,
++ unsigned char *dmac,
++ unsigned char dsap);
++extern void llc_build_and_send_xid_pkt(struct llc_sap *sap,
++ struct sk_buff *skb,
++ unsigned char *dmac,
++ unsigned char dsap);
+ #endif /* LLC_SAP_H */
+Index: linux-2.6.0-test5/include/net/llc_s_st.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/net/llc_s_st.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/net/llc_s_st.h 2003-09-27 11:38:41.172269248 +0800
+@@ -11,10 +11,7 @@
+ *
+ * See the GNU General Public License for more details.
+ */
+-/* Defines SAP component states */
+
+-#define LLC_SAP_STATE_INACTIVE 1
+-#define LLC_SAP_STATE_ACTIVE 2
+ #define LLC_NR_SAP_STATES 2 /* size of state table */
+
+ /* structures and types */
+Index: linux-2.6.0-test5/include/net/rose.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/net/rose.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/net/rose.h 2003-09-27 11:38:41.175268792 +0800
+@@ -140,9 +140,6 @@
+
+ #define rose_sk(__sk) ((rose_cb *)(__sk)->sk_protinfo)
+
+-/* Magic value indicating first entry in /proc (ie header) */
+-#define ROSE_PROC_START ((void *) 1)
+-
+ /* af_rose.c */
+ extern ax25_address rose_callsign;
+ extern int sysctl_rose_restart_request_timeout;
+Index: linux-2.6.0-test5/include/net/syncppp.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/net/syncppp.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/net/syncppp.h 2003-09-27 11:38:41.177268488 +0800
+@@ -57,8 +57,11 @@
+ struct sppp sppp; /* Synchronous PPP */
+ };
+
+-#define sppp_of(dev) \
+- (&((struct ppp_device *)(*(unsigned long *)((dev)->priv)))->sppp)
++static inline struct sppp *sppp_of(struct net_device *dev)
++{
++ struct ppp_device *ppp = dev->priv;
++ return &ppp->sppp;
++}
+
+ #define PP_KEEPALIVE 0x01 /* use keepalive protocol */
+ #define PP_CISCO 0x02 /* use Cisco protocol instead of PPP */
+Index: linux-2.6.0-test5/include/pcmcia/ss.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/pcmcia/ss.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/pcmcia/ss.h 2003-09-27 11:38:41.179268184 +0800
+@@ -78,7 +78,6 @@
+ #define SS_DMA_MODE 0x0080
+ #define SS_SPKR_ENA 0x0100
+ #define SS_OUTPUT_ENA 0x0200
+-#define SS_DEBOUNCED 0x0400 /* Tell driver that the debounce delay has ended */
+
+ /* Flags for I/O port and memory windows */
+ #define MAP_ACTIVE 0x01
+@@ -176,7 +175,6 @@
+ u_short functions;
+ u_short lock_count;
+ client_handle_t clients;
+- u_int real_clients;
+ pccard_mem_map cis_mem;
+ u_char *cis_virt;
+ struct config_t *config;
+@@ -249,7 +247,7 @@
+ extern struct class pcmcia_socket_class;
+
+ /* socket drivers are expected to use these callbacks in their .drv struct */
+-extern int pcmcia_socket_dev_suspend(struct device *dev, u32 state, u32 level);
+-extern int pcmcia_socket_dev_resume(struct device *dev, u32 level);
++extern int pcmcia_socket_dev_suspend(struct device *dev, u32 state);
++extern int pcmcia_socket_dev_resume(struct device *dev);
+
+ #endif /* _LINUX_SS_H */
+Index: linux-2.6.0-test5/include/rxrpc/call.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/rxrpc/call.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/rxrpc/call.h 2003-09-27 11:38:41.182267728 +0800
+@@ -67,8 +67,8 @@
+ wait_queue_head_t waitq; /* wait queue for events to happen */
+ struct list_head link; /* general internal list link */
+ struct list_head call_link; /* master call list link */
+- u32 chan_ix; /* connection channel index (net order) */
+- u32 call_id; /* call ID on connection (net order) */
++ uint32_t chan_ix; /* connection channel index (net order) */
++ uint32_t call_id; /* call ID on connection (net order) */
+ unsigned long cjif; /* jiffies at call creation */
+ unsigned long flags; /* control flags */
+ #define RXRPC_CALL_ACKS_TIMO 0x00000001 /* ACKS timeout reached */
+@@ -103,7 +103,7 @@
+ char ackr_dfr_perm; /* request for deferred ACKs permitted */
+ rxrpc_seq_t ackr_dfr_seq; /* seqno for deferred ACK */
+ struct rxrpc_ackpacket ackr; /* pending normal ACK packet */
+- u8 ackr_array[RXRPC_CALL_ACK_WINDOW_SIZE]; /* ACK records */
++ uint8_t ackr_array[RXRPC_CALL_ACK_WINDOW_SIZE]; /* ACK records */
+
+ /* presentation layer */
+ char app_last_rcv; /* T if received last packet from remote end */
+@@ -131,14 +131,14 @@
+ struct list_head app_attn_link; /* application attention list linkage */
+ size_t app_mark; /* trigger callback when app_ready_qty>=app_mark */
+ char app_async_read; /* T if in async-read mode */
+- u8 *app_read_buf; /* application async read buffer (app_mark size) */
+- u8 *app_scr_alloc; /* application scratch allocation pointer */
++ uint8_t *app_read_buf; /* application async read buffer (app_mark size) */
++ uint8_t *app_scr_alloc; /* application scratch allocation pointer */
+ void *app_scr_ptr; /* application pointer into scratch buffer */
+
+ #define RXRPC_APP_MARK_EOF 0xFFFFFFFFU /* mark at end of input */
+
+ /* application scratch buffer */
+- u8 app_scratch[0] __attribute__((aligned(sizeof(long))));
++ uint8_t app_scratch[0] __attribute__((aligned(sizeof(long))));
+ };
+
+ #define RXRPC_CALL_SCRATCH_SIZE (PAGE_SIZE - sizeof(struct rxrpc_call))
+@@ -206,7 +206,7 @@
+ extern int rxrpc_call_write_data(struct rxrpc_call *call,
+ size_t sioc,
+ struct iovec siov[],
+- u8 rxhdr_flags,
++ uint8_t rxhdr_flags,
+ int alloc_flags,
+ int dup_data,
+ size_t *size_sent);
+Index: linux-2.6.0-test5/include/rxrpc/connection.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/rxrpc/connection.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/rxrpc/connection.h 2003-09-27 11:38:41.184267424 +0800
+@@ -34,6 +34,7 @@
+ struct list_head link; /* link in peer's list */
+ struct list_head proc_link; /* link in proc list */
+ struct list_head err_link; /* link in ICMP error processing list */
++ struct list_head id_link; /* link in ID grant list */
+ struct sockaddr_in addr; /* remote address */
+ struct rxrpc_call *channels[4]; /* channels (active calls) */
+ wait_queue_head_t chanwait; /* wait for channel to become available */
+@@ -44,19 +45,19 @@
+ rxrpc_serial_t serial_counter; /* packet serial number counter */
+
+ /* the following should all be in net order */
+- u32 in_epoch; /* peer's epoch */
+- u32 out_epoch; /* my epoch */
+- u32 conn_id; /* connection ID, appropriately shifted */
+- u16 service_id; /* service ID */
+- u8 security_ix; /* security ID */
+- u8 in_clientflag; /* RXRPC_CLIENT_INITIATED if we are server */
+- u8 out_clientflag; /* RXRPC_CLIENT_INITIATED if we are client */
++ uint32_t in_epoch; /* peer's epoch */
++ uint32_t out_epoch; /* my epoch */
++ uint32_t conn_id; /* connection ID, appropriately shifted */
++ uint16_t service_id; /* service ID */
++ uint8_t security_ix; /* security ID */
++ uint8_t in_clientflag; /* RXRPC_CLIENT_INITIATED if we are server */
++ uint8_t out_clientflag; /* RXRPC_CLIENT_INITIATED if we are client */
+ };
+
+ extern int rxrpc_create_connection(struct rxrpc_transport *trans,
+- u16 port,
+- u32 addr,
+- unsigned short service_id,
++ uint16_t port,
++ uint32_t addr,
++ uint16_t service_id,
+ void *security,
+ struct rxrpc_connection **_conn);
+
+Index: linux-2.6.0-test5/include/rxrpc/message.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/rxrpc/message.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/rxrpc/message.h 2003-09-27 11:38:41.185267272 +0800
+@@ -9,8 +9,8 @@
+ * 2 of the License, or (at your option) any later version.
+ */
+
+-#ifndef _H_3AD3363A_3A9C_11D6_83D8_0002B3163499
+-#define _H_3AD3363A_3A9C_11D6_83D8_0002B3163499
++#ifndef _LINUX_RXRPC_MESSAGE_H
++#define _LINUX_RXRPC_MESSAGE_H
+
+ #include <rxrpc/packet.h>
+
+@@ -61,7 +61,7 @@
+
+ extern int rxrpc_conn_newmsg(struct rxrpc_connection *conn,
+ struct rxrpc_call *call,
+- u8 type,
++ uint8_t type,
+ int count,
+ struct iovec diov[],
+ int alloc_flags,
+@@ -69,4 +69,4 @@
+
+ extern int rxrpc_conn_sendmsg(struct rxrpc_connection *conn, struct rxrpc_message *msg);
+
+-#endif /* _H_3AD3363A_3A9C_11D6_83D8_0002B3163499 */
++#endif /* _LINUX_RXRPC_MESSAGE_H */
+Index: linux-2.6.0-test5/include/rxrpc/packet.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/rxrpc/packet.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/rxrpc/packet.h 2003-09-27 11:38:41.188266816 +0800
+@@ -27,21 +27,21 @@
+ */
+ struct rxrpc_header
+ {
+- u32 epoch; /* client boot timestamp */
++ uint32_t epoch; /* client boot timestamp */
+
+- u32 cid; /* connection and channel ID */
++ uint32_t cid; /* connection and channel ID */
+ #define RXRPC_MAXCALLS 4 /* max active calls per conn */
+ #define RXRPC_CHANNELMASK (RXRPC_MAXCALLS-1) /* mask for channel ID */
+ #define RXRPC_CIDMASK (~RXRPC_CHANNELMASK) /* mask for connection ID */
+ #define RXRPC_CIDSHIFT 2 /* shift for connection ID */
+
+- u32 callNumber; /* call ID (0 for connection-level packets) */
++ uint32_t callNumber; /* call ID (0 for connection-level packets) */
+ #define RXRPC_PROCESS_MAXCALLS (1<<2) /* maximum number of active calls per conn (power of 2) */
+
+- u32 seq; /* sequence number of pkt in call stream */
+- u32 serial; /* serial number of pkt sent to network */
++ uint32_t seq; /* sequence number of pkt in call stream */
++ uint32_t serial; /* serial number of pkt sent to network */
+
+- u8 type; /* packet type */
++ uint8_t type; /* packet type */
+ #define RXRPC_PACKET_TYPE_DATA 1 /* data */
+ #define RXRPC_PACKET_TYPE_ACK 2 /* ACK */
+ #define RXRPC_PACKET_TYPE_BUSY 3 /* call reject */
+@@ -52,7 +52,7 @@
+ #define RXRPC_PACKET_TYPE_DEBUG 8 /* debug info request */
+ #define RXRPC_N_PACKET_TYPES 9 /* number of packet types (incl type 0) */
+
+- u8 flags; /* packet flags */
++ uint8_t flags; /* packet flags */
+ #define RXRPC_CLIENT_INITIATED 0x01 /* signifies a packet generated by a client */
+ #define RXRPC_REQUEST_ACK 0x02 /* request an unconditional ACK of this packet */
+ #define RXRPC_LAST_PACKET 0x04 /* the last packet from this side for this call */
+@@ -60,10 +60,10 @@
+ #define RXRPC_JUMBO_PACKET 0x20 /* [DATA] this is a jumbo packet */
+ #define RXRPC_SLOW_START_OK 0x20 /* [ACK] slow start supported */
+
+- u8 userStatus; /* app-layer defined status */
+- u8 securityIndex; /* security protocol ID */
+- u16 _rsvd; /* reserved (used by kerberos security as cksum) */
+- u16 serviceId; /* service ID */
++ uint8_t userStatus; /* app-layer defined status */
++ uint8_t securityIndex; /* security protocol ID */
++ uint16_t _rsvd; /* reserved (used by kerberos security as cksum) */
++ uint16_t serviceId; /* service ID */
+
+ } __attribute__((packed));
+
+@@ -83,9 +83,9 @@
+ */
+ struct rxrpc_jumbo_header
+ {
+- u8 flags; /* packet flags (as per rxrpc_header) */
+- u8 pad;
+- u16 _rsvd; /* reserved (used by kerberos security as cksum) */
++ uint8_t flags; /* packet flags (as per rxrpc_header) */
++ uint8_t pad;
++ uint16_t _rsvd; /* reserved (used by kerberos security as cksum) */
+ };
+
+ #define RXRPC_JUMBO_DATALEN 1412 /* non-terminal jumbo packet data length */
+@@ -97,13 +97,14 @@
+ */
+ struct rxrpc_ackpacket
+ {
+- u16 bufferSpace; /* number of packet buffers available */
+- u16 maxSkew; /* diff between serno being ACK'd and highest serial no received */
+- u32 firstPacket; /* sequence no of first ACK'd packet in attached list */
+- u32 previousPacket; /* sequence no of previous packet received */
+- u32 serial; /* serial no of packet that prompted this ACK */
++ uint16_t bufferSpace; /* number of packet buffers available */
++ uint16_t maxSkew; /* diff between serno being ACK'd and highest serial no
++ * received */
++ uint32_t firstPacket; /* sequence no of first ACK'd packet in attached list */
++ uint32_t previousPacket; /* sequence no of previous packet received */
++ uint32_t serial; /* serial no of packet that prompted this ACK */
+
+- u8 reason; /* reason for ACK */
++ uint8_t reason; /* reason for ACK */
+ #define RXRPC_ACK_REQUESTED 1 /* ACK was requested on packet */
+ #define RXRPC_ACK_DUPLICATE 2 /* duplicate packet received */
+ #define RXRPC_ACK_OUT_OF_SEQUENCE 3 /* out of sequence packet received */
+@@ -114,10 +115,10 @@
+ #define RXRPC_ACK_DELAY 8 /* nothing happened since received packet */
+ #define RXRPC_ACK_IDLE 9 /* ACK due to fully received ACK window */
+
+- u8 nAcks; /* number of ACKs */
++ uint8_t nAcks; /* number of ACKs */
+ #define RXRPC_MAXACKS 255
+
+- u8 acks[0]; /* list of ACK/NAKs */
++ uint8_t acks[0]; /* list of ACK/NAKs */
+ #define RXRPC_ACK_TYPE_NACK 0
+ #define RXRPC_ACK_TYPE_ACK 1
+
+Index: linux-2.6.0-test5/include/rxrpc/peer.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/rxrpc/peer.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/rxrpc/peer.h 2003-09-27 11:38:41.190266512 +0800
+@@ -42,7 +42,10 @@
+ struct rxrpc_timer timeout; /* timeout for grave destruction */
+ struct list_head link; /* link in transport's peer list */
+ struct list_head proc_link; /* link in /proc list */
+- rwlock_t conn_lock; /* lock for connections */
++ rwlock_t conn_idlock; /* lock for connection IDs */
++ struct list_head conn_idlist; /* list of connections granted IDs */
++ uint32_t conn_idcounter; /* connection ID counter */
++ rwlock_t conn_lock; /* lock for active/dead connections */
+ struct list_head conn_active; /* active connections to/from this peer */
+ struct list_head conn_graveyard; /* graveyard for inactive connections */
+ spinlock_t conn_gylock; /* lock for conn_graveyard */
+Index: linux-2.6.0-test5/include/rxrpc/rxrpc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/rxrpc/rxrpc.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/rxrpc/rxrpc.h 2003-09-27 11:38:41.191266360 +0800
+@@ -14,7 +14,7 @@
+
+ #ifdef __KERNEL__
+
+-extern u32 rxrpc_epoch;
++extern uint32_t rxrpc_epoch;
+
+ extern int rxrpc_ktrace;
+ extern int rxrpc_kdebug;
+Index: linux-2.6.0-test5/include/rxrpc/transport.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/rxrpc/transport.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/rxrpc/transport.h 2003-09-27 11:38:41.192266208 +0800
+@@ -85,10 +85,11 @@
+
+ static inline void rxrpc_get_transport(struct rxrpc_transport *trans)
+ {
+- if (atomic_read(&trans->usage)<=0)
++ if (atomic_read(&trans->usage) <= 0)
+ BUG();
+ atomic_inc(&trans->usage);
+- //printk("rxrpc_get_transport(%p{u=%d})\n",trans,atomic_read(&trans->usage));
++ //printk("rxrpc_get_transport(%p{u=%d})\n",
++ // trans, atomic_read(&trans->usage));
+ }
+
+ extern void rxrpc_put_transport(struct rxrpc_transport *trans);
+@@ -99,11 +100,6 @@
+ extern void rxrpc_del_service(struct rxrpc_transport *trans,
+ struct rxrpc_service *srv);
+
+-#if 0
+-extern int rxrpc_trans_add_connection(struct rxrpc_transport *trans,
+- struct rxrpc_connection *conn);
+-#endif
+-
+ extern void rxrpc_trans_receive_packet(struct rxrpc_transport *trans);
+
+ extern int rxrpc_trans_immediate_abort(struct rxrpc_transport *trans,
+Index: linux-2.6.0-test5/include/rxrpc/types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/rxrpc/types.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/rxrpc/types.h 2003-09-27 11:38:41.194265904 +0800
+@@ -19,8 +19,8 @@
+ #include <linux/spinlock.h>
+ #include <asm/atomic.h>
+
+-typedef unsigned rxrpc_seq_t; /* Rx message sequence number */
+-typedef unsigned rxrpc_serial_t; /* Rx message serial number */
++typedef uint32_t rxrpc_seq_t; /* Rx message sequence number */
++typedef uint32_t rxrpc_serial_t; /* Rx message serial number */
+
+ struct rxrpc_call;
+ struct rxrpc_connection;
+Index: linux-2.6.0-test5/include/scsi/scsi_tcq.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/scsi/scsi_tcq.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/scsi/scsi_tcq.h 2003-09-27 11:38:41.195265752 +0800
+@@ -27,7 +27,7 @@
+ {
+ if (sdev->tagged_supported) {
+ if (!blk_queue_tagged(sdev->request_queue))
+- blk_queue_init_tags(sdev->request_queue, depth);
++ blk_queue_init_tags(sdev->request_queue, depth, NULL);
+ scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, depth);
+ }
+ }
+Index: linux-2.6.0-test5/include/video/epson1355.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/video/epson1355.h 2003-09-27 11:38:18.488717672 +0800
++++ linux-2.6.0-test5/include/video/epson1355.h 2003-09-27 11:38:41.196265600 +0800
+@@ -0,0 +1,64 @@
++/*
++ * include/video/epson13xx.h -- Epson 13xx frame buffer
++ *
++ * Copyright (C) Hewlett-Packard Company. All rights reserved.
++ *
++ * Written by Christopher Hoover <ch@hpl.hp.com>
++ *
++ */
++
++#ifndef _EPSON13XX_H_
++#define _EPSON13XX_H_
++
++#define REG_REVISION_CODE 0x00
++#define REG_MEMORY_CONFIG 0x01
++#define REG_PANEL_TYPE 0x02
++#define REG_MOD_RATE 0x03
++#define REG_HORZ_DISP_WIDTH 0x04
++#define REG_HORZ_NONDISP_PERIOD 0x05
++#define REG_HRTC_START_POSITION 0x06
++#define REG_HRTC_PULSE_WIDTH 0x07
++#define REG_VERT_DISP_HEIGHT0 0x08
++#define REG_VERT_DISP_HEIGHT1 0x09
++#define REG_VERT_NONDISP_PERIOD 0x0A
++#define REG_VRTC_START_POSITION 0x0B
++#define REG_VRTC_PULSE_WIDTH 0x0C
++#define REG_DISPLAY_MODE 0x0D
++#define REG_SCRN1_LINE_COMPARE0 0x0E
++#define REG_SCRN1_LINE_COMPARE1 0x0F
++#define REG_SCRN1_DISP_START_ADDR0 0x10
++#define REG_SCRN1_DISP_START_ADDR1 0x11
++#define REG_SCRN1_DISP_START_ADDR2 0x12
++#define REG_SCRN2_DISP_START_ADDR0 0x13
++#define REG_SCRN2_DISP_START_ADDR1 0x14
++#define REG_SCRN2_DISP_START_ADDR2 0x15
++#define REG_MEM_ADDR_OFFSET0 0x16
++#define REG_MEM_ADDR_OFFSET1 0x17
++#define REG_PIXEL_PANNING 0x18
++#define REG_CLOCK_CONFIG 0x19
++#define REG_POWER_SAVE_CONFIG 0x1A
++#define REG_MISC 0x1B
++#define REG_MD_CONFIG_READBACK0 0x1C
++#define REG_MD_CONFIG_READBACK1 0x1D
++#define REG_GPIO_CONFIG0 0x1E
++#define REG_GPIO_CONFIG1 0x1F
++#define REG_GPIO_CONTROL0 0x20
++#define REG_GPIO_CONTROL1 0x21
++#define REG_PERF_ENHANCEMENT0 0x22
++#define REG_PERF_ENHANCEMENT1 0x23
++#define REG_LUT_ADDR 0x24
++#define REG_RESERVED_1 0x25
++#define REG_LUT_DATA 0x26
++#define REG_INK_CURSOR_CONTROL 0x27
++#define REG_CURSOR_X_POSITION0 0x28
++#define REG_CURSOR_X_POSITION1 0x29
++#define REG_CURSOR_Y_POSITION0 0x2A
++#define REG_CURSOR_Y_POSITION1 0x2B
++#define REG_INK_CURSOR_COLOR0_0 0x2C
++#define REG_INK_CURSOR_COLOR0_1 0x2D
++#define REG_INK_CURSOR_COLOR1_0 0x2E
++#define REG_INK_CURSOR_COLOR1_1 0x2F
++#define REG_INK_CURSOR_START_ADDR 0x30
++#define REG_ALTERNATE_FRM 0x31
++
++#endif
+Index: linux-2.6.0-test5/include/video/neomagic.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/video/neomagic.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/video/neomagic.h 2003-09-27 11:38:41.199265144 +0800
+@@ -55,6 +55,20 @@
+ #define NEO_MODE1_X_1600 0x1c00
+ #define NEO_MODE1_BLT_ON_ADDR 0x2000
+
++/* These are offseted in MMIO space by par->CursorOff */
++#define NEOREG_CURSCNTL 0x00
++#define NEOREG_CURSX 0x04
++#define NEOREG_CURSY 0x08
++#define NEOREG_CURSBGCOLOR 0x0C
++#define NEOREG_CURSFGCOLOR 0x10
++#define NEOREG_CURSMEMPOS 0x14
++
++#define NEO_CURS_DISABLE 0x00000000
++#define NEO_CURS_ENABLE 0x00000001
++#define NEO_ICON64_ENABLE 0x00000008
++#define NEO_ICON128_ENABLE 0x0000000C
++#define NEO_ICON_BLANK 0x00000010
++
+ #ifdef __KERNEL__
+
+ #ifdef NEOFB_DEBUG
+@@ -75,45 +89,45 @@
+
+
+ struct xtimings {
+- unsigned int pixclock;
+- unsigned int HDisplay;
+- unsigned int HSyncStart;
+- unsigned int HSyncEnd;
+- unsigned int HTotal;
+- unsigned int VDisplay;
+- unsigned int VSyncStart;
+- unsigned int VSyncEnd;
+- unsigned int VTotal;
+- unsigned int sync;
+- int dblscan;
+- int interlaced;
++ unsigned int pixclock;
++ unsigned int HDisplay;
++ unsigned int HSyncStart;
++ unsigned int HSyncEnd;
++ unsigned int HTotal;
++ unsigned int VDisplay;
++ unsigned int VSyncStart;
++ unsigned int VSyncEnd;
++ unsigned int VTotal;
++ unsigned int sync;
++ int dblscan;
++ int interlaced;
+ };
+
+
+ /* --------------------------------------------------------------------- */
+
+ typedef volatile struct {
+- __u32 bltStat;
+- __u32 bltCntl;
+- __u32 xpColor;
+- __u32 fgColor;
+- __u32 bgColor;
+- __u32 pitch;
+- __u32 clipLT;
+- __u32 clipRB;
+- __u32 srcBitOffset;
+- __u32 srcStart;
+- __u32 reserved0;
+- __u32 dstStart;
+- __u32 xyExt;
+-
+- __u32 reserved1[19];
+-
+- __u32 pageCntl;
+- __u32 pageBase;
+- __u32 postBase;
+- __u32 postPtr;
+- __u32 dataPtr;
++ __u32 bltStat;
++ __u32 bltCntl;
++ __u32 xpColor;
++ __u32 fgColor;
++ __u32 bgColor;
++ __u32 pitch;
++ __u32 clipLT;
++ __u32 clipRB;
++ __u32 srcBitOffset;
++ __u32 srcStart;
++ __u32 reserved0;
++ __u32 dstStart;
++ __u32 xyExt;
++
++ __u32 reserved1[19];
++
++ __u32 pageCntl;
++ __u32 pageBase;
++ __u32 postBase;
++ __u32 postPtr;
++ __u32 dataPtr;
+ } Neo2200;
+
+ #define NR_PALETTE 256
+@@ -124,142 +138,69 @@
+ #define NEO_EXT_GR_MAX 0xC7
+
+ struct neofb_par {
+-
+- unsigned char MiscOutReg; /* Misc */
+- unsigned char CRTC[25]; /* Crtc Controller */
+- unsigned char Sequencer[5]; /* Video Sequencer */
+- unsigned char Graphics[9]; /* Video Graphics */
+- unsigned char Attribute[21]; /* Video Atribute */
+-
+- unsigned char GeneralLockReg;
+- unsigned char ExtCRTDispAddr;
+- unsigned char ExtCRTOffset;
+- unsigned char SysIfaceCntl1;
+- unsigned char SysIfaceCntl2;
+- unsigned char ExtColorModeSelect;
+- unsigned char biosMode;
+-
+- unsigned char PanelDispCntlReg1;
+- unsigned char PanelDispCntlReg2;
+- unsigned char PanelDispCntlReg3;
+- unsigned char PanelVertCenterReg1;
+- unsigned char PanelVertCenterReg2;
+- unsigned char PanelVertCenterReg3;
+- unsigned char PanelVertCenterReg4;
+- unsigned char PanelVertCenterReg5;
+- unsigned char PanelHorizCenterReg1;
+- unsigned char PanelHorizCenterReg2;
+- unsigned char PanelHorizCenterReg3;
+- unsigned char PanelHorizCenterReg4;
+- unsigned char PanelHorizCenterReg5;
+-
+- int ProgramVCLK;
+- unsigned char VCLK3NumeratorLow;
+- unsigned char VCLK3NumeratorHigh;
+- unsigned char VCLK3Denominator;
+- unsigned char VerticalExt;
++ struct vgastate state;
++ atomic_t ref_count;
++
++ unsigned char MiscOutReg; /* Misc */
++ unsigned char CRTC[25]; /* Crtc Controller */
++ unsigned char Sequencer[5]; /* Video Sequencer */
++ unsigned char Graphics[9]; /* Video Graphics */
++ unsigned char Attribute[21]; /* Video Atribute */
++
++ unsigned char GeneralLockReg;
++ unsigned char ExtCRTDispAddr;
++ unsigned char ExtCRTOffset;
++ unsigned char SysIfaceCntl1;
++ unsigned char SysIfaceCntl2;
++ unsigned char ExtColorModeSelect;
++ unsigned char biosMode;
++
++ unsigned char PanelDispCntlReg1;
++ unsigned char PanelDispCntlReg2;
++ unsigned char PanelDispCntlReg3;
++ unsigned char PanelVertCenterReg1;
++ unsigned char PanelVertCenterReg2;
++ unsigned char PanelVertCenterReg3;
++ unsigned char PanelVertCenterReg4;
++ unsigned char PanelVertCenterReg5;
++ unsigned char PanelHorizCenterReg1;
++ unsigned char PanelHorizCenterReg2;
++ unsigned char PanelHorizCenterReg3;
++ unsigned char PanelHorizCenterReg4;
++ unsigned char PanelHorizCenterReg5;
++
++ int ProgramVCLK;
++ unsigned char VCLK3NumeratorLow;
++ unsigned char VCLK3NumeratorHigh;
++ unsigned char VCLK3Denominator;
++ unsigned char VerticalExt;
+
+ #ifdef CONFIG_MTRR
+- int mtrr;
++ int mtrr;
+ #endif
+- u8 *mmio_vbase;
+-
+- Neo2200 *neo2200;
+-
+- /* Panels size */
+- int NeoPanelWidth;
+- int NeoPanelHeight;
+-
+- int maxClock;
+-
+- int pci_burst;
+- int lcd_stretch;
+- int internal_display;
+- int external_display;
+- int libretto;
++ u8 *mmio_vbase;
++ u8 cursorOff;
++ u8 *cursorPad; /* Must die !! */
++
++ Neo2200 *neo2200;
++
++ /* Panels size */
++ int NeoPanelWidth;
++ int NeoPanelHeight;
++
++ int maxClock;
++
++ int pci_burst;
++ int lcd_stretch;
++ int internal_display;
++ int external_display;
++ int libretto;
+ };
+
+ typedef struct {
+- int x_res;
+- int y_res;
+- int mode;
++ int x_res;
++ int y_res;
++ int mode;
+ } biosMode;
+
+-/* vga IO functions */
+-static inline u8 VGArCR (u8 index)
+-{
+- outb (index, 0x3d4);
+- return inb (0x3d5);
+-}
+-
+-static inline void VGAwCR (u8 index, u8 val)
+-{
+- outb (index, 0x3d4);
+- outb (val, 0x3d5);
+-}
+-
+-static inline u8 VGArGR (u8 index)
+-{
+- outb (index, 0x3ce);
+- return inb (0x3cf);
+-}
+-
+-static inline void VGAwGR (u8 index, u8 val)
+-{
+- outb (index, 0x3ce);
+- outb (val, 0x3cf);
+-}
+-
+-static inline u8 VGArSEQ (u8 index)
+-{
+- outb (index, 0x3c4);
+- return inb (0x3c5);
+-}
+-
+-static inline void VGAwSEQ (u8 index, u8 val)
+-{
+- outb (index, 0x3c4);
+- outb (val, 0x3c5);
+-}
+-
+-
+-static int paletteEnabled = 0;
+-
+-static inline void VGAenablePalette (void)
+-{
+- u8 tmp;
+-
+- tmp = inb (0x3da);
+- outb (0x00, 0x3c0);
+- paletteEnabled = 1;
+-}
+-
+-static inline void VGAdisablePalette (void)
+-{
+- u8 tmp;
+-
+- tmp = inb (0x3da);
+- outb (0x20, 0x3c0);
+- paletteEnabled = 0;
+-}
+-
+-static inline void VGAwATTR (u8 index, u8 value)
+-{
+- u8 tmp;
+-
+- if (paletteEnabled)
+- index &= ~0x20;
+- else
+- index |= 0x20;
+-
+- tmp = inb (0x3da);
+- outb (index, 0x3c0);
+- outb (value, 0x3c0);
+-}
+-
+-static inline void VGAwMISC (u8 value)
+-{
+- outb (value, 0x3c2);
+-}
+ #endif
+-
+Index: linux-2.6.0-test5/include/video/sisfb.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/video/sisfb.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/video/sisfb.h 2003-09-27 11:38:41.201264840 +0800
+@@ -6,6 +6,53 @@
+ #include <asm/ioctl.h>
+ #include <asm/types.h>
+
++/* TW: vbflags */
++#define CRT2_DEFAULT 0x00000001
++#define CRT2_LCD 0x00000002 /* TW: Never change the order of the CRT2_XXX entries */
++#define CRT2_TV 0x00000004 /* (see SISCycleCRT2Type()) */
++#define CRT2_VGA 0x00000008
++#define CRT2_ENABLE (CRT2_LCD | CRT2_TV | CRT2_VGA)
++#define VB_DISPTYPE_DISP2 CRT2_ENABLE
++#define VB_DISPTYPE_CRT2 CRT2_ENABLE
++#define TV_NTSC 0x00000010
++#define TV_PAL 0x00000020
++#define TV_HIVISION 0x00000040
++#define TV_HIVISION_LV 0x00000080
++#define TV_TYPE (TV_NTSC | TV_PAL | TV_HIVISION | TV_HIVISION_LV)
++#define TV_AVIDEO 0x00000100
++#define TV_SVIDEO 0x00000200
++#define TV_SCART 0x00000400
++#define TV_INTERFACE (TV_AVIDEO | TV_SVIDEO | TV_SCART | TV_CHSCART | TV_CHHDTV)
++#define VB_USELCDA 0x00000800
++#define TV_PALM 0x00001000
++#define TV_PALN 0x00002000
++#define TV_CHSCART 0x00008000
++#define TV_CHHDTV 0x00010000
++#define VGA2_CONNECTED 0x00040000
++#define VB_DISPTYPE_CRT1 0x00080000 /* CRT1 connected and used */
++#define VBDISPTYPE_DISP1 VB_DISPTYPE_CRT1
++#define VB_301 0x00100000 /* Video bridge type */
++#define VB_301B 0x00200000
++#define VB_302B 0x00400000
++#define VB_30xBDH 0x00800000 /* 30xB DH version (w/o LCD support) */
++#define VB_LVDS 0x01000000
++#define VB_CHRONTEL 0x02000000
++#define VB_301LV 0x04000000
++#define VB_302LV 0x08000000
++#define VB_TRUMPION 0x10000000
++#define VB_VIDEOBRIDGE (VB_301|VB_301B|VB_302B|VB_301LV|VB_302LV| \
++ VB_LVDS|VB_CHRONTEL|VB_TRUMPION)
++#define VB_SISBRIDGE (VB_301|VB_301B|VB_302B|VB_301LV|VB_302LV)
++#define VB_SINGLE_MODE 0x20000000 /* CRT1 or CRT2; determined by VB_DISPTYPE_CRTx */
++#define VB_DISPMODE_SINGLE VB_SINGLE_MODE
++#define VB_MIRROR_MODE 0x40000000 /* CRT1 + CRT2 identical (mirror mode) */
++#define VB_DISPMODE_MIRROR VB_MIRROR_MODE
++#define VB_DUALVIEW_MODE 0x80000000 /* CRT1 + CRT2 independent (dual head mode) */
++#define VB_DISPMODE_DUAL VB_DUALVIEW_MODE
++#define VB_DISPLAY_MODE (VB_SINGLE_MODE | VB_MIRROR_MODE | VB_DUALVIEW_MODE)
++
++
++/* entries for disp_state - deprecated as of 1.6.02 */
+ #define DISPTYPE_CRT1 0x00000008L
+ #define DISPTYPE_CRT2 0x00000004L
+ #define DISPTYPE_LCD 0x00000002L
+@@ -16,6 +63,7 @@
+ #define DISPMODE_MIRROR 0x00000010L
+ #define DISPMODE_DUALVIEW 0x00000040L
+
++/* Deprecated as of 1.6.02 - use vbflags instead */
+ #define HASVB_NONE 0x00
+ #define HASVB_301 0x01
+ #define HASVB_LVDS 0x02
+@@ -39,6 +87,8 @@
+ SIS_650,
+ SIS_740,
+ SIS_330,
++ SIS_660,
++ SIS_760,
+ MAX_SIS_CHIP
+ } SIS_CHIP_TYPE;
+
+@@ -83,13 +133,15 @@
+ struct mode_info minfo;
+ unsigned long iobase;
+ unsigned int mem_size;
+- unsigned long disp_state;
++ unsigned long disp_state; /* deprecated */
+ SIS_CHIP_TYPE chip;
+ unsigned char hasVB;
+- SIS_TV_TYPE TV_type;
+- SIS_TV_PLUG TV_plug;
++ SIS_TV_TYPE TV_type; /* deprecated */
++ SIS_TV_PLUG TV_plug; /* deprecated */
+ unsigned long version;
+- char reserved[256];
++ unsigned long vbflags; /* replaces deprecated entries above */
++ unsigned long currentvbflags;
++ char reserved[248];
+ };
+
+ struct video_info {
+@@ -114,10 +166,10 @@
+ int video_linelength;
+ unsigned int refresh_rate;
+
+- unsigned long disp_state;
+- unsigned char hasVB;
+- unsigned char TV_type;
+- unsigned char TV_plug;
++ unsigned long disp_state; /* DEPRECATED */
++ unsigned char hasVB; /* DEPRECATED */
++ unsigned char TV_type; /* DEPRECATED */
++ unsigned char TV_plug; /* DEPRECATED */
+
+ SIS_CHIP_TYPE chip;
+ unsigned char revision_id;
+@@ -137,7 +189,18 @@
+ unsigned short subsysvendor;
+ unsigned short subsysdevice;
+
+- char reserved[236];
++ unsigned long vbflags; /* Replacing deprecated stuff from above */
++ unsigned long currentvbflags;
++
++ int current_bpp;
++ int current_width;
++ int current_height;
++ int current_htotal;
++ int current_vtotal;
++ __u32 current_pixclock;
++ int current_refresh_rate;
++
++ char reserved[200];
+ };
+
+
+@@ -185,7 +248,13 @@
+
+ unsigned char sisfb_lcda; /* Detected status of LCDA for low res/text modes */
+
+- char reserved[235]; /* for future use */
++ unsigned long sisfb_vbflags;
++ unsigned long sisfb_currentvbflags;
++
++ int sisfb_scalelcd;
++ unsigned long sisfb_specialtiming;
++
++ char reserved[219]; /* for future use */
+ };
+
+ #ifdef __KERNEL__
+Index: linux-2.6.0-test5/init/do_mounts.c
+===================================================================
+--- linux-2.6.0-test5.orig/init/do_mounts.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/init/do_mounts.c 2003-09-27 11:38:41.205264232 +0800
+@@ -76,11 +76,13 @@
+ * Try the %u:%u format -- see print_dev_t()
+ */
+ res = MKDEV(maj, min);
++ if (maj != MAJOR(res) || min != MINOR(res))
++ goto fail;
+ } else {
+ /*
+ * Nope. Try old-style "0321"
+ */
+- res = (dev_t)simple_strtoul(buf, &s, 16);
++ res = new_decode_dev(simple_strtoul(buf, &s, 16));
+ if (*s)
+ goto fail;
+ }
+@@ -107,7 +109,7 @@
+ if (part < range)
+ return res + part;
+ fail:
+- return (dev_t) 0;
++ return 0;
+ }
+
+ /*
+@@ -145,8 +147,10 @@
+
+ if (sscanf(name, "%u:%u", &maj, &min) == 2) {
+ res = MKDEV(maj, min);
++ if (maj != MAJOR(res) || min != MINOR(res))
++ goto fail;
+ } else {
+- res = (dev_t)simple_strtoul(name, &p, 16);
++ res = new_decode_dev(simple_strtoul(name, &p, 16));
+ if (*p)
+ goto fail;
+ }
+@@ -187,7 +191,7 @@
+ sys_rmdir("/sys");
+ return res;
+ fail:
+- res = (dev_t) 0;
++ res = 0;
+ goto done;
+ }
+
+Index: linux-2.6.0-test5/init/do_mounts_devfs.c
+===================================================================
+--- linux-2.6.0-test5.orig/init/do_mounts_devfs.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/init/do_mounts_devfs.c 2003-09-27 11:38:41.206264080 +0800
+@@ -78,9 +78,8 @@
+ /*
+ * recursively scan <path>, looking for a device node of type <dev>
+ */
+-static int __init find_in_devfs(char *path, dev_t dev)
++static int __init find_in_devfs(char *path, unsigned dev)
+ {
+- struct stat buf;
+ char *end = path + strlen(path);
+ int rest = path + 64 - end;
+ int size;
+@@ -96,11 +95,7 @@
+ switch (d->d_type) {
+ case DT_BLK:
+ sprintf(end, "/%s", d->d_name);
+- if (sys_newstat(path, &buf) < 0)
+- break;
+- if (!S_ISBLK(buf.st_mode))
+- break;
+- if (buf.st_rdev != dev)
++ if (bstat(path) != dev)
+ break;
+ kfree(p);
+ return 0;
+@@ -140,7 +135,7 @@
+ if (!dev)
+ return -1;
+ strcpy(path, "/dev");
+- if (find_in_devfs(path, dev) < 0)
++ if (find_in_devfs(path, new_encode_dev(dev)) < 0)
+ return -1;
+ return sys_symlink(path + 5, name);
+ }
+Index: linux-2.6.0-test5/init/do_mounts.h
+===================================================================
+--- linux-2.6.0-test5.orig/init/do_mounts.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/init/do_mounts.h 2003-09-27 11:38:41.208263776 +0800
+@@ -10,7 +10,7 @@
+ #include <linux/root_dev.h>
+
+ asmlinkage long sys_unlink(const char *name);
+-asmlinkage long sys_mknod(const char *name, int mode, dev_t dev);
++asmlinkage long sys_mknod(const char *name, int mode, unsigned dev);
+ asmlinkage long sys_newstat(char * filename, struct stat * statbuf);
+ asmlinkage long sys_ioctl(int fd, int cmd, unsigned long arg);
+ asmlinkage long sys_mkdir(const char *name, int mode);
+@@ -43,11 +43,36 @@
+ static inline int create_dev(char *name, dev_t dev, char *devfs_name)
+ {
+ sys_unlink(name);
+- return sys_mknod(name, S_IFBLK|0600, dev);
++ return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
+ }
+
+ #endif
+
++#if BITS_PER_LONG == 32
++asmlinkage long sys_stat64(char *name, struct stat64 *stat);
++static inline u32 bstat(char *name)
++{
++ struct stat64 stat;
++ if (!sys_stat64(name, &stat) != 0)
++ return 0;
++ if (!S_ISBLK(stat.st_mode))
++ return 0;
++ if (stat.st_rdev != (u32)stat.st_rdev)
++ return 0;
++ return stat.st_rdev;
++}
++#else
++static inline u32 bstat(char *name)
++{
++ struct stat stat;
++ if (!sys_newstat(name, &stat) != 0)
++ return 0;
++ if (!S_ISBLK(stat.st_mode))
++ return 0;
++ return stat.st_rdev;
++}
++#endif
++
+ #ifdef CONFIG_BLK_DEV_RAM
+
+ int __init rd_load_disk(int n);
+@@ -79,4 +104,3 @@
+ static inline void md_run_setup(void) {}
+
+ #endif
+-
+Index: linux-2.6.0-test5/init/do_mounts_initrd.c
+===================================================================
+--- linux-2.6.0-test5.orig/init/do_mounts_initrd.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/init/do_mounts_initrd.c 2003-09-27 11:38:41.209263624 +0800
+@@ -40,7 +40,7 @@
+ int error;
+ int i, pid;
+
+- real_root_dev = ROOT_DEV;
++ real_root_dev = new_encode_dev(ROOT_DEV);
+ create_dev("/dev/root.old", Root_RAM0, NULL);
+ /* mount initrd on rootfs' /root */
+ mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
+@@ -69,12 +69,12 @@
+ close(root_fd);
+ umount_devfs("/old/dev");
+
+- if (real_root_dev == Root_RAM0) {
++ if (new_decode_dev(real_root_dev) == Root_RAM0) {
+ sys_chdir("/old");
+ return;
+ }
+
+- ROOT_DEV = real_root_dev;
++ ROOT_DEV = new_decode_dev(real_root_dev);
+ mount_root();
+
+ printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
+Index: linux-2.6.0-test5/init/do_mounts_md.c
+===================================================================
+--- linux-2.6.0-test5.orig/init/do_mounts_md.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/init/do_mounts_md.c 2003-09-27 11:38:41.212263168 +0800
+@@ -124,7 +124,7 @@
+ for (i = 0; i < MD_SB_DISKS && devname != 0; i++) {
+ char *p;
+ char comp_name[64];
+- struct stat buf;
++ u32 rdev;
+
+ p = strchr(devname, ',');
+ if (p)
+@@ -134,9 +134,9 @@
+ if (strncmp(devname, "/dev/", 5) == 0)
+ devname += 5;
+ snprintf(comp_name, 63, "/dev/%s", devname);
+- if (sys_newstat(comp_name, &buf) == 0 &&
+- S_ISBLK(buf.st_mode))
+- dev = buf.st_rdev;
++ rdev = bstat(comp_name);
++ if (rdev)
++ dev = new_decode_dev(rdev);
+ if (!dev) {
+ printk(KERN_WARNING "md: Unknown device name: %s\n", devname);
+ break;
+Index: linux-2.6.0-test5/init/do_mounts_rd.c
+===================================================================
+--- linux-2.6.0-test5.orig/init/do_mounts_rd.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/init/do_mounts_rd.c 2003-09-27 11:38:41.215262712 +0800
+@@ -332,7 +332,7 @@
+
+ insize = read(crd_infd, inbuf, INBUFSIZ);
+ if (insize == 0) {
+- error("RAMDISK: ran out of compressed data\n");
++ error("RAMDISK: ran out of compressed data");
+ return -1;
+ }
+
+@@ -369,7 +369,7 @@
+
+ static void __init error(char *x)
+ {
+- printk(KERN_ERR "%s", x);
++ printk(KERN_ERR "%s\n", x);
+ exit_code = 1;
+ unzip_error = 1;
+ }
+Index: linux-2.6.0-test5/init/initramfs.c
+===================================================================
+--- linux-2.6.0-test5.orig/init/initramfs.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/init/initramfs.c 2003-09-27 11:38:41.219262104 +0800
+@@ -24,7 +24,7 @@
+ }
+
+ asmlinkage long sys_mkdir(char *name, int mode);
+-asmlinkage long sys_mknod(char *name, int mode, dev_t dev);
++asmlinkage long sys_mknod(char *name, int mode, unsigned dev);
+ asmlinkage long sys_symlink(char *old, char *new);
+ asmlinkage long sys_link(char *old, char *new);
+ asmlinkage long sys_write(int fd, const char *buf, size_t size);
+@@ -92,7 +92,7 @@
+ static __initdata unsigned long body_len, name_len;
+ static __initdata uid_t uid;
+ static __initdata gid_t gid;
+-static __initdata dev_t rdev;
++static __initdata unsigned rdev;
+
+ static void __init parse_header(char *s)
+ {
+@@ -113,7 +113,7 @@
+ body_len = parsed[6];
+ major = parsed[7];
+ minor = parsed[8];
+- rdev = MKDEV(parsed[9], parsed[10]);
++ rdev = new_encode_dev(MKDEV(parsed[9], parsed[10]));
+ name_len = parsed[11];
+ }
+
+@@ -248,7 +248,6 @@
+ next_state = Reset;
+ return 0;
+ }
+- printk(KERN_INFO "-> %s\n", collected);
+ if (S_ISREG(mode)) {
+ if (maybe_link() >= 0) {
+ wfd = sys_open(collected, O_WRONLY|O_CREAT, mode);
+@@ -261,11 +260,13 @@
+ } else if (S_ISDIR(mode)) {
+ sys_mkdir(collected, mode);
+ sys_chown(collected, uid, gid);
++ sys_chmod(collected, mode);
+ } else if (S_ISBLK(mode) || S_ISCHR(mode) ||
+ S_ISFIFO(mode) || S_ISSOCK(mode)) {
+ if (maybe_link() == 0) {
+ sys_mknod(collected, mode, rdev);
+ sys_chown(collected, uid, gid);
++ sys_chmod(collected, mode);
+ }
+ } else
+ panic("populate_root: bogus mode: %o\n", mode);
+Index: linux-2.6.0-test5/init/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/init/Kconfig 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/init/Kconfig 2003-09-27 11:38:41.222261648 +0800
+@@ -143,24 +143,24 @@
+ This option enables the complete Linux kernel ".config" file
+ contents, information on compiler used to build the kernel,
+ kernel running when this kernel was built and kernel version
+- from Makefile to be saved in kernel. It provides documentation
++ from Makefile to be saved in the kernel. It provides documentation
+ of which kernel options are used in a running kernel or in an
+ on-disk kernel. This information can be extracted from the kernel
+ image file with the script scripts/extract-ikconfig and used as
+ input to rebuild the current kernel or to build another kernel.
+ It can also be extracted from a running kernel by reading
+- /proc/ikconfig/config and /proc/ikconfig/built_with, if enabled.
+- /proc/ikconfig/config will list the configuration that was used
+- to build the kernel and /proc/ikconfig/built_with will list
++ /proc/config.gz and /proc/config_built_with, if enabled (below).
++ /proc/config.gz will list the configuration that was used
++ to build the kernel and /proc/config_built_with will list
+ information on the compiler and host machine that was used to
+ build the kernel.
+
+ config IKCONFIG_PROC
+- bool "Enable access to .config through /proc/ikconfig"
++ bool "Enable access to .config through /proc/config.gz"
+ depends on IKCONFIG && PROC_FS
+ ---help---
+ This option enables access to kernel configuration file and build
+- information through /proc/ikconfig.
++ information through /proc/config.gz.
+
+
+ menuconfig EMBEDDED
+@@ -204,15 +204,22 @@
+ config MODULES
+ bool "Enable loadable module support"
+ help
+- Kernel modules are small pieces of compiled code which can be
+- inserted in or removed from the running kernel, using the programs
+- insmod and rmmod. This is described in the file
+- <file:Documentation/modules.txt>, including the fact that you have
+- to say "make modules" in order to compile the modules that you chose
+- during kernel configuration. Modules can be device drivers, file
+- systems, binary executable formats, and so on. If you think that you
+- may want to make use of modules with this kernel in the future, then
+- say Y here. If unsure, say Y.
++ Kernel modules are small pieces of compiled code which can
++ be inserted in the running kernel, rather than being
++ permanently built into the kernel. You use the "modprobe"
++ tool to add (and sometimes remove) them. If you say Y here,
++ many parts of the kernel can be built as modules (by
++ answering M instead of Y where indicated): this is most
++ useful for infrequently used options which are not required
++ for booting. For more information, see the man pages for
++ modprobe, lsmod, modinfo, insmod and rmmod.
++
++ If you say Y here, you will need to run "make
++ modules_install" to put the modules under /lib/modules/
++ where modprobe can find them (you may need to be root to do
++ this).
++
++ If unsure, say Y.
+
+ config MODULE_UNLOAD
+ bool "Module unloading"
+@@ -251,21 +258,18 @@
+ compiled for different kernels, by adding enough information
+ to the modules to (hopefully) spot any changes which would
+ make them incompatible with the kernel you are running. If
+- you say Y here, you will need a copy of genksyms. If
+ unsure, say N.
+
+ config KMOD
+- bool "Kernel module loader"
++ bool "Automatic kernel module loading"
+ depends on MODULES
+ help
+- Normally when you have selected some drivers and/or file systems to
+- be created as loadable modules, you also have the responsibility to
+- load the corresponding modules (using the programs insmod or
+- modprobe) before you can use them. If you say Y here however, the
+- kernel will be able to load modules for itself: when a part of the
+- kernel needs a module, it runs modprobe with the appropriate
+- arguments, thereby loading the module if it is available. (This is a
+- replacement for kerneld.) Say Y here and read about configuring it
+- in <file:Documentation/kmod.txt>.
++ Normally when you have selected some parts of the kernel to
++ be created as kernel modules, you must load them (using the
++ "modprobe" command) before you can use them. If you say Y
++ here, some parts of the kernel will be able to load modules
++ automatically: when a part of the kernel needs a module, it
++ runs modprobe with the appropriate arguments, thereby
++ loading the module if it is available. If unsure, say Y.
+
+ endmenu
+Index: linux-2.6.0-test5/init/main.c
+===================================================================
+--- linux-2.6.0-test5.orig/init/main.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/init/main.c 2003-09-27 11:38:41.227260888 +0800
+@@ -542,12 +542,16 @@
+ spawn_ksoftirqd();
+ }
+
++static void run_init_process(char *init_filename)
++{
++ argv_init[0] = init_filename;
++ execve(init_filename, argv_init, envp_init);
++}
++
+ extern void prepare_namespace(void);
+
+ static int init(void * unused)
+ {
+- static char * argv_sh[] = { "sh", NULL, };
+-
+ lock_kernel();
+ /*
+ * Tell the world that we're going to be the grim
+@@ -592,10 +596,12 @@
+ */
+
+ if (execute_command)
+- execve(execute_command,argv_init,envp_init);
+- execve("/sbin/init",argv_init,envp_init);
+- execve("/etc/init",argv_init,envp_init);
+- execve("/bin/init",argv_init,envp_init);
+- execve("/bin/sh",argv_sh,envp_init);
++ run_init_process(execute_command);
++
++ run_init_process("/sbin/init");
++ run_init_process("/etc/init");
++ run_init_process("/bin/init");
++ run_init_process("/bin/sh");
++
+ panic("No init found. Try passing init= option to kernel.");
+ }
+Index: linux-2.6.0-test5/ipc/sem.c
+===================================================================
+--- linux-2.6.0-test5.orig/ipc/sem.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/ipc/sem.c 2003-09-27 11:38:41.235259672 +0800
+@@ -1038,8 +1038,10 @@
+ * allocated an undo structure, it was invalidated by an RMID
+ * and now a new array with received the same id. Check and retry.
+ */
+- if (un && un->semid == -1)
++ if (un && un->semid == -1) {
++ sem_unlock(sma);
+ goto retry_undos;
++ }
+ error = -EFBIG;
+ if (max >= sma->sem_nsems)
+ goto out_unlock_free;
+Index: linux-2.6.0-test5/kernel/acct.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/acct.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/acct.c 2003-09-27 11:38:41.238259216 +0800
+@@ -342,7 +342,7 @@
+ ac.ac_stime = encode_comp_t(current->stime);
+ ac.ac_uid = current->uid;
+ ac.ac_gid = current->gid;
+- ac.ac_tty = current->tty ? current->tty->device : 0;
++ ac.ac_tty = current->tty ? tty_devnum(current->tty) : 0;
+
+ ac.ac_flag = 0;
+ if (current->flags & PF_FORKNOEXEC)
+Index: linux-2.6.0-test5/kernel/configs.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/configs.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/configs.c 2003-09-27 11:38:41.241258760 +0800
+@@ -23,6 +23,7 @@
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
++#include <linux/config.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/proc_fs.h>
+@@ -35,129 +36,74 @@
+ /**************************************************/
+ /* the actual current config file */
+
++/* This one is for extraction from the kernel binary file image. */
+ #include "ikconfig.h"
+
+ #ifdef CONFIG_IKCONFIG_PROC
+
++/* This is the data that can be read from /proc/config.gz. */
++#include "config_data.h"
++
+ /**************************************************/
+ /* globals and useful constants */
+
+-static const char IKCONFIG_NAME[] = "ikconfig";
+-static const char IKCONFIG_VERSION[] = "0.6";
+-
+-static int ikconfig_size;
+-static struct proc_dir_entry *ikconfig_dir;
++static const char IKCONFIG_VERSION[] __initdata = "0.7";
+
+ static ssize_t
+-ikconfig_read(struct file *file, char __user *buf,
+- size_t len, loff_t *offset)
++ikconfig_read_current(struct file *file, char __user *buf,
++ size_t len, loff_t * offset)
+ {
+ loff_t pos = *offset;
+ ssize_t count;
+-
+- if (pos >= ikconfig_size)
++
++ if (pos >= kernel_config_data_size)
+ return 0;
+
+- count = min(len, (size_t)(ikconfig_size - pos));
+- if(copy_to_user(buf, ikconfig_config + pos, count))
++ count = min(len, (size_t)(kernel_config_data_size - pos));
++ if(copy_to_user(buf, kernel_config_data + pos, count))
+ return -EFAULT;
+
+ *offset += count;
+ return count;
+ }
+
+-static struct file_operations config_fops = {
++static struct file_operations ikconfig_file_ops = {
+ .owner = THIS_MODULE,
+- .read = ikconfig_read,
++ .read = ikconfig_read_current,
+ };
+
+ /***************************************************/
+-/* built_with_show: let people read the info */
+-/* we have on the tools used to build this kernel */
+-
+-static int builtwith_show(struct seq_file *seq, void *v)
+-{
+- seq_printf(seq,
+- "Kernel: %s\nCompiler: %s\nVersion_in_Makefile: %s\n",
+- ikconfig_built_with, LINUX_COMPILER, UTS_RELEASE);
+- return 0;
+-}
+-
+-static int built_with_open(struct inode *inode, struct file *file)
+-{
+- return single_open(file, builtwith_show, PDE(inode)->data);
+-}
+-
+-static struct file_operations builtwith_fops = {
+- .owner = THIS_MODULE,
+- .open = built_with_open,
+- .read = seq_read,
+- .llseek = seq_lseek,
+- .release = single_release,
+-};
+-
+-/***************************************************/
+ /* ikconfig_init: start up everything we need to */
+
+-int __init
+-ikconfig_init(void)
++static int __init ikconfig_init(void)
+ {
+ struct proc_dir_entry *entry;
+
+- printk(KERN_INFO "ikconfig %s with /proc/ikconfig\n",
++ printk(KERN_INFO "ikconfig %s with /proc/config*\n",
+ IKCONFIG_VERSION);
+
+- /* create the ikconfig directory */
+- ikconfig_dir = proc_mkdir(IKCONFIG_NAME, NULL);
+- if (ikconfig_dir == NULL)
+- goto leave;
+- ikconfig_dir->owner = THIS_MODULE;
+-
+ /* create the current config file */
+- entry = create_proc_entry("config", S_IFREG | S_IRUGO, ikconfig_dir);
++ entry = create_proc_entry("config.gz", S_IFREG | S_IRUGO,
++ &proc_root);
+ if (!entry)
+- goto leave2;
++ return -ENOMEM;
+
+- entry->proc_fops = &config_fops;
+- entry->size = ikconfig_size = strlen(ikconfig_config);
+-
+- /* create the "built with" file */
+- entry = create_proc_entry("built_with", S_IFREG | S_IRUGO,
+- ikconfig_dir);
+- if (!entry)
+- goto leave3;
+- entry->proc_fops = &builtwith_fops;
++ entry->proc_fops = &ikconfig_file_ops;
++ entry->size = kernel_config_data_size;
+
+ return 0;
+-
+-leave3:
+- /* remove the file from proc */
+- remove_proc_entry("config", ikconfig_dir);
+-
+-leave2:
+- /* remove the ikconfig directory */
+- remove_proc_entry(IKCONFIG_NAME, NULL);
+-
+-leave:
+- return -ENOMEM;
+ }
+
+ /***************************************************/
+-/* cleanup_ikconfig: clean up our mess */
++/* ikconfig_cleanup: clean up our mess */
+
+-static void
+-cleanup_ikconfig(void)
++static void __exit ikconfig_cleanup(void)
+ {
+- /* remove the files */
+- remove_proc_entry("config", ikconfig_dir);
+- remove_proc_entry("built_with", ikconfig_dir);
+-
+- /* remove the ikconfig directory */
+- remove_proc_entry(IKCONFIG_NAME, NULL);
++ remove_proc_entry("config.gz", &proc_root);
+ }
+
+ module_init(ikconfig_init);
+-module_exit(cleanup_ikconfig);
++module_exit(ikconfig_cleanup);
+
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("Randy Dunlap");
+Index: linux-2.6.0-test5/kernel/exit.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/exit.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/exit.c 2003-09-27 11:38:41.248257696 +0800
+@@ -152,7 +152,7 @@
+ || p->state >= TASK_ZOMBIE
+ || p->real_parent->pid == 1)
+ continue;
+- if (p->real_parent->pgrp != pgrp
++ if (process_group(p->real_parent) != pgrp
+ && p->real_parent->session == p->session) {
+ ret = 0;
+ break;
+@@ -247,9 +247,9 @@
+ curr->session = session;
+ attach_pid(curr, PIDTYPE_SID, session);
+ }
+- if (curr->pgrp != pgrp) {
++ if (process_group(curr) != pgrp) {
+ detach_pid(curr, PIDTYPE_PGID);
+- curr->pgrp = pgrp;
++ curr->group_leader->__pgrp = pgrp;
+ attach_pid(curr, PIDTYPE_PGID, pgrp);
+ }
+ }
+@@ -508,9 +508,9 @@
+ * than we are, and it was the only connection
+ * outside, so the child pgrp is now orphaned.
+ */
+- if ((p->pgrp != father->pgrp) &&
++ if ((process_group(p) != process_group(father)) &&
+ (p->session == father->session)) {
+- int pgrp = p->pgrp;
++ int pgrp = process_group(p);
+
+ if (will_become_orphaned_pgrp(pgrp, NULL) && has_stopped_jobs(pgrp)) {
+ __kill_pg_info(SIGHUP, (void *)1, pgrp);
+@@ -618,12 +618,12 @@
+
+ t = tsk->real_parent;
+
+- if ((t->pgrp != tsk->pgrp) &&
++ if ((process_group(t) != process_group(tsk)) &&
+ (t->session == tsk->session) &&
+- will_become_orphaned_pgrp(tsk->pgrp, tsk) &&
+- has_stopped_jobs(tsk->pgrp)) {
+- __kill_pg_info(SIGHUP, (void *)1, tsk->pgrp);
+- __kill_pg_info(SIGCONT, (void *)1, tsk->pgrp);
++ will_become_orphaned_pgrp(process_group(tsk), tsk) &&
++ has_stopped_jobs(process_group(tsk))) {
++ __kill_pg_info(SIGHUP, (void *)1, process_group(tsk));
++ __kill_pg_info(SIGCONT, (void *)1, process_group(tsk));
+ }
+
+ /* Let father know we died
+@@ -813,10 +813,10 @@
+ if (p->pid != pid)
+ return 0;
+ } else if (!pid) {
+- if (p->pgrp != current->pgrp)
++ if (process_group(p) != process_group(current))
+ return 0;
+ } else if (pid != -1) {
+- if (p->pgrp != -pid)
++ if (process_group(p) != -pid)
+ return 0;
+ }
+
+Index: linux-2.6.0-test5/kernel/fork.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/fork.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/fork.c 2003-09-27 11:38:41.256256480 +0800
+@@ -121,7 +121,12 @@
+ {
+ unsigned long flags;
+
+- __set_current_state(state);
++ /*
++ * don't alter the task state if this is just going to
++ * queue an async wait queue callback
++ */
++ if (is_sync_wait(wait))
++ __set_current_state(state);
+ wait->flags &= ~WQ_FLAG_EXCLUSIVE;
+ spin_lock_irqsave(&q->lock, flags);
+ if (list_empty(&wait->task_list))
+@@ -134,7 +139,12 @@
+ {
+ unsigned long flags;
+
+- __set_current_state(state);
++ /*
++ * don't alter the task state if this is just going to
++ * queue an async wait queue callback
++ */
++ if (is_sync_wait(wait))
++ __set_current_state(state);
+ wait->flags |= WQ_FLAG_EXCLUSIVE;
+ spin_lock_irqsave(&q->lock, flags);
+ if (list_empty(&wait->task_list))
+@@ -305,7 +315,7 @@
+ return retval;
+ fail_nomem:
+ retval = -ENOMEM;
+- fail:
++fail:
+ vm_unacct_memory(charge);
+ goto out;
+ }
+@@ -499,7 +509,7 @@
+ goto fail_nomem;
+
+ if (init_new_context(tsk,mm))
+- goto free_pt;
++ goto fail_nocontext;
+
+ retval = dup_mmap(mm, oldmm);
+ if (retval)
+@@ -514,6 +524,15 @@
+ mmput(mm);
+ fail_nomem:
+ return retval;
++
++fail_nocontext:
++ /*
++ * If init_new_context() failed, we cannot use mmput() to free the mm
++ * because it calls destroy_context()
++ */
++ mm_free_pgd(mm);
++ free_mm(mm);
++ return retval;
+ }
+
+ static inline struct fs_struct *__copy_fs_struct(struct fs_struct *old)
+@@ -868,6 +887,7 @@
+ p->start_time = get_jiffies_64();
+ p->security = NULL;
+ p->io_context = NULL;
++ p->io_wait = NULL;
+
+ retval = -ENOMEM;
+ if ((retval = security_task_alloc(p)))
+@@ -925,7 +945,7 @@
+ */
+ p->first_time_slice = 1;
+ current->time_slice >>= 1;
+- p->last_run = jiffies;
++ p->timestamp = sched_clock();
+ if (!current->time_slice) {
+ /*
+ * This case is rare, it happens when the parent has only
+@@ -1004,7 +1024,7 @@
+ attach_pid(p, PIDTYPE_PID, p->pid);
+ if (thread_group_leader(p)) {
+ attach_pid(p, PIDTYPE_TGID, p->tgid);
+- attach_pid(p, PIDTYPE_PGID, p->pgrp);
++ attach_pid(p, PIDTYPE_PGID, process_group(p));
+ attach_pid(p, PIDTYPE_SID, p->session);
+ if (p->pid)
+ __get_cpu_var(process_counts)++;
+Index: linux-2.6.0-test5/kernel/futex.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/futex.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/futex.c 2003-09-27 11:38:41.261255720 +0800
+@@ -33,7 +33,7 @@
+ #include <linux/poll.h>
+ #include <linux/fs.h>
+ #include <linux/file.h>
+-#include <linux/hash.h>
++#include <linux/jhash.h>
+ #include <linux/init.h>
+ #include <linux/futex.h>
+ #include <linux/mount.h>
+@@ -44,6 +44,7 @@
+ /*
+ * Futexes are matched on equal values of this key.
+ * The key type depends on whether it's a shared or private mapping.
++ * Don't rearrange members without looking at hash_futex().
+ */
+ union futex_key {
+ struct {
+@@ -79,9 +80,15 @@
+ struct file *filp;
+ };
+
+-/* The key for the hash is the address + index + offset within page */
+-static struct list_head futex_queues[1<<FUTEX_HASHBITS];
+-static spinlock_t futex_lock = SPIN_LOCK_UNLOCKED;
++/*
++ * Split the global futex_lock into every hash list lock.
++ */
++struct futex_hash_bucket {
++ spinlock_t lock;
++ struct list_head chain;
++};
++
++static struct futex_hash_bucket futex_queues[1<<FUTEX_HASHBITS];
+
+ /* Futex-fs vfsmount entry: */
+ static struct vfsmount *futex_mnt;
+@@ -89,11 +96,12 @@
+ /*
+ * We hash on the keys returned from get_futex_key (see below).
+ */
+-static inline struct list_head *hash_futex(union futex_key *key)
++static struct futex_hash_bucket *hash_futex(union futex_key *key)
+ {
+- return &futex_queues[hash_long(key->both.word
+- + (unsigned long) key->both.ptr
+- + key->both.offset, FUTEX_HASHBITS)];
++ u32 hash = jhash2((u32*)&key->both.word,
++ (sizeof(key->both.word)+sizeof(key->both.ptr))/4,
++ key->both.offset);
++ return &futex_queues[hash & ((1 << FUTEX_HASHBITS)-1)];
+ }
+
+ /*
+@@ -214,6 +222,7 @@
+ static int futex_wake(unsigned long uaddr, int num)
+ {
+ struct list_head *i, *next, *head;
++ struct futex_hash_bucket *bh;
+ union futex_key key;
+ int ret;
+
+@@ -223,9 +232,10 @@
+ if (unlikely(ret != 0))
+ goto out;
+
+- head = hash_futex(&key);
++ bh = hash_futex(&key);
++ spin_lock(&bh->lock);
++ head = &bh->chain;
+
+- spin_lock(&futex_lock);
+ list_for_each_safe(i, next, head) {
+ struct futex_q *this = list_entry(i, struct futex_q, list);
+
+@@ -239,7 +249,7 @@
+ break;
+ }
+ }
+- spin_unlock(&futex_lock);
++ spin_unlock(&bh->lock);
+
+ out:
+ up_read(¤t->mm->mmap_sem);
+@@ -254,6 +264,7 @@
+ int nr_wake, int nr_requeue)
+ {
+ struct list_head *i, *next, *head1, *head2;
++ struct futex_hash_bucket *bh1, *bh2;
+ union futex_key key1, key2;
+ int ret;
+
+@@ -266,10 +277,19 @@
+ if (unlikely(ret != 0))
+ goto out;
+
+- head1 = hash_futex(&key1);
+- head2 = hash_futex(&key2);
++ bh1 = hash_futex(&key1);
++ bh2 = hash_futex(&key2);
++ if (bh1 < bh2) {
++ spin_lock(&bh1->lock);
++ spin_lock(&bh2->lock);
++ } else {
++ spin_lock(&bh2->lock);
++ if (bh1 > bh2)
++ spin_lock(&bh1->lock);
++ }
++ head1 = &bh1->chain;
++ head2 = &bh2->chain;
+
+- spin_lock(&futex_lock);
+ list_for_each_safe(i, next, head1) {
+ struct futex_q *this = list_entry(i, struct futex_q, list);
+
+@@ -291,38 +311,46 @@
+ }
+ }
+ }
+- spin_unlock(&futex_lock);
+-
++ if (bh1 < bh2) {
++ spin_unlock(&bh2->lock);
++ spin_unlock(&bh1->lock);
++ } else {
++ if (bh1 > bh2)
++ spin_unlock(&bh1->lock);
++ spin_unlock(&bh2->lock);
++ }
+ out:
+ up_read(¤t->mm->mmap_sem);
+ return ret;
+ }
+
+-static inline void queue_me(struct futex_q *q, union futex_key *key,
++static void queue_me(struct futex_q *q, union futex_key *key,
+ int fd, struct file *filp)
+ {
+- struct list_head *head = hash_futex(key);
++ struct futex_hash_bucket *bh = hash_futex(key);
++ struct list_head *head = &bh->chain;
+
+ q->key = *key;
+ q->fd = fd;
+ q->filp = filp;
+
+- spin_lock(&futex_lock);
++ spin_lock(&bh->lock);
+ list_add_tail(&q->list, head);
+- spin_unlock(&futex_lock);
++ spin_unlock(&bh->lock);
+ }
+
+ /* Return 1 if we were still queued (ie. 0 means we were woken) */
+-static inline int unqueue_me(struct futex_q *q)
++static int unqueue_me(struct futex_q *q)
+ {
++ struct futex_hash_bucket *bh = hash_futex(&q->key);
+ int ret = 0;
+
+- spin_lock(&futex_lock);
++ spin_lock(&bh->lock);
+ if (!list_empty(&q->list)) {
+ list_del(&q->list);
+ ret = 1;
+ }
+- spin_unlock(&futex_lock);
++ spin_unlock(&bh->lock);
+ return ret;
+ }
+
+@@ -332,8 +360,8 @@
+ int ret, curval;
+ union futex_key key;
+ struct futex_q q;
++ struct futex_hash_bucket *bh = NULL;
+
+- try_again:
+ init_waitqueue_head(&q.waiters);
+
+ down_read(¤t->mm->mmap_sem);
+@@ -367,25 +395,26 @@
+ /*
+ * There might have been scheduling since the queue_me(), as we
+ * cannot hold a spinlock across the get_user() in case it
+- * faults. So we cannot just set TASK_INTERRUPTIBLE state when
++ * faults, and we cannot just set TASK_INTERRUPTIBLE state when
+ * queueing ourselves into the futex hash. This code thus has to
+- * rely on the futex_wake() code doing a wakeup after removing
+- * the waiter from the list.
++ * rely on the futex_wake() code removing us from hash when it
++ * wakes us up.
+ */
+ add_wait_queue(&q.waiters, &wait);
+- spin_lock(&futex_lock);
++ bh = hash_futex(&key);
++ spin_lock(&bh->lock);
+ set_current_state(TASK_INTERRUPTIBLE);
+
+ if (unlikely(list_empty(&q.list))) {
+ /*
+ * We were woken already.
+ */
+- spin_unlock(&futex_lock);
++ spin_unlock(&bh->lock);
+ set_current_state(TASK_RUNNING);
+ return 0;
+ }
+
+- spin_unlock(&futex_lock);
++ spin_unlock(&bh->lock);
+ time = schedule_timeout(time);
+ set_current_state(TASK_RUNNING);
+
+@@ -394,26 +423,17 @@
+ * we are the only user of it.
+ */
+
+- /*
+- * Were we woken or interrupted for a valid reason?
+- */
+- ret = unqueue_me(&q);
+- if (ret == 0)
++ /* If we were woken (and unqueued), we succeeded, whatever. */
++ if (!unqueue_me(&q))
+ return 0;
+ if (time == 0)
+ return -ETIMEDOUT;
+- if (signal_pending(current))
+- return -EINTR;
+-
+- /*
+- * No, it was a spurious wakeup. Try again. Should never happen. :)
+- */
+- goto try_again;
++ /* A spurious wakeup should never happen. */
++ WARN_ON(!signal_pending(current));
++ return -EINTR;
+
+ out_unqueue:
+- /*
+- * Were we unqueued anyway?
+- */
++ /* If we were woken (and unqueued), we succeeded, whatever. */
+ if (!unqueue_me(&q))
+ ret = 0;
+ out_release_sem:
+@@ -435,13 +455,14 @@
+ struct poll_table_struct *wait)
+ {
+ struct futex_q *q = filp->private_data;
++ struct futex_hash_bucket *bh = hash_futex(&q->key);
+ int ret = 0;
+
+ poll_wait(filp, &q->waiters, wait);
+- spin_lock(&futex_lock);
++ spin_lock(&bh->lock);
+ if (list_empty(&q->list))
+ ret = POLLIN | POLLRDNORM;
+- spin_unlock(&futex_lock);
++ spin_unlock(&bh->lock);
+
+ return ret;
+ }
+@@ -587,8 +608,10 @@
+ register_filesystem(&futex_fs_type);
+ futex_mnt = kern_mount(&futex_fs_type);
+
+- for (i = 0; i < ARRAY_SIZE(futex_queues); i++)
+- INIT_LIST_HEAD(&futex_queues[i]);
++ for (i = 0; i < ARRAY_SIZE(futex_queues); i++) {
++ INIT_LIST_HEAD(&futex_queues[i].chain);
++ futex_queues[i].lock = SPIN_LOCK_UNLOCKED;
++ }
+ return 0;
+ }
+ __initcall(init);
+Index: linux-2.6.0-test5/kernel/ksyms.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/ksyms.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/ksyms.c 2003-09-27 11:38:41.267254808 +0800
+@@ -126,11 +126,11 @@
+ EXPORT_SYMBOL(init_mm);
+ EXPORT_SYMBOL(blk_queue_bounce);
+ EXPORT_SYMBOL(blk_congestion_wait);
++EXPORT_SYMBOL(blk_congestion_wait_wq);
+ #ifdef CONFIG_HIGHMEM
+ EXPORT_SYMBOL(kmap_high);
+ EXPORT_SYMBOL(kunmap_high);
+ EXPORT_SYMBOL(highmem_start_page);
+-EXPORT_SYMBOL(kmap_prot);
+ EXPORT_SYMBOL(kmap_pte);
+ #endif
+ #ifdef HASHED_PAGE_VIRTUAL
+@@ -221,6 +221,7 @@
+ EXPORT_SYMBOL(submit_bh);
+ EXPORT_SYMBOL(unlock_buffer);
+ EXPORT_SYMBOL(__wait_on_buffer);
++EXPORT_SYMBOL(__wait_on_buffer_wq);
+ EXPORT_SYMBOL(blockdev_direct_IO);
+ EXPORT_SYMBOL(block_write_full_page);
+ EXPORT_SYMBOL(block_read_full_page);
+@@ -348,8 +349,6 @@
+ EXPORT_SYMBOL(unlock_page);
+
+ /* device registration */
+-EXPORT_SYMBOL(register_chrdev);
+-EXPORT_SYMBOL(unregister_chrdev);
+ EXPORT_SYMBOL(register_blkdev);
+ EXPORT_SYMBOL(unregister_blkdev);
+ EXPORT_SYMBOL(tty_register_driver);
+@@ -609,6 +608,16 @@
+ EXPORT_SYMBOL(set_fs_pwd);
+ EXPORT_SYMBOL(set_fs_root);
+
++#if defined(CONFIG_LOCKMETER)
++EXPORT_SYMBOL(_metered_spin_lock);
++EXPORT_SYMBOL(_metered_spin_unlock);
++EXPORT_SYMBOL(_metered_spin_trylock);
++EXPORT_SYMBOL(_metered_read_lock);
++EXPORT_SYMBOL(_metered_read_unlock);
++EXPORT_SYMBOL(_metered_write_lock);
++EXPORT_SYMBOL(_metered_write_unlock);
++#endif
++
+ /* debug */
+ EXPORT_SYMBOL(dump_stack);
+ EXPORT_SYMBOL(ptrace_notify);
+Index: linux-2.6.0-test5/kernel/lockmeter.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/lockmeter.c 2003-09-27 11:38:18.488717672 +0800
++++ linux-2.6.0-test5/kernel/lockmeter.c 2003-09-27 11:38:41.269254504 +0800
+@@ -0,0 +1,1169 @@
++/*
++ * Copyright (C) 1999,2000 Silicon Graphics, Inc.
++ *
++ * Written by John Hawkes (hawkes@sgi.com)
++ * Based on klstat.c by Jack Steiner (steiner@sgi.com)
++ *
++ * Modified by Ray Bryant (raybry@us.ibm.com)
++ * Changes Copyright (C) 2000 IBM, Inc.
++ * Added save of index in spinlock_t to improve efficiency
++ * of "hold" time reporting for spinlocks
++ * Added support for hold time statistics for read and write
++ * locks.
++ */
++
++#include <linux/config.h>
++#include <linux/types.h>
++#include <linux/errno.h>
++#include <linux/slab.h>
++#include <linux/sched.h>
++#include <linux/smp.h>
++#include <linux/threads.h>
++#include <linux/version.h>
++#include <linux/vmalloc.h>
++#include <linux/spinlock.h>
++#include <linux/utsname.h>
++#include <asm/system.h>
++#include <asm/uaccess.h>
++
++#include <linux/lockmeter.h>
++
++#define ASSERT(cond)
++#define bzero(loc,size) memset(loc,0,size)
++
++/*<---------------------------------------------------*/
++/* lockmeter.c */
++/*>---------------------------------------------------*/
++
++static lstat_control_t lstat_control __cacheline_aligned =
++ { LSTAT_OFF, SPIN_LOCK_UNLOCKED, SPIN_LOCK_UNLOCKED,
++ 19 * 0, NR_CPUS * 0, 0, NR_CPUS * 0 };
++
++static ushort lstat_make_dir_entry(void *, void *);
++
++/*
++ * lstat_lookup
++ *
++ * Given a RA, locate the directory entry for the lock.
++ */
++static ushort
++lstat_lookup(void *lock_ptr, void *caller_ra)
++{
++ ushort index;
++ lstat_directory_entry_t *dirp;
++
++ dirp = lstat_control.dir;
++
++ index = lstat_control.hashtab[DIRHASH(caller_ra)];
++ while (dirp[index].caller_ra != caller_ra) {
++ if (index == 0) {
++ return lstat_make_dir_entry(lock_ptr, caller_ra);
++ }
++ index = dirp[index].next_stat_index;
++ }
++
++ if (dirp[index].lock_ptr != NULL && dirp[index].lock_ptr != lock_ptr) {
++ dirp[index].lock_ptr = NULL;
++ }
++
++ return index;
++}
++
++/*
++ * lstat_make_dir_entry
++ * Called to add a new lock to the lock directory.
++ */
++static ushort
++lstat_make_dir_entry(void *lock_ptr, void *caller_ra)
++{
++ lstat_directory_entry_t *dirp;
++ ushort index, hindex;
++ unsigned long flags;
++
++ /* lock the table without recursively reentering this metering code */
++ local_irq_save(flags);
++ _raw_spin_lock(&lstat_control.directory_lock);
++
++ hindex = DIRHASH(caller_ra);
++ index = lstat_control.hashtab[hindex];
++ dirp = lstat_control.dir;
++ while (index && dirp[index].caller_ra != caller_ra)
++ index = dirp[index].next_stat_index;
++
++ if (index == 0) {
++ if (lstat_control.next_free_dir_index < LSTAT_MAX_STAT_INDEX) {
++ index = lstat_control.next_free_dir_index++;
++ lstat_control.dir[index].caller_ra = caller_ra;
++ lstat_control.dir[index].lock_ptr = lock_ptr;
++ lstat_control.dir[index].next_stat_index =
++ lstat_control.hashtab[hindex];
++ lstat_control.hashtab[hindex] = index;
++ } else {
++ lstat_control.dir_overflow++;
++ }
++ }
++ _raw_spin_unlock(&lstat_control.directory_lock);
++ local_irq_restore(flags);
++ return index;
++}
++
++int
++lstat_update(void *lock_ptr, void *caller_ra, int action)
++{
++ int index;
++ int cpu;
++
++ ASSERT(action < LSTAT_ACT_MAX_VALUES);
++
++ if (lstat_control.state == LSTAT_OFF)
++ return 0;
++
++ index = lstat_lookup(lock_ptr, caller_ra);
++ cpu = THIS_CPU_NUMBER;
++ (*lstat_control.counts[cpu])[index].count[action]++;
++ (*lstat_control.counts[cpu])[index].acquire_time = get_cycles();
++
++ return index;
++}
++
++int
++lstat_update_time(void *lock_ptr, void *caller_ra, int action, uint32_t ticks)
++{
++ ushort index;
++ int cpu;
++
++ ASSERT(action < LSTAT_ACT_MAX_VALUES);
++
++ if (lstat_control.state == LSTAT_OFF)
++ return 0;
++
++ index = lstat_lookup(lock_ptr, caller_ra);
++ cpu = THIS_CPU_NUMBER;
++ (*lstat_control.counts[cpu])[index].count[action]++;
++ (*lstat_control.counts[cpu])[index].cum_wait_ticks += (uint64_t) ticks;
++ if ((*lstat_control.counts[cpu])[index].max_wait_ticks < ticks)
++ (*lstat_control.counts[cpu])[index].max_wait_ticks = ticks;
++
++ (*lstat_control.counts[cpu])[index].acquire_time = get_cycles();
++
++ return index;
++}
++
++void
++_metered_spin_lock(spinlock_t * lock_ptr)
++{
++ if (lstat_control.state == LSTAT_OFF) {
++ _raw_spin_lock(lock_ptr); /* do the real lock */
++ PUT_INDEX(lock_ptr, 0); /* clean index in case lockmetering */
++ /* gets turned on before unlock */
++ } else {
++ void *this_pc = LSTAT_RA(LSTAT_RA_SPIN);
++ int index;
++
++ if (_raw_spin_trylock(lock_ptr)) {
++ index = lstat_update(lock_ptr, this_pc,
++ LSTAT_ACT_NO_WAIT);
++ } else {
++ uint32_t start_cycles = get_cycles();
++ _raw_spin_lock(lock_ptr); /* do the real lock */
++ index = lstat_update_time(lock_ptr, this_pc,
++ LSTAT_ACT_SPIN, get_cycles() - start_cycles);
++ }
++ /* save the index in the lock itself for use in spin unlock */
++ PUT_INDEX(lock_ptr, index);
++ }
++}
++
++int
++_metered_spin_trylock(spinlock_t * lock_ptr)
++{
++ if (lstat_control.state == LSTAT_OFF) {
++ return _raw_spin_trylock(lock_ptr);
++ } else {
++ int retval;
++ void *this_pc = LSTAT_RA(LSTAT_RA_SPIN);
++
++ if ((retval = _raw_spin_trylock(lock_ptr))) {
++ int index = lstat_update(lock_ptr, this_pc,
++ LSTAT_ACT_NO_WAIT);
++ /*
++ * save the index in the lock itself for use in spin
++ * unlock
++ */
++ PUT_INDEX(lock_ptr, index);
++ } else {
++ lstat_update(lock_ptr, this_pc, LSTAT_ACT_REJECT);
++ }
++
++ return retval;
++ }
++}
++
++void
++_metered_spin_unlock(spinlock_t * lock_ptr)
++{
++ int index = -1;
++
++ if (lstat_control.state != LSTAT_OFF) {
++ index = GET_INDEX(lock_ptr);
++ /*
++ * If statistics were turned off when we set the lock,
++ * then the index can be zero. If that is the case,
++ * then collect no stats on this call.
++ */
++ if (index > 0) {
++ uint32_t hold_time;
++ int cpu = THIS_CPU_NUMBER;
++ hold_time = get_cycles() -
++ (*lstat_control.counts[cpu])[index].acquire_time;
++ (*lstat_control.counts[cpu])[index].cum_hold_ticks +=
++ (uint64_t) hold_time;
++ if ((*lstat_control.counts[cpu])[index].max_hold_ticks <
++ hold_time)
++ (*lstat_control.counts[cpu])[index].
++ max_hold_ticks = hold_time;
++ }
++ }
++
++ /* make sure we don't have a stale index value saved */
++ PUT_INDEX(lock_ptr, 0);
++ _raw_spin_unlock(lock_ptr); /* do the real unlock */
++}
++
++/*
++ * allocate the next global read lock structure and store its index
++ * in the rwlock at "lock_ptr".
++ */
++uint32_t
++alloc_rwlock_struct(rwlock_t * rwlock_ptr)
++{
++ int index;
++ unsigned long flags;
++ int cpu = THIS_CPU_NUMBER;
++
++ /* If we've already overflowed, then do a quick exit */
++ if (lstat_control.next_free_read_lock_index >
++ LSTAT_MAX_READ_LOCK_INDEX) {
++ lstat_control.rwlock_overflow++;
++ return 0;
++ }
++
++ local_irq_save(flags);
++ _raw_spin_lock(&lstat_control.directory_lock);
++
++ /* It is possible this changed while we were waiting for the directory_lock */
++ if (lstat_control.state == LSTAT_OFF) {
++ index = 0;
++ goto unlock;
++ }
++
++ /* It is possible someone else got here first and set the index */
++ if ((index = GET_RWINDEX(rwlock_ptr)) == 0) {
++ /*
++ * we can't turn on read stats for this lock while there are
++ * readers (this would mess up the running hold time sum at
++ * unlock time)
++ */
++ if (RWLOCK_READERS(rwlock_ptr) != 0) {
++ index = 0;
++ goto unlock;
++ }
++
++ /*
++ * if stats are turned on after being off, we may need to
++ * return an old index from when the statistics were on last
++ * time.
++ */
++ for (index = 1; index < lstat_control.next_free_read_lock_index;
++ index++)
++ if ((*lstat_control.read_lock_counts[cpu])[index].
++ lock_ptr == rwlock_ptr)
++ goto put_index_and_unlock;
++
++ /* allocate the next global read lock structure */
++ if (lstat_control.next_free_read_lock_index >=
++ LSTAT_MAX_READ_LOCK_INDEX) {
++ lstat_control.rwlock_overflow++;
++ index = 0;
++ goto unlock;
++ }
++ index = lstat_control.next_free_read_lock_index++;
++
++ /*
++ * initialize the global read stats data structure for each
++ * cpu
++ */
++ for (cpu = 0; cpu < num_online_cpus(); cpu++) {
++ (*lstat_control.read_lock_counts[cpu])[index].lock_ptr =
++ rwlock_ptr;
++ }
++put_index_and_unlock:
++ /* store the index for the read lock structure into the lock */
++ PUT_RWINDEX(rwlock_ptr, index);
++ }
++
++unlock:
++ _raw_spin_unlock(&lstat_control.directory_lock);
++ local_irq_restore(flags);
++ return index;
++}
++
++void
++_metered_read_lock(rwlock_t * rwlock_ptr)
++{
++ void *this_pc;
++ uint32_t start_cycles;
++ int index;
++ int cpu;
++ unsigned long flags;
++ int readers_before, readers_after;
++ uint64_t cycles64;
++
++ if (lstat_control.state == LSTAT_OFF) {
++ _raw_read_lock(rwlock_ptr);
++ /* clean index in case lockmetering turns on before an unlock */
++ PUT_RWINDEX(rwlock_ptr, 0);
++ return;
++ }
++
++ this_pc = LSTAT_RA(LSTAT_RA_READ);
++ cpu = THIS_CPU_NUMBER;
++ index = GET_RWINDEX(rwlock_ptr);
++
++ /* allocate the global stats entry for this lock, if needed */
++ if (index == 0)
++ index = alloc_rwlock_struct(rwlock_ptr);
++
++ readers_before = RWLOCK_READERS(rwlock_ptr);
++ if (_raw_read_trylock(rwlock_ptr)) {
++ /*
++ * We have decremented the lock to count a new reader,
++ * and have confirmed that no writer has it locked.
++ */
++ /* update statistics if enabled */
++ if (index > 0) {
++ local_irq_save(flags);
++ lstat_update((void *) rwlock_ptr, this_pc,
++ LSTAT_ACT_NO_WAIT);
++ /* preserve value of TSC so cum_hold_ticks and start_busy use same value */
++ cycles64 = get_cycles64();
++ (*lstat_control.read_lock_counts[cpu])[index].
++ cum_hold_ticks -= cycles64;
++
++ /* record time and cpu of start of busy period */
++ /* this is not perfect (some race conditions are possible) */
++ if (readers_before == 0) {
++ (*lstat_control.read_lock_counts[cpu])[index].
++ start_busy = cycles64;
++ PUT_RW_CPU(rwlock_ptr, cpu);
++ }
++ readers_after = RWLOCK_READERS(rwlock_ptr);
++ if (readers_after >
++ (*lstat_control.read_lock_counts[cpu])[index].
++ max_readers)
++ (*lstat_control.read_lock_counts[cpu])[index].
++ max_readers = readers_after;
++ local_irq_restore(flags);
++ }
++
++ return;
++ }
++ /* If we get here, then we could not quickly grab the read lock */
++
++ start_cycles = get_cycles(); /* start counting the wait time */
++
++ /* Now spin until read_lock is successful */
++ _raw_read_lock(rwlock_ptr);
++
++ lstat_update_time((void *) rwlock_ptr, this_pc, LSTAT_ACT_SPIN,
++ get_cycles() - start_cycles);
++
++ /* update statistics if they are enabled for this lock */
++ if (index > 0) {
++ local_irq_save(flags);
++ cycles64 = get_cycles64();
++ (*lstat_control.read_lock_counts[cpu])[index].cum_hold_ticks -=
++ cycles64;
++
++ /* this is not perfect (some race conditions are possible) */
++ if (readers_before == 0) {
++ (*lstat_control.read_lock_counts[cpu])[index].
++ start_busy = cycles64;
++ PUT_RW_CPU(rwlock_ptr, cpu);
++ }
++ readers_after = RWLOCK_READERS(rwlock_ptr);
++ if (readers_after >
++ (*lstat_control.read_lock_counts[cpu])[index].max_readers)
++ (*lstat_control.read_lock_counts[cpu])[index].
++ max_readers = readers_after;
++ local_irq_restore(flags);
++ }
++}
++
++void
++_metered_read_unlock(rwlock_t * rwlock_ptr)
++{
++ int index;
++ int cpu;
++ unsigned long flags;
++ uint64_t busy_length;
++ uint64_t cycles64;
++
++ if (lstat_control.state == LSTAT_OFF) {
++ _raw_read_unlock(rwlock_ptr);
++ return;
++ }
++
++ index = GET_RWINDEX(rwlock_ptr);
++ cpu = THIS_CPU_NUMBER;
++
++ if (index > 0) {
++ local_irq_save(flags);
++ /*
++ * preserve value of TSC so cum_hold_ticks and busy_ticks are
++ * consistent.
++ */
++ cycles64 = get_cycles64();
++ (*lstat_control.read_lock_counts[cpu])[index].cum_hold_ticks +=
++ cycles64;
++ (*lstat_control.read_lock_counts[cpu])[index].read_lock_count++;
++
++ /*
++ * once again, this is not perfect (some race conditions are
++ * possible)
++ */
++ if (RWLOCK_READERS(rwlock_ptr) == 1) {
++ int cpu1 = GET_RW_CPU(rwlock_ptr);
++ uint64_t last_start_busy =
++ (*lstat_control.read_lock_counts[cpu1])[index].
++ start_busy;
++ (*lstat_control.read_lock_counts[cpu])[index].
++ busy_periods++;
++ if (cycles64 > last_start_busy) {
++ busy_length = cycles64 - last_start_busy;
++ (*lstat_control.read_lock_counts[cpu])[index].
++ busy_ticks += busy_length;
++ if (busy_length >
++ (*lstat_control.
++ read_lock_counts[cpu])[index].
++ max_busy)
++ (*lstat_control.
++ read_lock_counts[cpu])[index].
++ max_busy = busy_length;
++ }
++ }
++ local_irq_restore(flags);
++ }
++ _raw_read_unlock(rwlock_ptr);
++}
++
++void
++_metered_write_lock(rwlock_t * rwlock_ptr)
++{
++ uint32_t start_cycles;
++ void *this_pc;
++ uint32_t spin_ticks = 0; /* in anticipation of a potential wait */
++ int index;
++ int write_index = 0;
++ int cpu;
++ enum {
++ writer_writer_conflict,
++ writer_reader_conflict
++ } why_wait = writer_writer_conflict;
++
++ if (lstat_control.state == LSTAT_OFF) {
++ _raw_write_lock(rwlock_ptr);
++ /* clean index in case lockmetering turns on before an unlock */
++ PUT_RWINDEX(rwlock_ptr, 0);
++ return;
++ }
++
++ this_pc = LSTAT_RA(LSTAT_RA_WRITE);
++ cpu = THIS_CPU_NUMBER;
++ index = GET_RWINDEX(rwlock_ptr);
++
++ /* allocate the global stats entry for this lock, if needed */
++ if (index == 0) {
++ index = alloc_rwlock_struct(rwlock_ptr);
++ }
++
++ if (_raw_write_trylock(rwlock_ptr)) {
++ /* We acquired the lock on the first try */
++ write_index = lstat_update((void *) rwlock_ptr, this_pc,
++ LSTAT_ACT_NO_WAIT);
++ /* save the write_index for use in unlock if stats enabled */
++ if (index > 0)
++ (*lstat_control.read_lock_counts[cpu])[index].
++ write_index = write_index;
++ return;
++ }
++
++ /* If we get here, then we could not quickly grab the write lock */
++ start_cycles = get_cycles(); /* start counting the wait time */
++
++ why_wait = RWLOCK_READERS(rwlock_ptr) ?
++ writer_reader_conflict : writer_writer_conflict;
++
++ /* Now set the lock and wait for conflicts to disappear */
++ _raw_write_lock(rwlock_ptr);
++
++ spin_ticks = get_cycles() - start_cycles;
++
++ /* update stats -- if enabled */
++ if (index > 0 && spin_ticks) {
++ if (why_wait == writer_reader_conflict) {
++ /* waited due to a reader holding the lock */
++ write_index = lstat_update_time((void *)rwlock_ptr,
++ this_pc, LSTAT_ACT_SPIN, spin_ticks);
++ } else {
++ /*
++ * waited due to another writer holding the lock
++ */
++ write_index = lstat_update_time((void *)rwlock_ptr,
++ this_pc, LSTAT_ACT_WW_SPIN, spin_ticks);
++ (*lstat_control.counts[cpu])[write_index].
++ cum_wait_ww_ticks += spin_ticks;
++ if (spin_ticks >
++ (*lstat_control.counts[cpu])[write_index].
++ max_wait_ww_ticks) {
++ (*lstat_control.counts[cpu])[write_index].
++ max_wait_ww_ticks = spin_ticks;
++ }
++ }
++
++ /* save the directory index for use on write_unlock */
++ (*lstat_control.read_lock_counts[cpu])[index].
++ write_index = write_index;
++ }
++}
++
++void
++_metered_write_unlock(rwlock_t * rwlock_ptr)
++{
++ int index;
++ int cpu;
++ int write_index;
++ uint32_t hold_time;
++
++ if (lstat_control.state == LSTAT_OFF) {
++ _raw_write_unlock(rwlock_ptr);
++ return;
++ }
++
++ cpu = THIS_CPU_NUMBER;
++ index = GET_RWINDEX(rwlock_ptr);
++
++ /* update statistics if stats enabled for this lock */
++ if (index > 0) {
++ write_index =
++ (*lstat_control.read_lock_counts[cpu])[index].write_index;
++
++ hold_time = get_cycles() -
++ (*lstat_control.counts[cpu])[write_index].acquire_time;
++ (*lstat_control.counts[cpu])[write_index].cum_hold_ticks +=
++ (uint64_t) hold_time;
++ if ((*lstat_control.counts[cpu])[write_index].max_hold_ticks <
++ hold_time)
++ (*lstat_control.counts[cpu])[write_index].
++ max_hold_ticks = hold_time;
++ }
++ _raw_write_unlock(rwlock_ptr);
++}
++
++int
++_metered_write_trylock(rwlock_t * rwlock_ptr)
++{
++ int retval;
++ void *this_pc = LSTAT_RA(LSTAT_RA_WRITE);
++
++ if ((retval = _raw_write_trylock(rwlock_ptr))) {
++ lstat_update(rwlock_ptr, this_pc, LSTAT_ACT_NO_WAIT);
++ } else {
++ lstat_update(rwlock_ptr, this_pc, LSTAT_ACT_REJECT);
++ }
++
++ return retval;
++}
++
++static void
++init_control_space(void)
++{
++ /* Set all control space pointers to null and indices to "empty" */
++ int cpu;
++
++ /*
++ * Access CPU_CYCLE_FREQUENCY at the outset, which in some
++ * architectures may trigger a runtime calculation that uses a
++ * spinlock. Let's do this before lockmetering is turned on.
++ */
++ if (CPU_CYCLE_FREQUENCY == 0)
++ BUG();
++
++ lstat_control.hashtab = NULL;
++ lstat_control.dir = NULL;
++ for (cpu = 0; cpu < NR_CPUS; cpu++) {
++ lstat_control.counts[cpu] = NULL;
++ lstat_control.read_lock_counts[cpu] = NULL;
++ }
++}
++
++static int
++reset_lstat_data(void)
++{
++ int cpu, flags;
++
++ flags = 0;
++ lstat_control.next_free_dir_index = 1; /* 0 is for overflows */
++ lstat_control.next_free_read_lock_index = 1;
++ lstat_control.dir_overflow = 0;
++ lstat_control.rwlock_overflow = 0;
++
++ lstat_control.started_cycles64 = 0;
++ lstat_control.ending_cycles64 = 0;
++ lstat_control.enabled_cycles64 = 0;
++ lstat_control.first_started_time = 0;
++ lstat_control.started_time = 0;
++ lstat_control.ending_time = 0;
++ lstat_control.intervals = 0;
++
++ /*
++ * paranoia -- in case someone does a "lockstat reset" before
++ * "lockstat on"
++ */
++ if (lstat_control.hashtab) {
++ bzero(lstat_control.hashtab,
++ LSTAT_HASH_TABLE_SIZE * sizeof (short));
++ bzero(lstat_control.dir, LSTAT_MAX_STAT_INDEX *
++ sizeof (lstat_directory_entry_t));
++
++ for (cpu = 0; cpu < num_online_cpus(); cpu++) {
++ bzero(lstat_control.counts[cpu],
++ sizeof (lstat_cpu_counts_t));
++ bzero(lstat_control.read_lock_counts[cpu],
++ sizeof (lstat_read_lock_cpu_counts_t));
++ }
++ }
++#ifdef NOTDEF
++ _raw_spin_unlock(&lstat_control.directory_lock);
++ local_irq_restore(flags);
++#endif
++ return 1;
++}
++
++static void
++release_control_space(void)
++{
++ /*
++ * Called when either (1) allocation of kmem
++ * or (2) when user writes LSTAT_RELEASE to /pro/lockmeter.
++ * Assume that all pointers have been initialized to zero,
++ * i.e., nonzero pointers are valid addresses.
++ */
++ int cpu;
++
++ if (lstat_control.hashtab) {
++ kfree(lstat_control.hashtab);
++ lstat_control.hashtab = NULL;
++ }
++
++ if (lstat_control.dir) {
++ vfree(lstat_control.dir);
++ lstat_control.dir = NULL;
++ }
++
++ for (cpu = 0; cpu < NR_CPUS; cpu++) {
++ if (lstat_control.counts[cpu]) {
++ vfree(lstat_control.counts[cpu]);
++ lstat_control.counts[cpu] = NULL;
++ }
++ if (lstat_control.read_lock_counts[cpu]) {
++ kfree(lstat_control.read_lock_counts[cpu]);
++ lstat_control.read_lock_counts[cpu] = NULL;
++ }
++ }
++}
++
++int
++get_lockmeter_info_size(void)
++{
++ return sizeof (lstat_user_request_t)
++ + num_online_cpus() * sizeof (lstat_cpu_counts_t)
++ + num_online_cpus() * sizeof (lstat_read_lock_cpu_counts_t)
++ + (LSTAT_MAX_STAT_INDEX * sizeof (lstat_directory_entry_t));
++}
++
++ssize_t
++get_lockmeter_info(char *buffer, size_t max_len, loff_t * last_index)
++{
++ lstat_user_request_t req;
++ struct timeval tv;
++ ssize_t next_ret_bcount;
++ ssize_t actual_ret_bcount = 0;
++ int cpu;
++
++ *last_index = 0; /* a one-shot read */
++
++ req.lstat_version = LSTAT_VERSION;
++ req.state = lstat_control.state;
++ req.maxcpus = num_online_cpus();
++ req.cycleval = CPU_CYCLE_FREQUENCY;
++#ifdef notyet
++ req.kernel_magic_addr = (void *) &_etext;
++ req.kernel_end_addr = (void *) &_etext;
++#endif
++ req.uts = system_utsname;
++ req.intervals = lstat_control.intervals;
++
++ req.first_started_time = lstat_control.first_started_time;
++ req.started_time = lstat_control.started_time;
++ req.started_cycles64 = lstat_control.started_cycles64;
++
++ req.next_free_dir_index = lstat_control.next_free_dir_index;
++ req.next_free_read_lock_index = lstat_control.next_free_read_lock_index;
++ req.dir_overflow = lstat_control.dir_overflow;
++ req.rwlock_overflow = lstat_control.rwlock_overflow;
++
++ if (lstat_control.state == LSTAT_OFF) {
++ if (req.intervals == 0) {
++ /* mesasurement is off and no valid data present */
++ next_ret_bcount = sizeof (lstat_user_request_t);
++ req.enabled_cycles64 = 0;
++
++ if ((actual_ret_bcount + next_ret_bcount) > max_len)
++ return actual_ret_bcount;
++
++ copy_to_user(buffer, (void *) &req, next_ret_bcount);
++ actual_ret_bcount += next_ret_bcount;
++ return actual_ret_bcount;
++ } else {
++ /*
++ * measurement is off but valid data present
++ * fetch time info from lstat_control
++ */
++ req.ending_time = lstat_control.ending_time;
++ req.ending_cycles64 = lstat_control.ending_cycles64;
++ req.enabled_cycles64 = lstat_control.enabled_cycles64;
++ }
++ } else {
++ /*
++ * this must be a read while data active--use current time,
++ * etc
++ */
++ do_gettimeofday(&tv);
++ req.ending_time = tv.tv_sec;
++ req.ending_cycles64 = get_cycles64();
++ req.enabled_cycles64 = req.ending_cycles64 -
++ req.started_cycles64 + lstat_control.enabled_cycles64;
++ }
++
++ next_ret_bcount = sizeof (lstat_user_request_t);
++ if ((actual_ret_bcount + next_ret_bcount) > max_len)
++ return actual_ret_bcount;
++
++ copy_to_user(buffer, (void *) &req, next_ret_bcount);
++ actual_ret_bcount += next_ret_bcount;
++
++ if (!lstat_control.counts[0]) /* not initialized? */
++ return actual_ret_bcount;
++
++ next_ret_bcount = sizeof (lstat_cpu_counts_t);
++ for (cpu = 0; cpu < num_online_cpus(); cpu++) {
++ if ((actual_ret_bcount + next_ret_bcount) > max_len)
++ return actual_ret_bcount; /* leave early */
++ copy_to_user(buffer + actual_ret_bcount,
++ lstat_control.counts[cpu], next_ret_bcount);
++ actual_ret_bcount += next_ret_bcount;
++ }
++
++ next_ret_bcount = LSTAT_MAX_STAT_INDEX *
++ sizeof (lstat_directory_entry_t);
++ if (((actual_ret_bcount + next_ret_bcount) > max_len)
++ || !lstat_control.dir)
++ return actual_ret_bcount; /* leave early */
++
++ copy_to_user(buffer + actual_ret_bcount, lstat_control.dir,
++ next_ret_bcount);
++ actual_ret_bcount += next_ret_bcount;
++
++ next_ret_bcount = sizeof (lstat_read_lock_cpu_counts_t);
++ for (cpu = 0; cpu < num_online_cpus(); cpu++) {
++ if (actual_ret_bcount + next_ret_bcount > max_len)
++ return actual_ret_bcount;
++ copy_to_user(buffer + actual_ret_bcount,
++ lstat_control.read_lock_counts[cpu],
++ next_ret_bcount);
++ actual_ret_bcount += next_ret_bcount;
++ }
++
++ return actual_ret_bcount;
++}
++
++/*
++ * Writing to the /proc lockmeter node enables or disables metering.
++ * based upon the first byte of the "written" data.
++ * The following values are defined:
++ * LSTAT_ON: 1st call: allocates storage, intializes and turns on measurement
++ * subsequent calls just turn on measurement
++ * LSTAT_OFF: turns off measurement
++ * LSTAT_RESET: resets statistics
++ * LSTAT_RELEASE: releases statistics storage
++ *
++ * This allows one to accumulate statistics over several lockstat runs:
++ *
++ * lockstat on
++ * lockstat off
++ * ...repeat above as desired...
++ * lockstat get
++ * ...now start a new set of measurements...
++ * lockstat reset
++ * lockstat on
++ * ...
++ *
++ */
++ssize_t
++put_lockmeter_info(const char *buffer, size_t len)
++{
++ int error = 0;
++ int dirsize, countsize, read_lock_countsize, hashsize;
++ int cpu;
++ char put_char;
++ int i, read_lock_blocks;
++ unsigned long flags;
++ rwlock_t *lock_ptr;
++ struct timeval tv;
++
++ if (len <= 0)
++ return -EINVAL;
++
++ _raw_spin_lock(&lstat_control.control_lock);
++
++ get_user(put_char, buffer);
++ switch (put_char) {
++
++ case LSTAT_OFF:
++ if (lstat_control.state != LSTAT_OFF) {
++ /*
++ * To avoid seeing read lock hold times in an
++ * inconsisent state, we have to follow this protocol
++ * to turn off statistics
++ */
++ local_irq_save(flags);
++ /*
++ * getting this lock will stop any read lock block
++ * allocations
++ */
++ _raw_spin_lock(&lstat_control.directory_lock);
++ /*
++ * keep any more read lock blocks from being
++ * allocated
++ */
++ lstat_control.state = LSTAT_OFF;
++ /* record how may read lock blocks there are */
++ read_lock_blocks =
++ lstat_control.next_free_read_lock_index;
++ _raw_spin_unlock(&lstat_control.directory_lock);
++ /* now go through the list of read locks */
++ cpu = THIS_CPU_NUMBER;
++ for (i = 1; i < read_lock_blocks; i++) {
++ lock_ptr =
++ (*lstat_control.read_lock_counts[cpu])[i].
++ lock_ptr;
++ /* is this saved lock address still valid? */
++ if (GET_RWINDEX(lock_ptr) == i) {
++ /*
++ * lock address appears to still be
++ * valid because we only hold one lock
++ * at a time, this can't cause a
++ * deadlock unless this is a lock held
++ * as part of the current system call
++ * path. At the moment there
++ * are no READ mode locks held to get
++ * here from user space, so we solve
++ * this by skipping locks held in
++ * write mode.
++ */
++ if (RWLOCK_IS_WRITE_LOCKED(lock_ptr)) {
++ PUT_RWINDEX(lock_ptr, 0);
++ continue;
++ }
++ /*
++ * now we know there are no read
++ * holders of this lock! stop
++ * statistics collection for this
++ * lock
++ */
++ _raw_write_lock(lock_ptr);
++ PUT_RWINDEX(lock_ptr, 0);
++ _raw_write_unlock(lock_ptr);
++ }
++ /*
++ * it may still be possible for the hold time
++ * sum to be negative e.g. if a lock is
++ * reallocated while "busy" we will have to fix
++ * this up in the data reduction program.
++ */
++ }
++ local_irq_restore(flags);
++ lstat_control.intervals++;
++ lstat_control.ending_cycles64 = get_cycles64();
++ lstat_control.enabled_cycles64 +=
++ lstat_control.ending_cycles64 -
++ lstat_control.started_cycles64;
++ do_gettimeofday(&tv);
++ lstat_control.ending_time = tv.tv_sec;
++ /*
++ * don't deallocate the structures -- we may do a
++ * lockstat on to add to the data that is already
++ * there. Use LSTAT_RELEASE to release storage
++ */
++ } else {
++ error = -EBUSY; /* already OFF */
++ }
++ break;
++
++ case LSTAT_ON:
++ if (lstat_control.state == LSTAT_OFF) {
++#ifdef DEBUG_LOCKMETER
++ printk("put_lockmeter_info(cpu=%d): LSTAT_ON\n",
++ THIS_CPU_NUMBER);
++#endif
++ lstat_control.next_free_dir_index = 1; /* 0 is for overflows */
++
++ dirsize = LSTAT_MAX_STAT_INDEX *
++ sizeof (lstat_directory_entry_t);
++ hashsize =
++ (1 + LSTAT_HASH_TABLE_SIZE) * sizeof (ushort);
++ countsize = sizeof (lstat_cpu_counts_t);
++ read_lock_countsize =
++ sizeof (lstat_read_lock_cpu_counts_t);
++#ifdef DEBUG_LOCKMETER
++ printk(" dirsize:%d", dirsize);
++ printk(" hashsize:%d", hashsize);
++ printk(" countsize:%d", countsize);
++ printk(" read_lock_countsize:%d\n",
++ read_lock_countsize);
++#endif
++#ifdef DEBUG_LOCKMETER
++ {
++ int secs;
++ unsigned long cycles;
++ uint64_t cycles64;
++
++ do_gettimeofday(&tv);
++ secs = tv.tv_sec;
++ do {
++ do_gettimeofday(&tv);
++ } while (secs == tv.tv_sec);
++ cycles = get_cycles();
++ cycles64 = get_cycles64();
++ secs = tv.tv_sec;
++ do {
++ do_gettimeofday(&tv);
++ } while (secs == tv.tv_sec);
++ cycles = get_cycles() - cycles;
++ cycles64 = get_cycles64() - cycles;
++ printk("lockmeter: cycleFrequency:%d "
++ "cycles:%d cycles64:%d\n",
++ CPU_CYCLE_FREQUENCY, cycles, cycles64);
++ }
++#endif
++
++ /*
++ * if this is the first call, allocate storage and
++ * initialize
++ */
++ if (!lstat_control.hashtab) {
++
++ spin_lock_init(&lstat_control.directory_lock);
++
++ /* guarantee all pointers at zero */
++ init_control_space();
++
++ lstat_control.hashtab =
++ kmalloc(hashsize, GFP_KERNEL);
++ if (!lstat_control.hashtab) {
++ error = -ENOSPC;
++#ifdef DEBUG_LOCKMETER
++ printk("!!error kmalloc of hashtab\n");
++#endif
++ }
++ lstat_control.dir = vmalloc(dirsize);
++ if (!lstat_control.dir) {
++ error = -ENOSPC;
++#ifdef DEBUG_LOCKMETER
++ printk("!!error kmalloc of dir\n");
++#endif
++ }
++
++ for (cpu = 0; cpu < num_online_cpus(); cpu++) {
++ lstat_control.counts[cpu] =
++ vmalloc(countsize);
++ if (!lstat_control.counts[cpu]) {
++ error = -ENOSPC;
++#ifdef DEBUG_LOCKMETER
++ printk("!!error vmalloc of "
++ "counts[%d]\n", cpu);
++#endif
++ }
++ lstat_control.read_lock_counts[cpu] =
++ (lstat_read_lock_cpu_counts_t *)
++ kmalloc(read_lock_countsize,
++ GFP_KERNEL);
++ if (!lstat_control.
++ read_lock_counts[cpu]) {
++ error = -ENOSPC;
++#ifdef DEBUG_LOCKMETER
++ printk("!!error kmalloc of "
++ "read_lock_counts[%d]\n",
++ cpu);
++#endif
++ }
++ }
++ }
++
++ if (error) {
++ /*
++ * One or more kmalloc failures -- free
++ * everything
++ */
++ release_control_space();
++ } else {
++
++ if (!reset_lstat_data()) {
++ error = -EINVAL;
++ break;
++ };
++
++ /*
++ * record starting and ending times and the
++ * like
++ */
++ if (lstat_control.intervals == 0) {
++ do_gettimeofday(&tv);
++ lstat_control.first_started_time =
++ tv.tv_sec;
++ }
++ lstat_control.started_cycles64 = get_cycles64();
++ do_gettimeofday(&tv);
++ lstat_control.started_time = tv.tv_sec;
++
++ lstat_control.state = LSTAT_ON;
++ }
++ } else {
++ error = -EBUSY; /* already ON */
++ }
++ break;
++
++ case LSTAT_RESET:
++ if (lstat_control.state == LSTAT_OFF) {
++ if (!reset_lstat_data())
++ error = -EINVAL;
++ } else {
++ error = -EBUSY; /* still on; can't reset */
++ }
++ break;
++
++ case LSTAT_RELEASE:
++ if (lstat_control.state == LSTAT_OFF) {
++ release_control_space();
++ lstat_control.intervals = 0;
++ lstat_control.enabled_cycles64 = 0;
++ } else {
++ error = -EBUSY;
++ }
++ break;
++
++ default:
++ error = -EINVAL;
++ } /* switch */
++
++ _raw_spin_unlock(&lstat_control.control_lock);
++ return error ? error : len;
++}
++
++#ifdef USER_MODE_TESTING
++/* following used for user mode testing */
++void
++lockmeter_init()
++{
++ int dirsize, hashsize, countsize, read_lock_countsize, cpu;
++
++ printf("lstat_control is at %x size=%d\n", &lstat_control,
++ sizeof (lstat_control));
++ printf("sizeof(spinlock_t)=%d\n", sizeof (spinlock_t));
++ lstat_control.state = LSTAT_ON;
++
++ lstat_control.directory_lock = SPIN_LOCK_UNLOCKED;
++ lstat_control.next_free_dir_index = 1; /* 0 is for overflows */
++ lstat_control.next_free_read_lock_index = 1;
++
++ dirsize = LSTAT_MAX_STAT_INDEX * sizeof (lstat_directory_entry_t);
++ hashsize = (1 + LSTAT_HASH_TABLE_SIZE) * sizeof (ushort);
++ countsize = sizeof (lstat_cpu_counts_t);
++ read_lock_countsize = sizeof (lstat_read_lock_cpu_counts_t);
++
++ lstat_control.hashtab = (ushort *) malloc(hashsize);
++
++ if (lstat_control.hashtab == 0) {
++ printf("malloc failure for at line %d in lockmeter.c\n",
++ __LINE__);
++ exit(0);
++ }
++
++ lstat_control.dir = (lstat_directory_entry_t *) malloc(dirsize);
++
++ if (lstat_control.dir == 0) {
++ printf("malloc failure for at line %d in lockmeter.c\n", cpu,
++ __LINE__);
++ exit(0);
++ }
++
++ for (cpu = 0; cpu < num_online_cpus(); cpu++) {
++ int j, k;
++ j = (int) (lstat_control.counts[cpu] =
++ (lstat_cpu_counts_t *) malloc(countsize));
++ k = (int) (lstat_control.read_lock_counts[cpu] =
++ (lstat_read_lock_cpu_counts_t *)
++ malloc(read_lock_countsize));
++ if (j * k == 0) {
++ printf("malloc failure for cpu=%d at line %d in "
++ "lockmeter.c\n", cpu, __LINE__);
++ exit(0);
++ }
++ }
++
++ memset(lstat_control.hashtab, 0, hashsize);
++ memset(lstat_control.dir, 0, dirsize);
++
++ for (cpu = 0; cpu < num_online_cpus(); cpu++) {
++ memset(lstat_control.counts[cpu], 0, countsize);
++ memset(lstat_control.read_lock_counts[cpu], 0,
++ read_lock_countsize);
++ }
++}
++
++asm(" \
++.align 4 \
++.globl __write_lock_failed \
++__write_lock_failed: \
++ " LOCK "addl $" RW_LOCK_BIAS_STR ",(%eax) \
++1: cmpl $" RW_LOCK_BIAS_STR ",(%eax) \
++ jne 1b \
++\
++ " LOCK "subl $" RW_LOCK_BIAS_STR ",(%eax) \
++ jnz __write_lock_failed \
++ ret \
++\
++\
++.align 4 \
++.globl __read_lock_failed \
++__read_lock_failed: \
++ lock ; incl (%eax) \
++1: cmpl $1,(%eax) \
++ js 1b \
++\
++ lock ; decl (%eax) \
++ js __read_lock_failed \
++ ret \
++");
++#endif
+Index: linux-2.6.0-test5/kernel/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/Makefile 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/Makefile 2003-09-27 11:38:41.271254200 +0800
+@@ -11,6 +11,7 @@
+ obj-$(CONFIG_FUTEX) += futex.o
+ obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
+ obj-$(CONFIG_SMP) += cpu.o
++obj-$(CONFIG_LOCKMETER) += lockmeter.o
+ obj-$(CONFIG_UID16) += uid16.o
+ obj-$(CONFIG_MODULES) += ksyms.o module.o
+ obj-$(CONFIG_KALLSYMS) += kallsyms.o
+@@ -18,6 +19,7 @@
+ obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
+ obj-$(CONFIG_COMPAT) += compat.o
+ obj-$(CONFIG_IKCONFIG) += configs.o
++obj-$(CONFIG_IKCONFIG_PROC) += configs.o
+
+ ifneq ($(CONFIG_IA64),y)
+ # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
+@@ -28,12 +30,32 @@
+ CFLAGS_sched.o := $(PROFILING) -fno-omit-frame-pointer
+ endif
+
++# configs.o uses generated files - dependecies must be listed explicitly
++$(obj)/configs.o: $(obj)/ikconfig.h
++
++ifdef CONFIG_IKCONFIG_PROC
++$(obj)/configs.o: $(obj)/config_data.h
++endif
++
++# ikconfig.h contains all the selected config entries - generated
++# from top-level Makefile and .config. Info from ikconfig.h can
++# be extracted from the kernel binary.
++
+ quiet_cmd_ikconfig = IKCFG $@
+ cmd_ikconfig = $(CONFIG_SHELL) $< .config $(srctree)/Makefile > $@
+
+ targets += ikconfig.h
+-
+ $(obj)/ikconfig.h: scripts/mkconfigs .config Makefile FORCE
+ $(call if_changed,ikconfig)
+
+-$(obj)/configs.o: $(obj)/ikconfig.h
++# config_data.h contains the same information as ikconfig.h but gzipped.
++# Info from config_data can be extracted from /proc/config*
++targets += config_data.gz
++$(obj)/config_data.gz: .config FORCE
++ $(call if_changed,gzip)
++
++quiet_cmd_ikconfiggz = IKCFG $@
++ cmd_ikconfiggz = cat $< | scripts/bin2c kernel_config_data > $@
++targets += config_data.h
++$(obj)/config_data.h: $(obj)/config_data.gz FORCE
++ $(call if_changed,ikconfiggz)
+Index: linux-2.6.0-test5/kernel/pid.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/pid.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/pid.c 2003-09-27 11:38:41.274253744 +0800
+@@ -250,13 +250,13 @@
+
+ attach_pid(thread, PIDTYPE_PID, thread->pid);
+ attach_pid(thread, PIDTYPE_TGID, thread->tgid);
+- attach_pid(thread, PIDTYPE_PGID, thread->pgrp);
++ attach_pid(thread, PIDTYPE_PGID, leader->__pgrp);
+ attach_pid(thread, PIDTYPE_SID, thread->session);
+ list_add_tail(&thread->tasks, &init_task.tasks);
+
+ attach_pid(leader, PIDTYPE_PID, leader->pid);
+ attach_pid(leader, PIDTYPE_TGID, leader->tgid);
+- attach_pid(leader, PIDTYPE_PGID, leader->pgrp);
++ attach_pid(leader, PIDTYPE_PGID, leader->__pgrp);
+ attach_pid(leader, PIDTYPE_SID, leader->session);
+ }
+
+@@ -265,6 +265,9 @@
+ * machine. From a minimum of 16 slots up to 4096 slots at one gigabyte or
+ * more.
+ */
++#ifdef CONFIG_KGDB
++int kgdb_pid_init_done; /* so we don't call prior to... */
++#endif
+ void __init pidhash_init(void)
+ {
+ int i, j, pidhash_size;
+@@ -286,6 +289,9 @@
+ for (j = 0; j < pidhash_size; j++)
+ INIT_LIST_HEAD(&pid_hash[i][j]);
+ }
++#ifdef CONFIG_KGDB
++ kgdb_pid_init_done++;
++#endif
+ }
+
+ void __init pidmap_init(void)
+Index: linux-2.6.0-test5/kernel/posix-timers.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/posix-timers.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/posix-timers.c 2003-09-27 11:38:41.283252376 +0800
+@@ -344,6 +344,7 @@
+ return NULL;
+
+ if ((event->sigev_notify & ~SIGEV_NONE & MIPS_SIGEV) &&
++ event->sigev_signo &&
+ ((unsigned) (event->sigev_signo > SIGRTMAX)))
+ return NULL;
+
+Index: linux-2.6.0-test5/kernel/power/console.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/power/console.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/power/console.c 2003-09-27 11:38:41.284252224 +0800
+@@ -8,7 +8,7 @@
+ #include <linux/kbd_kern.h>
+ #include "power.h"
+
+-static int new_loglevel = 7;
++static int new_loglevel = 10;
+ static int orig_loglevel;
+ static int orig_fgconsole, orig_kmsg;
+
+Index: linux-2.6.0-test5/kernel/power/disk.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/power/disk.c 2003-09-27 11:38:18.489717520 +0800
++++ linux-2.6.0-test5/kernel/power/disk.c 2003-09-27 11:38:41.285252072 +0800
+@@ -0,0 +1,335 @@
++/*
++ * kernel/power/disk.c - Suspend-to-disk support.
++ *
++ * Copyright (c) 2003 Patrick Mochel
++ * Copyright (c) 2003 Open Source Development Lab
++ *
++ * This file is release under the GPLv2
++ *
++ */
++
++#define DEBUG
++
++
++#include <linux/suspend.h>
++#include <linux/reboot.h>
++#include <linux/string.h>
++#include <linux/delay.h>
++#include <linux/fs.h>
++#include "power.h"
++
++
++extern u32 pm_disk_mode;
++extern struct pm_ops * pm_ops;
++
++extern int pmdisk_save(void);
++extern int pmdisk_write(void);
++extern int pmdisk_read(void);
++extern int pmdisk_restore(void);
++extern int pmdisk_free(void);
++
++extern long sys_sync(void);
++
++
++/**
++ * power_down - Shut machine down for hibernate.
++ * @mode: Suspend-to-disk mode
++ *
++ * Use the platform driver, if configured so, and return gracefully if it
++ * fails.
++ * Otherwise, try to power off and reboot. If they fail, halt the machine,
++ * there ain't no turning back.
++ */
++
++static int power_down(u32 mode)
++{
++ unsigned long flags;
++ int error = 0;
++
++ local_irq_save(flags);
++ device_power_down(PM_SUSPEND_DISK);
++ switch(mode) {
++ case PM_DISK_PLATFORM:
++ error = pm_ops->enter(PM_SUSPEND_DISK);
++ break;
++ case PM_DISK_SHUTDOWN:
++ printk("Powering off system\n");
++ machine_power_off();
++ break;
++ case PM_DISK_REBOOT:
++ machine_restart(NULL);
++ break;
++ }
++ machine_halt();
++ device_power_up();
++ local_irq_restore(flags);
++ return 0;
++}
++
++
++static int in_suspend __nosavedata = 0;
++
++
++/**
++ * free_some_memory - Try to free as much memory as possible
++ *
++ * ... but do not OOM-kill anyone
++ *
++ * Notice: all userland should be stopped at this point, or
++ * livelock is possible.
++ */
++
++static void free_some_memory(void)
++{
++ printk("Freeing memory: ");
++ while (shrink_all_memory(10000))
++ printk(".");
++ printk("|\n");
++ blk_run_queues();
++}
++
++
++static inline void platform_finish(void)
++{
++ if (pm_disk_mode == PM_DISK_PLATFORM) {
++ if (pm_ops && pm_ops->finish)
++ pm_ops->finish(PM_SUSPEND_DISK);
++ }
++}
++
++static void finish(void)
++{
++ device_resume();
++ platform_finish();
++ thaw_processes();
++ pm_restore_console();
++}
++
++
++static int prepare(void)
++{
++ int error;
++
++ pm_prepare_console();
++
++ sys_sync();
++ if (freeze_processes()) {
++ error = -EBUSY;
++ goto Thaw;
++ }
++
++ if (pm_disk_mode == PM_DISK_PLATFORM) {
++ if (pm_ops && pm_ops->prepare) {
++ if ((error = pm_ops->prepare(PM_SUSPEND_DISK)))
++ goto Thaw;
++ }
++ }
++
++ /* Free memory before shutting down devices. */
++ free_some_memory();
++
++ if ((error = device_suspend(PM_SUSPEND_DISK)))
++ goto Finish;
++
++ return 0;
++ Finish:
++ platform_finish();
++ Thaw:
++ thaw_processes();
++ pm_restore_console();
++ return error;
++}
++
++
++/**
++ * pm_suspend_disk - The granpappy of power management.
++ *
++ * If we're going through the firmware, then get it over with quickly.
++ *
++ * If not, then call pmdis to do it's thing, then figure out how
++ * to power down the system.
++ */
++
++int pm_suspend_disk(void)
++{
++ int error;
++
++ if ((error = prepare()))
++ return error;
++
++ pr_debug("PM: Attempting to suspend to disk.\n");
++ if (pm_disk_mode == PM_DISK_FIRMWARE)
++ return pm_ops->enter(PM_SUSPEND_DISK);
++
++ pr_debug("PM: snapshotting memory.\n");
++ in_suspend = 1;
++ if ((error = pmdisk_save()))
++ goto Done;
++
++ if (in_suspend) {
++ pr_debug("PM: writing image.\n");
++
++ /*
++ * FIXME: Leftover from swsusp. Are they necessary?
++ */
++ mb();
++ barrier();
++
++ error = pmdisk_write();
++ if (!error) {
++ error = power_down(pm_disk_mode);
++ pr_debug("PM: Power down failed.\n");
++ }
++ } else
++ pr_debug("PM: Image restored successfully.\n");
++ pmdisk_free();
++ Done:
++ finish();
++ return error;
++}
++
++
++/**
++ * pm_resume - Resume from a saved image.
++ *
++ * Called as a late_initcall (so all devices are discovered and
++ * initialized), we call pmdisk to see if we have a saved image or not.
++ * If so, we quiesce devices, the restore the saved image. We will
++ * return above (in pm_suspend_disk() ) if everything goes well.
++ * Otherwise, we fail gracefully and return to the normally
++ * scheduled program.
++ *
++ */
++
++static int pm_resume(void)
++{
++ int error;
++
++ pr_debug("PM: Reading pmdisk image.\n");
++
++ if ((error = pmdisk_read()))
++ goto Done;
++
++ pr_debug("PM: Preparing system for restore.\n");
++
++ if ((error = prepare()))
++ goto Free;
++
++ barrier();
++ mb();
++
++ /* FIXME: The following (comment and mdelay()) are from swsusp.
++ * Are they really necessary?
++ *
++ * We do not want some readahead with DMA to corrupt our memory, right?
++ * Do it with disabled interrupts for best effect. That way, if some
++ * driver scheduled DMA, we have good chance for DMA to finish ;-).
++ */
++ pr_debug("PM: Waiting for DMAs to settle down.\n");
++ mdelay(1000);
++
++ pr_debug("PM: Restoring saved image.\n");
++ pmdisk_restore();
++ pr_debug("PM: Restore failed, recovering.n");
++ finish();
++ Free:
++ pmdisk_free();
++ Done:
++ pr_debug("PM: Resume from disk failed.\n");
++ return 0;
++}
++
++late_initcall(pm_resume);
++
++
++static char * pm_disk_modes[] = {
++ [PM_DISK_FIRMWARE] = "firmware",
++ [PM_DISK_PLATFORM] = "platform",
++ [PM_DISK_SHUTDOWN] = "shutdown",
++ [PM_DISK_REBOOT] = "reboot",
++};
++
++/**
++ * disk - Control suspend-to-disk mode
++ *
++ * Suspend-to-disk can be handled in several ways. The greatest
++ * distinction is who writes memory to disk - the firmware or the OS.
++ * If the firmware does it, we assume that it also handles suspending
++ * the system.
++ * If the OS does it, then we have three options for putting the system
++ * to sleep - using the platform driver (e.g. ACPI or other PM registers),
++ * powering off the system or rebooting the system (for testing).
++ *
++ * The system will support either 'firmware' or 'platform', and that is
++ * known a priori (and encoded in pm_ops). But, the user may choose
++ * 'shutdown' or 'reboot' as alternatives.
++ *
++ * show() will display what the mode is currently set to.
++ * store() will accept one of
++ *
++ * 'firmware'
++ * 'platform'
++ * 'shutdown'
++ * 'reboot'
++ *
++ * It will only change to 'firmware' or 'platform' if the system
++ * supports it (as determined from pm_ops->pm_disk_mode).
++ */
++
++static ssize_t disk_show(struct subsystem * subsys, char * buf)
++{
++ return sprintf(buf,"%s\n",pm_disk_modes[pm_disk_mode]);
++}
++
++
++static ssize_t disk_store(struct subsystem * s, const char * buf, size_t n)
++{
++ int error = 0;
++ int i;
++ u32 mode = 0;
++
++ down(&pm_sem);
++ for (i = PM_DISK_FIRMWARE; i < PM_DISK_MAX; i++) {
++ if (!strcmp(buf,pm_disk_modes[i])) {
++ mode = i;
++ break;
++ }
++ }
++ if (mode) {
++ if (mode == PM_DISK_SHUTDOWN || mode == PM_DISK_REBOOT)
++ pm_disk_mode = mode;
++ else {
++ if (pm_ops && pm_ops->enter &&
++ (mode == pm_ops->pm_disk_mode))
++ pm_disk_mode = mode;
++ else
++ error = -EINVAL;
++ }
++ } else
++ error = -EINVAL;
++
++ pr_debug("PM: suspend-to-disk mode set to '%s'\n",
++ pm_disk_modes[mode]);
++ up(&pm_sem);
++ return error ? error : n;
++}
++
++power_attr(disk);
++
++static struct attribute * g[] = {
++ &disk_attr.attr,
++ NULL,
++};
++
++
++static struct attribute_group attr_group = {
++ .attrs = g,
++};
++
++
++static int __init pm_disk_init(void)
++{
++ return sysfs_create_group(&power_subsys.kset.kobj,&attr_group);
++}
++
++core_initcall(pm_disk_init);
+Index: linux-2.6.0-test5/kernel/power/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/power/Kconfig 2003-09-27 11:38:18.489717520 +0800
++++ linux-2.6.0-test5/kernel/power/Kconfig 2003-09-27 11:38:41.286251920 +0800
+@@ -0,0 +1,92 @@
++config PM
++ bool "Power Management support"
++ ---help---
++ "Power Management" means that parts of your computer are shut
++ off or put into a power conserving "sleep" mode if they are not
++ being used. There are two competing standards for doing this: APM
++ and ACPI. If you want to use either one, say Y here and then also
++ to the requisite support below.
++
++ Power Management is most important for battery powered laptop
++ computers; if you have a laptop, check out the Linux Laptop home
++ page on the WWW at
++ <http://www.cs.utexas.edu/users/kharker/linux-laptop/> and the
++ Battery Powered Linux mini-HOWTO, available from
++ <http://www.tldp.org/docs.html#howto>.
++
++ Note that, even if you say N here, Linux on the x86 architecture
++ will issue the hlt instruction if nothing is to be done, thereby
++ sending the processor to sleep and saving power.
++
++config SOFTWARE_SUSPEND
++ bool "Software Suspend (EXPERIMENTAL)"
++ depends on EXPERIMENTAL && PM && SWAP
++ ---help---
++ Enable the possibilty of suspendig machine. It doesn't need APM.
++ You may suspend your machine by 'swsusp' or 'shutdown -z <time>'
++ (patch for sysvinit needed).
++
++ It creates an image which is saved in your active swaps. By the next
++ booting the, pass 'resume=/dev/swappartition' and kernel will
++ detect the saved image, restore the memory from
++ it and then it continues to run as before you've suspended.
++ If you don't want the previous state to continue use the 'noresume'
++ kernel option. However note that your partitions will be fsck'd and
++ you must re-mkswap your swap partitions. It does not work with swap
++ files.
++
++ Right now you may boot without resuming and then later resume but
++ in meantime you cannot use those swap partitions/files which were
++ involved in suspending. Also in this case there is a risk that buffers
++ on disk won't match with saved ones.
++
++ For more information take a look at Documentation/swsusp.txt.
++
++config PM_DISK
++ bool "Suspend-to-Disk Support"
++ depends on PM && SWAP
++ ---help---
++ Suspend-to-disk is a power management state in which the contents
++ of memory are stored on disk and the entire system is shut down or
++ put into a low-power state (e.g. ACPI S4). When the computer is
++ turned back on, the stored image is loaded from disk and execution
++ resumes from where it left off before suspending.
++
++ This config option enables the core infrastructure necessary to
++ perform the suspend and resume transition.
++
++ Currently, this suspend-to-disk implementation is based on a forked
++ version of the swsusp code base. As such, it's still experimental,
++ and still relies on CONFIG_SWAP.
++
++ More information can be found in Documentation/power/.
++
++ If unsure, Say N.
++
++config PM_DISK_PARTITION
++ string "Default resume partition"
++ default ""
++ ---help---
++ The default resume partition is the partition that the pmdisk suspend-
++ to-disk implementation will look for a suspended disk image.
++
++ The partition specified here will be different for almost every user.
++ It should be a valid swap partition (at least for now) that is turned
++ on before suspending.
++
++ The partition specified can be overridden by specifying:
++
++ pmdisk=/dev/<other device>
++
++ which will set the resume partition to the device specified.
++
++ One may also do:
++
++ pmdisk=off
++
++ to inform the kernel not to perform a resume transition.
++
++ Note there is currently not a way to specify which device to save the
++ suspended image to. It will simply pick the first available swap
++ device.
++
+Index: linux-2.6.0-test5/kernel/power/main.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/power/main.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/power/main.c 2003-09-27 11:38:41.290251312 +0800
+@@ -8,32 +8,23 @@
+ *
+ */
+
++#define DEBUG
++
+ #include <linux/suspend.h>
+ #include <linux/kobject.h>
+-#include <linux/reboot.h>
+ #include <linux/string.h>
++#include <linux/delay.h>
+ #include <linux/errno.h>
+ #include <linux/init.h>
+ #include <linux/pm.h>
+-#include <linux/fs.h>
+
+
+ #include "power.h"
+
+-static DECLARE_MUTEX(pm_sem);
+-
+-static struct pm_ops * pm_ops = NULL;
+-
+-static u32 pm_disk_mode = PM_DISK_SHUTDOWN;
+-
+-#ifdef CONFIG_SOFTWARE_SUSPEND
+-static int have_swsusp = 1;
+-#else
+-static int have_swsusp = 0;
+-#endif
+-
+-extern long sys_sync(void);
++DECLARE_MUTEX(pm_sem);
+
++struct pm_ops * pm_ops = NULL;
++u32 pm_disk_mode = PM_DISK_SHUTDOWN;
+
+ /**
+ * pm_set_ops - Set the global power method table.
+@@ -51,171 +42,6 @@
+
+
+ /**
+- * pm_suspend_standby - Enter 'standby' state.
+- *
+- * 'standby' is also known as 'Power-On Suspend'. Here, we power down
+- * devices, disable interrupts, and enter the state.
+- */
+-
+-static int pm_suspend_standby(void)
+-{
+- int error = 0;
+- unsigned long flags;
+-
+- if (!pm_ops || !pm_ops->enter)
+- return -EPERM;
+-
+- local_irq_save(flags);
+- if ((error = device_power_down(PM_SUSPEND_STANDBY)))
+- goto Done;
+- error = pm_ops->enter(PM_SUSPEND_STANDBY);
+- local_irq_restore(flags);
+- device_power_up();
+- Done:
+- return error;
+-}
+-
+-
+-/**
+- * pm_suspend_mem - Enter suspend-to-RAM state.
+- *
+- * Identical to pm_suspend_standby() - we power down devices, disable
+- * interrupts, and enter the low-power state.
+- */
+-
+-static int pm_suspend_mem(void)
+-{
+- int error = 0;
+- unsigned long flags;
+-
+- if (!pm_ops || !pm_ops->enter)
+- return -EPERM;
+-
+- local_irq_save(flags);
+- if ((error = device_power_down(PM_SUSPEND_STANDBY)))
+- goto Done;
+- error = pm_ops->enter(PM_SUSPEND_STANDBY);
+- local_irq_restore(flags);
+- device_power_up();
+- Done:
+- return error;
+-}
+-
+-
+-/**
+- * power_down - Shut machine down for hibernate.
+- * @mode: Suspend-to-disk mode
+- *
+- * Use the platform driver, if configured so, and return gracefully if it
+- * fails.
+- * Otherwise, try to power off and reboot. If they fail, halt the machine,
+- * there ain't no turning back.
+- */
+-
+-static int power_down(u32 mode)
+-{
+- unsigned long flags;
+- int error = 0;
+-
+- local_irq_save(flags);
+- device_power_down(PM_SUSPEND_DISK);
+- switch(mode) {
+- case PM_DISK_PLATFORM:
+- error = pm_ops->enter(PM_SUSPEND_DISK);
+- if (error) {
+- device_power_up();
+- local_irq_restore(flags);
+- return error;
+- }
+- case PM_DISK_SHUTDOWN:
+- machine_power_off();
+- break;
+- case PM_DISK_REBOOT:
+- machine_restart(NULL);
+- break;
+- }
+- machine_halt();
+- return 0;
+-}
+-
+-
+-static int in_suspend __nosavedata = 0;
+-
+-
+-/**
+- * free_some_memory - Try to free as much memory as possible
+- *
+- * ... but do not OOM-kill anyone
+- *
+- * Notice: all userland should be stopped at this point, or
+- * livelock is possible.
+- */
+-
+-static void free_some_memory(void)
+-{
+- printk("Freeing memory: ");
+- while (shrink_all_memory(10000))
+- printk(".");
+- printk("|\n");
+- blk_run_queues();
+-}
+-
+-
+-/**
+- * pm_suspend_disk - The granpappy of power management.
+- *
+- * If we're going through the firmware, then get it over with quickly.
+- *
+- * If not, then call swsusp to do it's thing, then figure out how
+- * to power down the system.
+- */
+-
+-static int pm_suspend_disk(void)
+-{
+- int error;
+-
+- pr_debug("PM: Attempting to suspend to disk.\n");
+- if (pm_disk_mode == PM_DISK_FIRMWARE)
+- return pm_ops->enter(PM_SUSPEND_DISK);
+-
+- if (!have_swsusp)
+- return -EPERM;
+-
+- pr_debug("PM: snapshotting memory.\n");
+- in_suspend = 1;
+- if ((error = swsusp_save()))
+- goto Done;
+-
+- if (in_suspend) {
+- pr_debug("PM: writing image.\n");
+- error = swsusp_write();
+- if (!error)
+- error = power_down(pm_disk_mode);
+- pr_debug("PM: Power down failed.\n");
+- } else
+- pr_debug("PM: Image restored successfully.\n");
+- swsusp_free();
+- Done:
+- return error;
+-}
+-
+-
+-
+-#define decl_state(_name) \
+- { .name = __stringify(_name), .fn = pm_suspend_##_name }
+-
+-struct pm_state {
+- char * name;
+- int (*fn)(void);
+-} pm_states[] = {
+- [PM_SUSPEND_STANDBY] = decl_state(standby),
+- [PM_SUSPEND_MEM] = decl_state(mem),
+- [PM_SUSPEND_DISK] = decl_state(disk),
+- { NULL },
+-};
+-
+-
+-/**
+ * suspend_prepare - Do prep work before entering low-power state.
+ * @state: State we're entering.
+ *
+@@ -228,36 +54,47 @@
+ {
+ int error = 0;
+
++ if (!pm_ops || !pm_ops->enter)
++ return -EPERM;
++
+ pm_prepare_console();
+
+- sys_sync();
+ if (freeze_processes()) {
+ error = -EAGAIN;
+ goto Thaw;
+ }
+
+- if (pm_ops && pm_ops->prepare) {
++ if (pm_ops->prepare) {
+ if ((error = pm_ops->prepare(state)))
+ goto Thaw;
+ }
+
+- /* Free memory before shutting down devices. */
+- if (state == PM_SUSPEND_DISK)
+- free_some_memory();
+-
+ if ((error = device_suspend(state)))
+ goto Finish;
+-
+ return 0;
+- Done:
+- pm_restore_console();
+- return error;
+ Finish:
+- if (pm_ops && pm_ops->finish)
++ if (pm_ops->finish)
+ pm_ops->finish(state);
+ Thaw:
+ thaw_processes();
+- goto Done;
++ pm_restore_console();
++ return error;
++}
++
++
++static int suspend_enter(u32 state)
++{
++ int error = 0;
++ unsigned long flags;
++
++ local_irq_save(flags);
++ if ((error = device_power_down(state)))
++ goto Done;
++ error = pm_ops->enter(state);
++ device_power_up();
++ Done:
++ local_irq_restore(flags);
++ return error;
+ }
+
+
+@@ -279,6 +116,16 @@
+ }
+
+
++
++
++char * pm_states[] = {
++ [PM_SUSPEND_STANDBY] = "standby",
++ [PM_SUSPEND_MEM] = "mem",
++ [PM_SUSPEND_DISK] = "disk",
++ NULL,
++};
++
++
+ /**
+ * enter_state - Do common work of entering low-power state.
+ * @state: pm_state structure for state we're entering.
+@@ -293,7 +140,6 @@
+ static int enter_state(u32 state)
+ {
+ int error;
+- struct pm_state * s = &pm_states[state];
+
+ if (down_trylock(&pm_sem))
+ return -EBUSY;
+@@ -304,12 +150,17 @@
+ goto Unlock;
+ }
+
+- pr_debug("PM: Preparing system for suspend.\n");
++ if (state == PM_SUSPEND_DISK) {
++ error = pm_suspend_disk();
++ goto Unlock;
++ }
++
++ pr_debug("PM: Preparing system for suspend\n");
+ if ((error = suspend_prepare(state)))
+ goto Unlock;
+
+ pr_debug("PM: Entering state.\n");
+- error = s->fn();
++ error = suspend_enter(state);
+
+ pr_debug("PM: Finishing up.\n");
+ suspend_finish(state);
+@@ -335,138 +186,10 @@
+ }
+
+
+-/**
+- * pm_resume - Resume from a saved image.
+- *
+- * Called as a late_initcall (so all devices are discovered and
+- * initialized), we call swsusp to see if we have a saved image or not.
+- * If so, we quiesce devices, the restore the saved image. We will
+- * return above (in pm_suspend_disk() ) if everything goes well.
+- * Otherwise, we fail gracefully and return to the normally
+- * scheduled program.
+- *
+- */
+-
+-static int pm_resume(void)
+-{
+- int error;
+-
+- if (!have_swsusp)
+- return 0;
+-
+- pr_debug("PM: Reading swsusp image.\n");
+-
+- if ((error = swsusp_read()))
+- goto Done;
+-
+- pr_debug("PM: Preparing system for restore.\n");
+-
+- if ((error = suspend_prepare(PM_SUSPEND_DISK)))
+- goto Free;
+-
+- pr_debug("PM: Restoring saved image.\n");
+- swsusp_restore();
+-
+- pr_debug("PM: Restore failed, recovering.n");
+- suspend_finish(PM_SUSPEND_DISK);
+- Free:
+- swsusp_free();
+- Done:
+- pr_debug("PM: Resume from disk failed.\n");
+- return 0;
+-}
+-
+-late_initcall(pm_resume);
+-
+
+ decl_subsys(power,NULL,NULL);
+
+
+-#define power_attr(_name) \
+-static struct subsys_attribute _name##_attr = { \
+- .attr = { \
+- .name = __stringify(_name), \
+- .mode = 0644, \
+- }, \
+- .show = _name##_show, \
+- .store = _name##_store, \
+-}
+-
+-
+-static char * pm_disk_modes[] = {
+- [PM_DISK_FIRMWARE] = "firmware",
+- [PM_DISK_PLATFORM] = "platform",
+- [PM_DISK_SHUTDOWN] = "shutdown",
+- [PM_DISK_REBOOT] = "reboot",
+-};
+-
+-/**
+- * disk - Control suspend-to-disk mode
+- *
+- * Suspend-to-disk can be handled in several ways. The greatest
+- * distinction is who writes memory to disk - the firmware or the OS.
+- * If the firmware does it, we assume that it also handles suspending
+- * the system.
+- * If the OS does it, then we have three options for putting the system
+- * to sleep - using the platform driver (e.g. ACPI or other PM registers),
+- * powering off the system or rebooting the system (for testing).
+- *
+- * The system will support either 'firmware' or 'platform', and that is
+- * known a priori (and encoded in pm_ops). But, the user may choose
+- * 'shutdown' or 'reboot' as alternatives.
+- *
+- * show() will display what the mode is currently set to.
+- * store() will accept one of
+- *
+- * 'firmware'
+- * 'platform'
+- * 'shutdown'
+- * 'reboot'
+- *
+- * It will only change to 'firmware' or 'platform' if the system
+- * supports it (as determined from pm_ops->pm_disk_mode).
+- */
+-
+-static ssize_t disk_show(struct subsystem * subsys, char * buf)
+-{
+- return sprintf(buf,"%s\n",pm_disk_modes[pm_disk_mode]);
+-}
+-
+-
+-static ssize_t disk_store(struct subsystem * s, const char * buf, size_t n)
+-{
+- int error = 0;
+- int i;
+- u32 mode = 0;
+-
+- down(&pm_sem);
+- for (i = PM_DISK_FIRMWARE; i < PM_DISK_MAX; i++) {
+- if (!strcmp(buf,pm_disk_modes[i])) {
+- mode = i;
+- break;
+- }
+- }
+- if (mode) {
+- if (mode == PM_DISK_SHUTDOWN || mode == PM_DISK_REBOOT)
+- pm_disk_mode = mode;
+- else {
+- if (pm_ops && pm_ops->enter &&
+- (mode == pm_ops->pm_disk_mode))
+- pm_disk_mode = mode;
+- else
+- error = -EINVAL;
+- }
+- } else
+- error = -EINVAL;
+-
+- pr_debug("PM: suspend-to-disk mode set to '%s'\n",
+- pm_disk_modes[mode]);
+- up(&pm_sem);
+- return error ? error : n;
+-}
+-
+-power_attr(disk);
+-
+ /**
+ * state - control system power state.
+ *
+@@ -480,27 +203,28 @@
+
+ static ssize_t state_show(struct subsystem * subsys, char * buf)
+ {
+- struct pm_state * state;
++ int i;
+ char * s = buf;
+
+- for (state = &pm_states[0]; state->name; state++)
+- s += sprintf(s,"%s ",state->name);
++ for (i = 0; i < PM_SUSPEND_MAX; i++) {
++ if (pm_states[i])
++ s += sprintf(s,"%s ",pm_states[i]);
++ }
+ s += sprintf(s,"\n");
+ return (s - buf);
+ }
+
+ static ssize_t state_store(struct subsystem * subsys, const char * buf, size_t n)
+ {
+- u32 state;
+- struct pm_state * s;
++ u32 state = PM_SUSPEND_STANDBY;
++ char ** s;
+ int error;
+
+- for (state = 0; state < PM_SUSPEND_MAX; state++) {
+- s = &pm_states[state];
+- if (s->name && !strcmp(buf,s->name))
++ for (s = &pm_states[state]; *s; s++, state++) {
++ if (!strcmp(buf,*s))
+ break;
+ }
+- if (s)
++ if (*s)
+ error = enter_state(state);
+ else
+ error = -EINVAL;
+@@ -511,7 +235,6 @@
+
+ static struct attribute * g[] = {
+ &state_attr.attr,
+- &disk_attr.attr,
+ NULL,
+ };
+
+@@ -520,7 +243,7 @@
+ };
+
+
+-static int pm_init(void)
++static int __init pm_init(void)
+ {
+ int error = subsystem_register(&power_subsys);
+ if (!error)
+Index: linux-2.6.0-test5/kernel/power/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/power/Makefile 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/power/Makefile 2003-09-27 11:38:41.291251160 +0800
+@@ -1,4 +1,5 @@
+ obj-y := main.o process.o console.o pm.o
+ obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o
++obj-$(CONFIG_PM_DISK) += disk.o pmdisk.o
+
+ obj-$(CONFIG_MAGIC_SYSRQ) += poweroff.o
+Index: linux-2.6.0-test5/kernel/power/pmdisk.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/power/pmdisk.c 2003-09-27 11:38:18.489717520 +0800
++++ linux-2.6.0-test5/kernel/power/pmdisk.c 2003-09-27 11:38:41.293250856 +0800
+@@ -0,0 +1,942 @@
++/*
++ * kernel/power/pmdisk.c - Suspend-to-disk implmentation
++ *
++ * This STD implementation is initially derived from swsusp (suspend-to-swap).
++ * The original copyright on that was:
++ *
++ * Copyright (C) 1998-2001 Gabor Kuti <seasons@fornax.hu>
++ * Copyright (C) 1998,2001,2002 Pavel Machek <pavel@suse.cz>
++ *
++ * The additional parts are:
++ *
++ * Copyright (C) 2003 Patrick Mochel
++ * Copyright (C) 2003 Open Source Development Lab
++ *
++ * This file is released under the GPLv2.
++ *
++ * For more information, please see the text files in Documentation/power/
++ *
++ */
++
++#include <linux/mm.h>
++#include <linux/bio.h>
++#include <linux/suspend.h>
++#include <linux/version.h>
++#include <linux/reboot.h>
++#include <linux/device.h>
++#include <linux/swapops.h>
++#include <linux/bootmem.h>
++
++#include <asm/mmu_context.h>
++
++#include "power.h"
++
++
++extern int pmdisk_arch_suspend(int resume);
++
++#define __ADDRESS(x) ((unsigned long) phys_to_virt(x))
++#define ADDRESS(x) __ADDRESS((x) << PAGE_SHIFT)
++#define ADDRESS2(x) __ADDRESS(__pa(x)) /* Needed for x86-64 where some pages are in memory twice */
++
++/* References to section boundaries */
++extern char __nosave_begin, __nosave_end;
++
++extern int is_head_of_free_region(struct page *);
++
++/* Variables to be preserved over suspend */
++static int pagedir_order_check;
++static int nr_copy_pages_check;
++
++/* For resume= kernel option */
++static char resume_file[256] = CONFIG_PM_DISK_PARTITION;
++
++static dev_t resume_device;
++/* Local variables that should not be affected by save */
++unsigned int pmdisk_pages __nosavedata = 0;
++
++/* Suspend pagedir is allocated before final copy, therefore it
++ must be freed after resume
++
++ Warning: this is evil. There are actually two pagedirs at time of
++ resume. One is "pagedir_save", which is empty frame allocated at
++ time of suspend, that must be freed. Second is "pagedir_nosave",
++ allocated at time of resume, that travels through memory not to
++ collide with anything.
++ */
++suspend_pagedir_t *pm_pagedir_nosave __nosavedata = NULL;
++static suspend_pagedir_t *pagedir_save;
++static int pagedir_order __nosavedata = 0;
++
++struct link {
++ char dummy[PAGE_SIZE - sizeof(swp_entry_t)];
++ swp_entry_t next;
++};
++
++union diskpage {
++ union swap_header swh;
++ struct link link;
++ struct suspend_header sh;
++};
++
++/*
++ * XXX: We try to keep some more pages free so that I/O operations succeed
++ * without paging. Might this be more?
++ */
++#define PAGES_FOR_IO 512
++
++static const char name_suspend[] = "Suspend Machine: ";
++static const char name_resume[] = "Resume Machine: ";
++
++/*
++ * Debug
++ */
++#define DEBUG_DEFAULT
++#undef DEBUG_PROCESS
++#undef DEBUG_SLOW
++#define TEST_SWSUSP 0 /* Set to 1 to reboot instead of halt machine after suspension */
++
++#ifdef DEBUG_DEFAULT
++# define PRINTK(f, a...) printk(f, ## a)
++#else
++# define PRINTK(f, a...)
++#endif
++
++#ifdef DEBUG_SLOW
++#define MDELAY(a) mdelay(a)
++#else
++#define MDELAY(a)
++#endif
++
++/*
++ * Saving part...
++ */
++
++static __inline__ int fill_suspend_header(struct suspend_header *sh)
++{
++ memset((char *)sh, 0, sizeof(*sh));
++
++ sh->version_code = LINUX_VERSION_CODE;
++ sh->num_physpages = num_physpages;
++ strncpy(sh->machine, system_utsname.machine, 8);
++ strncpy(sh->version, system_utsname.version, 20);
++ /* FIXME: Is this bogus? --RR */
++ sh->num_cpus = num_online_cpus();
++ sh->page_size = PAGE_SIZE;
++ sh->suspend_pagedir = pm_pagedir_nosave;
++ BUG_ON (pagedir_save != pm_pagedir_nosave);
++ sh->num_pbes = pmdisk_pages;
++ /* TODO: needed? mounted fs' last mounted date comparison
++ * [so they haven't been mounted since last suspend.
++ * Maybe it isn't.] [we'd need to do this for _all_ fs-es]
++ */
++ return 0;
++}
++
++/* We memorize in swapfile_used what swap devices are used for suspension */
++#define SWAPFILE_UNUSED 0
++#define SWAPFILE_SUSPEND 1 /* This is the suspending device */
++#define SWAPFILE_IGNORED 2 /* Those are other swap devices ignored for suspension */
++
++static unsigned short swapfile_used[MAX_SWAPFILES];
++static unsigned short root_swap;
++#define MARK_SWAP_SUSPEND 0
++#define MARK_SWAP_RESUME 2
++
++static void mark_swapfiles(swp_entry_t prev, int mode)
++{
++ swp_entry_t entry;
++ union diskpage *cur;
++ struct page *page;
++
++ if (root_swap == 0xFFFF) /* ignored */
++ return;
++
++ page = alloc_page(GFP_ATOMIC);
++ if (!page)
++ panic("Out of memory in mark_swapfiles");
++ cur = page_address(page);
++ /* XXX: this is dirty hack to get first page of swap file */
++ entry = swp_entry(root_swap, 0);
++ rw_swap_page_sync(READ, entry, page);
++
++ if (mode == MARK_SWAP_RESUME) {
++ if (!memcmp("S1",cur->swh.magic.magic,2))
++ memcpy(cur->swh.magic.magic,"SWAP-SPACE",10);
++ else if (!memcmp("S2",cur->swh.magic.magic,2))
++ memcpy(cur->swh.magic.magic,"SWAPSPACE2",10);
++ else printk("%sUnable to find suspended-data signature (%.10s - misspelled?\n",
++ name_resume, cur->swh.magic.magic);
++ } else {
++ if ((!memcmp("SWAP-SPACE",cur->swh.magic.magic,10)))
++ memcpy(cur->swh.magic.magic,"S1SUSP....",10);
++ else if ((!memcmp("SWAPSPACE2",cur->swh.magic.magic,10)))
++ memcpy(cur->swh.magic.magic,"S2SUSP....",10);
++ else panic("\nSwapspace is not swapspace (%.10s)\n", cur->swh.magic.magic);
++ cur->link.next = prev; /* prev is the first/last swap page of the resume area */
++ /* link.next lies *no more* in last 4/8 bytes of magic */
++ }
++ rw_swap_page_sync(WRITE, entry, page);
++ __free_page(page);
++}
++
++static void read_swapfiles(void) /* This is called before saving image */
++{
++ int i, len;
++
++ len=strlen(resume_file);
++ root_swap = 0xFFFF;
++
++ swap_list_lock();
++ for(i=0; i<MAX_SWAPFILES; i++) {
++ if (swap_info[i].flags == 0) {
++ swapfile_used[i]=SWAPFILE_UNUSED;
++ } else {
++ if(!len) {
++ printk(KERN_WARNING "resume= option should be used to set suspend device" );
++ if(root_swap == 0xFFFF) {
++ swapfile_used[i] = SWAPFILE_SUSPEND;
++ root_swap = i;
++ } else
++ swapfile_used[i] = SWAPFILE_IGNORED;
++ } else {
++ /* we ignore all swap devices that are not the resume_file */
++ if (1) {
++// FIXME if(resume_device == swap_info[i].swap_device) {
++ swapfile_used[i] = SWAPFILE_SUSPEND;
++ root_swap = i;
++ } else {
++#if 0
++ printk( "Resume: device %s (%x != %x) ignored\n", swap_info[i].swap_file->d_name.name, swap_info[i].swap_device, resume_device );
++#endif
++ swapfile_used[i] = SWAPFILE_IGNORED;
++ }
++ }
++ }
++ }
++ swap_list_unlock();
++}
++
++static void lock_swapdevices(void) /* This is called after saving image so modification
++ will be lost after resume... and that's what we want. */
++{
++ int i;
++
++ swap_list_lock();
++ for(i = 0; i< MAX_SWAPFILES; i++)
++ if(swapfile_used[i] == SWAPFILE_IGNORED) {
++ swap_info[i].flags ^= 0xFF; /* we make the device unusable. A new call to
++ lock_swapdevices can unlock the devices. */
++ }
++ swap_list_unlock();
++}
++
++static int write_suspend_image(void)
++{
++ int i;
++ swp_entry_t entry, prev = { 0 };
++ int nr_pgdir_pages = SUSPEND_PD_PAGES(pmdisk_pages);
++ union diskpage *cur, *buffer = (union diskpage *)get_zeroed_page(GFP_ATOMIC);
++ unsigned long address;
++ struct page *page;
++
++ printk( "Writing data to swap (%d pages): ", pmdisk_pages );
++ for (i=0; i<pmdisk_pages; i++) {
++ if (!(i%100))
++ printk( "." );
++ if (!(entry = get_swap_page()).val)
++ panic("\nNot enough swapspace when writing data" );
++
++ if (swapfile_used[swp_type(entry)] != SWAPFILE_SUSPEND)
++ panic("\nPage %d: not enough swapspace on suspend device", i );
++
++ address = (pm_pagedir_nosave+i)->address;
++ page = virt_to_page(address);
++ rw_swap_page_sync(WRITE, entry, page);
++ (pm_pagedir_nosave+i)->swap_address = entry;
++ }
++ printk( "|\n" );
++ printk( "Writing pagedir (%d pages): ", nr_pgdir_pages);
++ for (i=0; i<nr_pgdir_pages; i++) {
++ cur = (union diskpage *)((char *) pm_pagedir_nosave)+i;
++ BUG_ON ((char *) cur != (((char *) pm_pagedir_nosave) + i*PAGE_SIZE));
++ printk( "." );
++ if (!(entry = get_swap_page()).val) {
++ printk(KERN_CRIT "Not enough swapspace when writing pgdir\n" );
++ panic("Don't know how to recover");
++ free_page((unsigned long) buffer);
++ return -ENOSPC;
++ }
++
++ if(swapfile_used[swp_type(entry)] != SWAPFILE_SUSPEND)
++ panic("\nNot enough swapspace for pagedir on suspend device" );
++
++ BUG_ON (sizeof(swp_entry_t) != sizeof(long));
++ BUG_ON (PAGE_SIZE % sizeof(struct pbe));
++
++ cur->link.next = prev;
++ page = virt_to_page((unsigned long)cur);
++ rw_swap_page_sync(WRITE, entry, page);
++ prev = entry;
++ }
++ printk("H");
++ BUG_ON (sizeof(struct suspend_header) > PAGE_SIZE-sizeof(swp_entry_t));
++ BUG_ON (sizeof(union diskpage) != PAGE_SIZE);
++ if (!(entry = get_swap_page()).val)
++ panic( "\nNot enough swapspace when writing header" );
++ if (swapfile_used[swp_type(entry)] != SWAPFILE_SUSPEND)
++ panic("\nNot enough swapspace for header on suspend device" );
++
++ cur = (void *) buffer;
++ if (fill_suspend_header(&cur->sh))
++ panic("\nOut of memory while writing header");
++
++ cur->link.next = prev;
++
++ page = virt_to_page((unsigned long)cur);
++ rw_swap_page_sync(WRITE, entry, page);
++ prev = entry;
++
++ printk( "S" );
++ mark_swapfiles(prev, MARK_SWAP_SUSPEND);
++ printk( "|\n" );
++
++ MDELAY(1000);
++ free_page((unsigned long) buffer);
++ return 0;
++}
++
++/* if pagedir_p != NULL it also copies the counted pages */
++static int count_and_copy_data_pages(struct pbe *pagedir_p)
++{
++ int chunk_size;
++ int nr_copy_pages = 0;
++ int pfn;
++ struct page *page;
++
++ BUG_ON (max_pfn != num_physpages);
++
++ for (pfn = 0; pfn < max_pfn; pfn++) {
++ page = pfn_to_page(pfn);
++
++ if (!PageReserved(page)) {
++ if (PageNosave(page))
++ continue;
++
++ if ((chunk_size=is_head_of_free_region(page))!=0) {
++ pfn += chunk_size - 1;
++ continue;
++ }
++ } else if (PageReserved(page)) {
++ BUG_ON (PageNosave(page));
++
++ /*
++ * Just copy whole code segment. Hopefully it is not that big.
++ */
++ if ((ADDRESS(pfn) >= (unsigned long) ADDRESS2(&__nosave_begin)) &&
++ (ADDRESS(pfn) < (unsigned long) ADDRESS2(&__nosave_end))) {
++ PRINTK("[nosave %lx]", ADDRESS(pfn));
++ continue;
++ }
++ /* Hmm, perhaps copying all reserved pages is not too healthy as they may contain
++ critical bios data? */
++ } else BUG();
++
++ nr_copy_pages++;
++ if (pagedir_p) {
++ pagedir_p->orig_address = ADDRESS(pfn);
++ copy_page((void *) pagedir_p->address, (void *) pagedir_p->orig_address);
++ pagedir_p++;
++ }
++ }
++ return nr_copy_pages;
++}
++
++static void free_suspend_pagedir(unsigned long this_pagedir)
++{
++ struct page *page;
++ int pfn;
++ unsigned long this_pagedir_end = this_pagedir +
++ (PAGE_SIZE << pagedir_order);
++
++ for(pfn = 0; pfn < num_physpages; pfn++) {
++ page = pfn_to_page(pfn);
++ if (!TestClearPageNosave(page))
++ continue;
++
++ if (ADDRESS(pfn) >= this_pagedir && ADDRESS(pfn) < this_pagedir_end)
++ continue; /* old pagedir gets freed in one */
++
++ free_page(ADDRESS(pfn));
++ }
++ free_pages(this_pagedir, pagedir_order);
++}
++
++static suspend_pagedir_t *create_suspend_pagedir(int nr_copy_pages)
++{
++ int i;
++ suspend_pagedir_t *pagedir;
++ struct pbe *p;
++ struct page *page;
++
++ pagedir_order = get_bitmask_order(SUSPEND_PD_PAGES(nr_copy_pages));
++
++ p = pagedir = (suspend_pagedir_t *)__get_free_pages(GFP_ATOMIC | __GFP_COLD, pagedir_order);
++ if(!pagedir)
++ return NULL;
++
++ page = virt_to_page(pagedir);
++ for(i=0; i < 1<<pagedir_order; i++)
++ SetPageNosave(page++);
++
++ while(nr_copy_pages--) {
++ p->address = get_zeroed_page(GFP_ATOMIC | __GFP_COLD);
++ if(!p->address) {
++ free_suspend_pagedir((unsigned long) pagedir);
++ return NULL;
++ }
++ SetPageNosave(virt_to_page(p->address));
++ p->orig_address = 0;
++ p++;
++ }
++ return pagedir;
++}
++
++
++int pmdisk_suspend(void)
++{
++ struct sysinfo i;
++ unsigned int nr_needed_pages = 0;
++
++ read_swapfiles();
++ drain_local_pages();
++
++ pm_pagedir_nosave = NULL;
++ printk( "/critical section: Counting pages to copy" );
++ pmdisk_pages = count_and_copy_data_pages(NULL);
++ nr_needed_pages = pmdisk_pages + PAGES_FOR_IO;
++
++ printk(" (pages needed: %d+%d=%d free: %d)\n",pmdisk_pages,PAGES_FOR_IO,nr_needed_pages,nr_free_pages());
++ if(nr_free_pages() < nr_needed_pages) {
++ printk(KERN_CRIT "%sCouldn't get enough free pages, on %d pages short\n",
++ name_suspend, nr_needed_pages-nr_free_pages());
++ root_swap = 0xFFFF;
++ return 1;
++ }
++ si_swapinfo(&i); /* FIXME: si_swapinfo(&i) returns all swap devices information.
++ We should only consider resume_device. */
++ if (i.freeswap < nr_needed_pages) {
++ printk(KERN_CRIT "%sThere's not enough swap space available, on %ld pages short\n",
++ name_suspend, nr_needed_pages-i.freeswap);
++ return 1;
++ }
++
++ PRINTK( "Alloc pagedir\n" );
++ pagedir_save = pm_pagedir_nosave = create_suspend_pagedir(pmdisk_pages);
++ if(!pm_pagedir_nosave) {
++ /* Shouldn't happen */
++ printk(KERN_CRIT "%sCouldn't allocate enough pages\n",name_suspend);
++ panic("Really should not happen");
++ return 1;
++ }
++ nr_copy_pages_check = pmdisk_pages;
++ pagedir_order_check = pagedir_order;
++
++ drain_local_pages(); /* During allocating of suspend pagedir, new cold pages may appear. Kill them */
++ if (pmdisk_pages != count_and_copy_data_pages(pm_pagedir_nosave)) /* copy */
++ BUG();
++
++ /*
++ * End of critical section. From now on, we can write to memory,
++ * but we should not touch disk. This specially means we must _not_
++ * touch swap space! Except we must write out our image of course.
++ */
++
++ printk( "critical section/: done (%d pages copied)\n", pmdisk_pages );
++ return 0;
++}
++
++
++/**
++ * suspend_save_image - Prepare and write saved image to swap.
++ *
++ * IRQs are re-enabled here so we can resume devices and safely write
++ * to the swap devices. We disable them again before we leave.
++ *
++ * The second lock_swapdevices() will unlock ignored swap devices since
++ * writing is finished.
++ * It is important _NOT_ to umount filesystems at this point. We want
++ * them synced (in case something goes wrong) but we DO not want to mark
++ * filesystem clean: it is not. (And it does not matter, if we resume
++ * correctly, we'll mark system clean, anyway.)
++ */
++
++static int suspend_save_image(void)
++{
++ int error;
++ device_resume();
++ lock_swapdevices();
++ error = write_suspend_image();
++ lock_swapdevices();
++ return error;
++}
++
++/*
++ * Magic happens here
++ */
++
++int pmdisk_resume(void)
++{
++ BUG_ON (nr_copy_pages_check != pmdisk_pages);
++ BUG_ON (pagedir_order_check != pagedir_order);
++
++ /* Even mappings of "global" things (vmalloc) need to be fixed */
++ __flush_tlb_global();
++ return 0;
++}
++
++/* pmdisk_arch_suspend() is implemented in arch/?/power/pmdisk.S,
++ and basically does:
++
++ if (!resume) {
++ save_processor_state();
++ SAVE_REGISTERS
++ return pmdisk_suspend();
++ }
++ GO_TO_SWAPPER_PAGE_TABLES
++ COPY_PAGES_BACK
++ RESTORE_REGISTERS
++ restore_processor_state();
++ return pmdisk_resume();
++
++ */
++
++
++/* More restore stuff */
++
++/* FIXME: Why not memcpy(to, from, 1<<pagedir_order*PAGE_SIZE)? */
++static void __init copy_pagedir(suspend_pagedir_t *to, suspend_pagedir_t *from)
++{
++ int i;
++ char *topointer=(char *)to, *frompointer=(char *)from;
++
++ for(i=0; i < 1 << pagedir_order; i++) {
++ copy_page(topointer, frompointer);
++ topointer += PAGE_SIZE;
++ frompointer += PAGE_SIZE;
++ }
++}
++
++#define does_collide(addr) does_collide_order(pm_pagedir_nosave, addr, 0)
++
++/*
++ * Returns true if given address/order collides with any orig_address
++ */
++static int __init does_collide_order(suspend_pagedir_t *pagedir,
++ unsigned long addr, int order)
++{
++ int i;
++ unsigned long addre = addr + (PAGE_SIZE<<order);
++
++ for(i=0; i < pmdisk_pages; i++)
++ if((pagedir+i)->orig_address >= addr &&
++ (pagedir+i)->orig_address < addre)
++ return 1;
++
++ return 0;
++}
++
++/*
++ * We check here that pagedir & pages it points to won't collide with pages
++ * where we're going to restore from the loaded pages later
++ */
++static int __init check_pagedir(void)
++{
++ int i;
++
++ for(i=0; i < pmdisk_pages; i++) {
++ unsigned long addr;
++
++ do {
++ addr = get_zeroed_page(GFP_ATOMIC);
++ if(!addr)
++ return -ENOMEM;
++ } while (does_collide(addr));
++
++ (pm_pagedir_nosave+i)->address = addr;
++ }
++ return 0;
++}
++
++static int __init relocate_pagedir(void)
++{
++ /*
++ * We have to avoid recursion (not to overflow kernel stack),
++ * and that's why code looks pretty cryptic
++ */
++ suspend_pagedir_t *new_pagedir, *old_pagedir = pm_pagedir_nosave;
++ void **eaten_memory = NULL;
++ void **c = eaten_memory, *m, *f;
++
++ printk("Relocating pagedir");
++
++ if(!does_collide_order(old_pagedir, (unsigned long)old_pagedir, pagedir_order)) {
++ printk("not necessary\n");
++ return 0;
++ }
++
++ while ((m = (void *) __get_free_pages(GFP_ATOMIC, pagedir_order))) {
++ memset(m, 0, PAGE_SIZE);
++ if (!does_collide_order(old_pagedir, (unsigned long)m, pagedir_order))
++ break;
++ eaten_memory = m;
++ printk( "." );
++ *eaten_memory = c;
++ c = eaten_memory;
++ }
++
++ if (!m)
++ return -ENOMEM;
++
++ pm_pagedir_nosave = new_pagedir = m;
++ copy_pagedir(new_pagedir, old_pagedir);
++
++ c = eaten_memory;
++ while(c) {
++ printk(":");
++ f = *c;
++ c = *c;
++ if (f)
++ free_pages((unsigned long)f, pagedir_order);
++ }
++ printk("|\n");
++ return 0;
++}
++
++/*
++ * Sanity check if this image makes sense with this kernel/swap context
++ * I really don't think that it's foolproof but more than nothing..
++ */
++
++static int __init sanity_check_failed(char *reason)
++{
++ printk(KERN_ERR "%s%s\n",name_resume,reason);
++ return -EPERM;
++}
++
++static int __init sanity_check(struct suspend_header *sh)
++{
++ if(sh->version_code != LINUX_VERSION_CODE)
++ return sanity_check_failed("Incorrect kernel version");
++ if(sh->num_physpages != num_physpages)
++ return sanity_check_failed("Incorrect memory size");
++ if(strncmp(sh->machine, system_utsname.machine, 8))
++ return sanity_check_failed("Incorrect machine type");
++ if(strncmp(sh->version, system_utsname.version, 20))
++ return sanity_check_failed("Incorrect version");
++ if(sh->num_cpus != num_online_cpus())
++ return sanity_check_failed("Incorrect number of cpus");
++ if(sh->page_size != PAGE_SIZE)
++ return sanity_check_failed("Incorrect PAGE_SIZE");
++ return 0;
++}
++
++static struct block_device * resume_bdev;
++
++
++/**
++ * Using bio to read from swap.
++ * This code requires a bit more work than just using buffer heads
++ * but, it is the recommended way for 2.5/2.6.
++ * The following are to signal the beginning and end of I/O. Bios
++ * finish asynchronously, while we want them to happen synchronously.
++ * A simple atomic_t, and a wait loop take care of this problem.
++ */
++
++static atomic_t io_done = ATOMIC_INIT(0);
++
++static void start_io(void)
++{
++ atomic_set(&io_done,1);
++}
++
++static int end_io(struct bio * bio, unsigned int num, int err)
++{
++ atomic_set(&io_done,0);
++ return 0;
++}
++
++static void wait_io(void)
++{
++ blk_run_queues();
++ while(atomic_read(&io_done))
++ io_schedule();
++}
++
++
++/**
++ * submit - submit BIO request.
++ * @rw: READ or WRITE.
++ * @off physical offset of page.
++ * @page: page we're reading or writing.
++ *
++ * Straight from the textbook - allocate and initialize the bio.
++ * If we're writing, make sure the page is marked as dirty.
++ * Then submit it and wait.
++ */
++
++static int submit(int rw, pgoff_t page_off, void * page)
++{
++ int error = 0;
++ struct bio * bio;
++
++ bio = bio_alloc(GFP_ATOMIC,1);
++ if (!bio)
++ return -ENOMEM;
++ bio->bi_sector = page_off * (PAGE_SIZE >> 9);
++ bio_get(bio);
++ bio->bi_bdev = resume_bdev;
++ bio->bi_end_io = end_io;
++
++ if (bio_add_page(bio, virt_to_page(page), PAGE_SIZE, 0) < PAGE_SIZE) {
++ printk("ERROR: adding page to bio at %ld\n",page_off);
++ error = -EFAULT;
++ goto Done;
++ }
++
++ if (rw == WRITE)
++ bio_set_pages_dirty(bio);
++ start_io();
++ submit_bio(rw,bio);
++ wait_io();
++ Done:
++ bio_put(bio);
++ return error;
++}
++
++static int
++read_page(pgoff_t page_off, void * page)
++{
++ return submit(READ,page_off,page);
++}
++
++static int
++write_page(pgoff_t page_off, void * page)
++{
++ return submit(WRITE,page_off,page);
++}
++
++
++extern dev_t __init name_to_dev_t(const char *line);
++
++
++#define next_entry(diskpage) diskpage->link.next
++
++static int __init read_suspend_image(void)
++{
++ swp_entry_t next;
++ int i, nr_pgdir_pages;
++ union diskpage *cur;
++ int error = 0;
++
++ cur = (union diskpage *)get_zeroed_page(GFP_ATOMIC);
++ if (!cur)
++ return -ENOMEM;
++
++ if ((error = read_page(0, cur)))
++ goto Done;
++
++ /*
++ * We have to read next position before we overwrite it
++ */
++ next = next_entry(cur);
++
++ if (!memcmp("S1",cur->swh.magic.magic,2))
++ memcpy(cur->swh.magic.magic,"SWAP-SPACE",10);
++ else if (!memcmp("S2",cur->swh.magic.magic,2))
++ memcpy(cur->swh.magic.magic,"SWAPSPACE2",10);
++ else if ((!memcmp("SWAP-SPACE",cur->swh.magic.magic,10)) ||
++ (!memcmp("SWAPSPACE2",cur->swh.magic.magic,10))) {
++ printk(KERN_ERR "pmdisk: Partition is normal swap space\n");
++ error = -EINVAL;
++ goto Done;
++ } else {
++ printk(KERN_ERR "pmdisk: Invalid partition type.\n");
++ error = -EINVAL;
++ goto Done;
++ }
++
++ /*
++ * Reset swap signature now.
++ */
++ if ((error = write_page(0,cur)))
++ goto Done;
++
++ printk( "%sSignature found, resuming\n", name_resume );
++ MDELAY(1000);
++
++ if ((error = read_page(swp_offset(next), cur)))
++ goto Done;
++ /* Is this same machine? */
++ if ((error = sanity_check(&cur->sh)))
++ goto Done;
++ next = next_entry(cur);
++
++ pagedir_save = cur->sh.suspend_pagedir;
++ pmdisk_pages = cur->sh.num_pbes;
++ nr_pgdir_pages = SUSPEND_PD_PAGES(pmdisk_pages);
++ pagedir_order = get_bitmask_order(nr_pgdir_pages);
++
++ pm_pagedir_nosave = (suspend_pagedir_t *)__get_free_pages(GFP_ATOMIC, pagedir_order);
++ if (!pm_pagedir_nosave) {
++ error = -ENOMEM;
++ goto Done;
++ }
++
++ PRINTK( "%sReading pagedir, ", name_resume );
++
++ /* We get pages in reverse order of saving! */
++ for (i=nr_pgdir_pages-1; i>=0; i--) {
++ BUG_ON (!next.val);
++ cur = (union diskpage *)((char *) pm_pagedir_nosave)+i;
++ error = read_page(swp_offset(next), cur);
++ if (error)
++ goto FreePagedir;
++ next = next_entry(cur);
++ }
++ BUG_ON (next.val);
++
++ if ((error = relocate_pagedir()))
++ goto FreePagedir;
++ if ((error = check_pagedir()))
++ goto FreePagedir;
++
++ printk( "Reading image data (%d pages): ", pmdisk_pages );
++ for(i=0; i < pmdisk_pages; i++) {
++ swp_entry_t swap_address = (pm_pagedir_nosave+i)->swap_address;
++ if (!(i%100))
++ printk( "." );
++ /* You do not need to check for overlaps...
++ ... check_pagedir already did this work */
++ error = read_page(swp_offset(swap_address),
++ (char *)((pm_pagedir_nosave+i)->address));
++ if (error)
++ goto FreePagedir;
++ }
++ printk( "|\n" );
++ Done:
++ free_page((unsigned long)cur);
++ return error;
++ FreePagedir:
++ free_pages((unsigned long)pm_pagedir_nosave,pagedir_order);
++ goto Done;
++}
++
++/**
++ * pmdisk_save - Snapshot memory
++ */
++
++int pmdisk_save(void)
++{
++ int error;
++
++#if defined (CONFIG_HIGHMEM) || defined (COFNIG_DISCONTIGMEM)
++ printk("pmdisk is not supported with high- or discontig-mem.\n");
++ return -EPERM;
++#endif
++ if ((error = arch_prepare_suspend()))
++ return error;
++ local_irq_disable();
++ error = pmdisk_arch_suspend(0);
++ local_irq_enable();
++ return error;
++}
++
++
++/**
++ * pmdisk_write - Write saved memory image to swap.
++ *
++ * pmdisk_arch_suspend(0) returns after system is resumed.
++ *
++ * pmdisk_arch_suspend() copies all "used" memory to "free" memory,
++ * then unsuspends all device drivers, and writes memory to disk
++ * using normal kernel mechanism.
++ */
++
++int pmdisk_write(void)
++{
++ return suspend_save_image();
++}
++
++
++/**
++ * pmdisk_read - Read saved image from swap.
++ */
++
++int __init pmdisk_read(void)
++{
++ int error;
++ char b[BDEVNAME_SIZE];
++
++ if (!strlen(resume_file))
++ return -ENOENT;
++
++ resume_device = name_to_dev_t(resume_file);
++ printk("pmdisk: Resume From Partition: %s, Device: %s\n",
++ resume_file, __bdevname(resume_device, b));
++
++ resume_bdev = open_by_devnum(resume_device, FMODE_READ, BDEV_RAW);
++ if (!IS_ERR(resume_bdev)) {
++ set_blocksize(resume_bdev, PAGE_SIZE);
++ error = read_suspend_image();
++ blkdev_put(resume_bdev, BDEV_RAW);
++ } else
++ error = PTR_ERR(resume_bdev);
++
++ if (!error)
++ PRINTK("Reading resume file was successful\n");
++ else
++ printk( "%sError %d resuming\n", name_resume, error );
++ MDELAY(1000);
++ return error;
++}
++
++
++/**
++ * pmdisk_restore - Replace running kernel with saved image.
++ */
++
++int __init pmdisk_restore(void)
++{
++ int error;
++ local_irq_disable();
++ error = pmdisk_arch_suspend(1);
++ local_irq_enable();
++ return error;
++}
++
++
++/**
++ * pmdisk_free - Free memory allocated to hold snapshot.
++ */
++
++int pmdisk_free(void)
++{
++ PRINTK( "Freeing prev allocated pagedir\n" );
++ free_suspend_pagedir((unsigned long) pagedir_save);
++ return 0;
++}
++
++static int __init pmdisk_setup(char *str)
++{
++ if (strlen(str)) {
++ if (!strcmp(str,"off"))
++ resume_file[0] = '\0';
++ else
++ strncpy(resume_file, str, 255);
++ } else
++ resume_file[0] = '\0';
++ return 1;
++}
++
++__setup("pmdisk=", pmdisk_setup);
++
+Index: linux-2.6.0-test5/kernel/power/power.h
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/power/power.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/power/power.h 2003-09-27 11:38:41.295250552 +0800
+@@ -9,35 +9,28 @@
+ #endif
+
+
+-#ifdef CONFIG_SOFTWARE_SUSPEND
+-extern int swsusp_save(void);
+-extern int swsusp_write(void);
+-extern int swsusp_read(void);
+-extern int swsusp_restore(void);
+-extern int swsusp_free(void);
++#ifdef CONFIG_PM_DISK
++extern int pm_suspend_disk(void);
++
+ #else
+-static inline int swsusp_save(void)
+-{
+- return 0;
+-}
+-static inline int swsusp_write(void)
++static inline int pm_suspend_disk(void)
+ {
+- return 0;
+-}
+-static inline int swsusp_read(void)
+-{
+- return 0;
+-}
+-static inline int swsusp_restore(void)
+-{
+- return 0;
+-}
+-static inline int swsusp_free(void)
+-{
+- return 0;
++ return -EPERM;
+ }
+ #endif
+
++extern struct semaphore pm_sem;
++#define power_attr(_name) \
++static struct subsys_attribute _name##_attr = { \
++ .attr = { \
++ .name = __stringify(_name), \
++ .mode = 0644, \
++ }, \
++ .show = _name##_show, \
++ .store = _name##_store, \
++}
++
++extern struct subsystem power_subsys;
+
+ extern int freeze_processes(void);
+ extern void thaw_processes(void);
+Index: linux-2.6.0-test5/kernel/power/swsusp.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/power/swsusp.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/power/swsusp.c 2003-09-27 11:38:41.302249488 +0800
+@@ -65,7 +65,15 @@
+
+ #include "power.h"
+
+-unsigned char software_suspend_enabled = 1;
++extern long sys_sync(void);
++
++unsigned char software_suspend_enabled = 0;
++
++extern void do_magic(int resume);
++
++#define NORESUME 1
++#define RESUME_SPECIFIED 2
++
+
+ #define __ADDRESS(x) ((unsigned long) phys_to_virt(x))
+ #define ADDRESS(x) __ADDRESS((x) << PAGE_SHIFT)
+@@ -83,7 +91,8 @@
+ static int pagedir_order_check;
+ static int nr_copy_pages_check;
+
+-static char resume_file[256]; /* For resume= kernel option */
++static int resume_status;
++static char resume_file[256] = ""; /* For resume= kernel option */
+ static dev_t resume_device;
+ /* Local variables that should not be affected by save */
+ unsigned int nr_copy_pages __nosavedata = 0;
+@@ -347,10 +356,15 @@
+ int pfn;
+ struct page *page;
+
++#ifdef CONFIG_DISCONTIGMEM
++ panic("Discontingmem not supported");
++#else
+ BUG_ON (max_pfn != num_physpages);
+-
++#endif
+ for (pfn = 0; pfn < max_pfn; pfn++) {
+ page = pfn_to_page(pfn);
++ if (PageHighMem(page))
++ panic("Swsusp not supported on highmem boxes. Send 1GB of RAM to <pavel@ucw.cz> and try again ;-).");
+
+ if (!PageReserved(page)) {
+ if (PageNosave(page))
+@@ -435,6 +449,56 @@
+ return pagedir;
+ }
+
++static int prepare_suspend_processes(void)
++{
++ sys_sync(); /* Syncing needs pdflushd, so do it before stopping processes */
++ if (freeze_processes()) {
++ printk( KERN_ERR "Suspend failed: Not all processes stopped!\n" );
++ thaw_processes();
++ return 1;
++ }
++ return 0;
++}
++
++/*
++ * Try to free as much memory as possible, but do not OOM-kill anyone
++ *
++ * Notice: all userland should be stopped at this point, or livelock is possible.
++ */
++static void free_some_memory(void)
++{
++ printk("Freeing memory: ");
++ while (shrink_all_memory(10000))
++ printk(".");
++ printk("|\n");
++}
++
++/* Make disk drivers accept operations, again */
++static void drivers_unsuspend(void)
++{
++ device_resume();
++}
++
++/* Called from process context */
++static int drivers_suspend(void)
++{
++ return device_suspend(4);
++}
++
++#define RESUME_PHASE1 1 /* Called from interrupts disabled */
++#define RESUME_PHASE2 2 /* Called with interrupts enabled */
++#define RESUME_ALL_PHASES (RESUME_PHASE1 | RESUME_PHASE2)
++static void drivers_resume(int flags)
++{
++ if (flags & RESUME_PHASE1) {
++ device_resume();
++ }
++ if (flags & RESUME_PHASE2) {
++#ifdef SUSPEND_CONSOLE
++ update_screen(fg_console); /* Hmm, is this the problem? */
++#endif
++ }
++}
+
+ static int suspend_prepare_image(void)
+ {
+@@ -488,14 +552,12 @@
+ return 0;
+ }
+
+-static int suspend_save_image(void)
++static void suspend_save_image(void)
+ {
+- int error;
+-
+- device_resume();
++ drivers_unsuspend();
+
+ lock_swapdevices();
+- error = write_suspend_image();
++ write_suspend_image();
+ lock_swapdevices(); /* This will unlock ignored swap devices since writing is finished */
+
+ /* It is important _NOT_ to umount filesystems at this point. We want
+@@ -503,7 +565,29 @@
+ * filesystem clean: it is not. (And it does not matter, if we resume
+ * correctly, we'll mark system clean, anyway.)
+ */
+- return error;
++}
++
++static void suspend_power_down(void)
++{
++ extern int C_A_D;
++ C_A_D = 0;
++ printk(KERN_EMERG "%s%s Trying to power down.\n", name_suspend, TEST_SWSUSP ? "Disable TEST_SWSUSP. NOT ": "");
++#ifdef CONFIG_VT
++ PRINTK(KERN_EMERG "shift_state: %04x\n", shift_state);
++ mdelay(1000);
++ if (TEST_SWSUSP ^ (!!(shift_state & (1 << KG_CTRL))))
++ machine_restart(NULL);
++ else
++#endif
++ {
++ device_shutdown();
++ machine_power_off();
++ }
++
++ printk(KERN_EMERG "%sProbably not capable for powerdown. System halted.\n", name_suspend);
++ machine_halt();
++ while (1);
++ /* NOTREACHED */
+ }
+
+ /*
+@@ -515,21 +599,32 @@
+ barrier();
+ mb();
+ spin_lock_irq(&suspend_pagedir_lock); /* Done to disable interrupts */
++
+ PRINTK( "Waiting for DMAs to settle down...\n");
+- /* We do not want some readahead with DMA to corrupt our memory, right?
+- Do it with disabled interrupts for best effect. That way, if some
+- driver scheduled DMA, we have good chance for DMA to finish ;-). */
+- mdelay(1000);
++ mdelay(1000); /* We do not want some readahead with DMA to corrupt our memory, right?
++ Do it with disabled interrupts for best effect. That way, if some
++ driver scheduled DMA, we have good chance for DMA to finish ;-). */
+ }
+
+ void do_magic_resume_2(void)
+ {
+ BUG_ON (nr_copy_pages_check != nr_copy_pages);
+ BUG_ON (pagedir_order_check != pagedir_order);
+-
+- /* Even mappings of "global" things (vmalloc) need to be fixed */
+- __flush_tlb_global();
++
++ __flush_tlb_global(); /* Even mappings of "global" things (vmalloc) need to be fixed */
++
++ PRINTK( "Freeing prev allocated pagedir\n" );
++ free_suspend_pagedir((unsigned long) pagedir_save);
+ spin_unlock_irq(&suspend_pagedir_lock);
++ drivers_resume(RESUME_ALL_PHASES);
++
++ PRINTK( "Fixing swap signatures... " );
++ mark_swapfiles(((swp_entry_t) {0}), MARK_SWAP_RESUME);
++ PRINTK( "ok\n" );
++
++#ifdef SUSPEND_CONSOLE
++ update_screen(fg_console); /* Hmm, is this the problem? */
++#endif
+ }
+
+ /* do_magic() is implemented in arch/?/kernel/suspend_asm.S, and basically does:
+@@ -554,28 +649,91 @@
+ {
+ mb();
+ barrier();
++ BUG_ON(in_atomic());
+ spin_lock_irq(&suspend_pagedir_lock);
+ }
+
+-int do_magic_suspend_2(void)
++void do_magic_suspend_2(void)
+ {
+ int is_problem;
+ read_swapfiles();
+ is_problem = suspend_prepare_image();
+ spin_unlock_irq(&suspend_pagedir_lock);
+- if (!is_problem)
+- return suspend_save_image();
++ if (!is_problem) {
++ kernel_fpu_end(); /* save_processor_state() does kernel_fpu_begin, and we need to revert it in order to pass in_atomic() checks */
++ BUG_ON(in_atomic());
++ suspend_save_image();
++ suspend_power_down(); /* FIXME: if suspend_power_down is commented out, console is lost after few suspends ?! */
++ }
++
+ printk(KERN_EMERG "%sSuspend failed, trying to recover...\n", name_suspend);
++ MDELAY(1000); /* So user can wait and report us messages if armageddon comes :-) */
++
+ barrier();
+ mb();
++ spin_lock_irq(&suspend_pagedir_lock); /* Done to disable interrupts */
+ mdelay(1000);
+- return -EFAULT;
++
++ free_pages((unsigned long) pagedir_nosave, pagedir_order);
++ spin_unlock_irq(&suspend_pagedir_lock);
++ mark_swapfiles(((swp_entry_t) {0}), MARK_SWAP_RESUME);
++}
++
++static void do_software_suspend(void)
++{
++ arch_prepare_suspend();
++ if (pm_prepare_console())
++ printk( "%sCan't allocate a console... proceeding\n", name_suspend);
++ if (!prepare_suspend_processes()) {
++
++ /* At this point, all user processes and "dangerous"
++ kernel threads are stopped. Free some memory, as we
++ need half of memory free. */
++
++ free_some_memory();
++
++ /* No need to invalidate any vfsmnt list --
++ * they will be valid after resume, anyway.
++ */
++ blk_run_queues();
++
++ /* Save state of all device drivers, and stop them. */
++ if(drivers_suspend()==0)
++ /* If stopping device drivers worked, we proceed basically into
++ * suspend_save_image.
++ *
++ * do_magic(0) returns after system is resumed.
++ *
++ * do_magic() copies all "used" memory to "free" memory, then
++ * unsuspends all device drivers, and writes memory to disk
++ * using normal kernel mechanism.
++ */
++ do_magic(0);
++ thaw_processes();
++ }
++ software_suspend_enabled = 1;
++ MDELAY(1000);
++ pm_restore_console();
++}
++
++/*
++ * This is main interface to the outside world. It needs to be
++ * called from process context.
++ */
++void software_suspend(void)
++{
++ if(!software_suspend_enabled)
++ return;
++
++ software_suspend_enabled = 0;
++ might_sleep();
++ do_software_suspend();
+ }
+
+ /* More restore stuff */
+
+ /* FIXME: Why not memcpy(to, from, 1<<pagedir_order*PAGE_SIZE)? */
+-static void __init copy_pagedir(suspend_pagedir_t *to, suspend_pagedir_t *from)
++static void copy_pagedir(suspend_pagedir_t *to, suspend_pagedir_t *from)
+ {
+ int i;
+ char *topointer=(char *)to, *frompointer=(char *)from;
+@@ -592,8 +750,8 @@
+ /*
+ * Returns true if given address/order collides with any orig_address
+ */
+-static int __init does_collide_order(suspend_pagedir_t *pagedir,
+- unsigned long addr, int order)
++static int does_collide_order(suspend_pagedir_t *pagedir, unsigned long addr,
++ int order)
+ {
+ int i;
+ unsigned long addre = addr + (PAGE_SIZE<<order);
+@@ -610,7 +768,7 @@
+ * We check here that pagedir & pages it points to won't collide with pages
+ * where we're going to restore from the loaded pages later
+ */
+-static int __init check_pagedir(void)
++static int check_pagedir(void)
+ {
+ int i;
+
+@@ -628,7 +786,7 @@
+ return 0;
+ }
+
+-static int __init relocate_pagedir(void)
++static int relocate_pagedir(void)
+ {
+ /*
+ * We have to avoid recursion (not to overflow kernel stack),
+@@ -678,13 +836,13 @@
+ * I really don't think that it's foolproof but more than nothing..
+ */
+
+-static int __init sanity_check_failed(char *reason)
++static int sanity_check_failed(char *reason)
+ {
+ printk(KERN_ERR "%s%s\n",name_resume,reason);
+ return -EPERM;
+ }
+
+-static int __init sanity_check(struct suspend_header *sh)
++static int sanity_check(struct suspend_header *sh)
+ {
+ if(sh->version_code != LINUX_VERSION_CODE)
+ return sanity_check_failed("Incorrect kernel version");
+@@ -701,8 +859,7 @@
+ return 0;
+ }
+
+-static int __init bdev_read_page(struct block_device *bdev,
+- long pos, void *buf)
++static int bdev_read_page(struct block_device *bdev, long pos, void *buf)
+ {
+ struct buffer_head *bh;
+ BUG_ON (pos%PAGE_SIZE);
+@@ -716,10 +873,31 @@
+ return 0;
+ }
+
++static int bdev_write_page(struct block_device *bdev, long pos, void *buf)
++{
++#if 0
++ struct buffer_head *bh;
++ BUG_ON (pos%PAGE_SIZE);
++ bh = __bread(bdev, pos/PAGE_SIZE, PAGE_SIZE);
++ if (!bh || (!bh->b_data)) {
++ return -1;
++ }
++ memcpy(bh->b_data, buf, PAGE_SIZE); /* FIXME: may need kmap() */
++ BUG_ON(!buffer_uptodate(bh));
++ generic_make_request(WRITE, bh);
++ if (!buffer_uptodate(bh))
++ printk(KERN_CRIT "%sWarning %s: Fixing swap signatures unsuccessful...\n", name_resume, resume_file);
++ wait_on_buffer(bh);
++ brelse(bh);
++ return 0;
++#endif
++ printk(KERN_CRIT "%sWarning %s: Fixing swap signatures unimplemented...\n", name_resume, resume_file);
++ return 0;
++}
++
+ extern dev_t __init name_to_dev_t(const char *line);
+
+-static int __init read_suspend_image(struct block_device *bdev,
+- union diskpage *cur)
++static int __read_suspend_image(struct block_device *bdev, union diskpage *cur, int noresume)
+ {
+ swp_entry_t next;
+ int i, nr_pgdir_pages;
+@@ -744,9 +922,18 @@
+ else if (!memcmp("S2",cur->swh.magic.magic,2))
+ memcpy(cur->swh.magic.magic,"SWAPSPACE2",10);
+ else {
+- printk("swsusp: %s: Unable to find suspended-data signature (%.10s - misspelled?\n",
++ if (noresume)
++ return -EINVAL;
++ panic("%sUnable to find suspended-data signature (%.10s - misspelled?\n",
+ name_resume, cur->swh.magic.magic);
+- return -EFAULT;
++ }
++ if (noresume) {
++ /* We don't do a sanity check here: we want to restore the swap
++ whatever version of kernel made the suspend image;
++ We need to write swap, but swap is *not* enabled so
++ we must write the device directly */
++ printk("%s: Fixing swap signatures %s...\n", name_resume, resume_file);
++ bdev_write_page(bdev, 0, cur);
+ }
+
+ printk( "%sSignature found, resuming\n", name_resume );
+@@ -796,115 +983,117 @@
+ return 0;
+ }
+
+-/**
+- * swsusp_save - Snapshot memory
+- */
+-
+-int swsusp_save(void)
+-{
+-#if defined (CONFIG_HIGHMEM) || defined (COFNIG_DISCONTIGMEM)
+- printk("swsusp is not supported with high- or discontig-mem.\n");
+- return -EPERM;
+-#endif
+- return 0;
+-}
+-
+-
+-/**
+- * swsusp_write - Write saved memory image to swap.
+- *
+- * do_magic(0) returns after system is resumed.
+- *
+- * do_magic() copies all "used" memory to "free" memory, then
+- * unsuspends all device drivers, and writes memory to disk
+- * using normal kernel mechanism.
+- */
+-
+-int swsusp_write(void)
+-{
+- arch_prepare_suspend();
+- return do_magic(0);
+-}
+-
+-
+-/**
+- * swsusp_read - Read saved image from swap.
+- */
+-
+-int __init swsusp_read(void)
++static int read_suspend_image(const char * specialfile, int noresume)
+ {
+ union diskpage *cur;
++ unsigned long scratch_page = 0;
+ int error;
+ char b[BDEVNAME_SIZE];
+
+- if (!strlen(resume_file))
+- return -ENOENT;
+-
+- resume_device = name_to_dev_t(resume_file);
+- printk("swsusp: Resume From Partition: %s, Device: %s\n",
+- resume_file, __bdevname(resume_device, b));
+-
+- cur = (union diskpage *)get_zeroed_page(GFP_ATOMIC);
++ resume_device = name_to_dev_t(specialfile);
++ scratch_page = get_zeroed_page(GFP_ATOMIC);
++ cur = (void *) scratch_page;
+ if (cur) {
+ struct block_device *bdev;
++ printk("Resuming from device %s\n",
++ __bdevname(resume_device, b));
+ bdev = open_by_devnum(resume_device, FMODE_READ, BDEV_RAW);
+- if (!IS_ERR(bdev)) {
++ if (IS_ERR(bdev)) {
++ error = PTR_ERR(bdev);
++ } else {
+ set_blocksize(bdev, PAGE_SIZE);
+- error = read_suspend_image(bdev, cur);
++ error = __read_suspend_image(bdev, cur, noresume);
+ blkdev_put(bdev, BDEV_RAW);
+- } else
+- error = PTR_ERR(bdev);
+- free_page((unsigned long)cur);
+- } else
+- error = -ENOMEM;
++ }
++ } else error = -ENOMEM;
+
+- if (!error)
+- PRINTK("Reading resume file was successful\n");
+- else
+- printk( "%sError %d resuming\n", name_resume, error );
++ if (scratch_page)
++ free_page(scratch_page);
++ switch (error) {
++ case 0:
++ PRINTK("Reading resume file was successful\n");
++ break;
++ case -EINVAL:
++ break;
++ case -EIO:
++ printk( "%sI/O error\n", name_resume);
++ break;
++ case -ENOENT:
++ printk( "%s%s: No such file or directory\n", name_resume, specialfile);
++ break;
++ case -ENOMEM:
++ printk( "%sNot enough memory\n", name_resume);
++ break;
++ default:
++ printk( "%sError %d resuming\n", name_resume, error );
++ }
+ MDELAY(1000);
+ return error;
+ }
+
+-
+-/**
+- * swsusp_restore - Replace running kernel with saved image.
++/*
++ * Called from init kernel_thread.
++ * We check if we have an image and if so we try to resume
+ */
+
+-int __init swsusp_restore(void)
++void software_resume(void)
+ {
+- return do_magic(1);
+-}
++ if (num_online_cpus() > 1) {
++ printk(KERN_WARNING "Software Suspend has malfunctioning SMP support. Disabled :(\n");
++ return;
++ }
++ /* We enable the possibility of machine suspend */
++ software_suspend_enabled = 1;
++ if (!resume_status)
++ return;
+
++ printk( "%s", name_resume );
++ if (resume_status == NORESUME) {
++ if(resume_file[0])
++ read_suspend_image(resume_file, 1);
++ printk( "disabled\n" );
++ return;
++ }
++ MDELAY(1000);
+
+-/**
+- * swsusp_free - Free memory allocated to hold snapshot.
+- */
++ if (pm_prepare_console())
++ printk("swsusp: Can't allocate a console... proceeding\n");
+
+-int swsusp_free(void)
+-{
+- PRINTK( "Freeing prev allocated pagedir\n" );
+- free_suspend_pagedir((unsigned long) pagedir_save);
++ if (!resume_file[0] && resume_status == RESUME_SPECIFIED) {
++ printk( "suspension device unspecified\n" );
++ return;
++ }
+
+- PRINTK( "Fixing swap signatures... " );
+- mark_swapfiles(((swp_entry_t) {0}), MARK_SWAP_RESUME);
+- PRINTK( "ok\n" );
+- return 0;
++ printk( "resuming from %s\n", resume_file);
++ if (read_suspend_image(resume_file, 0))
++ goto read_failure;
++ do_magic(1);
++ panic("This never returns");
++
++read_failure:
++ pm_restore_console();
++ return;
+ }
+
+ static int __init resume_setup(char *str)
+ {
+- if (strlen(str))
+- strncpy(resume_file, str, 255);
++ if (resume_status == NORESUME)
++ return 1;
++
++ strncpy( resume_file, str, 255 );
++ resume_status = RESUME_SPECIFIED;
++
+ return 1;
+ }
+
+ static int __init noresume_setup(char *str)
+ {
+- resume_file[0] = '\0';
++ resume_status = NORESUME;
+ return 1;
+ }
+
+ __setup("noresume", noresume_setup);
+ __setup("resume=", resume_setup);
+
++EXPORT_SYMBOL(software_suspend);
++EXPORT_SYMBOL(software_suspend_enabled);
+Index: linux-2.6.0-test5/kernel/printk.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/printk.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/printk.c 2003-09-27 11:38:41.308248576 +0800
+@@ -399,9 +399,13 @@
+ char *p;
+ static char printk_buf[1024];
+ static int log_level_unknown = 1;
++ static int printk_cpu = -1;
+
+- if (oops_in_progress) {
+- /* If a crash is occurring, make sure we can't deadlock */
++ if (oops_in_progress && printk_cpu == smp_processor_id()) {
++ /*
++ * If a crash is occurring during printk() on this CPU, make
++ * sure we can't deadlock
++ */
+ spin_lock_init(&logbuf_lock);
+ /* And make sure that we print immediately */
+ init_MUTEX(&console_sem);
+@@ -409,6 +413,7 @@
+
+ /* This stops the holder of console_sem just where we want him */
+ spin_lock_irqsave(&logbuf_lock, flags);
++ printk_cpu = smp_processor_id();
+
+ /* Emit the output into the temporary buffer */
+ va_start(args, fmt);
+Index: linux-2.6.0-test5/kernel/ptrace.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/ptrace.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/ptrace.c 2003-09-27 11:38:41.310248272 +0800
+@@ -179,19 +179,14 @@
+
+ flush_cache_page(vma, addr);
+
+- /*
+- * FIXME! We used to have flush_page_to_ram() in here, but
+- * that was wrong. davem says we need a new per-arch primitive
+- * to handle this correctly.
+- */
+-
+ maddr = kmap(page);
+ if (write) {
+- memcpy(maddr + offset, buf, bytes);
+- flush_icache_user_range(vma, page, addr, bytes);
++ copy_to_user_page(vma, page, addr,
++ maddr + offset, buf, bytes);
+ set_page_dirty_lock(page);
+ } else {
+- memcpy(buf, maddr + offset, bytes);
++ copy_from_user_page(vma, page, addr,
++ buf, maddr + offset, bytes);
+ }
+ kunmap(page);
+ page_cache_release(page);
+Index: linux-2.6.0-test5/kernel/sched.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/sched.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/sched.c 2003-09-27 11:38:41.329245384 +0800
+@@ -14,6 +14,7 @@
+ * an array-switch method of distributing timeslices
+ * and per-CPU runqueues. Cleanups and useful suggestions
+ * by Davide Libenzi, preemptible kernel bits by Robert Love.
++ * 2003-09-03 Interactivity tuning by Con Kolivas.
+ */
+
+ #include <linux/mm.h>
+@@ -28,6 +29,7 @@
+ #include <linux/kernel_stat.h>
+ #include <linux/security.h>
+ #include <linux/notifier.h>
++#include <linux/suspend.h>
+ #include <linux/blkdev.h>
+ #include <linux/delay.h>
+ #include <linux/timer.h>
+@@ -58,6 +60,14 @@
+ #define USER_PRIO(p) ((p)-MAX_RT_PRIO)
+ #define TASK_USER_PRIO(p) USER_PRIO((p)->static_prio)
+ #define MAX_USER_PRIO (USER_PRIO(MAX_PRIO))
++#define AVG_TIMESLICE (MIN_TIMESLICE + ((MAX_TIMESLICE - MIN_TIMESLICE) *\
++ (MAX_PRIO-1-NICE_TO_PRIO(0))/(MAX_USER_PRIO - 1)))
++
++/*
++ * Some helpers for converting nanosecond timing to jiffy resolution
++ */
++#define NS_TO_JIFFIES(TIME) ((TIME) / (1000000000 / HZ))
++#define JIFFIES_TO_NS(TIME) ((TIME) * (1000000000 / HZ))
+
+ /*
+ * These are the 'tuning knobs' of the scheduler:
+@@ -68,14 +78,18 @@
+ */
+ #define MIN_TIMESLICE ( 10 * HZ / 1000)
+ #define MAX_TIMESLICE (200 * HZ / 1000)
+-#define CHILD_PENALTY 50
++#define ON_RUNQUEUE_WEIGHT 30
++#define CHILD_PENALTY 95
+ #define PARENT_PENALTY 100
+ #define EXIT_WEIGHT 3
+ #define PRIO_BONUS_RATIO 25
++#define MAX_BONUS (MAX_USER_PRIO * PRIO_BONUS_RATIO / 100)
+ #define INTERACTIVE_DELTA 2
+-#define MAX_SLEEP_AVG (10*HZ)
+-#define STARVATION_LIMIT (10*HZ)
++#define MAX_SLEEP_AVG (AVG_TIMESLICE * MAX_BONUS)
++#define STARVATION_LIMIT (MAX_SLEEP_AVG)
++#define NS_MAX_SLEEP_AVG (JIFFIES_TO_NS(MAX_SLEEP_AVG))
+ #define NODE_THRESHOLD 125
++#define CREDIT_LIMIT 100
+
+ /*
+ * If a task is 'interactive' then we reinsert it in the active
+@@ -105,6 +119,19 @@
+ * too hard.
+ */
+
++#define CURRENT_BONUS(p) \
++ (NS_TO_JIFFIES((p)->sleep_avg) * MAX_BONUS / \
++ MAX_SLEEP_AVG)
++
++#ifdef CONFIG_SMP
++#define TIMESLICE_GRANULARITY(p) (MIN_TIMESLICE * \
++ (1 << (((MAX_BONUS - CURRENT_BONUS(p)) ? : 1) - 1)) * \
++ num_online_cpus())
++#else
++#define TIMESLICE_GRANULARITY(p) (MIN_TIMESLICE * \
++ (1 << (((MAX_BONUS - CURRENT_BONUS(p)) ? : 1) - 1)))
++#endif
++
+ #define SCALE(v1,v1_max,v2_max) \
+ (v1) * (v2_max) / (v1_max)
+
+@@ -115,6 +142,19 @@
+ #define TASK_INTERACTIVE(p) \
+ ((p)->prio <= (p)->static_prio - DELTA(p))
+
++#define JUST_INTERACTIVE_SLEEP(p) \
++ (JIFFIES_TO_NS(MAX_SLEEP_AVG * \
++ (MAX_BONUS / 2 + DELTA((p)) + 1) / MAX_BONUS - 1))
++
++#define HIGH_CREDIT(p) \
++ ((p)->interactive_credit > CREDIT_LIMIT)
++
++#define LOW_CREDIT(p) \
++ ((p)->interactive_credit < -CREDIT_LIMIT)
++
++#define TASK_PREEMPTS_CURR(p, rq) \
++ ((p)->prio < (rq)->curr->prio)
++
+ /*
+ * BASE_TIMESLICE scales user-nice values [ -20 ... 19 ]
+ * to time slice values.
+@@ -179,7 +219,6 @@
+ #define this_rq() (&__get_cpu_var(runqueues))
+ #define task_rq(p) cpu_rq(task_cpu(p))
+ #define cpu_curr(cpu) (cpu_rq(cpu)->curr)
+-#define rt_task(p) ((p)->prio < MAX_RT_PRIO)
+
+ /*
+ * Default context-switch locking:
+@@ -319,8 +358,7 @@
+ if (rt_task(p))
+ return p->prio;
+
+- bonus = MAX_USER_PRIO*PRIO_BONUS_RATIO*p->sleep_avg/MAX_SLEEP_AVG/100 -
+- MAX_USER_PRIO*PRIO_BONUS_RATIO/100/2;
++ bonus = CURRENT_BONUS(p) - MAX_BONUS / 2;
+
+ prio = p->static_prio - bonus;
+ if (prio < MAX_RT_PRIO)
+@@ -339,6 +377,82 @@
+ nr_running_inc(rq);
+ }
+
++static void recalc_task_prio(task_t *p, unsigned long long now)
++{
++ unsigned long long __sleep_time = now - p->timestamp;
++ unsigned long sleep_time;
++
++ if (__sleep_time > NS_MAX_SLEEP_AVG)
++ sleep_time = NS_MAX_SLEEP_AVG;
++ else
++ sleep_time = (unsigned long)__sleep_time;
++
++ if (likely(sleep_time > 0)) {
++ /*
++ * User tasks that sleep a long time are categorised as
++ * idle and will get just interactive status to stay active &
++ * prevent them suddenly becoming cpu hogs and starving
++ * other processes.
++ */
++ if (p->mm && p->activated != -1 &&
++ sleep_time > JUST_INTERACTIVE_SLEEP(p)){
++ p->sleep_avg = JIFFIES_TO_NS(MAX_SLEEP_AVG -
++ AVG_TIMESLICE);
++ if (!HIGH_CREDIT(p))
++ p->interactive_credit++;
++ } else {
++ /*
++ * The lower the sleep avg a task has the more
++ * rapidly it will rise with sleep time.
++ */
++ sleep_time *= (MAX_BONUS - CURRENT_BONUS(p)) ? : 1;
++
++ /*
++ * Tasks with low interactive_credit are limited to
++ * one timeslice worth of sleep avg bonus.
++ */
++ if (LOW_CREDIT(p) &&
++ sleep_time > JIFFIES_TO_NS(task_timeslice(p)))
++ sleep_time =
++ JIFFIES_TO_NS(task_timeslice(p));
++
++ /*
++ * Non high_credit tasks waking from uninterruptible
++ * sleep are limited in their sleep_avg rise as they
++ * are likely to be cpu hogs waiting on I/O
++ */
++ if (p->activated == -1 && !HIGH_CREDIT(p) && p->mm){
++ if (p->sleep_avg >= JUST_INTERACTIVE_SLEEP(p))
++ sleep_time = 0;
++ else if (p->sleep_avg + sleep_time >=
++ JUST_INTERACTIVE_SLEEP(p)){
++ p->sleep_avg =
++ JUST_INTERACTIVE_SLEEP(p);
++ sleep_time = 0;
++ }
++ }
++
++ /*
++ * This code gives a bonus to interactive tasks.
++ *
++ * The boost works by updating the 'average sleep time'
++ * value here, based on ->timestamp. The more time a task
++ * spends sleeping, the higher the average gets - and the
++ * higher the priority boost gets as well.
++ */
++ p->sleep_avg += sleep_time;
++
++ if (p->sleep_avg > NS_MAX_SLEEP_AVG){
++ p->sleep_avg = NS_MAX_SLEEP_AVG;
++ if (!HIGH_CREDIT(p))
++ p->interactive_credit++;
++ }
++ }
++ }
++
++ p->prio = effective_prio(p);
++}
++
+ /*
+ * activate_task - move a task to the runqueue and do priority recalculation
+ *
+@@ -347,34 +461,33 @@
+ */
+ static inline void activate_task(task_t *p, runqueue_t *rq)
+ {
+- long sleep_time = jiffies - p->last_run - 1;
++ unsigned long long now = sched_clock();
+
+- if (sleep_time > 0) {
+- int sleep_avg;
++ recalc_task_prio(p, now);
+
++ /*
++ * This checks to make sure it's not an uninterruptible task
++ * that is now waking up.
++ */
++ if (!p->activated){
+ /*
+- * This code gives a bonus to interactive tasks.
+- *
+- * The boost works by updating the 'average sleep time'
+- * value here, based on ->last_run. The more time a task
+- * spends sleeping, the higher the average gets - and the
+- * higher the priority boost gets as well.
++ * Tasks which were woken up by interrupts (ie. hw events)
++ * are most likely of interactive nature. So we give them
++ * the credit of extending their sleep time to the period
++ * of time they spend on the runqueue, waiting for execution
++ * on a CPU, first time around:
+ */
+- sleep_avg = p->sleep_avg + sleep_time;
+-
++ if (in_interrupt())
++ p->activated = 2;
++ else
+ /*
+- * 'Overflow' bonus ticks go to the waker as well, so the
+- * ticks are not lost. This has the effect of further
+- * boosting tasks that are related to maximum-interactive
+- * tasks.
++ * Normal first-time wakeups get a credit too for on-runqueue
++ * time, but it will be weighted down:
+ */
+- if (sleep_avg > MAX_SLEEP_AVG)
+- sleep_avg = MAX_SLEEP_AVG;
+- if (p->sleep_avg != sleep_avg) {
+- p->sleep_avg = sleep_avg;
+- p->prio = effective_prio(p);
++ p->activated = 1;
+ }
+- }
++ p->timestamp = now;
++
+ __activate_task(p, rq);
+ }
+
+@@ -495,13 +608,19 @@
+ task_rq_unlock(rq, &flags);
+ goto repeat_lock_task;
+ }
+- if (old_state == TASK_UNINTERRUPTIBLE)
++ if (old_state == TASK_UNINTERRUPTIBLE){
+ rq->nr_uninterruptible--;
++ /*
++ * Tasks on involuntary sleep don't earn
++ * sleep_avg beyond just interactive state.
++ */
++ p->activated = -1;
++ }
+ if (sync)
+ __activate_task(p, rq);
+ else {
+ activate_task(p, rq);
+- if (p->prio < rq->curr->prio)
++ if (TASK_PREEMPTS_CURR(p, rq))
+ resched_task(rq->curr);
+ }
+ success = 1;
+@@ -550,8 +669,14 @@
+ * and children as well, to keep max-interactive tasks
+ * from forking tasks that are max-interactive.
+ */
+- current->sleep_avg = current->sleep_avg * PARENT_PENALTY / 100;
+- p->sleep_avg = p->sleep_avg * CHILD_PENALTY / 100;
++ current->sleep_avg = JIFFIES_TO_NS(CURRENT_BONUS(current) *
++ PARENT_PENALTY / 100 * MAX_SLEEP_AVG / MAX_BONUS);
++
++ p->sleep_avg = JIFFIES_TO_NS(CURRENT_BONUS(p) *
++ CHILD_PENALTY / 100 * MAX_SLEEP_AVG / MAX_BONUS);
++
++ p->interactive_credit = 0;
++
+ p->prio = effective_prio(p);
+ set_task_cpu(p, smp_processor_id());
+
+@@ -592,8 +717,9 @@
+ * the sleep_avg of the parent as well.
+ */
+ if (p->sleep_avg < p->parent->sleep_avg)
+- p->parent->sleep_avg = (p->parent->sleep_avg * EXIT_WEIGHT +
+- p->sleep_avg) / (EXIT_WEIGHT + 1);
++ p->parent->sleep_avg = p->parent->sleep_avg /
++ (EXIT_WEIGHT + 1) * EXIT_WEIGHT + p->sleep_avg /
++ (EXIT_WEIGHT + 1);
+ }
+
+ /**
+@@ -959,10 +1085,10 @@
+ if (likely(!busiest))
+ goto out;
+
+- *imbalance = (max_load - nr_running) / 2;
++ *imbalance = max_load - nr_running;
+
+ /* It needs an at least ~25% imbalance to trigger balancing. */
+- if (!idle && (*imbalance < (max_load + 3)/4)) {
++ if (!idle && ((*imbalance)*4 < max_load)) {
+ busiest = NULL;
+ goto out;
+ }
+@@ -972,7 +1098,7 @@
+ * Make sure nothing changed since we checked the
+ * runqueue length.
+ */
+- if (busiest->nr_running <= nr_running + 1) {
++ if (busiest->nr_running <= nr_running) {
+ spin_unlock(&busiest->lock);
+ busiest = NULL;
+ }
+@@ -995,13 +1121,31 @@
+ * Note that idle threads have a prio of MAX_PRIO, for this test
+ * to be always true for them.
+ */
+- if (p->prio < this_rq->curr->prio)
++ if (TASK_PREEMPTS_CURR(p, this_rq))
+ set_need_resched();
+- else {
+- if (p->prio == this_rq->curr->prio &&
+- p->time_slice > this_rq->curr->time_slice)
+- set_need_resched();
+- }
++}
++
++/*
++ * Previously:
++ *
++ * #define CAN_MIGRATE_TASK(p,rq,this_cpu) \
++ * ((!idle || (NS_TO_JIFFIES(now - (p)->timestamp) > \
++ * cache_decay_ticks)) && !task_running(rq, p) && \
++ * cpu_isset(this_cpu, (p)->cpus_allowed))
++ */
++
++static inline int
++can_migrate_task(task_t *tsk, runqueue_t *rq, int this_cpu, int idle)
++{
++ unsigned long delta = sched_clock() - tsk->timestamp;
++
++ if (!idle && (delta <= JIFFIES_TO_NS(cache_decay_ticks)))
++ return 0;
++ if (task_running(rq, tsk))
++ return 0;
++ if (!cpu_isset(this_cpu, tsk->cpus_allowed))
++ return 0;
++ return 1;
+ }
+
+ /*
+@@ -1025,6 +1169,12 @@
+ goto out;
+
+ /*
++ * We only want to steal a number of tasks equal to 1/2 the imbalance,
++ * otherwise we'll just shift the imbalance to the new queue:
++ */
++ imbalance /= 2;
++
++ /*
+ * We first consider expired tasks. Those will likely not be
+ * executed in the near future, and they are most likely to
+ * be cache-cold, thus switching CPUs has the least effect
+@@ -1063,14 +1213,9 @@
+ * 3) are cache-hot on their current CPU.
+ */
+
+-#define CAN_MIGRATE_TASK(p,rq,this_cpu) \
+- ((!idle || (jiffies - (p)->last_run > cache_decay_ticks)) && \
+- !task_running(rq, p) && \
+- cpu_isset(this_cpu, (p)->cpus_allowed))
+-
+ curr = curr->prev;
+
+- if (!CAN_MIGRATE_TASK(tmp, busiest, this_cpu)) {
++ if (!can_migrate_task(tmp, busiest, this_cpu, idle)) {
+ if (curr != head)
+ goto skip_queue;
+ idx++;
+@@ -1232,14 +1377,11 @@
+ spin_lock(&rq->lock);
+ /*
+ * The task was running during this tick - update the
+- * time slice counter and the sleep average. Note: we
+- * do not update a thread's priority until it either
+- * goes to sleep or uses up its timeslice. This makes
+- * it possible for interactive tasks to use up their
+- * timeslices at their highest priority levels.
++ * time slice counter. Note: we do not update a thread's
++ * priority until it either goes to sleep or uses up its
++ * timeslice. This makes it possible for interactive tasks
++ * to use up their timeslices at their highest priority levels.
+ */
+- if (p->sleep_avg)
+- p->sleep_avg--;
+ if (unlikely(rt_task(p))) {
+ /*
+ * RR tasks need a special form of timeslice management.
+@@ -1263,12 +1405,39 @@
+ p->time_slice = task_timeslice(p);
+ p->first_time_slice = 0;
+
++ if (!rq->expired_timestamp)
++ rq->expired_timestamp = jiffies;
+ if (!TASK_INTERACTIVE(p) || EXPIRED_STARVING(rq)) {
+- if (!rq->expired_timestamp)
+- rq->expired_timestamp = jiffies;
+ enqueue_task(p, rq->expired);
+ } else
+ enqueue_task(p, rq->active);
++ } else {
++ /*
++ * Prevent a too long timeslice allowing a task to monopolize
++ * the CPU. We do this by splitting up the timeslice into
++ * smaller pieces.
++ *
++ * Note: this does not mean the task's timeslices expire or
++ * get lost in any way, they just might be preempted by
++ * another task of equal priority. (one with higher
++ * priority would have preempted this task already.) We
++ * requeue this task to the end of the list on this priority
++ * level, which is in essence a round-robin of tasks with
++ * equal priority.
++ *
++ * This only applies to tasks in the interactive
++ * delta range with at least TIMESLICE_GRANULARITY to requeue.
++ */
++ if (TASK_INTERACTIVE(p) && !((task_timeslice(p) -
++ p->time_slice) % TIMESLICE_GRANULARITY(p)) &&
++ (p->time_slice >= TIMESLICE_GRANULARITY(p)) &&
++ (p->array == rq->active)) {
++
++ dequeue_task(p, rq->active);
++ set_tsk_need_resched(p);
++ p->prio = effective_prio(p);
++ enqueue_task(p, rq->active);
++ }
+ }
+ out_unlock:
+ spin_unlock(&rq->lock);
+@@ -1287,6 +1456,8 @@
+ runqueue_t *rq;
+ prio_array_t *array;
+ struct list_head *queue;
++ unsigned long long now;
++ unsigned long run_time;
+ int idx;
+
+ /*
+@@ -1307,7 +1478,20 @@
+ rq = this_rq();
+
+ release_kernel_lock(prev);
+- prev->last_run = jiffies;
++ now = sched_clock();
++ if (likely(now - prev->timestamp < NS_MAX_SLEEP_AVG))
++ run_time = now - prev->timestamp;
++ else
++ run_time = NS_MAX_SLEEP_AVG;
++
++ /*
++ * Tasks with interactive credits get charged less run_time
++ * at high sleep_avg to delay them losing their interactive
++ * status
++ */
++ if (HIGH_CREDIT(prev))
++ run_time /= (CURRENT_BONUS(prev) ? : 1);
++
+ spin_lock_irq(&rq->lock);
+
+ /*
+@@ -1357,12 +1541,33 @@
+ queue = array->queue + idx;
+ next = list_entry(queue->next, task_t, run_list);
+
++ if (next->activated > 0) {
++ unsigned long long delta = now - next->timestamp;
++
++ if (next->activated == 1)
++ delta = delta * (ON_RUNQUEUE_WEIGHT * 128 / 100) / 128;
++
++ array = next->array;
++ dequeue_task(next, array);
++ recalc_task_prio(next, next->timestamp + delta);
++ enqueue_task(next, array);
++ }
++ next->activated = 0;
+ switch_tasks:
+ prefetch(next);
+ clear_tsk_need_resched(prev);
+ RCU_qsctr(task_cpu(prev))++;
+
++ prev->sleep_avg -= run_time;
++ if ((long)prev->sleep_avg <= 0){
++ prev->sleep_avg = 0;
++ if (!(HIGH_CREDIT(prev) || LOW_CREDIT(prev)))
++ prev->interactive_credit--;
++ }
++ prev->timestamp = now;
++
+ if (likely(prev != next)) {
++ next->timestamp = now;
+ rq->nr_switches++;
+ rq->curr = next;
+
+@@ -1602,6 +1807,7 @@
+ unsigned long flags;
+ prio_array_t *array;
+ runqueue_t *rq;
++ int old_prio, new_prio, delta;
+
+ if (TASK_NICE(p) == nice || nice < -20 || nice > 19)
+ return;
+@@ -1610,6 +1816,12 @@
+ * the task might be in the middle of scheduling on another CPU.
+ */
+ rq = task_rq_lock(p, &flags);
++ /*
++ * The RT priorities are set via setscheduler(), but we still
++ * allow the 'normal' nice value to be set - but as expected
++ * it wont have any effect on scheduling until the task is
++ * not SCHED_NORMAL:
++ */
+ if (rt_task(p)) {
+ p->static_prio = NICE_TO_PRIO(nice);
+ goto out_unlock;
+@@ -1617,22 +1829,33 @@
+ array = p->array;
+ if (array)
+ dequeue_task(p, array);
++
++ old_prio = p->prio;
++ new_prio = NICE_TO_PRIO(nice);
++ delta = new_prio - old_prio;
+ p->static_prio = NICE_TO_PRIO(nice);
+- p->prio = NICE_TO_PRIO(nice);
++ p->prio += delta;
++
+ if (array) {
+ enqueue_task(p, array);
+ /*
+- * If the task is running and lowered its priority,
+- * or increased its priority then reschedule its CPU:
++ * If the task increased its priority or is running and
++ * lowered its priority, then reschedule its CPU:
+ */
+- if ((NICE_TO_PRIO(nice) < p->static_prio) ||
+- task_running(rq, p))
++ if (delta < 0 || (delta > 0 && task_running(rq, p)))
+ resched_task(rq->curr);
+ }
+ out_unlock:
+ task_rq_unlock(rq, &flags);
+ }
+
++#if defined( CONFIG_KGDB)
++struct task_struct * kgdb_get_idle(int this_cpu)
++{
++ return cpu_rq(this_cpu)->idle;
++}
++#endif
++
+ #ifndef __alpha__
+
+ /*
+@@ -2186,17 +2409,16 @@
+
+ static void show_task(task_t * p)
+ {
+- unsigned long free = 0;
+ task_t *relative;
+- int state;
+- static const char * stat_nam[] = { "R", "S", "D", "T", "Z", "W" };
++ unsigned state;
++ static const char *stat_nam[] = { "R", "S", "D", "T", "Z", "W" };
+
+ printk("%-13.13s ", p->comm);
+ state = p->state ? __ffs(p->state) + 1 : 0;
+- if (((unsigned) state) < sizeof(stat_nam)/sizeof(char *))
++ if (state < ARRAY_SIZE(stat_nam))
+ printk(stat_nam[state]);
+ else
+- printk(" ");
++ printk("?");
+ #if (BITS_PER_LONG == 32)
+ if (p == current)
+ printk(" current ");
+@@ -2208,13 +2430,7 @@
+ else
+ printk(" %016lx ", thread_saved_pc(p));
+ #endif
+- {
+- unsigned long * n = (unsigned long *) (p->thread_info+1);
+- while (!*n)
+- n++;
+- free = (unsigned long) n - (unsigned long)(p+1);
+- }
+- printk("%5lu %5d %6d ", free, p->pid, p->parent->pid);
++ printk("%5d %6d ", p->pid, p->parent->pid);
+ if ((relative = eldest_child(p)))
+ printk("%5d ", relative->pid);
+ else
+@@ -2241,12 +2457,12 @@
+
+ #if (BITS_PER_LONG == 32)
+ printk("\n"
+- " free sibling\n");
+- printk(" task PC stack pid father child younger older\n");
++ " sibling\n");
++ printk(" task PC pid father child younger older\n");
+ #else
+ printk("\n"
+- " free sibling\n");
+- printk(" task PC stack pid father child younger older\n");
++ " sibling\n");
++ printk(" task PC pid father child younger older\n");
+ #endif
+ read_lock(&tasklist_lock);
+ do_each_thread(g, p) {
+@@ -2383,6 +2599,12 @@
+ local_irq_restore(flags);
+ }
+
++typedef struct {
++ int cpu;
++ struct completion startup_done;
++ task_t *task;
++} migration_startup_t;
++
+ /*
+ * migration_thread - this is a highprio system thread that performs
+ * thread migration by bumping thread off CPU then 'pushing' onto
+@@ -2392,20 +2614,21 @@
+ {
+ /* Marking "param" __user is ok, since we do a set_fs(KERNEL_DS); */
+ struct sched_param __user param = { .sched_priority = MAX_RT_PRIO-1 };
+- int cpu = (long) data;
++ migration_startup_t *startup = data;
++ int cpu = startup->cpu;
+ runqueue_t *rq;
+ int ret;
+
++ startup->task = current;
++ complete(&startup->startup_done);
++ set_current_state(TASK_UNINTERRUPTIBLE);
++ schedule();
++
++ BUG_ON(smp_processor_id() != cpu);
++
+ daemonize("migration/%d", cpu);
+ set_fs(KERNEL_DS);
+
+- /*
+- * Either we are running on the right CPU, or there's a a
+- * migration thread on this CPU, guaranteed (we're started
+- * serially).
+- */
+- set_cpus_allowed(current, cpumask_of_cpu(cpu));
+-
+ ret = setscheduler(0, SCHED_FIFO, ¶m);
+
+ rq = this_rq();
+@@ -2415,6 +2638,9 @@
+ struct list_head *head;
+ migration_req_t *req;
+
++ if (current->flags & PF_FREEZE)
++ refrigerator(PF_IOTHREAD);
++
+ spin_lock_irq(&rq->lock);
+ head = &rq->migration_queue;
+ current->state = TASK_INTERRUPTIBLE;
+@@ -2441,13 +2667,30 @@
+ unsigned long action,
+ void *hcpu)
+ {
++ long cpu = (long) hcpu;
++ migration_startup_t startup;
++
+ switch (action) {
+ case CPU_ONLINE:
+- printk("Starting migration thread for cpu %li\n",
+- (long)hcpu);
+- kernel_thread(migration_thread, hcpu, CLONE_KERNEL);
+- while (!cpu_rq((long)hcpu)->migration_thread)
++
++ printk("Starting migration thread for cpu %li\n", cpu);
++
++ startup.cpu = cpu;
++ startup.task = NULL;
++ init_completion(&startup.startup_done);
++
++ kernel_thread(migration_thread, &startup, CLONE_KERNEL);
++ wait_for_completion(&startup.startup_done);
++ wait_task_inactive(startup.task);
++
++ startup.task->thread_info->cpu = cpu;
++ startup.task->cpus_allowed = cpumask_of_cpu(cpu);
++
++ wake_up_process(startup.task);
++
++ while (!cpu_rq(cpu)->migration_thread)
+ yield();
++
+ break;
+ }
+ return NOTIFY_OK;
+@@ -2570,6 +2813,8 @@
+ prev_jiffy = jiffies;
+ printk(KERN_ERR "Debug: sleeping function called from invalid"
+ " context at %s:%d\n", file, line);
++ printk("in_atomic():%d, irqs_disabled():%d\n",
++ in_atomic(), irqs_disabled());
+ dump_stack();
+ }
+ #endif
+Index: linux-2.6.0-test5/kernel/signal.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/signal.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/signal.c 2003-09-27 11:38:41.346242800 +0800
+@@ -1139,7 +1139,7 @@
+ static int kill_something_info(int sig, struct siginfo *info, int pid)
+ {
+ if (!pid) {
+- return kill_pg_info(sig, info, current->pgrp);
++ return kill_pg_info(sig, info, process_group(current));
+ } else if (pid == -1) {
+ int retval = 0, count = 0;
+ struct task_struct * p;
+@@ -1798,7 +1798,7 @@
+
+ /* signals can be posted during this window */
+
+- if (is_orphaned_pgrp(current->pgrp))
++ if (is_orphaned_pgrp(process_group(current)))
+ goto relock;
+
+ spin_lock_irq(¤t->sighand->siglock);
+Index: linux-2.6.0-test5/kernel/softirq.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/softirq.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/softirq.c 2003-09-27 11:38:41.349242344 +0800
+@@ -9,8 +9,6 @@
+ #include <linux/module.h>
+ #include <linux/kernel_stat.h>
+ #include <linux/interrupt.h>
+-#include <linux/notifier.h>
+-#include <linux/percpu.h>
+ #include <linux/init.h>
+ #include <linux/mm.h>
+ #include <linux/notifier.h>
+@@ -59,11 +57,22 @@
+ wake_up_process(tsk);
+ }
+
++/*
++ * We restart softirq processing MAX_SOFTIRQ_RESTART times,
++ * and we fall back to softirqd after that.
++ *
++ * This number has been established via experimentation.
++ * The two things to balance is latency against fairness -
++ * we want to handle softirqs as soon as possible, but they
++ * should not be able to lock up the box.
++ */
++#define MAX_SOFTIRQ_RESTART 10
++
+ asmlinkage void do_softirq(void)
+ {
++ int max_restart = MAX_SOFTIRQ_RESTART;
+ __u32 pending;
+ unsigned long flags;
+- __u32 mask;
+
+ if (in_interrupt())
+ return;
+@@ -75,7 +84,6 @@
+ if (pending) {
+ struct softirq_action *h;
+
+- mask = ~pending;
+ local_bh_disable();
+ restart:
+ /* Reset the pending bitmask before enabling irqs */
+@@ -95,10 +103,8 @@
+ local_irq_disable();
+
+ pending = local_softirq_pending();
+- if (pending & mask) {
+- mask &= ~pending;
++ if (pending && --max_restart)
+ goto restart;
+- }
+ if (pending)
+ wakeup_softirqd();
+ __local_bh_enable();
+Index: linux-2.6.0-test5/kernel/sys.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/sys.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/sys.c 2003-09-27 11:38:41.358240976 +0800
+@@ -290,7 +290,7 @@
+ break;
+ case PRIO_PGRP:
+ if (!who)
+- who = current->pgrp;
++ who = process_group(current);
+ for_each_task_pid(who, PIDTYPE_PGID, p, l, pid)
+ error = set_one_prio(p, niceval, error);
+ break;
+@@ -346,7 +346,7 @@
+ break;
+ case PRIO_PGRP:
+ if (!who)
+- who = current->pgrp;
++ who = process_group(current);
+ for_each_task_pid(who, PIDTYPE_PGID, p, l, pid) {
+ niceval = 20 - task_nice(p);
+ if (niceval > retval)
+@@ -456,8 +456,11 @@
+
+ #ifdef CONFIG_SOFTWARE_SUSPEND
+ case LINUX_REBOOT_CMD_SW_SUSPEND:
+- if (!pm_suspend(PM_SUSPEND_DISK))
+- break;
++ if (!software_suspend_enabled) {
++ unlock_kernel();
++ return -EAGAIN;
++ }
++ software_suspend();
+ do_exit(0);
+ break;
+ #endif
+@@ -979,11 +982,12 @@
+ if (err)
+ goto out;
+
+- if (p->pgrp != pgid) {
++ if (process_group(p) != pgid) {
+ detach_pid(p, PIDTYPE_PGID);
+- p->pgrp = pgid;
++ p->group_leader->__pgrp = pgid;
+ attach_pid(p, PIDTYPE_PGID, pgid);
+ }
++
+ err = 0;
+ out:
+ /* All paths lead to here, thus we are safe. -DaveM */
+@@ -994,7 +998,7 @@
+ asmlinkage long sys_getpgid(pid_t pid)
+ {
+ if (!pid) {
+- return current->pgrp;
++ return process_group(current);
+ } else {
+ int retval;
+ struct task_struct *p;
+@@ -1006,7 +1010,7 @@
+ if (p) {
+ retval = security_task_getpgid(p);
+ if (!retval)
+- retval = p->pgrp;
++ retval = process_group(p);
+ }
+ read_unlock(&tasklist_lock);
+ return retval;
+@@ -1016,7 +1020,7 @@
+ asmlinkage long sys_getpgrp(void)
+ {
+ /* SMP - assuming writes are word atomic this is fine */
+- return current->pgrp;
++ return process_group(current);
+ }
+
+ asmlinkage long sys_getsid(pid_t pid)
+@@ -1059,7 +1063,7 @@
+ __set_special_pids(current->pid, current->pid);
+ current->tty = NULL;
+ current->tty_old_pgrp = 0;
+- err = current->pgrp;
++ err = process_group(current);
+ out:
+ write_unlock_irq(&tasklist_lock);
+ return err;
+Index: linux-2.6.0-test5/kernel/sysctl.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/sysctl.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/sysctl.c 2003-09-27 11:38:41.370239152 +0800
+@@ -643,7 +643,7 @@
+ .data = &dirty_writeback_centisecs,
+ .maxlen = sizeof(dirty_writeback_centisecs),
+ .mode = 0644,
+- .proc_handler = dirty_writeback_centisecs_handler,
++ .proc_handler = &dirty_writeback_centisecs_handler,
+ },
+ {
+ .ctl_name = VM_DIRTY_EXPIRE_CS,
+Index: linux-2.6.0-test5/lib/inflate.c
+===================================================================
+--- linux-2.6.0-test5.orig/lib/inflate.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/lib/inflate.c 2003-09-27 11:38:41.380237632 +0800
+@@ -871,7 +871,7 @@
+ {
+ DEBG("dyn5b ");
+ if (i == 1) {
+- error(" incomplete literal tree\n");
++ error("incomplete literal tree");
+ huft_free(tl);
+ }
+ return i; /* incomplete code set */
+@@ -882,7 +882,7 @@
+ {
+ DEBG("dyn5d ");
+ if (i == 1) {
+- error(" incomplete distance tree\n");
++ error("incomplete distance tree");
+ #ifdef PKZIP_BUG_WORKAROUND
+ i = 0;
+ }
+@@ -1097,15 +1097,15 @@
+
+ flags = (uch)get_byte();
+ if ((flags & ENCRYPTED) != 0) {
+- error("Input is encrypted\n");
++ error("Input is encrypted");
+ return -1;
+ }
+ if ((flags & CONTINUATION) != 0) {
+- error("Multi part input\n");
++ error("Multi part input");
+ return -1;
+ }
+ if ((flags & RESERVED) != 0) {
+- error("Input has invalid flags\n");
++ error("Input has invalid flags");
+ return -1;
+ }
+ (ulg)get_byte(); /* Get timestamp */
+Index: linux-2.6.0-test5/lib/kobject.c
+===================================================================
+--- linux-2.6.0-test5.orig/lib/kobject.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/lib/kobject.c 2003-09-27 11:38:41.385236872 +0800
+@@ -236,8 +236,6 @@
+ list_del_init(&kobj->entry);
+ up_write(&kobj->kset->subsys->rwsem);
+ }
+- if (kobj->parent)
+- kobject_put(kobj->parent);
+ kobject_put(kobj);
+ }
+
+@@ -448,6 +446,8 @@
+ if (kobj->k_name != kobj->name)
+ kfree(kobj->k_name);
+ kobj->k_name = NULL;
++ if (kobj->parent)
++ kobject_put(kobj->parent);
+ if (t && t->release)
+ t->release(kobj);
+ if (s)
+Index: linux-2.6.0-test5/lib/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/lib/Makefile 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/lib/Makefile 2003-09-27 11:38:41.386236720 +0800
+@@ -5,7 +5,7 @@
+
+ lib-y := errno.o ctype.o string.o vsprintf.o cmdline.o \
+ bust_spinlocks.o rbtree.o radix-tree.o dump_stack.o \
+- kobject.o idr.o div64.o
++ kobject.o idr.o div64.o parser.o
+
+ lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o
+ lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
+Index: linux-2.6.0-test5/lib/parser.c
+===================================================================
+--- linux-2.6.0-test5.orig/lib/parser.c 2003-09-27 11:38:18.489717520 +0800
++++ linux-2.6.0-test5/lib/parser.c 2003-09-27 11:38:41.387236568 +0800
+@@ -0,0 +1,138 @@
++/*
++ * lib/parser.c - simple parser for mount, etc. options.
++ *
++ * This source code is licensed under the GNU General Public License,
++ * Version 2. See the file COPYING for more details.
++ */
++
++#include <linux/ctype.h>
++#include <linux/module.h>
++#include <linux/parser.h>
++#include <linux/slab.h>
++#include <linux/string.h>
++
++static int match_one(char *s, char *p, substring_t args[])
++{
++ char *meta;
++ int argc = 0;
++
++ if (!p)
++ return 1;
++
++ while(1) {
++ int len = -1;
++ meta = strchr(p, '%');
++ if (!meta)
++ return strcmp(p, s) == 0;
++
++ if (strncmp(p, s, meta-p))
++ return 0;
++
++ s += meta - p;
++ p = meta + 1;
++
++ if (isdigit(*p))
++ len = simple_strtoul(p, &p, 10);
++ else if (*p == '%') {
++ if (*s++ != '%')
++ return 0;
++ continue;
++ }
++
++ if (argc >= MAX_OPT_ARGS)
++ return 0;
++
++ args[argc].from = s;
++ switch (*p++) {
++ case 's':
++ if (len == -1 || len > strlen(s))
++ len = strlen(s);
++ args[argc].to = s + len;
++ break;
++ case 'd':
++ simple_strtol(s, &args[argc].to, 0);
++ goto num;
++ case 'u':
++ simple_strtoul(s, &args[argc].to, 0);
++ goto num;
++ case 'o':
++ simple_strtoul(s, &args[argc].to, 8);
++ goto num;
++ case 'x':
++ simple_strtoul(s, &args[argc].to, 16);
++ num:
++ if (args[argc].to == args[argc].from)
++ return 0;
++ break;
++ default:
++ return 0;
++ }
++ s = args[argc].to;
++ argc++;
++ }
++}
++
++int match_token(char *s, match_table_t table, substring_t args[])
++{
++ struct match_token *p;
++
++ for (p = table; !match_one(s, p->pattern, args) ; p++)
++ ;
++
++ return p->token;
++}
++
++static int match_number(substring_t *s, int *result, int base)
++{
++ char *endp;
++ char *buf;
++ int ret;
++
++ buf = kmalloc(s->to - s->from + 1, GFP_KERNEL);
++ if (!buf)
++ return -ENOMEM;
++ memcpy(buf, s->from, s->to - s->from);
++ buf[s->to - s->from] = '\0';
++ *result = simple_strtol(buf, &endp, 0);
++ ret = 0;
++ if (endp == buf)
++ ret = -EINVAL;
++ kfree(buf);
++ return ret;
++}
++
++int match_int(substring_t *s, int *result)
++{
++ return match_number(s, result, 0);
++}
++
++int match_octal(substring_t *s, int *result)
++{
++ return match_number(s, result, 8);
++}
++
++int match_hex(substring_t *s, int *result)
++{
++ return match_number(s, result, 16);
++}
++
++void match_strcpy(char *to, substring_t *s)
++{
++ memcpy(to, s->from, s->to - s->from);
++ to[s->to - s->from] = '\0';
++}
++
++char *match_strdup(substring_t *s)
++{
++ char *p = kmalloc(s->to - s->from + 1, GFP_KERNEL);
++ if (p)
++ match_strcpy(p, s);
++ return p;
++}
++
++EXPORT_SYMBOL(match_token);
++EXPORT_SYMBOL(match_int);
++EXPORT_SYMBOL(match_octal);
++EXPORT_SYMBOL(match_hex);
++EXPORT_SYMBOL(match_strcpy);
++EXPORT_SYMBOL(match_strdup);
+Index: linux-2.6.0-test5/MAINTAINERS
+===================================================================
+--- linux-2.6.0-test5.orig/MAINTAINERS 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/MAINTAINERS 2003-09-27 11:38:41.399234744 +0800
+@@ -169,8 +169,8 @@
+ S: Supported
+
+ ACPI
+-P: Andy Grover
+-M: andrew.grover@intel.com
++P: Len Brown
++M: len.brown@intel.com
+ L: acpi-devel@lists.sourceforge.net
+ W: http://sf.net/projects/acpi/
+ S: Maintained
+@@ -212,7 +212,7 @@
+
+ ALCATEL SPEEDTOUCH USB DRIVER
+ P: Duncan Sands
+-M: duncan.sands@wanadoo.fr
++M: duncan.sands@free.fr
+ L: linux-usb-users@lists.sourceforge.net
+ L: linux-usb-devel@lists.sourceforge.net
+ W: http://www.linux-usb.org/SpeedTouch/
+@@ -328,18 +328,66 @@
+ L: linux-kernel@vger.kernel.org
+ S: Maintained
+
+-BLUETOOTH SUBSYSTEM (BlueZ)
++BLUETOOTH SUBSYSTEM
+ P: Maxim Krasnyansky
+ M: maxk@qualcomm.com
+ W: http://bluez.sf.net
+ S: Maintained
+
+-BLUETOOTH SUBSYSTEM (PC Card Drivers)
++BLUETOOTH RFCOMM LAYER
++P: Maxim Krasnyansky
++M: maxk@qualcomm.com
++W: http://bluez.sf.net
++S: Maintained
++
++BLUETOOTH BNEP LAYER
++P: Maxim Krasnyansky
++M: maxk@qualcomm.com
++W: http://bluez.sf.net
++S: Maintained
++
++BLUETOOTH HCI USB DRIVER
++P: Maxim Krasnyansky
++M: maxk@qualcomm.com
++W: http://bluez.sf.net
++S: Maintained
++
++BLUETOOTH HCI UART DRIVER
++P: Maxim Krasnyansky
++M: maxk@qualcomm.com
++W: http://bluez.sf.net
++S: Maintained
++
++BLUETOOTH HCI DTL1 DRIVER
++P: Marcel Holtmann
++M: marcel@holtmann.org
++W: http://www.holtmann.org/linux/bluetooth/
++S: Maintained
++
++BLUETOOTH HCI BLUECARD DRIVER
+ P: Marcel Holtmann
+ M: marcel@holtmann.org
+ W: http://www.holtmann.org/linux/bluetooth/
+ S: Maintained
+
++BLUETOOTH HCI BT3C DRIVER
++P: Marcel Holtmann
++M: marcel@holtmann.org
++W: http://www.holtmann.org/linux/bluetooth/
++S: Maintained
++
++BLUETOOTH HCI BTUART DRIVER
++P: Marcel Holtmann
++M: marcel@holtmann.org
++W: http://www.holtmann.org/linux/bluetooth/
++S: Maintained
++
++BLUETOOTH HCI VHCI DRIVER
++P: Maxim Krasnyansky
++M: maxk@qualcomm.com
++W: http://bluez.sf.net
++S: Maintained
++
+ BONDING DRIVER
+ P: Chad Tindel
+ M: ctindel@users.sourceforge.net
+@@ -557,21 +605,19 @@
+ S: Maintained
+
+ DEVICE FILESYSTEM
+-P: Richard Gooch
+-M: rgooch@atnf.csiro.au
+-L: linux-kernel@vger.kernel.org
+-S: Maintained
++S: Obsolete
+
+-DIGI INTL. EPCA DRIVER
++DIGI INTL. EPCA PCI (DGAP) DRIVER
+ P: Digi International, Inc
+ M: Eng.Linux@digi.com
+ L: Eng.Linux@digi.com
+ W: http://www.digi.com
+-S: Maintained
++S: Supported
+
+-DIGI RIGHTSWITCH NETWORK DRIVER
+-P: Rick Richardson
+-L: linux-net@vger.kernel.org
++DIGI INTL. EPCA ISA DRIVER
++P: Digi International, Inc
++M: Eng.Linux@digi.com
++L: Eng.Linux@digi.com
+ W: http://www.digi.com
+ S: Orphaned
+
+@@ -582,6 +628,12 @@
+ L: digilnux@dgii.com
+ S: Orphaned
+
++DIGI RIGHTSWITCH NETWORK DRIVER
++P: Rick Richardson
++L: linux-net@vger.kernel.org
++W: http://www.digi.com
++S: Orphaned
++
+ DIRECTORY NOTIFICATION
+ P: Stephen Rothwell
+ M: sfr@canb.auug.org.au
+@@ -661,6 +713,11 @@
+ W: http://sourceforge.net/projects/emu10k1/
+ S: Maintained
+
++EPSON 1355 FRAMEBUFFER DRIVER
++P: Christopher Hoover
++M: ch@murgatroid.com, ch@hpl.hp.com
++S: Maintained
++
+ ETHEREXPRESS-16 NETWORK DRIVER
+ P: Philip Blundell
+ M: Philip.Blundell@pobox.com
+@@ -1094,6 +1151,12 @@
+ W: http://developer.osdl.org/rddunlap/kj-patches/
+ S: Maintained
+
++KGDB FOR I386 PLATFORM
++P: George Anzinger
++M: george@mvista.com
++L: linux-net@vger.kernel.org
++S: Supported
++
+ KERNEL NFSD
+ P: Neil Brown
+ M: neilb@cse.unsw.edu.au
+@@ -1159,6 +1222,13 @@
+ L: linuxppc64-dev@lists.linuxppc.org
+ S: Supported
+
++LINUX SECURITY MODULE (LSM) FRAMEWORK
++P: Chris Wright
++M: chrisw@osdl.org
++L: linux-security-module@wirex.com
++W: http://lsm.immunix.org
++S: Supported
++
+ LOGICAL DISK MANAGER SUPPORT (LDM, Windows 2000/XP Dynamic Disks)
+ P: Richard Russon (FlatCap)
+ M: ldm@flatcap.org
+Index: linux-2.6.0-test5/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/Makefile 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/Makefile 2003-09-27 11:38:41.408233376 +0800
+@@ -1,7 +1,7 @@
+ VERSION = 2
+ PATCHLEVEL = 6
+ SUBLEVEL = 0
+-EXTRAVERSION = -test5
++EXTRAVERSION = -test5-mm4
+
+ # *DOCUMENTATION*
+ # To see a list of typical targets execute "make help"
+@@ -9,6 +9,9 @@
+ # Comments in this file are targeted only to the developer, do not
+ # expect to learn how to build the kernel reading this file.
+
++# Do not print "Entering directory ..."
++MAKEFLAGS += --no-print-directory
++
+ # We are using a recursive build, so we need to do a little thinking
+ # to get the ordering right.
+ #
+@@ -25,6 +28,87 @@
+ # descending is started. They are now explicitly listed as the
+ # prepare rule.
+
++# To put more focus on warnings, be less verbose as default
++# Use 'make V=1' to see the full commands
++
++ifdef V
++ ifeq ("$(origin V)", "command line")
++ KBUILD_VERBOSE = $(V)
++ endif
++endif
++ifndef KBUILD_VERBOSE
++ KBUILD_VERBOSE = 0
++endif
++
++# Call sparse as part of compilation of C files
++# Use 'make C=1' to enable sparse checking
++
++ifdef C
++ ifeq ("$(origin C)", "command line")
++ KBUILD_CHECKSRC = $(C)
++ endif
++endif
++ifndef KBUILD_CHECKSRC
++ KBUILD_CHECKSRC = 0
++endif
++
++# kbuild supports saving output files in a separate directory.
++# To locate output files in a separate directory two syntax'es are supported.
++# In both cases the working directory must be the root of the kernel src.
++# 1) O=
++# Use "make O=dir/to/store/output/files/"
++#
++# 2) Set KBUILD_OUTPUT
++# Set the environment variable KBUILD_OUTPUT to point to the directory
++# where the output files shall be placed.
++# export KBUILD_OUTPUT=dir/to/store/output/files/
++# make
++#
++# The O= assigment takes precedence over the KBUILD_OUTPUT environment variable.
++
++
++# KBUILD_SRC is set on invocation of make in OBJ directory
++# KBUILD_SRC is not intended to be used by the regular user (for now)
++ifeq ($(KBUILD_SRC),)
++
++# OK, Make called in directory where kernel src resides
++# Do we want to locate output files in a separate directory?
++ifdef O
++ ifeq ("$(origin O)", "command line")
++ KBUILD_OUTPUT := $(O)
++ endif
++endif
++
++ifneq ($(KBUILD_OUTPUT),)
++# Invoke a second make in the output directory, passing relevant variables
++ KBUILD_OUTPUT := $(shell cd $(KBUILD_OUTPUT); /bin/pwd)
++
++.PHONY: $(MAKECMDGOALS) all
++
++$(MAKECMDGOALS) all:
++ $(if $(KBUILD_VERBOSE:1=),@)$(MAKE) -C $(KBUILD_OUTPUT) \
++ KBUILD_SRC=$(CURDIR) KBUILD_VERBOSE=$(KBUILD_VERBOSE) \
++ KBUILD_CHECK=$(KBUILD_CHECK) -f $(CURDIR)/Makefile $(MAKECMDGOALS)
++
++# Leave processing to above invocation of make
++skip-makefile := 1
++endif # ifneq ($(KBUILD_OUTPUT),)
++endif # ifeq ($(KBUILD_SRC),)
++
++# We process the rest of the Makefile if this is the final invocation of make
++ifeq ($(skip-makefile),)
++
++srctree := $(if $(KBUILD_SRC),$(KBUILD_SRC),$(CURDIR))
++TOPDIR := $(srctree)
++# FIXME - TOPDIR is obsolete, use srctree/objtree
++objtree := $(CURDIR)
++src := $(srctree)
++obj := $(objtree)
++
++VPATH := $(srctree)
++
++export srctree objtree VPATH TOPDIR
++
+ KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
+
+ # SUBARCH tells the usermode build what the underlying arch is. That is set
+@@ -37,9 +121,6 @@
+ -e s/arm.*/arm/ -e s/sa110/arm/ \
+ -e s/s390x/s390/ -e s/parisc64/parisc/ )
+
+-# Remove hyphens since they have special meaning in RPM filenames
+-KERNELPATH=kernel-$(subst -,,$(KERNELRELEASE))
+-
+ # Cross compiling and selecting different set of gcc/bin-utils
+ # ---------------------------------------------------------------------------
+ #
+@@ -69,7 +150,6 @@
+ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
+ else if [ -x /bin/bash ]; then echo /bin/bash; \
+ else echo sh; fi ; fi)
+-TOPDIR := $(CURDIR)
+
+ HOSTCC = gcc
+ HOSTCXX = g++
+@@ -110,40 +190,8 @@
+ KBUILD_MODULES := 1
+ endif
+
+-export KBUILD_MODULES KBUILD_BUILTIN KBUILD_VERBOSE KBUILD_CHECKSRC
+-
+-# To put more focus on warnings, less verbose as default
+-# Use 'make V=1' to see the full commands
+-
+-ifdef V
+- ifeq ("$(origin V)", "command line")
+- KBUILD_VERBOSE = $(V)
+- endif
+-endif
+-ifndef KBUILD_VERBOSE
+- KBUILD_VERBOSE = 0
+-endif
+-
+-# Call sparse as part of compilation of C files
+-# Use 'make C=1' to enable sparse checking
+-
+-ifdef C
+- ifeq ("$(origin C)", "command line")
+- KBUILD_CHECKSRC = $(C)
+- endif
+-endif
+-ifndef KBUILD_CHECKSRC
+- KBUILD_CHECKSRC = 0
+-endif
+-
+-# Do not print 'Entering directory ...'
+-
+-MAKEFLAGS += --no-print-directory
+-
+-# For maximum performance (+ possibly random breakage, uncomment
+-# the following)
+-
+-#MAKEFLAGS += -rR
++export KBUILD_MODULES KBUILD_BUILTIN KBUILD_VERBOSE
++export KBUILD_CHECKSRC KBUILD_SRC
+
+ # Beautify output
+ # ---------------------------------------------------------------------------
+@@ -183,16 +231,17 @@
+ quiet=silent_
+ endif
+
+-export quiet Q KBUILD_VERBOSE
++check_gcc = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;)
+
+-# Paths to obj / src tree
++export quiet Q KBUILD_VERBOSE check_gcc
+
+-src := .
+-obj := .
+-srctree := .
+-objtree := .
++# Look for make include files relative to root of kernel src
++MAKEFLAGS += --include-dir=$(srctree)
++
++# For maximum performance (+ possibly random breakage, uncomment
++# the following)
+
+-export srctree objtree
++#MAKEFLAGS += -rR
+
+ # Make variables (CC, etc...)
+
+@@ -222,13 +271,15 @@
+
+ NOSTDINC_FLAGS = -nostdinc -iwithprefix include
+
+-CPPFLAGS := -D__KERNEL__ -Iinclude
++CPPFLAGS := -D__KERNEL__ -Iinclude \
++ $(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include)
++
+ CFLAGS := -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \
+ -fno-strict-aliasing -fno-common
+ AFLAGS := -D__ASSEMBLY__
+
+ export VERSION PATCHLEVEL SUBLEVEL EXTRAVERSION KERNELRELEASE ARCH \
+- CONFIG_SHELL TOPDIR HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC \
++ CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC \
+ CPP AR NM STRIP OBJCOPY OBJDUMP MAKE AWK GENKSYMS PERL UTS_MACHINE \
+ HOSTCXX HOSTCXXFLAGS LDFLAGS_BLOB LDFLAGS_MODULE CHECK
+
+@@ -294,7 +345,7 @@
+ # Handle them one by one.
+
+ %:: FORCE
+- $(Q)$(MAKE) $@
++ $(Q)$(MAKE) -C $(srctree) KBUILD_SRC= $@
+
+ else
+ ifeq ($(config-targets),1)
+@@ -341,7 +392,7 @@
+
+ endif
+
+-include arch/$(ARCH)/Makefile
++include $(srctree)/arch/$(ARCH)/Makefile
+
+ # Let architecture Makefiles change CPPFLAGS if needed
+ CFLAGS := $(CPPFLAGS) $(CFLAGS)
+@@ -378,6 +429,9 @@
+ CFLAGS += -g
+ endif
+
++# warn about C99 declaration after statement
++CFLAGS += $(call check_gcc,-Wdeclaration-after-statement,)
++
+ #
+ # INSTALL_PATH specifies where to place the updated kernel and system map
+ # images. Uncomment if you want to place them anywhere other than root.
+@@ -487,14 +541,34 @@
+ # Handle descending into subdirectories listed in $(SUBDIRS)
+
+ .PHONY: $(SUBDIRS)
+-$(SUBDIRS): prepare
++$(SUBDIRS): prepare-all
+ $(Q)$(MAKE) $(build)=$@
+
+-# Things we need done before we descend to build or make
+-# module versions are listed in "prepare"
++# Things we need to do before we recursively start building the kernel
++# or the modules are listed in "prepare-all".
++# A multi level approach is used. prepare1 is updated first, then prepare0.
++# prepare-all is the collection point for the prepare targets.
++
++.PHONY: prepare-all prepare prepare0 prepare1
++
++# prepare1 is used to check if we are building in a separate output directory,
++# and if so do:
++# 1) Check that make has not been executed in the kernel src $(srctree)
++# 2) Create the include2 directory, used for the second asm symlink
++
++prepare1:
++ifneq ($(KBUILD_SRC),)
++ @echo ' Using $(srctree) as source for kernel'
++ $(Q)if [ -h $(srctree)/include/asm -o -f $(srctree)/.config ]; then \
++ echo " $(srctree) is not clean, please run 'make mrproper'";\
++ echo " in the '$(srctree)' directory.";\
++ /bin/false; \
++ fi;
++ $(Q)if [ ! -d include2 ]; then mkdir -p include2; fi;
++ $(Q)ln -fsn $(srctree)/include/asm-$(ARCH) include2/asm
++endif
+
+-.PHONY: prepare
+-prepare: include/linux/version.h include/asm include/config/MARKER
++prepare0: prepare1 include/linux/version.h include/asm include/config/MARKER
+ ifdef KBUILD_MODULES
+ ifeq ($(origin SUBDIRS),file)
+ $(Q)rm -rf $(MODVERDIR)
+@@ -505,6 +579,9 @@
+ endif
+ $(if $(CONFIG_MODULES),$(Q)mkdir -p $(MODVERDIR))
+
++# All the preparing..
++prepare-all: prepare0 prepare
++
+ # Leave this as default for preprocessing vmlinux.lds.S, which is now
+ # done in arch/$(ARCH)/kernel/Makefile
+
+@@ -533,8 +610,9 @@
+ # before switching between archs anyway.
+
+ include/asm:
+- @echo ' Making asm->asm-$(ARCH) symlink'
+- @ln -s asm-$(ARCH) $@
++ @echo ' SYMLINK $@ -> include/asm-$(ARCH)'
++ $(Q)if [ ! -d include ]; then mkdir -p include; fi;
++ @ln -fsn asm-$(ARCH) $@
+
+ # Split autoconf.h into include/linux/config/*
+
+@@ -585,7 +663,7 @@
+ .PHONY: modules
+ modules: $(SUBDIRS) $(if $(KBUILD_BUILTIN),vmlinux)
+ @echo ' Building modules, stage 2.';
+- $(Q)$(MAKE) -rR -f scripts/Makefile.modpost
++ $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modpost
+
+ # Install modules
+
+@@ -603,7 +681,7 @@
+ @rm -f $(MODLIB)/build
+ @mkdir -p $(MODLIB)/kernel
+ @ln -s $(TOPDIR) $(MODLIB)/build
+- $(Q)$(MAKE) -rR -f scripts/Makefile.modinst
++ $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modinst
+
+ # If System.map exists, run depmod. This deliberately does not have a
+ # dependency on System.map since that would run the dependency tree on
+@@ -680,7 +758,8 @@
+ $(MODVERDIR) \
+ .tmp_export-objs \
+ include/config \
+- include/linux/modules
++ include/linux/modules \
++ include2
+
+ # clean - Delete all intermediate files
+ #
+@@ -759,31 +838,32 @@
+
+ .PHONY: rpm
+
++# Remove hyphens since they have special meaning in RPM filenames
++KERNELPATH=kernel-$(subst -,,$(KERNELRELEASE))
++
+ # If you do a make spec before packing the tarball you can rpm -ta it
+
+ spec:
+- . $(srctree)/scripts/mkspec >kernel.spec
++ $(CONFIG_SHELL) $(srctree)/scripts/mkspec > $(objtree)/kernel.spec
+
+-# Build a tar ball, generate an rpm from it and pack the result
+-# There are two bits of magic here
+-# 1) The use of /. to avoid tar packing just the symlink
+-# 2) Removing the .dep files as they have source paths in them that
+-# will become invalid
++# a) Build a tar ball
++# b) generate an rpm from it
++# c) and pack the result
++# - Use /. to avoid tar packing just the symlink
+
+ rpm: clean spec
+- find . $(RCS_FIND_IGNORE) \
+- \( -size 0 -o -name .depend -o -name .hdepend \) \
+- -type f -print | xargs rm -f
+ set -e; \
+- cd $(TOPDIR)/.. ; \
+- ln -sf $(TOPDIR) $(KERNELPATH) ; \
++ cd .. ; \
++ ln -sf $(srctree) $(KERNELPATH) ; \
+ tar -cvz $(RCS_TAR_IGNORE) -f $(KERNELPATH).tar.gz $(KERNELPATH)/. ; \
+- rm $(KERNELPATH) ; \
+- cd $(TOPDIR) ; \
+- $(CONFIG_SHELL) $(srctree)/scripts/mkversion > .tmp_version ; \
+- mv -f .tmp_version .version; \
+- $(RPM) -ta $(TOPDIR)/../$(KERNELPATH).tar.gz ; \
+- rm $(TOPDIR)/../$(KERNELPATH).tar.gz
++ rm $(KERNELPATH)
++
++ set -e; \
++ $(CONFIG_SHELL) $(srctree)/scripts/mkversion > $(objtree)/.tmp_version;\
++ mv -f $(objtree)/.tmp_version $(objtree)/.version;
++
++ $(RPM) -ta ../$(KERNELPATH).tar.gz
++ rm ../$(KERNELPATH).tar.gz
+
+ # Brief documentation of the typical targets used
+ # ---------------------------------------------------------------------------
+@@ -814,6 +894,7 @@
+ echo ' No architecture specific help defined for $(ARCH)')
+ @echo ''
+ @echo ' make V=0|1 [targets] 0 => quiet build (default), 1 => verbose build'
++ @echo ' make O=dir [targets] Locate all output files in "dir", including .config'
+ @echo ' make C=1 [targets] Check all c source with checker tool'
+ @echo ''
+ @echo 'Execute "make" or "make all" to build all targets marked with [*] '
+@@ -849,7 +930,8 @@
+ # FIXME Should go into a make.lib or something
+ # ===========================================================================
+
+-a_flags = -Wp,-MD,$(depfile) $(AFLAGS) $(AFLAGS_KERNEL) $(NOSTDINC_FLAGS) \
++a_flags = -Wp,-MD,$(depfile) $(AFLAGS) $(AFLAGS_KERNEL) \
++ $(NOSTDINC_FLAGS) $(CPPFLAGS) \
+ $(modkern_aflags) $(EXTRA_AFLAGS) $(AFLAGS_$(*F).o)
+
+ quiet_cmd_as_o_S = AS $@
+@@ -907,6 +989,7 @@
+ define filechk
+ @set -e; \
+ echo ' CHK $@'; \
++ mkdir -p $(dir $@); \
+ $(filechk_$(1)) < $< > $@.tmp; \
+ if [ -r $@ ] && cmp -s $@ $@.tmp; then \
+ rm -f $@.tmp; \
+@@ -919,16 +1002,18 @@
+ # Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj=dir
+ # Usage:
+ # $(Q)$(MAKE) $(build)=dir
+-build := -f scripts/Makefile.build obj
++build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj
+
+ # Shorthand for $(Q)$(MAKE) -f scripts/Makefile.clean obj=dir
+ # Usage:
+ # $(Q)$(MAKE) $(clean)=dir
+-clean := -f scripts/Makefile.clean obj
++clean := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.clean obj
+
+ # $(call descend,<dir>,<target>)
+ # Recursively call a sub-make in <dir> with target <target>
+ # Usage is deprecated, because make does not see this as an invocation of make.
+-descend =$(Q)$(MAKE) -f scripts/Makefile.build obj=$(1) $(2)
++descend =$(Q)$(MAKE) -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj=$(1) $(2)
++
++endif # skip-makefile
+
+ FORCE:
+Index: linux-2.6.0-test5/mm/fadvise.c
+===================================================================
+--- linux-2.6.0-test5.orig/mm/fadvise.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/mm/fadvise.c 2003-09-27 11:38:41.410233072 +0800
+@@ -20,7 +20,7 @@
+ * POSIX_FADV_WILLNEED could set PG_Referenced, and POSIX_FADV_NOREUSE could
+ * deactivate the pages and clear PG_Referenced.
+ */
+-long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice)
++asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice)
+ {
+ struct file *file = fget(fd);
+ struct inode *inode;
+@@ -80,7 +80,7 @@
+ return ret;
+ }
+
+-long sys_fadvise64(int fd, loff_t offset, size_t len, int advice)
++asmlinkage long sys_fadvise64(int fd, loff_t offset, size_t len, int advice)
+ {
+ return sys_fadvise64_64(fd, offset, len, advice);
+ }
+Index: linux-2.6.0-test5/mm/filemap.c
+===================================================================
+--- linux-2.6.0-test5.orig/mm/filemap.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/mm/filemap.c 2003-09-27 11:38:41.423231096 +0800
+@@ -70,6 +70,9 @@
+ * ->mmap_sem
+ * ->i_sem (msync)
+ *
++ * ->i_alloc_sem
++ * ->i_sem (various)
++ *
+ * ->inode_lock
+ * ->sb_lock (fs/fs-writeback.c)
+ * ->mapping->page_lock (__sync_single_inode)
+@@ -281,21 +284,42 @@
+ return &zone->wait_table[hash_ptr(page, zone->wait_table_bits)];
+ }
+
+-void wait_on_page_bit(struct page *page, int bit_nr)
++/*
++ * wait for the specified page bit to be cleared
++ * this could be a synchronous wait or could just queue an async
++ * notification callback depending on the wait queue entry parameter
++ *
++ * A NULL wait queue parameter defaults to sync behaviour
++ */
++int wait_on_page_bit_wq(struct page *page, int bit_nr, wait_queue_t *wait)
+ {
+ wait_queue_head_t *waitqueue = page_waitqueue(page);
+- DEFINE_WAIT(wait);
++ DEFINE_WAIT(local_wait);
++
++ if (!wait)
++ wait = &local_wait; /* default to a sync wait entry */
+
+ do {
+- prepare_to_wait(waitqueue, &wait, TASK_UNINTERRUPTIBLE);
++ prepare_to_wait(waitqueue, wait, TASK_UNINTERRUPTIBLE);
+ if (test_bit(bit_nr, &page->flags)) {
+ sync_page(page);
++ if (!is_sync_wait(wait)) {
++ /*
++ * if we've queued an async wait queue
++ * callback do not block; just tell the
++ * caller to return and retry later when
++ * the callback is notified
++ */
++ return -EIOCBRETRY;
++ }
+ io_schedule();
+ }
+ } while (test_bit(bit_nr, &page->flags));
+- finish_wait(waitqueue, &wait);
++ finish_wait(waitqueue, wait);
++
++ return 0;
+ }
+-EXPORT_SYMBOL(wait_on_page_bit);
++EXPORT_SYMBOL(wait_on_page_bit_wq);
+
+ /**
+ * unlock_page() - unlock a locked page
+@@ -305,7 +329,9 @@
+ * Unlocks the page and wakes up sleepers in ___wait_on_page_locked().
+ * Also wakes sleepers in wait_on_page_writeback() because the wakeup
+ * mechananism between PageLocked pages and PageWriteback pages is shared.
+- * But that's OK - sleepers in wait_on_page_writeback() just go back to sleep.
++ * But that's OK - sleepers in wait_on_page_writeback() just go back to sleep,
++ * or in case the wakeup notifies async wait queue entries, as in the case
++ * of aio, retries would be triggered and may re-queue their callbacks.
+ *
+ * The first mb is necessary to safely close the critical section opened by the
+ * TestSetPageLocked(), the second mb is necessary to enforce ordering between
+@@ -342,26 +368,51 @@
+ EXPORT_SYMBOL(end_page_writeback);
+
+ /*
+- * Get a lock on the page, assuming we need to sleep to get it.
++ * Get a lock on the page, assuming we need to either sleep to get it
++ * or to queue an async notification callback to try again when its
++ * available.
++ *
++ * A NULL wait queue parameter defaults to sync behaviour. Otherwise
++ * it specifies the wait queue entry to be used for async notification
++ * or waiting.
+ *
+ * Ugly: running sync_page() in state TASK_UNINTERRUPTIBLE is scary. If some
+ * random driver's requestfn sets TASK_RUNNING, we could busywait. However
+ * chances are that on the second loop, the block layer's plug list is empty,
+ * so sync_page() will then return in state TASK_UNINTERRUPTIBLE.
+ */
+-void __lock_page(struct page *page)
++int __lock_page_wq(struct page *page, wait_queue_t *wait)
+ {
+ wait_queue_head_t *wqh = page_waitqueue(page);
+- DEFINE_WAIT(wait);
++ DEFINE_WAIT(local_wait);
++
++ if (!wait)
++ wait = &local_wait;
+
+ while (TestSetPageLocked(page)) {
+- prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE);
++ prepare_to_wait(wqh, wait, TASK_UNINTERRUPTIBLE);
+ if (PageLocked(page)) {
+ sync_page(page);
++ if (!is_sync_wait(wait)) {
++ /*
++ * if we've queued an async wait queue
++ * callback do not block; just tell the
++ * caller to return and retry later when
++ * the callback is notified
++ */
++ return -EIOCBRETRY;
++ }
+ io_schedule();
+ }
+ }
+- finish_wait(wqh, &wait);
++ finish_wait(wqh, wait);
++ return 0;
++}
++EXPORT_SYMBOL(__lock_page_wq);
++
++void __lock_page(struct page *page)
++{
++ __lock_page_wq(page, NULL);
+ }
+ EXPORT_SYMBOL(__lock_page);
+
+@@ -411,8 +462,8 @@
+ *
+ * Returns zero if the page was not present. find_lock_page() may sleep.
+ */
+-struct page *find_lock_page(struct address_space *mapping,
+- unsigned long offset)
++struct page *find_lock_page_wq(struct address_space *mapping,
++ unsigned long offset, wait_queue_t *wait)
+ {
+ struct page *page;
+
+@@ -423,7 +474,10 @@
+ page_cache_get(page);
+ if (TestSetPageLocked(page)) {
+ spin_unlock(&mapping->page_lock);
+- lock_page(page);
++ if (-EIOCBRETRY == lock_page_wq(page, wait)) {
++ page_cache_release(page);
++ return ERR_PTR(-EIOCBRETRY);
++ }
+ spin_lock(&mapping->page_lock);
+
+ /* Has the page been truncated while we slept? */
+@@ -438,6 +492,12 @@
+ return page;
+ }
+
++struct page *find_lock_page(struct address_space *mapping,
++ unsigned long offset)
++{
++ return find_lock_page_wq(mapping, offset, NULL);
++}
++
+ /**
+ * find_or_create_page - locate or add a pagecache page
+ *
+@@ -496,9 +556,12 @@
+ * The search returns a group of mapping-contiguous pages with ascending
+ * indexes. There may be holes in the indices due to not-present pages.
+ *
+- * find_get_pages() returns the number of pages which were found.
++ * find_get_pages() returns the number of pages which were found
++ * and also atomically sets the next offset to continue looking up
++ * mapping contiguous pages from (useful when doing a range of
++ * pagevec lookups in chunks of PAGEVEC_SIZE).
+ */
+-unsigned int find_get_pages(struct address_space *mapping, pgoff_t start,
++unsigned int find_get_pages(struct address_space *mapping, pgoff_t *next,
+ unsigned int nr_pages, struct page **pages)
+ {
+ unsigned int i;
+@@ -506,9 +569,12 @@
+
+ spin_lock(&mapping->page_lock);
+ ret = radix_tree_gang_lookup(&mapping->page_tree,
+- (void **)pages, start, nr_pages);
++ (void **)pages, *next, nr_pages);
+ for (i = 0; i < ret; i++)
+ page_cache_get(pages[i]);
++ if (ret)
++ *next = pages[ret - 1]->index + 1;
++
+ spin_unlock(&mapping->page_lock);
+ return ret;
+ }
+@@ -560,21 +626,47 @@
+ read_actor_t actor)
+ {
+ struct inode *inode = mapping->host;
+- unsigned long index, offset;
++ unsigned long index, offset, first, last, end_index;
+ struct page *cached_page;
++ loff_t isize = i_size_read(inode);
+ int error;
+
+ cached_page = NULL;
+- index = *ppos >> PAGE_CACHE_SHIFT;
++ first = *ppos >> PAGE_CACHE_SHIFT;
+ offset = *ppos & ~PAGE_CACHE_MASK;
+
++ last = (*ppos + desc->count) >> PAGE_CACHE_SHIFT;
++ end_index = isize >> PAGE_CACHE_SHIFT;
++ if (last > end_index)
++ last = end_index;
++
++ /* Don't repeat the readahead if we are executing aio retries */
++ if (in_aio()) {
++ if (is_retried_kiocb(io_wait_to_kiocb(current->io_wait)))
++ goto done_readahead;
++ }
++
++ /*
++ * Let the readahead logic know upfront about all
++ * the pages we'll need to satisfy this request
++ */
++ for (index = first ; index < last; index++)
++ page_cache_readahead(mapping, ra, filp, index);
++
++ if (ra->next_size == -1UL) {
++ /* the readahead window was maximally shrunk */
++ /* explicitly readahead at least what is needed now */
++ for (index = first; index < last; index++)
++ handle_ra_miss(mapping, ra, index);
++ do_page_cache_readahead(mapping, filp, first, last - first);
++ }
++
++done_readahead:
++ index = first;
+ for (;;) {
+ struct page *page;
+- unsigned long end_index, nr, ret;
+- loff_t isize = i_size_read(inode);
++ unsigned long nr, ret;
+
+- end_index = isize >> PAGE_CACHE_SHIFT;
+-
+ if (index > end_index)
+ break;
+ nr = PAGE_CACHE_SIZE;
+@@ -585,7 +677,6 @@
+ }
+
+ cond_resched();
+- page_cache_readahead(mapping, ra, filp, index);
+
+ nr = nr - offset;
+ find_page:
+@@ -635,7 +726,12 @@
+ goto page_ok;
+
+ /* Get exclusive access to the page ... */
+- lock_page(page);
++
++ if (lock_page_wq(page, current->io_wait)) {
++ pr_debug("queued lock page \n");
++ error = -EIOCBRETRY;
++ goto sync_error;
++ }
+
+ /* Did it get unhashed before we got the lock? */
+ if (!page->mapping) {
+@@ -657,13 +753,23 @@
+ if (!error) {
+ if (PageUptodate(page))
+ goto page_ok;
+- wait_on_page_locked(page);
++ if (wait_on_page_locked_wq(page, current->io_wait)) {
++ pr_debug("queued wait_on_page \n");
++ error = -EIOCBRETRY;
++ goto sync_error;
++ }
++
+ if (PageUptodate(page))
+ goto page_ok;
+ error = -EIO;
+ }
+
+- /* UHHUH! A synchronous read error occurred. Report it */
++sync_error:
++ /* We don't have uptodate data in the page yet */
++ /* Could be due to an error or because we need to
++ * retry when we get an async i/o notification.
++ * Report the reason.
++ */
+ desc->error = error;
+ page_cache_release(page);
+ break;
+@@ -782,6 +888,10 @@
+ goto out; /* skip atime */
+ size = i_size_read(inode);
+ if (pos < size) {
++ if (S_ISREG(inode->i_mode)) {
++ down_read(&inode->i_alloc_sem);
++ down(&inode->i_sem);
++ }
+ retval = generic_file_direct_IO(READ, iocb,
+ iov, pos, nr_segs);
+ if (retval >= 0 && !is_sync_kiocb(iocb))
+@@ -790,6 +900,12 @@
+ *ppos = pos + retval;
+ }
+ update_atime(filp->f_dentry->d_inode);
++ /*
++ * i_sem and i_alloc_sem release are handled by
++ * the direct i/o code, the former is released after
++ * i/o submission, the latter set up to be released
++ * on actual i/o completion.
++ */
+ goto out;
+ }
+
+@@ -816,19 +932,18 @@
+ return retval;
+ }
+
+-ssize_t
+-generic_file_aio_read(struct kiocb *iocb, char __user *buf, size_t count, loff_t pos)
++ssize_t generic_file_aio_read(struct kiocb *iocb, char __user *buf,
++ size_t count, loff_t pos)
+ {
+ struct iovec local_iov = { .iov_base = buf, .iov_len = count };
+
+- BUG_ON(iocb->ki_pos != pos);
+ return __generic_file_aio_read(iocb, &local_iov, 1, &iocb->ki_pos);
+ }
+ EXPORT_SYMBOL(generic_file_aio_read);
+ EXPORT_SYMBOL(__generic_file_aio_read);
+
+-ssize_t
+-generic_file_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
++ssize_t generic_file_read(struct file *filp, char __user *buf,
++ size_t count, loff_t *ppos)
+ {
+ struct iovec local_iov = { .iov_base = buf, .iov_len = count };
+ struct kiocb kiocb;
+@@ -841,7 +956,8 @@
+ return ret;
+ }
+
+-int file_send_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size)
++int file_send_actor(read_descriptor_t * desc, struct page *page,
++ unsigned long offset, unsigned long size)
+ {
+ ssize_t written;
+ unsigned long count = desc->count;
+@@ -1266,6 +1382,20 @@
+ page_cache_release(page);
+ return err;
+ }
++ } else {
++ /*
++ * If a nonlinear mapping then store the file page offset
++ * in the pte.
++ */
++ unsigned long pgidx;
++ pgidx = (addr - vma->vm_start) >> PAGE_SHIFT;
++ pgidx += vma->vm_pgoff;
++ pgidx >>= PAGE_CACHE_SHIFT - PAGE_SHIFT;
++ if (pgoff != pgidx) {
++ err = install_file_pte(mm, vma, addr, pgoff, prot);
++ if (err)
++ return err;
++ }
+ }
+
+ len -= PAGE_SIZE;
+@@ -1404,7 +1534,9 @@
+ int err;
+ struct page *page;
+ repeat:
+- page = find_lock_page(mapping, index);
++ page = find_lock_page_wq(mapping, index, current->io_wait);
++ if (IS_ERR(page))
++ return page;
+ if (!page) {
+ if (!*cached_page) {
+ *cached_page = page_cache_alloc(mapping);
+@@ -1437,7 +1569,7 @@
+
+ /* was any of the uid bits set? */
+ if (mode && !capable(CAP_FSETID)) {
+- newattrs.ia_valid = ATTR_KILL_SUID | ATTR_KILL_SGID;
++ newattrs.ia_valid = ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_FORCE;
+ notify_change(dentry, &newattrs);
+ }
+ }
+@@ -1628,6 +1760,9 @@
+
+ /*
+ * Write to a file through the page cache.
++ * Should be called with the following semaphores already held:
++ * i_alloc_sem (only for O_DIRECT writes to regular files)
++ * i_sem (only for regular files)
+ *
+ * We put everything into the page cache prior to writing it. This is not a
+ * problem when writing full pages. With partial pages, however, we first have
+@@ -1636,7 +1771,7 @@
+ * okir@monad.swb.de
+ */
+ ssize_t
+-generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov,
++__generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t *ppos)
+ {
+ struct file *file = iocb->ki_filp;
+@@ -1691,7 +1826,6 @@
+ if (err)
+ goto out;
+
+-
+ if (count == 0)
+ goto out;
+
+@@ -1721,7 +1855,14 @@
+ status = generic_osync_inode(inode, OSYNC_METADATA);
+ if (written >= 0 && !is_sync_kiocb(iocb))
+ written = -EIOCBQUEUED;
+- goto out_status;
++ if (written != -ENOTBLK)
++ goto out_status;
++ /*
++ * direct-io write to a hole: fall through to buffered I/O
++ */
++ written = 0;
++ if (S_ISREG(inode->i_mode))
++ down(&inode->i_sem);
+ }
+
+ buf = iov->iov_base;
+@@ -1745,6 +1886,10 @@
+ fault_in_pages_readable(buf, bytes);
+
+ page = __grab_cache_page(mapping,index,&cached_page,&lru_pvec);
++ if (IS_ERR(page)) {
++ status = PTR_ERR(page);
++ break;
++ }
+ if (!page) {
+ status = -ENOMEM;
+ break;
+@@ -1793,7 +1938,11 @@
+ page_cache_release(page);
+ if (status < 0)
+ break;
+- balance_dirty_pages_ratelimited(mapping);
++ status = balance_dirty_pages_ratelimited(mapping);
++ if (status < 0) {
++ pr_debug("async balance_dirty_pages\n");
++ break;
++ }
+ cond_resched();
+ } while (count);
+ *ppos = pos;
+@@ -1804,12 +1953,21 @@
+ /*
+ * For now, when the user asks for O_SYNC, we'll actually give O_DSYNC
+ */
+- if (status >= 0) {
+- if ((file->f_flags & O_SYNC) || IS_SYNC(inode))
+- status = generic_osync_inode(inode,
+- OSYNC_METADATA|OSYNC_DATA);
++ if (likely(status >= 0)) {
++ if (unlikely((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
++ if (!a_ops->writepage)
++ status = generic_osync_inode(inode,
++ OSYNC_METADATA|OSYNC_DATA);
++ }
++ }
++
++ if (unlikely(file->f_flags & O_DIRECT)) {
++ if (written)
++ do_fdatasync(file);
++ if (S_ISREG(inode->i_mode))
++ up(&inode->i_sem);
+ }
+-
++
+ out_status:
+ err = written ? written : status;
+ out:
+@@ -1818,6 +1976,65 @@
+ return err;
+ }
+
++/*
++ * Should be called with the following semaphores already held:
++ * i_alloc_sem (only for O_DIRECT writes to regular files)
++ * i_sem (only for regular files)
++ */
++ssize_t
++generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov,
++ unsigned long nr_segs, loff_t *ppos)
++{
++ struct file *file = iocb->ki_filp;
++ struct address_space * mapping = file->f_dentry->d_inode->i_mapping;
++ struct inode *inode = mapping->host;
++ ssize_t ret;
++ loff_t pos = *ppos;
++
++ if (!iov->iov_base && !is_sync_kiocb(iocb)) {
++ /* nothing to transfer, may just need to sync data */
++ ret = iov->iov_len; /* vector AIO not supported yet */
++ goto osync;
++ }
++
++ ret = __generic_file_aio_write_nolock(iocb, iov, nr_segs, ppos);
++
++ /*
++ * Avoid doing a sync in parts for aio - its more efficient to
++ * call in again after all the data has been copied
++ */
++ if (!is_sync_kiocb(iocb))
++ return ret;
++
++osync:
++ if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
++ ret = sync_page_range_nolock(inode, mapping, pos, ret);
++ if (ret >= 0)
++ *ppos = pos + ret;
++ }
++ return ret;
++}
++
++
++ssize_t
++__generic_file_write_nolock(struct file *file, const struct iovec *iov,
++ unsigned long nr_segs, loff_t *ppos)
++{
++ struct kiocb kiocb;
++ ssize_t ret;
++
++ init_sync_kiocb(&kiocb, file);
++ ret = __generic_file_aio_write_nolock(&kiocb, iov, nr_segs, ppos);
++ if (-EIOCBQUEUED == ret)
++ ret = wait_on_sync_kiocb(&kiocb);
++ return ret;
++}
++
++/*
++ * Should be called with the following semaphores already held:
++ * i_alloc_sem (only for O_DIRECT writes to regular files)
++ * i_sem (only for regular files)
++ */
+ ssize_t
+ generic_file_write_nolock(struct file *file, const struct iovec *iov,
+ unsigned long nr_segs, loff_t *ppos)
+@@ -1836,18 +2053,44 @@
+ size_t count, loff_t pos)
+ {
+ struct file *file = iocb->ki_filp;
+- struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
+- ssize_t err;
+- struct iovec local_iov = { .iov_base = (void __user *)buf, .iov_len = count };
++ struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
++ struct inode *inode = mapping->host;
++ ssize_t ret;
++ struct iovec local_iov = { .iov_base = (void __user *)buf,
++ .iov_len = count };
+
+- BUG_ON(iocb->ki_pos != pos);
++ if (!buf && !is_sync_kiocb(iocb)) {
++ /* nothing to transfer, may just need to sync data */
++ ret = count;
++ goto osync;
++ }
+
+ down(&inode->i_sem);
+- err = generic_file_aio_write_nolock(iocb, &local_iov, 1,
++ if (file->f_flags & O_DIRECT)
++ down_read(&inode->i_alloc_sem);
++ ret = __generic_file_aio_write_nolock(iocb, &local_iov, 1,
+ &iocb->ki_pos);
+- up(&inode->i_sem);
++ /*
++ * For O_DIRECT, i_sem would have already been released and
++ * i_alloc_sem is released on i/o completion.
++ */
++ if (!(file->f_flags & O_DIRECT))
++ up(&inode->i_sem);
+
+- return err;
++ /*
++ * Avoid doing a sync in parts for aio - its more efficient to
++ * call in again after all the data has been copied
++ */
++ if (!is_sync_kiocb(iocb))
++ return ret;
++
++osync:
++ if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
++ ret = sync_page_range(inode, mapping, pos, ret);
++ if (ret >= 0)
++ iocb->ki_pos = pos + ret;
++ }
++ return ret;
+ }
+ EXPORT_SYMBOL(generic_file_aio_write);
+ EXPORT_SYMBOL(generic_file_aio_write_nolock);
+@@ -1855,15 +2098,31 @@
+ ssize_t generic_file_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+ {
+- struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
+- ssize_t err;
+- struct iovec local_iov = { .iov_base = (void __user *)buf, .iov_len = count };
++ struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
++ struct inode *inode = mapping->host;
++ ssize_t ret;
++ struct iovec local_iov = { .iov_base = (void __user *)buf,
++ .iov_len = count };
+
++ if (file->f_flags & O_DIRECT)
++ down_read(&inode->i_alloc_sem);
+ down(&inode->i_sem);
+- err = generic_file_write_nolock(file, &local_iov, 1, ppos);
+- up(&inode->i_sem);
++ ret = __generic_file_write_nolock(file, &local_iov, 1, ppos);
++ /*
++ * For O_DIRECT, i_sem would have already been released and
++ * i_alloc_sem is released on i/o completion
++ */
++ if (!(file->f_flags & O_DIRECT))
++ up(&inode->i_sem);
+
+- return err;
++ if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
++ ssize_t err;
++
++ err = sync_page_range(inode, mapping, *ppos - ret, ret);
++ if (err < 0)
++ ret = err;
++ }
++ return ret;
+ }
+
+ ssize_t generic_file_readv(struct file *filp, const struct iovec *iov,
+@@ -1880,23 +2139,45 @@
+ }
+
+ ssize_t generic_file_writev(struct file *file, const struct iovec *iov,
+- unsigned long nr_segs, loff_t * ppos)
++ unsigned long nr_segs, loff_t *ppos)
+ {
+ struct inode *inode = file->f_dentry->d_inode;
+ ssize_t ret;
+
++ if (file->f_flags & O_DIRECT)
++ down_read(&inode->i_alloc_sem);
+ down(&inode->i_sem);
+- ret = generic_file_write_nolock(file, iov, nr_segs, ppos);
+- up(&inode->i_sem);
++ ret = __generic_file_write_nolock(file, iov, nr_segs, ppos);
++ /*
++ * For O_DIRECT, i_sem would have already been released and
++ * i_alloc_sem is released on i/o completion.
++ */
++ if (!(file->f_flags & O_DIRECT))
++ up(&inode->i_sem);
++
++ if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
++ ssize_t err;
++
++ err = sync_page_range(inode, inode->i_mapping,
++ *ppos - ret, ret);
++ if (err < 0)
++ ret = err;
++ }
+ return ret;
+ }
+
++/*
++ * For regular files, i_sem and i_alloc_sem should be held already.
++ * i_sem may be dropped later once we've mapped the new IO.
++ * i_alloc_sem is kept until the IO completes.
++ */
+ ssize_t
+ generic_file_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
+ loff_t offset, unsigned long nr_segs)
+ {
+ struct file *file = iocb->ki_filp;
+- struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
++ struct inode *inode = file->f_dentry->d_inode;
++ struct address_space *mapping = inode->i_mapping;
+ ssize_t retval;
+
+ if (mapping->nrpages) {
+@@ -1910,6 +2191,10 @@
+ retval = mapping->a_ops->direct_IO(rw, iocb, iov, offset, nr_segs);
+ if (rw == WRITE && mapping->nrpages)
+ invalidate_inode_pages2(mapping);
++ return retval;
+ out:
++ up(&inode->i_sem);
++ if (S_ISREG(inode->i_mode))
++ up_read(&inode->i_alloc_sem);
+ return retval;
+ }
+Index: linux-2.6.0-test5/mm/fremap.c
+===================================================================
+--- linux-2.6.0-test5.orig/mm/fremap.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/mm/fremap.c 2003-09-27 11:38:41.426230640 +0800
+@@ -61,6 +61,7 @@
+ pte_t *pte;
+ pgd_t *pgd;
+ pmd_t *pmd;
++ pte_t pte_val;
+ struct pte_chain *pte_chain;
+
+ pte_chain = pte_chain_alloc(GFP_KERNEL);
+@@ -83,10 +84,11 @@
+ flush_icache_page(vma, page);
+ set_pte(pte, mk_pte(page, prot));
+ pte_chain = page_add_rmap(page, pte, pte_chain);
++ pte_val = *pte;
+ pte_unmap(pte);
+ if (flush)
+ flush_tlb_page(vma, addr);
+- update_mmu_cache(vma, addr, *pte);
++ update_mmu_cache(vma, addr, pte_val);
+ spin_unlock(&mm->page_table_lock);
+ pte_chain_free(pte_chain);
+ return 0;
+@@ -100,6 +102,47 @@
+ EXPORT_SYMBOL(install_page);
+
+
++/*
++ * Install a file pte to a given virtual memory address, release any
++ * previously existing mapping.
++ */
++int install_file_pte(struct mm_struct *mm, struct vm_area_struct *vma,
++ unsigned long addr, unsigned long pgoff, pgprot_t prot)
++{
++ int err = -ENOMEM, flush;
++ pte_t *pte;
++ pgd_t *pgd;
++ pmd_t *pmd;
++ pte_t pte_val;
++
++ pgd = pgd_offset(mm, addr);
++ spin_lock(&mm->page_table_lock);
++
++ pmd = pmd_alloc(mm, pgd, addr);
++ if (!pmd)
++ goto err_unlock;
++
++ pte = pte_alloc_map(mm, pmd, addr);
++ if (!pte)
++ goto err_unlock;
++
++ flush = zap_pte(mm, vma, addr, pte);
++
++ set_pte(pte, pgoff_to_pte(pgoff));
++ pte_val = *pte;
++ pte_unmap(pte);
++ if (flush)
++ flush_tlb_page(vma, addr);
++ update_mmu_cache(vma, addr, pte_val);
++ spin_unlock(&mm->page_table_lock);
++ return 0;
++
++err_unlock:
++ spin_unlock(&mm->page_table_lock);
++ return err;
++}
++
++
+ /***
+ * sys_remap_file_pages - remap arbitrary pages of a shared backing store
+ * file within an existing vma.
+Index: linux-2.6.0-test5/mm/highmem.c
+===================================================================
+--- linux-2.6.0-test5.orig/mm/highmem.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/mm/highmem.c 2003-09-27 11:38:41.430230032 +0800
+@@ -24,6 +24,7 @@
+ #include <linux/blkdev.h>
+ #include <linux/init.h>
+ #include <linux/hash.h>
++#include <linux/highmem.h>
+ #include <asm/pgalloc.h>
+ #include <asm/tlbflush.h>
+
+@@ -62,7 +63,7 @@
+ {
+ int i;
+
+- flush_cache_all();
++ flush_cache_kmaps();
+
+ for (i = 0; i < LAST_PKMAP; i++) {
+ struct page *page;
+Index: linux-2.6.0-test5/mm/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/mm/Makefile 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/mm/Makefile 2003-09-27 11:38:41.432229728 +0800
+@@ -12,3 +12,6 @@
+ slab.o swap.o truncate.o vmscan.o $(mmu-y)
+
+ obj-$(CONFIG_SWAP) += page_io.o swap_state.o swapfile.o
++
++obj-$(CONFIG_X86_4G) += usercopy.o
++
+Index: linux-2.6.0-test5/mm/memory.c
+===================================================================
+--- linux-2.6.0-test5.orig/mm/memory.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/mm/memory.c 2003-09-27 11:38:41.443228056 +0800
+@@ -100,7 +100,8 @@
+ pte_free_tlb(tlb, page);
+ }
+
+-static inline void free_one_pgd(struct mmu_gather *tlb, pgd_t * dir)
++static inline void free_one_pgd(struct mmu_gather *tlb, pgd_t * dir,
++ int pgd_idx)
+ {
+ int j;
+ pmd_t * pmd;
+@@ -114,8 +115,11 @@
+ }
+ pmd = pmd_offset(dir, 0);
+ pgd_clear(dir);
+- for (j = 0; j < PTRS_PER_PMD ; j++)
++ for (j = 0; j < PTRS_PER_PMD ; j++) {
++ if (pgd_idx * PGDIR_SIZE + j * PMD_SIZE >= TASK_SIZE)
++ break;
+ free_one_pmd(tlb, pmd+j);
++ }
+ pmd_free_tlb(tlb, pmd);
+ }
+
+@@ -128,11 +132,13 @@
+ void clear_page_tables(struct mmu_gather *tlb, unsigned long first, int nr)
+ {
+ pgd_t * page_dir = tlb->mm->pgd;
++ int pgd_idx = first;
+
+ page_dir += first;
+ do {
+- free_one_pgd(tlb, page_dir);
++ free_one_pgd(tlb, page_dir, pgd_idx);
+ page_dir++;
++ pgd_idx++;
+ } while (--nr);
+ }
+
+@@ -430,7 +436,7 @@
+ unsigned long address, unsigned long size)
+ {
+ pmd_t * pmd;
+- unsigned long end;
++ unsigned long end, pgd_boundary;
+
+ if (pgd_none(*dir))
+ return;
+@@ -441,8 +447,9 @@
+ }
+ pmd = pmd_offset(dir, address);
+ end = address + size;
+- if (end > ((address + PGDIR_SIZE) & PGDIR_MASK))
+- end = ((address + PGDIR_SIZE) & PGDIR_MASK);
++ pgd_boundary = ((address + PGDIR_SIZE) & PGDIR_MASK);
++ if (pgd_boundary && (end > pgd_boundary))
++ end = pgd_boundary;
+ do {
+ zap_pte_range(tlb, pmd, address, end - address);
+ address = (address + PMD_SIZE) & PMD_MASK;
+@@ -596,6 +603,11 @@
+ might_sleep();
+
+ if (is_vm_hugetlb_page(vma)) {
++ static int x;
++ if (x < 10) {
++ x++;
++ dump_stack();
++ }
+ zap_hugepage_range(vma, address, size);
+ return;
+ }
+@@ -1398,6 +1410,7 @@
+ spin_unlock(&mm->page_table_lock);
+
+ if (vma->vm_file) {
++ WARN_ON(!atomic_read(&vma->vm_file->f_count));
+ mapping = vma->vm_file->f_dentry->d_inode->i_mapping;
+ sequence = atomic_read(&mapping->truncate_count);
+ }
+@@ -1655,6 +1668,8 @@
+ len = (end+PAGE_SIZE-1)/PAGE_SIZE-addr/PAGE_SIZE;
+ ret = get_user_pages(current, current->mm, addr,
+ len, write, 0, NULL, NULL);
++ if (ret < 0)
++ return ret;
+ return ret == len ? 0 : -1;
+ }
+
+Index: linux-2.6.0-test5/mm/mlock.c
+===================================================================
+--- linux-2.6.0-test5.orig/mm/mlock.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/mm/mlock.c 2003-09-27 11:38:41.445227752 +0800
+@@ -13,21 +13,24 @@
+ unsigned long start, unsigned long end, unsigned int newflags)
+ {
+ struct mm_struct * mm = vma->vm_mm;
+- int pages, error;
++ int pages;
++ int ret = 0;
+
+ if (newflags == vma->vm_flags)
+- return 0;
++ goto out;
+
+ if (start != vma->vm_start) {
+- error = split_vma(mm, vma, start, 1);
+- if (error)
+- return -EAGAIN;
++ if (split_vma(mm, vma, start, 1)) {
++ ret = -EAGAIN;
++ goto out;
++ }
+ }
+
+ if (end != vma->vm_end) {
+- error = split_vma(mm, vma, end, 0);
+- if (error)
+- return -EAGAIN;
++ if (split_vma(mm, vma, end, 0)) {
++ ret = -EAGAIN;
++ goto out;
++ }
+ }
+
+ spin_lock(&mm->page_table_lock);
+@@ -40,11 +43,12 @@
+ pages = (end - start) >> PAGE_SHIFT;
+ if (newflags & VM_LOCKED) {
+ pages = -pages;
+- make_pages_present(start, end);
++ ret = make_pages_present(start, end);
+ }
+
+ vma->vm_mm->locked_vm -= pages;
+- return 0;
++out:
++ return ret;
+ }
+
+ static int do_mlock(unsigned long start, size_t len, int on)
+Index: linux-2.6.0-test5/mm/page_alloc.c
+===================================================================
+--- linux-2.6.0-test5.orig/mm/page_alloc.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/mm/page_alloc.c 2003-09-27 11:38:41.455226232 +0800
+@@ -50,7 +50,7 @@
+ * Used by page_zone() to look up the address of the struct zone whose
+ * id is encoded in the upper bits of page->flags
+ */
+-struct zone *zone_table[MAX_NR_ZONES*MAX_NR_NODES];
++struct zone *zone_table[MAX_NR_ZONES*MAX_NUMNODES];
+ EXPORT_SYMBOL(zone_table);
+
+ static char *zone_names[MAX_NR_ZONES] = { "DMA", "Normal", "HighMem" };
+@@ -520,7 +520,8 @@
+ *
+ * Herein lies the mysterious "incremental min". That's the
+ *
+- * min += z->pages_low;
++ * local_low = z->pages_low;
++ * min += local_low;
+ *
+ * thing. The intent here is to provide additional protection to low zones for
+ * allocation requests which _could_ use higher zones. So a GFP_HIGHMEM
+@@ -538,10 +539,11 @@
+ unsigned long min;
+ struct zone **zones, *classzone;
+ struct page *page;
++ struct reclaim_state reclaim_state;
++ struct task_struct *p = current;
+ int i;
+ int cold;
+ int do_retry;
+- struct reclaim_state reclaim_state;
+
+ might_sleep_if(wait);
+
+@@ -558,8 +560,17 @@
+ min = 1UL << order;
+ for (i = 0; zones[i] != NULL; i++) {
+ struct zone *z = zones[i];
++ unsigned long local_low;
++
++ /*
++ * This is the fabled 'incremental min'. We let real-time tasks
++ * dip their real-time paws a little deeper into reserves.
++ */
++ local_low = z->pages_low;
++ if (rt_task(p))
++ local_low >>= 1;
++ min += local_low;
+
+- min += z->pages_low;
+ if (z->free_pages >= min ||
+ (!wait && z->free_pages >= z->pages_high)) {
+ page = buffered_rmqueue(z, order, cold);
+@@ -582,6 +593,8 @@
+ local_min = z->pages_min;
+ if (gfp_mask & __GFP_HIGH)
+ local_min >>= 2;
++ if (rt_task(p))
++ local_min >>= 1;
+ min += local_min;
+ if (z->free_pages >= min ||
+ (!wait && z->free_pages >= z->pages_high)) {
+@@ -595,7 +608,7 @@
+ /* here we're in the low on memory slow path */
+
+ rebalance:
+- if ((current->flags & (PF_MEMALLOC | PF_MEMDIE)) && !in_interrupt()) {
++ if ((p->flags & (PF_MEMALLOC | PF_MEMDIE)) && !in_interrupt()) {
+ /* go through the zonelist yet again, ignoring mins */
+ for (i = 0; zones[i] != NULL; i++) {
+ struct zone *z = zones[i];
+@@ -611,14 +624,14 @@
+ if (!wait)
+ goto nopage;
+
+- current->flags |= PF_MEMALLOC;
++ p->flags |= PF_MEMALLOC;
+ reclaim_state.reclaimed_slab = 0;
+- current->reclaim_state = &reclaim_state;
++ p->reclaim_state = &reclaim_state;
+
+ try_to_free_pages(classzone, gfp_mask, order);
+
+- current->reclaim_state = NULL;
+- current->flags &= ~PF_MEMALLOC;
++ p->reclaim_state = NULL;
++ p->flags &= ~PF_MEMALLOC;
+
+ /* go through the zonelist yet one more time */
+ min = 1UL << order;
+@@ -658,7 +671,7 @@
+ if (!(gfp_mask & __GFP_NOWARN)) {
+ printk("%s: page allocation failure."
+ " order:%d, mode:0x%x\n",
+- current->comm, order, gfp_mask);
++ p->comm, order, gfp_mask);
+ }
+ return NULL;
+ got_pg:
+Index: linux-2.6.0-test5/mm/page-writeback.c
+===================================================================
+--- linux-2.6.0-test5.orig/mm/page-writeback.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/mm/page-writeback.c 2003-09-27 11:38:41.460225472 +0800
+@@ -28,6 +28,7 @@
+ #include <linux/smp.h>
+ #include <linux/sysctl.h>
+ #include <linux/cpu.h>
++#include <linux/pagevec.h>
+
+ /*
+ * The maximum number of pages to writeout in a single bdflush/kupdate
+@@ -111,6 +112,7 @@
+ int unmapped_ratio;
+ long background;
+ long dirty;
++ struct task_struct *tsk;
+
+ get_page_state(ps);
+
+@@ -129,7 +131,8 @@
+
+ background = (background_ratio * total_pages) / 100;
+ dirty = (dirty_ratio * total_pages) / 100;
+- if (current->flags & PF_LESS_THROTTLE) {
++ tsk = current;
++ if (tsk->flags & PF_LESS_THROTTLE || rt_task(tsk)) {
+ background += background / 4;
+ dirty += dirty / 4;
+ }
+@@ -144,7 +147,7 @@
+ * If we're over `background_thresh' then pdflush is woken to perform some
+ * writeout.
+ */
+-void balance_dirty_pages(struct address_space *mapping)
++static int balance_dirty_pages(struct address_space *mapping)
+ {
+ struct page_state ps;
+ long nr_reclaimable;
+@@ -161,6 +164,7 @@
+ .sync_mode = WB_SYNC_NONE,
+ .older_than_this = NULL,
+ .nr_to_write = write_chunk,
++ .nonblocking = !is_sync_wait(current->io_wait)
+ };
+
+ get_dirty_limits(&ps, &background_thresh, &dirty_thresh);
+@@ -187,7 +191,11 @@
+ if (pages_written >= write_chunk)
+ break; /* We've done our duty */
+ }
+- blk_congestion_wait(WRITE, HZ/10);
++ if (-EIOCBRETRY == blk_congestion_wait_wq(WRITE, HZ/10,
++ current->io_wait)) {
++ pr_debug("async blk congestion wait\n");
++ return -EIOCBRETRY;
++ }
+ }
+
+ if (nr_reclaimable + ps.nr_writeback <= dirty_thresh)
+@@ -195,6 +203,8 @@
+
+ if (!writeback_in_progress(bdi) && nr_reclaimable > background_thresh)
+ pdflush_operation(background_writeout, 0);
++
++ return 0;
+ }
+
+ /**
+@@ -210,7 +220,7 @@
+ * decrease the ratelimiting by a lot, to prevent individual processes from
+ * overshooting the limit by (ratelimit_pages) each.
+ */
+-void balance_dirty_pages_ratelimited(struct address_space *mapping)
++int balance_dirty_pages_ratelimited(struct address_space *mapping)
+ {
+ static DEFINE_PER_CPU(int, ratelimits) = 0;
+ long ratelimit;
+@@ -219,13 +229,17 @@
+ if (dirty_exceeded)
+ ratelimit = 8;
+
++ /*
++ * Check the rate limiting. Also, we do not want to throttle real-time
++ * tasks in balance_dirty_pages(). Period.
++ */
+ if (get_cpu_var(ratelimits)++ >= ratelimit) {
+ __get_cpu_var(ratelimits) = 0;
+ put_cpu_var(ratelimits);
+- balance_dirty_pages(mapping);
+- return;
++ return balance_dirty_pages(mapping);
+ }
+ put_cpu_var(ratelimits);
++ return 0;
+ }
+
+ /*
+@@ -560,3 +574,152 @@
+ return 0;
+ }
+ EXPORT_SYMBOL(test_clear_page_dirty);
++
++
++static ssize_t operate_on_page_range(struct address_space *mapping,
++ loff_t pos, size_t count, int (*operator)(struct page *))
++{
++ pgoff_t first = pos >> PAGE_CACHE_SHIFT;
++ pgoff_t last = (pos + count - 1) >> PAGE_CACHE_SHIFT; /* inclusive */
++ pgoff_t next = first, curr = first;
++ struct pagevec pvec;
++ ssize_t ret = 0, bytes = 0;
++ int i, nr;
++
++ if (count == 0)
++ return 0;
++
++ pagevec_init(&pvec, 0);
++ while ((nr = pagevec_lookup(&pvec, mapping, &next,
++ min((pgoff_t)PAGEVEC_SIZE, last - next + 1)))) {
++ for (i = 0; i < pagevec_count(&pvec); i++) {
++ struct page *page = pvec.pages[i];
++
++ curr = page->index;
++ if (page->mapping != mapping) /* truncated ?*/ {
++ curr = next;
++ break;
++ } else {
++ ret = (*operator)(page);
++ if (ret == -EIOCBRETRY)
++ break;
++ if (PageError(page)) {
++ if (!ret)
++ ret = -EIO;
++ } else
++ curr++;
++ }
++ }
++ pagevec_release(&pvec);
++ if ((ret == -EIOCBRETRY) || (next > last))
++ break;
++ }
++ if (!nr)
++ curr = last + 1;
++
++ bytes = (curr << PAGE_CACHE_SHIFT) - pos;
++ if (bytes > count)
++ bytes = count;
++ return (bytes && (!ret || (ret == -EIOCBRETRY))) ? bytes : ret;
++}
++
++static int page_waiter(struct page *page)
++{
++ return wait_on_page_writeback_wq(page, current->io_wait);
++}
++
++static size_t
++wait_on_page_range(struct address_space *mapping, loff_t pos, size_t count)
++{
++ return operate_on_page_range(mapping, pos, count, page_waiter);
++}
++
++static int page_writer(struct page *page)
++{
++ struct writeback_control wbc = {
++ .sync_mode = WB_SYNC_ALL,
++ .nr_to_write = 1,
++ };
++
++ lock_page(page);
++ if (!page->mapping) { /* truncated */
++ unlock_page(page);
++ return 0;
++ }
++ if (!test_clear_page_dirty(page)) {
++ unlock_page(page);
++ return 0;
++ }
++ wait_on_page_writeback(page);
++ return page->mapping->a_ops->writepage(page, &wbc);
++}
++
++static ssize_t
++write_out_page_range(struct address_space *mapping, loff_t pos, size_t count)
++{
++ return operate_on_page_range(mapping, pos, count, page_writer);
++}
++
++/*
++ * Write and wait upon all the pages in the passed range. This is a "data
++ * integrity" operation. It waits upon in-flight writeout before starting and
++ * waiting upon new writeout. If there was an IO error, return it.
++ *
++ * We need to re-take i_sem during the generic_osync_inode list walk because
++ * it is otherwise livelockable.
++ */
++ssize_t sync_page_range(struct inode *inode, struct address_space *mapping,
++ loff_t pos, size_t count)
++{
++ int ret = 0;
++
++ if (in_aio()) {
++ /* Already issued writeouts for this iocb ? */
++ if (kiocbTrySync(io_wait_to_kiocb(current->io_wait)))
++ goto do_wait; /* just need to check if done */
++ }
++ if (!mapping->a_ops->writepage)
++ return 0;
++ if (mapping->backing_dev_info->memory_backed)
++ return 0;
++ ret = write_out_page_range(mapping, pos, count);
++ if (ret >= 0) {
++ down(&inode->i_sem);
++ ret = generic_osync_inode(inode, OSYNC_METADATA);
++ up(&inode->i_sem);
++ }
++do_wait:
++ if (ret >= 0)
++ ret = wait_on_page_range(mapping, pos, count);
++ return ret;
++}
++
++/*
++ * It is really better to use sync_page_range, rather than call
++ * sync_page_range_nolock while holding i_sem, if you don't
++ * want to block parallel O_SYNC writes until the pages in this
++ * range are written out.
++ */
++ssize_t sync_page_range_nolock(struct inode *inode, struct address_space
++ *mapping, loff_t pos, size_t count)
++{
++ ssize_t ret = 0;
++
++ if (in_aio()) {
++ /* Already issued writeouts for this iocb ? */
++ if (kiocbTrySync(io_wait_to_kiocb(current->io_wait)))
++ goto do_wait; /* just need to check if done */
++ }
++ if (!mapping->a_ops->writepage)
++ return 0;
++ if (mapping->backing_dev_info->memory_backed)
++ return 0;
++ ret = write_out_page_range(mapping, pos, count);
++ if (ret >= 0) {
++ ret = generic_osync_inode(inode, OSYNC_METADATA);
++ }
++do_wait:
++ if (ret >= 0)
++ ret = wait_on_page_range(mapping, pos, count);
++ return ret;
++}
+Index: linux-2.6.0-test5/mm/pdflush.c
+===================================================================
+--- linux-2.6.0-test5.orig/mm/pdflush.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/mm/pdflush.c 2003-09-27 11:38:41.462225168 +0800
+@@ -84,6 +84,8 @@
+ unsigned long when_i_went_to_sleep;
+ };
+
++static int wakeup_count = 100;
++
+ static int __pdflush(struct pdflush_work *my_work)
+ {
+ daemonize("pdflush");
+@@ -112,7 +114,10 @@
+
+ spin_lock_irq(&pdflush_lock);
+ if (!list_empty(&my_work->list)) {
+- printk("pdflush: bogus wakeup!\n");
++ if (wakeup_count > 0) {
++ wakeup_count--;
++ printk("pdflush: bogus wakeup!\n");
++ }
+ my_work->fn = NULL;
+ continue;
+ }
+@@ -182,6 +187,7 @@
+ {
+ unsigned long flags;
+ int ret = 0;
++ static int poke_count = 0;
+
+ if (fn == NULL)
+ BUG(); /* Hard to diagnose if it's deferred */
+@@ -190,9 +196,19 @@
+ if (list_empty(&pdflush_list)) {
+ spin_unlock_irqrestore(&pdflush_lock, flags);
+ ret = -1;
++ if (wakeup_count < 100 && poke_count < 10) {
++ printk("%s: no threads\n", __FUNCTION__);
++ dump_stack();
++ poke_count++;
++ }
+ } else {
+ struct pdflush_work *pdf;
+
++ if (wakeup_count < 100 && poke_count < 10) {
++ printk("%s: found a thread\n", __FUNCTION__);
++ dump_stack();
++ poke_count++;
++ }
+ pdf = list_entry(pdflush_list.next, struct pdflush_work, list);
+ list_del_init(&pdf->list);
+ if (list_empty(&pdflush_list))
+Index: linux-2.6.0-test5/mm/shmem.c
+===================================================================
+--- linux-2.6.0-test5.orig/mm/shmem.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/mm/shmem.c 2003-09-27 11:38:41.474223344 +0800
+@@ -984,7 +984,22 @@
+ page_cache_release(page);
+ return err;
+ }
++ } else if (nonblock) {
++ /*
++ * If a nonlinear mapping then store the file page
++ * offset in the pte.
++ */
++ unsigned long pgidx;
++ pgidx = (addr - vma->vm_start) >> PAGE_SHIFT;
++ pgidx += vma->vm_pgoff;
++ pgidx >>= PAGE_CACHE_SHIFT - PAGE_SHIFT;
++ if (pgoff != pgidx) {
++ err = install_file_pte(mm, vma, addr, pgoff, prot);
++ if (err)
++ return err;
++ }
+ }
++
+ len -= PAGE_SIZE;
+ addr += PAGE_SIZE;
+ pgoff++;
+Index: linux-2.6.0-test5/mm/slab.c
+===================================================================
+--- linux-2.6.0-test5.orig/mm/slab.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/mm/slab.c 2003-09-27 11:38:41.495220152 +0800
+@@ -153,8 +153,9 @@
+ * is less than 512 (PAGE_SIZE<<3), but greater than 256.
+ */
+
+-#define BUFCTL_END 0xffffFFFF
+-#define SLAB_LIMIT 0xffffFFFE
++#define BUFCTL_END 0xffffFFFF
++#define BUFCTL_FREE 0xffffFFFE
++#define SLAB_LIMIT 0xffffFFFD
+ typedef unsigned int kmem_bufctl_t;
+
+ /* Max number of objs-per-slab for caches which use off-slab slabs.
+@@ -249,7 +250,7 @@
+ unsigned int limit;
+ /* 2) touched by every alloc & free from the backend */
+ struct kmem_list3 lists;
+- /* NUMA: kmem_3list_t *nodelists[NR_NODES] */
++ /* NUMA: kmem_3list_t *nodelists[MAX_NUMNODES] */
+ unsigned int objsize;
+ unsigned int flags; /* constant flags */
+ unsigned int num; /* # of objs per slab */
+@@ -293,6 +294,10 @@
+ atomic_t freehit;
+ atomic_t freemiss;
+ #endif
++#if DEBUG
++ int dbghead;
++ int reallen;
++#endif
+ };
+
+ #define CFLGS_OFF_SLAB (0x80000000UL)
+@@ -356,32 +361,68 @@
+ #define POISON_AFTER 0x6b /* for use-after-free poisoning */
+ #define POISON_END 0xa5 /* end-byte of poisoning */
+
++/* memory layout of objects:
++ * 0 : objp
++ * 0 .. cachep->dbghead - BYTES_PER_WORD - 1: padding. This ensures that
++ * the end of an object is aligned with the end of the real
++ * allocation. Catches writes behind the end of the allocation.
++ * cachep->dbghead - BYTES_PER_WORD .. cachep->dbghead - 1:
++ * redzone word.
++ * cachep->dbghead: The real object.
++ * cachep->objsize - 2* BYTES_PER_WORD: redzone word [BYTES_PER_WORD long]
++ * cachep->objsize - 1* BYTES_PER_WORD: last caller address [BYTES_PER_WORD long]
++ */
+ static inline int obj_dbghead(kmem_cache_t *cachep)
+ {
+- if (cachep->flags & SLAB_RED_ZONE)
+- return BYTES_PER_WORD;
+- return 0;
++ return cachep->dbghead;
+ }
+
+-static inline int obj_dbglen(kmem_cache_t *cachep)
++static inline int obj_reallen(kmem_cache_t *cachep)
+ {
+- int len = 0;
++ return cachep->reallen;
++}
+
+- if (cachep->flags & SLAB_RED_ZONE) {
+- len += 2*BYTES_PER_WORD;
+- }
+- if (cachep->flags & SLAB_STORE_USER) {
+- len += BYTES_PER_WORD;
+- }
+- return len;
++static unsigned long *dbg_redzone1(kmem_cache_t *cachep, void *objp)
++{
++ BUG_ON(!(cachep->flags & SLAB_RED_ZONE));
++ return (unsigned long*) (objp+obj_dbghead(cachep)-BYTES_PER_WORD);
++}
++
++static unsigned long *dbg_redzone2(kmem_cache_t *cachep, void *objp)
++{
++ BUG_ON(!(cachep->flags & SLAB_RED_ZONE));
++ if (cachep->flags & SLAB_STORE_USER)
++ return (unsigned long*) (objp+cachep->objsize-2*BYTES_PER_WORD);
++ return (unsigned long*) (objp+cachep->objsize-BYTES_PER_WORD);
++}
++
++static void **dbg_userword(kmem_cache_t *cachep, void *objp)
++{
++ BUG_ON(!(cachep->flags & SLAB_STORE_USER));
++ return (void**)(objp+cachep->objsize-BYTES_PER_WORD);
+ }
+ #else
+ static inline int obj_dbghead(kmem_cache_t *cachep)
+ {
+ return 0;
+ }
+-static inline int obj_dbglen(kmem_cache_t *cachep)
++static inline int obj_reallen(kmem_cache_t *cachep)
++{
++ return cachep->objsize;
++}
++static inline unsigned long *dbg_redzone1(kmem_cache_t *cachep, void *objp)
++{
++ BUG();
++ return 0;
++}
++static inline unsigned long *dbg_redzone2(kmem_cache_t *cachep, void *objp)
+ {
++ BUG();
++ return 0;
++}
++static inline void **dbg_userword(kmem_cache_t *cachep, void *objp)
++{
++ BUG();
+ return 0;
+ }
+ #endif
+@@ -804,7 +845,7 @@
+ #ifdef CONFIG_DEBUG_PAGEALLOC
+ static void store_stackinfo(kmem_cache_t *cachep, unsigned long *addr, unsigned long caller)
+ {
+- int size = cachep->objsize-obj_dbglen(cachep);
++ int size = obj_reallen(cachep);
+
+ addr = (unsigned long *)&((char*)addr)[obj_dbghead(cachep)];
+
+@@ -836,7 +877,7 @@
+
+ static void poison_obj(kmem_cache_t *cachep, void *addr, unsigned char val)
+ {
+- int size = cachep->objsize-obj_dbglen(cachep);
++ int size = obj_reallen(cachep);
+ addr = &((char*)addr)[obj_dbghead(cachep)];
+
+ memset(addr, val, size);
+@@ -858,47 +899,42 @@
+ return NULL;
+ }
+
+-static void check_poison_obj(kmem_cache_t *cachep, void *addr)
++static void check_poison_obj(kmem_cache_t *cachep, void *objp)
+ {
+ void *end;
+- int size = cachep->objsize-obj_dbglen(cachep);
++ void *realobj;
++ int size = obj_reallen(cachep);
+
+- addr = &((char*)addr)[obj_dbghead(cachep)];
++ realobj = objp+obj_dbghead(cachep);
+
+- end = scan_poisoned_obj(addr, size);
++ end = scan_poisoned_obj(realobj, size);
+ if (end) {
+ int s;
+ printk(KERN_ERR "Slab corruption: start=%p, expend=%p, "
+- "problemat=%p\n", addr, addr+size-1, end);
++ "problemat=%p\n", realobj, realobj+size-1, end);
+ if (cachep->flags & SLAB_STORE_USER) {
+- void *pc;
+-
+- if (cachep->flags & SLAB_RED_ZONE)
+- pc = *(void**)(addr+size+BYTES_PER_WORD);
+- else
+- pc = *(void**)(addr+size);
+- printk(KERN_ERR "Last user: [<%p>]", pc);
+- print_symbol("(%s)", (unsigned long)pc);
++ printk(KERN_ERR "Last user: [<%p>]", *dbg_userword(cachep, objp));
++ print_symbol("(%s)", (unsigned long)*dbg_userword(cachep, objp));
+ printk("\n");
+ }
+ printk(KERN_ERR "Data: ");
+ for (s = 0; s < size; s++) {
+- if (((char*)addr)[s] == POISON_BEFORE)
++ if (((char*)realobj)[s] == POISON_BEFORE)
+ printk(".");
+- else if (((char*)addr)[s] == POISON_AFTER)
++ else if (((char*)realobj)[s] == POISON_AFTER)
+ printk("*");
+ else
+- printk("%02X ", ((unsigned char*)addr)[s]);
++ printk("%02X ", ((unsigned char*)realobj)[s]);
+ }
+ printk("\n");
+ printk(KERN_ERR "Next: ");
+ for (; s < size + 32; s++) {
+- if (((char*)addr)[s] == POISON_BEFORE)
++ if (((char*)realobj)[s] == POISON_BEFORE)
+ printk(".");
+- else if (((char*)addr)[s] == POISON_AFTER)
++ else if (((char*)realobj)[s] == POISON_AFTER)
+ printk("*");
+ else
+- printk("%02X ", ((unsigned char*)addr)[s]);
++ printk("%02X ", ((unsigned char*)realobj)[s]);
+ }
+ printk("\n");
+ slab_error(cachep, "object was modified after freeing");
+@@ -916,7 +952,6 @@
+ int i;
+ for (i = 0; i < cachep->num; i++) {
+ void *objp = slabp->s_mem + cachep->objsize * i;
+- int objlen = cachep->objsize;
+
+ if (cachep->flags & SLAB_POISON) {
+ #ifdef CONFIG_DEBUG_PAGEALLOC
+@@ -928,21 +963,16 @@
+ check_poison_obj(cachep, objp);
+ #endif
+ }
+- if (cachep->flags & SLAB_STORE_USER)
+- objlen -= BYTES_PER_WORD;
+-
+ if (cachep->flags & SLAB_RED_ZONE) {
+- if (*((unsigned long*)(objp)) != RED_INACTIVE)
++ if (*dbg_redzone1(cachep, objp) != RED_INACTIVE)
+ slab_error(cachep, "start of a freed object "
+ "was overwritten");
+- if (*((unsigned long*)(objp + objlen - BYTES_PER_WORD))
+- != RED_INACTIVE)
++ if (*dbg_redzone2(cachep, objp) != RED_INACTIVE)
+ slab_error(cachep, "end of a freed object "
+ "was overwritten");
+- objp += BYTES_PER_WORD;
+ }
+ if (cachep->dtor && !(cachep->flags & SLAB_POISON))
+- (cachep->dtor)(objp, cachep, 0);
++ (cachep->dtor)(objp+obj_dbghead(cachep), cachep, 0);
+ }
+ #else
+ if (cachep->dtor) {
+@@ -1013,6 +1043,7 @@
+ BUG();
+
+ #if DEBUG
++ BUG_ON(strchr(name, ' ')); /* It confuses parsers */
+ if ((flags & SLAB_DEBUG_INITIAL) && !ctor) {
+ /* No constructor, but inital state check requested */
+ printk("%sNo con, but init state check requested - %s\n", func_nm, name);
+@@ -1020,10 +1051,6 @@
+ }
+
+ #if FORCED_DEBUG
+-#ifdef CONFIG_DEBUG_PAGEALLOC
+- if (size < PAGE_SIZE-3*BYTES_PER_WORD && size > 128)
+- size = PAGE_SIZE-3*BYTES_PER_WORD;
+-#endif
+ /*
+ * Enable redzoning and last user accounting, except
+ * - for caches with forced alignment: redzoning would violate the
+@@ -1054,6 +1081,9 @@
+ goto opps;
+ memset(cachep, 0, sizeof(kmem_cache_t));
+
++#if DEBUG
++ cachep->reallen = size;
++#endif
+ /* Check that size is in terms of words. This is needed to avoid
+ * unaligned accesses for some archs when redzoning is used, and makes
+ * sure any on-slab bufctl's are also correctly aligned.
+@@ -1071,13 +1101,21 @@
+ * when redzoning.
+ */
+ flags &= ~SLAB_HWCACHE_ALIGN;
+- size += 2*BYTES_PER_WORD; /* words for redzone */
++ /* add space for red zone words */
++ cachep->dbghead += BYTES_PER_WORD;
++ size += 2*BYTES_PER_WORD;
+ }
+ if (flags & SLAB_STORE_USER) {
+ flags &= ~SLAB_HWCACHE_ALIGN;
+- size += BYTES_PER_WORD; /* word for kfree caller address */
++ size += BYTES_PER_WORD; /* add space */
++ }
++#if FORCED_DEBUG && defined(CONFIG_DEBUG_PAGEALLOC)
++ if (size > 128 && cachep->reallen > L1_CACHE_BYTES && size < PAGE_SIZE) {
++ cachep->dbghead += PAGE_SIZE - size;
++ size = PAGE_SIZE;
+ }
+ #endif
++#endif
+ align = BYTES_PER_WORD;
+ if (flags & SLAB_HWCACHE_ALIGN)
+ align = L1_CACHE_BYTES;
+@@ -1140,7 +1178,8 @@
+ cachep = NULL;
+ goto opps;
+ }
+- slab_size = L1_CACHE_ALIGN(cachep->num*sizeof(kmem_bufctl_t)+sizeof(struct slab));
++ slab_size = L1_CACHE_ALIGN(cachep->num*sizeof(kmem_bufctl_t) +
++ sizeof(struct slab));
+
+ /*
+ * If the slab has been placed off-slab, and we have enough space then
+@@ -1184,10 +1223,13 @@
+ * the cache that's used by kmalloc(24), otherwise
+ * the creation of further caches will BUG().
+ */
+- cachep->array[smp_processor_id()] = &initarray_generic.cache;
++ cachep->array[smp_processor_id()] =
++ &initarray_generic.cache;
+ g_cpucache_up = PARTIAL;
+ } else {
+- cachep->array[smp_processor_id()] = kmalloc(sizeof(struct arraycache_init),GFP_KERNEL);
++ cachep->array[smp_processor_id()] =
++ kmalloc(sizeof(struct arraycache_init),
++ GFP_KERNEL);
+ }
+ BUG_ON(!ac_data(cachep));
+ ac_data(cachep)->avail = 0;
+@@ -1201,7 +1243,7 @@
+ }
+
+ cachep->lists.next_reap = jiffies + REAPTIMEOUT_LIST3 +
+- ((unsigned long)cachep)%REAPTIMEOUT_LIST3;
++ ((unsigned long)cachep)%REAPTIMEOUT_LIST3;
+
+ /* Need the semaphore to access the chain. */
+ down(&cache_chain_sem);
+@@ -1214,16 +1256,24 @@
+ list_for_each(p, &cache_chain) {
+ kmem_cache_t *pc = list_entry(p, kmem_cache_t, next);
+ char tmp;
+- /* This happens when the module gets unloaded and doesn't
+- destroy its slab cache and noone else reuses the vmalloc
+- area of the module. Print a warning. */
+- if (__get_user(tmp,pc->name)) {
+- printk("SLAB: cache with size %d has lost its name\n",
+- pc->objsize);
++
++ /*
++ * This happens when the module gets unloaded and
++ * doesn't destroy its slab cache and noone else reuses
++ * the vmalloc area of the module. Print a warning.
++ */
++#ifdef CONFIG_X86_UACCESS_INDIRECT
++ if (__direct_get_user(tmp,pc->name)) {
++#else
++ if (__get_user(tmp,pc->name)) {
++#endif
++ printk("SLAB: cache with size %d has lost its "
++ "name\n", pc->objsize);
+ continue;
+ }
+ if (!strcmp(pc->name,name)) {
+- printk("kmem_cache_create: duplicate cache %s\n",name);
++ printk("kmem_cache_create: duplicate "
++ "cache %s\n",name);
+ up(&cache_chain_sem);
+ BUG();
+ }
+@@ -1444,20 +1494,15 @@
+ for (i = 0; i < cachep->num; i++) {
+ void* objp = slabp->s_mem+cachep->objsize*i;
+ #if DEBUG
+- int objlen = cachep->objsize;
+ /* need to poison the objs? */
+ if (cachep->flags & SLAB_POISON)
+ poison_obj(cachep, objp, POISON_BEFORE);
+- if (cachep->flags & SLAB_STORE_USER) {
+- objlen -= BYTES_PER_WORD;
+- ((unsigned long*)(objp+objlen))[0] = 0;
+- }
++ if (cachep->flags & SLAB_STORE_USER)
++ *dbg_userword(cachep, objp) = NULL;
+
+ if (cachep->flags & SLAB_RED_ZONE) {
+- *((unsigned long*)(objp)) = RED_INACTIVE;
+- objp += BYTES_PER_WORD;
+- objlen -= 2* BYTES_PER_WORD;
+- *((unsigned long*)(objp + objlen)) = RED_INACTIVE;
++ *dbg_redzone1(cachep, objp) = RED_INACTIVE;
++ *dbg_redzone2(cachep, objp) = RED_INACTIVE;
+ }
+ /*
+ * Constructors are not allowed to allocate memory from
+@@ -1465,14 +1510,13 @@
+ * Otherwise, deadlock. They must also be threaded.
+ */
+ if (cachep->ctor && !(cachep->flags & SLAB_POISON))
+- cachep->ctor(objp, cachep, ctor_flags);
++ cachep->ctor(objp+obj_dbghead(cachep), cachep, ctor_flags);
+
+ if (cachep->flags & SLAB_RED_ZONE) {
+- if (*((unsigned long*)(objp + objlen)) != RED_INACTIVE)
++ if (*dbg_redzone2(cachep, objp) != RED_INACTIVE)
+ slab_error(cachep, "constructor overwrote the"
+ " end of an object");
+- objp -= BYTES_PER_WORD;
+- if (*((unsigned long*)(objp)) != RED_INACTIVE)
++ if (*dbg_redzone1(cachep, objp) != RED_INACTIVE)
+ slab_error(cachep, "constructor overwrote the"
+ " start of an object");
+ }
+@@ -1623,9 +1667,9 @@
+ #if DEBUG
+ struct page *page;
+ unsigned int objnr;
+- int objlen = cachep->objsize;
+ struct slab *slabp;
+
++ objp -= obj_dbghead(cachep);
+ kfree_debugcheck(objp);
+ page = virt_to_page(objp);
+
+@@ -1638,21 +1682,18 @@
+ }
+ slabp = GET_PAGE_SLAB(page);
+
+- if (cachep->flags & SLAB_STORE_USER) {
+- objlen -= BYTES_PER_WORD;
+- }
+ if (cachep->flags & SLAB_RED_ZONE) {
+- objp -= BYTES_PER_WORD;
+- if (xchg((unsigned long *)objp, RED_INACTIVE) != RED_ACTIVE)
+- slab_error(cachep, "double free, or memory before"
++ if (*dbg_redzone1(cachep, objp) != RED_ACTIVE || *dbg_redzone2(cachep, objp) != RED_ACTIVE) {
++ slab_error(cachep, "double free, or memory outside"
+ " object was overwritten");
+- if (xchg((unsigned long *)(objp+objlen-BYTES_PER_WORD), RED_INACTIVE) != RED_ACTIVE)
+- slab_error(cachep, "double free, or memory after "
+- " object was overwritten");
+- }
+- if (cachep->flags & SLAB_STORE_USER) {
+- *((void**)(objp+objlen)) = caller;
++ printk(KERN_ERR "%p: redzone 1: 0x%lx, redzone 2: 0x%lx.\n",
++ objp, *dbg_redzone1(cachep, objp), *dbg_redzone2(cachep, objp));
++ }
++ *dbg_redzone1(cachep, objp) = RED_INACTIVE;
++ *dbg_redzone2(cachep, objp) = RED_INACTIVE;
+ }
++ if (cachep->flags & SLAB_STORE_USER)
++ *dbg_userword(cachep, objp) = caller;
+
+ objnr = (objp-slabp->s_mem)/cachep->objsize;
+
+@@ -1699,40 +1740,23 @@
+ /* Check slab's freelist to see if this obj is there. */
+ for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) {
+ entries++;
+- BUG_ON(entries > cachep->num);
+- BUG_ON(i < 0 || i >= cachep->num);
++ if (entries > cachep->num || i < 0 || i >= cachep->num)
++ goto bad;
+ }
+- BUG_ON(entries != cachep->num - slabp->inuse);
+-#endif
+-}
+-
+-static inline void * cache_alloc_one_tail (kmem_cache_t *cachep,
+- struct slab *slabp)
+-{
+- void *objp;
+-
+- check_spinlock_acquired(cachep);
+-
+- STATS_INC_ALLOCED(cachep);
+- STATS_INC_ACTIVE(cachep);
+- STATS_SET_HIGH(cachep);
+-
+- /* get obj pointer */
+- slabp->inuse++;
+- objp = slabp->s_mem + slabp->free*cachep->objsize;
+- slabp->free=slab_bufctl(slabp)[slabp->free];
+-
+- return objp;
+-}
+-
+-static inline void cache_alloc_listfixup(struct kmem_list3 *l3, struct slab *slabp)
+-{
+- list_del(&slabp->list);
+- if (slabp->free == BUFCTL_END) {
+- list_add(&slabp->list, &l3->slabs_full);
+- } else {
+- list_add(&slabp->list, &l3->slabs_partial);
++ if (entries != cachep->num - slabp->inuse) {
++ int i;
++bad:
++ printk(KERN_ERR "slab: Internal list corruption detected in cache '%s'(%d), slabp %p(%d). Hexdump:\n",
++ cachep->name, cachep->num, slabp, slabp->inuse);
++ for (i=0;i<sizeof(slabp)+cachep->num*sizeof(kmem_bufctl_t);i++) {
++ if ((i%16)==0)
++ printk("\n%03x:", i);
++ printk(" %02x", ((unsigned char*)slabp)[i]);
++ }
++ printk("\n");
++ BUG();
+ }
++#endif
+ }
+
+ static void* cache_alloc_refill(kmem_cache_t* cachep, int flags)
+@@ -1783,11 +1807,31 @@
+
+ slabp = list_entry(entry, struct slab, list);
+ check_slabp(cachep, slabp);
+- while (slabp->inuse < cachep->num && batchcount--)
+- ac_entry(ac)[ac->avail++] =
+- cache_alloc_one_tail(cachep, slabp);
++ check_spinlock_acquired(cachep);
++ while (slabp->inuse < cachep->num && batchcount--) {
++ kmem_bufctl_t next;
++ STATS_INC_ALLOCED(cachep);
++ STATS_INC_ACTIVE(cachep);
++ STATS_SET_HIGH(cachep);
++
++ /* get obj pointer */
++ ac_entry(ac)[ac->avail++] = slabp->s_mem + slabp->free*cachep->objsize;
++
++ slabp->inuse++;
++ next = slab_bufctl(slabp)[slabp->free];
++#if DEBUG
++ slab_bufctl(slabp)[slabp->free] = BUFCTL_FREE;
++#endif
++ slabp->free = next;
++ }
+ check_slabp(cachep, slabp);
+- cache_alloc_listfixup(l3, slabp);
++
++ /* move slabp to correct slabp list: */
++ list_del(&slabp->list);
++ if (slabp->free == BUFCTL_END)
++ list_add(&slabp->list, &l3->slabs_full);
++ else
++ list_add(&slabp->list, &l3->slabs_partial);
+ }
+
+ must_grow:
+@@ -1825,8 +1869,6 @@
+ unsigned long flags, void *objp, void *caller)
+ {
+ #if DEBUG
+- int objlen = cachep->objsize;
+-
+ if (!objp)
+ return objp;
+ if (cachep->flags & SLAB_POISON) {
+@@ -1840,24 +1882,20 @@
+ #endif
+ poison_obj(cachep, objp, POISON_BEFORE);
+ }
+- if (cachep->flags & SLAB_STORE_USER) {
+- objlen -= BYTES_PER_WORD;
+- *((void **)(objp+objlen)) = caller;
+- }
++ if (cachep->flags & SLAB_STORE_USER)
++ *dbg_userword(cachep, objp) = caller;
+
+ if (cachep->flags & SLAB_RED_ZONE) {
+- /* Set alloc red-zone, and check old one. */
+- if (xchg((unsigned long *)objp, RED_ACTIVE) != RED_INACTIVE) {
+- slab_error(cachep, "memory before object was "
+- "overwritten");
+- }
+- if (xchg((unsigned long *)(objp+objlen - BYTES_PER_WORD),
+- RED_ACTIVE) != RED_INACTIVE) {
+- slab_error(cachep, "memory after object was "
+- "overwritten");
++ if (*dbg_redzone1(cachep, objp) != RED_INACTIVE || *dbg_redzone2(cachep, objp) != RED_INACTIVE) {
++ slab_error(cachep, "double free, or memory outside"
++ " object was overwritten");
++ printk(KERN_ERR "%p: redzone 1: 0x%lx, redzone 2: 0x%lx.\n",
++ objp, *dbg_redzone1(cachep, objp), *dbg_redzone2(cachep, objp));
+ }
+- objp += BYTES_PER_WORD;
++ *dbg_redzone1(cachep, objp) = RED_ACTIVE;
++ *dbg_redzone2(cachep, objp) = RED_ACTIVE;
+ }
++ objp += obj_dbghead(cachep);
+ if (cachep->ctor && cachep->flags & SLAB_POISON) {
+ unsigned long ctor_flags = SLAB_CTOR_CONSTRUCTOR;
+
+@@ -1917,6 +1955,13 @@
+ list_del(&slabp->list);
+ objnr = (objp - slabp->s_mem) / cachep->objsize;
+ check_slabp(cachep, slabp);
++#if DEBUG
++ if (slab_bufctl(slabp)[objnr] != BUFCTL_FREE) {
++ printk(KERN_ERR "slab: double free detected in cache '%s', objp %p.\n",
++ cachep->name, objp);
++ BUG();
++ }
++#endif
+ slab_bufctl(slabp)[objnr] = slabp->free;
+ slabp->free = objnr;
+ STATS_DEC_ACTIVE(cachep);
+@@ -2175,7 +2220,7 @@
+
+ unsigned int kmem_cache_size(kmem_cache_t *cachep)
+ {
+- return cachep->objsize-obj_dbglen(cachep);
++ return obj_reallen(cachep);
+ }
+
+ kmem_cache_t * kmem_find_general_cachep (size_t size, int gfpflags)
+@@ -2763,12 +2808,17 @@
+ if (objnr >= c->num) {
+ printk("Bad obj number.\n");
+ } else {
+- kernel_map_pages(virt_to_page(objp), c->objsize/PAGE_SIZE, 1);
++ kernel_map_pages(virt_to_page(objp),
++ c->objsize/PAGE_SIZE, 1);
+
+- printk("redzone: %lxh/%lxh/%lxh.\n",
+- ((unsigned long*)objp)[0],
+- ((unsigned long*)(objp+c->objsize))[-2],
+- ((unsigned long*)(objp+c->objsize))[-1]);
++ if (c->flags & SLAB_RED_ZONE)
++ printk("redzone: 0x%lx/0x%lx.\n",
++ *dbg_redzone1(c, objp),
++ *dbg_redzone2(c, objp));
++
++ if (c->flags & SLAB_STORE_USER)
++ printk("Last user: %p.\n",
++ *dbg_userword(c, objp));
+ }
+ spin_unlock_irqrestore(&c->spinlock, flags);
+
+Index: linux-2.6.0-test5/mm/swap.c
+===================================================================
+--- linux-2.6.0-test5.orig/mm/swap.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/mm/swap.c 2003-09-27 11:38:41.499219544 +0800
+@@ -339,12 +339,15 @@
+ * The search returns a group of mapping-contiguous pages with ascending
+ * indexes. There may be holes in the indices due to not-present pages.
+ *
+- * pagevec_lookup() returns the number of pages which were found.
++ * pagevec_lookup() returns the number of pages which were found
++ * and also atomically sets the next offset to continue looking up
++ * mapping contiguous pages from (useful when doing a range of
++ * pagevec lookups in chunks of PAGEVEC_SIZE).
+ */
+ unsigned int pagevec_lookup(struct pagevec *pvec, struct address_space *mapping,
+- pgoff_t start, unsigned int nr_pages)
++ pgoff_t *next, unsigned int nr_pages)
+ {
+- pvec->nr = find_get_pages(mapping, start, nr_pages, pvec->pages);
++ pvec->nr = find_get_pages(mapping, next, nr_pages, pvec->pages);
+ return pagevec_count(pvec);
+ }
+
+Index: linux-2.6.0-test5/mm/truncate.c
+===================================================================
+--- linux-2.6.0-test5.orig/mm/truncate.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/mm/truncate.c 2003-09-27 11:38:41.501219240 +0800
+@@ -121,14 +121,10 @@
+
+ pagevec_init(&pvec, 0);
+ next = start;
+- while (pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
++ while (pagevec_lookup(&pvec, mapping, &next, PAGEVEC_SIZE)) {
+ for (i = 0; i < pagevec_count(&pvec); i++) {
+ struct page *page = pvec.pages[i];
+- pgoff_t page_index = page->index;
+
+- if (page_index > next)
+- next = page_index;
+- next++;
+ if (TestSetPageLocked(page))
+ continue;
+ if (PageWriteback(page)) {
+@@ -154,7 +150,7 @@
+
+ next = start;
+ for ( ; ; ) {
+- if (!pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
++ if (!pagevec_lookup(&pvec, mapping, &next, PAGEVEC_SIZE)) {
+ if (next == start)
+ break;
+ next = start;
+@@ -165,9 +161,6 @@
+
+ lock_page(page);
+ wait_on_page_writeback(page);
+- if (page->index > next)
+- next = page->index;
+- next++;
+ truncate_complete_page(mapping, page);
+ unlock_page(page);
+ }
+@@ -198,17 +191,13 @@
+
+ pagevec_init(&pvec, 0);
+ while (next <= end &&
+- pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
++ pagevec_lookup(&pvec, mapping, &next, PAGEVEC_SIZE)) {
+ for (i = 0; i < pagevec_count(&pvec); i++) {
+ struct page *page = pvec.pages[i];
+
+ if (TestSetPageLocked(page)) {
+- next++;
+ continue;
+ }
+- if (page->index > next)
+- next = page->index;
+- next++;
+ if (PageDirty(page) || PageWriteback(page))
+ goto unlock;
+ if (page_mapped(page))
+@@ -245,14 +234,13 @@
+ int i;
+
+ pagevec_init(&pvec, 0);
+- while (pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
++ while (pagevec_lookup(&pvec, mapping, &next, PAGEVEC_SIZE)) {
+ for (i = 0; i < pagevec_count(&pvec); i++) {
+ struct page *page = pvec.pages[i];
+
+ lock_page(page);
+ if (page->mapping == mapping) { /* truncate race? */
+ wait_on_page_writeback(page);
+- next = page->index + 1;
+ if (page_mapped(page))
+ clear_page_dirty(page);
+ else
+Index: linux-2.6.0-test5/mm/usercopy.c
+===================================================================
+--- linux-2.6.0-test5.orig/mm/usercopy.c 2003-09-27 11:38:18.490717368 +0800
++++ linux-2.6.0-test5/mm/usercopy.c 2003-09-27 11:38:41.502219088 +0800
+@@ -0,0 +1,279 @@
++/*
++ * linux/mm/usercopy.c
++ *
++ * (C) Copyright 2003 Ingo Molnar
++ *
++ * Generic implementation of all the user-VM access functions, without
++ * relying on being able to access the VM directly.
++ */
++
++#include <linux/module.h>
++#include <linux/sched.h>
++#include <linux/errno.h>
++#include <linux/mm.h>
++#include <linux/highmem.h>
++#include <linux/pagemap.h>
++#include <linux/smp_lock.h>
++#include <linux/ptrace.h>
++#include <linux/interrupt.h>
++
++#include <asm/pgtable.h>
++#include <asm/uaccess.h>
++#include <asm/atomic_kmap.h>
++
++/*
++ * Get kernel address of the user page and pin it.
++ */
++static inline struct page *pin_page(unsigned long addr, int write)
++{
++ struct mm_struct *mm = current->mm ? : &init_mm;
++ struct page *page = NULL;
++ int ret;
++
++ spin_lock(&mm->page_table_lock);
++ /*
++ * Do a quick atomic lookup first - this is the fastpath.
++ */
++ page = follow_page(mm, addr, write);
++ if (likely(page != NULL)) {
++ if (!PageReserved(page))
++ get_page(page);
++ spin_unlock(&mm->page_table_lock);
++ return page;
++ }
++
++ /*
++ * No luck - bad address or need to fault in the page:
++ */
++ spin_unlock(&mm->page_table_lock);
++
++ /*
++ * In the context of filemap_copy_from_user(), we are not allowed
++ * to sleep. We must fail this usercopy attempt and allow
++ * filemap_copy_from_user() to recover: drop its atomic kmap and use
++ * a sleeping kmap instead.
++ */
++ if (in_atomic())
++ return NULL;
++
++ down_read(&mm->mmap_sem);
++ ret = get_user_pages(current, mm, addr, 1, write, 0, &page, NULL);
++ up_read(&mm->mmap_sem);
++ if (ret <= 0)
++ return NULL;
++ return page;
++}
++
++static inline void unpin_page(struct page *page)
++{
++ put_page(page);
++}
++
++/*
++ * Access another process' address space.
++ * Source/target buffer must be kernel space,
++ * Do not walk the page table directly, use get_user_pages
++ */
++static int rw_vm(unsigned long addr, void *buf, int len, int write)
++{
++ if (!len)
++ return 0;
++
++ /* ignore errors, just check how much was sucessfully transfered */
++ while (len) {
++ struct page *page = NULL;
++ int bytes, offset;
++ void *maddr;
++
++ page = pin_page(addr, write);
++ if (!page)
++ break;
++
++ bytes = len;
++ offset = addr & (PAGE_SIZE-1);
++ if (bytes > PAGE_SIZE-offset)
++ bytes = PAGE_SIZE-offset;
++
++ maddr = kmap_atomic(page, KM_USER_COPY);
++
++#define HANDLE_TYPE(type) \
++ case sizeof(type): *(type *)(maddr+offset) = *(type *)(buf); break;
++
++ if (write) {
++ switch (bytes) {
++ HANDLE_TYPE(char);
++ HANDLE_TYPE(int);
++ HANDLE_TYPE(long long);
++ default:
++ memcpy(maddr + offset, buf, bytes);
++ }
++ } else {
++#undef HANDLE_TYPE
++#define HANDLE_TYPE(type) \
++ case sizeof(type): *(type *)(buf) = *(type *)(maddr+offset); break;
++ switch (bytes) {
++ HANDLE_TYPE(char);
++ HANDLE_TYPE(int);
++ HANDLE_TYPE(long long);
++ default:
++ memcpy(buf, maddr + offset, bytes);
++ }
++#undef HANDLE_TYPE
++ }
++ kunmap_atomic(maddr, KM_USER_COPY);
++ unpin_page(page);
++ len -= bytes;
++ buf += bytes;
++ addr += bytes;
++ }
++
++ return len;
++}
++
++static int str_vm(unsigned long addr, void *buf0, int len, int copy)
++{
++ struct mm_struct *mm = current->mm ? : &init_mm;
++ struct page *page;
++ void *buf = buf0;
++
++ if (!len)
++ return len;
++
++ down_read(&mm->mmap_sem);
++ /* ignore errors, just check how much was sucessfully transfered */
++ while (len) {
++ int bytes, ret, offset, left, copied;
++ char *maddr;
++
++ ret = get_user_pages(current, mm, addr, 1, copy == 2, 0, &page, NULL);
++ if (ret <= 0) {
++ up_read(&mm->mmap_sem);
++ return -EFAULT;
++ }
++
++ bytes = len;
++ offset = addr & (PAGE_SIZE-1);
++ if (bytes > PAGE_SIZE-offset)
++ bytes = PAGE_SIZE-offset;
++
++ maddr = kmap_atomic(page, KM_USER_COPY);
++ if (copy == 2) {
++ memset(maddr + offset, 0, bytes);
++ copied = bytes;
++ left = 0;
++ } else if (copy == 1) {
++ left = strncpy_count(buf, maddr + offset, bytes);
++ copied = bytes - left;
++ } else {
++ copied = strnlen(maddr + offset, bytes);
++ left = bytes - copied;
++ }
++ BUG_ON(bytes < 0 || copied < 0);
++ kunmap_atomic(maddr, KM_USER_COPY);
++ page_cache_release(page);
++ len -= copied;
++ buf += copied;
++ addr += copied;
++ if (left)
++ break;
++ }
++ up_read(&mm->mmap_sem);
++
++ return len;
++}
++
++/*
++ * Copies memory from userspace (ptr) into kernelspace (val).
++ *
++ * returns # of bytes not copied.
++ */
++int get_user_size(unsigned int size, void *val, const void *ptr)
++{
++ int ret;
++
++ if (unlikely(segment_eq(get_fs(), KERNEL_DS))) {
++ __direct_copy_from_user(val, ptr, size);
++ return 0;
++ }
++ ret = rw_vm((unsigned long)ptr, val, size, 0);
++ if (ret)
++ /*
++ * Zero the rest:
++ */
++ memset(val + size - ret, 0, ret);
++ return ret;
++}
++
++/*
++ * Copies memory from kernelspace (val) into userspace (ptr).
++ *
++ * returns # of bytes not copied.
++ */
++int put_user_size(unsigned int size, const void *val, void *ptr)
++{
++ if (unlikely(segment_eq(get_fs(), KERNEL_DS))) {
++ __direct_copy_to_user(ptr, val, size);
++ return 0;
++ }
++ return rw_vm((unsigned long)ptr, (void *)val, size, 1);
++}
++
++int copy_str_fromuser_size(unsigned int size, void *val, const void *ptr)
++{
++ int copied, left;
++
++ if (unlikely(segment_eq(get_fs(), KERNEL_DS))) {
++ left = strncpy_count(val, ptr, size);
++ copied = size - left;
++ BUG_ON(copied < 0);
++
++ return copied;
++ }
++ left = str_vm((unsigned long)ptr, val, size, 1);
++ if (left < 0)
++ return left;
++ copied = size - left;
++ BUG_ON(copied < 0);
++
++ return copied;
++}
++
++int strlen_fromuser_size(unsigned int size, const void *ptr)
++{
++ int copied, left;
++
++ if (unlikely(segment_eq(get_fs(), KERNEL_DS))) {
++ copied = strnlen(ptr, size) + 1;
++ BUG_ON(copied < 0);
++
++ return copied;
++ }
++ left = str_vm((unsigned long)ptr, NULL, size, 0);
++ if (left < 0)
++ return 0;
++ copied = size - left + 1;
++ BUG_ON(copied < 0);
++
++ return copied;
++}
++
++int zero_user_size(unsigned int size, void *ptr)
++{
++ int left;
++
++ if (unlikely(segment_eq(get_fs(), KERNEL_DS))) {
++ memset(ptr, 0, size);
++ return 0;
++ }
++ left = str_vm((unsigned long)ptr, NULL, size, 2);
++ if (left < 0)
++ return size;
++ return left;
++}
++
++EXPORT_SYMBOL(get_user_size);
++EXPORT_SYMBOL(put_user_size);
++EXPORT_SYMBOL(zero_user_size);
++EXPORT_SYMBOL(copy_str_fromuser_size);
++EXPORT_SYMBOL(strlen_fromuser_size);
++
+Index: linux-2.6.0-test5/mm/vmalloc.c
+===================================================================
+--- linux-2.6.0-test5.orig/mm/vmalloc.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/mm/vmalloc.c 2003-09-27 11:38:41.506218480 +0800
+@@ -135,23 +135,23 @@
+
+ void unmap_vm_area(struct vm_struct *area)
+ {
+- unsigned long address = VMALLOC_VMADDR(area->addr);
++ unsigned long address = (unsigned long) area->addr;
+ unsigned long end = (address + area->size);
+ pgd_t *dir;
+
+ dir = pgd_offset_k(address);
+- flush_cache_all();
++ flush_cache_vunmap(address, end);
+ do {
+ unmap_area_pmd(dir, address, end - address);
+ address = (address + PGDIR_SIZE) & PGDIR_MASK;
+ dir++;
+ } while (address && (address < end));
+- flush_tlb_kernel_range(VMALLOC_VMADDR(area->addr), end);
++ flush_tlb_kernel_range((unsigned long) area->addr, end);
+ }
+
+ int map_vm_area(struct vm_struct *area, pgprot_t prot, struct page ***pages)
+ {
+- unsigned long address = VMALLOC_VMADDR(area->addr);
++ unsigned long address = (unsigned long) area->addr;
+ unsigned long end = address + (area->size-PAGE_SIZE);
+ pgd_t *dir;
+ int err = 0;
+@@ -174,7 +174,7 @@
+ } while (address && (address < end));
+
+ spin_unlock(&init_mm.page_table_lock);
+- flush_cache_all();
++ flush_cache_vmap((unsigned long) area->addr, end);
+ return err;
+ }
+
+Index: linux-2.6.0-test5/net/8021q/vlanproc.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/8021q/vlanproc.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/8021q/vlanproc.c 2003-09-27 11:38:41.509218024 +0800
+@@ -46,10 +46,6 @@
+ static void vlan_seq_stop(struct seq_file *seq, void *);
+ static int vlandev_seq_show(struct seq_file *seq, void *v);
+
+-/* Miscellaneous */
+-#define SEQ_START_TOKEN ((void *) 1)
+-
+-
+ /*
+ * Global Data
+ */
+Index: linux-2.6.0-test5/net/802/p8022.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/802/p8022.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/802/p8022.c 2003-09-27 11:38:41.511217720 +0800
+@@ -22,8 +22,8 @@
+ #include <linux/mm.h>
+ #include <linux/in.h>
+ #include <linux/init.h>
++#include <net/llc.h>
+ #include <net/p8022.h>
+-#include <net/llc_sap.h>
+
+ static int p8022_request(struct datalink_proto *dl, struct sk_buff *skb,
+ unsigned char *dest)
+Index: linux-2.6.0-test5/net/802/psnap.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/802/psnap.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/802/psnap.c 2003-09-27 11:38:41.512217568 +0800
+@@ -15,9 +15,8 @@
+ #include <linux/netdevice.h>
+ #include <linux/skbuff.h>
+ #include <net/datalink.h>
++#include <net/llc.h>
+ #include <net/psnap.h>
+-#include <net/llc_if.h>
+-#include <net/llc_sap.h>
+ #include <linux/mm.h>
+ #include <linux/in.h>
+ #include <linux/init.h>
+Index: linux-2.6.0-test5/net/802/tr.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/802/tr.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/802/tr.c 2003-09-27 11:38:41.516216960 +0800
+@@ -464,8 +464,6 @@
+ */
+
+ #ifdef CONFIG_PROC_FS
+-/* Magic token to indicate first entry (header line) */
+-#define RIF_PROC_START ((void *)1)
+
+ static struct rif_cache_s *rif_get_idx(loff_t pos)
+ {
+@@ -487,7 +485,7 @@
+ {
+ spin_lock_bh(&rif_lock);
+
+- return *pos ? rif_get_idx(*pos - 1) : RIF_PROC_START;
++ return *pos ? rif_get_idx(*pos - 1) : SEQ_START_TOKEN;
+ }
+
+ static void *rif_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -497,7 +495,7 @@
+
+ ++*pos;
+
+- if (v == RIF_PROC_START) {
++ if (v == SEQ_START_TOKEN) {
+ i = -1;
+ goto scan;
+ }
+@@ -524,7 +522,7 @@
+ int j, rcf_len, segment, brdgnmb;
+ struct rif_cache_s *entry = v;
+
+- if (v == RIF_PROC_START)
++ if (v == SEQ_START_TOKEN)
+ seq_puts(seq,
+ "if TR address TTL rcf routing segments\n");
+ else {
+Index: linux-2.6.0-test5/net/appletalk/aarp.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/appletalk/aarp.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/appletalk/aarp.c 2003-09-27 11:38:41.524215744 +0800
+@@ -941,7 +941,7 @@
+ iter->table = resolved;
+ iter->bucket = 0;
+
+- return *pos ? iter_next(iter, pos) : ((void *)1);
++ return *pos ? iter_next(iter, pos) : SEQ_START_TOKEN;
+ }
+
+ static void *aarp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -952,7 +952,7 @@
+ ++*pos;
+
+ /* first line after header */
+- if (v == ((void *)1))
++ if (v == SEQ_START_TOKEN)
+ entry = iter_next(iter, NULL);
+
+ /* next entry in current bucket */
+@@ -987,7 +987,7 @@
+ struct aarp_entry *entry = v;
+ unsigned long now = jiffies;
+
+- if (v == ((void *)1))
++ if (v == SEQ_START_TOKEN)
+ seq_puts(seq,
+ "Address Interface Hardware Address"
+ " Expires LastSend Retry Status\n");
+Index: linux-2.6.0-test5/net/appletalk/atalk_proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/appletalk/atalk_proc.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/appletalk/atalk_proc.c 2003-09-27 11:38:41.526215440 +0800
+@@ -33,7 +33,7 @@
+ loff_t l = *pos;
+
+ read_lock_bh(&atalk_interfaces_lock);
+- return l ? atalk_get_interface_idx(--l) : (void *)1;
++ return l ? atalk_get_interface_idx(--l) : SEQ_START_TOKEN;
+ }
+
+ static void *atalk_seq_interface_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -41,7 +41,7 @@
+ struct atalk_iface *i;
+
+ ++*pos;
+- if (v == (void *)1) {
++ if (v == SEQ_START_TOKEN) {
+ i = NULL;
+ if (atalk_interfaces)
+ i = atalk_interfaces;
+@@ -62,7 +62,7 @@
+ {
+ struct atalk_iface *iface;
+
+- if (v == (void *)1) {
++ if (v == SEQ_START_TOKEN) {
+ seq_puts(seq, "Interface Address Networks "
+ "Status\n");
+ goto out;
+@@ -92,7 +92,7 @@
+ loff_t l = *pos;
+
+ read_lock_bh(&atalk_routes_lock);
+- return l ? atalk_get_route_idx(--l) : (void *)1;
++ return l ? atalk_get_route_idx(--l) : SEQ_START_TOKEN;
+ }
+
+ static void *atalk_seq_route_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -100,7 +100,7 @@
+ struct atalk_route *r;
+
+ ++*pos;
+- if (v == (void *)1) {
++ if (v == SEQ_START_TOKEN) {
+ r = NULL;
+ if (atalk_routes)
+ r = atalk_routes;
+@@ -121,7 +121,7 @@
+ {
+ struct atalk_route *rt;
+
+- if (v == (void *)1) {
++ if (v == SEQ_START_TOKEN) {
+ seq_puts(seq, "Target Router Flags Dev\n");
+ goto out;
+ }
+@@ -160,7 +160,7 @@
+ loff_t l = *pos;
+
+ read_lock_bh(&atalk_sockets_lock);
+- return l ? atalk_get_socket_idx(--l) : (void *)1;
++ return l ? atalk_get_socket_idx(--l) : SEQ_START_TOKEN;
+ }
+
+ static void *atalk_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -168,7 +168,7 @@
+ struct sock *i;
+
+ ++*pos;
+- if (v == (void *)1) {
++ if (v == SEQ_START_TOKEN) {
+ i = sk_head(&atalk_sockets);
+ goto out;
+ }
+@@ -187,7 +187,7 @@
+ struct sock *s;
+ struct atalk_sock *at;
+
+- if (v == (void *)1) {
++ if (v == SEQ_START_TOKEN) {
+ seq_printf(seq, "Type Local_addr Remote_addr Tx_queue "
+ "Rx_queue St UID\n");
+ goto out;
+Index: linux-2.6.0-test5/net/atm/br2684.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/atm/br2684.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/atm/br2684.c 2003-09-27 11:38:41.532214528 +0800
+@@ -732,9 +732,10 @@
+ #ifdef CONFIG_ATM_BR2684_IPFILTER
+ #define b1(var, byte) ((u8 *) &brvcc->filter.var)[byte]
+ #define bs(var) b1(var, 0), b1(var, 1), b1(var, 2), b1(var, 3)
+- if (brvcc->filter.netmask != 0 && pos-- == 0)
+- return sprintf(buf, " filter=%d.%d.%d.%d/"
+- "%d.%d.%d.%d\n", bs(prefix), bs(netmask));
++ if (brvcc->filter.netmask != 0)
++ seq_printf(seq, " filter=%d.%d.%d.%d/"
++ "%d.%d.%d.%d\n",
++ bs(prefix), bs(netmask));
+ #undef bs
+ #undef b1
+ #endif /* CONFIG_ATM_BR2684_IPFILTER */
+Index: linux-2.6.0-test5/net/atm/clip.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/atm/clip.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/atm/clip.c 2003-09-27 11:38:41.539213464 +0800
+@@ -93,6 +93,7 @@
+ printk(KERN_CRIT "!clip_vcc->entry (clip_vcc %p)\n",clip_vcc);
+ return;
+ }
++ spin_lock_bh(&entry->neigh->dev->xmit_lock); /* block clip_start_xmit() */
+ entry->neigh->used = jiffies;
+ for (walk = &entry->vccs; *walk; walk = &(*walk)->next)
+ if (*walk == clip_vcc) {
+@@ -102,17 +103,20 @@
+ clip_vcc->entry = NULL;
+ if (clip_vcc->xoff)
+ netif_wake_queue(entry->neigh->dev);
+- if (entry->vccs) return;
++ if (entry->vccs)
++ goto out;
+ entry->expires = jiffies-1;
+ /* force resolution or expiration */
+ error = neigh_update(entry->neigh,NULL,NUD_NONE,0,0);
+ if (error)
+ printk(KERN_CRIT "unlink_clip_vcc: "
+ "neigh_update failed with %d\n",error);
+- return;
++ goto out;
+ }
+ printk(KERN_CRIT "ATMARP: unlink_clip_vcc failed (entry %p, vcc "
+ "0x%p)\n",entry,clip_vcc);
++out:
++ spin_unlock_bh(&entry->neigh->dev->xmit_lock);
+ }
+
+
+@@ -189,6 +193,13 @@
+ return 0;
+ }
+
++static const unsigned char llc_oui[] = {
++ 0xaa, /* DSAP: non-ISO */
++ 0xaa, /* SSAP: non-ISO */
++ 0x03, /* Ctrl: Unnumbered Information Command PDU */
++ 0x00, /* OUI: EtherType */
++ 0x00,
++ 0x00 };
+
+ static void clip_push(struct atm_vcc *vcc,struct sk_buff *skb)
+ {
+Index: linux-2.6.0-test5/net/atm/ipcommon.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/atm/ipcommon.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/atm/ipcommon.c 2003-09-27 11:38:41.540213312 +0800
+@@ -22,15 +22,6 @@
+ #endif
+
+
+-const unsigned char llc_oui[] = {
+- 0xaa, /* DSAP: non-ISO */
+- 0xaa, /* SSAP: non-ISO */
+- 0x03, /* Ctrl: Unnumbered Information Command PDU */
+- 0x00, /* OUI: EtherType */
+- 0x00,
+- 0x00 };
+-
+-
+ /*
+ * skb_migrate appends the list at "from" to "to", emptying "from" in the
+ * process. skb_migrate is atomic with respect to all other skb operations on
+@@ -67,5 +58,4 @@
+ }
+
+
+-EXPORT_SYMBOL(llc_oui);
+ EXPORT_SYMBOL(skb_migrate);
+Index: linux-2.6.0-test5/net/atm/proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/atm/proc.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/atm/proc.c 2003-09-27 11:38:41.548212096 +0800
+@@ -1,21 +1,13 @@
+-/* net/atm/proc.c - ATM /proc interface */
+-
+-/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
+-
+-/*
+- * The mechanism used here isn't designed for speed but rather for convenience
+- * of implementation. We only return one entry per read system call, so we can
+- * be reasonably sure not to overrun the page and race conditions may lead to
+- * the addition or omission of some lines but never to any corruption of a
+- * line's internal structure.
++/* net/atm/proc.c - ATM /proc interface
++ *
++ * Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA
+ *
+- * Making the whole thing slightly more efficient is left as an exercise to the
+- * reader. (Suggestions: wrapper which loops to get several entries per system
+- * call; or make --left slightly more clever to avoid O(n^2) characteristics.)
+- * I find it fast enough on my unloaded 266 MHz Pentium 2 :-)
++ * seq_file api usage by romieu@fr.zoreil.com
++ *
++ * Evaluating the efficiency of the whole thing if left as an exercise to
++ * the reader.
+ */
+
+-
+ #include <linux/config.h>
+ #include <linux/module.h> /* for EXPORT_SYMBOL */
+ #include <linux/string.h>
+@@ -24,6 +16,7 @@
+ #include <linux/fs.h>
+ #include <linux/stat.h>
+ #include <linux/proc_fs.h>
++#include <linux/seq_file.h>
+ #include <linux/errno.h>
+ #include <linux/atm.h>
+ #include <linux/atmdev.h>
+@@ -51,119 +44,202 @@
+
+ static ssize_t proc_dev_atm_read(struct file *file,char *buf,size_t count,
+ loff_t *pos);
+-static ssize_t proc_spec_atm_read(struct file *file,char *buf,size_t count,
+- loff_t *pos);
+
+-static struct file_operations proc_dev_atm_operations = {
++static struct file_operations proc_atm_dev_ops = {
+ .owner = THIS_MODULE,
+ .read = proc_dev_atm_read,
+ };
+
+-static struct file_operations proc_spec_atm_operations = {
+- .owner = THIS_MODULE,
+- .read = proc_spec_atm_read,
+-};
+-
+-static void add_stats(char *buf,const char *aal,
++static void add_stats(struct seq_file *seq, const char *aal,
+ const struct k_atm_aal_stats *stats)
+ {
+- sprintf(strchr(buf,0),"%s ( %d %d %d %d %d )",aal,
++ seq_printf(seq, "%s ( %d %d %d %d %d )", aal,
+ atomic_read(&stats->tx),atomic_read(&stats->tx_err),
+ atomic_read(&stats->rx),atomic_read(&stats->rx_err),
+ atomic_read(&stats->rx_drop));
+ }
+
+-
+-static void atm_dev_info(const struct atm_dev *dev,char *buf)
++static void atm_dev_info(struct seq_file *seq, const struct atm_dev *dev)
+ {
+- int off,i;
++ int i;
+
+- off = sprintf(buf,"%3d %-8s",dev->number,dev->type);
++ seq_printf(seq, "%3d %-8s", dev->number, dev->type);
+ for (i = 0; i < ESI_LEN; i++)
+- off += sprintf(buf+off,"%02x",dev->esi[i]);
+- strcat(buf," ");
+- add_stats(buf,"0",&dev->stats.aal0);
+- strcat(buf," ");
+- add_stats(buf,"5",&dev->stats.aal5);
+- sprintf(strchr(buf,0), "\t[%d]", atomic_read(&dev->refcnt));
+- strcat(buf,"\n");
++ seq_printf(seq, "%02x", dev->esi[i]);
++ seq_puts(seq, " ");
++ add_stats(seq, "0", &dev->stats.aal0);
++ seq_puts(seq, " ");
++ add_stats(seq, "5", &dev->stats.aal5);
++ seq_printf(seq, "\t[%d]", atomic_read(&dev->refcnt));
++ seq_putc(seq, '\n');
+ }
+
+-
+ #if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
+
+-
+-static int svc_addr(char *buf,struct sockaddr_atmsvc *addr)
++static void svc_addr(struct seq_file *seq, struct sockaddr_atmsvc *addr)
+ {
+ static int code[] = { 1,2,10,6,1,0 };
+ static int e164[] = { 1,8,4,6,1,0 };
+- int *fields;
+- int len,i,j,pos;
+
+- len = 0;
+ if (*addr->sas_addr.pub) {
+- strcpy(buf,addr->sas_addr.pub);
+- len = strlen(addr->sas_addr.pub);
+- buf += len;
+- if (*addr->sas_addr.prv) {
+- *buf++ = '+';
+- len++;
+- }
++ seq_printf(seq, "%s", addr->sas_addr.pub);
++ if (*addr->sas_addr.prv)
++ seq_putc(seq, '+');
++ } else if (!*addr->sas_addr.prv) {
++ seq_printf(seq, "%s", "(none)");
++ return;
+ }
+- else if (!*addr->sas_addr.prv) {
+- strcpy(buf,"(none)");
+- return strlen(buf);
+- }
+ if (*addr->sas_addr.prv) {
+- len += 44;
+- pos = 0;
+- fields = *addr->sas_addr.prv == ATM_AFI_E164 ? e164 : code;
++ unsigned char *prv = addr->sas_addr.prv;
++ int *fields;
++ int i, j;
++
++ fields = *prv == ATM_AFI_E164 ? e164 : code;
+ for (i = 0; fields[i]; i++) {
+- for (j = fields[i]; j; j--) {
+- sprintf(buf,"%02X",addr->sas_addr.prv[pos++]);
+- buf += 2;
+- }
+- if (fields[i+1]) *buf++ = '.';
++ for (j = fields[i]; j; j--)
++ seq_printf(seq, "%02X", *prv++);
++ if (fields[i+1])
++ seq_putc(seq, '.');
+ }
+ }
+- return len;
+ }
+
+-
+-static void atmarp_info(struct net_device *dev,struct atmarp_entry *entry,
+- struct clip_vcc *clip_vcc,char *buf)
++static void atmarp_info(struct seq_file *seq, struct net_device *dev,
++ struct atmarp_entry *entry, struct clip_vcc *clip_vcc)
+ {
+- unsigned char *ip;
+- int svc,off,ip_len;
++ char buf[17];
++ int svc, off;
+
+ svc = !clip_vcc || clip_vcc->vcc->sk->sk_family == AF_ATMSVC;
+- off = sprintf(buf,"%-6s%-4s%-4s%5ld ",dev->name,svc ? "SVC" : "PVC",
++ seq_printf(seq, "%-6s%-4s%-4s%5ld ", dev->name, svc ? "SVC" : "PVC",
+ !clip_vcc || clip_vcc->encap ? "LLC" : "NULL",
+- (jiffies-(clip_vcc ? clip_vcc->last_use : entry->neigh->used))/
+- HZ);
+- ip = (unsigned char *) &entry->ip;
+- ip_len = sprintf(buf+off,"%d.%d.%d.%d",ip[0],ip[1],ip[2],ip[3]);
+- off += ip_len;
+- while (ip_len++ < 16) buf[off++] = ' ';
+- if (!clip_vcc)
++ (jiffies-(clip_vcc ? clip_vcc->last_use : entry->neigh->used))/HZ);
++
++ off = snprintf(buf, sizeof(buf) - 1, "%d.%d.%d.%d", NIPQUAD(entry->ip));
++ while (off < 16)
++ buf[off++] = ' ';
++ buf[off] = '\0';
++ seq_printf(seq, "%s", buf);
++
++ if (!clip_vcc) {
+ if (time_before(jiffies, entry->expires))
+- strcpy(buf+off,"(resolving)\n");
+- else sprintf(buf+off,"(expired, ref %d)\n",
+- atomic_read(&entry->neigh->refcnt));
+- else if (!svc)
+- sprintf(buf+off,"%d.%d.%d\n",clip_vcc->vcc->dev->number,
+- clip_vcc->vcc->vpi,clip_vcc->vcc->vci);
+- else {
+- off += svc_addr(buf+off,&clip_vcc->vcc->remote);
+- strcpy(buf+off,"\n");
+- }
++ seq_printf(seq, "(resolving)\n");
++ else
++ seq_printf(seq, "(expired, ref %d)\n",
++ atomic_read(&entry->neigh->refcnt));
++ } else if (!svc) {
++ seq_printf(seq, "%d.%d.%d\n", clip_vcc->vcc->dev->number,
++ clip_vcc->vcc->vpi, clip_vcc->vcc->vci);
++ } else {
++ svc_addr(seq, &clip_vcc->vcc->remote);
++ seq_putc(seq, '\n');
++ }
++}
++
++#endif /* CONFIG_ATM_CLIP */
++
++struct vcc_state {
++ struct sock *sk;
++ int family;
++ int clip_info;
++};
++
++static inline int compare_family(struct sock *sk, int family)
++{
++ struct atm_vcc *vcc = atm_sk(sk);
++
++ return !family || (vcc->sk->sk_family == family);
++}
++
++static int __vcc_walk(struct sock **sock, int family, loff_t l)
++{
++ struct sock *sk = *sock;
++
++ if (sk == (void *)1) {
++ sk = hlist_empty(&vcc_sklist) ? NULL : __sk_head(&vcc_sklist);
++ l--;
++ }
++ for (; sk; sk = sk_next(sk)) {
++ l -= compare_family(sk, family);
++ if (l < 0)
++ goto out;
++ }
++ sk = (void *)1;
++out:
++ *sock = sk;
++ return (l < 0);
++}
++
++static inline void *vcc_walk(struct vcc_state *state, loff_t l)
++{
++ return __vcc_walk(&state->sk, state->family, l) ?
++ state : NULL;
++}
++
++static int __vcc_seq_open(struct inode *inode, struct file *file,
++ int family, struct seq_operations *ops)
++{
++ struct vcc_state *state;
++ struct seq_file *seq;
++ int rc = -ENOMEM;
++
++ state = kmalloc(sizeof(*state), GFP_KERNEL);
++ if (!state)
++ goto out;
++
++ rc = seq_open(file, ops);
++ if (rc)
++ goto out_kfree;
++
++ state->family = family;
++ state->clip_info = try_atm_clip_ops();
++
++ seq = file->private_data;
++ seq->private = state;
++out:
++ return rc;
++out_kfree:
++ kfree(state);
++ goto out;
+ }
+
++static int vcc_seq_release(struct inode *inode, struct file *file)
++{
++#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
++ struct seq_file *seq = file->private_data;
++ struct vcc_state *state = seq->private;
+
++ if (state->clip_info)
++ module_put(atm_clip_ops->owner);
+ #endif
++ return seq_release_private(inode, file);
++}
+
++static void *vcc_seq_start(struct seq_file *seq, loff_t *pos)
++{
++ struct vcc_state *state = seq->private;
++ loff_t left = *pos;
+
+-static void pvc_info(struct atm_vcc *vcc, char *buf, int clip_info)
++ read_lock(&vcc_sklist_lock);
++ state->sk = (void *)1;
++ return left ? vcc_walk(state, left) : (void *)1;
++}
++
++static void vcc_seq_stop(struct seq_file *seq, void *v)
++{
++ read_unlock(&vcc_sklist_lock);
++}
++
++static void *vcc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++{
++ struct vcc_state *state = seq->private;
++
++ v = vcc_walk(state, 1);
++ *pos += !!PTR_ERR(v);
++ return v;
++}
++
++static void pvc_info(struct seq_file *seq, struct atm_vcc *vcc, int clip_info)
+ {
+ static const char *class_name[] = { "off","UBR","CBR","VBR","ABR" };
+ static const char *aal_name[] = {
+@@ -171,9 +247,8 @@
+ "???", "5", "???", "???", /* 4- 7 */
+ "???", "???", "???", "???", /* 8-11 */
+ "???", "0", "???", "???"}; /* 12-15 */
+- int off;
+
+- off = sprintf(buf,"%3d %3d %5d %-3s %7d %-5s %7d %-6s",
++ seq_printf(seq, "%3d %3d %5d %-3s %7d %-5s %7d %-6s",
+ vcc->dev->number,vcc->vpi,vcc->vci,
+ vcc->qos.aal >= sizeof(aal_name)/sizeof(aal_name[0]) ? "err" :
+ aal_name[vcc->qos.aal],vcc->qos.rxtp.min_pcr,
+@@ -185,18 +260,14 @@
+ struct net_device *dev;
+
+ dev = clip_vcc->entry ? clip_vcc->entry->neigh->dev : NULL;
+- off += sprintf(buf+off,"CLIP, Itf:%s, Encap:",
++ seq_printf(seq, "CLIP, Itf:%s, Encap:",
+ dev ? dev->name : "none?");
+- if (clip_vcc->encap)
+- off += sprintf(buf+off,"LLC/SNAP");
+- else
+- off += sprintf(buf+off,"None");
++ seq_printf(seq, "%s", clip_vcc->encap ? "LLC/SNAP" : "None");
+ }
+ #endif
+- strcpy(buf+off,"\n");
++ seq_putc(seq, '\n');
+ }
+
+-
+ static const char *vcc_state(struct atm_vcc *vcc)
+ {
+ static const char *map[] = { ATM_VS2TXT_MAP };
+@@ -204,337 +275,592 @@
+ return map[ATM_VF2VS(vcc->flags)];
+ }
+
+-
+-static void vc_info(struct atm_vcc *vcc,char *buf)
++static void vcc_info(struct seq_file *seq, struct atm_vcc *vcc)
+ {
+- char *here;
+-
+- here = buf+sprintf(buf,"%p ",vcc);
+- if (!vcc->dev) here += sprintf(here,"Unassigned ");
+- else here += sprintf(here,"%3d %3d %5d ",vcc->dev->number,vcc->vpi,
+- vcc->vci);
++ seq_printf(seq, "%p ", vcc);
++ if (!vcc->dev)
++ seq_printf(seq, "Unassigned ");
++ else
++ seq_printf(seq, "%3d %3d %5d ", vcc->dev->number, vcc->vpi,
++ vcc->vci);
+ switch (vcc->sk->sk_family) {
+ case AF_ATMPVC:
+- here += sprintf(here,"PVC");
++ seq_printf(seq, "PVC");
+ break;
+ case AF_ATMSVC:
+- here += sprintf(here,"SVC");
++ seq_printf(seq, "SVC");
+ break;
+ default:
+- here += sprintf(here, "%3d", vcc->sk->sk_family);
++ seq_printf(seq, "%3d", vcc->sk->sk_family);
+ }
+- here += sprintf(here," %04lx %5d %7d/%7d %7d/%7d\n",vcc->flags,
+- vcc->sk->sk_err,
+- atomic_read(&vcc->sk->sk_wmem_alloc), vcc->sk->sk_sndbuf,
+- atomic_read(&vcc->sk->sk_rmem_alloc), vcc->sk->sk_rcvbuf);
++ seq_printf(seq, " %04lx %5d %7d/%7d %7d/%7d\n", vcc->flags, vcc->sk->sk_err,
++ atomic_read(&vcc->sk->sk_wmem_alloc),vcc->sk->sk_sndbuf,
++ atomic_read(&vcc->sk->sk_rmem_alloc),vcc->sk->sk_rcvbuf);
+ }
+
+-
+-static void svc_info(struct atm_vcc *vcc,char *buf)
++static void svc_info(struct seq_file *seq, struct atm_vcc *vcc)
+ {
+- char *here;
+- int i;
+-
+ if (!vcc->dev)
+- sprintf(buf,sizeof(void *) == 4 ? "N/A@%p%10s" : "N/A@%p%2s",
+- vcc,"");
+- else sprintf(buf,"%3d %3d %5d ",vcc->dev->number,vcc->vpi,
+- vcc->vci);
+- here = strchr(buf,0);
+- here += sprintf(here,"%-10s ",vcc_state(vcc));
+- here += sprintf(here,"%s%s",vcc->remote.sas_addr.pub,
++ seq_printf(seq, sizeof(void *) == 4 ?
++ "N/A@%p%10s" : "N/A@%p%2s", vcc, "");
++ else
++ seq_printf(seq, "%3d %3d %5d ",
++ vcc->dev->number, vcc->vpi, vcc->vci);
++ seq_printf(seq, "%-10s ", vcc_state(vcc));
++ seq_printf(seq, "%s%s", vcc->remote.sas_addr.pub,
+ *vcc->remote.sas_addr.pub && *vcc->remote.sas_addr.prv ? "+" : "");
+- if (*vcc->remote.sas_addr.prv)
++ if (*vcc->remote.sas_addr.prv) {
++ int i;
++
+ for (i = 0; i < ATM_ESA_LEN; i++)
+- here += sprintf(here,"%02x",
+- vcc->remote.sas_addr.prv[i]);
+- strcat(here,"\n");
++ seq_printf(seq, "%02x", vcc->remote.sas_addr.prv[i]);
++ }
++ seq_putc(seq, '\n');
+ }
+
+-
+ #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
+
+-static char*
+-lec_arp_get_status_string(unsigned char status)
++static char* lec_arp_get_status_string(unsigned char status)
+ {
+- switch(status) {
+- case ESI_UNKNOWN:
+- return "ESI_UNKNOWN ";
+- case ESI_ARP_PENDING:
+- return "ESI_ARP_PENDING ";
+- case ESI_VC_PENDING:
+- return "ESI_VC_PENDING ";
+- case ESI_FLUSH_PENDING:
+- return "ESI_FLUSH_PENDING ";
+- case ESI_FORWARD_DIRECT:
+- return "ESI_FORWARD_DIRECT";
+- default:
+- return "<Unknown> ";
+- }
++ static char *lec_arp_status_string[] = {
++ "ESI_UNKNOWN ",
++ "ESI_ARP_PENDING ",
++ "ESI_VC_PENDING ",
++ "<Unknown> ",
++ "ESI_FLUSH_PENDING ",
++ "ESI_FORWARD_DIRECT",
++ "<Undefined>"
++ };
++
++ if (status > ESI_FORWARD_DIRECT)
++ status = ESI_FORWARD_DIRECT + 1;
++ return lec_arp_status_string[status];
+ }
+
+-static void
+-lec_info(struct lec_arp_table *entry, char *buf)
++static void lec_info(struct seq_file *seq, struct lec_arp_table *entry)
+ {
+- int j, offset=0;
++ int i;
+
+- for(j=0;j<ETH_ALEN;j++) {
+- offset+=sprintf(buf+offset,"%2.2x",0xff&entry->mac_addr[j]);
+- }
+- offset+=sprintf(buf+offset, " ");
+- for(j=0;j<ATM_ESA_LEN;j++) {
+- offset+=sprintf(buf+offset,"%2.2x",0xff&entry->atm_addr[j]);
++ for (i = 0; i < ETH_ALEN; i++)
++ seq_printf(seq, "%2.2x", entry->mac_addr[i] & 0xff);
++ seq_printf(seq, " ");
++ for (i = 0; i < ATM_ESA_LEN; i++)
++ seq_printf(seq, "%2.2x", entry->atm_addr[i] & 0xff);
++ seq_printf(seq, " %s %4.4x", lec_arp_get_status_string(entry->status),
++ entry->flags & 0xffff);
++ if (entry->vcc)
++ seq_printf(seq, "%3d %3d ", entry->vcc->vpi, entry->vcc->vci);
++ else
++ seq_printf(seq, " ");
++ if (entry->recv_vcc) {
++ seq_printf(seq, " %3d %3d", entry->recv_vcc->vpi,
++ entry->recv_vcc->vci);
+ }
+- offset+=sprintf(buf+offset, " %s %4.4x",
+- lec_arp_get_status_string(entry->status),
+- entry->flags&0xffff);
+- if (entry->vcc) {
+- offset+=sprintf(buf+offset, "%3d %3d ", entry->vcc->vpi,
+- entry->vcc->vci);
+- } else
+- offset+=sprintf(buf+offset, " ");
+- if (entry->recv_vcc) {
+- offset+=sprintf(buf+offset, " %3d %3d",
+- entry->recv_vcc->vpi, entry->recv_vcc->vci);
+- }
+-
+- sprintf(buf+offset,"\n");
++ seq_putc(seq, '\n');
+ }
+
+-#endif
++#endif /* CONFIG_ATM_LANE */
+
+-static int atm_devices_info(loff_t pos,char *buf)
++static int atm_dev_seq_show(struct seq_file *seq, void *v)
+ {
+- struct atm_dev *dev;
+- struct list_head *p;
+- int left;
++ static char atm_dev_banner[] =
++ "Itf Type ESI/\"MAC\"addr "
++ "AAL(TX,err,RX,err,drop) ... [refcnt]\n";
++
++ if (v == (void *)1)
++ seq_puts(seq, atm_dev_banner);
++ else {
++ struct atm_dev *dev = list_entry(v, struct atm_dev, dev_list);
+
+- if (!pos) {
+- return sprintf(buf,"Itf Type ESI/\"MAC\"addr "
+- "AAL(TX,err,RX,err,drop) ... [refcnt]\n");
+- }
+- left = pos-1;
+- spin_lock(&atm_dev_lock);
+- list_for_each(p, &atm_devs) {
+- dev = list_entry(p, struct atm_dev, dev_list);
+- if (left-- == 0) {
+- atm_dev_info(dev,buf);
+- spin_unlock(&atm_dev_lock);
+- return strlen(buf);
+- }
++ atm_dev_info(seq, dev);
++ }
++ return 0;
++}
++
++static struct seq_operations atm_dev_seq_ops = {
++ .start = atm_dev_seq_start,
++ .next = atm_dev_seq_next,
++ .stop = atm_dev_seq_stop,
++ .show = atm_dev_seq_show,
++};
++
++static int atm_dev_seq_open(struct inode *inode, struct file *file)
++{
++ return seq_open(file, &atm_dev_seq_ops);
++}
++
++static struct file_operations devices_seq_fops = {
++ .open = atm_dev_seq_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = seq_release,
++};
++
++static int pvc_seq_show(struct seq_file *seq, void *v)
++{
++ static char atm_pvc_banner[] =
++ "Itf VPI VCI AAL RX(PCR,Class) TX(PCR,Class)\n";
++
++ if (v == (void *)1)
++ seq_puts(seq, atm_pvc_banner);
++ else {
++ struct vcc_state *state = seq->private;
++ struct atm_vcc *vcc = atm_sk(state->sk);
++
++ pvc_info(seq, vcc, state->clip_info);
+ }
+- spin_unlock(&atm_dev_lock);
+ return 0;
+ }
+
+-/*
+- * FIXME: it isn't safe to walk the VCC list without turning off interrupts.
+- * What is really needed is some lock on the devices. Ditto for ATMARP.
+- */
++static struct seq_operations pvc_seq_ops = {
++ .start = vcc_seq_start,
++ .next = vcc_seq_next,
++ .stop = vcc_seq_stop,
++ .show = pvc_seq_show,
++};
++
++static int pvc_seq_open(struct inode *inode, struct file *file)
++{
++ return __vcc_seq_open(inode, file, PF_ATMPVC, &pvc_seq_ops);
++}
++
++static struct file_operations pvc_seq_fops = {
++ .open = pvc_seq_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = vcc_seq_release,
++};
+
+-static int atm_pvc_info(loff_t pos,char *buf)
++static int vcc_seq_show(struct seq_file *seq, void *v)
+ {
+- struct hlist_node *node;
+- struct sock *s;
+- struct atm_vcc *vcc;
+- int left, clip_info = 0;
+-
+- if (!pos) {
+- return sprintf(buf,"Itf VPI VCI AAL RX(PCR,Class) "
+- "TX(PCR,Class)\n");
++ if (v == (void *)1) {
++ seq_printf(seq, sizeof(void *) == 4 ? "%-8s%s" : "%-16s%s",
++ "Address ", "Itf VPI VCI Fam Flags Reply "
++ "Send buffer Recv buffer\n");
++ } else {
++ struct vcc_state *state = seq->private;
++ struct atm_vcc *vcc = atm_sk(state->sk);
++
++ vcc_info(seq, vcc);
++ }
++ return 0;
++}
++
++static struct seq_operations vcc_seq_ops = {
++ .start = vcc_seq_start,
++ .next = vcc_seq_next,
++ .stop = vcc_seq_stop,
++ .show = vcc_seq_show,
++};
++
++static int vcc_seq_open(struct inode *inode, struct file *file)
++{
++ return __vcc_seq_open(inode, file, 0, &vcc_seq_ops);
++}
++
++static struct file_operations vcc_seq_fops = {
++ .open = vcc_seq_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = vcc_seq_release,
++};
++
++static int svc_seq_show(struct seq_file *seq, void *v)
++{
++ static char atm_svc_banner[] =
++ "Itf VPI VCI State Remote\n";
++
++ if (v == (void *)1)
++ seq_puts(seq, atm_svc_banner);
++ else {
++ struct vcc_state *state = seq->private;
++ struct atm_vcc *vcc = atm_sk(state->sk);
++
++ svc_info(seq, vcc);
+ }
+- left = pos-1;
+-#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
+- if (try_atm_clip_ops())
+- clip_info = 1;
+-#endif
+- read_lock(&vcc_sklist_lock);
+- sk_for_each(s, node, &vcc_sklist) {
+- vcc = atm_sk(s);
+- if (vcc->sk->sk_family == PF_ATMPVC && vcc->dev && !left--) {
+- pvc_info(vcc,buf,clip_info);
+- read_unlock(&vcc_sklist_lock);
++ return 0;
++}
++
++static struct seq_operations svc_seq_ops = {
++ .start = vcc_seq_start,
++ .next = vcc_seq_next,
++ .stop = vcc_seq_stop,
++ .show = svc_seq_show,
++};
++
++static int svc_seq_open(struct inode *inode, struct file *file)
++{
++ return __vcc_seq_open(inode, file, PF_ATMSVC, &svc_seq_ops);
++}
++
++static struct file_operations svc_seq_fops = {
++ .open = svc_seq_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = vcc_seq_release,
++};
++
+ #if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
+- if (clip_info)
+- module_put(atm_clip_ops->owner);
+-#endif
+- return strlen(buf);
+- }
++
++struct arp_state {
++ int bucket;
++ struct neighbour *n;
++ struct clip_vcc *vcc;
++};
++
++static void *arp_vcc_walk(struct arp_state *state,
++ struct atmarp_entry *e, loff_t *l)
++{
++ struct clip_vcc *vcc = state->vcc;
++
++ if (!vcc)
++ vcc = e->vccs;
++ if (vcc == (void *)1) {
++ vcc = e->vccs;
++ --*l;
++ }
++ for (; vcc; vcc = vcc->next) {
++ if (--*l < 0)
++ break;
+ }
+- read_unlock(&vcc_sklist_lock);
+-#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
+- if (clip_info)
+- module_put(atm_clip_ops->owner);
+-#endif
+- return 0;
++ state->vcc = vcc;
++ return (*l < 0) ? state : NULL;
+ }
++
++static void *arp_get_idx(struct arp_state *state, loff_t l)
++{
++ void *v = NULL;
+
++ for (; state->bucket <= NEIGH_HASHMASK; state->bucket++) {
++ for (; state->n; state->n = state->n->next) {
++ v = arp_vcc_walk(state, NEIGH2ENTRY(state->n), &l);
++ if (v)
++ goto done;
++ }
++ state->n = clip_tbl_hook->hash_buckets[state->bucket + 1];
++ }
++done:
++ return v;
++}
+
+-static int atm_vc_info(loff_t pos,char *buf)
++static void *arp_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+- struct atm_vcc *vcc;
+- struct hlist_node *node;
+- struct sock *s;
+- int left;
+-
+- if (!pos)
+- return sprintf(buf,sizeof(void *) == 4 ? "%-8s%s" : "%-16s%s",
+- "Address"," Itf VPI VCI Fam Flags Reply Send buffer"
+- " Recv buffer\n");
+- left = pos-1;
+- read_lock(&vcc_sklist_lock);
+- sk_for_each(s, node, &vcc_sklist) {
+- vcc = atm_sk(s);
+- if (!left--) {
+- vc_info(vcc,buf);
+- read_unlock(&vcc_sklist_lock);
+- return strlen(buf);
+- }
++ struct arp_state *state = seq->private;
++ void *ret = (void *)1;
++
++ if (!clip_tbl_hook) {
++ state->bucket = -1;
++ goto out;
+ }
+- read_unlock(&vcc_sklist_lock);
+
+- return 0;
++ read_lock_bh(&clip_tbl_hook->lock);
++ state->bucket = 0;
++ state->n = clip_tbl_hook->hash_buckets[0];
++ state->vcc = (void *)1;
++ if (*pos)
++ ret = arp_get_idx(state, *pos);
++out:
++ return ret;
+ }
+
++static void arp_seq_stop(struct seq_file *seq, void *v)
++{
++ struct arp_state *state = seq->private;
+
+-static int atm_svc_info(loff_t pos,char *buf)
++ if (state->bucket != -1)
++ read_unlock_bh(&clip_tbl_hook->lock);
++}
++
++static void *arp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
+- struct hlist_node *node;
+- struct sock *s;
+- struct atm_vcc *vcc;
+- int left;
+-
+- if (!pos)
+- return sprintf(buf,"Itf VPI VCI State Remote\n");
+- left = pos-1;
+- read_lock(&vcc_sklist_lock);
+- sk_for_each(s, node, &vcc_sklist) {
+- vcc = atm_sk(s);
+- if (vcc->sk->sk_family == PF_ATMSVC && !left--) {
+- svc_info(vcc,buf);
+- read_unlock(&vcc_sklist_lock);
+- return strlen(buf);
+- }
+- }
+- read_unlock(&vcc_sklist_lock);
++ struct arp_state *state = seq->private;
+
+- return 0;
++ v = arp_get_idx(state, 1);
++ *pos += !!PTR_ERR(v);
++ return v;
+ }
+
+-#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
+-static int atm_arp_info(loff_t pos,char *buf)
++static int arp_seq_show(struct seq_file *seq, void *v)
+ {
+- struct neighbour *n;
+- int i,count;
++ static char atm_arp_banner[] =
++ "IPitf TypeEncp Idle IP address ATM address\n";
++
++ if (v == (void *)1)
++ seq_puts(seq, atm_arp_banner);
++ else {
++ struct arp_state *state = seq->private;
++ struct neighbour *n = state->n;
++ struct clip_vcc *vcc = state->vcc;
+
+- if (!pos) {
+- return sprintf(buf,"IPitf TypeEncp Idle IP address "
+- "ATM address\n");
++ atmarp_info(seq, n->dev, NEIGH2ENTRY(n), vcc);
+ }
++ return 0;
++}
++
++static struct seq_operations arp_seq_ops = {
++ .start = arp_seq_start,
++ .next = arp_seq_next,
++ .stop = arp_seq_stop,
++ .show = arp_seq_show,
++};
++
++static int arp_seq_open(struct inode *inode, struct file *file)
++{
++ struct arp_state *state;
++ struct seq_file *seq;
++ int rc = -EAGAIN;
++
+ if (!try_atm_clip_ops())
+- return 0;
+- count = pos;
+- read_lock_bh(&clip_tbl_hook->lock);
+- for (i = 0; i <= NEIGH_HASHMASK; i++)
+- for (n = clip_tbl_hook->hash_buckets[i]; n; n = n->next) {
+- struct atmarp_entry *entry = NEIGH2ENTRY(n);
+- struct clip_vcc *vcc;
+-
+- if (!entry->vccs) {
+- if (--count) continue;
+- atmarp_info(n->dev,entry,NULL,buf);
+- read_unlock_bh(&clip_tbl_hook->lock);
+- module_put(atm_clip_ops->owner);
+- return strlen(buf);
+- }
+- for (vcc = entry->vccs; vcc;
+- vcc = vcc->next) {
+- if (--count) continue;
+- atmarp_info(n->dev,entry,vcc,buf);
+- read_unlock_bh(&clip_tbl_hook->lock);
+- module_put(atm_clip_ops->owner);
+- return strlen(buf);
+- }
+- }
+- read_unlock_bh(&clip_tbl_hook->lock);
++ goto out;
++
++ state = kmalloc(sizeof(*state), GFP_KERNEL);
++ if (!state) {
++ rc = -ENOMEM;
++ goto out_put;
++ }
++
++ rc = seq_open(file, &arp_seq_ops);
++ if (rc)
++ goto out_kfree;
++
++ seq = file->private_data;
++ seq->private = state;
++out:
++ return rc;
++
++out_put:
+ module_put(atm_clip_ops->owner);
+- return 0;
++out_kfree:
++ kfree(state);
++ goto out;
+ }
+-#endif
+
+-#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
+-static int atm_lec_info(loff_t pos,char *buf)
++static int arp_seq_release(struct inode *inode, struct file *file)
+ {
++ module_put(atm_clip_ops->owner);
++ return seq_release_private(inode, file);
++}
++
++static struct file_operations arp_seq_fops = {
++ .open = arp_seq_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = arp_seq_release,
++};
++
++#endif /* CONFIG_ATM_CLIP */
++
++#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
++
++struct lec_state {
+ unsigned long flags;
+- struct lec_priv *priv;
++ struct lec_priv *locked;
+ struct lec_arp_table *entry;
+- int i, count, d, e;
+ struct net_device *dev;
++ int itf;
++ int arp_table;
++ int misc_table;
++};
+
+- if (!pos) {
+- return sprintf(buf,"Itf MAC ATM destination"
+- " Status Flags "
+- "VPI/VCI Recv VPI/VCI\n");
++static void *lec_tbl_walk(struct lec_state *state, struct lec_arp_table *tbl,
++ loff_t *l)
++{
++ struct lec_arp_table *e = state->entry;
++
++ if (!e)
++ e = tbl;
++ if (e == (void *)1) {
++ e = tbl;
++ --*l;
+ }
+- if (!try_atm_lane_ops())
+- return 0; /* the lane module is not there yet */
++ for (; e; e = e->next) {
++ if (--*l < 0)
++ break;
++ }
++ state->entry = e;
++ return (*l < 0) ? state : NULL;
++}
+
+- count = pos;
+- for(d = 0; d < MAX_LEC_ITF; d++) {
+- dev = atm_lane_ops->get_lec(d);
+- if (!dev || !(priv = (struct lec_priv *) dev->priv))
+- continue;
+- spin_lock_irqsave(&priv->lec_arp_lock, flags);
+- for(i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
+- for(entry = priv->lec_arp_tables[i]; entry; entry = entry->next) {
+- if (--count)
+- continue;
+- e = sprintf(buf,"%s ", dev->name);
+- lec_info(entry, buf+e);
+- spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
+- dev_put(dev);
+- module_put(atm_lane_ops->owner);
+- return strlen(buf);
+- }
+- }
+- for(entry = priv->lec_arp_empty_ones; entry; entry = entry->next) {
+- if (--count)
+- continue;
+- e = sprintf(buf,"%s ", dev->name);
+- lec_info(entry, buf+e);
+- spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
+- dev_put(dev);
+- module_put(atm_lane_ops->owner);
+- return strlen(buf);
+- }
+- for(entry = priv->lec_no_forward; entry; entry=entry->next) {
+- if (--count)
+- continue;
+- e = sprintf(buf,"%s ", dev->name);
+- lec_info(entry, buf+e);
+- spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
+- dev_put(dev);
+- module_put(atm_lane_ops->owner);
+- return strlen(buf);
+- }
+- for(entry = priv->mcast_fwds; entry; entry = entry->next) {
+- if (--count)
+- continue;
+- e = sprintf(buf,"%s ", dev->name);
+- lec_info(entry, buf+e);
+- spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
+- dev_put(dev);
+- module_put(atm_lane_ops->owner);
+- return strlen(buf);
+- }
+- spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
++static void *lec_arp_walk(struct lec_state *state, loff_t *l,
++ struct lec_priv *priv)
++{
++ void *v = NULL;
++ int p;
++
++ for (p = state->arp_table; p < LEC_ARP_TABLE_SIZE; p++) {
++ v = lec_tbl_walk(state, priv->lec_arp_tables[p], l);
++ if (v)
++ break;
++ }
++ state->arp_table = p;
++ return v;
++}
++
++static void *lec_misc_walk(struct lec_state *state, loff_t *l,
++ struct lec_priv *priv)
++{
++ struct lec_arp_table *lec_misc_tables[] = {
++ priv->lec_arp_empty_ones,
++ priv->lec_no_forward,
++ priv->mcast_fwds
++ };
++ void *v = NULL;
++ int q;
++
++ for (q = state->misc_table; q < ARRAY_SIZE(lec_misc_tables); q++) {
++ v = lec_tbl_walk(state, lec_misc_tables[q], l);
++ if (v)
++ break;
++ }
++ state->misc_table = q;
++ return v;
++}
++
++static void *lec_priv_walk(struct lec_state *state, loff_t *l,
++ struct lec_priv *priv)
++{
++ if (!state->locked) {
++ state->locked = priv;
++ spin_lock_irqsave(&priv->lec_arp_lock, state->flags);
++ }
++ if (!lec_arp_walk(state, l, priv) &&
++ !lec_misc_walk(state, l, priv)) {
++ spin_unlock_irqrestore(&priv->lec_arp_lock, state->flags);
++ state->locked = NULL;
++ /* Partial state reset for the next time we get called */
++ state->arp_table = state->misc_table = 0;
++ }
++ return state->locked;
++}
++
++static void *lec_itf_walk(struct lec_state *state, loff_t *l)
++{
++ struct net_device *dev;
++ void *v;
++
++ dev = state->dev ? state->dev : atm_lane_ops->get_lec(state->itf);
++ v = (dev && dev->priv) ? lec_priv_walk(state, l, dev->priv) : NULL;
++ if (!v && dev) {
+ dev_put(dev);
++ /* Partial state reset for the next time we get called */
++ dev = NULL;
++ }
++ state->dev = dev;
++ return v;
++}
++
++static void *lec_get_idx(struct lec_state *state, loff_t l)
++{
++ void *v = NULL;
++
++ for (; state->itf < MAX_LEC_ITF; state->itf++) {
++ v = lec_itf_walk(state, &l);
++ if (v)
++ break;
++ }
++ return v;
++}
++
++static void *lec_seq_start(struct seq_file *seq, loff_t *pos)
++{
++ struct lec_state *state = seq->private;
++
++ state->itf = 0;
++ state->dev = NULL;
++ state->locked = NULL;
++ state->arp_table = 0;
++ state->misc_table = 0;
++ state->entry = (void *)1;
++
++ return *pos ? lec_get_idx(state, *pos) : (void*)1;
++}
++
++static void lec_seq_stop(struct seq_file *seq, void *v)
++{
++ struct lec_state *state = seq->private;
++
++ if (state->dev) {
++ spin_unlock_irqrestore(&state->locked->lec_arp_lock,
++ state->flags);
++ dev_put(state->dev);
++ }
++}
++
++static void *lec_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++{
++ struct lec_state *state = seq->private;
++
++ v = lec_get_idx(state, 1);
++ *pos += !!PTR_ERR(v);
++ return v;
++}
++
++static int lec_seq_show(struct seq_file *seq, void *v)
++{
++ static char lec_banner[] = "Itf MAC ATM destination"
++ " Status Flags "
++ "VPI/VCI Recv VPI/VCI\n";
++
++ if (v == (void *)1)
++ seq_puts(seq, lec_banner);
++ else {
++ struct lec_state *state = seq->private;
++ struct net_device *dev = state->dev;
++
++ seq_printf(seq, "%s ", dev->name);
++ lec_info(seq, state->entry);
+ }
+- module_put(atm_lane_ops->owner);
+ return 0;
+ }
+-#endif
+
++static struct seq_operations lec_seq_ops = {
++ .start = lec_seq_start,
++ .next = lec_seq_next,
++ .stop = lec_seq_stop,
++ .show = lec_seq_show,
++};
++
++static int lec_seq_open(struct inode *inode, struct file *file)
++{
++ struct lec_state *state;
++ struct seq_file *seq;
++ int rc = -EAGAIN;
++
++ if (!try_atm_lane_ops())
++ goto out;
++
++ state = kmalloc(sizeof(*state), GFP_KERNEL);
++ if (!state) {
++ rc = -ENOMEM;
++ goto out;
++ }
++
++ rc = seq_open(file, &lec_seq_ops);
++ if (rc)
++ goto out_kfree;
++ seq = file->private_data;
++ seq->private = state;
++out:
++ return rc;
++out_kfree:
++ kfree(state);
++ goto out;
++}
++
++static int lec_seq_release(struct inode *inode, struct file *file)
++{
++ module_put(atm_lane_ops->owner);
++ return seq_release_private(inode, file);
++}
++
++static struct file_operations lec_seq_fops = {
++ .open = lec_seq_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = lec_seq_release,
++};
++
++#endif /* CONFIG_ATM_LANE */
+
+ static ssize_t proc_dev_atm_read(struct file *file,char *buf,size_t count,
+ loff_t *pos)
+@@ -562,28 +888,6 @@
+ }
+
+
+-static ssize_t proc_spec_atm_read(struct file *file,char *buf,size_t count,
+- loff_t *pos)
+-{
+- unsigned long page;
+- int length;
+- int (*info)(loff_t,char *);
+- info = PDE(file->f_dentry->d_inode)->data;
+-
+- if (count == 0) return 0;
+- page = get_zeroed_page(GFP_KERNEL);
+- if (!page) return -ENOMEM;
+- length = (*info)(*pos,(char *) page);
+- if (length > count) length = -EINVAL;
+- if (length >= 0) {
+- if (copy_to_user(buf,(char *) page,length)) length = -EFAULT;
+- (*pos)++;
+- }
+- free_page(page);
+- return length;
+-}
+-
+-
+ struct proc_dir_entry *atm_proc_root;
+ EXPORT_SYMBOL(atm_proc_root);
+
+@@ -604,19 +908,19 @@
+
+ dev->proc_name = kmalloc(strlen(dev->type) + digits + 2, GFP_KERNEL);
+ if (!dev->proc_name)
+- goto fail1;
++ goto err_out;
+ sprintf(dev->proc_name,"%s:%d",dev->type, dev->number);
+
+ dev->proc_entry = create_proc_entry(dev->proc_name, 0, atm_proc_root);
+ if (!dev->proc_entry)
+- goto fail0;
++ goto err_free_name;
+ dev->proc_entry->data = dev;
+- dev->proc_entry->proc_fops = &proc_dev_atm_operations;
++ dev->proc_entry->proc_fops = &proc_atm_dev_ops;
+ dev->proc_entry->owner = THIS_MODULE;
+ return 0;
+-fail0:
++err_free_name:
+ kfree(dev->proc_name);
+-fail1:
++err_out:
+ return error;
+ }
+
+@@ -630,57 +934,65 @@
+ kfree(dev->proc_name);
+ }
+
++static struct atm_proc_entry {
++ char *name;
++ struct file_operations *proc_fops;
++ struct proc_dir_entry *dirent;
++} atm_proc_ents[] = {
++ { .name = "devices", .proc_fops = &devices_seq_fops },
++ { .name = "pvc", .proc_fops = &pvc_seq_fops },
++ { .name = "svc", .proc_fops = &svc_seq_fops },
++ { .name = "vc", .proc_fops = &vcc_seq_fops },
++#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
++ { .name = "arp", .proc_fops = &arp_seq_fops },
++#endif
++#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
++ { .name = "lec", .proc_fops = &lec_seq_fops },
++#endif
++ { .name = NULL, .proc_fops = NULL }
++};
++
++static void atm_proc_dirs_remove(void)
++{
++ static struct atm_proc_entry *e;
+
+-#define CREATE_ENTRY(name) \
+- name = create_proc_entry(#name,0,atm_proc_root); \
+- if (!name) goto cleanup; \
+- name->data = atm_##name##_info; \
+- name->proc_fops = &proc_spec_atm_operations; \
+- name->owner = THIS_MODULE
+-
+-static struct proc_dir_entry *devices = NULL, *pvc = NULL,
+- *svc = NULL, *arp = NULL, *lec = NULL, *vc = NULL;
+-
+-static void atm_proc_cleanup(void)
+-{
+- if (devices)
+- remove_proc_entry("devices",atm_proc_root);
+- if (pvc)
+- remove_proc_entry("pvc",atm_proc_root);
+- if (svc)
+- remove_proc_entry("svc",atm_proc_root);
+- if (arp)
+- remove_proc_entry("arp",atm_proc_root);
+- if (lec)
+- remove_proc_entry("lec",atm_proc_root);
+- if (vc)
+- remove_proc_entry("vc",atm_proc_root);
+- remove_proc_entry("net/atm",NULL);
++ for (e = atm_proc_ents; e->name; e++) {
++ if (e->dirent)
++ remove_proc_entry(e->name, atm_proc_root);
++ }
++ remove_proc_entry("net/atm", NULL);
+ }
+
+ int __init atm_proc_init(void)
+ {
++ static struct atm_proc_entry *e;
++ int ret;
++
+ atm_proc_root = proc_mkdir("net/atm",NULL);
+ if (!atm_proc_root)
+- return -ENOMEM;
+- CREATE_ENTRY(devices);
+- CREATE_ENTRY(pvc);
+- CREATE_ENTRY(svc);
+- CREATE_ENTRY(vc);
+-#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
+- CREATE_ENTRY(arp);
+-#endif
+-#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
+- CREATE_ENTRY(lec);
+-#endif
+- return 0;
+-
+-cleanup:
+- atm_proc_cleanup();
+- return -ENOMEM;
++ goto err_out;
++ for (e = atm_proc_ents; e->name; e++) {
++ struct proc_dir_entry *dirent;
++
++ dirent = create_proc_entry(e->name, S_IRUGO, atm_proc_root);
++ if (!dirent)
++ goto err_out_remove;
++ dirent->proc_fops = e->proc_fops;
++ dirent->owner = THIS_MODULE;
++ e->dirent = dirent;
++ }
++ ret = 0;
++out:
++ return ret;
++
++err_out_remove:
++ atm_proc_dirs_remove();
++err_out:
++ ret = -ENOMEM;
++ goto out;
+ }
+
+-void atm_proc_exit(void)
++void __exit atm_proc_exit(void)
+ {
+- atm_proc_cleanup();
++ atm_proc_dirs_remove();
+ }
+Index: linux-2.6.0-test5/net/atm/resources.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/atm/resources.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/atm/resources.c 2003-09-27 11:38:41.552211488 +0800
+@@ -30,7 +30,7 @@
+ {
+ struct atm_dev *dev;
+
+- dev = kmalloc(sizeof(*dev), GFP_ATOMIC);
++ dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev)
+ return NULL;
+ memset(dev, 0, sizeof(*dev));
+@@ -395,6 +395,35 @@
+ return error;
+ }
+
++static __inline__ void *dev_get_idx(loff_t left)
++{
++ struct list_head *p;
++
++ list_for_each(p, &atm_devs) {
++ if (!--left)
++ break;
++ }
++ return (p != &atm_devs) ? p : NULL;
++}
++
++void *atm_dev_seq_start(struct seq_file *seq, loff_t *pos)
++{
++ spin_lock(&atm_dev_lock);
++ return *pos ? dev_get_idx(*pos) : (void *) 1;
++}
++
++void atm_dev_seq_stop(struct seq_file *seq, void *v)
++{
++ spin_unlock(&atm_dev_lock);
++}
++
++void *atm_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++{
++ ++*pos;
++ v = (v == (void *)1) ? atm_devs.next : ((struct list_head *)v)->next;
++ return (v == &atm_devs) ? NULL : v;
++}
++
+
+ EXPORT_SYMBOL(atm_dev_register);
+ EXPORT_SYMBOL(atm_dev_deregister);
+Index: linux-2.6.0-test5/net/atm/resources.h
+===================================================================
+--- linux-2.6.0-test5.orig/net/atm/resources.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/atm/resources.h 2003-09-27 11:38:41.553211336 +0800
+@@ -21,6 +21,11 @@
+
+ #include <linux/proc_fs.h>
+
++void *atm_dev_seq_start(struct seq_file *seq, loff_t *pos);
++void atm_dev_seq_stop(struct seq_file *seq, void *v);
++void *atm_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos);
++
++
+ int atm_proc_dev_register(struct atm_dev *dev);
+ void atm_proc_dev_deregister(struct atm_dev *dev);
+
+Index: linux-2.6.0-test5/net/ax25/ax25_route.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ax25/ax25_route.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ax25/ax25_route.c 2003-09-27 11:38:41.557210728 +0800
+@@ -281,8 +281,6 @@
+
+ #ifdef CONFIG_PROC_FS
+
+-#define AX25_PROC_START ((void *)1)
+-
+ static void *ax25_rt_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+ struct ax25_route *ax25_rt;
+@@ -290,7 +288,7 @@
+
+ read_lock(&ax25_route_lock);
+ if (*pos == 0)
+- return AX25_PROC_START;
++ return SEQ_START_TOKEN;
+
+ for (ax25_rt = ax25_route_list; ax25_rt != NULL; ax25_rt = ax25_rt->next) {
+ if (i == *pos)
+@@ -304,7 +302,7 @@
+ static void *ax25_rt_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
+ ++*pos;
+- return (v == AX25_PROC_START) ? ax25_route_list :
++ return (v == SEQ_START_TOKEN) ? ax25_route_list :
+ ((struct ax25_route *) v)->next;
+ }
+
+@@ -315,7 +313,7 @@
+
+ static int ax25_rt_seq_show(struct seq_file *seq, void *v)
+ {
+- if (v == AX25_PROC_START)
++ if (v == SEQ_START_TOKEN)
+ seq_puts(seq, "callsign dev mode digipeaters\n");
+ else {
+ struct ax25_route *ax25_rt = v;
+Index: linux-2.6.0-test5/net/ax25/ax25_uid.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ax25/ax25_uid.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ax25/ax25_uid.c 2003-09-27 11:38:41.560210272 +0800
+@@ -144,8 +144,6 @@
+
+ #ifdef CONFIG_PROC_FS
+
+-#define AX25_PROC_START ((void *)1)
+-
+ static void *ax25_uid_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+ struct ax25_uid_assoc *pt;
+@@ -153,7 +151,7 @@
+
+ read_lock(&ax25_uid_lock);
+ if (*pos == 0)
+- return AX25_PROC_START;
++ return SEQ_START_TOKEN;
+
+ for (pt = ax25_uid_list; pt != NULL; pt = pt->next) {
+ if (i == *pos)
+@@ -166,7 +164,7 @@
+ static void *ax25_uid_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
+ ++*pos;
+- return (v == AX25_PROC_START) ? ax25_uid_list :
++ return (v == SEQ_START_TOKEN) ? ax25_uid_list :
+ ((struct ax25_uid_assoc *) v)->next;
+ }
+
+@@ -177,7 +175,7 @@
+
+ static int ax25_uid_seq_show(struct seq_file *seq, void *v)
+ {
+- if (v == AX25_PROC_START)
++ if (v == SEQ_START_TOKEN)
+ seq_printf(seq, "Policy: %d\n", ax25_uid_policy);
+ else {
+ struct ax25_uid_assoc *pt = v;
+Index: linux-2.6.0-test5/net/bluetooth/af_bluetooth.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/bluetooth/af_bluetooth.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/bluetooth/af_bluetooth.c 2003-09-27 11:38:41.562209968 +0800
+@@ -27,7 +27,7 @@
+ *
+ * $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
+ */
+-#define VERSION "2.2"
++#define VERSION "2.3"
+
+ #include <linux/config.h>
+ #include <linux/module.h>
+@@ -130,7 +130,6 @@
+ }
+
+ sock_init_data(sock, sk);
+- sk_set_owner(sk, THIS_MODULE);
+ INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
+
+ sk->sk_zapped = 0;
+@@ -273,39 +272,35 @@
+ return mask;
+ }
+
+-int bt_sock_w4_connect(struct sock *sk, int flags)
++int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
+ {
+ DECLARE_WAITQUEUE(wait, current);
+- long timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
+ int err = 0;
+
+ BT_DBG("sk %p", sk);
+
+ add_wait_queue(sk->sk_sleep, &wait);
+- while (sk->sk_state != BT_CONNECTED) {
++ while (sk->sk_state != state) {
+ set_current_state(TASK_INTERRUPTIBLE);
++
+ if (!timeo) {
+ err = -EAGAIN;
+ break;
+ }
+
++ if (signal_pending(current)) {
++ err = sock_intr_errno(timeo);
++ break;
++ }
++
+ release_sock(sk);
+ timeo = schedule_timeout(timeo);
+ lock_sock(sk);
+
+- err = 0;
+- if (sk->sk_state == BT_CONNECTED)
+- break;
+-
+ if (sk->sk_err) {
+ err = sock_error(sk);
+ break;
+ }
+-
+- if (signal_pending(current)) {
+- err = sock_intr_errno(timeo);
+- break;
+- }
+ }
+ set_current_state(TASK_RUNNING);
+ remove_wait_queue(sk->sk_sleep, &wait);
+Index: linux-2.6.0-test5/net/bluetooth/bnep/bnep.h
+===================================================================
+--- linux-2.6.0-test5.orig/net/bluetooth/bnep/bnep.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/bluetooth/bnep/bnep.h 2003-09-27 11:38:41.565209512 +0800
+@@ -168,11 +168,11 @@
+ u64 mc_filter;
+
+ struct socket *sock;
+- struct net_device dev;
++ struct net_device *dev;
+ struct net_device_stats stats;
+ };
+
+-int bnep_net_init(struct net_device *dev);
++void bnep_net_setup(struct net_device *dev);
+ int bnep_sock_init(void);
+ int bnep_sock_cleanup(void);
+
+Index: linux-2.6.0-test5/net/bluetooth/bnep/core.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/bluetooth/bnep/core.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/bluetooth/bnep/core.c 2003-09-27 11:38:41.569208904 +0800
+@@ -180,7 +180,7 @@
+ s->mc_filter = 0;
+
+ /* Always send broadcast */
+- set_bit(bnep_mc_hash(s->dev.broadcast), (ulong *) &s->mc_filter);
++ set_bit(bnep_mc_hash(s->dev->broadcast), (ulong *) &s->mc_filter);
+
+ /* Add address ranges to the multicast hash */
+ for (; n > 0; n--) {
+@@ -293,7 +293,7 @@
+
+ static inline int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb)
+ {
+- struct net_device *dev = &s->dev;
++ struct net_device *dev = s->dev;
+ struct sk_buff *nskb;
+ u8 type;
+
+@@ -451,7 +451,7 @@
+ static int bnep_session(void *arg)
+ {
+ struct bnep_session *s = arg;
+- struct net_device *dev = &s->dev;
++ struct net_device *dev = s->dev;
+ struct sock *sk = s->sock->sk;
+ struct sk_buff *skb;
+ wait_queue_t wait;
+@@ -501,7 +501,7 @@
+ __bnep_unlink_session(s);
+
+ up_write(&bnep_session_sem);
+- kfree(s);
++ kfree(dev);
+ return 0;
+ }
+
+@@ -517,10 +517,13 @@
+ baswap((void *) dst, &bt_sk(sock->sk)->dst);
+ baswap((void *) src, &bt_sk(sock->sk)->src);
+
+- s = kmalloc(sizeof(struct bnep_session), GFP_KERNEL);
+- if (!s)
+- return -ENOMEM;
+- memset(s, 0, sizeof(struct bnep_session));
++ /* session struct allocated as private part of net_device */
++ dev = alloc_netdev(sizeof(struct bnep_session),
++ (*req->device) ? req->device : "bnep%d",
++ bnep_net_setup);
++ if (!dev)
++ return ENOMEM;
++
+
+ down_write(&bnep_session_sem);
+
+@@ -530,20 +533,15 @@
+ goto failed;
+ }
+
+- dev = &s->dev;
+-
+- if (*req->device)
+- strcpy(dev->name, req->device);
+- else
+- strcpy(dev->name, "bnep%d");
++ s = dev->priv;
+
+- memset(dev->broadcast, 0xff, ETH_ALEN);
+-
+ /* This is rx header therefore addresses are swapped.
+ * ie eh.h_dest is our local address. */
+ memcpy(s->eh.h_dest, &src, ETH_ALEN);
+ memcpy(s->eh.h_source, &dst, ETH_ALEN);
++ memcpy(dev->dev_addr, s->eh.h_dest, ETH_ALEN);
+
++ s->dev = dev;
+ s->sock = sock;
+ s->role = req->role;
+ s->state = BT_CONNECTED;
+@@ -569,8 +567,6 @@
+ s->proto_filter[2].end = htons(0x86DD);
+ #endif
+
+- dev->init = bnep_net_init;
+- dev->priv = s;
+ err = register_netdev(dev);
+ if (err) {
+ goto failed;
+@@ -578,7 +574,7 @@
+
+ __bnep_link_session(s);
+
+- err = kernel_thread(bnep_session, s, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++ err = kernel_thread(bnep_session, s, CLONE_KERNEL);
+ if (err < 0) {
+ /* Session thread start failed, gotta cleanup. */
+ unregister_netdev(dev);
+@@ -592,7 +588,7 @@
+
+ failed:
+ up_write(&bnep_session_sem);
+- kfree(s);
++ kfree(dev);
+ return err;
+ }
+
+@@ -624,7 +620,7 @@
+ static void __bnep_copy_ci(struct bnep_conninfo *ci, struct bnep_session *s)
+ {
+ memcpy(ci->dst, s->eh.h_source, ETH_ALEN);
+- strcpy(ci->device, s->dev.name);
++ strcpy(ci->device, s->dev->name);
+ ci->flags = s->flags;
+ ci->state = s->state;
+ ci->role = s->role;
+Index: linux-2.6.0-test5/net/bluetooth/bnep/netdev.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/bluetooth/bnep/netdev.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/bluetooth/bnep/netdev.c 2003-09-27 11:38:41.572208448 +0800
+@@ -226,11 +226,10 @@
+ return 0;
+ }
+
+-int bnep_net_init(struct net_device *dev)
++void bnep_net_setup(struct net_device *dev)
+ {
+- struct bnep_session *s = dev->priv;
+
+- memcpy(dev->dev_addr, s->eh.h_dest, ETH_ALEN);
++ memset(dev->broadcast, 0xff, ETH_ALEN);
+ dev->addr_len = ETH_ALEN;
+
+ ether_setup(dev);
+@@ -245,6 +244,4 @@
+
+ dev->watchdog_timeo = HZ * 2;
+ dev->tx_timeout = bnep_net_timeout;
+-
+- return 0;
+ }
+Index: linux-2.6.0-test5/net/bluetooth/bnep/sock.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/bluetooth/bnep/sock.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/bluetooth/bnep/sock.c 2003-09-27 11:38:41.574208144 +0800
+@@ -175,6 +175,9 @@
+
+ if (!(sk = bt_sock_alloc(sock, PF_BLUETOOTH, 0, GFP_KERNEL)))
+ return -ENOMEM;
++
++ sk_set_owner(sk, THIS_MODULE);
++
+ sock->ops = &bnep_sock_ops;
+
+ sock->state = SS_UNCONNECTED;
+@@ -186,6 +189,7 @@
+
+ static struct net_proto_family bnep_sock_family_ops = {
+ .family = PF_BLUETOOTH,
++ .owner = THIS_MODULE,
+ .create = bnep_sock_create
+ };
+
+Index: linux-2.6.0-test5/net/bluetooth/hci_core.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/bluetooth/hci_core.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/bluetooth/hci_core.c 2003-09-27 11:38:41.583206776 +0800
+@@ -394,7 +394,7 @@
+ {
+ struct hci_inquiry_req ir;
+ struct hci_dev *hdev;
+- int err = 0, do_inquiry = 0;
++ int err = 0, do_inquiry = 0, max_rsp;
+ long timeo;
+ __u8 *buf, *ptr;
+
+@@ -417,16 +417,19 @@
+ if (do_inquiry && (err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo)) < 0)
+ goto done;
+
++ /* for unlimited number of responses we will use buffer with 255 entries */
++ max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
++
+ /* cache_dump can't sleep. Therefore we allocate temp buffer and then
+ * copy it to the user space.
+ */
+- if (!(buf = kmalloc(sizeof(struct inquiry_info) * ir.num_rsp, GFP_KERNEL))) {
++ if (!(buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL))) {
+ err = -ENOMEM;
+ goto done;
+ }
+
+ hci_dev_lock_bh(hdev);
+- ir.num_rsp = inquiry_cache_dump(hdev, ir.num_rsp, buf);
++ ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
+ hci_dev_unlock_bh(hdev);
+
+ BT_DBG("num_rsp %d", ir.num_rsp);
+Index: linux-2.6.0-test5/net/bluetooth/hci_event.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/bluetooth/hci_event.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/bluetooth/hci_event.c 2003-09-27 11:38:41.589205864 +0800
+@@ -62,9 +62,22 @@
+ /* Command Complete OGF LINK_CTL */
+ static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
+ {
++ __u8 status;
++
+ BT_DBG("%s ocf 0x%x", hdev->name, ocf);
+
+ switch (ocf) {
++ case OCF_INQUIRY_CANCEL:
++ status = *((__u8 *) skb->data);
++
++ if (status) {
++ BT_DBG("%s Inquiry cancel error: status 0x%x", hdev->name, status);
++ } else {
++ clear_bit(HCI_INQUIRY, &hdev->flags);
++ hci_req_complete(hdev, status);
++ }
++ break;
++
+ default:
+ BT_DBG("%s Command complete: ogf LINK_CTL ocf %x", hdev->name, ocf);
+ break;
+Index: linux-2.6.0-test5/net/bluetooth/hci_sock.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/bluetooth/hci_sock.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/bluetooth/hci_sock.c 2003-09-27 11:38:41.593205256 +0800
+@@ -75,7 +75,7 @@
+ /* OGF_LINK_POLICY */
+ { 0x1200, 0x0, 0x0, 0x0 },
+ /* OGF_HOST_CTL */
+- { 0x80100000, 0x2a, 0x0, 0x0 },
++ { 0x80100000, 0x202a, 0x0, 0x0 },
+ /* OGF_INFO_PARAM */
+ { 0x22a, 0x0, 0x0, 0x0 },
+ /* OGF_STATUS_PARAM */
+@@ -587,6 +587,8 @@
+ if (!sk)
+ return -ENOMEM;
+
++ sk_set_owner(sk, THIS_MODULE);
++
+ sock->state = SS_UNCONNECTED;
+ sk->sk_state = BT_OPEN;
+
+Index: linux-2.6.0-test5/net/bluetooth/l2cap.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/bluetooth/l2cap.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/bluetooth/l2cap.c 2003-09-27 11:38:41.606203280 +0800
+@@ -289,7 +289,7 @@
+ struct l2cap_disconn_req req;
+
+ sk->sk_state = BT_DISCONN;
+- l2cap_sock_set_timer(sk, HZ * 5);
++ l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
+
+ req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
+ req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
+@@ -314,11 +314,9 @@
+ static void l2cap_sock_close(struct sock *sk)
+ {
+ l2cap_sock_clear_timer(sk);
+-
+ lock_sock(sk);
+ __l2cap_sock_close(sk, ECONNRESET);
+ release_sock(sk);
+-
+ l2cap_sock_kill(sk);
+ }
+
+@@ -530,8 +528,8 @@
+ goto done;
+
+ wait:
+- err = bt_sock_w4_connect(sk, flags);
+-
++ err = bt_sock_wait_state(sk, BT_CONNECTED,
++ sock_sndtimeo(sk, flags & O_NONBLOCK));
+ done:
+ release_sock(sk);
+ return err;
+@@ -831,32 +829,39 @@
+ static int l2cap_sock_shutdown(struct socket *sock, int how)
+ {
+ struct sock *sk = sock->sk;
++ int err = 0;
+
+ BT_DBG("sock %p, sk %p", sock, sk);
+
+ if (!sk) return 0;
+
+- l2cap_sock_clear_timer(sk);
+-
+ lock_sock(sk);
+- sk->sk_shutdown = SHUTDOWN_MASK;
+- __l2cap_sock_close(sk, ECONNRESET);
+- release_sock(sk);
++ if (!sk->sk_shutdown) {
++ sk->sk_shutdown = SHUTDOWN_MASK;
++ l2cap_sock_clear_timer(sk);
++ __l2cap_sock_close(sk, 0);
+
+- return 0;
++ if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
++ err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime);
++ }
++ release_sock(sk);
++ return err;
+ }
+
+ static int l2cap_sock_release(struct socket *sock)
+ {
+ struct sock *sk = sock->sk;
++ int err;
+
+ BT_DBG("sock %p, sk %p", sock, sk);
+
+ if (!sk) return 0;
+
++ err = l2cap_sock_shutdown(sock, 2);
++
+ sock_orphan(sk);
+- l2cap_sock_close(sk);
+- return 0;
++ l2cap_sock_kill(sk);
++ return err;
+ }
+
+ /* ---- L2CAP channels ---- */
+@@ -980,9 +985,11 @@
+ hci_conn_put(conn->hcon);
+ }
+
+- sk->sk_state = BT_CLOSED;
+- sk->sk_err = err;
++ sk->sk_state = BT_CLOSED;
+ sk->sk_zapped = 1;
++
++ if (err)
++ sk->sk_err = err;
+
+ if (parent)
+ parent->sk_data_ready(parent, 0);
+@@ -1518,18 +1525,35 @@
+ if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
+ return -ENOENT;
+
+- if (result) {
+- struct l2cap_disconn_req req;
++ switch (result) {
++ case L2CAP_CONF_SUCCESS:
++ break;
+
+- /* They didn't like our options. Well... we do not negotiate.
+- * Close channel.
+- */
++ case L2CAP_CONF_UNACCEPT:
++ if (++l2cap_pi(sk)->conf_retry < L2CAP_CONF_MAX_RETRIES) {
++ char req[128];
++ /*
++ It does not make sense to adjust L2CAP parameters
++ that are currently defined in the spec. We simply
++ resend config request that we sent earlier. It is
++ stupid :) but it helps qualification testing
++ which expects at least some response from us.
++ */
++ l2cap_send_req(conn, L2CAP_CONF_REQ,
++ l2cap_build_conf_req(sk, req), req);
++ goto done;
++ }
++
++ default:
+ sk->sk_state = BT_DISCONN;
++ sk->sk_err = ECONNRESET;
+ l2cap_sock_set_timer(sk, HZ * 5);
+-
+- req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
+- req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
+- l2cap_send_req(conn, L2CAP_DISCONN_REQ, sizeof(req), &req);
++ {
++ struct l2cap_disconn_req req;
++ req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
++ req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
++ l2cap_send_req(conn, L2CAP_DISCONN_REQ, sizeof(req), &req);
++ }
+ goto done;
+ }
+
+@@ -1590,7 +1614,7 @@
+
+ if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
+ return 0;
+- l2cap_chan_del(sk, ECONNABORTED);
++ l2cap_chan_del(sk, 0);
+ bh_unlock_sock(sk);
+
+ l2cap_sock_kill(sk);
+Index: linux-2.6.0-test5/net/bluetooth/rfcomm/core.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/bluetooth/rfcomm/core.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/bluetooth/rfcomm/core.c 2003-09-27 11:38:41.617201608 +0800
+@@ -280,13 +280,13 @@
+ static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel)
+ {
+ struct rfcomm_session *s;
+- u8 dlci = __dlci(0, channel);
+ int err = 0;
++ u8 dlci;
+
+- BT_DBG("dlc %p state %ld %s %s channel %d dlci %d",
+- d, d->state, batostr(src), batostr(dst), channel, dlci);
++ BT_DBG("dlc %p state %ld %s %s channel %d",
++ d, d->state, batostr(src), batostr(dst), channel);
+
+- if (dlci < 1 || dlci > 62)
++ if (channel < 1 || channel > 30)
+ return -EINVAL;
+
+ if (d->state != BT_OPEN && d->state != BT_CLOSED)
+@@ -299,6 +299,8 @@
+ return err;
+ }
+
++ dlci = __dlci(!s->initiator, channel);
++
+ /* Check if DLCI already exists */
+ if (rfcomm_dlc_get(s, dlci))
+ return -EBUSY;
+@@ -715,7 +717,7 @@
+ hdr->len = __len8(sizeof(*mcc) + 1);
+
+ mcc = (void *) ptr; ptr += sizeof(*mcc);
+- mcc->type = __mcc_type(s->initiator, RFCOMM_NSC);
++ mcc->type = __mcc_type(cr, RFCOMM_NSC);
+ mcc->len = __len8(1);
+
+ /* Type that we didn't like */
+@@ -741,7 +743,7 @@
+ hdr->len = __len8(sizeof(*mcc) + sizeof(*pn));
+
+ mcc = (void *) ptr; ptr += sizeof(*mcc);
+- mcc->type = __mcc_type(s->initiator, RFCOMM_PN);
++ mcc->type = __mcc_type(cr, RFCOMM_PN);
+ mcc->len = __len8(sizeof(*pn));
+
+ pn = (void *) ptr; ptr += sizeof(*pn);
+@@ -850,7 +852,51 @@
+
+ msc = (void *) ptr; ptr += sizeof(*msc);
+ msc->dlci = __addr(1, dlci);
+- msc->v24_sig = v24_sig;
++ msc->v24_sig = v24_sig | 0x01;
++
++ *ptr = __fcs(buf); ptr++;
++
++ return rfcomm_send_frame(s, buf, ptr - buf);
++}
++
++static int rfcomm_send_fcoff(struct rfcomm_session *s, int cr)
++{
++ struct rfcomm_hdr *hdr;
++ struct rfcomm_mcc *mcc;
++ u8 buf[16], *ptr = buf;
++
++ BT_DBG("%p cr %d", s, cr);
++
++ hdr = (void *) ptr; ptr += sizeof(*hdr);
++ hdr->addr = __addr(s->initiator, 0);
++ hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
++ hdr->len = __len8(sizeof(*mcc));
++
++ mcc = (void *) ptr; ptr += sizeof(*mcc);
++ mcc->type = __mcc_type(cr, RFCOMM_FCOFF);
++ mcc->len = __len8(0);
++
++ *ptr = __fcs(buf); ptr++;
++
++ return rfcomm_send_frame(s, buf, ptr - buf);
++}
++
++static int rfcomm_send_fcon(struct rfcomm_session *s, int cr)
++{
++ struct rfcomm_hdr *hdr;
++ struct rfcomm_mcc *mcc;
++ u8 buf[16], *ptr = buf;
++
++ BT_DBG("%p cr %d", s, cr);
++
++ hdr = (void *) ptr; ptr += sizeof(*hdr);
++ hdr->addr = __addr(s->initiator, 0);
++ hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
++ hdr->len = __len8(sizeof(*mcc));
++
++ mcc = (void *) ptr; ptr += sizeof(*mcc);
++ mcc->type = __mcc_type(cr, RFCOMM_FCON);
++ mcc->len = __len8(0);
+
+ *ptr = __fcs(buf); ptr++;
+
+@@ -1085,6 +1131,8 @@
+ d->state = BT_CONNECTED;
+ d->state_change(d, 0);
+ rfcomm_dlc_unlock(d);
++
++ rfcomm_send_msc(s, 1, dlci, d->v24_sig);
+ } else {
+ rfcomm_send_dm(s, dlci);
+ }
+@@ -1207,6 +1255,14 @@
+ }
+ /* check for sane values: ignore/accept bit_rate, 8 bits, 1 stop bit, no parity,
+ no flow control lines, normal XON/XOFF chars */
++ if (rpn->param_mask & RFCOMM_RPN_PM_BITRATE) {
++ bit_rate = rpn->bit_rate;
++ if (bit_rate != RFCOMM_RPN_BR_115200) {
++ BT_DBG("RPN bit rate mismatch 0x%x", bit_rate);
++ bit_rate = RFCOMM_RPN_BR_115200;
++ rpn_mask ^= RFCOMM_RPN_PM_BITRATE;
++ }
++ }
+ if (rpn->param_mask & RFCOMM_RPN_PM_DATA) {
+ data_bits = __get_rpn_data_bits(rpn->line_settings);
+ if (data_bits != RFCOMM_RPN_DATA_8) {
+@@ -1232,22 +1288,25 @@
+ }
+ }
+ if (rpn->param_mask & RFCOMM_RPN_PM_FLOW) {
+- if (rpn->flow_ctrl != RFCOMM_RPN_FLOW_NONE) {
+- BT_DBG("RPN flow ctrl mismatch 0x%x", rpn->flow_ctrl);
++ flow_ctrl = rpn->flow_ctrl;
++ if (flow_ctrl != RFCOMM_RPN_FLOW_NONE) {
++ BT_DBG("RPN flow ctrl mismatch 0x%x", flow_ctrl);
+ flow_ctrl = RFCOMM_RPN_FLOW_NONE;
+ rpn_mask ^= RFCOMM_RPN_PM_FLOW;
+ }
+ }
+ if (rpn->param_mask & RFCOMM_RPN_PM_XON) {
+- if (rpn->xon_char != RFCOMM_RPN_XON_CHAR) {
+- BT_DBG("RPN XON char mismatch 0x%x", rpn->xon_char);
++ xon_char = rpn->xon_char;
++ if (xon_char != RFCOMM_RPN_XON_CHAR) {
++ BT_DBG("RPN XON char mismatch 0x%x", xon_char);
+ xon_char = RFCOMM_RPN_XON_CHAR;
+ rpn_mask ^= RFCOMM_RPN_PM_XON;
+ }
+ }
+ if (rpn->param_mask & RFCOMM_RPN_PM_XOFF) {
+- if (rpn->xoff_char != RFCOMM_RPN_XOFF_CHAR) {
+- BT_DBG("RPN XOFF char mismatch 0x%x", rpn->xoff_char);
++ xoff_char = rpn->xoff_char;
++ if (xoff_char != RFCOMM_RPN_XOFF_CHAR) {
++ BT_DBG("RPN XOFF char mismatch 0x%x", xoff_char);
+ xoff_char = RFCOMM_RPN_XOFF_CHAR;
+ rpn_mask ^= RFCOMM_RPN_PM_XOFF;
+ }
+@@ -1343,6 +1402,20 @@
+ rfcomm_recv_msc(s, cr, skb);
+ break;
+
++ case RFCOMM_FCOFF:
++ if (cr) {
++ set_bit(RFCOMM_TX_THROTTLED, &s->flags);
++ rfcomm_send_fcoff(s, 0);
++ }
++ break;
++
++ case RFCOMM_FCON:
++ if (cr) {
++ clear_bit(RFCOMM_TX_THROTTLED, &s->flags);
++ rfcomm_send_fcon(s, 0);
++ }
++ break;
++
+ case RFCOMM_TEST:
+ if (cr)
+ rfcomm_send_test(s, 0, skb->data, skb->len);
+@@ -1533,6 +1606,9 @@
+ continue;
+ }
+
++ if (test_bit(RFCOMM_TX_THROTTLED, &s->flags))
++ continue;
++
+ if ((d->state == BT_CONNECTED || d->state == BT_DISCONN) &&
+ d->mscex == RFCOMM_MSCEX_OK)
+ rfcomm_process_tx(d);
+@@ -1881,7 +1957,7 @@
+ {
+ l2cap_load();
+
+- kernel_thread(rfcomm_run, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++ kernel_thread(rfcomm_run, NULL, CLONE_KERNEL);
+
+ BT_INFO("RFCOMM ver %s", VERSION);
+
+Index: linux-2.6.0-test5/net/bluetooth/rfcomm/sock.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/bluetooth/rfcomm/sock.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/bluetooth/rfcomm/sock.c 2003-09-27 11:38:41.623200696 +0800
+@@ -192,8 +192,10 @@
+ BT_DBG("parent %p", parent);
+
+ /* Close not yet accepted dlcs */
+- while ((sk = bt_accept_dequeue(parent, NULL)))
++ while ((sk = bt_accept_dequeue(parent, NULL))) {
+ rfcomm_sock_close(sk);
++ rfcomm_sock_kill(sk);
++ }
+
+ parent->sk_state = BT_CLOSED;
+ parent->sk_zapped = 1;
+@@ -215,15 +217,10 @@
+ sock_put(sk);
+ }
+
+-/* Close socket.
+- * Must be called on unlocked socket.
+- */
+-static void rfcomm_sock_close(struct sock *sk)
++static void __rfcomm_sock_close(struct sock *sk)
+ {
+ struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
+
+- lock_sock(sk);
+-
+ BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
+
+ switch (sk->sk_state) {
+@@ -240,11 +237,17 @@
+ default:
+ sk->sk_zapped = 1;
+ break;
+- };
++ }
++}
+
++/* Close socket.
++ * Must be called on unlocked socket.
++ */
++static void rfcomm_sock_close(struct sock *sk)
++{
++ lock_sock(sk);
++ __rfcomm_sock_close(sk);
+ release_sock(sk);
+-
+- rfcomm_sock_kill(sk);
+ }
+
+ static void rfcomm_sock_init(struct sock *sk, struct sock *parent)
+@@ -374,7 +377,8 @@
+
+ err = rfcomm_dlc_open(d, &bt_sk(sk)->src, &sa->rc_bdaddr, sa->rc_channel);
+ if (!err)
+- err = bt_sock_w4_connect(sk, flags);
++ err = bt_sock_wait_state(sk, BT_CONNECTED,
++ sock_sndtimeo(sk, flags & O_NONBLOCK));
+
+ release_sock(sk);
+ return err;
+@@ -558,9 +562,6 @@
+ int target, err = 0, copied = 0;
+ long timeo;
+
+- if (sk->sk_state != BT_CONNECTED)
+- return -EINVAL;
+-
+ if (flags & MSG_OOB)
+ return -EOPNOTSUPP;
+
+@@ -635,23 +636,6 @@
+ return copied ? : err;
+ }
+
+-static int rfcomm_sock_shutdown(struct socket *sock, int how)
+-{
+- struct sock *sk = sock->sk;
+-
+- BT_DBG("sock %p, sk %p", sock, sk);
+-
+- if (!sk) return 0;
+-
+- lock_sock(sk);
+- sk->sk_shutdown = SHUTDOWN_MASK;
+- if (sk->sk_state == BT_CONNECTED)
+- rfcomm_dlc_close(rfcomm_pi(sk)->dlc, 0);
+- release_sock(sk);
+-
+- return 0;
+-}
+-
+ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
+ {
+ struct sock *sk = sock->sk;
+@@ -710,19 +694,42 @@
+ return err;
+ }
+
++static int rfcomm_sock_shutdown(struct socket *sock, int how)
++{
++ struct sock *sk = sock->sk;
++ int err = 0;
++
++ BT_DBG("sock %p, sk %p", sock, sk);
++
++ if (!sk) return 0;
++
++ lock_sock(sk);
++ if (!sk->sk_shutdown) {
++ sk->sk_shutdown = SHUTDOWN_MASK;
++ __rfcomm_sock_close(sk);
++
++ if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
++ err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime);
++ }
++ release_sock(sk);
++ return err;
++}
++
+ static int rfcomm_sock_release(struct socket *sock)
+ {
+ struct sock *sk = sock->sk;
++ int err;
+
+ BT_DBG("sock %p, sk %p", sock, sk);
+
+ if (!sk)
+ return 0;
+
+- sock_orphan(sk);
+- rfcomm_sock_close(sk);
++ err = rfcomm_sock_shutdown(sock, 2);
+
+- return 0;
++ sock_orphan(sk);
++ rfcomm_sock_kill(sk);
++ return err;
+ }
+
+ /* ---- RFCOMM core layer callbacks ----
+Index: linux-2.6.0-test5/net/bluetooth/rfcomm/tty.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/bluetooth/rfcomm/tty.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/bluetooth/rfcomm/tty.c 2003-09-27 11:38:41.629199784 +0800
+@@ -668,40 +668,8 @@
+ return room;
+ }
+
+-static int rfcomm_tty_set_modem_status(uint cmd, struct rfcomm_dlc *dlc, uint status)
+-{
+- u8 v24_sig, mask;
+-
+- BT_DBG("dlc %p cmd 0x%02x", dlc, cmd);
+-
+- if (cmd == TIOCMSET)
+- v24_sig = 0;
+- else
+- rfcomm_dlc_get_modem_status(dlc, &v24_sig);
+-
+- mask = ((status & TIOCM_DSR) ? RFCOMM_V24_RTC : 0) |
+- ((status & TIOCM_DTR) ? RFCOMM_V24_RTC : 0) |
+- ((status & TIOCM_RTS) ? RFCOMM_V24_RTR : 0) |
+- ((status & TIOCM_CTS) ? RFCOMM_V24_RTR : 0) |
+- ((status & TIOCM_RI) ? RFCOMM_V24_IC : 0) |
+- ((status & TIOCM_CD) ? RFCOMM_V24_DV : 0);
+-
+- if (cmd == TIOCMBIC)
+- v24_sig &= ~mask;
+- else
+- v24_sig |= mask;
+-
+- rfcomm_dlc_set_modem_status(dlc, v24_sig);
+- return 0;
+-}
+-
+ static int rfcomm_tty_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd, unsigned long arg)
+ {
+- struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
+- struct rfcomm_dlc *dlc = dev->dlc;
+- uint status;
+- int err;
+-
+ BT_DBG("tty %p cmd 0x%02x", tty, cmd);
+
+ switch (cmd) {
+@@ -713,18 +681,6 @@
+ BT_DBG("TCSETS is not supported");
+ return -ENOIOCTLCMD;
+
+- case TIOCMGET:
+- BT_DBG("TIOCMGET");
+-
+- return put_user(dev->modem_status, (unsigned int *)arg);
+-
+- case TIOCMSET: /* Turns on and off the lines as specified by the mask */
+- case TIOCMBIS: /* Turns on the lines as specified by the mask */
+- case TIOCMBIC: /* Turns off the lines as specified by the mask */
+- if ((err = get_user(status, (unsigned int *)arg)))
+- return err;
+- return rfcomm_tty_set_modem_status(cmd, dlc, status);
+-
+ case TIOCMIWAIT:
+ BT_DBG("TIOCMIWAIT");
+ break;
+@@ -851,6 +807,48 @@
+ return 0;
+ }
+
++static int rfcomm_tty_tiocmget(struct tty_struct *tty, struct file *filp)
++{
++ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
++
++ BT_DBG("tty %p dev %p", tty, dev);
++
++ return dev->modem_status;
++}
++
++static int rfcomm_tty_tiocmset(struct tty_struct *tty, struct file *filp, unsigned int set, unsigned int clear)
++{
++ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
++ struct rfcomm_dlc *dlc = dev->dlc;
++ u8 v24_sig;
++
++ BT_DBG("tty %p dev %p set 0x%02x clear 0x%02x", tty, dev, set, clear);
++
++ rfcomm_dlc_get_modem_status(dlc, &v24_sig);
++
++ if (set & TIOCM_DSR || set & TIOCM_DTR)
++ v24_sig |= RFCOMM_V24_RTC;
++ if (set & TIOCM_RTS || set & TIOCM_CTS)
++ v24_sig |= RFCOMM_V24_RTR;
++ if (set & TIOCM_RI)
++ v24_sig |= RFCOMM_V24_IC;
++ if (set & TIOCM_CD)
++ v24_sig |= RFCOMM_V24_DV;
++
++ if (clear & TIOCM_DSR || clear & TIOCM_DTR)
++ v24_sig &= ~RFCOMM_V24_RTC;
++ if (clear & TIOCM_RTS || clear & TIOCM_CTS)
++ v24_sig &= ~RFCOMM_V24_RTR;
++ if (clear & TIOCM_RI)
++ v24_sig &= ~RFCOMM_V24_IC;
++ if (clear & TIOCM_CD)
++ v24_sig &= ~RFCOMM_V24_DV;
++
++ rfcomm_dlc_set_modem_status(dlc, v24_sig);
++
++ return 0;
++}
++
+ /* ---- TTY structure ---- */
+
+ static struct tty_driver *rfcomm_tty_driver;
+@@ -870,6 +868,8 @@
+ .hangup = rfcomm_tty_hangup,
+ .wait_until_sent = rfcomm_tty_wait_until_sent,
+ .read_proc = rfcomm_tty_read_proc,
++ .tiocmget = rfcomm_tty_tiocmget,
++ .tiocmset = rfcomm_tty_tiocmset,
+ };
+
+ int rfcomm_init_ttys(void)
+@@ -878,18 +878,17 @@
+ if (!rfcomm_tty_driver)
+ return -1;
+
+- rfcomm_tty_driver->owner = THIS_MODULE,
+- rfcomm_tty_driver->driver_name = "rfcomm",
+- rfcomm_tty_driver->devfs_name = "bluetooth/rfcomm/",
+- rfcomm_tty_driver->name = "rfcomm",
+- rfcomm_tty_driver->major = RFCOMM_TTY_MAJOR,
+- rfcomm_tty_driver->minor_start = RFCOMM_TTY_MINOR,
+- rfcomm_tty_driver->type = TTY_DRIVER_TYPE_SERIAL,
+- rfcomm_tty_driver->subtype = SERIAL_TYPE_NORMAL,
+- rfcomm_tty_driver->flags = TTY_DRIVER_REAL_RAW,
+- rfcomm_tty_driver->init_termios = tty_std_termios;
+- rfcomm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+- rfcomm_tty_driver->flags = TTY_DRIVER_REAL_RAW;
++ rfcomm_tty_driver->owner = THIS_MODULE;
++ rfcomm_tty_driver->driver_name = "rfcomm";
++ rfcomm_tty_driver->devfs_name = "bluetooth/rfcomm/";
++ rfcomm_tty_driver->name = "rfcomm";
++ rfcomm_tty_driver->major = RFCOMM_TTY_MAJOR;
++ rfcomm_tty_driver->minor_start = RFCOMM_TTY_MINOR;
++ rfcomm_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
++ rfcomm_tty_driver->subtype = SERIAL_TYPE_NORMAL;
++ rfcomm_tty_driver->flags = TTY_DRIVER_REAL_RAW;
++ rfcomm_tty_driver->init_termios = tty_std_termios;
++ rfcomm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+ tty_set_operations(rfcomm_tty_driver, &rfcomm_ops);
+
+ if (tty_register_driver(rfcomm_tty_driver)) {
+Index: linux-2.6.0-test5/net/bluetooth/sco.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/bluetooth/sco.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/bluetooth/sco.c 2003-09-27 11:38:41.636198720 +0800
+@@ -353,8 +353,10 @@
+ BT_DBG("parent %p", parent);
+
+ /* Close not yet accepted channels */
+- while ((sk = bt_accept_dequeue(parent, NULL)))
++ while ((sk = bt_accept_dequeue(parent, NULL))) {
+ sco_sock_close(sk);
++ sco_sock_kill(sk);
++ }
+
+ parent->sk_state = BT_CLOSED;
+ parent->sk_zapped = 1;
+@@ -523,7 +525,8 @@
+ if ((err = sco_connect(sk)))
+ goto done;
+
+- err = bt_sock_w4_connect(sk, flags);
++ err = bt_sock_wait_state(sk, BT_CONNECTED,
++ sock_sndtimeo(sk, flags & O_NONBLOCK));
+
+ done:
+ release_sock(sk);
+@@ -727,16 +730,24 @@
+ static int sco_sock_release(struct socket *sock)
+ {
+ struct sock *sk = sock->sk;
++ int err = 0;
+
+ BT_DBG("sock %p, sk %p", sock, sk);
+
+ if (!sk)
+ return 0;
+-
+- sock_orphan(sk);
++
+ sco_sock_close(sk);
+
+- return 0;
++ if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) {
++ lock_sock(sk);
++ err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime);
++ release_sock(sk);
++ }
++
++ sock_orphan(sk);
++ sco_sock_kill(sk);
++ return err;
+ }
+
+ static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent)
+Index: linux-2.6.0-test5/net/bluetooth/syms.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/bluetooth/syms.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/bluetooth/syms.c 2003-09-27 11:38:41.637198568 +0800
+@@ -77,6 +77,6 @@
+ EXPORT_SYMBOL(bt_sock_poll);
+ EXPORT_SYMBOL(bt_accept_enqueue);
+ EXPORT_SYMBOL(bt_accept_dequeue);
+-EXPORT_SYMBOL(bt_sock_w4_connect);
++EXPORT_SYMBOL(bt_sock_wait_state);
+
+ EXPORT_SYMBOL(proc_bt);
+Index: linux-2.6.0-test5/net/bridge/br_forward.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/bridge/br_forward.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/bridge/br_forward.c 2003-09-27 11:38:41.639198264 +0800
+@@ -69,6 +69,7 @@
+
+ indev = skb->dev;
+ skb->dev = to->dev;
++ skb->ip_summed = CHECKSUM_NONE;
+
+ NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, indev, skb->dev,
+ br_forward_finish);
+Index: linux-2.6.0-test5/net/core/dev.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/core/dev.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/core/dev.c 2003-09-27 11:38:41.659195224 +0800
+@@ -183,6 +183,10 @@
+
+ extern int netdev_sysfs_init(void);
+ extern int netdev_register_sysfs(struct net_device *);
++extern int netdev_unregister_sysfs(struct net_device *);
++#ifdef CONFIG_KGDB
++extern int kgdb_net_interrupt(struct sk_buff *skb);
++#endif
+
+
+ /*******************************************************************************
+@@ -470,10 +474,10 @@
+ * to be sure the name is not allocated or removed during the test the
+ * caller must hold the rtnl semaphore.
+ *
+- * This function primarily exists for back compatibility with older
++ * This function exists only for back compatibility with older
+ * drivers.
+ */
+-int dev_get(const char *name)
++int __dev_get(const char *name)
+ {
+ struct net_device *dev;
+
+@@ -698,7 +702,13 @@
+
+ void dev_load(const char *name)
+ {
+- if (!dev_get(name) && capable(CAP_SYS_MODULE))
++ struct net_device *dev;
++
++ read_lock(&dev_base_lock);
++ dev = __dev_get_by_name(name);
++ read_unlock(&dev_base_lock);
++
++ if (!dev && capable(CAP_SYS_MODULE))
+ request_module("%s", name);
+ }
+
+@@ -841,7 +851,11 @@
+ * engine, but this requires more changes in devices. */
+
+ smp_mb__after_clear_bit(); /* Commit netif_running(). */
+- netif_poll_disable(dev);
++ while (test_bit(__LINK_STATE_RX_SCHED, &dev->state)) {
++ /* No hurry. */
++ current->state = TASK_INTERRUPTIBLE;
++ schedule_timeout(1);
++ }
+
+ /*
+ * Call the device specific close. This cannot fail.
+@@ -1315,7 +1329,6 @@
+ }
+ #endif
+
+-
+ /**
+ * netif_rx - post buffer to the network code
+ * @skb: buffer to post
+@@ -1340,6 +1353,21 @@
+ struct softnet_data *queue;
+ unsigned long flags;
+
++#ifdef CONFIG_KGDB
++ /* See if kgdb_eth wants this packet */
++ if (!kgdb_net_interrupt(skb)) {
++ /* No.. if we're 'trapped' then junk it */
++ if (kgdb_eth_is_trapped()) {
++ kfree_skb(skb);
++ return NET_RX_DROP;
++ }
++ } else {
++ /* kgdb_eth ate the packet... drop it silently */
++ kfree_skb(skb);
++ return NET_RX_DROP;
++ }
++#endif
++
+ if (!skb->stamp.tv_sec)
+ do_gettimeofday(&skb->stamp);
+
+@@ -1840,13 +1868,13 @@
+ void *dev_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+ read_lock(&dev_base_lock);
+- return *pos ? dev_get_idx(*pos - 1) : (void *)1;
++ return *pos ? dev_get_idx(*pos - 1) : SEQ_START_TOKEN;
+ }
+
+ void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
+ ++*pos;
+- return v == (void *)1 ? dev_base : ((struct net_device *)v)->next;
++ return v == SEQ_START_TOKEN ? dev_base : ((struct net_device *)v)->next;
+ }
+
+ void dev_seq_stop(struct seq_file *seq, void *v)
+@@ -1886,7 +1914,7 @@
+ */
+ static int dev_seq_show(struct seq_file *seq, void *v)
+ {
+- if (v == (void *)1)
++ if (v == SEQ_START_TOKEN)
+ seq_puts(seq, "Inter-| Receive "
+ " | Transmit\n"
+ " face |bytes packets errs drop fifo frame "
+@@ -1990,26 +2018,21 @@
+
+ static int __init dev_proc_init(void)
+ {
+- struct proc_dir_entry *p;
+ int rc = -ENOMEM;
+
+- p = create_proc_entry("dev", S_IRUGO, proc_net);
+- if (!p)
++ if (!proc_net_fops_create("dev", S_IRUGO, &dev_seq_fops))
+ goto out;
+- p->proc_fops = &dev_seq_fops;
+- p = create_proc_entry("softnet_stat", S_IRUGO, proc_net);
+- if (!p)
++ if (!proc_net_fops_create("softnet_stat", S_IRUGO, &softnet_seq_fops))
+ goto out_dev;
+- p->proc_fops = &softnet_seq_fops;
+ if (wireless_proc_init())
+ goto out_softnet;
+ rc = 0;
+ out:
+ return rc;
+ out_softnet:
+- remove_proc_entry("softnet_stat", proc_net);
++ proc_net_remove("softnet_stat");
+ out_dev:
+- remove_proc_entry("dev", proc_net);
++ proc_net_remove("dev");
+ goto out;
+ }
+ #else
+@@ -2755,7 +2778,6 @@
+
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(HZ / 4);
+- current->state = TASK_RUNNING;
+
+ if (time_after(jiffies, warning_time + 10 * HZ)) {
+ printk(KERN_EMERG "unregister_netdevice: "
+@@ -2819,7 +2841,7 @@
+ break;
+
+ case NETREG_UNREGISTERING:
+- class_device_del(&dev->class_dev);
++ netdev_unregister_sysfs(dev);
+ dev->reg_state = NETREG_UNREGISTERED;
+
+ netdev_wait_allrefs(dev);
+Index: linux-2.6.0-test5/net/core/net-sysfs.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/core/net-sysfs.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/core/net-sysfs.c 2003-09-27 11:38:41.662194768 +0800
+@@ -383,6 +383,21 @@
+ #endif
+ };
+
++void netdev_unregister_sysfs(struct net_device * net)
++{
++ struct class_device * class_dev = &(net->class_dev);
++
++ if (net->get_stats)
++ sysfs_remove_group(&class_dev->kobj, &netstat_group);
++
++#ifdef WIRELESS_EXT
++ if (net->get_wireless_stats)
++ sysfs_remove_group(&class_dev->kobj, &wireless_group);
++#endif
++ class_device_del(class_dev);
++
++}
++
+ /* Create sysfs entries for network device. */
+ int netdev_register_sysfs(struct net_device *net)
+ {
+@@ -411,9 +426,15 @@
+ #ifdef WIRELESS_EXT
+ if (net->get_wireless_stats &&
+ (ret = sysfs_create_group(&class_dev->kobj, &wireless_group)))
+- goto out_unreg;
+-#endif
++ goto out_cleanup;
++
++ return 0;
++out_cleanup:
++ if (net->get_stats)
++ sysfs_remove_group(&class_dev->kobj, &netstat_group);
++#else
+ return 0;
++#endif
+
+ out_unreg:
+ printk(KERN_WARNING "%s: sysfs attribute registration failed %d\n",
+Index: linux-2.6.0-test5/net/core/wireless.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/core/wireless.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/core/wireless.c 2003-09-27 11:38:41.673193096 +0800
+@@ -458,7 +458,7 @@
+ */
+ static int wireless_seq_show(struct seq_file *seq, void *v)
+ {
+- if (v == (void *)1)
++ if (v == SEQ_START_TOKEN)
+ seq_printf(seq, "Inter-| sta-| Quality | Discarded "
+ "packets | Missed | WE\n"
+ " face | tus | link level noise | nwid "
+@@ -495,15 +495,10 @@
+
+ int __init wireless_proc_init(void)
+ {
+- struct proc_dir_entry *p;
+- int rc = 0;
++ if (!proc_net_fops_create("wireless", S_IRUGO, &wireless_seq_fops))
++ return -ENOMEM;
+
+- p = create_proc_entry("wireless", S_IRUGO, proc_net);
+- if (p)
+- p->proc_fops = &wireless_seq_fops;
+- else
+- rc = -ENOMEM;
+- return rc;
++ return 0;
+ }
+ #endif /* CONFIG_PROC_FS */
+
+Index: linux-2.6.0-test5/net/decnet/af_decnet.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/decnet/af_decnet.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/decnet/af_decnet.c 2003-09-27 11:38:41.688190816 +0800
+@@ -2146,14 +2146,14 @@
+
+ static void *dn_socket_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+- return *pos ? dn_socket_get_idx(seq, *pos - 1) : (void*)1;
++ return *pos ? dn_socket_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+ }
+
+ static void *dn_socket_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
+ void *rc;
+
+- if (v == (void*)1) {
++ if (v == SEQ_START_TOKEN) {
+ rc = dn_socket_get_idx(seq, 0);
+ goto out;
+ }
+@@ -2169,7 +2169,7 @@
+
+ static void dn_socket_seq_stop(struct seq_file *seq, void *v)
+ {
+- if (v && v != (void*)1)
++ if (v && v != SEQ_START_TOKEN)
+ read_unlock_bh(&dn_hash_lock);
+ }
+
+@@ -2269,7 +2269,7 @@
+
+ static int dn_socket_seq_show(struct seq_file *seq, void *v)
+ {
+- if (v == (void*)1) {
++ if (v == SEQ_START_TOKEN) {
+ seq_puts(seq, "Local Remote\n");
+ } else {
+ dn_socket_format_entry(seq, v);
+Index: linux-2.6.0-test5/net/decnet/dn_dev.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/decnet/dn_dev.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/decnet/dn_dev.c 2003-09-27 11:38:41.698189296 +0800
+@@ -1365,7 +1365,7 @@
+ read_unlock(&dev_base_lock);
+ return dev;
+ }
+- return (void*)1;
++ return SEQ_START_TOKEN;
+ }
+
+ static void *dn_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -1373,7 +1373,7 @@
+ struct net_device *dev = v;
+ loff_t one = 1;
+
+- if (v == (void*)1) {
++ if (v == SEQ_START_TOKEN) {
+ dev = dn_dev_seq_start(seq, &one);
+ } else {
+ dev = dn_dev_get_next(seq, dev);
+@@ -1386,7 +1386,7 @@
+
+ static void dn_dev_seq_stop(struct seq_file *seq, void *v)
+ {
+- if (v && v != (void*)1)
++ if (v && v != SEQ_START_TOKEN)
+ read_unlock(&dev_base_lock);
+ }
+
+@@ -1406,7 +1406,7 @@
+
+ static int dn_dev_seq_show(struct seq_file *seq, void *v)
+ {
+- if (v == (void*)1)
++ if (v == SEQ_START_TOKEN)
+ seq_puts(seq, "Name Flags T1 Timer1 T3 Timer3 BlkSize Pri State DevType Router Peer\n");
+ else {
+ struct net_device *dev = v;
+Index: linux-2.6.0-test5/net/decnet/dn_neigh.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/decnet/dn_neigh.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/decnet/dn_neigh.c 2003-09-27 11:38:41.703188536 +0800
+@@ -604,7 +604,7 @@
+
+ static void *dn_neigh_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+- return *pos ? dn_neigh_get_idx(seq, *pos - 1) : (void*)1;
++ return *pos ? dn_neigh_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+ }
+
+ static void *dn_neigh_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -612,7 +612,7 @@
+ void *rc;
+
+
+- if (v == (void*)1) {
++ if (v == SEQ_START_TOKEN) {
+ rc = dn_neigh_get_idx(seq, 0);
+ goto out;
+ }
+@@ -628,7 +628,7 @@
+
+ static void dn_neigh_seq_stop(struct seq_file *seq, void *v)
+ {
+- if (v && v != (void*)1)
++ if (v && v != SEQ_START_TOKEN)
+ read_unlock_bh(&dn_neigh_table.lock);
+ }
+
+@@ -653,7 +653,7 @@
+
+ static int dn_neigh_seq_show(struct seq_file *seq, void *v)
+ {
+- if (v == (void*)1) {
++ if (v == SEQ_START_TOKEN) {
+ seq_puts(seq, "Addr Flags State Use Blksize Dev\n");
+ } else {
+ dn_neigh_format_entry(seq, v);
+Index: linux-2.6.0-test5/net/ipv4/arp.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/arp.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/arp.c 2003-09-27 11:38:41.712187168 +0800
+@@ -1275,7 +1275,7 @@
+
+ static void *arp_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+- return *pos ? arp_get_idx(seq, *pos - 1) : (void *)1;
++ return *pos ? arp_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+ }
+
+ static void *arp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -1283,7 +1283,7 @@
+ void *rc;
+ struct arp_iter_state* state;
+
+- if (v == (void *)1) {
++ if (v == SEQ_START_TOKEN) {
+ rc = arp_get_idx(seq, 0);
+ goto out;
+ }
+@@ -1306,7 +1306,7 @@
+ {
+ struct arp_iter_state* state = seq->private;
+
+- if (!state->is_pneigh && v != (void *)1)
++ if (!state->is_pneigh && v != SEQ_START_TOKEN)
+ read_unlock_bh(&arp_tbl.lock);
+ }
+
+@@ -1359,7 +1359,7 @@
+
+ static int arp_seq_show(struct seq_file *seq, void *v)
+ {
+- if (v == (void *)1)
++ if (v == SEQ_START_TOKEN)
+ seq_puts(seq, "IP address HW type Flags "
+ "HW address Mask Device\n");
+ else {
+@@ -1416,14 +1416,9 @@
+
+ static int __init arp_proc_init(void)
+ {
+- int rc = 0;
+- struct proc_dir_entry *p = create_proc_entry("arp", S_IRUGO, proc_net);
+-
+- if (p)
+- p->proc_fops = &arp_seq_fops;
+- else
+- rc = -ENOMEM;
+- return rc;
++ if (!proc_net_fops_create("arp", S_IRUGO, &arp_seq_fops))
++ return -ENOMEM;
++ return 0;
+ }
+
+ #else /* CONFIG_PROC_FS */
+Index: linux-2.6.0-test5/net/ipv4/fib_hash.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/fib_hash.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/fib_hash.c 2003-09-27 11:38:41.720185952 +0800
+@@ -979,14 +979,14 @@
+
+ read_lock(&fib_hash_lock);
+ if (ip_fib_main_table)
+- v = *pos ? fib_get_next(seq) : (void *)1;
++ v = *pos ? fib_get_next(seq) : SEQ_START_TOKEN;
+ return v;
+ }
+
+ static void *fib_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
+ ++*pos;
+- return v == (void *)1 ? fib_get_first(seq) : fib_get_next(seq);
++ return v == SEQ_START_TOKEN ? fib_get_first(seq) : fib_get_next(seq);
+ }
+
+ static void fib_seq_stop(struct seq_file *seq, void *v)
+@@ -1025,7 +1025,7 @@
+ struct fib_node *f;
+ struct fib_info *fi;
+
+- if (v == (void *)1) {
++ if (v == SEQ_START_TOKEN) {
+ seq_printf(seq, "%-127s\n", "Iface\tDestination\tGateway "
+ "\tFlags\tRefCnt\tUse\tMetric\tMask\t\tMTU"
+ "\tWindow\tIRTT");
+@@ -1096,19 +1096,13 @@
+
+ int __init fib_proc_init(void)
+ {
+- struct proc_dir_entry *p;
+- int rc = 0;
+-
+- p = create_proc_entry("route", S_IRUGO, proc_net);
+- if (p)
+- p->proc_fops = &fib_seq_fops;
+- else
+- rc = -ENOMEM;
+- return rc;
++ if (!proc_net_fops_create("route", S_IRUGO, &fib_seq_fops))
++ return -ENOMEM;
++ return 0;
+ }
+
+ void __init fib_proc_exit(void)
+ {
+- remove_proc_entry("route", proc_net);
++ proc_net_remove("route");
+ }
+ #endif /* CONFIG_PROC_FS */
+Index: linux-2.6.0-test5/net/ipv4/icmp.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/icmp.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/icmp.c 2003-09-27 11:38:41.728184736 +0800
+@@ -669,7 +669,7 @@
+ printk(KERN_WARNING "%u.%u.%u.%u sent an invalid ICMP "
+ "type %u, code %u "
+ "error to a broadcast: %u.%u.%u.%u on %s\n",
+- NIPQUAD(iph->saddr),
++ NIPQUAD(skb->nh.iph->saddr),
+ icmph->type, icmph->code,
+ NIPQUAD(iph->daddr),
+ skb->dev->name);
+Index: linux-2.6.0-test5/net/ipv4/igmp.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/igmp.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/igmp.c 2003-09-27 11:38:41.744182304 +0800
+@@ -280,8 +280,10 @@
+ .nl_u = { .ip4_u = {
+ .daddr = IGMPV3_ALL_MCR } },
+ .proto = IPPROTO_IGMP };
+- if (ip_route_output_key(&rt, &fl))
++ if (ip_route_output_key(&rt, &fl)) {
++ kfree_skb(skb);
+ return 0;
++ }
+ }
+ if (rt->rt_src == 0) {
+ ip_rt_put(rt);
+@@ -2162,13 +2164,13 @@
+ static void *igmp_mc_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+ read_lock(&dev_base_lock);
+- return *pos ? igmp_mc_get_idx(seq, *pos) : (void *)1;
++ return *pos ? igmp_mc_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+ }
+
+ static void *igmp_mc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
+ struct ip_mc_list *im;
+- if (v == (void *)1)
++ if (v == SEQ_START_TOKEN)
+ im = igmp_mc_get_first(seq);
+ else
+ im = igmp_mc_get_next(seq, v);
+@@ -2190,7 +2192,7 @@
+
+ static int igmp_mc_seq_show(struct seq_file *seq, void *v)
+ {
+- if (v == (void *)1)
++ if (v == SEQ_START_TOKEN)
+ seq_printf(seq,
+ "Idx\tDevice : Count Querier\tGroup Users Timer\tReporter\n");
+ else {
+@@ -2337,13 +2339,13 @@
+ static void *igmp_mcf_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+ read_lock(&dev_base_lock);
+- return *pos ? igmp_mcf_get_idx(seq, *pos) : (void *)1;
++ return *pos ? igmp_mcf_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+ }
+
+ static void *igmp_mcf_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
+ struct ip_sf_list *psf;
+- if (v == (void *)1)
++ if (v == SEQ_START_TOKEN)
+ psf = igmp_mcf_get_first(seq);
+ else
+ psf = igmp_mcf_get_next(seq, v);
+@@ -2372,7 +2374,7 @@
+ struct ip_sf_list *psf = (struct ip_sf_list *)v;
+ struct igmp_mcf_iter_state *state = igmp_mcf_seq_private(seq);
+
+- if (v == (void *)1) {
++ if (v == SEQ_START_TOKEN) {
+ seq_printf(seq,
+ "%3s %6s "
+ "%10s %10s %6s %6s\n", "Idx",
+@@ -2430,15 +2432,8 @@
+
+ int __init igmp_mc_proc_init(void)
+ {
+- struct proc_dir_entry *p;
+-
+- p = create_proc_entry("igmp", S_IRUGO, proc_net);
+- if (p)
+- p->proc_fops = &igmp_mc_seq_fops;
+-
+- p = create_proc_entry("mcfilter", S_IRUGO, proc_net);
+- if (p)
+- p->proc_fops = &igmp_mcf_seq_fops;
++ proc_net_fops_create("igmp", S_IRUGO, &igmp_mc_seq_fops);
++ proc_net_fops_create("mcfilter", S_IRUGO, &igmp_mcf_seq_fops);
+ return 0;
+ }
+ #endif
+Index: linux-2.6.0-test5/net/ipv4/ipconfig.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/ipconfig.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/ipconfig.c 2003-09-27 11:38:41.753180936 +0800
+@@ -50,6 +50,7 @@
+ #include <linux/route.h>
+ #include <linux/udp.h>
+ #include <linux/proc_fs.h>
++#include <linux/seq_file.h>
+ #include <linux/major.h>
+ #include <linux/root_dev.h>
+ #include <net/arp.h>
+@@ -1092,43 +1093,45 @@
+
+ #ifdef CONFIG_PROC_FS
+
+-static int pnp_get_info(char *buffer, char **start,
+- off_t offset, int length)
++static int pnp_seq_show(struct seq_file *seq, void *v)
+ {
+- int len;
+- int i;
++ int i;
+
+ if (ic_proto_used & IC_PROTO)
+- sprintf(buffer, "#PROTO: %s\n",
+- (ic_proto_used & IC_RARP) ? "RARP"
+- : (ic_proto_used & IC_USE_DHCP) ? "DHCP" : "BOOTP");
++ seq_printf(seq, "#PROTO: %s\n",
++ (ic_proto_used & IC_RARP) ? "RARP"
++ : (ic_proto_used & IC_USE_DHCP) ? "DHCP" : "BOOTP");
+ else
+- strcpy(buffer, "#MANUAL\n");
+- len = strlen(buffer);
++ seq_puts(seq, "#MANUAL\n");
+
+ if (ic_domain[0])
+- len += sprintf(buffer + len,
+- "domain %s\n", ic_domain);
++ seq_printf(seq,
++ "domain %s\n", ic_domain);
+ for (i = 0; i < CONF_NAMESERVERS_MAX; i++) {
+ if (ic_nameservers[i] != INADDR_NONE)
+- len += sprintf(buffer + len,
+- "nameserver %u.%u.%u.%u\n",
+- NIPQUAD(ic_nameservers[i]));
++ seq_printf(seq,
++ "nameserver %u.%u.%u.%u\n",
++ NIPQUAD(ic_nameservers[i]));
+ }
+ if (ic_servaddr != INADDR_NONE)
+- len += sprintf(buffer + len,
+- "bootserver %u.%u.%u.%u\n",
+- NIPQUAD(ic_servaddr));
+-
+- if (offset > len)
+- offset = len;
+- *start = buffer + offset;
+-
+- if (offset + length > len)
+- length = len - offset;
+- return length;
++ seq_printf(seq,
++ "bootserver %u.%u.%u.%u\n",
++ NIPQUAD(ic_servaddr));
++ return 0;
+ }
+
++static int pnp_seq_open(struct inode *indoe, struct file *file)
++{
++ return single_open(file, pnp_seq_show, NULL);
++}
++
++static struct file_operations pnp_seq_fops = {
++ .owner = THIS_MODULE,
++ .open = pnp_seq_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
+ #endif /* CONFIG_PROC_FS */
+
+ /*
+@@ -1140,7 +1143,7 @@
+ unsigned long jiff;
+
+ #ifdef CONFIG_PROC_FS
+- proc_net_create("pnp", 0, pnp_get_info);
++ proc_net_fops_create("pnp", S_IRUGO, &pnp_seq_fops);
+ #endif /* CONFIG_PROC_FS */
+
+ if (!ic_enable)
+@@ -1153,7 +1156,7 @@
+ /* Give hardware a chance to settle */
+ jiff = jiffies + CONF_PRE_OPEN;
+ while (time_before(jiffies, jiff))
+- ;
++ cpu_relax();
+
+ /* Setup all network devices */
+ if (ic_open_devs() < 0)
+@@ -1162,7 +1165,7 @@
+ /* Give drivers a chance to settle */
+ jiff = jiffies + CONF_POST_OPEN;
+ while (time_before(jiffies, jiff))
+- ;
++ cpu_relax();
+
+ /*
+ * If the config information is insufficient (e.g., our IP address or
+Index: linux-2.6.0-test5/net/ipv4/ip_input.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/ip_input.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/ip_input.c 2003-09-27 11:38:41.758180176 +0800
+@@ -201,6 +201,7 @@
+
+ #ifdef CONFIG_NETFILTER_DEBUG
+ nf_debug_ip_local_deliver(skb);
++ skb->nf_debug = 0;
+ #endif /*CONFIG_NETFILTER_DEBUG*/
+
+ __skb_pull(skb, ihl);
+Index: linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_app.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/ipvs/ip_vs_app.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_app.c 2003-09-27 11:38:41.762179568 +0800
+@@ -35,6 +35,7 @@
+ #include <asm/system.h>
+ #include <linux/stat.h>
+ #include <linux/proc_fs.h>
++#include <linux/seq_file.h>
+
+ #include <net/ip_vs.h>
+
+@@ -213,18 +214,14 @@
+ */
+ void unregister_ip_vs_app(struct ip_vs_app *app)
+ {
+- struct ip_vs_app *inc;
+- struct list_head *l = &app->incs_list;
++ struct ip_vs_app *inc, *nxt;
+
+ down(&__ip_vs_app_mutex);
+
+- while (l->next != l) {
+- inc = list_entry(l->next, struct ip_vs_app, a_list);
++ list_for_each_entry_safe(inc, nxt, &app->incs_list, a_list) {
+ ip_vs_app_inc_release(inc);
+ }
+
+- list_del(&app->a_list);
+-
+ up(&__ip_vs_app_mutex);
+
+ /* decrease the module use count */
+@@ -238,13 +235,11 @@
+ */
+ struct ip_vs_app *ip_vs_app_get_by_name(char *appname)
+ {
+- struct list_head *p;
+ struct ip_vs_app *app, *a = NULL;
+
+ down(&__ip_vs_app_mutex);
+
+- list_for_each (p, &ip_vs_app_list) {
+- app = list_entry(p, struct ip_vs_app, a_list);
++ list_for_each_entry(ent, &ip_vs_app_list, a_list) {
+ if (strcmp(app->name, appname))
+ continue;
+
+@@ -480,55 +475,99 @@
+ }
+
+
++#ifdef CONFIG_PROC_FS
+ /*
+ * /proc/net/ip_vs_app entry function
+ */
+-static int
+-ip_vs_app_getinfo(char *buffer, char **start, off_t offset, int length)
++
++static struct ip_vs_app *ip_vs_app_idx(loff_t pos)
+ {
+- off_t pos=0;
+- int len=0;
+- char temp[64];
+ struct ip_vs_app *app, *inc;
+- struct list_head *e, *i;
+
+- pos = 64;
+- if (pos > offset) {
+- len += sprintf(buffer+len, "%-63s\n",
+- "prot port usecnt name");
++ list_for_each_entry(app, &ip_vs_app_list, a_list) {
++ list_for_each_entry(inc, &app->incs_list, a_list) {
++ if (pos-- == 0)
++ return inc;
++ }
+ }
++ return NULL;
+
++}
++
++static void *ip_vs_app_seq_start(struct seq_file *seq, loff_t *pos)
++{
+ down(&__ip_vs_app_mutex);
+- list_for_each (e, &ip_vs_app_list) {
+- app = list_entry(e, struct ip_vs_app, a_list);
+- list_for_each (i, &app->incs_list) {
+- inc = list_entry(i, struct ip_vs_app, a_list);
++
++ return *pos ? ip_vs_app_idx(*pos - 1) : SEQ_START_TOKEN;
++}
++
++static void *ip_vs_app_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++{
++ struct ip_vs_app *inc, *app;
++ struct list_head *e;
++
++ ++*pos;
++ if (v == SEQ_START_TOKEN)
++ return ip_vs_app_idx(0);
++
++ inc = v;
++ app = inc->app;
+
+- pos += 64;
+- if (pos <= offset)
+- continue;
+- sprintf(temp, "%-3s %-7u %-6d %-17s",
+- ip_vs_proto_name(inc->protocol),
+- ntohs(inc->port),
+- atomic_read(&inc->usecnt),
+- inc->name);
+- len += sprintf(buffer+len, "%-63s\n", temp);
+- if (pos >= offset+length)
+- goto done;
++ if ((e = inc->a_list.next) != &app->incs_list)
++ return list_entry(e, struct ip_vs_app, a_list);
++
++ /* go on to next application */
++ for (e = app->a_list.next; e != &ip_vs_app_list; e = e->next) {
++ app = list_entry(e, struct ip_vs_app, a_list);
++ list_for_each_entry(inc, &app->incs_list, a_list) {
++ return inc;
+ }
+ }
+- done:
++ return NULL;
++}
++
++static void ip_vs_app_seq_stop(struct seq_file *seq, void *v)
++{
+ up(&__ip_vs_app_mutex);
++}
+
+- *start = buffer+len-(pos-offset); /* Start of wanted data */
+- len = pos-offset;
+- if (len > length)
+- len = length;
+- if (len < 0)
+- len = 0;
+- return len;
++static int ip_vs_app_seq_show(struct seq_file *seq, void *v)
++{
++ if (v == SEQ_START_TOKEN)
++ seq_puts(seq, "prot port usecnt name\n");
++ else {
++ const struct ip_vs_app *inc = v;
++
++ seq_printf(seq, "%-3s %-7u %-6d %-17s\n",
++ ip_vs_proto_name(inc->protocol),
++ ntohs(inc->port),
++ atomic_read(&inc->usecnt),
++ inc->name);
++ }
++ return 0;
+ }
+
++static struct seq_operations ip_vs_app_seq_ops = {
++ .start = ip_vs_app_seq_start,
++ .next = ip_vs_app_seq_next,
++ .stop = ip_vs_app_seq_stop,
++ .show = ip_vs_app_seq_show,
++};
++
++static int ip_vs_app_open(struct inode *inode, struct file *file)
++{
++ return seq_open(file, &ip_vs_app_seq_ops);
++}
++
++static struct file_operations ip_vs_app_fops = {
++ .owner = THIS_MODULE,
++ .open = ip_vs_app_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = seq_release,
++};
++#endif
++
+
+ /*
+ * Replace a segment of data with a new segment
+@@ -577,7 +616,7 @@
+ int ip_vs_app_init(void)
+ {
+ /* we will replace it with proc_net_ipvs_create() soon */
+- proc_net_create("ip_vs_app", 0, ip_vs_app_getinfo);
++ proc_net_fops_create("ip_vs_app", 0, &ip_vs_app_fops);
+ return 0;
+ }
+
+Index: linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_conn.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/ipvs/ip_vs_conn.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_conn.c 2003-09-27 11:38:41.769178504 +0800
+@@ -30,6 +30,7 @@
+ #include <linux/compiler.h>
+ #include <linux/vmalloc.h>
+ #include <linux/proc_fs.h> /* for proc_net_* */
++#include <linux/seq_file.h>
+ #include <linux/jhash.h>
+ #include <linux/random.h>
+
+@@ -188,15 +189,12 @@
+ {
+ unsigned hash;
+ struct ip_vs_conn *cp;
+- struct list_head *l,*e;
+
+ hash = ip_vs_conn_hashkey(protocol, s_addr, s_port);
+- l = &ip_vs_conn_tab[hash];
+
+ ct_read_lock(hash);
+
+- for (e=l->next; e!=l; e=e->next) {
+- cp = list_entry(e, struct ip_vs_conn, c_list);
++ list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) {
+ if (s_addr==cp->caddr && s_port==cp->cport &&
+ d_port==cp->vport && d_addr==cp->vaddr &&
+ protocol==cp->protocol) {
+@@ -242,18 +240,15 @@
+ {
+ unsigned hash;
+ struct ip_vs_conn *cp, *ret=NULL;
+- struct list_head *l,*e;
+
+ /*
+ * Check for "full" addressed entries
+ */
+ hash = ip_vs_conn_hashkey(protocol, d_addr, d_port);
+- l = &ip_vs_conn_tab[hash];
+
+ ct_read_lock(hash);
+
+- for (e=l->next; e!=l; e=e->next) {
+- cp = list_entry(e, struct ip_vs_conn, c_list);
++ list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) {
+ if (d_addr == cp->caddr && d_port == cp->cport &&
+ s_port == cp->dport && s_addr == cp->daddr &&
+ protocol == cp->protocol) {
+@@ -615,61 +610,112 @@
+ /*
+ * /proc/net/ip_vs_conn entries
+ */
+-static int
+-ip_vs_conn_getinfo(char *buffer, char **start, off_t offset, int length)
++#ifdef CONFIG_PROC_FS
++
++static void *ip_vs_conn_array(struct seq_file *seq, loff_t pos)
+ {
+- off_t pos=0;
+- int idx, len=0;
+- char temp[70];
++ int idx;
+ struct ip_vs_conn *cp;
+- struct list_head *l, *e;
+-
+- pos = 128;
+- if (pos > offset) {
+- len += sprintf(buffer+len, "%-127s\n",
+- "Pro FromIP FPrt ToIP TPrt DestIP DPrt State Expires");
++
++ for(idx = 0; idx < IP_VS_CONN_TAB_SIZE; idx++) {
++ ct_read_lock_bh(idx);
++ list_for_each_entry(cp, &ip_vs_conn_tab[idx], c_list) {
++ if (pos-- == 0) {
++ seq->private = &ip_vs_conn_tab[idx];
++ return cp;
++ }
++ }
++ ct_read_unlock_bh(idx);
+ }
+
+- for(idx = 0; idx < IP_VS_CONN_TAB_SIZE; idx++) {
+- /*
+- * Lock is actually only need in next loop
+- * we are called from uspace: must stop bh.
+- */
++ return NULL;
++}
++
++static void *ip_vs_conn_seq_start(struct seq_file *seq, loff_t *pos)
++{
++ seq->private = NULL;
++ return *pos ? ip_vs_conn_array(seq, *pos - 1) :SEQ_START_TOKEN;
++}
++
++static void *ip_vs_conn_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++{
++ struct ip_vs_conn *cp = v;
++ struct list_head *e, *l = seq->private;
++ int idx;
++
++ ++*pos;
++ if (v == SEQ_START_TOKEN)
++ return ip_vs_conn_array(seq, 0);
++
++ /* more on same hash chain? */
++ if ((e = cp->c_list.next) != l)
++ return list_entry(e, struct ip_vs_conn, c_list);
++
++ idx = l - ip_vs_conn_tab;
++ ct_read_unlock_bh(idx);
++
++ while (++idx < IP_VS_CONN_TAB_SIZE) {
+ ct_read_lock_bh(idx);
++ list_for_each_entry(cp, &ip_vs_conn_tab[idx], c_list) {
++ seq->private = &ip_vs_conn_tab[idx];
++ return cp;
++ }
++ ct_read_unlock_bh(idx);
++ }
++ seq->private = NULL;
++ return NULL;
++}
+
+- l = &ip_vs_conn_tab[idx];
+- for (e=l->next; e!=l; e=e->next) {
+- cp = list_entry(e, struct ip_vs_conn, c_list);
+- pos += 128;
+- if (pos <= offset)
+- continue;
+- sprintf(temp,
+- "%-3s %08X %04X %08X %04X %08X %04X %-11s %7lu",
++static void ip_vs_conn_seq_stop(struct seq_file *seq, void *v)
++{
++ struct list_head *l = seq->private;
++
++ if (l)
++ ct_read_unlock(l - ip_vs_conn_tab);
++}
++
++static int ip_vs_conn_seq_show(struct seq_file *seq, void *v)
++{
++
++ if (v == SEQ_START_TOKEN)
++ seq_puts(seq,
++ "Pro FromIP FPrt ToIP TPrt DestIP DPrt State Expires\n");
++ else {
++ const struct ip_vs_conn *cp = v;
++
++ seq_printf(seq,
++ "%-3s %08X %04X %08X %04X %08X %04X %-11s %7lu\n",
+ ip_vs_proto_name(cp->protocol),
+ ntohl(cp->caddr), ntohs(cp->cport),
+ ntohl(cp->vaddr), ntohs(cp->vport),
+ ntohl(cp->daddr), ntohs(cp->dport),
+ ip_vs_state_name(cp->protocol, cp->state),
+ (cp->timer.expires-jiffies)/HZ);
+- len += sprintf(buffer+len, "%-127s\n", temp);
+- if (pos >= offset+length) {
+- ct_read_unlock_bh(idx);
+- goto done;
+- }
+- }
+- ct_read_unlock_bh(idx);
+ }
+-
+- done:
+- *start = buffer+len-(pos-offset); /* Start of wanted data */
+- len = pos-offset;
+- if (len > length)
+- len = length;
+- if (len < 0)
+- len = 0;
+- return len;
++ return 0;
+ }
+
++static struct seq_operations ip_vs_conn_seq_ops = {
++ .start = ip_vs_conn_seq_start,
++ .next = ip_vs_conn_seq_next,
++ .stop = ip_vs_conn_seq_stop,
++ .show = ip_vs_conn_seq_show,
++};
++
++static int ip_vs_conn_open(struct inode *inode, struct file *file)
++{
++ return seq_open(file, &ip_vs_conn_seq_ops);
++}
++
++static struct file_operations ip_vs_conn_fops = {
++ .owner = THIS_MODULE,
++ .open = ip_vs_conn_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = seq_release,
++};
++#endif
++
+
+ /*
+ * Randomly drop connection entries before running out of memory
+@@ -687,7 +733,7 @@
+ /* if the conn entry hasn't lasted for 60 seconds, don't drop it.
+ This will leave enough time for normal connection to get
+ through. */
+- if (cp->timeout+jiffies-cp->timer.expires < 60*HZ)
++ if (time_before(cp->timeout + jiffies, cp->timer.expires + 60*HZ))
+ return 0;
+
+ /* Don't drop the entry if its number of incoming packets is not
+@@ -707,7 +753,6 @@
+ {
+ int idx;
+ struct ip_vs_conn *cp;
+- struct list_head *l,*e;
+ struct ip_vs_conn *ct;
+
+ /*
+@@ -721,9 +766,7 @@
+ */
+ ct_write_lock(hash);
+
+- l = &ip_vs_conn_tab[hash];
+- for (e=l->next; e!=l; e=e->next) {
+- cp = list_entry(e, struct ip_vs_conn, c_list);
++ list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) {
+ if (!cp->cport && !(cp->flags & IP_VS_CONN_F_NO_CPORT))
+ /* connection template */
+ continue;
+@@ -775,7 +818,6 @@
+ {
+ int idx;
+ struct ip_vs_conn *cp;
+- struct list_head *l,*e;
+ struct ip_vs_conn *ct;
+
+ flush_again:
+@@ -785,9 +827,7 @@
+ */
+ ct_write_lock_bh(idx);
+
+- l = &ip_vs_conn_tab[idx];
+- for (e=l->next; e!=l; e=e->next) {
+- cp = list_entry(e, struct ip_vs_conn, c_list);
++ list_for_each_entry(cp, &ip_vs_conn_tab[idx], c_list) {
+ atomic_inc(&cp->refcnt);
+ ct_write_unlock(idx);
+
+@@ -848,7 +888,7 @@
+ __ip_vs_conntbl_lock_array[idx].l = RW_LOCK_UNLOCKED;
+ }
+
+- proc_net_create("ip_vs_conn", 0, ip_vs_conn_getinfo);
++ proc_net_fops_create("ip_vs_conn", 0, &ip_vs_conn_fops);
+
+ /* calculate the random value for connection hash */
+ get_random_bytes(&ip_vs_conn_rnd, sizeof(ip_vs_conn_rnd));
+Index: linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_ctl.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/ipvs/ip_vs_ctl.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_ctl.c 2003-09-27 11:38:41.785176072 +0800
+@@ -31,6 +31,8 @@
+ #include <linux/proc_fs.h>
+ #include <linux/timer.h>
+ #include <linux/swap.h>
++#include <linux/proc_fs.h>
++#include <linux/seq_file.h>
+
+ #include <linux/netfilter.h>
+ #include <linux/netfilter_ipv4.h>
+@@ -46,7 +48,7 @@
+ static DECLARE_MUTEX(__ip_vs_mutex);
+
+ /* lock for service table */
+-rwlock_t __ip_vs_svc_lock = RW_LOCK_UNLOCKED;
++static rwlock_t __ip_vs_svc_lock = RW_LOCK_UNLOCKED;
+
+ /* lock for table with the real services */
+ static rwlock_t __ip_vs_rs_lock = RW_LOCK_UNLOCKED;
+@@ -361,14 +363,11 @@
+ {
+ unsigned hash;
+ struct ip_vs_service *svc;
+- struct list_head *l,*e;
+
+ /* Check for "full" addressed entries */
+ hash = ip_vs_svc_hashkey(protocol, vaddr, vport);
+
+- l = &ip_vs_svc_table[hash];
+- for (e=l->next; e!=l; e=e->next) {
+- svc = list_entry(e, struct ip_vs_service, s_list);
++ list_for_each_entry(svc, &ip_vs_svc_table[hash], s_list){
+ if ((svc->addr == vaddr)
+ && (svc->port == vport)
+ && (svc->protocol == protocol)) {
+@@ -389,14 +388,11 @@
+ {
+ unsigned hash;
+ struct ip_vs_service *svc;
+- struct list_head *l,*e;
+
+ /* Check for fwmark addressed entries */
+ hash = ip_vs_svc_fwm_hashkey(fwmark);
+
+- l = &ip_vs_svc_fwm_table[hash];
+- for (e=l->next; e!=l; e=e->next) {
+- svc = list_entry(e, struct ip_vs_service, f_list);
++ list_for_each_entry(svc, &ip_vs_svc_fwm_table[hash], f_list) {
+ if (svc->fwmark == fwmark) {
+ /* HIT */
+ atomic_inc(&svc->usecnt);
+@@ -533,7 +529,6 @@
+ {
+ unsigned hash;
+ struct ip_vs_dest *dest;
+- struct list_head *l,*e;
+
+ /*
+ * Check for "full" addressed entries
+@@ -541,11 +536,8 @@
+ */
+ hash = ip_vs_rs_hashkey(daddr, dport);
+
+- l = &ip_vs_rtable[hash];
+-
+ read_lock(&__ip_vs_rs_lock);
+- for (e=l->next; e!=l; e=e->next) {
+- dest = list_entry(e, struct ip_vs_dest, d_list);
++ list_for_each_entry(dest, &ip_vs_rtable[hash], d_list) {
+ if ((dest->addr == daddr)
+ && (dest->port == dport)
+ && ((dest->protocol == protocol) ||
+@@ -567,14 +559,11 @@
+ ip_vs_lookup_dest(struct ip_vs_service *svc, __u32 daddr, __u16 dport)
+ {
+ struct ip_vs_dest *dest;
+- struct list_head *l, *e;
+
+ /*
+ * Find the destination for the given service
+ */
+- l = &svc->destinations;
+- for (e=l->next; e!=l; e=e->next) {
+- dest = list_entry(e, struct ip_vs_dest, n_list);
++ list_for_each_entry(dest, &svc->destinations, n_list) {
+ if ((dest->addr == daddr) && (dest->port == dport)) {
+ /* HIT */
+ return dest;
+@@ -598,16 +587,12 @@
+ static struct ip_vs_dest *
+ ip_vs_trash_get_dest(struct ip_vs_service *svc, __u32 daddr, __u16 dport)
+ {
+- struct ip_vs_dest *dest;
+- struct list_head *l, *e;
++ struct ip_vs_dest *dest, *nxt;
+
+ /*
+ * Find the destination in trash
+ */
+- l = &ip_vs_dest_trash;
+-
+- for (e=l->next; e!=l; e=e->next) {
+- dest = list_entry(e, struct ip_vs_dest, n_list);
++ list_for_each_entry_safe(dest, nxt, &ip_vs_dest_trash, n_list) {
+ IP_VS_DBG(3, "Destination %u/%u.%u.%u.%u:%u still in trash, "
+ "refcnt=%d\n",
+ dest->vfwmark,
+@@ -632,7 +617,6 @@
+ "from trash\n",
+ dest->vfwmark,
+ NIPQUAD(dest->addr), ntohs(dest->port));
+- e = e->prev;
+ list_del(&dest->n_list);
+ ip_vs_dst_reset(dest);
+ __ip_vs_unbind_svc(dest);
+@@ -655,13 +639,9 @@
+ */
+ static void ip_vs_trash_cleanup(void)
+ {
+- struct ip_vs_dest *dest;
+- struct list_head *l;
+-
+- l = &ip_vs_dest_trash;
++ struct ip_vs_dest *dest, *nxt;
+
+- while (l->next != l) {
+- dest = list_entry(l->next, struct ip_vs_dest, n_list);
++ list_for_each_entry_safe(dest, nxt, &ip_vs_dest_trash, n_list) {
+ list_del(&dest->n_list);
+ ip_vs_dst_reset(dest);
+ __ip_vs_unbind_svc(dest);
+@@ -1196,8 +1176,7 @@
+ */
+ static void __ip_vs_del_service(struct ip_vs_service *svc)
+ {
+- struct list_head *l;
+- struct ip_vs_dest *dest;
++ struct ip_vs_dest *dest, *nxt;
+ struct ip_vs_scheduler *old_sched;
+
+ ip_vs_num_services--;
+@@ -1218,9 +1197,7 @@
+ /*
+ * Unlink the whole destination list
+ */
+- l = &svc->destinations;
+- while (l->next != l) {
+- dest = list_entry(l->next, struct ip_vs_dest, n_list);
++ list_for_each_entry_safe(dest, nxt, &svc->destinations, n_list) {
+ __ip_vs_unlink_dest(svc, dest, 0);
+ __ip_vs_del_dest(dest);
+ }
+@@ -1277,16 +1254,13 @@
+ static int ip_vs_flush(void)
+ {
+ int idx;
+- struct ip_vs_service *svc;
+- struct list_head *l;
++ struct ip_vs_service *svc, *nxt;
+
+ /*
+ * Flush the service table hashed by <protocol,addr,port>
+ */
+ for(idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {
+- l = &ip_vs_svc_table[idx];
+- while (l->next != l) {
+- svc = list_entry(l->next,struct ip_vs_service,s_list);
++ list_for_each_entry_safe(svc, nxt, &ip_vs_svc_table[idx], s_list) {
+ write_lock_bh(&__ip_vs_svc_lock);
+ ip_vs_svc_unhash(svc);
+ /*
+@@ -1302,9 +1276,8 @@
+ * Flush the service table hashed by fwmark
+ */
+ for(idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {
+- l = &ip_vs_svc_fwm_table[idx];
+- while (l->next != l) {
+- svc = list_entry(l->next,struct ip_vs_service,f_list);
++ list_for_each_entry_safe(svc, nxt,
++ &ip_vs_svc_fwm_table[idx], f_list) {
+ write_lock_bh(&__ip_vs_svc_lock);
+ ip_vs_svc_unhash(svc);
+ /*
+@@ -1334,12 +1307,10 @@
+
+ static int ip_vs_zero_service(struct ip_vs_service *svc)
+ {
+- struct list_head *l;
+ struct ip_vs_dest *dest;
+
+ write_lock_bh(&__ip_vs_svc_lock);
+- list_for_each (l, &svc->destinations) {
+- dest = list_entry(l, struct ip_vs_dest, n_list);
++ list_for_each_entry(dest, &svc->destinations, n_list) {
+ ip_vs_zero_stats(&dest->stats);
+ }
+ ip_vs_zero_stats(&svc->stats);
+@@ -1350,19 +1321,16 @@
+ static int ip_vs_zero_all(void)
+ {
+ int idx;
+- struct list_head *l;
+ struct ip_vs_service *svc;
+
+ for(idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {
+- list_for_each (l, &ip_vs_svc_table[idx]) {
+- svc = list_entry(l, struct ip_vs_service, s_list);
++ list_for_each_entry(svc, &ip_vs_svc_table[idx], s_list) {
+ ip_vs_zero_service(svc);
+ }
+ }
+
+ for(idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {
+- list_for_each (l, &ip_vs_svc_fwm_table[idx]) {
+- svc = list_entry(l, struct ip_vs_service, f_list);
++ list_for_each_entry(svc, &ip_vs_svc_fwm_table[idx], f_list) {
+ ip_vs_zero_service(svc);
+ }
+ }
+@@ -1507,207 +1475,253 @@
+ {0}}
+ };
+
++#ifdef CONFIG_PROC_FS
++
++struct ip_vs_iter {
++ struct list_head *table;
++ int bucket;
++};
+
+ /*
+ * Write the contents of the VS rule table to a PROCfs file.
+ * (It is kept just for backward compatibility)
+ */
+-static inline char *ip_vs_fwd_name(unsigned flags)
++static inline const char *ip_vs_fwd_name(unsigned flags)
+ {
+- char *fwd;
+-
+ switch (flags & IP_VS_CONN_F_FWD_MASK) {
+ case IP_VS_CONN_F_LOCALNODE:
+- fwd = "Local";
+- break;
++ return "Local";
+ case IP_VS_CONN_F_TUNNEL:
+- fwd = "Tunnel";
+- break;
++ return "Tunnel";
+ case IP_VS_CONN_F_DROUTE:
+- fwd = "Route";
+- break;
++ return "Route";
+ default:
+- fwd = "Masq";
++ return "Masq";
+ }
+- return fwd;
+ }
+
+-static inline int sprintf_dest(char *str, struct ip_vs_dest *dest)
+-{
+- return sprintf(str, " -> %08X:%04X %-7s %-6d %-10d %-10d",
+- ntohl(dest->addr), ntohs(dest->port),
+- ip_vs_fwd_name(atomic_read(&dest->conn_flags)),
+- atomic_read(&dest->weight),
+- atomic_read(&dest->activeconns),
+- atomic_read(&dest->inactconns));
+-}
+
+-static int ip_vs_get_info(char *buf, char **start, off_t offset, int length)
++/* Get the Nth entry in the two lists */
++static struct ip_vs_service *ip_vs_info_array(struct seq_file *seq, loff_t pos)
+ {
+- int len=0;
+- off_t pos=0;
+- char temp[64], temp2[32];
++ struct ip_vs_iter *iter = seq->private;
+ int idx;
+ struct ip_vs_service *svc;
+- struct ip_vs_dest *dest;
+- struct list_head *l, *e, *p, *q;
+
+- /*
+- * Note: since the length of the buffer is usually the multiple
+- * of 512, it is good to use fixed record of the divisor of 512,
+- * so that records won't be truncated at buffer boundary.
+- */
+- pos = 192;
+- if (pos > offset) {
+- sprintf(temp,
+- "IP Virtual Server version %d.%d.%d (size=%d)",
+- NVERSION(IP_VS_VERSION_CODE), IP_VS_CONN_TAB_SIZE);
+- len += sprintf(buf+len, "%-63s\n", temp);
+- len += sprintf(buf+len, "%-63s\n",
+- "Prot LocalAddress:Port Scheduler Flags");
+- len += sprintf(buf+len, "%-63s\n",
+- " -> RemoteAddress:Port Forward Weight ActiveConn InActConn");
+- }
+-
+- read_lock_bh(&__ip_vs_svc_lock);
+-
+- /* print the service table hashed by <protocol,addr,port> */
++ /* look in hash by protocol */
+ for (idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {
+- l = &ip_vs_svc_table[idx];
+- for (e=l->next; e!=l; e=e->next) {
+- svc = list_entry(e, struct ip_vs_service, s_list);
+- pos += 64;
+- if (pos > offset) {
+- if (svc->flags & IP_VS_SVC_F_PERSISTENT)
+- sprintf(temp2, "persistent %d %08X",
+- svc->timeout,
+- ntohl(svc->netmask));
+- else
+- temp2[0] = '\0';
+-
+- sprintf(temp, "%s %08X:%04X %s %s",
+- ip_vs_proto_name(svc->protocol),
+- ntohl(svc->addr),
+- ntohs(svc->port),
+- svc->scheduler->name, temp2);
+- len += sprintf(buf+len, "%-63s\n", temp);
+- if (len >= length)
+- goto done;
+- }
+-
+- p = &svc->destinations;
+- for (q=p->next; q!=p; q=q->next) {
+- dest = list_entry(q, struct ip_vs_dest, n_list);
+- pos += 64;
+- if (pos <= offset)
+- continue;
+- sprintf_dest(temp, dest);
+- len += sprintf(buf+len, "%-63s\n", temp);
+- if (len >= length)
+- goto done;
++ list_for_each_entry(svc, &ip_vs_svc_table[idx], s_list) {
++ if (pos-- == 0){
++ iter->table = ip_vs_svc_table;
++ iter->bucket = idx;
++ return svc;
+ }
+ }
+ }
+
+- /* print the service table hashed by fwmark */
++ /* keep looking in fwmark */
+ for (idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {
+- l = &ip_vs_svc_fwm_table[idx];
+- for (e=l->next; e!=l; e=e->next) {
+- svc = list_entry(e, struct ip_vs_service, f_list);
+- pos += 64;
+- if (pos > offset) {
+- if (svc->flags & IP_VS_SVC_F_PERSISTENT)
+- sprintf(temp2, "persistent %d %08X",
+- svc->timeout,
+- ntohl(svc->netmask));
+- else
+- temp2[0] = '\0';
+-
+- sprintf(temp, "FWM %08X %s %s",
+- svc->fwmark,
+- svc->scheduler->name, temp2);
+- len += sprintf(buf+len, "%-63s\n", temp);
+- if (len >= length)
+- goto done;
++ list_for_each_entry(svc, &ip_vs_svc_fwm_table[idx], f_list) {
++ if (pos-- == 0) {
++ iter->table = ip_vs_svc_fwm_table;
++ iter->bucket = idx;
++ return svc;
+ }
++ }
++ }
++
++ return NULL;
++}
+
+- p = &svc->destinations;
+- for (q=p->next; q!=p; q=q->next) {
+- dest = list_entry(q, struct ip_vs_dest, n_list);
+- pos += 64;
+- if (pos <= offset)
+- continue;
+- sprintf_dest(temp, dest);
+- len += sprintf(buf+len, "%-63s\n", temp);
+- if (len >= length)
+- goto done;
++static void *ip_vs_info_seq_start(struct seq_file *seq, loff_t *pos)
++{
++
++ read_lock_bh(&__ip_vs_svc_lock);
++ return *pos ? ip_vs_info_array(seq, *pos - 1) : SEQ_START_TOKEN;
++}
++
++
++static void *ip_vs_info_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++{
++ struct list_head *e;
++ struct ip_vs_iter *iter;
++ struct ip_vs_service *svc;
++
++ ++*pos;
++ if (v == SEQ_START_TOKEN)
++ return ip_vs_info_array(seq,0);
++
++ svc = v;
++ iter = seq->private;
++
++ if (iter->table == ip_vs_svc_table) {
++ /* next service in table hashed by protocol */
++ if ((e = svc->s_list.next) != &ip_vs_svc_table[iter->bucket])
++ return list_entry(e, struct ip_vs_service, s_list);
++
++
++ while (++iter->bucket < IP_VS_SVC_TAB_SIZE) {
++ list_for_each_entry(svc,&ip_vs_svc_table[iter->bucket],
++ s_list) {
++ return svc;
+ }
+ }
++
++ iter->table = ip_vs_svc_fwm_table;
++ iter->bucket = -1;
++ goto scan_fwmark;
+ }
+
+- done:
++ /* next service in hashed by fwmark */
++ if ((e = svc->f_list.next) != &ip_vs_svc_fwm_table[iter->bucket])
++ return list_entry(e, struct ip_vs_service, f_list);
++
++ scan_fwmark:
++ while (++iter->bucket < IP_VS_SVC_TAB_SIZE) {
++ list_for_each_entry(svc, &ip_vs_svc_fwm_table[iter->bucket],
++ f_list)
++ return svc;
++ }
++
++ return NULL;
++}
++
++static void ip_vs_info_seq_stop(struct seq_file *seq, void *v)
++{
+ read_unlock_bh(&__ip_vs_svc_lock);
++}
++
+
+- *start = buf+len-(pos-offset); /* Start of wanted data */
+- len = pos-offset;
+- if (len > length)
+- len = length;
+- if (len < 0)
+- len = 0;
+- return len;
++static int ip_vs_info_seq_show(struct seq_file *seq, void *v)
++{
++ if (v == SEQ_START_TOKEN) {
++ seq_printf(seq,
++ "IP Virtual Server version %d.%d.%d (size=%d)\n",
++ NVERSION(IP_VS_VERSION_CODE), IP_VS_CONN_TAB_SIZE);
++ seq_puts(seq,
++ "Prot LocalAddress:Port Scheduler Flags\n");
++ seq_puts(seq,
++ " -> RemoteAddress:Port Forward Weight ActiveConn InActConn\n");
++ } else {
++ const struct ip_vs_service *svc = v;
++ const struct ip_vs_iter *iter = seq->private;
++ const struct ip_vs_dest *dest;
++
++ if (iter->table == ip_vs_svc_table)
++ seq_printf(seq, "%s %08X:%04X %s ",
++ ip_vs_proto_name(svc->protocol),
++ ntohl(svc->addr),
++ ntohs(svc->port),
++ svc->scheduler->name);
++ else
++ seq_printf(seq, "FWM %08X %s ",
++ svc->fwmark, svc->scheduler->name);
++
++ if (svc->flags & IP_VS_SVC_F_PERSISTENT)
++ seq_printf(seq, "persistent %d %08X\n",
++ svc->timeout,
++ ntohl(svc->netmask));
++ else
++ seq_putc(seq, '\n');
++
++ list_for_each_entry(dest, &svc->destinations, n_list) {
++ seq_printf(seq,
++ " -> %08X:%04X %-7s %-6d %-10d %-10d\n",
++ ntohl(dest->addr), ntohs(dest->port),
++ ip_vs_fwd_name(atomic_read(&dest->conn_flags)),
++ atomic_read(&dest->weight),
++ atomic_read(&dest->activeconns),
++ atomic_read(&dest->inactconns));
++ }
++ }
++ return 0;
+ }
+
++static struct seq_operations ip_vs_info_seq_ops = {
++ .start = ip_vs_info_seq_start,
++ .next = ip_vs_info_seq_next,
++ .stop = ip_vs_info_seq_stop,
++ .show = ip_vs_info_seq_show,
++};
++
++static int ip_vs_info_open(struct inode *inode, struct file *file)
++{
++ struct seq_file *seq;
++ int rc = -ENOMEM;
++ struct ip_vs_iter *s = kmalloc(sizeof(*s), GFP_KERNEL);
++
++ if (!s)
++ goto out;
++
++ rc = seq_open(file, &ip_vs_info_seq_ops);
++ if (rc)
++ goto out_kfree;
++
++ seq = file->private_data;
++ seq->private = s;
++ memset(s, 0, sizeof(*s));
++out:
++ return rc;
++out_kfree:
++ kfree(s);
++ goto out;
++}
++
++static struct file_operations ip_vs_info_fops = {
++ .owner = THIS_MODULE,
++ .open = ip_vs_info_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = seq_release_private,
++};
++
++#endif
+
+ struct ip_vs_stats ip_vs_stats;
+
+-static int
+-ip_vs_stats_get_info(char *buf, char **start, off_t offset, int length)
++#ifdef CONFIG_PROC_FS
++static int ip_vs_stats_show(struct seq_file *seq, void *v)
+ {
+- int len=0;
+- off_t pos=0;
+- char temp[64];
+-
+- pos += 320;
+- if (pos > offset) {
+- len += sprintf(buf+len, "%-63s\n%-63s\n",
+-/* 01234567 01234567 01234567 0123456701234567 0123456701234567 */
+- " Total Incoming Outgoing Incoming Outgoing",
+- " Conns Packets Packets Bytes Bytes");
+-
+- spin_lock_bh(&ip_vs_stats.lock);
+- sprintf(temp, "%8X %8X %8X %8X%08X %8X%08X",
+- ip_vs_stats.conns,
+- ip_vs_stats.inpkts,
+- ip_vs_stats.outpkts,
+- (__u32)(ip_vs_stats.inbytes>>32),
+- (__u32)ip_vs_stats.inbytes,
+- (__u32)(ip_vs_stats.outbytes>>32),
+- (__u32)ip_vs_stats.outbytes);
+- len += sprintf(buf+len, "%-62s\n\n", temp);
+-
+- len += sprintf(buf+len, "%-63s\n",
+-/* 01234567 01234567 01234567 0123456701234567 0123456701234567 */
+- " Conns/s Pkts/s Pkts/s Bytes/s Bytes/s");
+- sprintf(temp, "%8X %8X %8X %16X %16X",
++
++/* 01234567 01234567 01234567 0123456701234567 0123456701234567 */
++ seq_puts(seq,
++ " Total Incoming Outgoing Incoming Outgoing\n");
++ seq_printf(seq,
++ " Conns Packets Packets Bytes Bytes\n");
++
++ spin_lock_bh(&ip_vs_stats.lock);
++ seq_printf(seq, "%8X %8X %8X %16LX %16LX\n\n", ip_vs_stats.conns,
++ ip_vs_stats.inpkts, ip_vs_stats.outpkts,
++ ip_vs_stats.inbytes, ip_vs_stats.outbytes);
++
++/* 01234567 01234567 01234567 0123456701234567 0123456701234567 */
++ seq_puts(seq,
++ " Conns/s Pkts/s Pkts/s Bytes/s Bytes/s\n");
++ seq_printf(seq,"%8X %8X %8X %16X %16X\n",
+ ip_vs_stats.cps,
+ ip_vs_stats.inpps,
+ ip_vs_stats.outpps,
+ ip_vs_stats.inbps,
+ ip_vs_stats.outbps);
+- len += sprintf(buf+len, "%-63s\n", temp);
++ spin_unlock_bh(&ip_vs_stats.lock);
+
+- spin_unlock_bh(&ip_vs_stats.lock);
+- }
++ return 0;
++}
+
+- *start = buf+len-(pos-offset); /* Start of wanted data */
+- len = pos-offset;
+- if (len > length)
+- len = length;
+- if (len < 0)
+- len = 0;
+- return len;
++static int ip_vs_stats_seq_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, ip_vs_stats_show, NULL);
+ }
+
++static struct file_operations ip_vs_stats_fops = {
++ .owner = THIS_MODULE,
++ .open = ip_vs_stats_seq_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
++#endif
+
+ /*
+ * Set timeout values for tcp tcpfin udp in the timeout_table.
+@@ -1912,19 +1926,17 @@
+
+ static inline int
+ __ip_vs_get_service_entries(const struct ip_vs_get_services *get,
+- struct ip_vs_get_services *uptr)
++ struct ip_vs_get_services __user *uptr)
+ {
+ int idx, count=0;
+ struct ip_vs_service *svc;
+- struct list_head *l;
+ struct ip_vs_service_entry entry;
+ int ret = 0;
+
+ for (idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {
+- list_for_each (l, &ip_vs_svc_table[idx]) {
++ list_for_each_entry(svc, &ip_vs_svc_table[idx], s_list) {
+ if (count >= get->num_services)
+ goto out;
+- svc = list_entry(l, struct ip_vs_service, s_list);
+ ip_vs_copy_service(&entry, svc);
+ if (copy_to_user(&uptr->entrytable[count],
+ &entry, sizeof(entry))) {
+@@ -1936,10 +1948,9 @@
+ }
+
+ for (idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {
+- list_for_each (l, &ip_vs_svc_fwm_table[idx]) {
++ list_for_each_entry(svc, &ip_vs_svc_fwm_table[idx], f_list) {
+ if (count >= get->num_services)
+ goto out;
+- svc = list_entry(l, struct ip_vs_service, f_list);
+ ip_vs_copy_service(&entry, svc);
+ if (copy_to_user(&uptr->entrytable[count],
+ &entry, sizeof(entry))) {
+@@ -1955,7 +1966,7 @@
+
+ static inline int
+ __ip_vs_get_dest_entries(const struct ip_vs_get_dests *get,
+- struct ip_vs_get_dests *uptr)
++ struct ip_vs_get_dests __user *uptr)
+ {
+ struct ip_vs_service *svc;
+ int ret = 0;
+@@ -1968,14 +1979,12 @@
+ if (svc) {
+ int count = 0;
+ struct ip_vs_dest *dest;
+- struct list_head *l, *e;
+ struct ip_vs_dest_entry entry;
+
+- l = &svc->destinations;
+- for (e=l->next; e!=l; e=e->next) {
++ list_for_each_entry(dest, &svc->destinations, n_list) {
+ if (count >= get->num_dests)
+ break;
+- dest = list_entry(e, struct ip_vs_dest, n_list);
++
+ entry.addr = dest->addr;
+ entry.port = dest->port;
+ entry.conn_flags = atomic_read(&dest->conn_flags);
+@@ -2034,7 +2043,7 @@
+ };
+
+ static int
+-do_ip_vs_get_ctl(struct sock *sk, int cmd, void *user, int *len)
++do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
+ {
+ unsigned char arg[128];
+ int ret = 0;
+@@ -2195,8 +2204,8 @@
+ return ret;
+ }
+
+- proc_net_create("ip_vs", 0, ip_vs_get_info);
+- proc_net_create("ip_vs_stats", 0, ip_vs_stats_get_info);
++ proc_net_fops_create("ip_vs", 0, &ip_vs_info_fops);
++ proc_net_fops_create("ip_vs_stats",0, &ip_vs_stats_fops);
+
+ ipv4_vs_table.sysctl_header =
+ register_sysctl_table(ipv4_vs_table.root_dir, 0);
+Index: linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_lblc.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/ipvs/ip_vs_lblc.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_lblc.c 2003-09-27 11:38:41.790175312 +0800
+@@ -246,15 +246,12 @@
+ {
+ unsigned hash;
+ struct ip_vs_lblc_entry *en;
+- struct list_head *l,*e;
+
+ hash = ip_vs_lblc_hashkey(addr);
+- l = &tbl->bucket[hash];
+
+ read_lock(&tbl->lock);
+
+- for (e=l->next; e!=l; e=e->next) {
+- en = list_entry(e, struct ip_vs_lblc_entry, list);
++ list_for_each_entry(en, &tbl->bucket[hash], list) {
+ if (en->addr == addr) {
+ /* HIT */
+ read_unlock(&tbl->lock);
+@@ -274,14 +271,11 @@
+ static void ip_vs_lblc_flush(struct ip_vs_lblc_table *tbl)
+ {
+ int i;
+- struct list_head *l;
+- struct ip_vs_lblc_entry *en;
++ struct ip_vs_lblc_entry *en, *nxt;
+
+ for (i=0; i<IP_VS_LBLC_TAB_SIZE; i++) {
+ write_lock(&tbl->lock);
+- for (l=&tbl->bucket[i]; l->next!=l; ) {
+- en = list_entry(l->next,
+- struct ip_vs_lblc_entry, list);
++ list_for_each_entry_safe(en, nxt, &tbl->bucket[i], list) {
+ ip_vs_lblc_free(en);
+ atomic_dec(&tbl->entries);
+ }
+@@ -294,21 +288,17 @@
+ {
+ unsigned long now = jiffies;
+ int i, j;
+- struct list_head *l, *e;
+- struct ip_vs_lblc_entry *en;
++ struct ip_vs_lblc_entry *en, *nxt;
+
+ for (i=0, j=tbl->rover; i<IP_VS_LBLC_TAB_SIZE; i++) {
+ j = (j + 1) & IP_VS_LBLC_TAB_MASK;
+- e = l = &tbl->bucket[j];
++
+ write_lock(&tbl->lock);
+- while (e->next != l) {
+- en = list_entry(e->next,
+- struct ip_vs_lblc_entry, list);
+- if ((now - en->lastuse) <
+- sysctl_ip_vs_lblc_expiration) {
+- e = e->next;
++ list_for_each_entry_safe(en, nxt, &tbl->bucket[j], list) {
++ if (time_before(now,
++ en->lastuse + sysctl_ip_vs_lblc_expiration))
+ continue;
+- }
++
+ ip_vs_lblc_free(en);
+ atomic_dec(&tbl->entries);
+ }
+@@ -335,8 +325,7 @@
+ unsigned long now = jiffies;
+ int goal;
+ int i, j;
+- struct list_head *l, *e;
+- struct ip_vs_lblc_entry *en;
++ struct ip_vs_lblc_entry *en, *nxt;
+
+ tbl = (struct ip_vs_lblc_table *)data;
+
+@@ -358,15 +347,12 @@
+
+ for (i=0, j=tbl->rover; i<IP_VS_LBLC_TAB_SIZE; i++) {
+ j = (j + 1) & IP_VS_LBLC_TAB_MASK;
+- e = l = &tbl->bucket[j];
++
+ write_lock(&tbl->lock);
+- while (e->next != l) {
+- en = list_entry(e->next,
+- struct ip_vs_lblc_entry, list);
+- if ((now - en->lastuse) < ENTRY_TIMEOUT) {
+- e = e->next;
++ list_for_each_entry_safe(en, nxt, &tbl->bucket[j], list) {
++ if (time_before(now, en->lastuse + ENTRY_TIMEOUT))
+ continue;
+- }
++
+ ip_vs_lblc_free(en);
+ atomic_dec(&tbl->entries);
+ goal--;
+@@ -452,7 +438,6 @@
+ static inline struct ip_vs_dest *
+ __ip_vs_wlc_schedule(struct ip_vs_service *svc, struct iphdr *iph)
+ {
+- register struct list_head *l, *e;
+ struct ip_vs_dest *dest, *least;
+ int loh, doh;
+
+@@ -473,10 +458,7 @@
+ * The server with weight=0 is quiesced and will not receive any
+ * new connection.
+ */
+-
+- l = &svc->destinations;
+- for (e=l->next; e!=l; e=e->next) {
+- least = list_entry(e, struct ip_vs_dest, n_list);
++ list_for_each_entry(least, &svc->destinations, n_list) {
+ if (least->flags & IP_VS_DEST_F_OVERLOAD)
+ continue;
+ if (atomic_read(&least->weight) > 0) {
+@@ -491,9 +473,7 @@
+ * Find the destination with the least load.
+ */
+ nextstage:
+- for (e=e->next; e!=l; e=e->next) {
+- dest = list_entry(e, struct ip_vs_dest, n_list);
+-
++ list_for_each_entry(dest, &svc->destinations, n_list) {
+ if (dest->flags & IP_VS_DEST_F_OVERLOAD)
+ continue;
+
+@@ -525,12 +505,9 @@
+ is_overloaded(struct ip_vs_dest *dest, struct ip_vs_service *svc)
+ {
+ if (atomic_read(&dest->activeconns) > atomic_read(&dest->weight)) {
+- register struct list_head *l, *e;
+ struct ip_vs_dest *d;
+
+- l = &svc->destinations;
+- for (e=l->next; e!=l; e=e->next) {
+- d = list_entry(e, struct ip_vs_dest, n_list);
++ list_for_each_entry(d, &svc->destinations, n_list) {
+ if (atomic_read(&d->activeconns)*2
+ < atomic_read(&d->weight)) {
+ return 1;
+Index: linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_lblcr.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/ipvs/ip_vs_lblcr.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_lblcr.c 2003-09-27 11:38:41.797174248 +0800
+@@ -432,15 +432,12 @@
+ {
+ unsigned hash;
+ struct ip_vs_lblcr_entry *en;
+- struct list_head *l,*e;
+
+ hash = ip_vs_lblcr_hashkey(addr);
+- l = &tbl->bucket[hash];
+
+ read_lock(&tbl->lock);
+
+- for (e=l->next; e!=l; e=e->next) {
+- en = list_entry(e, struct ip_vs_lblcr_entry, list);
++ list_for_each_entry(en, &tbl->bucket[hash], list) {
+ if (en->addr == addr) {
+ /* HIT */
+ read_unlock(&tbl->lock);
+@@ -460,14 +457,11 @@
+ static void ip_vs_lblcr_flush(struct ip_vs_lblcr_table *tbl)
+ {
+ int i;
+- struct list_head *l;
+- struct ip_vs_lblcr_entry *en;
++ struct ip_vs_lblcr_entry *en, *nxt;
+
+ for (i=0; i<IP_VS_LBLCR_TAB_SIZE; i++) {
+ write_lock(&tbl->lock);
+- for (l=&tbl->bucket[i]; l->next!=l; ) {
+- en = list_entry(l->next,
+- struct ip_vs_lblcr_entry, list);
++ list_for_each_entry_safe(en, nxt, &tbl->bucket[i], list) {
+ ip_vs_lblcr_free(en);
+ atomic_dec(&tbl->entries);
+ }
+@@ -480,21 +474,17 @@
+ {
+ unsigned long now = jiffies;
+ int i, j;
+- struct list_head *l, *e;
+- struct ip_vs_lblcr_entry *en;
++ struct ip_vs_lblcr_entry *en, *nxt;
+
+ for (i=0, j=tbl->rover; i<IP_VS_LBLCR_TAB_SIZE; i++) {
+ j = (j + 1) & IP_VS_LBLCR_TAB_MASK;
+- e = l = &tbl->bucket[j];
++
+ write_lock(&tbl->lock);
+- while (e->next != l) {
+- en = list_entry(e->next,
+- struct ip_vs_lblcr_entry, list);
+- if ((now - en->lastuse) <
+- sysctl_ip_vs_lblcr_expiration) {
+- e = e->next;
++ list_for_each_entry_safe(en, nxt, &tbl->bucket[j], list) {
++ if (time_after(en->lastuse+sysctl_ip_vs_lblcr_expiration,
++ now))
+ continue;
+- }
++
+ ip_vs_lblcr_free(en);
+ atomic_dec(&tbl->entries);
+ }
+@@ -521,8 +511,7 @@
+ unsigned long now = jiffies;
+ int goal;
+ int i, j;
+- struct list_head *l, *e;
+- struct ip_vs_lblcr_entry *en;
++ struct ip_vs_lblcr_entry *en, *nxt;
+
+ tbl = (struct ip_vs_lblcr_table *)data;
+
+@@ -544,15 +533,12 @@
+
+ for (i=0, j=tbl->rover; i<IP_VS_LBLCR_TAB_SIZE; i++) {
+ j = (j + 1) & IP_VS_LBLCR_TAB_MASK;
+- e = l = &tbl->bucket[j];
++
+ write_lock(&tbl->lock);
+- while (e->next != l) {
+- en = list_entry(e->next,
+- struct ip_vs_lblcr_entry, list);
+- if ((now - en->lastuse) < ENTRY_TIMEOUT) {
+- e = e->next;
++ list_for_each_entry_safe(en, nxt, &tbl->bucket[j], list) {
++ if (time_before(now, en->lastuse+ENTRY_TIMEOUT))
+ continue;
+- }
++
+ ip_vs_lblcr_free(en);
+ atomic_dec(&tbl->entries);
+ goal--;
+@@ -583,7 +569,6 @@
+ struct ip_vs_lblcr_table *tbl;
+ unsigned long now = jiffies;
+ int i;
+- struct list_head *l, *e;
+ struct ip_vs_lblcr_entry *en;
+
+ tbl = lblcr_table_list;
+@@ -593,13 +578,11 @@
+ len += size;
+
+ for (i=0; i<IP_VS_LBLCR_TAB_SIZE; i++) {
+- l = &tbl->bucket[i];
+ read_lock_bh(&tbl->lock);
+- for (e=l->next; e!=l; e=e->next) {
++ list_for_each_entry(en, &tbl->bucket[i], list) {
+ char tbuf[16];
+ struct ip_vs_dest_list *d;
+
+- en = list_entry(e, struct ip_vs_lblcr_entry, list);
+ sprintf(tbuf, "%u.%u.%u.%u", NIPQUAD(en->addr));
+ size = sprintf(buffer+len, "%8lu %-16s ",
+ now-en->lastuse, tbuf);
+@@ -708,7 +691,6 @@
+ static inline struct ip_vs_dest *
+ __ip_vs_wlc_schedule(struct ip_vs_service *svc, struct iphdr *iph)
+ {
+- register struct list_head *l, *e;
+ struct ip_vs_dest *dest, *least;
+ int loh, doh;
+
+@@ -729,10 +711,7 @@
+ * The server with weight=0 is quiesced and will not receive any
+ * new connection.
+ */
+-
+- l = &svc->destinations;
+- for (e=l->next; e!=l; e=e->next) {
+- least = list_entry(e, struct ip_vs_dest, n_list);
++ list_for_each_entry(least, &svc->destinations, n_list) {
+ if (least->flags & IP_VS_DEST_F_OVERLOAD)
+ continue;
+
+@@ -748,8 +727,7 @@
+ * Find the destination with the least load.
+ */
+ nextstage:
+- for (e=e->next; e!=l; e=e->next) {
+- dest = list_entry(e, struct ip_vs_dest, n_list);
++ list_for_each_entry(dest, &svc->destinations, n_list) {
+ if (dest->flags & IP_VS_DEST_F_OVERLOAD)
+ continue;
+
+@@ -781,12 +759,9 @@
+ is_overloaded(struct ip_vs_dest *dest, struct ip_vs_service *svc)
+ {
+ if (atomic_read(&dest->activeconns) > atomic_read(&dest->weight)) {
+- register struct list_head *l, *e;
+ struct ip_vs_dest *d;
+
+- l = &svc->destinations;
+- for (e=l->next; e!=l; e=e->next) {
+- d = list_entry(e, struct ip_vs_dest, n_list);
++ list_for_each_entry(d, &svc->destinations, n_list) {
+ if (atomic_read(&d->activeconns)*2
+ < atomic_read(&d->weight)) {
+ return 1;
+Index: linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_lc.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/ipvs/ip_vs_lc.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_lc.c 2003-09-27 11:38:41.798174096 +0800
+@@ -65,7 +65,6 @@
+ static struct ip_vs_dest *
+ ip_vs_lc_schedule(struct ip_vs_service *svc, struct iphdr *iph)
+ {
+- struct list_head *l, *e;
+ struct ip_vs_dest *dest, *least;
+ unsigned int loh, doh;
+
+@@ -80,9 +79,7 @@
+ * served, but no new connection is assigned to the server.
+ */
+
+- l = &svc->destinations;
+- for (e=l->next; e!=l; e=e->next) {
+- least = list_entry (e, struct ip_vs_dest, n_list);
++ list_for_each_entry(least, &svc->destinations, n_list) {
+ if (least->flags & IP_VS_DEST_F_OVERLOAD)
+ continue;
+ if (atomic_read(&least->weight) > 0) {
+@@ -96,8 +93,7 @@
+ * Find the destination with the least load.
+ */
+ nextstage:
+- for (e=e->next; e!=l; e=e->next) {
+- dest = list_entry(e, struct ip_vs_dest, n_list);
++ list_for_each_entry(dest, &svc->destinations, n_list) {
+ if ((dest->flags & IP_VS_DEST_F_OVERLOAD) ||
+ atomic_read(&dest->weight) == 0)
+ continue;
+Index: linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_nq.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/ipvs/ip_vs_nq.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_nq.c 2003-09-27 11:38:41.801173640 +0800
+@@ -81,7 +81,6 @@
+ static struct ip_vs_dest *
+ ip_vs_nq_schedule(struct ip_vs_service *svc, struct iphdr *iph)
+ {
+- register struct list_head *l, *e;
+ struct ip_vs_dest *dest, *least;
+ unsigned int loh, doh;
+
+@@ -100,9 +99,7 @@
+ * new connections.
+ */
+
+- l = &svc->destinations;
+- for (e=l->next; e!=l; e=e->next) {
+- least = list_entry(e, struct ip_vs_dest, n_list);
++ list_for_each_entry(least, &svc->destinations, n_list) {
+ if (!(least->flags & IP_VS_DEST_F_OVERLOAD) &&
+ atomic_read(&least->weight) > 0) {
+ loh = ip_vs_nq_dest_overhead(least);
+@@ -120,8 +117,7 @@
+ * Find the destination with the least load.
+ */
+ nextstage:
+- for (e=e->next; e!=l; e=e->next) {
+- dest = list_entry(e, struct ip_vs_dest, n_list);
++ list_for_each_entry(dest, &svc->destinations, n_list) {
+
+ if (dest->flags & IP_VS_DEST_F_OVERLOAD)
+ continue;
+Index: linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_proto_tcp.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/ipvs/ip_vs_proto_tcp.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_proto_tcp.c 2003-09-27 11:38:41.805173032 +0800
+@@ -479,22 +479,19 @@
+ static int tcp_register_app(struct ip_vs_app *inc)
+ {
+ struct ip_vs_app *i;
+- struct list_head *t, *p;
+ __u16 hash, port = inc->port;
+ int ret = 0;
+
+ hash = tcp_app_hashkey(port);
+- t = &tcp_apps[hash];
+
+ spin_lock_bh(&tcp_app_lock);
+- for (p = t->next; p != t; p = p->next) {
+- i = list_entry(p, struct ip_vs_app, p_list);
++ list_for_each_entry(i, &tcp_apps[hash], p_list) {
+ if (i->port == port) {
+ ret = -EEXIST;
+ goto out;
+ }
+ }
+- list_add(&inc->p_list, t);
++ list_add(&inc->p_list, &tcp_apps[hash]);
+ atomic_inc(&ip_vs_protocol_tcp.appcnt);
+
+ out:
+@@ -516,7 +513,6 @@
+ static int
+ tcp_app_conn_bind(struct ip_vs_conn *cp)
+ {
+- struct list_head *t, *p;
+ int hash;
+ struct ip_vs_app *inc;
+ int result = 0;
+@@ -527,11 +523,9 @@
+
+ /* Lookup application incarnations and bind the right one */
+ hash = tcp_app_hashkey(cp->vport);
+- t = &tcp_apps[hash];
+
+ spin_lock(&tcp_app_lock);
+- for (p = t->next; p != t; p = p->next) {
+- inc = list_entry(p, struct ip_vs_app, p_list);
++ list_for_each_entry(inc, &tcp_apps[hash], p_list) {
+ if (inc->port == cp->vport) {
+ if (unlikely(!ip_vs_app_inc_get(inc)))
+ break;
+Index: linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_proto_udp.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/ipvs/ip_vs_proto_udp.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_proto_udp.c 2003-09-27 11:38:41.809172424 +0800
+@@ -245,22 +245,20 @@
+ static int udp_register_app(struct ip_vs_app *inc)
+ {
+ struct ip_vs_app *i;
+- struct list_head *t, *p;
+ __u16 hash, port = inc->port;
+ int ret = 0;
+
+ hash = udp_app_hashkey(port);
+- t = &udp_apps[hash];
++
+
+ spin_lock_bh(&udp_app_lock);
+- for (p = t->next; p != t; p = p->next) {
+- i = list_entry(p, struct ip_vs_app, p_list);
++ list_for_each_entry(i, &udp_apps[hash], p_list) {
+ if (i->port == port) {
+ ret = -EEXIST;
+ goto out;
+ }
+ }
+- list_add(&inc->p_list, t);
++ list_add(&inc->p_list, &udp_apps[hash]);
+ atomic_inc(&ip_vs_protocol_udp.appcnt);
+
+ out:
+@@ -281,7 +279,6 @@
+
+ static int udp_app_conn_bind(struct ip_vs_conn *cp)
+ {
+- struct list_head *t, *p;
+ int hash;
+ struct ip_vs_app *inc;
+ int result = 0;
+@@ -292,11 +289,9 @@
+
+ /* Lookup application incarnations and bind the right one */
+ hash = udp_app_hashkey(cp->vport);
+- t = &udp_apps[hash];
+
+ spin_lock(&udp_app_lock);
+- for (p = t->next; p != t; p = p->next) {
+- inc = list_entry(p, struct ip_vs_app, p_list);
++ list_for_each_entry(inc, &udp_apps[hash], p_list) {
+ if (inc->port == cp->vport) {
+ if (unlikely(!ip_vs_app_inc_get(inc)))
+ break;
+Index: linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_rr.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/ipvs/ip_vs_rr.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_rr.c 2003-09-27 11:38:41.811172120 +0800
+@@ -57,7 +57,7 @@
+ static struct ip_vs_dest *
+ ip_vs_rr_schedule(struct ip_vs_service *svc, struct iphdr *iph)
+ {
+- register struct list_head *p, *q;
++ struct list_head *p, *q;
+ struct ip_vs_dest *dest;
+
+ IP_VS_DBG(6, "ip_vs_rr_schedule(): Scheduling...\n");
+@@ -73,12 +73,12 @@
+ continue;
+ }
+
++
+ dest = list_entry(q, struct ip_vs_dest, n_list);
+ if (!(dest->flags & IP_VS_DEST_F_OVERLOAD) &&
+ atomic_read(&dest->weight) > 0)
+ /* HIT */
+ goto out;
+- q = q->next;
+ } while (q != p);
+ write_unlock(&svc->sched_lock);
+ return NULL;
+Index: linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_sched.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/ipvs/ip_vs_sched.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_sched.c 2003-09-27 11:38:41.813171816 +0800
+@@ -106,18 +106,13 @@
+ static struct ip_vs_scheduler *ip_vs_sched_getbyname(const char *sched_name)
+ {
+ struct ip_vs_scheduler *sched;
+- struct list_head *l, *e;
+
+ IP_VS_DBG(2, "ip_vs_sched_getbyname(): sched_name \"%s\"\n",
+ sched_name);
+
+- l = &ip_vs_schedulers;
+-
+ read_lock_bh(&__ip_vs_sched_lock);
+
+- for (e=l->next; e!=l; e=e->next) {
+- sched = list_entry(e, struct ip_vs_scheduler, n_list);
+-
++ list_for_each_entry(sched, &ip_vs_schedulers, n_list) {
+ /*
+ * Test and get the modules atomically
+ */
+Index: linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_sed.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/ipvs/ip_vs_sed.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_sed.c 2003-09-27 11:38:41.816171360 +0800
+@@ -85,7 +85,6 @@
+ static struct ip_vs_dest *
+ ip_vs_sed_schedule(struct ip_vs_service *svc, struct iphdr *iph)
+ {
+- register struct list_head *l, *e;
+ struct ip_vs_dest *dest, *least;
+ unsigned int loh, doh;
+
+@@ -104,9 +103,7 @@
+ * new connections.
+ */
+
+- l = &svc->destinations;
+- for (e=l->next; e!=l; e=e->next) {
+- least = list_entry(e, struct ip_vs_dest, n_list);
++ list_for_each_entry(least, &svc->destinations, n_list) {
+ if (!(least->flags & IP_VS_DEST_F_OVERLOAD) &&
+ atomic_read(&least->weight) > 0) {
+ loh = ip_vs_sed_dest_overhead(least);
+@@ -119,9 +116,7 @@
+ * Find the destination with the least load.
+ */
+ nextstage:
+- for (e=e->next; e!=l; e=e->next) {
+- dest = list_entry(e, struct ip_vs_dest, n_list);
+-
++ list_for_each_entry(dest, &svc->destinations, n_list) {
+ if (dest->flags & IP_VS_DEST_F_OVERLOAD)
+ continue;
+ doh = ip_vs_sed_dest_overhead(dest);
+Index: linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_sync.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/ipvs/ip_vs_sync.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_sync.c 2003-09-27 11:38:41.822170448 +0800
+@@ -206,8 +206,8 @@
+ struct ip_vs_sync_buff *sb;
+
+ spin_lock_bh(&curr_sb_lock);
+- if (curr_sb &&
+- (jiffies - curr_sb->firstuse > time || time == 0)) {
++ if (curr_sb && (time == 0 ||
++ time_before(jiffies - curr_sb->firstuse, time))) {
+ sb = curr_sb;
+ curr_sb = NULL;
+ } else
+Index: linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_wlc.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/ipvs/ip_vs_wlc.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_wlc.c 2003-09-27 11:38:41.824170144 +0800
+@@ -73,7 +73,6 @@
+ static struct ip_vs_dest *
+ ip_vs_wlc_schedule(struct ip_vs_service *svc, struct iphdr *iph)
+ {
+- register struct list_head *l, *e;
+ struct ip_vs_dest *dest, *least;
+ unsigned int loh, doh;
+
+@@ -92,9 +91,7 @@
+ * new connections.
+ */
+
+- l = &svc->destinations;
+- for (e=l->next; e!=l; e=e->next) {
+- least = list_entry(e, struct ip_vs_dest, n_list);
++ list_for_each_entry(least, &svc->destinations, n_list) {
+ if (!(least->flags & IP_VS_DEST_F_OVERLOAD) &&
+ atomic_read(&least->weight) > 0) {
+ loh = ip_vs_wlc_dest_overhead(least);
+@@ -107,9 +104,7 @@
+ * Find the destination with the least load.
+ */
+ nextstage:
+- for (e=e->next; e!=l; e=e->next) {
+- dest = list_entry(e, struct ip_vs_dest, n_list);
+-
++ list_for_each_entry(dest, &svc->destinations, n_list) {
+ if (dest->flags & IP_VS_DEST_F_OVERLOAD)
+ continue;
+ doh = ip_vs_wlc_dest_overhead(dest);
+Index: linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_wrr.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/ipvs/ip_vs_wrr.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_wrr.c 2003-09-27 11:38:41.827169688 +0800
+@@ -56,25 +56,22 @@
+
+ static int ip_vs_wrr_gcd_weight(struct ip_vs_service *svc)
+ {
+- register struct list_head *l, *e;
+ struct ip_vs_dest *dest;
+ int weight;
+ int g = 1;
+
+- l = &svc->destinations;
+- for (e=l->next; e!=l; e=e->next) {
+- dest = list_entry(e, struct ip_vs_dest, n_list);
++ list_for_each_entry(dest, &svc->destinations, n_list) {
+ weight = atomic_read(&dest->weight);
+ if (weight > 0) {
+ g = weight;
+- break;
++ goto search_gcd;
+ }
+ }
+- if (e == l)
+- return g;
+
+- for (e=e->next; e!=l; e=e->next) {
+- dest = list_entry(e, struct ip_vs_dest, n_list);
++ return g;
++
++ search_gcd:
++ list_for_each_entry(dest, &svc->destinations, n_list) {
+ weight = atomic_read(&dest->weight);
+ if (weight > 0)
+ g = gcd(weight, g);
+@@ -89,13 +86,10 @@
+ */
+ static int ip_vs_wrr_max_weight(struct ip_vs_service *svc)
+ {
+- register struct list_head *l, *e;
+ struct ip_vs_dest *dest;
+ int weight = 0;
+
+- l = &svc->destinations;
+- for (e=l->next; e!=l; e=e->next) {
+- dest = list_entry(e, struct ip_vs_dest, n_list);
++ list_for_each_entry(dest, &svc->destinations, n_list) {
+ if (atomic_read(&dest->weight) > weight)
+ weight = atomic_read(&dest->weight);
+ }
+Index: linux-2.6.0-test5/net/ipv4/netfilter/ip_nat_amanda.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/netfilter/ip_nat_amanda.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/netfilter/ip_nat_amanda.c 2003-09-27 11:38:41.829169384 +0800
+@@ -101,7 +101,7 @@
+ struct ip_conntrack_expect *exp = expect;
+ struct ip_ct_amanda_expect *ct_amanda_info = &exp->help.exp_amanda_info;
+ struct ip_conntrack_tuple t = exp->tuple;
+- int port;
++ u_int16_t port;
+
+ MUST_BE_LOCKED(&ip_amanda_lock);
+
+@@ -115,7 +115,7 @@
+ writable */
+
+ t.dst.ip = newip;
+- for (port = ct_amanda_info->port + 10; port != 0; port++) {
++ for (port = ct_amanda_info->port; port != 0; port++) {
+ t.dst.u.tcp.port = htons(port);
+ if (ip_conntrack_change_expect(exp, &t) == 0)
+ break;
+Index: linux-2.6.0-test5/net/ipv4/netfilter/ip_nat_irc.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/netfilter/ip_nat_irc.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/netfilter/ip_nat_irc.c 2003-09-27 11:38:41.832168928 +0800
+@@ -99,7 +99,7 @@
+ struct ip_conntrack_tuple t;
+ struct iphdr *iph = (*pskb)->nh.iph;
+ struct tcphdr *tcph = (void *) iph + iph->ihl * 4;
+- int port;
++ u_int16_t port;
+
+ /* "4294967296 65635 " */
+ char buffer[18];
+Index: linux-2.6.0-test5/net/ipv4/netfilter/ip_nat_snmp_basic.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/netfilter/ip_nat_snmp_basic.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/netfilter/ip_nat_snmp_basic.c 2003-09-27 11:38:41.840167712 +0800
+@@ -51,9 +51,9 @@
+ #include <linux/netfilter_ipv4/ip_nat.h>
+ #include <linux/netfilter_ipv4/ip_nat_helper.h>
+ #include <linux/ip.h>
++#include <net/checksum.h>
+ #include <net/udp.h>
+ #include <asm/uaccess.h>
+-#include <asm/checksum.h>
+
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");
+Index: linux-2.6.0-test5/net/ipv4/netfilter/ip_nat_tftp.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/netfilter/ip_nat_tftp.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/netfilter/ip_nat_tftp.c 2003-09-27 11:38:41.842167408 +0800
+@@ -30,7 +30,7 @@
+ #include <linux/netfilter_ipv4/ip_nat_rule.h>
+
+ MODULE_AUTHOR("Magnus Boden <mb@ozaba.mine.nu>");
+-MODULE_DESCRIPTION("tfpt NAT helper");
++MODULE_DESCRIPTION("tftp NAT helper");
+ MODULE_LICENSE("GPL");
+
+ #define MAX_PORTS 8
+Index: linux-2.6.0-test5/net/ipv4/netfilter/ipt_MASQUERADE.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/netfilter/ipt_MASQUERADE.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/netfilter/ipt_MASQUERADE.c 2003-09-27 11:38:41.845166952 +0800
+@@ -130,57 +130,35 @@
+ }
+
+ static inline int
+-device_cmp(const struct ip_conntrack *i, void *ifindex)
++device_cmp(const struct ip_conntrack *i, void *_ina)
+ {
+- int ret;
++ int ret = 0;
++ struct in_ifaddr *ina = _ina;
+
+ READ_LOCK(&masq_lock);
+- ret = (i->nat.masq_index == (int)(long)ifindex);
++ /* If it's masquerading out this interface with a different address,
++ or we don't know the new address of this interface. */
++ if (i->nat.masq_index == ina->ifa_dev->dev->ifindex
++ && i->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip != ina->ifa_address)
++ ret = 1;
+ READ_UNLOCK(&masq_lock);
+
+ return ret;
+ }
+
+-static int masq_device_event(struct notifier_block *this,
+- unsigned long event,
+- void *ptr)
+-{
+- struct net_device *dev = ptr;
+-
+- if (event == NETDEV_DOWN) {
+- /* Device was downed. Search entire table for
+- conntracks which were associated with that device,
+- and forget them. */
+- IP_NF_ASSERT(dev->ifindex != 0);
+-
+- ip_ct_selective_cleanup(device_cmp, (void *)(long)dev->ifindex);
+- }
+-
+- return NOTIFY_DONE;
+-}
+-
+ static int masq_inet_event(struct notifier_block *this,
+ unsigned long event,
+ void *ptr)
+ {
+- struct net_device *dev = ((struct in_ifaddr *)ptr)->ifa_dev->dev;
+-
+- if (event == NETDEV_DOWN) {
+- /* IP address was deleted. Search entire table for
+- conntracks which were associated with that device,
+- and forget them. */
+- IP_NF_ASSERT(dev->ifindex != 0);
+-
+- ip_ct_selective_cleanup(device_cmp, (void *)(long)dev->ifindex);
+- }
++ /* For some configurations, interfaces often come back with
++ * the same address. If not, clean up old conntrack
++ * entries. */
++ if (event == NETDEV_UP)
++ ip_ct_selective_cleanup(device_cmp, ptr);
+
+ return NOTIFY_DONE;
+ }
+
+-static struct notifier_block masq_dev_notifier = {
+- .notifier_call = masq_device_event,
+-};
+-
+ static struct notifier_block masq_inet_notifier = {
+ .notifier_call = masq_inet_event,
+ };
+@@ -198,12 +176,9 @@
+
+ ret = ipt_register_target(&masquerade);
+
+- if (ret == 0) {
+- /* Register for device down reports */
+- register_netdevice_notifier(&masq_dev_notifier);
++ if (ret == 0)
+ /* Register IP address change reports */
+ register_inetaddr_notifier(&masq_inet_notifier);
+- }
+
+ return ret;
+ }
+@@ -211,7 +186,6 @@
+ static void __exit fini(void)
+ {
+ ipt_unregister_target(&masquerade);
+- unregister_netdevice_notifier(&masq_dev_notifier);
+ unregister_inetaddr_notifier(&masq_inet_notifier);
+ }
+
+Index: linux-2.6.0-test5/net/ipv4/netfilter/ipt_physdev.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/netfilter/ipt_physdev.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/netfilter/ipt_physdev.c 2003-09-27 11:38:41.846166800 +0800
+@@ -23,7 +23,7 @@
+ int i;
+ static const char nulldevname[IFNAMSIZ];
+ const struct ipt_physdev_info *info = matchinfo;
+- unsigned long ret;
++ unsigned int ret;
+ const char *indev, *outdev;
+ struct nf_bridge_info *nf_bridge;
+
+@@ -65,10 +65,10 @@
+ if (!(info->bitmask & IPT_PHYSDEV_OP_IN))
+ goto match_outdev;
+ indev = nf_bridge->physindev ? nf_bridge->physindev->name : nulldevname;
+- for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) {
+- ret |= (((const unsigned long *)indev)[i]
+- ^ ((const unsigned long *)info->physindev)[i])
+- & ((const unsigned long *)info->in_mask)[i];
++ for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) {
++ ret |= (((const unsigned int *)indev)[i]
++ ^ ((const unsigned int *)info->physindev)[i])
++ & ((const unsigned int *)info->in_mask)[i];
+ }
+
+ if ((ret == 0) ^ !(info->invert & IPT_PHYSDEV_OP_IN))
+@@ -79,10 +79,10 @@
+ return MATCH;
+ outdev = nf_bridge->physoutdev ?
+ nf_bridge->physoutdev->name : nulldevname;
+- for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) {
+- ret |= (((const unsigned long *)outdev)[i]
+- ^ ((const unsigned long *)info->physoutdev)[i])
+- & ((const unsigned long *)info->out_mask)[i];
++ for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) {
++ ret |= (((const unsigned int *)outdev)[i]
++ ^ ((const unsigned int *)info->physoutdev)[i])
++ & ((const unsigned int *)info->out_mask)[i];
+ }
+
+ return (ret != 0) ^ !(info->invert & IPT_PHYSDEV_OP_OUT);
+Index: linux-2.6.0-test5/net/ipv4/netfilter/ipt_REJECT.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/netfilter/ipt_REJECT.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/netfilter/ipt_REJECT.c 2003-09-27 11:38:41.851166040 +0800
+@@ -84,45 +84,34 @@
+ static void send_reset(struct sk_buff *oldskb, int local)
+ {
+ struct sk_buff *nskb;
+- struct tcphdr *otcph, *tcph;
++ struct tcphdr otcph, *tcph;
+ struct rtable *rt;
+- unsigned int otcplen;
+ u_int16_t tmp_port;
+ u_int32_t tmp_addr;
+ int needs_ack;
+ int hh_len;
+
+- /* IP header checks: fragment, too short. */
+- if (oldskb->nh.iph->frag_off & htons(IP_OFFSET)
+- || oldskb->len < (oldskb->nh.iph->ihl<<2) + sizeof(struct tcphdr))
++ /* IP header checks: fragment. */
++ if (oldskb->nh.iph->frag_off & htons(IP_OFFSET))
+ return;
+
+- otcph = (struct tcphdr *)((u_int32_t*)oldskb->nh.iph + oldskb->nh.iph->ihl);
+- otcplen = oldskb->len - oldskb->nh.iph->ihl*4;
+-
+ if (skb_copy_bits(oldskb, oldskb->nh.iph->ihl*4,
+- otcph, sizeof(*otcph)) < 0)
+- return;
++ &otcph, sizeof(otcph)) < 0)
++ return;
+
+ /* No RST for RST. */
+- if (otcph->rst)
+- return;
+-
+- /* Check checksum. */
+- if (tcp_v4_check(otcph, otcplen, oldskb->nh.iph->saddr,
+- oldskb->nh.iph->daddr,
+- csum_partial((char *)otcph, otcplen, 0)) != 0)
++ if (otcph.rst)
+ return;
+
++ /* FIXME: Check checksum --RR */
+ if ((rt = route_reverse(oldskb, local)) == NULL)
+ return;
+
+ hh_len = (rt->u.dst.dev->hard_header_len + 15)&~15;
+
+- /* Copy skb (even if skb is about to be dropped, we can't just
+- clone it because there may be other things, such as tcpdump,
+- interested in it). We also need to expand headroom in case
+- hh_len of incoming interface < hh_len of outgoing interface */
++ /* We need a linear, writeable skb. We also need to expand
++ headroom in case hh_len of incoming interface < hh_len of
++ outgoing interface */
+ nskb = skb_copy_expand(oldskb, hh_len, skb_tailroom(oldskb),
+ GFP_ATOMIC);
+ if (!nskb) {
+@@ -163,12 +152,13 @@
+
+ if (tcph->ack) {
+ needs_ack = 0;
+- tcph->seq = otcph->ack_seq;
++ tcph->seq = otcph.ack_seq;
+ tcph->ack_seq = 0;
+ } else {
+ needs_ack = 1;
+- tcph->ack_seq = htonl(ntohl(otcph->seq) + otcph->syn + otcph->fin
+- + otcplen - (otcph->doff<<2));
++ tcph->ack_seq = htonl(ntohl(otcph.seq) + otcph.syn + otcph.fin
++ + oldskb->len - oldskb->nh.iph->ihl*4
++ - (otcph.doff<<2));
+ tcph->seq = 0;
+ }
+
+Index: linux-2.6.0-test5/net/ipv4/proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/proc.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/proc.c 2003-09-27 11:38:41.853165736 +0800
+@@ -238,28 +238,21 @@
+ int __init ip_misc_proc_init(void)
+ {
+ int rc = 0;
+- struct proc_dir_entry *p;
+
+- p = create_proc_entry("netstat", S_IRUGO, proc_net);
+- if (!p)
++ if (!proc_net_fops_create("netstat", S_IRUGO, &netstat_seq_fops))
+ goto out_netstat;
+- p->proc_fops = &netstat_seq_fops;
+
+- p = create_proc_entry("snmp", S_IRUGO, proc_net);
+- if (!p)
++ if (!proc_net_fops_create("snmp", S_IRUGO, &snmp_seq_fops))
+ goto out_snmp;
+- p->proc_fops = &snmp_seq_fops;
+
+- p = create_proc_entry("sockstat", S_IRUGO, proc_net);
+- if (!p)
++ if (!proc_net_fops_create("sockstat", S_IRUGO, &sockstat_seq_fops))
+ goto out_sockstat;
+- p->proc_fops = &sockstat_seq_fops;
+ out:
+ return rc;
+ out_sockstat:
+- remove_proc_entry("snmp", proc_net);
++ proc_net_remove("snmp");
+ out_snmp:
+- remove_proc_entry("netstat", proc_net);
++ proc_net_remove("netstat");
+ out_netstat:
+ rc = -ENOMEM;
+ goto out;
+Index: linux-2.6.0-test5/net/ipv4/raw.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/raw.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/raw.c 2003-09-27 11:38:41.859164824 +0800
+@@ -736,14 +736,14 @@
+ static void *raw_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+ read_lock(&raw_v4_lock);
+- return *pos ? raw_get_idx(seq, *pos) : (void *)1;
++ return *pos ? raw_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+ }
+
+ static void *raw_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
+ struct sock *sk;
+
+- if (v == (void *)1)
++ if (v == SEQ_START_TOKEN)
+ sk = raw_get_first(seq);
+ else
+ sk = raw_get_next(seq, v);
+@@ -778,7 +778,7 @@
+ {
+ char tmpbuf[129];
+
+- if (v == (void *)1)
++ if (v == SEQ_START_TOKEN)
+ seq_printf(seq, "%-127s\n",
+ " sl local_address rem_address st tx_queue "
+ "rx_queue tr tm->when retrnsmt uid timeout "
+@@ -831,19 +831,13 @@
+
+ int __init raw_proc_init(void)
+ {
+- struct proc_dir_entry *p;
+- int rc = 0;
+-
+- p = create_proc_entry("raw", S_IRUGO, proc_net);
+- if (p)
+- p->proc_fops = &raw_seq_fops;
+- else
+- rc = -ENOMEM;
+- return rc;
++ if (!proc_net_fops_create("raw", S_IRUGO, &raw_seq_fops))
++ return -ENOMEM;
++ return 0;
+ }
+
+ void __init raw_proc_exit(void)
+ {
+- remove_proc_entry("raw", proc_net);
++ proc_net_remove("raw");
+ }
+ #endif /* CONFIG_PROC_FS */
+Index: linux-2.6.0-test5/net/ipv4/route.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/route.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/route.c 2003-09-27 11:38:41.877162088 +0800
+@@ -259,14 +259,14 @@
+
+ static void *rt_cache_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+- return *pos ? rt_cache_get_idx(seq, *pos) : (void *)1;
++ return *pos ? rt_cache_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+ }
+
+ static void *rt_cache_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
+ struct rtable *r = NULL;
+
+- if (v == (void *)1)
++ if (v == SEQ_START_TOKEN)
+ r = rt_cache_get_first(seq);
+ else
+ r = rt_cache_get_next(seq, v);
+@@ -276,13 +276,13 @@
+
+ static void rt_cache_seq_stop(struct seq_file *seq, void *v)
+ {
+- if (v && v != (void *)1)
++ if (v && v != SEQ_START_TOKEN)
+ rcu_read_unlock();
+ }
+
+ static int rt_cache_seq_show(struct seq_file *seq, void *v)
+ {
+- if (v == (void *)1)
++ if (v == SEQ_START_TOKEN)
+ seq_printf(seq, "%-127s\n",
+ "Iface\tDestination\tGateway \tFlags\t\tRefCnt\tUse\t"
+ "Metric\tSource\t\tMTU\tWindow\tIRTT\tTOS\tHHRef\t"
+Index: linux-2.6.0-test5/net/ipv4/tcp_diag.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/tcp_diag.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/tcp_diag.c 2003-09-27 11:38:41.882161328 +0800
+@@ -213,7 +213,7 @@
+ int dif);
+ #endif
+
+-static int tcpdiag_get_exact(struct sk_buff *in_skb, struct nlmsghdr *nlh)
++static int tcpdiag_get_exact(struct sk_buff *in_skb, const struct nlmsghdr *nlh)
+ {
+ int err;
+ struct sock *sk;
+@@ -272,7 +272,7 @@
+ return err;
+ }
+
+-int bitstring_match(u32 *a1, u32 *a2, int bits)
++static int bitstring_match(const u32 *a1, const u32 *a2, int bits)
+ {
+ int words = bits >> 5;
+
+@@ -299,12 +299,12 @@
+ }
+
+
+-int tcpdiag_bc_run(char *bc, int len, struct sock *sk)
++static int tcpdiag_bc_run(const void *bc, int len, struct sock *sk)
+ {
+ while (len > 0) {
+ int yes = 1;
+ struct inet_opt *inet = inet_sk(sk);
+- struct tcpdiag_bc_op *op = (struct tcpdiag_bc_op*)bc;
++ const struct tcpdiag_bc_op *op = bc;
+
+ switch (op->code) {
+ case TCPDIAG_BC_NOP:
+@@ -385,10 +385,10 @@
+ return (len == 0);
+ }
+
+-int valid_cc(char *bc, int len, int cc)
++static int valid_cc(const void *bc, int len, int cc)
+ {
+ while (len >= 0) {
+- struct tcpdiag_bc_op *op = (struct tcpdiag_bc_op*)bc;
++ const struct tcpdiag_bc_op *op = bc;
+
+ if (cc > len)
+ return 0;
+@@ -402,9 +402,9 @@
+ return 0;
+ }
+
+-int tcpdiag_bc_audit(char *bytecode, int bytecode_len)
++static int tcpdiag_bc_audit(const void *bytecode, int bytecode_len)
+ {
+- char *bc = bytecode;
++ const unsigned char *bc = bytecode;
+ int len = bytecode_len;
+
+ while (len > 0) {
+@@ -442,7 +442,7 @@
+ }
+
+
+-int tcpdiag_dump(struct sk_buff *skb, struct netlink_callback *cb)
++static int tcpdiag_dump(struct sk_buff *skb, struct netlink_callback *cb)
+ {
+ int i, num;
+ int s_i, s_num;
+Index: linux-2.6.0-test5/net/ipv4/tcp_ipv4.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/tcp_ipv4.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/tcp_ipv4.c 2003-09-27 11:38:41.900158592 +0800
+@@ -2351,7 +2351,7 @@
+
+ static void *tcp_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+- return *pos ? tcp_get_idx(seq, *pos - 1) : (void *)1;
++ return *pos ? tcp_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+ }
+
+ static void *tcp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -2359,7 +2359,7 @@
+ void *rc = NULL;
+ struct tcp_iter_state* st;
+
+- if (v == (void *)1) {
++ if (v == SEQ_START_TOKEN) {
+ rc = tcp_get_idx(seq, 0);
+ goto out;
+ }
+@@ -2397,7 +2397,7 @@
+ read_unlock_bh(&tp->syn_wait_lock);
+ }
+ case TCP_SEQ_STATE_LISTENING:
+- if (v != (void *)1)
++ if (v != SEQ_START_TOKEN)
+ tcp_listen_unlock();
+ break;
+ case TCP_SEQ_STATE_TIME_WAIT:
+@@ -2413,11 +2413,15 @@
+ {
+ struct tcp_seq_afinfo *afinfo = PDE(inode)->data;
+ struct seq_file *seq;
+- int rc = -ENOMEM;
+- struct tcp_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
++ struct tcp_iter_state *s;
++ int rc;
+
++ if (unlikely(afinfo == NULL))
++ return -EINVAL;
++
++ s = kmalloc(sizeof(*s), GFP_KERNEL);
+ if (!s)
+- goto out;
++ return -ENOMEM;
+ memset(s, 0, sizeof(*s));
+ s->family = afinfo->family;
+ s->seq_ops.start = tcp_seq_start;
+@@ -2450,11 +2454,10 @@
+ afinfo->seq_fops->llseek = seq_lseek;
+ afinfo->seq_fops->release = seq_release_private;
+
+- p = create_proc_entry(afinfo->name, S_IRUGO, proc_net);
+- if (p) {
++ p = proc_net_fops_create(afinfo->name, S_IRUGO, afinfo->seq_fops);
++ if (p)
+ p->data = afinfo;
+- p->proc_fops = afinfo->seq_fops;
+- } else
++ else
+ rc = -ENOMEM;
+ return rc;
+ }
+@@ -2463,7 +2466,7 @@
+ {
+ if (!afinfo)
+ return;
+- remove_proc_entry(afinfo->name, proc_net);
++ proc_net_remove(afinfo->name);
+ memset(afinfo->seq_fops, 0, sizeof(*afinfo->seq_fops));
+ }
+
+@@ -2559,7 +2562,7 @@
+ struct tcp_iter_state* st;
+ char tmpbuf[TMPSZ + 1];
+
+- if (v == (void *)1) {
++ if (v == SEQ_START_TOKEN) {
+ seq_printf(seq, "%-*s\n", TMPSZ - 1,
+ " sl local_address rem_address st tx_queue "
+ "rx_queue tr tm->when retrnsmt uid timeout "
+Index: linux-2.6.0-test5/net/ipv4/udp.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/udp.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/udp.c 2003-09-27 11:38:41.910157072 +0800
+@@ -384,6 +384,7 @@
+ struct udp_opt *up = udp_sk(sk);
+
+ if (up->pending) {
++ up->len = 0;
+ up->pending = 0;
+ ip_flush_pending_frames(sk);
+ }
+@@ -1460,11 +1461,10 @@
+ afinfo->seq_fops->llseek = seq_lseek;
+ afinfo->seq_fops->release = seq_release_private;
+
+- p = create_proc_entry(afinfo->name, S_IRUGO, proc_net);
+- if (p) {
++ p = proc_net_fops_create(afinfo->name, S_IRUGO, afinfo->seq_fops);
++ if (p)
+ p->data = afinfo;
+- p->proc_fops = afinfo->seq_fops;
+- } else
++ else
+ rc = -ENOMEM;
+ return rc;
+ }
+@@ -1473,7 +1473,7 @@
+ {
+ if (!afinfo)
+ return;
+- remove_proc_entry(afinfo->name, proc_net);
++ proc_net_remove(afinfo->name);
+ memset(afinfo->seq_fops, 0, sizeof(*afinfo->seq_fops));
+ }
+
+@@ -1497,7 +1497,7 @@
+
+ static int udp4_seq_show(struct seq_file *seq, void *v)
+ {
+- if (v == (void *)1)
++ if (v == SEQ_START_TOKEN)
+ seq_printf(seq, "%-127s\n",
+ " sl local_address rem_address st tx_queue "
+ "rx_queue tr tm->when retrnsmt uid timeout "
+Index: linux-2.6.0-test5/net/ipv6/addrconf.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv6/addrconf.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv6/addrconf.c 2003-09-27 11:38:41.929154184 +0800
+@@ -2149,59 +2149,65 @@
+ int bucket;
+ };
+
+-static inline struct inet6_ifaddr *if6_get_bucket(struct seq_file *seq, loff_t *pos)
++static struct inet6_ifaddr *if6_get_first(struct seq_file *seq)
+ {
+- int i;
+ struct inet6_ifaddr *ifa = NULL;
+- loff_t l = *pos;
+ struct if6_iter_state *state = seq->private;
+
+- for (; state->bucket < IN6_ADDR_HSIZE; ++state->bucket)
+- for (i = 0, ifa = inet6_addr_lst[state->bucket]; ifa; ++i, ifa=ifa->lst_next) {
+- if (l--)
+- continue;
+- *pos = i;
+- goto out;
+- }
+-out:
++ for (state->bucket = 0; state->bucket < IN6_ADDR_HSIZE; ++state->bucket) {
++ ifa = inet6_addr_lst[state->bucket];
++ if (ifa)
++ break;
++ }
+ return ifa;
+ }
+
++static struct inet6_ifaddr *if6_get_next(struct seq_file *seq, struct inet6_ifaddr *ifa)
++{
++ struct if6_iter_state *state = seq->private;
++
++ ifa = ifa->lst_next;
++try_again:
++ if (!ifa && ++state->bucket < IN6_ADDR_HSIZE) {
++ ifa = inet6_addr_lst[state->bucket];
++ goto try_again;
++ }
++ return ifa;
++}
++
++static struct inet6_ifaddr *if6_get_idx(struct seq_file *seq, loff_t pos)
++{
++ struct inet6_ifaddr *ifa = if6_get_first(seq);
++
++ if (ifa)
++ while(pos && (ifa = if6_get_next(seq, ifa)) != NULL)
++ --pos;
++ return pos ? NULL : ifa;
++}
++
+ static void *if6_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+ read_lock_bh(&addrconf_hash_lock);
+- return *pos ? if6_get_bucket(seq, pos) : (void *)1;
++ return if6_get_idx(seq, *pos);
+ }
+
+ static void *if6_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
+ struct inet6_ifaddr *ifa;
+- struct if6_iter_state *state;
+-
+- if (v == (void *)1) {
+- ifa = if6_get_bucket(seq, pos);
+- goto out;
+- }
+-
+- state = seq->private;
+
+- ifa = v;
+- ifa = ifa->lst_next;
+- if (ifa)
+- goto out;
+-
+- if (++state->bucket >= IN6_ADDR_HSIZE)
+- goto out;
+-
+- *pos = 0;
+- ifa = if6_get_bucket(seq, pos);
+-out:
++ ifa = if6_get_next(seq, v);
+ ++*pos;
+ return ifa;
+ }
+
+-static inline void if6_iface_seq_show(struct seq_file *seq, struct inet6_ifaddr *ifp)
++static void if6_seq_stop(struct seq_file *seq, void *v)
++{
++ read_unlock_bh(&addrconf_hash_lock);
++}
++
++static int if6_seq_show(struct seq_file *seq, void *v)
+ {
++ struct inet6_ifaddr *ifp = (struct inet6_ifaddr *)v;
+ seq_printf(seq,
+ "%04x%04x%04x%04x%04x%04x%04x%04x %02x %02x %02x %02x %8s\n",
+ NIP6(ifp->addr),
+@@ -2210,22 +2216,9 @@
+ ifp->scope,
+ ifp->flags,
+ ifp->idev->dev->name);
+-}
+-
+-static int if6_seq_show(struct seq_file *seq, void *v)
+-{
+- if (v == (void *)1)
+- return 0;
+- else
+- if6_iface_seq_show(seq, v);
+ return 0;
+ }
+
+-static void if6_seq_stop(struct seq_file *seq, void *v)
+-{
+- read_unlock_bh(&addrconf_hash_lock);
+-}
+-
+ static struct seq_operations if6_seq_ops = {
+ .start = if6_seq_start,
+ .next = if6_seq_next,
+@@ -2266,16 +2259,11 @@
+
+ int __init if6_proc_init(void)
+ {
+- struct proc_dir_entry *p;
+- int rc = 0;
+-
+- p = create_proc_entry("if_inet6", S_IRUGO, proc_net);
+- if (p)
+- p->proc_fops = &if6_fops;
+- else
+- rc = -ENOMEM;
+- return rc;
++ if (!proc_net_fops_create("if_inet6", S_IRUGO, &if6_fops))
++ return -ENOMEM;
++ return 0;
+ }
++
+ void if6_proc_exit(void)
+ {
+ proc_net_remove("if_inet6");
+@@ -2529,7 +2517,109 @@
+ netlink_broadcast(rtnl, skb, 0, RTMGRP_IPV6_IFADDR, GFP_ATOMIC);
+ }
+
++static void inline ipv6_store_devconf(struct ipv6_devconf *cnf,
++ __s32 *array, int bytes)
++{
++ memset(array, 0, bytes);
++ array[DEVCONF_FORWARDING] = cnf->forwarding;
++ array[DEVCONF_HOPLIMIT] = cnf->hop_limit;
++ array[DEVCONF_MTU6] = cnf->mtu6;
++ array[DEVCONF_ACCEPT_RA] = cnf->accept_ra;
++ array[DEVCONF_ACCEPT_REDIRECTS] = cnf->accept_redirects;
++ array[DEVCONF_AUTOCONF] = cnf->autoconf;
++ array[DEVCONF_DAD_TRANSMITS] = cnf->dad_transmits;
++ array[DEVCONF_RTR_SOLICITS] = cnf->rtr_solicits;
++ array[DEVCONF_RTR_SOLICIT_INTERVAL] = cnf->rtr_solicit_interval;
++ array[DEVCONF_RTR_SOLICIT_DELAY] = cnf->rtr_solicit_delay;
++#ifdef CONFIG_IPV6_PRIVACY
++ array[DEVCONF_USE_TEMPADDR] = cnf->use_tempaddr;
++ array[DEVCONF_TEMP_VALID_LFT] = cnf->temp_valid_lft;
++ array[DEVCONF_TEMP_PREFERED_LFT] = cnf->temp_prefered_lft;
++ array[DEVCONF_REGEN_MAX_RETRY] = cnf->regen_max_retry;
++ array[DEVCONF_MAX_DESYNC_FACTOR] = cnf->max_desync_factor;
++#endif
++}
++
++static int inet6_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
++ struct inet6_dev *idev,
++ int type, u32 pid, u32 seq)
++{
++ __s32 *array = NULL;
++ struct ifinfomsg *r;
++ struct nlmsghdr *nlh;
++ unsigned char *b = skb->tail;
++ struct rtattr *subattr;
++
++ nlh = NLMSG_PUT(skb, pid, seq, type, sizeof(*r));
++ if (pid) nlh->nlmsg_flags |= NLM_F_MULTI;
++ r = NLMSG_DATA(nlh);
++ r->ifi_family = AF_INET6;
++ r->ifi_type = dev->type;
++ r->ifi_index = dev->ifindex;
++ r->ifi_flags = dev->flags;
++ r->ifi_change = 0;
++ if (!netif_running(dev) || !netif_carrier_ok(dev))
++ r->ifi_flags &= ~IFF_RUNNING;
++ else
++ r->ifi_flags |= IFF_RUNNING;
++
++ RTA_PUT(skb, IFLA_IFNAME, strlen(dev->name)+1, dev->name);
++
++ subattr = (struct rtattr*)skb->tail;
++
++ RTA_PUT(skb, IFLA_PROTINFO, 0, NULL);
++
++ /* return the device flags */
++ RTA_PUT(skb, IFLA_INET6_FLAGS, sizeof(__u32), &idev->if_flags);
++
++ /* return the device sysctl params */
++ if ((array = kmalloc(DEVCONF_MAX * sizeof(*array), GFP_ATOMIC)) == NULL)
++ goto rtattr_failure;
++ ipv6_store_devconf(&idev->cnf, array, DEVCONF_MAX * sizeof(*array));
++ RTA_PUT(skb, IFLA_INET6_CONF, DEVCONF_MAX * sizeof(*array), array);
++
++ /* XXX - Statistics/MC not implemented */
++ subattr->rta_len = skb->tail - (u8*)subattr;
++
++ nlh->nlmsg_len = skb->tail - b;
++ kfree(array);
++ return skb->len;
++
++nlmsg_failure:
++rtattr_failure:
++ if (array)
++ kfree(array);
++ skb_trim(skb, b - skb->data);
++ return -1;
++}
++
++static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
++{
++ int idx, err;
++ int s_idx = cb->args[0];
++ struct net_device *dev;
++ struct inet6_dev *idev;
++
++ read_lock(&dev_base_lock);
++ for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) {
++ if (idx < s_idx)
++ continue;
++ if ((idev = in6_dev_get(dev)) == NULL)
++ continue;
++ err = inet6_fill_ifinfo(skb, dev, idev, RTM_NEWLINK,
++ NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq);
++ in6_dev_put(idev);
++ if (err <= 0)
++ break;
++ }
++ read_unlock(&dev_base_lock);
++ cb->args[0] = idx;
++
++ return skb->len;
++}
++
+ static struct rtnetlink_link inet6_rtnetlink_table[RTM_MAX - RTM_BASE + 1] = {
++ [RTM_GETLINK - RTM_BASE] = { .dumpit = inet6_dump_ifinfo, },
+ [RTM_NEWADDR - RTM_BASE] = { .doit = inet6_rtm_newaddr, },
+ [RTM_DELADDR - RTM_BASE] = { .doit = inet6_rtm_deladdr, },
+ [RTM_GETADDR - RTM_BASE] = { .dumpit = inet6_dump_ifaddr, },
+Index: linux-2.6.0-test5/net/ipv6/anycast.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv6/anycast.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv6/anycast.c 2003-09-27 11:38:41.934153424 +0800
+@@ -505,7 +505,7 @@
+ static void *ac6_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+ read_lock(&dev_base_lock);
+- return *pos ? ac6_get_idx(seq, *pos) : ac6_get_first(seq);
++ return ac6_get_idx(seq, *pos);
+ }
+
+ static void *ac6_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -581,11 +581,9 @@
+
+ int __init ac6_proc_init(void)
+ {
+- struct proc_dir_entry *p;
++ if (!proc_net_fops_create("anycast6", S_IRUGO, &ac6_seq_fops))
++ return -ENOMEM;
+
+- p = create_proc_entry("anycast6", S_IRUGO, proc_net);
+- if (p)
+- p->proc_fops = &ac6_seq_fops;
+ return 0;
+ }
+
+Index: linux-2.6.0-test5/net/ipv6/ip6_flowlabel.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv6/ip6_flowlabel.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv6/ip6_flowlabel.c 2003-09-27 11:38:41.938152816 +0800
+@@ -603,14 +603,14 @@
+ static void *ip6fl_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+ read_lock_bh(&ip6_fl_lock);
+- return *pos ? ip6fl_get_idx(seq, *pos) : (void *)1;
++ return *pos ? ip6fl_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+ }
+
+ static void *ip6fl_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
+ struct ip6_flowlabel *fl;
+
+- if (v == (void *)1)
++ if (v == SEQ_START_TOKEN)
+ fl = ip6fl_get_first(seq);
+ else
+ fl = ip6fl_get_next(seq, v);
+@@ -644,7 +644,7 @@
+
+ static int ip6fl_seq_show(struct seq_file *seq, void *v)
+ {
+- if (v == (void *)1)
++ if (v == SEQ_START_TOKEN)
+ seq_printf(seq, "Label S Owner Users Linger Expires "
+ "Dst Opt\n");
+ else
+@@ -695,12 +695,7 @@
+ void ip6_flowlabel_init()
+ {
+ #ifdef CONFIG_PROC_FS
+- struct proc_dir_entry *p;
+-#endif
+-#ifdef CONFIG_PROC_FS
+- p = create_proc_entry("ip6_flowlabel", S_IRUGO, proc_net);
+- if (p)
+- p->proc_fops = &ip6fl_seq_fops;
++ proc_net_fops_create("ip6_flowlabel", S_IRUGO, &ip6fl_seq_fops);
+ #endif
+ }
+
+Index: linux-2.6.0-test5/net/ipv6/mcast.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv6/mcast.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv6/mcast.c 2003-09-27 11:38:41.954150384 +0800
+@@ -2119,7 +2119,7 @@
+ static void *igmp6_mc_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+ read_lock(&dev_base_lock);
+- return *pos ? igmp6_mc_get_idx(seq, *pos) : igmp6_mc_get_first(seq);
++ return igmp6_mc_get_idx(seq, *pos);
+ }
+
+ static void *igmp6_mc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -2278,13 +2278,13 @@
+ static void *igmp6_mcf_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+ read_lock(&dev_base_lock);
+- return *pos ? igmp6_mcf_get_idx(seq, *pos) : (void *)1;
++ return *pos ? igmp6_mcf_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+ }
+
+ static void *igmp6_mcf_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
+ struct ip6_sf_list *psf;
+- if (v == (void *)1)
++ if (v == SEQ_START_TOKEN)
+ psf = igmp6_mcf_get_first(seq);
+ else
+ psf = igmp6_mcf_get_next(seq, v);
+@@ -2313,7 +2313,7 @@
+ struct ip6_sf_list *psf = (struct ip6_sf_list *)v;
+ struct igmp6_mcf_iter_state *state = igmp6_mcf_seq_private(seq);
+
+- if (v == (void *)1) {
++ if (v == SEQ_START_TOKEN) {
+ seq_printf(seq,
+ "%3s %6s "
+ "%32s %32s %6s %6s\n", "Idx",
+@@ -2378,9 +2378,6 @@
+ struct ipv6_pinfo *np;
+ struct sock *sk;
+ int err;
+-#ifdef CONFIG_PROC_FS
+- struct proc_dir_entry *p;
+-#endif
+
+ err = sock_create(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, &igmp6_socket);
+ if (err < 0) {
+@@ -2399,12 +2396,8 @@
+ np->hop_limit = 1;
+
+ #ifdef CONFIG_PROC_FS
+- p = create_proc_entry("igmp6", S_IRUGO, proc_net);
+- if (p)
+- p->proc_fops = &igmp6_mc_seq_fops;
+- p = create_proc_entry("mcfilter6", S_IRUGO, proc_net);
+- if (p)
+- p->proc_fops = &igmp6_mcf_seq_fops;
++ proc_net_fops_create("igmp6", S_IRUGO, &igmp6_mc_seq_fops);
++ proc_net_fops_create("mcfilter6", S_IRUGO, &igmp6_mcf_seq_fops);
+ #endif
+
+ return 0;
+@@ -2414,6 +2407,7 @@
+ {
+ sock_release(igmp6_socket);
+ igmp6_socket = NULL; /* for safety */
++
+ #ifdef CONFIG_PROC_FS
+ proc_net_remove("mcfilter6");
+ proc_net_remove("igmp6");
+Index: linux-2.6.0-test5/net/ipv6/ndisc.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv6/ndisc.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv6/ndisc.c 2003-09-27 11:38:41.965148712 +0800
+@@ -1044,6 +1044,17 @@
+ in6_dev->if_flags |= IF_RA_RCVD;
+ }
+
++ /*
++ * Remember the managed/otherconf flags from most recently
++ * received RA message (RFC 2462) -- yoshfuji
++ */
++ in6_dev->if_flags = (in6_dev->if_flags & ~(IF_RA_MANAGED |
++ IF_RA_OTHERCONF)) |
++ (ra_msg->icmph.icmp6_addrconf_managed ?
++ IF_RA_MANAGED : 0) |
++ (ra_msg->icmph.icmp6_addrconf_other ?
++ IF_RA_OTHERCONF : 0);
++
+ lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime);
+
+ rt = rt6_get_dflt_router(&skb->nh.ipv6h->saddr, skb->dev);
+Index: linux-2.6.0-test5/net/ipv6/proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv6/proc.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv6/proc.c 2003-09-27 11:38:41.967148408 +0800
+@@ -32,7 +32,6 @@
+
+ #ifdef CONFIG_PROC_FS
+ static struct proc_dir_entry *proc_net_devsnmp6;
+-#endif
+
+ static int fold_prot_inuse(struct proto *proto)
+ {
+@@ -58,7 +57,6 @@
+ return 0;
+ }
+
+-
+ struct snmp6_item
+ {
+ char *name;
+@@ -221,9 +219,7 @@
+ int snmp6_register_dev(struct inet6_dev *idev)
+ {
+ int err = -ENOMEM;
+-#ifdef CONFIG_PROC_FS
+ struct proc_dir_entry *p;
+-#endif
+
+ if (!idev || !idev->dev)
+ return -EINVAL;
+@@ -232,7 +228,6 @@
+ __alignof__(struct icmpv6_mib)) < 0)
+ goto err_icmp;
+
+-#ifdef CONFIG_PROC_FS
+ if (!proc_net_devsnmp6) {
+ err = -ENOENT;
+ goto err_proc;
+@@ -244,27 +239,22 @@
+ p->proc_fops = &snmp6_seq_fops;
+
+ idev->stats.proc_dir_entry = p;
+-#endif
+ return 0;
+
+-#ifdef CONFIG_PROC_FS
+ err_proc:
+ snmp6_mib_free((void **)idev->stats.icmpv6);
+-#endif
+ err_icmp:
+ return err;
+ }
+
+ int snmp6_unregister_dev(struct inet6_dev *idev)
+ {
+-#ifdef CONFIG_PROC_FS
+ if (!proc_net_devsnmp6)
+ return -ENOENT;
+ if (!idev || !idev->stats.proc_dir_entry)
+ return -EINVAL;
+ remove_proc_entry(idev->stats.proc_dir_entry->name,
+ proc_net_devsnmp6);
+-#endif
+ snmp6_mib_free((void **)idev->stats.icmpv6);
+
+ return 0;
+@@ -273,21 +263,16 @@
+ int __init ipv6_misc_proc_init(void)
+ {
+ int rc = 0;
+- struct proc_dir_entry *p;
+
+- p = create_proc_entry("snmp6", S_IRUGO, proc_net);
+- if (!p)
++ if (!proc_net_fops_create("snmp6", S_IRUGO, &snmp6_seq_fops))
+ goto proc_snmp6_fail;
+- else
+- p->proc_fops = &snmp6_seq_fops;
++
+ proc_net_devsnmp6 = proc_mkdir("dev_snmp6", proc_net);
+ if (!proc_net_devsnmp6)
+ goto proc_dev_snmp6_fail;
+- p = create_proc_entry("sockstat6", S_IRUGO, proc_net);
+- if (!p)
++
++ if (!proc_net_fops_create("sockstat6", S_IRUGO, &sockstat6_seq_fops))
+ goto proc_sockstat6_fail;
+- else
+- p->proc_fops = &sockstat6_seq_fops;
+ out:
+ return rc;
+
+@@ -307,3 +292,31 @@
+ proc_net_remove("snmp6");
+ }
+
++#else /* CONFIG_PROC_FS */
++
++
++int snmp6_register_dev(struct inet6_dev *idev)
++{
++ int err = -ENOMEM;
++
++ if (!idev || !idev->dev)
++ return -EINVAL;
++
++ if (snmp6_mib_init((void **)idev->stats.icmpv6, sizeof(struct icmpv6_mib),
++ __alignof__(struct icmpv6_mib)) < 0)
++ goto err_icmp;
++
++ return 0;
++
++err_icmp:
++ return err;
++}
++
++int snmp6_unregister_dev(struct inet6_dev *idev)
++{
++ snmp6_mib_free((void **)idev->stats.icmpv6);
++ return 0;
++}
++
++#endif
++
+Index: linux-2.6.0-test5/net/ipv6/raw.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv6/raw.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv6/raw.c 2003-09-27 11:38:41.975147192 +0800
+@@ -961,14 +961,14 @@
+ static void *raw6_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+ read_lock(&raw_v6_lock);
+- return *pos ? raw6_get_idx(seq, *pos) : (void *)1;
++ return *pos ? raw6_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+ }
+
+ static void *raw6_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
+ struct sock *sk;
+
+- if (v == (void *)1)
++ if (v == SEQ_START_TOKEN)
+ sk = raw6_get_first(seq);
+ else
+ sk = raw6_get_next(seq, v);
+@@ -1010,7 +1010,7 @@
+
+ static int raw6_seq_show(struct seq_file *seq, void *v)
+ {
+- if (v == (void *)1)
++ if (v == SEQ_START_TOKEN)
+ seq_printf(seq,
+ " sl "
+ "local_address "
+@@ -1059,12 +1059,8 @@
+
+ int __init raw6_proc_init(void)
+ {
+- struct proc_dir_entry *p = create_proc_entry("raw6", S_IRUGO, proc_net);
+-
+- if (!p)
++ if (!proc_net_fops_create("raw6", S_IRUGO, &raw6_seq_fops))
+ return -ENOMEM;
+- p->proc_fops = &raw6_seq_fops;
+-
+ return 0;
+ }
+
+Index: linux-2.6.0-test5/net/ipv6/tcp_ipv6.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv6/tcp_ipv6.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv6/tcp_ipv6.c 2003-09-27 11:38:41.989145064 +0800
+@@ -2023,11 +2023,12 @@
+ atomic_read(&tw->tw_refcnt), tw);
+ }
+
++#ifdef CONFIG_PROC_FS
+ static int tcp6_seq_show(struct seq_file *seq, void *v)
+ {
+ struct tcp_iter_state *st;
+
+- if (v == (void *)1) {
++ if (v == SEQ_START_TOKEN) {
+ seq_printf(seq,
+ " sl "
+ "local_address "
+@@ -2072,6 +2073,7 @@
+ {
+ tcp_proc_unregister(&tcp6_seq_afinfo);
+ }
++#endif
+
+ struct proto tcpv6_prot = {
+ .name = "TCPv6",
+Index: linux-2.6.0-test5/net/ipv6/udp.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv6/udp.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv6/udp.c 2003-09-27 11:38:41.996144000 +0800
+@@ -704,6 +704,7 @@
+ struct udp_opt *up = udp_sk(sk);
+
+ if (up->pending) {
++ up->len = 0;
+ up->pending = 0;
+ ip6_flush_pending_frames(sk);
+ }
+@@ -1113,7 +1114,7 @@
+
+ static int udp6_seq_show(struct seq_file *seq, void *v)
+ {
+- if (v == (void *)1)
++ if (v == SEQ_START_TOKEN)
+ seq_printf(seq,
+ " sl "
+ "local_address "
+Index: linux-2.6.0-test5/net/ipx/ipx_proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipx/ipx_proc.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipx/ipx_proc.c 2003-09-27 11:38:42.000143392 +0800
+@@ -39,7 +39,7 @@
+ loff_t l = *pos;
+
+ spin_lock_bh(&ipx_interfaces_lock);
+- return l ? ipx_get_interface_idx(--l) : (void *)1;
++ return l ? ipx_get_interface_idx(--l) : SEQ_START_TOKEN;
+ }
+
+ static void *ipx_seq_interface_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -47,7 +47,7 @@
+ struct ipx_interface *i;
+
+ ++*pos;
+- if (v == (void *)1)
++ if (v == SEQ_START_TOKEN)
+ i = ipx_interfaces_head();
+ else
+ i = ipx_interfaces_next(v);
+@@ -63,7 +63,7 @@
+ {
+ struct ipx_interface *i;
+
+- if (v == (void *)1) {
++ if (v == SEQ_START_TOKEN) {
+ seq_puts(seq, "Network Node_Address Primary Device "
+ "Frame_Type");
+ #ifdef IPX_REFCNT_DEBUG
+@@ -123,7 +123,7 @@
+ {
+ loff_t l = *pos;
+ read_lock_bh(&ipx_routes_lock);
+- return l ? ipx_get_route_idx(--l) : (void *)1;
++ return l ? ipx_get_route_idx(--l) : SEQ_START_TOKEN;
+ }
+
+ static void *ipx_seq_route_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -131,7 +131,7 @@
+ struct ipx_route *r;
+
+ ++*pos;
+- if (v == (void *)1)
++ if (v == SEQ_START_TOKEN)
+ r = ipx_routes_head();
+ else
+ r = ipx_routes_next(v);
+@@ -147,7 +147,7 @@
+ {
+ struct ipx_route *rt;
+
+- if (v == (void *)1) {
++ if (v == SEQ_START_TOKEN) {
+ seq_puts(seq, "Network Router_Net Router_Node\n");
+ goto out;
+ }
+@@ -195,7 +195,7 @@
+ loff_t l = *pos;
+
+ spin_lock_bh(&ipx_interfaces_lock);
+- return l ? ipx_get_socket_idx(--l) : (void *)1;
++ return l ? ipx_get_socket_idx(--l) : SEQ_START_TOKEN;
+ }
+
+ static void *ipx_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -205,7 +205,7 @@
+ struct ipx_opt *ipxs;
+
+ ++*pos;
+- if (v == (void *)1) {
++ if (v == SEQ_START_TOKEN) {
+ sk = NULL;
+ i = ipx_interfaces_head();
+ if (!i)
+@@ -245,7 +245,7 @@
+ struct sock *s;
+ struct ipx_opt *ipxs;
+
+- if (v == (void *)1) {
++ if (v == SEQ_START_TOKEN) {
+ #ifdef CONFIG_IPX_INTERN
+ seq_puts(seq, "Local_Address "
+ "Remote_Address Tx_Queue "
+Index: linux-2.6.0-test5/net/irda/discovery.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/irda/discovery.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/irda/discovery.c 2003-09-27 11:38:42.004142784 +0800
+@@ -32,6 +32,7 @@
+
+ #include <linux/string.h>
+ #include <linux/socket.h>
++#include <linux/seq_file.h>
+
+ #include <net/irda/irda.h>
+ #include <net/irda/irlmp.h>
+@@ -349,70 +350,131 @@
+ return 0;
+ }
+
+-/*
+- * Function proc_discovery_read (buf, start, offset, len, unused)
+- *
+- * Print discovery information in /proc file system
+- *
+- */
+-int discovery_proc_read(char *buf, char **start, off_t offset, int length,
+- int unused)
+-{
+- discovery_t *discovery;
++#ifdef CONFIG_PROC_FS
++struct discovery_iter_state {
+ unsigned long flags;
+- hashbin_t *cachelog = irlmp->cachelog;
+- int len = 0;
++};
+
+- if (!irlmp)
+- return len;
++static inline discovery_t *discovery_seq_idx(loff_t pos)
+
+- len = sprintf(buf, "IrLMP: Discovery log:\n\n");
+-
+- spin_lock_irqsave(&cachelog->hb_spinlock, flags);
++{
++ discovery_t *discovery;
+
+- discovery = (discovery_t *) hashbin_get_first(cachelog);
+- while (( discovery != NULL) && (len < length)) {
+- len += sprintf(buf+len, "nickname: %s,", discovery->data.info);
++ for (discovery = (discovery_t *) hashbin_get_first(irlmp->cachelog);
++ discovery != NULL;
++ discovery = (discovery_t *) hashbin_get_next(irlmp->cachelog)) {
++ if (pos-- == 0)
++ break;
++ }
+
+- len += sprintf(buf+len, " hint: 0x%02x%02x",
+- discovery->data.hints[0],
+- discovery->data.hints[1]);
++ return discovery;
++}
++
++static void *discovery_seq_start(struct seq_file *seq, loff_t *pos)
++{
++ struct discovery_iter_state *iter = seq->private;
++
++ spin_lock_irqsave(&irlmp->cachelog->hb_spinlock, iter->flags);
++ return *pos ? discovery_seq_idx(*pos - 1) : SEQ_START_TOKEN;
++}
++
++static void *discovery_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++{
++ ++*pos;
++ return (v == SEQ_START_TOKEN)
++ ? (void *) hashbin_get_first(irlmp->cachelog)
++ : (void *) hashbin_get_next(irlmp->cachelog);
++}
++
++static void discovery_seq_stop(struct seq_file *seq, void *v)
++{
++ struct discovery_iter_state *iter = seq->private;
++ spin_unlock_irqrestore(&irlmp->cachelog->hb_spinlock, iter->flags);
++}
++
++static int discovery_seq_show(struct seq_file *seq, void *v)
++{
++ if (v == SEQ_START_TOKEN)
++ seq_puts(seq, "IrLMP: Discovery log:\n\n");
++ else {
++ const discovery_t *discovery = v;
++
++ seq_printf(seq, "nickname: %s, hint: 0x%02x%02x",
++ discovery->data.info,
++ discovery->data.hints[0],
++ discovery->data.hints[1]);
+ #if 0
+ if ( discovery->data.hints[0] & HINT_PNP)
+- len += sprintf( buf+len, "PnP Compatible ");
++ seq_puts(seq, "PnP Compatible ");
+ if ( discovery->data.hints[0] & HINT_PDA)
+- len += sprintf( buf+len, "PDA/Palmtop ");
++ seq_puts(seq, "PDA/Palmtop ");
+ if ( discovery->data.hints[0] & HINT_COMPUTER)
+- len += sprintf( buf+len, "Computer ");
++ seq_puts(seq, "Computer ");
+ if ( discovery->data.hints[0] & HINT_PRINTER)
+- len += sprintf( buf+len, "Printer ");
++ seq_puts(seq, "Printer ");
+ if ( discovery->data.hints[0] & HINT_MODEM)
+- len += sprintf( buf+len, "Modem ");
++ seq_puts(seq, "Modem ");
+ if ( discovery->data.hints[0] & HINT_FAX)
+- len += sprintf( buf+len, "Fax ");
++ seq_puts(seq, "Fax ");
+ if ( discovery->data.hints[0] & HINT_LAN)
+- len += sprintf( buf+len, "LAN Access ");
++ seq_puts(seq, "LAN Access ");
+
+ if ( discovery->data.hints[1] & HINT_TELEPHONY)
+- len += sprintf( buf+len, "Telephony ");
++ seq_puts(seq, "Telephony ");
+ if ( discovery->data.hints[1] & HINT_FILE_SERVER)
+- len += sprintf( buf+len, "File Server ");
++ seq_puts(seq, "File Server ");
+ if ( discovery->data.hints[1] & HINT_COMM)
+- len += sprintf( buf+len, "IrCOMM ");
++ seq_puts(seq, "IrCOMM ");
+ if ( discovery->data.hints[1] & HINT_OBEX)
+- len += sprintf( buf+len, "IrOBEX ");
++ seq_puts(seq, "IrOBEX ");
+ #endif
+- len += sprintf(buf+len, ", saddr: 0x%08x",
+- discovery->data.saddr);
+-
+- len += sprintf(buf+len, ", daddr: 0x%08x\n",
++ seq_printf(seq,", saddr: 0x%08x, daddr: 0x%08x\n\n",
++ discovery->data.saddr,
+ discovery->data.daddr);
+
+- len += sprintf(buf+len, "\n");
+-
+- discovery = (discovery_t *) hashbin_get_next(cachelog);
++ seq_putc(seq, '\n');
+ }
+- spin_unlock_irqrestore(&cachelog->hb_spinlock, flags);
++ return 0;
++}
+
+- return len;
++static struct seq_operations discovery_seq_ops = {
++ .start = discovery_seq_start,
++ .next = discovery_seq_next,
++ .stop = discovery_seq_stop,
++ .show = discovery_seq_show,
++};
++
++static int discovery_seq_open(struct inode *inode, struct file *file)
++{
++ struct seq_file *seq;
++ int rc = -ENOMEM;
++ struct discovery_iter_state *s;
++
++ ASSERT(irlmp != NULL, return -EINVAL;);
++
++ s = kmalloc(sizeof(*s), GFP_KERNEL);
++ if (!s)
++ goto out;
++
++ rc = seq_open(file, &discovery_seq_ops);
++ if (rc)
++ goto out_kfree;
++
++ seq = file->private_data;
++ seq->private = s;
++ memset(s, 0, sizeof(*s));
++out:
++ return rc;
++out_kfree:
++ kfree(s);
++ goto out;
+ }
++
++struct file_operations discovery_seq_fops = {
++ .owner = THIS_MODULE,
++ .open = discovery_seq_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = seq_release_private,
++};
++#endif
+Index: linux-2.6.0-test5/net/irda/ircomm/ircomm_core.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/irda/ircomm/ircomm_core.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/irda/ircomm/ircomm_core.c 2003-09-27 11:38:42.009142024 +0800
+@@ -33,6 +33,7 @@
+ #include <linux/module.h>
+ #include <linux/sched.h>
+ #include <linux/proc_fs.h>
++#include <linux/seq_file.h>
+ #include <linux/init.h>
+
+ #include <net/irda/irda.h>
+@@ -53,9 +54,16 @@
+ struct sk_buff *skb, int clen);
+
+ #ifdef CONFIG_PROC_FS
+-static int ircomm_proc_read(char *buf, char **start, off_t offset, int len);
+-
+ extern struct proc_dir_entry *proc_irda;
++static int ircomm_seq_open(struct inode *, struct file *);
++
++static struct file_operations ircomm_proc_fops = {
++ .owner = THIS_MODULE,
++ .open = ircomm_seq_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = seq_release_private,
++};
+ #endif /* CONFIG_PROC_FS */
+
+ hashbin_t *ircomm = NULL;
+@@ -69,7 +77,11 @@
+ }
+
+ #ifdef CONFIG_PROC_FS
+- create_proc_info_entry("ircomm", 0, proc_irda, ircomm_proc_read);
++ { struct proc_dir_entry *ent;
++ ent = create_proc_entry("ircomm", 0, proc_irda);
++ if (ent)
++ ent->proc_fops = &ircomm_proc_fops;
++ }
+ #endif /* CONFIG_PROC_FS */
+
+ MESSAGE("IrCOMM protocol (Dag Brattli)\n");
+@@ -496,49 +508,98 @@
+ EXPORT_SYMBOL(ircomm_flow_request);
+
+ #ifdef CONFIG_PROC_FS
+-/*
+- * Function ircomm_proc_read (buf, start, offset, len, unused)
+- *
+- *
+- *
+- */
+-int ircomm_proc_read(char *buf, char **start, off_t offset, int len)
+-{
+- struct ircomm_cb *self;
++struct ircomm_iter_state {
+ unsigned long flags;
+-
+- len = 0;
++};
++
++static void *ircomm_seq_start(struct seq_file *seq, loff_t *pos)
++{
++ struct ircomm_iter_state *iter = seq->private;
++ struct ircomm_cb *self;
++ loff_t off = 0;
++
++ spin_lock_irqsave(&ircomm->hb_spinlock, iter->flags);
++
++ for (self = (struct ircomm_cb *) hashbin_get_first(ircomm);
++ self != NULL;
++ self = (struct ircomm_cb *) hashbin_get_next(ircomm)) {
++ if (off++ == *pos)
++ break;
++
++ }
++ return self;
++}
++
++static void *ircomm_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++{
++ ++*pos;
+
+- spin_lock_irqsave(&ircomm->hb_spinlock, flags);
++ return (void *) hashbin_get_next(ircomm);
++}
++
++static void ircomm_seq_stop(struct seq_file *seq, void *v)
++{
++ struct ircomm_iter_state *iter = seq->private;
++ spin_unlock_irqrestore(&ircomm->hb_spinlock, iter->flags);
++}
+
+- self = (struct ircomm_cb *) hashbin_get_first(ircomm);
+- while (self != NULL) {
+- ASSERT(self->magic == IRCOMM_MAGIC, break;);
+-
+- if(self->line < 0x10)
+- len += sprintf(buf+len, "ircomm%d", self->line);
+- else
+- len += sprintf(buf+len, "irlpt%d", self->line - 0x10);
+- len += sprintf(buf+len, " state: %s, ",
+- ircomm_state[ self->state]);
+- len += sprintf(buf+len,
+- "slsap_sel: %#02x, dlsap_sel: %#02x, mode:",
+- self->slsap_sel, self->dlsap_sel);
+- if(self->service_type & IRCOMM_3_WIRE_RAW)
+- len += sprintf(buf+len, " 3-wire-raw");
+- if(self->service_type & IRCOMM_3_WIRE)
+- len += sprintf(buf+len, " 3-wire");
+- if(self->service_type & IRCOMM_9_WIRE)
+- len += sprintf(buf+len, " 9-wire");
+- if(self->service_type & IRCOMM_CENTRONICS)
+- len += sprintf(buf+len, " Centronics");
+- len += sprintf(buf+len, "\n");
+-
+- self = (struct ircomm_cb *) hashbin_get_next(ircomm);
+- }
+- spin_unlock_irqrestore(&ircomm->hb_spinlock, flags);
++static int ircomm_seq_show(struct seq_file *seq, void *v)
++{
++ const struct ircomm_cb *self = v;
++
++ ASSERT(self->magic == IRCOMM_MAGIC, return -EINVAL; );
++
++ if(self->line < 0x10)
++ seq_printf(seq, "ircomm%d", self->line);
++ else
++ seq_printf(seq, "irlpt%d", self->line - 0x10);
++
++ seq_printf(seq,
++ " state: %s, slsap_sel: %#02x, dlsap_sel: %#02x, mode:",
++ ircomm_state[ self->state],
++ self->slsap_sel, self->dlsap_sel);
++
++ if(self->service_type & IRCOMM_3_WIRE_RAW)
++ seq_printf(seq, " 3-wire-raw");
++ if(self->service_type & IRCOMM_3_WIRE)
++ seq_printf(seq, " 3-wire");
++ if(self->service_type & IRCOMM_9_WIRE)
++ seq_printf(seq, " 9-wire");
++ if(self->service_type & IRCOMM_CENTRONICS)
++ seq_printf(seq, " Centronics");
++ seq_putc(seq, '\n');
++
++ return 0;
++}
++
++static struct seq_operations ircomm_seq_ops = {
++ .start = ircomm_seq_start,
++ .next = ircomm_seq_next,
++ .stop = ircomm_seq_stop,
++ .show = ircomm_seq_show,
++};
++
++static int ircomm_seq_open(struct inode *inode, struct file *file)
++{
++ struct seq_file *seq;
++ int rc = -ENOMEM;
++ struct ircomm_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
++
++ if (!s)
++ goto out;
+
+- return len;
++ rc = seq_open(file, &ircomm_seq_ops);
++ if (rc)
++ goto out_kfree;
++
++ seq = file->private_data;
++ seq->private = s;
++ memset(s, 0, sizeof(*s));
++out:
++ return rc;
++out_kfree:
++ kfree(s);
++ goto out;
+ }
+ #endif /* CONFIG_PROC_FS */
+
+Index: linux-2.6.0-test5/net/irda/iriap.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/irda/iriap.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/irda/iriap.c 2003-09-27 11:38:42.017140808 +0800
+@@ -29,6 +29,7 @@
+ #include <linux/skbuff.h>
+ #include <linux/string.h>
+ #include <linux/init.h>
++#include <linux/seq_file.h>
+
+ #include <asm/byteorder.h>
+ #include <asm/unaligned.h>
+@@ -970,35 +971,67 @@
+
+ #ifdef CONFIG_PROC_FS
+
+-static char *ias_value_types[] = {
++static const char *ias_value_types[] = {
+ "IAS_MISSING",
+ "IAS_INTEGER",
+ "IAS_OCT_SEQ",
+ "IAS_STRING"
+ };
+
+-int irias_proc_read(char *buf, char **start, off_t offset, int len)
++struct irias_iter_state {
++ unsigned long flags;
++};
++
++static inline struct ias_object *irias_seq_idx(loff_t pos)
+ {
+ struct ias_object *obj;
+- struct ias_attrib *attrib;
+- unsigned long flags;
+
+- ASSERT( irias_objects != NULL, return 0;);
++ for (obj = (struct ias_object *) hashbin_get_first(irias_objects);
++ obj; obj = (struct ias_object *) hashbin_get_next(irias_objects)) {
++ if (pos-- == 0)
++ break;
++ }
++
++ return obj;
++}
+
+- len = 0;
++static void *irias_seq_start(struct seq_file *seq, loff_t *pos)
++{
++ struct irias_iter_state *iter = seq->private;
+
+- len += sprintf(buf+len, "LM-IAS Objects:\n");
++ spin_lock_irqsave(&irias_objects->hb_spinlock, iter->flags);
+
+- spin_lock_irqsave(&irias_objects->hb_spinlock, flags);
++ return *pos ? irias_seq_idx(*pos - 1) : SEQ_START_TOKEN;
++}
++
++static void *irias_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++{
++ ++*pos;
++
++ return (v == SEQ_START_TOKEN)
++ ? (void *) hashbin_get_first(irias_objects)
++ : (void *) hashbin_get_next(irias_objects);
++}
+
+- /* List all irias_objects */
+- obj = (struct ias_object *) hashbin_get_first(irias_objects);
+- while ( obj != NULL) {
+- ASSERT(obj->magic == IAS_OBJECT_MAGIC, return 0;);
++static void irias_seq_stop(struct seq_file *seq, void *v)
++{
++ struct irias_iter_state *iter = seq->private;
+
+- len += sprintf(buf+len, "name: %s, ", obj->name);
+- len += sprintf(buf+len, "id=%d", obj->id);
+- len += sprintf(buf+len, "\n");
++ spin_unlock_irqrestore(&irias_objects->hb_spinlock, iter->flags);
++}
++
++static int irias_seq_show(struct seq_file *seq, void *v)
++{
++ if (v == SEQ_START_TOKEN)
++ seq_puts(seq, "LM-IAS Objects:\n");
++ else {
++ struct ias_object *obj = v;
++ struct ias_attrib *attrib;
++
++ ASSERT(obj->magic == IAS_OBJECT_MAGIC, return -EINVAL;);
++
++ seq_printf(seq, "name: %s, id=%d\n",
++ obj->name, obj->id);
+
+ /* Careful for priority inversions here !
+ * All other uses of attrib spinlock are independent of
+@@ -1006,48 +1039,83 @@
+ spin_lock(&obj->attribs->hb_spinlock);
+
+ /* List all attributes for this object */
+- attrib = (struct ias_attrib *)
+- hashbin_get_first(obj->attribs);
+- while (attrib != NULL) {
+- ASSERT(attrib->magic == IAS_ATTRIB_MAGIC, return 0;);
+-
+- len += sprintf(buf+len, " - Attribute name: \"%s\", ",
+- attrib->name);
+- len += sprintf(buf+len, "value[%s]: ",
+- ias_value_types[attrib->value->type]);
++ for (attrib = (struct ias_attrib *) hashbin_get_first(obj->attribs);
++ attrib != NULL;
++ attrib = (struct ias_attrib *) hashbin_get_next(obj->attribs)) {
++
++ ASSERT(attrib->magic == IAS_ATTRIB_MAGIC, break; );
++
++ seq_printf(seq, " - Attribute name: \"%s\", ",
++ attrib->name);
++ seq_printf(seq, "value[%s]: ",
++ ias_value_types[attrib->value->type]);
+
+ switch (attrib->value->type) {
+ case IAS_INTEGER:
+- len += sprintf(buf+len, "%d\n",
+- attrib->value->t.integer);
++ seq_printf(seq, "%d\n",
++ attrib->value->t.integer);
+ break;
+ case IAS_STRING:
+- len += sprintf(buf+len, "\"%s\"\n",
+- attrib->value->t.string);
++ seq_printf(seq, "\"%s\"\n",
++ attrib->value->t.string);
+ break;
+ case IAS_OCT_SEQ:
+- len += sprintf(buf+len, "octet sequence (%d bytes)\n", attrib->value->len);
++ seq_printf(seq, "octet sequence (%d bytes)\n",
++ attrib->value->len);
+ break;
+ case IAS_MISSING:
+- len += sprintf(buf+len, "missing\n");
++ seq_puts(seq, "missing\n");
+ break;
+ default:
+- IRDA_DEBUG(0, "%s(), Unknown value type!\n",
+- __FUNCTION__);
+- return -1;
++ seq_printf(seq, "type %d?\n",
++ attrib->value->type);
+ }
+- len += sprintf(buf+len, "\n");
++ seq_putc(seq, '\n');
+
+- attrib = (struct ias_attrib *)
+- hashbin_get_next(obj->attribs);
+ }
+ spin_unlock(&obj->attribs->hb_spinlock);
+-
+- obj = (struct ias_object *) hashbin_get_next(irias_objects);
+ }
+- spin_unlock_irqrestore(&irias_objects->hb_spinlock, flags);
+
+- return len;
++ return 0;
++}
++
++static struct seq_operations irias_seq_ops = {
++ .start = irias_seq_start,
++ .next = irias_seq_next,
++ .stop = irias_seq_stop,
++ .show = irias_seq_show,
++};
++
++static int irias_seq_open(struct inode *inode, struct file *file)
++{
++ struct seq_file *seq;
++ int rc = -ENOMEM;
++ struct irias_iter_state *s;
++
++ ASSERT( irias_objects != NULL, return -EINVAL;);
++ s = kmalloc(sizeof(*s), GFP_KERNEL);
++ if (!s)
++ goto out;
++
++ rc = seq_open(file, &irias_seq_ops);
++ if (rc)
++ goto out_kfree;
++ seq = file->private_data;
++ seq->private = s;
++ memset(s, 0, sizeof(*s));
++out:
++ return rc;
++out_kfree:
++ kfree(s);
++ goto out;
+ }
+
++struct file_operations irias_seq_fops = {
++ .owner = THIS_MODULE,
++ .open = irias_seq_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = seq_release_private,
++};
++
+ #endif /* PROC_FS */
+Index: linux-2.6.0-test5/net/irda/irlan/irlan_common.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/irda/irlan/irlan_common.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/irda/irlan/irlan_common.c 2003-09-27 11:38:42.025139592 +0800
+@@ -1068,7 +1068,6 @@
+ }
+
+ #ifdef CONFIG_PROC_FS
+-#define IRLAN_PROC_START_TOKEN ((void *)1)
+
+ /*
+ * Start of reading /proc entries.
+@@ -1083,7 +1082,7 @@
+
+ rcu_read_lock();
+ if (*pos == 0)
+- return IRLAN_PROC_START_TOKEN;
++ return SEQ_START_TOKEN;
+
+ list_for_each_entry(self, &irlans, dev_list) {
+ if (*pos == i)
+@@ -1099,7 +1098,7 @@
+ struct list_head *nxt;
+
+ ++*pos;
+- if (v == IRLAN_PROC_START_TOKEN)
++ if (v == SEQ_START_TOKEN)
+ nxt = irlans.next;
+ else
+ nxt = ((struct irlan_cb *)v)->dev_list.next;
+@@ -1120,7 +1119,7 @@
+ */
+ static int irlan_seq_show(struct seq_file *seq, void *v)
+ {
+- if (v == IRLAN_PROC_START_TOKEN)
++ if (v == SEQ_START_TOKEN)
+ seq_puts(seq, "IrLAN instances:\n");
+ else {
+ struct irlan_cb *self = v;
+Index: linux-2.6.0-test5/net/irda/irlap.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/irda/irlap.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/irda/irlap.c 2003-09-27 11:38:42.035138072 +0800
+@@ -37,6 +37,7 @@
+ #include <linux/proc_fs.h>
+ #include <linux/init.h>
+ #include <linux/random.h>
++#include <linux/seq_file.h>
+
+ #include <net/irda/irda.h>
+ #include <net/irda/irda_device.h>
+@@ -72,11 +73,6 @@
+ };
+ #endif /* CONFIG_IRDA_DEBUG */
+
+-#ifdef CONFIG_PROC_FS
+-int irlap_proc_read(char *, char **, off_t, int);
+-
+-#endif /* CONFIG_PROC_FS */
+-
+ int __init irlap_init(void)
+ {
+ /* Check if the compiler did its job properly.
+@@ -1096,100 +1092,163 @@
+ }
+
+ #ifdef CONFIG_PROC_FS
+-/*
+- * Function irlap_proc_read (buf, start, offset, len, unused)
+- *
+- * Give some info to the /proc file system
+- *
+- */
+-int irlap_proc_read(char *buf, char **start, off_t offset, int len)
++struct irlap_iter_state {
++ int id;
++ unsigned long flags;
++};
++
++static void *irlap_seq_start(struct seq_file *seq, loff_t *pos)
+ {
++ struct irlap_iter_state *iter = seq->private;
+ struct irlap_cb *self;
+- unsigned long flags;
+- int i = 0;
+
+- spin_lock_irqsave(&irlap->hb_spinlock, flags);
++ /* Protect our access to the tsap list */
++ spin_lock_irqsave(&irlap->hb_spinlock, iter->flags);
++ iter->id = 0;
++
++ for (self = (struct irlap_cb *) hashbin_get_first(irlap);
++ self; self = (struct irlap_cb *) hashbin_get_next(irlap)) {
++ if (iter->id == *pos)
++ break;
++ ++iter->id;
++ }
++
++ return self;
++}
++
++static void *irlap_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++{
++ struct irlap_iter_state *iter = seq->private;
++
++ ++*pos;
++ ++iter->id;
++ return (void *) hashbin_get_next(irlap);
++}
+
+- len = 0;
++static void irlap_seq_stop(struct seq_file *seq, void *v)
++{
++ struct irlap_iter_state *iter = seq->private;
++ spin_unlock_irqrestore(&irlap->hb_spinlock, iter->flags);
++}
+
+- self = (struct irlap_cb *) hashbin_get_first(irlap);
+- while (self != NULL) {
+- ASSERT(self != NULL, break;);
+- ASSERT(self->magic == LAP_MAGIC, break;);
++static int irlap_seq_show(struct seq_file *seq, void *v)
++{
++ const struct irlap_iter_state *iter = seq->private;
++ const struct irlap_cb *self = v;
++
++ ASSERT(self->magic == LAP_MAGIC, return -EINVAL;);
+
+- len += sprintf(buf+len, "irlap%d ", i++);
+- len += sprintf(buf+len, "state: %s\n",
+- irlap_state[self->state]);
++ seq_printf(seq, "irlap%d ", iter->id);
++ seq_printf(seq, "state: %s\n",
++ irlap_state[self->state]);
+
+- len += sprintf(buf+len, " device name: %s, ",
+- (self->netdev) ? self->netdev->name : "bug");
+- len += sprintf(buf+len, "hardware name: %s\n", self->hw_name);
++ seq_printf(seq, " device name: %s, ",
++ (self->netdev) ? self->netdev->name : "bug");
++ seq_printf(seq, "hardware name: %s\n", self->hw_name);
+
+- len += sprintf(buf+len, " caddr: %#02x, ", self->caddr);
+- len += sprintf(buf+len, "saddr: %#08x, ", self->saddr);
+- len += sprintf(buf+len, "daddr: %#08x\n", self->daddr);
++ seq_printf(seq, " caddr: %#02x, ", self->caddr);
++ seq_printf(seq, "saddr: %#08x, ", self->saddr);
++ seq_printf(seq, "daddr: %#08x\n", self->daddr);
+
+- len += sprintf(buf+len, " win size: %d, ",
+- self->window_size);
+- len += sprintf(buf+len, "win: %d, ", self->window);
++ seq_printf(seq, " win size: %d, ",
++ self->window_size);
++ seq_printf(seq, "win: %d, ", self->window);
+ #ifdef CONFIG_IRDA_DYNAMIC_WINDOW
+- len += sprintf(buf+len, "line capacity: %d, ",
+- self->line_capacity);
+- len += sprintf(buf+len, "bytes left: %d\n", self->bytes_left);
++ seq_printf(seq, "line capacity: %d, ",
++ self->line_capacity);
++ seq_printf(seq, "bytes left: %d\n", self->bytes_left);
+ #endif /* CONFIG_IRDA_DYNAMIC_WINDOW */
+- len += sprintf(buf+len, " tx queue len: %d ",
+- skb_queue_len(&self->txq));
+- len += sprintf(buf+len, "win queue len: %d ",
+- skb_queue_len(&self->wx_list));
+- len += sprintf(buf+len, "rbusy: %s", self->remote_busy ?
+- "TRUE" : "FALSE");
+- len += sprintf(buf+len, " mbusy: %s\n", self->media_busy ?
+- "TRUE" : "FALSE");
+-
+- len += sprintf(buf+len, " retrans: %d ", self->retry_count);
+- len += sprintf(buf+len, "vs: %d ", self->vs);
+- len += sprintf(buf+len, "vr: %d ", self->vr);
+- len += sprintf(buf+len, "va: %d\n", self->va);
+-
+- len += sprintf(buf+len, " qos\tbps\tmaxtt\tdsize\twinsize\taddbofs\tmintt\tldisc\tcomp\n");
+-
+- len += sprintf(buf+len, " tx\t%d\t",
+- self->qos_tx.baud_rate.value);
+- len += sprintf(buf+len, "%d\t",
+- self->qos_tx.max_turn_time.value);
+- len += sprintf(buf+len, "%d\t",
+- self->qos_tx.data_size.value);
+- len += sprintf(buf+len, "%d\t",
+- self->qos_tx.window_size.value);
+- len += sprintf(buf+len, "%d\t",
+- self->qos_tx.additional_bofs.value);
+- len += sprintf(buf+len, "%d\t",
+- self->qos_tx.min_turn_time.value);
+- len += sprintf(buf+len, "%d\t",
+- self->qos_tx.link_disc_time.value);
+- len += sprintf(buf+len, "\n");
+-
+- len += sprintf(buf+len, " rx\t%d\t",
+- self->qos_rx.baud_rate.value);
+- len += sprintf(buf+len, "%d\t",
+- self->qos_rx.max_turn_time.value);
+- len += sprintf(buf+len, "%d\t",
+- self->qos_rx.data_size.value);
+- len += sprintf(buf+len, "%d\t",
+- self->qos_rx.window_size.value);
+- len += sprintf(buf+len, "%d\t",
+- self->qos_rx.additional_bofs.value);
+- len += sprintf(buf+len, "%d\t",
+- self->qos_rx.min_turn_time.value);
+- len += sprintf(buf+len, "%d\t",
+- self->qos_rx.link_disc_time.value);
+- len += sprintf(buf+len, "\n");
++ seq_printf(seq, " tx queue len: %d ",
++ skb_queue_len(&self->txq));
++ seq_printf(seq, "win queue len: %d ",
++ skb_queue_len(&self->wx_list));
++ seq_printf(seq, "rbusy: %s", self->remote_busy ?
++ "TRUE" : "FALSE");
++ seq_printf(seq, " mbusy: %s\n", self->media_busy ?
++ "TRUE" : "FALSE");
++
++ seq_printf(seq, " retrans: %d ", self->retry_count);
++ seq_printf(seq, "vs: %d ", self->vs);
++ seq_printf(seq, "vr: %d ", self->vr);
++ seq_printf(seq, "va: %d\n", self->va);
++
++ seq_printf(seq, " qos\tbps\tmaxtt\tdsize\twinsize\taddbofs\tmintt\tldisc\tcomp\n");
++
++ seq_printf(seq, " tx\t%d\t",
++ self->qos_tx.baud_rate.value);
++ seq_printf(seq, "%d\t",
++ self->qos_tx.max_turn_time.value);
++ seq_printf(seq, "%d\t",
++ self->qos_tx.data_size.value);
++ seq_printf(seq, "%d\t",
++ self->qos_tx.window_size.value);
++ seq_printf(seq, "%d\t",
++ self->qos_tx.additional_bofs.value);
++ seq_printf(seq, "%d\t",
++ self->qos_tx.min_turn_time.value);
++ seq_printf(seq, "%d\t",
++ self->qos_tx.link_disc_time.value);
++ seq_printf(seq, "\n");
++
++ seq_printf(seq, " rx\t%d\t",
++ self->qos_rx.baud_rate.value);
++ seq_printf(seq, "%d\t",
++ self->qos_rx.max_turn_time.value);
++ seq_printf(seq, "%d\t",
++ self->qos_rx.data_size.value);
++ seq_printf(seq, "%d\t",
++ self->qos_rx.window_size.value);
++ seq_printf(seq, "%d\t",
++ self->qos_rx.additional_bofs.value);
++ seq_printf(seq, "%d\t",
++ self->qos_rx.min_turn_time.value);
++ seq_printf(seq, "%d\n",
++ self->qos_rx.link_disc_time.value);
++
++ return 0;
++}
++
++static struct seq_operations irlap_seq_ops = {
++ .start = irlap_seq_start,
++ .next = irlap_seq_next,
++ .stop = irlap_seq_stop,
++ .show = irlap_seq_show,
++};
++
++static int irlap_seq_open(struct inode *inode, struct file *file)
++{
++ struct seq_file *seq;
++ int rc = -ENOMEM;
++ struct irlap_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
++
++ if (!s)
++ goto out;
+
+- self = (struct irlap_cb *) hashbin_get_next(irlap);
++ if (irlap == NULL) {
++ rc = -EINVAL;
++ goto out_kfree;
+ }
+- spin_unlock_irqrestore(&irlap->hb_spinlock, flags);
+
+- return len;
+-}
++ rc = seq_open(file, &irlap_seq_ops);
++ if (rc)
++ goto out_kfree;
++
++ seq = file->private_data;
++ seq->private = s;
++ memset(s, 0, sizeof(*s));
++out:
++ return rc;
++out_kfree:
++ kfree(s);
++ goto out;
++}
++
++struct file_operations irlap_seq_fops = {
++ .owner = THIS_MODULE,
++ .open = irlap_seq_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = seq_release_private,
++};
+
+ #endif /* CONFIG_PROC_FS */
+Index: linux-2.6.0-test5/net/irda/irlap_frame.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/irda/irlap_frame.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/irda/irlap_frame.c 2003-09-27 11:38:42.044136704 +0800
+@@ -159,9 +159,9 @@
+ {
+ struct snrm_frame *frame;
+
+- frame = (struct snrm_frame *) skb->data;
++ if (pskb_may_pull(skb,sizeof(struct snrm_frame))) {
++ frame = (struct snrm_frame *) skb->data;
+
+- if (skb->len >= sizeof(struct snrm_frame)) {
+ /* Copy the new connection address ignoring the C/R bit */
+ info->caddr = frame->ncaddr & 0xFE;
+
+@@ -402,6 +402,11 @@
+ ASSERT(self != NULL, return;);
+ ASSERT(self->magic == LAP_MAGIC, return;);
+
++ if (!pskb_may_pull(skb, sizeof(struct xid_frame))) {
++ ERROR("%s: frame to short!\n", __FUNCTION__);
++ return;
++ }
++
+ xid = (struct xid_frame *) skb->data;
+
+ info->daddr = le32_to_cpu(xid->saddr);
+@@ -469,6 +474,11 @@
+ __u8 *discovery_info;
+ char *text;
+
++ if (!pskb_may_pull(skb, sizeof(struct xid_frame))) {
++ ERROR("%s: frame to short!\n", __FUNCTION__);
++ return;
++ }
++
+ xid = (struct xid_frame *) skb->data;
+
+ info->daddr = le32_to_cpu(xid->saddr);
+@@ -507,7 +517,8 @@
+ */
+ if (info->s == 0xff) {
+ /* Check if things are sane at this point... */
+- if((discovery_info == NULL) || (skb->len < 3)) {
++ if((discovery_info == NULL) ||
++ !pskb_may_pull(skb, 3)) {
+ ERROR("%s: discovery frame to short!\n", __FUNCTION__);
+ return;
+ }
+@@ -1150,6 +1161,11 @@
+ ASSERT(skb != NULL, return;);
+ ASSERT(info != NULL, return;);
+
++ if (!pskb_may_pull(skb, 4)) {
++ ERROR("%s: frame to short!\n", __FUNCTION__);
++ return;
++ }
++
+ frame = skb->data;
+
+ info->nr = frame[2] >> 5; /* Next to receive */
+@@ -1234,6 +1250,10 @@
+
+ IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
+
++ if (!pskb_may_pull(skb, sizeof(*frame))) {
++ ERROR("%s: frame to short!\n", __FUNCTION__);
++ return;
++ }
+ frame = (struct test_frame *) skb->data;
+
+ /* Broadcast frames must carry saddr and daddr fields */
+@@ -1302,15 +1322,9 @@
+ dev_kfree_skb(skb);
+ return -1;
+ }
+- if (skb_is_nonlinear(skb))
+- if (skb_linearize(skb, GFP_ATOMIC) != 0) {
+- ERROR("%s: can't linearize skb!\n", __FUNCTION__);
+- dev_kfree_skb(skb);
+- return -1;
+- }
+
+ /* Check if frame is large enough for parsing */
+- if (skb->len < 2) {
++ if (!pskb_may_pull(skb, 2)) {
+ ERROR("%s: frame to short!\n", __FUNCTION__);
+ dev_kfree_skb(skb);
+ return -1;
+Index: linux-2.6.0-test5/net/irda/irlmp.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/irda/irlmp.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/irda/irlmp.c 2003-09-27 11:38:42.058134576 +0800
+@@ -33,6 +33,7 @@
+ #include <linux/init.h>
+ #include <linux/kmod.h>
+ #include <linux/random.h>
++#include <linux/seq_file.h>
+
+ #include <net/irda/irda.h>
+ #include <net/irda/timer.h>
+@@ -63,9 +64,6 @@
+ };
+
+ __u8 *irlmp_hint_to_service(__u8 *hint);
+-#ifdef CONFIG_PROC_FS
+-int irlmp_proc_read(char *buf, char **start, off_t offst, int len);
+-#endif
+
+ /*
+ * Function irlmp_init (void)
+@@ -1780,81 +1778,190 @@
+ }
+
+ #ifdef CONFIG_PROC_FS
+-/*
+- * Function irlmp_proc_read (buf, start, offset, len, unused)
+- *
+- * Give some info to the /proc file system
+- *
+- */
+-int irlmp_proc_read(char *buf, char **start, off_t offset, int len)
+-{
+- struct lsap_cb *self;
+- struct lap_cb *lap;
++
++struct irlmp_iter_state {
+ unsigned long flags;
++ hashbin_t *hashbin;
++};
+
+- ASSERT(irlmp != NULL, return 0;);
++#define LSAP_START_TOKEN ((void *)1)
++#define LINK_START_TOKEN ((void *)2)
+
+- len = 0;
++static void *irlmp_seq_hb_idx(struct irlmp_iter_state *iter,
++ hashbin_t *bin, loff_t *off)
++{
++ void *element;
+
+- len += sprintf( buf+len, "Unconnected LSAPs:\n");
+- spin_lock_irqsave(&irlmp->unconnected_lsaps->hb_spinlock, flags);
+- self = (struct lsap_cb *) hashbin_get_first( irlmp->unconnected_lsaps);
+- while (self != NULL) {
+- ASSERT(self->magic == LMP_LSAP_MAGIC, break;);
+- len += sprintf(buf+len, "lsap state: %s, ",
+- irlsap_state[ self->lsap_state]);
+- len += sprintf(buf+len,
+- "slsap_sel: %#02x, dlsap_sel: %#02x, ",
+- self->slsap_sel, self->dlsap_sel);
+- len += sprintf(buf+len, "(%s)", self->notify.name);
+- len += sprintf(buf+len, "\n");
++ spin_lock_irqsave(&bin->hb_spinlock, iter->flags);
++ for (element = hashbin_get_first(bin);
++ element != NULL;
++ element = hashbin_get_next(bin)) {
++ if (!off || *off-- == 0) {
++ /* NB: hashbin left locked */
++ iter->hashbin = bin;
++ return element;
++ }
++ }
++ spin_unlock_irqrestore(&bin->hb_spinlock, iter->flags);
++ return NULL;
++}
++
++
++static void *irlmp_seq_start(struct seq_file *seq, loff_t *pos)
++{
++ struct irlmp_iter_state *iter = seq->private;
++ void *v;
++ loff_t off = *pos;
++
++ iter->hashbin = NULL;
++ if (off-- == 0)
++ return LSAP_START_TOKEN;
++
++ v = irlmp_seq_hb_idx(iter, irlmp->unconnected_lsaps, &off);
++ if (v)
++ return v;
+
+- self = (struct lsap_cb *) hashbin_get_next(
+- irlmp->unconnected_lsaps);
++ if (off-- == 0)
++ return LINK_START_TOKEN;
++
++ return irlmp_seq_hb_idx(iter, irlmp->links, &off);
++}
++
++static void *irlmp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++{
++ struct irlmp_iter_state *iter = seq->private;
++
++ ++*pos;
++
++ if (v == LSAP_START_TOKEN) {
++ v = irlmp_seq_hb_idx(iter, irlmp->unconnected_lsaps, NULL);
++ return v ? v : LINK_START_TOKEN;
+ }
+- spin_unlock_irqrestore(&irlmp->unconnected_lsaps->hb_spinlock, flags);
+
+- len += sprintf(buf+len, "\nRegistred Link Layers:\n");
+- spin_lock_irqsave(&irlmp->links->hb_spinlock, flags);
+- lap = (struct lap_cb *) hashbin_get_first(irlmp->links);
+- while (lap != NULL) {
+- len += sprintf(buf+len, "lap state: %s, ",
+- irlmp_state[lap->lap_state]);
++ if (v == LINK_START_TOKEN)
++ return irlmp_seq_hb_idx(iter, irlmp->links, NULL);
++
++ ASSERT( iter->hashbin != NULL, return NULL; );
++
++ v = hashbin_get_next(iter->hashbin);
++ if (v)
++ return v;
++
++ spin_unlock_irqrestore(&iter->hashbin->hb_spinlock, iter->flags);
++
++ if (iter->hashbin == irlmp->unconnected_lsaps) {
++ iter->hashbin = NULL;
++ return LINK_START_TOKEN;
++ }
++ return NULL;
++}
++
++static void irlmp_seq_stop(struct seq_file *seq, void *v)
++{
++ struct irlmp_iter_state *iter = seq->private;
++
++ if (iter->hashbin)
++ spin_unlock_irqrestore(&iter->hashbin->hb_spinlock, iter->flags);
++
++}
++
++static int irlmp_seq_show(struct seq_file *seq, void *v)
++{
++ const struct irlmp_iter_state *iter = seq->private;
++ struct lsap_cb *self = v;
++
++ if (v == LSAP_START_TOKEN)
++ seq_puts(seq, "Unconnected LSAPs:\n");
++ else if (v == LINK_START_TOKEN)
++ seq_puts(seq, "\nRegistered Link Layers:\n");
++ else if (iter->hashbin == irlmp->unconnected_lsaps) {
++ self = v;
++ ASSERT(self->magic == LMP_LSAP_MAGIC, return -EINVAL; );
++ seq_printf(seq, "lsap state: %s, ",
++ irlsap_state[ self->lsap_state]);
++ seq_printf(seq,
++ "slsap_sel: %#02x, dlsap_sel: %#02x, ",
++ self->slsap_sel, self->dlsap_sel);
++ seq_printf(seq, "(%s)", self->notify.name);
++ seq_printf(seq, "\n");
++ } else if (iter->hashbin == irlmp->links) {
++ struct lap_cb *lap = v;
+
+- len += sprintf(buf+len, "saddr: %#08x, daddr: %#08x, ",
+- lap->saddr, lap->daddr);
+- len += sprintf(buf+len, "num lsaps: %d",
+- HASHBIN_GET_SIZE(lap->lsaps));
+- len += sprintf(buf+len, "\n");
++ seq_printf(seq, "lap state: %s, ",
++ irlmp_state[lap->lap_state]);
++
++ seq_printf(seq, "saddr: %#08x, daddr: %#08x, ",
++ lap->saddr, lap->daddr);
++ seq_printf(seq, "num lsaps: %d",
++ HASHBIN_GET_SIZE(lap->lsaps));
++ seq_printf(seq, "\n");
+
+ /* Careful for priority inversions here !
+ * All other uses of attrib spinlock are independent of
+ * the object spinlock, so we are safe. Jean II */
+ spin_lock(&lap->lsaps->hb_spinlock);
+
+- len += sprintf(buf+len, "\n Connected LSAPs:\n");
+- self = (struct lsap_cb *) hashbin_get_first(lap->lsaps);
+- while (self != NULL) {
++ seq_printf(seq, "\n Connected LSAPs:\n");
++ for (self = (struct lsap_cb *) hashbin_get_first(lap->lsaps);
++ self != NULL;
++ self = (struct lsap_cb *)hashbin_get_next(lap->lsaps)) {
+ ASSERT(self->magic == LMP_LSAP_MAGIC, break;);
+- len += sprintf(buf+len, " lsap state: %s, ",
+- irlsap_state[ self->lsap_state]);
+- len += sprintf(buf+len,
+- "slsap_sel: %#02x, dlsap_sel: %#02x, ",
+- self->slsap_sel, self->dlsap_sel);
+- len += sprintf(buf+len, "(%s)", self->notify.name);
+- len += sprintf(buf+len, "\n");
++ seq_printf(seq, " lsap state: %s, ",
++ irlsap_state[ self->lsap_state]);
++ seq_printf(seq,
++ "slsap_sel: %#02x, dlsap_sel: %#02x, ",
++ self->slsap_sel, self->dlsap_sel);
++ seq_printf(seq, "(%s)", self->notify.name);
++ seq_putc(seq, '\n');
+
+- self = (struct lsap_cb *) hashbin_get_next(
+- lap->lsaps);
+ }
+ spin_unlock(&lap->lsaps->hb_spinlock);
+- len += sprintf(buf+len, "\n");
+-
+- lap = (struct lap_cb *) hashbin_get_next(irlmp->links);
+- }
+- spin_unlock_irqrestore(&irlmp->links->hb_spinlock, flags);
++ seq_putc(seq, '\n');
++ } else
++ return -EINVAL;
+
+- return len;
++ return 0;
+ }
+
++static struct seq_operations irlmp_seq_ops = {
++ .start = irlmp_seq_start,
++ .next = irlmp_seq_next,
++ .stop = irlmp_seq_stop,
++ .show = irlmp_seq_show,
++};
++
++static int irlmp_seq_open(struct inode *inode, struct file *file)
++{
++ struct seq_file *seq;
++ int rc = -ENOMEM;
++ struct irlmp_iter_state *s;
++
++ ASSERT(irlmp != NULL, return -EINVAL;);
++
++ s = kmalloc(sizeof(*s), GFP_KERNEL);
++ if (!s)
++ goto out;
++
++ rc = seq_open(file, &irlmp_seq_ops);
++ if (rc)
++ goto out_kfree;
++
++ seq = file->private_data;
++ seq->private = s;
++ memset(s, 0, sizeof(*s));
++out:
++ return rc;
++out_kfree:
++ kfree(s);
++ goto out;
++}
++
++struct file_operations irlmp_seq_fops = {
++ .owner = THIS_MODULE,
++ .open = irlmp_seq_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = seq_release_private,
++};
++
+ #endif /* PROC_FS */
+Index: linux-2.6.0-test5/net/irda/irproc.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/irda/irproc.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/irda/irproc.c 2003-09-27 11:38:42.060134272 +0800
+@@ -25,6 +25,7 @@
+
+ #include <linux/miscdevice.h>
+ #include <linux/proc_fs.h>
++#include <linux/seq_file.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+
+@@ -32,25 +33,25 @@
+ #include <net/irda/irlap.h>
+ #include <net/irda/irlmp.h>
+
+-extern int irlap_proc_read(char *buf, char **start, off_t offset, int len);
+-extern int irlmp_proc_read(char *buf, char **start, off_t offset, int len);
+-extern int irttp_proc_read(char *buf, char **start, off_t offset, int len);
+-extern int irias_proc_read(char *buf, char **start, off_t offset, int len);
+-extern int discovery_proc_read(char *buf, char **start, off_t offset, int len);
++extern struct file_operations discovery_seq_fops;
++extern struct file_operations irlap_seq_fops;
++extern struct file_operations irlmp_seq_fops;
++extern struct file_operations irttp_seq_fops;
++extern struct file_operations irias_seq_fops;
+
+ struct irda_entry {
+- char *name;
+- int (*fn)(char*, char**, off_t, int);
++ const char *name;
++ struct file_operations *fops;
+ };
+
+ struct proc_dir_entry *proc_irda;
+
+-static struct irda_entry dir[] = {
+- {"discovery", discovery_proc_read},
+- {"irttp", irttp_proc_read},
+- {"irlmp", irlmp_proc_read},
+- {"irlap", irlap_proc_read},
+- {"irias", irias_proc_read},
++static struct irda_entry irda_dirs[] = {
++ {"discovery", &discovery_seq_fops},
++ {"irttp", &irttp_seq_fops},
++ {"irlmp", &irlmp_seq_fops},
++ {"irlap", &irlap_seq_fops},
++ {"irias", &irias_seq_fops},
+ };
+
+ /*
+@@ -64,15 +65,15 @@
+ int i;
+ struct proc_dir_entry *d;
+
+- proc_irda = proc_mkdir("net/irda", NULL);
++ proc_irda = proc_mkdir("irda", proc_net);
+ if (proc_irda == NULL)
+ return;
+ proc_irda->owner = THIS_MODULE;
+
+- for (i=0; i<ARRAY_SIZE(dir); i++) {
+- d = create_proc_info_entry(dir[i].name,0,proc_irda,dir[i].fn);
+- if (d)
+- d->owner = THIS_MODULE;
++ for (i=0; i<ARRAY_SIZE(irda_dirs); i++) {
++ d = create_proc_entry(irda_dirs[i].name, 0, proc_irda);
++ if (d)
++ d->proc_fops = irda_dirs[i].fops;
+ }
+ }
+
+@@ -87,10 +88,10 @@
+ int i;
+
+ if (proc_irda) {
+- for (i=0; i<ARRAY_SIZE(dir); i++)
+- remove_proc_entry(dir[i].name, proc_irda);
++ for (i=0; i<ARRAY_SIZE(irda_dirs); i++)
++ remove_proc_entry(irda_dirs[i].name, proc_irda);
+
+- remove_proc_entry("net/irda", NULL);
++ remove_proc_entry("irda", proc_net);
+ proc_irda = NULL;
+ }
+ }
+Index: linux-2.6.0-test5/net/irda/irttp.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/irda/irttp.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/irda/irttp.c 2003-09-27 11:38:42.074132144 +0800
+@@ -27,6 +27,7 @@
+ #include <linux/config.h>
+ #include <linux/skbuff.h>
+ #include <linux/init.h>
++#include <linux/seq_file.h>
+
+ #include <asm/byteorder.h>
+ #include <asm/unaligned.h>
+@@ -1767,71 +1768,127 @@
+ }
+
+ #ifdef CONFIG_PROC_FS
+-/*
+- * Function irttp_proc_read (buf, start, offset, len, unused)
+- *
+- * Give some info to the /proc file system
+- */
+-int irttp_proc_read(char *buf, char **start, off_t offset, int len)
+-{
+- struct tsap_cb *self;
++struct irttp_iter_state {
++ int id;
+ unsigned long flags;
+- int i = 0;
+-
+- ASSERT(irttp != NULL, return 0;);
++};
+
+- len = 0;
++static void *irttp_seq_start(struct seq_file *seq, loff_t *pos)
++{
++ struct irttp_iter_state *iter = seq->private;
++ struct tsap_cb *self;
+
+ /* Protect our access to the tsap list */
+- spin_lock_irqsave(&irttp->tsaps->hb_spinlock, flags);
++ spin_lock_irqsave(&irttp->tsaps->hb_spinlock, iter->flags);
++ iter->id = 0;
+
+- self = (struct tsap_cb *) hashbin_get_first(irttp->tsaps);
+- while (self != NULL) {
+- if (!self || self->magic != TTP_TSAP_MAGIC)
++ for (self = (struct tsap_cb *) hashbin_get_first(irttp->tsaps);
++ self != NULL;
++ self = (struct tsap_cb *) hashbin_get_next(irttp->tsaps)) {
++ if (iter->id == *pos)
+ break;
++ ++iter->id;
++ }
++
++ return self;
++}
++
++static void *irttp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++{
++ struct irttp_iter_state *iter = seq->private;
+
+- len += sprintf(buf+len, "TSAP %d, ", i++);
+- len += sprintf(buf+len, "stsap_sel: %02x, ",
+- self->stsap_sel);
+- len += sprintf(buf+len, "dtsap_sel: %02x\n",
+- self->dtsap_sel);
+- len += sprintf(buf+len, " connected: %s, ",
+- self->connected? "TRUE":"FALSE");
+- len += sprintf(buf+len, "avail credit: %d, ",
+- self->avail_credit);
+- len += sprintf(buf+len, "remote credit: %d, ",
+- self->remote_credit);
+- len += sprintf(buf+len, "send credit: %d\n",
+- self->send_credit);
+- len += sprintf(buf+len, " tx packets: %ld, ",
+- self->stats.tx_packets);
+- len += sprintf(buf+len, "rx packets: %ld, ",
+- self->stats.rx_packets);
+- len += sprintf(buf+len, "tx_queue len: %d ",
+- skb_queue_len(&self->tx_queue));
+- len += sprintf(buf+len, "rx_queue len: %d\n",
+- skb_queue_len(&self->rx_queue));
+- len += sprintf(buf+len, " tx_sdu_busy: %s, ",
+- self->tx_sdu_busy? "TRUE":"FALSE");
+- len += sprintf(buf+len, "rx_sdu_busy: %s\n",
+- self->rx_sdu_busy? "TRUE":"FALSE");
+- len += sprintf(buf+len, " max_seg_size: %d, ",
+- self->max_seg_size);
+- len += sprintf(buf+len, "tx_max_sdu_size: %d, ",
+- self->tx_max_sdu_size);
+- len += sprintf(buf+len, "rx_max_sdu_size: %d\n",
+- self->rx_max_sdu_size);
++ ++*pos;
++ ++iter->id;
++ return (void *) hashbin_get_next(irttp->tsaps);
++}
+
+- len += sprintf(buf+len, " Used by (%s)\n",
+- self->notify.name);
++static void irttp_seq_stop(struct seq_file *seq, void *v)
++{
++ struct irttp_iter_state *iter = seq->private;
++ spin_unlock_irqrestore(&irttp->tsaps->hb_spinlock, iter->flags);
++}
+
+- len += sprintf(buf+len, "\n");
++static int irttp_seq_show(struct seq_file *seq, void *v)
++{
++ const struct irttp_iter_state *iter = seq->private;
++ const struct tsap_cb *self = v;
+
+- self = (struct tsap_cb *) hashbin_get_next(irttp->tsaps);
+- }
+- spin_unlock_irqrestore(&irttp->tsaps->hb_spinlock, flags);
++ seq_printf(seq, "TSAP %d, ", iter->id);
++ seq_printf(seq, "stsap_sel: %02x, ",
++ self->stsap_sel);
++ seq_printf(seq, "dtsap_sel: %02x\n",
++ self->dtsap_sel);
++ seq_printf(seq, " connected: %s, ",
++ self->connected? "TRUE":"FALSE");
++ seq_printf(seq, "avail credit: %d, ",
++ self->avail_credit);
++ seq_printf(seq, "remote credit: %d, ",
++ self->remote_credit);
++ seq_printf(seq, "send credit: %d\n",
++ self->send_credit);
++ seq_printf(seq, " tx packets: %ld, ",
++ self->stats.tx_packets);
++ seq_printf(seq, "rx packets: %ld, ",
++ self->stats.rx_packets);
++ seq_printf(seq, "tx_queue len: %d ",
++ skb_queue_len(&self->tx_queue));
++ seq_printf(seq, "rx_queue len: %d\n",
++ skb_queue_len(&self->rx_queue));
++ seq_printf(seq, " tx_sdu_busy: %s, ",
++ self->tx_sdu_busy? "TRUE":"FALSE");
++ seq_printf(seq, "rx_sdu_busy: %s\n",
++ self->rx_sdu_busy? "TRUE":"FALSE");
++ seq_printf(seq, " max_seg_size: %d, ",
++ self->max_seg_size);
++ seq_printf(seq, "tx_max_sdu_size: %d, ",
++ self->tx_max_sdu_size);
++ seq_printf(seq, "rx_max_sdu_size: %d\n",
++ self->rx_max_sdu_size);
+
+- return len;
++ seq_printf(seq, " Used by (%s)\n\n",
++ self->notify.name);
++ return 0;
+ }
+
++static struct seq_operations irttp_seq_ops = {
++ .start = irttp_seq_start,
++ .next = irttp_seq_next,
++ .stop = irttp_seq_stop,
++ .show = irttp_seq_show,
++};
++
++static int irttp_seq_open(struct inode *inode, struct file *file)
++{
++ struct seq_file *seq;
++ int rc = -ENOMEM;
++ struct irttp_iter_state *s;
++
++ ASSERT(irttp != NULL, return -EINVAL;);
++
++ s = kmalloc(sizeof(*s), GFP_KERNEL);
++ if (!s)
++ goto out;
++
++ rc = seq_open(file, &irttp_seq_ops);
++ if (rc)
++ goto out_kfree;
++
++ seq = file->private_data;
++ seq->private = s;
++ memset(s, 0, sizeof(*s));
++out:
++ return rc;
++out_kfree:
++ kfree(s);
++ goto out;
++}
++
++struct file_operations irttp_seq_fops = {
++ .owner = THIS_MODULE,
++ .open = irttp_seq_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = seq_release_private,
++};
++
+ #endif /* PROC_FS */
+Index: linux-2.6.0-test5/net/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/net/Kconfig 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/Kconfig 2003-09-27 11:38:42.083130776 +0800
+@@ -370,24 +370,11 @@
+ config VLAN_8021Q
+ tristate "802.1Q VLAN Support"
+
+-config LLC
+- tristate "ANSI/IEEE 802.2 - aka LLC (IPX, Appletalk, Token Ring)"
+- help
+- This is a Logical Link Layer protocol used for Appletalk, IPX,
+- Token Ring devices, the linux-sna.org project and in the future by
+- NetBEUI. It originally came from Procom Inc. that released the code
+- for 2.0.36 and was heavily modified to work with 2.{4,5}.
+- Select this if you want to have support for those protocols or if
+- you want to have the sockets interface for LLC.
+-
+-
+-config LLC_UI
+- bool "LLC sockets interface"
+- depends on LLC
++source "net/llc/Kconfig"
+
+ config IPX
+ tristate "The IPX protocol"
+- depends on LLC
++ select LLC
+ ---help---
+ This is support for the Novell networking protocol, IPX, commonly
+ used for local networks of Windows machines. You need it if you
+@@ -424,7 +411,7 @@
+
+ config ATALK
+ tristate "Appletalk protocol support"
+- depends on LLC
++ select LLC
+ ---help---
+ AppleTalk is the protocol that Apple computers can use to communicate
+ on a network. If your Linux box is connected to such a network and you
+@@ -479,9 +466,8 @@
+ using the X.21 protocol (not yet supported by Linux) or one can do
+ X.25 over a standard telephone line using an ordinary modem (say Y
+ to "X.25 async driver" below) or over Ethernet using an ordinary
+- Ethernet card and either the 802.2 LLC protocol (say Y to "802.2
+- LLC" below) or LAPB over Ethernet (say Y to "LAPB Data Link Driver"
+- and "LAPB over Ethernet driver" below).
++ Ethernet card and the LAPB over Ethernet (say Y to "LAPB Data Link
++ Driver" and "LAPB over Ethernet driver" below).
+
+ If you want to compile this driver as a module ( = code which can be
+ inserted in and removed from the running kernel whenever you want),
+Index: linux-2.6.0-test5/net/llc/af_llc.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/llc/af_llc.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/llc/af_llc.c 2003-09-27 11:38:42.090129712 +0800
+@@ -24,13 +24,13 @@
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/tcp.h>
++#include <linux/rtnetlink.h>
++#include <linux/init.h>
++#include <net/llc.h>
+ #include <net/llc_sap.h>
+ #include <net/llc_pdu.h>
+ #include <net/llc_conn.h>
+-#include <net/llc_mac.h>
+-#include <net/llc_main.h>
+-#include <linux/rtnetlink.h>
+-#include <linux/init.h>
++#include <net/llc_proc.h>
+
+ /* remember: uninitialized global data is zeroed because its in .bss */
+ static u16 llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
+@@ -182,10 +182,12 @@
+ if (!llc_send_disc(sk))
+ llc_ui_wait_for_disc(sk, sk->sk_rcvtimeo);
+ if (!sk->sk_zapped)
+- llc_sap_unassign_sock(llc->sap, sk);
++ llc_sap_remove_socket(llc->sap, sk);
+ release_sock(sk);
+- if (llc->sap && hlist_empty(&llc->sap->sk_list.list))
++ if (llc->sap && hlist_empty(&llc->sap->sk_list.list)) {
++ llc_release_sockets(llc->sap);
+ llc_sap_close(llc->sap);
++ }
+ sock_put(sk);
+ llc_sk_free(sk);
+ out:
+@@ -303,7 +305,7 @@
+ memcpy(llc->daddr.mac, addr->sllc_dmac, IFHWADDRLEN);
+ memcpy(&llc->addr, addr, sizeof(llc->addr));
+ /* assign new connection to its SAP */
+- llc_sap_assign_sock(sap, sk);
++ llc_sap_add_socket(sap, sk);
+ rc = sk->sk_zapped = 0;
+ out:
+ return rc;
+@@ -1042,14 +1044,38 @@
+ .sendpage = sock_no_sendpage,
+ };
+
+-int __init llc_ui_init(void)
++extern void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb);
++extern void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb);
++
++static int __init llc2_init(void)
+ {
++ int rc;
++
++ llc_build_offset_table();
++ llc_station_init();
+ llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
+- sock_register(&llc_ui_family_ops);
+- return 0;
++ rc = llc_proc_init();
++ if (!rc) {
++ sock_register(&llc_ui_family_ops);
++ llc_add_pack(LLC_DEST_SAP, llc_sap_handler);
++ llc_add_pack(LLC_DEST_CONN, llc_conn_handler);
++ }
++ return rc;
+ }
+
+-void __exit llc_ui_exit(void)
++static void __exit llc2_exit(void)
+ {
++ llc_station_exit();
++ llc_remove_pack(LLC_DEST_SAP);
++ llc_remove_pack(LLC_DEST_CONN);
+ sock_unregister(PF_LLC);
++ llc_proc_exit();
+ }
++
++module_init(llc2_init);
++module_exit(llc2_exit);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Procom 1997, Jay Schullist 2001, Arnaldo C. Melo 2001-2003");
++MODULE_DESCRIPTION("IEEE 802.2 PF_LLC support");
++MODULE_ALIAS_NETPROTO(PF_LLC);
+Index: linux-2.6.0-test5/net/llc/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/net/llc/Kconfig 2003-09-27 11:38:18.493716912 +0800
++++ linux-2.6.0-test5/net/llc/Kconfig 2003-09-27 11:38:42.091129560 +0800
+@@ -0,0 +1,10 @@
++config LLC
++ tristate
++ depends on NET
++
++config LLC2
++ tristate "ANSI/IEEE 802.2 LLC type 2 Support"
++ select LLC
++ help
++ This is a Logical Link Layer type 2, connection oriented support.
++ Select this if you want to have support for PF_LLC sockets.
+Index: linux-2.6.0-test5/net/llc/llc_c_ac.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/llc/llc_c_ac.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/llc/llc_c_ac.c 2003-09-27 11:38:42.102127888 +0800
+@@ -21,12 +21,13 @@
+ #include <net/llc_conn.h>
+ #include <net/llc_sap.h>
+ #include <net/sock.h>
+-#include <net/llc_main.h>
+ #include <net/llc_c_ev.h>
+ #include <net/llc_c_ac.h>
+ #include <net/llc_c_st.h>
+ #include <net/llc_pdu.h>
+-#include <net/llc_mac.h>
++#include <net/llc.h>
++
++#include "llc_output.h"
+
+ static int llc_conn_ac_inc_vs_by_1(struct sock *sk, struct sk_buff *skb);
+ static void llc_process_tmr_ev(struct sock *sk, struct sk_buff *skb);
+@@ -52,7 +53,7 @@
+
+ int llc_conn_ac_conn_ind(struct sock *sk, struct sk_buff *skb)
+ {
+- int rc = 1;
++ int rc = -ENOTCONN;
+ u8 dsap;
+ struct llc_sap *sap;
+
+@@ -97,28 +98,24 @@
+ {
+ struct llc_conn_state_ev *ev = llc_conn_ev(skb);
+ u8 reason = 0;
+- int rc = 1;
++ int rc = 0;
+
+ if (ev->type == LLC_CONN_EV_TYPE_PDU) {
+ struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
+
+ if (LLC_PDU_IS_RSP(pdu) &&
+ LLC_PDU_TYPE_IS_U(pdu) &&
+- LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_DM) {
++ LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_DM)
+ reason = LLC_DISC_REASON_RX_DM_RSP_PDU;
+- rc = 0;
+- } else if (LLC_PDU_IS_CMD(pdu) &&
++ else if (LLC_PDU_IS_CMD(pdu) &&
+ LLC_PDU_TYPE_IS_U(pdu) &&
+- LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_DISC) {
++ LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_DISC)
+ reason = LLC_DISC_REASON_RX_DISC_CMD_PDU;
+- rc = 0;
+- }
+- } else if (ev->type == LLC_CONN_EV_TYPE_ACK_TMR) {
++ } else if (ev->type == LLC_CONN_EV_TYPE_ACK_TMR)
+ reason = LLC_DISC_REASON_ACK_TMR_EXP;
+- rc = 0;
+- } else {
++ else {
+ reason = 0;
+- rc = 1;
++ rc = -EINVAL;
+ }
+ if (!rc) {
+ ev->reason = reason;
+@@ -217,29 +214,33 @@
+
+ int llc_conn_ac_send_disc_cmd_p_set_x(struct sock *sk, struct sk_buff *skb)
+ {
+- int rc = 1;
++ int rc = -ENOBUFS;
+ struct sk_buff *nskb = llc_alloc_frame();
+
+ if (nskb) {
+- u8 p_bit = 1;
+ struct llc_opt *llc = llc_sk(sk);
+ struct llc_sap *sap = llc->sap;
+
+ nskb->dev = llc->dev;
+ llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
+ llc->daddr.lsap, LLC_PDU_CMD);
+- llc_pdu_init_as_disc_cmd(nskb, p_bit);
+- lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+- rc = 0;
+- llc_conn_send_pdu(sk, nskb);
+- }
+- llc_conn_ac_set_p_flag_1(sk, skb);
+- return rc;
++ llc_pdu_init_as_disc_cmd(nskb, 1);
++ rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++ if (rc)
++ goto free;
++ llc_conn_send_pdu(sk, nskb);
++ llc_conn_ac_set_p_flag_1(sk, skb);
++ }
++out:
++ return rc;
++free:
++ kfree_skb(nskb);
++ goto out;
+ }
+
+ int llc_conn_ac_send_dm_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
+ {
+- int rc = 1;
++ int rc = -ENOBUFS;
+ struct sk_buff *nskb = llc_alloc_frame();
+
+ if (nskb) {
+@@ -252,16 +253,21 @@
+ llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
+ llc->daddr.lsap, LLC_PDU_RSP);
+ llc_pdu_init_as_dm_rsp(nskb, f_bit);
+- lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+- rc = 0;
++ rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++ if (rc)
++ goto free;
+ llc_conn_send_pdu(sk, nskb);
+ }
++out:
+ return rc;
++free:
++ kfree_skb(nskb);
++ goto out;
+ }
+
+ int llc_conn_ac_send_dm_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
+ {
+- int rc = 1;
++ int rc = -ENOBUFS;
+ struct sk_buff *nskb = llc_alloc_frame();
+
+ if (nskb) {
+@@ -273,16 +279,21 @@
+ llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
+ llc->daddr.lsap, LLC_PDU_RSP);
+ llc_pdu_init_as_dm_rsp(nskb, f_bit);
+- lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+- rc = 0;
++ rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++ if (rc)
++ goto free;
+ llc_conn_send_pdu(sk, nskb);
+ }
++out:
+ return rc;
++free:
++ kfree_skb(nskb);
++ goto out;
+ }
+
+ int llc_conn_ac_send_dm_rsp_f_set_f_flag(struct sock *sk, struct sk_buff *skb)
+ {
+- int rc = 1;
++ int rc = -ENOBUFS;
+ struct sk_buff *nskb = llc_alloc_frame();
+
+ if (nskb) {
+@@ -294,17 +305,22 @@
+ llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
+ llc->daddr.lsap, LLC_PDU_RSP);
+ llc_pdu_init_as_dm_rsp(nskb, f_bit);
+- lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+- rc = 0;
++ rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++ if (rc)
++ goto free;
+ llc_conn_send_pdu(sk, nskb);
+ }
++out:
+ return rc;
++free:
++ kfree_skb(nskb);
++ goto out;
+ }
+
+ int llc_conn_ac_send_frmr_rsp_f_set_x(struct sock *sk, struct sk_buff *skb)
+ {
+ u8 f_bit;
+- int rc = 1;
++ int rc = -ENOBUFS;
+ struct sk_buff *nskb;
+ struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+ struct llc_opt *llc = llc_sk(sk);
+@@ -323,16 +339,21 @@
+ llc->daddr.lsap, LLC_PDU_RSP);
+ llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS,
+ llc->vR, INCORRECT);
+- lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+- rc = 0;
++ rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++ if (rc)
++ goto free;
+ llc_conn_send_pdu(sk, nskb);
+ }
++out:
+ return rc;
++free:
++ kfree_skb(nskb);
++ goto out;
+ }
+
+ int llc_conn_ac_resend_frmr_rsp_f_set_0(struct sock *sk, struct sk_buff *skb)
+ {
+- int rc = 1;
++ int rc = -ENOBUFS;
+ struct sk_buff *nskb = llc_alloc_frame();
+
+ if (nskb) {
+@@ -346,17 +367,22 @@
+ llc->daddr.lsap, LLC_PDU_RSP);
+ llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS,
+ llc->vR, INCORRECT);
+- lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+- rc = 0;
++ rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++ if (rc)
++ goto free;
+ llc_conn_send_pdu(sk, nskb);
+ }
++out:
+ return rc;
++free:
++ kfree_skb(nskb);
++ goto out;
+ }
+
+ int llc_conn_ac_resend_frmr_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
+ {
+ u8 f_bit;
+- int rc = 1;
++ int rc = -ENOBUFS;
+ struct sk_buff *nskb;
+
+ llc_pdu_decode_pf_bit(skb, &f_bit);
+@@ -371,41 +397,50 @@
+ llc->daddr.lsap, LLC_PDU_RSP);
+ llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS,
+ llc->vR, INCORRECT);
+- lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+- rc = 0;
++ rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++ if (rc)
++ goto free;
+ llc_conn_send_pdu(sk, nskb);
+ }
++out:
+ return rc;
++free:
++ kfree_skb(nskb);
++ goto out;
+ }
+
+ int llc_conn_ac_send_i_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
+ {
+- u8 p_bit = 1;
++ int rc;
+ struct llc_opt *llc = llc_sk(sk);
+ struct llc_sap *sap = llc->sap;
+
+ llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,
+ llc->daddr.lsap, LLC_PDU_CMD);
+- llc_pdu_init_as_i_cmd(skb, p_bit, llc->vS, llc->vR);
+- lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+- llc_conn_send_pdu(sk, skb);
+- llc_conn_ac_inc_vs_by_1(sk, skb);
+- return 0;
++ llc_pdu_init_as_i_cmd(skb, 1, llc->vS, llc->vR);
++ rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
++ if (!rc) {
++ llc_conn_send_pdu(sk, skb);
++ llc_conn_ac_inc_vs_by_1(sk, skb);
++ }
++ return rc;
+ }
+
+ int llc_conn_ac_send_i_cmd_p_set_0(struct sock *sk, struct sk_buff *skb)
+ {
+- u8 p_bit = 0;
++ int rc;
+ struct llc_opt *llc = llc_sk(sk);
+ struct llc_sap *sap = llc->sap;
+
+ llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,
+ llc->daddr.lsap, LLC_PDU_CMD);
+- llc_pdu_init_as_i_cmd(skb, p_bit, llc->vS, llc->vR);
+- lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+- llc_conn_send_pdu(sk, skb);
+- llc_conn_ac_inc_vs_by_1(sk, skb);
+- return 0;
++ llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR);
++ rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
++ if (!rc) {
++ llc_conn_send_pdu(sk, skb);
++ llc_conn_ac_inc_vs_by_1(sk, skb);
++ }
++ return rc;
+ }
+
+ int llc_conn_ac_resend_i_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
+@@ -431,16 +466,18 @@
+
+ int llc_conn_ac_send_i_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
+ {
+- u8 p_bit = 0;
++ int rc;
+ struct llc_opt *llc = llc_sk(sk);
+ struct llc_sap *sap = llc->sap;
+
+ llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,
+ llc->daddr.lsap, LLC_PDU_CMD);
+- llc_pdu_init_as_i_cmd(skb, p_bit, llc->vS, llc->vR);
+- lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+- llc_conn_send_pdu(sk, skb);
+- llc_conn_ac_inc_vs_by_1(sk, skb);
++ llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR);
++ rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
++ if (!rc) {
++ llc_conn_send_pdu(sk, skb);
++ llc_conn_ac_inc_vs_by_1(sk, skb);
++ }
+ return 0;
+ }
+
+@@ -457,9 +494,8 @@
+ struct sk_buff *skb)
+ {
+ u8 nr;
+- u8 f_bit = 0;
+ struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+- int rc = 1;
++ int rc = -ENOBUFS;
+ struct sk_buff *nskb = llc_alloc_frame();
+
+ if (nskb) {
+@@ -469,15 +505,17 @@
+ nskb->dev = llc->dev;
+ llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
+ llc->daddr.lsap, LLC_PDU_RSP);
+- llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR);
+- lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+- rc = 0;
+- llc_conn_send_pdu(sk, nskb);
++ llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR);
++ rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++ if (!rc)
++ llc_conn_send_pdu(sk, nskb);
++ else
++ kfree_skb(skb);
+ }
+ if (rc) {
+ nr = LLC_I_GET_NR(pdu);
+ rc = 0;
+- llc_conn_resend_i_pdu_as_cmd(sk, nr, f_bit);
++ llc_conn_resend_i_pdu_as_cmd(sk, nr, 0);
+ }
+ return rc;
+ }
+@@ -493,28 +531,32 @@
+
+ int llc_conn_ac_send_rej_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
+ {
+- int rc = 1;
++ int rc = -ENOBUFS;
+ struct sk_buff *nskb = llc_alloc_frame();
+
+ if (nskb) {
+ struct llc_opt *llc = llc_sk(sk);
+ struct llc_sap *sap = llc->sap;
+- u8 p_bit = 1;
+
+ nskb->dev = llc->dev;
+ llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+ llc->daddr.lsap, LLC_PDU_CMD);
+- llc_pdu_init_as_rej_cmd(nskb, p_bit, llc->vR);
+- lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+- rc = 0;
++ llc_pdu_init_as_rej_cmd(nskb, 1, llc->vR);
++ rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++ if (rc)
++ goto free;
+ llc_conn_send_pdu(sk, nskb);
+ }
++out:
+ return rc;
++free:
++ kfree_skb(nskb);
++ goto out;
+ }
+
+ int llc_conn_ac_send_rej_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
+ {
+- int rc = 1;
++ int rc = -ENOBUFS;
+ struct sk_buff *nskb = llc_alloc_frame();
+
+ if (nskb) {
+@@ -526,16 +568,21 @@
+ llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+ llc->daddr.lsap, LLC_PDU_RSP);
+ llc_pdu_init_as_rej_rsp(nskb, f_bit, llc->vR);
+- lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+- rc = 0;
++ rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++ if (rc)
++ goto free;
+ llc_conn_send_pdu(sk, nskb);
+ }
++out:
+ return rc;
++free:
++ kfree_skb(nskb);
++ goto out;
+ }
+
+ int llc_conn_ac_send_rej_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
+ {
+- int rc = 1;
++ int rc = -ENOBUFS;
+ struct sk_buff *nskb = llc_alloc_frame();
+
+ if (nskb) {
+@@ -547,37 +594,46 @@
+ llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+ llc->daddr.lsap, LLC_PDU_RSP);
+ llc_pdu_init_as_rej_rsp(nskb, f_bit, llc->vR);
+- lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+- rc = 0;
++ rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++ if (rc)
++ goto free;
+ llc_conn_send_pdu(sk, nskb);
+ }
++out:
+ return rc;
++free:
++ kfree_skb(nskb);
++ goto out;
+ }
+
+ int llc_conn_ac_send_rnr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
+ {
+- int rc = 1;
++ int rc = -ENOBUFS;
+ struct sk_buff *nskb = llc_alloc_frame();
+
+ if (nskb) {
+ struct llc_opt *llc = llc_sk(sk);
+ struct llc_sap *sap = llc->sap;
+- u8 p_bit = 1;
+
+ nskb->dev = llc->dev;
+ llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+ llc->daddr.lsap, LLC_PDU_CMD);
+- llc_pdu_init_as_rnr_cmd(nskb, p_bit, llc->vR);
+- lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+- rc = 0;
++ llc_pdu_init_as_rnr_cmd(nskb, 1, llc->vR);
++ rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++ if (rc)
++ goto free;
+ llc_conn_send_pdu(sk, nskb);
+ }
++out:
+ return rc;
++free:
++ kfree_skb(nskb);
++ goto out;
+ }
+
+ int llc_conn_ac_send_rnr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
+ {
+- int rc = 1;
++ int rc = -ENOBUFS;
+ struct sk_buff *nskb = llc_alloc_frame();
+
+ if (nskb) {
+@@ -589,16 +645,21 @@
+ llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+ llc->daddr.lsap, LLC_PDU_RSP);
+ llc_pdu_init_as_rnr_rsp(nskb, f_bit, llc->vR);
+- lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+- rc = 0;
++ rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++ if (rc)
++ goto free;
+ llc_conn_send_pdu(sk, nskb);
+ }
++out:
+ return rc;
++free:
++ kfree_skb(nskb);
++ goto out;
+ }
+
+ int llc_conn_ac_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
+ {
+- int rc = 1;
++ int rc = -ENOBUFS;
+ struct sk_buff *nskb = llc_alloc_frame();
+
+ if (nskb) {
+@@ -610,11 +671,16 @@
+ llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+ llc->daddr.lsap, LLC_PDU_RSP);
+ llc_pdu_init_as_rnr_rsp(nskb, f_bit, llc->vR);
+- lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+- rc = 0;
++ rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++ if (rc)
++ goto free;
+ llc_conn_send_pdu(sk, nskb);
+ }
++out:
+ return rc;
++free:
++ kfree_skb(nskb);
++ goto out;
+ }
+
+ int llc_conn_ac_set_remote_busy(struct sock *sk, struct sk_buff *skb)
+@@ -631,70 +697,82 @@
+
+ int llc_conn_ac_opt_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
+ {
+- int rc = 1;
++ int rc = -ENOBUFS;
+ struct sk_buff *nskb = llc_alloc_frame();
+
+ if (nskb) {
+ struct llc_opt *llc = llc_sk(sk);
+ struct llc_sap *sap = llc->sap;
+- u8 f_bit = 0;
+
+ nskb->dev = llc->dev;
+ llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+ llc->daddr.lsap, LLC_PDU_RSP);
+- llc_pdu_init_as_rnr_rsp(nskb, f_bit, llc->vR);
+- lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+- rc = 0;
++ llc_pdu_init_as_rnr_rsp(nskb, 0, llc->vR);
++ rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++ if (rc)
++ goto free;
+ llc_conn_send_pdu(sk, nskb);
+ }
++out:
+ return rc;
++free:
++ kfree_skb(nskb);
++ goto out;
+ }
+
+ int llc_conn_ac_send_rr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
+ {
+- int rc = 1;
++ int rc = -ENOBUFS;
+ struct sk_buff *nskb = llc_alloc_frame();
+
+ if (nskb) {
+- u8 p_bit = 1;
+ struct llc_opt *llc = llc_sk(sk);
+ struct llc_sap *sap = llc->sap;
+
+ nskb->dev = llc->dev;
+ llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+ llc->daddr.lsap, LLC_PDU_CMD);
+- llc_pdu_init_as_rr_cmd(nskb, p_bit, llc->vR);
+- lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+- rc = 0;
++ llc_pdu_init_as_rr_cmd(nskb, 1, llc->vR);
++ rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++ if (rc)
++ goto free;
+ llc_conn_send_pdu(sk, nskb);
+ }
++out:
+ return rc;
++free:
++ kfree_skb(nskb);
++ goto out;
+ }
+
+ int llc_conn_ac_send_ack_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
+ {
+- int rc = 1;
++ int rc = -ENOBUFS;
+ struct sk_buff *nskb = llc_alloc_frame();
+
+ if (nskb) {
+- u8 p_bit = 1;
+ struct llc_opt *llc = llc_sk(sk);
+ struct llc_sap *sap = llc->sap;
+
+ nskb->dev = llc->dev;
+ llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+ llc->daddr.lsap, LLC_PDU_CMD);
+- llc_pdu_init_as_rr_cmd(nskb, p_bit, llc->vR);
+- lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+- rc = 0;
++ llc_pdu_init_as_rr_cmd(nskb, 1, llc->vR);
++ rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++ if (rc)
++ goto free;
+ llc_conn_send_pdu(sk, nskb);
+ }
++out:
+ return rc;
++free:
++ kfree_skb(nskb);
++ goto out;
+ }
+
+ int llc_conn_ac_send_rr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
+ {
+- int rc = 1;
++ int rc = -ENOBUFS;
+ struct sk_buff *nskb = llc_alloc_frame();
+
+ if (nskb) {
+@@ -706,16 +784,21 @@
+ llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+ llc->daddr.lsap, LLC_PDU_RSP);
+ llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR);
+- lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+- rc = 0;
++ rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++ if (rc)
++ goto free;
+ llc_conn_send_pdu(sk, nskb);
+ }
++out:
+ return rc;
++free:
++ kfree_skb(nskb);
++ goto out;
+ }
+
+ int llc_conn_ac_send_ack_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
+ {
+- int rc = 1;
++ int rc = -ENOBUFS;
+ struct sk_buff *nskb = llc_alloc_frame();
+
+ if (nskb) {
+@@ -727,53 +810,66 @@
+ llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+ llc->daddr.lsap, LLC_PDU_RSP);
+ llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR);
+- lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+- rc = 0;
++ rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++ if (rc)
++ goto free;
+ llc_conn_send_pdu(sk, nskb);
+ }
++out:
+ return rc;
++free:
++ kfree_skb(nskb);
++ goto out;
+ }
+
+ int llc_conn_ac_send_rr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
+ {
+- int rc = 1;
++ int rc = -ENOBUFS;
+ struct sk_buff *nskb = llc_alloc_frame();
+
+ if (nskb) {
+ struct llc_opt *llc = llc_sk(sk);
+ struct llc_sap *sap = llc->sap;
+- u8 f_bit = 0;
+
+ nskb->dev = llc->dev;
+ llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+ llc->daddr.lsap, LLC_PDU_RSP);
+- llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR);
+- lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+- rc = 0;
++ llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR);
++ rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++ if (rc)
++ goto free;
+ llc_conn_send_pdu(sk, nskb);
+ }
++out:
+ return rc;
++free:
++ kfree_skb(nskb);
++ goto out;
+ }
+
+ int llc_conn_ac_send_ack_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
+ {
+- int rc = 1;
++ int rc = -ENOBUFS;
+ struct sk_buff *nskb = llc_alloc_frame();
+
+ if (nskb) {
+ struct llc_opt *llc = llc_sk(sk);
+ struct llc_sap *sap = llc->sap;
+- u8 f_bit = 0;
+
+ nskb->dev = llc->dev;
+ llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+ llc->daddr.lsap, LLC_PDU_RSP);
+- llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR);
+- lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+- rc = 0;
++ llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR);
++ rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++ if (rc)
++ goto free;
+ llc_conn_send_pdu(sk, nskb);
+ }
++out:
+ return rc;
++free:
++ kfree_skb(nskb);
++ goto out;
+ }
+
+ void llc_conn_set_p_flag(struct sock *sk, u8 value)
+@@ -788,10 +884,9 @@
+
+ int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk, struct sk_buff *skb)
+ {
+- int rc = 1;
++ int rc = -ENOBUFS;
+ struct sk_buff *nskb = llc_alloc_frame();
+ struct llc_opt *llc = llc_sk(sk);
+- u8 p_bit = 1;
+
+ if (nskb) {
+ struct llc_sap *sap = llc->sap;
+@@ -802,41 +897,49 @@
+ nskb->dev = llc->dev;
+ llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
+ llc->daddr.lsap, LLC_PDU_CMD);
+- llc_pdu_init_as_sabme_cmd(nskb, p_bit);
+- lan_hdrs_init(nskb, llc->dev->dev_addr, dmac);
+- rc = 0;
+- llc_conn_send_pdu(sk, nskb);
+- }
+- llc_conn_set_p_flag(sk, p_bit);
+-
+- return rc;
++ llc_pdu_init_as_sabme_cmd(nskb, 1);
++ rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, dmac);
++ if (rc)
++ goto free;
++ llc_conn_send_pdu(sk, nskb);
++ llc_conn_set_p_flag(sk, 1);
++ }
++out:
++ return rc;
++free:
++ kfree_skb(nskb);
++ goto out;
+ }
+
+ int llc_conn_ac_send_ua_rsp_f_set_f_flag(struct sock *sk, struct sk_buff *skb)
+ {
+- int rc = 1;
++ int rc = -ENOBUFS;
+ struct sk_buff *nskb = llc_alloc_frame();
+
+ if (nskb) {
+ struct llc_opt *llc = llc_sk(sk);
+ struct llc_sap *sap = llc->sap;
+- u8 f_bit = llc->f_flag;
+
+ nskb->dev = llc->dev;
+ llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
+ llc->daddr.lsap, LLC_PDU_RSP);
+- llc_pdu_init_as_ua_rsp(nskb, f_bit);
+- lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+- rc = 0;
++ llc_pdu_init_as_ua_rsp(nskb, llc->f_flag);
++ rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++ if (rc)
++ goto free;
+ llc_conn_send_pdu(sk, nskb);
+ }
++out:
+ return rc;
++free:
++ kfree_skb(nskb);
++ goto out;
+ }
+
+ int llc_conn_ac_send_ua_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
+ {
+ u8 f_bit;
+- int rc = 1;
++ int rc = -ENOBUFS;
+ struct sk_buff *nskb = llc_alloc_frame();
+
+ llc_pdu_decode_pf_bit(skb, &f_bit);
+@@ -848,11 +951,16 @@
+ llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
+ llc->daddr.lsap, LLC_PDU_RSP);
+ llc_pdu_init_as_ua_rsp(nskb, f_bit);
+- lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+- rc = 0;
++ rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++ if (rc)
++ goto free;
+ llc_conn_send_pdu(sk, nskb);
+ }
++out:
+ return rc;
++free:
++ kfree_skb(nskb);
++ goto out;
+ }
+
+ int llc_conn_ac_set_s_flag_0(struct sock *sk, struct sk_buff *skb)
+@@ -935,17 +1043,19 @@
+ */
+ int llc_conn_ac_send_i_rsp_f_set_ackpf(struct sock *sk, struct sk_buff *skb)
+ {
++ int rc;
+ struct llc_opt *llc = llc_sk(sk);
+- u8 p_bit = llc->ack_pf;
+ struct llc_sap *sap = llc->sap;
+
+ llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,
+ llc->daddr.lsap, LLC_PDU_RSP);
+- llc_pdu_init_as_i_cmd(skb, p_bit, llc->vS, llc->vR);
+- lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+- llc_conn_send_pdu(sk, skb);
+- llc_conn_ac_inc_vs_by_1(sk, skb);
+- return 0;
++ llc_pdu_init_as_i_cmd(skb, llc->ack_pf, llc->vS, llc->vR);
++ rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
++ if (!rc) {
++ llc_conn_send_pdu(sk, skb);
++ llc_conn_ac_inc_vs_by_1(sk, skb);
++ }
++ return rc;
+ }
+
+ /**
+@@ -983,23 +1093,27 @@
+ */
+ int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock *sk, struct sk_buff *skb)
+ {
+- int rc = 1;
++ int rc = -ENOBUFS;
+ struct sk_buff *nskb = llc_alloc_frame();
+
+ if (nskb) {
+ struct llc_opt *llc = llc_sk(sk);
+ struct llc_sap *sap = llc->sap;
+- u8 f_bit = llc->ack_pf;
+
+ nskb->dev = llc->dev;
+ llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+ llc->daddr.lsap, LLC_PDU_RSP);
+- llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR);
+- lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+- rc = 0;
++ llc_pdu_init_as_rr_rsp(nskb, llc->ack_pf, llc->vR);
++ rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++ if (rc)
++ goto free;
+ llc_conn_send_pdu(sk, nskb);
+ }
++out:
+ return rc;
++free:
++ kfree_skb(nskb);
++ goto out;
+ }
+
+ /**
+@@ -1193,7 +1307,6 @@
+ {
+ int acked;
+ u16 unacked = 0;
+- u8 fbit;
+ struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+ struct llc_opt *llc = llc_sk(sk);
+
+@@ -1215,8 +1328,10 @@
+ mod_timer(&llc->ack_timer.timer,
+ jiffies + llc->ack_timer.expire * HZ);
+ } else if (llc->failed_data_req) {
+- llc_pdu_decode_pf_bit(skb, &fbit);
+- if (fbit == 1) {
++ u8 f_bit;
++
++ llc_pdu_decode_pf_bit(skb, &f_bit);
++ if (f_bit == 1) {
+ llc->failed_data_req = 0;
+ llc_conn_ac_data_confirm(sk, skb);
+ }
+Index: linux-2.6.0-test5/net/llc/llc_conn.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/llc/llc_conn.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/llc/llc_conn.c 2003-09-27 11:38:42.108126976 +0800
+@@ -11,21 +11,22 @@
+ *
+ * See the GNU General Public License for more details.
+ */
+-#include <linux/netdevice.h>
+-#include <linux/interrupt.h>
++
+ #include <linux/init.h>
+-#include <net/llc_if.h>
+ #include <net/llc_sap.h>
+ #include <net/llc_conn.h>
+ #include <net/sock.h>
+ #include <linux/tcp.h>
+-#include <net/llc_main.h>
+ #include <net/llc_c_ev.h>
+ #include <net/llc_c_ac.h>
+ #include <net/llc_c_st.h>
+-#include <net/llc_mac.h>
+ #include <net/llc_pdu.h>
+-#include <net/llc_s_ev.h>
++
++#if 0
++#define dprintk(args...) printk(KERN_DEBUG args)
++#else
++#define dprintk(args...)
++#endif
+
+ static int llc_find_offset(int state, int ev_type);
+ static void llc_conn_send_pdus(struct sock *sk);
+@@ -39,22 +40,6 @@
+ /* Offset table on connection states transition diagram */
+ static int llc_offset_table[NBR_CONN_STATES][NBR_CONN_EV];
+
+-void llc_save_primitive(struct sk_buff* skb, u8 prim)
+-{
+- struct sockaddr_llc *addr = llc_ui_skb_cb(skb);
+-
+- /* save primitive for use by the user. */
+- addr->sllc_family = skb->sk->sk_family;
+- addr->sllc_arphrd = skb->dev->type;
+- addr->sllc_test = prim == LLC_TEST_PRIM;
+- addr->sllc_xid = prim == LLC_XID_PRIM;
+- addr->sllc_ua = prim == LLC_DATAUNIT_PRIM;
+- llc_pdu_decode_sa(skb, addr->sllc_smac);
+- llc_pdu_decode_da(skb, addr->sllc_dmac);
+- llc_pdu_decode_dsap(skb, &addr->sllc_dsap);
+- llc_pdu_decode_ssap(skb, &addr->sllc_ssap);
+-}
+-
+ /**
+ * llc_conn_state_process - sends event to connection state machine
+ * @sk: connection
+@@ -541,35 +526,6 @@
+ }
+
+ /**
+- * llc_lookup_dgram - Finds dgram socket for the local sap/mac
+- * @sap: SAP
+- * @laddr: address of local LLC (MAC + SAP)
+- *
+- * Search socket list of the SAP and finds connection using the local
+- * mac, and local sap. Returns pointer for socket found, %NULL otherwise.
+- */
+-struct sock *llc_lookup_dgram(struct llc_sap *sap, struct llc_addr *laddr)
+-{
+- struct sock *rc;
+- struct hlist_node *node;
+-
+- read_lock_bh(&sap->sk_list.lock);
+- sk_for_each(rc, node, &sap->sk_list.list) {
+- struct llc_opt *llc = llc_sk(rc);
+-
+- if (rc->sk_type == SOCK_DGRAM &&
+- llc->laddr.lsap == laddr->lsap &&
+- llc_mac_match(llc->laddr.mac, laddr->mac)) {
+- sock_hold(rc);
+- goto found;
+- }
+- }
+- rc = NULL;
+-found:
+- read_unlock_bh(&sap->sk_list.lock);
+- return rc;
+-}
+-/**
+ * llc_data_accept_state - designates if in this state data can be sent.
+ * @state: state of connection.
+ *
+@@ -651,3 +607,323 @@
+ }
+ return rc;
+ }
++
++/**
++ * llc_sap_add_socket - adds a socket to a SAP
++ * @sap: SAP
++ * @sk: socket
++ *
++ * This function adds a socket to sk_list of a SAP.
++ */
++void llc_sap_add_socket(struct llc_sap *sap, struct sock *sk)
++{
++ write_lock_bh(&sap->sk_list.lock);
++ llc_sk(sk)->sap = sap;
++ sk_add_node(sk, &sap->sk_list.list);
++ write_unlock_bh(&sap->sk_list.lock);
++}
++
++/**
++ * llc_sap_remove_socket - removes a socket from SAP
++ * @sap: SAP
++ * @sk: socket
++ *
++ * This function removes a connection from sk_list.list of a SAP if
++ * the connection was in this list.
++ */
++void llc_sap_remove_socket(struct llc_sap *sap, struct sock *sk)
++{
++ write_lock_bh(&sap->sk_list.lock);
++ sk_del_node_init(sk);
++ write_unlock_bh(&sap->sk_list.lock);
++}
++
++/**
++ * llc_conn_rcv - sends received pdus to the connection state machine
++ * @sk: current connection structure.
++ * @skb: received frame.
++ *
++ * Sends received pdus to the connection state machine.
++ */
++static int llc_conn_rcv(struct sock* sk, struct sk_buff *skb)
++{
++ struct llc_conn_state_ev *ev = llc_conn_ev(skb);
++ struct llc_opt *llc = llc_sk(sk);
++
++ if (!llc->dev)
++ llc->dev = skb->dev;
++ ev->type = LLC_CONN_EV_TYPE_PDU;
++ ev->reason = 0;
++ return llc_conn_state_process(sk, skb);
++}
++
++void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb)
++{
++ struct llc_addr saddr, daddr;
++ struct sock *sk;
++
++ llc_pdu_decode_sa(skb, saddr.mac);
++ llc_pdu_decode_ssap(skb, &saddr.lsap);
++ llc_pdu_decode_da(skb, daddr.mac);
++ llc_pdu_decode_dsap(skb, &daddr.lsap);
++
++ sk = llc_lookup_established(sap, &saddr, &daddr);
++ if (!sk) {
++ /*
++ * Didn't find an active connection; verify if there
++ * is a listening socket for this llc addr
++ */
++ struct llc_opt *llc;
++ struct sock *parent = llc_lookup_listener(sap, &daddr);
++
++ if (!parent) {
++ dprintk("llc_lookup_listener failed!\n");
++ goto drop;
++ }
++
++ sk = llc_sk_alloc(parent->sk_family, GFP_ATOMIC);
++ if (!sk) {
++ sock_put(parent);
++ goto drop;
++ }
++ llc = llc_sk(sk);
++ memcpy(&llc->laddr, &daddr, sizeof(llc->laddr));
++ memcpy(&llc->daddr, &saddr, sizeof(llc->daddr));
++ llc_sap_add_socket(sap, sk);
++ sock_hold(sk);
++ sock_put(parent);
++ skb->sk = parent;
++ } else
++ skb->sk = sk;
++ bh_lock_sock(sk);
++ if (!sock_owned_by_user(sk))
++ llc_conn_rcv(sk, skb);
++ else {
++ dprintk("%s: adding to backlog...\n", __FUNCTION__);
++ llc_set_backlog_type(skb, LLC_PACKET);
++ sk_add_backlog(sk, skb);
++ }
++ bh_unlock_sock(sk);
++ sock_put(sk);
++ return;
++drop:
++ kfree_skb(skb);
++}
++
++#undef LLC_REFCNT_DEBUG
++#ifdef LLC_REFCNT_DEBUG
++static atomic_t llc_sock_nr;
++#endif
++
++/**
++ * llc_release_sockets - releases all sockets in a sap
++ * @sap: sap to release its sockets
++ *
++ * Releases all connections of a sap. Returns 0 if all actions complete
++ * successfully, nonzero otherwise
++ */
++int llc_release_sockets(struct llc_sap *sap)
++{
++ int rc = 0;
++ struct sock *sk;
++ struct hlist_node *node;
++
++ write_lock_bh(&sap->sk_list.lock);
++
++ sk_for_each(sk, node, &sap->sk_list.list) {
++ llc_sk(sk)->state = LLC_CONN_STATE_TEMP;
++
++ if (llc_send_disc(sk))
++ rc = 1;
++ }
++
++ write_unlock_bh(&sap->sk_list.lock);
++ return rc;
++}
++
++/**
++ * llc_backlog_rcv - Processes rx frames and expired timers.
++ * @sk: LLC sock (p8022 connection)
++ * @skb: queued rx frame or event
++ *
++ * This function processes frames that has received and timers that has
++ * expired during sending an I pdu (refer to data_req_handler). frames
++ * queue by llc_rcv function (llc_mac.c) and timers queue by timer
++ * callback functions(llc_c_ac.c).
++ */
++static int llc_backlog_rcv(struct sock *sk, struct sk_buff *skb)
++{
++ int rc = 0;
++ struct llc_opt *llc = llc_sk(sk);
++
++ if (llc_backlog_type(skb) == LLC_PACKET) {
++ if (llc->state > 1) /* not closed */
++ rc = llc_conn_rcv(sk, skb);
++ else
++ goto out_kfree_skb;
++ } else if (llc_backlog_type(skb) == LLC_EVENT) {
++ /* timer expiration event */
++ if (llc->state > 1) /* not closed */
++ rc = llc_conn_state_process(sk, skb);
++ else
++ goto out_kfree_skb;
++ } else {
++ printk(KERN_ERR "%s: invalid skb in backlog\n", __FUNCTION__);
++ goto out_kfree_skb;
++ }
++out:
++ return rc;
++out_kfree_skb:
++ kfree_skb(skb);
++ goto out;
++}
++
++/**
++ * llc_sk_init - Initializes a socket with default llc values.
++ * @sk: socket to initialize.
++ *
++ * Initializes a socket with default llc values.
++ */
++int llc_sk_init(struct sock* sk)
++{
++ struct llc_opt *llc = kmalloc(sizeof(*llc), GFP_ATOMIC);
++ int rc = -ENOMEM;
++
++ if (!llc)
++ goto out;
++ memset(llc, 0, sizeof(*llc));
++ rc = 0;
++
++ llc->sk = sk;
++ llc->state = LLC_CONN_STATE_ADM;
++ llc->inc_cntr = llc->dec_cntr = 2;
++ llc->dec_step = llc->connect_step = 1;
++
++ init_timer(&llc->ack_timer.timer);
++ llc->ack_timer.expire = LLC_ACK_TIME;
++ llc->ack_timer.timer.data = (unsigned long)sk;
++ llc->ack_timer.timer.function = llc_conn_ack_tmr_cb;
++
++ init_timer(&llc->pf_cycle_timer.timer);
++ llc->pf_cycle_timer.expire = LLC_P_TIME;
++ llc->pf_cycle_timer.timer.data = (unsigned long)sk;
++ llc->pf_cycle_timer.timer.function = llc_conn_pf_cycle_tmr_cb;
++
++ init_timer(&llc->rej_sent_timer.timer);
++ llc->rej_sent_timer.expire = LLC_REJ_TIME;
++ llc->rej_sent_timer.timer.data = (unsigned long)sk;
++ llc->rej_sent_timer.timer.function = llc_conn_rej_tmr_cb;
++
++ init_timer(&llc->busy_state_timer.timer);
++ llc->busy_state_timer.expire = LLC_BUSY_TIME;
++ llc->busy_state_timer.timer.data = (unsigned long)sk;
++ llc->busy_state_timer.timer.function = llc_conn_busy_tmr_cb;
++
++ llc->n2 = 2; /* max retransmit */
++ llc->k = 2; /* tx win size, will adjust dynam */
++ llc->rw = 128; /* rx win size (opt and equal to
++ * tx_win of remote LLC) */
++ skb_queue_head_init(&llc->pdu_unack_q);
++ sk->sk_backlog_rcv = llc_backlog_rcv;
++ llc_sk(sk) = llc;
++out:
++ return rc;
++}
++
++/**
++ * llc_sk_alloc - Allocates LLC sock
++ * @family: upper layer protocol family
++ * @priority: for allocation (%GFP_KERNEL, %GFP_ATOMIC, etc)
++ *
++ * Allocates a LLC sock and initializes it. Returns the new LLC sock
++ * or %NULL if there's no memory available for one
++ */
++struct sock *llc_sk_alloc(int family, int priority)
++{
++ struct sock *sk = sk_alloc(family, priority, 1, NULL);
++
++ if (!sk)
++ goto out;
++ if (llc_sk_init(sk))
++ goto outsk;
++ sock_init_data(NULL, sk);
++ sk_set_owner(sk, THIS_MODULE);
++#ifdef LLC_REFCNT_DEBUG
++ atomic_inc(&llc_sock_nr);
++ printk(KERN_DEBUG "LLC socket %p created in %s, now we have %d alive\n", sk,
++ __FUNCTION__, atomic_read(&llc_sock_nr));
++#endif
++out:
++ return sk;
++outsk:
++ sk_free(sk);
++ sk = NULL;
++ goto out;
++}
++
++/**
++ * llc_sk_free - Frees a LLC socket
++ * @sk - socket to free
++ *
++ * Frees a LLC socket
++ */
++void llc_sk_free(struct sock *sk)
++{
++ struct llc_opt *llc = llc_sk(sk);
++
++ llc->state = LLC_CONN_OUT_OF_SVC;
++ /* Stop all (possibly) running timers */
++ llc_conn_ac_stop_all_timers(sk, NULL);
++#ifdef DEBUG_LLC_CONN_ALLOC
++ printk(KERN_INFO "%s: unackq=%d, txq=%d\n", __FUNCTION__,
++ skb_queue_len(&llc->pdu_unack_q),
++ skb_queue_len(&sk->sk_write_queue));
++#endif
++ skb_queue_purge(&sk->sk_receive_queue);
++ skb_queue_purge(&sk->sk_write_queue);
++ skb_queue_purge(&llc->pdu_unack_q);
++#ifdef LLC_REFCNT_DEBUG
++ if (atomic_read(&sk->sk_refcnt) != 1) {
++ printk(KERN_DEBUG "Destruction of LLC sock %p delayed in %s, cnt=%d\n",
++ sk, __FUNCTION__, atomic_read(&sk->sk_refcnt));
++ printk(KERN_DEBUG "%d LLC sockets are still alive\n",
++ atomic_read(&llc_sock_nr));
++ } else {
++ atomic_dec(&llc_sock_nr);
++ printk(KERN_DEBUG "LLC socket %p released in %s, %d are still alive\n", sk,
++ __FUNCTION__, atomic_read(&llc_sock_nr));
++ }
++#endif
++ sock_put(sk);
++}
++
++/**
++ * llc_sk_reset - resets a connection
++ * @sk: LLC socket to reset
++ *
++ * Resets a connection to the out of service state. Stops its timers
++ * and frees any frames in the queues of the connection.
++ */
++void llc_sk_reset(struct sock *sk)
++{
++ struct llc_opt *llc = llc_sk(sk);
++
++ llc_conn_ac_stop_all_timers(sk, NULL);
++ skb_queue_purge(&sk->sk_write_queue);
++ skb_queue_purge(&llc->pdu_unack_q);
++ llc->remote_busy_flag = 0;
++ llc->cause_flag = 0;
++ llc->retry_count = 0;
++ llc_conn_set_p_flag(sk, 0);
++ llc->f_flag = 0;
++ llc->s_flag = 0;
++ llc->ack_pf = 0;
++ llc->first_pdu_Ns = 0;
++ llc->ack_must_be_send = 0;
++ llc->dec_step = 1;
++ llc->inc_cntr = 2;
++ llc->dec_cntr = 2;
++ llc->X = 0;
++ llc->failed_data_req = 0 ;
++ llc->last_nr = 0;
++}
+Index: linux-2.6.0-test5/net/llc/llc_core.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/llc/llc_core.c 2003-09-27 11:38:18.493716912 +0800
++++ linux-2.6.0-test5/net/llc/llc_core.c 2003-09-27 11:38:42.109126824 +0800
+@@ -0,0 +1,181 @@
++/*
++ * llc_core.c - Minimum needed routines for sap handling and module init/exit
++ *
++ * Copyright (c) 1997 by Procom Technology, Inc.
++ * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
++ *
++ * This program can be redistributed or modified under the terms of the
++ * GNU General Public License as published by the Free Software Foundation.
++ * This program is distributed without any warranty or implied warranty
++ * of merchantability or fitness for a particular purpose.
++ *
++ * See the GNU General Public License for more details.
++ */
++
++#include <linux/module.h>
++#include <linux/interrupt.h>
++#include <linux/if_ether.h>
++#include <linux/netdevice.h>
++#include <linux/slab.h>
++#include <linux/string.h>
++#include <linux/init.h>
++#include <net/llc.h>
++
++LIST_HEAD(llc_sap_list);
++rwlock_t llc_sap_list_lock = RW_LOCK_UNLOCKED;
++
++unsigned char llc_station_mac_sa[ETH_ALEN];
++
++/**
++ * llc_sap_alloc - allocates and initializes sap.
++ *
++ * Allocates and initializes sap.
++ */
++struct llc_sap *llc_sap_alloc(void)
++{
++ struct llc_sap *sap = kmalloc(sizeof(*sap), GFP_ATOMIC);
++
++ if (sap) {
++ memset(sap, 0, sizeof(*sap));
++ sap->state = LLC_SAP_STATE_ACTIVE;
++ memcpy(sap->laddr.mac, llc_station_mac_sa, ETH_ALEN);
++ rwlock_init(&sap->sk_list.lock);
++ }
++ return sap;
++}
++
++/**
++ * llc_add_sap - add sap to station list
++ * @sap: Address of the sap
++ *
++ * Adds a sap to the LLC's station sap list.
++ */
++void llc_add_sap(struct llc_sap *sap)
++{
++ write_lock_bh(&llc_sap_list_lock);
++ list_add_tail(&sap->node, &llc_sap_list);
++ write_unlock_bh(&llc_sap_list_lock);
++}
++
++/**
++ * llc_del_sap - del sap from station list
++ * @sap: Address of the sap
++ *
++ * Removes a sap to the LLC's station sap list.
++ */
++void llc_del_sap(struct llc_sap *sap)
++{
++ write_lock_bh(&llc_sap_list_lock);
++ list_del(&sap->node);
++ write_unlock_bh(&llc_sap_list_lock);
++}
++
++/**
++ * llc_sap_find - searchs a SAP in station
++ * @sap_value: sap to be found
++ *
++ * Searchs for a sap in the sap list of the LLC's station upon the sap ID.
++ * Returns the sap or %NULL if not found.
++ */
++struct llc_sap *llc_sap_find(unsigned char sap_value)
++{
++ struct llc_sap* sap;
++
++ read_lock_bh(&llc_sap_list_lock);
++ list_for_each_entry(sap, &llc_sap_list, node)
++ if (sap->laddr.lsap == sap_value)
++ goto out;
++ sap = NULL;
++out:
++ read_unlock_bh(&llc_sap_list_lock);
++ return sap;
++}
++
++/**
++ * llc_sap_open - open interface to the upper layers.
++ * @lsap: SAP number.
++ * @func: rcv func for datalink protos
++ *
++ * Interface function to upper layer. Each one who wants to get a SAP
++ * (for example NetBEUI) should call this function. Returns the opened
++ * SAP for success, NULL for failure.
++ */
++struct llc_sap *llc_sap_open(unsigned char lsap,
++ int (*func)(struct sk_buff *skb,
++ struct net_device *dev,
++ struct packet_type *pt))
++{
++ struct llc_sap *sap = llc_sap_find(lsap);
++
++ if (sap) { /* SAP already exists */
++ sap = NULL;
++ goto out;
++ }
++ sap = llc_sap_alloc();
++ if (!sap)
++ goto out;
++ sap->laddr.lsap = lsap;
++ sap->rcv_func = func;
++ llc_add_sap(sap);
++out:
++ return sap;
++}
++
++/**
++ * llc_sap_close - close interface for upper layers.
++ * @sap: SAP to be closed.
++ *
++ * Close interface function to upper layer. Each one who wants to
++ * close an open SAP (for example NetBEUI) should call this function.
++ * Removes this sap from the list of saps in the station and then
++ * frees the memory for this sap.
++ */
++void llc_sap_close(struct llc_sap *sap)
++{
++ WARN_ON(!hlist_empty(&sap->sk_list.list));
++ llc_del_sap(sap);
++ kfree(sap);
++}
++
++static struct packet_type llc_packet_type = {
++ .type = __constant_htons(ETH_P_802_2),
++ .func = llc_rcv,
++ .data = (void *)1,
++};
++
++static struct packet_type llc_tr_packet_type = {
++ .type = __constant_htons(ETH_P_TR_802_2),
++ .func = llc_rcv,
++ .data = (void *)1,
++};
++
++static int __init llc_init(void)
++{
++ if (dev_base->next)
++ memcpy(llc_station_mac_sa, dev_base->next->dev_addr, ETH_ALEN);
++ else
++ memset(llc_station_mac_sa, 0, ETH_ALEN);
++ dev_add_pack(&llc_packet_type);
++ dev_add_pack(&llc_tr_packet_type);
++ return 0;
++}
++
++static void __exit llc_exit(void)
++{
++ dev_remove_pack(&llc_packet_type);
++ dev_remove_pack(&llc_tr_packet_type);
++}
++
++module_init(llc_init);
++module_exit(llc_exit);
++
++EXPORT_SYMBOL(llc_station_mac_sa);
++EXPORT_SYMBOL(llc_sap_list);
++EXPORT_SYMBOL(llc_sap_list_lock);
++EXPORT_SYMBOL(llc_sap_find);
++EXPORT_SYMBOL(llc_sap_open);
++EXPORT_SYMBOL(llc_sap_close);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Procom 1997, Jay Schullist 2001, Arnaldo C. Melo 2001-2003");
++MODULE_DESCRIPTION("LLC IEEE 802.2 core support");
+Index: linux-2.6.0-test5/net/llc/llc_if.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/llc/llc_if.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/llc/llc_if.c 2003-09-27 11:38:42.113126216 +0800
+@@ -25,136 +25,8 @@
+ #include <net/llc_c_ev.h>
+ #include <net/llc_c_ac.h>
+ #include <net/llc_c_st.h>
+-#include <net/llc_main.h>
+
+-/**
+- * llc_sap_open - open interface to the upper layers.
+- * @lsap: SAP number.
+- * @func: rcv func for datalink protos
+- *
+- * Interface function to upper layer. Each one who wants to get a SAP
+- * (for example NetBEUI) should call this function. Returns the opened
+- * SAP for success, NULL for failure.
+- */
+-struct llc_sap *llc_sap_open(u8 lsap, int (*func)(struct sk_buff *skb,
+- struct net_device *dev,
+- struct packet_type *pt))
+-{
+- /* verify this SAP is not already open; if so, return error */
+- struct llc_sap *sap;
+-
+- sap = llc_sap_find(lsap);
+- if (sap) { /* SAP already exists */
+- sap = NULL;
+- goto out;
+- }
+- /* sap requested does not yet exist */
+- sap = llc_sap_alloc();
+- if (!sap)
+- goto out;
+- /* allocated a SAP; initialize it and clear out its memory pool */
+- sap->laddr.lsap = lsap;
+- sap->rcv_func = func;
+- sap->station = &llc_main_station;
+- /* initialized SAP; add it to list of SAPs this station manages */
+- llc_sap_save(sap);
+-out:
+- return sap;
+-}
+-
+-/**
+- * llc_sap_close - close interface for upper layers.
+- * @sap: SAP to be closed.
+- *
+- * Close interface function to upper layer. Each one who wants to
+- * close an open SAP (for example NetBEUI) should call this function.
+- */
+-void llc_sap_close(struct llc_sap *sap)
+-{
+- llc_free_sap(sap);
+-}
+-
+-/**
+- * llc_build_and_send_ui_pkt - unitdata request interface for upper layers
+- * @sap: sap to use
+- * @skb: packet to send
+- * @dmac: destination mac address
+- * @dsap: destination sap
+- *
+- * Upper layers calls this function when upper layer wants to send data
+- * using connection-less mode communication (UI pdu).
+- *
+- * Accept data frame from network layer to be sent using connection-
+- * less mode communication; timeout/retries handled by network layer;
+- * package primitive as an event and send to SAP event handler
+- */
+-void llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb,
+- u8 *dmac, u8 dsap)
+-{
+- struct llc_sap_state_ev *ev = llc_sap_ev(skb);
+-
+- ev->saddr.lsap = sap->laddr.lsap;
+- ev->daddr.lsap = dsap;
+- memcpy(ev->saddr.mac, skb->dev->dev_addr, IFHWADDRLEN);
+- memcpy(ev->daddr.mac, dmac, IFHWADDRLEN);
+-
+- ev->type = LLC_SAP_EV_TYPE_PRIM;
+- ev->prim = LLC_DATAUNIT_PRIM;
+- ev->prim_type = LLC_PRIM_TYPE_REQ;
+- llc_sap_state_process(sap, skb);
+-}
+-
+-/**
+- * llc_build_and_send_test_pkt - TEST interface for upper layers.
+- * @sap: sap to use
+- * @skb: packet to send
+- * @dmac: destination mac address
+- * @dsap: destination sap
+- *
+- * This function is called when upper layer wants to send a TEST pdu.
+- * Returns 0 for success, 1 otherwise.
+- */
+-void llc_build_and_send_test_pkt(struct llc_sap *sap,
+- struct sk_buff *skb, u8 *dmac, u8 dsap)
+-{
+- struct llc_sap_state_ev *ev = llc_sap_ev(skb);
+-
+- ev->saddr.lsap = sap->laddr.lsap;
+- ev->daddr.lsap = dsap;
+- memcpy(ev->saddr.mac, skb->dev->dev_addr, IFHWADDRLEN);
+- memcpy(ev->daddr.mac, dmac, IFHWADDRLEN);
+-
+- ev->type = LLC_SAP_EV_TYPE_PRIM;
+- ev->prim = LLC_TEST_PRIM;
+- ev->prim_type = LLC_PRIM_TYPE_REQ;
+- llc_sap_state_process(sap, skb);
+-}
+-
+-/**
+- * llc_build_and_send_xid_pkt - XID interface for upper layers
+- * @sap: sap to use
+- * @skb: packet to send
+- * @dmac: destination mac address
+- * @dsap: destination sap
+- *
+- * This function is called when upper layer wants to send a XID pdu.
+- * Returns 0 for success, 1 otherwise.
+- */
+-void llc_build_and_send_xid_pkt(struct llc_sap *sap, struct sk_buff *skb,
+- u8 *dmac, u8 dsap)
+-{
+- struct llc_sap_state_ev *ev = llc_sap_ev(skb);
+-
+- ev->saddr.lsap = sap->laddr.lsap;
+- ev->daddr.lsap = dsap;
+- memcpy(ev->saddr.mac, skb->dev->dev_addr, IFHWADDRLEN);
+- memcpy(ev->daddr.mac, dmac, IFHWADDRLEN);
+-
+- ev->type = LLC_SAP_EV_TYPE_PRIM;
+- ev->prim = LLC_XID_PRIM;
+- ev->prim_type = LLC_PRIM_TYPE_REQ;
+- llc_sap_state_process(sap, skb);
+-}
++u8 llc_mac_null_var[IFHWADDRLEN];
+
+ /**
+ * llc_build_and_send_pkt - Connection data sending for upper layers.
+@@ -307,7 +179,3 @@
+ }
+ return rc;
+ }
+-
+-EXPORT_SYMBOL(llc_sap_open);
+-EXPORT_SYMBOL(llc_sap_close);
+-EXPORT_SYMBOL(llc_build_and_send_ui_pkt);
+Index: linux-2.6.0-test5/net/llc/llc_input.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/llc/llc_input.c 2003-09-27 11:38:18.493716912 +0800
++++ linux-2.6.0-test5/net/llc/llc_input.c 2003-09-27 11:38:42.114126064 +0800
+@@ -0,0 +1,189 @@
++/*
++ * llc_input.c - Minimal input path for LLC
++ *
++ * Copyright (c) 1997 by Procom Technology, Inc.
++ * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
++ *
++ * This program can be redistributed or modified under the terms of the
++ * GNU General Public License as published by the Free Software Foundation.
++ * This program is distributed without any warranty or implied warranty
++ * of merchantability or fitness for a particular purpose.
++ *
++ * See the GNU General Public License for more details.
++ */
++#include <linux/netdevice.h>
++#include <net/llc.h>
++#include <net/llc_pdu.h>
++#include <net/llc_sap.h>
++
++#if 0
++#define dprintk(args...) printk(KERN_DEBUG args)
++#else
++#define dprintk(args...)
++#endif
++
++/*
++ * Packet handler for the station, registerable because in the minimal
++ * LLC core that is taking shape only the very minimal subset of LLC that
++ * is needed for things like IPX, Appletalk, etc will stay, with all the
++ * rest in the llc1 and llc2 modules.
++ */
++static void (*llc_station_handler)(struct sk_buff *skb);
++
++/*
++ * Packet handlers for LLC_DEST_SAP and LLC_DEST_CONN.
++ */
++static void (*llc_type_handlers[2])(struct llc_sap *sap,
++ struct sk_buff *skb);
++
++void llc_add_pack(int type, void (*handler)(struct llc_sap *sap,
++ struct sk_buff *skb))
++{
++ if (type == LLC_DEST_SAP || type == LLC_DEST_CONN)
++ llc_type_handlers[type] = handler;
++}
++
++void llc_remove_pack(int type)
++{
++ if (type == LLC_DEST_SAP || type == LLC_DEST_CONN)
++ llc_type_handlers[type] = NULL;
++}
++
++void llc_set_station_handler(void (*handler)(struct sk_buff *skb))
++{
++ llc_station_handler = handler;
++}
++
++/**
++ * llc_pdu_type - returns which LLC component must handle for PDU
++ * @skb: input skb
++ *
++ * This function returns which LLC component must handle this PDU.
++ */
++static __inline__ int llc_pdu_type(struct sk_buff *skb)
++{
++ int type = LLC_DEST_CONN; /* I-PDU or S-PDU type */
++ struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
++
++ if ((pdu->ctrl_1 & LLC_PDU_TYPE_MASK) != LLC_PDU_TYPE_U)
++ goto out;
++ switch (LLC_U_PDU_CMD(pdu)) {
++ case LLC_1_PDU_CMD_XID:
++ case LLC_1_PDU_CMD_UI:
++ case LLC_1_PDU_CMD_TEST:
++ type = LLC_DEST_SAP;
++ break;
++ case LLC_2_PDU_CMD_SABME:
++ case LLC_2_PDU_CMD_DISC:
++ case LLC_2_PDU_RSP_UA:
++ case LLC_2_PDU_RSP_DM:
++ case LLC_2_PDU_RSP_FRMR:
++ break;
++ default:
++ type = LLC_DEST_INVALID;
++ break;
++ }
++out:
++ return type;
++}
++
++/**
++ * llc_fixup_skb - initializes skb pointers
++ * @skb: This argument points to incoming skb
++ *
++ * Initializes internal skb pointer to start of network layer by deriving
++ * length of LLC header; finds length of LLC control field in LLC header
++ * by looking at the two lowest-order bits of the first control field
++ * byte; field is either 3 or 4 bytes long.
++ */
++static inline int llc_fixup_skb(struct sk_buff *skb)
++{
++ u8 llc_len = 2;
++ struct llc_pdu_sn *pdu;
++
++ if (!pskb_may_pull(skb, sizeof(*pdu)))
++ return 0;
++
++ pdu = (struct llc_pdu_sn *)skb->data;
++ if ((pdu->ctrl_1 & LLC_PDU_TYPE_MASK) == LLC_PDU_TYPE_U)
++ llc_len = 1;
++ llc_len += 2;
++ skb->h.raw += llc_len;
++ skb_pull(skb, llc_len);
++ if (skb->protocol == htons(ETH_P_802_2)) {
++ u16 pdulen = ((struct ethhdr *)skb->mac.raw)->h_proto,
++ data_size = ntohs(pdulen) - llc_len;
++
++ skb_trim(skb, data_size);
++ }
++ return 1;
++}
++
++/**
++ * llc_rcv - 802.2 entry point from net lower layers
++ * @skb: received pdu
++ * @dev: device that receive pdu
++ * @pt: packet type
++ *
++ * When the system receives a 802.2 frame this function is called. It
++ * checks SAP and connection of received pdu and passes frame to
++ * llc_{station,sap,conn}_rcv for sending to proper state machine. If
++ * the frame is related to a busy connection (a connection is sending
++ * data now), it queues this frame in the connection's backlog.
++ */
++int llc_rcv(struct sk_buff *skb, struct net_device *dev,
++ struct packet_type *pt)
++{
++ struct llc_sap *sap;
++ struct llc_pdu_sn *pdu;
++ int dest;
++
++ /*
++ * When the interface is in promisc. mode, drop all the crap that it
++ * receives, do not try to analyse it.
++ */
++ if (unlikely(skb->pkt_type == PACKET_OTHERHOST)) {
++ dprintk("%s: PACKET_OTHERHOST\n", __FUNCTION__);
++ goto drop;
++ }
++ skb = skb_share_check(skb, GFP_ATOMIC);
++ if (unlikely(!skb))
++ goto out;
++ if (unlikely(!llc_fixup_skb(skb)))
++ goto drop;
++ pdu = llc_pdu_sn_hdr(skb);
++ if (unlikely(!pdu->dsap)) /* NULL DSAP, refer to station */
++ goto handle_station;
++ sap = llc_sap_find(pdu->dsap);
++ if (unlikely(!sap)) {/* unknown SAP */
++ dprintk("%s: llc_sap_find(%02X) failed!\n", __FUNCTION__,
++ pdu->dsap);
++ goto drop;
++ }
++ /*
++ * First the upper layer protocols that don't need the full
++ * LLC functionality
++ */
++ if (sap->rcv_func) {
++ sap->rcv_func(skb, dev, pt);
++ goto out;
++ }
++ dest = llc_pdu_type(skb);
++ if (unlikely(!dest || !llc_type_handlers[dest - 1]))
++ goto drop;
++ llc_type_handlers[dest - 1](sap, skb);
++out:
++ return 0;
++drop:
++ kfree_skb(skb);
++ goto out;
++handle_station:
++ if (!llc_station_handler)
++ goto drop;
++ llc_station_handler(skb);
++ goto out;
++}
++
++EXPORT_SYMBOL(llc_add_pack);
++EXPORT_SYMBOL(llc_remove_pack);
++EXPORT_SYMBOL(llc_set_station_handler);
+Index: linux-2.6.0-test5/net/llc/llc_output.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/llc/llc_output.c 2003-09-27 11:38:18.493716912 +0800
++++ linux-2.6.0-test5/net/llc/llc_output.c 2003-09-27 11:38:42.114126064 +0800
+@@ -0,0 +1,105 @@
++/*
++ * llc_output.c - LLC minimal output path
++ *
++ * Copyright (c) 1997 by Procom Technology, Inc.
++ * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
++ *
++ * This program can be redistributed or modified under the terms of the
++ * GNU General Public License version 2 as published by the Free Software
++ * Foundation.
++ * This program is distributed without any warranty or implied warranty
++ * of merchantability or fitness for a particular purpose.
++ *
++ * See the GNU General Public License version 2 for more details.
++ */
++
++#include <linux/if_arp.h>
++#include <linux/if_tr.h>
++#include <linux/netdevice.h>
++#include <linux/skbuff.h>
++#include <net/llc.h>
++#include <net/llc_pdu.h>
++
++/**
++ * llc_mac_hdr_init - fills MAC header fields
++ * @skb: Address of the frame to initialize its MAC header
++ * @sa: The MAC source address
++ * @da: The MAC destination address
++ *
++ * Fills MAC header fields, depending on MAC type. Returns 0, If MAC type
++ * is a valid type and initialization completes correctly 1, otherwise.
++ */
++int llc_mac_hdr_init(struct sk_buff *skb, unsigned char *sa, unsigned char *da)
++{
++ int rc = 0;
++
++ switch (skb->dev->type) {
++#ifdef CONFIG_TR
++ case ARPHRD_IEEE802_TR: {
++ struct net_device *dev = skb->dev;
++ struct trh_hdr *trh;
++
++ trh = (struct trh_hdr *)skb_push(skb, sizeof(*trh));
++ trh->ac = AC;
++ trh->fc = LLC_FRAME;
++ if (sa)
++ memcpy(trh->saddr, sa, dev->addr_len);
++ else
++ memset(trh->saddr, 0, dev->addr_len);
++ if (da) {
++ memcpy(trh->daddr, da, dev->addr_len);
++ tr_source_route(skb, trh, dev);
++ }
++ skb->mac.raw = skb->data;
++ break;
++ }
++#endif
++ case ARPHRD_ETHER:
++ case ARPHRD_LOOPBACK: {
++ unsigned short len = skb->len;
++ struct ethhdr *eth;
++
++ skb->mac.raw = skb_push(skb, sizeof(*eth));
++ eth = (struct ethhdr *)skb->mac.raw;
++ eth->h_proto = htons(len);
++ memcpy(eth->h_dest, da, ETH_ALEN);
++ memcpy(eth->h_source, sa, ETH_ALEN);
++ break;
++ }
++ default:
++ printk(KERN_WARNING "device type not supported: %d\n",
++ skb->dev->type);
++ rc = -EINVAL;
++ }
++ return rc;
++}
++
++/**
++ * llc_build_and_send_ui_pkt - unitdata request interface for upper layers
++ * @sap: sap to use
++ * @skb: packet to send
++ * @dmac: destination mac address
++ * @dsap: destination sap
++ *
++ * Upper layers calls this function when upper layer wants to send data
++ * using connection-less mode communication (UI pdu).
++ *
++ * Accept data frame from network layer to be sent using connection-
++ * less mode communication; timeout/retries handled by network layer;
++ * package primitive as an event and send to SAP event handler
++ */
++int llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb,
++ unsigned char *dmac, unsigned char dsap)
++{
++ int rc;
++ llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap,
++ dsap, LLC_PDU_CMD);
++ llc_pdu_init_as_ui_cmd(skb);
++ rc = llc_mac_hdr_init(skb, skb->dev->dev_addr, dmac);
++ if (!rc)
++ rc = dev_queue_xmit(skb);
++ return rc;
++}
++
++EXPORT_SYMBOL(llc_mac_hdr_init);
++EXPORT_SYMBOL(llc_build_and_send_ui_pkt);
+Index: linux-2.6.0-test5/net/llc/llc_output.h
+===================================================================
+--- linux-2.6.0-test5.orig/net/llc/llc_output.h 2003-09-27 11:38:18.493716912 +0800
++++ linux-2.6.0-test5/net/llc/llc_output.h 2003-09-27 11:38:42.115125912 +0800
+@@ -0,0 +1,20 @@
++#ifndef LLC_OUTPUT_H
++#define LLC_OUTPUT_H
++/*
++ * Copyright (c) 1997 by Procom Technology, Inc.
++ * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
++ *
++ * This program can be redistributed or modified under the terms of the
++ * GNU General Public License version 2 as published by the Free Software
++ * Foundation.
++ * This program is distributed without any warranty or implied warranty
++ * of merchantability or fitness for a particular purpose.
++ *
++ * See the GNU General Public License version 2 for more details.
++ */
++
++struct sk_buff;
++
++int llc_mac_hdr_init(struct sk_buff *skb, unsigned char *sa, unsigned char *da);
++
++#endif /* LLC_OUTPUT_H */
+Index: linux-2.6.0-test5/net/llc/llc_pdu.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/llc/llc_pdu.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/llc/llc_pdu.c 2003-09-27 11:38:42.120125152 +0800
+@@ -11,35 +11,13 @@
+ *
+ * See the GNU General Public License for more details.
+ */
++
+ #include <linux/netdevice.h>
+-#include <linux/if_tr.h>
+ #include <net/llc_pdu.h>
+-#include <net/llc_if.h>
+-#include <net/llc_main.h>
+
+ static void llc_pdu_decode_pdu_type(struct sk_buff *skb, u8 *type);
+-static __inline__ int llc_get_hdr_len(u8 pdu_type);
+ static u8 llc_pdu_get_pf_bit(struct llc_pdu_sn *pdu);
+
+-/**
+- * llc_pdu_header_init - initializes pdu header
+- * @skb: input skb that header must be set into it.
+- * @type: type of PDU (U, I or S).
+- * @ssap: source sap.
+- * @dsap: destination sap.
+- * @cr: command/response bit (0 or 1).
+- *
+- * This function sets DSAP, SSAP and command/Response bit in LLC header.
+- */
+-void llc_pdu_header_init(struct sk_buff *skb, u8 type, u8 ssap, u8 dsap, u8 cr)
+-{
+- struct llc_pdu_un *pdu =
+- llc_set_pdu_hdr(skb, skb_push(skb, llc_get_hdr_len(type)));
+- pdu->dsap = dsap;
+- pdu->ssap = ssap;
+- pdu->ssap |= cr;
+-}
+-
+ void llc_pdu_set_cmd_rsp(struct sk_buff *skb, u8 pdu_type)
+ {
+ llc_pdu_un_hdr(skb)->ssap |= pdu_type;
+@@ -115,114 +93,6 @@
+ }
+
+ /**
+- * llc_pdu_decode_sa - extracs source address (MAC) of input frame
+- * @skb: input skb that source address must be extracted from it.
+- * @sa: pointer to source address (6 byte array).
+- *
+- * This function extracts source address(MAC) of input frame.
+- */
+-void llc_pdu_decode_sa(struct sk_buff *skb, u8 *sa)
+-{
+- if (skb->protocol == ntohs(ETH_P_802_2))
+- memcpy(sa, ((struct ethhdr *)skb->mac.raw)->h_source, ETH_ALEN);
+- else if (skb->protocol == ntohs(ETH_P_TR_802_2))
+- memcpy(sa, ((struct trh_hdr *)skb->mac.raw)->saddr, ETH_ALEN);
+-}
+-
+-/**
+- * llc_pdu_decode_da - extracts dest address of input frame
+- * @skb: input skb that destination address must be extracted from it
+- * @sa: pointer to destination address (6 byte array).
+- *
+- * This function extracts destination address(MAC) of input frame.
+- */
+-void llc_pdu_decode_da(struct sk_buff *skb, u8 *da)
+-{
+- if (skb->protocol == ntohs(ETH_P_802_2))
+- memcpy(da, ((struct ethhdr *)skb->mac.raw)->h_dest, ETH_ALEN);
+- else if (skb->protocol == ntohs(ETH_P_TR_802_2))
+- memcpy(da, ((struct trh_hdr *)skb->mac.raw)->daddr, ETH_ALEN);
+-}
+-
+-/**
+- * llc_pdu_decode_dsap - extracts dest SAP of input frame
+- * @skb: input skb that destination SAP must be extracted from it.
+- * @dsap: destination SAP (output argument).
+- *
+- * This function extracts destination SAP of input frame. right bit of
+- * DSAP designates individual/group SAP.
+- */
+-void llc_pdu_decode_dsap(struct sk_buff *skb, u8 *dsap)
+-{
+- *dsap = llc_pdu_un_hdr(skb)->dsap & 0xFE;
+-}
+-
+-/**
+- * llc_pdu_decode_ssap - extracts source SAP of input frame
+- * @skb: input skb that source SAP must be extracted from it.
+- * @ssap: source SAP (output argument).
+- *
+- * This function extracts source SAP of input frame. Right bit of SSAP is
+- * command/response bit.
+- */
+-void llc_pdu_decode_ssap(struct sk_buff *skb, u8 *ssap)
+-{
+- *ssap = llc_pdu_un_hdr(skb)->ssap & 0xFE;
+-}
+-
+-/**
+- * llc_pdu_init_as_ui_cmd - sets LLC header as UI PDU
+- * @skb: input skb that header must be set into it.
+- *
+- * This function sets third byte of LLC header as a UI PDU.
+- */
+-void llc_pdu_init_as_ui_cmd(struct sk_buff *skb)
+-{
+- struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
+-
+- pdu->ctrl_1 = LLC_PDU_TYPE_U;
+- pdu->ctrl_1 |= LLC_1_PDU_CMD_UI;
+-}
+-
+-/**
+- * llc_pdu_init_as_xid_cmd - sets bytes 3, 4 & 5 of LLC header as XID
+- * @skb: input skb that header must be set into it.
+- *
+- * This function sets third,fourth,fifth and sixth bytes of LLC header as
+- * a XID PDU.
+- */
+-void llc_pdu_init_as_xid_cmd(struct sk_buff *skb, u8 svcs_supported,
+- u8 rx_window)
+-{
+- struct llc_xid_info *xid_info;
+- struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
+-
+- pdu->ctrl_1 = LLC_PDU_TYPE_U;
+- pdu->ctrl_1 |= LLC_1_PDU_CMD_XID;
+- pdu->ctrl_1 |= LLC_U_PF_BIT_MASK;
+- xid_info = (struct llc_xid_info *)(((u8 *)&pdu->ctrl_1) + 1);
+- xid_info->fmt_id = LLC_XID_FMT_ID; /* 0x81 */
+- xid_info->type = svcs_supported;
+- xid_info->rw = rx_window << 1; /* size of receive window */
+- skb_put(skb, 3);
+-}
+-
+-/**
+- * llc_pdu_init_as_test_cmd - sets PDU as TEST
+- * @skb - Address of the skb to build
+- *
+- * Sets a PDU as TEST
+- */
+-void llc_pdu_init_as_test_cmd(struct sk_buff *skb)
+-{
+- struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
+-
+- pdu->ctrl_1 = LLC_PDU_TYPE_U;
+- pdu->ctrl_1 |= LLC_1_PDU_CMD_TEST;
+- pdu->ctrl_1 |= LLC_U_PF_BIT_MASK;
+-}
+-
+-/**
+ * llc_pdu_init_as_disc_cmd - Builds DISC PDU
+ * @skb: Address of the skb to build
+ * @p_bit: The P bit to set in the PDU
+@@ -350,55 +220,6 @@
+ }
+
+ /**
+- * llc_pdu_init_as_xid_rsp - builds XID response PDU
+- * @skb: Address of the skb to build
+- * @svcs_supported: The class of the LLC (I or II)
+- * @rx_window: The size of the receive window of the LLC
+- *
+- * Builds a pdu frame as an XID response.
+- */
+-void llc_pdu_init_as_xid_rsp(struct sk_buff *skb, u8 svcs_supported,
+- u8 rx_window)
+-{
+- struct llc_xid_info *xid_info;
+- struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
+-
+- pdu->ctrl_1 = LLC_PDU_TYPE_U;
+- pdu->ctrl_1 |= LLC_1_PDU_CMD_XID;
+- pdu->ctrl_1 |= LLC_U_PF_BIT_MASK;
+-
+- xid_info = (struct llc_xid_info *)(((u8 *)&pdu->ctrl_1) + 1);
+- xid_info->fmt_id = LLC_XID_FMT_ID;
+- xid_info->type = svcs_supported;
+- xid_info->rw = rx_window << 1;
+- skb_put(skb, 3);
+-}
+-
+-/**
+- * llc_pdu_init_as_test_rsp - build TEST response PDU
+- * @skb: Address of the skb to build
+- * @ev_skb: The received TEST command PDU frame
+- *
+- * Builds a pdu frame as a TEST response.
+- */
+-void llc_pdu_init_as_test_rsp(struct sk_buff *skb, struct sk_buff *ev_skb)
+-{
+- int dsize;
+- struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
+-
+- pdu->ctrl_1 = LLC_PDU_TYPE_U;
+- pdu->ctrl_1 |= LLC_1_PDU_CMD_TEST;
+- pdu->ctrl_1 |= LLC_U_PF_BIT_MASK;
+- if (ev_skb->protocol == ntohs(ETH_P_802_2)) {
+- struct llc_pdu_un *ev_pdu = llc_pdu_un_hdr(ev_skb);
+-
+- dsize = ntohs(((struct ethhdr *)ev_skb->mac.raw)->h_proto) - 3;
+- memcpy(((u8 *)pdu) + 3, ((u8 *)ev_pdu) + 3, dsize);
+- skb_put(skb, dsize);
+- }
+-}
+-
+-/**
+ * llc_pdu_init_as_frmr_rsp - builds FRMR response PDU
+ * @skb: Address of the frame to build
+ * @prev_pdu: The rejected PDU frame
+@@ -533,58 +354,6 @@
+ }
+
+ /**
+- * llc_decode_pdu_type - designates component LLC must handle for PDU
+- * @skb: input skb
+- * @dest: destination component
+- *
+- * This function designates which component of LLC must handle this PDU.
+- */
+-void llc_decode_pdu_type(struct sk_buff *skb, u8 *dest)
+-{
+- u8 type = LLC_DEST_CONN; /* I-PDU or S-PDU type */
+- struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+-
+- if ((pdu->ctrl_1 & LLC_PDU_TYPE_MASK) != LLC_PDU_TYPE_U)
+- goto out;
+- switch (LLC_U_PDU_CMD(pdu)) {
+- case LLC_1_PDU_CMD_XID:
+- case LLC_1_PDU_CMD_UI:
+- case LLC_1_PDU_CMD_TEST:
+- type = LLC_DEST_SAP;
+- break;
+- case LLC_2_PDU_CMD_SABME:
+- case LLC_2_PDU_CMD_DISC:
+- case LLC_2_PDU_RSP_UA:
+- case LLC_2_PDU_RSP_DM:
+- case LLC_2_PDU_RSP_FRMR:
+- break;
+- default:
+- type = LLC_DEST_INVALID;
+- break;
+- }
+-out:
+- *dest = type;
+-}
+-
+-/**
+- * llc_get_hdr_len - designates LLC header length
+- * @type: type of PDU.
+- *
+- * This function designates LLC header length of PDU. header length for I
+- * and S PDU is 4 and for U is 3 bytes. Returns the length of header.
+- */
+-static __inline__ int llc_get_hdr_len(u8 type)
+-{
+- static int hdr_len[] = {
+- [LLC_PDU_TYPE_U] = 3,
+- [LLC_PDU_TYPE_I] = 4,
+- [LLC_PDU_TYPE_S] = 4,
+- };
+-
+- return hdr_len[type];
+-}
+-
+-/**
+ * llc_pdu_get_pf_bit - extracts p/f bit of input PDU
+ * @pdu: pointer to LLC header.
+ *
+Index: linux-2.6.0-test5/net/llc/llc_proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/llc/llc_proc.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/llc/llc_proc.c 2003-09-27 11:38:42.123124696 +0800
+@@ -20,13 +20,11 @@
+ #include <linux/errno.h>
+ #include <linux/seq_file.h>
+ #include <net/sock.h>
++#include <net/llc.h>
+ #include <net/llc_c_ac.h>
+ #include <net/llc_c_ev.h>
+ #include <net/llc_c_st.h>
+ #include <net/llc_conn.h>
+-#include <net/llc_mac.h>
+-#include <net/llc_main.h>
+-#include <net/llc_sap.h>
+
+ static void llc_ui_format_mac(struct seq_file *seq, unsigned char *mac)
+ {
+@@ -41,7 +39,7 @@
+ struct hlist_node *node;
+ struct sock *sk = NULL;
+
+- list_for_each(sap_entry, &llc_main_station.sap_list.list) {
++ list_for_each(sap_entry, &llc_sap_list) {
+ sap = list_entry(sap_entry, struct llc_sap, node);
+
+ read_lock_bh(&sap->sk_list.lock);
+@@ -66,8 +64,8 @@
+ {
+ loff_t l = *pos;
+
+- read_lock_bh(&llc_main_station.sap_list.lock);
+- return l ? llc_get_sk_idx(--l) : (void *)1;
++ read_lock_bh(&llc_sap_list_lock);
++ return l ? llc_get_sk_idx(--l) : SEQ_START_TOKEN;
+ }
+
+ static void *llc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -77,7 +75,7 @@
+ struct llc_sap *sap;
+
+ ++*pos;
+- if (v == (void *)1) {
++ if (v == SEQ_START_TOKEN) {
+ sk = llc_get_sk_idx(0);
+ goto out;
+ }
+@@ -92,7 +90,7 @@
+ read_unlock_bh(&sap->sk_list.lock);
+ sk = NULL;
+ for (;;) {
+- if (sap->node.next == &llc_main_station.sap_list.list)
++ if (sap->node.next == &llc_sap_list)
+ break;
+ sap = list_entry(sap->node.next, struct llc_sap, node);
+ read_lock_bh(&sap->sk_list.lock);
+@@ -115,7 +113,7 @@
+
+ read_unlock_bh(&sap->sk_list.lock);
+ }
+- read_unlock_bh(&llc_main_station.sap_list.lock);
++ read_unlock_bh(&llc_sap_list_lock);
+ }
+
+ static int llc_seq_socket_show(struct seq_file *seq, void *v)
+@@ -123,7 +121,7 @@
+ struct sock* sk;
+ struct llc_opt *llc;
+
+- if (v == (void *)1) {
++ if (v == SEQ_START_TOKEN) {
+ seq_puts(seq, "SKt Mc local_mac_sap remote_mac_sap "
+ " tx_queue rx_queue st uid link\n");
+ goto out;
+@@ -172,7 +170,7 @@
+ struct sock* sk;
+ struct llc_opt *llc;
+
+- if (v == (void *)1) {
++ if (v == SEQ_START_TOKEN) {
+ seq_puts(seq, "Connection list:\n"
+ "dsap state retr txw rxw pf ff sf df rs cs "
+ "tack tpfc trs tbs blog busr\n");
+Index: linux-2.6.0-test5/net/llc/llc_s_ac.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/llc/llc_s_ac.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/llc/llc_s_ac.c 2003-09-27 11:38:42.125124392 +0800
+@@ -17,13 +17,14 @@
+ *
+ * See the GNU General Public License for more details.
+ */
++
+ #include <linux/netdevice.h>
+-#include <net/llc_if.h>
+-#include <net/llc_sap.h>
+-#include <net/llc_main.h>
+-#include <net/llc_s_ev.h>
++#include <net/llc.h>
+ #include <net/llc_pdu.h>
+-#include <net/llc_mac.h>
++#include <net/llc_s_ac.h>
++#include <net/llc_s_ev.h>
++#include <net/llc_sap.h>
++#include "llc_output.h"
+
+ /**
+ * llc_sap_action_unit_data_ind - forward UI PDU to network layer
+@@ -56,7 +57,7 @@
+ llc_pdu_header_init(skb, LLC_PDU_TYPE_U, ev->saddr.lsap,
+ ev->daddr.lsap, LLC_PDU_CMD);
+ llc_pdu_init_as_ui_cmd(skb);
+- rc = lan_hdrs_init(skb, ev->saddr.mac, ev->daddr.mac);
++ rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac);
+ if (!rc)
+ rc = dev_queue_xmit(skb);
+ return rc;
+@@ -79,7 +80,7 @@
+ llc_pdu_header_init(skb, LLC_PDU_TYPE_U, ev->saddr.lsap,
+ ev->daddr.lsap, LLC_PDU_CMD);
+ llc_pdu_init_as_xid_cmd(skb, LLC_XID_NULL_CLASS_2, 0);
+- rc = lan_hdrs_init(skb, ev->saddr.mac, ev->daddr.mac);
++ rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac);
+ if (!rc)
+ rc = dev_queue_xmit(skb);
+ return rc;
+@@ -109,7 +110,7 @@
+ llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap,
+ LLC_PDU_RSP);
+ llc_pdu_init_as_xid_rsp(nskb, LLC_XID_NULL_CLASS_2, 0);
+- rc = lan_hdrs_init(nskb, mac_sa, mac_da);
++ rc = llc_mac_hdr_init(nskb, mac_sa, mac_da);
+ if (!rc)
+ rc = dev_queue_xmit(nskb);
+ out:
+@@ -133,7 +134,7 @@
+ llc_pdu_header_init(skb, LLC_PDU_TYPE_U, ev->saddr.lsap,
+ ev->daddr.lsap, LLC_PDU_CMD);
+ llc_pdu_init_as_test_cmd(skb);
+- rc = lan_hdrs_init(skb, ev->saddr.mac, ev->daddr.mac);
++ rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac);
+ if (!rc)
+ rc = dev_queue_xmit(skb);
+ return rc;
+@@ -155,7 +156,7 @@
+ llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap,
+ LLC_PDU_RSP);
+ llc_pdu_init_as_test_rsp(nskb, skb);
+- rc = lan_hdrs_init(nskb, mac_sa, mac_da);
++ rc = llc_mac_hdr_init(nskb, mac_sa, mac_da);
+ if (!rc)
+ rc = dev_queue_xmit(nskb);
+ out:
+Index: linux-2.6.0-test5/net/llc/llc_sap.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/llc/llc_sap.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/llc/llc_sap.c 2003-09-27 11:38:42.128123936 +0800
+@@ -11,46 +11,53 @@
+ *
+ * See the GNU General Public License for more details.
+ */
+-#include <linux/skbuff.h>
++
++#include <net/llc.h>
++#include <net/llc_if.h>
+ #include <net/llc_conn.h>
++#include <net/llc_pdu.h>
+ #include <net/llc_sap.h>
+-#include <net/llc_s_ev.h>
+ #include <net/llc_s_ac.h>
++#include <net/llc_s_ev.h>
+ #include <net/llc_s_st.h>
+ #include <net/sock.h>
+ #include <linux/tcp.h>
+-#include <net/llc_main.h>
+-#include <net/llc_pdu.h>
+-#include <linux/if_tr.h>
++#include <linux/llc.h>
+
+ /**
+- * llc_sap_assign_sock - adds a connection to a SAP
+- * @sap: pointer to SAP.
+- * @conn: pointer to connection.
++ * llc_alloc_frame - allocates sk_buff for frame
+ *
+- * This function adds a connection to connection_list of a SAP.
++ * Allocates an sk_buff for frame and initializes sk_buff fields.
++ * Returns allocated skb or %NULL when out of memory.
+ */
+-void llc_sap_assign_sock(struct llc_sap *sap, struct sock *sk)
++struct sk_buff *llc_alloc_frame(void)
+ {
+- write_lock_bh(&sap->sk_list.lock);
+- llc_sk(sk)->sap = sap;
+- sk_add_node(sk, &sap->sk_list.list);
+- write_unlock_bh(&sap->sk_list.lock);
++ struct sk_buff *skb = alloc_skb(128, GFP_ATOMIC);
++
++ if (skb) {
++ skb_reserve(skb, 50);
++ skb->nh.raw = skb->h.raw = skb->data;
++ skb->protocol = htons(ETH_P_802_2);
++ skb->dev = dev_base->next;
++ skb->mac.raw = skb->head;
++ }
++ return skb;
+ }
+
+-/**
+- * llc_sap_unassign_sock - removes a connection from SAP
+- * @sap: SAP
+- * @sk: pointer to connection
+- *
+- * This function removes a connection from sk_list.list of a SAP if
+- * the connection was in this list.
+- */
+-void llc_sap_unassign_sock(struct llc_sap *sap, struct sock *sk)
++void llc_save_primitive(struct sk_buff* skb, u8 prim)
+ {
+- write_lock_bh(&sap->sk_list.lock);
+- sk_del_node_init(sk);
+- write_unlock_bh(&sap->sk_list.lock);
++ struct sockaddr_llc *addr = llc_ui_skb_cb(skb);
++
++ /* save primitive for use by the user. */
++ addr->sllc_family = skb->sk->sk_family;
++ addr->sllc_arphrd = skb->dev->type;
++ addr->sllc_test = prim == LLC_TEST_PRIM;
++ addr->sllc_xid = prim == LLC_XID_PRIM;
++ addr->sllc_ua = prim == LLC_DATAUNIT_PRIM;
++ llc_pdu_decode_sa(skb, addr->sllc_smac);
++ llc_pdu_decode_da(skb, addr->sllc_dmac);
++ llc_pdu_decode_dsap(skb, &addr->sllc_dsap);
++ llc_pdu_decode_ssap(skb, &addr->sllc_ssap);
+ }
+
+ /**
+@@ -193,3 +200,118 @@
+ }
+ kfree_skb(skb);
+ }
++
++/**
++ * llc_build_and_send_test_pkt - TEST interface for upper layers.
++ * @sap: sap to use
++ * @skb: packet to send
++ * @dmac: destination mac address
++ * @dsap: destination sap
++ *
++ * This function is called when upper layer wants to send a TEST pdu.
++ * Returns 0 for success, 1 otherwise.
++ */
++void llc_build_and_send_test_pkt(struct llc_sap *sap,
++ struct sk_buff *skb, u8 *dmac, u8 dsap)
++{
++ struct llc_sap_state_ev *ev = llc_sap_ev(skb);
++
++ ev->saddr.lsap = sap->laddr.lsap;
++ ev->daddr.lsap = dsap;
++ memcpy(ev->saddr.mac, skb->dev->dev_addr, IFHWADDRLEN);
++ memcpy(ev->daddr.mac, dmac, IFHWADDRLEN);
++
++ ev->type = LLC_SAP_EV_TYPE_PRIM;
++ ev->prim = LLC_TEST_PRIM;
++ ev->prim_type = LLC_PRIM_TYPE_REQ;
++ llc_sap_state_process(sap, skb);
++}
++
++/**
++ * llc_build_and_send_xid_pkt - XID interface for upper layers
++ * @sap: sap to use
++ * @skb: packet to send
++ * @dmac: destination mac address
++ * @dsap: destination sap
++ *
++ * This function is called when upper layer wants to send a XID pdu.
++ * Returns 0 for success, 1 otherwise.
++ */
++void llc_build_and_send_xid_pkt(struct llc_sap *sap, struct sk_buff *skb,
++ u8 *dmac, u8 dsap)
++{
++ struct llc_sap_state_ev *ev = llc_sap_ev(skb);
++
++ ev->saddr.lsap = sap->laddr.lsap;
++ ev->daddr.lsap = dsap;
++ memcpy(ev->saddr.mac, skb->dev->dev_addr, IFHWADDRLEN);
++ memcpy(ev->daddr.mac, dmac, IFHWADDRLEN);
++
++ ev->type = LLC_SAP_EV_TYPE_PRIM;
++ ev->prim = LLC_XID_PRIM;
++ ev->prim_type = LLC_PRIM_TYPE_REQ;
++ llc_sap_state_process(sap, skb);
++}
++
++/**
++ * llc_sap_rcv - sends received pdus to the sap state machine
++ * @sap: current sap component structure.
++ * @skb: received frame.
++ *
++ * Sends received pdus to the sap state machine.
++ */
++static void llc_sap_rcv(struct llc_sap *sap, struct sk_buff *skb)
++{
++ struct llc_sap_state_ev *ev = llc_sap_ev(skb);
++
++ ev->type = LLC_SAP_EV_TYPE_PDU;
++ ev->reason = 0;
++ llc_sap_state_process(sap, skb);
++}
++
++/**
++ * llc_lookup_dgram - Finds dgram socket for the local sap/mac
++ * @sap: SAP
++ * @laddr: address of local LLC (MAC + SAP)
++ *
++ * Search socket list of the SAP and finds connection using the local
++ * mac, and local sap. Returns pointer for socket found, %NULL otherwise.
++ */
++struct sock *llc_lookup_dgram(struct llc_sap *sap, struct llc_addr *laddr)
++{
++ struct sock *rc;
++ struct hlist_node *node;
++
++ read_lock_bh(&sap->sk_list.lock);
++ sk_for_each(rc, node, &sap->sk_list.list) {
++ struct llc_opt *llc = llc_sk(rc);
++
++ if (rc->sk_type == SOCK_DGRAM &&
++ llc->laddr.lsap == laddr->lsap &&
++ llc_mac_match(llc->laddr.mac, laddr->mac)) {
++ sock_hold(rc);
++ goto found;
++ }
++ }
++ rc = NULL;
++found:
++ read_unlock_bh(&sap->sk_list.lock);
++ return rc;
++}
++
++void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb)
++{
++ struct llc_addr laddr;
++ struct sock *sk;
++
++ llc_pdu_decode_da(skb, laddr.mac);
++ llc_pdu_decode_dsap(skb, &laddr.lsap);
++
++ sk = llc_lookup_dgram(sap, &laddr);
++ if (sk) {
++ skb->sk = sk;
++ llc_sap_rcv(sap, skb);
++ sock_put(sk);
++ } else
++ kfree_skb(skb);
++}
+Index: linux-2.6.0-test5/net/llc/llc_station.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/llc/llc_station.c 2003-09-27 11:38:18.493716912 +0800
++++ linux-2.6.0-test5/net/llc/llc_station.c 2003-09-27 11:38:42.130123632 +0800
+@@ -0,0 +1,713 @@
++/*
++ * llc_station.c - station component of LLC
++ *
++ * Copyright (c) 1997 by Procom Technology, Inc.
++ * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
++ *
++ * This program can be redistributed or modified under the terms of the
++ * GNU General Public License as published by the Free Software Foundation.
++ * This program is distributed without any warranty or implied warranty
++ * of merchantability or fitness for a particular purpose.
++ *
++ * See the GNU General Public License for more details.
++ */
++#include <linux/config.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <net/llc.h>
++#include <net/llc_sap.h>
++#include <net/llc_conn.h>
++#include <net/llc_c_ac.h>
++#include <net/llc_s_ac.h>
++#include <net/llc_c_ev.h>
++#include <net/llc_c_st.h>
++#include <net/llc_s_ev.h>
++#include <net/llc_s_st.h>
++#include <net/llc_pdu.h>
++
++/**
++ * struct llc_station - LLC station component
++ *
++ * SAP and connection resource manager, one per adapter.
++ *
++ * @state - state of station
++ * @xid_r_count - XID response PDU counter
++ * @mac_sa - MAC source address
++ * @sap_list - list of related SAPs
++ * @ev_q - events entering state mach.
++ * @mac_pdu_q - PDUs ready to send to MAC
++ */
++struct llc_station {
++ u8 state;
++ u8 xid_r_count;
++ struct timer_list ack_timer;
++ u8 retry_count;
++ u8 maximum_retry;
++ struct {
++ struct sk_buff_head list;
++ spinlock_t lock;
++ } ev_q;
++ struct sk_buff_head mac_pdu_q;
++};
++
++/* Types of events (possible values in 'ev->type') */
++#define LLC_STATION_EV_TYPE_SIMPLE 1
++#define LLC_STATION_EV_TYPE_CONDITION 2
++#define LLC_STATION_EV_TYPE_PRIM 3
++#define LLC_STATION_EV_TYPE_PDU 4 /* command/response PDU */
++#define LLC_STATION_EV_TYPE_ACK_TMR 5
++#define LLC_STATION_EV_TYPE_RPT_STATUS 6
++
++/* Events */
++#define LLC_STATION_EV_ENABLE_WITH_DUP_ADDR_CHECK 1
++#define LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK 2
++#define LLC_STATION_EV_ACK_TMR_EXP_LT_RETRY_CNT_MAX_RETRY 3
++#define LLC_STATION_EV_ACK_TMR_EXP_EQ_RETRY_CNT_MAX_RETRY 4
++#define LLC_STATION_EV_RX_NULL_DSAP_XID_C 5
++#define LLC_STATION_EV_RX_NULL_DSAP_0_XID_R_XID_R_CNT_EQ 6
++#define LLC_STATION_EV_RX_NULL_DSAP_1_XID_R_XID_R_CNT_EQ 7
++#define LLC_STATION_EV_RX_NULL_DSAP_TEST_C 8
++#define LLC_STATION_EV_DISABLE_REQ 9
++
++struct llc_station_state_ev {
++ u8 type;
++ u8 prim;
++ u8 prim_type;
++ u8 reason;
++ struct list_head node; /* node in station->ev_q.list */
++};
++
++static __inline__ struct llc_station_state_ev *
++ llc_station_ev(struct sk_buff *skb)
++{
++ return (struct llc_station_state_ev *)skb->cb;
++}
++
++typedef int (*llc_station_ev_t)(struct sk_buff *skb);
++
++#define LLC_STATION_STATE_DOWN 1 /* initial state */
++#define LLC_STATION_STATE_DUP_ADDR_CHK 2
++#define LLC_STATION_STATE_UP 3
++
++#define LLC_NBR_STATION_STATES 3 /* size of state table */
++
++typedef int (*llc_station_action_t)(struct sk_buff *skb);
++
++/* Station component state table structure */
++struct llc_station_state_trans {
++ llc_station_ev_t ev;
++ u8 next_state;
++ llc_station_action_t *ev_actions;
++};
++
++struct llc_station_state {
++ u8 curr_state;
++ struct llc_station_state_trans **transitions;
++};
++
++static struct llc_station llc_main_station;
++
++static int llc_stat_ev_enable_with_dup_addr_check(struct sk_buff *skb)
++{
++ struct llc_station_state_ev *ev = llc_station_ev(skb);
++
++ return ev->type == LLC_STATION_EV_TYPE_SIMPLE &&
++ ev->prim_type ==
++ LLC_STATION_EV_ENABLE_WITH_DUP_ADDR_CHECK ? 0 : 1;
++}
++
++static int llc_stat_ev_enable_without_dup_addr_check(struct sk_buff *skb)
++{
++ struct llc_station_state_ev *ev = llc_station_ev(skb);
++
++ return ev->type == LLC_STATION_EV_TYPE_SIMPLE &&
++ ev->prim_type ==
++ LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK ? 0 : 1;
++}
++
++static int llc_stat_ev_ack_tmr_exp_lt_retry_cnt_max_retry(struct sk_buff *skb)
++{
++ struct llc_station_state_ev *ev = llc_station_ev(skb);
++
++ return ev->type == LLC_STATION_EV_TYPE_ACK_TMR &&
++ llc_main_station.retry_count <
++ llc_main_station.maximum_retry ? 0 : 1;
++}
++
++static int llc_stat_ev_ack_tmr_exp_eq_retry_cnt_max_retry(struct sk_buff *skb)
++{
++ struct llc_station_state_ev *ev = llc_station_ev(skb);
++
++ return ev->type == LLC_STATION_EV_TYPE_ACK_TMR &&
++ llc_main_station.retry_count ==
++ llc_main_station.maximum_retry ? 0 : 1;
++}
++
++static int llc_stat_ev_rx_null_dsap_xid_c(struct sk_buff *skb)
++{
++ struct llc_station_state_ev *ev = llc_station_ev(skb);
++ struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
++
++ return ev->type == LLC_STATION_EV_TYPE_PDU &&
++ LLC_PDU_IS_CMD(pdu) && /* command PDU */
++ LLC_PDU_TYPE_IS_U(pdu) && /* U type PDU */
++ LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_XID &&
++ !pdu->dsap ? 0 : 1; /* NULL DSAP value */
++}
++
++static int llc_stat_ev_rx_null_dsap_0_xid_r_xid_r_cnt_eq(struct sk_buff *skb)
++{
++ struct llc_station_state_ev *ev = llc_station_ev(skb);
++ struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
++
++ return ev->type == LLC_STATION_EV_TYPE_PDU &&
++ LLC_PDU_IS_RSP(pdu) && /* response PDU */
++ LLC_PDU_TYPE_IS_U(pdu) && /* U type PDU */
++ LLC_U_PDU_RSP(pdu) == LLC_1_PDU_CMD_XID &&
++ !pdu->dsap && /* NULL DSAP value */
++ !llc_main_station.xid_r_count ? 0 : 1;
++}
++
++static int llc_stat_ev_rx_null_dsap_1_xid_r_xid_r_cnt_eq(struct sk_buff *skb)
++{
++ struct llc_station_state_ev *ev = llc_station_ev(skb);
++ struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
++
++ return ev->type == LLC_STATION_EV_TYPE_PDU &&
++ LLC_PDU_IS_RSP(pdu) && /* response PDU */
++ LLC_PDU_TYPE_IS_U(pdu) && /* U type PDU */
++ LLC_U_PDU_RSP(pdu) == LLC_1_PDU_CMD_XID &&
++ !pdu->dsap && /* NULL DSAP value */
++ llc_main_station.xid_r_count == 1 ? 0 : 1;
++}
++
++static int llc_stat_ev_rx_null_dsap_test_c(struct sk_buff *skb)
++{
++ struct llc_station_state_ev *ev = llc_station_ev(skb);
++ struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
++
++ return ev->type == LLC_STATION_EV_TYPE_PDU &&
++ LLC_PDU_IS_CMD(pdu) && /* command PDU */
++ LLC_PDU_TYPE_IS_U(pdu) && /* U type PDU */
++ LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_TEST &&
++ !pdu->dsap ? 0 : 1; /* NULL DSAP */
++}
++
++static int llc_stat_ev_disable_req(struct sk_buff *skb)
++{
++ struct llc_station_state_ev *ev = llc_station_ev(skb);
++
++ return ev->type == LLC_STATION_EV_TYPE_PRIM &&
++ ev->prim == LLC_DISABLE_PRIM &&
++ ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
++}
++
++/**
++ * llc_station_send_pdu - queues PDU to send
++ * @skb: Address of the PDU
++ *
++ * Queues a PDU to send to the MAC layer.
++ */
++static void llc_station_send_pdu(struct sk_buff *skb)
++{
++ skb_queue_tail(&llc_main_station.mac_pdu_q, skb);
++ while ((skb = skb_dequeue(&llc_main_station.mac_pdu_q)) != NULL)
++ if (dev_queue_xmit(skb))
++ break;
++}
++
++static int llc_station_ac_start_ack_timer(struct sk_buff *skb)
++{
++ mod_timer(&llc_main_station.ack_timer, jiffies + LLC_ACK_TIME * HZ);
++ return 0;
++}
++
++static int llc_station_ac_set_retry_cnt_0(struct sk_buff *skb)
++{
++ llc_main_station.retry_count = 0;
++ return 0;
++}
++
++static int llc_station_ac_inc_retry_cnt_by_1(struct sk_buff *skb)
++{
++ llc_main_station.retry_count++;
++ return 0;
++}
++
++static int llc_station_ac_set_xid_r_cnt_0(struct sk_buff *skb)
++{
++ llc_main_station.xid_r_count = 0;
++ return 0;
++}
++
++static int llc_station_ac_inc_xid_r_cnt_by_1(struct sk_buff *skb)
++{
++ llc_main_station.xid_r_count++;
++ return 0;
++}
++
++static int llc_station_ac_send_null_dsap_xid_c(struct sk_buff *skb)
++{
++ int rc = 1;
++ struct sk_buff *nskb = llc_alloc_frame();
++
++ if (!nskb)
++ goto out;
++ llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, 0, LLC_PDU_CMD);
++ llc_pdu_init_as_xid_cmd(nskb, LLC_XID_NULL_CLASS_2, 127);
++ rc = llc_mac_hdr_init(nskb, llc_station_mac_sa, llc_station_mac_sa);
++ if (rc)
++ goto free;
++ llc_station_send_pdu(nskb);
++out:
++ return rc;
++free:
++ kfree_skb(skb);
++ goto out;
++}
++
++static int llc_station_ac_send_xid_r(struct sk_buff *skb)
++{
++ u8 mac_da[ETH_ALEN], dsap;
++ int rc = 1;
++ struct sk_buff* nskb = llc_alloc_frame();
++
++ if (!nskb)
++ goto out;
++ rc = 0;
++ nskb->dev = skb->dev;
++ llc_pdu_decode_sa(skb, mac_da);
++ llc_pdu_decode_ssap(skb, &dsap);
++ llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP);
++ llc_pdu_init_as_xid_rsp(nskb, LLC_XID_NULL_CLASS_2, 127);
++ rc = llc_mac_hdr_init(nskb, llc_station_mac_sa, mac_da);
++ if (rc)
++ goto free;
++ llc_station_send_pdu(nskb);
++out:
++ return rc;
++free:
++ kfree_skb(skb);
++ goto out;
++}
++
++static int llc_station_ac_send_test_r(struct sk_buff *skb)
++{
++ u8 mac_da[ETH_ALEN], dsap;
++ int rc = 1;
++ struct sk_buff *nskb = llc_alloc_frame();
++
++ if (!nskb)
++ goto out;
++ rc = 0;
++ nskb->dev = skb->dev;
++ llc_pdu_decode_sa(skb, mac_da);
++ llc_pdu_decode_ssap(skb, &dsap);
++ llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP);
++ llc_pdu_init_as_test_rsp(nskb, skb);
++ rc = llc_mac_hdr_init(nskb, llc_station_mac_sa, mac_da);
++ if (rc)
++ goto free;
++ llc_station_send_pdu(nskb);
++out:
++ return rc;
++free:
++ kfree_skb(skb);
++ goto out;
++}
++
++static int llc_station_ac_report_status(struct sk_buff *skb)
++{
++ return 0;
++}
++
++/* COMMON STATION STATE transitions */
++
++/* dummy last-transition indicator; common to all state transition groups
++ * last entry for this state
++ * all members are zeros, .bss zeroes it
++ */
++static struct llc_station_state_trans llc_stat_state_trans_end;
++
++/* DOWN STATE transitions */
++
++/* state transition for LLC_STATION_EV_ENABLE_WITH_DUP_ADDR_CHECK event */
++static llc_station_action_t llc_stat_down_state_actions_1[] = {
++ [0] = llc_station_ac_start_ack_timer,
++ [1] = llc_station_ac_set_retry_cnt_0,
++ [2] = llc_station_ac_set_xid_r_cnt_0,
++ [3] = llc_station_ac_send_null_dsap_xid_c,
++ [4] = NULL,
++};
++
++static struct llc_station_state_trans llc_stat_down_state_trans_1 = {
++ .ev = llc_stat_ev_enable_with_dup_addr_check,
++ .next_state = LLC_STATION_STATE_DUP_ADDR_CHK,
++ .ev_actions = llc_stat_down_state_actions_1,
++};
++
++/* state transition for LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK event */
++static llc_station_action_t llc_stat_down_state_actions_2[] = {
++ [0] = llc_station_ac_report_status, /* STATION UP */
++ [1] = NULL,
++};
++
++static struct llc_station_state_trans llc_stat_down_state_trans_2 = {
++ .ev = llc_stat_ev_enable_without_dup_addr_check,
++ .next_state = LLC_STATION_STATE_UP,
++ .ev_actions = llc_stat_down_state_actions_2,
++};
++
++/* array of pointers; one to each transition */
++static struct llc_station_state_trans *llc_stat_dwn_state_trans[] = {
++ [0] = &llc_stat_down_state_trans_1,
++ [1] = &llc_stat_down_state_trans_2,
++ [2] = &llc_stat_state_trans_end,
++};
++
++/* UP STATE transitions */
++/* state transition for LLC_STATION_EV_DISABLE_REQ event */
++static llc_station_action_t llc_stat_up_state_actions_1[] = {
++ [0] = llc_station_ac_report_status, /* STATION DOWN */
++ [1] = NULL,
++};
++
++static struct llc_station_state_trans llc_stat_up_state_trans_1 = {
++ .ev = llc_stat_ev_disable_req,
++ .next_state = LLC_STATION_STATE_DOWN,
++ .ev_actions = llc_stat_up_state_actions_1,
++};
++
++/* state transition for LLC_STATION_EV_RX_NULL_DSAP_XID_C event */
++static llc_station_action_t llc_stat_up_state_actions_2[] = {
++ [0] = llc_station_ac_send_xid_r,
++ [1] = NULL,
++};
++
++static struct llc_station_state_trans llc_stat_up_state_trans_2 = {
++ .ev = llc_stat_ev_rx_null_dsap_xid_c,
++ .next_state = LLC_STATION_STATE_UP,
++ .ev_actions = llc_stat_up_state_actions_2,
++};
++
++/* state transition for LLC_STATION_EV_RX_NULL_DSAP_TEST_C event */
++static llc_station_action_t llc_stat_up_state_actions_3[] = {
++ [0] = llc_station_ac_send_test_r,
++ [1] = NULL,
++};
++
++static struct llc_station_state_trans llc_stat_up_state_trans_3 = {
++ .ev = llc_stat_ev_rx_null_dsap_test_c,
++ .next_state = LLC_STATION_STATE_UP,
++ .ev_actions = llc_stat_up_state_actions_3,
++};
++
++/* array of pointers; one to each transition */
++static struct llc_station_state_trans *llc_stat_up_state_trans [] = {
++ [0] = &llc_stat_up_state_trans_1,
++ [1] = &llc_stat_up_state_trans_2,
++ [2] = &llc_stat_up_state_trans_3,
++ [3] = &llc_stat_state_trans_end,
++};
++
++/* DUP ADDR CHK STATE transitions */
++/* state transition for LLC_STATION_EV_RX_NULL_DSAP_0_XID_R_XID_R_CNT_EQ
++ * event
++ */
++static llc_station_action_t llc_stat_dupaddr_state_actions_1[] = {
++ [0] = llc_station_ac_inc_xid_r_cnt_by_1,
++ [1] = NULL,
++};
++
++static struct llc_station_state_trans llc_stat_dupaddr_state_trans_1 = {
++ .ev = llc_stat_ev_rx_null_dsap_0_xid_r_xid_r_cnt_eq,
++ .next_state = LLC_STATION_STATE_DUP_ADDR_CHK,
++ .ev_actions = llc_stat_dupaddr_state_actions_1,
++};
++
++/* state transition for LLC_STATION_EV_RX_NULL_DSAP_1_XID_R_XID_R_CNT_EQ
++ * event
++ */
++static llc_station_action_t llc_stat_dupaddr_state_actions_2[] = {
++ [0] = llc_station_ac_report_status, /* DUPLICATE ADDRESS FOUND */
++ [1] = NULL,
++};
++
++static struct llc_station_state_trans llc_stat_dupaddr_state_trans_2 = {
++ .ev = llc_stat_ev_rx_null_dsap_1_xid_r_xid_r_cnt_eq,
++ .next_state = LLC_STATION_STATE_DOWN,
++ .ev_actions = llc_stat_dupaddr_state_actions_2,
++};
++
++/* state transition for LLC_STATION_EV_RX_NULL_DSAP_XID_C event */
++static llc_station_action_t llc_stat_dupaddr_state_actions_3[] = {
++ [0] = llc_station_ac_send_xid_r,
++ [1] = NULL,
++};
++
++static struct llc_station_state_trans llc_stat_dupaddr_state_trans_3 = {
++ .ev = llc_stat_ev_rx_null_dsap_xid_c,
++ .next_state = LLC_STATION_STATE_DUP_ADDR_CHK,
++ .ev_actions = llc_stat_dupaddr_state_actions_3,
++};
++
++/* state transition for LLC_STATION_EV_ACK_TMR_EXP_LT_RETRY_CNT_MAX_RETRY
++ * event
++ */
++static llc_station_action_t llc_stat_dupaddr_state_actions_4[] = {
++ [0] = llc_station_ac_start_ack_timer,
++ [1] = llc_station_ac_inc_retry_cnt_by_1,
++ [2] = llc_station_ac_set_xid_r_cnt_0,
++ [3] = llc_station_ac_send_null_dsap_xid_c,
++ [4] = NULL,
++};
++
++static struct llc_station_state_trans llc_stat_dupaddr_state_trans_4 = {
++ .ev = llc_stat_ev_ack_tmr_exp_lt_retry_cnt_max_retry,
++ .next_state = LLC_STATION_STATE_DUP_ADDR_CHK,
++ .ev_actions = llc_stat_dupaddr_state_actions_4,
++};
++
++/* state transition for LLC_STATION_EV_ACK_TMR_EXP_EQ_RETRY_CNT_MAX_RETRY
++ * event
++ */
++static llc_station_action_t llc_stat_dupaddr_state_actions_5[] = {
++ [0] = llc_station_ac_report_status, /* STATION UP */
++ [1] = NULL,
++};
++
++static struct llc_station_state_trans llc_stat_dupaddr_state_trans_5 = {
++ .ev = llc_stat_ev_ack_tmr_exp_eq_retry_cnt_max_retry,
++ .next_state = LLC_STATION_STATE_UP,
++ .ev_actions = llc_stat_dupaddr_state_actions_5,
++};
++
++/* state transition for LLC_STATION_EV_DISABLE_REQ event */
++static llc_station_action_t llc_stat_dupaddr_state_actions_6[] = {
++ [0] = llc_station_ac_report_status, /* STATION DOWN */
++ [1] = NULL,
++};
++
++static struct llc_station_state_trans llc_stat_dupaddr_state_trans_6 = {
++ .ev = llc_stat_ev_disable_req,
++ .next_state = LLC_STATION_STATE_DOWN,
++ .ev_actions = llc_stat_dupaddr_state_actions_6,
++};
++
++/* array of pointers; one to each transition */
++static struct llc_station_state_trans *llc_stat_dupaddr_state_trans[] = {
++ [0] = &llc_stat_dupaddr_state_trans_6, /* Request */
++ [1] = &llc_stat_dupaddr_state_trans_4, /* Timer */
++ [2] = &llc_stat_dupaddr_state_trans_5,
++ [3] = &llc_stat_dupaddr_state_trans_1, /* Receive frame */
++ [4] = &llc_stat_dupaddr_state_trans_2,
++ [5] = &llc_stat_dupaddr_state_trans_3,
++ [6] = &llc_stat_state_trans_end,
++};
++
++static struct llc_station_state
++ llc_station_state_table[LLC_NBR_STATION_STATES] = {
++ [LLC_STATION_STATE_DOWN - 1] = {
++ .curr_state = LLC_STATION_STATE_DOWN,
++ .transitions = llc_stat_dwn_state_trans,
++ },
++ [LLC_STATION_STATE_DUP_ADDR_CHK - 1] = {
++ .curr_state = LLC_STATION_STATE_DUP_ADDR_CHK,
++ .transitions = llc_stat_dupaddr_state_trans,
++ },
++ [LLC_STATION_STATE_UP - 1] = {
++ .curr_state = LLC_STATION_STATE_UP,
++ .transitions = llc_stat_up_state_trans,
++ },
++};
++
++/**
++ * llc_exec_station_trans_actions - executes actions for transition
++ * @trans: Address of the transition
++ * @skb: Address of the event that caused the transition
++ *
++ * Executes actions of a transition of the station state machine. Returns
++ * 0 if all actions complete successfully, nonzero otherwise.
++ */
++static u16 llc_exec_station_trans_actions(struct llc_station_state_trans *trans,
++ struct sk_buff *skb)
++{
++ u16 rc = 0;
++ llc_station_action_t *next_action = trans->ev_actions;
++
++ for (; next_action && *next_action; next_action++)
++ if ((*next_action)(skb))
++ rc = 1;
++ return rc;
++}
++
++/**
++ * llc_find_station_trans - finds transition for this event
++ * @skb: Address of the event
++ *
++ * Search thru events of the current state of the station until list
++ * exhausted or it's obvious that the event is not valid for the current
++ * state. Returns the address of the transition if cound, %NULL otherwise.
++ */
++static struct llc_station_state_trans *
++ llc_find_station_trans(struct sk_buff *skb)
++{
++ int i = 0;
++ struct llc_station_state_trans *rc = NULL;
++ struct llc_station_state_trans **next_trans;
++ struct llc_station_state *curr_state =
++ &llc_station_state_table[llc_main_station.state - 1];
++
++ for (next_trans = curr_state->transitions; next_trans[i]->ev; i++)
++ if (!next_trans[i]->ev(skb)) {
++ rc = next_trans[i];
++ break;
++ }
++ return rc;
++}
++
++/**
++ * llc_station_free_ev - frees an event
++ * @skb: Address of the event
++ *
++ * Frees an event.
++ */
++static void llc_station_free_ev(struct sk_buff *skb)
++{
++ struct llc_station_state_ev *ev = llc_station_ev(skb);
++
++ if (ev->type == LLC_STATION_EV_TYPE_PDU)
++ kfree_skb(skb);
++}
++
++/**
++ * llc_station_next_state - processes event and goes to the next state
++ * @skb: Address of the event
++ *
++ * Processes an event, executes any transitions related to that event and
++ * updates the state of the station.
++ */
++static u16 llc_station_next_state(struct sk_buff *skb)
++{
++ u16 rc = 1;
++ struct llc_station_state_trans *trans;
++
++ if (llc_main_station.state > LLC_NBR_STATION_STATES)
++ goto out;
++ trans = llc_find_station_trans(skb);
++ if (trans) {
++ /* got the state to which we next transition; perform the
++ * actions associated with this transition before actually
++ * transitioning to the next state
++ */
++ rc = llc_exec_station_trans_actions(trans, skb);
++ if (!rc)
++ /* transition station to next state if all actions
++ * execute successfully; done; wait for next event
++ */
++ llc_main_station.state = trans->next_state;
++ } else
++ /* event not recognized in current state; re-queue it for
++ * processing again at a later time; return failure
++ */
++ rc = 0;
++out:
++ llc_station_free_ev(skb);
++ return rc;
++}
++
++/**
++ * llc_station_service_events - service events in the queue
++ *
++ * Get an event from the station event queue (if any); attempt to service
++ * the event; if event serviced, get the next event (if any) on the event
++ * queue; if event not service, re-queue the event on the event queue and
++ * attempt to service the next event; when serviced all events in queue,
++ * finished; if don't transition to different state, just service all
++ * events once; if transition to new state, service all events again.
++ * Caller must hold llc_main_station.ev_q.lock.
++ */
++static void llc_station_service_events(void)
++{
++ struct sk_buff *skb;
++
++ while ((skb = skb_dequeue(&llc_main_station.ev_q.list)) != NULL)
++ llc_station_next_state(skb);
++}
++
++/**
++ * llc_station_state_process: queue event and try to process queue.
++ * @skb: Address of the event
++ *
++ * Queues an event (on the station event queue) for handling by the
++ * station state machine and attempts to process any queued-up events.
++ */
++void llc_station_state_process(struct sk_buff *skb)
++{
++ spin_lock_bh(&llc_main_station.ev_q.lock);
++ skb_queue_tail(&llc_main_station.ev_q.list, skb);
++ llc_station_service_events();
++ spin_unlock_bh(&llc_main_station.ev_q.lock);
++}
++
++static void llc_station_ack_tmr_cb(unsigned long timeout_data)
++{
++ struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC);
++
++ if (skb) {
++ struct llc_station_state_ev *ev = llc_station_ev(skb);
++
++ ev->type = LLC_STATION_EV_TYPE_ACK_TMR;
++ llc_station_state_process(skb);
++ }
++}
++
++/*
++ * llc_station_rcv - send received pdu to the station state machine
++ * @skb: received frame.
++ *
++ * Sends data unit to station state machine.
++ */
++static void llc_station_rcv(struct sk_buff *skb)
++{
++ struct llc_station_state_ev *ev = llc_station_ev(skb);
++
++ ev->type = LLC_STATION_EV_TYPE_PDU;
++ ev->reason = 0;
++ llc_station_state_process(skb);
++}
++
++int __init llc_station_init(void)
++{
++ u16 rc = -ENOBUFS;
++ struct sk_buff *skb;
++ struct llc_station_state_ev *ev;
++
++ skb_queue_head_init(&llc_main_station.mac_pdu_q);
++ skb_queue_head_init(&llc_main_station.ev_q.list);
++ spin_lock_init(&llc_main_station.ev_q.lock);
++ init_timer(&llc_main_station.ack_timer);
++ llc_main_station.ack_timer.data = (unsigned long)&llc_main_station;
++ llc_main_station.ack_timer.function = llc_station_ack_tmr_cb;
++
++ skb = alloc_skb(0, GFP_ATOMIC);
++ if (!skb)
++ goto out;
++ rc = 0;
++ llc_set_station_handler(llc_station_rcv);
++ ev = llc_station_ev(skb);
++ memset(ev, 0, sizeof(*ev));
++ llc_main_station.ack_timer.expires = jiffies + 3 * HZ;
++ llc_main_station.maximum_retry = 1;
++ llc_main_station.state = LLC_STATION_STATE_DOWN;
++ ev->type = LLC_STATION_EV_TYPE_SIMPLE;
++ ev->prim_type = LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK;
++ rc = llc_station_next_state(skb);
++out:
++ return rc;
++}
++
++void __exit llc_station_exit(void)
++{
++ llc_set_station_handler(NULL);
++}
+Index: linux-2.6.0-test5/net/llc/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/net/llc/Makefile 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/llc/Makefile 2003-09-27 11:38:42.132123328 +0800
+@@ -2,7 +2,7 @@
+ # Makefile for the Linux 802.2 LLC (fully-functional) layer.
+ #
+ # Copyright (c) 1997 by Procom Technology,Inc.
+-# 2001, 2002 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
++# 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ #
+ # This program can be redistributed or modified under the terms of the
+ # GNU General Public License as published by the Free Software Foundation.
+@@ -14,7 +14,11 @@
+
+ obj-$(CONFIG_LLC) += llc.o
+
+-llc-y := llc_if.o llc_c_ev.o llc_c_ac.o llc_mac.o llc_sap.o llc_s_st.o \
+- llc_main.o llc_s_ac.o llc_conn.o llc_c_st.o llc_stat.o llc_actn.o \
+- llc_s_ev.o llc_evnt.o llc_pdu.o llc_proc.o
+-llc-$(CONFIG_LLC_UI) += af_llc.o
++llc-y := llc_core.o llc_input.o llc_output.o
++
++obj-$(CONFIG_LLC2) += llc2.o
++
++llc2-y := llc_if.o llc_c_ev.o llc_c_ac.o llc_conn.o llc_c_st.o llc_pdu.o \
++ llc_sap.o llc_s_ac.o llc_s_ev.o llc_s_st.o af_llc.o llc_station.o
++
++llc2-$(CONFIG_PROC_FS) += llc_proc.o
+Index: linux-2.6.0-test5/net/netlink/af_netlink.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/netlink/af_netlink.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/netlink/af_netlink.c 2003-09-27 11:38:42.138122416 +0800
+@@ -988,7 +988,7 @@
+ static void *netlink_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+ read_lock(&nl_table_lock);
+- return *pos ? netlink_seq_socket_idx(seq, *pos - 1) : (void *) 1;
++ return *pos ? netlink_seq_socket_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+ }
+
+ static void *netlink_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -997,7 +997,7 @@
+
+ ++*pos;
+
+- if (v == (void *) 1)
++ if (v == SEQ_START_TOKEN)
+ return netlink_seq_socket_idx(seq, 0);
+
+ s = sk_next(v);
+@@ -1023,7 +1023,7 @@
+
+ static int netlink_seq_show(struct seq_file *seq, void *v)
+ {
+- if (v == (void *)1)
++ if (v == SEQ_START_TOKEN)
+ seq_puts(seq,
+ "sk Eth Pid Groups "
+ "Rmem Wmem Dump Locks\n");
+Index: linux-2.6.0-test5/net/netrom/af_netrom.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/netrom/af_netrom.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/netrom/af_netrom.c 2003-09-27 11:38:42.147121048 +0800
+@@ -62,6 +62,7 @@
+ static spinlock_t nr_list_lock = SPIN_LOCK_UNLOCKED;
+
+ static struct proto_ops nr_proto_ops;
++void nr_init_timers(struct sock *sk);
+
+ static struct sock *nr_alloc_sock(void)
+ {
+@@ -279,17 +280,12 @@
+
+ kfree_skb(skb);
+ }
+- while ((skb = skb_dequeue(&sk->sk_write_queue)) != NULL) {
+- kfree_skb(skb);
+- }
+
+ if (atomic_read(&sk->sk_wmem_alloc) ||
+ atomic_read(&sk->sk_rmem_alloc)) {
+ /* Defer: outstanding buffers */
+- init_timer(&sk->sk_timer);
+- sk->sk_timer.expires = jiffies + 2 * HZ;
+ sk->sk_timer.function = nr_destroy_timer;
+- sk->sk_timer.data = (unsigned long)sk;
++ sk->sk_timer.expires = jiffies + 2 * HZ;
+ add_timer(&sk->sk_timer);
+ } else
+ sock_put(sk);
+@@ -442,10 +438,7 @@
+ skb_queue_head_init(&nr->reseq_queue);
+ skb_queue_head_init(&nr->frag_queue);
+
+- init_timer(&nr->t1timer);
+- init_timer(&nr->t2timer);
+- init_timer(&nr->t4timer);
+- init_timer(&nr->idletimer);
++ nr_init_timers(sk);
+
+ nr->t1 = sysctl_netrom_transport_timeout;
+ nr->t2 = sysctl_netrom_transport_acknowledge_delay;
+@@ -491,10 +484,7 @@
+ skb_queue_head_init(&nr->reseq_queue);
+ skb_queue_head_init(&nr->frag_queue);
+
+- init_timer(&nr->t1timer);
+- init_timer(&nr->t2timer);
+- init_timer(&nr->t4timer);
+- init_timer(&nr->idletimer);
++ nr_init_timers(sk);
+
+ onr = nr_sk(osk);
+
+@@ -1241,8 +1231,6 @@
+
+ #ifdef CONFIG_PROC_FS
+
+-/* Marker for header entry */
+-#define NETROM_PROC_START ((void *)1)
+ static void *nr_info_start(struct seq_file *seq, loff_t *pos)
+ {
+ struct sock *s;
+@@ -1251,7 +1239,7 @@
+
+ spin_lock_bh(&nr_list_lock);
+ if (*pos == 0)
+- return NETROM_PROC_START;
++ return SEQ_START_TOKEN;
+
+ sk_for_each(s, node, &nr_list) {
+ if (i == *pos)
+@@ -1265,7 +1253,7 @@
+ {
+ ++*pos;
+
+- return (v == NETROM_PROC_START) ? sk_head(&nr_list)
++ return (v == SEQ_START_TOKEN) ? sk_head(&nr_list)
+ : sk_next((struct sock *)v);
+ }
+
+@@ -1281,7 +1269,7 @@
+ nr_cb *nr;
+ const char *devname;
+
+- if (v == NETROM_PROC_START)
++ if (v == SEQ_START_TOKEN)
+ seq_puts(seq,
+ "user_addr dest_node src_node dev my your st vs vr va t1 t2 t4 idle n2 wnd Snd-Q Rcv-Q inode\n");
+
+Index: linux-2.6.0-test5/net/netrom/nr_loopback.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/netrom/nr_loopback.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/netrom/nr_loopback.c 2003-09-27 11:38:42.148120896 +0800
+@@ -14,19 +14,17 @@
+ #include <net/netrom.h>
+ #include <linux/init.h>
+
+-static struct sk_buff_head loopback_queue;
+-static struct timer_list loopback_timer;
++static void nr_loopback_timer(unsigned long);
+
+-static void nr_set_loopback_timer(void);
++static struct sk_buff_head loopback_queue;
++static struct timer_list loopback_timer = TIMER_INITIALIZER(nr_loopback_timer, 0, 0);
+
+-void nr_loopback_init(void)
++void __init nr_loopback_init(void)
+ {
+ skb_queue_head_init(&loopback_queue);
+-
+- init_timer(&loopback_timer);
+ }
+
+-static int nr_loopback_running(void)
++static inline int nr_loopback_running(void)
+ {
+ return timer_pending(&loopback_timer);
+ }
+@@ -42,26 +40,13 @@
+ skb_queue_tail(&loopback_queue, skbn);
+
+ if (!nr_loopback_running())
+- nr_set_loopback_timer();
++ mod_timer(&loopback_timer, jiffies + 10);
+ }
+
+ kfree_skb(skb);
+ return 1;
+ }
+
+-static void nr_loopback_timer(unsigned long);
+-
+-static void nr_set_loopback_timer(void)
+-{
+- del_timer(&loopback_timer);
+-
+- loopback_timer.data = 0;
+- loopback_timer.function = &nr_loopback_timer;
+- loopback_timer.expires = jiffies + 10;
+-
+- add_timer(&loopback_timer);
+-}
+-
+ static void nr_loopback_timer(unsigned long param)
+ {
+ struct sk_buff *skb;
+@@ -80,12 +65,12 @@
+ dev_put(dev);
+
+ if (!skb_queue_empty(&loopback_queue) && !nr_loopback_running())
+- nr_set_loopback_timer();
++ mod_timer(&loopback_timer, jiffies + 10);
+ }
+ }
+
+ void __exit nr_loopback_clear(void)
+ {
+- del_timer(&loopback_timer);
++ del_timer_sync(&loopback_timer);
+ skb_queue_purge(&loopback_queue);
+ }
+Index: linux-2.6.0-test5/net/netrom/nr_route.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/netrom/nr_route.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/netrom/nr_route.c 2003-09-27 11:38:42.155119832 +0800
+@@ -841,7 +841,6 @@
+ }
+
+ #ifdef CONFIG_PROC_FS
+-#define NETROM_PROC_START ((void *) 1)
+
+ static void *nr_node_start(struct seq_file *seq, loff_t *pos)
+ {
+@@ -851,7 +850,7 @@
+
+ spin_lock_bh(&nr_node_list_lock);
+ if (*pos == 0)
+- return NETROM_PROC_START;
++ return SEQ_START_TOKEN;
+
+ nr_node_for_each(nr_node, node, &nr_node_list) {
+ if (i == *pos)
+@@ -867,7 +866,7 @@
+ struct hlist_node *node;
+ ++*pos;
+
+- node = (v == NETROM_PROC_START)
++ node = (v == SEQ_START_TOKEN)
+ ? nr_node_list.first
+ : ((struct nr_node *)v)->node_node.next;
+
+@@ -883,7 +882,7 @@
+ {
+ int i;
+
+- if (v == NETROM_PROC_START)
++ if (v == SEQ_START_TOKEN)
+ seq_puts(seq,
+ "callsign mnemonic w n qual obs neigh qual obs neigh qual obs neigh\n");
+ else {
+@@ -936,7 +935,7 @@
+
+ spin_lock_bh(&nr_neigh_list_lock);
+ if (*pos == 0)
+- return NETROM_PROC_START;
++ return SEQ_START_TOKEN;
+
+ nr_neigh_for_each(nr_neigh, node, &nr_neigh_list) {
+ if (i == *pos)
+@@ -950,7 +949,7 @@
+ struct hlist_node *node;
+ ++*pos;
+
+- node = (v == NETROM_PROC_START)
++ node = (v == SEQ_START_TOKEN)
+ ? nr_neigh_list.first
+ : ((struct nr_neigh *)v)->neigh_node.next;
+
+@@ -966,7 +965,7 @@
+ {
+ int i;
+
+- if (v == NETROM_PROC_START)
++ if (v == SEQ_START_TOKEN)
+ seq_puts(seq, "addr callsign dev qual lock count failed digipeaters\n");
+ else {
+ struct nr_neigh *nr_neigh = v;
+Index: linux-2.6.0-test5/net/netrom/nr_timer.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/netrom/nr_timer.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/netrom/nr_timer.c 2003-09-27 11:38:42.157119528 +0800
+@@ -36,69 +36,63 @@
+ static void nr_t4timer_expiry(unsigned long);
+ static void nr_idletimer_expiry(unsigned long);
+
+-void nr_start_t1timer(struct sock *sk)
++void nr_init_timers(struct sock *sk)
+ {
+ nr_cb *nr = nr_sk(sk);
+
+- del_timer(&nr->t1timer);
+-
++ init_timer(&nr->t1timer);
+ nr->t1timer.data = (unsigned long)sk;
+ nr->t1timer.function = &nr_t1timer_expiry;
+- nr->t1timer.expires = jiffies + nr->t1;
++
++ init_timer(&nr->t2timer);
++ nr->t2timer.data = (unsigned long)sk;
++ nr->t2timer.function = &nr_t2timer_expiry;
++
++ init_timer(&nr->t4timer);
++ nr->t4timer.data = (unsigned long)sk;
++ nr->t4timer.function = &nr_t4timer_expiry;
++
++ init_timer(&nr->idletimer);
++ nr->idletimer.data = (unsigned long)sk;
++ nr->idletimer.function = &nr_idletimer_expiry;
+
+- add_timer(&nr->t1timer);
++ /* initialized by sock_init_data */
++ sk->sk_timer.data = (unsigned long)sk;
++ sk->sk_timer.function = &nr_heartbeat_expiry;
+ }
+
+-void nr_start_t2timer(struct sock *sk)
++void nr_start_t1timer(struct sock *sk)
+ {
+ nr_cb *nr = nr_sk(sk);
+
+- del_timer(&nr->t2timer);
++ mod_timer(&nr->t1timer, jiffies + nr->t1);
++}
+
+- nr->t2timer.data = (unsigned long)sk;
+- nr->t2timer.function = &nr_t2timer_expiry;
+- nr->t2timer.expires = jiffies + nr->t2;
++void nr_start_t2timer(struct sock *sk)
++{
++ nr_cb *nr = nr_sk(sk);
+
+- add_timer(&nr->t2timer);
++ mod_timer(&nr->t2timer, jiffies + nr->t2);
+ }
+
+ void nr_start_t4timer(struct sock *sk)
+ {
+ nr_cb *nr = nr_sk(sk);
+
+- del_timer(&nr->t4timer);
+-
+- nr->t4timer.data = (unsigned long)sk;
+- nr->t4timer.function = &nr_t4timer_expiry;
+- nr->t4timer.expires = jiffies + nr->t4;
+-
+- add_timer(&nr->t4timer);
++ mod_timer(&nr->t4timer, jiffies + nr->t4);
+ }
+
+ void nr_start_idletimer(struct sock *sk)
+ {
+ nr_cb *nr = nr_sk(sk);
+
+- del_timer(&nr->idletimer);
+-
+- if (nr->idle > 0) {
+- nr->idletimer.data = (unsigned long)sk;
+- nr->idletimer.function = &nr_idletimer_expiry;
+- nr->idletimer.expires = jiffies + nr->idle;
+-
+- add_timer(&nr->idletimer);
+- }
++ if (nr->idle > 0)
++ mod_timer(&nr->idletimer, jiffies + nr->idle);
+ }
+
+ void nr_start_heartbeat(struct sock *sk)
+ {
+- del_timer(&sk->sk_timer);
+-
+- sk->sk_timer.data = (unsigned long)sk;
+- sk->sk_timer.function = &nr_heartbeat_expiry;
+- sk->sk_timer.expires = jiffies + 5 * HZ;
+-
+- add_timer(&sk->sk_timer);
++ mod_timer(&sk->sk_timer, jiffies + 5 * HZ);
+ }
+
+ void nr_stop_t1timer(struct sock *sk)
+Index: linux-2.6.0-test5/net/netsyms.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/netsyms.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/netsyms.c 2003-09-27 11:38:42.163118616 +0800
+@@ -511,7 +511,7 @@
+ EXPORT_SYMBOL(dev_add_pack);
+ EXPORT_SYMBOL(dev_remove_pack);
+ EXPORT_SYMBOL(__dev_remove_pack);
+-EXPORT_SYMBOL(dev_get);
++EXPORT_SYMBOL(__dev_get);
+ EXPORT_SYMBOL(dev_alloc);
+ EXPORT_SYMBOL(dev_alloc_name);
+ EXPORT_SYMBOL(__netdev_watchdog_up);
+Index: linux-2.6.0-test5/net/packet/af_packet.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/packet/af_packet.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/packet/af_packet.c 2003-09-27 11:38:42.173117096 +0800
+@@ -381,6 +381,23 @@
+ }
+ #endif
+
++static inline unsigned run_filter(struct sk_buff *skb, struct sock *sk, unsigned res)
++{
++ struct sk_filter *filter;
++
++ bh_lock_sock(sk);
++ filter = sk->sk_filter;
++ /*
++ * Our caller already checked that filter != NULL but we need to
++ * verify that under bh_lock_sock() to be safe
++ */
++ if (likely(filter != NULL))
++ res = sk_run_filter(skb, filter->insns, filter->len);
++ bh_unlock_sock(sk);
++
++ return res;
++}
++
+ /*
+ This function makes lazy skb cloning in hope that most of packets
+ are discarded by BPF.
+@@ -429,15 +446,7 @@
+ snaplen = skb->len;
+
+ if (sk->sk_filter) {
+- unsigned res = snaplen;
+- struct sk_filter *filter;
+-
+- bh_lock_sock(sk);
+- if ((filter = sk->sk_filter) != NULL)
+- res = sk_run_filter(skb, sk->sk_filter->insns,
+- sk->sk_filter->len);
+- bh_unlock_sock(sk);
+-
++ unsigned res = run_filter(skb, sk, snaplen);
+ if (res == 0)
+ goto drop_n_restore;
+ if (snaplen > res)
+@@ -533,15 +542,7 @@
+ snaplen = skb->len;
+
+ if (sk->sk_filter) {
+- unsigned res = snaplen;
+- struct sk_filter *filter;
+-
+- bh_lock_sock(sk);
+- if ((filter = sk->sk_filter) != NULL)
+- res = sk_run_filter(skb, sk->sk_filter->insns,
+- sk->sk_filter->len);
+- bh_unlock_sock(sk);
+-
++ unsigned res = run_filter(skb, sk, snaplen);
+ if (res == 0)
+ goto drop_n_restore;
+ if (snaplen > res)
+Index: linux-2.6.0-test5/net/rose/af_rose.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/rose/af_rose.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/rose/af_rose.c 2003-09-27 11:38:42.183115576 +0800
+@@ -1344,7 +1344,7 @@
+
+ spin_lock_bh(&rose_list_lock);
+ if (*pos == 0)
+- return ROSE_PROC_START;
++ return SEQ_START_TOKEN;
+
+ i = 1;
+ sk_for_each(s, node, &rose_list) {
+@@ -1359,7 +1359,7 @@
+ {
+ ++*pos;
+
+- return (v == ROSE_PROC_START) ? sk_head(&rose_list)
++ return (v == SEQ_START_TOKEN) ? sk_head(&rose_list)
+ : sk_next((struct sock *)v);
+ }
+
+@@ -1370,7 +1370,7 @@
+
+ static int rose_info_show(struct seq_file *seq, void *v)
+ {
+- if (v == ROSE_PROC_START)
++ if (v == SEQ_START_TOKEN)
+ seq_puts(seq,
+ "dest_addr dest_call src_addr src_call dev lci neigh st vs vr va t t1 t2 t3 hb idle Snd-Q Rcv-Q inode\n");
+
+Index: linux-2.6.0-test5/net/rose/rose_route.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/rose/rose_route.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/rose/rose_route.c 2003-09-27 11:38:42.191114360 +0800
+@@ -1076,7 +1076,7 @@
+
+ spin_lock_bh(&rose_neigh_list_lock);
+ if (*pos == 0)
+- return ROSE_PROC_START;
++ return SEQ_START_TOKEN;
+
+ for (rose_node = rose_node_list; rose_node && i < *pos;
+ rose_node = rose_node->next, ++i);
+@@ -1088,7 +1088,7 @@
+ {
+ ++*pos;
+
+- return (v == ROSE_PROC_START) ? rose_node_list
++ return (v == SEQ_START_TOKEN) ? rose_node_list
+ : ((struct rose_node *)v)->next;
+ }
+
+@@ -1101,7 +1101,7 @@
+ {
+ int i;
+
+- if (v == ROSE_PROC_START)
++ if (v == SEQ_START_TOKEN)
+ seq_puts(seq, "address mask n neigh neigh neigh\n");
+ else {
+ const struct rose_node *rose_node = v;
+@@ -1152,7 +1152,7 @@
+
+ spin_lock_bh(&rose_neigh_list_lock);
+ if (*pos == 0)
+- return ROSE_PROC_START;
++ return SEQ_START_TOKEN;
+
+ for (rose_neigh = rose_neigh_list; rose_neigh && i < *pos;
+ rose_neigh = rose_neigh->next, ++i);
+@@ -1164,7 +1164,7 @@
+ {
+ ++*pos;
+
+- return (v == ROSE_PROC_START) ? rose_neigh_list
++ return (v == SEQ_START_TOKEN) ? rose_neigh_list
+ : ((struct rose_neigh *)v)->next;
+ }
+
+@@ -1177,7 +1177,7 @@
+ {
+ int i;
+
+- if (v == ROSE_PROC_START)
++ if (v == SEQ_START_TOKEN)
+ seq_puts(seq,
+ "addr callsign dev count use mode restart t0 tf digipeaters\n");
+ else {
+@@ -1234,7 +1234,7 @@
+
+ spin_lock_bh(&rose_route_list_lock);
+ if (*pos == 0)
+- return ROSE_PROC_START;
++ return SEQ_START_TOKEN;
+
+ for (rose_route = rose_route_list; rose_route && i < *pos;
+ rose_route = rose_route->next, ++i);
+@@ -1246,7 +1246,7 @@
+ {
+ ++*pos;
+
+- return (v == ROSE_PROC_START) ? rose_route_list
++ return (v == SEQ_START_TOKEN) ? rose_route_list
+ : ((struct rose_route *)v)->next;
+ }
+
+@@ -1257,7 +1257,7 @@
+
+ static int rose_route_show(struct seq_file *seq, void *v)
+ {
+- if (v == ROSE_PROC_START)
++ if (v == SEQ_START_TOKEN)
+ seq_puts(seq,
+ "lci address callsign neigh <-> lci address callsign neigh\n");
+ else {
+Index: linux-2.6.0-test5/net/rxrpc/call.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/rxrpc/call.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/rxrpc/call.c 2003-09-27 11:38:42.211111320 +0800
+@@ -53,20 +53,25 @@
+ };
+
+ const char *rxrpc_pkts[] = {
+- "?00", "data", "ack", "busy", "abort", "ackall", "chall", "resp", "debug",
++ "?00",
++ "data", "ack", "busy", "abort", "ackall", "chall", "resp", "debug",
+ "?09", "?10", "?11", "?12", "?13", "?14", "?15"
+ };
+
+ const char *rxrpc_acks[] = {
+- "---", "REQ", "DUP", "SEQ", "WIN", "MEM", "PNG", "PNR", "DLY", "IDL", "-?-"
++ "---", "REQ", "DUP", "SEQ", "WIN", "MEM", "PNG", "PNR", "DLY", "IDL",
++ "-?-"
+ };
+
+ static const char _acktype[] = "NA-";
+
+ static void rxrpc_call_receive_packet(struct rxrpc_call *call);
+-static void rxrpc_call_receive_data_packet(struct rxrpc_call *call, struct rxrpc_message *msg);
+-static void rxrpc_call_receive_ack_packet(struct rxrpc_call *call, struct rxrpc_message *msg);
+-static void rxrpc_call_definitively_ACK(struct rxrpc_call *call, rxrpc_seq_t higest);
++static void rxrpc_call_receive_data_packet(struct rxrpc_call *call,
++ struct rxrpc_message *msg);
++static void rxrpc_call_receive_ack_packet(struct rxrpc_call *call,
++ struct rxrpc_message *msg);
++static void rxrpc_call_definitively_ACK(struct rxrpc_call *call,
++ rxrpc_seq_t higest);
+ static void rxrpc_call_resend(struct rxrpc_call *call, rxrpc_seq_t highest);
+ static int __rxrpc_call_read_data(struct rxrpc_call *call);
+
+@@ -75,7 +80,7 @@
+ rxrpc_seq_t seq,
+ size_t count);
+ #define _state(call) \
+- _debug("[[[ state %s ]]]",rxrpc_call_states[call->app_call_state]);
++ _debug("[[[ state %s ]]]", rxrpc_call_states[call->app_call_state]);
+
+ static void rxrpc_call_default_attn_func(struct rxrpc_call *call)
+ {
+@@ -103,7 +108,7 @@
+ {
+ struct rxrpc_call *call = (struct rxrpc_call *) _call;
+
+- _debug("ACKS TIMEOUT %05lu",jiffies - call->cjif);
++ _debug("ACKS TIMEOUT %05lu", jiffies - call->cjif);
+
+ call->flags |= RXRPC_CALL_ACKS_TIMO;
+ rxrpc_krxiod_queue_call(call);
+@@ -113,7 +118,7 @@
+ {
+ struct rxrpc_call *call = (struct rxrpc_call *) _call;
+
+- _debug("RCV TIMEOUT %05lu",jiffies - call->cjif);
++ _debug("RCV TIMEOUT %05lu", jiffies - call->cjif);
+
+ call->flags |= RXRPC_CALL_RCV_TIMO;
+ rxrpc_krxiod_queue_call(call);
+@@ -133,15 +138,18 @@
+ /*
+ * calculate a timeout based on an RTT value
+ */
+-static inline unsigned long __rxrpc_rtt_based_timeout(struct rxrpc_call *call, unsigned long val)
++static inline unsigned long __rxrpc_rtt_based_timeout(struct rxrpc_call *call,
++ unsigned long val)
+ {
+- unsigned long expiry = call->conn->peer->rtt / (1000000/HZ);
++ unsigned long expiry = call->conn->peer->rtt / (1000000 / HZ);
+
+ expiry += 10;
+- if (expiry<HZ/25) expiry = HZ/25;
+- if (expiry>HZ) expiry = HZ;
++ if (expiry < HZ / 25)
++ expiry = HZ / 25;
++ if (expiry > HZ)
++ expiry = HZ;
+
+- _leave(" = %lu jiffies",expiry);
++ _leave(" = %lu jiffies", expiry);
+ return jiffies + expiry;
+ } /* end __rxrpc_rtt_based_timeout() */
+
+@@ -154,7 +162,7 @@
+ {
+ struct rxrpc_call *call;
+
+- _enter("%p",conn);
++ _enter("%p", conn);
+
+ /* allocate and initialise a call record */
+ call = (struct rxrpc_call *) get_zeroed_page(GFP_KERNEL);
+@@ -163,7 +171,7 @@
+ return -ENOMEM;
+ }
+
+- atomic_set(&call->usage,1);
++ atomic_set(&call->usage, 1);
+
+ init_waitqueue_head(&call->waitq);
+ spin_lock_init(&call->lock);
+@@ -200,7 +208,7 @@
+
+ call->cjif = jiffies;
+
+- _leave(" = 0 (%p)",call);
++ _leave(" = 0 (%p)", call);
+
+ *_call = call;
+
+@@ -217,34 +225,37 @@
+ rxrpc_call_aemap_func_t aemap,
+ struct rxrpc_call **_call)
+ {
+- DECLARE_WAITQUEUE(myself,current);
++ DECLARE_WAITQUEUE(myself, current);
+
+ struct rxrpc_call *call;
+ int ret, cix, loop;
+
+- _enter("%p",conn);
++ _enter("%p", conn);
+
+ /* allocate and initialise a call record */
+- ret = __rxrpc_create_call(conn,&call);
+- if (ret<0) {
+- _leave(" = %d",ret);
++ ret = __rxrpc_create_call(conn, &call);
++ if (ret < 0) {
++ _leave(" = %d", ret);
+ return ret;
+ }
+
+ call->app_call_state = RXRPC_CSTATE_CLNT_SND_ARGS;
+- if (attn) call->app_attn_func = attn;
+- if (error) call->app_error_func = error;
+- if (aemap) call->app_aemap_func = aemap;
++ if (attn)
++ call->app_attn_func = attn;
++ if (error)
++ call->app_error_func = error;
++ if (aemap)
++ call->app_aemap_func = aemap;
+
+ _state(call);
+
+ spin_lock(&conn->lock);
+ set_current_state(TASK_INTERRUPTIBLE);
+- add_wait_queue(&conn->chanwait,&myself);
++ add_wait_queue(&conn->chanwait, &myself);
+
+ try_again:
+ /* try to find an unused channel */
+- for (cix=0; cix<4; cix++)
++ for (cix = 0; cix < 4; cix++)
+ if (!conn->channels[cix])
+ goto obtained_chan;
+
+@@ -263,14 +274,15 @@
+
+ /* got a channel - now attach to the connection */
+ obtained_chan:
+- remove_wait_queue(&conn->chanwait,&myself);
++ remove_wait_queue(&conn->chanwait, &myself);
+ set_current_state(TASK_RUNNING);
+
+ /* concoct a unique call number */
+ next_callid:
+ call->call_id = htonl(++conn->call_counter);
+- for (loop=0; loop<4; loop++)
+- if (conn->channels[loop] && conn->channels[loop]->call_id==call->call_id)
++ for (loop = 0; loop < 4; loop++)
++ if (conn->channels[loop] &&
++ conn->channels[loop]->call_id == call->call_id)
+ goto next_callid;
+
+ rxrpc_get_connection(conn);
+@@ -281,24 +293,23 @@
+ spin_unlock(&conn->lock);
+
+ down_write(&rxrpc_calls_sem);
+- list_add_tail(&call->call_link,&rxrpc_calls);
++ list_add_tail(&call->call_link, &rxrpc_calls);
+ up_write(&rxrpc_calls_sem);
+
+ __RXACCT(atomic_inc(&rxrpc_call_count));
+ *_call = call;
+
+- _leave(" = 0 (call=%p cix=%u)",call,cix);
++ _leave(" = 0 (call=%p cix=%u)", call, cix);
+ return 0;
+
+ error_unwait:
+- remove_wait_queue(&conn->chanwait,&myself);
++ remove_wait_queue(&conn->chanwait, &myself);
+ set_current_state(TASK_RUNNING);
+ spin_unlock(&conn->lock);
+
+- free_page((unsigned long)call);
+- _leave(" = %d",ret);
++ free_page((unsigned long) call);
++ _leave(" = %d", ret);
+ return ret;
+-
+ } /* end rxrpc_create_call() */
+
+ /*****************************************************************************/
+@@ -315,18 +326,18 @@
+
+ cix = ntohl(msg->hdr.cid) & RXRPC_CHANNELMASK;
+
+- _enter("%p,%u,%u",conn,ntohl(msg->hdr.callNumber),cix);
++ _enter("%p,%u,%u", conn, ntohl(msg->hdr.callNumber), cix);
+
+ /* allocate and initialise a call record */
+- ret = __rxrpc_create_call(conn,&call);
+- if (ret<0) {
+- _leave(" = %d",ret);
++ ret = __rxrpc_create_call(conn, &call);
++ if (ret < 0) {
++ _leave(" = %d", ret);
+ return ret;
+ }
+
+ call->pkt_rcv_count = 1;
+ call->app_call_state = RXRPC_CSTATE_SRVR_RCV_OPID;
+- call->app_mark = sizeof(u32);
++ call->app_mark = sizeof(uint32_t);
+
+ _state(call);
+
+@@ -348,20 +359,20 @@
+
+ spin_unlock(&conn->lock);
+
+- if (ret<0) {
+- free_page((unsigned long)call);
++ if (ret < 0) {
++ free_page((unsigned long) call);
+ call = NULL;
+ }
+
+- if (ret==0) {
++ if (ret == 0) {
+ down_write(&rxrpc_calls_sem);
+- list_add_tail(&call->call_link,&rxrpc_calls);
++ list_add_tail(&call->call_link, &rxrpc_calls);
+ up_write(&rxrpc_calls_sem);
+ __RXACCT(atomic_inc(&rxrpc_call_count));
+ *_call = call;
+ }
+
+- _leave(" = %d [%p]",ret,call);
++ _leave(" = %d [%p]", ret, call);
+ return ret;
+ } /* end rxrpc_incoming_call() */
+
+@@ -377,10 +388,11 @@
+ _enter("%p{u=%d}",call,atomic_read(&call->usage));
+
+ /* sanity check */
+- if (atomic_read(&call->usage)<=0)
++ if (atomic_read(&call->usage) <= 0)
+ BUG();
+
+- /* to prevent a race, the decrement and the de-list must be effectively atomic */
++ /* to prevent a race, the decrement and the de-list must be effectively
++ * atomic */
+ spin_lock(&conn->lock);
+ if (likely(!atomic_dec_and_test(&call->usage))) {
+ spin_unlock(&conn->lock);
+@@ -388,7 +400,7 @@
+ return;
+ }
+
+- if (conn->channels[ntohl(call->chan_ix)]==call)
++ if (conn->channels[ntohl(call->chan_ix)] == call)
+ conn->channels[ntohl(call->chan_ix)] = NULL;
+
+ spin_unlock(&conn->lock);
+@@ -412,25 +424,29 @@
+ rxrpc_put_message(call->snd_ping);
+
+ while (!list_empty(&call->acks_pendq)) {
+- msg = list_entry(call->acks_pendq.next,struct rxrpc_message,link);
++ msg = list_entry(call->acks_pendq.next,
++ struct rxrpc_message, link);
+ list_del(&msg->link);
+ rxrpc_put_message(msg);
+ }
+
+ while (!list_empty(&call->rcv_receiveq)) {
+- msg = list_entry(call->rcv_receiveq.next,struct rxrpc_message,link);
++ msg = list_entry(call->rcv_receiveq.next,
++ struct rxrpc_message, link);
+ list_del(&msg->link);
+ rxrpc_put_message(msg);
+ }
+
+ while (!list_empty(&call->app_readyq)) {
+- msg = list_entry(call->app_readyq.next,struct rxrpc_message,link);
++ msg = list_entry(call->app_readyq.next,
++ struct rxrpc_message, link);
+ list_del(&msg->link);
+ rxrpc_put_message(msg);
+ }
+
+ while (!list_empty(&call->app_unreadyq)) {
+- msg = list_entry(call->app_unreadyq.next,struct rxrpc_message,link);
++ msg = list_entry(call->app_unreadyq.next,
++ struct rxrpc_message, link);
+ list_del(&msg->link);
+ rxrpc_put_message(msg);
+ }
+@@ -442,7 +458,7 @@
+ up_write(&rxrpc_calls_sem);
+
+ __RXACCT(atomic_dec(&rxrpc_call_count));
+- free_page((unsigned long)call);
++ free_page((unsigned long) call);
+
+ _leave(" [destroyed]");
+ } /* end rxrpc_put_call() */
+@@ -451,7 +467,8 @@
+ /*
+ * actually generate a normal ACK
+ */
+-static inline int __rxrpc_call_gen_normal_ACK(struct rxrpc_call *call, rxrpc_seq_t seq)
++static inline int __rxrpc_call_gen_normal_ACK(struct rxrpc_call *call,
++ rxrpc_seq_t seq)
+ {
+ struct rxrpc_message *msg;
+ struct iovec diov[3];
+@@ -478,35 +495,36 @@
+
+ diov[0].iov_len = sizeof(struct rxrpc_ackpacket);
+ diov[0].iov_base = &call->ackr;
+- diov[1].iov_len = (call->ackr_pend_cnt+3);
++ diov[1].iov_len = call->ackr_pend_cnt + 3;
+ diov[1].iov_base = call->ackr_array;
+ diov[2].iov_len = sizeof(aux);
+ diov[2].iov_base = &aux;
+
+ /* build and send the message */
+- ret = rxrpc_conn_newmsg(call->conn,call,RXRPC_PACKET_TYPE_ACK,3,diov,GFP_KERNEL,&msg);
+- if (ret<0)
++ ret = rxrpc_conn_newmsg(call->conn,call, RXRPC_PACKET_TYPE_ACK,
++ 3, diov, GFP_KERNEL, &msg);
++ if (ret < 0)
+ goto out;
+
+ msg->seq = seq;
+ msg->hdr.seq = htonl(seq);
+ msg->hdr.flags |= RXRPC_SLOW_START_OK;
+
+- ret = rxrpc_conn_sendmsg(call->conn,msg);
++ ret = rxrpc_conn_sendmsg(call->conn, msg);
+ rxrpc_put_message(msg);
+- if (ret<0)
++ if (ret < 0)
+ goto out;
+ call->pkt_snd_count++;
+
+ /* count how many actual ACKs there were at the front */
+- for (delta=0; delta<call->ackr_pend_cnt; delta++)
+- if (call->ackr_array[delta]!=RXRPC_ACK_TYPE_ACK)
++ for (delta = 0; delta < call->ackr_pend_cnt; delta++)
++ if (call->ackr_array[delta] != RXRPC_ACK_TYPE_ACK)
+ break;
+
+ call->ackr_pend_cnt -= delta; /* all ACK'd to this point */
+
+ /* crank the ACK window around */
+- if (delta==0) {
++ if (delta == 0) {
+ /* un-ACK'd window */
+ }
+ else if (delta < RXRPC_CALL_ACK_WINDOW_SIZE) {
+@@ -528,22 +546,26 @@
+ /* fully ACK'd window
+ * - just clear the whole thing
+ */
+- memset(&call->ackr_array,RXRPC_ACK_TYPE_NACK,sizeof(call->ackr_array));
++ memset(&call->ackr_array,
++ RXRPC_ACK_TYPE_NACK,
++ sizeof(call->ackr_array));
+ }
+
+ /* clear this ACK */
+- memset(&call->ackr,0,sizeof(call->ackr));
++ memset(&call->ackr, 0, sizeof(call->ackr));
+
+ out:
+- if (!call->app_call_state) printk("___ STATE 0 ___\n");
++ if (!call->app_call_state)
++ printk("___ STATE 0 ___\n");
+ return ret;
+ } /* end __rxrpc_call_gen_normal_ACK() */
+
+ /*****************************************************************************/
+ /*
+- * note the reception of a packet in the call's ACK records and generate an appropriate ACK packet
+- * if necessary
+- * - returns 0 if packet should be processed, 1 if packet should be ignored and -ve on an error
++ * note the reception of a packet in the call's ACK records and generate an
++ * appropriate ACK packet if necessary
++ * - returns 0 if packet should be processed, 1 if packet should be ignored
++ * and -ve on an error
+ */
+ static int rxrpc_call_generate_ACK(struct rxrpc_call *call,
+ struct rxrpc_header *hdr,
+@@ -555,19 +577,20 @@
+ int ret = 0, err;
+ u8 special_ACK, do_ACK, force;
+
+- _enter("%p,%p { seq=%d tp=%d fl=%02x }",call,hdr,ntohl(hdr->seq),hdr->type,hdr->flags);
++ _enter("%p,%p { seq=%d tp=%d fl=%02x }",
++ call, hdr, ntohl(hdr->seq), hdr->type, hdr->flags);
+
+ seq = ntohl(hdr->seq);
+ offset = seq - call->ackr_win_bot;
+ do_ACK = RXRPC_ACK_DELAY;
+ special_ACK = 0;
+- force = (seq==1);
++ force = (seq == 1);
+
+ if (call->ackr_high_seq < seq)
+ call->ackr_high_seq = seq;
+
+ /* deal with generation of obvious special ACKs first */
+- if (ack && ack->reason==RXRPC_ACK_PING) {
++ if (ack && ack->reason == RXRPC_ACK_PING) {
+ special_ACK = RXRPC_ACK_PING_RESPONSE;
+ ret = 1;
+ goto gen_ACK;
+@@ -594,9 +617,9 @@
+ /* okay... it's a normal data packet inside the ACK window */
+ call->ackr_array[offset] = RXRPC_ACK_TYPE_ACK;
+
+- if (offset<call->ackr_pend_cnt) {
++ if (offset < call->ackr_pend_cnt) {
+ }
+- else if (offset>call->ackr_pend_cnt) {
++ else if (offset > call->ackr_pend_cnt) {
+ do_ACK = RXRPC_ACK_OUT_OF_SEQUENCE;
+ call->ackr_pend_cnt = offset;
+ goto gen_ACK;
+@@ -616,8 +639,8 @@
+ }
+
+ /* re-ACK packets previously received out-of-order */
+- for (offset++; offset<RXRPC_CALL_ACK_WINDOW_SIZE; offset++)
+- if (call->ackr_array[offset]!=RXRPC_ACK_TYPE_ACK)
++ for (offset++; offset < RXRPC_CALL_ACK_WINDOW_SIZE; offset++)
++ if (call->ackr_array[offset] != RXRPC_ACK_TYPE_ACK)
+ break;
+
+ call->ackr_pend_cnt = offset;
+@@ -629,55 +652,61 @@
+ gen_ACK:
+ _debug("%05lu ACKs pend=%u norm=%s special=%s%s",
+ jiffies - call->cjif,
+- call->ackr_pend_cnt,rxrpc_acks[do_ACK],rxrpc_acks[special_ACK],
++ call->ackr_pend_cnt,
++ rxrpc_acks[do_ACK],
++ rxrpc_acks[special_ACK],
+ force ? " immediate" :
+- do_ACK==RXRPC_ACK_REQUESTED ? " merge-req" :
++ do_ACK == RXRPC_ACK_REQUESTED ? " merge-req" :
+ hdr->flags & RXRPC_LAST_PACKET ? " finalise" :
+ " defer"
+ );
+
+ /* send any pending normal ACKs if need be */
+- if (call->ackr_pend_cnt>0) {
++ if (call->ackr_pend_cnt > 0) {
+ /* fill out the appropriate form */
+- call->ackr.bufferSpace = htons(RXRPC_CALL_ACK_WINDOW_SIZE);
+- call->ackr.maxSkew = htons(min(call->ackr_high_seq - seq,65535U));
+- call->ackr.firstPacket = htonl(call->ackr_win_bot);
+- call->ackr.previousPacket = call->ackr_prev_seq;
+- call->ackr.serial = hdr->serial;
+- call->ackr.nAcks = call->ackr_pend_cnt;
++ call->ackr.bufferSpace = htons(RXRPC_CALL_ACK_WINDOW_SIZE);
++ call->ackr.maxSkew = htons(min(call->ackr_high_seq - seq,
++ 65535U));
++ call->ackr.firstPacket = htonl(call->ackr_win_bot);
++ call->ackr.previousPacket = call->ackr_prev_seq;
++ call->ackr.serial = hdr->serial;
++ call->ackr.nAcks = call->ackr_pend_cnt;
+
+- if (do_ACK==RXRPC_ACK_REQUESTED)
++ if (do_ACK == RXRPC_ACK_REQUESTED)
+ call->ackr.reason = do_ACK;
+
+ /* generate the ACK immediately if necessary */
+ if (special_ACK || force) {
+- err = __rxrpc_call_gen_normal_ACK(call,do_ACK==RXRPC_ACK_DELAY ? 0 : seq);
+- if (err<0) {
++ err = __rxrpc_call_gen_normal_ACK(
++ call, do_ACK == RXRPC_ACK_DELAY ? 0 : seq);
++ if (err < 0) {
+ ret = err;
+ goto out;
+ }
+ }
+ }
+
+- if (call->ackr.reason==RXRPC_ACK_REQUESTED)
++ if (call->ackr.reason == RXRPC_ACK_REQUESTED)
+ call->ackr_dfr_seq = seq;
+
+- /* start the ACK timer if not running if there are any pending deferred ACKs */
+- if (call->ackr_pend_cnt>0 &&
+- call->ackr.reason!=RXRPC_ACK_REQUESTED &&
++ /* start the ACK timer if not running if there are any pending deferred
++ * ACKs */
++ if (call->ackr_pend_cnt > 0 &&
++ call->ackr.reason != RXRPC_ACK_REQUESTED &&
+ !timer_pending(&call->ackr_dfr_timo)
+ ) {
+ unsigned long timo;
+
+ timo = rxrpc_call_dfr_ack_timeout + jiffies;
+
+- _debug("START ACKR TIMER for cj=%lu",timo-call->cjif);
++ _debug("START ACKR TIMER for cj=%lu", timo-call->cjif);
+
+ spin_lock(&call->lock);
+- mod_timer(&call->ackr_dfr_timo,timo);
++ mod_timer(&call->ackr_dfr_timo, timo);
+ spin_unlock(&call->lock);
+ }
+- else if ((call->ackr_pend_cnt==0 || call->ackr.reason==RXRPC_ACK_REQUESTED) &&
++ else if ((call->ackr_pend_cnt == 0 ||
++ call->ackr.reason == RXRPC_ACK_REQUESTED) &&
+ timer_pending(&call->ackr_dfr_timo)
+ ) {
+ /* stop timer if no pending ACKs */
+@@ -689,21 +718,25 @@
+ if (special_ACK) {
+ struct rxrpc_ackpacket ack;
+ struct iovec diov[2];
+- u8 acks[1] = { RXRPC_ACK_TYPE_ACK };
++ uint8_t acks[1] = { RXRPC_ACK_TYPE_ACK };
+
+ /* fill out the appropriate form */
+- ack.bufferSpace = htons(RXRPC_CALL_ACK_WINDOW_SIZE);
+- ack.maxSkew = htons(min(call->ackr_high_seq - seq,65535U));
+- ack.firstPacket = htonl(call->ackr_win_bot);
+- ack.previousPacket = call->ackr_prev_seq;
+- ack.serial = hdr->serial;
+- ack.reason = special_ACK;
+- ack.nAcks = 0;
+- //ack.nAcks = special_ACK==RXRPC_ACK_OUT_OF_SEQUENCE ? 0 : hdr->seq ? 1 : 0;
+-
+- _proto("Rx Sending s-ACK { m=%hu f=#%u p=#%u s=%%%u r=%s n=%u }",
+- ntohs(ack.maxSkew),ntohl(ack.firstPacket),ntohl(ack.previousPacket),
+- ntohl(ack.serial),rxrpc_acks[ack.reason],ack.nAcks);
++ ack.bufferSpace = htons(RXRPC_CALL_ACK_WINDOW_SIZE);
++ ack.maxSkew = htons(min(call->ackr_high_seq - seq,65535U));
++ ack.firstPacket = htonl(call->ackr_win_bot);
++ ack.previousPacket = call->ackr_prev_seq;
++ ack.serial = hdr->serial;
++ ack.reason = special_ACK;
++ ack.nAcks = 0;
++
++ _proto("Rx Sending s-ACK"
++ " { m=%hu f=#%u p=#%u s=%%%u r=%s n=%u }",
++ ntohs(ack.maxSkew),
++ ntohl(ack.firstPacket),
++ ntohl(ack.previousPacket),
++ ntohl(ack.serial),
++ rxrpc_acks[ack.reason],
++ ack.nAcks);
+
+ diov[0].iov_len = sizeof(struct rxrpc_ackpacket);
+ diov[0].iov_base = &ack;
+@@ -711,11 +744,11 @@
+ diov[1].iov_base = acks;
+
+ /* build and send the message */
+- err = rxrpc_conn_newmsg(call->conn,call,RXRPC_PACKET_TYPE_ACK,
+- hdr->seq ? 2 : 1,diov,
++ err = rxrpc_conn_newmsg(call->conn,call, RXRPC_PACKET_TYPE_ACK,
++ hdr->seq ? 2 : 1, diov,
+ GFP_KERNEL,
+ &msg);
+- if (err<0) {
++ if (err < 0) {
+ ret = err;
+ goto out;
+ }
+@@ -724,9 +757,9 @@
+ msg->hdr.seq = htonl(seq);
+ msg->hdr.flags |= RXRPC_SLOW_START_OK;
+
+- err = rxrpc_conn_sendmsg(call->conn,msg);
++ err = rxrpc_conn_sendmsg(call->conn, msg);
+ rxrpc_put_message(msg);
+- if (err<0) {
++ if (err < 0) {
+ ret = err;
+ goto out;
+ }
+@@ -737,7 +770,7 @@
+ if (hdr->seq)
+ call->ackr_prev_seq = hdr->seq;
+
+- _leave(" = %d",ret);
++ _leave(" = %d", ret);
+ return ret;
+ } /* end rxrpc_call_generate_ACK() */
+
+@@ -748,7 +781,7 @@
+ */
+ void rxrpc_call_do_stuff(struct rxrpc_call *call)
+ {
+- _enter("%p{flags=%lx}",call,call->flags);
++ _enter("%p{flags=%lx}", call, call->flags);
+
+ /* handle packet reception */
+ if (call->flags & RXRPC_CALL_RCV_PKT) {
+@@ -761,19 +794,19 @@
+ if (call->flags & RXRPC_CALL_ACKS_TIMO) {
+ _debug("- overdue ACK timeout");
+ call->flags &= ~RXRPC_CALL_ACKS_TIMO;
+- rxrpc_call_resend(call,call->snd_seq_count);
++ rxrpc_call_resend(call, call->snd_seq_count);
+ }
+
+ /* handle lack of reception */
+ if (call->flags & RXRPC_CALL_RCV_TIMO) {
+ _debug("- reception timeout");
+ call->flags &= ~RXRPC_CALL_RCV_TIMO;
+- rxrpc_call_abort(call,-EIO);
++ rxrpc_call_abort(call, -EIO);
+ }
+
+ /* handle deferred ACKs */
+ if (call->flags & RXRPC_CALL_ACKR_TIMO ||
+- (call->ackr.nAcks>0 && call->ackr.reason==RXRPC_ACK_REQUESTED)
++ (call->ackr.nAcks > 0 && call->ackr.reason == RXRPC_ACK_REQUESTED)
+ ) {
+ _debug("- deferred ACK timeout: cj=%05lu r=%s n=%u",
+ jiffies - call->cjif,
+@@ -782,9 +815,10 @@
+
+ call->flags &= ~RXRPC_CALL_ACKR_TIMO;
+
+- if (call->ackr.nAcks>0 && call->app_call_state!=RXRPC_CSTATE_ERROR) {
++ if (call->ackr.nAcks > 0 &&
++ call->app_call_state != RXRPC_CSTATE_ERROR) {
+ /* generate ACK */
+- __rxrpc_call_gen_normal_ACK(call,call->ackr_dfr_seq);
++ __rxrpc_call_gen_normal_ACK(call, call->ackr_dfr_seq);
+ call->ackr_dfr_seq = 0;
+ }
+ }
+@@ -807,10 +841,11 @@
+ int ret;
+ u32 _error;
+
+- _enter("%p{%08x},%p{%d},%d",conn,ntohl(conn->conn_id),call,ntohl(call->call_id),errno);
++ _enter("%p{%08x},%p{%d},%d",
++ conn, ntohl(conn->conn_id), call, ntohl(call->call_id), errno);
+
+ /* if this call is already aborted, then just wake up any waiters */
+- if (call->app_call_state==RXRPC_CSTATE_ERROR) {
++ if (call->app_call_state == RXRPC_CSTATE_ERROR) {
+ spin_unlock(&call->lock);
+ call->app_error_func(call);
+ _leave(" = 0");
+@@ -820,12 +855,12 @@
+ rxrpc_get_call(call);
+
+ /* change the state _with_ the lock still held */
+- call->app_call_state = RXRPC_CSTATE_ERROR;
+- call->app_err_state = RXRPC_ESTATE_LOCAL_ABORT;
+- call->app_errno = errno;
+- call->app_mark = RXRPC_APP_MARK_EOF;
+- call->app_read_buf = NULL;
+- call->app_async_read = 0;
++ call->app_call_state = RXRPC_CSTATE_ERROR;
++ call->app_err_state = RXRPC_ESTATE_LOCAL_ABORT;
++ call->app_errno = errno;
++ call->app_mark = RXRPC_APP_MARK_EOF;
++ call->app_read_buf = NULL;
++ call->app_async_read = 0;
+
+ _state(call);
+
+@@ -840,22 +875,25 @@
+ del_timer_sync(&call->ackr_dfr_timo);
+
+ if (rxrpc_call_is_ack_pending(call))
+- __rxrpc_call_gen_normal_ACK(call,0);
++ __rxrpc_call_gen_normal_ACK(call, 0);
+
+- /* send the abort packet only if we actually traded some other packets */
++ /* send the abort packet only if we actually traded some other
++ * packets */
+ ret = 0;
+ if (call->pkt_snd_count || call->pkt_rcv_count) {
+ /* actually send the abort */
+- _proto("Rx Sending Call ABORT { data=%d }",call->app_abort_code);
++ _proto("Rx Sending Call ABORT { data=%d }",
++ call->app_abort_code);
+
+ _error = htonl(call->app_abort_code);
+
+ diov[0].iov_len = sizeof(_error);
+ diov[0].iov_base = &_error;
+
+- ret = rxrpc_conn_newmsg(conn,call,RXRPC_PACKET_TYPE_ABORT,1,diov,GFP_KERNEL,&msg);
+- if (ret==0) {
+- ret = rxrpc_conn_sendmsg(conn,msg);
++ ret = rxrpc_conn_newmsg(conn, call, RXRPC_PACKET_TYPE_ABORT,
++ 1, diov, GFP_KERNEL, &msg);
++ if (ret == 0) {
++ ret = rxrpc_conn_sendmsg(conn, msg);
+ rxrpc_put_message(msg);
+ }
+ }
+@@ -865,8 +903,7 @@
+
+ rxrpc_put_call(call);
+
+- _leave(" = %d",ret);
+-
++ _leave(" = %d", ret);
+ return ret;
+ } /* end __rxrpc_call_abort() */
+
+@@ -879,7 +916,7 @@
+ {
+ spin_lock(&call->lock);
+
+- return __rxrpc_call_abort(call,error);
++ return __rxrpc_call_abort(call, error);
+
+ } /* end rxrpc_call_abort() */
+
+@@ -891,11 +928,12 @@
+ {
+ struct rxrpc_message *msg;
+ struct list_head *_p;
+- u32 data32;
++ uint32_t data32;
+
+- _enter("%p",call);
++ _enter("%p", call);
+
+- rxrpc_get_call(call); /* must not go away too soon if aborted by app-layer */
++ rxrpc_get_call(call); /* must not go away too soon if aborted by
++ * app-layer */
+
+ while (!list_empty(&call->rcv_receiveq)) {
+ /* try to get next packet */
+@@ -907,9 +945,10 @@
+ }
+ spin_unlock(&call->lock);
+
+- if (!_p) break;
++ if (!_p)
++ break;
+
+- msg = list_entry(_p,struct rxrpc_message,link);
++ msg = list_entry(_p, struct rxrpc_message, link);
+
+ _proto("Rx %05lu Received %s packet (%%%u,#%u,%c%c%c%c%c)",
+ jiffies - call->cjif,
+@@ -927,9 +966,10 @@
+ /* deal with data packets */
+ case RXRPC_PACKET_TYPE_DATA:
+ /* ACK the packet if necessary */
+- switch (rxrpc_call_generate_ACK(call,&msg->hdr,NULL)) {
++ switch (rxrpc_call_generate_ACK(call, &msg->hdr,
++ NULL)) {
+ case 0: /* useful packet */
+- rxrpc_call_receive_data_packet(call,msg);
++ rxrpc_call_receive_data_packet(call, msg);
+ break;
+ case 1: /* duplicate or out-of-window packet */
+ break;
+@@ -941,29 +981,30 @@
+
+ /* deal with ACK packets */
+ case RXRPC_PACKET_TYPE_ACK:
+- rxrpc_call_receive_ack_packet(call,msg);
++ rxrpc_call_receive_ack_packet(call, msg);
+ break;
+
+ /* deal with abort packets */
+ case RXRPC_PACKET_TYPE_ABORT:
+ data32 = 0;
+- if (skb_copy_bits(msg->pkt,msg->offset,&data32,sizeof(data32))<0) {
++ if (skb_copy_bits(msg->pkt, msg->offset,
++ &data32, sizeof(data32)) < 0) {
+ printk("Rx Received short ABORT packet\n");
+ }
+ else {
+ data32 = ntohl(data32);
+ }
+
+- _proto("Rx Received Call ABORT { data=%d }",data32);
++ _proto("Rx Received Call ABORT { data=%d }", data32);
+
+ spin_lock(&call->lock);
+- call->app_call_state = RXRPC_CSTATE_ERROR;
+- call->app_err_state = RXRPC_ESTATE_PEER_ABORT;
+- call->app_abort_code = data32;
+- call->app_errno = -ECONNABORTED;
+- call->app_mark = RXRPC_APP_MARK_EOF;
+- call->app_read_buf = NULL;
+- call->app_async_read = 0;
++ call->app_call_state = RXRPC_CSTATE_ERROR;
++ call->app_err_state = RXRPC_ESTATE_PEER_ABORT;
++ call->app_abort_code = data32;
++ call->app_errno = -ECONNABORTED;
++ call->app_mark = RXRPC_APP_MARK_EOF;
++ call->app_read_buf = NULL;
++ call->app_async_read = 0;
+
+ /* ask the app to translate the error code */
+ call->app_aemap_func(call);
+@@ -974,7 +1015,8 @@
+
+ default:
+ /* deal with other packet types */
+- _proto("Rx Unsupported packet type %u (#%u)",msg->hdr.type,msg->seq);
++ _proto("Rx Unsupported packet type %u (#%u)",
++ msg->hdr.type, msg->seq);
+ break;
+ }
+
+@@ -990,14 +1032,18 @@
+ /*
+ * process next data packet
+ * - as the next data packet arrives:
+- * - it is queued on app_readyq _if_ it is the next one expected (app_ready_seq+1)
++ * - it is queued on app_readyq _if_ it is the next one expected
++ * (app_ready_seq+1)
+ * - it is queued on app_unreadyq _if_ it is not the next one expected
+- * - if a packet placed on app_readyq completely fills a hole leading up to the first packet
+- * on app_unreadyq, then packets now in sequence are tranferred to app_readyq
+- * - the application layer can only see packets on app_readyq (app_ready_qty bytes)
++ * - if a packet placed on app_readyq completely fills a hole leading up to
++ * the first packet on app_unreadyq, then packets now in sequence are
++ * tranferred to app_readyq
++ * - the application layer can only see packets on app_readyq
++ * (app_ready_qty bytes)
+ * - the application layer is prodded every time a new packet arrives
+ */
+-static void rxrpc_call_receive_data_packet(struct rxrpc_call *call, struct rxrpc_message *msg)
++static void rxrpc_call_receive_data_packet(struct rxrpc_call *call,
++ struct rxrpc_message *msg)
+ {
+ const struct rxrpc_operation *optbl, *op;
+ struct rxrpc_message *pmsg;
+@@ -1005,22 +1051,23 @@
+ int ret, lo, hi, rmtimo;
+ u32 opid;
+
+- _enter("%p{%u},%p{%u}",call,ntohl(call->call_id),msg,msg->seq);
++ _enter("%p{%u},%p{%u}", call, ntohl(call->call_id), msg, msg->seq);
+
+ rxrpc_get_message(msg);
+
+- /* add to the unready queue if we'd have to create a hole in the ready queue otherwise */
+- if (msg->seq != call->app_ready_seq+1) {
+- _debug("Call add packet %d to unreadyq",msg->seq);
++ /* add to the unready queue if we'd have to create a hole in the ready
++ * queue otherwise */
++ if (msg->seq != call->app_ready_seq + 1) {
++ _debug("Call add packet %d to unreadyq", msg->seq);
+
+ /* insert in seq order */
+ list_for_each(_p,&call->app_unreadyq) {
+- pmsg = list_entry(_p,struct rxrpc_message,link);
+- if (pmsg->seq>msg->seq)
++ pmsg = list_entry(_p, struct rxrpc_message, link);
++ if (pmsg->seq > msg->seq)
+ break;
+ }
+
+- list_add_tail(&msg->link,_p);
++ list_add_tail(&msg->link, _p);
+
+ _leave(" [unreadyq]");
+ return;
+@@ -1028,33 +1075,35 @@
+
+ /* next in sequence - simply append into the call's ready queue */
+ _debug("Call add packet %d to readyq (+%Zd => %Zd bytes)",
+- msg->seq,msg->dsize,call->app_ready_qty);
++ msg->seq, msg->dsize, call->app_ready_qty);
+
+ spin_lock(&call->lock);
+ call->app_ready_seq = msg->seq;
+ call->app_ready_qty += msg->dsize;
+- list_add_tail(&msg->link,&call->app_readyq);
++ list_add_tail(&msg->link, &call->app_readyq);
+
+ /* move unready packets to the readyq if we got rid of a hole */
+ while (!list_empty(&call->app_unreadyq)) {
+- pmsg = list_entry(call->app_unreadyq.next,struct rxrpc_message,link);
++ pmsg = list_entry(call->app_unreadyq.next,
++ struct rxrpc_message, link);
+
+- if (pmsg->seq != call->app_ready_seq+1)
++ if (pmsg->seq != call->app_ready_seq + 1)
+ break;
+
+ /* next in sequence - just move list-to-list */
+ _debug("Call transfer packet %d to readyq (+%Zd => %Zd bytes)",
+- pmsg->seq,pmsg->dsize,call->app_ready_qty);
++ pmsg->seq, pmsg->dsize, call->app_ready_qty);
+
+ call->app_ready_seq = pmsg->seq;
+ call->app_ready_qty += pmsg->dsize;
+ list_del_init(&pmsg->link);
+- list_add_tail(&pmsg->link,&call->app_readyq);
++ list_add_tail(&pmsg->link, &call->app_readyq);
+ }
+
+ /* see if we've got the last packet yet */
+ if (!list_empty(&call->app_readyq)) {
+- pmsg = list_entry(call->app_readyq.prev,struct rxrpc_message,link);
++ pmsg = list_entry(call->app_readyq.prev,
++ struct rxrpc_message, link);
+ if (pmsg->hdr.flags & RXRPC_LAST_PACKET) {
+ call->app_last_rcv = 1;
+ _debug("Last packet on readyq");
+@@ -1068,25 +1117,27 @@
+ _leave(" [error]");
+ return;
+
+- /* extract the operation ID from an incoming call if that's not yet been done */
++ /* extract the operation ID from an incoming call if that's not
++ * yet been done */
+ case RXRPC_CSTATE_SRVR_RCV_OPID:
+ spin_unlock(&call->lock);
+
+ /* handle as yet insufficient data for the operation ID */
+- if (call->app_ready_qty<4) {
++ if (call->app_ready_qty < 4) {
+ if (call->app_last_rcv)
+- rxrpc_call_abort(call,-EINVAL); /* trouble - last packet seen */
++ /* trouble - last packet seen */
++ rxrpc_call_abort(call, -EINVAL);
+
+ _leave("");
+ return;
+ }
+
+ /* pull the operation ID out of the buffer */
+- ret = rxrpc_call_read_data(call,&opid,sizeof(opid),0);
+- if (ret<0) {
+- printk("Unexpected error from read-data: %d\n",ret);
+- if (call->app_call_state!=RXRPC_CSTATE_ERROR)
+- rxrpc_call_abort(call,ret);
++ ret = rxrpc_call_read_data(call, &opid, sizeof(opid), 0);
++ if (ret < 0) {
++ printk("Unexpected error from read-data: %d\n", ret);
++ if (call->app_call_state != RXRPC_CSTATE_ERROR)
++ rxrpc_call_abort(call, ret);
+ _leave("");
+ return;
+ }
+@@ -1097,38 +1148,42 @@
+ lo = 0;
+ hi = call->conn->service->ops_end - optbl;
+
+- while (lo<hi) {
+- int mid = (hi+lo) / 2;
++ while (lo < hi) {
++ int mid = (hi + lo) / 2;
+ op = &optbl[mid];
+- if (call->app_opcode==op->id)
++ if (call->app_opcode == op->id)
+ goto found_op;
+- if (call->app_opcode>op->id)
+- lo = mid+1;
++ if (call->app_opcode > op->id)
++ lo = mid + 1;
+ else
+ hi = mid;
+ }
+
+ /* search failed */
+ kproto("Rx Client requested operation %d from %s service",
+- call->app_opcode,call->conn->service->name);
+- rxrpc_call_abort(call,-EINVAL);
++ call->app_opcode, call->conn->service->name);
++ rxrpc_call_abort(call, -EINVAL);
+ _leave(" [inval]");
+ return;
+
+ found_op:
+ _proto("Rx Client requested operation %s from %s service",
+- op->name,call->conn->service->name);
++ op->name, call->conn->service->name);
+
+- /* we're now waiting for the argument block (unless the call was aborted) */
++ /* we're now waiting for the argument block (unless the call
++ * was aborted) */
+ spin_lock(&call->lock);
+- if (call->app_call_state==RXRPC_CSTATE_SRVR_RCV_OPID ||
+- call->app_call_state==RXRPC_CSTATE_SRVR_SND_REPLY) {
++ if (call->app_call_state == RXRPC_CSTATE_SRVR_RCV_OPID ||
++ call->app_call_state == RXRPC_CSTATE_SRVR_SND_REPLY) {
+ if (!call->app_last_rcv)
+- call->app_call_state = RXRPC_CSTATE_SRVR_RCV_ARGS;
+- else if (call->app_ready_qty>0)
+- call->app_call_state = RXRPC_CSTATE_SRVR_GOT_ARGS;
++ call->app_call_state =
++ RXRPC_CSTATE_SRVR_RCV_ARGS;
++ else if (call->app_ready_qty > 0)
++ call->app_call_state =
++ RXRPC_CSTATE_SRVR_GOT_ARGS;
+ else
+- call->app_call_state = RXRPC_CSTATE_SRVR_SND_REPLY;
++ call->app_call_state =
++ RXRPC_CSTATE_SRVR_SND_REPLY;
+ call->app_mark = op->asize;
+ call->app_user = op->user;
+ }
+@@ -1166,20 +1221,21 @@
+
+ default:
+ /* deal with data reception in an unexpected state */
+- printk("Unexpected state [[[ %u ]]]\n",call->app_call_state);
+- __rxrpc_call_abort(call,-EBADMSG);
++ printk("Unexpected state [[[ %u ]]]\n", call->app_call_state);
++ __rxrpc_call_abort(call, -EBADMSG);
+ _leave("");
+ return;
+ }
+
+- if (call->app_call_state==RXRPC_CSTATE_CLNT_RCV_REPLY && call->app_last_rcv)
++ if (call->app_call_state == RXRPC_CSTATE_CLNT_RCV_REPLY &&
++ call->app_last_rcv)
+ BUG();
+
+ /* otherwise just invoke the data function whenever we can satisfy its desire for more
+ * data
+ */
+ _proto("Rx Received Op Data: st=%u qty=%Zu mk=%Zu%s",
+- call->app_call_state,call->app_ready_qty,call->app_mark,
++ call->app_call_state, call->app_ready_qty, call->app_mark,
+ call->app_last_rcv ? " last-rcvd" : "");
+
+ spin_lock(&call->lock);
+@@ -1196,8 +1252,8 @@
+ case -ECONNABORTED:
+ spin_unlock(&call->lock);
+ break;
+- default:
+- __rxrpc_call_abort(call,ret);
++ default:
++ __rxrpc_call_abort(call, ret);
+ break;
+ }
+
+@@ -1211,17 +1267,18 @@
+ /*
+ * received an ACK packet
+ */
+-static void rxrpc_call_receive_ack_packet(struct rxrpc_call *call, struct rxrpc_message *msg)
++static void rxrpc_call_receive_ack_packet(struct rxrpc_call *call,
++ struct rxrpc_message *msg)
+ {
+ struct rxrpc_ackpacket ack;
+ rxrpc_serial_t serial;
+ rxrpc_seq_t seq;
+ int ret;
+
+- _enter("%p{%u},%p{%u}",call,ntohl(call->call_id),msg,msg->seq);
++ _enter("%p{%u},%p{%u}", call, ntohl(call->call_id), msg, msg->seq);
+
+ /* extract the basic ACK record */
+- if (skb_copy_bits(msg->pkt,msg->offset,&ack,sizeof(ack))<0) {
++ if (skb_copy_bits(msg->pkt, msg->offset, &ack, sizeof(ack)) < 0) {
+ printk("Rx Received short ACK packet\n");
+ return;
+ }
+@@ -1241,10 +1298,14 @@
+ call->ackr.nAcks
+ );
+
+- /* check the other side isn't ACK'ing a sequence number I haven't sent yet */
+- if (ack.nAcks>0 && (seq > call->snd_seq_count || seq+ack.nAcks-1 > call->snd_seq_count)) {
+- printk("Received ACK (#%u-#%u) for unsent packet\n",seq,seq+ack.nAcks-1);
+- rxrpc_call_abort(call,-EINVAL);
++ /* check the other side isn't ACK'ing a sequence number I haven't sent
++ * yet */
++ if (ack.nAcks > 0 &&
++ (seq > call->snd_seq_count ||
++ seq + ack.nAcks - 1 > call->snd_seq_count)) {
++ printk("Received ACK (#%u-#%u) for unsent packet\n",
++ seq, seq + ack.nAcks - 1);
++ rxrpc_call_abort(call, -EINVAL);
+ _leave("");
+ return;
+ }
+@@ -1255,7 +1316,7 @@
+
+ /* find the prompting packet */
+ spin_lock(&call->lock);
+- if (call->snd_ping && call->snd_ping->hdr.serial==serial) {
++ if (call->snd_ping && call->snd_ping->hdr.serial == serial) {
+ /* it was a ping packet */
+ rttmsg = call->snd_ping;
+ call->snd_ping = NULL;
+@@ -1263,22 +1324,28 @@
+
+ if (rttmsg) {
+ rttmsg->rttdone = 1;
+- rxrpc_peer_calculate_rtt(call->conn->peer,rttmsg,msg);
++ rxrpc_peer_calculate_rtt(call->conn->peer,
++ rttmsg, msg);
+ rxrpc_put_message(rttmsg);
+ }
+ }
+ else {
+ struct list_head *_p;
+
+- /* it ought to be a data packet - look in the pending ACK list */
+- list_for_each(_p,&call->acks_pendq) {
+- rttmsg = list_entry(_p,struct rxrpc_message,link);
+- if (rttmsg->hdr.serial==serial) {
++ /* it ought to be a data packet - look in the pending
++ * ACK list */
++ list_for_each(_p, &call->acks_pendq) {
++ rttmsg = list_entry(_p, struct rxrpc_message,
++ link);
++ if (rttmsg->hdr.serial == serial) {
+ if (rttmsg->rttdone)
+- break; /* never do RTT twice without resending */
++ /* never do RTT twice without
++ * resending */
++ break;
+
+ rttmsg->rttdone = 1;
+- rxrpc_peer_calculate_rtt(call->conn->peer,rttmsg,msg);
++ rxrpc_peer_calculate_rtt(
++ call->conn->peer, rttmsg, msg);
+ break;
+ }
+ }
+@@ -1287,24 +1354,25 @@
+ }
+
+ switch (ack.reason) {
+- /* deal with negative/positive acknowledgement of data packets */
++ /* deal with negative/positive acknowledgement of data
++ * packets */
+ case RXRPC_ACK_REQUESTED:
+ case RXRPC_ACK_DELAY:
+ case RXRPC_ACK_IDLE:
+- rxrpc_call_definitively_ACK(call,seq-1);
++ rxrpc_call_definitively_ACK(call, seq - 1);
+
+ case RXRPC_ACK_DUPLICATE:
+ case RXRPC_ACK_OUT_OF_SEQUENCE:
+ case RXRPC_ACK_EXCEEDS_WINDOW:
+ call->snd_resend_cnt = 0;
+- ret = rxrpc_call_record_ACK(call,msg,seq,ack.nAcks);
+- if (ret<0)
+- rxrpc_call_abort(call,ret);
++ ret = rxrpc_call_record_ACK(call, msg, seq, ack.nAcks);
++ if (ret < 0)
++ rxrpc_call_abort(call, ret);
+ break;
+
+ /* respond to ping packets immediately */
+ case RXRPC_ACK_PING:
+- rxrpc_call_generate_ACK(call,&msg->hdr,&ack);
++ rxrpc_call_generate_ACK(call, &msg->hdr, &ack);
+ break;
+
+ /* only record RTT on ping response packets */
+@@ -1312,10 +1380,12 @@
+ if (call->snd_ping) {
+ struct rxrpc_message *rttmsg;
+
+- /* only do RTT stuff if the response matches the retained ping */
++ /* only do RTT stuff if the response matches the
++ * retained ping */
+ rttmsg = NULL;
+ spin_lock(&call->lock);
+- if (call->snd_ping && call->snd_ping->hdr.serial==ack.serial) {
++ if (call->snd_ping &&
++ call->snd_ping->hdr.serial == ack.serial) {
+ rttmsg = call->snd_ping;
+ call->snd_ping = NULL;
+ }
+@@ -1323,14 +1393,15 @@
+
+ if (rttmsg) {
+ rttmsg->rttdone = 1;
+- rxrpc_peer_calculate_rtt(call->conn->peer,rttmsg,msg);
++ rxrpc_peer_calculate_rtt(call->conn->peer,
++ rttmsg, msg);
+ rxrpc_put_message(rttmsg);
+ }
+ }
+ break;
+
+ default:
+- printk("Unsupported ACK reason %u\n",ack.reason);
++ printk("Unsupported ACK reason %u\n", ack.reason);
+ break;
+ }
+
+@@ -1339,38 +1410,44 @@
+
+ /*****************************************************************************/
+ /*
+- * record definitive ACKs for all messages up to and including the one with the 'highest' seq
++ * record definitive ACKs for all messages up to and including the one with the
++ * 'highest' seq
+ */
+-static void rxrpc_call_definitively_ACK(struct rxrpc_call *call, rxrpc_seq_t highest)
++static void rxrpc_call_definitively_ACK(struct rxrpc_call *call,
++ rxrpc_seq_t highest)
+ {
+ struct rxrpc_message *msg;
+ int now_complete;
+
+- _enter("%p{ads=%u},%u",call,call->acks_dftv_seq,highest);
++ _enter("%p{ads=%u},%u", call, call->acks_dftv_seq, highest);
+
+- while (call->acks_dftv_seq<highest) {
++ while (call->acks_dftv_seq < highest) {
+ call->acks_dftv_seq++;
+
+- _proto("Definitive ACK on packet #%u",call->acks_dftv_seq);
++ _proto("Definitive ACK on packet #%u", call->acks_dftv_seq);
+
+- /* discard those at front of queue until message with highest ACK is found */
++ /* discard those at front of queue until message with highest
++ * ACK is found */
+ spin_lock(&call->lock);
+ msg = NULL;
+ if (!list_empty(&call->acks_pendq)) {
+- msg = list_entry(call->acks_pendq.next,struct rxrpc_message,link);
++ msg = list_entry(call->acks_pendq.next,
++ struct rxrpc_message, link);
+ list_del_init(&msg->link); /* dequeue */
+- if (msg->state==RXRPC_MSG_SENT)
++ if (msg->state == RXRPC_MSG_SENT)
+ call->acks_pend_cnt--;
+ }
+ spin_unlock(&call->lock);
+
+ /* insanity check */
+ if (!msg)
+- panic("%s(): acks_pendq unexpectedly empty\n",__FUNCTION__);
++ panic("%s(): acks_pendq unexpectedly empty\n",
++ __FUNCTION__);
+
+- if (msg->seq!=call->acks_dftv_seq)
+- panic("%s(): Packet #%u expected at front of acks_pendq (#%u found)\n",
+- __FUNCTION__,call->acks_dftv_seq,msg->seq);
++ if (msg->seq != call->acks_dftv_seq)
++ panic("%s(): Packet #%u expected at front of acks_pendq"
++ " (#%u found)\n",
++ __FUNCTION__, call->acks_dftv_seq, msg->seq);
+
+ /* discard the message */
+ msg->state = RXRPC_MSG_DONE;
+@@ -1380,8 +1457,8 @@
+ /* if all sent packets are definitively ACK'd then prod any sleepers just in case */
+ now_complete = 0;
+ spin_lock(&call->lock);
+- if (call->acks_dftv_seq==call->snd_seq_count) {
+- if (call->app_call_state!=RXRPC_CSTATE_COMPLETE) {
++ if (call->acks_dftv_seq == call->snd_seq_count) {
++ if (call->app_call_state != RXRPC_CSTATE_COMPLETE) {
+ call->app_call_state = RXRPC_CSTATE_COMPLETE;
+ _state(call);
+ now_complete = 1;
+@@ -1417,13 +1494,15 @@
+ u8 acks[16];
+
+ _enter("%p{apc=%u ads=%u},%p,%u,%Zu",
+- call,call->acks_pend_cnt,call->acks_dftv_seq,msg,seq,count);
++ call, call->acks_pend_cnt, call->acks_dftv_seq,
++ msg, seq, count);
+
+- /* handle re-ACK'ing of definitively ACK'd packets (may be out-of-order ACKs) */
+- if (seq<=call->acks_dftv_seq) {
++ /* handle re-ACK'ing of definitively ACK'd packets (may be out-of-order
++ * ACKs) */
++ if (seq <= call->acks_dftv_seq) {
+ unsigned delta = call->acks_dftv_seq - seq;
+
+- if (count<=delta) {
++ if (count <= delta) {
+ _leave(" = 0 [all definitively ACK'd]");
+ return 0;
+ }
+@@ -1435,14 +1514,14 @@
+
+ highest = seq + count - 1;
+ resend = 0;
+- while (count>0) {
++ while (count > 0) {
+ /* extract up to 16 ACK slots at a time */
+- chunk = min(count,sizeof(acks));
++ chunk = min(count, sizeof(acks));
+ count -= chunk;
+
+- memset(acks,2,sizeof(acks));
++ memset(acks, 2, sizeof(acks));
+
+- if (skb_copy_bits(msg->pkt,msg->offset,&acks,chunk)<0) {
++ if (skb_copy_bits(msg->pkt, msg->offset, &acks, chunk) < 0) {
+ printk("Rx Received short ACK packet\n");
+ _leave(" = -EINVAL");
+ return -EINVAL;
+@@ -1450,7 +1529,7 @@
+ msg->offset += chunk;
+
+ /* check that the ACK set is valid */
+- for (ix=0; ix<chunk; ix++) {
++ for (ix = 0; ix < chunk; ix++) {
+ switch (acks[ix]) {
+ case RXRPC_ACK_TYPE_ACK:
+ break;
+@@ -1458,14 +1537,16 @@
+ resend = 1;
+ break;
+ default:
+- printk("Rx Received unsupported ACK state %u\n",acks[ix]);
++ printk("Rx Received unsupported ACK state"
++ " %u\n", acks[ix]);
+ _leave(" = -EINVAL");
+ return -EINVAL;
+ }
+ }
+
+- _proto("Rx ACK of packets #%u-#%u [%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c] (pend=%u)",
+- seq,(unsigned)(seq+chunk-1),
++ _proto("Rx ACK of packets #%u-#%u "
++ "[%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c] (pend=%u)",
++ seq, (unsigned) (seq + chunk - 1),
+ _acktype[acks[0x0]],
+ _acktype[acks[0x1]],
+ _acktype[acks[0x2]],
+@@ -1485,53 +1566,60 @@
+ call->acks_pend_cnt
+ );
+
+- /* mark the packets in the ACK queue as being provisionally ACK'd */
++ /* mark the packets in the ACK queue as being provisionally
++ * ACK'd */
+ ix = 0;
+ spin_lock(&call->lock);
+
+ /* find the first packet ACK'd/NAK'd here */
+- list_for_each(_p,&call->acks_pendq) {
+- dmsg = list_entry(_p,struct rxrpc_message,link);
+- if (dmsg->seq==seq)
++ list_for_each(_p, &call->acks_pendq) {
++ dmsg = list_entry(_p, struct rxrpc_message, link);
++ if (dmsg->seq == seq)
+ goto found_first;
+- _debug("- %u: skipping #%u",ix,dmsg->seq);
++ _debug("- %u: skipping #%u", ix, dmsg->seq);
+ }
+ goto bad_queue;
+
+ found_first:
+ do {
+ _debug("- %u: processing #%u (%c) apc=%u",
+- ix,dmsg->seq,_acktype[acks[ix]],call->acks_pend_cnt);
++ ix, dmsg->seq, _acktype[acks[ix]],
++ call->acks_pend_cnt);
+
+- if (acks[ix]==RXRPC_ACK_TYPE_ACK) {
+- if (dmsg->state==RXRPC_MSG_SENT) call->acks_pend_cnt--;
++ if (acks[ix] == RXRPC_ACK_TYPE_ACK) {
++ if (dmsg->state == RXRPC_MSG_SENT)
++ call->acks_pend_cnt--;
+ dmsg->state = RXRPC_MSG_ACKED;
+ }
+ else {
+- if (dmsg->state==RXRPC_MSG_ACKED) call->acks_pend_cnt++;
++ if (dmsg->state == RXRPC_MSG_ACKED)
++ call->acks_pend_cnt++;
+ dmsg->state = RXRPC_MSG_SENT;
+ }
+ ix++;
+ seq++;
+
+ _p = dmsg->link.next;
+- dmsg = list_entry(_p,struct rxrpc_message,link);
+- } while(ix<chunk && _p!=&call->acks_pendq && dmsg->seq==seq);
++ dmsg = list_entry(_p, struct rxrpc_message, link);
++ } while(ix < chunk &&
++ _p != &call->acks_pendq &&
++ dmsg->seq == seq);
+
+- if (ix<chunk)
++ if (ix < chunk)
+ goto bad_queue;
+
+ spin_unlock(&call->lock);
+ }
+
+ if (resend)
+- rxrpc_call_resend(call,highest);
++ rxrpc_call_resend(call, highest);
+
+- /* if all packets are provisionally ACK'd, then wake up anyone who's waiting for that */
++ /* if all packets are provisionally ACK'd, then wake up anyone who's
++ * waiting for that */
+ now_complete = 0;
+ spin_lock(&call->lock);
+- if (call->acks_pend_cnt==0) {
+- if (call->app_call_state==RXRPC_CSTATE_SRVR_RCV_FINAL_ACK) {
++ if (call->acks_pend_cnt == 0) {
++ if (call->app_call_state == RXRPC_CSTATE_SRVR_RCV_FINAL_ACK) {
+ call->app_call_state = RXRPC_CSTATE_COMPLETE;
+ _state(call);
+ }
+@@ -1547,19 +1635,21 @@
+ call->app_attn_func(call);
+ }
+
+- _leave(" = 0 (apc=%u)",call->acks_pend_cnt);
++ _leave(" = 0 (apc=%u)", call->acks_pend_cnt);
+ return 0;
+
+ bad_queue:
+- panic("%s(): acks_pendq in bad state (packet #%u absent)\n",__FUNCTION__,seq);
++ panic("%s(): acks_pendq in bad state (packet #%u absent)\n",
++ __FUNCTION__, seq);
+
+ } /* end rxrpc_call_record_ACK() */
+
+ /*****************************************************************************/
+ /*
+ * transfer data from the ready packet queue to the asynchronous read buffer
+- * - since this func is the only one going to look at packets queued on app_readyq, we don't need
+- * a lock to modify or access them, only to modify the queue pointers
++ * - since this func is the only one going to look at packets queued on
++ * app_readyq, we don't need a lock to modify or access them, only to modify
++ * the queue pointers
+ * - called with call->lock held
+ * - the buffer must be in kernel space
+ * - returns:
+@@ -1575,16 +1665,20 @@
+ int ret;
+
+ _enter("%p{as=%d buf=%p qty=%Zu/%Zu}",
+- call,call->app_async_read,call->app_read_buf,call->app_ready_qty,call->app_mark);
++ call,
++ call->app_async_read, call->app_read_buf,
++ call->app_ready_qty, call->app_mark);
+
+ /* check the state */
+ switch (call->app_call_state) {
+ case RXRPC_CSTATE_SRVR_RCV_ARGS:
+ case RXRPC_CSTATE_CLNT_RCV_REPLY:
+ if (call->app_last_rcv) {
+- printk("%s(%p,%p,%Zd): Inconsistent call state (%s, last pkt)",
+- __FUNCTION__,call,call->app_read_buf,call->app_mark,
+- rxrpc_call_states[call->app_call_state]);
++ printk("%s(%p,%p,%Zd):"
++ " Inconsistent call state (%s, last pkt)",
++ __FUNCTION__,
++ call, call->app_read_buf, call->app_mark,
++ rxrpc_call_states[call->app_call_state]);
+ BUG();
+ }
+ break;
+@@ -1596,9 +1690,11 @@
+
+ case RXRPC_CSTATE_SRVR_SND_REPLY:
+ if (!call->app_last_rcv) {
+- printk("%s(%p,%p,%Zd): Inconsistent call state (%s, not last pkt)",
+- __FUNCTION__,call,call->app_read_buf,call->app_mark,
+- rxrpc_call_states[call->app_call_state]);
++ printk("%s(%p,%p,%Zd):"
++ " Inconsistent call state (%s, not last pkt)",
++ __FUNCTION__,
++ call, call->app_read_buf, call->app_mark,
++ rxrpc_call_states[call->app_call_state]);
+ BUG();
+ }
+ _debug("Trying to read data from call in SND_REPLY state");
+@@ -1609,13 +1705,14 @@
+ return -ECONNABORTED;
+
+ default:
+- printk("reading in unexpected state [[[ %u ]]]\n",call->app_call_state);
++ printk("reading in unexpected state [[[ %u ]]]\n",
++ call->app_call_state);
+ BUG();
+ }
+
+ /* handle the case of not having an async buffer */
+ if (!call->app_async_read) {
+- if (call->app_mark==RXRPC_APP_MARK_EOF) {
++ if (call->app_mark == RXRPC_APP_MARK_EOF) {
+ ret = call->app_last_rcv ? 0 : -EAGAIN;
+ }
+ else {
+@@ -1628,28 +1725,33 @@
+ }
+ }
+
+- _leave(" = %d [no buf]",ret);
++ _leave(" = %d [no buf]", ret);
+ return 0;
+ }
+
+- while (!list_empty(&call->app_readyq) && call->app_mark>0) {
+- msg = list_entry(call->app_readyq.next,struct rxrpc_message,link);
++ while (!list_empty(&call->app_readyq) && call->app_mark > 0) {
++ msg = list_entry(call->app_readyq.next,
++ struct rxrpc_message, link);
+
+ /* drag as much data as we need out of this packet */
+- qty = min(call->app_mark,msg->dsize);
++ qty = min(call->app_mark, msg->dsize);
+
+- _debug("reading %Zu from skb=%p off=%lu",qty,msg->pkt,msg->offset);
++ _debug("reading %Zu from skb=%p off=%lu",
++ qty, msg->pkt, msg->offset);
+
+ if (call->app_read_buf)
+- if (skb_copy_bits(msg->pkt,msg->offset,call->app_read_buf,qty)<0)
+- panic("%s: Failed to copy data from packet: (%p,%p,%Zd)",
+- __FUNCTION__,call,call->app_read_buf,qty);
++ if (skb_copy_bits(msg->pkt, msg->offset,
++ call->app_read_buf, qty) < 0)
++ panic("%s: Failed to copy data from packet:"
++ " (%p,%p,%Zd)",
++ __FUNCTION__,
++ call, call->app_read_buf, qty);
+
+ /* if that packet is now empty, discard it */
+ call->app_ready_qty -= qty;
+ msg->dsize -= qty;
+
+- if (msg->dsize==0) {
++ if (msg->dsize == 0) {
+ list_del_init(&msg->link);
+ rxrpc_put_message(msg);
+ }
+@@ -1658,10 +1760,11 @@
+ }
+
+ call->app_mark -= qty;
+- if (call->app_read_buf) call->app_read_buf += qty;
++ if (call->app_read_buf)
++ call->app_read_buf += qty;
+ }
+
+- if (call->app_mark==0) {
++ if (call->app_mark == 0) {
+ call->app_async_read = 0;
+ call->app_mark = RXRPC_APP_MARK_EOF;
+ call->app_read_buf = NULL;
+@@ -1695,7 +1798,8 @@
+ }
+
+ if (call->app_last_rcv) {
+- _debug("Insufficient data (%Zu/%Zu)",call->app_ready_qty,call->app_mark);
++ _debug("Insufficient data (%Zu/%Zu)",
++ call->app_ready_qty, call->app_mark);
+ call->app_async_read = 0;
+ call->app_mark = RXRPC_APP_MARK_EOF;
+ call->app_read_buf = NULL;
+@@ -1710,22 +1814,26 @@
+
+ /*****************************************************************************/
+ /*
+- * attempt to read the specified amount of data from the call's ready queue into the buffer
+- * provided
+- * - since this func is the only one going to look at packets queued on app_readyq, we don't need
+- * a lock to modify or access them, only to modify the queue pointers
++ * attempt to read the specified amount of data from the call's ready queue
++ * into the buffer provided
++ * - since this func is the only one going to look at packets queued on
++ * app_readyq, we don't need a lock to modify or access them, only to modify
++ * the queue pointers
+ * - if the buffer pointer is NULL, then data is merely drained, not copied
+- * - if flags&RXRPC_CALL_READ_BLOCK, then the function will wait until there is enough data or an
+- * error will be generated
+- * - note that the caller must have added the calling task to the call's wait queue beforehand
+- * - if flags&RXRPC_CALL_READ_ALL, then an error will be generated if this function doesn't read
+- * all available data
++ * - if flags&RXRPC_CALL_READ_BLOCK, then the function will wait until there is
++ * enough data or an error will be generated
++ * - note that the caller must have added the calling task to the call's wait
++ * queue beforehand
++ * - if flags&RXRPC_CALL_READ_ALL, then an error will be generated if this
++ * function doesn't read all available data
+ */
+-int rxrpc_call_read_data(struct rxrpc_call *call, void *buffer, size_t size, int flags)
++int rxrpc_call_read_data(struct rxrpc_call *call,
++ void *buffer, size_t size, int flags)
+ {
+ int ret;
+
+- _enter("%p{arq=%Zu},%p,%Zd,%x",call,call->app_ready_qty,buffer,size,flags);
++ _enter("%p{arq=%Zu},%p,%Zd,%x",
++ call, call->app_ready_qty, buffer, size, flags);
+
+ spin_lock(&call->lock);
+
+@@ -1744,9 +1852,10 @@
+ ret = __rxrpc_call_read_data(call);
+ switch (ret) {
+ case 0:
+- if (flags&RXRPC_CALL_READ_ALL && (!call->app_last_rcv || call->app_ready_qty>0)) {
++ if (flags & RXRPC_CALL_READ_ALL &&
++ (!call->app_last_rcv || call->app_ready_qty > 0)) {
+ _leave(" = -EBADMSG");
+- __rxrpc_call_abort(call,-EBADMSG);
++ __rxrpc_call_abort(call, -EBADMSG);
+ return -EBADMSG;
+ }
+
+@@ -1757,18 +1866,18 @@
+
+ case -ECONNABORTED:
+ spin_unlock(&call->lock);
+- _leave(" = %d [aborted]",ret);
++ _leave(" = %d [aborted]", ret);
+ return ret;
+
+- default:
+- __rxrpc_call_abort(call,ret);
+- _leave(" = %d",ret);
++ default:
++ __rxrpc_call_abort(call, ret);
++ _leave(" = %d", ret);
+ return ret;
+
+ case -EAGAIN:
+ spin_unlock(&call->lock);
+
+- if (!(flags&RXRPC_CALL_READ_BLOCK)) {
++ if (!(flags & RXRPC_CALL_READ_BLOCK)) {
+ _leave(" = -EAGAIN");
+ return -EAGAIN;
+ }
+@@ -1789,7 +1898,7 @@
+ return -EINTR;
+ }
+
+- if (call->app_call_state==RXRPC_CSTATE_ERROR) {
++ if (call->app_call_state == RXRPC_CSTATE_ERROR) {
+ _leave(" = -ECONNABORTED");
+ return -ECONNABORTED;
+ }
+@@ -1804,8 +1913,8 @@
+ /*
+ * write data to a call
+ * - the data may not be sent immediately if it doesn't fill a buffer
+- * - if we can't queue all the data for buffering now, siov[] will have been adjusted to take
+- * account of what has been sent
++ * - if we can't queue all the data for buffering now, siov[] will have been
++ * adjusted to take account of what has been sent
+ */
+ int rxrpc_call_write_data(struct rxrpc_call *call,
+ size_t sioc,
+@@ -1821,7 +1930,9 @@
+ char *buf;
+ int ret;
+
+- _enter("%p,%Zu,%p,%02x,%x,%d,%p",call,sioc,siov,rxhdr_flags,alloc_flags,dup_data,size_sent);
++ _enter("%p,%Zu,%p,%02x,%x,%d,%p",
++ call, sioc, siov, rxhdr_flags, alloc_flags, dup_data,
++ size_sent);
+
+ *size_sent = 0;
+ size = 0;
+@@ -1840,8 +1951,9 @@
+
+ /* calculate how much data we've been given */
+ sptr = siov;
+- for (; sioc>0; sptr++, sioc--) {
+- if (!sptr->iov_len) continue;
++ for (; sioc > 0; sptr++, sioc--) {
++ if (!sptr->iov_len)
++ continue;
+
+ if (!sptr->iov_base)
+ goto out;
+@@ -1849,27 +1961,30 @@
+ size += sptr->iov_len;
+ }
+
+- _debug("- size=%Zu mtu=%Zu",size,call->conn->mtu_size);
++ _debug("- size=%Zu mtu=%Zu", size, call->conn->mtu_size);
+
+ do {
+ /* make sure there's a message under construction */
+ if (!call->snd_nextmsg) {
+ /* no - allocate a message with no data yet attached */
+- ret = rxrpc_conn_newmsg(call->conn,call,RXRPC_PACKET_TYPE_DATA,
+- 0,NULL,alloc_flags,&call->snd_nextmsg);
+- if (ret<0)
++ ret = rxrpc_conn_newmsg(call->conn, call,
++ RXRPC_PACKET_TYPE_DATA,
++ 0, NULL, alloc_flags,
++ &call->snd_nextmsg);
++ if (ret < 0)
+ goto out;
+- _debug("- allocated new message [ds=%Zu]",call->snd_nextmsg->dsize);
++ _debug("- allocated new message [ds=%Zu]",
++ call->snd_nextmsg->dsize);
+ }
+
+ msg = call->snd_nextmsg;
+ msg->hdr.flags |= rxhdr_flags;
+
+ /* deal with zero-length terminal packet */
+- if (size==0) {
++ if (size == 0) {
+ if (rxhdr_flags & RXRPC_LAST_PACKET) {
+ ret = rxrpc_call_flush(call);
+- if (ret<0)
++ if (ret < 0)
+ goto out;
+ }
+ break;
+@@ -1877,24 +1992,27 @@
+
+ /* work out how much space current packet has available */
+ space = call->conn->mtu_size - msg->dsize;
+- chunk = min(space,size);
++ chunk = min(space, size);
+
+- _debug("- [before] space=%Zu chunk=%Zu",space,chunk);
++ _debug("- [before] space=%Zu chunk=%Zu", space, chunk);
+
+ while (!siov->iov_len)
+ siov++;
+
+- /* if we are going to have to duplicate the data then coalesce it too */
++ /* if we are going to have to duplicate the data then coalesce
++ * it too */
+ if (dup_data) {
+ /* don't allocate more that 1 page at a time */
+- if (chunk>PAGE_SIZE)
++ if (chunk > PAGE_SIZE)
+ chunk = PAGE_SIZE;
+
+ /* allocate a data buffer and attach to the message */
+- buf = kmalloc(chunk,alloc_flags);
++ buf = kmalloc(chunk, alloc_flags);
+ if (unlikely(!buf)) {
+- if (msg->dsize==sizeof(struct rxrpc_header)) {
+- /* discard an empty msg and wind back the seq counter */
++ if (msg->dsize ==
++ sizeof(struct rxrpc_header)) {
++ /* discard an empty msg and wind back
++ * the seq counter */
+ rxrpc_put_message(msg);
+ call->snd_nextmsg = NULL;
+ call->snd_seq_count--;
+@@ -1905,7 +2023,7 @@
+ }
+
+ tmp = msg->dcount++;
+- set_bit(tmp,&msg->dfree);
++ set_bit(tmp, &msg->dfree);
+ msg->data[tmp].iov_base = buf;
+ msg->data[tmp].iov_len = chunk;
+ msg->dsize += chunk;
+@@ -1913,9 +2031,9 @@
+ size -= chunk;
+
+ /* load the buffer with data */
+- while (chunk>0) {
+- tmp = min(chunk,siov->iov_len);
+- memcpy(buf,siov->iov_base,tmp);
++ while (chunk > 0) {
++ tmp = min(chunk, siov->iov_len);
++ memcpy(buf, siov->iov_base, tmp);
+ buf += tmp;
+ siov->iov_base += tmp;
+ siov->iov_len -= tmp;
+@@ -1926,7 +2044,8 @@
+ }
+ else {
+ /* we want to attach the supplied buffers directly */
+- while (chunk>0 && msg->dcount<RXRPC_MSG_MAX_IOCS) {
++ while (chunk > 0 &&
++ msg->dcount < RXRPC_MSG_MAX_IOCS) {
+ tmp = msg->dcount++;
+ msg->data[tmp].iov_base = siov->iov_base;
+ msg->data[tmp].iov_len = siov->iov_len;
+@@ -1938,20 +2057,20 @@
+ }
+ }
+
+- _debug("- [loaded] chunk=%Zu size=%Zu",chunk,size);
++ _debug("- [loaded] chunk=%Zu size=%Zu", chunk, size);
+
+ /* dispatch the message when full, final or requesting ACK */
+- if (msg->dsize>=call->conn->mtu_size || rxhdr_flags) {
++ if (msg->dsize >= call->conn->mtu_size || rxhdr_flags) {
+ ret = rxrpc_call_flush(call);
+- if (ret<0)
++ if (ret < 0)
+ goto out;
+ }
+
+- } while(size>0);
++ } while(size > 0);
+
+ ret = 0;
+ out:
+- _leave(" = %d (%Zd queued, %Zd rem)",ret,*size_sent,size);
++ _leave(" = %d (%Zd queued, %Zd rem)", ret, *size_sent, size);
+ return ret;
+
+ } /* end rxrpc_call_write_data() */
+@@ -1965,7 +2084,7 @@
+ struct rxrpc_message *msg;
+ int ret = 0;
+
+- _enter("%p",call);
++ _enter("%p", call);
+
+ rxrpc_get_call(call);
+
+@@ -1983,25 +2102,28 @@
+ }
+
+ _proto("Sending DATA message { ds=%Zu dc=%u df=%02lu }",
+- msg->dsize,msg->dcount,msg->dfree);
++ msg->dsize, msg->dcount, msg->dfree);
+
+ /* queue and adjust call state */
+ spin_lock(&call->lock);
+- list_add_tail(&msg->link,&call->acks_pendq);
++ list_add_tail(&msg->link, &call->acks_pendq);
+
+- /* decide what to do depending on current state and if this is the last packet */
++ /* decide what to do depending on current state and if this is
++ * the last packet */
+ ret = -EINVAL;
+ switch (call->app_call_state) {
+ case RXRPC_CSTATE_SRVR_SND_REPLY:
+ if (msg->hdr.flags & RXRPC_LAST_PACKET) {
+- call->app_call_state = RXRPC_CSTATE_SRVR_RCV_FINAL_ACK;
++ call->app_call_state =
++ RXRPC_CSTATE_SRVR_RCV_FINAL_ACK;
+ _state(call);
+ }
+ break;
+
+ case RXRPC_CSTATE_CLNT_SND_ARGS:
+ if (msg->hdr.flags & RXRPC_LAST_PACKET) {
+- call->app_call_state = RXRPC_CSTATE_CLNT_RCV_REPLY;
++ call->app_call_state =
++ RXRPC_CSTATE_CLNT_RCV_REPLY;
+ _state(call);
+ }
+ break;
+@@ -2016,19 +2138,20 @@
+ call->acks_pend_cnt++;
+
+ mod_timer(&call->acks_timeout,
+- __rxrpc_rtt_based_timeout(call,rxrpc_call_acks_timeout));
++ __rxrpc_rtt_based_timeout(call,
++ rxrpc_call_acks_timeout));
+
+ spin_unlock(&call->lock);
+
+- ret = rxrpc_conn_sendmsg(call->conn,msg);
+- if (ret==0)
++ ret = rxrpc_conn_sendmsg(call->conn, msg);
++ if (ret == 0)
+ call->pkt_snd_count++;
+ }
+
+ out:
+ rxrpc_put_call(call);
+
+- _leave(" = %d",ret);
++ _leave(" = %d", ret);
+ return ret;
+
+ } /* end rxrpc_call_flush() */
+@@ -2043,14 +2166,16 @@
+ struct list_head *_p;
+ rxrpc_seq_t seq = 0;
+
+- _enter("%p,%u",call,highest);
++ _enter("%p,%u", call, highest);
+
+ _proto("Rx Resend required");
+
+ /* handle too many resends */
+- if (call->snd_resend_cnt>=rxrpc_call_max_resend) {
+- _debug("Aborting due to too many resends (rcv=%d)",call->pkt_rcv_count);
+- rxrpc_call_abort(call,call->pkt_rcv_count>0?-EIO:-ETIMEDOUT);
++ if (call->snd_resend_cnt >= rxrpc_call_max_resend) {
++ _debug("Aborting due to too many resends (rcv=%d)",
++ call->pkt_rcv_count);
++ rxrpc_call_abort(call,
++ call->pkt_rcv_count > 0 ? -EIO : -ETIMEDOUT);
+ _leave("");
+ return;
+ }
+@@ -2059,35 +2184,38 @@
+ call->snd_resend_cnt++;
+ for (;;) {
+ /* determine which the next packet we might need to ACK is */
+- if (seq<=call->acks_dftv_seq)
++ if (seq <= call->acks_dftv_seq)
+ seq = call->acks_dftv_seq;
+ seq++;
+
+- if (seq>highest)
++ if (seq > highest)
+ break;
+
+ /* look for the packet in the pending-ACK queue */
+- list_for_each(_p,&call->acks_pendq) {
+- msg = list_entry(_p,struct rxrpc_message,link);
+- if (msg->seq==seq)
++ list_for_each(_p, &call->acks_pendq) {
++ msg = list_entry(_p, struct rxrpc_message, link);
++ if (msg->seq == seq)
+ goto found_msg;
+ }
+
+- panic("%s(%p,%d): Inconsistent pending-ACK queue (ds=%u sc=%u sq=%u)\n",
+- __FUNCTION__,call,highest,call->acks_dftv_seq,call->snd_seq_count,seq);
++ panic("%s(%p,%d):"
++ " Inconsistent pending-ACK queue (ds=%u sc=%u sq=%u)\n",
++ __FUNCTION__, call, highest,
++ call->acks_dftv_seq, call->snd_seq_count, seq);
+
+ found_msg:
+- if (msg->state!=RXRPC_MSG_SENT)
++ if (msg->state != RXRPC_MSG_SENT)
+ continue; /* only un-ACK'd packets */
+
+ rxrpc_get_message(msg);
+ spin_unlock(&call->lock);
+
+- /* send each message again (and ignore any errors we might incur) */
++ /* send each message again (and ignore any errors we might
++ * incur) */
+ _proto("Resending DATA message { ds=%Zu dc=%u df=%02lu }",
+- msg->dsize,msg->dcount,msg->dfree);
++ msg->dsize, msg->dcount, msg->dfree);
+
+- if (rxrpc_conn_sendmsg(call->conn,msg)==0)
++ if (rxrpc_conn_sendmsg(call->conn, msg) == 0)
+ call->pkt_snd_count++;
+
+ rxrpc_put_message(msg);
+@@ -2096,7 +2224,8 @@
+ }
+
+ /* reset the timeout */
+- mod_timer(&call->acks_timeout,__rxrpc_rtt_based_timeout(call,rxrpc_call_acks_timeout));
++ mod_timer(&call->acks_timeout,
++ __rxrpc_rtt_based_timeout(call, rxrpc_call_acks_timeout));
+
+ spin_unlock(&call->lock);
+
+@@ -2109,10 +2238,10 @@
+ */
+ void rxrpc_call_handle_error(struct rxrpc_call *call, int local, int errno)
+ {
+- _enter("%p{%u},%d",call,ntohl(call->call_id),errno);
++ _enter("%p{%u},%d", call, ntohl(call->call_id), errno);
+
+ /* if this call is already aborted, then just wake up any waiters */
+- if (call->app_call_state==RXRPC_CSTATE_ERROR) {
++ if (call->app_call_state == RXRPC_CSTATE_ERROR) {
+ call->app_error_func(call);
+ }
+ else {
+@@ -2124,10 +2253,10 @@
+ call->app_err_state = RXRPC_ESTATE_LOCAL_ERROR;
+ else
+ call->app_err_state = RXRPC_ESTATE_REMOTE_ERROR;
+- call->app_errno = errno;
+- call->app_mark = RXRPC_APP_MARK_EOF;
+- call->app_read_buf = NULL;
+- call->app_async_read = 0;
++ call->app_errno = errno;
++ call->app_mark = RXRPC_APP_MARK_EOF;
++ call->app_read_buf = NULL;
++ call->app_async_read = 0;
+
+ /* map the error */
+ call->app_aemap_func(call);
+Index: linux-2.6.0-test5/net/rxrpc/connection.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/rxrpc/connection.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/rxrpc/connection.c 2003-09-27 11:38:42.218110256 +0800
+@@ -28,18 +28,20 @@
+
+ LIST_HEAD(rxrpc_conns);
+ DECLARE_RWSEM(rxrpc_conns_sem);
++unsigned long rxrpc_conn_timeout = 60 * 60;
+
+ static void __rxrpc_conn_timeout(rxrpc_timer_t *timer)
+ {
+- struct rxrpc_connection *conn = list_entry(timer,struct rxrpc_connection,timeout);
++ struct rxrpc_connection *conn =
++ list_entry(timer, struct rxrpc_connection, timeout);
+
+- _debug("Rx CONN TIMEOUT [%p{u=%d}]",conn,atomic_read(&conn->usage));
++ _debug("Rx CONN TIMEOUT [%p{u=%d}]", conn, atomic_read(&conn->usage));
+
+ rxrpc_conn_do_timeout(conn);
+ }
+
+ static const struct rxrpc_timer_ops rxrpc_conn_timer_ops = {
+- .timed_out = __rxrpc_conn_timeout,
++ timed_out: __rxrpc_conn_timeout,
+ };
+
+ /*****************************************************************************/
+@@ -54,19 +56,20 @@
+ _enter("%p",peer);
+
+ /* allocate and initialise a connection record */
+- conn = kmalloc(sizeof(struct rxrpc_connection),GFP_KERNEL);
++ conn = kmalloc(sizeof(struct rxrpc_connection), GFP_KERNEL);
+ if (!conn) {
+ _leave(" = -ENOMEM");
+ return -ENOMEM;
+ }
+
+- memset(conn,0,sizeof(struct rxrpc_connection));
+- atomic_set(&conn->usage,1);
++ memset(conn, 0, sizeof(struct rxrpc_connection));
++ atomic_set(&conn->usage, 1);
+
+ INIT_LIST_HEAD(&conn->link);
++ INIT_LIST_HEAD(&conn->id_link);
+ init_waitqueue_head(&conn->chanwait);
+ spin_lock_init(&conn->lock);
+- rxrpc_timer_init(&conn->timeout,&rxrpc_conn_timer_ops);
++ rxrpc_timer_init(&conn->timeout, &rxrpc_conn_timer_ops);
+
+ do_gettimeofday(&conn->atime);
+ conn->mtu_size = 1024;
+@@ -75,7 +78,7 @@
+
+ __RXACCT(atomic_inc(&rxrpc_connection_count));
+ *_conn = conn;
+- _leave(" = 0 (%p)",conn);
++ _leave(" = 0 (%p)", conn);
+
+ return 0;
+ } /* end __rxrpc_create_connection() */
+@@ -85,61 +88,123 @@
+ * create a new connection record for outgoing connections
+ */
+ int rxrpc_create_connection(struct rxrpc_transport *trans,
+- u16 port,
+- u32 addr,
+- unsigned short service_id,
++ uint16_t port,
++ uint32_t addr,
++ uint16_t service_id,
+ void *security,
+ struct rxrpc_connection **_conn)
+ {
+- struct rxrpc_connection *conn;
++ struct rxrpc_connection *candidate, *conn;
+ struct rxrpc_peer *peer;
++ struct list_head *_p;
++ uint32_t connid;
+ int ret;
+
+- _enter("%p{%hu},%u,%hu",trans,trans->port,ntohs(port),service_id);
++ _enter("%p{%hu},%u,%hu", trans, trans->port, ntohs(port), service_id);
+
+ /* get a peer record */
+- ret = rxrpc_peer_lookup(trans,addr,&peer);
+- if (ret<0) {
+- _leave(" = %d",ret);
++ ret = rxrpc_peer_lookup(trans, addr, &peer);
++ if (ret < 0) {
++ _leave(" = %d", ret);
+ return ret;
+ }
+
+ /* allocate and initialise a connection record */
+- ret = __rxrpc_create_connection(peer,&conn);
+- if (ret<0) {
++ ret = __rxrpc_create_connection(peer, &candidate);
++ if (ret < 0) {
+ rxrpc_put_peer(peer);
+- _leave(" = %d",ret);
++ _leave(" = %d", ret);
+ return ret;
+ }
+
+ /* fill in the specific bits */
+- conn->addr.sin_family = AF_INET;
+- conn->addr.sin_port = port;
+- conn->addr.sin_addr.s_addr = addr;
+-
+- conn->in_epoch = rxrpc_epoch;
+- conn->out_epoch = rxrpc_epoch;
+- conn->in_clientflag = 0;
+- conn->out_clientflag = RXRPC_CLIENT_INITIATED;
+- conn->conn_id = htonl((unsigned long) conn & RXRPC_CIDMASK);
+- conn->service_id = htons(service_id);
++ candidate->addr.sin_family = AF_INET;
++ candidate->addr.sin_port = port;
++ candidate->addr.sin_addr.s_addr = addr;
++
++ candidate->in_epoch = rxrpc_epoch;
++ candidate->out_epoch = rxrpc_epoch;
++ candidate->in_clientflag = 0;
++ candidate->out_clientflag = RXRPC_CLIENT_INITIATED;
++ candidate->service_id = htons(service_id);
++
++ /* invent a unique connection ID */
++ write_lock(&peer->conn_idlock);
++
++ try_next_id:
++ connid = htonl(peer->conn_idcounter & RXRPC_CIDMASK);
++ peer->conn_idcounter += RXRPC_MAXCALLS;
++
++ list_for_each(_p, &peer->conn_idlist) {
++ conn = list_entry(_p, struct rxrpc_connection, id_link);
++ if (connid == conn->conn_id)
++ goto try_next_id;
++ if (connid > conn->conn_id)
++ break;
++ }
++
++ _debug("selected candidate conn ID %x.%u",
++ ntohl(peer->addr.s_addr), ntohl(connid));
++
++ candidate->conn_id = connid;
++ list_add_tail(&candidate->id_link, _p);
++
++ write_unlock(&peer->conn_idlock);
+
+ /* attach to peer */
+- conn->peer = peer;
++ candidate->peer = peer;
+
+ write_lock(&peer->conn_lock);
+- list_add_tail(&conn->link,&peer->conn_active);
++
++ /* search the peer's transport graveyard list */
++ spin_lock(&peer->conn_gylock);
++ list_for_each(_p, &peer->conn_graveyard) {
++ conn = list_entry(_p, struct rxrpc_connection, link);
++ if (conn->addr.sin_port == candidate->addr.sin_port &&
++ conn->security_ix == candidate->security_ix &&
++ conn->service_id == candidate->service_id &&
++ conn->in_clientflag == 0)
++ goto found_in_graveyard;
++ }
++ spin_unlock(&peer->conn_gylock);
++
++ /* pick the new candidate */
++ _debug("created connection: {%08x} [out]", htonl(candidate->conn_id));
+ atomic_inc(&peer->conn_count);
++ conn = candidate;
++ candidate = NULL;
++
++ make_active:
++ list_add_tail(&conn->link, &peer->conn_active);
+ write_unlock(&peer->conn_lock);
+
+- down_write(&rxrpc_conns_sem);
+- list_add_tail(&conn->proc_link,&rxrpc_conns);
+- up_write(&rxrpc_conns_sem);
++ if (candidate) {
++ write_lock(&peer->conn_idlock);
++ list_del(&candidate->id_link);
++ write_unlock(&peer->conn_idlock);
++
++ __RXACCT(atomic_dec(&rxrpc_connection_count));
++ kfree(candidate);
++ }
++ else {
++ down_write(&rxrpc_conns_sem);
++ list_add_tail(&conn->proc_link, &rxrpc_conns);
++ up_write(&rxrpc_conns_sem);
++ }
+
+ *_conn = conn;
+- _leave(" = 0 (%p)",conn);
++ _leave(" = 0 (%p)", conn);
+
+ return 0;
++
++ /* handle resurrecting a connection from the graveyard */
++ found_in_graveyard:
++ _debug("resurrecting connection: {%08x} [out]", htonl(conn->conn_id));
++ rxrpc_get_connection(conn);
++ rxrpc_krxtimod_del_timer(&conn->timeout);
++ list_del_init(&conn->link);
++ spin_unlock(&peer->conn_gylock);
++ goto make_active;
+ } /* end rxrpc_create_connection() */
+
+ /*****************************************************************************/
+@@ -159,7 +224,10 @@
+ u8 x_clflag;
+
+ _enter("%p{{%hu}},%u,%hu",
+- peer,peer->trans->port,ntohs(msg->pkt->h.uh->source),ntohs(msg->hdr.serviceId));
++ peer,
++ peer->trans->port,
++ ntohs(msg->pkt->h.uh->source),
++ ntohs(msg->hdr.serviceId));
+
+ x_port = msg->pkt->h.uh->source;
+ x_epoch = msg->hdr.epoch;
+@@ -170,8 +238,8 @@
+
+ /* [common case] search the transport's active list first */
+ read_lock(&peer->conn_lock);
+- list_for_each(_p,&peer->conn_active) {
+- conn = list_entry(_p,struct rxrpc_connection,link);
++ list_for_each(_p, &peer->conn_active) {
++ conn = list_entry(_p, struct rxrpc_connection, link);
+ if (conn->addr.sin_port == x_port &&
+ conn->in_epoch == x_epoch &&
+ conn->conn_id == x_connid &&
+@@ -187,9 +255,9 @@
+ * - only examine the graveyard for an outbound connection
+ */
+ if (x_clflag) {
+- ret = __rxrpc_create_connection(peer,&candidate);
+- if (ret<0) {
+- _leave(" = %d",ret);
++ ret = __rxrpc_create_connection(peer, &candidate);
++ if (ret < 0) {
++ _leave(" = %d", ret);
+ return ret;
+ }
+
+@@ -206,10 +274,11 @@
+ candidate->security_ix = x_secix;
+ }
+
+- /* search the active list again, just in case it appeared whilst we were busy */
++ /* search the active list again, just in case it appeared whilst we
++ * were busy */
+ write_lock(&peer->conn_lock);
+- list_for_each(_p,&peer->conn_active) {
+- conn = list_entry(_p,struct rxrpc_connection,link);
++ list_for_each(_p, &peer->conn_active) {
++ conn = list_entry(_p, struct rxrpc_connection, link);
+ if (conn->addr.sin_port == x_port &&
+ conn->in_epoch == x_epoch &&
+ conn->conn_id == x_connid &&
+@@ -221,8 +290,8 @@
+
+ /* search the transport's graveyard list */
+ spin_lock(&peer->conn_gylock);
+- list_for_each(_p,&peer->conn_graveyard) {
+- conn = list_entry(_p,struct rxrpc_connection,link);
++ list_for_each(_p, &peer->conn_graveyard) {
++ conn = list_entry(_p, struct rxrpc_connection, link);
+ if (conn->addr.sin_port == x_port &&
+ conn->in_epoch == x_epoch &&
+ conn->conn_id == x_connid &&
+@@ -241,6 +310,7 @@
+ }
+
+ /* we can now add the new candidate to the list */
++ _debug("created connection: {%08x} [in]", htonl(candidate->conn_id));
+ rxrpc_get_peer(peer);
+ conn = candidate;
+ candidate = NULL;
+@@ -248,25 +318,29 @@
+ fresh = 1;
+
+ make_active:
+- list_add_tail(&conn->link,&peer->conn_active);
++ list_add_tail(&conn->link, &peer->conn_active);
+
+ success_uwfree:
+ write_unlock(&peer->conn_lock);
+
+ if (candidate) {
++ write_lock(&peer->conn_idlock);
++ list_del(&candidate->id_link);
++ write_unlock(&peer->conn_idlock);
++
+ __RXACCT(atomic_dec(&rxrpc_connection_count));
+ kfree(candidate);
+ }
+
+ if (fresh) {
+ down_write(&rxrpc_conns_sem);
+- list_add_tail(&conn->proc_link,&rxrpc_conns);
++ list_add_tail(&conn->proc_link, &rxrpc_conns);
+ up_write(&rxrpc_conns_sem);
+ }
+
+ success:
+ *_conn = conn;
+- _leave(" = 0 (%p)",conn);
++ _leave(" = 0 (%p)", conn);
+ return 0;
+
+ /* handle the connection being found in the active list straight off */
+@@ -277,6 +351,7 @@
+
+ /* handle resurrecting a connection from the graveyard */
+ found_in_graveyard:
++ _debug("resurrecting connection: {%08x} [in]", htonl(conn->conn_id));
+ rxrpc_get_peer(peer);
+ rxrpc_get_connection(conn);
+ rxrpc_krxtimod_del_timer(&conn->timeout);
+@@ -284,7 +359,8 @@
+ spin_unlock(&peer->conn_gylock);
+ goto make_active;
+
+- /* handle finding the connection on the second time through the active list */
++ /* handle finding the connection on the second time through the active
++ * list */
+ found_active_second_chance:
+ rxrpc_get_connection(conn);
+ goto success_uwfree;
+@@ -294,19 +370,26 @@
+ /*****************************************************************************/
+ /*
+ * finish using a connection record
+- * - it will be transferred to the peer's connection graveyard when refcount reaches 0
++ * - it will be transferred to the peer's connection graveyard when refcount
++ * reaches 0
+ */
+ void rxrpc_put_connection(struct rxrpc_connection *conn)
+ {
+- struct rxrpc_peer *peer = conn->peer;
++ struct rxrpc_peer *peer;
++
++ if (!conn)
++ return;
++
++ _enter("%p{u=%d p=%hu}",
++ conn, atomic_read(&conn->usage), ntohs(conn->addr.sin_port));
+
+- _enter("%p{u=%d p=%hu}",conn,atomic_read(&conn->usage),ntohs(conn->addr.sin_port));
++ peer = conn->peer;
++ spin_lock(&peer->conn_gylock);
+
+ /* sanity check */
+- if (atomic_read(&conn->usage)<=0)
++ if (atomic_read(&conn->usage) <= 0)
+ BUG();
+
+- spin_lock(&peer->conn_gylock);
+ if (likely(!atomic_dec_and_test(&conn->usage))) {
+ spin_unlock(&peer->conn_gylock);
+ _leave("");
+@@ -314,11 +397,11 @@
+ }
+
+ /* move to graveyard queue */
++ _debug("burying connection: {%08x}", htonl(conn->conn_id));
+ list_del(&conn->link);
+- list_add_tail(&conn->link,&peer->conn_graveyard);
++ list_add_tail(&conn->link, &peer->conn_graveyard);
+
+- /* discard in 100 secs */
+- rxrpc_krxtimod_add_timer(&conn->timeout,20*HZ);
++ rxrpc_krxtimod_add_timer(&conn->timeout, rxrpc_conn_timeout * HZ);
+
+ spin_unlock(&peer->conn_gylock);
+
+@@ -335,16 +418,17 @@
+ {
+ struct rxrpc_peer *peer;
+
+- _enter("%p{u=%d p=%hu}",conn,atomic_read(&conn->usage),ntohs(conn->addr.sin_port));
++ _enter("%p{u=%d p=%hu}",
++ conn, atomic_read(&conn->usage), ntohs(conn->addr.sin_port));
+
+ peer = conn->peer;
+
+- if (atomic_read(&conn->usage)<0)
++ if (atomic_read(&conn->usage) < 0)
+ BUG();
+
+ /* remove from graveyard if still dead */
+ spin_lock(&peer->conn_gylock);
+- if (atomic_read(&conn->usage)==0) {
++ if (atomic_read(&conn->usage) == 0) {
+ list_del_init(&conn->link);
+ }
+ else {
+@@ -357,12 +441,17 @@
+ return; /* resurrected */
+ }
+
+- _debug("--- Destroying Connection %p ---",conn);
++ _debug("--- Destroying Connection %p{%08x} ---",
++ conn, htonl(conn->conn_id));
+
+ down_write(&rxrpc_conns_sem);
+ list_del(&conn->proc_link);
+ up_write(&rxrpc_conns_sem);
+
++ write_lock(&peer->conn_idlock);
++ list_del(&conn->id_link);
++ write_unlock(&peer->conn_idlock);
++
+ __RXACCT(atomic_dec(&rxrpc_connection_count));
+ kfree(conn);
+
+@@ -379,12 +468,12 @@
+ */
+ void rxrpc_conn_clearall(struct rxrpc_peer *peer)
+ {
+- DECLARE_WAITQUEUE(myself,current);
++ DECLARE_WAITQUEUE(myself, current);
+
+ struct rxrpc_connection *conn;
+ int err;
+
+- _enter("%p",peer);
++ _enter("%p", peer);
+
+ /* there shouldn't be any active conns remaining */
+ if (!list_empty(&peer->conn_active))
+@@ -393,11 +482,12 @@
+ /* manually timeout all conns in the graveyard */
+ spin_lock(&peer->conn_gylock);
+ while (!list_empty(&peer->conn_graveyard)) {
+- conn = list_entry(peer->conn_graveyard.next,struct rxrpc_connection,link);
++ conn = list_entry(peer->conn_graveyard.next,
++ struct rxrpc_connection, link);
+ err = rxrpc_krxtimod_del_timer(&conn->timeout);
+ spin_unlock(&peer->conn_gylock);
+
+- if (err==0)
++ if (err == 0)
+ rxrpc_conn_do_timeout(conn);
+
+ spin_lock(&peer->conn_gylock);
+@@ -406,27 +496,27 @@
+
+ /* wait for the the conn graveyard to be completely cleared */
+ set_current_state(TASK_UNINTERRUPTIBLE);
+- add_wait_queue(&peer->conn_gy_waitq,&myself);
++ add_wait_queue(&peer->conn_gy_waitq, &myself);
+
+- while (atomic_read(&peer->conn_count)!=0) {
++ while (atomic_read(&peer->conn_count) != 0) {
+ schedule();
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ }
+
+- remove_wait_queue(&peer->conn_gy_waitq,&myself);
++ remove_wait_queue(&peer->conn_gy_waitq, &myself);
+ set_current_state(TASK_RUNNING);
+
+ _leave("");
+-
+ } /* end rxrpc_conn_clearall() */
+
+ /*****************************************************************************/
+ /*
+- * allocate and prepare a message for sending out through the transport endpoint
++ * allocate and prepare a message for sending out through the transport
++ * endpoint
+ */
+ int rxrpc_conn_newmsg(struct rxrpc_connection *conn,
+ struct rxrpc_call *call,
+- u8 type,
++ uint8_t type,
+ int dcount,
+ struct iovec diov[],
+ int alloc_flags,
+@@ -435,21 +525,21 @@
+ struct rxrpc_message *msg;
+ int loop;
+
+- _enter("%p{%d},%p,%u",conn,ntohs(conn->addr.sin_port),call,type);
++ _enter("%p{%d},%p,%u", conn, ntohs(conn->addr.sin_port), call, type);
+
+- if (dcount>3) {
++ if (dcount > 3) {
+ _leave(" = -EINVAL");
+ return -EINVAL;
+ }
+
+- msg = kmalloc(sizeof(struct rxrpc_message),alloc_flags);
++ msg = kmalloc(sizeof(struct rxrpc_message), alloc_flags);
+ if (!msg) {
+ _leave(" = -ENOMEM");
+ return -ENOMEM;
+ }
+
+- memset(msg,0,sizeof(*msg));
+- atomic_set(&msg->usage,1);
++ memset(msg, 0, sizeof(*msg));
++ atomic_set(&msg->usage, 1);
+
+ INIT_LIST_HEAD(&msg->link);
+
+@@ -471,7 +561,8 @@
+ msg->hdr.seq = htonl(msg->seq);
+ break;
+ case RXRPC_PACKET_TYPE_ACK:
+- /* ACK sequence numbers are complicated. The following may be wrong:
++ /* ACK sequence numbers are complicated. The following
++ * may be wrong:
+ * - jumbo packet ACKs should have a seq number
+ * - normal ACKs should not
+ */
+@@ -485,7 +576,7 @@
+ msg->data[0].iov_len = sizeof(msg->hdr);
+ msg->data[0].iov_base = &msg->hdr;
+
+- for (loop=0; loop<dcount; loop++) {
++ for (loop=0; loop < dcount; loop++) {
+ msg->dsize += diov[loop].iov_len;
+ msg->data[loop+1].iov_len = diov[loop].iov_len;
+ msg->data[loop+1].iov_base = diov[loop].iov_base;
+@@ -493,7 +584,7 @@
+
+ __RXACCT(atomic_inc(&rxrpc_message_count));
+ *_msg = msg;
+- _leave(" = 0 (%p) #%d",msg,atomic_read(&rxrpc_message_count));
++ _leave(" = 0 (%p) #%d", msg, atomic_read(&rxrpc_message_count));
+ return 0;
+ } /* end rxrpc_conn_newmsg() */
+
+@@ -505,13 +596,14 @@
+ {
+ int loop;
+
+- _enter("%p #%d",msg,atomic_read(&rxrpc_message_count));
++ _enter("%p #%d", msg, atomic_read(&rxrpc_message_count));
+
+- if (msg->pkt) kfree_skb(msg->pkt);
+- if (msg->conn) rxrpc_put_connection(msg->conn);
++ if (msg->pkt)
++ kfree_skb(msg->pkt);
++ rxrpc_put_connection(msg->conn);
+
+- for (loop=0; loop<8; loop++)
+- if (test_bit(loop,&msg->dfree))
++ for (loop = 0; loop < 8; loop++)
++ if (test_bit(loop, &msg->dfree))
+ kfree(msg->data[loop].iov_base);
+
+ __RXACCT(atomic_dec(&rxrpc_message_count));
+@@ -524,13 +616,14 @@
+ /*
+ * send a message out through the transport endpoint
+ */
+-int rxrpc_conn_sendmsg(struct rxrpc_connection *conn, struct rxrpc_message *msg)
++int rxrpc_conn_sendmsg(struct rxrpc_connection *conn,
++ struct rxrpc_message *msg)
+ {
+ struct msghdr msghdr;
+ mm_segment_t oldfs;
+ int ret;
+
+- _enter("%p{%d}",conn,ntohs(conn->addr.sin_port));
++ _enter("%p{%d}", conn, ntohs(conn->addr.sin_port));
+
+ /* fill in some fields in the header */
+ spin_lock(&conn->lock);
+@@ -545,7 +638,7 @@
+ msghdr.msg_iovlen = msg->dcount;
+ msghdr.msg_control = NULL;
+ msghdr.msg_controllen = 0;
+- msghdr.msg_flags = MSG_CONFIRM|MSG_DONTWAIT;
++ msghdr.msg_flags = MSG_CONFIRM | MSG_DONTWAIT;
+
+ _net("Sending message type %d of %Zd bytes to %08x:%d",
+ msg->hdr.type,
+@@ -556,10 +649,10 @@
+ /* send the message */
+ oldfs = get_fs();
+ set_fs(KERNEL_DS);
+- ret = sock_sendmsg(conn->trans->socket,&msghdr,msg->dsize);
++ ret = sock_sendmsg(conn->trans->socket, &msghdr, msg->dsize);
+ set_fs(oldfs);
+
+- if (ret<0) {
++ if (ret < 0) {
+ msg->state = RXRPC_MSG_ERROR;
+ }
+ else {
+@@ -572,7 +665,7 @@
+ spin_unlock(&conn->lock);
+ }
+
+- _leave(" = %d",ret);
++ _leave(" = %d", ret);
+
+ return ret;
+ } /* end rxrpc_conn_sendmsg() */
+@@ -590,7 +683,7 @@
+ unsigned cix, seq;
+ int ret = 0;
+
+- _enter("%p,%p,%p",conn,call,msg);
++ _enter("%p,%p,%p", conn, call, msg);
+
+ if (!call) {
+ cix = ntohl(msg->hdr.cid) & RXRPC_CHANNELMASK;
+@@ -600,7 +693,7 @@
+
+ if (!call || call->call_id != msg->hdr.callNumber) {
+ spin_unlock(&conn->lock);
+- rxrpc_trans_immediate_abort(conn->trans,msg,-ENOENT);
++ rxrpc_trans_immediate_abort(conn->trans, msg, -ENOENT);
+ goto out;
+ }
+ else {
+@@ -622,19 +715,21 @@
+ call->pkt_rcv_count++;
+
+ if (msg->pkt->dst && msg->pkt->dst->dev)
+- conn->peer->if_mtu = msg->pkt->dst->dev->mtu - msg->pkt->dst->dev->hard_header_len;
++ conn->peer->if_mtu =
++ msg->pkt->dst->dev->mtu -
++ msg->pkt->dst->dev->hard_header_len;
+
+ /* queue on the call in seq order */
+ rxrpc_get_message(msg);
+ seq = msg->seq;
+
+ spin_lock(&call->lock);
+- list_for_each(_p,&call->rcv_receiveq) {
+- pmsg = list_entry(_p,struct rxrpc_message,link);
+- if (pmsg->seq>seq)
++ list_for_each(_p, &call->rcv_receiveq) {
++ pmsg = list_entry(_p, struct rxrpc_message, link);
++ if (pmsg->seq > seq)
+ break;
+ }
+- list_add_tail(&msg->link,_p);
++ list_add_tail(&msg->link, _p);
+
+ /* reset the activity timeout */
+ call->flags |= RXRPC_CALL_RCV_PKT;
+@@ -646,8 +741,7 @@
+
+ rxrpc_put_call(call);
+ out:
+- _leave(" = %d",ret);
+-
++ _leave(" = %d", ret);
+ return ret;
+ } /* end rxrpc_conn_receive_call_packet() */
+
+@@ -655,18 +749,19 @@
+ /*
+ * handle an ICMP error being applied to a connection
+ */
+-void rxrpc_conn_handle_error(struct rxrpc_connection *conn, int local, int errno)
++void rxrpc_conn_handle_error(struct rxrpc_connection *conn,
++ int local, int errno)
+ {
+ struct rxrpc_call *calls[4];
+ int loop;
+
+- _enter("%p{%d},%d",conn,ntohs(conn->addr.sin_port),errno);
++ _enter("%p{%d},%d", conn, ntohs(conn->addr.sin_port), errno);
+
+ /* get a ref to all my calls in one go */
+- memset(calls,0,sizeof(calls));
++ memset(calls, 0, sizeof(calls));
+ spin_lock(&conn->lock);
+
+- for (loop=3; loop>=0; loop--) {
++ for (loop = 3; loop >= 0; loop--) {
+ if (conn->channels[loop]) {
+ calls[loop] = conn->channels[loop];
+ rxrpc_get_call(calls[loop]);
+@@ -676,9 +771,9 @@
+ spin_unlock(&conn->lock);
+
+ /* now kick them all */
+- for (loop=3; loop>=0; loop--) {
++ for (loop = 3; loop >= 0; loop--) {
+ if (calls[loop]) {
+- rxrpc_call_handle_error(calls[loop],local,errno);
++ rxrpc_call_handle_error(calls[loop], local, errno);
+ rxrpc_put_call(calls[loop]);
+ }
+ }
+Index: linux-2.6.0-test5/net/rxrpc/internal.h
+===================================================================
+--- linux-2.6.0-test5.orig/net/rxrpc/internal.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/rxrpc/internal.h 2003-09-27 11:38:42.219110104 +0800
+@@ -55,7 +55,7 @@
+ siginfo_t sinfo;
+
+ spin_lock_irq(¤t->sighand->siglock);
+- dequeue_signal(current,¤t->blocked,&sinfo);
++ dequeue_signal(current, ¤t->blocked, &sinfo);
+ spin_unlock_irq(¤t->sighand->siglock);
+ }
+ }
+@@ -71,6 +71,7 @@
+ */
+ extern struct list_head rxrpc_conns;
+ extern struct rw_semaphore rxrpc_conns_sem;
++extern unsigned long rxrpc_conn_timeout;
+
+ extern void rxrpc_conn_do_timeout(struct rxrpc_connection *conn);
+ extern void rxrpc_conn_clearall(struct rxrpc_peer *peer);
+@@ -80,6 +81,7 @@
+ */
+ extern struct list_head rxrpc_peers;
+ extern struct rw_semaphore rxrpc_peers_sem;
++extern unsigned long rxrpc_peer_timeout;
+
+ extern void rxrpc_peer_calculate_rtt(struct rxrpc_peer *peer,
+ struct rxrpc_message *msg,
+Index: linux-2.6.0-test5/net/rxrpc/krxiod.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/rxrpc/krxiod.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/rxrpc/krxiod.c 2003-09-27 11:38:42.222109648 +0800
+@@ -44,6 +44,12 @@
+
+ daemonize("krxiod");
+
++ /* only certain signals are of interest */
++ spin_lock_irq(¤t->sighand->siglock);
++ siginitsetinv(¤t->blocked, 0);
++ recalc_sigpending();
++ spin_unlock_irq(¤t->sighand->siglock);
++
+ /* loop around waiting for work to do */
+ do {
+ /* wait for work or to be told to exit */
+@@ -51,7 +57,7 @@
+ if (!atomic_read(&rxrpc_krxiod_qcount)) {
+ set_current_state(TASK_INTERRUPTIBLE);
+
+- add_wait_queue(&rxrpc_krxiod_sleepq,&krxiod);
++ add_wait_queue(&rxrpc_krxiod_sleepq, &krxiod);
+
+ for (;;) {
+ set_current_state(TASK_INTERRUPTIBLE);
+@@ -63,7 +69,7 @@
+ schedule();
+ }
+
+- remove_wait_queue(&rxrpc_krxiod_sleepq,&krxiod);
++ remove_wait_queue(&rxrpc_krxiod_sleepq, &krxiod);
+ set_current_state(TASK_RUNNING);
+ }
+ _debug("### End Wait");
+@@ -78,12 +84,16 @@
+ spin_lock_irq(&rxrpc_krxiod_transportq_lock);
+
+ if (!list_empty(&rxrpc_krxiod_transportq)) {
+- trans = list_entry(rxrpc_krxiod_transportq.next,
+- struct rxrpc_transport,krxiodq_link);
++ trans = list_entry(
++ rxrpc_krxiod_transportq.next,
++ struct rxrpc_transport,
++ krxiodq_link);
++
+ list_del_init(&trans->krxiodq_link);
+ atomic_dec(&rxrpc_krxiod_qcount);
+
+- /* make sure it hasn't gone away and doesn't go away */
++ /* make sure it hasn't gone away and doesn't go
++ * away */
+ if (atomic_read(&trans->usage)>0)
+ rxrpc_get_transport(trans);
+ else
+@@ -106,13 +116,16 @@
+
+ if (!list_empty(&rxrpc_krxiod_callq)) {
+ call = list_entry(rxrpc_krxiod_callq.next,
+- struct rxrpc_call,rcv_krxiodq_lk);
++ struct rxrpc_call,
++ rcv_krxiodq_lk);
+ list_del_init(&call->rcv_krxiodq_lk);
+ atomic_dec(&rxrpc_krxiod_qcount);
+
+- /* make sure it hasn't gone away and doesn't go away */
+- if (atomic_read(&call->usage)>0) {
+- _debug("@@@ KRXIOD Begin Attend Call %p",call);
++ /* make sure it hasn't gone away and doesn't go
++ * away */
++ if (atomic_read(&call->usage) > 0) {
++ _debug("@@@ KRXIOD"
++ " Begin Attend Call %p",call);
+ rxrpc_get_call(call);
+ }
+ else {
+@@ -125,7 +138,7 @@
+ if (call) {
+ rxrpc_call_do_stuff(call);
+ rxrpc_put_call(call);
+- _debug("@@@ KRXIOD End Attend Call %p",call);
++ _debug("@@@ KRXIOD End Attend Call %p", call);
+ }
+ }
+
+@@ -137,7 +150,7 @@
+ } while (!rxrpc_krxiod_die);
+
+ /* and that's all */
+- complete_and_exit(&rxrpc_krxiod_dead,0);
++ complete_and_exit(&rxrpc_krxiod_dead, 0);
+
+ } /* end rxrpc_krxiod() */
+
+@@ -147,7 +160,7 @@
+ */
+ int __init rxrpc_krxiod_init(void)
+ {
+- return kernel_thread(rxrpc_krxiod,NULL,0);
++ return kernel_thread(rxrpc_krxiod, NULL, 0);
+
+ } /* end rxrpc_krxiod_init() */
+
+@@ -174,16 +187,17 @@
+ _enter("");
+
+ if (list_empty(&trans->krxiodq_link)) {
+- spin_lock_irqsave(&rxrpc_krxiod_transportq_lock,flags);
++ spin_lock_irqsave(&rxrpc_krxiod_transportq_lock, flags);
+
+ if (list_empty(&trans->krxiodq_link)) {
+- if (atomic_read(&trans->usage)>0) {
+- list_add_tail(&trans->krxiodq_link,&rxrpc_krxiod_transportq);
++ if (atomic_read(&trans->usage) > 0) {
++ list_add_tail(&trans->krxiodq_link,
++ &rxrpc_krxiod_transportq);
+ atomic_inc(&rxrpc_krxiod_qcount);
+ }
+ }
+
+- spin_unlock_irqrestore(&rxrpc_krxiod_transportq_lock,flags);
++ spin_unlock_irqrestore(&rxrpc_krxiod_transportq_lock, flags);
+ wake_up_all(&rxrpc_krxiod_sleepq);
+ }
+
+@@ -201,12 +215,12 @@
+
+ _enter("");
+
+- spin_lock_irqsave(&rxrpc_krxiod_transportq_lock,flags);
++ spin_lock_irqsave(&rxrpc_krxiod_transportq_lock, flags);
+ if (!list_empty(&trans->krxiodq_link)) {
+ list_del_init(&trans->krxiodq_link);
+ atomic_dec(&rxrpc_krxiod_qcount);
+ }
+- spin_unlock_irqrestore(&rxrpc_krxiod_transportq_lock,flags);
++ spin_unlock_irqrestore(&rxrpc_krxiod_transportq_lock, flags);
+
+ _leave("");
+
+@@ -221,15 +235,16 @@
+ unsigned long flags;
+
+ if (list_empty(&call->rcv_krxiodq_lk)) {
+- spin_lock_irqsave(&rxrpc_krxiod_callq_lock,flags);
+- if (atomic_read(&call->usage)>0) {
+- list_add_tail(&call->rcv_krxiodq_lk,&rxrpc_krxiod_callq);
++ spin_lock_irqsave(&rxrpc_krxiod_callq_lock, flags);
++ if (atomic_read(&call->usage) > 0) {
++ list_add_tail(&call->rcv_krxiodq_lk,
++ &rxrpc_krxiod_callq);
+ atomic_inc(&rxrpc_krxiod_qcount);
+ }
+- spin_unlock_irqrestore(&rxrpc_krxiod_callq_lock,flags);
++ spin_unlock_irqrestore(&rxrpc_krxiod_callq_lock, flags);
+ }
+ wake_up_all(&rxrpc_krxiod_sleepq);
+-
++
+ } /* end rxrpc_krxiod_queue_call() */
+
+ /*****************************************************************************/
+@@ -240,11 +255,11 @@
+ {
+ unsigned long flags;
+
+- spin_lock_irqsave(&rxrpc_krxiod_callq_lock,flags);
++ spin_lock_irqsave(&rxrpc_krxiod_callq_lock, flags);
+ if (!list_empty(&call->rcv_krxiodq_lk)) {
+ list_del_init(&call->rcv_krxiodq_lk);
+ atomic_dec(&rxrpc_krxiod_qcount);
+ }
+- spin_unlock_irqrestore(&rxrpc_krxiod_callq_lock,flags);
++ spin_unlock_irqrestore(&rxrpc_krxiod_callq_lock, flags);
+
+ } /* end rxrpc_krxiod_dequeue_call() */
+Index: linux-2.6.0-test5/net/rxrpc/krxsecd.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/rxrpc/krxsecd.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/rxrpc/krxsecd.c 2003-09-27 11:38:42.225109192 +0800
+@@ -36,7 +36,8 @@
+
+ static atomic_t rxrpc_krxsecd_qcount;
+
+-/* queue of unprocessed inbound messages with seqno #1 and RXRPC_CLIENT_INITIATED flag set */
++/* queue of unprocessed inbound messages with seqno #1 and
++ * RXRPC_CLIENT_INITIATED flag set */
+ static LIST_HEAD(rxrpc_krxsecd_initmsgq);
+ static spinlock_t rxrpc_krxsecd_initmsgq_lock = SPIN_LOCK_UNLOCKED;
+
+@@ -48,14 +49,20 @@
+ */
+ static int rxrpc_krxsecd(void *arg)
+ {
+- DECLARE_WAITQUEUE(krxsecd,current);
++ DECLARE_WAITQUEUE(krxsecd, current);
+
+ int die;
+
+- printk("Started krxsecd %d\n",current->pid);
++ printk("Started krxsecd %d\n", current->pid);
+
+ daemonize("krxsecd");
+
++ /* only certain signals are of interest */
++ spin_lock_irq(¤t->sighand->siglock);
++ siginitsetinv(¤t->blocked, 0);
++ recalc_sigpending();
++ spin_unlock_irq(¤t->sighand->siglock);
++
+ /* loop around waiting for work to do */
+ do {
+ /* wait for work or to be told to exit */
+@@ -63,7 +70,7 @@
+ if (!atomic_read(&rxrpc_krxsecd_qcount)) {
+ set_current_state(TASK_INTERRUPTIBLE);
+
+- add_wait_queue(&rxrpc_krxsecd_sleepq,&krxsecd);
++ add_wait_queue(&rxrpc_krxsecd_sleepq, &krxsecd);
+
+ for (;;) {
+ set_current_state(TASK_INTERRUPTIBLE);
+@@ -75,7 +82,7 @@
+ schedule();
+ }
+
+- remove_wait_queue(&rxrpc_krxsecd_sleepq,&krxsecd);
++ remove_wait_queue(&rxrpc_krxsecd_sleepq, &krxsecd);
+ set_current_state(TASK_RUNNING);
+ }
+ die = rxrpc_krxsecd_die;
+@@ -91,7 +98,7 @@
+
+ if (!list_empty(&rxrpc_krxsecd_initmsgq)) {
+ msg = list_entry(rxrpc_krxsecd_initmsgq.next,
+- struct rxrpc_message,link);
++ struct rxrpc_message, link);
+ list_del_init(&msg->link);
+ atomic_dec(&rxrpc_krxsecd_qcount);
+ }
+@@ -112,7 +119,7 @@
+ } while (!die);
+
+ /* and that's all */
+- complete_and_exit(&rxrpc_krxsecd_dead,0);
++ complete_and_exit(&rxrpc_krxsecd_dead, 0);
+
+ } /* end rxrpc_krxsecd() */
+
+@@ -122,7 +129,7 @@
+ */
+ int __init rxrpc_krxsecd_init(void)
+ {
+- return kernel_thread(rxrpc_krxsecd,NULL,0);
++ return kernel_thread(rxrpc_krxsecd, NULL, 0);
+
+ } /* end rxrpc_krxsecd_init() */
+
+@@ -154,11 +161,11 @@
+ /* move all the messages for this transport onto a temp list */
+ spin_lock(&rxrpc_krxsecd_initmsgq_lock);
+
+- list_for_each_safe(_p,_n,&rxrpc_krxsecd_initmsgq) {
+- msg = list_entry(_p,struct rxrpc_message,link);
+- if (msg->trans==trans) {
++ list_for_each_safe(_p, _n, &rxrpc_krxsecd_initmsgq) {
++ msg = list_entry(_p, struct rxrpc_message, link);
++ if (msg->trans == trans) {
+ list_del(&msg->link);
+- list_add_tail(&msg->link,&tmp);
++ list_add_tail(&msg->link, &tmp);
+ atomic_dec(&rxrpc_krxsecd_qcount);
+ }
+ }
+@@ -167,7 +174,7 @@
+
+ /* zap all messages on the temp list */
+ while (!list_empty(&tmp)) {
+- msg = list_entry(tmp.next,struct rxrpc_message,link);
++ msg = list_entry(tmp.next, struct rxrpc_message, link);
+ list_del_init(&msg->link);
+ rxrpc_put_message(msg);
+ }
+@@ -181,14 +188,14 @@
+ */
+ void rxrpc_krxsecd_queue_incoming_call(struct rxrpc_message *msg)
+ {
+- _enter("%p",msg);
++ _enter("%p", msg);
+
+ /* queue for processing by krxsecd */
+ spin_lock(&rxrpc_krxsecd_initmsgq_lock);
+
+ if (!rxrpc_krxsecd_die) {
+ rxrpc_get_message(msg);
+- list_add_tail(&msg->link,&rxrpc_krxsecd_initmsgq);
++ list_add_tail(&msg->link, &rxrpc_krxsecd_initmsgq);
+ atomic_inc(&rxrpc_krxsecd_qcount);
+ }
+
+@@ -212,10 +219,10 @@
+ unsigned short sid;
+ int ret;
+
+- _enter("%p{tr=%p}",msg,trans);
++ _enter("%p{tr=%p}", msg, trans);
+
+- ret = rxrpc_incoming_call(msg->conn,msg,&call);
+- if (ret<0)
++ ret = rxrpc_incoming_call(msg->conn, msg, &call);
++ if (ret < 0)
+ goto out;
+
+ /* find the matching service on the transport */
+@@ -223,11 +230,11 @@
+ srv = NULL;
+
+ spin_lock(&trans->lock);
+- list_for_each(_p,&trans->services) {
+- srv = list_entry(_p,struct rxrpc_service,link);
+- if (srv->service_id==sid && try_module_get(srv->owner)) {
++ list_for_each(_p, &trans->services) {
++ srv = list_entry(_p, struct rxrpc_service, link);
++ if (srv->service_id == sid && try_module_get(srv->owner)) {
+ /* found a match (made sure it won't vanish) */
+- _debug("found service '%s'",srv->name);
++ _debug("found service '%s'", srv->name);
+ call->owner = srv->owner;
+ break;
+ }
+@@ -238,7 +245,7 @@
+ * - the func must inc the call's usage count to keep it
+ */
+ ret = -ENOENT;
+- if (_p!=&trans->services) {
++ if (_p != &trans->services) {
+ /* attempt to accept the call */
+ call->conn->service = srv;
+ call->app_attn_func = srv->attn_func;
+@@ -248,19 +255,20 @@
+ ret = srv->new_call(call);
+
+ /* send an abort if an error occurred */
+- if (ret<0) {
+- rxrpc_call_abort(call,ret);
++ if (ret < 0) {
++ rxrpc_call_abort(call, ret);
+ }
+ else {
+ /* formally receive and ACK the new packet */
+- ret = rxrpc_conn_receive_call_packet(call->conn,call,msg);
++ ret = rxrpc_conn_receive_call_packet(call->conn,
++ call, msg);
+ }
+ }
+
+ rxrpc_put_call(call);
+ out:
+- if (ret<0)
+- rxrpc_trans_immediate_abort(trans,msg,ret);
++ if (ret < 0)
++ rxrpc_trans_immediate_abort(trans, msg, ret);
+
+- _leave(" (%d)",ret);
++ _leave(" (%d)", ret);
+ } /* end rxrpc_krxsecd_process_incoming_call() */
+Index: linux-2.6.0-test5/net/rxrpc/krxtimod.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/rxrpc/krxtimod.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/rxrpc/krxtimod.c 2003-09-27 11:38:42.228108736 +0800
+@@ -36,8 +36,8 @@
+ {
+ int ret;
+
+- ret = kernel_thread(krxtimod,NULL,0);
+- if (ret<0)
++ ret = kernel_thread(krxtimod, NULL, 0);
++ if (ret < 0)
+ return ret;
+
+ wait_for_completion(&krxtimod_alive);
+@@ -64,30 +64,36 @@
+ */
+ static int krxtimod(void *arg)
+ {
+- DECLARE_WAITQUEUE(myself,current);
++ DECLARE_WAITQUEUE(myself, current);
+
+ rxrpc_timer_t *timer;
+
+- printk("Started krxtimod %d\n",current->pid);
++ printk("Started krxtimod %d\n", current->pid);
+
+ daemonize("krxtimod");
+
+ complete(&krxtimod_alive);
+
++ /* only certain signals are of interest */
++ spin_lock_irq(¤t->sighand->siglock);
++ siginitsetinv(¤t->blocked, 0);
++ recalc_sigpending();
++ spin_unlock_irq(¤t->sighand->siglock);
++
+ /* loop around looking for things to attend to */
+ loop:
+ set_current_state(TASK_INTERRUPTIBLE);
+- add_wait_queue(&krxtimod_sleepq,&myself);
++ add_wait_queue(&krxtimod_sleepq, &myself);
+
+ for (;;) {
+ unsigned long jif;
+- unsigned long timeout;
++ signed long timeout;
+
+ /* deal with the server being asked to die */
+ if (krxtimod_die) {
+- remove_wait_queue(&krxtimod_sleepq,&myself);
++ remove_wait_queue(&krxtimod_sleepq, &myself);
+ _leave("");
+- complete_and_exit(&krxtimod_dead,0);
++ complete_and_exit(&krxtimod_dead, 0);
+ }
+
+ /* discard pending signals */
+@@ -97,18 +103,19 @@
+ spin_lock(&krxtimod_lock);
+ if (list_empty(&krxtimod_list)) {
+ timeout = MAX_SCHEDULE_TIMEOUT;
+- } else {
+- unsigned long tmo;
+-
++ }
++ else {
+ timer = list_entry(krxtimod_list.next,
+ rxrpc_timer_t, link);
+- tmo = timer->timo_jif;
++ timeout = timer->timo_jif;
+ jif = jiffies;
+
+- if (time_before_eq(tmo,jif))
++ if (time_before_eq((unsigned long) timeout, jif))
+ goto immediate;
+
+- timeout = (long)tmo - (long)jiffies;
++ else {
++ timeout = (long) timeout - (long) jiffies;
++ }
+ }
+ spin_unlock(&krxtimod_lock);
+
+@@ -118,13 +125,14 @@
+ }
+
+ /* the thing on the front of the queue needs processing
+- * - we come here with the lock held and timer pointing to the expired entry
++ * - we come here with the lock held and timer pointing to the expired
++ * entry
+ */
+ immediate:
+- remove_wait_queue(&krxtimod_sleepq,&myself);
++ remove_wait_queue(&krxtimod_sleepq, &myself);
+ set_current_state(TASK_RUNNING);
+
+- _debug("@@@ Begin Timeout of %p",timer);
++ _debug("@@@ Begin Timeout of %p", timer);
+
+ /* dequeue the timer */
+ list_del_init(&timer->link);
+@@ -147,29 +155,30 @@
+ struct list_head *_p;
+ rxrpc_timer_t *ptimer;
+
+- _enter("%p,%lu",timer,timeout);
++ _enter("%p,%lu", timer, timeout);
+
+ spin_lock(&krxtimod_lock);
+
+ list_del(&timer->link);
+
+- /* the timer was deferred or reset - put it back in the queue at the right place */
++ /* the timer was deferred or reset - put it back in the queue at the
++ * right place */
+ timer->timo_jif = jiffies + timeout;
+
+- list_for_each(_p,&krxtimod_list) {
+- ptimer = list_entry(_p,rxrpc_timer_t,link);
+- if (time_before(timer->timo_jif,ptimer->timo_jif))
++ list_for_each(_p, &krxtimod_list) {
++ ptimer = list_entry(_p, rxrpc_timer_t, link);
++ if (time_before(timer->timo_jif, ptimer->timo_jif))
+ break;
+ }
+
+- list_add_tail(&timer->link,_p); /* insert before stopping point */
++ list_add_tail(&timer->link, _p); /* insert before stopping point */
+
+ spin_unlock(&krxtimod_lock);
+
+ wake_up(&krxtimod_sleepq);
+
+ _leave("");
+-} /* end rxrpc_krxtimod_queue_vlocation() */
++} /* end rxrpc_krxtimod_add_timer() */
+
+ /*****************************************************************************/
+ /*
+@@ -180,7 +189,7 @@
+ {
+ int ret = 0;
+
+- _enter("%p",timer);
++ _enter("%p", timer);
+
+ spin_lock(&krxtimod_lock);
+
+@@ -193,6 +202,6 @@
+
+ wake_up(&krxtimod_sleepq);
+
+- _leave(" = %d",ret);
++ _leave(" = %d", ret);
+ return ret;
+ } /* end rxrpc_krxtimod_del_timer() */
+Index: linux-2.6.0-test5/net/rxrpc/main.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/rxrpc/main.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/rxrpc/main.c 2003-09-27 11:38:42.230108432 +0800
+@@ -32,7 +32,7 @@
+ MODULE_AUTHOR("Red Hat, Inc.");
+ MODULE_LICENSE("GPL");
+
+-u32 rxrpc_epoch;
++uint32_t rxrpc_epoch;
+
+ /*****************************************************************************/
+ /*
+@@ -101,11 +101,16 @@
+ {
+ kenter("");
+
+- __RXACCT(printk("Outstanding Messages : %d\n",atomic_read(&rxrpc_message_count)));
+- __RXACCT(printk("Outstanding Calls : %d\n",atomic_read(&rxrpc_call_count)));
+- __RXACCT(printk("Outstanding Connections: %d\n",atomic_read(&rxrpc_connection_count)));
+- __RXACCT(printk("Outstanding Peers : %d\n",atomic_read(&rxrpc_peer_count)));
+- __RXACCT(printk("Outstanding Transports : %d\n",atomic_read(&rxrpc_transport_count)));
++ __RXACCT(printk("Outstanding Messages : %d\n",
++ atomic_read(&rxrpc_message_count)));
++ __RXACCT(printk("Outstanding Calls : %d\n",
++ atomic_read(&rxrpc_call_count)));
++ __RXACCT(printk("Outstanding Connections: %d\n",
++ atomic_read(&rxrpc_connection_count)));
++ __RXACCT(printk("Outstanding Peers : %d\n",
++ atomic_read(&rxrpc_peer_count)));
++ __RXACCT(printk("Outstanding Transports : %d\n",
++ atomic_read(&rxrpc_transport_count)));
+
+ rxrpc_krxsecd_kill();
+ rxrpc_krxiod_kill();
+@@ -117,11 +122,61 @@
+ rxrpc_proc_cleanup();
+ #endif
+
+- __RXACCT(printk("Outstanding Messages : %d\n",atomic_read(&rxrpc_message_count)));
+- __RXACCT(printk("Outstanding Calls : %d\n",atomic_read(&rxrpc_call_count)));
+- __RXACCT(printk("Outstanding Connections: %d\n",atomic_read(&rxrpc_connection_count)));
+- __RXACCT(printk("Outstanding Peers : %d\n",atomic_read(&rxrpc_peer_count)));
+- __RXACCT(printk("Outstanding Transports : %d\n",atomic_read(&rxrpc_transport_count)));
++ __RXACCT(printk("Outstanding Messages : %d\n",
++ atomic_read(&rxrpc_message_count)));
++ __RXACCT(printk("Outstanding Calls : %d\n",
++ atomic_read(&rxrpc_call_count)));
++ __RXACCT(printk("Outstanding Connections: %d\n",
++ atomic_read(&rxrpc_connection_count)));
++ __RXACCT(printk("Outstanding Peers : %d\n",
++ atomic_read(&rxrpc_peer_count)));
++ __RXACCT(printk("Outstanding Transports : %d\n",
++ atomic_read(&rxrpc_transport_count)));
+
+ kleave("");
+ } /* end rxrpc_cleanup() */
++
++/*****************************************************************************/
++/*
++ * clear the dead space between task_struct and kernel stack
++ * - called by supplying -finstrument-functions to gcc
++ */
++#if 0
++void __cyg_profile_func_enter (void *this_fn, void *call_site)
++__attribute__((no_instrument_function));
++
++void __cyg_profile_func_enter (void *this_fn, void *call_site)
++{
++ asm volatile(" movl %%esp,%%edi \n"
++ " andl %0,%%edi \n"
++ " addl %1,%%edi \n"
++ " movl %%esp,%%ecx \n"
++ " subl %%edi,%%ecx \n"
++ " shrl $2,%%ecx \n"
++ " movl $0xedededed,%%eax \n"
++ " rep stosl \n"
++ :
++ : "i"(~(THREAD_SIZE-1)), "i"(sizeof(struct thread_info))
++ : "eax", "ecx", "edi", "memory", "cc"
++ );
++}
++
++void __cyg_profile_func_exit(void *this_fn, void *call_site)
++__attribute__((no_instrument_function));
++
++void __cyg_profile_func_exit(void *this_fn, void *call_site)
++{
++ asm volatile(" movl %%esp,%%edi \n"
++ " andl %0,%%edi \n"
++ " addl %1,%%edi \n"
++ " movl %%esp,%%ecx \n"
++ " subl %%edi,%%ecx \n"
++ " shrl $2,%%ecx \n"
++ " movl $0xdadadada,%%eax \n"
++ " rep stosl \n"
++ :
++ : "i"(~(THREAD_SIZE-1)), "i"(sizeof(struct thread_info))
++ : "eax", "ecx", "edi", "memory", "cc"
++ );
++}
++#endif
+Index: linux-2.6.0-test5/net/rxrpc/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/net/rxrpc/Makefile 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/rxrpc/Makefile 2003-09-27 11:38:42.231108280 +0800
+@@ -2,7 +2,9 @@
+ # Makefile for Linux kernel Rx RPC
+ #
+
+-rxrpc-y := \
++#CFLAGS += -finstrument-functions
++
++rxrpc-objs := \
+ call.o \
+ connection.o \
+ krxiod.o \
+@@ -13,7 +15,11 @@
+ rxrpc_syms.o \
+ transport.o
+
+-rxrpc-$(CONFIG_PROC_FS) += proc.o
+-rxrpc-$(CONFIG_SYSCTL) += sysctl.o
++ifeq ($(CONFIG_PROC_FS),y)
++rxrpc-objs += proc.o
++endif
++ifeq ($(CONFIG_SYSCTL),y)
++rxrpc-objs += sysctl.o
++endif
+
+ obj-$(CONFIG_RXRPC) := rxrpc.o
+Index: linux-2.6.0-test5/net/rxrpc/peer.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/rxrpc/peer.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/rxrpc/peer.c 2003-09-27 11:38:42.235107672 +0800
+@@ -28,12 +28,14 @@
+ __RXACCT_DECL(atomic_t rxrpc_peer_count);
+ LIST_HEAD(rxrpc_peers);
+ DECLARE_RWSEM(rxrpc_peers_sem);
++unsigned long rxrpc_peer_timeout = 12 * 60 * 60;
+
+ static void __rxrpc_peer_timeout(rxrpc_timer_t *timer)
+ {
+- struct rxrpc_peer *peer = list_entry(timer,struct rxrpc_peer,timeout);
++ struct rxrpc_peer *peer =
++ list_entry(timer, struct rxrpc_peer, timeout);
+
+- _debug("Rx PEER TIMEOUT [%p{u=%d}]",peer,atomic_read(&peer->usage));
++ _debug("Rx PEER TIMEOUT [%p{u=%d}]", peer, atomic_read(&peer->usage));
+
+ rxrpc_peer_do_timeout(peer);
+ }
+@@ -46,32 +48,35 @@
+ /*
+ * create a peer record
+ */
+-static int __rxrpc_create_peer(struct rxrpc_transport *trans, u32 addr, struct rxrpc_peer **_peer)
++static int __rxrpc_create_peer(struct rxrpc_transport *trans, uint32_t addr,
++ struct rxrpc_peer **_peer)
+ {
+ struct rxrpc_peer *peer;
+
+- _enter("%p,%08x",trans,ntohl(addr));
++ _enter("%p,%08x", trans, ntohl(addr));
+
+ /* allocate and initialise a peer record */
+- peer = kmalloc(sizeof(struct rxrpc_peer),GFP_KERNEL);
++ peer = kmalloc(sizeof(struct rxrpc_peer), GFP_KERNEL);
+ if (!peer) {
+ _leave(" = -ENOMEM");
+ return -ENOMEM;
+ }
+
+- memset(peer,0,sizeof(struct rxrpc_peer));
+- atomic_set(&peer->usage,1);
++ memset(peer, 0, sizeof(struct rxrpc_peer));
++ atomic_set(&peer->usage, 1);
+
+ INIT_LIST_HEAD(&peer->link);
+ INIT_LIST_HEAD(&peer->proc_link);
++ INIT_LIST_HEAD(&peer->conn_idlist);
+ INIT_LIST_HEAD(&peer->conn_active);
+ INIT_LIST_HEAD(&peer->conn_graveyard);
+ spin_lock_init(&peer->conn_gylock);
+ init_waitqueue_head(&peer->conn_gy_waitq);
++ rwlock_init(&peer->conn_idlock);
+ rwlock_init(&peer->conn_lock);
+- atomic_set(&peer->conn_count,0);
++ atomic_set(&peer->conn_count, 0);
+ spin_lock_init(&peer->lock);
+- rxrpc_timer_init(&peer->timeout,&rxrpc_peer_timer_ops);
++ rxrpc_timer_init(&peer->timeout, &rxrpc_peer_timer_ops);
+
+ peer->addr.s_addr = addr;
+
+@@ -80,7 +85,7 @@
+
+ __RXACCT(atomic_inc(&rxrpc_peer_count));
+ *_peer = peer;
+- _leave(" = 0 (%p)",peer);
++ _leave(" = 0 (%p)", peer);
+
+ return 0;
+ } /* end __rxrpc_create_peer() */
+@@ -91,43 +96,45 @@
+ * - returns (if successful) with peer record usage incremented
+ * - resurrects it from the graveyard if found there
+ */
+-int rxrpc_peer_lookup(struct rxrpc_transport *trans, u32 addr, struct rxrpc_peer **_peer)
++int rxrpc_peer_lookup(struct rxrpc_transport *trans, uint32_t addr,
++ struct rxrpc_peer **_peer)
+ {
+ struct rxrpc_peer *peer, *candidate = NULL;
+ struct list_head *_p;
+ int ret;
+
+- _enter("%p{%hu},%08x",trans,trans->port,ntohl(addr));
++ _enter("%p{%hu},%08x", trans, trans->port, ntohl(addr));
+
+ /* [common case] search the transport's active list first */
+ read_lock(&trans->peer_lock);
+- list_for_each(_p,&trans->peer_active) {
+- peer = list_entry(_p,struct rxrpc_peer,link);
+- if (peer->addr.s_addr==addr)
++ list_for_each(_p, &trans->peer_active) {
++ peer = list_entry(_p, struct rxrpc_peer, link);
++ if (peer->addr.s_addr == addr)
+ goto found_active;
+ }
+ read_unlock(&trans->peer_lock);
+
+ /* [uncommon case] not active - create a candidate for a new record */
+- ret = __rxrpc_create_peer(trans,addr,&candidate);
+- if (ret<0) {
+- _leave(" = %d",ret);
++ ret = __rxrpc_create_peer(trans, addr, &candidate);
++ if (ret < 0) {
++ _leave(" = %d", ret);
+ return ret;
+ }
+
+- /* search the active list again, just in case it appeared whilst we were busy */
++ /* search the active list again, just in case it appeared whilst we
++ * were busy */
+ write_lock(&trans->peer_lock);
+- list_for_each(_p,&trans->peer_active) {
+- peer = list_entry(_p,struct rxrpc_peer,link);
+- if (peer->addr.s_addr==addr)
++ list_for_each(_p, &trans->peer_active) {
++ peer = list_entry(_p, struct rxrpc_peer, link);
++ if (peer->addr.s_addr == addr)
+ goto found_active_second_chance;
+ }
+
+ /* search the transport's graveyard list */
+ spin_lock(&trans->peer_gylock);
+- list_for_each(_p,&trans->peer_graveyard) {
+- peer = list_entry(_p,struct rxrpc_peer,link);
+- if (peer->addr.s_addr==addr)
++ list_for_each(_p, &trans->peer_graveyard) {
++ peer = list_entry(_p, struct rxrpc_peer, link);
++ if (peer->addr.s_addr == addr)
+ goto found_in_graveyard;
+ }
+ spin_unlock(&trans->peer_gylock);
+@@ -141,12 +148,12 @@
+
+ if (peer->ops && peer->ops->adding) {
+ ret = peer->ops->adding(peer);
+- if (ret<0) {
++ if (ret < 0) {
+ write_unlock(&trans->peer_lock);
+ __RXACCT(atomic_dec(&rxrpc_peer_count));
+ kfree(peer);
+ rxrpc_put_transport(trans);
+- _leave(" = %d",ret);
++ _leave(" = %d", ret);
+ return ret;
+ }
+ }
+@@ -154,7 +161,7 @@
+ atomic_inc(&trans->peer_count);
+
+ make_active:
+- list_add_tail(&peer->link,&trans->peer_active);
++ list_add_tail(&peer->link, &trans->peer_active);
+
+ success_uwfree:
+ write_unlock(&trans->peer_lock);
+@@ -166,7 +173,7 @@
+
+ if (list_empty(&peer->proc_link)) {
+ down_write(&rxrpc_peers_sem);
+- list_add_tail(&peer->proc_link,&rxrpc_peers);
++ list_add_tail(&peer->proc_link, &rxrpc_peers);
+ up_write(&rxrpc_peers_sem);
+ }
+
+@@ -174,7 +181,9 @@
+ *_peer = peer;
+
+ _leave(" = 0 (%p{u=%d cc=%d})",
+- peer,atomic_read(&peer->usage),atomic_read(&peer->conn_count));
++ peer,
++ atomic_read(&peer->usage),
++ atomic_read(&peer->conn_count));
+ return 0;
+
+ /* handle the peer being found in the active list straight off */
+@@ -192,7 +201,8 @@
+ spin_unlock(&trans->peer_gylock);
+ goto make_active;
+
+- /* handle finding the peer on the second time through the active list */
++ /* handle finding the peer on the second time through the active
++ * list */
+ found_active_second_chance:
+ rxrpc_get_peer(peer);
+ goto success_uwfree;
+@@ -202,16 +212,20 @@
+ /*****************************************************************************/
+ /*
+ * finish with a peer record
+- * - it gets sent to the graveyard from where it can be resurrected or timed out
++ * - it gets sent to the graveyard from where it can be resurrected or timed
++ * out
+ */
+ void rxrpc_put_peer(struct rxrpc_peer *peer)
+ {
+ struct rxrpc_transport *trans = peer->trans;
+
+- _enter("%p{cc=%d a=%08x}",peer,atomic_read(&peer->conn_count),ntohl(peer->addr.s_addr));
++ _enter("%p{cc=%d a=%08x}",
++ peer,
++ atomic_read(&peer->conn_count),
++ ntohl(peer->addr.s_addr));
+
+ /* sanity check */
+- if (atomic_read(&peer->usage)<=0)
++ if (atomic_read(&peer->usage) <= 0)
+ BUG();
+
+ write_lock(&trans->peer_lock);
+@@ -227,12 +241,11 @@
+ list_del(&peer->link);
+ write_unlock(&trans->peer_lock);
+
+- list_add_tail(&peer->link,&trans->peer_graveyard);
++ list_add_tail(&peer->link, &trans->peer_graveyard);
+
+- if (!list_empty(&peer->conn_active)) BUG();
++ BUG_ON(!list_empty(&peer->conn_active));
+
+- /* discard in 600 secs */
+- rxrpc_krxtimod_add_timer(&peer->timeout,100*HZ);
++ rxrpc_krxtimod_add_timer(&peer->timeout, rxrpc_peer_timeout * HZ);
+
+ spin_unlock(&trans->peer_gylock);
+
+@@ -251,15 +264,16 @@
+ struct rxrpc_transport *trans = peer->trans;
+
+ _enter("%p{u=%d cc=%d a=%08x}",
+- peer,atomic_read(&peer->usage),atomic_read(&peer->conn_count),
++ peer,
++ atomic_read(&peer->usage),
++ atomic_read(&peer->conn_count),
+ ntohl(peer->addr.s_addr));
+
+- if (atomic_read(&peer->usage)<0)
+- BUG();
++ BUG_ON(atomic_read(&peer->usage) < 0);
+
+ /* remove from graveyard if still dead */
+ spin_lock(&trans->peer_gylock);
+- if (atomic_read(&peer->usage)==0)
++ if (atomic_read(&peer->usage) == 0)
+ list_del_init(&peer->link);
+ else
+ peer = NULL;
+@@ -273,8 +287,8 @@
+ /* clear all connections on this peer */
+ rxrpc_conn_clearall(peer);
+
+- if (!list_empty(&peer->conn_active)) BUG();
+- if (!list_empty(&peer->conn_graveyard)) BUG();
++ BUG_ON(!list_empty(&peer->conn_active));
++ BUG_ON(!list_empty(&peer->conn_graveyard));
+
+ /* inform the application layer */
+ if (peer->ops && peer->ops->discarding)
+@@ -310,18 +324,18 @@
+ _enter("%p",trans);
+
+ /* there shouldn't be any active peers remaining */
+- if (!list_empty(&trans->peer_active))
+- BUG();
++ BUG_ON(!list_empty(&trans->peer_active));
+
+ /* manually timeout all peers in the graveyard */
+ spin_lock(&trans->peer_gylock);
+ while (!list_empty(&trans->peer_graveyard)) {
+- peer = list_entry(trans->peer_graveyard.next,struct rxrpc_peer,link);
+- _debug("Clearing peer %p\n",peer);
++ peer = list_entry(trans->peer_graveyard.next,
++ struct rxrpc_peer, link);
++ _debug("Clearing peer %p\n", peer);
+ err = rxrpc_krxtimod_del_timer(&peer->timeout);
+ spin_unlock(&trans->peer_gylock);
+
+- if (err==0)
++ if (err == 0)
+ rxrpc_peer_do_timeout(peer);
+
+ spin_lock(&trans->peer_gylock);
+@@ -330,18 +344,17 @@
+
+ /* wait for the the peer graveyard to be completely cleared */
+ set_current_state(TASK_UNINTERRUPTIBLE);
+- add_wait_queue(&trans->peer_gy_waitq,&myself);
++ add_wait_queue(&trans->peer_gy_waitq, &myself);
+
+- while (atomic_read(&trans->peer_count)!=0) {
++ while (atomic_read(&trans->peer_count) != 0) {
+ schedule();
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ }
+
+- remove_wait_queue(&trans->peer_gy_waitq,&myself);
++ remove_wait_queue(&trans->peer_gy_waitq, &myself);
+ set_current_state(TASK_RUNNING);
+
+ _leave("");
+-
+ } /* end rxrpc_peer_clearall() */
+
+ /*****************************************************************************/
+@@ -355,7 +368,7 @@
+ unsigned long long rtt;
+ int loop;
+
+- _enter("%p,%p,%p",peer,msg,resp);
++ _enter("%p,%p,%p", peer, msg, resp);
+
+ /* calculate the latest RTT */
+ rtt = resp->stamp.tv_sec - msg->stamp.tv_sec;
+@@ -367,16 +380,18 @@
+ peer->rtt_point++;
+ peer->rtt_point %= RXRPC_RTT_CACHE_SIZE;
+
+- if (peer->rtt_usage<RXRPC_RTT_CACHE_SIZE) peer->rtt_usage++;
++ if (peer->rtt_usage < RXRPC_RTT_CACHE_SIZE)
++ peer->rtt_usage++;
+
+ /* recalculate RTT */
+ rtt = 0;
+- for (loop=peer->rtt_usage-1; loop>=0; loop--)
++ for (loop = peer->rtt_usage - 1; loop >= 0; loop--)
+ rtt += peer->rtt_cache[loop];
+
+- do_div(rtt,peer->rtt_usage);
++ do_div(rtt, peer->rtt_usage);
+ peer->rtt = rtt;
+
+- _leave(" RTT=%lu.%lums",(long)(peer->rtt/1000),(long)(peer->rtt%1000));
++ _leave(" RTT=%lu.%lums",
++ (long) (peer->rtt / 1000), (long) (peer->rtt % 1000));
+
+ } /* end rxrpc_peer_calculate_rtt() */
+Index: linux-2.6.0-test5/net/rxrpc/proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/rxrpc/proc.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/rxrpc/proc.c 2003-09-27 11:38:42.241106760 +0800
+@@ -38,7 +38,6 @@
+ };
+
+ static struct file_operations rxrpc_proc_transports_fops = {
+- .owner = THIS_MODULE,
+ .open = rxrpc_proc_transports_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+@@ -59,7 +58,6 @@
+ };
+
+ static struct file_operations rxrpc_proc_peers_fops = {
+- .owner = THIS_MODULE,
+ .open = rxrpc_proc_peers_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+@@ -80,7 +78,6 @@
+ };
+
+ static struct file_operations rxrpc_proc_conns_fops = {
+- .owner = THIS_MODULE,
+ .open = rxrpc_proc_conns_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+@@ -101,7 +98,6 @@
+ };
+
+ static struct file_operations rxrpc_proc_calls_fops = {
+- .owner = THIS_MODULE,
+ .open = rxrpc_proc_calls_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+@@ -137,30 +133,30 @@
+ {
+ struct proc_dir_entry *p;
+
+- proc_rxrpc = proc_mkdir("rxrpc",proc_net);
++ proc_rxrpc = proc_mkdir("rxrpc", proc_net);
+ if (!proc_rxrpc)
+ goto error;
+ proc_rxrpc->owner = THIS_MODULE;
+
+- p = create_proc_entry("calls",0,proc_rxrpc);
++ p = create_proc_entry("calls", 0, proc_rxrpc);
+ if (!p)
+ goto error_proc;
+ p->proc_fops = &rxrpc_proc_calls_fops;
+ p->owner = THIS_MODULE;
+
+- p = create_proc_entry("connections",0,proc_rxrpc);
++ p = create_proc_entry("connections", 0, proc_rxrpc);
+ if (!p)
+ goto error_calls;
+ p->proc_fops = &rxrpc_proc_conns_fops;
+ p->owner = THIS_MODULE;
+
+- p = create_proc_entry("peers",0,proc_rxrpc);
++ p = create_proc_entry("peers", 0, proc_rxrpc);
+ if (!p)
+ goto error_calls;
+ p->proc_fops = &rxrpc_proc_peers_fops;
+ p->owner = THIS_MODULE;
+
+- p = create_proc_entry("transports",0,proc_rxrpc);
++ p = create_proc_entry("transports", 0, proc_rxrpc);
+ if (!p)
+ goto error_conns;
+ p->proc_fops = &rxrpc_proc_transports_fops;
+@@ -169,11 +165,11 @@
+ return 0;
+
+ error_conns:
+- remove_proc_entry("conns",proc_rxrpc);
++ remove_proc_entry("connections", proc_rxrpc);
+ error_calls:
+- remove_proc_entry("calls",proc_rxrpc);
++ remove_proc_entry("calls", proc_rxrpc);
+ error_proc:
+- remove_proc_entry("rxrpc",proc_net);
++ remove_proc_entry("rxrpc", proc_net);
+ error:
+ return -ENOMEM;
+ } /* end rxrpc_proc_init() */
+@@ -184,12 +180,12 @@
+ */
+ void rxrpc_proc_cleanup(void)
+ {
+- remove_proc_entry("transports",proc_rxrpc);
+- remove_proc_entry("peers",proc_rxrpc);
+- remove_proc_entry("connections",proc_rxrpc);
+- remove_proc_entry("calls",proc_rxrpc);
++ remove_proc_entry("transports", proc_rxrpc);
++ remove_proc_entry("peers", proc_rxrpc);
++ remove_proc_entry("connections", proc_rxrpc);
++ remove_proc_entry("calls", proc_rxrpc);
+
+- remove_proc_entry("rxrpc",proc_net);
++ remove_proc_entry("rxrpc", proc_net);
+
+ } /* end rxrpc_proc_cleanup() */
+
+@@ -202,8 +198,8 @@
+ struct seq_file *m;
+ int ret;
+
+- ret = seq_open(file,&rxrpc_proc_transports_ops);
+- if (ret<0)
++ ret = seq_open(file, &rxrpc_proc_transports_ops);
++ if (ret < 0)
+ return ret;
+
+ m = file->private_data;
+@@ -226,15 +222,15 @@
+
+ /* allow for the header line */
+ if (!pos)
+- return (void *)1;
++ return SEQ_START_TOKEN;
+ pos--;
+
+ /* find the n'th element in the list */
+- list_for_each(_p,&rxrpc_proc_transports)
++ list_for_each(_p, &rxrpc_proc_transports)
+ if (!pos--)
+ break;
+
+- return _p!=&rxrpc_proc_transports ? _p : NULL;
++ return _p != &rxrpc_proc_transports ? _p : NULL;
+ } /* end rxrpc_proc_transports_start() */
+
+ /*****************************************************************************/
+@@ -248,9 +244,9 @@
+ (*pos)++;
+
+ _p = v;
+- _p = v==(void*)1 ? rxrpc_proc_transports.next : _p->next;
++ _p = (v == SEQ_START_TOKEN) ? rxrpc_proc_transports.next : _p->next;
+
+- return _p!=&rxrpc_proc_transports ? _p : NULL;
++ return _p != &rxrpc_proc_transports ? _p : NULL;
+ } /* end rxrpc_proc_transports_next() */
+
+ /*****************************************************************************/
+@@ -269,16 +265,17 @@
+ */
+ static int rxrpc_proc_transports_show(struct seq_file *m, void *v)
+ {
+- struct rxrpc_transport *trans = list_entry(v,struct rxrpc_transport,proc_link);
++ struct rxrpc_transport *trans =
++ list_entry(v, struct rxrpc_transport, proc_link);
+
+ /* display header on line 1 */
+- if (v == (void *)1) {
++ if (v == SEQ_START_TOKEN) {
+ seq_puts(m, "LOCAL USE\n");
+ return 0;
+ }
+
+ /* display one transport per line on subsequent lines */
+- seq_printf(m,"%5hu %3d\n",
++ seq_printf(m, "%5hu %3d\n",
+ trans->port,
+ atomic_read(&trans->usage)
+ );
+@@ -295,8 +292,8 @@
+ struct seq_file *m;
+ int ret;
+
+- ret = seq_open(file,&rxrpc_proc_peers_ops);
+- if (ret<0)
++ ret = seq_open(file, &rxrpc_proc_peers_ops);
++ if (ret < 0)
+ return ret;
+
+ m = file->private_data;
+@@ -307,7 +304,8 @@
+
+ /*****************************************************************************/
+ /*
+- * set up the iterator to start reading from the peers list and return the first item
++ * set up the iterator to start reading from the peers list and return the
++ * first item
+ */
+ static void *rxrpc_proc_peers_start(struct seq_file *m, loff_t *_pos)
+ {
+@@ -319,15 +317,15 @@
+
+ /* allow for the header line */
+ if (!pos)
+- return (void *)1;
++ return SEQ_START_TOKEN;
+ pos--;
+
+ /* find the n'th element in the list */
+- list_for_each(_p,&rxrpc_peers)
++ list_for_each(_p, &rxrpc_peers)
+ if (!pos--)
+ break;
+
+- return _p!=&rxrpc_peers ? _p : NULL;
++ return _p != &rxrpc_peers ? _p : NULL;
+ } /* end rxrpc_proc_peers_start() */
+
+ /*****************************************************************************/
+@@ -341,9 +339,9 @@
+ (*pos)++;
+
+ _p = v;
+- _p = v==(void*)1 ? rxrpc_peers.next : _p->next;
++ _p = (v == SEQ_START_TOKEN) ? rxrpc_peers.next : _p->next;
+
+- return _p!=&rxrpc_peers ? _p : NULL;
++ return _p != &rxrpc_peers ? _p : NULL;
+ } /* end rxrpc_proc_peers_next() */
+
+ /*****************************************************************************/
+@@ -362,21 +360,23 @@
+ */
+ static int rxrpc_proc_peers_show(struct seq_file *m, void *v)
+ {
+- struct rxrpc_peer *peer = list_entry(v,struct rxrpc_peer,proc_link);
++ struct rxrpc_peer *peer = list_entry(v, struct rxrpc_peer, proc_link);
+ signed long timeout;
+
+ /* display header on line 1 */
+- if (v == (void *)1) {
+- seq_puts(m,"LOCAL REMOTE USAGE CONNS TIMEOUT MTU RTT(uS)\n");
++ if (v == SEQ_START_TOKEN) {
++ seq_puts(m, "LOCAL REMOTE USAGE CONNS TIMEOUT"
++ " MTU RTT(uS)\n");
+ return 0;
+ }
+
+ /* display one peer per line on subsequent lines */
+ timeout = 0;
+ if (!list_empty(&peer->timeout.link))
+- timeout = (signed long)peer->timeout.timo_jif - (signed long)jiffies;
++ timeout = (signed long) peer->timeout.timo_jif -
++ (signed long) jiffies;
+
+- seq_printf(m,"%5hu %08x %5d %5d %8ld %5Zu %7lu\n",
++ seq_printf(m, "%5hu %08x %5d %5d %8ld %5Zu %7lu\n",
+ peer->trans->port,
+ ntohl(peer->addr.s_addr),
+ atomic_read(&peer->usage),
+@@ -391,15 +391,16 @@
+
+ /*****************************************************************************/
+ /*
+- * open "/proc/net/rxrpc/connections" which provides a summary of extant connections
++ * open "/proc/net/rxrpc/connections" which provides a summary of extant
++ * connections
+ */
+ static int rxrpc_proc_conns_open(struct inode *inode, struct file *file)
+ {
+ struct seq_file *m;
+ int ret;
+
+- ret = seq_open(file,&rxrpc_proc_conns_ops);
+- if (ret<0)
++ ret = seq_open(file, &rxrpc_proc_conns_ops);
++ if (ret < 0)
+ return ret;
+
+ m = file->private_data;
+@@ -410,7 +411,8 @@
+
+ /*****************************************************************************/
+ /*
+- * set up the iterator to start reading from the conns list and return the first item
++ * set up the iterator to start reading from the conns list and return the
++ * first item
+ */
+ static void *rxrpc_proc_conns_start(struct seq_file *m, loff_t *_pos)
+ {
+@@ -422,15 +424,15 @@
+
+ /* allow for the header line */
+ if (!pos)
+- return (void *)1;
++ return SEQ_START_TOKEN;
+ pos--;
+
+ /* find the n'th element in the list */
+- list_for_each(_p,&rxrpc_conns)
++ list_for_each(_p, &rxrpc_conns)
+ if (!pos--)
+ break;
+
+- return _p!=&rxrpc_conns ? _p : NULL;
++ return _p != &rxrpc_conns ? _p : NULL;
+ } /* end rxrpc_proc_conns_start() */
+
+ /*****************************************************************************/
+@@ -444,9 +446,9 @@
+ (*pos)++;
+
+ _p = v;
+- _p = v==(void*)1 ? rxrpc_conns.next : _p->next;
++ _p = (v == SEQ_START_TOKEN) ? rxrpc_conns.next : _p->next;
+
+- return _p!=&rxrpc_conns ? _p : NULL;
++ return _p != &rxrpc_conns ? _p : NULL;
+ } /* end rxrpc_proc_conns_next() */
+
+ /*****************************************************************************/
+@@ -465,13 +467,16 @@
+ */
+ static int rxrpc_proc_conns_show(struct seq_file *m, void *v)
+ {
+- struct rxrpc_connection *conn = list_entry(v,struct rxrpc_connection,proc_link);
++ struct rxrpc_connection *conn;
+ signed long timeout;
+
++ conn = list_entry(v, struct rxrpc_connection, proc_link);
++
+ /* display header on line 1 */
+- if (v == (void *)1) {
++ if (v == SEQ_START_TOKEN) {
+ seq_puts(m,
+- "LOCAL REMOTE RPORT SRVC CONN END SERIALNO CALLNO MTU TIMEOUT"
++ "LOCAL REMOTE RPORT SRVC CONN END SERIALNO "
++ "CALLNO MTU TIMEOUT"
+ "\n");
+ return 0;
+ }
+@@ -479,9 +484,11 @@
+ /* display one conn per line on subsequent lines */
+ timeout = 0;
+ if (!list_empty(&conn->timeout.link))
+- timeout = (signed long)conn->timeout.timo_jif - (signed long)jiffies;
++ timeout = (signed long) conn->timeout.timo_jif -
++ (signed long) jiffies;
+
+- seq_printf(m,"%5hu %08x %5hu %04hx %08x %-3.3s %08x %08x %5Zu %8ld\n",
++ seq_printf(m,
++ "%5hu %08x %5hu %04hx %08x %-3.3s %08x %08x %5Zu %8ld\n",
+ conn->trans->port,
+ ntohl(conn->addr.sin_addr.s_addr),
+ ntohs(conn->addr.sin_port),
+@@ -506,8 +513,8 @@
+ struct seq_file *m;
+ int ret;
+
+- ret = seq_open(file,&rxrpc_proc_calls_ops);
+- if (ret<0)
++ ret = seq_open(file, &rxrpc_proc_calls_ops);
++ if (ret < 0)
+ return ret;
+
+ m = file->private_data;
+@@ -518,7 +525,8 @@
+
+ /*****************************************************************************/
+ /*
+- * set up the iterator to start reading from the calls list and return the first item
++ * set up the iterator to start reading from the calls list and return the
++ * first item
+ */
+ static void *rxrpc_proc_calls_start(struct seq_file *m, loff_t *_pos)
+ {
+@@ -530,15 +538,15 @@
+
+ /* allow for the header line */
+ if (!pos)
+- return (void *)1;
++ return SEQ_START_TOKEN;
+ pos--;
+
+ /* find the n'th element in the list */
+- list_for_each(_p,&rxrpc_calls)
++ list_for_each(_p, &rxrpc_calls)
+ if (!pos--)
+ break;
+
+- return _p!=&rxrpc_calls ? _p : NULL;
++ return _p != &rxrpc_calls ? _p : NULL;
+ } /* end rxrpc_proc_calls_start() */
+
+ /*****************************************************************************/
+@@ -552,9 +560,9 @@
+ (*pos)++;
+
+ _p = v;
+- _p = v==(void*)1 ? rxrpc_calls.next : _p->next;
++ _p = (v == SEQ_START_TOKEN) ? rxrpc_calls.next : _p->next;
+
+- return _p!=&rxrpc_calls ? _p : NULL;
++ return _p != &rxrpc_calls ? _p : NULL;
+ } /* end rxrpc_proc_calls_next() */
+
+ /*****************************************************************************/
+@@ -573,10 +581,10 @@
+ */
+ static int rxrpc_proc_calls_show(struct seq_file *m, void *v)
+ {
+- struct rxrpc_call *call = list_entry(v,struct rxrpc_call,call_link);
++ struct rxrpc_call *call = list_entry(v, struct rxrpc_call, call_link);
+
+ /* display header on line 1 */
+- if (v == (void *)1) {
++ if (v == SEQ_START_TOKEN) {
+ seq_puts(m,
+ "LOCAL REMOT SRVC CONN CALL DIR USE "
+ " L STATE OPCODE ABORT ERRNO\n"
+Index: linux-2.6.0-test5/net/rxrpc/sysctl.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/rxrpc/sysctl.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/rxrpc/sysctl.c 2003-09-27 11:38:42.242106608 +0800
+@@ -60,6 +60,22 @@
+ .mode = 0644,
+ .proc_handler = &proc_dointvec
+ },
++ {
++ .ctl_name = 5,
++ .procname = "peertimo",
++ .data = &rxrpc_peer_timeout,
++ .maxlen = sizeof(unsigned long),
++ .mode = 0644,
++ .proc_handler = &proc_doulongvec_minmax
++ },
++ {
++ .ctl_name = 6,
++ .procname = "conntimo",
++ .data = &rxrpc_conn_timeout,
++ .maxlen = sizeof(unsigned long),
++ .mode = 0644,
++ .proc_handler = &proc_doulongvec_minmax
++ },
+ { .ctl_name = 0 }
+ };
+
+@@ -67,6 +83,7 @@
+ {
+ .ctl_name = 1,
+ .procname = "rxrpc",
++ .maxlen = 0,
+ .mode = 0555,
+ .child = rxrpc_sysctl_table
+ },
+@@ -81,7 +98,7 @@
+ int rxrpc_sysctl_init(void)
+ {
+ #ifdef CONFIG_SYSCTL
+- rxrpc_sysctl = register_sysctl_table(rxrpc_dir_sysctl_table,0);
++ rxrpc_sysctl = register_sysctl_table(rxrpc_dir_sysctl_table, 0);
+ if (!rxrpc_sysctl)
+ return -ENOMEM;
+ #endif /* CONFIG_SYSCTL */
+Index: linux-2.6.0-test5/net/rxrpc/transport.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/rxrpc/transport.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/rxrpc/transport.c 2003-09-27 11:38:42.265103112 +0800
+@@ -56,7 +56,8 @@
+ /*
+ * create a new transport endpoint using the specified UDP port
+ */
+-int rxrpc_create_transport(unsigned short port, struct rxrpc_transport **_trans)
++int rxrpc_create_transport(unsigned short port,
++ struct rxrpc_transport **_trans)
+ {
+ struct rxrpc_transport *trans;
+ struct sockaddr_in sin;
+@@ -64,14 +65,14 @@
+ struct sock *sock;
+ int ret, opt;
+
+- _enter("%hu",port);
++ _enter("%hu", port);
+
+- trans = kmalloc(sizeof(struct rxrpc_transport),GFP_KERNEL);
++ trans = kmalloc(sizeof(struct rxrpc_transport), GFP_KERNEL);
+ if (!trans)
+ return -ENOMEM;
+
+- memset(trans,0,sizeof(struct rxrpc_transport));
+- atomic_set(&trans->usage,1);
++ memset(trans, 0, sizeof(struct rxrpc_transport));
++ atomic_set(&trans->usage, 1);
+ INIT_LIST_HEAD(&trans->services);
+ INIT_LIST_HEAD(&trans->link);
+ INIT_LIST_HEAD(&trans->krxiodq_link);
+@@ -81,58 +82,58 @@
+ spin_lock_init(&trans->peer_gylock);
+ init_waitqueue_head(&trans->peer_gy_waitq);
+ rwlock_init(&trans->peer_lock);
+- atomic_set(&trans->peer_count,0);
++ atomic_set(&trans->peer_count, 0);
+ trans->port = port;
+
+ /* create a UDP socket to be my actual transport endpoint */
+- ret = sock_create(PF_INET,SOCK_DGRAM,IPPROTO_UDP,&trans->socket);
+- if (ret<0)
++ ret = sock_create(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &trans->socket);
++ if (ret < 0)
+ goto error;
+
+ /* use the specified port */
+ if (port) {
+- memset(&sin,0,sizeof(sin));
++ memset(&sin, 0, sizeof(sin));
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons(port);
+- ret = trans->socket->ops->bind(trans->socket,(struct sockaddr *)&sin,sizeof(sin));
+- if (ret<0)
++ ret = trans->socket->ops->bind(trans->socket,
++ (struct sockaddr *) &sin,
++ sizeof(sin));
++ if (ret < 0)
+ goto error;
+ }
+
+ opt = 1;
+ oldfs = get_fs();
+ set_fs(KERNEL_DS);
+- ret = trans->socket->ops->setsockopt(trans->socket,SOL_IP,IP_RECVERR,
+- (char*)&opt,sizeof(opt));
++ ret = trans->socket->ops->setsockopt(trans->socket, SOL_IP, IP_RECVERR,
++ (char *) &opt, sizeof(opt));
+ set_fs(oldfs);
+
+ spin_lock(&rxrpc_transports_lock);
+- list_add(&trans->link,&rxrpc_transports);
++ list_add(&trans->link, &rxrpc_transports);
+ spin_unlock(&rxrpc_transports_lock);
+
+ /* set the socket up */
+ sock = trans->socket->sk;
+- sock->sk_user_data = trans;
+- sock->sk_data_ready = rxrpc_data_ready;
+- sock->sk_error_report = rxrpc_error_report;
++ sock->sk_user_data = trans;
++ sock->sk_data_ready = rxrpc_data_ready;
++ sock->sk_error_report = rxrpc_error_report;
+
+ down_write(&rxrpc_proc_transports_sem);
+- list_add_tail(&trans->proc_link,&rxrpc_proc_transports);
++ list_add_tail(&trans->proc_link, &rxrpc_proc_transports);
+ up_write(&rxrpc_proc_transports_sem);
+
+ __RXACCT(atomic_inc(&rxrpc_transport_count));
+
+ *_trans = trans;
+- _leave(" = 0 (%p)",trans);
++ _leave(" = 0 (%p)", trans);
+ return 0;
+
+ error:
+ rxrpc_put_transport(trans);
+
+- _leave(" = %d",ret);
+-
++ _leave(" = %d", ret);
+ return ret;
+-
+ } /* end rxrpc_create_transport() */
+
+ /*****************************************************************************/
+@@ -151,12 +152,13 @@
+ */
+ void rxrpc_put_transport(struct rxrpc_transport *trans)
+ {
+- _enter("%p{u=%d p=%hu}",trans,atomic_read(&trans->usage),trans->port);
++ _enter("%p{u=%d p=%hu}",
++ trans, atomic_read(&trans->usage), trans->port);
+
+- if (atomic_read(&trans->usage)<=0)
+- BUG();
++ BUG_ON(atomic_read(&trans->usage) <= 0);
+
+- /* to prevent a race, the decrement and the dequeue must be effectively atomic */
++ /* to prevent a race, the decrement and the dequeue must be
++ * effectively atomic */
+ spin_lock(&rxrpc_transports_lock);
+ if (likely(!atomic_dec_and_test(&trans->usage))) {
+ spin_unlock(&rxrpc_transports_lock);
+@@ -169,7 +171,7 @@
+
+ /* finish cleaning up the transport */
+ if (trans->socket)
+- trans->socket->ops->shutdown(trans->socket,2);
++ trans->socket->ops->shutdown(trans->socket, 2);
+
+ rxrpc_krxsecd_clear_transport(trans);
+ rxrpc_krxiod_dequeue_transport(trans);
+@@ -192,41 +194,41 @@
+ kfree(trans);
+
+ _leave("");
+-
+ } /* end rxrpc_put_transport() */
+
+ /*****************************************************************************/
+ /*
+ * add a service to a transport to be listened upon
+ */
+-int rxrpc_add_service(struct rxrpc_transport *trans, struct rxrpc_service *newsrv)
++int rxrpc_add_service(struct rxrpc_transport *trans,
++ struct rxrpc_service *newsrv)
+ {
+ struct rxrpc_service *srv;
+ struct list_head *_p;
+ int ret = -EEXIST;
+
+- _enter("%p{%hu},%p{%hu}",trans,trans->port,newsrv,newsrv->service_id);
++ _enter("%p{%hu},%p{%hu}",
++ trans, trans->port, newsrv, newsrv->service_id);
+
+ /* verify that the service ID is not already present */
+ spin_lock(&trans->lock);
+
+- list_for_each(_p,&trans->services) {
+- srv = list_entry(_p,struct rxrpc_service,link);
+- if (srv->service_id==newsrv->service_id)
++ list_for_each(_p, &trans->services) {
++ srv = list_entry(_p, struct rxrpc_service, link);
++ if (srv->service_id == newsrv->service_id)
+ goto out;
+ }
+
+ /* okay - add the transport to the list */
+- list_add_tail(&newsrv->link,&trans->services);
++ list_add_tail(&newsrv->link, &trans->services);
+ rxrpc_get_transport(trans);
+ ret = 0;
+
+ out:
+ spin_unlock(&trans->lock);
+
+- _leave("= %d",ret);
++ _leave("= %d", ret);
+ return ret;
+-
+ } /* end rxrpc_add_service() */
+
+ /*****************************************************************************/
+@@ -235,7 +237,7 @@
+ */
+ void rxrpc_del_service(struct rxrpc_transport *trans, struct rxrpc_service *srv)
+ {
+- _enter("%p{%hu},%p{%hu}",trans,trans->port,srv,srv->service_id);
++ _enter("%p{%hu},%p{%hu}", trans, trans->port, srv, srv->service_id);
+
+ spin_lock(&trans->lock);
+ list_del(&srv->link);
+@@ -244,7 +246,6 @@
+ rxrpc_put_transport(trans);
+
+ _leave("");
+-
+ } /* end rxrpc_del_service() */
+
+ /*****************************************************************************/
+@@ -255,7 +256,7 @@
+ {
+ struct rxrpc_transport *trans;
+
+- _enter("%p{t=%p},%d",sk,sk->sk_user_data,count);
++ _enter("%p{t=%p},%d", sk, sk->sk_user_data, count);
+
+ /* queue the transport for attention by krxiod */
+ trans = (struct rxrpc_transport *) sk->sk_user_data;
+@@ -267,7 +268,6 @@
+ wake_up_interruptible(sk->sk_sleep);
+
+ _leave("");
+-
+ } /* end rxrpc_data_ready() */
+
+ /*****************************************************************************/
+@@ -279,7 +279,7 @@
+ {
+ struct rxrpc_transport *trans;
+
+- _enter("%p{t=%p}",sk,sk->sk_user_data);
++ _enter("%p{t=%p}", sk, sk->sk_user_data);
+
+ /* queue the transport for attention by krxiod */
+ trans = (struct rxrpc_transport *) sk->sk_user_data;
+@@ -293,13 +293,12 @@
+ wake_up_interruptible(sk->sk_sleep);
+
+ _leave("");
+-
+ } /* end rxrpc_error_report() */
+
+ /*****************************************************************************/
+ /*
+- * split a message up, allocating message records and filling them in from the contents of a
+- * socket buffer
++ * split a message up, allocating message records and filling them in
++ * from the contents of a socket buffer
+ */
+ static int rxrpc_incoming_msg(struct rxrpc_transport *trans,
+ struct sk_buff *pkt,
+@@ -310,18 +309,19 @@
+
+ _enter("");
+
+- msg = kmalloc(sizeof(struct rxrpc_message),GFP_KERNEL);
++ msg = kmalloc(sizeof(struct rxrpc_message), GFP_KERNEL);
+ if (!msg) {
+ _leave(" = -ENOMEM");
+ return -ENOMEM;
+ }
+
+- memset(msg,0,sizeof(*msg));
+- atomic_set(&msg->usage,1);
++ memset(msg, 0, sizeof(*msg));
++ atomic_set(&msg->usage, 1);
+ list_add_tail(&msg->link,msgq);
+
+ /* dig out the Rx routing parameters */
+- if (skb_copy_bits(pkt,sizeof(struct udphdr),&msg->hdr,sizeof(msg->hdr))<0) {
++ if (skb_copy_bits(pkt, sizeof(struct udphdr),
++ &msg->hdr, sizeof(msg->hdr)) < 0) {
+ ret = -EBADMSG;
+ goto error;
+ }
+@@ -352,7 +352,9 @@
+ __RXACCT(atomic_inc(&rxrpc_message_count));
+
+ /* split off jumbo packets */
+- while (msg->hdr.type==RXRPC_PACKET_TYPE_DATA && msg->hdr.flags & RXRPC_JUMBO_PACKET) {
++ while (msg->hdr.type == RXRPC_PACKET_TYPE_DATA &&
++ msg->hdr.flags & RXRPC_JUMBO_PACKET
++ ) {
+ struct rxrpc_jumbo_header jumbo;
+ struct rxrpc_message *jumbomsg = msg;
+
+@@ -360,23 +362,25 @@
+
+ /* quick sanity check */
+ ret = -EBADMSG;
+- if (msg->dsize < RXRPC_JUMBO_DATALEN+sizeof(struct rxrpc_jumbo_header))
++ if (msg->dsize <
++ RXRPC_JUMBO_DATALEN + sizeof(struct rxrpc_jumbo_header))
+ goto error;
+ if (msg->hdr.flags & RXRPC_LAST_PACKET)
+ goto error;
+
+ /* dig out the secondary header */
+- if (skb_copy_bits(pkt,msg->offset+RXRPC_JUMBO_DATALEN,&jumbo,sizeof(jumbo))<0)
++ if (skb_copy_bits(pkt, msg->offset + RXRPC_JUMBO_DATALEN,
++ &jumbo, sizeof(jumbo)) < 0)
+ goto error;
+
+ /* allocate a new message record */
+ ret = -ENOMEM;
+- msg = kmalloc(sizeof(struct rxrpc_message),GFP_KERNEL);
++ msg = kmalloc(sizeof(struct rxrpc_message), GFP_KERNEL);
+ if (!msg)
+ goto error;
+
+- memcpy(msg,jumbomsg,sizeof(*msg));
+- list_add_tail(&msg->link,msgq);
++ memcpy(msg, jumbomsg, sizeof(*msg));
++ list_add_tail(&msg->link, msgq);
+
+ /* adjust the jumbo packet */
+ jumbomsg->dsize = RXRPC_JUMBO_DATALEN;
+@@ -388,12 +392,15 @@
+ msg->seq++;
+ msg->hdr.seq = htonl(msg->seq);
+ msg->hdr.serial = htonl(ntohl(msg->hdr.serial) + 1);
+- msg->offset += RXRPC_JUMBO_DATALEN + sizeof(struct rxrpc_jumbo_header);
+- msg->dsize -= RXRPC_JUMBO_DATALEN + sizeof(struct rxrpc_jumbo_header);
++ msg->offset += RXRPC_JUMBO_DATALEN +
++ sizeof(struct rxrpc_jumbo_header);
++ msg->dsize -= RXRPC_JUMBO_DATALEN +
++ sizeof(struct rxrpc_jumbo_header);
+ msg->hdr.flags = jumbo.flags;
+ msg->hdr._rsvd = jumbo._rsvd;
+
+- _net("Rx Split jumbo packet from %s (%08x;%08x,%1x,%d,%s,%02x,%d,%d)",
++ _net("Rx Split jumbo packet from %s"
++ " (%08x;%08x,%1x,%d,%s,%02x,%d,%d)",
+ msg->hdr.flags & RXRPC_CLIENT_INITIATED ? "client" : "server",
+ ntohl(msg->hdr.epoch),
+ (ntohl(msg->hdr.cid) & RXRPC_CIDMASK) >> RXRPC_CIDSHIFT,
+@@ -407,18 +414,18 @@
+ __RXACCT(atomic_inc(&rxrpc_message_count));
+ }
+
+- _leave(" = 0 #%d",atomic_read(&rxrpc_message_count));
++ _leave(" = 0 #%d", atomic_read(&rxrpc_message_count));
+ return 0;
+
+ error:
+ while (!list_empty(msgq)) {
+- msg = list_entry(msgq->next,struct rxrpc_message,link);
++ msg = list_entry(msgq->next, struct rxrpc_message, link);
+ list_del_init(&msg->link);
+
+ rxrpc_put_message(msg);
+ }
+
+- _leave(" = %d",ret);
++ _leave(" = %d", ret);
+ return ret;
+ } /* end rxrpc_incoming_msg() */
+
+@@ -438,7 +445,7 @@
+
+ LIST_HEAD(msgq);
+
+- _enter("%p{%d}",trans,trans->port);
++ _enter("%p{%d}", trans, trans->port);
+
+ for (;;) {
+ /* deal with outstanting errors first */
+@@ -446,22 +453,25 @@
+ rxrpc_trans_receive_error_report(trans);
+
+ /* attempt to receive a packet */
+- pkt = skb_recv_datagram(trans->socket->sk,0,1,&ret);
++ pkt = skb_recv_datagram(trans->socket->sk, 0, 1, &ret);
+ if (!pkt) {
+- if (ret==-EAGAIN) {
++ if (ret == -EAGAIN) {
+ _leave(" EAGAIN");
+ return;
+ }
+
+ /* an icmp error may have occurred */
+ rxrpc_krxiod_queue_transport(trans);
+- _leave(" error %d\n",ret);
++ _leave(" error %d\n", ret);
+ return;
+ }
+
+- /* we'll probably need to checksum it (didn't call sock_recvmsg) */
++ /* we'll probably need to checksum it (didn't call
++ * sock_recvmsg) */
+ if (pkt->ip_summed != CHECKSUM_UNNECESSARY) {
+- if ((unsigned short)csum_fold(skb_checksum(pkt,0,pkt->len,pkt->csum))) {
++ if ((unsigned short)
++ csum_fold(skb_checksum(pkt, 0, pkt->len,
++ pkt->csum))) {
+ kfree_skb(pkt);
+ rxrpc_krxiod_queue_transport(trans);
+ _leave(" CSUM failed");
+@@ -472,34 +482,36 @@
+ addr = pkt->nh.iph->saddr;
+ port = pkt->h.uh->source;
+
+- _net("Rx Received UDP packet from %08x:%04hu",ntohl(addr),ntohs(port));
++ _net("Rx Received UDP packet from %08x:%04hu",
++ ntohl(addr), ntohs(port));
+
+ /* unmarshall the Rx parameters and split jumbo packets */
+- ret = rxrpc_incoming_msg(trans,pkt,&msgq);
+- if (ret<0) {
++ ret = rxrpc_incoming_msg(trans, pkt, &msgq);
++ if (ret < 0) {
+ kfree_skb(pkt);
+ rxrpc_krxiod_queue_transport(trans);
+ _leave(" bad packet");
+ return;
+ }
+
+- if (list_empty(&msgq)) BUG();
++ BUG_ON(list_empty(&msgq));
+
+- msg = list_entry(msgq.next,struct rxrpc_message,link);
++ msg = list_entry(msgq.next, struct rxrpc_message, link);
+
+- /* locate the record for the peer from which it originated */
+- ret = rxrpc_peer_lookup(trans,addr,&peer);
+- if (ret<0) {
++ /* locate the record for the peer from which it
++ * originated */
++ ret = rxrpc_peer_lookup(trans, addr, &peer);
++ if (ret < 0) {
+ kdebug("Rx No connections from that peer");
+- rxrpc_trans_immediate_abort(trans,msg,-EINVAL);
++ rxrpc_trans_immediate_abort(trans, msg, -EINVAL);
+ goto finished_msg;
+ }
+
+ /* try and find a matching connection */
+- ret = rxrpc_connection_lookup(peer,msg,&msg->conn);
+- if (ret<0) {
++ ret = rxrpc_connection_lookup(peer, msg, &msg->conn);
++ if (ret < 0) {
+ kdebug("Rx Unknown Connection");
+- rxrpc_trans_immediate_abort(trans,msg,-EINVAL);
++ rxrpc_trans_immediate_abort(trans, msg, -EINVAL);
+ rxrpc_put_peer(peer);
+ goto finished_msg;
+ }
+@@ -507,23 +519,23 @@
+
+ /* deal with the first packet of a new call */
+ if (msg->hdr.flags & RXRPC_CLIENT_INITIATED &&
+- msg->hdr.type==RXRPC_PACKET_TYPE_DATA &&
+- ntohl(msg->hdr.seq)==1
++ msg->hdr.type == RXRPC_PACKET_TYPE_DATA &&
++ ntohl(msg->hdr.seq) == 1
+ ) {
+ _debug("Rx New server call");
+- rxrpc_trans_receive_new_call(trans,&msgq);
++ rxrpc_trans_receive_new_call(trans, &msgq);
+ goto finished_msg;
+ }
+
+ /* deal with subsequent packet(s) of call */
+ _debug("Rx Call packet");
+ while (!list_empty(&msgq)) {
+- msg = list_entry(msgq.next,struct rxrpc_message,link);
++ msg = list_entry(msgq.next, struct rxrpc_message, link);
+ list_del_init(&msg->link);
+
+- ret = rxrpc_conn_receive_call_packet(msg->conn,NULL,msg);
+- if (ret<0) {
+- rxrpc_trans_immediate_abort(trans,msg,ret);
++ ret = rxrpc_conn_receive_call_packet(msg->conn, NULL, msg);
++ if (ret < 0) {
++ rxrpc_trans_immediate_abort(trans, msg, ret);
+ rxrpc_put_message(msg);
+ goto finished_msg;
+ }
+@@ -536,7 +548,7 @@
+ /* dispose of the packets */
+ finished_msg:
+ while (!list_empty(&msgq)) {
+- msg = list_entry(msgq.next,struct rxrpc_message,link);
++ msg = list_entry(msgq.next, struct rxrpc_message, link);
+ list_del_init(&msg->link);
+
+ rxrpc_put_message(msg);
+@@ -561,7 +573,7 @@
+ _enter("");
+
+ /* only bother with the first packet */
+- msg = list_entry(msgq->next,struct rxrpc_message,link);
++ msg = list_entry(msgq->next, struct rxrpc_message, link);
+ list_del_init(&msg->link);
+ rxrpc_krxsecd_queue_incoming_call(msg);
+ rxrpc_put_message(msg);
+@@ -584,13 +596,13 @@
+ struct msghdr msghdr;
+ struct iovec iov[2];
+ mm_segment_t oldfs;
++ uint32_t _error;
+ int len, ret;
+- u32 _error;
+
+- _enter("%p,%p,%d",trans,msg,error);
++ _enter("%p,%p,%d", trans, msg, error);
+
+ /* don't abort an abort packet */
+- if (msg->hdr.type==RXRPC_PACKET_TYPE_ABORT) {
++ if (msg->hdr.type == RXRPC_PACKET_TYPE_ABORT) {
+ _leave(" = 0");
+ return 0;
+ }
+@@ -598,12 +610,13 @@
+ _error = htonl(-error);
+
+ /* set up the message to be transmitted */
+- memcpy(&ahdr,&msg->hdr,sizeof(ahdr));
++ memcpy(&ahdr, &msg->hdr, sizeof(ahdr));
+ ahdr.epoch = msg->hdr.epoch;
+ ahdr.serial = htonl(1);
+ ahdr.seq = 0;
+ ahdr.type = RXRPC_PACKET_TYPE_ABORT;
+- ahdr.flags = RXRPC_LAST_PACKET | (~msg->hdr.flags & RXRPC_CLIENT_INITIATED);
++ ahdr.flags = RXRPC_LAST_PACKET;
++ ahdr.flags |= ~msg->hdr.flags & RXRPC_CLIENT_INITIATED;
+
+ iov[0].iov_len = sizeof(ahdr);
+ iov[0].iov_base = &ahdr;
+@@ -634,17 +647,17 @@
+ /* send the message */
+ oldfs = get_fs();
+ set_fs(KERNEL_DS);
+- ret = sock_sendmsg(trans->socket,&msghdr,len);
++ ret = sock_sendmsg(trans->socket, &msghdr, len);
+ set_fs(oldfs);
+
+- _leave(" = %d",ret);
++ _leave(" = %d", ret);
+ return ret;
+ } /* end rxrpc_trans_immediate_abort() */
+
+ /*****************************************************************************/
+ /*
+- * receive an ICMP error report and percolate it to all connections heading to the affected
+- * host or port
++ * receive an ICMP error report and percolate it to all connections
++ * heading to the affected host or port
+ */
+ static void rxrpc_trans_receive_error_report(struct rxrpc_transport *trans)
+ {
+@@ -655,10 +668,10 @@
+ struct errormsg emsg;
+ struct msghdr msg;
+ mm_segment_t oldfs;
++ uint16_t port;
+ int local, err;
+- u16 port;
+
+- _enter("%p",trans);
++ _enter("%p", trans);
+
+ for (;;) {
+ trans->error_rcvd = 0;
+@@ -674,48 +687,63 @@
+
+ oldfs = get_fs();
+ set_fs(KERNEL_DS);
+- err = sock_recvmsg(trans->socket,&msg,0,MSG_ERRQUEUE|MSG_DONTWAIT|MSG_TRUNC);
++ err = sock_recvmsg(trans->socket, &msg, 0,
++ MSG_ERRQUEUE | MSG_DONTWAIT | MSG_TRUNC);
+ set_fs(oldfs);
+
+- if (err==-EAGAIN) {
++ if (err == -EAGAIN) {
+ _leave("");
+ return;
+ }
+
+- if (err<0) {
+- printk("%s: unable to recv an error report: %d\n",__FUNCTION__,err);
++ if (err < 0) {
++ printk("%s: unable to recv an error report: %d\n",
++ __FUNCTION__, err);
+ _leave("");
+ return;
+ }
+
+- msg.msg_controllen = (char*)msg.msg_control - (char*)&emsg;
++ msg.msg_controllen = (char *) msg.msg_control - (char *) &emsg;
+
+- if (msg.msg_controllen<sizeof(emsg.cmsg) || msg.msg_namelen<sizeof(sin)) {
+- printk("%s: short control message (nlen=%u clen=%Zu fl=%x)\n",
+- __FUNCTION__,msg.msg_namelen,msg.msg_controllen,msg.msg_flags);
++ if (msg.msg_controllen < sizeof(emsg.cmsg) ||
++ msg.msg_namelen < sizeof(sin)) {
++ printk("%s: short control message"
++ " (nlen=%u clen=%Zu fl=%x)\n",
++ __FUNCTION__,
++ msg.msg_namelen,
++ msg.msg_controllen,
++ msg.msg_flags);
+ continue;
+ }
+
+- _net("Rx Received control message { len=%Zu level=%u type=%u }",
+- emsg.cmsg.cmsg_len,emsg.cmsg.cmsg_level,emsg.cmsg.cmsg_type);
+-
+- if (sin.sin_family!=AF_INET) {
+- printk("Rx Ignoring error report with non-INET address (fam=%u)",
++ _net("Rx Received control message"
++ " { len=%Zu level=%u type=%u }",
++ emsg.cmsg.cmsg_len,
++ emsg.cmsg.cmsg_level,
++ emsg.cmsg.cmsg_type);
++
++ if (sin.sin_family != AF_INET) {
++ printk("Rx Ignoring error report with non-INET address"
++ " (fam=%u)",
+ sin.sin_family);
+ continue;
+ }
+
+ _net("Rx Received message pertaining to host addr=%x port=%hu",
+- ntohl(sin.sin_addr.s_addr),ntohs(sin.sin_port));
++ ntohl(sin.sin_addr.s_addr), ntohs(sin.sin_port));
+
+- if (emsg.cmsg.cmsg_level!=SOL_IP || emsg.cmsg.cmsg_type!=IP_RECVERR) {
+- printk("Rx Ignoring unknown error report { level=%u type=%u }",
+- emsg.cmsg.cmsg_level,emsg.cmsg.cmsg_type);
++ if (emsg.cmsg.cmsg_level != SOL_IP ||
++ emsg.cmsg.cmsg_type != IP_RECVERR) {
++ printk("Rx Ignoring unknown error report"
++ " { level=%u type=%u }",
++ emsg.cmsg.cmsg_level,
++ emsg.cmsg.cmsg_type);
+ continue;
+ }
+
+- if (msg.msg_controllen<sizeof(emsg.cmsg)+sizeof(emsg.ee)) {
+- printk("%s: short error message (%Zu)\n",__FUNCTION__,msg.msg_controllen);
++ if (msg.msg_controllen < sizeof(emsg.cmsg) + sizeof(emsg.ee)) {
++ printk("%s: short error message (%Zu)\n",
++ __FUNCTION__, msg.msg_controllen);
+ _leave("");
+ return;
+ }
+@@ -767,14 +795,15 @@
+
+ default:
+ _proto("Rx Received ICMP error { type=%u code=%u }",
+- emsg.ee.ee_type,emsg.ee.ee_code);
++ emsg.ee.ee_type, emsg.ee.ee_code);
+ err = emsg.ee.ee_errno;
+ break;
+ }
+ break;
+
+ case SO_EE_ORIGIN_LOCAL:
+- _proto("Rx Received local error { error=%d }",emsg.ee.ee_errno);
++ _proto("Rx Received local error { error=%d }",
++ emsg.ee.ee_errno);
+ local = 1;
+ err = emsg.ee.ee_errno;
+ break;
+@@ -782,35 +811,41 @@
+ case SO_EE_ORIGIN_NONE:
+ case SO_EE_ORIGIN_ICMP6:
+ default:
+- _proto("Rx Received error report { orig=%u }",emsg.ee.ee_origin);
++ _proto("Rx Received error report { orig=%u }",
++ emsg.ee.ee_origin);
+ local = 0;
+ err = emsg.ee.ee_errno;
+ break;
+ }
+
+- /* find all the connections between this transport and the affected destination */
++ /* find all the connections between this transport and the
++ * affected destination */
+ INIT_LIST_HEAD(&connq);
+
+- if (rxrpc_peer_lookup(trans,sin.sin_addr.s_addr,&peer)==0) {
++ if (rxrpc_peer_lookup(trans, sin.sin_addr.s_addr,
++ &peer) == 0) {
+ read_lock(&peer->conn_lock);
+- list_for_each(_p,&peer->conn_active) {
+- conn = list_entry(_p,struct rxrpc_connection,link);
+- if (port && conn->addr.sin_port!=port)
++ list_for_each(_p, &peer->conn_active) {
++ conn = list_entry(_p, struct rxrpc_connection,
++ link);
++ if (port && conn->addr.sin_port != port)
+ continue;
+ if (!list_empty(&conn->err_link))
+ continue;
+
+ rxrpc_get_connection(conn);
+- list_add_tail(&conn->err_link,&connq);
++ list_add_tail(&conn->err_link, &connq);
+ }
+ read_unlock(&peer->conn_lock);
+
+ /* service all those connections */
+ while (!list_empty(&connq)) {
+- conn = list_entry(connq.next,struct rxrpc_connection,err_link);
++ conn = list_entry(connq.next,
++ struct rxrpc_connection,
++ err_link);
+ list_del(&conn->err_link);
+
+- rxrpc_conn_handle_error(conn,local,err);
++ rxrpc_conn_handle_error(conn, local, err);
+
+ rxrpc_put_connection(conn);
+ }
+Index: linux-2.6.0-test5/net/sched/estimator.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/sched/estimator.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/sched/estimator.c 2003-09-27 11:38:42.267102808 +0800
+@@ -26,7 +26,6 @@
+ #include <linux/skbuff.h>
+ #include <linux/rtnetlink.h>
+ #include <linux/init.h>
+-#include <linux/proc_fs.h>
+ #include <net/sock.h>
+ #include <net/pkt_sched.h>
+
+Index: linux-2.6.0-test5/net/sched/police.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/sched/police.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/sched/police.c 2003-09-27 11:38:42.270102352 +0800
+@@ -27,7 +27,6 @@
+ #include <linux/skbuff.h>
+ #include <linux/rtnetlink.h>
+ #include <linux/init.h>
+-#include <linux/proc_fs.h>
+ #include <net/sock.h>
+ #include <net/pkt_sched.h>
+
+Index: linux-2.6.0-test5/net/sched/sch_api.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/sched/sch_api.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/sched/sch_api.c 2003-09-27 11:38:42.278101136 +0800
+@@ -32,6 +32,7 @@
+ #include <linux/rtnetlink.h>
+ #include <linux/init.h>
+ #include <linux/proc_fs.h>
++#include <linux/seq_file.h>
+ #include <linux/kmod.h>
+
+ #include <net/sock.h>
+@@ -1059,27 +1060,27 @@
+ int psched_tick_per_us = 1;
+
+ #ifdef CONFIG_PROC_FS
+-static int psched_read_proc(char *buffer, char **start, off_t offset,
+- int length, int *eof, void *data)
++static int psched_show(struct seq_file *seq, void *v)
+ {
+- int len;
+-
+- len = sprintf(buffer, "%08x %08x %08x %08x\n",
++ seq_printf(seq, "%08x %08x %08x %08x\n",
+ psched_tick_per_us, psched_us_per_tick,
+ 1000000, HZ);
+
+- len -= offset;
+-
+- if (len > length)
+- len = length;
+- if(len < 0)
+- len = 0;
+-
+- *start = buffer + offset;
+- *eof = 1;
++ return 0;
++}
+
+- return len;
++static int psched_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, psched_show, PDE(inode)->data);
+ }
++
++static struct file_operations psched_fops = {
++ .owner = THIS_MODULE,
++ .open = psched_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
+ #endif
+
+ #if PSCHED_CLOCK_SOURCE == PSCHED_GETTIMEOFDAY
+@@ -1250,9 +1251,7 @@
+ tc_filter_init();
+ #endif
+
+-#ifdef CONFIG_PROC_FS
+- create_proc_read_entry("net/psched", 0, 0, psched_read_proc, NULL);
+-#endif
++ proc_net_fops_create("psched", 0, &psched_fops);
+
+ return 0;
+ }
+Index: linux-2.6.0-test5/net/sched/sch_atm.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/sched/sch_atm.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/sched/sch_atm.c 2003-09-27 11:38:42.283100376 +0800
+@@ -216,6 +216,13 @@
+ tasklet_schedule(&p->task);
+ }
+
++static const u8 llc_oui_ip[] = {
++ 0xaa, /* DSAP: non-ISO */
++ 0xaa, /* SSAP: non-ISO */
++ 0x03, /* Ctrl: Unnumbered Information Command PDU */
++ 0x00, /* OUI: EtherType */
++ 0x00, 0x00,
++ 0x08, 0x00 }; /* Ethertype IP (0800) */
+
+ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
+ struct rtattr **tca, unsigned long *arg)
+@@ -322,11 +329,10 @@
+ flow->next = p->link.next;
+ p->link.next = flow;
+ flow->hdr_len = hdr_len;
+- if (hdr) memcpy(flow->hdr,hdr,hdr_len);
+- else {
+- memcpy(flow->hdr,llc_oui,sizeof(llc_oui));
+- ((u16 *) flow->hdr)[3] = htons(ETH_P_IP);
+- }
++ if (hdr)
++ memcpy(flow->hdr,hdr,hdr_len);
++ else
++ memcpy(flow->hdr,llc_oui_ip,sizeof(llc_oui_ip));
+ *arg = (unsigned long) flow;
+ return 0;
+ err_out:
+Index: linux-2.6.0-test5/net/sched/sch_generic.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/sched/sch_generic.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/sched/sch_generic.c 2003-09-27 11:38:42.287099768 +0800
+@@ -7,7 +7,7 @@
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
+- * Jamal Hadi Salim, <hadi@nortelnetworks.com> 990601
++ * Jamal Hadi Salim, <hadi@cyberus.ca> 990601
+ * - Ingress support
+ */
+
+@@ -278,6 +278,8 @@
+ if (list->qlen <= qdisc->dev->tx_queue_len) {
+ __skb_queue_tail(list, skb);
+ qdisc->q.qlen++;
++ qdisc->stats.bytes += skb->len;
++ qdisc->stats.packets++;
+ return 0;
+ }
+ qdisc->stats.drops++;
+@@ -326,6 +328,21 @@
+ qdisc->q.qlen = 0;
+ }
+
++static int pfifo_fast_dump(struct Qdisc *qdisc, struct sk_buff *skb)
++{
++ unsigned char *b = skb->tail;
++ struct tc_prio_qopt opt;
++
++ opt.bands = 3;
++ memcpy(&opt.priomap, prio2band, TC_PRIO_MAX+1);
++ RTA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
++ return skb->len;
++
++rtattr_failure:
++ skb_trim(skb, b - skb->data);
++ return -1;
++}
++
+ static int pfifo_fast_init(struct Qdisc *qdisc, struct rtattr *opt)
+ {
+ int i;
+@@ -349,6 +366,7 @@
+ .requeue = pfifo_fast_requeue,
+ .init = pfifo_fast_init,
+ .reset = pfifo_fast_reset,
++ .dump = pfifo_fast_dump,
+ .owner = THIS_MODULE,
+ };
+
+@@ -438,6 +456,12 @@
+ printk(KERN_INFO "%s: activation failed\n", dev->name);
+ return;
+ }
++
++ write_lock(&qdisc_tree_lock);
++ qdisc->next = dev->qdisc_list;
++ dev->qdisc_list = qdisc;
++ write_unlock(&qdisc_tree_lock);
++
+ } else {
+ qdisc = &noqueue_qdisc;
+ }
+Index: linux-2.6.0-test5/net/sched/sch_htb.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/sched/sch_htb.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/sched/sch_htb.c 2003-09-27 11:38:42.301097640 +0800
+@@ -32,7 +32,6 @@
+ #include <asm/bitops.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+-#include <linux/version.h>
+ #include <linux/sched.h>
+ #include <linux/string.h>
+ #include <linux/mm.h>
+Index: linux-2.6.0-test5/net/sunrpc/cache.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/sunrpc/cache.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/sunrpc/cache.c 2003-09-27 11:38:42.308096576 +0800
+@@ -1035,7 +1035,7 @@
+
+ read_lock(&cd->hash_lock);
+ if (!n--)
+- return (void *)1;
++ return SEQ_START_TOKEN;
+ hash = n >> 32;
+ entry = n & ((1LL<<32) - 1);
+
+@@ -1060,7 +1060,7 @@
+ int hash = (*pos >> 32);
+ struct cache_detail *cd = ((struct handle*)m->private)->cd;
+
+- if (p == (void *)1)
++ if (p == SEQ_START_TOKEN)
+ hash = 0;
+ else if (ch->next == NULL) {
+ hash++;
+@@ -1092,7 +1092,7 @@
+ struct cache_head *cp = p;
+ struct cache_detail *cd = ((struct handle*)m->private)->cd;
+
+- if (p == (void *)1)
++ if (p == SEQ_START_TOKEN)
+ return cd->cache_show(m, cd, NULL);
+
+ ifdebug(CACHE)
+Index: linux-2.6.0-test5/net/wanrouter/af_wanpipe.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/wanrouter/af_wanpipe.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/wanrouter/af_wanpipe.c 2003-09-27 11:38:42.326093840 +0800
+@@ -32,7 +32,6 @@
+ *
+ ******************************************************************************/
+
+-#include <linux/version.h>
+ #include <linux/config.h>
+ #include <linux/types.h>
+ #include <linux/sched.h>
+Index: linux-2.6.0-test5/net/wanrouter/wanmain.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/wanrouter/wanmain.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/wanrouter/wanmain.c 2003-09-27 11:38:42.332092928 +0800
+@@ -42,7 +42,6 @@
+ * Jun 02, 1999 Gideon Hack Updates for Linux 2.0.X and 2.2.X kernels.
+ *****************************************************************************/
+
+-#include <linux/version.h>
+ #include <linux/config.h>
+ #include <linux/stddef.h> /* offsetof(), etc. */
+ #include <linux/errno.h> /* return codes */
+Index: linux-2.6.0-test5/net/wanrouter/wanproc.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/wanrouter/wanproc.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/wanrouter/wanproc.c 2003-09-27 11:38:42.336092320 +0800
+@@ -86,7 +86,7 @@
+
+ lock_kernel();
+ if (!l--)
+- return (void *)1;
++ return SEQ_START_TOKEN;
+ for (wandev = wanrouter_router_devlist; l-- && wandev;
+ wandev = wandev->next)
+ ;
+@@ -97,7 +97,7 @@
+ {
+ struct wan_device *wandev = v;
+ (*pos)++;
+- return (v == (void *)1) ? wanrouter_router_devlist : wandev->next;
++ return (v == SEQ_START_TOKEN) ? wanrouter_router_devlist : wandev->next;
+ }
+
+ static void r_stop(struct seq_file *m, void *v)
+@@ -108,7 +108,7 @@
+ static int config_show(struct seq_file *m, void *v)
+ {
+ struct wan_device *p = v;
+- if (v == (void *)1) {
++ if (v == SEQ_START_TOKEN) {
+ seq_puts(m, "Device name | port |IRQ|DMA| mem.addr |"
+ "mem.size|option1|option2|option3|option4\n");
+ return 0;
+@@ -124,7 +124,7 @@
+ static int status_show(struct seq_file *m, void *v)
+ {
+ struct wan_device *p = v;
+- if (v == (void *)1) {
++ if (v == SEQ_START_TOKEN) {
+ seq_puts(m, "Device name |protocol|station|interface|"
+ "clocking|baud rate| MTU |ndev|link state\n");
+ return 0;
+Index: linux-2.6.0-test5/net/x25/x25_proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/x25/x25_proc.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/x25/x25_proc.c 2003-09-27 11:38:42.338092016 +0800
+@@ -44,7 +44,7 @@
+ loff_t l = *pos;
+
+ read_lock_bh(&x25_route_list_lock);
+- return l ? x25_get_route_idx(--l) : (void *)1;
++ return l ? x25_get_route_idx(--l) : SEQ_START_TOKEN;
+ }
+
+ static void *x25_seq_route_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -52,7 +52,7 @@
+ struct x25_route *rt;
+
+ ++*pos;
+- if (v == (void *)1) {
++ if (v == SEQ_START_TOKEN) {
+ rt = NULL;
+ if (!list_empty(&x25_route_list))
+ rt = list_entry(x25_route_list.next,
+@@ -77,7 +77,7 @@
+ {
+ struct x25_route *rt;
+
+- if (v == (void *)1) {
++ if (v == SEQ_START_TOKEN) {
+ seq_puts(seq, "Address Digits Device\n");
+ goto out;
+ }
+@@ -108,7 +108,7 @@
+ loff_t l = *pos;
+
+ read_lock_bh(&x25_list_lock);
+- return l ? x25_get_socket_idx(--l) : (void *)1;
++ return l ? x25_get_socket_idx(--l) : SEQ_START_TOKEN;
+ }
+
+ static void *x25_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -116,7 +116,7 @@
+ struct sock *s;
+
+ ++*pos;
+- if (v == (void *)1) {
++ if (v == SEQ_START_TOKEN) {
+ s = sk_head(&x25_list);
+ goto out;
+ }
+@@ -137,7 +137,7 @@
+ struct net_device *dev;
+ const char *devname;
+
+- if (v == (void *)1) {
++ if (v == SEQ_START_TOKEN) {
+ seq_printf(seq, "dest_addr src_addr dev lci st vs vr "
+ "va t t2 t21 t22 t23 Snd-Q Rcv-Q inode\n");
+ goto out;
+Index: linux-2.6.0-test5/net/xfrm/xfrm_user.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/xfrm/xfrm_user.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/xfrm/xfrm_user.c 2003-09-27 11:38:42.346090800 +0800
+@@ -433,9 +433,9 @@
+
+ case IPPROTO_COMP:
+ /* IPCOMP spi is 16-bits. */
+- if (p->min >= 0x10000 ||
+- p->max >= 0x10000)
++ if (p->max >= 0x10000)
+ return -EINVAL;
++ break;
+
+ default:
+ return -EINVAL;
+@@ -470,7 +470,7 @@
+
+ spin_lock_bh(&x->lock);
+ if (x->km.state != XFRM_STATE_DEAD) {
+- xfrm_alloc_spi(x, p->min, p->max);
++ xfrm_alloc_spi(x, htonl(p->min), htonl(p->max));
+ if (x->id.spi)
+ resp_skb = xfrm_state_netlink(skb, x, nlh->nlmsg_seq);
+ }
+Index: linux-2.6.0-test5/README
+===================================================================
+--- linux-2.6.0-test5.orig/README 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/README 2003-09-27 11:38:42.350090192 +0800
+@@ -108,11 +108,26 @@
+ you can just update packages when obvious problems arise during
+ build or operation.
+
+-CONFIGURING the kernel:
++BUILD directory for the kernel:
++
++ When compiling the kernel all output files will per default be
++ stored together with the kernel source code.
++ Using the option "make O=output/dir" allow you to specify an alternate
++ place for the output files (including .config).
++ Example:
++ kernel source code: /usr/src/linux-2.6.N
++ build directory: /home/name/build/kernel
++
++ To configure and build the kernel use:
++ cd /usr/src/linux-2.6.N
++ make O=/home/name/build/kernel menuconfig
++ make O=/home/name/build/kernel
++ sudo make O=/home/name/build/kernel install_modules install
+
+- - Do a "make config" to configure the basic kernel. "make config" needs
+- bash to work: it will search for bash in $BASH, /bin/bash and /bin/sh
+- (in that order), so one of those must be correct for it to work.
++ Please note: If the 'O=output/dir' option is used then it must be
++ used for all invocations of make.
++
++CONFIGURING the kernel:
+
+ Do not skip this step even if you are only upgrading one minor
+ version. New configuration options are added in each release, and
+Index: linux-2.6.0-test5/scripts/bin2c.c
+===================================================================
+--- linux-2.6.0-test5.orig/scripts/bin2c.c 2003-09-27 11:38:18.495716608 +0800
++++ linux-2.6.0-test5/scripts/bin2c.c 2003-09-27 11:38:42.351090040 +0800
+@@ -0,0 +1,27 @@
++#include <stdio.h>
++
++int main(int argc, char *argv[])
++{
++ int ch, total=0;
++
++ if (argc > 1)
++ printf("const char %s[] %s=\n",
++ argv[1], argc > 2 ? argv[2] : "");
++
++ do {
++ printf("\t\"");
++ while ((ch = getchar()) != EOF)
++ {
++ total++;
++ printf("\\x%02x",ch);
++ if (total % 16 == 0)
++ break;
++ }
++ printf("\"\n");
++ } while (ch != EOF);
++
++ if (argc > 1)
++ printf("\t;\n\nconst int %s_size = %d;\n", argv[1], total);
++
++ return 0;
++}
+Index: linux-2.6.0-test5/scripts/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/scripts/Makefile 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/scripts/Makefile 2003-09-27 11:38:42.352089888 +0800
+@@ -9,7 +9,7 @@
+ # conmakehash: Create arrays for initializing the kernel console tables
+
+ host-progs := fixdep split-include conmakehash docproc kallsyms modpost \
+- mk_elfconfig pnmtologo
++ mk_elfconfig pnmtologo bin2c
+ always := $(host-progs) empty.o
+
+ modpost-objs := modpost.o file2alias.o
+Index: linux-2.6.0-test5/scripts/Makefile.build
+===================================================================
+--- linux-2.6.0-test5.orig/scripts/Makefile.build 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/scripts/Makefile.build 2003-09-27 11:38:42.355089432 +0800
+@@ -14,6 +14,16 @@
+
+ include scripts/Makefile.lib
+
++ifneq ($(KBUILD_SRC),)
++# Create output directory if not already present
++_dummy := $(shell [ -d $(obj) ] || mkdir -p $(obj))
++
++# Create directories for object files if directory does not exist
++# Needed when obj-y := dir/file.o syntax is used
++_dummy := $(foreach d,$(obj-dirs), $(shell [ -d $(d) ] || mkdir -p $(d)))
++endif
++
++
+ ifdef EXTRA_TARGETS
+ $(warning kbuild: $(obj)/Makefile - Usage of EXTRA_TARGETS is obsolete in 2.5. Please fix!)
+ endif
+Index: linux-2.6.0-test5/scripts/Makefile.clean
+===================================================================
+--- linux-2.6.0-test5.orig/scripts/Makefile.clean 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/scripts/Makefile.clean 2003-09-27 11:38:42.357089128 +0800
+@@ -63,4 +63,4 @@
+ # Shorthand for $(Q)$(MAKE) scripts/Makefile.clean obj=dir
+ # Usage:
+ # $(Q)$(MAKE) $(clean)=dir
+-clean := -f scripts/Makefile.clean obj
++clean := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.clean obj
+Index: linux-2.6.0-test5/scripts/Makefile.lib
+===================================================================
+--- linux-2.6.0-test5.orig/scripts/Makefile.lib 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/scripts/Makefile.lib 2003-09-27 11:38:42.361088520 +0800
+@@ -58,6 +58,11 @@
+ # in the local directory
+ subdir-obj-y := $(foreach o,$(obj-y),$(if $(filter-out $(o),$(notdir $(o))),$(o)))
+
++# $(obj-dirs) is a list of directories that contain object files
++obj-dirs := $(dir $(multi-objs) $(subdir-obj-y))
++obj-dirs += $(foreach f,$(host-progs), $(if $(dir $(f)),$(dir $(f))))
++obj-dirs := $(strip $(sort $(filter-out ./,$(obj-dirs))))
++
+ # Replace multi-part objects by their individual parts, look at local dir only
+ real-objs-y := $(foreach m, $(filter-out $(subdir-obj-y), $(obj-y)), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m))) $(extra-y)
+ real-objs-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m)))
+@@ -107,6 +112,7 @@
+ multi-objs-y := $(addprefix $(obj)/,$(multi-objs-y))
+ multi-objs-m := $(addprefix $(obj)/,$(multi-objs-m))
+ subdir-ym := $(addprefix $(obj)/,$(subdir-ym))
++obj-dirs := $(addprefix $(obj)/,$(obj-dirs))
+ host-progs := $(addprefix $(obj)/,$(host-progs))
+ host-csingle := $(addprefix $(obj)/,$(host-csingle))
+ host-cmulti := $(addprefix $(obj)/,$(host-cmulti))
+@@ -129,15 +135,46 @@
+ # where foo and bar are the name of the modules.
+ basename_flags = -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F)))
+ modname_flags = $(if $(filter 1,$(words $(modname))),-DKBUILD_MODNAME=$(subst $(comma),_,$(subst -,_,$(modname))))
+-c_flags = -Wp,-MD,$(depfile) $(CFLAGS) $(NOSTDINC_FLAGS) \
+- $(modkern_cflags) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o) \
+- $(basename_flags) $(modname_flags)
+-a_flags = -Wp,-MD,$(depfile) $(AFLAGS) $(NOSTDINC_FLAGS)\
+- $(modkern_aflags) $(EXTRA_AFLAGS) $(AFLAGS_$(*F).o)
+-hostc_flags = -Wp,-MD,$(depfile) $(HOSTCFLAGS) $(HOST_EXTRACFLAGS)\
+- $(HOSTCFLAGS_$(*F).o)
+-hostcxx_flags = -Wp,-MD,$(depfile) $(HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS)\
+- $(HOSTCXXFLAGS_$(*F).o)
++
++
++_c_flags = $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o)
++_a_flags = $(AFLAGS) $(EXTRA_AFLAGS) $(AFLAGS_$(*F).o)
++_hostc_flags = $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS_$(*F).o)
++_hostcxx_flags = $(HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) $(HOSTCXXFLAGS_$(*F).o)
++
++
++# If building the kernel in a separate objtree expand all occurrences
++# of -Idir to -Idir -I$(srctree)/dir.
++# hereby allowing gcc to locate files in both trees. Local tree first.
++
++ifeq ($(KBUILD_SRC),)
++__c_flags = $(_c_flags)
++__a_flags = $(_a_flags)
++__hostc_flags = $(_hostc_flags)
++__hostcxx_flags = $(_hostcxx_flags)
++else
++flags = $(foreach o,$($(1)),\
++ $(if $(filter -I%,$(o)),$(patsubst -I%,-I$(srctree)/%,$(o)),$(o)))
++
++# -I$(obj) locate generated .h files
++# -I$(srctree)/$(src) locate .h files in srctree, from generated .c files
++# FIXME: Replace both with specific EXTRA_CFLAGS statements
++__c_flags = -I$(obj) -I$(srctree)/$(src) $(call flags,_c_flags)
++__a_flags = $(call flags,_a_flags)
++__hostc_flags = -I$(obj) $(call flags,_hostc_flags)
++__hostcxx_flags = $(call flags,_hostcxx_flags)
++endif
++
++c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(CPPFLAGS) \
++ $(__c_flags) $(modkern_cflags) \
++ $(basename_flags) $(modname_flags)
++
++a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(CPPFLAGS) \
++ $(__a_flags) $(modkern_aflags)
++
++hostc_flags = -Wp,-MD,$(depfile) $(__hostc_flags)
++hostcxx_flags = -Wp,-MD,$(depfile) $(__hostcxx_flags)
++
+ ld_flags = $(LDFLAGS) $(EXTRA_LDFLAGS)
+
+ # Finds the multi-part object the current object will be linked into
+@@ -230,9 +267,9 @@
+ # $(call descend,<dir>,<target>)
+ # Recursively call a sub-make in <dir> with target <target>
+ # Usage is deprecated, because make do not see this as an invocation of make.
+-descend =$(Q)$(MAKE) -f scripts/Makefile.build obj=$(1) $(2)
++descend =$(Q)$(MAKE) -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj=$(1) $(2)
+
+ # Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj=
+ # Usage:
+ # $(Q)$(MAKE) $(build)=dir
+-build := -f scripts/Makefile.build obj
++build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj
+Index: linux-2.6.0-test5/scripts/Makefile.modpost
+===================================================================
+--- linux-2.6.0-test5.orig/scripts/Makefile.modpost 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/scripts/Makefile.modpost 2003-09-27 11:38:42.362088368 +0800
+@@ -35,7 +35,7 @@
+ # Compile version info for unresolved symbols
+
+ quiet_cmd_cc_o_c = CC $@
+- cmd_cc_o_c = $(CC) -Wp,-MD,$(depfile) $(CFLAGS) $(CFLAGS_MODULE) \
++ cmd_cc_o_c = $(CC) $(c_flags) $(CFLAGS_MODULE) \
+ -c -o $@ $<
+
+ $(modules:.ko=.mod.o): %.mod.o: %.mod.c FORCE
+Index: linux-2.6.0-test5/scripts/mkcompile_h
+===================================================================
+--- linux-2.6.0-test5.orig/scripts/mkcompile_h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/scripts/mkcompile_h 2003-09-27 11:38:42.363088216 +0800
+@@ -27,7 +27,7 @@
+
+ UTS_VERSION="#$VERSION"
+ if [ -n "$SMP" ] ; then UTS_VERSION="$UTS_VERSION SMP"; fi
+-UTS_VERSION="$UTS_VERSION `LANG=C date`"
++UTS_VERSION="$UTS_VERSION `LC_ALL=C LANG=C date`"
+
+ # Truncate to maximum length
+
+@@ -42,7 +42,7 @@
+
+ echo \#define UTS_VERSION \"`echo $UTS_VERSION | $UTS_TRUNCATE`\"
+
+- echo \#define LINUX_COMPILE_TIME \"`LANG=C date +%T`\"
++ echo \#define LINUX_COMPILE_TIME \"`LC_ALL=C LANG=C date +%T`\"
+ echo \#define LINUX_COMPILE_BY \"`whoami`\"
+ echo \#define LINUX_COMPILE_HOST \"`hostname | $UTS_TRUNCATE`\"
+
+Index: linux-2.6.0-test5/scripts/mkconfigs
+===================================================================
+--- linux-2.6.0-test5.orig/scripts/mkconfigs 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/scripts/mkconfigs 2003-09-27 11:38:42.365087912 +0800
+@@ -25,12 +25,6 @@
+ # - Retain lines that begin with "# CONFIG_"
+ # - lines that use double-quotes must \\-escape-quote them
+
+-
+-kernel_version()
+-{
+- KERNVER="`grep VERSION $1 | head -1 | cut -f3 -d' '`.`grep PATCHLEVEL $1 | head -1 | cut -f3 -d' '`.`grep SUBLEVEL $1 | head -1 | cut -f3 -d' '``grep EXTRAVERSION $1 | head -1 | cut -f3 -d' '`"
+-}
+-
+ if [ $# -lt 2 ]
+ then
+ echo "Usage: `basename $0` <configuration_file> <Makefile>"
+@@ -66,15 +60,7 @@
+ *
+ */"
+
+-echo "static char *ikconfig_built_with ="
+-echo " \"`uname -s` `uname -r` `uname -v` `uname -m`\";"
+-echo
+-kernel_version $makefile
+-echo "#ifdef CONFIG_IKCONFIG_PROC"
+-echo "static char *ikconfig_config = "
+-echo "#else"
+-echo "static char *ikconfig_config __initdata __attribute__((unused)) = "
+-echo "#endif"
++echo "static char const ikconfig_config[] __attribute__((unused)) = "
+ echo "\"CONFIG_BEGIN=n\\n\\"
+ echo "`cat $config | sed 's/\"/\\\\\"/g' | grep "^#\? \?CONFIG_" | awk '{ print $0 "\\\\n\\\\" }' `"
+ echo "CONFIG_END=n\\n\";"
+Index: linux-2.6.0-test5/scripts/mkspec
+===================================================================
+--- linux-2.6.0-test5.orig/scripts/mkspec 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/scripts/mkspec 2003-09-27 11:38:42.366087760 +0800
+@@ -27,7 +27,7 @@
+ echo "Version: "$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION | sed -e "s/-//g"
+ # we need to determine the NEXT version number so that uname and
+ # rpm -q will agree
+-echo "Release: `. scripts/mkversion`"
++echo "Release: `. $srctree/scripts/mkversion`"
+ echo "License: GPL"
+ echo "Group: System Environment/Kernel"
+ echo "Vendor: The Linux Community"
+@@ -45,7 +45,7 @@
+ echo "%setup -q"
+ echo ""
+ echo "%build"
+-echo "make clean oldconfig all"
++echo "make clean all"
+ echo ""
+ echo "%install"
+ echo 'mkdir -p $RPM_BUILD_ROOT/boot $RPM_BUILD_ROOT/lib $RPM_BUILD_ROOT/lib/modules'
+Index: linux-2.6.0-test5/scripts/modpost.c
+===================================================================
+--- linux-2.6.0-test5.orig/scripts/modpost.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/scripts/modpost.c 2003-09-27 11:38:42.370087152 +0800
+@@ -193,7 +193,7 @@
+
+ *size = st.st_size;
+ map = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
+- if (mmap == MAP_FAILED) {
++ if (map == MAP_FAILED) {
+ perror(filename);
+ abort();
+ }
+Index: linux-2.6.0-test5/security/capability.c
+===================================================================
+--- linux-2.6.0-test5.orig/security/capability.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/security/capability.c 2003-09-27 11:38:42.374086544 +0800
+@@ -23,334 +23,6 @@
+ #include <linux/netlink.h>
+ #include <linux/ptrace.h>
+
+-int cap_capable (struct task_struct *tsk, int cap)
+-{
+- /* Derived from include/linux/sched.h:capable. */
+- if (cap_raised (tsk->cap_effective, cap))
+- return 0;
+- else
+- return -EPERM;
+-}
+-
+-int cap_ptrace (struct task_struct *parent, struct task_struct *child)
+-{
+- /* Derived from arch/i386/kernel/ptrace.c:sys_ptrace. */
+- if (!cap_issubset (child->cap_permitted, current->cap_permitted) &&
+- !capable (CAP_SYS_PTRACE))
+- return -EPERM;
+- else
+- return 0;
+-}
+-
+-int cap_capget (struct task_struct *target, kernel_cap_t *effective,
+- kernel_cap_t *inheritable, kernel_cap_t *permitted)
+-{
+- /* Derived from kernel/capability.c:sys_capget. */
+- *effective = cap_t (target->cap_effective);
+- *inheritable = cap_t (target->cap_inheritable);
+- *permitted = cap_t (target->cap_permitted);
+- return 0;
+-}
+-
+-int cap_capset_check (struct task_struct *target, kernel_cap_t *effective,
+- kernel_cap_t *inheritable, kernel_cap_t *permitted)
+-{
+- /* Derived from kernel/capability.c:sys_capset. */
+- /* verify restrictions on target's new Inheritable set */
+- if (!cap_issubset (*inheritable,
+- cap_combine (target->cap_inheritable,
+- current->cap_permitted))) {
+- return -EPERM;
+- }
+-
+- /* verify restrictions on target's new Permitted set */
+- if (!cap_issubset (*permitted,
+- cap_combine (target->cap_permitted,
+- current->cap_permitted))) {
+- return -EPERM;
+- }
+-
+- /* verify the _new_Effective_ is a subset of the _new_Permitted_ */
+- if (!cap_issubset (*effective, *permitted)) {
+- return -EPERM;
+- }
+-
+- return 0;
+-}
+-
+-void cap_capset_set (struct task_struct *target, kernel_cap_t *effective,
+- kernel_cap_t *inheritable, kernel_cap_t *permitted)
+-{
+- target->cap_effective = *effective;
+- target->cap_inheritable = *inheritable;
+- target->cap_permitted = *permitted;
+-}
+-
+-int cap_bprm_set_security (struct linux_binprm *bprm)
+-{
+- /* Copied from fs/exec.c:prepare_binprm. */
+-
+- /* We don't have VFS support for capabilities yet */
+- cap_clear (bprm->cap_inheritable);
+- cap_clear (bprm->cap_permitted);
+- cap_clear (bprm->cap_effective);
+-
+- /* To support inheritance of root-permissions and suid-root
+- * executables under compatibility mode, we raise all three
+- * capability sets for the file.
+- *
+- * If only the real uid is 0, we only raise the inheritable
+- * and permitted sets of the executable file.
+- */
+-
+- if (!issecure (SECURE_NOROOT)) {
+- if (bprm->e_uid == 0 || current->uid == 0) {
+- cap_set_full (bprm->cap_inheritable);
+- cap_set_full (bprm->cap_permitted);
+- }
+- if (bprm->e_uid == 0)
+- cap_set_full (bprm->cap_effective);
+- }
+- return 0;
+-}
+-
+-/* Copied from fs/exec.c */
+-static inline int must_not_trace_exec (struct task_struct *p)
+-{
+- return (p->ptrace & PT_PTRACED) && !(p->ptrace & PT_PTRACE_CAP);
+-}
+-
+-void cap_bprm_compute_creds (struct linux_binprm *bprm)
+-{
+- /* Derived from fs/exec.c:compute_creds. */
+- kernel_cap_t new_permitted, working;
+-
+- new_permitted = cap_intersect (bprm->cap_permitted, cap_bset);
+- working = cap_intersect (bprm->cap_inheritable,
+- current->cap_inheritable);
+- new_permitted = cap_combine (new_permitted, working);
+-
+- task_lock(current);
+- if (!cap_issubset (new_permitted, current->cap_permitted)) {
+- current->mm->dumpable = 0;
+-
+- if (must_not_trace_exec (current)
+- || atomic_read (¤t->fs->count) > 1
+- || atomic_read (¤t->files->count) > 1
+- || atomic_read (¤t->sighand->count) > 1) {
+- if (!capable (CAP_SETPCAP)) {
+- new_permitted = cap_intersect (new_permitted,
+- current->
+- cap_permitted);
+- }
+- }
+- }
+-
+- /* For init, we want to retain the capabilities set
+- * in the init_task struct. Thus we skip the usual
+- * capability rules */
+- if (current->pid != 1) {
+- current->cap_permitted = new_permitted;
+- current->cap_effective =
+- cap_intersect (new_permitted, bprm->cap_effective);
+- }
+-
+- /* AUD: Audit candidate if current->cap_effective is set */
+- task_unlock(current);
+-
+- current->keep_capabilities = 0;
+-}
+-
+-int cap_bprm_secureexec (struct linux_binprm *bprm)
+-{
+- /* If/when this module is enhanced to incorporate capability
+- bits on files, the test below should be extended to also perform a
+- test between the old and new capability sets. For now,
+- it simply preserves the legacy decision algorithm used by
+- the old userland. */
+- return (current->euid != current->uid ||
+- current->egid != current->gid);
+-}
+-
+-/* moved from kernel/sys.c. */
+-/*
+- * cap_emulate_setxuid() fixes the effective / permitted capabilities of
+- * a process after a call to setuid, setreuid, or setresuid.
+- *
+- * 1) When set*uiding _from_ one of {r,e,s}uid == 0 _to_ all of
+- * {r,e,s}uid != 0, the permitted and effective capabilities are
+- * cleared.
+- *
+- * 2) When set*uiding _from_ euid == 0 _to_ euid != 0, the effective
+- * capabilities of the process are cleared.
+- *
+- * 3) When set*uiding _from_ euid != 0 _to_ euid == 0, the effective
+- * capabilities are set to the permitted capabilities.
+- *
+- * fsuid is handled elsewhere. fsuid == 0 and {r,e,s}uid!= 0 should
+- * never happen.
+- *
+- * -astor
+- *
+- * cevans - New behaviour, Oct '99
+- * A process may, via prctl(), elect to keep its capabilities when it
+- * calls setuid() and switches away from uid==0. Both permitted and
+- * effective sets will be retained.
+- * Without this change, it was impossible for a daemon to drop only some
+- * of its privilege. The call to setuid(!=0) would drop all privileges!
+- * Keeping uid 0 is not an option because uid 0 owns too many vital
+- * files..
+- * Thanks to Olaf Kirch and Peter Benie for spotting this.
+- */
+-static inline void cap_emulate_setxuid (int old_ruid, int old_euid,
+- int old_suid)
+-{
+- if ((old_ruid == 0 || old_euid == 0 || old_suid == 0) &&
+- (current->uid != 0 && current->euid != 0 && current->suid != 0) &&
+- !current->keep_capabilities) {
+- cap_clear (current->cap_permitted);
+- cap_clear (current->cap_effective);
+- }
+- if (old_euid == 0 && current->euid != 0) {
+- cap_clear (current->cap_effective);
+- }
+- if (old_euid != 0 && current->euid == 0) {
+- current->cap_effective = current->cap_permitted;
+- }
+-}
+-
+-int cap_task_post_setuid (uid_t old_ruid, uid_t old_euid, uid_t old_suid,
+- int flags)
+-{
+- switch (flags) {
+- case LSM_SETID_RE:
+- case LSM_SETID_ID:
+- case LSM_SETID_RES:
+- /* Copied from kernel/sys.c:setreuid/setuid/setresuid. */
+- if (!issecure (SECURE_NO_SETUID_FIXUP)) {
+- cap_emulate_setxuid (old_ruid, old_euid, old_suid);
+- }
+- break;
+- case LSM_SETID_FS:
+- {
+- uid_t old_fsuid = old_ruid;
+-
+- /* Copied from kernel/sys.c:setfsuid. */
+-
+- /*
+- * FIXME - is fsuser used for all CAP_FS_MASK capabilities?
+- * if not, we might be a bit too harsh here.
+- */
+-
+- if (!issecure (SECURE_NO_SETUID_FIXUP)) {
+- if (old_fsuid == 0 && current->fsuid != 0) {
+- cap_t (current->cap_effective) &=
+- ~CAP_FS_MASK;
+- }
+- if (old_fsuid != 0 && current->fsuid == 0) {
+- cap_t (current->cap_effective) |=
+- (cap_t (current->cap_permitted) &
+- CAP_FS_MASK);
+- }
+- }
+- break;
+- }
+- default:
+- return -EINVAL;
+- }
+-
+- return 0;
+-}
+-
+-void cap_task_reparent_to_init (struct task_struct *p)
+-{
+- p->cap_effective = CAP_INIT_EFF_SET;
+- p->cap_inheritable = CAP_INIT_INH_SET;
+- p->cap_permitted = CAP_FULL_SET;
+- p->keep_capabilities = 0;
+- return;
+-}
+-
+-int cap_syslog (int type)
+-{
+- if ((type != 3) && !capable(CAP_SYS_ADMIN))
+- return -EPERM;
+- return 0;
+-}
+-
+-/*
+- * Check that a process has enough memory to allocate a new virtual
+- * mapping. 0 means there is enough memory for the allocation to
+- * succeed and -ENOMEM implies there is not.
+- *
+- * We currently support three overcommit policies, which are set via the
+- * vm.overcommit_memory sysctl. See Documentation/vm/overcommit-acounting
+- *
+- * Strict overcommit modes added 2002 Feb 26 by Alan Cox.
+- * Additional code 2002 Jul 20 by Robert Love.
+- */
+-int cap_vm_enough_memory(long pages)
+-{
+- unsigned long free, allowed;
+-
+- vm_acct_memory(pages);
+-
+- /* We estimate memory ourselves (common case) */
+- if (sysctl_overcommit_memory == 0) {
+- free = get_page_cache_size();
+- free += nr_free_pages();
+- free += nr_swap_pages;
+-
+- /*
+- * Any slabs which are created with the
+- * SLAB_RECLAIM_ACCOUNT flag claim to have contents
+- * which are reclaimable, under pressure. The dentry
+- * cache and most inode caches should fall into this
+- */
+- free += atomic_read(&slab_reclaim_pages);
+-
+- /*
+- * Leave the last 3% for root
+- */
+- if (!capable(CAP_SYS_ADMIN))
+- free -= free / 32;
+-
+- if (free > pages)
+- return 0;
+-
+- vm_unacct_memory(pages);
+- return -ENOMEM;
+- }
+-
+- /* Kernel assumes allocation */
+- if (sysctl_overcommit_memory == 1)
+- return 0;
+-
+- /* sysctl_overcommit_memory must be 2 which means strict_overcommit*/
+- allowed = totalram_pages * sysctl_overcommit_ratio / 100;
+- allowed += total_swap_pages;
+-
+- if (atomic_read(&vm_committed_space) < allowed)
+- return 0;
+-
+- vm_unacct_memory(pages);
+-
+- return -ENOMEM;
+-}
+-
+-EXPORT_SYMBOL(cap_capable);
+-EXPORT_SYMBOL(cap_ptrace);
+-EXPORT_SYMBOL(cap_capget);
+-EXPORT_SYMBOL(cap_capset_check);
+-EXPORT_SYMBOL(cap_capset_set);
+-EXPORT_SYMBOL(cap_bprm_set_security);
+-EXPORT_SYMBOL(cap_bprm_compute_creds);
+-EXPORT_SYMBOL(cap_bprm_secureexec);
+-EXPORT_SYMBOL(cap_task_post_setuid);
+-EXPORT_SYMBOL(cap_task_reparent_to_init);
+-EXPORT_SYMBOL(cap_syslog);
+-EXPORT_SYMBOL(cap_vm_enough_memory);
+-
+ #ifdef CONFIG_SECURITY
+
+
+Index: linux-2.6.0-test5/security/commoncap.c
+===================================================================
+--- linux-2.6.0-test5.orig/security/commoncap.c 2003-09-27 11:38:18.495716608 +0800
++++ linux-2.6.0-test5/security/commoncap.c 2003-09-27 11:38:42.375086392 +0800
+@@ -0,0 +1,353 @@
++/* Common capabilities, needed by capability.o and root_plug.o
++ *
++ * 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/module.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/security.h>
++#include <linux/file.h>
++#include <linux/mm.h>
++#include <linux/mman.h>
++#include <linux/pagemap.h>
++#include <linux/swap.h>
++#include <linux/smp_lock.h>
++#include <linux/skbuff.h>
++#include <linux/netlink.h>
++#include <linux/ptrace.h>
++
++int cap_capable (struct task_struct *tsk, int cap)
++{
++ /* Derived from include/linux/sched.h:capable. */
++ if (cap_raised (tsk->cap_effective, cap))
++ return 0;
++ else
++ return -EPERM;
++}
++
++int cap_ptrace (struct task_struct *parent, struct task_struct *child)
++{
++ /* Derived from arch/i386/kernel/ptrace.c:sys_ptrace. */
++ if (!cap_issubset (child->cap_permitted, current->cap_permitted) &&
++ !capable (CAP_SYS_PTRACE))
++ return -EPERM;
++ else
++ return 0;
++}
++
++int cap_capget (struct task_struct *target, kernel_cap_t *effective,
++ kernel_cap_t *inheritable, kernel_cap_t *permitted)
++{
++ /* Derived from kernel/capability.c:sys_capget. */
++ *effective = cap_t (target->cap_effective);
++ *inheritable = cap_t (target->cap_inheritable);
++ *permitted = cap_t (target->cap_permitted);
++ return 0;
++}
++
++int cap_capset_check (struct task_struct *target, kernel_cap_t *effective,
++ kernel_cap_t *inheritable, kernel_cap_t *permitted)
++{
++ /* Derived from kernel/capability.c:sys_capset. */
++ /* verify restrictions on target's new Inheritable set */
++ if (!cap_issubset (*inheritable,
++ cap_combine (target->cap_inheritable,
++ current->cap_permitted))) {
++ return -EPERM;
++ }
++
++ /* verify restrictions on target's new Permitted set */
++ if (!cap_issubset (*permitted,
++ cap_combine (target->cap_permitted,
++ current->cap_permitted))) {
++ return -EPERM;
++ }
++
++ /* verify the _new_Effective_ is a subset of the _new_Permitted_ */
++ if (!cap_issubset (*effective, *permitted)) {
++ return -EPERM;
++ }
++
++ return 0;
++}
++
++void cap_capset_set (struct task_struct *target, kernel_cap_t *effective,
++ kernel_cap_t *inheritable, kernel_cap_t *permitted)
++{
++ target->cap_effective = *effective;
++ target->cap_inheritable = *inheritable;
++ target->cap_permitted = *permitted;
++}
++
++int cap_bprm_set_security (struct linux_binprm *bprm)
++{
++ /* Copied from fs/exec.c:prepare_binprm. */
++
++ /* We don't have VFS support for capabilities yet */
++ cap_clear (bprm->cap_inheritable);
++ cap_clear (bprm->cap_permitted);
++ cap_clear (bprm->cap_effective);
++
++ /* To support inheritance of root-permissions and suid-root
++ * executables under compatibility mode, we raise all three
++ * capability sets for the file.
++ *
++ * If only the real uid is 0, we only raise the inheritable
++ * and permitted sets of the executable file.
++ */
++
++ if (!issecure (SECURE_NOROOT)) {
++ if (bprm->e_uid == 0 || current->uid == 0) {
++ cap_set_full (bprm->cap_inheritable);
++ cap_set_full (bprm->cap_permitted);
++ }
++ if (bprm->e_uid == 0)
++ cap_set_full (bprm->cap_effective);
++ }
++ return 0;
++}
++
++/* Copied from fs/exec.c */
++static inline int must_not_trace_exec (struct task_struct *p)
++{
++ return (p->ptrace & PT_PTRACED) && !(p->ptrace & PT_PTRACE_CAP);
++}
++
++void cap_bprm_compute_creds (struct linux_binprm *bprm)
++{
++ /* Derived from fs/exec.c:compute_creds. */
++ kernel_cap_t new_permitted, working;
++
++ new_permitted = cap_intersect (bprm->cap_permitted, cap_bset);
++ working = cap_intersect (bprm->cap_inheritable,
++ current->cap_inheritable);
++ new_permitted = cap_combine (new_permitted, working);
++
++ task_lock(current);
++ if (!cap_issubset (new_permitted, current->cap_permitted)) {
++ current->mm->dumpable = 0;
++
++ if (must_not_trace_exec (current)
++ || atomic_read (¤t->fs->count) > 1
++ || atomic_read (¤t->files->count) > 1
++ || atomic_read (¤t->sighand->count) > 1) {
++ if (!capable (CAP_SETPCAP)) {
++ new_permitted = cap_intersect (new_permitted,
++ current->
++ cap_permitted);
++ }
++ }
++ }
++
++ /* For init, we want to retain the capabilities set
++ * in the init_task struct. Thus we skip the usual
++ * capability rules */
++ if (current->pid != 1) {
++ current->cap_permitted = new_permitted;
++ current->cap_effective =
++ cap_intersect (new_permitted, bprm->cap_effective);
++ }
++
++ /* AUD: Audit candidate if current->cap_effective is set */
++ task_unlock(current);
++
++ current->keep_capabilities = 0;
++}
++
++int cap_bprm_secureexec (struct linux_binprm *bprm)
++{
++ /* If/when this module is enhanced to incorporate capability
++ bits on files, the test below should be extended to also perform a
++ test between the old and new capability sets. For now,
++ it simply preserves the legacy decision algorithm used by
++ the old userland. */
++ return (current->euid != current->uid ||
++ current->egid != current->gid);
++}
++
++/* moved from kernel/sys.c. */
++/*
++ * cap_emulate_setxuid() fixes the effective / permitted capabilities of
++ * a process after a call to setuid, setreuid, or setresuid.
++ *
++ * 1) When set*uiding _from_ one of {r,e,s}uid == 0 _to_ all of
++ * {r,e,s}uid != 0, the permitted and effective capabilities are
++ * cleared.
++ *
++ * 2) When set*uiding _from_ euid == 0 _to_ euid != 0, the effective
++ * capabilities of the process are cleared.
++ *
++ * 3) When set*uiding _from_ euid != 0 _to_ euid == 0, the effective
++ * capabilities are set to the permitted capabilities.
++ *
++ * fsuid is handled elsewhere. fsuid == 0 and {r,e,s}uid!= 0 should
++ * never happen.
++ *
++ * -astor
++ *
++ * cevans - New behaviour, Oct '99
++ * A process may, via prctl(), elect to keep its capabilities when it
++ * calls setuid() and switches away from uid==0. Both permitted and
++ * effective sets will be retained.
++ * Without this change, it was impossible for a daemon to drop only some
++ * of its privilege. The call to setuid(!=0) would drop all privileges!
++ * Keeping uid 0 is not an option because uid 0 owns too many vital
++ * files..
++ * Thanks to Olaf Kirch and Peter Benie for spotting this.
++ */
++static inline void cap_emulate_setxuid (int old_ruid, int old_euid,
++ int old_suid)
++{
++ if ((old_ruid == 0 || old_euid == 0 || old_suid == 0) &&
++ (current->uid != 0 && current->euid != 0 && current->suid != 0) &&
++ !current->keep_capabilities) {
++ cap_clear (current->cap_permitted);
++ cap_clear (current->cap_effective);
++ }
++ if (old_euid == 0 && current->euid != 0) {
++ cap_clear (current->cap_effective);
++ }
++ if (old_euid != 0 && current->euid == 0) {
++ current->cap_effective = current->cap_permitted;
++ }
++}
++
++int cap_task_post_setuid (uid_t old_ruid, uid_t old_euid, uid_t old_suid,
++ int flags)
++{
++ switch (flags) {
++ case LSM_SETID_RE:
++ case LSM_SETID_ID:
++ case LSM_SETID_RES:
++ /* Copied from kernel/sys.c:setreuid/setuid/setresuid. */
++ if (!issecure (SECURE_NO_SETUID_FIXUP)) {
++ cap_emulate_setxuid (old_ruid, old_euid, old_suid);
++ }
++ break;
++ case LSM_SETID_FS:
++ {
++ uid_t old_fsuid = old_ruid;
++
++ /* Copied from kernel/sys.c:setfsuid. */
++
++ /*
++ * FIXME - is fsuser used for all CAP_FS_MASK capabilities?
++ * if not, we might be a bit too harsh here.
++ */
++
++ if (!issecure (SECURE_NO_SETUID_FIXUP)) {
++ if (old_fsuid == 0 && current->fsuid != 0) {
++ cap_t (current->cap_effective) &=
++ ~CAP_FS_MASK;
++ }
++ if (old_fsuid != 0 && current->fsuid == 0) {
++ cap_t (current->cap_effective) |=
++ (cap_t (current->cap_permitted) &
++ CAP_FS_MASK);
++ }
++ }
++ break;
++ }
++ default:
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++void cap_task_reparent_to_init (struct task_struct *p)
++{
++ p->cap_effective = CAP_INIT_EFF_SET;
++ p->cap_inheritable = CAP_INIT_INH_SET;
++ p->cap_permitted = CAP_FULL_SET;
++ p->keep_capabilities = 0;
++ return;
++}
++
++int cap_syslog (int type)
++{
++ if ((type != 3) && !capable(CAP_SYS_ADMIN))
++ return -EPERM;
++ return 0;
++}
++
++/*
++ * Check that a process has enough memory to allocate a new virtual
++ * mapping. 0 means there is enough memory for the allocation to
++ * succeed and -ENOMEM implies there is not.
++ *
++ * We currently support three overcommit policies, which are set via the
++ * vm.overcommit_memory sysctl. See Documentation/vm/overcommit-acounting
++ *
++ * Strict overcommit modes added 2002 Feb 26 by Alan Cox.
++ * Additional code 2002 Jul 20 by Robert Love.
++ */
++int cap_vm_enough_memory(long pages)
++{
++ unsigned long free, allowed;
++
++ vm_acct_memory(pages);
++
++ /*
++ * Sometimes we want to use more memory than we have
++ */
++ if (sysctl_overcommit_memory == 1)
++ return 0;
++
++ if (sysctl_overcommit_memory == 0) {
++ free = get_page_cache_size();
++ free += nr_free_pages();
++ free += nr_swap_pages;
++
++ /*
++ * Any slabs which are created with the
++ * SLAB_RECLAIM_ACCOUNT flag claim to have contents
++ * which are reclaimable, under pressure. The dentry
++ * cache and most inode caches should fall into this
++ */
++ free += atomic_read(&slab_reclaim_pages);
++
++ /*
++ * Leave the last 3% for root
++ */
++ if (!capable(CAP_SYS_ADMIN))
++ free -= free / 32;
++
++ if (free > pages)
++ return 0;
++ vm_unacct_memory(pages);
++ return -ENOMEM;
++ }
++
++ allowed = totalram_pages * sysctl_overcommit_ratio / 100;
++ allowed += total_swap_pages;
++
++ if (atomic_read(&vm_committed_space) < allowed)
++ return 0;
++
++ vm_unacct_memory(pages);
++
++ return -ENOMEM;
++}
++
++EXPORT_SYMBOL(cap_capable);
++EXPORT_SYMBOL(cap_ptrace);
++EXPORT_SYMBOL(cap_capget);
++EXPORT_SYMBOL(cap_capset_check);
++EXPORT_SYMBOL(cap_capset_set);
++EXPORT_SYMBOL(cap_bprm_set_security);
++EXPORT_SYMBOL(cap_bprm_compute_creds);
++EXPORT_SYMBOL(cap_bprm_secureexec);
++EXPORT_SYMBOL(cap_task_post_setuid);
++EXPORT_SYMBOL(cap_task_reparent_to_init);
++EXPORT_SYMBOL(cap_syslog);
++EXPORT_SYMBOL(cap_vm_enough_memory);
++
++MODULE_DESCRIPTION("Standard Linux Common Capabilities Security Module");
++MODULE_LICENSE("GPL");
+Index: linux-2.6.0-test5/security/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/security/Makefile 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/security/Makefile 2003-09-27 11:38:42.376086240 +0800
+@@ -6,7 +6,7 @@
+
+ # if we don't select a security model, use the default capabilities
+ ifneq ($(CONFIG_SECURITY),y)
+-obj-y += capability.o
++obj-y += commoncap.o capability.o
+ endif
+
+ # Object file lists
+@@ -15,5 +15,5 @@
+ ifeq ($(CONFIG_SECURITY_SELINUX),y)
+ obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o
+ endif
+-obj-$(CONFIG_SECURITY_CAPABILITIES) += capability.o
+-obj-$(CONFIG_SECURITY_ROOTPLUG) += root_plug.o
++obj-$(CONFIG_SECURITY_CAPABILITIES) += commoncap.o capability.o
++obj-$(CONFIG_SECURITY_ROOTPLUG) += commoncap.o root_plug.o
+Index: linux-2.6.0-test5/security/security.c
+===================================================================
+--- linux-2.6.0-test5.orig/security/security.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/security/security.c 2003-09-27 11:38:42.379085784 +0800
+@@ -79,9 +79,8 @@
+ * value passed to this function. A call to unregister_security() should be
+ * done to remove this security_options structure from the kernel.
+ *
+- * If the @ops structure does not contain function pointers for all hooks in
+- * the structure, or there is already a security module registered with the
+- * kernel, an error will be returned. Otherwise 0 is returned on success.
++ * If there is already a security module registered with the kernel,
++ * an error will be returned. Otherwise 0 is returned on success.
+ */
+ int register_security (struct security_operations *ops)
+ {
+Index: linux-2.6.0-test5/security/selinux/hooks.c
+===================================================================
+--- linux-2.6.0-test5.orig/security/selinux/hooks.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/security/selinux/hooks.c 2003-09-27 11:38:42.400082592 +0800
+@@ -73,7 +73,8 @@
+ __setup("enforcing=", enforcing_setup);
+ #endif
+
+-int selinux_enabled = 0;
++#ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM
++int selinux_enabled = 1;
+
+ static int __init selinux_enabled_setup(char *str)
+ {
+@@ -81,6 +82,7 @@
+ return 1;
+ }
+ __setup("selinux=", selinux_enabled_setup);
++#endif
+
+ /* Original (dummy) security module. */
+ static struct security_operations *original_ops = NULL;
+@@ -3357,7 +3359,7 @@
+ struct task_security_struct *tsec;
+
+ if (!selinux_enabled) {
+- printk(KERN_INFO "SELinux: Not enabled at boot.\n");
++ printk(KERN_INFO "SELinux: Disabled at boot.\n");
+ return 0;
+ }
+
+Index: linux-2.6.0-test5/security/selinux/include/security.h
+===================================================================
+--- linux-2.6.0-test5.orig/security/selinux/include/security.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/security/selinux/include/security.h 2003-09-27 11:38:42.402082288 +0800
+@@ -14,6 +14,12 @@
+
+ #define SELINUX_MAGIC 0xf97cff8c
+
++#ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM
++extern int selinux_enabled;
++#else
++#define selinux_enabled 1
++#endif
++
+ int security_load_policy(void * data, size_t len);
+
+ struct av_decision {
+Index: linux-2.6.0-test5/security/selinux/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/security/selinux/Kconfig 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/security/selinux/Kconfig 2003-09-27 11:38:42.403082136 +0800
+@@ -8,9 +8,20 @@
+ You can obtain the policy compiler (checkpolicy), the utility for
+ labeling filesystems (setfiles), and an example policy configuration
+ from http://www.nsa.gov/selinux.
+- SELinux needs to be explicitly enabled on the kernel command line with
+- selinux=1. If you specify selinux=0 or do not use this parameter,
+- SELinux will not be enabled.
++ If you are unsure how to answer this question, answer N.
++
++config SECURITY_SELINUX_BOOTPARAM
++ bool "NSA SELinux boot parameter"
++ depends on SECURITY_SELINUX
++ default n
++ help
++ This option adds a kernel parameter 'selinux', which allows SELinux
++ to be disabled at boot. If this option is selected, SELinux
++ functionality can be disabled with selinux=0 on the kernel
++ command line. The purpose of this option is to allow a single
++ kernel image to be distributed with SELinux built in, but not
++ necessarily enabled.
++
+ If you are unsure how to answer this question, answer N.
+
+ config SECURITY_SELINUX_DEVELOP
+Index: linux-2.6.0-test5/security/selinux/selinuxfs.c
+===================================================================
+--- linux-2.6.0-test5.orig/security/selinux/selinuxfs.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/security/selinux/selinuxfs.c 2003-09-27 11:38:42.408081376 +0800
+@@ -17,8 +17,6 @@
+ #include "security.h"
+ #include "objsec.h"
+
+-extern int selinux_enabled;
+-
+ /* Check whether a task is allowed to use a security operation. */
+ int task_has_security(struct task_struct *tsk,
+ u32 perms)
+Index: linux-2.6.0-test5/sound/core/ioctl32/ioctl32.c
+===================================================================
+--- linux-2.6.0-test5.orig/sound/core/ioctl32/ioctl32.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/sound/core/ioctl32/ioctl32.c 2003-09-27 11:38:42.411080920 +0800
+@@ -25,7 +25,6 @@
+ #include <linux/time.h>
+ #include <linux/slab.h>
+ #include <linux/fs.h>
+-#include <linux/init.h>
+ #include <sound/core.h>
+ #include <sound/control.h>
+ #include <asm/uaccess.h>
+Index: linux-2.6.0-test5/sound/oss/ac97_codec.c
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/ac97_codec.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/sound/oss/ac97_codec.c 2003-09-27 11:38:42.422079248 +0800
+@@ -1078,6 +1078,10 @@
+ /* WM9711, WM9712 */
+ static int wolfson_init11(struct ac97_codec * codec)
+ {
++ /* stop pop's during suspend/resume */
++ codec->codec_write(codec, AC97_WM97XX_TEST,
++ codec->codec_read(codec, AC97_WM97XX_TEST) & 0xffbf);
++
+ /* set out3 volume */
+ codec->codec_write(codec, AC97_WM9711_OUT3VOL, 0x0808);
+ return 0;
+Index: linux-2.6.0-test5/sound/oss/dmasound/awacs_defs.h
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/dmasound/awacs_defs.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/sound/oss/dmasound/awacs_defs.h 2003-09-27 11:38:42.426078640 +0800
+@@ -71,17 +71,20 @@
+ /* ------- - --- ----- - ------ */
+ #define MASK_GAINRIGHT (0xf) /* Gain Right Mask */
+ #define MASK_GAINLEFT (0xf << 4) /* Gain Left Mask */
+-#define MASK_GAINLINE (0x1 << 8) /* Change Gain for Line??? */
+-#define MASK_GAINMIC (0x0 << 8) /* Change Gain for Mic??? */
++#define MASK_GAINLINE (0x1 << 8) /* Disable Mic preamp */
++#define MASK_GAINMIC (0x0 << 8) /* Enable Mic preamp */
+
+ #define MASK_MUX_CD (0x1 << 9) /* Select CD in MUX */
+-#define MASK_MUX_AUDIN (0x1 << 10) /* Select Audio In in MUX */
+-#define MASK_MUX_MIC (0x1 << 11) /* Select Mic in MUX */
++#define MASK_MUX_MIC (0x1 << 10) /* Select Mic in MUX */
++#define MASK_MUX_AUDIN (0x1 << 11) /* Select Audio In in MUX */
+ #define MASK_MUX_LINE MASK_MUX_AUDIN
+
+ #define GAINRIGHT(x) ((x) & MASK_GAINRIGHT)
+ #define GAINLEFT(x) (((x) << 4) & MASK_GAINLEFT)
+
++#define DEF_CD_GAIN 0x00bb
++#define DEF_MIC_GAIN 0x00cc
++
+ /* Address 1 Bit Masks */
+ /* ------- - --- ----- */
+ #define MASK_ADDR1RES1 (0x3) /* Reserved */
+@@ -93,7 +96,10 @@
+ #define MASK_ADDR1RES2 (0x1 << 8) /* Reserved */
+ #define MASK_AMUTE (0x1 << 9) /* Output A (Headphone) Mute when 1 */
+ #define MASK_HDMUTE MASK_AMUTE
+-#define MASK_PAROUT (0x3 << 10) /* Parallel Out (???) */
++#define MASK_PAROUT0 (0x1 << 10) /* Parallel Output 0 */
++#define MASK_PAROUT1 (0x2 << 10) /* Parallel Output 1 */
++
++#define MASK_MIC_BOOST (0x4) /* screamer mic boost */
+
+ #define SAMPLERATE_48000 (0x0 << 3) /* 48 or 44.1 kHz */
+ #define SAMPLERATE_32000 (0x1 << 3) /* 32 or 29.4 kHz */
+@@ -162,8 +168,9 @@
+
+ #define RATE_LOW 1 /* HIGH = 48kHz, etc; LOW = 44.1kHz, etc. */
+
+-
++/*******************/
+ /* Burgundy values */
++/*******************/
+
+ #define MASK_ADDR_BURGUNDY_INPSEL21 (0x11 << 12)
+ #define MASK_ADDR_BURGUNDY_INPSEL3 (0x12 << 12)
+@@ -226,4 +233,19 @@
+ #define DEF_BURGUNDY_ATTENLINEOUT (0xCC)
+ #define DEF_BURGUNDY_ATTENHP (0xCC)
+
++/*********************/
++/* i2s layout values */
++/*********************/
++
++#define I2S_REG_INT_CTL 0x00
++#define I2S_REG_SERIAL_FORMAT 0x10
++#define I2S_REG_CODEC_MSG_OUT 0x20
++#define I2S_REG_CODEC_MSG_IN 0x30
++#define I2S_REG_FRAME_COUNT 0x40
++#define I2S_REG_FRAME_MATCH 0x50
++#define I2S_REG_DATAWORD_SIZES 0x60
++#define I2S_REG_PEAKLEVEL_SEL 0x70
++#define I2S_REG_PEAKLEVEL_IN0 0x80
++#define I2S_REG_PEAKLEVEL_IN1 0x90
++
+ #endif /* _AWACS_DEFS_H_ */
+Index: linux-2.6.0-test5/sound/oss/dmasound/dac3550a.c
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/dmasound/dac3550a.c 2003-09-27 11:38:18.495716608 +0800
++++ linux-2.6.0-test5/sound/oss/dmasound/dac3550a.c 2003-09-27 11:38:42.427078488 +0800
+@@ -0,0 +1,222 @@
++/*
++ * Driver for the i2c/i2s based DAC3550a sound chip used
++ * on some Apple iBooks. Also known as "DACA".
++ *
++ * 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.
++ */
++
++#include <linux/version.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/proc_fs.h>
++#include <linux/ioport.h>
++#include <linux/sysctl.h>
++#include <linux/types.h>
++#include <linux/i2c.h>
++#include <linux/init.h>
++#include <asm/uaccess.h>
++#include <asm/errno.h>
++#include <asm/io.h>
++
++#include "dmasound.h"
++
++/* FYI: This code was derived from the tas3001c.c Texas/Tumbler mixer
++ * control code, as well as info derived from the AppleDACAAudio driver
++ * from Darwin CVS (main thing I derived being register numbers and
++ * values, as well as when to make the calls). */
++
++#define I2C_DRIVERID_DACA (0xFDCB)
++
++#define DACA_VERSION "0.1"
++#define DACA_DATE "20010930"
++
++static int cur_left_vol;
++static int cur_right_vol;
++static struct i2c_client *daca_client;
++
++static int daca_attach_adapter(struct i2c_adapter *adapter);
++static int daca_detect_client(struct i2c_adapter *adapter, int address);
++static int daca_detach_client(struct i2c_client *client);
++
++/* Unique ID allocation */
++static int daca_id;
++
++struct daca_data
++{
++ int arf; /* place holder for furture use */
++};
++
++struct i2c_driver daca_driver = {
++ .owner = THIS_MODULE,
++ .name = "DAC3550A driver V " DACA_VERSION,
++ .id = I2C_DRIVERID_DACA,
++ .flags = I2C_DF_NOTIFY,
++ .attach_adapter = daca_attach_adapter,
++ .detach_client = daca_detach_client,
++};
++
++#define VOL_MAX ((1<<20) - 1)
++
++void daca_get_volume(uint * left_vol, uint *right_vol)
++{
++ *left_vol = cur_left_vol >> 5;
++ *right_vol = cur_right_vol >> 5;
++}
++
++int daca_set_volume(uint left_vol, uint right_vol)
++{
++ unsigned short voldata;
++
++ if (!daca_client)
++ return -1;
++
++ /* Derived from experience, not from any specific values */
++ left_vol <<= 5;
++ right_vol <<= 5;
++
++ if (left_vol > VOL_MAX)
++ left_vol = VOL_MAX;
++ if (right_vol > VOL_MAX)
++ right_vol = VOL_MAX;
++
++ voldata = ((left_vol >> 14) & 0x3f) << 8;
++ voldata |= (right_vol >> 14) & 0x3f;
++
++ if (i2c_smbus_write_word_data(daca_client, 2, voldata) < 0) {
++ printk("daca: failed to set volume \n");
++ return -1;
++ }
++
++ cur_left_vol = left_vol;
++ cur_right_vol = right_vol;
++
++ return 0;
++}
++
++int daca_leave_sleep(void)
++{
++ if (!daca_client)
++ return -1;
++
++ /* Do a short sleep, just to make sure I2C bus is awake and paying
++ * attention to us
++ */
++ wait_ms(20);
++ /* Write the sample rate reg the value it needs */
++ i2c_smbus_write_byte_data(daca_client, 1, 8);
++ daca_set_volume(cur_left_vol >> 5, cur_right_vol >> 5);
++ /* Another short delay, just to make sure the other I2C bus writes
++ * have taken...
++ */
++ wait_ms(20);
++ /* Write the global config reg - invert right power amp,
++ * DAC on, use 5-volt mode */
++ i2c_smbus_write_byte_data(daca_client, 3, 0x45);
++
++ return 0;
++}
++
++int daca_enter_sleep(void)
++{
++ if (!daca_client)
++ return -1;
++
++ i2c_smbus_write_byte_data(daca_client, 1, 8);
++ daca_set_volume(cur_left_vol >> 5, cur_right_vol >> 5);
++
++ /* Write the global config reg - invert right power amp,
++ * DAC on, enter low-power mode, use 5-volt mode
++ */
++ i2c_smbus_write_byte_data(daca_client, 3, 0x65);
++
++ return 0;
++}
++
++static int daca_attach_adapter(struct i2c_adapter *adapter)
++{
++ if (!strncmp(adapter->name, "mac-io", 6))
++ daca_detect_client(adapter, 0x4d);
++ return 0;
++}
++
++static int daca_init_client(struct i2c_client * new_client)
++{
++ /*
++ * Probe is not working with the current i2c-keywest
++ * driver. We try to use addr 0x4d on each adapters
++ * instead, by setting the format register.
++ *
++ * FIXME: I'm sure that can be obtained from the
++ * device-tree. --BenH.
++ */
++
++ /* Write the global config reg - invert right power amp,
++ * DAC on, use 5-volt mode
++ */
++ if (i2c_smbus_write_byte_data(new_client, 3, 0x45))
++ return -1;
++
++ i2c_smbus_write_byte_data(new_client, 1, 8);
++ daca_client = new_client;
++ daca_set_volume(15000, 15000);
++
++ return 0;
++}
++
++static int daca_detect_client(struct i2c_adapter *adapter, int address)
++{
++ const char *client_name = "DAC 3550A Digital Equalizer";
++ struct i2c_client *new_client;
++ struct daca_data *data;
++ int rc = -ENODEV;
++
++ new_client = kmalloc(sizeof(*new_client) + sizeof(*data), GFP_KERNEL);
++ if (!new_client)
++ return -ENOMEM;
++
++ new_client->addr = address;
++ new_client->adapter = adapter;
++ new_client->driver = &daca_driver;
++ new_client->flags = 0;
++ strcpy(new_client->name, client_name);
++ new_client->id = daca_id++; /* racy... */
++
++ data = (struct daca_data *)(new_client+1);
++ dev_set_drvdata(&new_client->dev, data);
++
++ if (daca_init_client(new_client))
++ goto bail;
++
++ /* Tell the i2c layer a new client has arrived */
++ if (i2c_attach_client(new_client))
++ goto bail;
++
++ return 0;
++ bail:
++ kfree(new_client);
++ return rc;
++}
++
++
++static int daca_detach_client(struct i2c_client *client)
++{
++ if (client == daca_client)
++ daca_client = NULL;
++
++ i2c_detach_client(client);
++ kfree(client);
++ return 0;
++}
++
++void daca_cleanup(void)
++{
++ i2c_del_driver(&daca_driver);
++}
++
++int daca_init(void)
++{
++ printk("dac3550a driver version %s (%s)\n",DACA_VERSION,DACA_DATE);
++ return i2c_add_driver(&daca_driver);
++}
+Index: linux-2.6.0-test5/sound/oss/dmasound/dmasound_awacs.c
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/dmasound/dmasound_awacs.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/sound/oss/dmasound/dmasound_awacs.c 2003-09-27 11:38:42.451074840 +0800
+@@ -45,7 +45,14 @@
+ * 01/02/2002 [0.7] - BenH
+ * - all sort of minor bits went in since the latest update, I
+ * bumped the version number for that reason
+-*/
++ *
++ * 07/26/2002 [0.8] - BenH
++ * - More minor bits since last changelog (I should be more careful
++ * with those)
++ * - Support for snapper & better tumbler integration by Toby Sargeant
++ * - Headphone detect for scremer by Julien Blache
++ * - More tumbler fixed by Andreas Schwab
++ */
+
+ /* GENERAL FIXME/TODO: check that the assumptions about what is written to
+ mac-io is valid for DACA & Tumbler.
+@@ -68,6 +75,7 @@
+ #include <linux/irq.h>
+ #include <linux/spinlock.h>
+ #include <linux/kmod.h>
++#include <linux/interrupt.h>
+ #include <asm/semaphore.h>
+ #ifdef CONFIG_ADB_CUDA
+ #include <linux/cuda.h>
+@@ -89,10 +97,14 @@
+
+ #include "awacs_defs.h"
+ #include "dmasound.h"
++#include "tas3001c.h"
++#include "tas3004.h"
++#include "tas_common.h"
+
+ #define DMASOUND_AWACS_REVISION 0
+ #define DMASOUND_AWACS_EDITION 7
+
++#define AWACS_SNAPPER 110 /* fake revision # for snapper */
+ #define AWACS_BURGUNDY 100 /* fake revision # for burgundy */
+ #define AWACS_TUMBLER 90 /* fake revision # for tumbler */
+ #define AWACS_DACA 80 /* fake revision # for daca (ibook) */
+@@ -103,11 +115,13 @@
+ */
+ static int awacs_irq, awacs_tx_irq, awacs_rx_irq;
+ static volatile struct awacs_regs *awacs;
++static volatile u32 *i2s;
+ static volatile struct dbdma_regs *awacs_txdma, *awacs_rxdma;
+ static int awacs_rate_index;
+ static int awacs_subframe;
+ static int awacs_spkr_vol;
+ static struct device_node* awacs_node;
++static struct device_node* i2s_node;
+
+ static char awacs_name[64];
+ static int awacs_revision;
+@@ -164,6 +178,8 @@
+ static int cd_lev = 0x6363 ; /* 99 % */
+ static int line_lev;
+
++static int hdp_connected;
++
+ /*
+ * Stuff for outputting a beep. The values range from -327 to +327
+ * so we can multiply by an amplitude in the range 0..100 to get a
+@@ -215,7 +231,6 @@
+ static short *beep_buf;
+ static void *beep_dbdma_cmd_space;
+ static volatile struct dbdma_cmd *beep_dbdma_cmd;
+-static void (*orig_mksound)(unsigned int, unsigned int);
+
+ /* Burgundy functions */
+ static void awacs_burgundy_wcw(unsigned addr,unsigned newval);
+@@ -286,25 +301,12 @@
+ extern TRANS transAwacsNormalRead ;
+
+ extern int daca_init(void);
+-extern int daca_cleanup(void);
++extern void daca_cleanup(void);
+ extern int daca_set_volume(uint left_vol, uint right_vol);
+ extern void daca_get_volume(uint * left_vol, uint *right_vol);
+ extern int daca_enter_sleep(void);
+ extern int daca_leave_sleep(void);
+
+-extern int tas_init(void);
+-extern int tas_cleanup(void);
+-extern int tumbler_set_volume(uint left_vol, uint right_vol);
+-extern void tumbler_get_volume(uint * left_vol, uint *right_vol);
+-extern void tumbler_set_treble(int treble);
+-extern void tumbler_get_treble(int *treble);
+-extern void tumbler_set_bass(int bass);
+-extern void tumbler_get_bass(int *bass);
+-extern void tumbler_set_pcm_lvl(int pcm_lvl);
+-extern void tumbler_get_pcm_lvl(int *pcm_lvl);
+-extern int tumbler_enter_sleep(void);
+-extern int tumbler_leave_sleep(void);
+-
+ #define TRY_LOCK() \
+ if ((rc = down_interruptible(&dmasound_sem)) != 0) \
+ return rc;
+@@ -331,7 +333,7 @@
+ }
+
+
+-/*** AE - TUMBLER START *********************************************************/
++/*** AE - TUMBLER / SNAPPER START ************************************************/
+
+
+ int gpio_audio_reset, gpio_audio_reset_pol;
+@@ -393,31 +395,35 @@
+ return ((pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, gpio_addr, 0) & 0x02) !=0);
+ }
+
++/*
++ * Headphone interrupt via GPIO (Tumbler, Snapper, DACA)
++ */
+ static irqreturn_t
+ headphone_intr(int irq, void *devid, struct pt_regs *regs)
+ {
+- int handled = 0;
+- spin_lock(&dmasound.lock);
++ unsigned long flags;
++
++ spin_lock_irqsave(&dmasound.lock, flags);
+ if (read_audio_gpio(gpio_headphone_detect) == gpio_headphone_detect_pol) {
+- handled = 1;
+ printk(KERN_INFO "Audio jack plugged, muting speakers.\n");
+- write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol);
+ write_audio_gpio(gpio_headphone_mute, !gpio_headphone_mute_pol);
++ write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol);
++ tas_output_device_change(sound_device_id,TAS_OUTPUT_HEADPHONES,0);
+ } else {
+- handled = 1;
+ printk(KERN_INFO "Audio jack unplugged, enabling speakers.\n");
+ write_audio_gpio(gpio_amp_mute, !gpio_amp_mute_pol);
+ write_audio_gpio(gpio_headphone_mute, gpio_headphone_mute_pol);
++ tas_output_device_change(sound_device_id,TAS_OUTPUT_INTERNAL_SPKR,0);
+ }
+- spin_unlock(&dmasound.lock);
+- return IRQ_RETVAL(handled);
++ spin_unlock_irqrestore(&dmasound.lock, flags);
++ return IRQ_HANDLED;
+ }
+
+
+ /* Initialize tumbler */
+
+ static int
+-awacs_tumbler_init(void)
++tas_dmasound_init(void)
+ {
+ setup_audio_gpio(
+ "audio-hw-reset",
+@@ -474,15 +480,124 @@
+
+
+ static int
+-awacs_tumbler_cleanup(void)
++tas_dmasound_cleanup(void)
+ {
+ if (gpio_headphone_irq)
+ free_irq(gpio_headphone_irq, 0);
+ return 0;
+ }
+
++/* We don't support 48k yet */
++static int tas_freqs[1] = { 44100 } ;
++static int tas_freqs_ok[1] = { 1 } ;
++
++/* don't know what to do really - just have to leave it where
++ * OF left things
++*/
++
++static int
++tas_set_frame_rate(void)
++{
++ if (i2s) {
++ out_le32(i2s + (I2S_REG_SERIAL_FORMAT >> 2), 0x41190000);
++ out_le32(i2s + (I2S_REG_DATAWORD_SIZES >> 2), 0x02000200);
++ }
++ dmasound.hard.speed = 44100 ;
++ awacs_rate_index = 0 ;
++ return 44100 ;
++}
++
++static int
++tas_mixer_ioctl(u_int cmd, u_long arg)
++{
++ int data;
++ int rc;
++
++ rc=tas_device_ioctl(cmd, arg);
++ if (rc != -EINVAL) {
++ return rc;
++ }
++
++ if ((cmd & ~0xff) == MIXER_WRITE(0) &&
++ tas_supported_mixers() & (1<<(cmd & 0xff))) {
++ rc = get_user(data, (int *)(arg));
++ if (rc<0) return rc;
++ tas_set_mixer_level(cmd & 0xff, data);
++ tas_get_mixer_level(cmd & 0xff, &data);
++ return ioctl_return2((int *)(arg), data);
++ }
++ if ((cmd & ~0xff) == MIXER_READ(0) &&
++ tas_supported_mixers() & (1<<(cmd & 0xff))) {
++ tas_get_mixer_level(cmd & 0xff, &data);
++ return ioctl_return2((int *)(arg), data);
++ }
++
++ switch(cmd) {
++ case SOUND_MIXER_READ_DEVMASK:
++ data = tas_supported_mixers() | SOUND_MASK_SPEAKER;
++ rc = IOCTL_OUT(arg, data);
++ break;
++ case SOUND_MIXER_READ_STEREODEVS:
++ data = tas_stereo_mixers();
++ rc = IOCTL_OUT(arg, data);
++ break;
++ case SOUND_MIXER_READ_CAPS:
++ rc = IOCTL_OUT(arg, 0);
++ break;
++ case SOUND_MIXER_READ_RECMASK:
++ data = 0;
++ rc = IOCTL_OUT(arg, data);
++ break;
++ case SOUND_MIXER_READ_RECSRC:
++ data = 0;
++ rc = IOCTL_OUT(arg, data);
++ break;
++ case SOUND_MIXER_WRITE_RECSRC:
++ IOCTL_IN(arg, data);
++ data =0;
++ rc = IOCTL_OUT(arg, data);
++ break;
++ case SOUND_MIXER_WRITE_SPEAKER: /* really bell volume */
++ IOCTL_IN(arg, data);
++ beep_vol = data & 0xff;
++ /* fall through */
++ case SOUND_MIXER_READ_SPEAKER:
++ rc = IOCTL_OUT(arg, (beep_vol<<8) | beep_vol);
++ break;
++ case SOUND_MIXER_OUTMASK:
++ case SOUND_MIXER_OUTSRC:
++ default:
++ rc = -EINVAL;
++ }
++
++ return rc;
++}
++
++static void __init
++tas_init_frame_rates(unsigned int *prop, unsigned int l)
++{
++ int i ;
++ if (prop) {
++ for (i=0; i<1; i++)
++ tas_freqs_ok[i] = 0;
++ for (l /= sizeof(int); l > 0; --l) {
++ unsigned int r = *prop++;
++ /* Apple 'Fixed' format */
++ if (r >= 0x10000)
++ r >>= 16;
++ for (i = 0; i < 1; ++i) {
++ if (r == tas_freqs[i]) {
++ tas_freqs_ok[i] = 1;
++ break;
++ }
++ }
++ }
++ }
++ /* else we assume that all the rates are available */
++}
++
+
+-/*** AE - TUMBLER END *********************************************************/
++/*** AE - TUMBLER / SNAPPER END ************************************************/
+
+
+
+@@ -503,8 +618,10 @@
+
+ static int __init PMacIrqInit(void)
+ {
+- if (request_irq(awacs_irq, pmac_awacs_intr, 0, "Built-in Sound misc", 0)
+- || request_irq(awacs_tx_irq, pmac_awacs_tx_intr, 0, "Built-in Sound out", 0)
++ if (awacs)
++ if (request_irq(awacs_irq, pmac_awacs_intr, 0, "Built-in Sound misc", 0))
++ return 0;
++ if (request_irq(awacs_tx_irq, pmac_awacs_tx_intr, 0, "Built-in Sound out", 0)
+ || request_irq(awacs_rx_irq, pmac_awacs_rx_intr, 0, "Built-in Sound in", 0))
+ return 0;
+ return 1;
+@@ -517,23 +634,28 @@
+ DBDMA_DO_STOP(awacs_txdma);
+ DBDMA_DO_STOP(awacs_rxdma);
+
+- /* disable interrupts from awacs interface */
+- out_le32(&awacs->control, in_le32(&awacs->control) & 0xfff);
+-
++ if (awacs)
++ /* disable interrupts from awacs interface */
++ out_le32(&awacs->control, in_le32(&awacs->control) & 0xfff);
++
+ /* Switch off the sound clock */
+ pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, awacs_node, 0, 0);
+ /* Make sure proper bits are set on pismo & tipb */
+- if (machine_is_compatible("PowerBook3,1") ||
+- machine_is_compatible("PowerBook3,2")) {
++ if ((machine_is_compatible("PowerBook3,1") ||
++ machine_is_compatible("PowerBook3,2")) && awacs) {
+ awacs_reg[1] |= MASK_PAROUT0 | MASK_PAROUT1;
+ awacs_write(MASK_ADDR1 | awacs_reg[1]);
+ wait_ms(200);
+ }
+- free_irq(awacs_irq, 0);
++ if (awacs)
++ free_irq(awacs_irq, 0);
+ free_irq(awacs_tx_irq, 0);
+ free_irq(awacs_rx_irq, 0);
+- /* all OF versions I've seen use this value */
+- iounmap((void *)awacs);
++
++ if (awacs)
++ iounmap((void *)awacs);
++ if (i2s)
++ iounmap((void *)i2s);
+ iounmap((void *)awacs_txdma);
+ iounmap((void *)awacs_rxdma);
+
+@@ -547,10 +669,8 @@
+ kfree(awacs_rx_cmd_space);
+ if (beep_dbdma_cmd_space)
+ kfree(beep_dbdma_cmd_space);
+- if (beep_buf) {
++ if (beep_buf)
+ kfree(beep_buf);
+- kd_mksound = orig_mksound;
+- }
+ #ifdef CONFIG_PMAC_PBOOK
+ pmu_unregister_sleep_notifier(&awacs_sleep_notifier);
+ #endif
+@@ -563,26 +683,16 @@
+ DBDMA_DO_STOP(awacs_txdma);
+ }
+
+-static int tumbler_freqs[2] = { 48000, 44100 } ;
+-static int tumbler_freqs_ok[2] = { 1, 1 } ;
+-
+-/* don't know what to do really - just have to leave it where
+- * OF left things
+-*/
+-
+-static int tumbler_set_frame_rate(void)
+-{
+- dmasound.hard.speed = 44100 ;
+- awacs_rate_index = 0 ;
+- return 44100 ;
+-}
+-
+ /* don't know what to do really - just have to leave it where
+ * OF left things
+ */
+
+ static int daca_set_frame_rate(void)
+ {
++ if (i2s) {
++ out_le32(i2s + (I2S_REG_SERIAL_FORMAT >> 2), 0x41190000);
++ out_le32(i2s + (I2S_REG_DATAWORD_SIZES >> 2), 0x02000200);
++ }
+ dmasound.hard.speed = 44100 ;
+ awacs_rate_index = 0 ;
+ return 44100 ;
+@@ -593,7 +703,8 @@
+ };
+ static int awacs_freqs_ok[8] = { 1, 1, 1, 1, 1, 1, 1, 1 };
+
+-static int awacs_set_frame_rate(int desired, int catch_r)
++static int
++awacs_set_frame_rate(int desired, int catch_r)
+ {
+ int tolerance, i = 8 ;
+ /*
+@@ -617,13 +728,9 @@
+ return dmasound.hard.speed;
+ }
+
+-static int burgundy_frame_rates = 1 ;
+-static int burgundy_set_frame_rate(void)
++static int
++burgundy_set_frame_rate(void)
+ {
+-#ifdef DEBUG_DMASOUND
+-if (burgundy_frame_rates > 1)
+- printk("dmasound_pmac: warning Burgundy had more than one frame rate\n");
+-#endif
+ awacs_rate_index = 0 ;
+ awacs_reg[1] = (awacs_reg[1] & ~MASK_SAMPLERATE) ;
+ /* XXX disable error interrupt on burgundy for now */
+@@ -631,24 +738,24 @@
+ return 44100 ;
+ }
+
+-static int set_frame_rate(int desired, int catch_r)
++static int
++set_frame_rate(int desired, int catch_r)
+ {
+ switch (awacs_revision) {
+ case AWACS_BURGUNDY:
+- dmasound.hard.speed =
+- burgundy_set_frame_rate();
++ dmasound.hard.speed = burgundy_set_frame_rate();
+ break ;
+ case AWACS_TUMBLER:
+- dmasound.hard.speed =
+- tumbler_set_frame_rate();
++ case AWACS_SNAPPER:
++ dmasound.hard.speed = tas_set_frame_rate();
+ break ;
+ case AWACS_DACA:
+ dmasound.hard.speed =
+ daca_set_frame_rate();
+ break ;
+ default:
+- dmasound.hard.speed =
+- awacs_set_frame_rate(desired, catch_r);
++ dmasound.hard.speed = awacs_set_frame_rate(desired,
++ catch_r);
+ break ;
+ }
+ return dmasound.hard.speed ;
+@@ -698,11 +805,13 @@
+ dmasound.trans_write = &transAwacsExpand;
+ dmasound.trans_read = &transAwacsNormalRead;
+
+- if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE))
+- out_le32(&awacs->byteswap, BS_VAL);
+- else
+- out_le32(&awacs->byteswap, 0);
+-
++ if (awacs) {
++ if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE))
++ out_le32(&awacs->byteswap, BS_VAL);
++ else
++ out_le32(&awacs->byteswap, 0);
++ }
++
+ expand_bal = -dmasound.soft.speed;
+ }
+
+@@ -787,18 +896,28 @@
+
+ static int PMacSetVolume(int volume)
+ {
+- return awacs_volume_setter(volume, 2, MASK_AMUTE, 6);
++ printk(KERN_WARNING "Bogus call to PMacSetVolume !\n");
++ return 0;
++}
++
++static void awacs_setup_for_beep(int speed)
++{
++ out_le32(&awacs->control,
++ (in_le32(&awacs->control) & ~0x1f00)
++ | ((speed > 0 ? speed : awacs_rate_index) << 8));
++
++ if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE) && speed == -1)
++ out_le32(&awacs->byteswap, BS_VAL);
++ else
++ out_le32(&awacs->byteswap, 0);
+ }
+
++/* CHECK: how much of this *really* needs IRQs masked? */
+ static void __PMacPlay(void)
+ {
+ volatile struct dbdma_cmd *cp;
+ int next_frg, count;
+- unsigned long flags;
+-
+- /* CHECK: how much of this *really* needs IRQs masked? */
+
+- spin_lock_irqsave(&dmasound.lock, flags);
+ count = 300 ; /* > two cycles at the lowest sample rate */
+
+ /* what we want to send next */
+@@ -810,15 +929,8 @@
+ out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
+ while ( (in_le32(&awacs_txdma->status) & RUN) && count--)
+ udelay(1);
+- /* FIXME: check that this is OK for other chip sets */
+- out_le32(&awacs->control,
+- (in_le32(&awacs->control) & ~0x1f00)
+- | (awacs_rate_index << 8));
+-
+- if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE))
+- out_le32(&awacs->byteswap, BS_VAL);
+- else
+- out_le32(&awacs->byteswap, 0);
++ if (awacs)
++ awacs_setup_for_beep(-1);
+ out_le32(&awacs_txdma->cmdptr,
+ virt_to_bus(&(awacs_tx_cmds[next_frg])));
+
+@@ -865,14 +977,18 @@
+ out_le32(&awacs_txdma->control, ((RUN|WAKE) << 16) + (RUN|WAKE));
+ ++write_sq.active;
+ }
+- spin_unlock_irqrestore(&dmasound.lock, flags);
+ }
+
+ static void PMacPlay(void)
+ {
+ LOCK();
+- if (!awacs_sleeping)
++ if (!awacs_sleeping) {
++ unsigned long flags;
++
++ spin_lock_irqsave(&dmasound.lock, flags);
+ __PMacPlay();
++ spin_unlock_irqrestore(&dmasound.lock, flags);
++ }
+ UNLOCK();
+ }
+
+@@ -919,6 +1035,7 @@
+ {
+ int i = write_sq.front;
+ int stat;
++ int i_nowrap = write_sq.front;
+ volatile struct dbdma_cmd *cp;
+ /* != 0 when we are dealing with a DEAD xfer */
+ static int emergency_in_use;
+@@ -976,6 +1093,7 @@
+ emergency_in_use = 0 ; /* done that */
+ --write_sq.count;
+ --write_sq.active;
++ i_nowrap++;
+ if (++i >= write_sq.max_count)
+ i = 0;
+ }
+@@ -988,7 +1106,7 @@
+ }
+
+ /* if we used some data up then wake the writer to supply some more*/
+- if (i != write_sq.front)
++ if (i_nowrap != write_sq.front)
+ WAKE_UP(write_sq.action_queue);
+ write_sq.front = i;
+
+@@ -1091,11 +1209,30 @@
+ pmac_awacs_intr(int irq, void *devid, struct pt_regs *regs)
+ {
+ int ctrl;
++ int status;
++ int r1;
++
+ spin_lock(&dmasound.lock);
+ ctrl = in_le32(&awacs->control);
++ status = in_le32(&awacs->codec_stat);
+
+ if (ctrl & MASK_PORTCHG) {
+- /* do something when headphone is plugged/unplugged? */
++ /* tested on Screamer, should work on others too */
++ if (awacs_revision == AWACS_SCREAMER) {
++ if (((status & MASK_HDPCONN) >> 3) && (hdp_connected == 0)) {
++ hdp_connected = 1;
++
++ r1 = awacs_reg[1] | MASK_SPKMUTE;
++ awacs_reg[1] = r1;
++ awacs_write(r1 | MASK_ADDR_MUTE);
++ } else if (((status & MASK_HDPCONN) >> 3 == 0) && (hdp_connected == 1)) {
++ hdp_connected = 0;
++
++ r1 = awacs_reg[1] & ~MASK_SPKMUTE;
++ awacs_reg[1] = r1;
++ awacs_write(r1 | MASK_ADDR_MUTE);
++ }
++ }
+ }
+ if (ctrl & MASK_CNTLERR) {
+ int err = (in_le32(&awacs->codec_stat) & MASK_ERRCODE) >> 16;
+@@ -1113,7 +1250,7 @@
+ awacs_write(int val)
+ {
+ int count = 300 ;
+- if (awacs_revision >= AWACS_DACA)
++ if (awacs_revision >= AWACS_DACA || !awacs)
+ return ;
+
+ while ((in_le32(&awacs->codec_ctrl) & MASK_NEWECMD) && count--)
+@@ -1136,22 +1273,16 @@
+ out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
+ while ((in_le32(&awacs_txdma->status) & RUN) && count--)
+ udelay(1);
+- /* FIXME: check this is OK for DACA, Tumbler */
+- out_le32(&awacs->control,
+- (in_le32(&awacs->control) & ~0x1f00)
+- | (awacs_rate_index << 8));
+- if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE))
+- out_le32(&awacs->byteswap, BS_VAL);
+- else
+- out_le32(&awacs->byteswap, 0);
++ if (awacs)
++ awacs_setup_for_beep(-1);
+ beep_playing = 0;
+ }
+ spin_unlock_irqrestore(&dmasound.lock, flags);
+ }
+
+ static struct timer_list beep_timer = TIMER_INITIALIZER(awacs_nosound, 0, 0);
+-};
+
++#if 0 /* would need to go through the input layer in 2.6, later.. --hch */
+ /* we generate the beep with a single dbdma command that loops a buffer
+ forever - without generating interrupts.
+ So, to stop it you have to stop dma output as per awacs_nosound.
+@@ -1237,17 +1368,15 @@
+ out_le32(&awacs_txdma->control, (RUN|WAKE|FLUSH|PAUSE) << 16);
+ while ((in_le32(&awacs_txdma->status) & RUN) && count--)
+ udelay(1); /* timeout > 2 samples at lowest rate*/
+- /* FIXME: check this is OK on DACA, Tumbler */
+- out_le32(&awacs->control,
+- (in_le32(&awacs->control) & ~0x1f00)
+- | (beep_speed << 8));
+- out_le32(&awacs->byteswap, 0); /* force BE */
++ if (awacs)
++ awacs_setup_for_beep(beep_speed);
+ out_le32(&awacs_txdma->cmdptr, virt_to_bus(beep_dbdma_cmd));
+ (void)in_le32(&awacs_txdma->status);
+ out_le32(&awacs_txdma->control, RUN | (RUN << 16));
+ }
+ spin_unlock_irqrestore(&dmasound.lock, flags);
+ }
++#endif
+
+ /* used in init and for wake-up */
+
+@@ -1267,10 +1396,12 @@
+ awacs_write(awacs_reg[1] + MASK_ADDR1);
+ awacs_write(awacs_reg[7] + MASK_ADDR7);
+ }
+- if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE))
+- out_le32(&awacs->byteswap, BS_VAL);
+- else
+- out_le32(&awacs->byteswap, 0);
++ if (awacs) {
++ if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE))
++ out_le32(&awacs->byteswap, BS_VAL);
++ else
++ out_le32(&awacs->byteswap, 0);
++ }
+ }
+
+ #ifdef CONFIG_PMAC_PBOOK
+@@ -1280,6 +1411,8 @@
+ /* FIXME: sort out disabling/re-enabling of read stuff as well */
+ static int awacs_sleep_notify(struct pmu_sleep_notifier *self, int when)
+ {
++ unsigned long flags;
++
+ switch (when) {
+ case PBOOK_SLEEP_NOW:
+ LOCK();
+@@ -1297,9 +1430,18 @@
+ /* stop rx - if going - a bit of a daft user... but */
+ out_le32(&awacs_rxdma->control, (RUN|WAKE|FLUSH << 16));
+ /* deny interrupts */
++ if (awacs)
++ disable_irq(awacs_irq);
++ disable_irq(awacs_tx_irq);
++ disable_irq(awacs_rx_irq);
++ /* Chip specific sleep code */
+ switch (awacs_revision) {
+ case AWACS_TUMBLER:
+- tumbler_enter_sleep(); /* Stub for now */
++ case AWACS_SNAPPER:
++ write_audio_gpio(gpio_headphone_mute, gpio_headphone_mute_pol);
++ write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol);
++ tas_enter_sleep();
++ write_audio_gpio(gpio_audio_reset, gpio_audio_reset_pol);
+ break ;
+ case AWACS_DACA:
+ daca_enter_sleep();
+@@ -1312,17 +1454,14 @@
+ out_le32(&awacs->control, 0x11) ;
+ break ;
+ }
+- disable_irq(awacs_irq);
+- disable_irq(awacs_tx_irq);
+- disable_irq(awacs_rx_irq);
+ /* Disable sound clock */
+ pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, awacs_node, 0, 0);
+ /* According to Darwin, we do that after turning off the sound
+ * chip clock. All this will have to be cleaned up once we properly
+ * parse the OF sound-objects
+ */
+- if (machine_is_compatible("PowerBook3,1") ||
+- machine_is_compatible("PowerBook3,2")) {
++ if ((machine_is_compatible("PowerBook3,1") ||
++ machine_is_compatible("PowerBook3,2")) && awacs) {
+ awacs_reg[1] |= MASK_PAROUT0 | MASK_PAROUT1;
+ awacs_write(MASK_ADDR1 | awacs_reg[1]);
+ wait_ms(200);
+@@ -1331,8 +1470,8 @@
+ case PBOOK_WAKE:
+ /* Enable sound clock */
+ pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, awacs_node, 0, 1);
+- if (machine_is_compatible("PowerBook3,1") ||
+- machine_is_compatible("PowerBook3,2")) {
++ if ((machine_is_compatible("PowerBook3,1") ||
++ machine_is_compatible("PowerBook3,2")) && awacs) {
+ wait_ms(100);
+ awacs_reg[1] &= ~(MASK_PAROUT0 | MASK_PAROUT1);
+ awacs_write(MASK_ADDR1 | awacs_reg[1]);
+@@ -1342,13 +1481,20 @@
+ /* restore settings */
+ switch (awacs_revision) {
+ case AWACS_TUMBLER:
++ case AWACS_SNAPPER:
++ write_audio_gpio(gpio_headphone_mute, gpio_headphone_mute_pol);
++ write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol);
++ write_audio_gpio(gpio_audio_reset, gpio_audio_reset_pol);
++ wait_ms(100);
++ write_audio_gpio(gpio_audio_reset, !gpio_audio_reset_pol);
++ wait_ms(150);
++ tas_leave_sleep(); /* Stub for now */
+ headphone_intr(0,0,0);
+- tumbler_leave_sleep(); /* Stub for now */
+ break;
+ case AWACS_DACA:
+ wait_ms(10); /* Check this !!! */
+ daca_leave_sleep();
+- break ; /* don't know how yet */
++ break ; /* dont know how yet */
+ case AWACS_BURGUNDY:
+ break ;
+ case AWACS_SCREAMER:
+@@ -1358,17 +1504,20 @@
+ break ;
+ }
+ /* Recalibrate chip */
+- if (awacs_revision == AWACS_SCREAMER)
++ if (awacs_revision == AWACS_SCREAMER && awacs)
+ awacs_recalibrate();
+ /* Make sure dma is stopped */
+ PMacSilence();
+- enable_irq(awacs_irq);
++ if (awacs)
++ enable_irq(awacs_irq);
+ enable_irq(awacs_tx_irq);
+ enable_irq(awacs_rx_irq);
+- /* OK, allow ints back again */
+- out_le32(&awacs->control, MASK_IEPC
+- | (awacs_rate_index << 8) | 0x11
+- | (awacs_revision < AWACS_DACA ? MASK_IEE: 0));
++ if (awacs) {
++ /* OK, allow ints back again */
++ out_le32(&awacs->control, MASK_IEPC
++ | (awacs_rate_index << 8) | 0x11
++ | (awacs_revision < AWACS_DACA ? MASK_IEE: 0));
++ }
+ if (macio_base && is_pbook_g3) {
+ /* FIXME: should restore the setup we had...*/
+ out_8(macio_base + 0x37, 3);
+@@ -1384,7 +1533,9 @@
+ awacs_sleeping = 0;
+ /* Resume pending sounds. */
+ /* we don't try to restart input... */
++ spin_lock_irqsave(&dmasound.lock, flags);
+ __PMacPlay();
++ spin_unlock_irqrestore(&dmasound.lock, flags);
+ UNLOCK();
+ }
+ return PBOOK_SLEEP_OK;
+@@ -1956,7 +2107,7 @@
+ case SOUND_MIXER_READ_SPEAKER:
+ data = awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_ATTENSPEAKER);
+ data = (((data & 0xf)*100)/16) + ((((data>>4)*100)/16)<<8);
+- rc = IOCTL_OUT(arg, ~data);
++ rc = IOCTL_OUT(arg, (~data) & 0x0000ffff);
+ break;
+ case SOUND_MIXER_WRITE_ALTPCM: /* really bell volume */
+ IOCTL_IN(arg, data);
+@@ -2011,89 +2162,6 @@
+ return rc;
+ }
+
+-static int tumbler_mixer_ioctl(u_int cmd, u_long arg)
+-{
+- int data;
+- int rc;
+-
+- /* We are, we are, we are... Tumbler (and very dumb) */
+- /* Ok, we're not THAT dumb anymore, but still pretty dumb :-) */
+-
+- switch(cmd) {
+- case SOUND_MIXER_READ_DEVMASK:
+- data = SOUND_MASK_VOLUME | SOUND_MASK_ALTPCM |
+- SOUND_MASK_BASS | SOUND_MASK_TREBLE |
+- SOUND_MASK_PCM;
+- rc = IOCTL_OUT(arg, data);
+- break;
+- case SOUND_MIXER_READ_RECMASK:
+- data = 0;
+- rc = IOCTL_OUT(arg, data);
+- break;
+- case SOUND_MIXER_READ_RECSRC:
+- data = 0;
+- rc = IOCTL_OUT(arg, data);
+- break;
+- case SOUND_MIXER_WRITE_RECSRC:
+- IOCTL_IN(arg, data);
+- data =0;
+- rc = IOCTL_OUT(arg, data);
+- break;
+- case SOUND_MIXER_READ_STEREODEVS:
+- data = SOUND_MASK_VOLUME | SOUND_MASK_PCM;
+- rc = IOCTL_OUT(arg, data);
+- break;
+- case SOUND_MIXER_READ_CAPS:
+- rc = IOCTL_OUT(arg, 0);
+- break;
+- case SOUND_MIXER_WRITE_BASS:
+- IOCTL_IN(arg, data);
+- tumbler_set_bass(data);
+- /* Fall through */
+- case SOUND_MIXER_READ_BASS:
+- tumbler_get_bass(&data);
+- rc = IOCTL_OUT(arg, data);
+- break;
+- case SOUND_MIXER_WRITE_TREBLE:
+- IOCTL_IN(arg, data);
+- tumbler_set_treble(data);
+- /* Fall through */
+- case SOUND_MIXER_READ_TREBLE:
+- tumbler_get_treble(&data);
+- rc = IOCTL_OUT(arg, data);
+- break;
+- case SOUND_MIXER_WRITE_PCM:
+- IOCTL_IN(arg, data);
+- tumbler_set_pcm_lvl(data);
+- /* Fall through */
+- case SOUND_MIXER_READ_PCM:
+- tumbler_get_pcm_lvl(&data);
+- IOCTL_OUT(arg, data);
+- break;
+- case SOUND_MIXER_WRITE_VOLUME:
+- IOCTL_IN(arg, data);
+- tumbler_set_volume(data, data);
+- /* Fall through */
+- case SOUND_MIXER_READ_VOLUME:
+- tumbler_get_volume(& data, &data);
+- rc = IOCTL_OUT(arg, data);
+- break;
+- case SOUND_MIXER_WRITE_ALTPCM: /* really bell volume */
+- IOCTL_IN(arg, data);
+- beep_vol = data & 0xff;
+- /* fall through */
+- case SOUND_MIXER_READ_ALTPCM:
+- rc = IOCTL_OUT(arg, beep_vol);
+- break;
+- case SOUND_MIXER_OUTMASK:
+- case SOUND_MIXER_OUTSRC:
+- default:
+- rc = -EINVAL;
+- }
+-
+- return rc;
+-}
+-
+ static int daca_mixer_ioctl(u_int cmd, u_long arg)
+ {
+ int data;
+@@ -2158,7 +2226,8 @@
+ rc = daca_mixer_ioctl(cmd, arg);
+ break;
+ case AWACS_TUMBLER:
+- rc = tumbler_mixer_ioctl(cmd, arg);
++ case AWACS_SNAPPER:
++ rc = tas_mixer_ioctl(cmd, arg);
+ break ;
+ default: /* ;-)) */
+ rc = awacs_mixer_ioctl(cmd, arg);
+@@ -2175,7 +2244,9 @@
+ case AWACS_TUMBLER:
+ printk("AE-Init tumbler mixer\n");
+ break ;
+-
++ case AWACS_SNAPPER:
++ printk("AE-Init snapper mixer\n");
++ break ;
+ case AWACS_DACA:
+ case AWACS_BURGUNDY:
+ break ; /* don't know yet */
+@@ -2366,12 +2437,12 @@
+ len += sprintf(b,"44100 ") ;
+ break ;
+ case AWACS_TUMBLER:
+- for (i=0; i<2; i++){
+- if (tumbler_freqs_ok[i])
+- len += sprintf(b+len,"%d ", tumbler_freqs[i]) ;
++ case AWACS_SNAPPER:
++ for (i=0; i<1; i++){
++ if (tas_freqs_ok[i])
++ len += sprintf(b+len,"%d ", tas_freqs[i]) ;
+ }
+ break ;
+-
+ case AWACS_AWACS:
+ case AWACS_SCREAMER:
+ default:
+@@ -2472,8 +2543,8 @@
+ code that looks for chip properties knows how to go about it.
+ */
+
+-static struct device_node
+-__init *get_snd_io_node(void)
++static struct device_node* __init
++get_snd_io_node(void)
+ {
+ struct device_node *np = NULL;
+
+@@ -2494,7 +2565,7 @@
+ * this seems to be what iBooks (& Tumbler) have.
+ */
+ if (np == NULL)
+- np = find_devices("i2s-a");
++ np = i2s_node = find_devices("i2s-a");
+
+ /* if we didn't find this - perhaps we are on an early model
+ * which _only_ has an 'awacs' node
+@@ -2514,23 +2585,22 @@
+ we have to deduce the info other ways for these.
+ */
+
+-static struct device_node
+-__init *get_snd_info_node(struct device_node *io)
++static struct device_node* __init
++get_snd_info_node(struct device_node *io)
+ {
+ struct device_node *info;
+
+ info = find_devices("sound");
+- while (info != 0 && info->parent != io)
++ while (info && info->parent != io)
+ info = info->next;
+-
+- return info ;
++ return info;
+ }
+
+ /* Find out what type of codec we have.
+ */
+
+-static int
+-__init get_codec_type(struct device_node *info)
++static int __init
++get_codec_type(struct device_node *info)
+ {
+ /* already set if pre-davbus model and info will be NULL */
+ int codec = awacs_revision ;
+@@ -2547,14 +2617,16 @@
+ codec = AWACS_DACA;
+ if (device_is_compatible(info, "tumbler"))
+ codec = AWACS_TUMBLER;
++ if (device_is_compatible(info, "snapper"))
++ codec = AWACS_SNAPPER;
+ }
+ return codec ;
+ }
+
+ /* find out what type, if any, of expansion card we have
+ */
+-static void
+-__init get_expansion_type(void)
++static void __init
++get_expansion_type(void)
+ {
+ if (find_devices("perch") != NULL)
+ has_perch = 1;
+@@ -2572,8 +2644,8 @@
+ * Set dmasound.mach.max_dsp_rate on the basis of these routines.
+ */
+
+-static void
+-__init init_awacs_frame_rates(unsigned int *prop, unsigned int l)
++static void __init
++awacs_init_frame_rates(unsigned int *prop, unsigned int l)
+ {
+ int i ;
+ if (prop) {
+@@ -2595,31 +2667,8 @@
+ /* else we assume that all the rates are available */
+ }
+
+-static void
+-__init init_tumbler_frame_rates(unsigned int *prop, unsigned int l)
+-{
+- int i ;
+- if (prop) {
+- for (i=0; i<2; i++)
+- tumbler_freqs_ok[i] = 0;
+- for (l /= sizeof(int); l > 0; --l) {
+- unsigned int r = *prop++;
+- /* Apple 'Fixed' format */
+- if (r >= 0x10000)
+- r >>= 16;
+- for (i = 0; i < 2; ++i) {
+- if (r == tumbler_freqs[i]) {
+- tumbler_freqs_ok[i] = 1;
+- break;
+- }
+- }
+- }
+- }
+- /* else we assume that all the rates are available */
+-}
+-
+-static void
+-__init init_burgundy_frame_rates(unsigned int *prop, unsigned int l)
++static void __init
++burgundy_init_frame_rates(unsigned int *prop, unsigned int l)
+ {
+ int temp[9] ;
+ int i = 0 ;
+@@ -2644,8 +2693,8 @@
+ #endif
+ }
+
+-static void
+-__init init_daca_frame_rates(unsigned int *prop, unsigned int l)
++static void __init
++daca_init_frame_rates(unsigned int *prop, unsigned int l)
+ {
+ int temp[9] ;
+ int i = 0 ;
+@@ -2671,21 +2720,22 @@
+ #endif
+ }
+
+-static void
+-__init init_frame_rates(unsigned int *prop, unsigned int l)
++static void __init
++init_frame_rates(unsigned int *prop, unsigned int l)
+ {
+- switch (awacs_revision){
++ switch (awacs_revision) {
+ case AWACS_TUMBLER:
+- init_tumbler_frame_rates(prop, l);
++ case AWACS_SNAPPER:
++ tas_init_frame_rates(prop, l);
+ break ;
+ case AWACS_DACA:
+- init_daca_frame_rates(prop, l);
++ daca_init_frame_rates(prop, l);
+ break ;
+ case AWACS_BURGUNDY:
+- init_burgundy_frame_rates(prop, l);
++ burgundy_init_frame_rates(prop, l);
+ break ;
+- default: /* ;-))) */
+- init_awacs_frame_rates(prop, l);
++ default:
++ awacs_init_frame_rates(prop, l);
+ break ;
+ }
+ }
+@@ -2693,11 +2743,11 @@
+ /* find things/machines that can't do mac-io byteswap
+ */
+
+-static void
+-__init set_hw_byteswap(struct device_node *io)
++static void __init
++set_hw_byteswap(struct device_node *io)
+ {
+ struct device_node *mio ;
+- unsigned int *p, kl = 0 ;
++ unsigned int kl = 0 ;
+
+ /* if seems that Keylargo can't byte-swap */
+
+@@ -2744,9 +2794,6 @@
+ if( beep_dbdma_cmd_space ) kfree(beep_dbdma_cmd_space) ;
+ return -ENOMEM ;
+ }
+- /* OK, we should be safe to claim the mksound vector now */
+- orig_mksound = kd_mksound;
+- kd_mksound = awacs_mksound;
+ return 0 ;
+ }
+
+@@ -2842,23 +2889,26 @@
+ }
+
+ /* all OF versions I've seen use this value */
+- awacs = (volatile struct awacs_regs *)
+- ioremap(io->addrs[0].address, 0x1000);
++ if (i2s_node)
++ i2s = (u32 *)ioremap(io->addrs[0].address, 0x1000);
++ else
++ awacs = (volatile struct awacs_regs *)
++ ioremap(io->addrs[0].address, 0x1000);
+ awacs_txdma = (volatile struct dbdma_regs *)
+ ioremap(io->addrs[1].address, 0x100);
+ awacs_rxdma = (volatile struct dbdma_regs *)
+ ioremap(io->addrs[2].address, 0x100);
+
+-#ifdef CONFIG_PMAC_PBOOK
+ /* first of all make sure that the chip is powered up....*/
+ pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, io, 0, 1);
+- if (awacs_revision == AWACS_SCREAMER)
++ if (awacs_revision == AWACS_SCREAMER && awacs)
+ awacs_recalibrate();
+-#endif
++
+ awacs_irq = io->intrs[0].line;
+ awacs_tx_irq = io->intrs[1].line;
+ awacs_rx_irq = io->intrs[2].line;
+
++ /* Hack for legacy crap that will be killed someday */
+ awacs_node = io;
+
+ /* if we have an awacs or screamer - probe the chip to make
+@@ -2909,8 +2959,9 @@
+ /* if it's there use it to set up frame rates */
+ init_frame_rates(prop, l) ;
+ }
+-
+- out_le32(&awacs->control, 0x11); /* set everything quiesent */
++
++ if (awacs)
++ out_le32(&awacs->control, 0x11); /* set everything quiesent */
+
+ set_hw_byteswap(io) ; /* figure out if the h/w can do it */
+
+@@ -2942,25 +2993,27 @@
+
+ switch (awacs_revision) {
+ case AWACS_TUMBLER:
+-#ifdef CONFIG_KMOD
+- request_module("i2c-keywest");
+-#endif /* CONFIG_KMOD */
+- awacs_tumbler_init();
+- tas_init();
+- break ;
++ tas_register_driver(&tas3001c_hooks);
++ tas_init(I2C_DRIVERID_TAS3001C, I2C_DRIVERNAME_TAS3001C);
++ tas_dmasound_init();
++ tas_post_init();
++ break ;
++ case AWACS_SNAPPER:
++ tas_register_driver(&tas3004_hooks);
++ tas_init(I2C_DRIVERID_TAS3004,I2C_DRIVERNAME_TAS3004);
++ tas_dmasound_init();
++ tas_post_init();
++ break;
+ case AWACS_DACA:
+-#ifdef CONFIG_KMOD
+- request_module("i2c-keywest");
+-#endif /* CONFIG_KMOD */
+ daca_init();
+- break ; /* don't know how yet */
++ break;
+ case AWACS_BURGUNDY:
+ awacs_burgundy_init();
+ break ;
+ case AWACS_SCREAMER:
+ case AWACS_AWACS:
+ default:
+- load_awacs() ;
++ load_awacs();
+ break ;
+ }
+
+@@ -3031,11 +3084,15 @@
+ dmasound.mach.hardware_afmts = AFMT_S16_BE ;
+
+ /* shut out chips that do output only.
+- may need to extend this to machines which have no inputs - even tho'
+- they use screamer - IIRC one of the powerbooks is like this.
+- */
++ * may need to extend this to machines which have no inputs - even tho'
++ * they use screamer - IIRC one of the powerbooks is like this.
++ *
++ * FIXME: Actually, some TUMBLER and SNAPPER do have inputs...
++ */
+
+- if (awacs_revision != AWACS_TUMBLER && awacs_revision != AWACS_DACA) {
++ if (awacs_revision != AWACS_TUMBLER &&
++ awacs_revision != AWACS_SNAPPER &&
++ awacs_revision != AWACS_DACA) {
+ dmasound.mach.capabilities = DSP_CAP_DUPLEX ;
+ dmasound.mach.record = PMacRecord ;
+ }
+@@ -3053,6 +3110,9 @@
+ case AWACS_TUMBLER:
+ sprintf(awacs_name, "PowerMac Tumbler ") ;
+ break ;
++ case AWACS_SNAPPER:
++ sprintf(awacs_name, "PowerMac Snapper ") ;
++ break ;
+ case AWACS_SCREAMER:
+ sprintf(awacs_name, "PowerMac Screamer ") ;
+ break ;
+@@ -3069,7 +3129,8 @@
+ {
+ switch (awacs_revision) {
+ case AWACS_TUMBLER:
+- awacs_tumbler_cleanup();
++ case AWACS_SNAPPER:
++ tas_dmasound_cleanup();
+ tas_cleanup();
+ break ;
+ case AWACS_DACA:
+Index: linux-2.6.0-test5/sound/oss/dmasound/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/dmasound/Kconfig 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/sound/oss/dmasound/Kconfig 2003-09-27 11:38:42.454074384 +0800
+@@ -12,9 +12,9 @@
+ want). If you want to compile it as a module, say M here and read
+ <file:Documentation/modules.txt>.
+
+-config DMASOUND_AWACS
++config DMASOUND_PMAC
+ tristate "PowerMac DMA sound support"
+- depends on PPC_PMAC && SOUND
++ depends on PPC_PMAC && SOUND && I2C
+ help
+ If you want to use the internal audio of your PowerMac in Linux,
+ answer Y to this question. This will provide a Sun-like /dev/audio,
+Index: linux-2.6.0-test5/sound/oss/dmasound/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/dmasound/Makefile 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/sound/oss/dmasound/Makefile 2003-09-27 11:38:42.455074232 +0800
+@@ -2,7 +2,12 @@
+ # Makefile for the DMA sound driver
+ #
+
+-obj-$(CONFIG_DMASOUND_ATARI) += dmasound_core.o dmasound_atari.o
+-obj-$(CONFIG_DMASOUND_AWACS) += dmasound_core.o dmasound_awacs.o
+-obj-$(CONFIG_DMASOUND_PAULA) += dmasound_core.o dmasound_paula.o
+-obj-$(CONFIG_DMASOUND_Q40) += dmasound_core.o dmasound_q40.o
++dmasound_pmac-y += dmasound_awacs.o \
++ trans_16.o dac3550a.o tas_common.o \
++ tas3001c.o tas3001c_tables.o \
++ tas3004.o tas3004_tables.o
++
++obj-$(CONFIG_DMASOUND_ATARI) += dmasound_core.o dmasound_atari.o
++obj-$(CONFIG_DMASOUND_PMAC) += dmasound_core.o dmasound_pmac.o
++obj-$(CONFIG_DMASOUND_PAULA) += dmasound_core.o dmasound_paula.o
++obj-$(CONFIG_DMASOUND_Q40) += dmasound_core.o dmasound_q40.o
+Index: linux-2.6.0-test5/sound/oss/dmasound/tas3001c.c
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/dmasound/tas3001c.c 2003-09-27 11:38:18.496716456 +0800
++++ linux-2.6.0-test5/sound/oss/dmasound/tas3001c.c 2003-09-27 11:38:42.457073928 +0800
+@@ -0,0 +1,861 @@
++/*
++ * Driver for the i2c/i2s based TA3004 sound chip used
++ * on some Apple hardware. Also known as "snapper".
++ *
++ * Tobias Sargeant <tobias.sargeant@bigpond.com>
++ * Based upon, tas3001c.c by Christopher C. Chimelis <chris@debian.org>:
++ *
++ * TODO:
++ * -----
++ * * Enable control over input line 2 (is this connected?)
++ * * Implement sleep support (at least mute everything and
++ * * set gains to minimum during sleep)
++ * * Look into some of Darwin's tweaks regarding the mute
++ * * lines (delays & different behaviour on some HW)
++ *
++ */
++
++#include <linux/version.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/proc_fs.h>
++#include <linux/ioport.h>
++#include <linux/sysctl.h>
++#include <linux/types.h>
++#include <linux/i2c.h>
++#include <linux/init.h>
++#include <linux/soundcard.h>
++#include <linux/workqueue.h>
++#include <asm/uaccess.h>
++#include <asm/errno.h>
++#include <asm/io.h>
++#include <asm/prom.h>
++
++#include "dmasound.h"
++#include "tas_common.h"
++#include "tas3001c.h"
++
++#include "tas_ioctl.h"
++
++#define TAS3001C_BIQUAD_FILTER_COUNT 6
++#define TAS3001C_BIQUAD_CHANNEL_COUNT 2
++
++#define VOL_DEFAULT (100 * 4 / 5)
++#define INPUT_DEFAULT (100 * 4 / 5)
++#define BASS_DEFAULT (100 / 2)
++#define TREBLE_DEFAULT (100 / 2)
++
++struct tas3001c_data_t {
++ struct tas_data_t super;
++ int device_id;
++ int output_id;
++ int speaker_id;
++ struct tas_drce_t drce_state;
++};
++
++
++static const union tas_biquad_t
++tas3001c_eq_unity={
++ buf: { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 }
++};
++
++
++static inline unsigned char db_to_regval(short db) {
++ int r=0;
++
++ r=(db+0x59a0) / 0x60;
++
++ if (r < 0x91) return 0x91;
++ if (r > 0xef) return 0xef;
++ return r;
++}
++
++static inline short quantize_db(short db) {
++ return db_to_regval(db) * 0x60 - 0x59a0;
++}
++
++
++static inline int
++register_width(enum tas3001c_reg_t r)
++{
++ switch(r) {
++ case TAS3001C_REG_MCR:
++ case TAS3001C_REG_TREBLE:
++ case TAS3001C_REG_BASS:
++ return 1;
++
++ case TAS3001C_REG_DRC:
++ return 2;
++
++ case TAS3001C_REG_MIXER1:
++ case TAS3001C_REG_MIXER2:
++ return 3;
++
++ case TAS3001C_REG_VOLUME:
++ return 6;
++
++ case TAS3001C_REG_LEFT_BIQUAD0:
++ case TAS3001C_REG_LEFT_BIQUAD1:
++ case TAS3001C_REG_LEFT_BIQUAD2:
++ case TAS3001C_REG_LEFT_BIQUAD3:
++ case TAS3001C_REG_LEFT_BIQUAD4:
++ case TAS3001C_REG_LEFT_BIQUAD5:
++ case TAS3001C_REG_LEFT_BIQUAD6:
++
++ case TAS3001C_REG_RIGHT_BIQUAD0:
++ case TAS3001C_REG_RIGHT_BIQUAD1:
++ case TAS3001C_REG_RIGHT_BIQUAD2:
++ case TAS3001C_REG_RIGHT_BIQUAD3:
++ case TAS3001C_REG_RIGHT_BIQUAD4:
++ case TAS3001C_REG_RIGHT_BIQUAD5:
++ case TAS3001C_REG_RIGHT_BIQUAD6:
++ return 15;
++
++ default:
++ return 0;
++ }
++}
++
++static int
++tas3001c_write_register( struct tas3001c_data_t *self,
++ enum tas3001c_reg_t reg_num,
++ char *data,
++ uint write_mode)
++{
++ if (reg_num==TAS3001C_REG_MCR ||
++ reg_num==TAS3001C_REG_BASS ||
++ reg_num==TAS3001C_REG_TREBLE) {
++ return tas_write_byte_register(&self->super,
++ (uint)reg_num,
++ *data,
++ write_mode);
++ } else {
++ return tas_write_register(&self->super,
++ (uint)reg_num,
++ register_width(reg_num),
++ data,
++ write_mode);
++ }
++}
++
++static int
++tas3001c_sync_register( struct tas3001c_data_t *self,
++ enum tas3001c_reg_t reg_num)
++{
++ if (reg_num==TAS3001C_REG_MCR ||
++ reg_num==TAS3001C_REG_BASS ||
++ reg_num==TAS3001C_REG_TREBLE) {
++ return tas_sync_byte_register(&self->super,
++ (uint)reg_num,
++ register_width(reg_num));
++ } else {
++ return tas_sync_register(&self->super,
++ (uint)reg_num,
++ register_width(reg_num));
++ }
++}
++
++static int
++tas3001c_read_register( struct tas3001c_data_t *self,
++ enum tas3001c_reg_t reg_num,
++ char *data,
++ uint write_mode)
++{
++ return tas_read_register(&self->super,
++ (uint)reg_num,
++ register_width(reg_num),
++ data);
++}
++
++static inline int
++tas3001c_fast_load(struct tas3001c_data_t *self, int fast)
++{
++ if (fast)
++ self->super.shadow[TAS3001C_REG_MCR][0] |= 0x80;
++ else
++ self->super.shadow[TAS3001C_REG_MCR][0] &= 0x7f;
++ return tas3001c_sync_register(self,TAS3001C_REG_MCR);
++}
++
++static uint
++tas3001c_supported_mixers(struct tas3001c_data_t *self)
++{
++ return SOUND_MASK_VOLUME |
++ SOUND_MASK_PCM |
++ SOUND_MASK_ALTPCM |
++ SOUND_MASK_TREBLE |
++ SOUND_MASK_BASS;
++}
++
++static int
++tas3001c_mixer_is_stereo(struct tas3001c_data_t *self,int mixer)
++{
++ switch(mixer) {
++ case SOUND_MIXER_VOLUME:
++ return 1;
++ default:
++ return 0;
++ }
++}
++
++static uint
++tas3001c_stereo_mixers(struct tas3001c_data_t *self)
++{
++ uint r=tas3001c_supported_mixers(self);
++ uint i;
++
++ for (i=1; i<SOUND_MIXER_NRDEVICES; i++)
++ if (r&(1<<i) && !tas3001c_mixer_is_stereo(self,i))
++ r &= ~(1<<i);
++ return r;
++}
++
++static int
++tas3001c_get_mixer_level(struct tas3001c_data_t *self,int mixer,uint *level)
++{
++ if (!self)
++ return -1;
++
++ *level=self->super.mixer[mixer];
++
++ return 0;
++}
++
++static int
++tas3001c_set_mixer_level(struct tas3001c_data_t *self,int mixer,uint level)
++{
++ int rc;
++ tas_shadow_t *shadow;
++
++ uint temp;
++ uint offset=0;
++
++ if (!self)
++ return -1;
++
++ shadow=self->super.shadow;
++
++ if (!tas3001c_mixer_is_stereo(self,mixer))
++ level = tas_mono_to_stereo(level);
++
++ switch(mixer) {
++ case SOUND_MIXER_VOLUME:
++ temp = tas3001c_gain.master[level&0xff];
++ shadow[TAS3001C_REG_VOLUME][0] = (temp >> 16) & 0xff;
++ shadow[TAS3001C_REG_VOLUME][1] = (temp >> 8) & 0xff;
++ shadow[TAS3001C_REG_VOLUME][2] = (temp >> 0) & 0xff;
++ temp = tas3001c_gain.master[(level>>8)&0xff];
++ shadow[TAS3001C_REG_VOLUME][3] = (temp >> 16) & 0xff;
++ shadow[TAS3001C_REG_VOLUME][4] = (temp >> 8) & 0xff;
++ shadow[TAS3001C_REG_VOLUME][5] = (temp >> 0) & 0xff;
++ rc = tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
++ break;
++ case SOUND_MIXER_ALTPCM:
++ /* tas3001c_fast_load(self, 1); */
++ level = tas_mono_to_stereo(level);
++ temp = tas3001c_gain.mixer[level&0xff];
++ shadow[TAS3001C_REG_MIXER2][offset+0] = (temp >> 16) & 0xff;
++ shadow[TAS3001C_REG_MIXER2][offset+1] = (temp >> 8) & 0xff;
++ shadow[TAS3001C_REG_MIXER2][offset+2] = (temp >> 0) & 0xff;
++ rc = tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
++ /* tas3001c_fast_load(self, 0); */
++ break;
++ case SOUND_MIXER_PCM:
++ /* tas3001c_fast_load(self, 1); */
++ level = tas_mono_to_stereo(level);
++ temp = tas3001c_gain.mixer[level&0xff];
++ shadow[TAS3001C_REG_MIXER1][offset+0] = (temp >> 16) & 0xff;
++ shadow[TAS3001C_REG_MIXER1][offset+1] = (temp >> 8) & 0xff;
++ shadow[TAS3001C_REG_MIXER1][offset+2] = (temp >> 0) & 0xff;
++ rc = tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
++ /* tas3001c_fast_load(self, 0); */
++ break;
++ case SOUND_MIXER_TREBLE:
++ temp = tas3001c_gain.treble[level&0xff];
++ shadow[TAS3001C_REG_TREBLE][0]=temp&0xff;
++ rc = tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
++ break;
++ case SOUND_MIXER_BASS:
++ temp = tas3001c_gain.bass[level&0xff];
++ shadow[TAS3001C_REG_BASS][0]=temp&0xff;
++ rc = tas3001c_sync_register(self,TAS3001C_REG_BASS);
++ break;
++ default:
++ rc = -1;
++ break;
++ }
++ if (rc < 0)
++ return rc;
++ self->super.mixer[mixer]=level;
++ return 0;
++}
++
++static int
++tas3001c_leave_sleep(struct tas3001c_data_t *self)
++{
++ unsigned char mcr = (1<<6)+(2<<4)+(2<<2);
++
++ if (!self)
++ return -1;
++
++ /* Make sure something answers on the i2c bus */
++ if (tas3001c_write_register(self, TAS3001C_REG_MCR, &mcr,
++ WRITE_NORMAL|FORCE_WRITE) < 0)
++ return -1;
++
++ tas3001c_fast_load(self, 1);
++
++ (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD0);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD1);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD2);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD3);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD4);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD5);
++
++ (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD0);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD1);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD2);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD3);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD4);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD5);
++
++ tas3001c_fast_load(self, 0);
++
++ (void)tas3001c_sync_register(self,TAS3001C_REG_BASS);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
++
++ return 0;
++}
++
++static int
++tas3001c_enter_sleep(struct tas3001c_data_t *self)
++{
++ /* Stub for now, but I have the details on low-power mode */
++ if (!self)
++ return -1;
++ return 0;
++}
++
++static int
++tas3001c_sync_biquad( struct tas3001c_data_t *self,
++ u_int channel,
++ u_int filter)
++{
++ enum tas3001c_reg_t reg;
++
++ if (channel >= TAS3001C_BIQUAD_CHANNEL_COUNT ||
++ filter >= TAS3001C_BIQUAD_FILTER_COUNT) return -EINVAL;
++
++ reg=( channel ? TAS3001C_REG_RIGHT_BIQUAD0 : TAS3001C_REG_LEFT_BIQUAD0 ) + filter;
++
++ return tas3001c_sync_register(self,reg);
++}
++
++static int
++tas3001c_write_biquad_shadow( struct tas3001c_data_t *self,
++ u_int channel,
++ u_int filter,
++ const union tas_biquad_t *biquad)
++{
++ tas_shadow_t *shadow=self->super.shadow;
++ enum tas3001c_reg_t reg;
++
++ if (channel >= TAS3001C_BIQUAD_CHANNEL_COUNT ||
++ filter >= TAS3001C_BIQUAD_FILTER_COUNT) return -EINVAL;
++
++ reg=( channel ? TAS3001C_REG_RIGHT_BIQUAD0 : TAS3001C_REG_LEFT_BIQUAD0 ) + filter;
++
++ SET_4_20(shadow[reg], 0,biquad->coeff.b0);
++ SET_4_20(shadow[reg], 3,biquad->coeff.b1);
++ SET_4_20(shadow[reg], 6,biquad->coeff.b2);
++ SET_4_20(shadow[reg], 9,biquad->coeff.a1);
++ SET_4_20(shadow[reg],12,biquad->coeff.a2);
++
++ return 0;
++}
++
++static int
++tas3001c_write_biquad( struct tas3001c_data_t *self,
++ u_int channel,
++ u_int filter,
++ const union tas_biquad_t *biquad)
++{
++ int rc;
++
++ rc=tas3001c_write_biquad_shadow(self, channel, filter, biquad);
++ if (rc < 0) return rc;
++
++ return tas3001c_sync_biquad(self, channel, filter);
++}
++
++static int
++tas3001c_write_biquad_list( struct tas3001c_data_t *self,
++ u_int filter_count,
++ u_int flags,
++ struct tas_biquad_ctrl_t *biquads)
++{
++ int i;
++ int rc;
++
++ if (flags & TAS_BIQUAD_FAST_LOAD) tas3001c_fast_load(self,1);
++
++ for (i=0; i<filter_count; i++) {
++ rc=tas3001c_write_biquad(self,
++ biquads[i].channel,
++ biquads[i].filter,
++ &biquads[i].data);
++ if (rc < 0) break;
++ }
++
++ if (flags & TAS_BIQUAD_FAST_LOAD) {
++ tas3001c_fast_load(self,0);
++
++ (void)tas3001c_sync_register(self,TAS3001C_REG_BASS);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
++ }
++
++ return rc;
++}
++
++static int
++tas3001c_read_biquad( struct tas3001c_data_t *self,
++ u_int channel,
++ u_int filter,
++ union tas_biquad_t *biquad)
++{
++ tas_shadow_t *shadow=self->super.shadow;
++ enum tas3001c_reg_t reg;
++
++ if (channel >= TAS3001C_BIQUAD_CHANNEL_COUNT ||
++ filter >= TAS3001C_BIQUAD_FILTER_COUNT) return -EINVAL;
++
++ reg=( channel ? TAS3001C_REG_RIGHT_BIQUAD0 : TAS3001C_REG_LEFT_BIQUAD0 ) + filter;
++
++ biquad->coeff.b0=GET_4_20(shadow[reg], 0);
++ biquad->coeff.b1=GET_4_20(shadow[reg], 3);
++ biquad->coeff.b2=GET_4_20(shadow[reg], 6);
++ biquad->coeff.a1=GET_4_20(shadow[reg], 9);
++ biquad->coeff.a2=GET_4_20(shadow[reg],12);
++
++ return 0;
++}
++
++static int
++tas3001c_eq_rw( struct tas3001c_data_t *self,
++ u_int cmd,
++ u_long arg)
++{
++ int rc;
++ struct tas_biquad_ctrl_t biquad;
++
++ if (copy_from_user((void *)&biquad, (const void *)arg, sizeof(struct tas_biquad_ctrl_t))) {
++ return -EFAULT;
++ }
++
++ if (cmd & SIOC_IN) {
++ rc=tas3001c_write_biquad(self, biquad.channel, biquad.filter, &biquad.data);
++ if (rc != 0) return rc;
++ }
++
++ if (cmd & SIOC_OUT) {
++ rc=tas3001c_read_biquad(self, biquad.channel, biquad.filter, &biquad.data);
++ if (rc != 0) return rc;
++
++ if (copy_to_user((void *)arg, (const void *)&biquad, sizeof(struct tas_biquad_ctrl_t))) {
++ return -EFAULT;
++ }
++
++ }
++ return 0;
++}
++
++static int
++tas3001c_eq_list_rw( struct tas3001c_data_t *self,
++ u_int cmd,
++ u_long arg)
++{
++ int rc;
++ int filter_count;
++ int flags;
++ int i,j;
++ char sync_required[2][6];
++ struct tas_biquad_ctrl_t biquad;
++
++ memset(sync_required,0,sizeof(sync_required));
++
++ if (copy_from_user((void *)&filter_count,
++ (const void *)arg + offsetof(struct tas_biquad_ctrl_list_t,filter_count),
++ sizeof(int))) {
++ return -EFAULT;
++ }
++
++ if (copy_from_user((void *)&flags,
++ (const void *)arg + offsetof(struct tas_biquad_ctrl_list_t,flags),
++ sizeof(int))) {
++ return -EFAULT;
++ }
++
++ if (cmd & SIOC_IN) {
++ }
++
++ for (i=0; i < filter_count; i++) {
++ if (copy_from_user((void *)&biquad,
++ (const void *)arg + offsetof(struct tas_biquad_ctrl_list_t, biquads[i]),
++ sizeof(struct tas_biquad_ctrl_t))) {
++ return -EFAULT;
++ }
++
++ if (cmd & SIOC_IN) {
++ sync_required[biquad.channel][biquad.filter]=1;
++ rc=tas3001c_write_biquad_shadow(self, biquad.channel, biquad.filter, &biquad.data);
++ if (rc != 0) return rc;
++ }
++
++ if (cmd & SIOC_OUT) {
++ rc=tas3001c_read_biquad(self, biquad.channel, biquad.filter, &biquad.data);
++ if (rc != 0) return rc;
++
++ if (copy_to_user((void *)arg + offsetof(struct tas_biquad_ctrl_list_t, biquads[i]),
++ (const void *)&biquad,
++ sizeof(struct tas_biquad_ctrl_t))) {
++ return -EFAULT;
++ }
++ }
++ }
++
++ if (cmd & SIOC_IN) {
++ if (flags & TAS_BIQUAD_FAST_LOAD) tas3001c_fast_load(self,1);
++ for (i=0; i<2; i++) {
++ for (j=0; j<6; j++) {
++ if (sync_required[i][j]) {
++ rc=tas3001c_sync_biquad(self, i, j);
++ if (rc < 0) return rc;
++ }
++ }
++ }
++ if (flags & TAS_BIQUAD_FAST_LOAD) {
++ tas3001c_fast_load(self,0);
++ /* now we need to set up the mixers again,
++ because leaving fast mode resets them. */
++ (void)tas3001c_sync_register(self,TAS3001C_REG_BASS);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
++ }
++ }
++
++ return 0;
++}
++
++static int
++tas3001c_update_drce( struct tas3001c_data_t *self,
++ int flags,
++ struct tas_drce_t *drce)
++{
++ tas_shadow_t *shadow;
++ shadow=self->super.shadow;
++
++ shadow[TAS3001C_REG_DRC][1] = 0xc1;
++
++ if (flags & TAS_DRCE_THRESHOLD) {
++ self->drce_state.threshold=quantize_db(drce->threshold);
++ shadow[TAS3001C_REG_DRC][2] = db_to_regval(self->drce_state.threshold);
++ }
++
++ if (flags & TAS_DRCE_ENABLE) {
++ self->drce_state.enable = drce->enable;
++ }
++
++ if (!self->drce_state.enable) {
++ shadow[TAS3001C_REG_DRC][0] = 0xf0;
++ }
++
++#ifdef DEBUG_DRCE
++ printk("DRCE IOCTL: set [ ENABLE:%x THRESH:%x\n",
++ self->drce_state.enable,
++ self->drce_state.threshold);
++
++ printk("DRCE IOCTL: reg [ %02x %02x ]\n",
++ (unsigned char)shadow[TAS3001C_REG_DRC][0],
++ (unsigned char)shadow[TAS3001C_REG_DRC][1]);
++#endif
++
++ return tas3001c_sync_register(self, TAS3001C_REG_DRC);
++}
++
++static int
++tas3001c_drce_rw( struct tas3001c_data_t *self,
++ u_int cmd,
++ u_long arg)
++{
++ int rc;
++ struct tas_drce_ctrl_t drce_ctrl;
++
++ if (copy_from_user((void *)&drce_ctrl,
++ (const void *)arg,
++ sizeof(struct tas_drce_ctrl_t))) {
++ return -EFAULT;
++ }
++
++#ifdef DEBUG_DRCE
++ printk("DRCE IOCTL: input [ FLAGS:%x ENABLE:%x THRESH:%x\n",
++ drce_ctrl.flags,
++ drce_ctrl.data.enable,
++ drce_ctrl.data.threshold);
++#endif
++
++ if (cmd & SIOC_IN) {
++ rc = tas3001c_update_drce(self, drce_ctrl.flags, &drce_ctrl.data);
++ if (rc < 0)
++ return rc;
++ }
++
++ if (cmd & SIOC_OUT) {
++ if (drce_ctrl.flags & TAS_DRCE_ENABLE)
++ drce_ctrl.data.enable = self->drce_state.enable;
++
++ if (drce_ctrl.flags & TAS_DRCE_THRESHOLD)
++ drce_ctrl.data.threshold = self->drce_state.threshold;
++
++ if (copy_to_user((void *)arg,
++ (const void *)&drce_ctrl,
++ sizeof(struct tas_drce_ctrl_t))) {
++ return -EFAULT;
++ }
++ }
++
++ return 0;
++}
++
++static void
++tas3001c_update_device_parameters(struct tas3001c_data_t *self)
++{
++ int i,j;
++
++ if (!self) return;
++
++ if (self->output_id == TAS_OUTPUT_HEADPHONES) {
++ tas3001c_fast_load(self, 1);
++
++ for (i=0; i<TAS3001C_BIQUAD_CHANNEL_COUNT; i++) {
++ for (j=0; j<TAS3001C_BIQUAD_FILTER_COUNT; j++) {
++ tas3001c_write_biquad(self, i, j, &tas3001c_eq_unity);
++ }
++ }
++
++ tas3001c_fast_load(self, 0);
++
++ (void)tas3001c_sync_register(self,TAS3001C_REG_BASS);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
++
++ return;
++ }
++
++ for (i=0; tas3001c_eq_prefs[i]; i++) {
++ struct tas_eq_pref_t *eq = tas3001c_eq_prefs[i];
++
++ if (eq->device_id == self->device_id &&
++ (eq->output_id == 0 || eq->output_id == self->output_id) &&
++ (eq->speaker_id == 0 || eq->speaker_id == self->speaker_id)) {
++
++ tas3001c_update_drce(self, TAS_DRCE_ALL, eq->drce);
++ tas3001c_write_biquad_list(self, eq->filter_count, TAS_BIQUAD_FAST_LOAD, eq->biquads);
++
++ break;
++ }
++ }
++}
++
++static void
++tas3001c_device_change_handler(void *self)
++{
++ if (self)
++ tas3001c_update_device_parameters(self);
++}
++
++static struct work_struct device_change;
++
++static int
++tas3001c_output_device_change( struct tas3001c_data_t *self,
++ int device_id,
++ int output_id,
++ int speaker_id)
++{
++ self->device_id=device_id;
++ self->output_id=output_id;
++ self->speaker_id=speaker_id;
++
++ schedule_work(&device_change);
++ return 0;
++}
++
++static int
++tas3001c_device_ioctl( struct tas3001c_data_t *self,
++ u_int cmd,
++ u_long arg)
++{
++ switch (cmd) {
++ case TAS_READ_EQ:
++ case TAS_WRITE_EQ:
++ return tas3001c_eq_rw(self, cmd, arg);
++
++ case TAS_READ_EQ_LIST:
++ case TAS_WRITE_EQ_LIST:
++ return tas3001c_eq_list_rw(self, cmd, arg);
++
++ case TAS_READ_EQ_FILTER_COUNT:
++ put_user(TAS3001C_BIQUAD_FILTER_COUNT, (uint *)(arg));
++ return 0;
++
++ case TAS_READ_EQ_CHANNEL_COUNT:
++ put_user(TAS3001C_BIQUAD_CHANNEL_COUNT, (uint *)(arg));
++ return 0;
++
++ case TAS_READ_DRCE:
++ case TAS_WRITE_DRCE:
++ return tas3001c_drce_rw(self, cmd, arg);
++
++ case TAS_READ_DRCE_CAPS:
++ put_user(TAS_DRCE_ENABLE | TAS_DRCE_THRESHOLD, (uint *)(arg));
++ return 0;
++
++ case TAS_READ_DRCE_MIN:
++ case TAS_READ_DRCE_MAX: {
++ struct tas_drce_ctrl_t drce_ctrl;
++
++ if (copy_from_user((void *)&drce_ctrl,
++ (const void *)arg,
++ sizeof(struct tas_drce_ctrl_t))) {
++ return -EFAULT;
++ }
++
++ if (drce_ctrl.flags & TAS_DRCE_THRESHOLD) {
++ if (cmd == TAS_READ_DRCE_MIN) {
++ drce_ctrl.data.threshold=-36<<8;
++ } else {
++ drce_ctrl.data.threshold=-6<<8;
++ }
++ }
++
++ if (copy_to_user((void *)arg,
++ (const void *)&drce_ctrl,
++ sizeof(struct tas_drce_ctrl_t))) {
++ return -EFAULT;
++ }
++ }
++ }
++
++ return -EINVAL;
++}
++
++static int
++tas3001c_init_mixer(struct tas3001c_data_t *self)
++{
++ unsigned char mcr = (1<<6)+(2<<4)+(2<<2);
++
++ /* Make sure something answers on the i2c bus */
++ if (tas3001c_write_register(self, TAS3001C_REG_MCR, &mcr,
++ WRITE_NORMAL|FORCE_WRITE) < 0)
++ return -1;
++
++ tas3001c_fast_load(self, 1);
++
++ (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD0);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD1);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD2);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD3);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD4);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD5);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD6);
++
++ (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD0);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD1);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD2);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD3);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD4);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD5);
++ (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD6);
++
++ tas3001c_fast_load(self, 0);
++
++ tas3001c_set_mixer_level(self, SOUND_MIXER_VOLUME, VOL_DEFAULT<<8 | VOL_DEFAULT);
++ tas3001c_set_mixer_level(self, SOUND_MIXER_PCM, INPUT_DEFAULT<<8 | INPUT_DEFAULT);
++ tas3001c_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0);
++
++ tas3001c_set_mixer_level(self, SOUND_MIXER_BASS, BASS_DEFAULT);
++ tas3001c_set_mixer_level(self, SOUND_MIXER_TREBLE, TREBLE_DEFAULT);
++
++ return 0;
++}
++
++static int
++tas3001c_uninit_mixer(struct tas3001c_data_t *self)
++{
++ tas3001c_set_mixer_level(self, SOUND_MIXER_VOLUME, 0);
++ tas3001c_set_mixer_level(self, SOUND_MIXER_PCM, 0);
++ tas3001c_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0);
++
++ tas3001c_set_mixer_level(self, SOUND_MIXER_BASS, 0);
++ tas3001c_set_mixer_level(self, SOUND_MIXER_TREBLE, 0);
++
++ return 0;
++}
++
++static int
++tas3001c_init(struct i2c_client *client)
++{
++ struct tas3001c_data_t *self;
++ size_t sz = sizeof(*self) + (TAS3001C_REG_MAX*sizeof(tas_shadow_t));
++ int i, j;
++
++ self = kmalloc(sz, GFP_KERNEL);
++ if (!self)
++ return -ENOMEM;
++ memset(self, 0, sz);
++
++ self->super.client = client;
++ self->super.shadow = (tas_shadow_t *)(self+1);
++ self->output_id = TAS_OUTPUT_HEADPHONES;
++
++ dev_set_drvdata(&client->dev, self);
++
++ for (i = 0; i < TAS3001C_BIQUAD_CHANNEL_COUNT; i++)
++ for (j = 0; j < TAS3001C_BIQUAD_FILTER_COUNT; j++)
++ tas3001c_write_biquad_shadow(self, i, j,
++ &tas3001c_eq_unity);
++
++ INIT_WORK(&device_change, tas3001c_device_change_handler, self);
++ return 0;
++}
++
++static void
++tas3001c_uninit(struct tas3001c_data_t *self)
++{
++ tas3001c_uninit_mixer(self);
++ kfree(self);
++}
++
++struct tas_driver_hooks_t tas3001c_hooks = {
++ .init = (tas_hook_init_t)tas3001c_init,
++ .post_init = (tas_hook_post_init_t)tas3001c_init_mixer,
++ .uninit = (tas_hook_uninit_t)tas3001c_uninit,
++ .get_mixer_level = (tas_hook_get_mixer_level_t)tas3001c_get_mixer_level,
++ .set_mixer_level = (tas_hook_set_mixer_level_t)tas3001c_set_mixer_level,
++ .enter_sleep = (tas_hook_enter_sleep_t)tas3001c_enter_sleep,
++ .leave_sleep = (tas_hook_leave_sleep_t)tas3001c_leave_sleep,
++ .supported_mixers = (tas_hook_supported_mixers_t)tas3001c_supported_mixers,
++ .mixer_is_stereo = (tas_hook_mixer_is_stereo_t)tas3001c_mixer_is_stereo,
++ .stereo_mixers = (tas_hook_stereo_mixers_t)tas3001c_stereo_mixers,
++ .output_device_change = (tas_hook_output_device_change_t)tas3001c_output_device_change,
++ .device_ioctl = (tas_hook_device_ioctl_t)tas3001c_device_ioctl
++};
+Index: linux-2.6.0-test5/sound/oss/dmasound/tas3001c.h
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/dmasound/tas3001c.h 2003-09-27 11:38:18.496716456 +0800
++++ linux-2.6.0-test5/sound/oss/dmasound/tas3001c.h 2003-09-27 11:38:42.458073776 +0800
+@@ -0,0 +1,64 @@
++/*
++ * Header file for the i2c/i2s based TA3001c sound chip used
++ * on some Apple hardware. Also known as "tumbler".
++ *
++ * 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.
++ *
++ * Written by Christopher C. Chimelis <chris@debian.org>
++ */
++
++#ifndef _TAS3001C_H_
++#define _TAS3001C_H_
++
++#include <linux/types.h>
++
++#include "tas_common.h"
++#include "tas_eq_prefs.h"
++
++/*
++ * Macros that correspond to the registers that we write to
++ * when setting the various values.
++ */
++
++#define TAS3001C_VERSION "0.3"
++#define TAS3001C_DATE "20011214"
++
++#define I2C_DRIVERNAME_TAS3001C "TAS3001c driver V " TAS3001C_VERSION
++#define I2C_DRIVERID_TAS3001C (I2C_DRIVERID_TAS_BASE+0)
++
++extern struct tas_driver_hooks_t tas3001c_hooks;
++extern struct tas_gain_t tas3001c_gain;
++extern struct tas_eq_pref_t *tas3001c_eq_prefs[];
++
++enum tas3001c_reg_t {
++ TAS3001C_REG_MCR = 0x01,
++ TAS3001C_REG_DRC = 0x02,
++
++ TAS3001C_REG_VOLUME = 0x04,
++ TAS3001C_REG_TREBLE = 0x05,
++ TAS3001C_REG_BASS = 0x06,
++ TAS3001C_REG_MIXER1 = 0x07,
++ TAS3001C_REG_MIXER2 = 0x08,
++
++ TAS3001C_REG_LEFT_BIQUAD0 = 0x0a,
++ TAS3001C_REG_LEFT_BIQUAD1 = 0x0b,
++ TAS3001C_REG_LEFT_BIQUAD2 = 0x0c,
++ TAS3001C_REG_LEFT_BIQUAD3 = 0x0d,
++ TAS3001C_REG_LEFT_BIQUAD4 = 0x0e,
++ TAS3001C_REG_LEFT_BIQUAD5 = 0x0f,
++ TAS3001C_REG_LEFT_BIQUAD6 = 0x10,
++
++ TAS3001C_REG_RIGHT_BIQUAD0 = 0x13,
++ TAS3001C_REG_RIGHT_BIQUAD1 = 0x14,
++ TAS3001C_REG_RIGHT_BIQUAD2 = 0x15,
++ TAS3001C_REG_RIGHT_BIQUAD3 = 0x16,
++ TAS3001C_REG_RIGHT_BIQUAD4 = 0x17,
++ TAS3001C_REG_RIGHT_BIQUAD5 = 0x18,
++ TAS3001C_REG_RIGHT_BIQUAD6 = 0x19,
++
++ TAS3001C_REG_MAX = 0x20
++};
++
++#endif /* _TAS3001C_H_ */
+Index: linux-2.6.0-test5/sound/oss/dmasound/tas3001c_tables.c
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/dmasound/tas3001c_tables.c 2003-09-27 11:38:18.496716456 +0800
++++ linux-2.6.0-test5/sound/oss/dmasound/tas3001c_tables.c 2003-09-27 11:38:42.459073624 +0800
+@@ -0,0 +1,375 @@
++#include "tas_common.h"
++#include "tas_eq_prefs.h"
++
++static struct tas_drce_t eqp_0e_2_1_drce = {
++ enable: 1,
++ above: { val: 3.0 * (1<<8), expand: 0 },
++ below: { val: 1.0 * (1<<8), expand: 0 },
++ threshold: -15.33 * (1<<8),
++ energy: 2.4 * (1<<12),
++ attack: 0.013 * (1<<12),
++ decay: 0.212 * (1<<12),
++};
++
++static struct tas_biquad_ctrl_t eqp_0e_2_1_biquads[]={
++ { channel: 0, filter: 0, data: { coeff: { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } },
++ { channel: 0, filter: 1, data: { coeff: { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } },
++ { channel: 0, filter: 2, data: { coeff: { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } },
++ { channel: 0, filter: 3, data: { coeff: { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } },
++ { channel: 0, filter: 4, data: { coeff: { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } },
++ { channel: 0, filter: 5, data: { coeff: { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } },
++
++ { channel: 1, filter: 0, data: { coeff: { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } },
++ { channel: 1, filter: 1, data: { coeff: { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } },
++ { channel: 1, filter: 2, data: { coeff: { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } },
++ { channel: 1, filter: 3, data: { coeff: { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } },
++ { channel: 1, filter: 4, data: { coeff: { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } },
++ { channel: 1, filter: 5, data: { coeff: { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } },
++};
++
++static struct tas_eq_pref_t eqp_0e_2_1 = {
++ sample_rate: 44100,
++ device_id: 0x0e,
++ output_id: TAS_OUTPUT_EXTERNAL_SPKR,
++ speaker_id: 0x01,
++
++ drce: &eqp_0e_2_1_drce,
++
++ filter_count: 12,
++ biquads: eqp_0e_2_1_biquads
++};
++
++/* ======================================================================== */
++
++static struct tas_drce_t eqp_10_1_0_drce={
++ enable: 1,
++ above: { val: 3.0 * (1<<8), expand: 0 },
++ below: { val: 1.0 * (1<<8), expand: 0 },
++ threshold: -12.46 * (1<<8),
++ energy: 2.4 * (1<<12),
++ attack: 0.013 * (1<<12),
++ decay: 0.212 * (1<<12),
++};
++
++static struct tas_biquad_ctrl_t eqp_10_1_0_biquads[]={
++ { channel: 0, filter: 0, data: { coeff: { 0x0F4A12, 0xE16BDA, 0x0F4A12, 0xE173F0, 0x0E9C3A } } },
++ { channel: 0, filter: 1, data: { coeff: { 0x02DD54, 0x05BAA8, 0x02DD54, 0xF8001D, 0x037532 } } },
++ { channel: 0, filter: 2, data: { coeff: { 0x0E2FC7, 0xE4D5DC, 0x0D7477, 0xE4D5DC, 0x0BA43F } } },
++ { channel: 0, filter: 3, data: { coeff: { 0x0E7899, 0xE67CCA, 0x0D0E93, 0xE67CCA, 0x0B872D } } },
++ { channel: 0, filter: 4, data: { coeff: { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
++ { channel: 0, filter: 5, data: { coeff: { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
++
++ { channel: 1, filter: 0, data: { coeff: { 0x0F4A12, 0xE16BDA, 0x0F4A12, 0xE173F0, 0x0E9C3A } } },
++ { channel: 1, filter: 1, data: { coeff: { 0x02DD54, 0x05BAA8, 0x02DD54, 0xF8001D, 0x037532 } } },
++ { channel: 1, filter: 2, data: { coeff: { 0x0E2FC7, 0xE4D5DC, 0x0D7477, 0xE4D5DC, 0x0BA43F } } },
++ { channel: 1, filter: 3, data: { coeff: { 0x0E7899, 0xE67CCA, 0x0D0E93, 0xE67CCA, 0x0B872D } } },
++ { channel: 1, filter: 4, data: { coeff: { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
++ { channel: 1, filter: 5, data: { coeff: { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
++};
++
++static struct tas_eq_pref_t eqp_10_1_0 = {
++ sample_rate: 44100,
++ device_id: 0x10,
++ output_id: TAS_OUTPUT_INTERNAL_SPKR,
++ speaker_id: 0x00,
++
++ drce: &eqp_10_1_0_drce,
++
++ filter_count: 12,
++ biquads: eqp_10_1_0_biquads
++};
++
++/* ======================================================================== */
++
++static struct tas_drce_t eqp_15_2_1_drce={
++ enable: 1,
++ above: { val: 3.0 * (1<<8), expand: 0 },
++ below: { val: 1.0 * (1<<8), expand: 0 },
++ threshold: -15.33 * (1<<8),
++ energy: 2.4 * (1<<12),
++ attack: 0.013 * (1<<12),
++ decay: 0.212 * (1<<12),
++};
++
++static struct tas_biquad_ctrl_t eqp_15_2_1_biquads[]={
++ { channel: 0, filter: 0, data: { coeff: { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } },
++ { channel: 0, filter: 1, data: { coeff: { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } },
++ { channel: 0, filter: 2, data: { coeff: { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } },
++ { channel: 0, filter: 3, data: { coeff: { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } },
++ { channel: 0, filter: 4, data: { coeff: { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } },
++ { channel: 0, filter: 5, data: { coeff: { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } },
++
++ { channel: 1, filter: 0, data: { coeff: { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } },
++ { channel: 1, filter: 1, data: { coeff: { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } },
++ { channel: 1, filter: 2, data: { coeff: { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } },
++ { channel: 1, filter: 3, data: { coeff: { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } },
++ { channel: 1, filter: 4, data: { coeff: { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } },
++ { channel: 1, filter: 5, data: { coeff: { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } },
++};
++
++static struct tas_eq_pref_t eqp_15_2_1 = {
++ sample_rate: 44100,
++ device_id: 0x15,
++ output_id: TAS_OUTPUT_EXTERNAL_SPKR,
++ speaker_id: 0x01,
++
++ drce: &eqp_15_2_1_drce,
++
++ filter_count: 12,
++ biquads: eqp_15_2_1_biquads
++};
++
++/* ======================================================================== */
++
++static struct tas_drce_t eqp_15_1_0_drce={
++ enable: 1,
++ above: { val: 3.0 * (1<<8), expand: 0 },
++ below: { val: 1.0 * (1<<8), expand: 0 },
++ threshold: 0.0 * (1<<8),
++ energy: 2.4 * (1<<12),
++ attack: 0.013 * (1<<12),
++ decay: 0.212 * (1<<12),
++};
++
++static struct tas_biquad_ctrl_t eqp_15_1_0_biquads[]={
++ { channel: 0, filter: 0, data: { coeff: { 0x0FAD08, 0xE0A5EF, 0x0FAD08, 0xE0A79D, 0x0F5BBE } } },
++ { channel: 0, filter: 1, data: { coeff: { 0x04B38D, 0x09671B, 0x04B38D, 0x000F71, 0x02BEC5 } } },
++ { channel: 0, filter: 2, data: { coeff: { 0x0FDD32, 0xE0A56F, 0x0F8A69, 0xE0A56F, 0x0F679C } } },
++ { channel: 0, filter: 3, data: { coeff: { 0x0FD284, 0xE135FB, 0x0F2161, 0xE135FB, 0x0EF3E5 } } },
++ { channel: 0, filter: 4, data: { coeff: { 0x0E81B1, 0xE6283F, 0x0CE49D, 0xE6283F, 0x0B664F } } },
++ { channel: 0, filter: 5, data: { coeff: { 0x0F2D62, 0xE98797, 0x0D1E19, 0xE98797, 0x0C4B7B } } },
++
++ { channel: 1, filter: 0, data: { coeff: { 0x0FAD08, 0xE0A5EF, 0x0FAD08, 0xE0A79D, 0x0F5BBE } } },
++ { channel: 1, filter: 1, data: { coeff: { 0x04B38D, 0x09671B, 0x04B38D, 0x000F71, 0x02BEC5 } } },
++ { channel: 1, filter: 2, data: { coeff: { 0x0FDD32, 0xE0A56F, 0x0F8A69, 0xE0A56F, 0x0F679C } } },
++ { channel: 1, filter: 3, data: { coeff: { 0x0FD284, 0xE135FB, 0x0F2161, 0xE135FB, 0x0EF3E5 } } },
++ { channel: 1, filter: 4, data: { coeff: { 0x0E81B1, 0xE6283F, 0x0CE49D, 0xE6283F, 0x0B664F } } },
++ { channel: 1, filter: 5, data: { coeff: { 0x0F2D62, 0xE98797, 0x0D1E19, 0xE98797, 0x0C4B7B } } },
++};
++
++static struct tas_eq_pref_t eqp_15_1_0 = {
++ sample_rate: 44100,
++ device_id: 0x15,
++ output_id: TAS_OUTPUT_INTERNAL_SPKR,
++ speaker_id: 0x00,
++
++ drce: &eqp_15_1_0_drce,
++
++ filter_count: 12,
++ biquads: eqp_15_1_0_biquads
++};
++
++/* ======================================================================== */
++
++static struct tas_drce_t eqp_0f_2_1_drce={
++ enable: 1,
++ above: { val: 3.0 * (1<<8), expand: 0 },
++ below: { val: 1.0 * (1<<8), expand: 0 },
++ threshold: -15.33 * (1<<8),
++ energy: 2.4 * (1<<12),
++ attack: 0.013 * (1<<12),
++ decay: 0.212 * (1<<12),
++};
++
++static struct tas_biquad_ctrl_t eqp_0f_2_1_biquads[]={
++ { channel: 0, filter: 0, data: { coeff: { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } },
++ { channel: 0, filter: 1, data: { coeff: { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } },
++ { channel: 0, filter: 2, data: { coeff: { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } },
++ { channel: 0, filter: 3, data: { coeff: { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } },
++ { channel: 0, filter: 4, data: { coeff: { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } },
++ { channel: 0, filter: 5, data: { coeff: { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } },
++
++ { channel: 1, filter: 0, data: { coeff: { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } },
++ { channel: 1, filter: 1, data: { coeff: { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } },
++ { channel: 1, filter: 2, data: { coeff: { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } },
++ { channel: 1, filter: 3, data: { coeff: { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } },
++ { channel: 1, filter: 4, data: { coeff: { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } },
++ { channel: 1, filter: 5, data: { coeff: { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } },
++};
++
++static struct tas_eq_pref_t eqp_0f_2_1 = {
++ sample_rate: 44100,
++ device_id: 0x0f,
++ output_id: TAS_OUTPUT_EXTERNAL_SPKR,
++ speaker_id: 0x01,
++
++ drce: &eqp_0f_2_1_drce,
++
++ filter_count: 12,
++ biquads: eqp_0f_2_1_biquads
++};
++
++/* ======================================================================== */
++
++static struct tas_drce_t eqp_0f_1_0_drce={
++ enable: 1,
++ above: { val: 3.0 * (1<<8), expand: 0 },
++ below: { val: 1.0 * (1<<8), expand: 0 },
++ threshold: -15.33 * (1<<8),
++ energy: 2.4 * (1<<12),
++ attack: 0.013 * (1<<12),
++ decay: 0.212 * (1<<12),
++};
++
++static struct tas_biquad_ctrl_t eqp_0f_1_0_biquads[]={
++ { channel: 0, filter: 0, data: { coeff: { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } },
++ { channel: 0, filter: 1, data: { coeff: { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } },
++ { channel: 0, filter: 2, data: { coeff: { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } },
++ { channel: 0, filter: 3, data: { coeff: { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } },
++ { channel: 0, filter: 4, data: { coeff: { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } },
++ { channel: 0, filter: 5, data: { coeff: { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } },
++
++ { channel: 1, filter: 0, data: { coeff: { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } },
++ { channel: 1, filter: 1, data: { coeff: { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } },
++ { channel: 1, filter: 2, data: { coeff: { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } },
++ { channel: 1, filter: 3, data: { coeff: { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } },
++ { channel: 1, filter: 4, data: { coeff: { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } },
++ { channel: 1, filter: 5, data: { coeff: { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } },
++};
++
++static struct tas_eq_pref_t eqp_0f_1_0 = {
++ sample_rate: 44100,
++ device_id: 0x0f,
++ output_id: TAS_OUTPUT_INTERNAL_SPKR,
++ speaker_id: 0x00,
++
++ drce: &eqp_0f_1_0_drce,
++
++ filter_count: 12,
++ biquads: eqp_0f_1_0_biquads
++};
++
++/* ======================================================================== */
++
++static uint tas3001c_master_tab[]={
++ 0x0, 0x75, 0x9c, 0xbb,
++ 0xdb, 0xfb, 0x11e, 0x143,
++ 0x16b, 0x196, 0x1c3, 0x1f5,
++ 0x229, 0x263, 0x29f, 0x2e1,
++ 0x328, 0x373, 0x3c5, 0x41b,
++ 0x478, 0x4dc, 0x547, 0x5b8,
++ 0x633, 0x6b5, 0x740, 0x7d5,
++ 0x873, 0x91c, 0x9d2, 0xa92,
++ 0xb5e, 0xc39, 0xd22, 0xe19,
++ 0xf20, 0x1037, 0x1161, 0x129e,
++ 0x13ed, 0x1551, 0x16ca, 0x185d,
++ 0x1a08, 0x1bcc, 0x1dac, 0x1fa7,
++ 0x21c1, 0x23fa, 0x2655, 0x28d6,
++ 0x2b7c, 0x2e4a, 0x3141, 0x3464,
++ 0x37b4, 0x3b35, 0x3ee9, 0x42d3,
++ 0x46f6, 0x4b53, 0x4ff0, 0x54ce,
++ 0x59f2, 0x5f5f, 0x6519, 0x6b24,
++ 0x7183, 0x783c, 0x7f53, 0x86cc,
++ 0x8ead, 0x96fa, 0x9fba, 0xa8f2,
++ 0xb2a7, 0xbce1, 0xc7a5, 0xd2fa,
++ 0xdee8, 0xeb75, 0xf8aa, 0x1068e,
++ 0x1152a, 0x12487, 0x134ad, 0x145a5,
++ 0x1577b, 0x16a37, 0x17df5, 0x192bd,
++ 0x1a890, 0x1bf7b, 0x1d78d, 0x1f0d1,
++ 0x20b55, 0x22727, 0x24456, 0x262f2,
++ 0x2830b
++};
++
++static uint tas3001c_mixer_tab[]={
++ 0x0, 0x748, 0x9be, 0xbaf,
++ 0xda4, 0xfb1, 0x11de, 0x1431,
++ 0x16ad, 0x1959, 0x1c37, 0x1f4b,
++ 0x2298, 0x2628, 0x29fb, 0x2e12,
++ 0x327d, 0x3734, 0x3c47, 0x41b4,
++ 0x4787, 0x4dbe, 0x546d, 0x5b86,
++ 0x632e, 0x6b52, 0x7400, 0x7d54,
++ 0x873b, 0x91c6, 0x9d1a, 0xa920,
++ 0xb5e5, 0xc38c, 0xd21b, 0xe18f,
++ 0xf1f5, 0x1036a, 0x1160f, 0x129d6,
++ 0x13ed0, 0x1550c, 0x16ca0, 0x185c9,
++ 0x1a07b, 0x1bcc3, 0x1dab9, 0x1fa75,
++ 0x21c0f, 0x23fa3, 0x26552, 0x28d64,
++ 0x2b7c9, 0x2e4a2, 0x31411, 0x3463b,
++ 0x37b44, 0x3b353, 0x3ee94, 0x42d30,
++ 0x46f55, 0x4b533, 0x4fefc, 0x54ce5,
++ 0x59f25, 0x5f5f6, 0x65193, 0x6b23c,
++ 0x71835, 0x783c3, 0x7f52c, 0x86cc0,
++ 0x8eacc, 0x96fa5, 0x9fba0, 0xa8f1a,
++ 0xb2a71, 0xbce0a, 0xc7a4a, 0xd2fa0,
++ 0xdee7b, 0xeb752, 0xf8a9f, 0x1068e4,
++ 0x1152a3, 0x12486a, 0x134ac8, 0x145a55,
++ 0x1577ac, 0x16a370, 0x17df51, 0x192bc2,
++ 0x1a88f8, 0x1bf7b7, 0x1d78c9, 0x1f0d04,
++ 0x20b542, 0x227268, 0x244564, 0x262f26,
++ 0x2830af
++};
++
++static uint tas3001c_treble_tab[]={
++ 0x96, 0x95, 0x95, 0x94,
++ 0x93, 0x92, 0x92, 0x91,
++ 0x90, 0x90, 0x8f, 0x8e,
++ 0x8d, 0x8d, 0x8c, 0x8b,
++ 0x8a, 0x8a, 0x89, 0x88,
++ 0x88, 0x87, 0x86, 0x85,
++ 0x85, 0x84, 0x83, 0x83,
++ 0x82, 0x81, 0x80, 0x80,
++ 0x7f, 0x7e, 0x7e, 0x7d,
++ 0x7c, 0x7b, 0x7b, 0x7a,
++ 0x79, 0x78, 0x78, 0x77,
++ 0x76, 0x76, 0x75, 0x74,
++ 0x73, 0x73, 0x72, 0x71,
++ 0x71, 0x70, 0x6e, 0x6d,
++ 0x6d, 0x6c, 0x6b, 0x6a,
++ 0x69, 0x68, 0x67, 0x66,
++ 0x65, 0x63, 0x62, 0x62,
++ 0x60, 0x5f, 0x5d, 0x5c,
++ 0x5a, 0x58, 0x56, 0x55,
++ 0x53, 0x51, 0x4f, 0x4c,
++ 0x4a, 0x48, 0x45, 0x43,
++ 0x40, 0x3d, 0x3a, 0x37,
++ 0x35, 0x32, 0x2e, 0x2a,
++ 0x27, 0x22, 0x1e, 0x1a,
++ 0x15, 0x11, 0xc, 0x7,
++ 0x1
++};
++
++static uint tas3001c_bass_tab[]={
++ 0x86, 0x83, 0x81, 0x7f,
++ 0x7d, 0x7b, 0x79, 0x78,
++ 0x76, 0x75, 0x74, 0x72,
++ 0x71, 0x6f, 0x6e, 0x6d,
++ 0x6c, 0x6b, 0x69, 0x67,
++ 0x65, 0x64, 0x61, 0x60,
++ 0x5e, 0x5d, 0x5c, 0x5b,
++ 0x5a, 0x59, 0x58, 0x57,
++ 0x56, 0x55, 0x55, 0x54,
++ 0x53, 0x52, 0x50, 0x4f,
++ 0x4d, 0x4c, 0x4b, 0x49,
++ 0x47, 0x45, 0x44, 0x42,
++ 0x41, 0x3f, 0x3e, 0x3d,
++ 0x3c, 0x3b, 0x39, 0x38,
++ 0x37, 0x36, 0x35, 0x34,
++ 0x33, 0x31, 0x30, 0x2f,
++ 0x2e, 0x2c, 0x2b, 0x2b,
++ 0x29, 0x28, 0x27, 0x26,
++ 0x25, 0x24, 0x22, 0x21,
++ 0x20, 0x1e, 0x1c, 0x19,
++ 0x18, 0x18, 0x17, 0x16,
++ 0x15, 0x14, 0x13, 0x12,
++ 0x11, 0x10, 0xf, 0xe,
++ 0xd, 0xb, 0xa, 0x9,
++ 0x8, 0x6, 0x4, 0x2,
++ 0x1
++};
++
++struct tas_gain_t tas3001c_gain = {
++ master: tas3001c_master_tab,
++ treble: tas3001c_treble_tab,
++ bass: tas3001c_bass_tab,
++ mixer: tas3001c_mixer_tab
++};
++
++struct tas_eq_pref_t *tas3001c_eq_prefs[]={
++ &eqp_0e_2_1,
++ &eqp_10_1_0,
++ &eqp_15_2_1,
++ &eqp_15_1_0,
++ &eqp_0f_2_1,
++ &eqp_0f_1_0,
++ NULL
++};
+Index: linux-2.6.0-test5/sound/oss/dmasound/tas3004.c
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/dmasound/tas3004.c 2003-09-27 11:38:18.496716456 +0800
++++ linux-2.6.0-test5/sound/oss/dmasound/tas3004.c 2003-09-27 11:38:42.462073168 +0800
+@@ -0,0 +1,1124 @@
++/*
++ * Driver for the i2c/i2s based TA3004 sound chip used
++ * on some Apple hardware. Also known as "snapper".
++ *
++ * Tobias Sargeant <tobias.sargeant@bigpond.com>
++ * Based upon tas3001c.c by Christopher C. Chimelis <chris@debian.org>:
++ *
++ * TODO:
++ * -----
++ * * Enable control over input line 2 (is this connected?)
++ * * Implement sleep support (at least mute everything and
++ * * set gains to minimum during sleep)
++ *
++ */
++
++#include <linux/version.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/proc_fs.h>
++#include <linux/ioport.h>
++#include <linux/sysctl.h>
++#include <linux/types.h>
++#include <linux/i2c.h>
++#include <linux/init.h>
++#include <linux/soundcard.h>
++#include <linux/interrupt.h>
++#include <linux/workqueue.h>
++
++#include <asm/uaccess.h>
++#include <asm/errno.h>
++#include <asm/io.h>
++#include <asm/prom.h>
++
++#include "dmasound.h"
++#include "tas_common.h"
++#include "tas3004.h"
++
++#include "tas_ioctl.h"
++
++/* #define DEBUG_DRCE */
++
++#define TAS3004_BIQUAD_FILTER_COUNT 7
++#define TAS3004_BIQUAD_CHANNEL_COUNT 2
++
++#define VOL_DEFAULT (100 * 4 / 5)
++#define INPUT_DEFAULT (100 * 4 / 5)
++#define BASS_DEFAULT (100 / 2)
++#define TREBLE_DEFAULT (100 / 2)
++
++struct tas3004_data_t {
++ struct tas_data_t super;
++ int device_id;
++ int output_id;
++ int speaker_id;
++ struct tas_drce_t drce_state;
++};
++
++#define MAKE_TIME(sec,usec) (((sec)<<12) + (50000+(usec/10)*(1<<12))/100000)
++
++#define MAKE_RATIO(i,f) (((i)<<8) + ((500+(f)*(1<<8))/1000))
++
++
++static const union tas_biquad_t tas3004_eq_unity = {
++ .buf = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 },
++};
++
++
++static const struct tas_drce_t tas3004_drce_min = {
++ .enable = 1,
++ .above = { .val = MAKE_RATIO(16,0), .expand = 0 },
++ .below = { .val = MAKE_RATIO(2,0), .expand = 0 },
++ .threshold = -0x59a0,
++ .energy = MAKE_TIME(0, 1700),
++ .attack = MAKE_TIME(0, 1700),
++ .decay = MAKE_TIME(0, 1700),
++};
++
++
++static const struct tas_drce_t tas3004_drce_max = {
++ .enable = 1,
++ .above = { .val = MAKE_RATIO(1,500), .expand = 1 },
++ .below = { .val = MAKE_RATIO(2,0), .expand = 1 },
++ .threshold = -0x0,
++ .energy = MAKE_TIME(2,400000),
++ .attack = MAKE_TIME(2,400000),
++ .decay = MAKE_TIME(2,400000),
++};
++
++
++static const unsigned short time_constants[]={
++ MAKE_TIME(0, 1700),
++ MAKE_TIME(0, 3500),
++ MAKE_TIME(0, 6700),
++ MAKE_TIME(0, 13000),
++ MAKE_TIME(0, 26000),
++ MAKE_TIME(0, 53000),
++ MAKE_TIME(0,106000),
++ MAKE_TIME(0,212000),
++ MAKE_TIME(0,425000),
++ MAKE_TIME(0,850000),
++ MAKE_TIME(1,700000),
++ MAKE_TIME(2,400000),
++};
++
++static const unsigned short above_threshold_compression_ratio[]={
++ MAKE_RATIO( 1, 70),
++ MAKE_RATIO( 1,140),
++ MAKE_RATIO( 1,230),
++ MAKE_RATIO( 1,330),
++ MAKE_RATIO( 1,450),
++ MAKE_RATIO( 1,600),
++ MAKE_RATIO( 1,780),
++ MAKE_RATIO( 2, 0),
++ MAKE_RATIO( 2,290),
++ MAKE_RATIO( 2,670),
++ MAKE_RATIO( 3,200),
++ MAKE_RATIO( 4, 0),
++ MAKE_RATIO( 5,330),
++ MAKE_RATIO( 8, 0),
++ MAKE_RATIO(16, 0),
++};
++
++static const unsigned short above_threshold_expansion_ratio[]={
++ MAKE_RATIO(1, 60),
++ MAKE_RATIO(1,130),
++ MAKE_RATIO(1,190),
++ MAKE_RATIO(1,250),
++ MAKE_RATIO(1,310),
++ MAKE_RATIO(1,380),
++ MAKE_RATIO(1,440),
++ MAKE_RATIO(1,500)
++};
++
++static const unsigned short below_threshold_compression_ratio[]={
++ MAKE_RATIO(1, 70),
++ MAKE_RATIO(1,140),
++ MAKE_RATIO(1,230),
++ MAKE_RATIO(1,330),
++ MAKE_RATIO(1,450),
++ MAKE_RATIO(1,600),
++ MAKE_RATIO(1,780),
++ MAKE_RATIO(2, 0)
++};
++
++static const unsigned short below_threshold_expansion_ratio[]={
++ MAKE_RATIO(1, 60),
++ MAKE_RATIO(1,130),
++ MAKE_RATIO(1,190),
++ MAKE_RATIO(1,250),
++ MAKE_RATIO(1,310),
++ MAKE_RATIO(1,380),
++ MAKE_RATIO(1,440),
++ MAKE_RATIO(1,500),
++ MAKE_RATIO(1,560),
++ MAKE_RATIO(1,630),
++ MAKE_RATIO(1,690),
++ MAKE_RATIO(1,750),
++ MAKE_RATIO(1,810),
++ MAKE_RATIO(1,880),
++ MAKE_RATIO(1,940),
++ MAKE_RATIO(2, 0)
++};
++
++static inline int
++search( unsigned short val,
++ const unsigned short *arr,
++ const int arrsize) {
++ /*
++ * This could be a binary search, but for small tables,
++ * a linear search is likely to be faster
++ */
++
++ int i;
++
++ for (i=0; i < arrsize; i++)
++ if (arr[i] >= val)
++ goto _1;
++ return arrsize-1;
++ _1:
++ if (i == 0)
++ return 0;
++ return (arr[i]-val < val-arr[i-1]) ? i : i-1;
++}
++
++#define SEARCH(a, b) search(a, b, ARRAY_SIZE(b))
++
++static inline int
++time_index(unsigned short time)
++{
++ return SEARCH(time, time_constants);
++}
++
++
++static inline int
++above_threshold_compression_index(unsigned short ratio)
++{
++ return SEARCH(ratio, above_threshold_compression_ratio);
++}
++
++
++static inline int
++above_threshold_expansion_index(unsigned short ratio)
++{
++ return SEARCH(ratio, above_threshold_expansion_ratio);
++}
++
++
++static inline int
++below_threshold_compression_index(unsigned short ratio)
++{
++ return SEARCH(ratio, below_threshold_compression_ratio);
++}
++
++
++static inline int
++below_threshold_expansion_index(unsigned short ratio)
++{
++ return SEARCH(ratio, below_threshold_expansion_ratio);
++}
++
++static inline unsigned char db_to_regval(short db) {
++ int r=0;
++
++ r=(db+0x59a0) / 0x60;
++
++ if (r < 0x91) return 0x91;
++ if (r > 0xef) return 0xef;
++ return r;
++}
++
++static inline short quantize_db(short db)
++{
++ return db_to_regval(db) * 0x60 - 0x59a0;
++}
++
++static inline int
++register_width(enum tas3004_reg_t r)
++{
++ switch(r) {
++ case TAS3004_REG_MCR:
++ case TAS3004_REG_TREBLE:
++ case TAS3004_REG_BASS:
++ case TAS3004_REG_ANALOG_CTRL:
++ case TAS3004_REG_TEST1:
++ case TAS3004_REG_TEST2:
++ case TAS3004_REG_MCR2:
++ return 1;
++
++ case TAS3004_REG_LEFT_LOUD_BIQUAD_GAIN:
++ case TAS3004_REG_RIGHT_LOUD_BIQUAD_GAIN:
++ return 3;
++
++ case TAS3004_REG_DRC:
++ case TAS3004_REG_VOLUME:
++ return 6;
++
++ case TAS3004_REG_LEFT_MIXER:
++ case TAS3004_REG_RIGHT_MIXER:
++ return 9;
++
++ case TAS3004_REG_TEST:
++ return 10;
++
++ case TAS3004_REG_LEFT_BIQUAD0:
++ case TAS3004_REG_LEFT_BIQUAD1:
++ case TAS3004_REG_LEFT_BIQUAD2:
++ case TAS3004_REG_LEFT_BIQUAD3:
++ case TAS3004_REG_LEFT_BIQUAD4:
++ case TAS3004_REG_LEFT_BIQUAD5:
++ case TAS3004_REG_LEFT_BIQUAD6:
++
++ case TAS3004_REG_RIGHT_BIQUAD0:
++ case TAS3004_REG_RIGHT_BIQUAD1:
++ case TAS3004_REG_RIGHT_BIQUAD2:
++ case TAS3004_REG_RIGHT_BIQUAD3:
++ case TAS3004_REG_RIGHT_BIQUAD4:
++ case TAS3004_REG_RIGHT_BIQUAD5:
++ case TAS3004_REG_RIGHT_BIQUAD6:
++
++ case TAS3004_REG_LEFT_LOUD_BIQUAD:
++ case TAS3004_REG_RIGHT_LOUD_BIQUAD:
++ return 15;
++
++ default:
++ return 0;
++ }
++}
++
++static int
++tas3004_write_register( struct tas3004_data_t *self,
++ enum tas3004_reg_t reg_num,
++ char *data,
++ uint write_mode)
++{
++ if (reg_num==TAS3004_REG_MCR ||
++ reg_num==TAS3004_REG_BASS ||
++ reg_num==TAS3004_REG_TREBLE) {
++ return tas_write_byte_register(&self->super,
++ (uint)reg_num,
++ *data,
++ write_mode);
++ } else {
++ return tas_write_register(&self->super,
++ (uint)reg_num,
++ register_width(reg_num),
++ data,
++ write_mode);
++ }
++}
++
++static int
++tas3004_sync_register( struct tas3004_data_t *self,
++ enum tas3004_reg_t reg_num)
++{
++ if (reg_num==TAS3004_REG_MCR ||
++ reg_num==TAS3004_REG_BASS ||
++ reg_num==TAS3004_REG_TREBLE) {
++ return tas_sync_byte_register(&self->super,
++ (uint)reg_num,
++ register_width(reg_num));
++ } else {
++ return tas_sync_register(&self->super,
++ (uint)reg_num,
++ register_width(reg_num));
++ }
++}
++
++static int
++tas3004_read_register( struct tas3004_data_t *self,
++ enum tas3004_reg_t reg_num,
++ char *data,
++ uint write_mode)
++{
++ return tas_read_register(&self->super,
++ (uint)reg_num,
++ register_width(reg_num),
++ data);
++}
++
++static inline int
++tas3004_fast_load(struct tas3004_data_t *self, int fast)
++{
++ if (fast)
++ self->super.shadow[TAS3004_REG_MCR][0] |= 0x80;
++ else
++ self->super.shadow[TAS3004_REG_MCR][0] &= 0x7f;
++ return tas3004_sync_register(self,TAS3004_REG_MCR);
++}
++
++static uint
++tas3004_supported_mixers(struct tas3004_data_t *self)
++{
++ return SOUND_MASK_VOLUME |
++ SOUND_MASK_PCM |
++ SOUND_MASK_ALTPCM |
++ SOUND_MASK_IMIX |
++ SOUND_MASK_TREBLE |
++ SOUND_MASK_BASS;
++}
++
++static int
++tas3004_mixer_is_stereo(struct tas3004_data_t *self, int mixer)
++{
++ switch(mixer) {
++ case SOUND_MIXER_VOLUME:
++ case SOUND_MIXER_PCM:
++ case SOUND_MIXER_ALTPCM:
++ case SOUND_MIXER_IMIX:
++ return 1;
++ default:
++ return 0;
++ }
++}
++
++static uint
++tas3004_stereo_mixers(struct tas3004_data_t *self)
++{
++ uint r = tas3004_supported_mixers(self);
++ uint i;
++
++ for (i=1; i<SOUND_MIXER_NRDEVICES; i++)
++ if (r&(1<<i) && !tas3004_mixer_is_stereo(self,i))
++ r &= ~(1<<i);
++ return r;
++}
++
++static int
++tas3004_get_mixer_level(struct tas3004_data_t *self, int mixer, uint *level)
++{
++ if (!self)
++ return -1;
++
++ *level = self->super.mixer[mixer];
++
++ return 0;
++}
++
++static int
++tas3004_set_mixer_level(struct tas3004_data_t *self, int mixer, uint level)
++{
++ int rc;
++ tas_shadow_t *shadow;
++ uint temp;
++ uint offset=0;
++
++ if (!self)
++ return -1;
++
++ shadow = self->super.shadow;
++
++ if (!tas3004_mixer_is_stereo(self,mixer))
++ level = tas_mono_to_stereo(level);
++ switch(mixer) {
++ case SOUND_MIXER_VOLUME:
++ temp = tas3004_gain.master[level&0xff];
++ SET_4_20(shadow[TAS3004_REG_VOLUME], 0, temp);
++ temp = tas3004_gain.master[(level>>8)&0xff];
++ SET_4_20(shadow[TAS3004_REG_VOLUME], 3, temp);
++ rc = tas3004_sync_register(self,TAS3004_REG_VOLUME);
++ break;
++ case SOUND_MIXER_IMIX:
++ offset += 3;
++ case SOUND_MIXER_ALTPCM:
++ offset += 3;
++ case SOUND_MIXER_PCM:
++ /*
++ * Don't load these in fast mode. The documentation
++ * says it can be done in either mode, but testing it
++ * shows that fast mode produces ugly clicking.
++ */
++ /* tas3004_fast_load(self,1); */
++ temp = tas3004_gain.mixer[level&0xff];
++ SET_4_20(shadow[TAS3004_REG_LEFT_MIXER], offset, temp);
++ temp = tas3004_gain.mixer[(level>>8)&0xff];
++ SET_4_20(shadow[TAS3004_REG_RIGHT_MIXER], offset, temp);
++ rc = tas3004_sync_register(self,TAS3004_REG_LEFT_MIXER);
++ if (rc == 0)
++ rc=tas3004_sync_register(self,TAS3004_REG_RIGHT_MIXER);
++ /* tas3004_fast_load(self,0); */
++ break;
++ case SOUND_MIXER_TREBLE:
++ temp = tas3004_gain.treble[level&0xff];
++ shadow[TAS3004_REG_TREBLE][0]=temp&0xff;
++ rc = tas3004_sync_register(self,TAS3004_REG_TREBLE);
++ break;
++ case SOUND_MIXER_BASS:
++ temp = tas3004_gain.bass[level&0xff];
++ shadow[TAS3004_REG_BASS][0]=temp&0xff;
++ rc = tas3004_sync_register(self,TAS3004_REG_BASS);
++ break;
++ default:
++ rc = -1;
++ break;
++ }
++ if (rc < 0)
++ return rc;
++ self->super.mixer[mixer] = level;
++
++ return 0;
++}
++
++static int
++tas3004_leave_sleep(struct tas3004_data_t *self)
++{
++ unsigned char mcr = (1<<6)+(2<<4)+(2<<2);
++
++ if (!self)
++ return -1;
++
++ /* Make sure something answers on the i2c bus */
++ if (tas3004_write_register(self, TAS3004_REG_MCR, &mcr,
++ WRITE_NORMAL | FORCE_WRITE) < 0)
++ return -1;
++
++ tas3004_fast_load(self, 1);
++
++ (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD0);
++ (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD1);
++ (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD2);
++ (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD3);
++ (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD4);
++ (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD5);
++ (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD6);
++
++ (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD0);
++ (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD1);
++ (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD2);
++ (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD3);
++ (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD4);
++ (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD5);
++ (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD6);
++
++ tas3004_fast_load(self, 0);
++
++ (void)tas3004_sync_register(self,TAS3004_REG_VOLUME);
++ (void)tas3004_sync_register(self,TAS3004_REG_LEFT_MIXER);
++ (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_MIXER);
++ (void)tas3004_sync_register(self,TAS3004_REG_TREBLE);
++ (void)tas3004_sync_register(self,TAS3004_REG_BASS);
++
++ return 0;
++}
++
++static int
++tas3004_enter_sleep(struct tas3004_data_t *self)
++{
++ if (!self)
++ return -1;
++ return 0;
++}
++
++static int
++tas3004_sync_biquad( struct tas3004_data_t *self,
++ u_int channel,
++ u_int filter)
++{
++ enum tas3004_reg_t reg;
++
++ if (channel >= TAS3004_BIQUAD_CHANNEL_COUNT ||
++ filter >= TAS3004_BIQUAD_FILTER_COUNT) return -EINVAL;
++
++ reg=( channel ? TAS3004_REG_RIGHT_BIQUAD0 : TAS3004_REG_LEFT_BIQUAD0 ) + filter;
++
++ return tas3004_sync_register(self,reg);
++}
++
++static int
++tas3004_write_biquad_shadow( struct tas3004_data_t *self,
++ u_int channel,
++ u_int filter,
++ const union tas_biquad_t *biquad)
++{
++ tas_shadow_t *shadow=self->super.shadow;
++ enum tas3004_reg_t reg;
++
++ if (channel >= TAS3004_BIQUAD_CHANNEL_COUNT ||
++ filter >= TAS3004_BIQUAD_FILTER_COUNT) return -EINVAL;
++
++ reg=( channel ? TAS3004_REG_RIGHT_BIQUAD0 : TAS3004_REG_LEFT_BIQUAD0 ) + filter;
++
++ SET_4_20(shadow[reg], 0,biquad->coeff.b0);
++ SET_4_20(shadow[reg], 3,biquad->coeff.b1);
++ SET_4_20(shadow[reg], 6,biquad->coeff.b2);
++ SET_4_20(shadow[reg], 9,biquad->coeff.a1);
++ SET_4_20(shadow[reg],12,biquad->coeff.a2);
++
++ return 0;
++}
++
++static int
++tas3004_write_biquad( struct tas3004_data_t *self,
++ u_int channel,
++ u_int filter,
++ const union tas_biquad_t *biquad)
++{
++ int rc;
++
++ rc=tas3004_write_biquad_shadow(self, channel, filter, biquad);
++ if (rc < 0) return rc;
++
++ return tas3004_sync_biquad(self, channel, filter);
++}
++
++static int
++tas3004_write_biquad_list( struct tas3004_data_t *self,
++ u_int filter_count,
++ u_int flags,
++ struct tas_biquad_ctrl_t *biquads)
++{
++ int i;
++ int rc;
++
++ if (flags & TAS_BIQUAD_FAST_LOAD) tas3004_fast_load(self,1);
++
++ for (i=0; i<filter_count; i++) {
++ rc=tas3004_write_biquad(self,
++ biquads[i].channel,
++ biquads[i].filter,
++ &biquads[i].data);
++ if (rc < 0) break;
++ }
++
++ if (flags & TAS_BIQUAD_FAST_LOAD) tas3004_fast_load(self,0);
++
++ return rc;
++}
++
++static int
++tas3004_read_biquad( struct tas3004_data_t *self,
++ u_int channel,
++ u_int filter,
++ union tas_biquad_t *biquad)
++{
++ tas_shadow_t *shadow=self->super.shadow;
++ enum tas3004_reg_t reg;
++
++ if (channel >= TAS3004_BIQUAD_CHANNEL_COUNT ||
++ filter >= TAS3004_BIQUAD_FILTER_COUNT) return -EINVAL;
++
++ reg=( channel ? TAS3004_REG_RIGHT_BIQUAD0 : TAS3004_REG_LEFT_BIQUAD0 ) + filter;
++
++ biquad->coeff.b0=GET_4_20(shadow[reg], 0);
++ biquad->coeff.b1=GET_4_20(shadow[reg], 3);
++ biquad->coeff.b2=GET_4_20(shadow[reg], 6);
++ biquad->coeff.a1=GET_4_20(shadow[reg], 9);
++ biquad->coeff.a2=GET_4_20(shadow[reg],12);
++
++ return 0;
++}
++
++static int
++tas3004_eq_rw( struct tas3004_data_t *self,
++ u_int cmd,
++ u_long arg)
++{
++ int rc;
++ struct tas_biquad_ctrl_t biquad;
++
++ if (copy_from_user((void *)&biquad, (const void *)arg, sizeof(struct tas_biquad_ctrl_t))) {
++ return -EFAULT;
++ }
++
++ if (cmd & SIOC_IN) {
++ rc=tas3004_write_biquad(self, biquad.channel, biquad.filter, &biquad.data);
++ if (rc != 0) return rc;
++ }
++
++ if (cmd & SIOC_OUT) {
++ rc=tas3004_read_biquad(self, biquad.channel, biquad.filter, &biquad.data);
++ if (rc != 0) return rc;
++
++ if (copy_to_user((void *)arg, (const void *)&biquad, sizeof(struct tas_biquad_ctrl_t))) {
++ return -EFAULT;
++ }
++
++ }
++ return 0;
++}
++
++static int
++tas3004_eq_list_rw( struct tas3004_data_t *self,
++ u_int cmd,
++ u_long arg)
++{
++ int rc = 0;
++ int filter_count;
++ int flags;
++ int i,j;
++ char sync_required[TAS3004_BIQUAD_CHANNEL_COUNT][TAS3004_BIQUAD_FILTER_COUNT];
++ struct tas_biquad_ctrl_t biquad;
++
++ memset(sync_required,0,sizeof(sync_required));
++
++ if (copy_from_user((void *)&filter_count,
++ (const void *)arg + offsetof(struct tas_biquad_ctrl_list_t,filter_count),
++ sizeof(int))) {
++ return -EFAULT;
++ }
++
++ if (copy_from_user((void *)&flags,
++ (const void *)arg + offsetof(struct tas_biquad_ctrl_list_t,flags),
++ sizeof(int))) {
++ return -EFAULT;
++ }
++
++ if (cmd & SIOC_IN) {
++ }
++
++ for (i=0; i < filter_count; i++) {
++ if (copy_from_user((void *)&biquad,
++ (const void *)arg + offsetof(struct tas_biquad_ctrl_list_t, biquads[i]),
++ sizeof(struct tas_biquad_ctrl_t))) {
++ return -EFAULT;
++ }
++
++ if (cmd & SIOC_IN) {
++ sync_required[biquad.channel][biquad.filter]=1;
++ rc=tas3004_write_biquad_shadow(self, biquad.channel, biquad.filter, &biquad.data);
++ if (rc != 0) return rc;
++ }
++
++ if (cmd & SIOC_OUT) {
++ rc=tas3004_read_biquad(self, biquad.channel, biquad.filter, &biquad.data);
++ if (rc != 0) return rc;
++
++ if (copy_to_user((void *)arg + offsetof(struct tas_biquad_ctrl_list_t, biquads[i]),
++ (const void *)&biquad,
++ sizeof(struct tas_biquad_ctrl_t))) {
++ return -EFAULT;
++ }
++ }
++ }
++
++ if (cmd & SIOC_IN) {
++ /*
++ * This is OK for the tas3004. For the
++ * tas3001c, going into fast load mode causes
++ * the treble and bass to be reset to 0dB, and
++ * volume controls to be muted.
++ */
++ if (flags & TAS_BIQUAD_FAST_LOAD) tas3004_fast_load(self,1);
++ for (i=0; i<TAS3004_BIQUAD_CHANNEL_COUNT; i++) {
++ for (j=0; j<TAS3004_BIQUAD_FILTER_COUNT; j++) {
++ if (sync_required[i][j]) {
++ rc=tas3004_sync_biquad(self, i, j);
++ if (rc < 0) goto out;
++ }
++ }
++ }
++ out:
++ if (flags & TAS_BIQUAD_FAST_LOAD)
++ tas3004_fast_load(self,0);
++ }
++
++ return rc;
++}
++
++static int
++tas3004_update_drce( struct tas3004_data_t *self,
++ int flags,
++ struct tas_drce_t *drce)
++{
++ tas_shadow_t *shadow;
++ int i;
++ shadow=self->super.shadow;
++
++ if (flags & TAS_DRCE_ABOVE_RATIO) {
++ self->drce_state.above.expand = drce->above.expand;
++ if (drce->above.val == (1<<8)) {
++ self->drce_state.above.val = 1<<8;
++ shadow[TAS3004_REG_DRC][0] = 0x02;
++
++ } else if (drce->above.expand) {
++ i=above_threshold_expansion_index(drce->above.val);
++ self->drce_state.above.val=above_threshold_expansion_ratio[i];
++ shadow[TAS3004_REG_DRC][0] = 0x0a + (i<<3);
++ } else {
++ i=above_threshold_compression_index(drce->above.val);
++ self->drce_state.above.val=above_threshold_compression_ratio[i];
++ shadow[TAS3004_REG_DRC][0] = 0x08 + (i<<3);
++ }
++ }
++
++ if (flags & TAS_DRCE_BELOW_RATIO) {
++ self->drce_state.below.expand = drce->below.expand;
++ if (drce->below.val == (1<<8)) {
++ self->drce_state.below.val = 1<<8;
++ shadow[TAS3004_REG_DRC][1] = 0x02;
++
++ } else if (drce->below.expand) {
++ i=below_threshold_expansion_index(drce->below.val);
++ self->drce_state.below.val=below_threshold_expansion_ratio[i];
++ shadow[TAS3004_REG_DRC][1] = 0x08 + (i<<3);
++ } else {
++ i=below_threshold_compression_index(drce->below.val);
++ self->drce_state.below.val=below_threshold_compression_ratio[i];
++ shadow[TAS3004_REG_DRC][1] = 0x0a + (i<<3);
++ }
++ }
++
++ if (flags & TAS_DRCE_THRESHOLD) {
++ self->drce_state.threshold=quantize_db(drce->threshold);
++ shadow[TAS3004_REG_DRC][2] = db_to_regval(self->drce_state.threshold);
++ }
++
++ if (flags & TAS_DRCE_ENERGY) {
++ i=time_index(drce->energy);
++ self->drce_state.energy=time_constants[i];
++ shadow[TAS3004_REG_DRC][3] = 0x40 + (i<<4);
++ }
++
++ if (flags & TAS_DRCE_ATTACK) {
++ i=time_index(drce->attack);
++ self->drce_state.attack=time_constants[i];
++ shadow[TAS3004_REG_DRC][4] = 0x40 + (i<<4);
++ }
++
++ if (flags & TAS_DRCE_DECAY) {
++ i=time_index(drce->decay);
++ self->drce_state.decay=time_constants[i];
++ shadow[TAS3004_REG_DRC][5] = 0x40 + (i<<4);
++ }
++
++ if (flags & TAS_DRCE_ENABLE) {
++ self->drce_state.enable = drce->enable;
++ }
++
++ if (!self->drce_state.enable) {
++ shadow[TAS3004_REG_DRC][0] |= 0x01;
++ }
++
++#ifdef DEBUG_DRCE
++ printk("DRCE: set [ ENABLE:%x ABOVE:%x/%x BELOW:%x/%x THRESH:%x ENERGY:%x ATTACK:%x DECAY:%x\n",
++ self->drce_state.enable,
++ self->drce_state.above.expand,self->drce_state.above.val,
++ self->drce_state.below.expand,self->drce_state.below.val,
++ self->drce_state.threshold,
++ self->drce_state.energy,
++ self->drce_state.attack,
++ self->drce_state.decay);
++
++ printk("DRCE: reg [ %02x %02x %02x %02x %02x %02x ]\n",
++ (unsigned char)shadow[TAS3004_REG_DRC][0],
++ (unsigned char)shadow[TAS3004_REG_DRC][1],
++ (unsigned char)shadow[TAS3004_REG_DRC][2],
++ (unsigned char)shadow[TAS3004_REG_DRC][3],
++ (unsigned char)shadow[TAS3004_REG_DRC][4],
++ (unsigned char)shadow[TAS3004_REG_DRC][5]);
++#endif
++
++ return tas3004_sync_register(self, TAS3004_REG_DRC);
++}
++
++static int
++tas3004_drce_rw( struct tas3004_data_t *self,
++ u_int cmd,
++ u_long arg)
++{
++ int rc;
++ struct tas_drce_ctrl_t drce_ctrl;
++
++ if (copy_from_user((void *)&drce_ctrl,
++ (const void *)arg,
++ sizeof(struct tas_drce_ctrl_t))) {
++ return -EFAULT;
++ }
++
++#ifdef DEBUG_DRCE
++ printk("DRCE: input [ FLAGS:%x ENABLE:%x ABOVE:%x/%x BELOW:%x/%x THRESH:%x ENERGY:%x ATTACK:%x DECAY:%x\n",
++ drce_ctrl.flags,
++ drce_ctrl.data.enable,
++ drce_ctrl.data.above.expand,drce_ctrl.data.above.val,
++ drce_ctrl.data.below.expand,drce_ctrl.data.below.val,
++ drce_ctrl.data.threshold,
++ drce_ctrl.data.energy,
++ drce_ctrl.data.attack,
++ drce_ctrl.data.decay);
++#endif
++
++ if (cmd & SIOC_IN) {
++ rc = tas3004_update_drce(self, drce_ctrl.flags, &drce_ctrl.data);
++ if (rc < 0) return rc;
++ }
++
++ if (cmd & SIOC_OUT) {
++ if (drce_ctrl.flags & TAS_DRCE_ENABLE)
++ drce_ctrl.data.enable = self->drce_state.enable;
++ if (drce_ctrl.flags & TAS_DRCE_ABOVE_RATIO)
++ drce_ctrl.data.above = self->drce_state.above;
++ if (drce_ctrl.flags & TAS_DRCE_BELOW_RATIO)
++ drce_ctrl.data.below = self->drce_state.below;
++ if (drce_ctrl.flags & TAS_DRCE_THRESHOLD)
++ drce_ctrl.data.threshold = self->drce_state.threshold;
++ if (drce_ctrl.flags & TAS_DRCE_ENERGY)
++ drce_ctrl.data.energy = self->drce_state.energy;
++ if (drce_ctrl.flags & TAS_DRCE_ATTACK)
++ drce_ctrl.data.attack = self->drce_state.attack;
++ if (drce_ctrl.flags & TAS_DRCE_DECAY)
++ drce_ctrl.data.decay = self->drce_state.decay;
++
++ if (copy_to_user((void *)arg,
++ (const void *)&drce_ctrl,
++ sizeof(struct tas_drce_ctrl_t))) {
++ return -EFAULT;
++ }
++ }
++
++ return 0;
++}
++
++static void
++tas3004_update_device_parameters(struct tas3004_data_t *self)
++{
++ char data;
++ int i;
++
++ if (!self) return;
++
++ if (self->output_id == TAS_OUTPUT_HEADPHONES) {
++ /* turn on allPass when headphones are plugged in */
++ data = 0x02;
++ } else {
++ data = 0x00;
++ }
++
++ tas3004_write_register(self, TAS3004_REG_MCR2, &data, WRITE_NORMAL | FORCE_WRITE);
++
++ for (i=0; tas3004_eq_prefs[i]; i++) {
++ struct tas_eq_pref_t *eq = tas3004_eq_prefs[i];
++
++ if (eq->device_id == self->device_id &&
++ (eq->output_id == 0 || eq->output_id == self->output_id) &&
++ (eq->speaker_id == 0 || eq->speaker_id == self->speaker_id)) {
++
++ tas3004_update_drce(self, TAS_DRCE_ALL, eq->drce);
++ tas3004_write_biquad_list(self, eq->filter_count, TAS_BIQUAD_FAST_LOAD, eq->biquads);
++
++ break;
++ }
++ }
++}
++
++static void
++tas3004_device_change_handler(void *self)
++{
++ if (!self) return;
++
++ tas3004_update_device_parameters((struct tas3004_data_t *)self);
++}
++
++static struct work_struct device_change;
++
++static int
++tas3004_output_device_change( struct tas3004_data_t *self,
++ int device_id,
++ int output_id,
++ int speaker_id)
++{
++ self->device_id=device_id;
++ self->output_id=output_id;
++ self->speaker_id=speaker_id;
++
++ schedule_work(&device_change);
++
++ return 0;
++}
++
++static int
++tas3004_device_ioctl( struct tas3004_data_t *self,
++ u_int cmd,
++ u_long arg)
++{
++ switch (cmd) {
++ case TAS_READ_EQ:
++ case TAS_WRITE_EQ:
++ return tas3004_eq_rw(self, cmd, arg);
++
++ case TAS_READ_EQ_LIST:
++ case TAS_WRITE_EQ_LIST:
++ return tas3004_eq_list_rw(self, cmd, arg);
++
++ case TAS_READ_EQ_FILTER_COUNT:
++ put_user(TAS3004_BIQUAD_FILTER_COUNT, (uint *)(arg));
++ return 0;
++
++ case TAS_READ_EQ_CHANNEL_COUNT:
++ put_user(TAS3004_BIQUAD_CHANNEL_COUNT, (uint *)(arg));
++ return 0;
++
++ case TAS_READ_DRCE:
++ case TAS_WRITE_DRCE:
++ return tas3004_drce_rw(self, cmd, arg);
++
++ case TAS_READ_DRCE_CAPS:
++ put_user(TAS_DRCE_ENABLE |
++ TAS_DRCE_ABOVE_RATIO |
++ TAS_DRCE_BELOW_RATIO |
++ TAS_DRCE_THRESHOLD |
++ TAS_DRCE_ENERGY |
++ TAS_DRCE_ATTACK |
++ TAS_DRCE_DECAY,
++ (uint *)(arg));
++ return 0;
++
++ case TAS_READ_DRCE_MIN:
++ case TAS_READ_DRCE_MAX: {
++ struct tas_drce_ctrl_t drce_ctrl;
++ const struct tas_drce_t *drce_copy;
++
++ if (copy_from_user((void *)&drce_ctrl,
++ (const void *)arg,
++ sizeof(struct tas_drce_ctrl_t))) {
++ return -EFAULT;
++ }
++
++ if (cmd == TAS_READ_DRCE_MIN) {
++ drce_copy=&tas3004_drce_min;
++ } else {
++ drce_copy=&tas3004_drce_max;
++ }
++
++ if (drce_ctrl.flags & TAS_DRCE_ABOVE_RATIO) {
++ drce_ctrl.data.above=drce_copy->above;
++ }
++ if (drce_ctrl.flags & TAS_DRCE_BELOW_RATIO) {
++ drce_ctrl.data.below=drce_copy->below;
++ }
++ if (drce_ctrl.flags & TAS_DRCE_THRESHOLD) {
++ drce_ctrl.data.threshold=drce_copy->threshold;
++ }
++ if (drce_ctrl.flags & TAS_DRCE_ENERGY) {
++ drce_ctrl.data.energy=drce_copy->energy;
++ }
++ if (drce_ctrl.flags & TAS_DRCE_ATTACK) {
++ drce_ctrl.data.attack=drce_copy->attack;
++ }
++ if (drce_ctrl.flags & TAS_DRCE_DECAY) {
++ drce_ctrl.data.decay=drce_copy->decay;
++ }
++
++ if (copy_to_user((void *)arg,
++ (const void *)&drce_ctrl,
++ sizeof(struct tas_drce_ctrl_t))) {
++ return -EFAULT;
++ }
++ }
++ }
++
++ return -EINVAL;
++}
++
++static int
++tas3004_init_mixer(struct tas3004_data_t *self)
++{
++ unsigned char mcr = (1<<6)+(2<<4)+(2<<2);
++
++ /* Make sure something answers on the i2c bus */
++ if (tas3004_write_register(self, TAS3004_REG_MCR, &mcr,
++ WRITE_NORMAL | FORCE_WRITE) < 0)
++ return -1;
++
++ tas3004_fast_load(self, 1);
++
++ (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD0);
++ (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD1);
++ (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD2);
++ (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD3);
++ (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD4);
++ (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD5);
++ (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD6);
++
++ (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD0);
++ (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD1);
++ (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD2);
++ (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD3);
++ (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD4);
++ (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD5);
++ (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD6);
++
++ tas3004_sync_register(self, TAS3004_REG_DRC);
++
++ tas3004_sync_register(self, TAS3004_REG_MCR2);
++
++ tas3004_fast_load(self, 0);
++
++ tas3004_set_mixer_level(self, SOUND_MIXER_VOLUME, VOL_DEFAULT<<8 | VOL_DEFAULT);
++ tas3004_set_mixer_level(self, SOUND_MIXER_PCM, INPUT_DEFAULT<<8 | INPUT_DEFAULT);
++ tas3004_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0);
++ tas3004_set_mixer_level(self, SOUND_MIXER_IMIX, 0);
++
++ tas3004_set_mixer_level(self, SOUND_MIXER_BASS, BASS_DEFAULT);
++ tas3004_set_mixer_level(self, SOUND_MIXER_TREBLE, TREBLE_DEFAULT);
++
++ return 0;
++}
++
++static int
++tas3004_uninit_mixer(struct tas3004_data_t *self)
++{
++ tas3004_set_mixer_level(self, SOUND_MIXER_VOLUME, 0);
++ tas3004_set_mixer_level(self, SOUND_MIXER_PCM, 0);
++ tas3004_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0);
++ tas3004_set_mixer_level(self, SOUND_MIXER_IMIX, 0);
++
++ tas3004_set_mixer_level(self, SOUND_MIXER_BASS, 0);
++ tas3004_set_mixer_level(self, SOUND_MIXER_TREBLE, 0);
++
++ return 0;
++}
++
++static int
++tas3004_init(struct i2c_client *client)
++{
++ struct tas3004_data_t *self;
++ size_t sz = sizeof(*self) + (TAS3004_REG_MAX*sizeof(tas_shadow_t));
++ char drce_init[] = { 0x69, 0x22, 0x9f, 0xb0, 0x60, 0xa0 };
++ char mcr2 = 0;
++ int i, j;
++
++ self = kmalloc(sz, GFP_KERNEL);
++ if (!self)
++ return -ENOMEM;
++ memset(self, 0, sz);
++
++ self->super.client = client;
++ self->super.shadow = (tas_shadow_t *)(self+1);
++ self->output_id = TAS_OUTPUT_HEADPHONES;
++
++ dev_set_drvdata(&client->dev, self);
++
++ for (i = 0; i < TAS3004_BIQUAD_CHANNEL_COUNT; i++)
++ for (j = 0; j<TAS3004_BIQUAD_FILTER_COUNT; j++)
++ tas3004_write_biquad_shadow(self, i, j,
++ &tas3004_eq_unity);
++
++ tas3004_write_register(self, TAS3004_REG_MCR2, &mcr2, WRITE_SHADOW);
++ tas3004_write_register(self, TAS3004_REG_DRC, drce_init, WRITE_SHADOW);
++
++ INIT_WORK(&device_change, tas3004_device_change_handler, self);
++ return 0;
++}
++
++static void
++tas3004_uninit(struct tas3004_data_t *self)
++{
++ tas3004_uninit_mixer(self);
++ kfree(self);
++}
++
++
++struct tas_driver_hooks_t tas3004_hooks = {
++ .init = (tas_hook_init_t)tas3004_init,
++ .post_init = (tas_hook_post_init_t)tas3004_init_mixer,
++ .uninit = (tas_hook_uninit_t)tas3004_uninit,
++ .get_mixer_level = (tas_hook_get_mixer_level_t)tas3004_get_mixer_level,
++ .set_mixer_level = (tas_hook_set_mixer_level_t)tas3004_set_mixer_level,
++ .enter_sleep = (tas_hook_enter_sleep_t)tas3004_enter_sleep,
++ .leave_sleep = (tas_hook_leave_sleep_t)tas3004_leave_sleep,
++ .supported_mixers = (tas_hook_supported_mixers_t)tas3004_supported_mixers,
++ .mixer_is_stereo = (tas_hook_mixer_is_stereo_t)tas3004_mixer_is_stereo,
++ .stereo_mixers = (tas_hook_stereo_mixers_t)tas3004_stereo_mixers,
++ .output_device_change = (tas_hook_output_device_change_t)tas3004_output_device_change,
++ .device_ioctl = (tas_hook_device_ioctl_t)tas3004_device_ioctl
++};
+Index: linux-2.6.0-test5/sound/oss/dmasound/tas3004.h
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/dmasound/tas3004.h 2003-09-27 11:38:18.496716456 +0800
++++ linux-2.6.0-test5/sound/oss/dmasound/tas3004.h 2003-09-27 11:38:42.462073168 +0800
+@@ -0,0 +1,77 @@
++/*
++ * Header file for the i2c/i2s based TA3004 sound chip used
++ * on some Apple hardware. Also known as "tumbler".
++ *
++ * 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.
++ *
++ * Written by Christopher C. Chimelis <chris@debian.org>
++ */
++
++#ifndef _TAS3004_H_
++#define _TAS3004_H_
++
++#include <linux/types.h>
++
++#include "tas_common.h"
++#include "tas_eq_prefs.h"
++
++/*
++ * Macros that correspond to the registers that we write to
++ * when setting the various values.
++ */
++
++#define TAS3004_VERSION "0.3"
++#define TAS3004_DATE "20011214"
++
++#define I2C_DRIVERNAME_TAS3004 "TAS3004 driver V " TAS3004_VERSION
++#define I2C_DRIVERID_TAS3004 (I2C_DRIVERID_TAS_BASE+1)
++
++extern struct tas_driver_hooks_t tas3004_hooks;
++extern struct tas_gain_t tas3004_gain;
++extern struct tas_eq_pref_t *tas3004_eq_prefs[];
++
++enum tas3004_reg_t {
++ TAS3004_REG_MCR = 0x01,
++ TAS3004_REG_DRC = 0x02,
++
++ TAS3004_REG_VOLUME = 0x04,
++ TAS3004_REG_TREBLE = 0x05,
++ TAS3004_REG_BASS = 0x06,
++ TAS3004_REG_LEFT_MIXER = 0x07,
++ TAS3004_REG_RIGHT_MIXER = 0x08,
++
++ TAS3004_REG_LEFT_BIQUAD0 = 0x0a,
++ TAS3004_REG_LEFT_BIQUAD1 = 0x0b,
++ TAS3004_REG_LEFT_BIQUAD2 = 0x0c,
++ TAS3004_REG_LEFT_BIQUAD3 = 0x0d,
++ TAS3004_REG_LEFT_BIQUAD4 = 0x0e,
++ TAS3004_REG_LEFT_BIQUAD5 = 0x0f,
++ TAS3004_REG_LEFT_BIQUAD6 = 0x10,
++
++ TAS3004_REG_RIGHT_BIQUAD0 = 0x13,
++ TAS3004_REG_RIGHT_BIQUAD1 = 0x14,
++ TAS3004_REG_RIGHT_BIQUAD2 = 0x15,
++ TAS3004_REG_RIGHT_BIQUAD3 = 0x16,
++ TAS3004_REG_RIGHT_BIQUAD4 = 0x17,
++ TAS3004_REG_RIGHT_BIQUAD5 = 0x18,
++ TAS3004_REG_RIGHT_BIQUAD6 = 0x19,
++
++ TAS3004_REG_LEFT_LOUD_BIQUAD = 0x21,
++ TAS3004_REG_RIGHT_LOUD_BIQUAD = 0x22,
++
++ TAS3004_REG_LEFT_LOUD_BIQUAD_GAIN = 0x23,
++ TAS3004_REG_RIGHT_LOUD_BIQUAD_GAIN = 0x24,
++
++ TAS3004_REG_TEST = 0x29,
++
++ TAS3004_REG_ANALOG_CTRL = 0x40,
++ TAS3004_REG_TEST1 = 0x41,
++ TAS3004_REG_TEST2 = 0x42,
++ TAS3004_REG_MCR2 = 0x43,
++
++ TAS3004_REG_MAX = 0x44
++};
++
++#endif /* _TAS3004_H_ */
+Index: linux-2.6.0-test5/sound/oss/dmasound/tas3004_tables.c
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/dmasound/tas3004_tables.c 2003-09-27 11:38:18.496716456 +0800
++++ linux-2.6.0-test5/sound/oss/dmasound/tas3004_tables.c 2003-09-27 11:38:42.464072864 +0800
+@@ -0,0 +1,301 @@
++#include "tas3004.h"
++#include "tas_eq_prefs.h"
++
++static struct tas_drce_t eqp_17_1_0_drce={
++ enable: 1,
++ above: { val: 3.0 * (1<<8), expand: 0 },
++ below: { val: 1.0 * (1<<8), expand: 0 },
++ threshold: -19.12 * (1<<8),
++ energy: 2.4 * (1<<12),
++ attack: 0.013 * (1<<12),
++ decay: 0.212 * (1<<12),
++};
++
++static struct tas_biquad_ctrl_t eqp_17_1_0_biquads[]={
++ { channel: 0, filter: 0, data: { coeff: { 0x0fd0d4, 0xe05e56, 0x0fd0d4, 0xe05ee1, 0x0fa234 } } },
++ { channel: 0, filter: 1, data: { coeff: { 0x0910d7, 0x088e1a, 0x030651, 0x01dcb1, 0x02c892 } } },
++ { channel: 0, filter: 2, data: { coeff: { 0x0ff895, 0xe0970b, 0x0f7f00, 0xe0970b, 0x0f7795 } } },
++ { channel: 0, filter: 3, data: { coeff: { 0x0fd1c4, 0xe1ac22, 0x0ec8cf, 0xe1ac22, 0x0e9a94 } } },
++ { channel: 0, filter: 4, data: { coeff: { 0x0f7c1c, 0xe3cc03, 0x0df786, 0xe3cc03, 0x0d73a2 } } },
++ { channel: 0, filter: 5, data: { coeff: { 0x11fb92, 0xf5a1a0, 0x073cd2, 0xf5a1a0, 0x093865 } } },
++ { channel: 0, filter: 6, data: { coeff: { 0x0e17a9, 0x068b6c, 0x08a0e5, 0x068b6c, 0x06b88e } } },
++
++ { channel: 1, filter: 0, data: { coeff: { 0x0fd0d4, 0xe05e56, 0x0fd0d4, 0xe05ee1, 0x0fa234 } } },
++ { channel: 1, filter: 1, data: { coeff: { 0x0910d7, 0x088e1a, 0x030651, 0x01dcb1, 0x02c892 } } },
++ { channel: 1, filter: 2, data: { coeff: { 0x0ff895, 0xe0970b, 0x0f7f00, 0xe0970b, 0x0f7795 } } },
++ { channel: 1, filter: 3, data: { coeff: { 0x0fd1c4, 0xe1ac22, 0x0ec8cf, 0xe1ac22, 0x0e9a94 } } },
++ { channel: 1, filter: 4, data: { coeff: { 0x0f7c1c, 0xe3cc03, 0x0df786, 0xe3cc03, 0x0d73a2 } } },
++ { channel: 1, filter: 5, data: { coeff: { 0x11fb92, 0xf5a1a0, 0x073cd2, 0xf5a1a0, 0x093865 } } },
++ { channel: 1, filter: 6, data: { coeff: { 0x0e17a9, 0x068b6c, 0x08a0e5, 0x068b6c, 0x06b88e } } }
++};
++
++static struct tas_eq_pref_t eqp_17_1_0 = {
++ sample_rate: 44100,
++ device_id: 0x17,
++ output_id: TAS_OUTPUT_INTERNAL_SPKR,
++ speaker_id: 0x00,
++
++ drce: &eqp_17_1_0_drce,
++
++ filter_count: 14,
++ biquads: eqp_17_1_0_biquads
++};
++
++/* ======================================================================== */
++
++static struct tas_drce_t eqp_18_1_0_drce={
++ enable: 1,
++ above: { val: 3.0 * (1<<8), expand: 0 },
++ below: { val: 1.0 * (1<<8), expand: 0 },
++ threshold: -13.14 * (1<<8),
++ energy: 2.4 * (1<<12),
++ attack: 0.013 * (1<<12),
++ decay: 0.212 * (1<<12),
++};
++
++static struct tas_biquad_ctrl_t eqp_18_1_0_biquads[]={
++ { channel: 0, filter: 0, data: { coeff: { 0x0f5514, 0xe155d7, 0x0f5514, 0xe15cfa, 0x0eb14b } } },
++ { channel: 0, filter: 1, data: { coeff: { 0x06ec33, 0x02abe3, 0x015eef, 0xf764d9, 0x03922d } } },
++ { channel: 0, filter: 2, data: { coeff: { 0x0ef5f2, 0xe67d1f, 0x0bcf37, 0xe67d1f, 0x0ac529 } } },
++ { channel: 0, filter: 3, data: { coeff: { 0x0db050, 0xe5be4d, 0x0d0c78, 0xe5be4d, 0x0abcc8 } } },
++ { channel: 0, filter: 4, data: { coeff: { 0x0f1298, 0xe64ec6, 0x0cc03e, 0xe64ec6, 0x0bd2d7 } } },
++ { channel: 0, filter: 5, data: { coeff: { 0x0c641a, 0x06537a, 0x08d155, 0x06537a, 0x053570 } } },
++ { channel: 0, filter: 6, data: { coeff: { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
++
++ { channel: 1, filter: 0, data: { coeff: { 0x0f5514, 0xe155d7, 0x0f5514, 0xe15cfa, 0x0eb14b } } },
++ { channel: 1, filter: 1, data: { coeff: { 0x06ec33, 0x02abe3, 0x015eef, 0xf764d9, 0x03922d } } },
++ { channel: 1, filter: 2, data: { coeff: { 0x0ef5f2, 0xe67d1f, 0x0bcf37, 0xe67d1f, 0x0ac529 } } },
++ { channel: 1, filter: 3, data: { coeff: { 0x0db050, 0xe5be4d, 0x0d0c78, 0xe5be4d, 0x0abcc8 } } },
++ { channel: 1, filter: 4, data: { coeff: { 0x0f1298, 0xe64ec6, 0x0cc03e, 0xe64ec6, 0x0bd2d7 } } },
++ { channel: 1, filter: 5, data: { coeff: { 0x0c641a, 0x06537a, 0x08d155, 0x06537a, 0x053570 } } },
++ { channel: 1, filter: 6, data: { coeff: { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } }
++};
++
++static struct tas_eq_pref_t eqp_18_1_0 = {
++ sample_rate: 44100,
++ device_id: 0x18,
++ output_id: TAS_OUTPUT_INTERNAL_SPKR,
++ speaker_id: 0x00,
++
++ drce: &eqp_18_1_0_drce,
++
++ filter_count: 14,
++ biquads: eqp_18_1_0_biquads
++};
++
++/* ======================================================================== */
++
++static struct tas_drce_t eqp_1a_1_0_drce={
++ enable: 1,
++ above: { val: 3.0 * (1<<8), expand: 0 },
++ below: { val: 1.0 * (1<<8), expand: 0 },
++ threshold: -10.75 * (1<<8),
++ energy: 2.4 * (1<<12),
++ attack: 0.013 * (1<<12),
++ decay: 0.212 * (1<<12),
++};
++
++static struct tas_biquad_ctrl_t eqp_1a_1_0_biquads[]={
++ { channel: 0, filter: 0, data: { coeff: { 0x0fb8fd, 0xe08e04, 0x0fb8fd, 0xe08f40, 0x0f7336 } } },
++ { channel: 0, filter: 1, data: { coeff: { 0x06371d, 0x0c6e3a, 0x06371d, 0x05bfd3, 0x031ca2 } } },
++ { channel: 0, filter: 2, data: { coeff: { 0x0fa1c0, 0xe18692, 0x0f030e, 0xe18692, 0x0ea4ce } } },
++ { channel: 0, filter: 3, data: { coeff: { 0x0fe495, 0xe17eff, 0x0f0452, 0xe17eff, 0x0ee8e7 } } },
++ { channel: 0, filter: 4, data: { coeff: { 0x100857, 0xe7e71c, 0x0e9599, 0xe7e71c, 0x0e9df1 } } },
++ { channel: 0, filter: 5, data: { coeff: { 0x0fb26e, 0x06a82c, 0x0db2b4, 0x06a82c, 0x0d6522 } } },
++ { channel: 0, filter: 6, data: { coeff: { 0x11419d, 0xf06cbf, 0x0a4f6e, 0xf06cbf, 0x0b910c } } },
++
++ { channel: 1, filter: 0, data: { coeff: { 0x0fb8fd, 0xe08e04, 0x0fb8fd, 0xe08f40, 0x0f7336 } } },
++ { channel: 1, filter: 1, data: { coeff: { 0x06371d, 0x0c6e3a, 0x06371d, 0x05bfd3, 0x031ca2 } } },
++ { channel: 1, filter: 2, data: { coeff: { 0x0fa1c0, 0xe18692, 0x0f030e, 0xe18692, 0x0ea4ce } } },
++ { channel: 1, filter: 3, data: { coeff: { 0x0fe495, 0xe17eff, 0x0f0452, 0xe17eff, 0x0ee8e7 } } },
++ { channel: 1, filter: 4, data: { coeff: { 0x100857, 0xe7e71c, 0x0e9599, 0xe7e71c, 0x0e9df1 } } },
++ { channel: 1, filter: 5, data: { coeff: { 0x0fb26e, 0x06a82c, 0x0db2b4, 0x06a82c, 0x0d6522 } } },
++ { channel: 1, filter: 6, data: { coeff: { 0x11419d, 0xf06cbf, 0x0a4f6e, 0xf06cbf, 0x0b910c } } }
++};
++
++static struct tas_eq_pref_t eqp_1a_1_0 = {
++ sample_rate: 44100,
++ device_id: 0x1a,
++ output_id: TAS_OUTPUT_INTERNAL_SPKR,
++ speaker_id: 0x00,
++
++ drce: &eqp_1a_1_0_drce,
++
++ filter_count: 14,
++ biquads: eqp_1a_1_0_biquads
++};
++
++/* ======================================================================== */
++
++static struct tas_drce_t eqp_1c_1_0_drce={
++ enable: 1,
++ above: { val: 3.0 * (1<<8), expand: 0 },
++ below: { val: 1.0 * (1<<8), expand: 0 },
++ threshold: -14.34 * (1<<8),
++ energy: 2.4 * (1<<12),
++ attack: 0.013 * (1<<12),
++ decay: 0.212 * (1<<12),
++};
++
++static struct tas_biquad_ctrl_t eqp_1c_1_0_biquads[]={
++ { channel: 0, filter: 0, data: { coeff: { 0x0f4f95, 0xe160d4, 0x0f4f95, 0xe1686e, 0x0ea6c5 } } },
++ { channel: 0, filter: 1, data: { coeff: { 0x066b92, 0x0290d4, 0x0148a0, 0xf6853f, 0x03bfc7 } } },
++ { channel: 0, filter: 2, data: { coeff: { 0x0f57dc, 0xe51c91, 0x0dd1cb, 0xe51c91, 0x0d29a8 } } },
++ { channel: 0, filter: 3, data: { coeff: { 0x0df1cb, 0xe4fa84, 0x0d7cdc, 0xe4fa84, 0x0b6ea7 } } },
++ { channel: 0, filter: 4, data: { coeff: { 0x0eba36, 0xe6aa48, 0x0b9f52, 0xe6aa48, 0x0a5989 } } },
++ { channel: 0, filter: 5, data: { coeff: { 0x0caf02, 0x05ef9d, 0x084beb, 0x05ef9d, 0x04faee } } },
++ { channel: 0, filter: 6, data: { coeff: { 0x0fc686, 0xe22947, 0x0e4b5d, 0xe22947, 0x0e11e4 } } },
++
++ { channel: 1, filter: 0, data: { coeff: { 0x0f4f95, 0xe160d4, 0x0f4f95, 0xe1686e, 0x0ea6c5 } } },
++ { channel: 1, filter: 1, data: { coeff: { 0x066b92, 0x0290d4, 0x0148a0, 0xf6853f, 0x03bfc7 } } },
++ { channel: 1, filter: 2, data: { coeff: { 0x0f57dc, 0xe51c91, 0x0dd1cb, 0xe51c91, 0x0d29a8 } } },
++ { channel: 1, filter: 3, data: { coeff: { 0x0df1cb, 0xe4fa84, 0x0d7cdc, 0xe4fa84, 0x0b6ea7 } } },
++ { channel: 1, filter: 4, data: { coeff: { 0x0eba36, 0xe6aa48, 0x0b9f52, 0xe6aa48, 0x0a5989 } } },
++ { channel: 1, filter: 5, data: { coeff: { 0x0caf02, 0x05ef9d, 0x084beb, 0x05ef9d, 0x04faee } } },
++ { channel: 1, filter: 6, data: { coeff: { 0x0fc686, 0xe22947, 0x0e4b5d, 0xe22947, 0x0e11e4 } } }
++};
++
++static struct tas_eq_pref_t eqp_1c_1_0 = {
++ sample_rate: 44100,
++ device_id: 0x1c,
++ output_id: TAS_OUTPUT_INTERNAL_SPKR,
++ speaker_id: 0x00,
++
++ drce: &eqp_1c_1_0_drce,
++
++ filter_count: 14,
++ biquads: eqp_1c_1_0_biquads
++};
++
++/* ======================================================================== */
++
++static uint tas3004_master_tab[]={
++ 0x0, 0x75, 0x9c, 0xbb,
++ 0xdb, 0xfb, 0x11e, 0x143,
++ 0x16b, 0x196, 0x1c3, 0x1f5,
++ 0x229, 0x263, 0x29f, 0x2e1,
++ 0x328, 0x373, 0x3c5, 0x41b,
++ 0x478, 0x4dc, 0x547, 0x5b8,
++ 0x633, 0x6b5, 0x740, 0x7d5,
++ 0x873, 0x91c, 0x9d2, 0xa92,
++ 0xb5e, 0xc39, 0xd22, 0xe19,
++ 0xf20, 0x1037, 0x1161, 0x129e,
++ 0x13ed, 0x1551, 0x16ca, 0x185d,
++ 0x1a08, 0x1bcc, 0x1dac, 0x1fa7,
++ 0x21c1, 0x23fa, 0x2655, 0x28d6,
++ 0x2b7c, 0x2e4a, 0x3141, 0x3464,
++ 0x37b4, 0x3b35, 0x3ee9, 0x42d3,
++ 0x46f6, 0x4b53, 0x4ff0, 0x54ce,
++ 0x59f2, 0x5f5f, 0x6519, 0x6b24,
++ 0x7183, 0x783c, 0x7f53, 0x86cc,
++ 0x8ead, 0x96fa, 0x9fba, 0xa8f2,
++ 0xb2a7, 0xbce1, 0xc7a5, 0xd2fa,
++ 0xdee8, 0xeb75, 0xf8aa, 0x1068e,
++ 0x1152a, 0x12487, 0x134ad, 0x145a5,
++ 0x1577b, 0x16a37, 0x17df5, 0x192bd,
++ 0x1a890, 0x1bf7b, 0x1d78d, 0x1f0d1,
++ 0x20b55, 0x22727, 0x24456, 0x262f2,
++ 0x2830b
++};
++
++static uint tas3004_mixer_tab[]={
++ 0x0, 0x748, 0x9be, 0xbaf,
++ 0xda4, 0xfb1, 0x11de, 0x1431,
++ 0x16ad, 0x1959, 0x1c37, 0x1f4b,
++ 0x2298, 0x2628, 0x29fb, 0x2e12,
++ 0x327d, 0x3734, 0x3c47, 0x41b4,
++ 0x4787, 0x4dbe, 0x546d, 0x5b86,
++ 0x632e, 0x6b52, 0x7400, 0x7d54,
++ 0x873b, 0x91c6, 0x9d1a, 0xa920,
++ 0xb5e5, 0xc38c, 0xd21b, 0xe18f,
++ 0xf1f5, 0x1036a, 0x1160f, 0x129d6,
++ 0x13ed0, 0x1550c, 0x16ca0, 0x185c9,
++ 0x1a07b, 0x1bcc3, 0x1dab9, 0x1fa75,
++ 0x21c0f, 0x23fa3, 0x26552, 0x28d64,
++ 0x2b7c9, 0x2e4a2, 0x31411, 0x3463b,
++ 0x37b44, 0x3b353, 0x3ee94, 0x42d30,
++ 0x46f55, 0x4b533, 0x4fefc, 0x54ce5,
++ 0x59f25, 0x5f5f6, 0x65193, 0x6b23c,
++ 0x71835, 0x783c3, 0x7f52c, 0x86cc0,
++ 0x8eacc, 0x96fa5, 0x9fba0, 0xa8f1a,
++ 0xb2a71, 0xbce0a, 0xc7a4a, 0xd2fa0,
++ 0xdee7b, 0xeb752, 0xf8a9f, 0x1068e4,
++ 0x1152a3, 0x12486a, 0x134ac8, 0x145a55,
++ 0x1577ac, 0x16a370, 0x17df51, 0x192bc2,
++ 0x1a88f8, 0x1bf7b7, 0x1d78c9, 0x1f0d04,
++ 0x20b542, 0x227268, 0x244564, 0x262f26,
++ 0x2830af
++};
++
++static uint tas3004_treble_tab[]={
++ 0x96, 0x95, 0x95, 0x94,
++ 0x93, 0x92, 0x92, 0x91,
++ 0x90, 0x90, 0x8f, 0x8e,
++ 0x8d, 0x8d, 0x8c, 0x8b,
++ 0x8a, 0x8a, 0x89, 0x88,
++ 0x88, 0x87, 0x86, 0x85,
++ 0x85, 0x84, 0x83, 0x83,
++ 0x82, 0x81, 0x80, 0x80,
++ 0x7f, 0x7e, 0x7e, 0x7d,
++ 0x7c, 0x7b, 0x7b, 0x7a,
++ 0x79, 0x78, 0x78, 0x77,
++ 0x76, 0x76, 0x75, 0x74,
++ 0x73, 0x73, 0x72, 0x71,
++ 0x71, 0x68, 0x45, 0x5b,
++ 0x6d, 0x6c, 0x6b, 0x6a,
++ 0x69, 0x68, 0x67, 0x66,
++ 0x65, 0x63, 0x62, 0x62,
++ 0x60, 0x5e, 0x5c, 0x5b,
++ 0x59, 0x57, 0x55, 0x53,
++ 0x52, 0x4f, 0x4d, 0x4a,
++ 0x48, 0x46, 0x43, 0x40,
++ 0x3d, 0x3a, 0x36, 0x33,
++ 0x2f, 0x2c, 0x27, 0x23,
++ 0x1f, 0x1a, 0x15, 0xf,
++ 0x8, 0x5, 0x2, 0x1,
++ 0x1
++};
++
++static uint tas3004_bass_tab[]={
++ 0x96, 0x95, 0x95, 0x94,
++ 0x93, 0x92, 0x92, 0x91,
++ 0x90, 0x90, 0x8f, 0x8e,
++ 0x8d, 0x8d, 0x8c, 0x8b,
++ 0x8a, 0x8a, 0x89, 0x88,
++ 0x88, 0x87, 0x86, 0x85,
++ 0x85, 0x84, 0x83, 0x83,
++ 0x82, 0x81, 0x80, 0x80,
++ 0x7f, 0x7e, 0x7e, 0x7d,
++ 0x7c, 0x7b, 0x7b, 0x7a,
++ 0x79, 0x78, 0x78, 0x77,
++ 0x76, 0x76, 0x75, 0x74,
++ 0x73, 0x73, 0x72, 0x71,
++ 0x70, 0x6f, 0x6e, 0x6d,
++ 0x6c, 0x6b, 0x6a, 0x6a,
++ 0x69, 0x67, 0x66, 0x66,
++ 0x65, 0x63, 0x62, 0x62,
++ 0x61, 0x60, 0x5e, 0x5d,
++ 0x5b, 0x59, 0x57, 0x55,
++ 0x53, 0x51, 0x4f, 0x4c,
++ 0x4a, 0x48, 0x46, 0x44,
++ 0x41, 0x3e, 0x3b, 0x38,
++ 0x36, 0x33, 0x2f, 0x2b,
++ 0x28, 0x24, 0x20, 0x1c,
++ 0x17, 0x12, 0xd, 0x7,
++ 0x1
++};
++
++struct tas_gain_t tas3004_gain={
++ master: tas3004_master_tab,
++ treble: tas3004_treble_tab,
++ bass: tas3004_bass_tab,
++ mixer: tas3004_mixer_tab
++};
++
++struct tas_eq_pref_t *tas3004_eq_prefs[]={
++ &eqp_17_1_0,
++ &eqp_18_1_0,
++ &eqp_1a_1_0,
++ &eqp_1c_1_0,
++ NULL
++};
+Index: linux-2.6.0-test5/sound/oss/dmasound/tas_common.c
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/dmasound/tas_common.c 2003-09-27 11:38:18.496716456 +0800
++++ linux-2.6.0-test5/sound/oss/dmasound/tas_common.c 2003-09-27 11:38:42.465072712 +0800
+@@ -0,0 +1,212 @@
++#include <linux/version.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/proc_fs.h>
++#include <linux/ioport.h>
++#include <linux/sysctl.h>
++#include <linux/types.h>
++#include <linux/i2c.h>
++#include <linux/init.h>
++#include <linux/soundcard.h>
++#include <asm/uaccess.h>
++#include <asm/errno.h>
++#include <asm/io.h>
++#include <asm/prom.h>
++
++#include "tas_common.h"
++
++#define CALL0(proc) \
++ do { \
++ struct tas_data_t *self; \
++ if (!tas_client || driver_hooks == NULL) \
++ return -1; \
++ self = dev_get_drvdata(&tas_client->dev); \
++ if (driver_hooks->proc) \
++ return driver_hooks->proc(self); \
++ else \
++ return -EINVAL; \
++ } while (0)
++
++#define CALL(proc,arg...) \
++ do { \
++ struct tas_data_t *self; \
++ if (!tas_client || driver_hooks == NULL) \
++ return -1; \
++ self = dev_get_drvdata(&tas_client->dev); \
++ if (driver_hooks->proc) \
++ return driver_hooks->proc(self, ## arg); \
++ else \
++ return -EINVAL; \
++ } while (0)
++
++
++static u8 tas_i2c_address = 0x34;
++static struct i2c_client *tas_client;
++static struct device_node* tas_node;
++
++static int tas_attach_adapter(struct i2c_adapter *);
++static int tas_detach_client(struct i2c_client *);
++
++struct i2c_driver tas_driver = {
++ .owner = THIS_MODULE,
++ .name = "tas",
++ .flags = I2C_DF_NOTIFY,
++ .attach_adapter = tas_attach_adapter,
++ .detach_client = tas_detach_client,
++};
++
++struct tas_driver_hooks_t *driver_hooks;
++
++int
++tas_register_driver(struct tas_driver_hooks_t *hooks)
++{
++ driver_hooks = hooks;
++ return 0;
++}
++
++int
++tas_get_mixer_level(int mixer, uint *level)
++{
++ CALL(get_mixer_level,mixer,level);
++}
++
++int
++tas_set_mixer_level(int mixer,uint level)
++{
++ CALL(set_mixer_level,mixer,level);
++}
++
++int
++tas_enter_sleep(void)
++{
++ CALL0(enter_sleep);
++}
++
++int
++tas_leave_sleep(void)
++{
++ CALL0(leave_sleep);
++}
++
++int
++tas_supported_mixers(void)
++{
++ CALL0(supported_mixers);
++}
++
++int
++tas_mixer_is_stereo(int mixer)
++{
++ CALL(mixer_is_stereo,mixer);
++}
++
++int
++tas_stereo_mixers(void)
++{
++ CALL0(stereo_mixers);
++}
++
++int
++tas_output_device_change(int device_id,int layout_id,int speaker_id)
++{
++ CALL(output_device_change,device_id,layout_id,speaker_id);
++}
++
++int
++tas_device_ioctl(u_int cmd, u_long arg)
++{
++ CALL(device_ioctl,cmd,arg);
++}
++
++int
++tas_post_init(void)
++{
++ CALL0(post_init);
++}
++
++static int
++tas_detect_client(struct i2c_adapter *adapter, int address)
++{
++ static const char *client_name = "tas Digital Equalizer";
++ struct i2c_client *new_client;
++ int rc = -ENODEV;
++
++ if (!driver_hooks) {
++ printk(KERN_ERR "tas_detect_client called with no hooks !\n");
++ return -ENODEV;
++ }
++
++ new_client = kmalloc(sizeof(*new_client), GFP_KERNEL);
++ if (!new_client)
++ return -ENOMEM;
++ memset(new_client, 0, sizeof(*new_client));
++
++ new_client->addr = address;
++ new_client->adapter = adapter;
++ new_client->driver = &tas_driver;
++ strlcpy(new_client->name, client_name, DEVICE_NAME_SIZE);
++
++ if (driver_hooks->init(new_client))
++ goto bail;
++
++ /* Tell the i2c layer a new client has arrived */
++ if (i2c_attach_client(new_client)) {
++ driver_hooks->uninit(dev_get_drvdata(&new_client->dev));
++ goto bail;
++ }
++
++ tas_client = new_client;
++ return 0;
++ bail:
++ tas_client = NULL;
++ kfree(new_client);
++ return rc;
++}
++
++static int
++tas_attach_adapter(struct i2c_adapter *adapter)
++{
++ if (!strncmp(adapter->name, "mac-io", 6))
++ return tas_detect_client(adapter, tas_i2c_address);
++ return 0;
++}
++
++static int
++tas_detach_client(struct i2c_client *client)
++{
++ if (client == tas_client) {
++ driver_hooks->uninit(dev_get_drvdata(&client->dev));
++
++ i2c_detach_client(client);
++ kfree(client);
++ }
++ return 0;
++}
++
++void
++tas_cleanup(void)
++{
++ i2c_del_driver(&tas_driver);
++}
++
++int __init
++tas_init(int driver_id, const char *driver_name)
++{
++ u32* paddr;
++
++ printk(KERN_INFO "tas driver [%s])\n", driver_name);
++
++ tas_node = find_devices("deq");
++ if (tas_node == NULL)
++ return -ENODEV;
++ paddr = (u32 *)get_property(tas_node, "i2c-address", NULL);
++ if (paddr) {
++ tas_i2c_address = (*paddr) >> 1;
++ printk(KERN_INFO "using i2c address: 0x%x from device-tree\n",
++ tas_i2c_address);
++ } else
++ printk(KERN_INFO "using i2c address: 0x%x (default)\n",
++ tas_i2c_address);
++
++ return i2c_add_driver(&tas_driver);
++}
+Index: linux-2.6.0-test5/sound/oss/dmasound/tas_common.h
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/dmasound/tas_common.h 2003-09-27 11:38:18.496716456 +0800
++++ linux-2.6.0-test5/sound/oss/dmasound/tas_common.h 2003-09-27 11:38:42.465072712 +0800
+@@ -0,0 +1,284 @@
++#ifndef _TAS_COMMON_H_
++#define _TAS_COMMON_H_
++
++#include <linux/i2c.h>
++#include <linux/soundcard.h>
++#include <asm/string.h>
++
++#define I2C_DRIVERID_TAS_BASE (0xFEBA)
++
++#define SET_4_20(shadow, offset, val) \
++ do { \
++ (shadow)[(offset)+0] = ((val) >> 16) & 0xff; \
++ (shadow)[(offset)+1] = ((val) >> 8) & 0xff; \
++ (shadow)[(offset)+2] = ((val) >> 0) & 0xff; \
++ } while (0)
++
++#define GET_4_20(shadow, offset) \
++ (((u_int)((shadow)[(offset)+0]) << 16) | \
++ ((u_int)((shadow)[(offset)+1]) << 8) | \
++ ((u_int)((shadow)[(offset)+2]) << 0))
++
++
++#define TAS_BIQUAD_FAST_LOAD 0x01
++
++#define TAS_DRCE_ENABLE 0x01
++#define TAS_DRCE_ABOVE_RATIO 0x02
++#define TAS_DRCE_BELOW_RATIO 0x04
++#define TAS_DRCE_THRESHOLD 0x08
++#define TAS_DRCE_ENERGY 0x10
++#define TAS_DRCE_ATTACK 0x20
++#define TAS_DRCE_DECAY 0x40
++
++#define TAS_DRCE_ALL 0x7f
++
++
++#define TAS_OUTPUT_HEADPHONES 0x00
++#define TAS_OUTPUT_INTERNAL_SPKR 0x01
++#define TAS_OUTPUT_EXTERNAL_SPKR 0x02
++
++
++union tas_biquad_t {
++ struct {
++ int b0,b1,b2,a1,a2;
++ } coeff;
++ int buf[5];
++};
++
++struct tas_biquad_ctrl_t {
++ u_int channel:4;
++ u_int filter:4;
++
++ union tas_biquad_t data;
++};
++
++struct tas_biquad_ctrl_list_t {
++ int flags;
++ int filter_count;
++ struct tas_biquad_ctrl_t biquads[0];
++};
++
++struct tas_ratio_t {
++ unsigned short val; /* 8.8 */
++ unsigned short expand; /* 0 = compress, !0 = expand. */
++};
++
++struct tas_drce_t {
++ unsigned short enable;
++ struct tas_ratio_t above;
++ struct tas_ratio_t below;
++ short threshold; /* dB, 8.8 signed */
++ unsigned short energy; /* seconds, 4.12 unsigned */
++ unsigned short attack; /* seconds, 4.12 unsigned */
++ unsigned short decay; /* seconds, 4.12 unsigned */
++};
++
++struct tas_drce_ctrl_t {
++ uint flags;
++
++ struct tas_drce_t data;
++};
++
++struct tas_gain_t
++{
++ unsigned int *master;
++ unsigned int *treble;
++ unsigned int *bass;
++ unsigned int *mixer;
++};
++
++typedef char tas_shadow_t[16];
++
++struct tas_data_t
++{
++ struct i2c_client *client;
++ tas_shadow_t *shadow;
++ uint mixer[SOUND_MIXER_NRDEVICES];
++};
++
++typedef int (*tas_hook_init_t)(struct i2c_client *);
++typedef int (*tas_hook_post_init_t)(struct tas_data_t *);
++typedef void (*tas_hook_uninit_t)(struct tas_data_t *);
++
++typedef int (*tas_hook_get_mixer_level_t)(struct tas_data_t *,int,uint *);
++typedef int (*tas_hook_set_mixer_level_t)(struct tas_data_t *,int,uint);
++
++typedef int (*tas_hook_enter_sleep_t)(struct tas_data_t *);
++typedef int (*tas_hook_leave_sleep_t)(struct tas_data_t *);
++
++typedef int (*tas_hook_supported_mixers_t)(struct tas_data_t *);
++typedef int (*tas_hook_mixer_is_stereo_t)(struct tas_data_t *,int);
++typedef int (*tas_hook_stereo_mixers_t)(struct tas_data_t *);
++
++typedef int (*tas_hook_output_device_change_t)(struct tas_data_t *,int,int,int);
++typedef int (*tas_hook_device_ioctl_t)(struct tas_data_t *,u_int,u_long);
++
++struct tas_driver_hooks_t {
++ /*
++ * All hardware initialisation must be performed in
++ * post_init(), as tas_dmasound_init() does a hardware reset.
++ *
++ * init() is called before tas_dmasound_init() so that
++ * ouput_device_change() is always called after i2c driver
++ * initialisation. The implication is that
++ * output_device_change() must cope with the fact that it
++ * may be called before post_init().
++ */
++
++ tas_hook_init_t init;
++ tas_hook_post_init_t post_init;
++ tas_hook_uninit_t uninit;
++
++ tas_hook_get_mixer_level_t get_mixer_level;
++ tas_hook_set_mixer_level_t set_mixer_level;
++
++ tas_hook_enter_sleep_t enter_sleep;
++ tas_hook_leave_sleep_t leave_sleep;
++
++ tas_hook_supported_mixers_t supported_mixers;
++ tas_hook_mixer_is_stereo_t mixer_is_stereo;
++ tas_hook_stereo_mixers_t stereo_mixers;
++
++ tas_hook_output_device_change_t output_device_change;
++ tas_hook_device_ioctl_t device_ioctl;
++};
++
++enum tas_write_mode_t {
++ WRITE_HW = 0x01,
++ WRITE_SHADOW = 0x02,
++ WRITE_NORMAL = 0x03,
++ FORCE_WRITE = 0x04
++};
++
++static inline uint
++tas_mono_to_stereo(uint mono)
++{
++ mono &=0xff;
++ return mono | (mono<<8);
++}
++
++/*
++ * Todo: make these functions a bit more efficient !
++ */
++static inline int
++tas_write_register( struct tas_data_t *self,
++ uint reg_num,
++ uint reg_width,
++ char *data,
++ uint write_mode)
++{
++ int rc;
++
++ if (reg_width==0 || data==NULL || self==NULL)
++ return -EINVAL;
++ if (!(write_mode & FORCE_WRITE) &&
++ !memcmp(data,self->shadow[reg_num],reg_width))
++ return 0;
++
++ if (write_mode & WRITE_SHADOW)
++ memcpy(self->shadow[reg_num],data,reg_width);
++ if (write_mode & WRITE_HW) {
++ rc=i2c_smbus_write_block_data(self->client,
++ reg_num,
++ reg_width,
++ data);
++ if (rc < 0) {
++ printk("tas: I2C block write failed \n");
++ return rc;
++ }
++ }
++ return 0;
++}
++
++static inline int
++tas_sync_register( struct tas_data_t *self,
++ uint reg_num,
++ uint reg_width)
++{
++ int rc;
++
++ if (reg_width==0 || self==NULL)
++ return -EINVAL;
++ rc=i2c_smbus_write_block_data(self->client,
++ reg_num,
++ reg_width,
++ self->shadow[reg_num]);
++ if (rc < 0) {
++ printk("tas: I2C block write failed \n");
++ return rc;
++ }
++ return 0;
++}
++
++static inline int
++tas_write_byte_register( struct tas_data_t *self,
++ uint reg_num,
++ char data,
++ uint write_mode)
++{
++ if (self==NULL)
++ return -1;
++ if (!(write_mode & FORCE_WRITE) && data != self->shadow[reg_num][0])
++ return 0;
++ if (write_mode & WRITE_SHADOW)
++ self->shadow[reg_num][0]=data;
++ if (write_mode & WRITE_HW) {
++ if (i2c_smbus_write_byte_data(self->client, reg_num, data) < 0) {
++ printk("tas: I2C byte write failed \n");
++ return -1;
++ }
++ }
++ return 0;
++}
++
++static inline int
++tas_sync_byte_register( struct tas_data_t *self,
++ uint reg_num,
++ uint reg_width)
++{
++ if (reg_width==0 || self==NULL)
++ return -1;
++ if (i2c_smbus_write_byte_data(
++ self->client, reg_num, self->shadow[reg_num][0]) < 0) {
++ printk("tas: I2C byte write failed \n");
++ return -1;
++ }
++ return 0;
++}
++
++static inline int
++tas_read_register( struct tas_data_t *self,
++ uint reg_num,
++ uint reg_width,
++ char *data)
++{
++ if (reg_width==0 || data==NULL || self==NULL)
++ return -1;
++ memcpy(data,self->shadow[reg_num],reg_width);
++ return 0;
++}
++
++extern int tas_register_driver(struct tas_driver_hooks_t *hooks);
++
++extern int tas_get_mixer_level(int mixer,uint *level);
++extern int tas_set_mixer_level(int mixer,uint level);
++extern int tas_enter_sleep(void);
++extern int tas_leave_sleep(void);
++extern int tas_supported_mixers(void);
++extern int tas_mixer_is_stereo(int mixer);
++extern int tas_stereo_mixers(void);
++extern int tas_output_device_change(int,int,int);
++extern int tas_device_ioctl(u_int, u_long);
++
++extern void tas_cleanup(void);
++extern int tas_init(int driver_id,const char *driver_name);
++extern int tas_post_init(void);
++
++#endif /* _TAS_COMMON_H_ */
++/*
++ * Local Variables:
++ * tab-width: 8
++ * indent-tabs-mode: t
++ * c-basic-offset: 8
++ * End:
++ */
+Index: linux-2.6.0-test5/sound/oss/dmasound/tas_eq_prefs.h
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/dmasound/tas_eq_prefs.h 2003-09-27 11:38:18.496716456 +0800
++++ linux-2.6.0-test5/sound/oss/dmasound/tas_eq_prefs.h 2003-09-27 11:38:42.466072560 +0800
+@@ -0,0 +1,24 @@
++#ifndef _TAS_EQ_PREFS_H_
++#define _TAS_EQ_PREFS_H_
++
++struct tas_eq_pref_t {
++ u_int sample_rate;
++ u_int device_id;
++ u_int output_id;
++ u_int speaker_id;
++
++ struct tas_drce_t *drce;
++
++ u_int filter_count;
++ struct tas_biquad_ctrl_t *biquads;
++};
++
++#endif /* _TAS_EQ_PREFS_H_ */
++
++/*
++ * Local Variables:
++ * tab-width: 8
++ * indent-tabs-mode: t
++ * c-basic-offset: 8
++ * End:
++ */
+Index: linux-2.6.0-test5/sound/oss/dmasound/tas_ioctl.h
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/dmasound/tas_ioctl.h 2003-09-27 11:38:18.496716456 +0800
++++ linux-2.6.0-test5/sound/oss/dmasound/tas_ioctl.h 2003-09-27 11:38:42.466072560 +0800
+@@ -0,0 +1,24 @@
++#ifndef _TAS_IOCTL_H_
++#define _TAS_IOCTL_H_
++
++#include <linux/i2c.h>
++#include <linux/soundcard.h>
++
++
++#define TAS_READ_EQ _SIOR('t',0,struct tas_biquad_ctrl_t)
++#define TAS_WRITE_EQ _SIOW('t',0,struct tas_biquad_ctrl_t)
++
++#define TAS_READ_EQ_LIST _SIOR('t',1,struct tas_biquad_ctrl_t)
++#define TAS_WRITE_EQ_LIST _SIOW('t',1,struct tas_biquad_ctrl_t)
++
++#define TAS_READ_EQ_FILTER_COUNT _SIOR('t',2,int)
++#define TAS_READ_EQ_CHANNEL_COUNT _SIOR('t',3,int)
++
++#define TAS_READ_DRCE _SIOR('t',4,struct tas_drce_ctrl_t)
++#define TAS_WRITE_DRCE _SIOW('t',4,struct tas_drce_ctrl_t)
++
++#define TAS_READ_DRCE_CAPS _SIOR('t',5,int)
++#define TAS_READ_DRCE_MIN _SIOR('t',6,int)
++#define TAS_READ_DRCE_MAX _SIOR('t',7,int)
++
++#endif
+Index: linux-2.6.0-test5/sound/oss/dmasound/trans_16.c
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/dmasound/trans_16.c 2003-09-27 11:38:18.496716456 +0800
++++ linux-2.6.0-test5/sound/oss/dmasound/trans_16.c 2003-09-27 11:38:42.468072256 +0800
+@@ -0,0 +1,679 @@
++/*
++ * linux/drivers/sound/dmasound/trans_16.c
++ *
++ * 16 bit translation routines. Only used by Power mac at present.
++ *
++ * See linux/drivers/sound/dmasound/dmasound_core.c for copyright and
++ * history prior to 08/02/2001.
++ *
++ * 08/02/2001 Iain Sandoe
++ * split from dmasound_awacs.c
++ */
++
++#include <linux/soundcard.h>
++#include <asm/uaccess.h>
++#include "dmasound.h"
++
++static short dmasound_alaw2dma16[] ;
++static short dmasound_ulaw2dma16[] ;
++
++static ssize_t pmac_ct_law(const u_char *userPtr, size_t userCount,
++ u_char frame[], ssize_t *frameUsed,
++ ssize_t frameLeft);
++static ssize_t pmac_ct_s8(const u_char *userPtr, size_t userCount,
++ u_char frame[], ssize_t *frameUsed,
++ ssize_t frameLeft);
++static ssize_t pmac_ct_u8(const u_char *userPtr, size_t userCount,
++ u_char frame[], ssize_t *frameUsed,
++ ssize_t frameLeft);
++static ssize_t pmac_ct_s16(const u_char *userPtr, size_t userCount,
++ u_char frame[], ssize_t *frameUsed,
++ ssize_t frameLeft);
++static ssize_t pmac_ct_u16(const u_char *userPtr, size_t userCount,
++ u_char frame[], ssize_t *frameUsed,
++ ssize_t frameLeft);
++
++static ssize_t pmac_ctx_law(const u_char *userPtr, size_t userCount,
++ u_char frame[], ssize_t *frameUsed,
++ ssize_t frameLeft);
++static ssize_t pmac_ctx_s8(const u_char *userPtr, size_t userCount,
++ u_char frame[], ssize_t *frameUsed,
++ ssize_t frameLeft);
++static ssize_t pmac_ctx_u8(const u_char *userPtr, size_t userCount,
++ u_char frame[], ssize_t *frameUsed,
++ ssize_t frameLeft);
++static ssize_t pmac_ctx_s16(const u_char *userPtr, size_t userCount,
++ u_char frame[], ssize_t *frameUsed,
++ ssize_t frameLeft);
++static ssize_t pmac_ctx_u16(const u_char *userPtr, size_t userCount,
++ u_char frame[], ssize_t *frameUsed,
++ ssize_t frameLeft);
++
++static ssize_t pmac_ct_s16_read(const u_char *userPtr, size_t userCount,
++ u_char frame[], ssize_t *frameUsed,
++ ssize_t frameLeft);
++static ssize_t pmac_ct_u16_read(const u_char *userPtr, size_t userCount,
++ u_char frame[], ssize_t *frameUsed,
++ ssize_t frameLeft);
++
++/*** Translations ************************************************************/
++
++extern int expand_bal; /* Balance factor for expanding (not volume!) */
++static int expand_data; /* Data for expanding */
++
++static ssize_t pmac_ct_law(const u_char *userPtr, size_t userCount,
++ u_char frame[], ssize_t *frameUsed,
++ ssize_t frameLeft)
++{
++ short *table = dmasound.soft.format == AFMT_MU_LAW
++ ? dmasound_ulaw2dma16 : dmasound_alaw2dma16;
++ ssize_t count, used;
++ short *p = (short *) &frame[*frameUsed];
++ int val, stereo = dmasound.soft.stereo;
++
++ frameLeft >>= 2;
++ if (stereo)
++ userCount >>= 1;
++ used = count = min_t(unsigned long, userCount, frameLeft);
++ while (count > 0) {
++ u_char data;
++ if (get_user(data, userPtr++))
++ return -EFAULT;
++ val = table[data];
++ *p++ = val;
++ if (stereo) {
++ if (get_user(data, userPtr++))
++ return -EFAULT;
++ val = table[data];
++ }
++ *p++ = val;
++ count--;
++ }
++ *frameUsed += used * 4;
++ return stereo? used * 2: used;
++}
++
++
++static ssize_t pmac_ct_s8(const u_char *userPtr, size_t userCount,
++ u_char frame[], ssize_t *frameUsed,
++ ssize_t frameLeft)
++{
++ ssize_t count, used;
++ short *p = (short *) &frame[*frameUsed];
++ int val, stereo = dmasound.soft.stereo;
++
++ frameLeft >>= 2;
++ if (stereo)
++ userCount >>= 1;
++ used = count = min_t(unsigned long, userCount, frameLeft);
++ while (count > 0) {
++ u_char data;
++ if (get_user(data, userPtr++))
++ return -EFAULT;
++ val = data << 8;
++ *p++ = val;
++ if (stereo) {
++ if (get_user(data, userPtr++))
++ return -EFAULT;
++ val = data << 8;
++ }
++ *p++ = val;
++ count--;
++ }
++ *frameUsed += used * 4;
++ return stereo? used * 2: used;
++}
++
++
++static ssize_t pmac_ct_u8(const u_char *userPtr, size_t userCount,
++ u_char frame[], ssize_t *frameUsed,
++ ssize_t frameLeft)
++{
++ ssize_t count, used;
++ short *p = (short *) &frame[*frameUsed];
++ int val, stereo = dmasound.soft.stereo;
++
++ frameLeft >>= 2;
++ if (stereo)
++ userCount >>= 1;
++ used = count = min_t(unsigned long, userCount, frameLeft);
++ while (count > 0) {
++ u_char data;
++ if (get_user(data, userPtr++))
++ return -EFAULT;
++ val = (data ^ 0x80) << 8;
++ *p++ = val;
++ if (stereo) {
++ if (get_user(data, userPtr++))
++ return -EFAULT;
++ val = (data ^ 0x80) << 8;
++ }
++ *p++ = val;
++ count--;
++ }
++ *frameUsed += used * 4;
++ return stereo? used * 2: used;
++}
++
++
++static ssize_t pmac_ct_s16(const u_char *userPtr, size_t userCount,
++ u_char frame[], ssize_t *frameUsed,
++ ssize_t frameLeft)
++{
++ ssize_t count, used;
++ int stereo = dmasound.soft.stereo;
++ short *fp = (short *) &frame[*frameUsed];
++
++ frameLeft >>= 2;
++ userCount >>= (stereo? 2: 1);
++ used = count = min_t(unsigned long, userCount, frameLeft);
++ if (!stereo) {
++ short *up = (short *) userPtr;
++ while (count > 0) {
++ short data;
++ if (get_user(data, up++))
++ return -EFAULT;
++ *fp++ = data;
++ *fp++ = data;
++ count--;
++ }
++ } else {
++ if (copy_from_user(fp, userPtr, count * 4))
++ return -EFAULT;
++ }
++ *frameUsed += used * 4;
++ return stereo? used * 4: used * 2;
++}
++
++static ssize_t pmac_ct_u16(const u_char *userPtr, size_t userCount,
++ u_char frame[], ssize_t *frameUsed,
++ ssize_t frameLeft)
++{
++ ssize_t count, used;
++ int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
++ int stereo = dmasound.soft.stereo;
++ short *fp = (short *) &frame[*frameUsed];
++ short *up = (short *) userPtr;
++
++ frameLeft >>= 2;
++ userCount >>= (stereo? 2: 1);
++ used = count = min_t(unsigned long, userCount, frameLeft);
++ while (count > 0) {
++ short data;
++ if (get_user(data, up++))
++ return -EFAULT;
++ data ^= mask;
++ *fp++ = data;
++ if (stereo) {
++ if (get_user(data, up++))
++ return -EFAULT;
++ data ^= mask;
++ }
++ *fp++ = data;
++ count--;
++ }
++ *frameUsed += used * 4;
++ return stereo? used * 4: used * 2;
++}
++
++
++static ssize_t pmac_ctx_law(const u_char *userPtr, size_t userCount,
++ u_char frame[], ssize_t *frameUsed,
++ ssize_t frameLeft)
++{
++ unsigned short *table = (unsigned short *)
++ (dmasound.soft.format == AFMT_MU_LAW
++ ? dmasound_ulaw2dma16 : dmasound_alaw2dma16);
++ unsigned int data = expand_data;
++ unsigned int *p = (unsigned int *) &frame[*frameUsed];
++ int bal = expand_bal;
++ int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
++ int utotal, ftotal;
++ int stereo = dmasound.soft.stereo;
++
++ frameLeft >>= 2;
++ if (stereo)
++ userCount >>= 1;
++ ftotal = frameLeft;
++ utotal = userCount;
++ while (frameLeft) {
++ u_char c;
++ if (bal < 0) {
++ if (userCount == 0)
++ break;
++ if (get_user(c, userPtr++))
++ return -EFAULT;
++ data = table[c];
++ if (stereo) {
++ if (get_user(c, userPtr++))
++ return -EFAULT;
++ data = (data << 16) + table[c];
++ } else
++ data = (data << 16) + data;
++ userCount--;
++ bal += hSpeed;
++ }
++ *p++ = data;
++ frameLeft--;
++ bal -= sSpeed;
++ }
++ expand_bal = bal;
++ expand_data = data;
++ *frameUsed += (ftotal - frameLeft) * 4;
++ utotal -= userCount;
++ return stereo? utotal * 2: utotal;
++}
++
++static ssize_t pmac_ctx_s8(const u_char *userPtr, size_t userCount,
++ u_char frame[], ssize_t *frameUsed,
++ ssize_t frameLeft)
++{
++ unsigned int *p = (unsigned int *) &frame[*frameUsed];
++ unsigned int data = expand_data;
++ int bal = expand_bal;
++ int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
++ int stereo = dmasound.soft.stereo;
++ int utotal, ftotal;
++
++ frameLeft >>= 2;
++ if (stereo)
++ userCount >>= 1;
++ ftotal = frameLeft;
++ utotal = userCount;
++ while (frameLeft) {
++ u_char c;
++ if (bal < 0) {
++ if (userCount == 0)
++ break;
++ if (get_user(c, userPtr++))
++ return -EFAULT;
++ data = c << 8;
++ if (stereo) {
++ if (get_user(c, userPtr++))
++ return -EFAULT;
++ data = (data << 16) + (c << 8);
++ } else
++ data = (data << 16) + data;
++ userCount--;
++ bal += hSpeed;
++ }
++ *p++ = data;
++ frameLeft--;
++ bal -= sSpeed;
++ }
++ expand_bal = bal;
++ expand_data = data;
++ *frameUsed += (ftotal - frameLeft) * 4;
++ utotal -= userCount;
++ return stereo? utotal * 2: utotal;
++}
++
++
++static ssize_t pmac_ctx_u8(const u_char *userPtr, size_t userCount,
++ u_char frame[], ssize_t *frameUsed,
++ ssize_t frameLeft)
++{
++ unsigned int *p = (unsigned int *) &frame[*frameUsed];
++ unsigned int data = expand_data;
++ int bal = expand_bal;
++ int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
++ int stereo = dmasound.soft.stereo;
++ int utotal, ftotal;
++
++ frameLeft >>= 2;
++ if (stereo)
++ userCount >>= 1;
++ ftotal = frameLeft;
++ utotal = userCount;
++ while (frameLeft) {
++ u_char c;
++ if (bal < 0) {
++ if (userCount == 0)
++ break;
++ if (get_user(c, userPtr++))
++ return -EFAULT;
++ data = (c ^ 0x80) << 8;
++ if (stereo) {
++ if (get_user(c, userPtr++))
++ return -EFAULT;
++ data = (data << 16) + ((c ^ 0x80) << 8);
++ } else
++ data = (data << 16) + data;
++ userCount--;
++ bal += hSpeed;
++ }
++ *p++ = data;
++ frameLeft--;
++ bal -= sSpeed;
++ }
++ expand_bal = bal;
++ expand_data = data;
++ *frameUsed += (ftotal - frameLeft) * 4;
++ utotal -= userCount;
++ return stereo? utotal * 2: utotal;
++}
++
++
++static ssize_t pmac_ctx_s16(const u_char *userPtr, size_t userCount,
++ u_char frame[], ssize_t *frameUsed,
++ ssize_t frameLeft)
++{
++ unsigned int *p = (unsigned int *) &frame[*frameUsed];
++ unsigned int data = expand_data;
++ unsigned short *up = (unsigned short *) userPtr;
++ int bal = expand_bal;
++ int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
++ int stereo = dmasound.soft.stereo;
++ int utotal, ftotal;
++
++ frameLeft >>= 2;
++ userCount >>= (stereo? 2: 1);
++ ftotal = frameLeft;
++ utotal = userCount;
++ while (frameLeft) {
++ unsigned short c;
++ if (bal < 0) {
++ if (userCount == 0)
++ break;
++ if (get_user(data, up++))
++ return -EFAULT;
++ if (stereo) {
++ if (get_user(c, up++))
++ return -EFAULT;
++ data = (data << 16) + c;
++ } else
++ data = (data << 16) + data;
++ userCount--;
++ bal += hSpeed;
++ }
++ *p++ = data;
++ frameLeft--;
++ bal -= sSpeed;
++ }
++ expand_bal = bal;
++ expand_data = data;
++ *frameUsed += (ftotal - frameLeft) * 4;
++ utotal -= userCount;
++ return stereo? utotal * 4: utotal * 2;
++}
++
++
++static ssize_t pmac_ctx_u16(const u_char *userPtr, size_t userCount,
++ u_char frame[], ssize_t *frameUsed,
++ ssize_t frameLeft)
++{
++ int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
++ unsigned int *p = (unsigned int *) &frame[*frameUsed];
++ unsigned int data = expand_data;
++ unsigned short *up = (unsigned short *) userPtr;
++ int bal = expand_bal;
++ int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
++ int stereo = dmasound.soft.stereo;
++ int utotal, ftotal;
++
++ frameLeft >>= 2;
++ userCount >>= (stereo? 2: 1);
++ ftotal = frameLeft;
++ utotal = userCount;
++ while (frameLeft) {
++ unsigned short c;
++ if (bal < 0) {
++ if (userCount == 0)
++ break;
++ if (get_user(data, up++))
++ return -EFAULT;
++ data ^= mask;
++ if (stereo) {
++ if (get_user(c, up++))
++ return -EFAULT;
++ data = (data << 16) + (c ^ mask);
++ } else
++ data = (data << 16) + data;
++ userCount--;
++ bal += hSpeed;
++ }
++ *p++ = data;
++ frameLeft--;
++ bal -= sSpeed;
++ }
++ expand_bal = bal;
++ expand_data = data;
++ *frameUsed += (ftotal - frameLeft) * 4;
++ utotal -= userCount;
++ return stereo? utotal * 4: utotal * 2;
++}
++
++/* data in routines... */
++
++static ssize_t pmac_ct_s8_read(const u_char *userPtr, size_t userCount,
++ u_char frame[], ssize_t *frameUsed,
++ ssize_t frameLeft)
++{
++ ssize_t count, used;
++ short *p = (short *) &frame[*frameUsed];
++ int val, stereo = dmasound.soft.stereo;
++
++ frameLeft >>= 2;
++ if (stereo)
++ userCount >>= 1;
++ used = count = min_t(unsigned long, userCount, frameLeft);
++ while (count > 0) {
++ u_char data;
++
++ val = *p++;
++ data = val >> 8;
++ if (put_user(data, (u_char *)userPtr++))
++ return -EFAULT;
++ if (stereo) {
++ val = *p;
++ data = val >> 8;
++ if (put_user(data, (u_char *)userPtr++))
++ return -EFAULT;
++ }
++ p++;
++ count--;
++ }
++ *frameUsed += used * 4;
++ return stereo? used * 2: used;
++}
++
++
++static ssize_t pmac_ct_u8_read(const u_char *userPtr, size_t userCount,
++ u_char frame[], ssize_t *frameUsed,
++ ssize_t frameLeft)
++{
++ ssize_t count, used;
++ short *p = (short *) &frame[*frameUsed];
++ int val, stereo = dmasound.soft.stereo;
++
++ frameLeft >>= 2;
++ if (stereo)
++ userCount >>= 1;
++ used = count = min_t(unsigned long, userCount, frameLeft);
++ while (count > 0) {
++ u_char data;
++
++ val = *p++;
++ data = (val >> 8) ^ 0x80;
++ if (put_user(data, (u_char *)userPtr++))
++ return -EFAULT;
++ if (stereo) {
++ val = *p;
++ data = (val >> 8) ^ 0x80;
++ if (put_user(data, (u_char *)userPtr++))
++ return -EFAULT;
++ }
++ p++;
++ count--;
++ }
++ *frameUsed += used * 4;
++ return stereo? used * 2: used;
++}
++
++static ssize_t pmac_ct_s16_read(const u_char *userPtr, size_t userCount,
++ u_char frame[], ssize_t *frameUsed,
++ ssize_t frameLeft)
++{
++ ssize_t count, used;
++ int stereo = dmasound.soft.stereo;
++ short *fp = (short *) &frame[*frameUsed];
++
++ frameLeft >>= 2;
++ userCount >>= (stereo? 2: 1);
++ used = count = min_t(unsigned long, userCount, frameLeft);
++ if (!stereo) {
++ short *up = (short *) userPtr;
++ while (count > 0) {
++ short data;
++ data = *fp;
++ if (put_user(data, up++))
++ return -EFAULT;
++ fp+=2;
++ count--;
++ }
++ } else {
++ if (copy_to_user((u_char *)userPtr, fp, count * 4))
++ return -EFAULT;
++ }
++ *frameUsed += used * 4;
++ return stereo? used * 4: used * 2;
++}
++
++static ssize_t pmac_ct_u16_read(const u_char *userPtr, size_t userCount,
++ u_char frame[], ssize_t *frameUsed,
++ ssize_t frameLeft)
++{
++ ssize_t count, used;
++ int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
++ int stereo = dmasound.soft.stereo;
++ short *fp = (short *) &frame[*frameUsed];
++ short *up = (short *) userPtr;
++
++ frameLeft >>= 2;
++ userCount >>= (stereo? 2: 1);
++ used = count = min_t(unsigned long, userCount, frameLeft);
++ while (count > 0) {
++ int data;
++
++ data = *fp++;
++ data ^= mask;
++ if (put_user(data, up++))
++ return -EFAULT;
++ if (stereo) {
++ data = *fp;
++ data ^= mask;
++ if (put_user(data, up++))
++ return -EFAULT;
++ }
++ fp++;
++ count--;
++ }
++ *frameUsed += used * 4;
++ return stereo? used * 4: used * 2;
++}
++
++TRANS transAwacsNormal = {
++ ct_ulaw: pmac_ct_law,
++ ct_alaw: pmac_ct_law,
++ ct_s8: pmac_ct_s8,
++ ct_u8: pmac_ct_u8,
++ ct_s16be: pmac_ct_s16,
++ ct_u16be: pmac_ct_u16,
++ ct_s16le: pmac_ct_s16,
++ ct_u16le: pmac_ct_u16,
++};
++
++TRANS transAwacsExpand = {
++ ct_ulaw: pmac_ctx_law,
++ ct_alaw: pmac_ctx_law,
++ ct_s8: pmac_ctx_s8,
++ ct_u8: pmac_ctx_u8,
++ ct_s16be: pmac_ctx_s16,
++ ct_u16be: pmac_ctx_u16,
++ ct_s16le: pmac_ctx_s16,
++ ct_u16le: pmac_ctx_u16,
++};
++
++TRANS transAwacsNormalRead = {
++ ct_s8: pmac_ct_s8_read,
++ ct_u8: pmac_ct_u8_read,
++ ct_s16be: pmac_ct_s16_read,
++ ct_u16be: pmac_ct_u16_read,
++ ct_s16le: pmac_ct_s16_read,
++ ct_u16le: pmac_ct_u16_read,
++};
++
++/* translation tables */
++/* 16 bit mu-law */
++
++static short dmasound_ulaw2dma16[] = {
++ -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
++ -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
++ -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
++ -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
++ -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
++ -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
++ -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
++ -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
++ -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
++ -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
++ -876, -844, -812, -780, -748, -716, -684, -652,
++ -620, -588, -556, -524, -492, -460, -428, -396,
++ -372, -356, -340, -324, -308, -292, -276, -260,
++ -244, -228, -212, -196, -180, -164, -148, -132,
++ -120, -112, -104, -96, -88, -80, -72, -64,
++ -56, -48, -40, -32, -24, -16, -8, 0,
++ 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
++ 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
++ 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
++ 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
++ 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
++ 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
++ 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
++ 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
++ 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
++ 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
++ 876, 844, 812, 780, 748, 716, 684, 652,
++ 620, 588, 556, 524, 492, 460, 428, 396,
++ 372, 356, 340, 324, 308, 292, 276, 260,
++ 244, 228, 212, 196, 180, 164, 148, 132,
++ 120, 112, 104, 96, 88, 80, 72, 64,
++ 56, 48, 40, 32, 24, 16, 8, 0,
++};
++
++/* 16 bit A-law */
++
++static short dmasound_alaw2dma16[] = {
++ -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736,
++ -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784,
++ -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368,
++ -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392,
++ -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
++ -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136,
++ -11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472,
++ -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568,
++ -344, -328, -376, -360, -280, -264, -312, -296,
++ -472, -456, -504, -488, -408, -392, -440, -424,
++ -88, -72, -120, -104, -24, -8, -56, -40,
++ -216, -200, -248, -232, -152, -136, -184, -168,
++ -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184,
++ -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696,
++ -688, -656, -752, -720, -560, -528, -624, -592,
++ -944, -912, -1008, -976, -816, -784, -880, -848,
++ 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736,
++ 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784,
++ 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368,
++ 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392,
++ 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944,
++ 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136,
++ 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472,
++ 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568,
++ 344, 328, 376, 360, 280, 264, 312, 296,
++ 472, 456, 504, 488, 408, 392, 440, 424,
++ 88, 72, 120, 104, 24, 8, 56, 40,
++ 216, 200, 248, 232, 152, 136, 184, 168,
++ 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184,
++ 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696,
++ 688, 656, 752, 720, 560, 528, 624, 592,
++ 944, 912, 1008, 976, 816, 784, 880, 848,
++};
+Index: linux-2.6.0-test5/sound/oss/forte.c
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/forte.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/sound/oss/forte.c 2003-09-27 11:38:42.572056448 +0800
+@@ -37,7 +37,6 @@
+
+ #include <linux/delay.h>
+ #include <linux/poll.h>
+-#include <linux/kernel.h>
+
+ #include <linux/sound.h>
+ #include <linux/ac97_codec.h>
+Index: linux-2.6.0-test5/sound/oss/i810_audio.c
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/i810_audio.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/sound/oss/i810_audio.c 2003-09-27 11:38:42.761027720 +0800
+@@ -2728,7 +2728,7 @@
+ i810_ac97_get(codec, AC97_POWER_CONTROL) & ~0x7f00);
+
+ /* wait for analog ready */
+- for (i=10; i && ((i810_ac97_get(codec, AC97_POWER_CONTROL) & 0xf) != 0xf); i--)
++ for (i=100; i && ((i810_ac97_get(codec, AC97_POWER_CONTROL) & 0xf) != 0xf); i--)
+ {
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(HZ/20);
+@@ -3091,10 +3091,17 @@
+ return -EIO;
+
+ if (pci_set_dma_mask(pci_dev, I810_DMA_MASK)) {
+- printk(KERN_ERR "intel810: architecture does not support"
++ printk(KERN_ERR "i810_audio: architecture does not support"
+ " 32bit PCI busmaster DMA\n");
+ return -ENODEV;
+ }
++
++ if( pci_resource_start(pci_dev, 1) == 0)
++ {
++ /* MMIO only ICH5 .. here be dragons .. */
++ printk(KERN_ERR "i810_audio: Pure MMIO interfaces not yet supported.\n");
++ return -ENODEV;
++ }
+
+ if ((card = kmalloc(sizeof(struct i810_card), GFP_KERNEL)) == NULL) {
+ printk(KERN_ERR "i810_audio: out of memory\n");
+Index: linux-2.6.0-test5/sound/oss/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/Kconfig 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/sound/oss/Kconfig 2003-09-27 11:38:43.119973152 +0800
+@@ -237,13 +237,6 @@
+ tristate "PA Harmony audio driver"
+ depends on GSC_LASI && SOUND
+
+-config SOUND_RME96XX
+- tristate "RME Hammerfall (RME96XX) support (EXPERIMENTAL)"
+- depends on SOUND_PRIME!=n && SOUND && PCI && EXPERIMENTAL
+- help
+- Say Y or M if you have a Hammerfall, Hammerfall light or Hammerfall
+- DSP card from RME.
+-
+ config SOUND_SONICVIBES
+ tristate "S3 SonicVibes"
+ depends on SOUND_PRIME!=n && SOUND && SOUND_GAMEPORT
+Index: linux-2.6.0-test5/sound/oss/nec_vrc5477.c
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/nec_vrc5477.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/sound/oss/nec_vrc5477.c 2003-09-27 11:38:43.583902624 +0800
+@@ -96,7 +96,6 @@
+ #endif
+
+ #if defined(VRC5477_AC97_DEBUG)
+-#include <linux/kernel.h>
+ #define ASSERT(x) if (!(x)) { \
+ panic("assertion failed at %s:%d: %s\n", __FILE__, __LINE__, #x); }
+ #else
+Index: linux-2.6.0-test5/sound/oss/rme96xx.c
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/rme96xx.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/sound/oss/rme96xx.c 2003-09-27 11:38:43.847862496 +0800
+@@ -54,7 +54,6 @@
+ #include <linux/smp_lock.h>
+ #include <linux/delay.h>
+ #include <linux/slab.h>
+-#include <asm/dma.h>
+ #include <asm/hardirq.h>
+ #include <linux/init.h>
+ #include <linux/interrupt.h>
+Index: linux-2.6.0-test5/sound/oss/vwsnd.c
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/vwsnd.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/sound/oss/vwsnd.c 2003-09-27 11:38:43.977842736 +0800
+@@ -158,8 +158,6 @@
+
+ #ifdef VWSND_DEBUG
+
+-#include <linux/interrupt.h> /* for in_interrupt() */
+-
+ static int shut_up = 1;
+
+ /*
+Index: linux-2.6.0-test5/sound/pci/ens1370.c
+===================================================================
+--- linux-2.6.0-test5.orig/sound/pci/ens1370.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/sound/pci/ens1370.c 2003-09-27 11:38:44.106823128 +0800
+@@ -47,6 +47,13 @@
+ #define CHIP1370
+ #endif
+
++#ifdef CHIP1370
++#define DRIVER_NAME "ENS1370"
++#else
++#define DRIVER_NAME "ENS1371"
++#endif
++
++
+ MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, Thomas Sailer <sailer@ife.ee.ethz.ch>");
+ MODULE_LICENSE("GPL");
+ MODULE_CLASSES("{sound}");
+@@ -2324,12 +2331,8 @@
+ snd_card_free(card);
+ return err;
+ }
+-#ifdef CHIP1370
+- strcpy(card->driver, "ENS1370");
+-#endif
+-#ifdef CHIP1371
+- strcpy(card->driver, "ENS1371");
+-#endif
++ strcpy(card->driver, DRIVER_NAME);
++
+ strcpy(card->shortname, "Ensoniq AudioPCI");
+ sprintf(card->longname, "%s %s at 0x%lx, irq %i",
+ card->shortname,
+@@ -2354,7 +2357,7 @@
+ }
+
+ static struct pci_driver driver = {
+- .name = "Ensoniq AudioPCI",
++ .name = DRIVER_NAME,
+ .id_table = snd_audiopci_ids,
+ .probe = snd_audiopci_probe,
+ .remove = __devexit_p(snd_audiopci_remove),
+Index: linux-2.6.0-test5/sound/pci/intel8x0.c
+===================================================================
+--- linux-2.6.0-test5.orig/sound/pci/intel8x0.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/sound/pci/intel8x0.c 2003-09-27 11:38:44.188810664 +0800
+@@ -2231,10 +2231,8 @@
+
+ t = stop_time.tv_sec - start_time.tv_sec;
+ t *= 1000000;
+- if (stop_time.tv_usec < start_time.tv_usec)
+- t -= start_time.tv_usec - stop_time.tv_usec;
+- else
+- t += stop_time.tv_usec - start_time.tv_usec;
++ t += stop_time.tv_usec - start_time.tv_usec;
++ printk(KERN_INFO "%s: measured %lu usecs\n", __FUNCTION__, t);
+ if (t == 0) {
+ snd_printk(KERN_ERR "?? calculation error..\n");
+ return;
+Index: linux-2.6.0-test5/usr/gen_init_cpio.c
+===================================================================
+--- linux-2.6.0-test5.orig/usr/gen_init_cpio.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/usr/gen_init_cpio.c 2003-09-27 11:38:44.576751688 +0800
+@@ -212,7 +212,7 @@
+
+ int main (int argc, char *argv[])
+ {
+- cpio_mkdir("/dev", 0700, 0, 0);
++ cpio_mkdir("/dev", 0755, 0, 0);
+ cpio_mknod("/dev/console", 0600, 0, 0, 'c', 5, 1);
+ cpio_mkdir("/root", 0700, 0, 0);
+ cpio_trailer();