[kernel] r6827 - in dists/trunk/linux-2.6/debian: . arch/hppa
patches/series
Kyle McMartin
kyle at costa.debian.org
Sun Jun 18 23:36:29 UTC 2006
Author: kyle
Date: Sun Jun 18 23:36:27 2006
New Revision: 6827
Added:
dists/trunk/linux-2.6/debian/patches/hppa.patch
Modified:
dists/trunk/linux-2.6/debian/arch/hppa/config
dists/trunk/linux-2.6/debian/arch/hppa/config.parisc-smp
dists/trunk/linux-2.6/debian/arch/hppa/config.parisc64-smp
dists/trunk/linux-2.6/debian/changelog
dists/trunk/linux-2.6/debian/patches/series/0experimental.1-extra
Log:
parisc changes for 2.6.17
Modified: dists/trunk/linux-2.6/debian/arch/hppa/config
==============================================================================
--- dists/trunk/linux-2.6/debian/arch/hppa/config (original)
+++ dists/trunk/linux-2.6/debian/arch/hppa/config Sun Jun 18 23:36:27 2006
@@ -40,6 +40,9 @@
# CONFIG_PA7100LC is not set
# CONFIG_PA7200 is not set
# CONFIG_PA7300LC is not set
+CONFIG_PARISC_PAGE_SIZE_4KB=y
+# CONFIG_PARISC_PAGE_SIZE_16KB is not set
+# CONFIG_PARISC_PAGE_SIZE_64KB is not set
CONFIG_GSC=y
CONFIG_HPPB=y
CONFIG_IOMMU_CCIO=y
Modified: dists/trunk/linux-2.6/debian/arch/hppa/config.parisc-smp
==============================================================================
--- dists/trunk/linux-2.6/debian/arch/hppa/config.parisc-smp (original)
+++ dists/trunk/linux-2.6/debian/arch/hppa/config.parisc-smp Sun Jun 18 23:36:27 2006
@@ -7,7 +7,7 @@
CONFIG_SMP=y
CONFIG_HOTPLUG_CPU=y
# CONFIG_HPUX is not set
-CONFIG_NR_CPUS=32
+CONFIG_NR_CPUS=8
# CONFIG_SCSI_DPT_I2O is not set
# CONFIG_SCSI_NSP32 is not set
CONFIG_PCMCIA_AHA152X=m
Modified: dists/trunk/linux-2.6/debian/arch/hppa/config.parisc64-smp
==============================================================================
--- dists/trunk/linux-2.6/debian/arch/hppa/config.parisc64-smp (original)
+++ dists/trunk/linux-2.6/debian/arch/hppa/config.parisc64-smp Sun Jun 18 23:36:27 2006
@@ -10,7 +10,7 @@
CONFIG_HOTPLUG_CPU=y
CONFIG_DISCONTIGMEM=y
CONFIG_COMPAT=y
-CONFIG_NR_CPUS=32
+CONFIG_NR_CPUS=8
# CONFIG_DEBUG_RWLOCK is not set
CONFIG_NEED_MULTIPLE_NODES=y
# CONFIG_FLATMEM_MANUAL is not set
Modified: dists/trunk/linux-2.6/debian/changelog
==============================================================================
--- dists/trunk/linux-2.6/debian/changelog (original)
+++ dists/trunk/linux-2.6/debian/changelog Sun Jun 18 23:36:27 2006
@@ -13,6 +13,11 @@
* [mips] Fix SWARM FPU detection.
* [mips] Update configurations.
+ [ Kyle McMartin ]
+ * [hppa] Update patchset (2.6.17-pa1) from parisc-linux.org.
+ * [hppa] Change NR_CPUS to 8 from 32 on both SMP flavours.
+ * [hppa] Set PARISC_PAGE_SIZE to 4K on all platforms.
+
[ Bastian Blank ]
* [s390] Use gcc 4.1.
* [i386] Enable REGPARM.
Added: dists/trunk/linux-2.6/debian/patches/hppa.patch
==============================================================================
--- (empty file)
+++ dists/trunk/linux-2.6/debian/patches/hppa.patch Sun Jun 18 23:36:27 2006
@@ -0,0 +1,2902 @@
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/CREDITS CVS2_6_17_PA0/CREDITS
+--- LINUS_2_6_17/CREDITS 2006-06-17 22:24:34.000000000 -0600
++++ CVS2_6_17_PA0/CREDITS 2006-05-27 10:29:47.000000000 -0600
+@@ -3400,10 +3400,10 @@
+
+ N: Thibaut Varene
+ E: T-Bone at parisc-linux.org
+-W: http://www.parisc-linux.org/
++W: http://www.parisc-linux.org/~varenet/
+ P: 1024D/B7D2F063 E67C 0D43 A75E 12A5 BB1C FA2F 1E32 C3DA B7D2 F063
+ D: PA-RISC port minion, PDC and GSCPS2 drivers, debuglocks and other bits
+-D: Some bits in an ARM port, S1D13XXX FB driver, random patches here and there
++D: Some ARM at91rm9200 bits, S1D13XXX FB driver, random patches here and there
+ D: AD1889 sound driver
+ S: Paris, France
+
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/Documentation/pci.txt CVS2_6_17_PA0/Documentation/pci.txt
+--- LINUS_2_6_17/Documentation/pci.txt 2006-06-17 22:24:34.000000000 -0600
++++ CVS2_6_17_PA0/Documentation/pci.txt 2006-06-05 15:32:03.000000000 -0600
+@@ -213,9 +213,17 @@
+
+ See Documentation/IO-mapping.txt for how to access device memory.
+
+- You still need to call request_region() for I/O regions and
+-request_mem_region() for memory regions to make sure nobody else is using the
+-same device.
++ The device driver needs to call pci_request_region() to make sure
++no other device is already using the same resource. The driver is expected
++to determine MMIO and IO Port resource availability _before_ calling
++pci_enable_device(). Conversely, drivers should call pci_release_region()
++_after_ calling pci_disable_device(). The idea is to prevent two devices
++colliding on the same address range.
++
++Generic flavors of pci_request_region() are request_mem_region()
++(for MMIO ranges) and request_region() (for IO Port ranges).
++Use these for address resources that are not described by "normal" PCI
++interfaces (e.g. BAR).
+
+ All interrupt handlers should be registered with SA_SHIRQ and use the devid
+ to map IRQs to devices (remember that all PCI interrupts are shared).
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/arch/parisc/kernel/cache.c CVS2_6_17_PA0/arch/parisc/kernel/cache.c
+--- LINUS_2_6_17/arch/parisc/kernel/cache.c 2006-06-17 22:24:39.000000000 -0600
++++ CVS2_6_17_PA0/arch/parisc/kernel/cache.c 2006-06-16 12:20:00.000000000 -0600
+@@ -97,15 +97,16 @@
+ void
+ show_cache_info(struct seq_file *m)
+ {
++ char buf[64];
++
+ seq_printf(m, "I-cache\t\t: %ld KB\n",
+ cache_info.ic_size/1024 );
+- seq_printf(m, "D-cache\t\t: %ld KB (%s%s, %d-way associative)\n",
++ snprintf(buf, 64, "%lu-way associative", cache_info.dc_loop);
++ seq_printf(m, "D-cache\t\t: %ld KB (%s%s, %s)\n",
+ cache_info.dc_size/1024,
+ (cache_info.dc_conf.cc_wt ? "WT":"WB"),
+ (cache_info.dc_conf.cc_sh ? ", shared I/D":""),
+- (cache_info.dc_conf.cc_assoc)
+- );
+-
++ ((cache_info.dc_loop == 1) ? "direct-mapped" : buf));
+ seq_printf(m, "ITLB entries\t: %ld\n" "DTLB entries\t: %ld%s\n",
+ cache_info.it_size,
+ cache_info.dt_size,
+@@ -158,11 +159,11 @@
+ cache_info.dc_conf.cc_block,
+ cache_info.dc_conf.cc_line,
+ cache_info.dc_conf.cc_shift);
+- printk(" wt %d sh %d cst %d assoc %d\n",
++ printk(" wt %d sh %d cst %d hv %d\n",
+ cache_info.dc_conf.cc_wt,
+ cache_info.dc_conf.cc_sh,
+ cache_info.dc_conf.cc_cst,
+- cache_info.dc_conf.cc_assoc);
++ cache_info.dc_conf.cc_hv);
+
+ printk("IC base 0x%lx stride 0x%lx count 0x%lx loop 0x%lx\n",
+ cache_info.ic_base,
+@@ -176,11 +177,11 @@
+ cache_info.ic_conf.cc_block,
+ cache_info.ic_conf.cc_line,
+ cache_info.ic_conf.cc_shift);
+- printk(" wt %d sh %d cst %d assoc %d\n",
++ printk(" wt %d sh %d cst %d hv %d\n",
+ cache_info.ic_conf.cc_wt,
+ cache_info.ic_conf.cc_sh,
+ cache_info.ic_conf.cc_cst,
+- cache_info.ic_conf.cc_assoc);
++ cache_info.ic_conf.cc_hv);
+
+ printk("D-TLB conf: sh %d page %d cst %d aid %d pad1 %d \n",
+ cache_info.dt_conf.tc_sh,
+@@ -234,7 +235,8 @@
+
+ void disable_sr_hashing(void)
+ {
+- int srhash_type;
++ int srhash_type, retval;
++ unsigned long space_bits;
+
+ switch (boot_cpu_data.cpu_type) {
+ case pcx: /* We shouldn't get this far. setup.c should prevent it. */
+@@ -260,6 +262,12 @@
+ }
+
+ disable_sr_hashing_asm(srhash_type);
++
++ retval = pdc_spaceid_bits(&space_bits);
++ if (retval < 0)
++ panic("pdc_spaceid_bits call failed.\n");
++ if (space_bits != 0)
++ panic("SpaceID hashing is still on!\n");
+ }
+
+ void flush_dcache_page(struct page *page)
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/arch/parisc/kernel/entry.S CVS2_6_17_PA0/arch/parisc/kernel/entry.S
+--- LINUS_2_6_17/arch/parisc/kernel/entry.S 2006-06-17 22:24:39.000000000 -0600
++++ CVS2_6_17_PA0/arch/parisc/kernel/entry.S 2006-04-23 20:26:57.000000000 -0600
+@@ -1638,7 +1638,7 @@
+ load32 PA(pa_dbit_lock),t0
+
+ dbit_spin_20w:
+- ldcw 0(t0),t1
++ LDCW 0(t0),t1
+ cmpib,= 0,t1,dbit_spin_20w
+ nop
+
+@@ -1674,7 +1674,7 @@
+ load32 PA(pa_dbit_lock),t0
+
+ dbit_spin_11:
+- ldcw 0(t0),t1
++ LDCW 0(t0),t1
+ cmpib,= 0,t1,dbit_spin_11
+ nop
+
+@@ -1714,7 +1714,7 @@
+ load32 PA(pa_dbit_lock),t0
+
+ dbit_spin_20:
+- ldcw 0(t0),t1
++ LDCW 0(t0),t1
+ cmpib,= 0,t1,dbit_spin_20
+ nop
+
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/arch/parisc/kernel/firmware.c CVS2_6_17_PA0/arch/parisc/kernel/firmware.c
+--- LINUS_2_6_17/arch/parisc/kernel/firmware.c 2006-06-17 22:24:39.000000000 -0600
++++ CVS2_6_17_PA0/arch/parisc/kernel/firmware.c 2006-06-16 12:20:00.000000000 -0600
+@@ -11,7 +11,7 @@
+ * Copyright 1999 The Puffin Group, (Alex deVries, David Kennedy)
+ * Copyright 2003 Grant Grundler <grundler parisc-linux org>
+ * Copyright 2003,2004 Ryan Bradetich <rbrad at parisc-linux.org>
+- * Copyright 2004 Thibaut VARENE <varenet at parisc-linux.org>
++ * Copyright 2004,2006 Thibaut VARENE <varenet at parisc-linux.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+@@ -252,10 +252,8 @@
+ #endif
+
+ /**
+- * pdc_chassis_disp - Updates display
++ * pdc_chassis_disp - Updates chassis code
+ * @retval: -1 on error, 0 on success
+- *
+- * Works on old PDC only (E class, others?)
+ */
+ int pdc_chassis_disp(unsigned long disp)
+ {
+@@ -269,6 +267,22 @@
+ }
+
+ /**
++ * pdc_chassis_warn - Fetches chassis warnings
++ * @retval: -1 on error, 0 on success
++ */
++int pdc_chassis_warn(unsigned long *warn)
++{
++ int retval = 0;
++
++ spin_lock_irq(&pdc_lock);
++ retval = mem_pdc_call(PDC_CHASSIS, PDC_CHASSIS_WARN, __pa(pdc_result));
++ *warn = pdc_result[0];
++ spin_unlock_irq(&pdc_lock);
++
++ return retval;
++}
++
++/**
+ * pdc_coproc_cfg - To identify coprocessors attached to the processor.
+ * @pdc_coproc_info: Return buffer address.
+ *
+@@ -498,6 +512,25 @@
+ return retval;
+ }
+
++/**
++ * pdc_spaceid_bits - Return whether Space ID hashing is turned on.
++ * @space_bits: Should be 0, if not, bad mojo!
++ *
++ * Returns information about Space ID hashing.
++ */
++int pdc_spaceid_bits(unsigned long *space_bits)
++{
++ int retval;
++
++ spin_lock_irq(&pdc_lock);
++ retval = mem_pdc_call(PDC_CACHE, PDC_CACHE_RET_SPID, __pa(pdc_result), 0);
++ convert_to_wide(pdc_result);
++ *space_bits = pdc_result[0];
++ spin_unlock_irq(&pdc_lock);
++
++ return retval;
++}
++
+ #ifndef CONFIG_PA20
+ /**
+ * pdc_btlb_info - Return block TLB information.
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/arch/parisc/kernel/pdc_chassis.c CVS2_6_17_PA0/arch/parisc/kernel/pdc_chassis.c
+--- LINUS_2_6_17/arch/parisc/kernel/pdc_chassis.c 2006-06-17 22:24:39.000000000 -0600
++++ CVS2_6_17_PA0/arch/parisc/kernel/pdc_chassis.c 2006-05-04 09:29:32.000000000 -0600
+@@ -1,8 +1,8 @@
+ /*
+- * interfaces to log Chassis Codes via PDC (firmware)
++ * interfaces to Chassis Codes via PDC (firmware)
+ *
+ * Copyright (C) 2002 Laurent Canet <canetl at esiee.fr>
+- * Copyright (C) 2002-2004 Thibaut VARENE <varenet at parisc-linux.org>
++ * Copyright (C) 2002-2006 Thibaut VARENE <varenet at parisc-linux.org>
+ *
+ * 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
+@@ -16,6 +16,10 @@
+ * 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
++ *
++ * TODO: poll chassis warns, trigger (configurable) machine shutdown when
++ * needed.
++ * Find out how to get Chassis warnings out of PAT boxes?
+ */
+
+ #undef PDC_CHASSIS_DEBUG
+@@ -30,15 +34,16 @@
+ #include <linux/reboot.h>
+ #include <linux/notifier.h>
+ #include <linux/cache.h>
++#include <linux/proc_fs.h>
+
+ #include <asm/pdc_chassis.h>
+ #include <asm/processor.h>
+ #include <asm/pdc.h>
+ #include <asm/pdcpat.h>
+
++#define PDC_CHASSIS_VER "0.05"
+
+ #ifdef CONFIG_PDC_CHASSIS
+-static int pdc_chassis_old __read_mostly = 0;
+ static unsigned int pdc_chassis_enabled __read_mostly = 1;
+
+
+@@ -64,7 +69,7 @@
+ * Currently, only E class and A180 are known to work with this.
+ * Inspired by Christoph Plattner
+ */
+-
++#if 0
+ static void __init pdc_chassis_checkold(void)
+ {
+ switch(CPU_HVERSION) {
+@@ -73,7 +78,6 @@
+ case 0x482: /* E45 */
+ case 0x483: /* E55 */
+ case 0x516: /* A180 */
+- pdc_chassis_old = 1;
+ break;
+
+ default:
+@@ -81,7 +85,7 @@
+ }
+ DPRINTK(KERN_DEBUG "%s: pdc_chassis_checkold(); pdc_chassis_old = %d\n", __FILE__, pdc_chassis_old);
+ }
+-
++#endif
+
+ /**
+ * pdc_chassis_panic_event() - Called by the panic handler.
+@@ -131,30 +135,20 @@
+ void __init parisc_pdc_chassis_init(void)
+ {
+ #ifdef CONFIG_PDC_CHASSIS
+- int handle = 0;
+ if (likely(pdc_chassis_enabled)) {
+ DPRINTK(KERN_DEBUG "%s: parisc_pdc_chassis_init()\n", __FILE__);
+
+ /* Let see if we have something to handle... */
+- /* Check for PDC_PAT or old LED Panel */
+- pdc_chassis_checkold();
+- if (is_pdc_pat()) {
+- printk(KERN_INFO "Enabling PDC_PAT chassis codes support.\n");
+- handle = 1;
+- }
+- else if (unlikely(pdc_chassis_old)) {
+- printk(KERN_INFO "Enabling old style chassis LED panel support.\n");
+- handle = 1;
+- }
+-
+- if (handle) {
+- /* initialize panic notifier chain */
+- atomic_notifier_chain_register(&panic_notifier_list,
+- &pdc_chassis_panic_block);
+-
+- /* initialize reboot notifier chain */
+- register_reboot_notifier(&pdc_chassis_reboot_block);
+- }
++ printk(KERN_INFO "Enabling %s chassis codes support v%s\n",
++ is_pdc_pat() ? "PDC_PAT" : "regular",
++ PDC_CHASSIS_VER);
++
++ /* initialize panic notifier chain */
++ atomic_notifier_chain_register(&panic_notifier_list,
++ &pdc_chassis_panic_block);
++
++ /* initialize reboot notifier chain */
++ register_reboot_notifier(&pdc_chassis_reboot_block);
+ }
+ #endif /* CONFIG_PDC_CHASSIS */
+ }
+@@ -215,9 +209,12 @@
+ }
+ } else retval = -1;
+ #else
+- if (unlikely(pdc_chassis_old)) {
++ if (1) {
+ switch (message) {
+ case PDC_CHASSIS_DIRECT_BSTART:
++ retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_INIT));
++ break;
++
+ case PDC_CHASSIS_DIRECT_BCOMPLETE:
+ retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_RUN));
+ break;
+@@ -244,3 +241,61 @@
+ #endif /* CONFIG_PDC_CHASSIS */
+ return retval;
+ }
++
++#ifdef CONFIG_PDC_CHASSIS_WARN
++#ifdef CONFIG_PROC_FS
++static int pdc_chassis_warn_pread(char *page, char **start, off_t off,
++ int count, int *eof, void *data)
++{
++ char *out = page;
++ int len, ret;
++ unsigned long warn;
++ u32 warnreg;
++
++ ret = pdc_chassis_warn(&warn);
++ if (ret != PDC_OK)
++ return -EIO;
++
++ warnreg = (warn & 0xFFFFFFFF);
++
++ if ((warnreg >> 24) & 0xFF)
++ out += sprintf(out, "Chassis component failure! (eg fan or PSU): 0x%.2x\n", ((warnreg >> 24) & 0xFF));
++
++ out += sprintf(out, "Battery: %s\n", (warnreg & 0x04) ? "Low!" : "OK");
++ out += sprintf(out, "Temp low: %s\n", (warnreg & 0x02) ? "Exceeded!" : "OK");
++ out += sprintf(out, "Temp mid: %s\n", (warnreg & 0x01) ? "Exceeded!" : "OK");
++
++ len = out - page - off;
++ if (len < count) {
++ *eof = 1;
++ if (len <= 0) return 0;
++ } else {
++ len = count;
++ }
++ *start = page + off;
++ return len;
++}
++
++static int __init pdc_chassis_create_procfs(void)
++{
++ unsigned long test;
++ int ret;
++
++ ret = pdc_chassis_warn(&test);
++ if ((ret == PDC_BAD_PROC) || (ret == PDC_BAD_OPTION)) {
++ /* seems that some boxes (eg L1000) do not implement this */
++ printk(KERN_INFO "Chassis warnings not supported.\n");
++ return 0;
++ }
++
++ printk(KERN_INFO "Enabling PDC chassis warnings support v%s\n",
++ PDC_CHASSIS_VER);
++ create_proc_read_entry("chassis", 0400, NULL, pdc_chassis_warn_pread,
++ NULL);
++ return 0;
++}
++
++__initcall(pdc_chassis_create_procfs);
++
++#endif /* CONFIG_PROC_FS */
++#endif /* CONFIG_PDC_CHASSIS_WARN */
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/arch/parisc/kernel/ptrace.c CVS2_6_17_PA0/arch/parisc/kernel/ptrace.c
+--- LINUS_2_6_17/arch/parisc/kernel/ptrace.c 2006-06-17 22:24:39.000000000 -0600
++++ CVS2_6_17_PA0/arch/parisc/kernel/ptrace.c 2006-06-16 13:10:02.000000000 -0600
+@@ -91,7 +91,7 @@
+ int copied;
+
+ #ifdef __LP64__
+- if (personality(child->personality) == PER_LINUX32) {
++ if (__is_compat_task(child)) {
+ unsigned int tmp;
+
+ addr &= 0xffffffffL;
+@@ -123,7 +123,7 @@
+ case PTRACE_POKEDATA:
+ ret = 0;
+ #ifdef __LP64__
+- if (personality(child->personality) == PER_LINUX32) {
++ if (__is_compat_task(child)) {
+ unsigned int tmp = (unsigned int)data;
+ DBG("sys_ptrace(POKE%s, %d, %lx, %lx)\n",
+ request == PTRACE_POKETEXT ? "TEXT" : "DATA",
+@@ -146,7 +146,7 @@
+ case PTRACE_PEEKUSR: {
+ ret = -EIO;
+ #ifdef __LP64__
+- if (personality(child->personality) == PER_LINUX32) {
++ if (__is_compat_task(child)) {
+ unsigned int tmp;
+
+ if (addr & (sizeof(int)-1))
+@@ -205,7 +205,7 @@
+ goto out_tsk;
+ }
+ #ifdef __LP64__
+- if (personality(child->personality) == PER_LINUX32) {
++ if (__is_compat_task(child)) {
+ if (addr & (sizeof(int)-1))
+ goto out_tsk;
+ if ((addr = translate_usr_offset(addr)) < 0)
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/arch/parisc/kernel/real2.S CVS2_6_17_PA0/arch/parisc/kernel/real2.S
+--- LINUS_2_6_17/arch/parisc/kernel/real2.S 2006-06-17 22:24:39.000000000 -0600
++++ CVS2_6_17_PA0/arch/parisc/kernel/real2.S 2006-05-25 10:22:30.000000000 -0600
+@@ -276,15 +276,6 @@
+
+ #endif
+
+- .export pc_in_user_space
+- .text
+- /* Doesn't belong here but I couldn't find a nicer spot. */
+- /* Should never get called, only used by profile stuff in time.c */
+-pc_in_user_space:
+- bv,n 0(%rp)
+- nop
+-
+-
+ .export __canonicalize_funcptr_for_compare
+ .text
+ /* http://lists.parisc-linux.org/hypermail/parisc-linux/10916.html
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/arch/parisc/kernel/setup.c CVS2_6_17_PA0/arch/parisc/kernel/setup.c
+--- LINUS_2_6_17/arch/parisc/kernel/setup.c 2006-06-17 22:24:39.000000000 -0600
++++ CVS2_6_17_PA0/arch/parisc/kernel/setup.c 2006-05-04 18:43:33.000000000 -0600
+@@ -303,6 +303,8 @@
+
+ static int __init parisc_init(void)
+ {
++ u32 osid = (0x0006 << 16);
++
+ parisc_proc_mkdir();
+ parisc_init_resources();
+ do_device_inventory(); /* probe for hardware */
+@@ -311,6 +313,9 @@
+
+ /* set up a new led state on systems shipped LED State panel */
+ pdc_chassis_send_status(PDC_CHASSIS_DIRECT_BSTART);
++
++ /* tell PDC we're Linux. Nevermind failure. */
++ pdc_stable_write(0x40, &osid, sizeof(osid));
+
+ processor_init();
+ printk(KERN_INFO "CPU(s): %d x %s at %d.%06d MHz\n",
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/arch/parisc/kernel/signal.c CVS2_6_17_PA0/arch/parisc/kernel/signal.c
+--- LINUS_2_6_17/arch/parisc/kernel/signal.c 2006-06-17 22:24:39.000000000 -0600
++++ CVS2_6_17_PA0/arch/parisc/kernel/signal.c 2006-06-16 13:10:02.000000000 -0600
+@@ -76,7 +76,7 @@
+ #ifdef __LP64__
+ compat_sigset_t newset32;
+
+- if(personality(current->personality) == PER_LINUX32){
++ if (is_compat_task()) {
+ /* XXX: Don't preclude handling different sized sigset_t's. */
+ if (sigsetsize != sizeof(compat_sigset_t))
+ return -EINVAL;
+@@ -153,7 +153,7 @@
+ compat_sigset_t compat_set;
+ struct compat_rt_sigframe __user * compat_frame;
+
+- if(personality(current->personality) == PER_LINUX32)
++ if (is_compat_task())
+ sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
+ #endif
+
+@@ -166,7 +166,7 @@
+ #ifdef __LP64__
+ compat_frame = (struct compat_rt_sigframe __user *)frame;
+
+- if(personality(current->personality) == PER_LINUX32){
++ if (is_compat_task()) {
+ DBG(2,"sys_rt_sigreturn: ELF32 process.\n");
+ if (__copy_from_user(&compat_set, &compat_frame->uc.uc_sigmask, sizeof(compat_set)))
+ goto give_sigsegv;
+@@ -186,7 +186,7 @@
+
+ /* Good thing we saved the old gr[30], eh? */
+ #ifdef __LP64__
+- if(personality(current->personality) == PER_LINUX32){
++ if (is_compat_task()) {
+ DBG(1,"sys_rt_sigreturn: compat_frame->uc.uc_mcontext 0x%p\n",
+ &compat_frame->uc.uc_mcontext);
+ // FIXME: Load upper half from register file
+@@ -315,7 +315,7 @@
+
+ compat_frame = (struct compat_rt_sigframe __user *)frame;
+
+- if(personality(current->personality) == PER_LINUX32) {
++ if (is_compat_task()) {
+ DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info);
+ err |= copy_siginfo_to_user32(&compat_frame->info, info);
+ DBG(1,"SETUP_RT_FRAME: 1\n");
+@@ -392,7 +392,7 @@
+ haddr = A(ka->sa.sa_handler);
+ /* The sa_handler may be a pointer to a function descriptor */
+ #ifdef __LP64__
+- if(personality(current->personality) == PER_LINUX32) {
++ if (is_compat_task()) {
+ #endif
+ if (haddr & PA_PLABEL_FDESC) {
+ Elf32_Fdesc fdesc;
+@@ -427,19 +427,19 @@
+ */
+ sigframe_size = PARISC_RT_SIGFRAME_SIZE;
+ #ifdef __LP64__
+- if(personality(current->personality) == PER_LINUX32)
++ if (is_compat_task())
+ sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
+ #endif
+ if (in_syscall) {
+ regs->gr[31] = haddr;
+ #ifdef __LP64__
+- if(personality(current->personality) == PER_LINUX)
++ if (personality(current->personality) == PER_LINUX)
+ sigframe_size |= 1;
+ #endif
+ } else {
+ unsigned long psw = USER_PSW;
+ #ifdef __LP64__
+- if(personality(current->personality) == PER_LINUX)
++ if (personality(current->personality) == PER_LINUX)
+ psw |= PSW_W;
+ #endif
+
+@@ -464,7 +464,7 @@
+ regs->gr[26] = sig; /* signal number */
+
+ #ifdef __LP64__
+- if(personality(current->personality) == PER_LINUX32){
++ if (is_compat_task()) {
+ regs->gr[25] = A(&compat_frame->info); /* siginfo pointer */
+ regs->gr[24] = A(&compat_frame->uc); /* ucontext pointer */
+ } else
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/arch/parisc/kernel/syscall.S CVS2_6_17_PA0/arch/parisc/kernel/syscall.S
+--- LINUS_2_6_17/arch/parisc/kernel/syscall.S 2006-06-17 22:24:39.000000000 -0600
++++ CVS2_6_17_PA0/arch/parisc/kernel/syscall.S 2006-06-17 11:53:43.000000000 -0600
+@@ -29,18 +29,6 @@
+ .level 1.1
+ #endif
+
+-#ifndef CONFIG_64BIT
+- .macro fixup_branch,lbl
+- b \lbl
+- .endm
+-#else
+- .macro fixup_branch,lbl
+- ldil L%\lbl, %r1
+- ldo R%\lbl(%r1), %r1
+- bv,n %r0(%r1)
+- .endm
+-#endif
+-
+ .text
+
+ .import syscall_exit,code
+@@ -541,7 +529,7 @@
+ # endif
+ /* ENABLE_LWS_DEBUG */
+
+- ldcw 0(%sr2,%r20), %r28 /* Try to acquire the lock */
++ LDCW 0(%sr2,%r20), %r28 /* Try to acquire the lock */
+ cmpb,<>,n %r0, %r28, cas_action /* Did we get it? */
+ cas_wouldblock:
+ ldo 2(%r0), %r28 /* 2nd case */
+@@ -701,5 +689,3 @@
+ /* CONFIG_SMP for lws_lock_start */
+
+ .end
+-
+-
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/arch/parisc/kernel/traps.c CVS2_6_17_PA0/arch/parisc/kernel/traps.c
+--- LINUS_2_6_17/arch/parisc/kernel/traps.c 2006-06-17 22:24:39.000000000 -0600
++++ CVS2_6_17_PA0/arch/parisc/kernel/traps.c 2006-06-01 05:33:33.000000000 -0600
+@@ -111,7 +111,10 @@
+ * in our way, otherwise we're screwed.
+ * The fldd is used to restore the T-bit if there was one, as the
+ * store clears it anyway.
+- * BTW, PA2.0 book says "thou shall not use fstw on FPSR/FPERs". */
++ * BTW, PA2.0 book says "thou shall not use fstw on FPSR/FPERs".
++ * We disabled use of fpregs in our kernel so far. Don't print them
++ * unnecessarily - T-Bone */
++ if (user_mode(regs)) {
+ __asm__ (
+ "fstd %%fr0,0(%1) \n\t"
+ "fldd 0(%1),%%fr0 \n\t"
+@@ -133,6 +136,7 @@
+ p += sprintf(p, " %016llx", (i+j) == 0 ? 0 : regs->fr[i+j]);
+ printk("%s\n", buf);
+ }
++ }
+
+ cr30 = mfctl(30);
+ cr31 = mfctl(31);
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/arch/parisc/kernel/unaligned.c CVS2_6_17_PA0/arch/parisc/kernel/unaligned.c
+--- LINUS_2_6_17/arch/parisc/kernel/unaligned.c 2006-06-17 22:24:39.000000000 -0600
++++ CVS2_6_17_PA0/arch/parisc/kernel/unaligned.c 2006-04-22 14:47:20.000000000 -0600
+@@ -43,6 +43,8 @@
+ "\tldil L%%" #lbl ", %%r1\n" \
+ "\tldo R%%" #lbl "(%%r1), %%r1\n" \
+ "\tbv,n %%r0(%%r1)\n"
++/* If you use FIXUP_BRANCH, then you must list this clobber */
++#define FIXUP_BRANCH_CLOBBER "r1"
+
+ /* 1111 1100 0000 0000 0001 0011 1100 0000 */
+ #define OPCODE1(a,b,c) ((a)<<26|(b)<<12|(c)<<6)
+@@ -157,7 +159,7 @@
+ " .previous\n"
+ : "=r" (val), "=r" (ret)
+ : "0" (val), "r" (saddr), "r" (regs->isr)
+- : "r20" );
++ : "r20", FIXUP_BRANCH_CLOBBER );
+
+ DPRINTF("val = 0x" RFMT "\n", val);
+
+@@ -202,7 +204,7 @@
+ " .previous\n"
+ : "=r" (val), "=r" (ret)
+ : "0" (val), "r" (saddr), "r" (regs->isr)
+- : "r19", "r20" );
++ : "r19", "r20", FIXUP_BRANCH_CLOBBER );
+
+ DPRINTF("val = 0x" RFMT "\n", val);
+
+@@ -253,7 +255,7 @@
+ " .previous\n"
+ : "=r" (val), "=r" (ret)
+ : "0" (val), "r" (saddr), "r" (regs->isr)
+- : "r19", "r20" );
++ : "r19", "r20", FIXUP_BRANCH_CLOBBER );
+ #else
+ {
+ unsigned long valh=0,vall=0;
+@@ -287,7 +289,7 @@
+ " .previous\n"
+ : "=r" (valh), "=r" (vall), "=r" (ret)
+ : "0" (valh), "1" (vall), "r" (saddr), "r" (regs->isr)
+- : "r19", "r20" );
++ : "r19", "r20", FIXUP_BRANCH_CLOBBER );
+ val=((__u64)valh<<32)|(__u64)vall;
+ }
+ #endif
+@@ -335,7 +337,7 @@
+ " .previous\n"
+ : "=r" (ret)
+ : "r" (val), "r" (regs->ior), "r" (regs->isr)
+- : "r19" );
++ : "r19", FIXUP_BRANCH_CLOBBER );
+
+ return ret;
+ }
+@@ -389,7 +391,7 @@
+ " .previous\n"
+ : "=r" (ret)
+ : "r" (val), "r" (regs->ior), "r" (regs->isr)
+- : "r19", "r20", "r21", "r22", "r1" );
++ : "r19", "r20", "r21", "r22", "r1", FIXUP_BRANCH_CLOBBER );
+
+ return 0;
+ }
+@@ -450,7 +452,7 @@
+ " .previous\n"
+ : "=r" (ret)
+ : "r" (val), "r" (regs->ior), "r" (regs->isr)
+- : "r19", "r20", "r21", "r22", "r1" );
++ : "r19", "r20", "r21", "r22", "r1", FIXUP_BRANCH_CLOBBER );
+ #else
+ {
+ unsigned long valh=(val>>32),vall=(val&0xffffffffl);
+@@ -495,7 +497,7 @@
+ " .previous\n"
+ : "=r" (ret)
+ : "r" (valh), "r" (vall), "r" (regs->ior), "r" (regs->isr)
+- : "r19", "r20", "r21", "r1" );
++ : "r19", "r20", "r21", "r1", FIXUP_BRANCH_CLOBBER );
+ }
+ #endif
+
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/drivers/net/dummy.c CVS2_6_17_PA0/drivers/net/dummy.c
+--- LINUS_2_6_17/drivers/net/dummy.c 2006-06-17 22:24:44.000000000 -0600
++++ CVS2_6_17_PA0/drivers/net/dummy.c 2006-04-20 14:25:07.000000000 -0600
+@@ -57,7 +57,7 @@
+ {
+ }
+
+-static void __init dummy_setup(struct net_device *dev)
++static void __devinit dummy_setup(struct net_device *dev)
+ {
+ /* Initialize the device structure. */
+ dev->get_stats = dummy_get_stats;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/drivers/net/tulip/21142.c CVS2_6_17_PA0/drivers/net/tulip/21142.c
+--- LINUS_2_6_17/drivers/net/tulip/21142.c 2006-06-17 22:24:45.000000000 -0600
++++ CVS2_6_17_PA0/drivers/net/tulip/21142.c 2006-06-14 09:23:41.000000000 -0600
+@@ -26,9 +26,9 @@
+
+ /* Handle the 21143 uniquely: do autoselect with NWay, not the EEPROM list
+ of available transceivers. */
+-void t21142_timer(unsigned long data)
++void t21142_media_task(void *data)
+ {
+- struct net_device *dev = (struct net_device *)data;
++ struct net_device *dev = data;
+ struct tulip_private *tp = netdev_priv(dev);
+ void __iomem *ioaddr = tp->base_addr;
+ int csr12 = ioread32(ioaddr + CSR12);
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/drivers/net/tulip/de2104x.c CVS2_6_17_PA0/drivers/net/tulip/de2104x.c
+--- LINUS_2_6_17/drivers/net/tulip/de2104x.c 2006-06-17 22:24:45.000000000 -0600
++++ CVS2_6_17_PA0/drivers/net/tulip/de2104x.c 2006-04-20 14:25:07.000000000 -0600
+@@ -1731,7 +1731,7 @@
+ }
+
+ /* Note: this routine returns extra data bits for size detection. */
+-static unsigned __init tulip_read_eeprom(void __iomem *regs, int location, int addr_len)
++static unsigned __devinit tulip_read_eeprom(void __iomem *regs, int location, int addr_len)
+ {
+ int i;
+ unsigned retval = 0;
+@@ -1927,7 +1927,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;
+@@ -2082,7 +2082,7 @@
+ return rc;
+ }
+
+-static void __exit de_remove_one (struct pci_dev *pdev)
++static void __devexit de_remove_one (struct pci_dev *pdev)
+ {
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct de_private *de = dev->priv;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/drivers/net/tulip/interrupt.c CVS2_6_17_PA0/drivers/net/tulip/interrupt.c
+--- LINUS_2_6_17/drivers/net/tulip/interrupt.c 2006-06-17 22:24:45.000000000 -0600
++++ CVS2_6_17_PA0/drivers/net/tulip/interrupt.c 2006-05-30 00:46:14.000000000 -0600
+@@ -88,6 +88,10 @@
+ }
+ tp->rx_ring[entry].status = cpu_to_le32(DescOwned);
+ }
++
++/* FIXME: restarting DMA breaks tulip_down() code path.
++ tulip_down() will unmap the RX and TX descriptors.
++ */
+ if(tp->chip_id == LC82C168) {
+ if(((ioread32(tp->base_addr + CSR5)>>17)&0x07) == 4) {
+ /* Rx stopped due to out of buffers,
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/drivers/net/tulip/media.c CVS2_6_17_PA0/drivers/net/tulip/media.c
+--- LINUS_2_6_17/drivers/net/tulip/media.c 2006-06-17 22:24:45.000000000 -0600
++++ CVS2_6_17_PA0/drivers/net/tulip/media.c 2006-06-14 10:12:39.000000000 -0600
+@@ -44,8 +44,10 @@
+
+ /* MII transceiver control section.
+ Read and write the MII registers using software-generated serial
+- MDIO protocol. See the MII specifications or DP83840A data sheet
+- for details. */
++ MDIO protocol.
++ See IEEE 802.3-2002.pdf (Section 2, Chapter "22.2.4 Management functions")
++ or DP83840A data sheet for more details.
++ */
+
+ int tulip_mdio_read(struct net_device *dev, int phy_id, int location)
+ {
+@@ -261,24 +263,56 @@
+ u16 *reset_sequence = &((u16*)(p+3))[init_length];
+ int reset_length = p[2 + init_length*2];
+ misc_info = reset_sequence + reset_length;
+- if (startup)
++ if (startup) {
++ int timeout = 10;
+ for (i = 0; i < reset_length; i++)
+ iowrite32(get_u16(&reset_sequence[i]) << 16, ioaddr + CSR15);
++
++ /* flush posted writes */
++ ioread32(ioaddr + CSR15);
++
++ /* Sect 3.10.3 in DP83840A.pdf (p39) */
++ udelay(500);
++
++ /* Section 4.2 in DP83840A.pdf (p43) */
++ /* and IEEE 802.3 "22.2.4.1.1 Reset" */
++ while (timeout-- &&
++ (tulip_mdio_read (dev, phy_num, MII_BMCR) & BMCR_RESET))
++ udelay(100);
++ }
+ for (i = 0; i < init_length; i++)
+ iowrite32(get_u16(&init_sequence[i]) << 16, ioaddr + CSR15);
++
++ ioread32(ioaddr + CSR15); /* flush posted writes */
+ } else {
+ u8 *init_sequence = p + 2;
+ u8 *reset_sequence = p + 3 + init_length;
+ int reset_length = p[2 + init_length];
+ misc_info = (u16*)(reset_sequence + reset_length);
+ if (startup) {
++ int timeout = 10;
+ iowrite32(mtable->csr12dir | 0x100, ioaddr + CSR12);
+ for (i = 0; i < reset_length; i++)
+ iowrite32(reset_sequence[i], ioaddr + CSR12);
++
++ /* flush posted writes */
++ ioread32(ioaddr + CSR12);
++
++ /* Sect 3.10.3 in DP83840A.pdf (p39) */
++ udelay(500);
++
++ /* Section 4.2 in DP83840A.pdf (p43) */
++ /* and IEEE 802.3 "22.2.4.1.1 Reset" */
++ while (timeout-- &&
++ (tulip_mdio_read (dev, phy_num, MII_BMCR) & BMCR_RESET))
++ udelay(100);
+ }
+ for (i = 0; i < init_length; i++)
+ iowrite32(init_sequence[i], ioaddr + CSR12);
++
++ ioread32(ioaddr + CSR12); /* flush posted writes */
+ }
++
+ tmp_info = get_u16(&misc_info[1]);
+ if (tmp_info)
+ tp->advertising[phy_num] = tmp_info | 1;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/drivers/net/tulip/timer.c CVS2_6_17_PA0/drivers/net/tulip/timer.c
+--- LINUS_2_6_17/drivers/net/tulip/timer.c 2006-06-17 22:24:45.000000000 -0600
++++ CVS2_6_17_PA0/drivers/net/tulip/timer.c 2006-06-14 09:23:41.000000000 -0600
+@@ -18,13 +18,14 @@
+ #include "tulip.h"
+
+
+-void tulip_timer(unsigned long data)
++void tulip_media_task(void *data)
+ {
+- struct net_device *dev = (struct net_device *)data;
++ struct net_device *dev = data;
+ struct tulip_private *tp = netdev_priv(dev);
+ void __iomem *ioaddr = tp->base_addr;
+ u32 csr12 = ioread32(ioaddr + CSR12);
+ int next_tick = 2*HZ;
++ unsigned long flags;
+
+ if (tulip_debug > 2) {
+ printk(KERN_DEBUG "%s: Media selection tick, %s, status %8.8x mode"
+@@ -126,6 +127,15 @@
+ }
+ break;
+ }
++
++
++ spin_lock_irqsave(&tp->lock, flags);
++ if (tp->timeout_recovery) {
++ tulip_tx_timeout_complete(tp, ioaddr);
++ tp->timeout_recovery = 0;
++ }
++ spin_unlock_irqrestore(&tp->lock, flags);
++
+ /* mod_timer synchronizes us with potential add_timer calls
+ * from interrupts.
+ */
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/drivers/net/tulip/tulip.h CVS2_6_17_PA0/drivers/net/tulip/tulip.h
+--- LINUS_2_6_17/drivers/net/tulip/tulip.h 2006-06-17 22:24:45.000000000 -0600
++++ CVS2_6_17_PA0/drivers/net/tulip/tulip.h 2006-06-14 09:23:41.000000000 -0600
+@@ -31,11 +31,10 @@
+ /* undefine, or define to various debugging levels (>4 == obscene levels) */
+ #define TULIP_DEBUG 1
+
+-/* undefine USE_IO_OPS for MMIO, define for PIO */
+ #ifdef CONFIG_TULIP_MMIO
+-# undef USE_IO_OPS
++#define TULIP_BAR 1 /* CBMA */
+ #else
+-# define USE_IO_OPS 1
++#define TULIP_BAR 0 /* CBIO */
+ #endif
+
+
+@@ -45,7 +44,8 @@
+ int io_size;
+ int valid_intrs; /* CSR7 interrupt enable settings */
+ int flags;
+- void (*media_timer) (unsigned long data);
++ void (*media_timer) (unsigned long);
++ void (*media_task) (void *);
+ };
+
+
+@@ -143,6 +143,7 @@
+ RxNoBuf = 0x80,
+ RxIntr = 0x40,
+ TxFIFOUnderflow = 0x20,
++ RxErrIntr = 0x10,
+ TxJabber = 0x08,
+ TxNoBuf = 0x04,
+ TxDied = 0x02,
+@@ -193,9 +194,14 @@
+
+
+ enum desc_status_bits {
+- DescOwned = 0x80000000,
+- RxDescFatalErr = 0x8000,
+- RxWholePkt = 0x0300,
++ DescOwned = 0x80000000,
++ DescWholePkt = 0x60000000,
++ DescEndPkt = 0x40000000,
++ DescStartPkt = 0x20000000,
++ DescEndRing = 0x02000000,
++ DescUseLink = 0x01000000,
++ RxDescFatalErr = 0x008000,
++ RxWholePkt = 0x00000300,
+ };
+
+
+@@ -367,6 +373,7 @@
+ unsigned int medialock:1; /* Don't sense media type. */
+ unsigned int mediasense:1; /* Media sensing in progress. */
+ unsigned int nway:1, nwayset:1; /* 21143 internal NWay. */
++ unsigned int timeout_recovery:1;
+ unsigned int csr0; /* CSR0 setting. */
+ unsigned int csr6; /* Current CSR6 control settings. */
+ unsigned char eeprom[EEPROM_SIZE]; /* Serial EEPROM contents. */
+@@ -385,6 +392,7 @@
+ void __iomem *base_addr;
+ int csr12_shadow;
+ int pad0; /* Used for 8-byte alignment */
++ struct work_struct media_work;
+ };
+
+
+@@ -399,7 +407,7 @@
+
+ /* 21142.c */
+ extern u16 t21142_csr14[];
+-void t21142_timer(unsigned long data);
++void t21142_media_task(void *data);
+ void t21142_start_nway(struct net_device *dev);
+ void t21142_lnk_change(struct net_device *dev, int csr5);
+
+@@ -437,7 +445,7 @@
+ void pnic_timer(unsigned long data);
+
+ /* timer.c */
+-void tulip_timer(unsigned long data);
++void tulip_media_task(void *data);
+ void mxic_timer(unsigned long data);
+ void comet_timer(unsigned long data);
+
+@@ -474,8 +482,11 @@
+ udelay(10);
+
+ if (!i)
+- printk(KERN_DEBUG "%s: tulip_stop_rxtx() failed\n",
+- pci_name(tp->pdev));
++ printk(KERN_DEBUG "%s: tulip_stop_rxtx() failed"
++ " (CSR5 0x%x CSR6 0x%x)\n",
++ pci_name(tp->pdev),
++ ioread32(ioaddr + CSR5),
++ ioread32(ioaddr + CSR6));
+ }
+ }
+
+@@ -486,4 +497,14 @@
+ tulip_start_rxtx(tp);
+ }
+
++static inline void tulip_tx_timeout_complete(struct tulip_private *tp, void __iomem *ioaddr)
++{
++ /* Stop and restart the chip's Tx processes. */
++ tulip_restart_rxtx(tp);
++ /* Trigger an immediate transmit demand. */
++ iowrite32(0, ioaddr + CSR1);
++
++ tp->stats.tx_errors++;
++}
++
+ #endif /* __NET_TULIP_H__ */
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/drivers/net/tulip/tulip_core.c CVS2_6_17_PA0/drivers/net/tulip/tulip_core.c
+--- LINUS_2_6_17/drivers/net/tulip/tulip_core.c 2006-06-17 22:24:45.000000000 -0600
++++ CVS2_6_17_PA0/drivers/net/tulip/tulip_core.c 2006-06-14 09:28:08.000000000 -0600
+@@ -18,11 +18,11 @@
+
+ #define DRV_NAME "tulip"
+ #ifdef CONFIG_TULIP_NAPI
+-#define DRV_VERSION "1.1.13-NAPI" /* Keep at least for test */
++#define DRV_VERSION "1.1.14-NAPI" /* Keep at least for test */
+ #else
+-#define DRV_VERSION "1.1.13"
++#define DRV_VERSION "1.1.14"
+ #endif
+-#define DRV_RELDATE "May 11, 2002"
++#define DRV_RELDATE "May 6, 2006"
+
+
+ #include <linux/module.h>
+@@ -131,7 +131,14 @@
+ int tulip_debug = 1;
+ #endif
+
++static void tulip_timer(unsigned long data)
++{
++ struct net_device *dev = (struct net_device *)data;
++ struct tulip_private *tp = netdev_priv(dev);
+
++ if (netif_running(dev))
++ schedule_work(&tp->media_work);
++}
+
+ /*
+ * This table use during operation for capabilities and media timer.
+@@ -145,59 +152,60 @@
+
+ /* DC21140 */
+ { "Digital DS21140 Tulip", 128, 0x0001ebef,
+- HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_PCI_MWI, tulip_timer },
++ HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_PCI_MWI, tulip_timer,
++ tulip_media_task },
+
+ /* DC21142, DC21143 */
+- { "Digital DS21143 Tulip", 128, 0x0801fbff,
++ { "Digital DS21142/43 Tulip", 128, 0x0801fbff,
+ HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_ACPI | HAS_NWAY
+- | HAS_INTR_MITIGATION | HAS_PCI_MWI, t21142_timer },
++ | HAS_INTR_MITIGATION | HAS_PCI_MWI, tulip_timer, t21142_media_task},
+
+ /* LC82C168 */
+ { "Lite-On 82c168 PNIC", 256, 0x0001fbef,
+- HAS_MII | HAS_PNICNWAY, pnic_timer },
++ HAS_MII | HAS_PNICNWAY, pnic_timer, },
+
+ /* MX98713 */
+ { "Macronix 98713 PMAC", 128, 0x0001ebef,
+- HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, mxic_timer },
++ HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, mxic_timer, },
+
+ /* MX98715 */
+ { "Macronix 98715 PMAC", 256, 0x0001ebef,
+- HAS_MEDIA_TABLE, mxic_timer },
++ HAS_MEDIA_TABLE, mxic_timer, },
+
+ /* MX98725 */
+ { "Macronix 98725 PMAC", 256, 0x0001ebef,
+- HAS_MEDIA_TABLE, mxic_timer },
++ HAS_MEDIA_TABLE, mxic_timer, },
+
+ /* AX88140 */
+ { "ASIX AX88140", 128, 0x0001fbff,
+ HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | MC_HASH_ONLY
+- | IS_ASIX, tulip_timer },
++ | IS_ASIX, tulip_timer, tulip_media_task },
+
+ /* PNIC2 */
+ { "Lite-On PNIC-II", 256, 0x0801fbff,
+- HAS_MII | HAS_NWAY | HAS_8023X | HAS_PCI_MWI, pnic2_timer },
++ HAS_MII | HAS_NWAY | HAS_8023X | HAS_PCI_MWI, pnic2_timer, },
+
+ /* COMET */
+ { "ADMtek Comet", 256, 0x0001abef,
+- HAS_MII | MC_HASH_ONLY | COMET_MAC_ADDR, comet_timer },
++ HAS_MII | MC_HASH_ONLY | COMET_MAC_ADDR, comet_timer, },
+
+ /* COMPEX9881 */
+ { "Compex 9881 PMAC", 128, 0x0001ebef,
+- HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, mxic_timer },
++ HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, mxic_timer, },
+
+ /* I21145 */
+ { "Intel DS21145 Tulip", 128, 0x0801fbff,
+ HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_ACPI
+- | HAS_NWAY | HAS_PCI_MWI, t21142_timer },
++ | HAS_NWAY | HAS_PCI_MWI, tulip_timer, tulip_media_task },
+
+ /* DM910X */
+ { "Davicom DM9102/DM9102A", 128, 0x0001ebef,
+ HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_ACPI,
+- tulip_timer },
++ tulip_timer, tulip_media_task },
+
+ /* RS7112 */
+ { "Conexant LANfinity", 256, 0x0001ebef,
+- HAS_MII | HAS_ACPI, tulip_timer },
++ HAS_MII | HAS_ACPI, tulip_timer, tulip_media_task },
+
+ };
+
+@@ -296,12 +304,14 @@
+
+ /* Reset the chip, holding bit 0 set at least 50 PCI cycles. */
+ iowrite32(0x00000001, ioaddr + CSR0);
++ pci_read_config_dword(tp->pdev, PCI_COMMAND, &i); /* flush write */
+ udelay(100);
+
+ /* Deassert reset.
+ Wait the specified 50 PCI cycles after a reset by initializing
+ Tx and Rx queues and the address filter list. */
+ iowrite32(tp->csr0, ioaddr + CSR0);
++ pci_read_config_dword(tp->pdev, PCI_COMMAND, &i); /* flush write */
+ udelay(100);
+
+ if (tulip_debug > 1)
+@@ -523,20 +533,9 @@
+ "SIA %8.8x %8.8x %8.8x %8.8x, resetting...\n",
+ dev->name, ioread32(ioaddr + CSR5), ioread32(ioaddr + CSR12),
+ ioread32(ioaddr + CSR13), ioread32(ioaddr + CSR14), ioread32(ioaddr + CSR15));
+- if ( ! tp->medialock && tp->mtable) {
+- do
+- --tp->cur_index;
+- while (tp->cur_index >= 0
+- && (tulip_media_cap[tp->mtable->mleaf[tp->cur_index].media]
+- & MediaIsFD));
+- if (--tp->cur_index < 0) {
+- /* We start again, but should instead look for default. */
+- tp->cur_index = tp->mtable->leafcount - 1;
+- }
+- tulip_select_media(dev, 0);
+- printk(KERN_WARNING "%s: transmit timed out, switching to %s "
+- "media.\n", dev->name, medianame[dev->if_port]);
+- }
++ tp->timeout_recovery = 1;
++ schedule_work(&tp->media_work);
++ goto out_unlock;
+ } else if (tp->chip_id == PNIC2) {
+ printk(KERN_WARNING "%s: PNIC2 transmit timed out, status %8.8x, "
+ "CSR6/7 %8.8x / %8.8x CSR12 %8.8x, resetting...\n",
+@@ -576,14 +575,9 @@
+ }
+ #endif
+
+- /* Stop and restart the chip's Tx processes . */
+-
+- tulip_restart_rxtx(tp);
+- /* Trigger an immediate transmit demand. */
+- iowrite32(0, ioaddr + CSR1);
+-
+- tp->stats.tx_errors++;
++ tulip_tx_timeout_complete(tp, ioaddr);
+
++out_unlock:
+ spin_unlock_irqrestore (&tp->lock, flags);
+ dev->trans_start = jiffies;
+ netif_wake_queue (dev);
+@@ -733,6 +727,8 @@
+ void __iomem *ioaddr = tp->base_addr;
+ unsigned long flags;
+
++ flush_scheduled_work();
++
+ del_timer_sync (&tp->timer);
+ #ifdef CONFIG_TULIP_NAPI
+ del_timer_sync (&tp->oom_timer);
+@@ -741,21 +737,20 @@
+
+ /* Disable interrupts by clearing the interrupt mask. */
+ iowrite32 (0x00000000, ioaddr + CSR7);
++ ioread32 (ioaddr + CSR7); /* flush posted write */
+
+- /* Stop the Tx and Rx processes. */
+- tulip_stop_rxtx(tp);
++ spin_unlock_irqrestore (&tp->lock, flags);
+
+- /* prepare receive buffers */
+- tulip_refill_rx(dev);
++ free_irq (dev->irq, dev); /* no more races after this */
++ tulip_stop_rxtx(tp); /* Stop DMA */
+
+- /* release any unconsumed transmit buffers */
+- tulip_clean_tx_ring(tp);
++ /* Put driver back into the state we start with */
++ tulip_refill_rx(dev); /* prepare RX buffers */
++ tulip_clean_tx_ring(tp); /* clean up unsent TX buffers */
+
+ if (ioread32 (ioaddr + CSR6) != 0xffffffff)
+ tp->stats.rx_missed_errors += ioread32 (ioaddr + CSR8) & 0xffff;
+
+- spin_unlock_irqrestore (&tp->lock, flags);
+-
+ init_timer(&tp->timer);
+ tp->timer.data = (unsigned long)dev;
+ tp->timer.function = tulip_tbl[tp->chip_id].media_timer;
+@@ -781,7 +776,6 @@
+ printk (KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n",
+ dev->name, ioread32 (ioaddr + CSR5));
+
+- free_irq (dev->irq, dev);
+
+ /* Free all the skbuffs in the Rx queue. */
+ for (i = 0; i < RX_RING_SIZE; i++) {
+@@ -1362,11 +1356,8 @@
+ if (pci_request_regions (pdev, "tulip"))
+ goto err_out_free_netdev;
+
+-#ifndef USE_IO_OPS
+- ioaddr = pci_iomap(pdev, 1, tulip_tbl[chip_idx].io_size);
+-#else
+- ioaddr = pci_iomap(pdev, 0, tulip_tbl[chip_idx].io_size);
+-#endif
++ ioaddr = pci_iomap(pdev, TULIP_BAR, tulip_tbl[chip_idx].io_size);
++
+ if (!ioaddr)
+ goto err_out_free_res;
+
+@@ -1399,6 +1390,8 @@
+ tp->timer.data = (unsigned long)dev;
+ tp->timer.function = tulip_tbl[tp->chip_id].media_timer;
+
++ INIT_WORK(&tp->media_work, tulip_tbl[tp->chip_id].media_task, dev);
++
+ dev->base_addr = (unsigned long)ioaddr;
+
+ #ifdef CONFIG_TULIP_MWI
+@@ -1649,8 +1642,14 @@
+ if (register_netdev(dev))
+ goto err_out_free_ring;
+
+- printk(KERN_INFO "%s: %s rev %d at %p,",
+- dev->name, chip_name, chip_rev, ioaddr);
++ printk(KERN_INFO "%s: %s rev %d at "
++#ifdef CONFIG_TULIP_MMIO
++ "MMIO"
++#else
++ "Port"
++#endif
++ " 0x%lx,", dev->name, chip_name, chip_rev,
++ pci_resource_start(pdev,TULIP_BAR) );
+ pci_set_drvdata(pdev, dev);
+
+ if (eeprom_missing)
+@@ -1752,7 +1751,6 @@
+ tulip_down(dev);
+
+ netif_device_detach(dev);
+- free_irq(dev->irq, dev);
+
+ pci_save_state(pdev);
+ pci_disable_device(pdev);
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/drivers/net/tulip/winbond-840.c CVS2_6_17_PA0/drivers/net/tulip/winbond-840.c
+--- LINUS_2_6_17/drivers/net/tulip/winbond-840.c 2006-06-17 22:24:45.000000000 -0600
++++ CVS2_6_17_PA0/drivers/net/tulip/winbond-840.c 2006-05-30 00:46:14.000000000 -0600
+@@ -90,10 +90,8 @@
+ Making the Tx ring too large decreases the effectiveness of channel
+ bonding and packet priority.
+ There are no ill effects from too-large receive rings. */
+-#define TX_RING_SIZE 16
+ #define TX_QUEUE_LEN 10 /* Limit ring entries actually used. */
+ #define TX_QUEUE_LEN_RESTART 5
+-#define RX_RING_SIZE 32
+
+ #define TX_BUFLIMIT (1024-128)
+
+@@ -137,6 +135,8 @@
+ #include <asm/io.h>
+ #include <asm/irq.h>
+
++#include "tulip.h"
++
+ /* These identify the driver base version and may not be removed. */
+ static char version[] __devinitdata =
+ KERN_INFO DRV_NAME ".c:v" DRV_VERSION " (2.4 port) " DRV_RELDATE " Donald Becker <becker at scyld.com>\n"
+@@ -221,7 +221,7 @@
+ };
+ enum chip_capability_flags {
+ CanHaveMII=1, HasBrokenTx=2, AlwaysFDX=4, FDXOnNoMII=8,};
+-#ifdef USE_IO_OPS
++#ifndef CONFIG_TULIP_MMIO
+ #define W840_FLAGS (PCI_USES_IO | PCI_ADDR0 | PCI_USES_MASTER)
+ #else
+ #define W840_FLAGS (PCI_USES_MEM | PCI_ADDR1 | PCI_USES_MASTER)
+@@ -257,8 +257,8 @@
+ };
+
+ /* This driver was written to use PCI memory space, however some x86 systems
+- work only with I/O space accesses. Pass -DUSE_IO_OPS to use PCI I/O space
+- accesses instead of memory space. */
++ work only with I/O space accesses. See CONFIG_TULIP_MMIO in .config
++*/
+
+ /* Offsets to the Command and Status Registers, "CSRs".
+ While similar to the Tulip, these registers are longword aligned.
+@@ -276,21 +276,11 @@
+ CurTxDescAddr=0x4C, CurTxBufAddr=0x50,
+ };
+
+-/* Bits in the interrupt status/enable registers. */
+-/* The bits in the Intr Status/Enable registers, mostly interrupt sources. */
+-enum intr_status_bits {
+- NormalIntr=0x10000, AbnormalIntr=0x8000,
+- IntrPCIErr=0x2000, TimerInt=0x800,
+- IntrRxDied=0x100, RxNoBuf=0x80, IntrRxDone=0x40,
+- TxFIFOUnderflow=0x20, RxErrIntr=0x10,
+- TxIdle=0x04, IntrTxStopped=0x02, IntrTxDone=0x01,
+-};
+-
+ /* Bits in the NetworkConfig register. */
+ enum rx_mode_bits {
+- AcceptErr=0x80, AcceptRunt=0x40,
+- AcceptBroadcast=0x20, AcceptMulticast=0x10,
+- AcceptAllPhys=0x08, AcceptMyPhys=0x02,
++ AcceptErr=0x80,
++ RxAcceptBroadcast=0x20, AcceptMulticast=0x10,
++ RxAcceptAllPhys=0x08, AcceptMyPhys=0x02,
+ };
+
+ enum mii_reg_bits {
+@@ -312,13 +302,6 @@
+ u32 buffer1, buffer2;
+ };
+
+-/* Bits in network_desc.status */
+-enum desc_status_bits {
+- DescOwn=0x80000000, DescEndRing=0x02000000, DescUseLink=0x01000000,
+- DescWholePkt=0x60000000, DescStartPkt=0x20000000, DescEndPkt=0x40000000,
+- DescIntr=0x80000000,
+-};
+-
+ #define MII_CNT 1 /* winbond only supports one MII */
+ struct netdev_private {
+ struct w840_rx_desc *rx_ring;
+@@ -386,7 +369,6 @@
+ int irq;
+ int i, option = find_cnt < MAX_UNITS ? options[find_cnt] : 0;
+ void __iomem *ioaddr;
+- int bar = 1;
+
+ i = pci_enable_device(pdev);
+ if (i) return i;
+@@ -408,10 +390,8 @@
+
+ if (pci_request_regions(pdev, DRV_NAME))
+ goto err_out_netdev;
+-#ifdef USE_IO_OPS
+- bar = 0;
+-#endif
+- ioaddr = pci_iomap(pdev, bar, pci_id_tbl[chip_idx].io_size);
++
++ ioaddr = pci_iomap(pdev, TULIP_BAR, pci_id_tbl[chip_idx].io_size);
+ if (!ioaddr)
+ goto err_out_free_res;
+
+@@ -853,7 +833,7 @@
+ np->rx_buf_sz,PCI_DMA_FROMDEVICE);
+
+ np->rx_ring[i].buffer1 = np->rx_addr[i];
+- np->rx_ring[i].status = DescOwn;
++ np->rx_ring[i].status = DescOwned;
+ }
+
+ np->cur_rx = 0;
+@@ -938,7 +918,7 @@
+ }
+ #elif defined(__powerpc__) || defined(__i386__) || defined(__alpha__) || defined(__ia64__) || defined(__x86_64__)
+ i |= 0xE000;
+-#elif defined(__sparc__)
++#elif defined(__sparc__) || defined (CONFIG_PARISC)
+ i |= 0x4800;
+ #else
+ #warning Processor architecture undefined
+@@ -1058,11 +1038,11 @@
+
+ /* Now acquire the irq spinlock.
+ * The difficult race is the the ordering between
+- * increasing np->cur_tx and setting DescOwn:
++ * increasing np->cur_tx and setting DescOwned:
+ * - if np->cur_tx is increased first the interrupt
+ * handler could consider the packet as transmitted
+- * since DescOwn is cleared.
+- * - If DescOwn is set first the NIC could report the
++ * since DescOwned is cleared.
++ * - If DescOwned is set first the NIC could report the
+ * packet as sent, but the interrupt handler would ignore it
+ * since the np->cur_tx was not yet increased.
+ */
+@@ -1070,7 +1050,7 @@
+ np->cur_tx++;
+
+ wmb(); /* flush length, buffer1, buffer2 */
+- np->tx_ring[entry].status = DescOwn;
++ np->tx_ring[entry].status = DescOwned;
+ wmb(); /* flush status and kick the hardware */
+ iowrite32(0, np->base_addr + TxStartDemand);
+ np->tx_q_bytes += skb->len;
+@@ -1170,12 +1150,12 @@
+
+ handled = 1;
+
+- if (intr_status & (IntrRxDone | RxNoBuf))
++ if (intr_status & (RxIntr | RxNoBuf))
+ netdev_rx(dev);
+ if (intr_status & RxNoBuf)
+ iowrite32(0, ioaddr + RxStartDemand);
+
+- if (intr_status & (TxIdle | IntrTxDone) &&
++ if (intr_status & (TxNoBuf | TxIntr) &&
+ np->cur_tx != np->dirty_tx) {
+ spin_lock(&np->lock);
+ netdev_tx_done(dev);
+@@ -1183,8 +1163,8 @@
+ }
+
+ /* Abnormal error summary/uncommon events handlers. */
+- if (intr_status & (AbnormalIntr | TxFIFOUnderflow | IntrPCIErr |
+- TimerInt | IntrTxStopped))
++ if (intr_status & (AbnormalIntr | TxFIFOUnderflow | SytemError |
++ TimerInt | TxDied))
+ netdev_error(dev, intr_status);
+
+ if (--work_limit < 0) {
+@@ -1320,7 +1300,7 @@
+ np->rx_ring[entry].buffer1 = np->rx_addr[entry];
+ }
+ wmb();
+- np->rx_ring[entry].status = DescOwn;
++ np->rx_ring[entry].status = DescOwned;
+ }
+
+ return 0;
+@@ -1357,7 +1337,7 @@
+ dev->name, new);
+ update_csr6(dev, new);
+ }
+- if (intr_status & IntrRxDied) { /* Missed a Rx frame. */
++ if (intr_status & RxDied) { /* Missed a Rx frame. */
+ np->stats.rx_errors++;
+ }
+ if (intr_status & TimerInt) {
+@@ -1396,13 +1376,13 @@
+ /* Unconditionally log net taps. */
+ printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);
+ memset(mc_filter, 0xff, sizeof(mc_filter));
+- rx_mode = AcceptBroadcast | AcceptMulticast | AcceptAllPhys
++ rx_mode = RxAcceptBroadcast | AcceptMulticast | RxAcceptAllPhys
+ | AcceptMyPhys;
+ } else if ((dev->mc_count > multicast_filter_limit)
+ || (dev->flags & IFF_ALLMULTI)) {
+ /* Too many to match, or accept all multicasts. */
+ memset(mc_filter, 0xff, sizeof(mc_filter));
+- rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
++ rx_mode = RxAcceptBroadcast | AcceptMulticast | AcceptMyPhys;
+ } else {
+ struct dev_mc_list *mclist;
+ int i;
+@@ -1413,7 +1393,7 @@
+ filterbit &= 0x3f;
+ mc_filter[filterbit >> 5] |= 1 << (filterbit & 31);
+ }
+- rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
++ rx_mode = RxAcceptBroadcast | AcceptMulticast | AcceptMyPhys;
+ }
+ iowrite32(mc_filter[0], ioaddr + MulticastFilter0);
+ iowrite32(mc_filter[1], ioaddr + MulticastFilter1);
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/drivers/parisc/Kconfig CVS2_6_17_PA0/drivers/parisc/Kconfig
+--- LINUS_2_6_17/drivers/parisc/Kconfig 2006-06-17 22:24:46.000000000 -0600
++++ CVS2_6_17_PA0/drivers/parisc/Kconfig 2006-05-03 17:27:35.000000000 -0600
+@@ -140,18 +140,37 @@
+ If unsure, say Y.
+
+ config PDC_CHASSIS
+- bool "PDC chassis State Panel support"
++ bool "PDC chassis state codes support"
+ default y
+ help
+- Say Y here if you want to enable support for the LED State front
+- panel as found on E class, and support for the GSP Virtual Front
+- Panel (LED State and message logging) as found on high end
+- servers such as A, L and N-class.
+-
+- This has nothing to do with Chassis LCD and LED support.
++ Say Y here if you want to enable support for Chassis codes.
++ That includes support for LED State front panel as found on E
++ class, and support for the GSP Virtual Front Panel (LED State and
++ message logging) as found on high end servers such as A, L and
++ N-class.
++ This driver will also display progress messages on LCD display,
++ such as "INI", "RUN" and "FLT", and might thus clobber messages
++ shown by the LED/LCD driver.
++ This driver updates the state panel (LED and/or LCD) upon system
++ state change (eg: boot, shutdown or panic).
+
+ If unsure, say Y.
+
++
++config PDC_CHASSIS_WARN
++ bool "PDC chassis warnings support"
++ depends on PROC_FS
++ default y
++ help
++ Say Y here if you want to enable support for Chassis warnings.
++ This will add a proc entry '/proc/chassis' giving some information
++ about the overall health state of the system.
++ This includes NVRAM battery level, overtemp or failures such as
++ fans or power units.
++
++ If unsure, say Y.
++
++
+ config PDC_STABLE
+ tristate "PDC Stable Storage support"
+ depends on SYSFS
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/drivers/parisc/pdc_stable.c CVS2_6_17_PA0/drivers/parisc/pdc_stable.c
+--- LINUS_2_6_17/drivers/parisc/pdc_stable.c 2006-06-17 22:24:46.000000000 -0600
++++ CVS2_6_17_PA0/drivers/parisc/pdc_stable.c 2006-05-05 04:58:32.000000000 -0600
+@@ -28,8 +28,15 @@
+ * following code can deal with just 96 bytes of Stable Storage, and all
+ * sizes between 96 and 192 bytes (provided they are multiple of struct
+ * device_path size, eg: 128, 160 and 192) to provide full information.
+- * The code makes no use of data above 192 bytes. One last word: there's one
+- * path we can always count on: the primary path.
++ * One last word: there's one path we can always count on: the primary path.
++ * Anything above 224 bytes is used for 'osdep2' OS-dependent storage area.
++ *
++ * The first OS-dependent area should always be available. Obviously, this is
++ * not true for the other one. Also bear in mind that reading/writing from/to
++ * osdep2 is much more expensive than from/to osdep1.
++ * NOTE: We do not handle the 2 bytes OS-dep area at 0x5D, nor the first
++ * 2 bytes of storage available right after OSID. That's a total of 4 bytes
++ * sacrificed: -ETOOLAZY :P
+ *
+ * The current policy wrt file permissions is:
+ * - write: root only
+@@ -64,15 +71,18 @@
+ #include <asm/uaccess.h>
+ #include <asm/hardware.h>
+
+-#define PDCS_VERSION "0.22"
++#define PDCS_VERSION "0.30"
+ #define PDCS_PREFIX "PDC Stable Storage"
+
+ #define PDCS_ADDR_PPRI 0x00
+ #define PDCS_ADDR_OSID 0x40
++#define PDCS_ADDR_OSD1 0x48
++#define PDCS_ADDR_DIAG 0x58
+ #define PDCS_ADDR_FSIZ 0x5C
+ #define PDCS_ADDR_PCON 0x60
+ #define PDCS_ADDR_PALT 0x80
+ #define PDCS_ADDR_PKBD 0xA0
++#define PDCS_ADDR_OSD2 0xE0
+
+ MODULE_AUTHOR("Thibaut VARENE <varenet at parisc-linux.org>");
+ MODULE_DESCRIPTION("sysfs interface to HP PDC Stable Storage data");
+@@ -82,6 +92,9 @@
+ /* holds Stable Storage size. Initialized once and for all, no lock needed */
+ static unsigned long pdcs_size __read_mostly;
+
++/* holds OS ID. Initialized once and for all, hopefully to 0x0006 */
++static u16 pdcs_osid __read_mostly;
++
+ /* This struct defines what we need to deal with a parisc pdc path entry */
+ struct pdcspath_entry {
+ rwlock_t rw_lock; /* to protect path entry access */
+@@ -609,32 +622,79 @@
+ pdcs_osid_read(struct subsystem *entry, char *buf)
+ {
+ char *out = buf;
+- __u32 result;
+ char *tmpstr = NULL;
+
+ if (!entry || !buf)
+ return -EINVAL;
+
+- /* get OSID */
+- if (pdc_stable_read(PDCS_ADDR_OSID, &result, sizeof(result)) != PDC_OK)
+- return -EIO;
+-
+- /* the actual result is 16 bits away */
+- switch (result >> 16) {
+- case 0x0000: tmpstr = "No OS-dependent data"; break;
+- case 0x0001: tmpstr = "HP-UX dependent data"; break;
+- case 0x0002: tmpstr = "MPE-iX dependent data"; break;
+- case 0x0003: tmpstr = "OSF dependent data"; break;
+- case 0x0004: tmpstr = "HP-RT dependent data"; break;
+- case 0x0005: tmpstr = "Novell Netware dependent data"; break;
++ switch (pdcs_osid) {
++ case 0x0000: tmpstr = "No OS"; break;
++ case 0x0001: tmpstr = "HP-UX"; break;
++ case 0x0002: tmpstr = "MPE-iX"; break;
++ case 0x0003: tmpstr = "OSF"; break;
++ case 0x0004: tmpstr = "HP-RT"; break;
++ case 0x0005: tmpstr = "Novell Netware"; break;
++ case 0x0006: tmpstr = "Linux"; break;
+ default: tmpstr = "Unknown"; break;
+ }
+- out += sprintf(out, "%s (0x%.4x)\n", tmpstr, (result >> 16));
++ out += sprintf(out, "%s dependent data (0x%.4x)\n", tmpstr, pdcs_osid);
+
+ return out - buf;
+ }
+
+ /**
++ * pdcs_osdep1_read - Stable Storage OS-Dependent data area 1 output.
++ * @entry: An allocated and populated subsytem struct. We don't use it tho.
++ * @buf: The output buffer to write to.
++ *
++ * This can hold 16 bytes of OS-Dependent data.
++ */
++static ssize_t
++pdcs_osdep1_read(struct subsystem *entry, char *buf)
++{
++ char *out = buf;
++ u32 result[4];
++
++ if (!entry || !buf)
++ return -EINVAL;
++
++ if (pdc_stable_read(PDCS_ADDR_OSD1, &result, sizeof(result)) != PDC_OK)
++ return -EIO;
++
++ out += sprintf(out, "0x%.8x\n", result[0]);
++ out += sprintf(out, "0x%.8x\n", result[1]);
++ out += sprintf(out, "0x%.8x\n", result[2]);
++ out += sprintf(out, "0x%.8x\n", result[3]);
++
++ return out - buf;
++}
++
++/**
++ * pdcs_diagnostic_read - Stable Storage Diagnostic register output.
++ * @entry: An allocated and populated subsytem struct. We don't use it tho.
++ * @buf: The output buffer to write to.
++ *
++ * I have NFC how to interpret the content of that register ;-).
++ */
++static ssize_t
++pdcs_diagnostic_read(struct subsystem *entry, char *buf)
++{
++ char *out = buf;
++ u32 result;
++
++ if (!entry || !buf)
++ return -EINVAL;
++
++ /* get diagnostic */
++ if (pdc_stable_read(PDCS_ADDR_DIAG, &result, sizeof(result)) != PDC_OK)
++ return -EIO;
++
++ out += sprintf(out, "0x%.4x\n", (result >> 16));
++
++ return out - buf;
++}
++
++/**
+ * pdcs_fastsize_read - Stable Storage FastSize register output.
+ * @entry: An allocated and populated subsytem struct. We don't use it tho.
+ * @buf: The output buffer to write to.
+@@ -645,7 +705,7 @@
+ pdcs_fastsize_read(struct subsystem *entry, char *buf)
+ {
+ char *out = buf;
+- __u32 result;
++ u32 result;
+
+ if (!entry || !buf)
+ return -EINVAL;
+@@ -664,6 +724,39 @@
+ }
+
+ /**
++ * pdcs_osdep2_read - Stable Storage OS-Dependent data area 2 output.
++ * @entry: An allocated and populated subsytem struct. We don't use it tho.
++ * @buf: The output buffer to write to.
++ *
++ * This can hold pdcs_size - 224 bytes of OS-Dependent data, when available.
++ */
++static ssize_t
++pdcs_osdep2_read(struct subsystem *entry, char *buf)
++{
++ char *out = buf;
++ unsigned long size;
++ unsigned short i;
++ u32 result;
++
++ if (unlikely(pdcs_size <= 224))
++ return -ENODATA;
++
++ size = pdcs_size - 224;
++
++ if (!entry || !buf)
++ return -EINVAL;
++
++ for (i=0; i<size; i+=4) {
++ if (unlikely(pdc_stable_read(PDCS_ADDR_OSD2 + i, &result,
++ sizeof(result)) != PDC_OK))
++ return -EIO;
++ out += sprintf(out, "0x%.8x\n", result);
++ }
++
++ return out - buf;
++}
++
++/**
+ * pdcs_auto_write - This function handles autoboot/search flag modifying.
+ * @entry: An allocated and populated subsytem struct. We don't use it tho.
+ * @buf: The input buffer to read from.
+@@ -770,13 +863,100 @@
+ return pdcs_auto_write(entry, buf, count, PF_AUTOSEARCH);
+ }
+
++/**
++ * pdcs_osdep1_write - Stable Storage OS-Dependent data area 1 input.
++ * @entry: An allocated and populated subsytem struct. We don't use it tho.
++ * @buf: The input buffer to read from.
++ * @count: The number of bytes to be read.
++ *
++ * This can store 16 bytes of OS-Dependent data. We use a byte-by-byte
++ * write approach. It's up to userspace to deal with it when constructing
++ * its input buffer.
++ */
++static ssize_t
++pdcs_osdep1_write(struct subsystem *entry, const char *buf, size_t count)
++{
++ u8 in[16];
++
++ if (!capable(CAP_SYS_ADMIN))
++ return -EACCES;
++
++ if (!entry || !buf || !count)
++ return -EINVAL;
++
++ if (unlikely(pdcs_osid != 0x0006))
++ return -EPERM;
++
++ if (count > 16)
++ return -EMSGSIZE;
++
++ /* We'll use a local copy of buf */
++ memset(in, 0, 16);
++ memcpy(in, buf, count);
++
++ if (pdc_stable_write(PDCS_ADDR_OSD1, &in, sizeof(in)) != PDC_OK)
++ return -EIO;
++
++ return count;
++}
++
++/**
++ * pdcs_osdep2_write - Stable Storage OS-Dependent data area 2 input.
++ * @entry: An allocated and populated subsytem struct. We don't use it tho.
++ * @buf: The input buffer to read from.
++ * @count: The number of bytes to be read.
++ *
++ * This can store pdcs_size - 224 bytes of OS-Dependent data. We use a
++ * byte-by-byte write approach. It's up to userspace to deal with it when
++ * constructing its input buffer.
++ */
++static ssize_t
++pdcs_osdep2_write(struct subsystem *entry, const char *buf, size_t count)
++{
++ unsigned long size;
++ unsigned short i;
++ u8 in[4];
++
++ if (!capable(CAP_SYS_ADMIN))
++ return -EACCES;
++
++ if (!entry || !buf || !count)
++ return -EINVAL;
++
++ if (unlikely(pdcs_size <= 224))
++ return -ENOSYS;
++
++ if (unlikely(pdcs_osid != 0x0006))
++ return -EPERM;
++
++ size = pdcs_size - 224;
++
++ if (count > size)
++ return -EMSGSIZE;
++
++ /* We'll use a local copy of buf */
++
++ for (i=0; i<count; i+=4) {
++ memset(in, 0, 4);
++ memcpy(in, buf+i, (count-i < 4) ? count-i : 4);
++ if (unlikely(pdc_stable_write(PDCS_ADDR_OSD2 + i, &in,
++ sizeof(in)) != PDC_OK))
++ return -EIO;
++ }
++
++ return count;
++}
++
+ /* The remaining attributes. */
+ static PDCS_ATTR(size, 0444, pdcs_size_read, NULL);
+ static PDCS_ATTR(autoboot, 0644, pdcs_autoboot_read, pdcs_autoboot_write);
+ static PDCS_ATTR(autosearch, 0644, pdcs_autosearch_read, pdcs_autosearch_write);
+ static PDCS_ATTR(timer, 0444, pdcs_timer_read, NULL);
+-static PDCS_ATTR(osid, 0400, pdcs_osid_read, NULL);
++static PDCS_ATTR(osid, 0444, pdcs_osid_read, NULL);
++static PDCS_ATTR(osdep1, 0600, pdcs_osdep1_read, pdcs_osdep1_write);
++static PDCS_ATTR(diagnostic, 0400, pdcs_diagnostic_read, NULL);
+ static PDCS_ATTR(fastsize, 0400, pdcs_fastsize_read, NULL);
++static PDCS_ATTR(osdep2, 0600, pdcs_osdep2_read, pdcs_osdep2_write);
+
+ static struct subsys_attribute *pdcs_subsys_attrs[] = {
+ &pdcs_attr_size,
+@@ -784,7 +964,10 @@
+ &pdcs_attr_autosearch,
+ &pdcs_attr_timer,
+ &pdcs_attr_osid,
++ &pdcs_attr_osdep1,
++ &pdcs_attr_diagnostic,
+ &pdcs_attr_fastsize,
++ &pdcs_attr_osdep2,
+ NULL,
+ };
+
+@@ -865,6 +1048,7 @@
+ {
+ struct subsys_attribute *attr;
+ int i, rc = 0, error = 0;
++ u32 result;
+
+ /* find the size of the stable storage */
+ if (pdc_stable_get_size(&pdcs_size) != PDC_OK)
+@@ -876,6 +1060,13 @@
+
+ printk(KERN_INFO PDCS_PREFIX " facility v%s\n", PDCS_VERSION);
+
++ /* get OSID */
++ if (pdc_stable_read(PDCS_ADDR_OSID, &result, sizeof(result)) != PDC_OK)
++ return -EIO;
++
++ /* the actual result is 16 bits away */
++ pdcs_osid = (u16)(result >> 16);
++
+ /* For now we'll register the stable subsys within this driver */
+ if ((rc = firmware_register(&stable_subsys)))
+ goto fail_firmreg;
+@@ -887,7 +1078,7 @@
+
+ /* register the paths subsys as a subsystem of stable subsys */
+ kset_set_kset_s(&paths_subsys, stable_subsys);
+- if ((rc= subsystem_register(&paths_subsys)))
++ if ((rc = subsystem_register(&paths_subsys)))
+ goto fail_subsysreg;
+
+ /* now we create all "files" for the paths subsys */
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/drivers/parisc/sba_iommu.c CVS2_6_17_PA0/drivers/parisc/sba_iommu.c
+--- LINUS_2_6_17/drivers/parisc/sba_iommu.c 2006-06-17 22:24:46.000000000 -0600
++++ CVS2_6_17_PA0/drivers/parisc/sba_iommu.c 2006-05-31 06:58:33.000000000 -0600
+@@ -39,15 +39,12 @@
+ #include <linux/proc_fs.h>
+ #include <linux/seq_file.h>
+
++#include <asm/mckinley.h> /* for proc_mckinley_root */
+ #include <asm/runway.h> /* for proc_runway_root */
+ #include <asm/pdc.h> /* for PDC_MODEL_* */
+ #include <asm/pdcpat.h> /* for is_pdc_pat() */
+ #include <asm/parisc-device.h>
+
+-
+-/* declared in arch/parisc/kernel/setup.c */
+-extern struct proc_dir_entry * proc_mckinley_root;
+-
+ #define MODULE_NAME "SBA"
+
+ #ifdef CONFIG_PROC_FS
+@@ -316,10 +313,10 @@
+ **
+ ** Superdome (in particular, REO) allows only 64-bit CSR accesses.
+ */
+-#define READ_REG32(addr) le32_to_cpu(__raw_readl(addr))
+-#define READ_REG64(addr) le64_to_cpu(__raw_readq(addr))
+-#define WRITE_REG32(val, addr) __raw_writel(cpu_to_le32(val), addr)
+-#define WRITE_REG64(val, addr) __raw_writeq(cpu_to_le64(val), addr)
++#define READ_REG32(addr) readl(addr)
++#define READ_REG64(addr) readq(addr)
++#define WRITE_REG32(val, addr) writel((val), (addr))
++#define WRITE_REG64(val, addr) writeq((val), (addr))
+
+ #ifdef CONFIG_64BIT
+ #define READ_REG(addr) READ_REG64(addr)
+@@ -1427,7 +1424,7 @@
+ iov_order = get_order(iova_space_size >> (IOVP_SHIFT - PAGE_SHIFT));
+ ioc->pdir_size = (iova_space_size / IOVP_SIZE) * sizeof(u64);
+
+- DBG_INIT("%s() hpa 0x%lx IOV %dMB (%d bits)\n",
++ DBG_INIT("%s() hpa 0x%p IOV %dMB (%d bits)\n",
+ __FUNCTION__, ioc->ioc_hpa, iova_space_size >> 20,
+ iov_order + PAGE_SHIFT);
+
+@@ -1764,7 +1761,7 @@
+
+ sba_dev->num_ioc = num_ioc;
+ for (i = 0; i < num_ioc; i++) {
+- unsigned long ioc_hpa = sba_dev->ioc[i].ioc_hpa;
++ void __iomem *ioc_hpa = sba_dev->ioc[i].ioc_hpa;
+ unsigned int j;
+
+ for (j=0; j < sizeof(u64) * ROPES_PER_IOC; j+=sizeof(u64)) {
+@@ -1776,7 +1773,8 @@
+ * Improves netperf UDP_STREAM by ~10% for bcm5701.
+ */
+ if (IS_PLUTO(sba_dev->iodc)) {
+- unsigned long rope_cfg, cfg_val;
++ void __iomem *rope_cfg;
++ unsigned long cfg_val;
+
+ rope_cfg = ioc_hpa + IOC_ROPE0_CFG + j;
+ cfg_val = READ_REG(rope_cfg);
+@@ -1902,7 +1900,7 @@
+ * (bit #61, big endian), we have to flush and sync every time
+ * IO-PDIR is changed in Ike/Astro.
+ */
+- if (boot_cpu_data.pdc.capabilities & PDC_MODEL_IOPDIR_FDC) {
++ if (ioc_needs_fdc) {
+ printk(KERN_INFO MODULE_NAME " FDC/SYNC required.\n");
+ } else {
+ printk(KERN_INFO MODULE_NAME " IOC has cache coherent PDIR.\n");
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/drivers/scsi/53c700.c CVS2_6_17_PA0/drivers/scsi/53c700.c
+--- LINUS_2_6_17/drivers/scsi/53c700.c 2006-06-17 22:24:46.000000000 -0600
++++ CVS2_6_17_PA0/drivers/scsi/53c700.c 2006-04-03 07:44:53.000000000 -0600
+@@ -294,6 +294,7 @@
+ __u8 *memory;
+ __u32 *script;
+ struct Scsi_Host *host;
++ const char *chipname;
+ static int banner = 0;
+ int j;
+
+@@ -394,11 +395,11 @@
+ printk(KERN_NOTICE "53c700: Version " NCR_700_VERSION " By James.Bottomley at HansenPartnership.com\n");
+ banner = 1;
+ }
++ chipname = hostdata->chip710 ? "53c710" : \
++ (hostdata->fast ? "53c700-66" : "53c700");
+ printk(KERN_NOTICE "scsi%d: %s rev %d %s\n", host->host_no,
+- hostdata->chip710 ? "53c710" :
+- (hostdata->fast ? "53c700-66" : "53c700"),
+- hostdata->rev, hostdata->differential ?
+- "(Differential)" : "");
++ chipname, hostdata->rev,
++ hostdata->differential ? "(Differential)" : "");
+ /* reset the chip */
+ NCR_700_chip_reset(host);
+
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/drivers/scsi/constants.c CVS2_6_17_PA0/drivers/scsi/constants.c
+--- LINUS_2_6_17/drivers/scsi/constants.c 2006-06-17 22:24:46.000000000 -0600
++++ CVS2_6_17_PA0/drivers/scsi/constants.c 2006-01-17 07:51:48.000000000 -0700
+@@ -114,8 +114,7 @@
+ {0xd, "Report supported task management functions"},
+ {0xe, "Report priority"},
+ };
+-#define MAINT_IN_SZ \
+- (int)(sizeof(maint_in_arr) / sizeof(maint_in_arr[0]))
++#define MAINT_IN_SZ (int)ARRAY_SIZE(maint_in_arr)
+
+ static const struct value_name_pair maint_out_arr[] = {
+ {0x6, "Set device identifier"},
+@@ -123,34 +122,29 @@
+ {0xb, "Change aliases"},
+ {0xe, "Set priority"},
+ };
+-#define MAINT_OUT_SZ \
+- (int)(sizeof(maint_out_arr) / sizeof(maint_out_arr[0]))
++#define MAINT_OUT_SZ (int)ARRAY_SIZE(maint_out_arr)
+
+ static const struct value_name_pair serv_in12_arr[] = {
+ {0x1, "Read media serial number"},
+ };
+-#define SERV_IN12_SZ \
+- (int)(sizeof(serv_in12_arr) / sizeof(serv_in12_arr[0]))
++#define SERV_IN12_SZ (int)ARRAY_SIZE(serv_in12_arr)
+
+ static const struct value_name_pair serv_out12_arr[] = {
+ {-1, "dummy entry"},
+ };
+-#define SERV_OUT12_SZ \
+- (int)(sizeof(serv_out12_arr) / sizeof(serv_in12_arr[0]))
++#define SERV_OUT12_SZ (int)ARRAY_SIZE(serv_out12_arr)
+
+ static const struct value_name_pair serv_in16_arr[] = {
+ {0x10, "Read capacity(16)"},
+ {0x11, "Read long(16)"},
+ };
+-#define SERV_IN16_SZ \
+- (int)(sizeof(serv_in16_arr) / sizeof(serv_in16_arr[0]))
++#define SERV_IN16_SZ (int)ARRAY_SIZE(serv_in16_arr)
+
+ static const struct value_name_pair serv_out16_arr[] = {
+ {0x11, "Write long(16)"},
+ {0x1f, "Notify data transfer device(16)"},
+ };
+-#define SERV_OUT16_SZ \
+- (int)(sizeof(serv_out16_arr) / sizeof(serv_in16_arr[0]))
++#define SERV_OUT16_SZ (int)ARRAY_SIZE(serv_out16_arr)
+
+ static const struct value_name_pair variable_length_arr[] = {
+ {0x1, "Rebuild(32)"},
+@@ -190,8 +184,7 @@
+ {0x8f7e, "Perform SCSI command (osd)"},
+ {0x8f7f, "Perform task management function (osd)"},
+ };
+-#define VARIABLE_LENGTH_SZ \
+- (int)(sizeof(variable_length_arr) / sizeof(variable_length_arr[0]))
++#define VARIABLE_LENGTH_SZ (int)ARRAY_SIZE(variable_length_arr)
+
+ static const char * get_sa_name(const struct value_name_pair * arr,
+ int arr_sz, int service_action)
+@@ -1293,7 +1286,7 @@
+ "DID_OK", "DID_NO_CONNECT", "DID_BUS_BUSY", "DID_TIME_OUT", "DID_BAD_TARGET",
+ "DID_ABORT", "DID_PARITY", "DID_ERROR", "DID_RESET", "DID_BAD_INTR",
+ "DID_PASSTHROUGH", "DID_SOFT_ERROR", "DID_IMM_RETRY"};
+-#define NUM_HOSTBYTE_STRS (sizeof(hostbyte_table) / sizeof(const char *))
++#define NUM_HOSTBYTE_STRS ARRAY_SIZE(hostbyte_table)
+
+ void scsi_print_hostbyte(int scsiresult)
+ {
+@@ -1317,12 +1310,12 @@
+ static const char * const driverbyte_table[]={
+ "DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT", "DRIVER_MEDIA", "DRIVER_ERROR",
+ "DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD", "DRIVER_SENSE"};
+-#define NUM_DRIVERBYTE_STRS (sizeof(driverbyte_table) / sizeof(const char *))
++#define NUM_DRIVERBYTE_STRS ARRAY_SIZE(driverbyte_table)
+
+ static const char * const driversuggest_table[]={"SUGGEST_OK",
+ "SUGGEST_RETRY", "SUGGEST_ABORT", "SUGGEST_REMAP", "SUGGEST_DIE",
+ "SUGGEST_5", "SUGGEST_6", "SUGGEST_7", "SUGGEST_SENSE"};
+-#define NUM_SUGGEST_STRS (sizeof(driversuggest_table) / sizeof(const char *))
++#define NUM_SUGGEST_STRS ARRAY_SIZE(driversuggest_table)
+
+ void scsi_print_driverbyte(int scsiresult)
+ {
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/drivers/scsi/scsi_scan.c CVS2_6_17_PA0/drivers/scsi/scsi_scan.c
+--- LINUS_2_6_17/drivers/scsi/scsi_scan.c 2006-06-17 22:24:46.000000000 -0600
++++ CVS2_6_17_PA0/drivers/scsi/scsi_scan.c 2006-05-28 20:51:18.000000000 -0600
+@@ -30,7 +30,9 @@
+ #include <linux/moduleparam.h>
+ #include <linux/init.h>
+ #include <linux/blkdev.h>
+-#include <asm/semaphore.h>
++#include <linux/delay.h>
++#include <linux/kthread.h>
++#include <linux/spinlock.h>
+
+ #include <scsi/scsi.h>
+ #include <scsi/scsi_device.h>
+@@ -88,6 +90,11 @@
+ MODULE_PARM_DESC(max_luns,
+ "last scsi LUN (should be between 1 and 2^32-1)");
+
++static char scsi_scan_type[] = "async";
++
++module_param_string(scan, scsi_scan_type, sizeof(scsi_scan_type), S_IRUGO);
++MODULE_PARM_DESC(scan, "sync, async or none");
++
+ /*
+ * max_scsi_report_luns: the maximum number of LUNS that will be
+ * returned from the REPORT LUNS command. 8 times this value must
+@@ -109,6 +116,50 @@
+ "Timeout (in seconds) waiting for devices to answer INQUIRY."
+ " Default is 5. Some non-compliant devices need more.");
+
++static spinlock_t async_scan_lock = SPIN_LOCK_UNLOCKED;
++static LIST_HEAD(scanning_hosts);
++
++struct async_scan_data {
++ struct list_head list;
++ struct Scsi_Host *shost;
++ struct completion prev_finished;
++};
++
++static int scsi_complete_async_scans(void)
++{
++ struct async_scan_data *data;
++
++ do {
++ if (list_empty(&scanning_hosts))
++ return 0;
++ data = kmalloc(sizeof(*data), GFP_KERNEL);
++ if (!data)
++ msleep(1);
++ } while (!data);
++
++ data->shost = NULL;
++ init_completion(&data->prev_finished);
++
++ spin_lock(&async_scan_lock);
++ if (list_empty(&scanning_hosts))
++ goto done;
++ list_add_tail(&data->list, &scanning_hosts);
++ spin_unlock(&async_scan_lock);
++
++ printk(KERN_INFO "scsi: waiting for bus probes to complete ...\n");
++ wait_for_completion(&data->prev_finished);
++
++ spin_lock(&async_scan_lock);
++ list_del(&data->list);
++ done:
++ spin_unlock(&async_scan_lock);
++
++ kfree(data);
++ return 0;
++}
++late_initcall(scsi_complete_async_scans);
++
++
+ /**
+ * scsi_unlock_floptical - unlock device via a special MODE SENSE command
+ * @sdev: scsi device to send command to
+@@ -629,7 +680,8 @@
+ * SCSI_SCAN_NO_RESPONSE: could not allocate or setup a scsi_device
+ * SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized
+ **/
+-static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags)
++static int scsi_add_lun(struct scsi_device *sdev, char *inq_result,
++ int *bflags, int async)
+ {
+ /*
+ * XXX do not save the inquiry, since it can change underneath us,
+@@ -802,7 +854,7 @@
+ * register it and tell the rest of the kernel
+ * about it.
+ */
+- if (scsi_sysfs_add_sdev(sdev) != 0)
++ if (!async && scsi_sysfs_add_sdev(sdev) != 0)
+ return SCSI_SCAN_NO_RESPONSE;
+
+ return SCSI_SCAN_LUN_PRESENT;
+@@ -914,7 +966,7 @@
+ goto out_free_result;
+ }
+
+- res = scsi_add_lun(sdev, result, &bflags);
++ res = scsi_add_lun(sdev, result, &bflags, shost->async_scan);
+ if (res == SCSI_SCAN_LUN_PRESENT) {
+ if (bflags & BLIST_KEY) {
+ sdev->lockable = 0;
+@@ -1427,6 +1479,12 @@
+ {
+ struct Scsi_Host *shost = dev_to_shost(parent);
+
++ if (strncmp(scsi_scan_type, "none", 4) == 0)
++ return;
++
++ if (!shost->async_scan)
++ scsi_complete_async_scans();
++
+ mutex_lock(&shost->scan_mutex);
+ if (scsi_host_scan_allowed(shost))
+ __scsi_scan_target(parent, channel, id, lun, rescan);
+@@ -1472,6 +1530,9 @@
+ "%s: <%u:%u:%u>\n",
+ __FUNCTION__, channel, id, lun));
+
++ if (!shost->async_scan)
++ scsi_complete_async_scans();
++
+ if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) ||
+ ((id != SCAN_WILD_CARD) && (id > shost->max_id)) ||
+ ((lun != SCAN_WILD_CARD) && (lun > shost->max_lun)))
+@@ -1492,14 +1553,143 @@
+ return 0;
+ }
+
++/* The error handling here is pretty yucky. Do we want an
++ * shost_for_each_device_safe() iterator?
++ */
++static void scsi_sysfs_add_devices(struct Scsi_Host *shost)
++{
++ struct scsi_device *sdev;
++ shost_for_each_device(sdev, shost) {
++ int err;
++ next:
++ err = scsi_sysfs_add_sdev(sdev);
++ if (err) {
++ struct scsi_device *tmp = sdev;
++ sdev = __scsi_iterate_devices(shost, sdev);
++ scsi_destroy_sdev(tmp);
++ goto next;
++ }
++ }
++}
++
++/**
++ * scsi_prep_async_scan - prepare for an async scan
++ * @shost: the host which will be scanned
++ * Returns: a cookie to be passed to scsi_finish_async_scan()
++ *
++ * If your driver does not use scsi_scan_host(), you can call this function
++ * to tell the midlayer you're about to commence an asynchronous scan.
++ * This reserves your device's position in the scanning list and ensures
++ * that other asynchronous scans started after yours won't affect the
++ * disc ordering.
++ */
++struct async_scan_data * scsi_prep_async_scan(struct Scsi_Host *shost)
++{
++ struct async_scan_data *data;
++
++ if (strncmp(scsi_scan_type, "sync", 4) == 0)
++ return NULL;
++
++ if (shost->async_scan) {
++ printk("%s called twice for host %d", __FUNCTION__,
++ shost->host_no);
++ dump_stack();
++ return NULL;
++ }
++
++ data = kmalloc(sizeof(*data), GFP_KERNEL);
++ if (!data)
++ goto err;
++ data->shost = scsi_host_get(shost);
++ if (!data->shost)
++ goto err;
++ init_completion(&data->prev_finished);
++
++ spin_lock(&async_scan_lock);
++ shost->async_scan = 1;
++ if (list_empty(&scanning_hosts))
++ complete(&data->prev_finished);
++ list_add_tail(&data->list, &scanning_hosts);
++ spin_unlock(&async_scan_lock);
++
++ return data;
++
++ err:
++ kfree(data);
++ return NULL;
++}
++EXPORT_SYMBOL_GPL(scsi_prep_async_scan);
++
++/**
++ * scsi_finish_async_scan - asynchronous scan has finished
++ * @data: cookie returned from earlier call to scsi_prep_async_scan()
++ *
++ * Once your driver has found all the devices currently present, call
++ * this function. It will announce all the devices it has found to
++ * the rest of the system.
++ */
++void scsi_finish_async_scan(struct async_scan_data *data)
++{
++ struct Scsi_Host *shost;
++
++ if (!data)
++ return;
++
++ shost = data->shost;
++ if (!shost->async_scan) {
++ printk("%s called twice for host %d", __FUNCTION__,
++ shost->host_no);
++ dump_stack();
++ return;
++ }
++
++ wait_for_completion(&data->prev_finished);
++
++ scsi_sysfs_add_devices(shost);
++
++ spin_lock(&async_scan_lock);
++ shost->async_scan = 0;
++ list_del(&data->list);
++ if (!list_empty(&scanning_hosts)) {
++ struct async_scan_data *next = list_entry(scanning_hosts.next,
++ struct async_scan_data, list);
++ complete(&next->prev_finished);
++ }
++ spin_unlock(&async_scan_lock);
++
++ scsi_host_put(shost);
++ kfree(data);
++}
++EXPORT_SYMBOL_GPL(scsi_finish_async_scan);
++
++static int do_scan_async(void *_data)
++{
++ struct async_scan_data *data = _data;
++ scsi_scan_host_selected(data->shost, SCAN_WILD_CARD, SCAN_WILD_CARD,
++ SCAN_WILD_CARD, 0);
++
++ scsi_finish_async_scan(data);
++ return 0;
++}
++
+ /**
+ * scsi_scan_host - scan the given adapter
+ * @shost: adapter to scan
+ **/
+ void scsi_scan_host(struct Scsi_Host *shost)
+ {
+- scsi_scan_host_selected(shost, SCAN_WILD_CARD, SCAN_WILD_CARD,
+- SCAN_WILD_CARD, 0);
++ struct async_scan_data *data;
++
++ if (strncmp(scsi_scan_type, "none", 4) == 0)
++ return;
++
++ data = scsi_prep_async_scan(shost);
++ if (!data) {
++ scsi_scan_host_selected(shost, SCAN_WILD_CARD, SCAN_WILD_CARD,
++ SCAN_WILD_CARD, 0);
++ return;
++ }
++ kthread_run(do_scan_async, data, "scsi_scan_%d", shost->host_no);
+ }
+ EXPORT_SYMBOL(scsi_scan_host);
+
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/drivers/scsi/sym53c8xx_2/sym_glue.c CVS2_6_17_PA0/drivers/scsi/sym53c8xx_2/sym_glue.c
+--- LINUS_2_6_17/drivers/scsi/sym53c8xx_2/sym_glue.c 2006-06-17 22:24:47.000000000 -0600
++++ CVS2_6_17_PA0/drivers/scsi/sym53c8xx_2/sym_glue.c 2006-04-28 00:43:26.000000000 -0600
+@@ -210,13 +210,6 @@
+ cmd->scsi_done(cmd);
+ }
+
+-static void sym_xpt_done2(struct sym_hcb *np, struct scsi_cmnd *cmd, int cam_status)
+-{
+- sym_set_cam_status(cmd, cam_status);
+- sym_xpt_done(np, cmd);
+-}
+-
+-
+ /*
+ * Tell the SCSI layer about a BUS RESET.
+ */
+@@ -421,10 +414,8 @@
+ * Minimal checkings, so that we will not
+ * go outside our tables.
+ */
+- if (sdev->id == np->myaddr) {
+- sym_xpt_done2(np, cmd, DID_NO_CONNECT);
+- return 0;
+- }
++ if (sdev->id == np->myaddr)
++ goto nodev;
+
+ /*
+ * Retrieve the target descriptor.
+@@ -445,6 +436,11 @@
+ return 1; /* Means resource shortage */
+ sym_queue_scsiio(np, cmd, cp);
+ return 0;
++
++ nodev:
++ cmd->result = DID_NO_CONNECT << 16;
++ cmd->scsi_done(cmd);
++ return 0;
+ }
+
+ /*
+@@ -1355,7 +1351,7 @@
+ "revision id 0x%x\n",
+ np->s.chip_name, np->device_id, np->revision_id);
+ copy_info(&info, "At PCI address %s, IRQ " IRQ_FMT "\n",
+- pci_name(np->s.device), IRQ_PRM(np->s.irq));
++ pci_name(np->s.device), IRQ_PRM(np->s.device->irq));
+ copy_info(&info, "Min. period factor %d, %s SCSI BUS%s\n",
+ (int) (np->minsync_dt ? np->minsync_dt : np->minsync),
+ np->maxwide ? "Wide" : "Narrow",
+@@ -1408,8 +1404,8 @@
+ /*
+ * Free O/S specific resources.
+ */
+- if (np->s.irq)
+- free_irq(np->s.irq, np);
++ if (pdev->irq)
++ free_irq(pdev->irq, np);
+ if (np->s.ioaddr)
+ pci_iounmap(pdev, np->s.ioaddr);
+ if (np->s.ramaddr)
+@@ -1558,7 +1554,6 @@
+ sym_name(np), pdev->irq);
+ goto attach_failed;
+ }
+- np->s.irq = pdev->irq;
+
+ /*
+ * After SCSI devices have been opened, we cannot
+@@ -1598,6 +1593,10 @@
+ BUG_ON(sym2_transport_template == NULL);
+ instance->transportt = sym2_transport_template;
+
++ /* 53c896 rev 1 errata: DMA may not cross 16MB boundary */
++ if (pdev->device == PCI_DEVICE_ID_NCR_53C896 && np->revision_id < 2)
++ instance->dma_boundary = 0xFFFFFF;
++
+ spin_unlock_irqrestore(instance->host_lock, flags);
+
+ return instance;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/drivers/scsi/sym53c8xx_2/sym_glue.h CVS2_6_17_PA0/drivers/scsi/sym53c8xx_2/sym_glue.h
+--- LINUS_2_6_17/drivers/scsi/sym53c8xx_2/sym_glue.h 2006-06-17 22:24:47.000000000 -0600
++++ CVS2_6_17_PA0/drivers/scsi/sym53c8xx_2/sym_glue.h 2006-04-19 22:08:31.000000000 -0600
+@@ -185,7 +185,6 @@
+ void __iomem * ioaddr; /* MMIO kernel io address */
+ void __iomem * ramaddr; /* RAM kernel io address */
+ u_short io_ws; /* IO window size */
+- int irq; /* IRQ number */
+
+ struct timer_list timer; /* Timer handler link header */
+ u_long lasttime;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/drivers/serial/serial_core.c CVS2_6_17_PA0/drivers/serial/serial_core.c
+--- LINUS_2_6_17/drivers/serial/serial_core.c 2006-06-17 22:24:47.000000000 -0600
++++ CVS2_6_17_PA0/drivers/serial/serial_core.c 2006-05-27 10:30:14.000000000 -0600
+@@ -2015,6 +2015,7 @@
+ uart_report_port(struct uart_driver *drv, struct uart_port *port)
+ {
+ char address[64];
++ char irq[16];
+
+ switch (port->iotype) {
+ case UPIO_PORT:
+@@ -2036,10 +2037,19 @@
+ break;
+ }
+
+- printk(KERN_INFO "%s%s%s%d at %s (irq = %d) is a %s\n",
++#ifndef NO_IRQ
++#define NO_IRQ (-1)
++#endif
++ if (port->irq == NO_IRQ) {
++ strlcpy(irq, "polled", sizeof(irq));
++ } else {
++ snprintf(irq, sizeof(irq), "irq = %d", port->irq);
++ }
++
++ printk(KERN_INFO "%s%s%s%d at %s (%s) is a %s\n",
+ port->dev ? port->dev->bus_id : "",
+ port->dev ? ": " : "",
+- drv->dev_name, port->line, address, port->irq, uart_type(port));
++ drv->dev_name, port->line, address, irq, uart_type(port));
+ }
+
+ static void
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/drivers/usb/host/pci-quirks.c CVS2_6_17_PA0/drivers/usb/host/pci-quirks.c
+--- LINUS_2_6_17/drivers/usb/host/pci-quirks.c 2006-06-17 22:24:47.000000000 -0600
++++ CVS2_6_17_PA0/drivers/usb/host/pci-quirks.c 2006-06-16 12:21:45.000000000 -0600
+@@ -168,8 +168,6 @@
+ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
+ {
+ void __iomem *base;
+- int wait_time;
+- u32 control;
+
+ if (!mmio_resource_enabled(pdev, 0))
+ return;
+@@ -180,9 +178,10 @@
+
+ /* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */
+ #ifndef __hppa__
+- control = readl(base + OHCI_CONTROL);
++{
++ u32 control = readl(base + OHCI_CONTROL);
+ if (control & OHCI_CTRL_IR) {
+- wait_time = 500; /* arbitrary; 5 seconds */
++ int wait_time = 500; /* arbitrary; 5 seconds */
+ writel(OHCI_INTR_OC, base + OHCI_INTRENABLE);
+ writel(OHCI_OCR, base + OHCI_CMDSTATUS);
+ while (wait_time > 0 &&
+@@ -199,6 +198,7 @@
+ /* reset controller, preserving RWC */
+ writel(control & OHCI_CTRL_RWC, base + OHCI_CONTROL);
+ }
++}
+ #endif
+
+ /*
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/drivers/usb/input/hid-core.c CVS2_6_17_PA0/drivers/usb/input/hid-core.c
+--- LINUS_2_6_17/drivers/usb/input/hid-core.c 2006-06-17 22:24:48.000000000 -0600
++++ CVS2_6_17_PA0/drivers/usb/input/hid-core.c 2006-05-27 10:30:15.000000000 -0600
+@@ -752,21 +752,31 @@
+ }
+
+ /*
+- * Extract/implement a data field from/to a report.
++ * Extract/implement a data field from/to a little endian report (bit array).
+ */
+
+ static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n)
+ {
+- report += (offset >> 5) << 2; offset &= 31;
+- return (le64_to_cpu(get_unaligned((__le64*)report)) >> offset) & ((1ULL << n) - 1);
++ u32 x;
++
++ report += offset >> 3; /* adjust byte index */
++ offset &= 8 - 1;
++ x = get_unaligned((u32 *) report);
++ x = le32_to_cpu(x);
++ x = (x >> offset) & ((1 << n) - 1);
++ return x;
+ }
+
+ static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value)
+ {
+- report += (offset >> 5) << 2; offset &= 31;
+- put_unaligned((get_unaligned((__le64*)report)
+- & cpu_to_le64(~((((__u64) 1 << n) - 1) << offset)))
+- | cpu_to_le64((__u64)value << offset), (__le64*)report);
++ u32 x;
++
++ report += offset >> 3;
++ offset &= 8 - 1;
++ x = get_unaligned((u32 *)report);
++ x &= cpu_to_le32(~((((__u32) 1 << n) - 1) << offset));
++ x |= cpu_to_le32(value << offset);
++ put_unaligned(x,(u32 *)report);
+ }
+
+ /*
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/include/asm-parisc/assembly.h CVS2_6_17_PA0/include/asm-parisc/assembly.h
+--- LINUS_2_6_17/include/asm-parisc/assembly.h 2006-06-17 22:24:50.000000000 -0600
++++ CVS2_6_17_PA0/include/asm-parisc/assembly.h 2006-04-23 20:26:58.000000000 -0600
+@@ -48,6 +48,7 @@
+ #define CALLEE_SAVE_FRAME_SIZE (CALLEE_REG_FRAME_SIZE + CALLEE_FLOAT_FRAME_SIZE)
+
+ #ifdef CONFIG_PA20
++#define LDCW ldcw,co
+ #define BL b,l
+ # ifdef CONFIG_64BIT
+ # define LEVEL 2.0w
+@@ -55,6 +56,7 @@
+ # define LEVEL 2.0
+ # endif
+ #else
++#define LDCW ldcw
+ #define BL bl
+ #define LEVEL 1.1
+ #endif
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/include/asm-parisc/compat.h CVS2_6_17_PA0/include/asm-parisc/compat.h
+--- LINUS_2_6_17/include/asm-parisc/compat.h 2006-06-17 22:24:50.000000000 -0600
++++ CVS2_6_17_PA0/include/asm-parisc/compat.h 2006-06-16 13:10:02.000000000 -0600
+@@ -5,6 +5,7 @@
+ */
+ #include <linux/types.h>
+ #include <linux/sched.h>
++#include <linux/personality.h>
+
+ #define COMPAT_USER_HZ 100
+
+@@ -149,4 +150,14 @@
+ return (void __user *)regs->gr[30];
+ }
+
++static inline int __is_compat_task(struct task_struct *t)
++{
++ return personality(t->personality) == PER_LINUX32;
++}
++
++static inline int is_compat_task(void)
++{
++ return __is_compat_task(current);
++}
++
+ #endif /* _ASM_PARISC_COMPAT_H */
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/include/asm-parisc/mckinley.h CVS2_6_17_PA0/include/asm-parisc/mckinley.h
+--- LINUS_2_6_17/include/asm-parisc/mckinley.h 1969-12-31 17:00:00.000000000 -0700
++++ CVS2_6_17_PA0/include/asm-parisc/mckinley.h 2006-05-31 06:58:34.000000000 -0600
+@@ -0,0 +1,9 @@
++#ifndef ASM_PARISC_MCKINLEY_H
++#define ASM_PARISC_MCKINLEY_H
++#ifdef __KERNEL__
++
++/* declared in arch/parisc/kernel/setup.c */
++extern struct proc_dir_entry * proc_mckinley_root;
++
++#endif /*__KERNEL__*/
++#endif /*ASM_PARISC_MCKINLEY_H*/
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/include/asm-parisc/pdc.h CVS2_6_17_PA0/include/asm-parisc/pdc.h
+--- LINUS_2_6_17/include/asm-parisc/pdc.h 2006-06-17 22:24:50.000000000 -0600
++++ CVS2_6_17_PA0/include/asm-parisc/pdc.h 2006-06-16 12:20:01.000000000 -0600
+@@ -353,8 +353,8 @@
+ cc_wt : 1, /* 0 = WT-Dcache, 1 = WB-Dcache */
+ cc_sh : 2, /* 0 = separate I/D-cache, else shared I/D-cache */
+ cc_cst : 3, /* 0 = incoherent D-cache, 1=coherent D-cache */
+- cc_pad1 : 5, /* reserved */
+- cc_assoc: 8; /* associativity of I/D-cache */
++ cc_pad1 : 10, /* reserved */
++ cc_hv : 3; /* hversion dependent */
+ };
+
+ struct pdc_tlb_cf { /* for PDC_CACHE (I/D-TLB's) */
+@@ -720,6 +720,7 @@
+ int pdc_add_valid(unsigned long address);
+ int pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsigned long len);
+ int pdc_chassis_disp(unsigned long disp);
++int pdc_chassis_warn(unsigned long *warn);
+ int pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info);
+ int pdc_iodc_read(unsigned long *actcnt, unsigned long hpa, unsigned int index,
+ void *iodc_data, unsigned int iodc_data_size);
+@@ -733,6 +734,7 @@
+ int pdc_model_versions(unsigned long *versions, int id);
+ int pdc_model_capabilities(unsigned long *capabilities);
+ int pdc_cache_info(struct pdc_cache_info *cache);
++int pdc_spaceid_bits(unsigned long *space_bits);
+ #ifndef CONFIG_PA20
+ int pdc_btlb_info(struct pdc_btlb_info *btlb);
+ int pdc_mem_map_hpa(struct pdc_memory_map *r_addr, struct pdc_module_path *mod_path);
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/include/asm-parisc/pgtable.h CVS2_6_17_PA0/include/asm-parisc/pgtable.h
+--- LINUS_2_6_17/include/asm-parisc/pgtable.h 2006-06-17 22:24:50.000000000 -0600
++++ CVS2_6_17_PA0/include/asm-parisc/pgtable.h 2006-04-20 20:20:37.000000000 -0600
+@@ -507,13 +507,13 @@
+
+ /* TLB page size encoding - see table 3-1 in parisc20.pdf */
+ #define _PAGE_SIZE_ENCODING_4K 0
+-#define _PAGE_SIZE_ENCODING_16K 1
+-#define _PAGE_SIZE_ENCODING_64K 2
++#define _PAGE_SIZE_ENCODING_16K 1
++#define _PAGE_SIZE_ENCODING_64K 2
+ #define _PAGE_SIZE_ENCODING_256K 3
+ #define _PAGE_SIZE_ENCODING_1M 4
+ #define _PAGE_SIZE_ENCODING_4M 5
+-#define _PAGE_SIZE_ENCODING_16M 6
+-#define _PAGE_SIZE_ENCODING_64M 7
++#define _PAGE_SIZE_ENCODING_16M 6
++#define _PAGE_SIZE_ENCODING_64M 7
+
+ #if defined(CONFIG_PARISC_PAGE_SIZE_4KB)
+ # define _PAGE_SIZE_ENCODING_DEFAULT _PAGE_SIZE_ENCODING_4K
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/include/asm-parisc/processor.h CVS2_6_17_PA0/include/asm-parisc/processor.h
+--- LINUS_2_6_17/include/asm-parisc/processor.h 2006-06-17 22:24:50.000000000 -0600
++++ CVS2_6_17_PA0/include/asm-parisc/processor.h 2006-05-19 14:18:17.000000000 -0600
+@@ -27,14 +27,12 @@
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+-
+-/* We cannot use MFIA as it was added for PA2.0 - prumpf
+-
+- At one point there were no "0f/0b" type local symbols in gas for
+- PA-RISC. This is no longer true, but this still seems like the
+- nicest way to implement this. */
+-
+-#define current_text_addr() ({ void *pc; __asm__("\n\tblr 0,%0\n\tnop":"=r" (pc)); pc; })
++#ifdef CONFIG_PA20
++#define current_ia(x) __asm__("mfia %0" : "=r"(x))
++#else /* mfia added in pa2.0 */
++#define current_ia(x) __asm__("blr 0,%0\n\tnop" : "=r"(x))
++#endif
++#define current_text_addr() ({ void *pc; current_ia(pc); pc; })
+
+ #define TASK_SIZE (current->thread.task_size)
+ #define TASK_UNMAPPED_BASE (current->thread.map_base)
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/include/asm-parisc/system.h CVS2_6_17_PA0/include/asm-parisc/system.h
+--- LINUS_2_6_17/include/asm-parisc/system.h 2006-06-17 22:24:50.000000000 -0600
++++ CVS2_6_17_PA0/include/asm-parisc/system.h 2006-04-23 20:26:58.000000000 -0600
+@@ -156,13 +156,14 @@
+ type and dynamically select the 16-byte aligned int from the array
+ for the semaphore. */
+
+-#define __PA_LDCW_ALIGNMENT 16
+-#define __ldcw_align(a) ({ \
+- unsigned long __ret = (unsigned long) &(a)->lock[0]; \
+- __ret = (__ret + __PA_LDCW_ALIGNMENT - 1) & ~(__PA_LDCW_ALIGNMENT - 1); \
+- (volatile unsigned int *) __ret; \
++#define __PA_LDCW_ALIGNMENT 16
++#define __ldcw_align(a) ({ \
++ unsigned long __ret = (unsigned long) &(a)->lock[0]; \
++ __ret = (__ret + __PA_LDCW_ALIGNMENT - 1) \
++ & ~(__PA_LDCW_ALIGNMENT - 1); \
++ (volatile unsigned int *) __ret; \
+ })
+-#define LDCW "ldcw"
++#define __LDCW "ldcw"
+
+ #else /*CONFIG_PA20*/
+ /* From: "Jim Hull" <jim.hull of hp.com>
+@@ -172,17 +173,18 @@
+ they only require "natural" alignment (4-byte for ldcw, 8-byte for
+ ldcd). */
+
+-#define __PA_LDCW_ALIGNMENT 4
++#define __PA_LDCW_ALIGNMENT 4
+ #define __ldcw_align(a) ((volatile unsigned int *)a)
+-#define LDCW "ldcw,co"
++#define __LDCW "ldcw,co"
+
+ #endif /*!CONFIG_PA20*/
+
+ /* LDCW, the only atomic read-write operation PA-RISC has. *sigh*. */
+-#define __ldcw(a) ({ \
+- unsigned __ret; \
+- __asm__ __volatile__(LDCW " 0(%1),%0" : "=r" (__ret) : "r" (a)); \
+- __ret; \
++#define __ldcw(a) ({ \
++ unsigned __ret; \
++ __asm__ __volatile__(__LDCW " 0(%1),%0" \
++ : "=r" (__ret) : "r" (a)); \
++ __ret; \
+ })
+
+ #ifdef CONFIG_SMP
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/include/asm-parisc/uaccess.h CVS2_6_17_PA0/include/asm-parisc/uaccess.h
+--- LINUS_2_6_17/include/asm-parisc/uaccess.h 2006-06-17 22:24:50.000000000 -0600
++++ CVS2_6_17_PA0/include/asm-parisc/uaccess.h 2006-04-22 14:47:20.000000000 -0600
+@@ -172,7 +172,11 @@
+ /*
+ * The "__put_user/kernel_asm()" macros tell gcc they read from memory
+ * instead of writing. This is because they do not write to any memory
+- * gcc knows about, so there are no aliasing issues.
++ * gcc knows about, so there are no aliasing issues. These macros must
++ * also be aware that "fixup_put_user_skip_[12]" are executed in the
++ * context of the fault, and any registers useed there must be listed
++ * as clobbers. In this case only "r1" is used by the current routines.
++ * r8/r9 are already listed as err/val.
+ */
+
+ #ifdef __LP64__
+@@ -183,7 +187,8 @@
+ "\t.dword\t1b,fixup_put_user_skip_1\n" \
+ "\t.previous" \
+ : "=r"(__pu_err) \
+- : "r"(ptr), "r"(x), "0"(__pu_err))
++ : "r"(ptr), "r"(x), "0"(__pu_err) \
++ : "r1")
+
+ #define __put_user_asm(stx,x,ptr) \
+ __asm__ __volatile__ ( \
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/include/scsi/scsi_device.h CVS2_6_17_PA0/include/scsi/scsi_device.h
+--- LINUS_2_6_17/include/scsi/scsi_device.h 2006-06-17 22:24:52.000000000 -0600
++++ CVS2_6_17_PA0/include/scsi/scsi_device.h 2006-05-18 20:43:19.000000000 -0600
+@@ -298,6 +298,10 @@
+ void (*done)(void *, char *, int, int),
+ gfp_t gfp);
+
++struct async_scan_data;
++struct async_scan_data * scsi_prep_async_scan(struct Scsi_Host *shost);
++void scsi_finish_async_scan(struct async_scan_data *data);
++
+ static inline void scsi_device_reprobe(struct scsi_device *sdev)
+ {
+ device_reprobe(&sdev->sdev_gendev);
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/include/scsi/scsi_host.h CVS2_6_17_PA0/include/scsi/scsi_host.h
+--- LINUS_2_6_17/include/scsi/scsi_host.h 2006-06-17 22:24:52.000000000 -0600
++++ CVS2_6_17_PA0/include/scsi/scsi_host.h 2006-05-18 20:43:19.000000000 -0600
+@@ -541,6 +541,9 @@
+ */
+ unsigned ordered_tag:1;
+
++ /* Are we currently performing an async scan? */
++ unsigned async_scan:1;
++
+ /*
+ * Optional work queue to be utilized by the transport
+ */
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/kernel/resource.c CVS2_6_17_PA0/kernel/resource.c
+--- LINUS_2_6_17/kernel/resource.c 2006-06-17 22:24:52.000000000 -0600
++++ CVS2_6_17_PA0/kernel/resource.c 2006-01-17 07:53:00.000000000 -0700
+@@ -181,6 +181,8 @@
+ {
+ struct resource *tmp, **p;
+
++ BUG_ON(old->child);
++
+ p = &old->parent->child;
+ for (;;) {
+ tmp = *p;
+@@ -308,12 +310,11 @@
+ *
+ * Returns 0 on success, -EBUSY if the resource can't be inserted.
+ *
+- * This function is equivalent of request_resource when no conflict
++ * This function is equivalent to request_resource when no conflict
+ * happens. If a conflict happens, and the conflicting resources
+ * entirely fit within the range of the new resource, then the new
+- * resource is inserted and the conflicting resources become childs of
+- * the new resource. Otherwise the new resource becomes the child of
+- * the conflicting resource
++ * resource is inserted and the conflicting resources become children of
++ * the new resource.
+ */
+ int insert_resource(struct resource *parent, struct resource *new)
+ {
+@@ -321,20 +322,21 @@
+ struct resource *first, *next;
+
+ write_lock(&resource_lock);
+- begin:
+- result = 0;
+- first = __request_resource(parent, new);
+- if (!first)
+- goto out;
+
+- result = -EBUSY;
+- if (first == parent)
+- goto out;
++ for (;; parent = first) {
++ result = 0;
++ first = __request_resource(parent, new);
++ if (!first)
++ goto out;
+
+- /* Resource fully contained by the clashing resource? Recurse into it */
+- if (first->start <= new->start && first->end >= new->end) {
+- parent = first;
+- goto begin;
++ result = -EBUSY;
++ if (first == parent)
++ goto out;
++
++ if ((first->start > new->start) || (first->end < new->end))
++ break;
++ if ((first->start == new->start) && (first->end == new->end))
++ break;
+ }
+
+ for (next = first; ; next = next->sibling) {
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/mm/shmem.c CVS2_6_17_PA0/mm/shmem.c
+--- LINUS_2_6_17/mm/shmem.c 2006-06-17 22:24:52.000000000 -0600
++++ CVS2_6_17_PA0/mm/shmem.c 2006-06-17 22:34:52.000000000 -0600
+@@ -627,7 +627,7 @@
+ }
+ }
+
+-static void shmem_truncate(struct inode *inode)
++/* static gcc-3.3 OPD bug - GGG */ void shmem_truncate(struct inode *inode)
+ {
+ shmem_truncate_range(inode, inode->i_size, (loff_t)-1);
+ }
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_17/sound/pci/ad1889.c CVS2_6_17_PA0/sound/pci/ad1889.c
+--- LINUS_2_6_17/sound/pci/ad1889.c 2006-06-17 22:24:53.000000000 -0600
++++ CVS2_6_17_PA0/sound/pci/ad1889.c 2006-05-12 22:12:43.000000000 -0600
+@@ -100,6 +100,7 @@
+ struct snd_pcm *pcm;
+ struct snd_info_entry *proc;
+
++ struct snd_dma_device dma;
+ struct snd_pcm_substream *psubs;
+ struct snd_pcm_substream *csubs;
+
+@@ -113,25 +114,25 @@
+ static inline u16
+ ad1889_readw(struct snd_ad1889 *chip, unsigned reg)
+ {
+- return readw(chip->iobase + reg);
++ return ioread16(chip->iobase + reg);
+ }
+
+ static inline void
+ ad1889_writew(struct snd_ad1889 *chip, unsigned reg, u16 val)
+ {
+- writew(val, chip->iobase + reg);
++ iowrite16(val, chip->iobase + reg);
+ }
+
+ static inline u32
+ ad1889_readl(struct snd_ad1889 *chip, unsigned reg)
+ {
+- return readl(chip->iobase + reg);
++ return ioread32(chip->iobase + reg);
+ }
+
+ static inline void
+ ad1889_writel(struct snd_ad1889 *chip, unsigned reg, u32 val)
+ {
+- writel(val, chip->iobase + reg);
++ iowrite32(val, chip->iobase + reg);
+ }
+
+ static inline void
+@@ -621,6 +622,9 @@
+ if ((st & AD_DMA_DISR_ADCI) && chip->csubs)
+ snd_pcm_period_elapsed(chip->csubs);
+
++ ad1889_readl(chip, AD_DMA_DISR); /* flush */
++ /* XXX under some circumstances the DISR write flush may not happen */
++
+ return IRQ_HANDLED;
+ }
+
+@@ -650,6 +654,9 @@
+ chip->psubs = NULL;
+ chip->csubs = NULL;
+
++ chip->dma.dev = &chip->pci->dev;
++ chip->dma.type = SNDRV_DMA_TYPE_DEV;
++
+ err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
+ snd_dma_pci_data(chip->pci),
+ BUFFER_BYTES_MAX / 2,
Modified: dists/trunk/linux-2.6/debian/patches/series/0experimental.1-extra
==============================================================================
--- dists/trunk/linux-2.6/debian/patches/series/0experimental.1-extra (original)
+++ dists/trunk/linux-2.6/debian/patches/series/0experimental.1-extra Sun Jun 18 23:36:27 2006
@@ -3,3 +3,4 @@
+ vserver-version.patch *_vserver *_xen-vserver
+ mips-tulip.patch mipsel
+ mips-tulip_dc21143.patch mipsel
++ hppa.patch hppa
More information about the Kernel-svn-changes
mailing list