Import 2.4.0-test6pre42.4.0-test6pre4
authorLinus Torvalds<torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:37:26 +0000 (23 15:37 -0500)
committerLinus Torvalds<torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:37:26 +0000 (23 15:37 -0500)
177 files changed:
CREDITS
Documentation/Configure.help
Documentation/kbuild/config-language.txt
arch/alpha/kernel/alpha_ksyms.c
arch/alpha/kernel/entry.S
arch/alpha/kernel/irq_alpha.c
arch/alpha/kernel/irq_smp.c
arch/alpha/kernel/smp.c
arch/arm/kernel/armksyms.c
arch/arm/kernel/entry-common.S
arch/arm/kernel/irq.c
arch/i386/kernel/entry.S
arch/i386/kernel/i386_ksyms.c
arch/i386/kernel/io_apic.c
arch/i386/kernel/irq.c
arch/i386/kernel/traps.c
arch/ia64/kernel/entry.S
arch/ia64/kernel/ia64_ksyms.c
arch/ia64/kernel/irq.c
arch/m68k/atari/ataints.c
arch/m68k/kernel/entry.S
arch/m68k/kernel/ints.c
arch/m68k/kernel/m68k_ksyms.c
arch/mips/baget/irq.c
arch/mips/dec/irq.c
arch/mips/kernel/entry.S
arch/mips/kernel/irq.c
arch/mips/kernel/mips_ksyms.c
arch/mips/kernel/scall_o32.S
arch/mips/orion/irq.c
arch/mips/orion/misc.c
arch/mips/orion/setup.c
arch/mips/sgi/kernel/indy_int.c
arch/mips64/kernel/entry.S
arch/mips64/kernel/scall_64.S
arch/mips64/kernel/scall_o32.S
arch/mips64/sgi-ip22/ip22-int.c
arch/mips64/sgi-ip27/ip27-irq.c
arch/ppc/kernel/entry.S
arch/ppc/kernel/irq.c
arch/ppc/kernel/local_irq.h
arch/ppc/kernel/ppc_ksyms.c
arch/s390/kernel/entry.S
arch/s390/kernel/irq.c
arch/s390/kernel/process.c
arch/s390/kernel/s390io.c
arch/s390/mm/fault.c
arch/sh/kernel/entry.S
arch/sh/kernel/irq.c
arch/sparc/config.in
arch/sparc/kernel/irq.c
arch/sparc/kernel/rtrap.S
arch/sparc/kernel/sparc_ksyms.c
arch/sparc/mm/init.c
arch/sparc/mm/srmmu.c
arch/sparc64/config.in
arch/sparc64/defconfig
arch/sparc64/kernel/ebus.c
arch/sparc64/kernel/entry.S
arch/sparc64/kernel/ioctl32.c
arch/sparc64/kernel/irq.c
arch/sparc64/kernel/process.c
arch/sparc64/kernel/rtrap.S
arch/sparc64/kernel/signal.c
arch/sparc64/kernel/smp.c
arch/sparc64/kernel/sparc64_ksyms.c
arch/sparc64/kernel/sunos_ioctl32.c
arch/sparc64/kernel/sys_sparc.c
arch/sparc64/kernel/sys_sparc32.c
arch/sparc64/kernel/sys_sunos32.c
arch/sparc64/kernel/traps.c
arch/sparc64/solaris/fs.c
arch/sparc64/solaris/ioctl.c
arch/sparc64/solaris/timod.c
drivers/char/Config.in
drivers/char/agp/agpgart_be.c
drivers/char/drm/agpsupport.c
drivers/char/drm/drmP.h
drivers/char/drm/drm_syms.c
drivers/char/radio-typhoon.c
drivers/net/appletalk/ltpc.c
drivers/net/pcmcia/ray_cs.c
drivers/net/pppoe.c
drivers/net/wan/syncppp.c
drivers/sbus/char/Makefile
drivers/sbus/char/display7seg.c[new file with mode: 0644]
drivers/scsi/3w-xxxx.c
drivers/scsi/ips.c
drivers/scsi/ips.h
drivers/sound/Makefile
drivers/video/Config.in
drivers/video/S3triofb.c
drivers/video/chipsfb.c
drivers/video/clgenfb.c
drivers/video/controlfb.c
drivers/video/fbmem.c
drivers/video/imsttfb.c
drivers/video/matrox/matroxfb_base.c
drivers/video/offb.c
drivers/video/platinumfb.c
drivers/video/valkyriefb.c
drivers/video/valkyriefb.h
fs/inode.c
include/asm-alpha/hardirq.h
include/asm-alpha/smp.h
include/asm-alpha/softirq.h
include/asm-arm/hardirq.h
include/asm-i386/hardirq.h
include/asm-ia64/hardirq.h
include/asm-m68k/hardirq.h
include/asm-m68k/softirq.h
include/asm-m68k/system.h
include/asm-mips/hardirq.h
include/asm-mips/mc146818rtc.h
include/asm-mips64/hardirq.h
include/asm-mips64/processor.h
include/asm-mips64/smp.h
include/asm-ppc/hardirq.h
include/asm-ppc/softirq.h
include/asm-s390/hardirq.h
include/asm-s390/irq.h
include/asm-s390/lowcore.h
include/asm-s390/softirq.h
include/asm-sh/hardirq.h
include/asm-sh/softirq.h
include/asm-sparc/hardirq.h
include/asm-sparc/highmem.h[new file with mode: 0644]
include/asm-sparc/irq.h
include/asm-sparc/kmap_types.h[new file with mode: 0644]
include/asm-sparc/pgalloc.h
include/asm-sparc/softirq.h
include/asm-sparc/stat.h
include/asm-sparc/system.h
include/asm-sparc/vaddrs.h
include/asm-sparc64/display7seg.h[new file with mode: 0644]
include/asm-sparc64/hardirq.h
include/asm-sparc64/smp.h
include/asm-sparc64/softirq.h
include/asm-sparc64/stat.h
include/asm-sparc64/system.h
include/linux/agp_backend.h
include/linux/interrupt.h
include/linux/irq_cpustat.h[new file with mode: 0644]
include/net/ipip.h
kernel/exit.c
kernel/kmod.c
kernel/ksyms.c
kernel/sched.c
kernel/softirq.c
kernel/user.c
mm/highmem.c
mm/page_alloc.c
mm/vmscan.c
net/bridge/br.c
net/core/neighbour.c
net/core/sock.c
net/ipv4/arp.c
net/ipv4/devinet.c
net/ipv4/icmp.c
net/ipv4/igmp.c
net/ipv4/ip_gre.c
net/ipv4/ip_options.c
net/ipv4/ip_sockglue.c
net/ipv4/ipconfig.c
net/ipv4/ipip.c
net/ipv4/ipmr.c
net/ipv4/netfilter/ipfwadm_core.c
net/ipv4/syncookies.c
net/ipv4/tcp_ipv4.c
net/ipv6/mcast.c
net/ipv6/netfilter/ip6_tables.c
net/ipv6/sit.c
net/netsyms.c
net/packet/af_packet.c
net/sunrpc/sched.c
net/unix/af_unix.c
scripts/Configure

index 6398542..49ba8e3 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -1816,6+1816,10 @@ S: Reinholdstrasse 14
 S: D-37083 Goettingen
 S: Germany
 
+N: Thomas Molina
+E: tmolina@home.com
+D: bug fixes, documentation, minor hackery
+
 N: David Mosberger-Tang
 E: davidm@hpl.hp.com if IA-64 related, else David.Mosberger@acm.org
 D: Linux/Alpha and Linux/ia64
index ebee495..baf746b 100644 (file)
@@ -16445,6+16445,19 @@ CONFIG_BVME6000_SCC
   boards from BVM Ltd.  Everyone using one of these boards should say
   Y here.
 
+7-Segment Display support
+CONFIG_DISPLAY7SEG
+  This is the driver for the 7-segment display and LED present on
+  Sun Microsystems CompactPCI models CP1400 and CP1500.
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called display7seg.o. If you want to compile it
+  as a module, say M here and read Documentation/modules.txt.
+
+  If you do not have a CompactPCI model CP1400 or CP1500, or
+  another UltraSPARC-IIi-cEngine boardset with a 7-segment display,
+  you should say N to this option. 
 
 #
 # A couple of things I keep forgetting:
index dc17560..d139848 100644 (file)
@@ -291,6+291,7 @@ Example:
 This verb displays /prompt/ to the user, accepts a value from the user,
 and assigns that value to /symbol/.  /word/ is the default value.  Legal
 input values are any ASCII string, except for the characters '"' and '\\'.
+Configure will trap an input string of "?" to display help.
 
 The default value is mandatory.
 
index 078aa7d..4ac2e8b 100644 (file)
@@ -199,9+199,6 @@ EXPORT_SYMBOL(debug_spin_trylock);
 EXPORT_SYMBOL(write_lock);
 EXPORT_SYMBOL(read_lock);
 #endif
-#else /* CONFIG_SMP */
-EXPORT_SYMBOL(__local_bh_count);
-EXPORT_SYMBOL(__local_irq_count);
 #endif /* CONFIG_SMP */
 
 EXPORT_SYMBOL(rtc_lock);
index 253b8d6..ac80051 100644 (file)
@@ -577,10+577,10 @@ entSys:
 ret_from_sys_call:
        cmovne  $26,0,$19               /* $19 = 0 => non-restartable */
        ldl     $3,TASK_PROCESSOR($8)
-       lda     $4,softirq_state
+       lda     $4,irq_stat             /* softirq_active */
        sll     $3,L1_CACHE_SHIFT,$3
        addq    $3,$4,$4
-       ldq     $4,0($4)
+       ldq     $4,0($4)                /* softirq_active[32] + softirq_mask[32] */
        sll     $4,32,$3
        and     $4,$3,$4
        bne     $4,handle_softirq
index 066af7e..59f1024 100644 (file)
 #include "proto.h"
 #include "irq_impl.h"
 
-/* Only uniprocessor needs this IRQ/BH locking depth, on SMP it lives
-   in the per-cpu structure for cache reasons.  */
 #ifndef CONFIG_SMP
-int __local_irq_count;
-int __local_bh_count;
 unsigned long __irq_attempt[NR_IRQS];
 #endif
 
index 90a3c30..9022228 100644 (file)
@@ -40,13+40,13 @@ show(char * str, void *where)
         printk("\n%s, CPU %d: %p\n", str, cpu, where);
         printk("irq:  %d [%d %d]\n",
               irqs_running(),
-               cpu_data[0].irq_count,
-              cpu_data[1].irq_count);
+               local_irq_count(0),
+               local_irq_count(1));
 
         printk("bh:   %d [%d %d]\n",
               spin_is_locked(&global_bh_lock) ? 1 : 0,
-              cpu_data[0].bh_count,
-              cpu_data[1].bh_count);
+              local_bh_count(0),
+              local_bh_count(1));
 #if 0
         stack = (unsigned long *) &str;
         for (i = 40; i ; i--) {
index e51ff9d..4f7a04b 100644 (file)
@@ -108,8+108,8 @@ smp_store_cpu_info(int cpuid)
        cpu_data[cpuid].loops_per_sec = loops_per_sec;
        cpu_data[cpuid].last_asn
          = (cpuid << WIDTH_HARDWARE_ASN) + ASN_FIRST_VERSION;
-       cpu_data[cpuid].irq_count = 0;
-       cpu_data[cpuid].bh_count = 0;
+       local_irq_count(cpuid) = 0;
+       local_bh_count(cpuid) = 0;
 }
 
 /*
index 6723291..fc14d6c 100644 (file)
@@ -91,8+91,6 @@ EXPORT_SYMBOL(kd_mksound);
 EXPORT_SYMBOL(dump_thread);
 EXPORT_SYMBOL(dump_fpu);
 EXPORT_SYMBOL(udelay);
-EXPORT_SYMBOL(local_bh_count);
-EXPORT_SYMBOL(local_irq_count);
 #ifdef CONFIG_CPU_32
 EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(__iounmap);
index b4fbfe6..c260b8e 100644 (file)
@@ -9,7+9,7 @@
 #ifdef CONFIG_SMP
 #error SMP not supported
 #else
-               ldr     \rd, __softirq_state
+               ldr     \rd, __irq_stat
 #endif
                .endm
 
@@ -22,7+22,7 @@ slow_syscall_return:
                add     sp, sp, #S_OFF
 ret_from_sys_call:                             @ external entry
                get_softirq r0
-               ldmia   r0, {r0, r1}
+               ldmia   r0, {r0, r1}            @ softirq_active, softirq_mask
                mov     r4, #1                  @ flag this as being syscall return
                tst     r0, r1
                blne    SYMBOL_NAME(do_softirq)
@@ -48,7+48,7 @@ ret_reschedule:       adrsvc  al, lr, ret_with_reschedule     @ internal
                .globl  ret_from_exception
 ret_from_exception:                            @ external entry
                get_softirq r0
-               ldmia   r0, {r0, r1}
+               ldmia   r0, {r0, r1}            @ softirq_active, softirq_mask
                mov     r4, #0
                tst     r0, r1
                blne    SYMBOL_NAME(do_softirq)
@@ -129,9+129,9 @@ vector_swi: save_user_regs
                b       SYMBOL_NAME(deferred)
 
                .align  5
-               .type   __softirq_state, #object
-__softirq_state:
-               .word   SYMBOL_NAME(softirq_state)
+               .type   __irq_stat, #object
+__irq_stat:
+               .word   SYMBOL_NAME(irq_stat)
 
                .type   sys_call_table, #object
 ENTRY(sys_call_table)
index 40a47c4..8af0c3b 100644 (file)
  */
 #define MAX_IRQ_CNT    100000
 
-unsigned int local_bh_count[NR_CPUS];
-unsigned int local_irq_count[NR_CPUS];
 spinlock_t irq_controller_lock;
 
 int setup_arm_irq(int, struct irqaction *);
@@ -236,7+234,7 @@ asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
 
        irq_exit(cpu, irq);
 
-       if (softirq_state[cpu].active & softirq_state[cpu].mask)
+       if (softirq_active(cpu) & softirq_mask(cpu))
                do_softirq();
        return;
 
index da7fd04..c36d01c 100644 (file)
@@ -206,11+206,11 @@ ENTRY(ret_from_sys_call)
 #ifdef CONFIG_SMP
        movl processor(%ebx),%eax
        shll $5,%eax
-       movl SYMBOL_NAME(softirq_state)(,%eax),%ecx
-       testl SYMBOL_NAME(softirq_state)+4(,%eax),%ecx
+       movl SYMBOL_NAME(irq_stat)(,%eax),%ecx          # softirq_active
+       testl SYMBOL_NAME(irq_stat)+4(,%eax),%ecx       # softirq_mask
 #else
-       movl SYMBOL_NAME(softirq_state),%ecx
-       testl SYMBOL_NAME(softirq_state)+4,%ecx
+       movl SYMBOL_NAME(irq_stat),%ecx         # softirq_active
+       testl SYMBOL_NAME(irq_stat)+4,%ecx      # softirq_mask
 #endif
        jne   handle_softirq
        
@@ -262,11+262,11 @@ ret_from_exception:
        GET_CURRENT(%ebx)
        movl processor(%ebx),%eax
        shll $5,%eax
-       movl SYMBOL_NAME(softirq_state)(,%eax),%ecx
-       testl SYMBOL_NAME(softirq_state)+4(,%eax),%ecx
+       movl SYMBOL_NAME(irq_stat)(,%eax),%ecx          # softirq_active
+       testl SYMBOL_NAME(irq_stat)+4(,%eax),%ecx       # softirq_mask
 #else
-       movl SYMBOL_NAME(softirq_state),%ecx
-       testl SYMBOL_NAME(softirq_state)+4,%ecx
+       movl SYMBOL_NAME(irq_stat),%ecx         # softirq_active
+       testl SYMBOL_NAME(irq_stat)+4,%ecx      # softirq_mask
 #endif
        jne   handle_softirq
 
index 380ac49..c11ab01 100644 (file)
@@ -141,6+141,4 @@ EXPORT_SYMBOL(screen_info);
 
 EXPORT_SYMBOL(get_wchan);
 
-EXPORT_SYMBOL(irq_stat);
-
 EXPORT_SYMBOL(rtc_lock);
index 406a307..525f786 100644 (file)
@@ -1070,7+1070,7 @@ static int __init nmi_irq_works(void)
 
        for (j = 0; j < smp_num_cpus; j++) {
                cpu = cpu_logical_map(j);
-               if (nmi_counter(cpu) - tmp[cpu].__nmi_counter <= 3) {
+               if (nmi_count(cpu) - tmp[cpu].__nmi_count <= 3) {
                        printk(KERN_WARNING "CPU#%d NMI appears to be stuck.\n", cpu);
                        return 0;
                }
index fcc0a72..92ddd01 100644 (file)
  * interrupt controllers, without having to do assembly magic.
  */
 
-irq_cpustat_t irq_stat [NR_CPUS];
-
 /*
  * Controller mappings for all interrupt sources:
  */
@@ -160,7+158,7 @@ int get_irq_list(char *buf)
        p += sprintf(p, "NMI: ");
        for (j = 0; j < smp_num_cpus; j++)
                p += sprintf(p, "%10u ",
-                       nmi_counter(cpu_logical_map(j)));
+                       nmi_count(cpu_logical_map(j)));
        p += sprintf(p, "\n");
 #if CONFIG_SMP
        p += sprintf(p, "LOC: ");
@@ -624,7+622,7 @@ out:
        desc->handler->end(irq);
        spin_unlock(&desc->lock);
 
-       if (softirq_state[cpu].active & softirq_state[cpu].mask)
+       if (softirq_active(cpu) & softirq_mask(cpu))
                do_softirq();
        return 1;
 }
index eea5258..7bd8a04 100644 (file)
@@ -459,7+459,7 @@ asmlinkage void do_nmi(struct pt_regs * regs, long error_code)
        unsigned char reason = inb(0x61);
 
 
-       ++nmi_counter(smp_processor_id());
+       ++nmi_count(smp_processor_id());
        if (!(reason & 0xc0)) {
 #if CONFIG_X86_IO_APIC
                /*
index 3aadb43..f9beac2 100644 (file)
@@ -506,7+506,7 @@ GLOBAL_ENTRY(ia64_leave_kernel)
        PT_REGS_UNWIND_INFO(0)
 #ifdef CONFIG_SMP
        adds r2=IA64_TASK_PROCESSOR_OFFSET,r13
-       movl r3=softirq_state
+       movl r3=irq_stat                // softirq_active
        ;;
        ld4 r2=[r2]
        ;;
@@ -514,10+514,10 @@ GLOBAL_ENTRY(ia64_leave_kernel)
        ;;
        add r3=r2,r3
 #else
-       movl r3=softirq_state
+       movl r3=irq_stat                // softirq_active
 #endif
        ;;
-       ld8 r2=[r3]             // r3 is guaranteed to be 8-byte aligned!
+       ld8 r2=[r3]             // r3 (softirq_active+softirq_mask) is guaranteed to be 8-byte aligned!
        ;;
        shr r3=r2,32
        ;;
index 7f01b66..2e4ffe4 100644 (file)
@@ -32,10+32,6 @@ EXPORT_SYMBOL(csum_partial_copy_nocheck);
 EXPORT_SYMBOL(enable_irq);
 EXPORT_SYMBOL(disable_irq);
 
-#include <asm/current.h>
-#include <asm/hardirq.h>
-EXPORT_SYMBOL(irq_stat);
-
 #include <asm/processor.h>
 EXPORT_SYMBOL(cpu_data);
 EXPORT_SYMBOL(kernel_thread);
index ed7eb88..c913fdc 100644 (file)
  * interrupt controllers, without having to do assembly magic.
  */
 
-irq_cpustat_t irq_stat [NR_CPUS];
-
 /*
  * Controller mappings for all interrupt sources:
  */
@@ -162,7+160,7 @@ int get_irq_list(char *buf)
        p += sprintf(p, "NMI: ");
        for (j = 0; j < smp_num_cpus; j++)
                p += sprintf(p, "%10u ",
-                       nmi_counter(cpu_logical_map(j)));
+                       nmi_count(cpu_logical_map(j)));
        p += sprintf(p, "\n");
 #if defined(CONFIG_SMP) && defined(__i386__)
        p += sprintf(p, "LOC: ");
index f47ff3a..f92c45f 100644 (file)
@@ -168,7+168,7 @@ asmlinkage void IRQ_NAME(n);                                                   \
 void atari_slow_irq_##n##_dummy (void) {                                  \
 __asm__ (__ALIGN_STR "\n"                                                 \
 SYMBOL_NAME_STR(atari_slow_irq_) #n "_handler:\t"                         \
-"      addql   #1,"SYMBOL_NAME_STR(local_irq_count)"\n"                   \
+"      addql   #1,"SYMBOL_NAME_STR(irq_stat)"+8\n" /* local_irq_count */  \
        SAVE_ALL_INT "\n"                                                  \
        GET_CURRENT(%%d0) "\n"                                             \
 "      andb    #~(1<<(%c3&7)),%a4:w\n" /* mask this interrupt */          \
@@ -274,7+274,7 @@ __asm__ (__ALIGN_STR "\n"
 SYMBOL_NAME_STR(atari_fast_irq_handler) ":
        orw     #0x700,%%sr             /* disable all interrupts */
 "SYMBOL_NAME_STR(atari_prio_irq_handler) ":\t
-       addql   #1,"SYMBOL_NAME_STR(local_irq_count)"\n"
+       addql   #1,"SYMBOL_NAME_STR(irq_stat)"+8\n" /* local_irq_count */
        SAVE_ALL_INT "\n"
        GET_CURRENT(%%d0) "
        /* get vector number from stack frame and convert to source */
index 5f08ef2..7cbb69d 100644 (file)
@@ -171,7+171,7 @@ do_delayed_trace:
 #if 0
 #if CONFIG_AMIGA
 SYMBOL_NAME_LABEL(ami_inthandler)
-       addql   #1,SYMBOL_NAME(local_irq_count)
+       addql   #1,SYMBOL_NAME(irq_stat)+8      | local_irq_count
        SAVE_ALL_INT
        GET_CURRENT(%d0)
 
@@ -203,7+203,7 @@ ENTRY(nmi_handler)
 SYMBOL_NAME_LABEL(inthandler)
        SAVE_ALL_INT
        GET_CURRENT(%d0)
-       addql   #1,SYMBOL_NAME(local_irq_count)
+       addql   #1,SYMBOL_NAME(irq_stat)+8      | local_irq_count
                                        |  put exception # in d0
        bfextu %sp@(PT_VECTOR){#4,#10},%d0
 
@@ -222,7+222,7 @@ SYMBOL_NAME_LABEL(inthandler)
 3:             addql   #8,%sp                  |  pop parameters off stack
 
 SYMBOL_NAME_LABEL(ret_from_interrupt)
-       subql   #1,SYMBOL_NAME(local_irq_count)
+       subql   #1,SYMBOL_NAME(irq_stat)+8      | local_irq_count
        jeq     1f
 2:
        RESTORE_ALL
@@ -236,8+236,8 @@ SYMBOL_NAME_LABEL(ret_from_interrupt)
 #endif
        /* check if we need to do software interrupts */
 
-       movel   SYMBOL_NAME(softirq_state),%d0
-       andl    SYMBOL_NAME(softirq_state)+4,%d0
+       movel   SYMBOL_NAME(irq_stat),%d0       | softirq_active
+       andl    SYMBOL_NAME(irq_stat)+4,%d0     | softirq_mask
        jeq     SYMBOL_NAME(ret_from_exception)
 
        pea     SYMBOL_NAME(ret_from_exception)
index 9dc6427..74e1e4c 100644 (file)
@@ -57,10+57,6 @@ volatile unsigned int num_spurious;
 #define NUM_IRQ_NODES 100
 static irq_node_t nodes[NUM_IRQ_NODES];
 
-unsigned int local_irq_count[NR_CPUS];
-
-unsigned int local_bh_count[NR_CPUS];
-
 static void dummy_enable_irq(unsigned int irq);
 static void dummy_disable_irq(unsigned int irq);
 static int dummy_request_irq(unsigned int irq,
index 6f83004..7bf4614 100644 (file)
@@ -52,8+52,6 @@ EXPORT_SYMBOL(dump_thread);
 EXPORT_SYMBOL(strnlen);
 EXPORT_SYMBOL(strrchr);
 EXPORT_SYMBOL(strstr);
-EXPORT_SYMBOL(local_irq_count);
-EXPORT_SYMBOL(local_bh_count);
 EXPORT_SYMBOL(enable_irq);
 EXPORT_SYMBOL(disable_irq);
 EXPORT_SYMBOL(kernel_thread);
index 08b15a7..03d68ee 100644 (file)
 
 #include <asm/baget/baget.h>
 
-irq_cpustat_t irq_stat [NR_CPUS];
 unsigned long spurious_count = 0;
 
 /*
index 7551ae6..91e1ce4 100644 (file)
@@ -31,10+31,6 @@ extern volatile unsigned int *isr;   /* address of the interrupt status register
 extern volatile unsigned int *imr;     /* address of the interrupt mask register       */
 extern decint_t dec_interrupt[NR_INTS];
 
-irq_cpustat_t irq_stat [NR_CPUS];
-
-unsigned int local_bh_count[NR_CPUS];
-unsigned int local_irq_count[NR_CPUS];
 unsigned long spurious_count = 0;
 
 static inline void mask_irq(unsigned int irq_nr)
index bde2101..bc56db5 100644 (file)
@@ -43,8+43,8 @@ reschedule:   jal     schedule
 EXPORT(ret_from_sys_call)
 EXPORT(ret_from_irq)
                .type   ret_from_irq,@function
-               lw      t0, softirq_state
-               lw      t1, softirq_state+4     # unused delay slot
+               lw      t0, irq_stat            # softirq_active
+               lw      t1, irq_stat+4          # softirq_mask.  unused delay slot
                and     t0, t1
                bnez    t0, handle_softirq
 
index 54c2c3c..fcb7a63 100644 (file)
  * interrupt controllers, without having to do assembly magic.
  */
 
-irq_cpustat_t irq_stat [NR_CPUS];
-
 /*
  * This contains the irq mask for both 8259A irq controllers, it's an
  * int so we can deal with the third PIC in some systems like the RM300.
@@ -63,8+61,6 @@ static unsigned int cached_irq_mask = 0xffff;
 #define cached_21       (__byte(0,cached_irq_mask))
 #define cached_A1       (__byte(1,cached_irq_mask))
 
-unsigned int local_bh_count[NR_CPUS];
-unsigned int local_irq_count[NR_CPUS];
 unsigned long spurious_count = 0;
 
 /*
@@ -228,7+224,7 @@ asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
        }
        irq_exit(cpu);
 
-       if (softirq_state[cpu].active&softirq_state[cpu].mask)
+       if (softirq_active(cpu)&softirq_mask(cpu))
                do_softirq();
 
        /* unmasking and bottom half handling is done magically for us. */
index b58272f..3b3c431 100644 (file)
@@ -140,4+140,3 @@ EXPORT_SYMBOL(ide_ops);
 #endif
 
 EXPORT_SYMBOL(get_wchan);
-EXPORT_SYMBOL(irq_stat);
index ddf69a9..bdc72ca 100644 (file)
@@ -65,8+65,8 @@ stack_done:
 1:     sw      v0, PT_R2(sp)           # result
 
 EXPORT(o32_ret_from_sys_call)
-       lw      t0, softirq_state
-       lw      t1, softirq_state+4     # unused delay slot
+       lw      t0, irq_stat            # softirq_active
+       lw      t1, irq_stat+4          # softirq_mask.  unused delay slot
        and     t0, t1
        bnez    t0, o32_handle_softirq
 
index f61690b..1721b47 100644 (file)
 
 void (*board_time_init)(struct irqaction *irq);
 extern asmlinkage void orionIRQ(void);
-irq_cpustat_t irq_stat [NR_CPUS];
-unsigned int local_bh_count[NR_CPUS];
-unsigned int local_irq_count[NR_CPUS];
 unsigned long spurious_count = 0;
 irq_desc_t irq_desc[NR_IRQS];
 
@@ -186,7+183,7 @@ asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
 
        irq_exit(cpu);
 
-       if (softirq_state[cpu].active&softirq_state[cpu].mask)
+       if (softirq_active(cpu)&softirq_mask(cpu))
                do_softirq();
 
        /* unmasking and bottom half handling is done magically for us. */
index 1c6d9e2..0d88810 100644 (file)
 #include <asm/stackframe.h>
 #include <asm/system.h>
 #include <asm/cpu.h>
-#include <linux/sched.h>
 #include <linux/bootmem.h>
 #include <asm/addrspace.h>
-#include <asm/bootinfo.h>
 #include <asm/mc146818rtc.h>
 
 char arcs_cmdline[CL_SIZE] = {0, };
index 8d4cc54..c247d6b 100644 (file)
 #include <asm/stackframe.h>
 #include <asm/system.h>
 #include <asm/cpu.h>
-#include <linux/sched.h>
 #include <linux/bootmem.h>
 #include <asm/addrspace.h>
-#include <asm/bootinfo.h>
 #include <asm/mc146818rtc.h>
 #include <asm/orion.h>
 
index 06d8573..2e104bf 100644 (file)
  * interrupt controllers, without having to do assembly magic.
  */
 
-irq_cpustat_t irq_stat [NR_CPUS];
-
 /* #define DEBUG_SGINT */
 
 struct sgi_int2_regs *sgi_i2regs;
@@ -72,8+70,6 @@ static char lc3msk_to_irqnr[256];
 
 extern asmlinkage void indyIRQ(void);
 
-unsigned int local_bh_count[NR_CPUS];
-unsigned int local_irq_count[NR_CPUS];
 unsigned long spurious_count = 0;
 
 /* Local IRQ's are layed out logically like this:
index 8f61ca7..ee48814 100644 (file)
@@ -35,14+35,14 @@ reschedule: jal     schedule
 
 FEXPORT(ret_from_sys_call)
 FEXPORT(ret_from_irq)
-               la      t1, softirq_state
+               la      t1, irq_stat            # softirq_active
 #ifdef CONFIG_SMP
                lwu     t0, TASK_PROCESSOR($28)
                dsll    t0, t0, 5
                daddu   t1, t0
 #endif
-               lw      t0, 0 (t1)
-               lw      t1, 4 (t1)              # unused delay slot
+               lw      t0, 0 (t1)              # softirq_active
+               lw      t1, 4 (t1)              # softirq_mask.  unused delay slot
                and     t0, t1
                bnez    t0, handle_softirq
 9:              ld     t0, PT_STATUS(sp)       # returning to kernel mode?
index a6ac27f..2e65e17 100644 (file)
@@ -63,8+63,8 @@ NESTED(handle_sys64, PT_SIZE, sp)
 1:     sd      v0, PT_R2(sp)           # result
 
 FEXPORT(ret_from_sys_call_64)
-       lw      t0, softirq_state
-       lw      t1, softirq_state+4     # unused delay slot
+       lw      t0, irq_stat            # softirq_active
+       lw      t1, irq_stat+4          # softirq_mask.  unused delay slot
        and     t0, t1
        bnez    t0, handle_softirq_64
 
index 2047c73..2d7782d 100644 (file)
@@ -76,8+76,8 @@ stack_done:
 1:     sd      v0, PT_R2(sp)           # result
        
 FEXPORT(o32_ret_from_sys_call)
-       lw      t0, softirq_state
-       lw      t1, softirq_state+4     # unused delay slot
+       lw      t0, irq_stat            # softirq_active
+       lw      t1, irq_stat+4          # softirq_mask.  unused delay slot
        and     t0, t1
        bnez    t0, o32_handle_softirq
 
index 891e121..19c61e6 100644 (file)
  * interrupt controllers, without having to do assembly magic.
  */
 
-irq_cpustat_t irq_stat [NR_CPUS];
-
 struct sgi_int2_regs *sgi_i2regs;
 struct sgi_int3_regs *sgi_i3regs;
 struct sgi_ioc_ints *ioc_icontrol;
@@ -73,8+71,6 @@ int (*irq_cannonicalize)(int irq);
 extern void rs_kgdb_hook(int);
 #endif
 
-unsigned int local_bh_count[NR_CPUS];
-unsigned int local_irq_count[NR_CPUS];
 unsigned long spurious_count = 0;
 
 /* Local IRQ's are layed out logically like this:
index f5160af..ead444b 100644 (file)
  * interrupt controllers, without having to do assembly magic.
  */
 
-irq_cpustat_t irq_stat [NR_CPUS];
-
 extern asmlinkage void ip27_irq(void);
 extern int irq_to_bus[], irq_to_slot[], bus_to_cpu[];
 int (*irq_cannonicalize)(int irq);
 int intr_connect_level(int cpu, int bit);
 int intr_disconnect_level(int cpu, int bit);
 
-unsigned int local_bh_count[NR_CPUS];
-unsigned int local_irq_count[NR_CPUS];
 unsigned long spurious_count = 0;
 
 /*
index 8ccb0f5..d40a54c 100644 (file)
@@ -319,16+319,16 @@ lost_irq_ret:
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      do_IRQ
        b       3b
-1:     lis     r4,softirq_state@ha
-       addi    r4,r4,softirq_state@l
+1:     lis     r4,irq_stat@ha          /* &softirq_active for cpu 0 */
+       addi    r4,r4,irq_stat@l
 #ifdef CONFIG_SMP
        /* get processor # */
        lwz     r3,PROCESSOR(r2)
        slwi    r3,r3,5
        add     r4,r4,r3
 #endif /* CONFIG_SMP */
-       lwz     r5,0(r4)
-       lwz     r4,4(r4)
+       lwz     r5,0(r4)                /* softirq_active */
+       lwz     r4,4(r4)                /* softirq_mask */
        and.    r5,r5,r4
        beq+    2f
        bl      do_softirq
index ee63ca9..64ef4b4 100644 (file)
@@ -74,7+74,6 @@ volatile unsigned char *chrp_int_ack_special;
 
 irq_desc_t irq_desc[NR_IRQS];
 int ppc_spurious_interrupts = 0;
-irq_cpustat_t irq_stat [NR_CPUS];
 struct irqaction *ppc_irq_action[NR_IRQS];
 unsigned int ppc_cached_irq_mask[NR_MASK_WORDS];
 unsigned int ppc_lost_interrupts[NR_MASK_WORDS];
index 840b14d..5c616bb 100644 (file)
@@ -15,8+15,6 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq);
 extern int ppc_spurious_interrupts;
 extern int ppc_second_irq;
 extern struct irqaction *ppc_irq_action[NR_IRQS];
-extern unsigned int ppc_local_bh_count[NR_CPUS];
-extern unsigned int ppc_local_irq_count[NR_CPUS];
 extern unsigned int ppc_cached_irq_mask[NR_MASK_WORDS];
 extern unsigned int ppc_lost_interrupts[NR_MASK_WORDS];
 extern atomic_t ppc_n_lost_interrupts;
index 3f0b52e..1317359 100644 (file)
@@ -78,7+78,6 @@ EXPORT_SYMBOL(do_lost_interrupts);
 EXPORT_SYMBOL(enable_irq);
 EXPORT_SYMBOL(disable_irq);
 EXPORT_SYMBOL(disable_irq_nosync);
-EXPORT_SYMBOL(irq_stat);
 #ifdef CONFIG_SMP
 EXPORT_SYMBOL(kernel_flag);
 #endif /* CONFIG_SMP */
index 9acccfd..9913d59 100644 (file)
@@ -193,7+193,6 @@ RES_DN1:
  */
 
 sysc_lit:
-  sysc_softirq_state: .long  softirq_state
   sysc_do_signal:     .long  do_signal
   sysc_do_softirq:    .long  do_softirq
   sysc_schedule:      .long  schedule
@@ -237,17+236,8 @@ sysc_return:
 #
 # check, if bottom-half has to be done
 #
-#ifdef CONFIG_SMP
-        l       %r1,processor(%r9) # get processor index
-        sll     %r1,5
-        al      %r1,sysc_softirq_state-sysc_lit(%r13)
-        l       %r0,0(%r1)        # get softirq_state[cpu].active
-        n       %r0,4(%r1)        # and it with softirq_state[cpu].mask
-#else
-        l       %r1,sysc_softirq_state-sysc_lit(%r13)
-        l       %r0,0(%r1)        # get softirq_state.active
-        n       %r0,4(%r1)        # and it with softirq_state.mask
-#endif
+        l       %r0,__LC_IRQ_STAT     # get softirq_active
+        n       %r0,__LC_IRQ_STAT+4   # and it with softirq_mask
         jnz     sysc_handle_bottom_half
 #
 # check, if reschedule is needed
@@ -714,7+704,6 @@ io_lit:
   io_do_IRQ:        .long do_IRQ
   io_schedule:     .long schedule
   io_do_signal:     .long do_signal
-  io_softirq_state: .long  softirq_state
   io_do_softirq:    .long  do_softirq
 
         .globl io_int_handler
@@ -737,17+726,8 @@ io_return:
 #
 # check, if bottom-half has to be done
 #
-#ifdef CONFIG_SMP
-        l       %r1,processor(%r9) # get processor index
-        sll     %r1,5
-        al      %r1,io_softirq_state-io_lit(%r13)
-        l       %r0,0(%r1)        # get softirq_state[cpu].active
-        n       %r0,4(%r1)        # and it with softirq_state[cpu].mask
-#else
-        l       %r1,io_softirq_state-io_lit(%r13)
-        l       %r0,0(%r1)        # get softirq_state.active
-        n       %r0,4(%r1)        # and it with softirq_state.mask
-#endif
+        l       %r0,__LC_IRQ_STAT     # get softirq_active
+        n       %r0,__LC_IRQ_STAT+4   # and it with softirq_mask
         jnz     io_handle_bottom_half
 io_return_bh:  
 #
index 298aa24..ba51332 100644 (file)
@@ -143,9+143,9 @@ static void show(char * str)
 
        printk("\n%s, CPU %d:\n", str, cpu);
        printk("irq:  %d [%d]\n",
-              atomic_read(&global_irq_count),atomic_read(&S390_lowcore.local_irq_count));
+              atomic_read(&global_irq_count),local_irq_count(smp_processor_id()));
        printk("bh:   %d [%d]\n",
-              atomic_read(&global_bh_count),atomic_read(&S390_lowcore.local_bh_count));
+              atomic_read(&global_bh_count),local_bh_count(smp_processor_id()));
        stack = (unsigned long *) &str;
        for (i = 40; i ; i--) {
                unsigned long x = *++stack;
@@ -181,7+181,7 @@ static inline void wait_on_irq(int cpu)
                 * already executing in one..
                 */
                if (!atomic_read(&global_irq_count)) {
-                       if (atomic_read(&safe_get_cpu_lowcore(cpu).local_bh_count)||
+                       if (local_bh_count(cpu)||
                            !atomic_read(&global_bh_count))
                                break;
                }
@@ -202,7+202,7 @@ static inline void wait_on_irq(int cpu)
                                continue;
                        if (atomic_read(&global_irq_lock))
                                continue;
-                       if (!(atomic_read(&safe_get_cpu_lowcore(cpu).local_bh_count))
+                       if (!local_bh_count(cpu)
                            && atomic_read(&global_bh_count))
                                continue;
                        if (!test_and_set_bit(0,&global_irq_lock))
@@ -288,7+288,7 @@ void __global_cli(void)
        if (flags & (1 << EFLAGS_I_SHIFT)) {
                int cpu = smp_processor_id();
                __cli();
-               if (!atomic_read(&S390_lowcore.local_irq_count))
+               if (!in_irq())
                        get_irqlock(cpu);
        }
 }
@@ -296,7+296,7 @@ void __global_cli(void)
 void __global_sti(void)
 {
 
-       if (!atomic_read(&S390_lowcore.local_irq_count))
+       if (!in_irq())
                release_irqlock(smp_processor_id());
        __sti();
 }
@@ -320,7+320,7 @@ unsigned long __global_save_flags(void)
        retval = 2 + local_enabled;
 
        /* check for global flags if we're not in an interrupt */
-       if (!atomic_read(&S390_lowcore.local_irq_count))
+       if (!in_irq())
        {
                if (local_enabled)
                        retval = 1;
index 93d4dff..6f6a528 100644 (file)
@@ -64,8+64,8 @@ int cpu_idle(void *unused)
        wait_psw.mask = _WAIT_PSW_MASK;
        wait_psw.addr = (unsigned long) &&idle_wakeup | 0x80000000L;
        while(1) {
-                if (softirq_state[smp_processor_id()].active &
-                   softirq_state[smp_processor_id()].mask) {
+                if (softirq_active(smp_processor_id()) &
+                   softirq_mask(smp_processor_id())) {
                         do_softirq();
                         continue;
                 }
index 7a4e531..b1db167 100644 (file)
@@ -621,8+621,11 @@ void s390_init_IRQ( void )
 
        // Hopefully bh_count's will get set when we copy the prefix lowcore
        // structure to other CPI's ( DJB )
-       atomic_set(&S390_lowcore.local_bh_count,0);
-       atomic_set(&S390_lowcore.local_irq_count,0);
+       softirq_active(smp_processor_id()) = 0;
+       softirq_mask(smp_processor_id()) = 0;
+       local_bh_count(smp_processor_id()) = 0;
+       local_irq_count(smp_processor_id()) = 0;
+       syscall_count(smp_processor_id()) = 0;
 
        asm volatile ("STCK %0" : "=m" (irq_IPL_TOD));
 
index cfc744a..f20a9d4 100644 (file)
@@ -65,7+65,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
 
         address = S390_lowcore.trans_exc_code&0x7ffff000;
 
-        if (atomic_read(&S390_lowcore.local_irq_count))
+        if (in_irq())
                 die("page fault from irq handler",regs,error_code);
 
         tsk = current;
index cbca87e..450d498 100644 (file)
@@ -462,9+462,9 @@ syscall_ret:
        /* fall through */
 
 ENTRY(ret_from_syscall)
-       mov.l   __softirq_state, $r0
+       mov.l   __irq_stat, $r0 ! softirq_active
        mov.l   @$r0, $r1
-       mov.l   @(4,$r0), $r2
+       mov.l   @(4,$r0), $r2   ! softirq_mask
        tst     $r2, $r1
        bt      ret_with_reschedule
 handle_softirq:
@@ -489,8+489,8 @@ signal_return:
        .align  2
 __do_signal:
        .long   SYMBOL_NAME(do_signal)
-__softirq_state:
-       .long   SYMBOL_NAME(softirq_state)
+__irq_stat:
+       .long   SYMBOL_NAME(irq_stat)
 __do_softirq:
        .long   SYMBOL_NAME(do_softirq)
 
index 399d435..a353b09 100644 (file)
 #include <asm/hd64461.h>
 #endif
 
-unsigned int __local_bh_count[NR_CPUS];
-unsigned int __local_irq_count[NR_CPUS];
-
 /*
  * Micro-access to controllers is serialized over the whole
  * system. We never hold this lock when we call the actual
@@ -183,7+180,7 @@ void disable_irq(unsigned int irq)
 {
        disable_irq_nosync(irq);
 
-       if (!__local_irq_count[smp_processor_id()]) {
+       if (!local_irq_count(smp_processor_id())) {
                do {
                        barrier();
                } while (irq_desc[irq].status & IRQ_INPROGRESS);
@@ -319,7+316,7 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
 #if 0
        __sti();
 #endif
-       if (softirq_state[cpu].active&softirq_state[cpu].mask)
+       if (softirq_active(cpu)&softirq_mask(cpu))
                do_softirq();
        return 1;
 }
index e79dfd8..570f863 100644 (file)
-# $Id: config.in,v 1.98 2000/07/06 01:41:29 davem Exp $
+# $Id: config.in,v 1.99 2000/08/01 04:53:58 anton Exp $
 # For a description of the syntax of this configuration file,
 # see Documentation/kbuild/config-language.txt.
 #
 mainmenu_name "Linux/SPARC Kernel Configuration"
 
 define_bool CONFIG_UID16 y
+define_bool CONFIG_HIGHMEM y
 
 mainmenu_option next_comment
 comment 'Code maturity level options'
index 65e95af..a6fd32f 100644 (file)
@@ -195,16+195,9 @@ void free_irq(unsigned int irq, void *dev_id)
         restore_flags(flags);
 }
 
-#ifndef CONFIG_SMP
-unsigned int __local_bh_count;
-unsigned int __local_irq_count;
-
-#else
+#ifdef CONFIG_SMP
 /* SMP interrupt locking on Sparc. */
 
-unsigned int __local_bh_count[NR_CPUS];
-unsigned int __local_irq_count[NR_CPUS];
-
 /* Who has global_irq_lock. */
 unsigned char global_irq_holder = NO_PROC_ID;
 
@@ -229,14+222,14 @@ static void show(char * str)
        printk("irq:  %d [ ", atomic_read(&global_irq_count));
 
        for (i = 0; i < NR_CPUS; i++) {
-               printk("%d ", __local_irq_count[i]);
+               printk("%d ", local_irq_count(i));
        }
        printk("]\n");
 
        printk("bh:   %d [ ", (spin_is_locked(&global_bh_lock) ? 1 : 0));
 
        for (i = 0; i < NR_CPUS; i++) {
-               printk("%d ", __local_bh_count[cpu]);
+               printk("%d ", local_bh_count(cpu));
        }
        printk("]\n");
 
@@ -263,7+256,7 @@ static inline void wait_on_irq(int cpu)
                 * already executing in one..
                 */
                if (!atomic_read(&global_irq_count)) {
-                       if (__local_bh_count[cpu] || !spin_is_locked(&global_bh_lock))
+                       if (local_bh_count(cpu) || !spin_is_locked(&global_bh_lock))
                                break;
                }
 
@@ -282,7+275,7 @@ static inline void wait_on_irq(int cpu)
                                continue;
                        if (spin_is_locked (&global_irq_lock))
                                continue;
-                       if (!__local_bh_count[cpu] && spin_is_locked(&global_bh_lock))
+                       if (!local_bh_count(cpu) && spin_is_locked(&global_bh_lock))
                                continue;
                        if (spin_trylock(&global_irq_lock))
                                break;
@@ -358,7+351,7 @@ void __global_cli(void)
        if ((flags & PSR_PIL) != PSR_PIL) {
                int cpu = smp_processor_id();
                __cli();
-               if (!__local_irq_count[cpu])
+               if (!local_irq_count(cpu))
                        get_irqlock(cpu);
        }
 }
@@ -367,7+360,7 @@ void __global_sti(void)
 {
        int cpu = smp_processor_id();
 
-       if (!__local_irq_count[cpu])
+       if (!local_irq_count(cpu))
                release_irqlock(cpu);
        __sti();
 }
@@ -394,7+387,7 @@ unsigned long __global_save_flags(void)
        retval = 2 + local_enabled;
 
        /* check for global flags if we're not in an interrupt */
-       if (!__local_irq_count[smp_processor_id()]) {
+       if (!local_irq_count(smp_processor_id())) {
                if (local_enabled)
                        retval = 1;
                if (global_irq_holder == (unsigned char) smp_processor_id())
index dcfc2dc..c44040b 100644 (file)
@@ -50,10+50,10 @@ rtrap_7win_patch5:  and     %g1, 0x7f, %g1
 ret_trap_entry:
        ld      [%curptr + AOFF_task_processor], %l3
        sll     %l3, 5, %l3
-       sethi   %hi(C_LABEL(softirq_state)), %l4
+       sethi   %hi(C_LABEL(irq_stat)), %l4             ! &softirq_active
        add     %l4, %l3, %l4
-       ld      [%l4 + %lo(C_LABEL(softirq_state))], %g5
-       ld      [%l4 + %lo(C_LABEL(softirq_state) + 4)], %g4
+       ld      [%l4 + %lo(C_LABEL(irq_stat))], %g5     ! softirq_active
+       ld      [%l4 + %lo(C_LABEL(irq_stat) + 4)], %g4 ! softirq_mask
        andcc   %g4, %g5, %g0
        be      C_LABEL(ret_trap_lockless_ipi)
         nop
index a519957..37c276c 100644 (file)
@@ -146,8+146,6 @@ EXPORT_SYMBOL(global_bh_lock);
 EXPORT_SYMBOL(global_irq_count);
 EXPORT_SYMBOL(synchronize_irq);
 #endif
-EXPORT_SYMBOL(__local_irq_count);
-EXPORT_SYMBOL(__local_bh_count);
 
 EXPORT_SYMBOL(udelay);
 EXPORT_SYMBOL(mstk48t02_regs);
index 5ac1845..ced31b9 100644 (file)
@@ -1,4+1,4 @@
-/*  $Id: init.c,v 1.88 2000/07/10 20:56:53 anton Exp $
+/*  $Id: init.c,v 1.89 2000/08/01 04:53:58 anton Exp $
  *  linux/arch/sparc/mm/init.c
  *
  *  Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -51,7+51,9 @@ extern char __init_begin, __init_end, _start, _end, etext , edata;
 extern unsigned int sparc_ramdisk_image;
 extern unsigned int sparc_ramdisk_size;
 
-unsigned long totalram_pages = 0;
+unsigned long highstart_pfn, highend_pfn;
+unsigned long totalram_pages;
+static unsigned long totalhigh_pages;
 
 /*
  * BAD_PAGE is the page that is used for page faults when linux
@@ -79,6+81,21 @@ pte_t __bad_page(void)
                                       PAGE_SHARED));
 }
 
+pte_t *kmap_pte;
+pgprot_t kmap_prot;
+
+#define kmap_get_fixed_pte(vaddr) \
+       pte_offset(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
+
+void __init kmap_init(void)
+{
+       unsigned long pteval;
+
+       /* cache the first kmap pte */
+       kmap_pte = kmap_get_fixed_pte(FIX_KMAP_BEGIN);
+       kmap_prot = __pgprot(SRMMU_ET_PTE | SRMMU_PRIV | SRMMU_CACHE);
+}
+
 void show_mem(void)
 {
        printk("Mem-info:\n");
@@ -119,22+136,15 @@ void __init sparc_context_init(int numctx)
 #define DEBUG_BOOTMEM
 
 extern unsigned long cmdline_memory_size;
+extern unsigned long last_valid_pfn;
 
-unsigned long __init bootmem_init(void)
+void __init bootmem_init(void)
 {
-       unsigned long bootmap_size, start_pfn, end_pfn;
+       unsigned long bootmap_size, start_pfn, max_pfn;
        unsigned long end_of_phys_memory = 0UL;
        unsigned long bootmap_pfn;
        int i;
 
-       /* 
-        * XXX Limit maximum memory until we implement highmem for sparc.
-        * The nocache region has taken up some room but I'll rearrange
-        * the virtual address regions soon - Anton
-        */
-       if (!cmdline_memory_size || cmdline_memory_size > 0x0c000000)
-               cmdline_memory_size = 0x0c000000;
-
        /* XXX It is a bit ambiguous here, whether we should
         * XXX treat the user specified mem=xxx as total wanted
         * XXX physical memory, or as a limit to the upper
@@ -181,7+191,16 @@ unsigned long __init bootmem_init(void)
 
        bootmap_pfn = start_pfn;
 
-       end_pfn = end_of_phys_memory >> PAGE_SHIFT;
+       max_pfn = end_of_phys_memory >> PAGE_SHIFT;
+
+       max_low_pfn = max_pfn;
+       highstart_pfn = highend_pfn = max_pfn;
+
+       if (max_low_pfn > (SRMMU_MAXMEM >> PAGE_SHIFT)) {
+               highstart_pfn = max_low_pfn = (SRMMU_MAXMEM >> PAGE_SHIFT);
+               printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
+               (highend_pfn - highstart_pfn) >> (20-PAGE_SHIFT));
+       }
 
 #ifdef CONFIG_BLK_DEV_INITRD
        /* Now have to check initial ramdisk, so that bootmap does not overwrite it */
@@ -205,22+224,41 @@ unsigned long __init bootmem_init(void)
 #endif 
        /* Initialize the boot-time allocator. */
 #ifdef DEBUG_BOOTMEM
-       prom_printf("init_bootmem(spfn[%lx],bpfn[%lx],epfn[%lx])\n",
-                   start_pfn, bootmap_pfn, end_pfn);
+       prom_printf("init_bootmem(spfn[%lx],bpfn[%lx],mlpfn[%lx])\n",
+                   start_pfn, bootmap_pfn, max_low_pfn);
 #endif
-       bootmap_size = init_bootmem(bootmap_pfn, end_pfn);
+       bootmap_size = init_bootmem(bootmap_pfn, max_low_pfn);
 
        /* Now register the available physical memory with the
         * allocator.
         */
        for (i = 0; sp_banks[i].num_bytes != 0; i++) {
+               unsigned long curr_pfn, last_pfn, size;
+
+               curr_pfn = sp_banks[i].base_addr >> PAGE_SHIFT;
+               if (curr_pfn >= max_low_pfn)
+                       break;
+
+               last_pfn = (sp_banks[i].base_addr + sp_banks[i].num_bytes) >> PAGE_SHIFT;
+               if (last_pfn > max_low_pfn)
+                       last_pfn = max_low_pfn;
+
+               /*
+                * .. finally, did all the rounding and playing
+                * around just make the area go away?
+                */
+               if (last_pfn <= curr_pfn)
+                       continue;
+
+               size = (last_pfn - curr_pfn) << PAGE_SHIFT;
+
 #ifdef DEBUG_BOOTMEM
                prom_printf("free_bootmem: base[%lx] size[%lx]\n",
                            sp_banks[i].base_addr,
-                           sp_banks[i].num_bytes);
+                           size);
 #endif
                free_bootmem(sp_banks[i].base_addr,
-                            sp_banks[i].num_bytes);
+                            size);
        }
 
        /* Reserve the kernel text/data/bss, the bootmem bitmap and initrd. */
@@ -245,10+283,7 @@ unsigned long __init bootmem_init(void)
        reserve_bootmem(phys_base, (start_pfn << PAGE_SHIFT) - phys_base);
        reserve_bootmem((bootmap_pfn << PAGE_SHIFT), bootmap_size);
 
-#ifdef DEBUG_BOOTMEM
-       prom_printf("init_bootmem: return end_pfn[%lx]\n", end_pfn);
-#endif
-       return end_pfn;
+       last_valid_pfn = max_pfn;
 }
 
 /*
@@ -391,6+426,25 @@ void __init free_unused_mem_map(void)
 #endif
 }
 
+void map_high_region(unsigned long start_pfn, unsigned long end_pfn)
+{
+       unsigned long tmp;
+
+#ifdef DEBUG_HIGHMEM
+       printk("mapping high region %08lx - %08lx\n", start_pfn, end_pfn);
+#endif
+
+       for (tmp = start_pfn; tmp < end_pfn; tmp++) {
+               struct page *page = mem_map + tmp;
+
+               ClearPageReserved(page);
+               set_bit(PG_highmem, &page->flags);
+               atomic_set(&page->count, 1);
+               __free_page(page);
+               totalhigh_pages++;
+       }
+}
+
 void __init mem_init(void)
 {
        int codepages = 0;
@@ -401,6+455,10 @@ void __init mem_init(void)
        unsigned long addr, last;
 #endif
 
+       highmem_start_page = mem_map + highstart_pfn;
+       /* cache the highmem_mapnr */
+       highmem_mapnr = highstart_pfn;
+
        /* Saves us work later. */
        memset((void *)&empty_zero_page, 0, PAGE_SIZE);
 
@@ -419,7+477,7 @@ void __init mem_init(void)
        taint_real_pages();
 
        max_mapnr = last_valid_pfn;
-       high_memory = __va(last_valid_pfn << PAGE_SHIFT);
+       high_memory = __va(max_low_pfn << PAGE_SHIFT);
 
 #ifdef DEBUG_BOOTMEM
        prom_printf("mem_init: Calling free_all_bootmem().\n");
@@ -430,6+488,21 @@ void __init mem_init(void)
        free_unused_mem_map();
 #endif
 
+       for (i = 0; sp_banks[i].num_bytes != 0; i++) {
+               unsigned long start_pfn = sp_banks[i].base_addr >> PAGE_SHIFT;
+               unsigned long end_pfn = (sp_banks[i].base_addr + sp_banks[i].num_bytes) >> PAGE_SHIFT;
+
+               if (end_pfn <= highstart_pfn)
+                       continue;
+
+               if (start_pfn < highstart_pfn)
+                       start_pfn = highstart_pfn;
+
+               map_high_region(start_pfn, end_pfn);
+       }
+       
+       totalram_pages += totalhigh_pages;
+
        codepages = (((unsigned long) &etext) - ((unsigned long)&_start));
        codepages = PAGE_ALIGN(codepages) >> PAGE_SHIFT;
        datapages = (((unsigned long) &edata) - ((unsigned long)&etext));
@@ -437,11+510,12 @@ void __init mem_init(void)
        initpages = (((unsigned long) &__init_end) - ((unsigned long) &__init_begin));
        initpages = PAGE_ALIGN(initpages) >> PAGE_SHIFT;
 
-       printk("Memory: %dk available (%dk kernel code, %dk data, %dk init) [%08lx,%08lx]\n",
+       printk("Memory: %dk available (%dk kernel code, %dk data, %dk init, %ldk highmem) [%08lx,%08lx]\n",
               nr_free_pages() << (PAGE_SHIFT-10),
               codepages << (PAGE_SHIFT-10),
               datapages << (PAGE_SHIFT-10), 
               initpages << (PAGE_SHIFT-10),
+              totalhigh_pages << (PAGE_SHIFT-10),
               (unsigned long)PAGE_OFFSET, (last_valid_pfn << PAGE_SHIFT));
 
        /* NOTE NOTE NOTE NOTE
@@ -501,9+575,16 @@ void si_meminfo(struct sysinfo *val)
        val->sharedram = 0;
        val->freeram = nr_free_pages();
        val->bufferram = atomic_read(&buffermem_pages);
-
-       val->totalhigh = 0;
-       val->freehigh = 0;
+       val->totalhigh = totalhigh_pages;
+       val->freehigh = nr_free_highpages();
 
        val->mem_unit = PAGE_SIZE;
 }
+
+void flush_page_to_ram(struct page *page)
+{
+       unsigned long vaddr;
+       vaddr = kmap(page);
+       __flush_page_to_ram(page_address(page));
+       kunmap(page);
+}
index 612436b..c7f839f 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: srmmu.c,v 1.218 2000/07/10 23:22:32 anton Exp $
+/* $Id: srmmu.c,v 1.219 2000/08/01 04:53:58 anton Exp $
  * srmmu.c:  SRMMU specific routines for memory management.
  *
  * Copyright (C) 1995 David S. Miller  (davem@caip.rutgers.edu)
@@ -87,7+87,7 @@ char *srmmu_name;
 ctxd_t *srmmu_ctx_table_phys;
 ctxd_t *srmmu_context_table;
 
-int viking_mxcc_present = 0;
+int viking_mxcc_present;
 spinlock_t srmmu_context_spinlock = SPIN_LOCK_UNLOCKED;
 
 int is_hypersparc;
@@ -117,10+117,6 @@ static inline int srmmu_device_memory(unsigned long x)
 int srmmu_cache_pagetables;
 
 /* XXX Make this dynamic based on ram size - Anton */
-#define SRMMU_NOCACHE_NPAGES 256
-#define SRMMU_NOCACHE_VADDR 0xfc000000
-#define SRMMU_NOCACHE_SIZE (SRMMU_NOCACHE_NPAGES*PAGE_SIZE)
-#define SRMMU_NOCACHE_END (SRMMU_NOCACHE_VADDR + SRMMU_NOCACHE_SIZE)
 #define SRMMU_NOCACHE_BITMAP_SIZE (SRMMU_NOCACHE_NPAGES * 16)
 #define SRMMU_NOCACHE_BITMAP_SHIFT (PAGE_SHIFT - 4)
 
@@ -1190,9+1186,11 @@ void __init srmmu_paging_init(void)
 {
        int i, cpunode;
        char node_str[128];
-       unsigned long end_pfn;
+       pgd_t *pgd;
+       pmd_t *pmd;
+       pte_t *pte;
 
-       sparc_iomap.start = 0xfd000000;    /* 16MB of IOSPACE on all sun4m's. */
+       sparc_iomap.start = SUN4M_IOBASE_VADDR; /* 16MB of IOSPACE on all sun4m's. */
 
        if (sparc_cpu_model == sun4d)
                num_contexts = 65536; /* We know it is Viking */
@@ -1215,7+1213,7 @@ void __init srmmu_paging_init(void)
                prom_halt();
        }
 
-       last_valid_pfn = end_pfn = bootmem_init();
+       bootmem_init();
 
        srmmu_nocache_init();
         srmmu_inherit_prom_mappings(0xfe400000,(LINUX_OPPROM_ENDVM-PAGE_SIZE));
@@ -1238,6+1236,14 @@ void __init srmmu_paging_init(void)
        srmmu_allocate_ptable_skeleton(DVMA_VADDR, DVMA_END);
 #endif
 
+       srmmu_allocate_ptable_skeleton(FIX_KMAP_BEGIN, FIX_KMAP_END);
+       srmmu_allocate_ptable_skeleton(PKMAP_BASE, PKMAP_BASE_END);
+
+       pgd = pgd_offset_k(PKMAP_BASE);
+       pmd = pmd_offset(pgd, PKMAP_BASE);
+       pte = pte_offset(pmd, PKMAP_BASE);
+       pkmap_page_table = pte;
+
        flush_cache_all();
        flush_tlb_all();
 
@@ -1253,10+1259,13 @@ void __init srmmu_paging_init(void)
 
        sparc_context_init(num_contexts);
 
+       kmap_init();
+
        {
                unsigned long zones_size[MAX_NR_ZONES] = { 0, 0, 0};
 
-               zones_size[ZONE_DMA] = end_pfn;
+               zones_size[ZONE_DMA] = max_low_pfn;
+               zones_size[ZONE_HIGHMEM] = highend_pfn - max_low_pfn;
                free_area_init(zones_size);
        }
 }
index 95c148e..c57f14b 100644 (file)
@@ -1,4+1,4 @@
-# $Id: config.in,v 1.117 2000/07/10 20:57:35 davem Exp $
+# $Id: config.in,v 1.119 2000/08/02 10:45:03 davem Exp $
 # For a description of the syntax of this configuration file,
 # see the Configure script.
 #
@@ -67,6+67,7 @@ source drivers/parport/Config.in
 dep_tristate '  Parallel printer support' CONFIG_PRINTER $CONFIG_PARPORT
 if [ "$CONFIG_PCI" = "y" ]; then
    tristate 'SUNW, envctrl support' CONFIG_ENVCTRL
+   tristate '7-Segment Display support' CONFIG_DISPLAY7SEG
 fi
 endmenu
 
@@ -200,6+201,28 @@ endmenu
 
 source drivers/fc4/Config.in
 
+if [ "$CONFIG_PCI" = "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then
+    mainmenu_option next_comment
+    comment 'IEEE 1394 (FireWire) support'
+
+    dep_tristate 'IEEE 1394 (FireWire) support (EXPERIMENTAL)' CONFIG_IEEE1394 $CONFIG_PCI
+
+    if [ "$CONFIG_IEEE1394" != "n" ]; then
+       dep_tristate 'Texas Instruments PCILynx support' CONFIG_IEEE1394_PCILYNX $CONFIG_IEEE1394
+       if [ "$CONFIG_IEEE1394_PCILYNX" != "n" ]; then
+           bool '  Use PCILynx local RAM' CONFIG_IEEE1394_PCILYNX_LOCALRAM
+           bool '  Support for non-IEEE1394 local ports' CONFIG_IEEE1394_PCILYNX_PORTS
+       fi
+
+       dep_tristate 'OHCI (Open Host Controller Interface) support' CONFIG_IEEE1394_OHCI1394 $CONFIG_IEEE1394
+
+       dep_tristate 'Raw IEEE1394 I/O support' CONFIG_IEEE1394_RAWIO $CONFIG_IEEE1394
+
+       bool 'Excessive debugging output' CONFIG_IEEE1394_VERBOSEDEBUG
+    fi
+    endmenu
+fi
+
 if [ "$CONFIG_NET" = "y" ]; then
    mainmenu_option next_comment
    comment 'Network device support'
index e013e47..168109d 100644 (file)
@@ -65,6+65,7 @@ CONFIG_PARPORT_PC_FIFO=y
 CONFIG_PARPORT_1284=y
 CONFIG_PRINTER=m
 CONFIG_ENVCTRL=m
+CONFIG_DISPLAY7SEG=m
 
 #
 # Console drivers
@@ -323,6+324,17 @@ CONFIG_SCSI_PLUTO=m
 CONFIG_SCSI_FCAL=m
 
 #
+# IEEE 1394 (FireWire) support
+#
+CONFIG_IEEE1394=m
+CONFIG_IEEE1394_PCILYNX=m
+# CONFIG_IEEE1394_PCILYNX_LOCALRAM is not set
+# CONFIG_IEEE1394_PCILYNX_PORTS is not set
+CONFIG_IEEE1394_OHCI1394=m
+CONFIG_IEEE1394_RAWIO=m
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+
+#
 # Network device support
 #
 CONFIG_NETDEVICES=y
index f64422a..5872046 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: ebus.c,v 1.47 2000/03/25 05:18:10 davem Exp $
+/* $Id: ebus.c,v 1.48 2000/08/02 06:22:35 davem Exp $
  * ebus.c: PCI to EBus bridge device.
  *
  * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
@@ -34,6+34,9 @@ extern int flash_init(void);
 #ifdef CONFIG_ENVCTRL
 extern int envctrl_init(void);
 #endif
+#ifdef CONFIG_DISPLAY7SEG
+extern int d7s_init(void);
+#endif
 
 static inline void *ebus_alloc(size_t size)
 {
@@ -384,6+387,9 @@ void __init ebus_init(void)
 #ifdef CONFIG_OBP_FLASH
        flash_init();
 #endif
+#ifdef CONFIG_DISPLAY7SEG
+       d7s_init();
+#endif
        clock_probe();
        power_init();
 }
index 3195d3e..e95e039 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: entry.S,v 1.117 2000/07/11 02:21:12 davem Exp $
+/* $Id: entry.S,v 1.118 2000/08/01 00:11:31 davem Exp $
  * arch/sparc64/kernel/entry.S:  Sparc64 trap low-level entry points.
  *
  * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu)
@@ -980,7+980,7 @@ linux_syscall_trace:
        .align  32
        .globl  linux_sparc_syscall32
 linux_sparc_syscall32:
-       /* Direct access to user regs, must faster. */
+       /* Direct access to user regs, much faster. */
        cmp             %g1, NR_SYSCALLS                        ! IEU1  Group
        bgeu,pn         %xcc, linux_sparc_ni_syscall            ! CTI
         srl            %i0, 0, %o0                             ! IEU0
@@ -1009,7+1009,7 @@ linux_sparc_syscall32:
        .align  32
        .globl  linux_sparc_syscall, ret_sys_call
 linux_sparc_syscall:
-       /* Direct access to user regs, must faster. */
+       /* Direct access to user regs, much faster. */
        cmp             %g1, NR_SYSCALLS                        ! IEU1  Group
        bgeu,pn         %xcc, linux_sparc_ni_syscall            ! CTI
         mov            %i0, %o0                                ! IEU0
index 98e209d..d4f4997 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: ioctl32.c,v 1.93 2000/07/24 22:43:15 anton Exp $
+/* $Id: ioctl32.c,v 1.96 2000/08/02 06:22:35 davem Exp $
  * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
  *
  * Copyright (C) 1997-2000  Jakub Jelinek  (jakub@redhat.com)
 #include <asm/envctrl.h>
 #include <asm/audioio.h>
 #include <asm/ethtool.h>
-
+#include <asm/display7seg.h>
 #include <linux/soundcard.h>
 
 #include <linux/atm.h>
@@ -3175,6+3175,9 @@ COMPATIBLE_IOCTL(RTCGET)
 COMPATIBLE_IOCTL(RTCSET)
 COMPATIBLE_IOCTL(I2CIOCSADR)
 COMPATIBLE_IOCTL(I2CIOCGADR)
+COMPATIBLE_IOCTL(D7SIOCRD)
+COMPATIBLE_IOCTL(D7SIOCWR)
+COMPATIBLE_IOCTL(D7SIOCTM)
 /* Little m */
 COMPATIBLE_IOCTL(MTIOCTOP)
 /* OPENPROMIO, SunOS/Solaris only, the NetBSD one's have
@@ -3725,7+3728,9 @@ int register_ioctl32_conversion(unsigned int cmd, int (*handler)(unsigned int, u
        int i;
        if (!additional_ioctls) {
                additional_ioctls = module_map(PAGE_SIZE);
-               if (!additional_ioctls) return -ENOMEM;
+               if (!additional_ioctls)
+                       return -ENOMEM;
+               memset(additional_ioctls, 0, PAGE_SIZE);
        }
        for (i = 0; i < PAGE_SIZE/sizeof(struct ioctl_trans); i++)
                if (!additional_ioctls[i].cmd)
@@ -3773,7+3778,6 @@ asmlinkage int sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
        int (*handler)(unsigned int, unsigned int, unsigned long, struct file * filp);
        struct ioctl_trans *t;
 
-       lock_kernel();
        filp = fget(fd);
        if(!filp)
                goto out2;
@@ -3801,6+3805,5 @@ asmlinkage int sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
 out:
        fput(filp);
 out2:
-       unlock_kernel();
        return error;
 }
index 12925b1..c7f4905 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: irq.c,v 1.89 2000/06/30 10:18:38 davem Exp $
+/* $Id: irq.c,v 1.90 2000/08/01 00:28:33 davem Exp $
  * irq.c: UltraSparc IRQ handling/init/registry.
  *
  * Copyright (C) 1997  David S. Miller  (davem@caip.rutgers.edu)
@@ -548,13+548,7 @@ out:
        restore_flags(flags);
 }
 
-/* Only uniprocessor needs this IRQ/BH locking depth, on SMP it
- * lives in the brlock table for cache reasons.
- */
-#ifndef CONFIG_SMP
-unsigned int __local_irq_count;
-unsigned int __local_bh_count;
-#else
+#ifdef CONFIG_SMP
 
 /* Who has global_irq_lock. */
 unsigned char global_irq_holder = NO_PROC_ID;
@@ -571,7+565,7 @@ static void show(char * str)
        printk("]\nbh:   %d [ ",
               (spin_is_locked(&global_bh_lock) ? 1 : 0));
        for (i = 0; i < smp_num_cpus; i++)
-               printk("%u ", cpu_data[i].bh_count);
+               printk("%u ", local_bh_count(i));
        printk("]\n");
 }
 
@@ -768,10+762,12 @@ void handler_irq(int irq, struct pt_regs *regs)
 
                nbp = __bucket(bp->irq_chain);
                if ((flags & IBF_ACTIVE) != 0) {
+#ifdef CONFIG_PCI
                        if ((flags & IBF_DMA_SYNC) != 0) {
                                upa_readl(dma_sync_reg_table[bp->synctab_ent]);
                                upa_readq(pci_dma_wsync);
                        }
+#endif
                        if ((flags & IBF_MULTI) == 0) {
                                struct irqaction *ap = bp->irq_info;
                                ap->handler(__irq(bp), ap->dev_id, regs);
index 2d5d814..5784201 100644 (file)
@@ -1,4+1,4 @@
-/*  $Id: process.c,v 1.109 2000/07/11 01:38:57 davem Exp $
+/*  $Id: process.c,v 1.110 2000/07/28 09:43:39 davem Exp $
  *  arch/sparc64/kernel/process.c
  *
  *  Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -524,7+524,7 @@ void synchronize_user_stack(void)
        }
 }
 
-void fault_in_user_windows(struct pt_regs *regs)
+void fault_in_user_windows(void)
 {
        struct thread_struct *t = &current->thread;
        unsigned long window;
index 1c9b6ac..3295938 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: rtrap.S,v 1.49 2000/03/29 09:55:31 davem Exp $
+/* $Id: rtrap.S,v 1.51 2000/07/28 09:43:39 davem Exp $
  * rtrap.S: Preparing for return from trap on Sparc V9.
  *
  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -40,8+40,9 @@ __handle_preemption:
 __handle_user_windows:
                wrpr                    %g0, RTRAP_PSTATE, %pstate
                call                    fault_in_user_windows
-                add                    %sp, STACK_BIAS + REGWIN_SZ, %g0
-               ba,a,pt                 %xcc, __handle_user_windows_continue
+                nop
+               ba,pt                   %xcc, __handle_user_windows_continue
+                nop
 __handle_perfctrs:
                /* Don't forget to preserve user window invariants. */
                wrpr                    %g0, RTRAP_PSTATE, %pstate
@@ -54,9+55,9 @@ __handle_perfctrs:
                wrpr                    %g0, RTRAP_PSTATE, %pstate
 
                call                    fault_in_user_windows
-                add                    %sp, STACK_BIAS + REGWIN_SZ, %o0
+                nop
                ba,pt                   %xcc, __handle_perfctrs_continue
-                nop                    
+                nop
 __handle_userfpu:
                rd                      %fprs, %l5
                andcc                   %l5, FPRS_FEF, %g0
@@ -69,18+70,25 @@ __handle_signal:
                mov                     %l6, %o3
                call                    do_signal
                 add                    %sp, STACK_BIAS + REGWIN_SZ, %o1
+               clr                     %l6
+
+               /* Signal delivery can modify pt_regs tstate, so we must
+                * reload it.
+                */
+               ldx                     [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
+               sethi                   %hi(0xf << 20), %l4
+               and                     %l1, %l4, %l4
                ba,pt                   %xcc, __handle_signal_continue
-                clr                    %l6
-               nop
+                andn                   %l1, %l4, %l1
 
                .align                  64
                .globl                  rtrap_clr_l6, rtrap
 rtrap_clr_l6:  clr                     %l6
 rtrap:         lduw                    [%g6 + AOFF_task_processor], %l0
-               sethi                   %hi(softirq_state), %l2
-               or                      %l2, %lo(softirq_state), %l2
+               sethi                   %hi(irq_stat), %l2      ! &softirq_active
+               or                      %l2, %lo(irq_stat), %l2 ! &softirq_active
                sllx                    %l0, 6, %l0
-               ldx                     [%l2 + %l0], %l1
+               ldx                     [%l2 + %l0], %l1        ! softirq_active + softirq_mask
                srlx                    %l1, 32, %l2
                andcc                   %l1, %l2, %g0
 
index c666dc4..d1e7e42 100644 (file)
@@ -1,4+1,4 @@
-/*  $Id: signal.c,v 1.52 2000/07/07 04:25:17 davem Exp $
+/*  $Id: signal.c,v 1.53 2000/07/30 23:12:24 davem Exp $
  *  arch/sparc64/kernel/signal.c
  *
  *  Copyright (C) 1991, 1992  Linus Torvalds
@@ -166,7+166,6 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs)
 
        return;
 do_sigsegv:
-       lock_kernel();
        do_exit(SIGSEGV);
 }
 
@@ -254,7+253,6 @@ asmlinkage void sparc64_get_context(struct pt_regs *regs)
 
        return;
 do_sigsegv:
-       lock_kernel();
        do_exit(SIGSEGV);
 }
 
@@ -566,10+564,8 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
        return;
 
 sigill:
-       lock_kernel();
        do_exit(SIGILL);
 sigsegv:
-       lock_kernel();
        do_exit(SIGSEGV);
 }
 
index f99b966..96f8624 100644 (file)
@@ -87,7+87,6 @@ void __init smp_store_cpu_info(int id)
 {
        int i;
 
-       cpu_data[id].bh_count                   = 0;
        /* multiplier and counter set by
           smp_setup_percpu_timer()  */
        cpu_data[id].udelay_val                 = loops_per_sec;
index eccc788..4a79b76 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: sparc64_ksyms.c,v 1.86 2000/06/30 10:18:38 davem Exp $
+/* $Id: sparc64_ksyms.c,v 1.89 2000/07/28 12:15:02 davem Exp $
  * arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -65,7+65,6 @@ extern int __strncmp(const char *, const char *, __kernel_size_t);
 extern __kernel_size_t __strlen(const char *);
 extern __kernel_size_t strlen(const char *);
 extern char saved_command_line[];
-extern char *getname32(u32 name);
 extern void linux_sparc_syscall(void);
 extern void rtrap(void);
 extern void show_regs(struct pt_regs *);
@@ -84,6+83,7 @@ extern long sparc32_open(const char * filename, int flags, int mode);
 extern int register_ioctl32_conversion(unsigned int cmd, int (*handler)(unsigned int, unsigned int, unsigned long, struct file *));
 extern int unregister_ioctl32_conversion(unsigned int cmd);
 extern int io_remap_page_range(unsigned long from, unsigned long offset, unsigned long size, pgprot_t prot, int space);
+extern void flush_dcache_page(void *addr);
                 
 extern int __ashrdi3(int, int);
 
@@ -156,9+156,6 @@ EXPORT_SYMBOL(_do_write_lock);
 EXPORT_SYMBOL(_do_write_unlock);
 #endif
 
-#else
-EXPORT_SYMBOL(__local_bh_count);
-EXPORT_SYMBOL(__local_irq_count);
 #endif
 
 /* rw semaphores */
@@ -183,6+180,8 @@ EXPORT_SYMBOL(disable_irq);
 
 EXPORT_SYMBOL_PRIVATE(flushw_user);
 
+EXPORT_SYMBOL(flush_dcache_page);
+
 EXPORT_SYMBOL(mstk48t02_regs);
 EXPORT_SYMBOL(request_fast_irq);
 #if CONFIG_SBUS
@@ -279,7+278,6 @@ EXPORT_SYMBOL(strtok);
 EXPORT_SYMBOL(strstr);
 
 #ifdef CONFIG_SOLARIS_EMUL_MODULE
-EXPORT_SYMBOL(getname32);
 EXPORT_SYMBOL(linux_sparc_syscall);
 EXPORT_SYMBOL(rtrap);
 EXPORT_SYMBOL(show_regs);
index d32ea68..bcfa77a 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: sunos_ioctl32.c,v 1.10 1998/08/15 20:42:46 davem Exp $
+/* $Id: sunos_ioctl32.c,v 1.11 2000/07/30 23:12:24 davem Exp $
  * sunos_ioctl32.c: SunOS ioctl compatability on sparc64.
  *
  * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
@@ -98,7+98,6 @@ asmlinkage int sunos_ioctl (int fd, u32 cmd, u32 arg)
 {
        int ret = -EBADF;
 
-       lock_kernel();
        if(fd >= SUNOS_NR_OPEN)
                goto out;
        if(!fcheck(fd))
@@ -281,6+280,5 @@ asmlinkage int sunos_ioctl (int fd, u32 cmd, u32 arg)
        /* so stupid... */
        ret = (ret == -EINVAL ? -EOPNOTSUPP : ret);
 out:
-       unlock_kernel();
        return ret;
 }
index 859d0c7..e869af4 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: sys_sparc.c,v 1.44 2000/07/10 20:57:35 davem Exp $
+/* $Id: sys_sparc.c,v 1.45 2000/07/30 23:12:24 davem Exp $
  * linux/arch/sparc64/kernel/sys_sparc.c
  *
  * This file contains various random system calls that
@@ -299,13+299,14 @@ c_sys_nis_syscall (struct pt_regs *regs)
        static int count=0;
        
        /* Don't make the system unusable, if someone goes stuck */
-       if (count++ > 5) return -ENOSYS;
-       lock_kernel();
+       if (count++ > 5)
+               return -ENOSYS;
+
        printk ("Unimplemented SPARC system call %ld\n",regs->u_regs[1]);
 #ifdef DEBUG_UNIMP_SYSCALL     
        show_regs (regs);
 #endif
-       unlock_kernel();
+
        return -ENOSYS;
 }
 
@@ -316,7+317,6 @@ sparc_breakpoint (struct pt_regs *regs)
 {
        siginfo_t info;
 
-       lock_kernel();
 #ifdef DEBUG_SPARC_BREAKPOINT
         printk ("TRAP: Entering kernel PC=%lx, nPC=%lx\n", regs->tpc, regs->tnpc);
 #endif
@@ -329,7+329,6 @@ sparc_breakpoint (struct pt_regs *regs)
 #ifdef DEBUG_SPARC_BREAKPOINT
        printk ("TRAP: Returning to space: PC=%lx nPC=%lx\n", regs->tpc, regs->tnpc);
 #endif
-       unlock_kernel();
 }
 
 extern void check_pending(int signum);
@@ -364,7+363,7 @@ asmlinkage int sys_aplib(void)
 asmlinkage int solaris_syscall(struct pt_regs *regs)
 {
        static int count = 0;
-       lock_kernel();
+
        regs->tpc = regs->tnpc;
        regs->tnpc += 4;
        if(++count <= 5) {
@@ -372,7+371,7 @@ asmlinkage int solaris_syscall(struct pt_regs *regs)
                show_regs (regs);
        }
        send_sig(SIGSEGV, current, 1);
-       unlock_kernel();
+
        return -ENOSYS;
 }
 
@@ -380,13+379,13 @@ asmlinkage int solaris_syscall(struct pt_regs *regs)
 asmlinkage int sunos_syscall(struct pt_regs *regs)
 {
        static int count = 0;
-       lock_kernel();
+
        regs->tpc = regs->tnpc;
        regs->tnpc += 4;
        if(++count <= 20)
                printk ("SunOS binary emulation not compiled in\n");
        force_sig(SIGSEGV, current);
-       unlock_kernel();
+
        return -ENOSYS;
 }
 #endif
@@ -408,32+407,37 @@ asmlinkage int sys_utrap_install(utrap_entry_t type, utrap_handler_t new_p,
                        put_user_ret(NULL, old_d, -EFAULT);
                return 0;
        }
-       lock_kernel();
        if (!current->thread.utraps) {
-               current->thread.utraps = kmalloc((UT_TRAP_INSTRUCTION_31+1)*sizeof(long), GFP_KERNEL);
+               current->thread.utraps =
+                       kmalloc((UT_TRAP_INSTRUCTION_31+1)*sizeof(long), GFP_KERNEL);
                if (!current->thread.utraps) return -ENOMEM;
                current->thread.utraps[0] = 1;
                memset(current->thread.utraps+1, 0, UT_TRAP_INSTRUCTION_31*sizeof(long));
        } else {
-               if ((utrap_handler_t)current->thread.utraps[type] != new_p && current->thread.utraps[0] > 1) {
+               if ((utrap_handler_t)current->thread.utraps[type] != new_p &&
+                   current->thread.utraps[0] > 1) {
                        long *p = current->thread.utraps;
-                       
-                       current->thread.utraps = kmalloc((UT_TRAP_INSTRUCTION_31+1)*sizeof(long), GFP_KERNEL);
+
+                       current->thread.utraps =
+                               kmalloc((UT_TRAP_INSTRUCTION_31+1)*sizeof(long),
+                                       GFP_KERNEL);
                        if (!current->thread.utraps) {
                                current->thread.utraps = p;
                                return -ENOMEM;
                        }
                        p[0]--;
                        current->thread.utraps[0] = 1;
-                       memcpy(current->thread.utraps+1, p+1, UT_TRAP_INSTRUCTION_31*sizeof(long));
+                       memcpy(current->thread.utraps+1, p+1,
+                              UT_TRAP_INSTRUCTION_31*sizeof(long));
                }
        }
        if (old_p)
-               put_user_ret((utrap_handler_t)(current->thread.utraps[type]), old_p, -EFAULT);
+               put_user_ret((utrap_handler_t)(current->thread.utraps[type]),
+                            old_p, -EFAULT);
        if (old_d)
                put_user_ret(NULL, old_d, -EFAULT);
        current->thread.utraps[type] = (long)new_p;
-       unlock_kernel();
+
        return 0;
 }
 
index 89c1a90..7d8a71d 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: sys_sparc32.c,v 1.156 2000/07/13 10:59:13 davem Exp $
+/* $Id: sys_sparc32.c,v 1.158 2000/07/29 00:55:49 davem Exp $
  * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
  *
  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -253,45+253,6 @@ asmlinkage long sys32_getegid16(void)
        return high2lowgid(current->egid);
 }
 
-/* In order to reduce some races, while at the same time doing additional
- * checking and hopefully speeding things up, we copy filenames to the
- * kernel data space before using them..
- *
- * POSIX.1 2.4: an empty pathname is invalid (ENOENT).
- */
-static inline int do_getname32(const char *filename, char *page)
-{
-       int retval;
-
-       /* 32bit pointer will be always far below TASK_SIZE :)) */
-       retval = strncpy_from_user((char *)page, (char *)filename, PAGE_SIZE);
-       if (retval > 0) {
-               if (retval < PAGE_SIZE)
-                       return 0;
-               return -ENAMETOOLONG;
-       } else if (!retval)
-               retval = -ENOENT;
-       return retval;
-}
-
-char * getname32(const char *filename)
-{
-       char *tmp, *result;
-
-       result = ERR_PTR(-ENOMEM);
-       tmp = __getname();
-       if (tmp)  {
-               int retval = do_getname32(filename, tmp);
-
-               result = tmp;
-               if (retval < 0) {
-                       putname(tmp);
-                       result = ERR_PTR(retval);
-               }
-       }
-       return result;
-}
-
 /* 32-bit timeval and related flotsam.  */
 
 struct timeval32
@@ -799,7+760,6 @@ asmlinkage int sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u
 {
        int version, err;
 
-       lock_kernel();
        version = call >> 16; /* hack for backward compatibility */
        call &= 0xffff;
 
@@ -861,7+821,6 @@ asmlinkage int sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u
        err = -EINVAL;
 
 out:
-       unlock_kernel();
        return err;
 }
 
@@ -953,7+912,7 @@ asmlinkage int sys32_quotactl(int cmd, const char *special, int id, unsigned lon
                return sys_quotactl(cmd, special,
                                    id, (caddr_t)addr);
        }
-       spec = getname32 (special);
+       spec = getname (special);
        err = PTR_ERR(spec);
        if (IS_ERR(spec)) return err;
        old_fs = get_fs ();
@@ -998,7+957,7 @@ asmlinkage int sys32_statfs(const char * path, struct statfs32 *buf)
        mm_segment_t old_fs = get_fs();
        char *pth;
        
-       pth = getname32 (path);
+       pth = getname (path);
        ret = PTR_ERR(pth);
        if (!IS_ERR(pth)) {
                set_fs (KERNEL_DS);
@@ -1064,7+1023,7 @@ asmlinkage int sys32_utime(char * filename, struct utimbuf32 *times)
        if (get_user (t.actime, &times->actime) ||
            __get_user (t.modtime, &times->modtime))
                return -EFAULT;
-       filenam = getname32 (filename);
+       filenam = getname (filename);
        ret = PTR_ERR(filenam);
        if (!IS_ERR(filenam)) {
                old_fs = get_fs();
@@ -1572,6+1531,16 @@ static int cp_new_stat32(struct inode *inode, struct stat32 *statbuf)
        return err;
 }
 
+/* Perhaps this belongs in fs.h or similar. -DaveM */
+static __inline__ int
+do_revalidate(struct dentry *dentry)
+{
+       struct inode * inode = dentry->d_inode;
+       if (inode->i_op && inode->i_op->revalidate)
+               return inode->i_op->revalidate(dentry);
+       return 0;
+}
+
 asmlinkage int sys32_newstat(char * filename, struct stat32 *statbuf)
 {
        struct nameidata nd;
@@ -1579,16+1548,9 @@ asmlinkage int sys32_newstat(char * filename, struct stat32 *statbuf)
 
        error = user_path_walk(filename, &nd);
        if (!error) {
-               struct inode *inode = nd.dentry->d_inode;
-
-               if (inode->i_op &&
-                   inode->i_op->revalidate)
-                       error = inode->i_op->revalidate(nd.dentry);
-               else
-                       error = 0;
+               error = do_revalidate(nd.dentry);
                if (!error)
-                       error = cp_new_stat32(inode, statbuf);
-
+                       error = cp_new_stat32(nd.dentry->d_inode, statbuf);
                path_release(&nd);
        }
        return error;
@@ -1601,15+1563,9 @@ asmlinkage int sys32_newlstat(char * filename, struct stat32 *statbuf)
 
        error = user_path_walk_link(filename, &nd);
        if (!error) {
-               struct inode *inode = nd.dentry->d_inode;
-
-               if (inode->i_op &&
-                   inode->i_op->revalidate)
-                       error = inode->i_op->revalidate(nd.dentry);
-               else
-                       error = 0;
+               error = do_revalidate(nd.dentry);
                if (!error)
-                       error = cp_new_stat32(inode, statbuf);
+                       error = cp_new_stat32(nd.dentry->d_inode, statbuf);
 
                path_release(&nd);
        }
@@ -1623,16+1579,11 @@ asmlinkage int sys32_newfstat(unsigned int fd, struct stat32 *statbuf)
 
        f = fget(fd);
        if (f) {
-               struct inode *inode = f->f_dentry->d_inode;
+               struct dentry * dentry = f->f_dentry;
 
-               if (inode->i_op &&
-                   inode->i_op->revalidate)
-                       err = inode->i_op->revalidate(f->f_dentry);
-               else
-                       err = 0;
+               err = do_revalidate(dentry);
                if (!err)
-                       err = cp_new_stat32(inode, statbuf);
-
+                       err = cp_new_stat32(dentry->d_inode, statbuf);
                fput(f);
        }
        return err;
@@ -1738,7+1689,6 @@ asmlinkage int sys32_mount(char *dev_name, char *dir_name, char *type, unsigned
 
        is_smb = is_ncp = 0;
 
-       lock_kernel();
        err = copy_mount_stuff_to_kernel((const void *)type, &type_page);
        if (err)
                goto out;
@@ -1764,16+1714,20 @@ asmlinkage int sys32_mount(char *dev_name, char *dir_name, char *type, unsigned
                goto dev_out;
 
        if (!is_smb && !is_ncp) {
+               lock_kernel();
                err = do_mount((char*)dev_page, (char*)dir_page,
                                (char*)type_page, new_flags, (char*)data_page);
+               unlock_kernel();
        } else {
                if (is_ncp)
                        do_ncp_super_data_conv((void *)data_page);
                else
                        do_smb_super_data_conv((void *)data_page);
 
+               lock_kernel();
                err = do_mount((char*)dev_page, (char*)dir_page,
                                (char*)type_page, new_flags, (char*)data_page);
+               unlock_kernel();
        }
        free_page(dir_page);
 
@@ -1787,7+1741,6 @@ type_out:
        free_page(type_page);
 
 out:
-       unlock_kernel();
        return err;
 }
 
@@ -2234,34+2187,9 @@ asmlinkage int sys32_getrusage(int who, struct rusage32 *ru)
                                           24 for IPv6,
                                           about 80 for AX.25 */
 
-/* XXX These as well... */
-extern __inline__ struct socket *socki_lookup(struct inode *inode)
-{
-       return &inode->u.socket_i;
-}
-
-extern __inline__ struct socket *sockfd_lookup(int fd, int *err)
-{
-       struct file *file;
-       struct inode *inode;
-
-       if (!(file = fget(fd)))
-       {
-               *err = -EBADF;
-               return NULL;
-       }
-
-       inode = file->f_dentry->d_inode;
-       if (!inode || !inode->i_sock || !socki_lookup(inode))
-       {
-               *err = -ENOTSOCK;
-               fput(file);
-               return NULL;
-       }
-
-       return socki_lookup(inode);
-}
+extern struct socket *sockfd_lookup(int fd, int *err);
 
+/* XXX This as well... */
 extern __inline__ void sockfd_put(struct socket *sock)
 {
        fput(sock->file);
@@ -2678,7+2606,6 @@ asmlinkage int sys32_sendmsg(int fd, struct msghdr32 *user_msg, unsigned user_fl
        }
        kern_msg.msg_flags = user_flags;
 
-       lock_kernel();
        sock = sockfd_lookup(fd, &err);
        if (sock != NULL) {
                if (sock->file->f_flags & O_NONBLOCK)
@@ -2686,7+2613,6 @@ asmlinkage int sys32_sendmsg(int fd, struct msghdr32 *user_msg, unsigned user_fl
                err = sock_sendmsg(sock, &kern_msg, total_len);
                sockfd_put(sock);
        }
-       unlock_kernel();
 
        /* N.B. Use kfree here, as kern_msg.msg_controllen might change? */
        if(ctl_buf != ctl)
@@ -2725,7+2651,6 @@ asmlinkage int sys32_recvmsg(int fd, struct msghdr32 *user_msg, unsigned int use
        cmsg_ptr = (unsigned long) kern_msg.msg_control;
        kern_msg.msg_flags = 0;
 
-       lock_kernel();
        sock = sockfd_lookup(fd, &err);
        if (sock != NULL) {
                struct scm_cookie scm;
@@ -2762,7+2687,6 @@ asmlinkage int sys32_recvmsg(int fd, struct msghdr32 *user_msg, unsigned int use
                }
                sockfd_put(sock);
        }
-       unlock_kernel();
 
        if(uaddr != NULL && err >= 0)
                err = move_addr_to_user(addr, kern_msg.msg_namelen, uaddr, uaddr_len);
@@ -3084,7+3008,7 @@ asmlinkage int sparc32_execve(struct pt_regs *regs)
         if((u32)regs->u_regs[UREG_G1] == 0)
                 base = 1;
 
-        filename = getname32((char *)AA(regs->u_regs[base + UREG_I0]));
+        filename = getname((char *)AA(regs->u_regs[base + UREG_I0]));
        error = PTR_ERR(filename);
         if(IS_ERR(filename))
                 goto out;
@@ -3926,7+3850,7 @@ asmlinkage int sys32_utimes(char *filename, struct timeval32 *tvs)
        mm_segment_t old_fs;
        int ret;
 
-       kfilename = getname32(filename);
+       kfilename = getname(filename);
        ret = PTR_ERR(kfilename);
        if (!IS_ERR(kfilename)) {
                if (tvs) {
index 3f43e99..9015a2f 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: sys_sunos32.c,v 1.52 2000/07/10 20:57:35 davem Exp $
+/* $Id: sys_sunos32.c,v 1.53 2000/07/30 23:12:24 davem Exp $
  * sys_sunos32.c: SunOS binary compatability layer on sparc64.
  *
  * Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -179,21+179,18 @@ asmlinkage u32 sunos_sbrk(int increment)
        int error, oldbrk;
 
        /* This should do it hopefully... */
-       lock_kernel();
        oldbrk = (int)current->mm->brk;
        error = sunos_brk(((int) current->mm->brk) + increment);
        if(!error)
                error = oldbrk;
-       unlock_kernel();
        return error;
 }
 
 asmlinkage u32 sunos_sstk(int increment)
 {
-       lock_kernel();
        printk("%s: Call to sunos_sstk(increment<%d>) is unsupported\n",
               current->comm, increment);
-       unlock_kernel();
+
        return (u32)-1;
 }
 
@@ -213,12+210,13 @@ static char *vstrings[] = {
 
 asmlinkage void sunos_vadvise(u32 strategy)
 {
+       static int count = 0;
+
        /* I wanna see who uses this... */
-       lock_kernel();
-       printk("%s: Advises us to use %s paging strategy\n",
-              current->comm,
-              strategy <= 3 ? vstrings[strategy] : "BOGUS");
-       unlock_kernel();
+       if (count++ < 5)
+               printk("%s: Advises us to use %s paging strategy\n",
+                      current->comm,
+                      strategy <= 3 ? vstrings[strategy] : "BOGUS");
 }
 
 /* This just wants the soft limit (ie. rlim_cur element) of the RLIMIT_NOFILE
@@ -457,7+455,6 @@ asmlinkage int sunos_nosys(void)
        siginfo_t info;
        static int cnt;
 
-       lock_kernel();
        regs = current->thread.kregs;
        info.si_signo = SIGSYS;
        info.si_errno = 0;
@@ -470,7+467,6 @@ asmlinkage int sunos_nosys(void)
                       (int) regs->u_regs[UREG_G1]);
                show_regs(regs);
        }
-       unlock_kernel();
        return -ENOSYS;
 }
 
@@ -726,7+722,7 @@ sunos_mount(char *type, char *dir, int flags, void *data)
 
        if (!capable (CAP_SYS_ADMIN))
                return -EPERM;
-       lock_kernel();
+
        /* We don't handle the integer fs type */
        if ((flags & SMNT_NEWTYPE) == 0)
                goto out;
@@ -772,7+768,9 @@ sunos_mount(char *type, char *dir, int flags, void *data)
        ret = PTR_ERR(dev_fname);
        if (IS_ERR(dev_fname))
                goto out2;
+       lock_kernel();
        ret = do_mount(dev_fname, dir_page, type_page, linux_flags, NULL);
+       unlock_kernel();
        if (dev_fname)
                putname(dev_fname);
 out2:
@@ -780,7+778,6 @@ out2:
 out1:
        putname(dir_page);
 out:
-       unlock_kernel();
        return ret;
 }
 
@@ -818,12+815,7 @@ asmlinkage int sunos_wait4(__kernel_pid_t32 pid, u32 stat_addr, int options, u32
 extern int kill_pg(int, int, int);
 asmlinkage int sunos_killpg(int pgrp, int sig)
 {
-       int ret;
-
-       lock_kernel();
-       ret = kill_pg(pgrp, sig, 0);
-       unlock_kernel();
-       return ret;
+       return kill_pg(pgrp, sig, 0);
 }
 
 asmlinkage int sunos_audit(void)
@@ -836,9+828,8 @@ extern asmlinkage u32 sunos_gethostid(void)
 {
        u32 ret;
 
-       lock_kernel();
        ret = (((u32)idprom->id_machtype << 24) | ((u32)idprom->id_sernum));
-       unlock_kernel();
+
        return ret;
 }
 
index 7b5d326..de4968a 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: traps.c,v 1.66 2000/05/09 17:40:14 davem Exp $
+/* $Id: traps.c,v 1.67 2000/07/30 23:12:24 davem Exp $
  * arch/sparc64/kernel/traps.c
  *
  * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu)
@@ -255,7+255,6 @@ void bad_trap (struct pt_regs *regs, long lvl)
 {
        siginfo_t info;
 
-       lock_kernel ();
        if (lvl < 0x100) {
                char buffer[24];
                
@@ -270,17+269,14 @@ void bad_trap (struct pt_regs *regs, long lvl)
        info.si_addr = (void *)regs->tpc;
        info.si_trapno = lvl - 0x100;
        force_sig_info(SIGILL, &info, current);
-       unlock_kernel ();
 }
 
 void bad_trap_tl1 (struct pt_regs *regs, long lvl)
 {
        char buffer[24];
        
-       lock_kernel();
        sprintf (buffer, "Bad trap %lx at tl>0", lvl);
        die_if_kernel (buffer, regs);
-       unlock_kernel();
 }
 
 void instruction_access_exception (struct pt_regs *regs,
@@ -288,7+284,6 @@ void instruction_access_exception (struct pt_regs *regs,
 {
        siginfo_t info;
 
-       lock_kernel();
        if (regs->tstate & TSTATE_PRIV) {
 #if 1
                printk("instruction_access_exception: Shit SFSR[%016lx] SFAR[%016lx], going.\n",
@@ -302,7+297,6 @@ void instruction_access_exception (struct pt_regs *regs,
        info.si_addr = (void *)regs->tpc;
        info.si_trapno = 0;
        force_sig_info(SIGSEGV, &info, current);
-       unlock_kernel();
 }
 
 void data_access_exception (struct pt_regs *regs,
@@ -343,9+337,7 @@ void data_access_exception (struct pt_regs *regs,
        info.si_code = SEGV_MAPERR;
        info.si_addr = (void *)sfar;
        info.si_trapno = 0;
-       lock_kernel();
        force_sig_info(SIGSEGV, &info, current);
-       unlock_kernel();
 }
 
 #ifdef CONFIG_PCI
@@ -389,9+381,7 @@ void do_iae(struct pt_regs *regs)
        info.si_code = BUS_OBJERR;
        info.si_addr = (void *)0;
        info.si_trapno = 0;
-       lock_kernel();
        force_sig_info(SIGBUS, &info, current);
-       unlock_kernel();
 }
 
 void do_dae(struct pt_regs *regs)
@@ -692,7+682,6 @@ void die_if_kernel(char *str, struct pt_regs *regs)
        smp_report_regs();
 #endif
                                                        
-       lock_kernel(); /* Or else! */
        if(regs->tstate & TSTATE_PRIV)
                do_exit(SIGKILL);
        do_exit(SIGSEGV);
index 090eb96..3cf5b68 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: fs.c,v 1.21 2000/07/10 20:57:35 davem Exp $
+/* $Id: fs.c,v 1.22 2000/07/28 12:15:02 davem Exp $
  * fs.c: fs related syscall emulation for Solaris
  *
  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
 
 #include "conv.h"
 
-extern char * getname32(u32 filename);
 #define R4_DEV(DEV) ((DEV & 0xff) | ((DEV & 0xff00) << 10))
 #define R4_MAJOR(DEV) (((DEV) >> 18) & 0x3fff)
 #define R4_MINOR(DEV) ((DEV) & 0x3ffff)
@@ -136,7+134,7 @@ asmlinkage int solaris_stat(u32 filename, u32 statbuf)
        int (*sys_newstat)(char *,struct stat *) = 
                (int (*)(char *,struct stat *))SYS(stat);
        
-       filenam = getname32 (filename);
+       filenam = getname ((char *)A(filename));
        ret = PTR_ERR(filenam);
        if (!IS_ERR(filenam)) {
                set_fs (KERNEL_DS);
@@ -164,7+162,7 @@ asmlinkage int solaris_stat64(u32 filename, u32 statbuf)
        int (*sys_newstat)(char *,struct stat *) = 
                (int (*)(char *,struct stat *))SYS(stat);
        
-       filenam = getname32 (filename);
+       filenam = getname ((char *)A(filename));
        ret = PTR_ERR(filenam);
        if (!IS_ERR(filenam)) {
                set_fs (KERNEL_DS);
@@ -186,7+184,7 @@ asmlinkage int solaris_lstat(u32 filename, u32 statbuf)
        int (*sys_newlstat)(char *,struct stat *) = 
                (int (*)(char *,struct stat *))SYS(lstat);
        
-       filenam = getname32 (filename);
+       filenam = getname ((char *)A(filename));
        ret = PTR_ERR(filenam);
        if (!IS_ERR(filenam)) {
                set_fs (KERNEL_DS);
@@ -213,7+211,7 @@ asmlinkage int solaris_lstat64(u32 filename, u32 statbuf)
        int (*sys_newlstat)(char *,struct stat *) = 
                (int (*)(char *,struct stat *))SYS(lstat);
        
-       filenam = getname32 (filename);
+       filenam = getname ((char *)A(filename));
        ret = PTR_ERR(filenam);
        if (!IS_ERR(filenam)) {
                set_fs (KERNEL_DS);
index 18d73e6..0e899da 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: ioctl.c,v 1.14 1999/09/22 09:28:50 davem Exp $
+/* $Id: ioctl.c,v 1.15 2000/07/28 12:15:02 davem Exp $
  * ioctl.c: Solaris ioctl emulation.
  *
  * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
 #include "conv.h"
 #include "socksys.h"
 
-extern char *getname32(u32 filename);
-#define putname32 putname
-
 extern asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, 
        unsigned long arg);
 extern asmlinkage int sys32_ioctl(unsigned int fd, unsigned int cmd,
@@ -486,7+483,7 @@ static inline int solaris_S(struct file *filp, unsigned int fd, unsigned int cmd
                return -ENOSYS;
        case 2: /* I_PUSH */
         {
-               p = getname32 (arg);
+               p = getname ((char *)A(arg));
                if (IS_ERR (p))
                        return PTR_ERR(p);
                 ret = -EINVAL;
@@ -503,7+500,7 @@ static inline int solaris_S(struct file *filp, unsigned int fd, unsigned int cmd
                                 break;
                         }
                 }
-               putname32 (p);
+               putname (p);
                return ret;
         }
        case 3: /* I_POP */
@@ -546,7+543,7 @@ static inline int solaris_S(struct file *filp, unsigned int fd, unsigned int cmd
        case 11: /* I_FIND */
         {
                 int i;
-               p = getname32 (arg);
+               p = getname ((char *)A(arg));
                if (IS_ERR (p))
                        return PTR_ERR(p);
                 ret = 0;
@@ -557,7+554,7 @@ static inline int solaris_S(struct file *filp, unsigned int fd, unsigned int cmd
                                 break;
                         } 
                 }
-               putname32 (p);
+               putname (p);
                return ret;
         }
        case 19: /* I_SWROPT */
index 946b20f..3ef9c94 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: timod.c,v 1.9 2000/07/12 23:21:02 davem Exp $
+/* $Id: timod.c,v 1.10 2000/07/28 12:15:02 davem Exp $
  * timod.c: timod emulation.
  *
  * Copyright (C) 1998 Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)
 #include "conv.h"
 #include "socksys.h"
 
-extern char *getname32(u32 filename);
-#define putname32 putname
-
 extern asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, 
        unsigned long arg);
 extern asmlinkage int sys32_ioctl(unsigned int fd, unsigned int cmd,
index f41c3d4..2ac9116 100644 (file)
@@ -259,7+259,7 @@ endmenu
 
 tristate '/dev/agpgart (AGP Support)' CONFIG_AGP $CONFIG_DRM_AGP
 if [ "$CONFIG_AGP" != "n" ]; then
-   bool '  Intel 440LX/BX/GX support' CONFIG_AGP_INTEL
+   bool '  Intel 440LX/BX/GX 840 support' CONFIG_AGP_INTEL
    bool '  Intel I810/I810 DC100/I810e support' CONFIG_AGP_I810
    bool '  VIA chipset support' CONFIG_AGP_VIA
    bool '  AMD Irongate support' CONFIG_AGP_AMD
index dcc8176..573419a 100644 (file)
@@ -2114,6+2114,12 @@ static struct {
 #endif /* CONFIG_AGP_SIS */
 
 #ifdef CONFIG_AGP_VIA
+       { PCI_DEVICE_ID_VIA_8371_0,
+               PCI_VENDOR_ID_VIA,
+               VIA_APOLLO_SUPER,
+               "Via",
+               "Apollo Super",
+               via_generic_setup },
        { PCI_DEVICE_ID_VIA_8501_0,
                PCI_VENDOR_ID_VIA,
                VIA_MVP4,
@@ -2183,16+2189,15 @@ static int __init agp_lookup_host_bridge (struct pci_dev *pdev)
         * there is a 'generic' bridge entry for this vendor */
        if (agp_try_unsupported && agp_bridge_info[i].device_id == 0) {
                printk(KERN_WARNING PFX "Trying generic %s routines"
-                      " for device id: %x\n",
+                      " for device id: %04x\n",
                       agp_bridge_info[i].vendor_name, pdev->device);
                agp_bridge.type = agp_bridge_info[i].chipset;
                return agp_bridge_info[i].chipset_setup (pdev);
        }
 
-       printk(KERN_ERR PFX "Unsupported %s chipset,"
-              " you might want to try "
-              "agp_try_unsupported=1.\n",
-              agp_bridge_info[i].vendor_name);
+       printk(KERN_ERR PFX "Unsupported %s chipset (device id: %04x),"
+              " you might want to try agp_try_unsupported=1.\n",
+              agp_bridge_info[i].vendor_name, pdev->device);
        return -ENODEV;
 }
 
index 48a6aa5..e1e1cce 100644 (file)
@@ -289,20+289,21 @@ drm_agp_head_t *drm_agp_init(void)
                (*drm_agp.copy_info)(&head->agp_info);
                head->memory = NULL;
                switch (head->agp_info.chipset) {
-               case INTEL_GENERIC:  head->chipset = "Intel";          break;
-               case INTEL_LX:       head->chipset = "Intel 440LX";    break;
-               case INTEL_BX:       head->chipset = "Intel 440BX";    break;
-               case INTEL_GX:       head->chipset = "Intel 440GX";    break;
-               case INTEL_I810:     head->chipset = "Intel i810";     break;
-               case VIA_GENERIC:    head->chipset = "VIA";            break;
-               case VIA_VP3:        head->chipset = "VIA VP3";        break;
-               case VIA_MVP3:       head->chipset = "VIA MVP3";       break;
-               case VIA_APOLLO_PRO: head->chipset = "VIA Apollo Pro"; break;
-               case SIS_GENERIC:    head->chipset = "SiS";            break;
-               case AMD_GENERIC:    head->chipset = "AMD";            break;
-               case AMD_IRONGATE:   head->chipset = "AMD Irongate";   break;
-               case ALI_GENERIC:    head->chipset = "ALi";            break;
-               case ALI_M1541:      head->chipset = "ALi M1541";      break;
+               case INTEL_GENERIC:    head->chipset = "Intel";            break;
+               case INTEL_LX:         head->chipset = "Intel 440LX";      break;
+               case INTEL_BX:         head->chipset = "Intel 440BX";      break;
+               case INTEL_GX:         head->chipset = "Intel 440GX";      break;
+               case INTEL_I810:       head->chipset = "Intel i810";       break;
+               case VIA_GENERIC:      head->chipset = "VIA";              break;
+               case VIA_VP3:          head->chipset = "VIA VP3";          break;
+               case VIA_MVP3:         head->chipset = "VIA MVP3";         break;
+               case VIA_APOLLO_PRO:   head->chipset = "VIA Apollo Pro";   break;
+               case VIA_APOLLO_SUPER: head->chipset = "VIA Apollo Super"; break;
+               case SIS_GENERIC:      head->chipset = "SiS";              break;
+               case AMD_GENERIC:      head->chipset = "AMD";              break;
+               case AMD_IRONGATE:     head->chipset = "AMD Irongate";     break;
+               case ALI_GENERIC:      head->chipset = "ALi";              break;
+               case ALI_M1541:        head->chipset = "ALi M1541";        break;
                default:
                }
                DRM_INFO("AGP %d.%d on %s @ 0x%08lx %dMB\n",
index 3e5149c..e4783c8 100644 (file)
@@ -578,7+578,9 @@ extern void      drm_vm_close(struct vm_area_struct *vma);
 extern int          drm_mmap_dma(struct file *filp,
                                  struct vm_area_struct *vma);
 extern int          drm_mmap(struct file *filp, struct vm_area_struct *vma);
-
+extern struct vm_operations_struct drm_vm_ops;
+extern struct vm_operations_struct drm_vm_shm_ops;
+extern struct vm_operations_struct drm_vm_dma_ops;
 
                                /* Proc support (proc.c) */
 extern int          drm_proc_init(drm_device_t *dev);
index e7aaf56..661ac48 100644 (file)
@@ -31,6+31,9 @@ EXPORT_SYMBOL(drm_vm_open);
 EXPORT_SYMBOL(drm_vm_close);
 EXPORT_SYMBOL(drm_mmap_dma);
 EXPORT_SYMBOL(drm_mmap);
+EXPORT_SYMBOL(drm_vm_ops);
+EXPORT_SYMBOL(drm_vm_shm_ops);
+EXPORT_SYMBOL(drm_vm_dma_ops);
 
 /* Proc support (proc.c) */
 EXPORT_SYMBOL(drm_proc_init);
index 434dff8..a0bbf34 100644 (file)
@@ -300,32+300,26 @@ static struct video_device typhoon_radio =
 
 static int typhoon_get_info(char *buf, char **start, off_t offset, int len)
 {
+       char *out = buf;
+
        #ifdef MODULE
            #define MODULEPROCSTRING "Driver loaded as a module"
        #else
            #define MODULEPROCSTRING "Driver compiled into kernel"
        #endif
 
-        #define LIMIT (PAGE_SIZE - 80)
-
-       len = 0;
-       len += sprintf(buf + len, BANNER);
-       if (len > LIMIT) return len;
-       len += sprintf(buf + len, "Load type: " MODULEPROCSTRING "\n\n");
-       if (len > LIMIT) return len;
-       len += sprintf(buf + len, "frequency = %lu kHz\n",
+       /* output must be kept under PAGE_SIZE */
+       out += sprintf(out, BANNER);
+       out += sprintf(out, "Load type: " MODULEPROCSTRING "\n\n");
+       out += sprintf(out, "frequency = %lu kHz\n",
                typhoon_unit.curfreq >> 4);
-       if (len > LIMIT) return len;
-       len += sprintf(buf + len, "volume = %d\n", typhoon_unit.curvol);
-       if (len > LIMIT) return len;
-       len += sprintf(buf + len, "mute = %s\n", typhoon_unit.muted ?
+       out += sprintf(out, "volume = %d\n", typhoon_unit.curvol);
+       out += sprintf(out, "mute = %s\n", typhoon_unit.muted ?
                "on" : "off");
-       if (len > LIMIT) return len;
-       len += sprintf(buf + len, "iobase = 0x%x\n", typhoon_unit.iobase);
-       if (len > LIMIT) return len;
-       len += sprintf(buf + len, "mute frequency = %lu kHz\n",
+       out += sprintf(out, "iobase = 0x%x\n", typhoon_unit.iobase);
+       out += sprintf(out, "mute frequency = %lu kHz\n",
                typhoon_unit.mutefreq >> 4);
-       return len;
+       return out - buf;
 }
 
 #endif /* CONFIG_RADIO_TYPHOON_PROC_FS */
index 6813797..d9b8188 100644 (file)
@@ -1273,19+1273,19 @@ static int __init ltpc_setup(char *str)
 __setup("ltpc=", ltpc_setup);
 #endif /* MODULE */
 
-MODULE_PARM(debug, "i");
-MODULE_PARM(io, "i");
-MODULE_PARM(irq, "i");
-MODULE_PARM(dma, "i");
-
-#ifdef MODULE
-
 static struct net_device dev_ltpc = {
                "", 
                0, 0, 0, 0,
                0x0, 0,
                0, 0, 0, NULL, ltpc_probe };
 
+#ifdef MODULE
+MODULE_PARM(debug, "i");
+MODULE_PARM(io, "i");
+MODULE_PARM(irq, "i");
+MODULE_PARM(dma, "i");
+
+
 int __init init_module(void)
 {
        int err, result;
index 36b11f9..2819408 100644 (file)
@@ -385,7+385,6 @@ static dev_link_t *ray_attach(void)
 
     DEBUG(2,"ray_cs ray_attach calling ether_setup.)\n");
     ether_setup(dev);
-    strcpy(dev->name, local->node.dev_name);
     dev->init = &ray_dev_init;
     dev->open = &ray_open;
     dev->stop = &ray_dev_close;
@@ -581,6+580,8 @@ static void ray_config(dev_link_t *link)
         return;
     }
 
+    strcpy(local->node.dev_name, dev->name);
+
     link->state &= ~DEV_CONFIG_PENDING;
     printk(KERN_INFO "%s: RayLink, irq %d, hw_addr ",
        dev->name, dev->irq);
index a2da244..84dc280 100644 (file)
@@ -5,9+5,16 @@
  * PPPoE --- PPP over Ethernet (RFC 2516)
  *
  *
- * Version:    0.5.1
+ * Version:    0.6.0
  *
- * 030700 :     Fixed connect logic to allow for disconnect
+ * 030700 :     Fixed connect logic to allow for disconnect.
+ * 270700 :    Fixed potential SMP problems; we must protect against 
+ *             simultaneous invocation of ppp_input 
+ *             and ppp_unregister_channel.
+ *
+ *             Module reference count is decremented in the right spot now,
+ *             guards against sock_put not actually freeing the sk 
+ *             in pppoe_release.
  *
  * Author:     Michal Ostrowski <mostrows@styx.uwaterloo.ca>
  *
@@ -204,6+211,8 @@ static inline struct pppox_opt *get_item(unsigned long sid,
 
        read_lock_bh(&pppoe_hash_lock);
        po = __get_item(sid, addr);
+       if(po)
+               sock_hold(po->sk);
        read_unlock_bh(&pppoe_hash_lock);
 
        return po;
@@ -245,14+254,16 @@ static struct pppox_opt *find_on_dev(struct net_device *dev,
        struct pppox_opt *po;
        read_lock_bh(&pppoe_hash_lock);
        po = __find_on_dev(dev,start);
+       if(po)
+               sock_hold(po->sk);
        read_unlock_bh(&pppoe_hash_lock);
        return po;
 }
 
 /***************************************************************************
  *
- *  Handler for device events
- *  Certain device events require that sockets be unconnected
+ *  Handler for device events.
+ *  Certain device events require that sockets be unconnected.
  *
  **************************************************************************/
 static int pppoe_device_event(struct notifier_block *this,
@@ -274,20+285,14 @@ static int pppoe_device_event(struct notifier_block *this,
                        po = find_on_dev(dev, po);
                        if(!po)
                                break;
-
+                       
+                       lock_sock(po->sk);
                        if (po->sk->state & PPPOX_CONNECTED)
                                pppox_unbind_sock(po->sk);
 
-                       if (po->sk->state & PPPOX_CONNECTED) {
-                               lock_sock(po->sk);
-                               po->sk->shutdown = RCV_SHUTDOWN&SEND_SHUTDOWN;
-                               
-                               po->sk->state = PPPOX_DEAD;
-                               po->pppoe_dev = NULL;
+                       release_sock(po->sk);
+                       sock_put(po->sk);
 
-                               wake_up(po->sk->sleep);
-                               release_sock(po->sk);
-                       }
                } while (1);
 
                break;
@@ -310,31+315,15 @@ static struct notifier_block pppoe_notifier = {
 
 /************************************************************************
  *
- * Receive a PPPoE Session frame.
+ * Do the real work of receiving a PPPoE Session frame.
  *
  ***********************************************************************/
-static int pppoe_rcv(struct sk_buff *skb,
-                     struct net_device *dev,
-                     struct packet_type *pt)
-
-{
-       struct pppoe_hdr *ph = (struct pppoe_hdr *) skb->nh.raw;
-       struct pppox_opt *po;
-       struct sock *sk ;
-       
-       po = get_item((unsigned long) ph->sid, skb->mac.ethernet->h_source);
-
-       if(!po)
-               goto abort;
-
-       sk = po->sk;
-
-       if (!sk || !(sk->state & PPPOX_CONNECTED))
-               goto abort;
+int pppoe_rcv_core(struct sock *sk, struct sk_buff *skb){
+       struct pppox_opt  *po=sk->protinfo.pppox;
 
        if (sk->state & PPPOX_BOUND) {
                skb_pull(skb, sizeof(struct pppoe_hdr));
-
+               
                ppp_input(&po->chan, skb);
        } else if( sk->state & PPPOX_RELAY ){
                struct pppox_opt *relay_po;
@@ -342,28+331,88 @@ static int pppoe_rcv(struct sk_buff *skb,
                relay_po = get_item_by_addr( &po->pppoe_relay );
 
                if( relay_po == NULL  ||
-                   !( relay_po->sk->state & PPPOX_CONNECTED ) )
+                   !( relay_po->sk->state & PPPOX_CONNECTED ) ){
+                       sock_put(relay_po->sk);
                        goto abort;
-
+               }
+               
                skb_pull(skb, sizeof(struct pppoe_hdr));
-               if( !__pppoe_xmit( relay_po->sk , skb) )
+               if( !__pppoe_xmit( relay_po->sk , skb) ){
+                       sock_put(relay_po->sk);
                        goto abort;
+               }
 
        } else {
                sock_queue_rcv_skb(sk, skb);
        }
-
        return 1;
-
 abort:
-       kfree_skb(skb);
+       sock_put(sk);
+       return 0;
+
+}
+
+
+
+
+/************************************************************************
+ *
+ * Receive wrapper called in BH context.
+ *
+ ***********************************************************************/
+static int pppoe_rcv(struct sk_buff *skb,
+                     struct net_device *dev,
+                     struct packet_type *pt)
+
+{
+       struct pppoe_hdr *ph = (struct pppoe_hdr *) skb->nh.raw;
+       struct pppox_opt *po;
+       struct sock *sk ;
+       int ret;
+
+       po = get_item((unsigned long) ph->sid, skb->mac.ethernet->h_source);
+
+       if(!po){
+               kfree(skb);
+               return 0;
+       }
+
+       sk = po->sk;
+        bh_lock_sock(sk);
+
+       /* Socket state is unknown, must put skb into backlog. */
+       if( sk->lock.users != 0 ){
+               sk_add_backlog( sk, skb);
+               ret = 1;
+       }else{
+               ret = pppoe_rcv_core(sk, skb);
+       }
+       
+       bh_unlock_sock(sk);
+       sock_put(sk);
+       return ret;
+}
+
+
+/************************************************************************
+ *
+ * Receive wrapper called in process context.
+ *
+ ***********************************************************************/
+int pppoe_backlog_rcv(struct sock *sk, struct sk_buff *skb)
+{
+       lock_sock(sk);
+       pppoe_rcv_core(sk, skb);
+       release_sock(sk);
        return 0;
 }
 
+
+
 /************************************************************************
  *
  * Receive a PPPoE Discovery frame.
- * -- This is solely for detection of PADT frames
+ * This is solely for detection of PADT frames
  *
  ***********************************************************************/
 static int pppoe_disc_rcv(struct sk_buff *skb,
@@ -373,7+422,7 @@ static int pppoe_disc_rcv(struct sk_buff *skb,
 {
        struct pppoe_hdr *ph = (struct pppoe_hdr *) skb->nh.raw;
        struct pppox_opt *po;
-       struct sock *sk ;
+       struct sock *sk = NULL;
 
        if (ph->code != PADT_CODE)
                goto abort;
@@ -381,13+430,15 @@ static int pppoe_disc_rcv(struct sk_buff *skb,
        po = get_item((unsigned long) ph->sid, skb->mac.ethernet->h_source);
 
        if (!po)
-               goto abort;
+               goto abort_put;
 
        sk = po->sk;
 
        pppox_unbind_sock(sk);
 
-abort:
+ abort_put:
+       sock_put(sk);
+ abort:
        kfree_skb(skb);
        return 0;
 }
@@ -422,22+473,7 @@ void sock_pppoe_destruct(struct sock *sk)
        if (sk->protinfo.destruct_hook)
                kfree(sk->protinfo.destruct_hook);
 
-       while (skb_queue_len(&sk->receive_queue) > 0) {
-               struct sk_buff *skb = skb_dequeue(&sk->receive_queue);
-               if (skb)
-                       kfree_skb(skb);
-       }
-}
-
-int pppoe_backlog_rcv(struct sock *sk, struct sk_buff *skb)
-{
-       /* Never seen this called, don't expect it to be called,
-          though I've curious whether or not it ever will be. */
-       DEBUG(KERN_CRIT "Backlog rcv called: %p\n", sk);
-
-       kfree_skb(skb);
-
-       return 0;
+       MOD_DEC_USE_COUNT;
 }
 
 /***********************************************************************
@@ -487,7+523,6 @@ static int pppoe_create(struct socket *sock)
 
 free_sk:
        sk_free(sk);
-       MOD_DEC_USE_COUNT;
        return error;
 }
 
@@ -505,8+540,6 @@ int pppoe_release(struct socket *sock)
 
        pppox_unbind_sock(sk);
 
-       sock_orphan(sk);
-
        /* Signal the death of the socket. */
        sk->state = PPPOX_DEAD;
 
@@ -514,12+547,9 @@ int pppoe_release(struct socket *sock)
        if (po->pppoe_pa.sid)
                delete_item(po->pppoe_pa.sid, po->pppoe_pa.remote);
 
-       kfree(po);
-
-
        /* Should also do a queue purge here */
 
-       sk->protinfo.pppox = NULL;
+       sock_orphan(sk);
        sock->sk = NULL;
 
        skb_queue_purge(&sk->receive_queue);
index 1ee37e2..096d816 100644 (file)
@@ -723,7+723,7 @@ static void sppp_cisco_input (struct sppp *sp, struct sk_buff *skb)
                struct in_device *in_dev;
                struct in_ifaddr *ifa;
                u32 addr = 0, mask = ~0; /* FIXME: is the mask correct? */
-
+#ifdef CONFIG_INET
                if ((in_dev=in_dev_get(dev)) != NULL)
                {
                        read_lock(&in_dev->lock);
@@ -739,6+739,7 @@ static void sppp_cisco_input (struct sppp *sp, struct sk_buff *skb)
                        read_unlock(&in_dev->lock);
                        in_dev_put(in_dev);
                }
+#endif         
                /* I hope both addr and mask are in the net order */
                sppp_cisco_send (sp, CISCO_ADDR_REPLY, addr, mask);
                break;
index 4a88efd..84ee1ad 100644 (file)
@@ -37,6+37,14 @@ else
   endif
 endif
 
+ifeq ($(CONFIG_DISPLAY7SEG),y)
+O_OBJS += display7seg.o
+else
+  ifeq ($(CONFIG_DISPLAY7SEG),m)
+  M_OBJS += display7seg.o
+  endif
+endif
+
 endif # eq($(CONFIG_PCI,y)
 
 ifeq ($(CONFIG_OBP_FLASH),y)
diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c
new file mode 100644 (file)
index 0000000..c9d4ea0
--- /dev/null
@@ -0,0 +1,238 @@
+/* $Id: display7seg.c,v 1.2 2000/08/02 06:22:35 davem Exp $
+ *
+ * display7seg - Driver implementation for the 7-segment display
+ * present on Sun Microsystems CP1400 and CP1500
+ *
+ * Copyright (c) 2000 Eric Brower (ebrower@usa.net)
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/major.h>
+#include <linux/init.h>
+#include <linux/miscdevice.h>
+#include <linux/ioport.h>              /* request_region, check_region */
+#include <asm/ebus.h>                  /* EBus device                                  */
+#include <asm/oplib.h>                 /* OpenProm Library                     */
+#include <asm/uaccess.h>               /* put_/get_user_ret                    */
+
+#include <asm/display7seg.h>
+
+#define D7S_MINOR      193
+#define D7S_OBPNAME    "display7seg"
+#define D7S_DEVNAME "d7s"
+
+static int sol_compat = 0;             /* Solaris compatibility mode   */
+
+#ifdef MODULE
+EXPORT_NO_SYMBOLS;
+
+/* Solaris compatibility flag -
+ * The Solaris implementation omits support for several
+ * documented driver features (ref Sun doc 806-0180-03).  
+ * By default, this module supports the documented driver 
+ * abilities, rather than the Solaris implementation:
+ *
+ *     1) Device ALWAYS reverts to OBP-specified FLIPPED mode
+ *        upon closure of device or module unload.
+ *     2) Device ioctls D7SIOCRD/D7SIOCWR honor toggling of
+ *        FLIP bit
+ *
+ * If you wish the device to operate as under Solaris,
+ * omitting above features, set this parameter to non-zero.
+ */
+MODULE_PARM
+       (sol_compat, "1i");
+MODULE_PARM_DESC
+       (sol_compat, 
+        "Disables documented functionality omitted from Solaris driver");
+
+MODULE_AUTHOR
+       ("Eric Brower <ebrower@usa.net>");
+MODULE_DESCRIPTION
+       ("7-Segment Display driver for Sun Microsystems CP1400/1500");
+MODULE_SUPPORTED_DEVICE
+       ("d7s");
+#endif /* ifdef MODULE */
+
+/*
+ * Register block address- see header for details
+ * -----------------------------------------
+ * | DP | ALARM | FLIP | 4 | 3 | 2 | 1 | 0 |
+ * -----------------------------------------
+ *
+ * DP          - Toggles decimal point on/off 
+ * ALARM       - Toggles "Alarm" LED green/red
+ * FLIP                - Inverts display for upside-down mounted board
+ * bits 0-4    - 7-segment display contents
+ */
+volatile u8* d7s_regs = 0;
+
+static inline void d7s_free(void)
+{
+       iounmap(d7s_regs);
+}
+
+static inline int d7s_obpflipped(void)
+{
+       int opt_node;
+
+       opt_node = prom_getchild(prom_root_node);
+       opt_node = prom_searchsiblings(opt_node, "options");
+       return ((-1 != prom_getintdefault(opt_node, "d7s-flipped?", -1)) ? 0 : 1);
+}
+
+static int d7s_open(struct inode *inode, struct file *f)
+{
+       if (D7S_MINOR != MINOR(inode->i_rdev))
+               return -ENODEV;
+
+       MOD_INC_USE_COUNT;
+       return 0;
+}
+
+static int d7s_release(struct inode *inode, struct file *f)
+{
+       if (D7S_MINOR != MINOR(inode->i_rdev))
+               return -ENODEV;
+       
+       MOD_DEC_USE_COUNT;
+
+       /* Reset flipped state to OBP default only if
+        * no other users have the device open and we
+        * are not operating in solaris-compat mode
+        */
+       if (0 == MOD_IN_USE && 0 == sol_compat) {
+               int regval = 0;
+
+               regval = readb(d7s_regs);
+               (0 == d7s_obpflipped()) ? 
+                       writeb(regval |= D7S_FLIP,  d7s_regs): 
+                       writeb(regval &= ~D7S_FLIP, d7s_regs);
+       }
+
+       return 0;
+}
+
+static int d7s_ioctl(struct inode *inode, struct file *f, 
+                    unsigned int cmd, unsigned long arg)
+{
+       __u8 regs = readb(d7s_regs);
+       __u8 ireg = 0;
+
+       if (D7S_MINOR != MINOR(inode->i_rdev))
+               return -ENODEV;
+
+       switch (cmd) {
+       case D7SIOCWR:
+               /* assign device register values
+                * we mask-out D7S_FLIP if in sol_compat mode
+                */
+               get_user_ret(ireg, (int *) arg, -EFAULT);
+               if (0 != sol_compat) {
+                       (regs & D7S_FLIP) ? 
+                               (ireg |= D7S_FLIP) : (ireg &= ~D7S_FLIP);
+               }
+               writeb(ireg, d7s_regs);
+               break;
+
+       case D7SIOCRD:
+               /* retrieve device register values
+                * NOTE: Solaris implementation returns D7S_FLIP bit
+                * as toggled by user, even though it does not honor it.
+                * This driver will not misinform you about the state
+                * of your hardware while in sol_compat mode
+                */
+               put_user_ret(regs, (int *) arg, -EFAULT);
+               break;
+
+       case D7SIOCTM:
+               /* toggle device mode-- flip display orientation */
+               (regs & D7S_FLIP) ? 
+                       (regs &= ~D7S_FLIP) : (regs |= D7S_FLIP);
+               writeb(regs, d7s_regs);
+               break;
+       };
+
+       return 0;
+}
+
+static struct file_operations d7s_fops = {
+       owner:          THIS_MODULE,
+       ioctl:          d7s_ioctl,
+       open:           d7s_open,
+       release:        d7s_release,
+};
+
+static struct miscdevice d7s_miscdev = { D7S_MINOR, D7S_DEVNAME, &d7s_fops };
+
+#ifdef MODULE
+int init_module(void)
+#else
+int __init d7s_init(void)
+#endif
+{
+       struct linux_ebus *ebus = NULL;
+       struct linux_ebus_device *edev = NULL;
+       int iTmp = 0, regs = 0;
+
+       for_each_ebus(ebus) {
+               for_each_ebusdev(edev, ebus) {
+                       if (!strcmp(edev->prom_name, D7S_OBPNAME))
+                               goto ebus_done;
+               }
+       }
+
+ebus_done:
+       if(!edev) {
+               printk("%s: unable to locate device\n", D7S_DEVNAME);
+               return -ENODEV;
+       }
+
+       d7s_regs = ioremap(edev->resource[0].start, sizeof(__u8));
+
+       iTmp = misc_register(&d7s_miscdev);
+       if (0 != iTmp) {
+               printk("%s: unable to acquire miscdevice minor %i\n",
+                      D7S_DEVNAME, D7S_MINOR);
+               return iTmp;
+       }
+
+       /* OBP option "d7s-flipped?" is honored as default
+        * for the device, and reset default when detached
+        */
+       regs = readb(d7s_regs);
+       iTmp = d7s_obpflipped();
+       (0 == iTmp) ? 
+               writeb(regs |= D7S_FLIP,  d7s_regs): 
+               writeb(regs &= ~D7S_FLIP, d7s_regs);
+
+       printk("%s: 7-Segment Display%s at 0x%lx %s\n", 
+              D7S_DEVNAME,
+              (0 == iTmp) ? (" (FLIPPED)") : (""),
+              edev->resource[0].start,
+              (0 != sol_compat) ? ("in sol_compat mode") : (""));
+
+       return 0;
+}
+
+#ifdef MODULE
+void cleanup_module(void)
+{
+       int regs = readb(d7s_regs);
+
+       /* Honor OBP d7s-flipped? unless operating in solaris-compat mode */
+       if (0 == sol_compat) {
+               (0 == d7s_obpflipped()) ? 
+                       writeb(regs |= D7S_FLIP,  d7s_regs):
+                       writeb(regs &= ~D7S_FLIP, d7s_regs);
+       }
+
+       misc_deregister(&d7s_miscdev);
+       d7s_free();
+}
+#endif
index ebe4e33..ba6cc03 100644 (file)
    1.02.00.001 - Added support for full command packet posts through ioctls
                  for 3DM.
                  Bug fix so hot spare drives don't show up.
+   1.02.00.002 - Fix bug with tw_setfeature() call that caused oops on some
+                 systems.
 */
 
 #include <linux/module.h>
@@ -107,7+109,7 @@ static struct notifier_block tw_notifier = {
 };
 
 /* Globals */
-char *tw_driver_version="1.02.00.001";
+char *tw_driver_version="1.02.00.002";
 TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT];
 int tw_device_extension_count = 0;
 
@@ -747,7+749,7 @@ int tw_findcards(Scsi_Host_Template *tw_host)
                        kfree(tw_dev);
 
                /* Tell the firmware we support shutdown notification*/
-               tw_setfeature(tw_dev, 2, 1, &c);
+               tw_setfeature(tw_dev2, 2, 1, &c);
        }
 
        if (numcards == 0) 
index e5c5ca1..9ebe9e9 100644 (file)
 /* 3.60.01  - Remove bogus error check in passthru routine                   */
 /* 3.60.02  - Make DCDB direction based on lookup table                      */
 /*          - Only allow one DCDB command to a SCSI ID at a time             */
+/* 4.00.00  - Add support for ServeRAID 4                                    */
+/* 4.00.01  - Add support for First Failure Data Capture                     */
+/* 4.00.02  - Fix problem with PT DCDB with no buffer                        */
+/* 4.00.03  - Add alternative passthru interface                             */
+/*          - Add ability to flash ServeRAID BIOS                            */
+/* 4.00.04  - Rename structures/constants to be prefixed with IPS_           */
+/* 4.00.05  - Remove wish_block from init routine                            */
+/*          - Use linux/spinlock.h instead of asm/spinlock.h for kernels     */
+/*            2.3.18 and later                                               */
+/*          - Sync with other changes from the 2.3 kernels                   */
+/* 4.00.06  - Fix timeout with initial FFDC command                          */
+/* 4.00.06a - Port to 2.4 (trivial) -- Christoph Hellwig <hch@caldera.de>    */
 /*                                                                           */
 /*****************************************************************************/
 
  *
  */
 
-#if defined (MODULE)
-   #include <linux/module.h>
-#endif /* MODULE */
+#include <linux/module.h>
 
 #include <asm/io.h>
 #include <asm/byteorder.h>
 
 #include <linux/stat.h>
 #include <linux/config.h>
+
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,18)
 #include <linux/spinlock.h>
+#else
+#include <asm/spinlock.h>
+#endif
+
 #include <linux/smp.h>
 
 /*
  * DRIVER_VER
  */
-#define IPS_VERSION_HIGH        "3.60"  /* MUST be 4 chars */
-#define IPS_VERSION_LOW         ".02 "  /* MUST be 4 chars */
+#define IPS_VERSION_HIGH        "4.00"  /* MUST be 4 chars */
+#define IPS_VERSION_LOW         ".06 "  /* MUST be 4 chars */
+
+#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,27)
+struct proc_dir_entry proc_scsi_ips = {
+#if !defined(PROC_SCSI_IPS)
+   0,                                /* Use dynamic inode allocation */
+#else
+   PROC_SCSI_IPS,
+#endif
+   3, "ips",
+   S_IFDIR | S_IRUGO | S_IXUGO, 2
+}
+;
+#endif
 
 #if !defined(__i386__)
    #error "This driver has only been tested on the x86 platform"
 #endif
 
 #if IPS_DEBUG >= 12
-   #define DBG(s)       printk(KERN_NOTICE s "\n"); MDELAY(2*ONE_SEC)
+   #define DBG(s)       printk(KERN_NOTICE s "\n"); MDELAY(2*IPS_ONE_SEC)
 #elif IPS_DEBUG >= 11
    #define DBG(s)       printk(KERN_NOTICE s "\n")
 #else
@@ -149,7+178,7 @@ static unsigned int ips_num_controllers = 0;
 static int          ips_cmd_timeout = 60;
 static int          ips_reset_timeout = 60 * 5;
 
-#define MAX_ADAPTER_NAME 6
+#define MAX_ADAPTER_NAME 7
 
 static char ips_adapter_name[][30] = {
    "ServeRAID",
@@ -157,64+186,65 @@ static char ips_adapter_name[][30] = {
    "ServeRAID on motherboard",
    "ServeRAID on motherboard",
    "ServeRAID 3H",
-   "ServeRAID 3L"
+   "ServeRAID 3L",
+   "ServeRAID 4H"
 };
 
 /*
  * Direction table
  */
 static char ips_command_direction[] = {
-IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT,
-IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK,
-IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT,
-IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_OUT,
-IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_OUT,
-IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_IN,
-IPS_DATA_UNK, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_UNK,
-IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT,
-IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_NONE,
-IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT,
-IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT,
-IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_NONE,
-IPS_DATA_UNK, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK,
-IPS_DATA_NONE, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_NONE,
-IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_OUT,
-IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_NONE,
-IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_IN,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_OUT,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK
+IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_IN,   IPS_DATA_IN,   IPS_DATA_OUT,
+IPS_DATA_IN,   IPS_DATA_IN,   IPS_DATA_OUT,  IPS_DATA_IN,   IPS_DATA_UNK,
+IPS_DATA_OUT,  IPS_DATA_OUT,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
+IPS_DATA_IN,   IPS_DATA_NONE, IPS_DATA_IN,   IPS_DATA_IN,   IPS_DATA_OUT,
+IPS_DATA_IN,   IPS_DATA_OUT,  IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_OUT,
+IPS_DATA_NONE, IPS_DATA_IN,   IPS_DATA_NONE, IPS_DATA_IN,   IPS_DATA_OUT,
+IPS_DATA_NONE, IPS_DATA_UNK,  IPS_DATA_IN,   IPS_DATA_UNK,  IPS_DATA_IN,
+IPS_DATA_UNK,  IPS_DATA_OUT,  IPS_DATA_IN,   IPS_DATA_UNK,  IPS_DATA_UNK,
+IPS_DATA_IN,   IPS_DATA_IN,   IPS_DATA_OUT,  IPS_DATA_NONE, IPS_DATA_UNK,
+IPS_DATA_IN,   IPS_DATA_OUT,  IPS_DATA_OUT,  IPS_DATA_OUT,  IPS_DATA_OUT,
+IPS_DATA_OUT,  IPS_DATA_NONE, IPS_DATA_IN,   IPS_DATA_NONE, IPS_DATA_NONE,
+IPS_DATA_IN,   IPS_DATA_OUT,  IPS_DATA_OUT,  IPS_DATA_OUT,  IPS_DATA_OUT,
+IPS_DATA_IN,   IPS_DATA_OUT,  IPS_DATA_IN,   IPS_DATA_OUT,  IPS_DATA_OUT,
+IPS_DATA_OUT,  IPS_DATA_IN,   IPS_DATA_IN,   IPS_DATA_IN,   IPS_DATA_NONE,
+IPS_DATA_UNK,  IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK,
+IPS_DATA_NONE, IPS_DATA_OUT,  IPS_DATA_IN,   IPS_DATA_UNK,  IPS_DATA_UNK,
+IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
+IPS_DATA_OUT,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
+IPS_DATA_IN,   IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
+IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
+IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
+IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
+IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
+IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
+IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
+IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
+IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
+IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
+IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
+IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
+IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
+IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
+IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
+IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK,  IPS_DATA_IN,   IPS_DATA_NONE,
+IPS_DATA_OUT,  IPS_DATA_UNK,  IPS_DATA_NONE, IPS_DATA_UNK,  IPS_DATA_OUT,
+IPS_DATA_OUT,  IPS_DATA_OUT,  IPS_DATA_OUT,  IPS_DATA_OUT,  IPS_DATA_NONE,
+IPS_DATA_UNK,  IPS_DATA_IN,   IPS_DATA_OUT,  IPS_DATA_IN,   IPS_DATA_IN,
+IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
+IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
+IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
+IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
+IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
+IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
+IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
+IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
+IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
+IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_OUT,
+IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
+IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
+IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
+IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK
 };
 
 /*
@@ -232,8+262,8 @@ const char * ips_info(struct Scsi_Host *);
 void do_ipsintr(int, void *, struct pt_regs *);
 static int ips_hainit(ips_ha_t *);
 static int ips_map_status(ips_scb_t *, ips_stat_t *);
-static int ips_send(ips_ha_t *, ips_scb_t *, scb_callback);
-static int ips_send_wait(ips_ha_t *, ips_scb_t *, int);
+static int ips_send(ips_ha_t *, ips_scb_t *, ips_scb_callback);
+static int ips_send_wait(ips_ha_t *, ips_scb_t *, int, int);
 static int ips_send_cmd(ips_ha_t *, ips_scb_t *);
 static int ips_chkstatus(ips_ha_t *);
 static int ips_online(ips_ha_t *, ips_scb_t *);
@@ -247,14+277,14 @@ static int ips_statupd(ips_ha_t *);
 static int ips_issue(ips_ha_t *, ips_scb_t *);
 static int ips_isintr(ips_ha_t *);
 static int ips_wait(ips_ha_t *, int, int);
-static int ips_write_driver_status(ips_ha_t *);
-static int ips_read_adapter_status(ips_ha_t *);
-static int ips_read_subsystem_parameters(ips_ha_t *);
-static int ips_read_config(ips_ha_t *);
-static int ips_clear_adapter(ips_ha_t *);
-static int ips_readwrite_page5(ips_ha_t *, int);
+static int ips_write_driver_status(ips_ha_t *, int);
+static int ips_read_adapter_status(ips_ha_t *, int);
+static int ips_read_subsystem_parameters(ips_ha_t *, int);
+static int ips_read_config(ips_ha_t *, int);
+static int ips_clear_adapter(ips_ha_t *, int);
+static int ips_readwrite_page5(ips_ha_t *, int, int);
 static void ips_intr(ips_ha_t *);
-static void ips_next(ips_ha_t *);
+static void ips_next(ips_ha_t *, int);
 static void ipsintr_blocking(ips_ha_t *, struct ips_scb *);
 static void ipsintr_done(ips_ha_t *, struct ips_scb *);
 static void ips_done(ips_ha_t *, ips_scb_t *);
@@ -262,6+292,9 @@ static void ips_free(ips_ha_t *);
 static void ips_init_scb(ips_ha_t *, ips_scb_t *);
 static void ips_freescb(ips_ha_t *, ips_scb_t *);
 static void ips_statinit(ips_ha_t *);
+static void ips_fix_ffdc_time(ips_ha_t *, ips_scb_t *, time_t);
+static void ips_ffdc_reset(ips_ha_t *, int);
+static void ips_ffdc_time(ips_ha_t *, int);
 static ips_scb_t * ips_getscb(ips_ha_t *);
 static inline void ips_putq_scb_head(ips_scb_queue_t *, ips_scb_t *);
 static inline void ips_putq_scb_tail(ips_scb_queue_t *, ips_scb_t *);
@@ -271,17+304,26 @@ static inline void ips_putq_wait_head(ips_wait_queue_t *, Scsi_Cmnd *);
 static inline void ips_putq_wait_tail(ips_wait_queue_t *, Scsi_Cmnd *);
 static inline Scsi_Cmnd * ips_removeq_wait_head(ips_wait_queue_t *);
 static inline Scsi_Cmnd * ips_removeq_wait(ips_wait_queue_t *, Scsi_Cmnd *);
+static inline void ips_putq_copp_head(ips_copp_queue_t *, ips_copp_wait_item_t *);
+static inline void ips_putq_copp_tail(ips_copp_queue_t *, ips_copp_wait_item_t *);
+static inline ips_copp_wait_item_t * ips_removeq_copp(ips_copp_queue_t *, ips_copp_wait_item_t *);
+static inline ips_copp_wait_item_t * ips_removeq_copp_head(ips_copp_queue_t *);
+static int ips_erase_bios(ips_ha_t *);
+static int ips_program_bios(ips_ha_t *, char *, int);
+static int ips_verify_bios(ips_ha_t *, char *, int);
 
 #ifndef NO_IPS_CMDLINE
 static int ips_is_passthru(Scsi_Cmnd *);
 static int ips_make_passthru(ips_ha_t *, Scsi_Cmnd *, ips_scb_t *);
 static int ips_usrcmd(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
+static int ips_newusrcmd(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
+static void ips_cleanup_passthru(ips_ha_t *, ips_scb_t *);
 #endif
 
 int  ips_proc_info(char *, char **, off_t, int, int, int);
 static int ips_host_info(ips_ha_t *, char *, off_t, int);
-static void copy_mem_info(INFOSTR *, char *, int);
-static int copy_info(INFOSTR *, char *, ...);
+static void copy_mem_info(IPS_INFOSTR *, char *, int);
+static int copy_info(IPS_INFOSTR *, char *, ...);
 
 /*--------------------------------------------------------------------------*/
 /* Exported Functions                                                       */
@@ -295,6+337,8 @@ static int copy_info(INFOSTR *, char *, ...);
 /*                                                                          */
 /*   Detect and initialize the driver                                       */
 /*                                                                          */
+/* NOTE: this routine is called under the io_request_lock spinlock          */
+/*                                                                          */
 /****************************************************************************/
 int
 ips_detect(Scsi_Host_Template *SHT) {
@@ -302,6+346,7 @@ ips_detect(Scsi_Host_Template *SHT) {
    ips_ha_t         *ha;
    u32               io_addr;
    u16               planer;
+   u8                revision_id;
    u8                bus;
    u8                func;
    u8                irq;
@@ -311,7+356,11 @@ ips_detect(Scsi_Host_Template *SHT) {
    DBG("ips_detect");
 
    SHT->proc_info = ips_proc_info;
+#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,27)
+   SHT->proc_dir = &proc_scsi_ips;
+#else
    SHT->proc_name = "ips";
+#endif
 
 #if defined(CONFIG_PCI)
 
@@ -325,26+374,27 @@ ips_detect(Scsi_Host_Template *SHT) {
 
       if (!(dev = pci_find_device(IPS_VENDORID, IPS_DEVICEID, dev)))
          break;
+
       if (pci_enable_device(dev))
-        break;
+         break;
+      
       /* stuff that we get in dev */
       irq = dev->irq;
       bus = dev->bus->number;
       func = dev->devfn;
       io_addr = pci_resource_start(dev, 0);
+      
+      /* check I/O address */
+      if (pci_resource_flags(dev, 0) & IORESOURCE_MEM)
+         continue;
 
       /* get planer status */
       if (pci_read_config_word(dev, 0x04, &planer)) {
          printk(KERN_WARNING "(%s%d) can't get planer status.\n",
                 ips_name, index);
-
          continue;
       }
 
-      /* check I/O address */
-      if (pci_resource_flags(dev, 0) & IORESOURCE_MEM)
-         continue;
-
       /* check to see if an onboard planer controller is disabled */
       if (!(planer & 0x000C)) {
 
@@ -361,6+411,14 @@ ips_detect(Scsi_Host_Template *SHT) {
              ips_name, index, bus, func, irq, io_addr);
    #endif
 
+      /* get the revision ID */
+      if (pci_read_config_byte(dev, 0x08, &revision_id)) {
+         printk(KERN_WARNING "(%s%d) can't get revision id.\n",
+                ips_name, index);
+
+         continue;
+      }
+
       /* found a controller */
       sh = scsi_register(SHT, sizeof(ips_ha_t));
 
@@ -371,19+429,23 @@ ips_detect(Scsi_Host_Template *SHT) {
          continue;
       }
 
-      ha = HA(sh);
+      ha = IPS_HA(sh);
       memset(ha, 0, sizeof(ips_ha_t));
 
       /* Initialize spin lock */
       spin_lock_init(&ha->scb_lock);
       spin_lock_init(&ha->copp_lock);
+      spin_lock_init(&ha->ips_lock);
+      spin_lock_init(&ha->copp_waitlist.lock);
+      spin_lock_init(&ha->scb_waitlist.lock);
+      spin_lock_init(&ha->scb_activelist.lock);
 
       ips_sh[ips_num_controllers] = sh;
       ips_ha[ips_num_controllers] = ha;
       ips_num_controllers++;
       ha->active = 1;
 
-      ha->enq = kmalloc(sizeof(ENQCMD), GFP_KERNEL|GFP_DMA);
+      ha->enq = kmalloc(sizeof(IPS_ENQ), GFP_KERNEL|GFP_DMA);
 
       if (!ha->enq) {
          printk(KERN_WARNING "(%s%d) Unable to allocate host inquiry structure - skipping contoller\n",
@@ -394,7+456,7 @@ ips_detect(Scsi_Host_Template *SHT) {
          continue;
       }
 
-      ha->adapt = kmalloc(sizeof(ADAPTER_AREA), GFP_KERNEL|GFP_DMA);
+      ha->adapt = kmalloc(sizeof(IPS_ADAPTER), GFP_KERNEL|GFP_DMA);
 
       if (!ha->adapt) {
          printk(KERN_WARNING "(%s%d) Unable to allocate host adapt structure - skipping controller\n",
@@ -405,7+467,7 @@ ips_detect(Scsi_Host_Template *SHT) {
          continue;
       }
 
-      ha->conf = kmalloc(sizeof(CONFCMD), GFP_KERNEL|GFP_DMA);
+      ha->conf = kmalloc(sizeof(IPS_CONF), GFP_KERNEL|GFP_DMA);
 
       if (!ha->conf) {
          printk(KERN_WARNING "(%s%d) Unable to allocate host conf structure - skipping controller\n",
@@ -416,7+478,7 @@ ips_detect(Scsi_Host_Template *SHT) {
          continue;
       }
 
-      ha->nvram = kmalloc(sizeof(NVRAM_PAGE5), GFP_KERNEL|GFP_DMA);
+      ha->nvram = kmalloc(sizeof(IPS_NVRAM_P5), GFP_KERNEL|GFP_DMA);
 
       if (!ha->nvram) {
          printk(KERN_WARNING "(%s%d) Unable to allocate host nvram structure - skipping controller\n",
@@ -427,7+489,7 @@ ips_detect(Scsi_Host_Template *SHT) {
          continue;
       }
 
-      ha->subsys = kmalloc(sizeof(SUBSYS_PARAM), GFP_KERNEL|GFP_DMA);
+      ha->subsys = kmalloc(sizeof(IPS_SUBSYS), GFP_KERNEL|GFP_DMA);
 
       if (!ha->subsys) {
          printk(KERN_WARNING "(%s%d) Unable to allocate host subsystem structure - skipping controller\n",
@@ -438,7+500,7 @@ ips_detect(Scsi_Host_Template *SHT) {
          continue;
       }
 
-      ha->dummy = kmalloc(sizeof(BASIC_IO_CMD), GFP_KERNEL|GFP_DMA);
+      ha->dummy = kmalloc(sizeof(IPS_IO_CMD), GFP_KERNEL|GFP_DMA);
 
       if (!ha->dummy) {
          printk(KERN_WARNING "(%s%d) Unable to allocate host dummy structure - skipping controller\n",
@@ -449,6+511,17 @@ ips_detect(Scsi_Host_Template *SHT) {
          continue;
       }
 
+      ha->ioctl_data = kmalloc(IPS_IOCTL_SIZE, GFP_KERNEL|GFP_DMA);
+      ha->ioctl_datasize = IPS_IOCTL_SIZE;
+      if (!ha->ioctl_data) {
+         printk(KERN_WARNING "(%s%d) Unable to allocate ioctl data - skipping controller\n",
+                ips_name, index);
+
+         ha->active = 0;
+
+         continue;
+      }
+
       /* Store away needed values for later use */
       sh->io_port = io_addr;
       sh->n_io_port = 255;
@@ -465,6+538,7 @@ ips_detect(Scsi_Host_Template *SHT) {
       ha->io_addr = io_addr;
       ha->irq = irq;
       ha->host_num = index;
+      ha->revision_id = revision_id;
 
       /* install the interrupt handler */
       if (request_irq(irq, do_ipsintr, SA_SHIRQ, ips_name, ha)) {
@@ -491,7+565,7 @@ ips_detect(Scsi_Host_Template *SHT) {
       }
 
       memset(ha->scbs, 0, sizeof(ips_scb_t));
-      ha->scbs->sg_list = (SG_LIST *) kmalloc(sizeof(SG_LIST) * MAX_SG_ELEMENTS, GFP_KERNEL|GFP_DMA);
+      ha->scbs->sg_list = (IPS_SG_LIST *) kmalloc(sizeof(IPS_SG_LIST) * IPS_MAX_SG, GFP_KERNEL|GFP_DMA);
       if (!ha->scbs->sg_list) {
          /* couldn't allocate a temp SCB S/G list */
          printk(KERN_WARNING "(%s%d) unable to allocate CCBs - skipping contoller\n",
@@ -569,7+643,7 @@ ips_release(struct Scsi_Host *sh) {
       panic("(%s) release, invalid Scsi_Host pointer.\n",
             ips_name);
 
-   ha = HA(sh);
+   ha = IPS_HA(sh);
 
    if (!ha)
       return (FALSE);
@@ -580,11+654,11 @@ ips_release(struct Scsi_Host *sh) {
    ips_init_scb(ha, scb);
 
    scb->timeout = ips_cmd_timeout;
-   scb->cdb[0] = FLUSH_CACHE;
+   scb->cdb[0] = IPS_CMD_FLUSH;
 
-   scb->cmd.flush_cache.op_code = FLUSH_CACHE;
+   scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
    scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb);
-   scb->cmd.flush_cache.state = NORM_STATE;
+   scb->cmd.flush_cache.state = IPS_NORM_STATE;
    scb->cmd.flush_cache.reserved = 0;
    scb->cmd.flush_cache.reserved2 = 0;
    scb->cmd.flush_cache.reserved3 = 0;
@@ -593,7+667,7 @@ ips_release(struct Scsi_Host *sh) {
    printk("(%s%d) Flushing Cache.\n", ips_name, ha->host_num);
 
    /* send command */
-   if (ips_send_wait(ha, scb, ips_cmd_timeout) == IPS_FAILURE)
+   if (ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_ON) == IPS_FAILURE)
       printk("(%s%d) Incomplete Flush.\n", ips_name, ha->host_num);
 
    printk("(%s%d) Flushing Complete.\n", ips_name, ha->host_num);
@@ -625,6+699,7 @@ ips_release(struct Scsi_Host *sh) {
 int
 ips_eh_abort(Scsi_Cmnd *SC) {
    ips_ha_t         *ha;
+   ips_copp_wait_item_t *item;
 
    DBG("ips_eh_abort");
 
@@ -651,9+726,23 @@ ips_eh_abort(Scsi_Cmnd *SC) {
    if (test_and_set_bit(IPS_IN_ABORT, &ha->flags))
       return (FAILED);
 
+   /* See if the command is on the copp queue */
+   IPS_QUEUE_LOCK(&ha->copp_waitlist);
+   item = ha->copp_waitlist.head;
+   while ((item) && (item->scsi_cmd != SC))
+      item = item->next;
+   IPS_QUEUE_UNLOCK(&ha->copp_waitlist);
+
+   if (item) {
+      /* Found it */
+      ips_removeq_copp(&ha->copp_waitlist, item);
+      clear_bit(IPS_IN_ABORT, &ha->flags);
+
+      return (SUCCESS);
+   }
+
    /* See if the command is on the wait queue */
-   if (ips_removeq_wait(&ha->scb_waitlist, SC) ||
-       ips_removeq_wait(&ha->copp_waitlist, SC)) {
+   if (ips_removeq_wait(&ha->scb_waitlist, SC)) {
       /* command not sent yet */
       clear_bit(IPS_IN_ABORT, &ha->flags);
 
@@ -678,6+767,7 @@ ips_eh_abort(Scsi_Cmnd *SC) {
 int
 ips_abort(Scsi_Cmnd *SC) {
    ips_ha_t         *ha;
+   ips_copp_wait_item_t *item;
 
    DBG("ips_abort");
 
@@ -704,9+794,23 @@ ips_abort(Scsi_Cmnd *SC) {
    if (test_and_set_bit(IPS_IN_ABORT, &ha->flags))
       return (SCSI_ABORT_SNOOZE);
 
+   /* See if the command is on the copp queue */
+   IPS_QUEUE_LOCK(&ha->copp_waitlist);
+   item = ha->copp_waitlist.head;
+   while ((item) && (item->scsi_cmd != SC))
+      item = item->next;
+   IPS_QUEUE_UNLOCK(&ha->copp_waitlist);
+
+   if (item) {
+      /* Found it */
+      ips_removeq_copp(&ha->copp_waitlist, item);
+      clear_bit(IPS_IN_ABORT, &ha->flags);
+
+      return (SCSI_ABORT_PENDING);
+   }
+
    /* See if the command is on the wait queue */
-   if (ips_removeq_wait(&ha->scb_waitlist, SC) ||
-       ips_removeq_wait(&ha->copp_waitlist, SC)) {
+   if (ips_removeq_wait(&ha->scb_waitlist, SC)) {
       /* command not sent yet */
       clear_bit(IPS_IN_ABORT, &ha->flags);
 
@@ -727,11+831,15 @@ ips_abort(Scsi_Cmnd *SC) {
 /*                                                                          */
 /*   Reset the controller (with new eh error code)                          */
 /*                                                                          */
+/* NOTE: this routine is called under the io_request_lock spinlock          */
+/*                                                                          */
 /****************************************************************************/
 int
 ips_eh_reset(Scsi_Cmnd *SC) {
-   ips_ha_t         *ha;
-   ips_scb_t        *scb;
+   u32                   cpu_flags;
+   ips_ha_t             *ha;
+   ips_scb_t            *scb;
+   ips_copp_wait_item_t *item;
 
    DBG("ips_eh_reset");
 
@@ -765,11+873,25 @@ ips_eh_reset(Scsi_Cmnd *SC) {
    if (test_and_set_bit(IPS_IN_RESET, &ha->flags))
       return (FAILED);
 
-   /* See if the command is on the waiting queue */
-   if (ips_removeq_wait(&ha->scb_waitlist, SC) ||
-       ips_removeq_wait(&ha->copp_waitlist, SC)) {
+   /* See if the command is on the copp queue */
+   IPS_QUEUE_LOCK(&ha->copp_waitlist);
+   item = ha->copp_waitlist.head;
+   while ((item) && (item->scsi_cmd != SC))
+      item = item->next;
+   IPS_QUEUE_UNLOCK(&ha->copp_waitlist);
+
+   if (item) {
+      /* Found it */
+      ips_removeq_copp(&ha->copp_waitlist, item);
+      clear_bit(IPS_IN_RESET, &ha->flags);
+
+      return (SUCCESS);
+   }
+
+   /* See if the command is on the wait queue */
+   if (ips_removeq_wait(&ha->scb_waitlist, SC)) {
       /* command not sent yet */
-      clear_bit(IPS_IN_ABORT, &ha->flags);
+      clear_bit(IPS_IN_RESET, &ha->flags);
 
       return (SUCCESS);
    }
@@ -784,25+906,39 @@ ips_eh_reset(Scsi_Cmnd *SC) {
       return (FAILED);
    }
 
-   if (!ips_clear_adapter(ha)) {
+   if (!ips_clear_adapter(ha, IPS_INTR_IORL)) {
       clear_bit(IPS_IN_RESET, &ha->flags);
 
       return (FAILED);
    }
 
+   /* FFDC */
+   if (ha->subsys->param[3] & 0x300000) {
+      struct timeval tv;
+
+      do_gettimeofday(&tv);
+      IPS_HA_LOCK(cpu_flags);
+      ha->last_ffdc = tv.tv_sec;
+      ha->reset_count++;
+      IPS_HA_UNLOCK(cpu_flags);
+      ips_ffdc_reset(ha, IPS_INTR_IORL);
+   }
+
    /* Now fail all of the active commands */
 #if IPS_DEBUG >= 1
    printk(KERN_WARNING "(%s%d) Failing active commands\n",
           ips_name, ha->host_num);
 #endif
    while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) {
-      scb->scsi_cmd->result = DID_RESET << 16;
+      scb->scsi_cmd->result = (DID_RESET << 16) | (SUGGEST_RETRY << 24);
       scb->scsi_cmd->scsi_done(scb->scsi_cmd);
       ips_freescb(ha, scb);
    }
 
    /* Reset the number of active IOCTLs */
+   IPS_HA_LOCK(cpu_flags);
    ha->num_ioctl = 0;
+   IPS_HA_UNLOCK(cpu_flags);
 
    clear_bit(IPS_IN_RESET, &ha->flags);
 
@@ -814,7+950,7 @@ ips_eh_reset(Scsi_Cmnd *SC) {
        * handler wants to do this and since
        * interrupts are turned off here....
        */
-      ips_next(ha);
+      ips_next(ha, IPS_INTR_IORL);
    }
 
    return (SUCCESS);
@@ -831,11+967,15 @@ ips_eh_reset(Scsi_Cmnd *SC) {
 /*                                                                          */
 /*   Reset the controller                                                   */
 /*                                                                          */
+/* NOTE: this routine is called under the io_request_lock spinlock          */
+/*                                                                          */
 /****************************************************************************/
 int
 ips_reset(Scsi_Cmnd *SC, unsigned int flags) {
-   ips_ha_t         *ha;
-   ips_scb_t        *scb;
+   u32                   cpu_flags;
+   ips_ha_t             *ha;
+   ips_scb_t            *scb;
+   ips_copp_wait_item_t *item;
 
    DBG("ips_reset");
 
@@ -869,11+1009,25 @@ ips_reset(Scsi_Cmnd *SC, unsigned int flags) {
    if (test_and_set_bit(IPS_IN_RESET, &ha->flags))
       return (SCSI_RESET_SNOOZE);
 
-   /* See if the command is on the waiting queue */
-   if (ips_removeq_wait(&ha->scb_waitlist, SC) ||
-       ips_removeq_wait(&ha->copp_waitlist, SC)) {
+   /* See if the command is on the copp queue */
+   IPS_QUEUE_LOCK(&ha->copp_waitlist);
+   item = ha->copp_waitlist.head;
+   while ((item) && (item->scsi_cmd != SC))
+      item = item->next;
+   IPS_QUEUE_UNLOCK(&ha->copp_waitlist);
+
+   if (item) {
+      /* Found it */
+      ips_removeq_copp(&ha->copp_waitlist, item);
+      clear_bit(IPS_IN_RESET, &ha->flags);
+
+      return (SCSI_RESET_SNOOZE);
+   }
+
+   /* See if the command is on the wait queue */
+   if (ips_removeq_wait(&ha->scb_waitlist, SC)) {
       /* command not sent yet */
-      clear_bit(IPS_IN_ABORT, &ha->flags);
+      clear_bit(IPS_IN_RESET, &ha->flags);
 
       return (SCSI_RESET_SNOOZE);
    }
@@ -885,25+1039,39 @@ ips_reset(Scsi_Cmnd *SC, unsigned int flags) {
       return (SCSI_RESET_ERROR);
    }
 
-   if (!ips_clear_adapter(ha)) {
+   if (!ips_clear_adapter(ha, IPS_INTR_IORL)) {
       clear_bit(IPS_IN_RESET, &ha->flags);
 
       return (SCSI_RESET_ERROR);
    }
 
+   /* FFDC */
+   if (ha->subsys->param[3] & 0x300000) {
+      struct timeval tv;
+
+      do_gettimeofday(&tv);
+      IPS_HA_LOCK(cpu_flags);
+      ha->last_ffdc = tv.tv_sec;
+      ha->reset_count++;
+      IPS_HA_UNLOCK(cpu_flags);
+      ips_ffdc_reset(ha, IPS_INTR_IORL);
+   }
+
    /* Now fail all of the active commands */
 #if IPS_DEBUG >= 1
    printk(KERN_WARNING "(%s%d) Failing active commands\n",
           ips_name, ha->host_num);
 #endif
    while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) {
-      scb->scsi_cmd->result = DID_RESET << 16;
+      scb->scsi_cmd->result = (DID_RESET << 16) | (SUGGEST_RETRY << 24);
       scb->scsi_cmd->scsi_done(scb->scsi_cmd);
       ips_freescb(ha, scb);
    }
 
    /* Reset the number of active IOCTLs */
+   IPS_HA_LOCK(cpu_flags);
    ha->num_ioctl = 0;
+   IPS_HA_UNLOCK(cpu_flags);
 
    clear_bit(IPS_IN_RESET, &ha->flags);
 
@@ -915,7+1083,7 @@ ips_reset(Scsi_Cmnd *SC, unsigned int flags) {
        * handler wants to do this and since
        * interrupts are turned off here....
        */
-      ips_next(ha);
+      ips_next(ha, IPS_INTR_IORL);
    }
 
    return (SCSI_RESET_SUCCESS);
@@ -932,10+1100,15 @@ ips_reset(Scsi_Cmnd *SC, unsigned int flags) {
 /*                                                                          */
 /*   Send a command to the controller                                       */
 /*                                                                          */
+/* NOTE:                                                                    */
+/*    Linux obtains io_request_lock before calling this function            */
+/*                                                                          */
 /****************************************************************************/
 int
 ips_queue(Scsi_Cmnd *SC, void (*done) (Scsi_Cmnd *)) {
    ips_ha_t         *ha;
+   u32               cpu_flags;
+   DECLARE_MUTEX_LOCKED(sem);
 
    DBG("ips_queue");
 
@@ -949,19+1122,27 @@ ips_queue(Scsi_Cmnd *SC, void (*done) (Scsi_Cmnd *)) {
 
 #ifndef NO_IPS_CMDLINE
    if (ips_is_passthru(SC)) {
+      IPS_QUEUE_LOCK(&ha->copp_waitlist);
       if (ha->copp_waitlist.count == IPS_MAX_IOCTL_QUEUE) {
+         IPS_QUEUE_UNLOCK(&ha->copp_waitlist);
          SC->result = DID_BUS_BUSY << 16;
          done(SC);
 
          return (0);
+      } else {
+         IPS_QUEUE_UNLOCK(&ha->copp_waitlist);
       }
    } else {
 #endif
+      IPS_QUEUE_LOCK(&ha->scb_waitlist);
       if (ha->scb_waitlist.count == IPS_MAX_QUEUE) {
+         IPS_QUEUE_UNLOCK(&ha->scb_waitlist);
          SC->result = DID_BUS_BUSY << 16;
          done(SC);
 
          return (0);
+      } else {
+         IPS_QUEUE_UNLOCK(&ha->scb_waitlist);
       }
 
 #ifndef NO_IPS_CMDLINE
@@ -978,21+1159,82 @@ ips_queue(Scsi_Cmnd *SC, void (*done) (Scsi_Cmnd *)) {
           SC->target,
           SC->lun);
 #if IPS_DEBUG >= 11
-        MDELAY(2*ONE_SEC);
+        MDELAY(2*IPS_ONE_SEC);
 #endif
 #endif
 
 #ifndef NO_IPS_CMDLINE
-   if (ips_is_passthru(SC))
-      ips_putq_wait_tail(&ha->copp_waitlist, SC);
+   if (ips_is_passthru(SC)) {
+      ips_copp_wait_item_t *scratch;
+
+      /* allocate space for the scribble */
+      scratch = kmalloc(sizeof(ips_copp_wait_item_t), GFP_KERNEL);
+
+      if (!scratch) {
+         SC->result = DID_ERROR << 16;
+         done(SC);
+
+         return (0);
+      }
+
+      scratch->scsi_cmd = SC;
+      scratch->sem = &sem;
+      scratch->next = NULL;
+
+      ips_putq_copp_tail(&ha->copp_waitlist, scratch);
+   }
    else
 #endif
       ips_putq_wait_tail(&ha->scb_waitlist, SC);
 
+   IPS_HA_LOCK(cpu_flags);
    if ((!test_bit(IPS_IN_INTR, &ha->flags)) &&
        (!test_bit(IPS_IN_ABORT, &ha->flags)) &&
-       (!test_bit(IPS_IN_RESET, &ha->flags)))
-      ips_next(ha);
+       (!test_bit(IPS_IN_RESET, &ha->flags))) {
+      IPS_HA_UNLOCK(cpu_flags);
+      ips_next(ha, IPS_INTR_IORL);
+   } else {
+      IPS_HA_UNLOCK(cpu_flags);
+   }
+
+   /*
+    * If this request was a new style IOCTL wait
+    * for it to finish.
+    *
+    * NOTE: we relinquished the lock above so this should
+    * not cause contention problems
+    */
+   if (ips_is_passthru(SC) && SC->cmnd[0] == IPS_IOCTL_NEW_COMMAND) {
+      char *user_area;
+      char *kern_area;
+      u32   datasize;
+
+      /* free io_request_lock */
+      spin_unlock_irq(&io_request_lock);
+
+      /* wait for the command to finish */
+      down(&sem);
+
+      /* reobtain the lock */
+      spin_lock_irq(&io_request_lock);
+
+      /* command finished -- copy back */
+      user_area = *((char **) &SC->cmnd[4]);
+      kern_area = ha->ioctl_data;
+      datasize = *((u32 *) &SC->cmnd[8]);
+
+      if (copy_to_user(user_area, kern_area, datasize) > 0) {
+#if IPS_DEBUG_PT >= 1
+         printk(KERN_NOTICE "(%s%d) passthru failed - unable to copy out user data\n",
+                ips_name, ha->host_num);
+#endif
+
+         SC->result = DID_ERROR << 16;
+         SC->scsi_done(SC);
+      } else {
+         SC->scsi_done(SC);
+      }
+   }
 
    return (0);
 }
@@ -1024,17+1266,17 @@ ips_biosparam(Disk *disk, kdev_t dev, int geom[]) {
    if (!ha->active)
       return (0);
 
-   if (!ips_read_adapter_status(ha))
+   if (!ips_read_adapter_status(ha, IPS_INTR_ON))
       /* ?!?! Enquiry command failed */
       return (0);
 
    if ((disk->capacity > 0x400000) &&
        ((ha->enq->ucMiscFlag & 0x8) == 0)) {
-      heads = NORM_MODE_HEADS;
-      sectors = NORM_MODE_SECTORS;
+      heads = IPS_NORM_HEADS;
+      sectors = IPS_NORM_SECTORS;
    } else {
-      heads = COMP_MODE_HEADS;
-      sectors = COMP_MODE_SECTORS;
+      heads = IPS_COMP_HEADS;
+      sectors = IPS_COMP_SECTORS;
    }
 
    cylinders = disk->capacity / (heads * sectors);
@@ -1063,7+1305,7 @@ ips_biosparam(Disk *disk, kdev_t dev, int geom[]) {
 void
 do_ipsintr(int irq, void *dev_id, struct pt_regs *regs) {
    ips_ha_t         *ha;
-   unsigned int      cpu_flags;
+   u32               cpu_flags;
 
    DBG("do_ipsintr");
 
@@ -1096,6+1338,9 @@ do_ipsintr(int irq, void *dev_id, struct pt_regs *regs) {
    clear_bit(IPS_IN_INTR, &ha->flags);
 
    spin_unlock_irqrestore(&io_request_lock, cpu_flags);
+
+   /* start the next command */
+   ips_next(ha, IPS_INTR_ON);
 }
 
 /****************************************************************************/
@@ -1114,6+1359,7 @@ ips_intr(ips_ha_t *ha) {
    ips_stat_t       *sp;
    ips_scb_t        *scb;
    int               status;
+   u32               cpu_flags;
 
    DBG("ips_intr");
 
@@ -1123,6+1369,7 @@ ips_intr(ips_ha_t *ha) {
    if (!ha->active)
       return;
 
+   IPS_HA_LOCK(cpu_flags);
    while (ips_isintr(ha)) {
       sp = &ha->sp;
 
@@ -1139,10+1386,12 @@ ips_intr(ips_ha_t *ha) {
        * use the callback function to finish things up
        * NOTE: interrupts are OFF for this
        */
+      IPS_HA_UNLOCK(cpu_flags);
       (*scb->callback) (ha, scb);
+      IPS_HA_LOCK(cpu_flags);
    }
 
-   clear_bit(IPS_IN_INTR, &ha->flags);
+   IPS_HA_UNLOCK(cpu_flags);
 }
 
 /****************************************************************************/
@@ -1162,7+1411,7 @@ ips_info(struct Scsi_Host *SH) {
 
    DBG("ips_info");
 
-   ha = HA(SH);
+   ha = IPS_HA(SH);
 
    if (!ha)
       return (NULL);
@@ -1250,10+1499,10 @@ ips_is_passthru(Scsi_Cmnd *SC) {
    if (!SC)
       return (0);
 
-   if ((SC->channel == 0) &&
+   if (((SC->cmnd[0] == IPS_IOCTL_COMMAND) || (SC->cmnd[0] == IPS_IOCTL_NEW_COMMAND)) &&
+       (SC->channel == 0) &&
        (SC->target == IPS_ADAPTER_ID) &&
        (SC->lun == 0) &&
-       (SC->cmnd[0] == 0x0d) &&
        (SC->request_bufflen) &&
        (!SC->use_sg) &&
        (((char *) SC->request_buffer)[0] == 'C') &&
@@ -1268,7+1517,7 @@ ips_is_passthru(Scsi_Cmnd *SC) {
 
 /****************************************************************************/
 /*                                                                          */
-/* Routine Name: ips_is_passthru                                            */
+/* Routine Name: ips_make_passthru                                          */
 /*                                                                          */
 /* Routine Description:                                                     */
 /*                                                                          */
@@ -1315,17+1564,23 @@ ips_make_passthru(ips_ha_t *ha, Scsi_Cmnd *SC, ips_scb_t *scb) {
    }
 
    pt = (ips_passthru_t *) SC->request_buffer;
-   scb->scsi_cmd = SC;
 
-   if (SC->request_bufflen < (sizeof(ips_passthru_t) + pt->CmdBSize)) {
-      /* wrong size */
-#if IPS_DEBUG_PT >= 1
-      printk(KERN_NOTICE "(%s%d) Passthru structure wrong size\n",
-             ips_name, ha->host_num);
-#endif
-
-      return (IPS_FAILURE);
-   }
+   /*
+    * Some notes about the passthru interface used
+    *
+    * IF the scsi op_code == 0x0d then we assume
+    * that the data came along with/goes with the
+    * packet we received from the sg driver. In this
+    * case the CmdBSize field of the pt structure is
+    * used for the size of the buffer.
+    *
+    * IF the scsi op_code == 0x81 then we assume that
+    * we will need our own buffer and we will copy the
+    * data to/from the user buffer passed in the scsi
+    * command.  The data address resides at offset 4
+    * in the scsi command.  The length of the data resides
+    * at offset 8 in the scsi command.
+    */
 
    switch (pt->CoppCmd) {
    case IPS_NUMCTRLS:
@@ -1334,19+1589,128 @@ ips_make_passthru(ips_ha_t *ha, Scsi_Cmnd *SC, ips_scb_t *scb) {
       SC->result = DID_OK << 16;
 
       return (IPS_SUCCESS_IMM);
+
    case IPS_CTRLINFO:
       memcpy(SC->request_buffer + sizeof(ips_passthru_t),
              ha, sizeof(ips_ha_t));
       SC->result = DID_OK << 16;
 
       return (IPS_SUCCESS_IMM);
-   case COPPUSRCMD:
-      if (ips_usrcmd(ha, pt, scb))
-         return (IPS_SUCCESS);
-      else
-         return (IPS_FAILURE);
+
+   case IPS_COPPUSRCMD:
+   case IPS_COPPIOCCMD:
+      if (SC->cmnd[0] == IPS_IOCTL_COMMAND) {
+         if (SC->request_bufflen < (sizeof(ips_passthru_t) + pt->CmdBSize)) {
+            /* wrong size */
+   #if IPS_DEBUG_PT >= 1
+            printk(KERN_NOTICE "(%s%d) Passthru structure wrong size\n",
+                   ips_name, ha->host_num);
+   #endif
+
+            return (IPS_FAILURE);
+         }
+
+         if (ips_usrcmd(ha, pt, scb))
+            return (IPS_SUCCESS);
+         else
+            return (IPS_FAILURE);
+      } else if (SC->cmnd[0] == IPS_IOCTL_NEW_COMMAND) {
+         if (SC->request_bufflen < (sizeof(ips_passthru_t))) {
+            /* wrong size */
+   #if IPS_DEBUG_PT >= 1
+            printk(KERN_NOTICE "(%s%d) Passthru structure wrong size\n",
+                   ips_name, ha->host_num);
+   #endif
+
+            return (IPS_FAILURE);
+         }
+
+         if (ips_newusrcmd(ha, pt, scb))
+            return (IPS_SUCCESS);
+         else
+            return (IPS_FAILURE);
+      }
+
       break;
-   }
+
+   case IPS_FLASHBIOS:
+      /* we must use the new interface */
+      if (SC->cmnd[0] != IPS_IOCTL_NEW_COMMAND)
+         return (IPS_FAILURE);
+
+      /* don't flash the BIOS on future cards */
+      if (ha->revision_id > IPS_REVID_TROMBONE64) {
+#if IPS_DEBUG_PT >= 1
+         printk(KERN_NOTICE "(%s%d) flash bios failed - unsupported controller\n",
+                ips_name, ha->host_num);
+#endif
+         return (IPS_FAILURE);
+      }
+
+      /* copy in the size/buffer ptr from the scsi command */
+      memcpy(&pt->CmdBuffer, &SC->cmnd[4], 4);
+      memcpy(&pt->CmdBSize, &SC->cmnd[8], 4);
+
+      /* must have a buffer */
+      if ((!pt->CmdBSize) || (!pt->CmdBuffer))
+         return (IPS_FAILURE);
+
+      /* make sure buffer is big enough */
+      if (pt->CmdBSize > ha->ioctl_datasize) {
+         void *bigger_struct;
+
+         /* try to allocate a bigger struct */
+         bigger_struct = kmalloc(pt->CmdBSize, GFP_KERNEL|GFP_DMA);
+         if (bigger_struct) {
+            /* free the old memory */
+            kfree(ha->ioctl_data);
+
+            /* use the new memory */
+            ha->ioctl_data = bigger_struct;
+            ha->ioctl_datasize = pt->CmdBSize;
+         } else
+            return (IPS_FAILURE);
+      }
+
+      /* copy in the buffer */
+      if (copy_from_user(ha->ioctl_data, pt->CmdBuffer, pt->CmdBSize) > 0) {
+#if IPS_DEBUG_PT >= 1
+         printk(KERN_NOTICE "(%s%d) flash bios failed - unable to copy user buffer\n",
+                ips_name, ha->host_num);
+#endif
+
+         return (IPS_FAILURE);
+      }
+
+      if (ips_erase_bios(ha)) {
+#if IPS_DEBUG_PT >= 1
+         printk(KERN_NOTICE "(%s%d) flash bios failed - unable to erase flash\n",
+                ips_name, ha->host_num);
+#endif
+
+         return (IPS_FAILURE);
+      }
+
+      if (ips_program_bios(ha, ha->ioctl_data, pt->CmdBSize)) {
+#if IPS_DEBUG_PT >= 1
+         printk(KERN_NOTICE "(%s%d) flash bios failed - unable to program flash\n",
+                ips_name, ha->host_num);
+#endif
+
+         return (IPS_FAILURE);
+      }
+
+      if (ips_verify_bios(ha, ha->ioctl_data, pt->CmdBSize)) {
+#if IPS_DEBUG_PT >= 1
+         printk(KERN_NOTICE "(%s%d) flash bios failed - unable to verify flash\n",
+                ips_name, ha->host_num);
+#endif
+
+         return (IPS_FAILURE);
+      }
+
+      return (IPS_SUCCESS_IMM);
+   } /* end switch */
 
    return (IPS_FAILURE);
 }
@@ -1362,7+1726,7 @@ ips_make_passthru(ips_ha_t *ha, Scsi_Cmnd *SC, ips_scb_t *scb) {
 /****************************************************************************/
 static int
 ips_usrcmd(ips_ha_t *ha, ips_passthru_t *pt, ips_scb_t *scb) {
-   SG_LIST        *sg_list;
+   IPS_SG_LIST *sg_list;
 
    DBG("ips_usrcmd");
 
@@ -1373,15+1737,15 @@ ips_usrcmd(ips_ha_t *ha, ips_passthru_t *pt, ips_scb_t *scb) {
    sg_list = scb->sg_list;
 
    /* copy in the CP */
-   memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof(IOCTL_INFO));
-   memcpy(&scb->dcdb, &pt->CoppCP.dcdb, sizeof(DCDB_TABLE));
+   memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof(IPS_IOCTL_CMD));
+   memcpy(&scb->dcdb, &pt->CoppCP.dcdb, sizeof(IPS_DCDB_TABLE));
 
    /* FIX stuff that might be wrong */
    scb->sg_list = sg_list;
    scb->scb_busaddr = VIRT_TO_BUS(scb);
-   scb->bus = 0;
-   scb->target_id = 0;
-   scb->lun = 0;
+   scb->bus = scb->scsi_cmd->channel;
+   scb->target_id = scb->scsi_cmd->target;
+   scb->lun = scb->scsi_cmd->lun;
    scb->sg_len = 0;
    scb->data_len = 0;
    scb->flags = 0;
@@ -1391,9+1755,9 @@ ips_usrcmd(ips_ha_t *ha, ips_passthru_t *pt, ips_scb_t *scb) {
    scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
 
    /* we don't support DCDB/READ/WRITE Scatter Gather */
-   if ((scb->cmd.basic_io.op_code == READ_SCATTER_GATHER) ||
-       (scb->cmd.basic_io.op_code == WRITE_SCATTER_GATHER) ||
-       (scb->cmd.basic_io.op_code == DIRECT_CDB_SCATTER_GATHER))
+   if ((scb->cmd.basic_io.op_code == IPS_CMD_READ_SG) ||
+       (scb->cmd.basic_io.op_code == IPS_CMD_WRITE_SG) ||
+       (scb->cmd.basic_io.op_code == IPS_CMD_DCDB_SG))
       return (0);
 
    if (pt->CmdBSize) {
@@ -1402,13+1766,129 @@ ips_usrcmd(ips_ha_t *ha, ips_passthru_t *pt, ips_scb_t *scb) {
       scb->data_busaddr = 0L;
    }
 
+   if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
+      scb->cmd.dcdb.dcdb_address = VIRT_TO_BUS(&scb->dcdb);
+
    if (pt->CmdBSize) {
-      if (scb->cmd.dcdb.op_code == DIRECT_CDB) {
-         scb->cmd.dcdb.dcdb_address = VIRT_TO_BUS(&scb->dcdb);
+      if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
          scb->dcdb.buffer_pointer = scb->data_busaddr;
-      } else {
+      else
          scb->cmd.basic_io.sg_addr = scb->data_busaddr;
+   }
+
+   /* set timeouts */
+   if (pt->TimeOut) {
+      scb->timeout = pt->TimeOut;
+
+      if (pt->TimeOut <= 10)
+         scb->dcdb.cmd_attribute |= IPS_TIMEOUT10;
+      else if (pt->TimeOut <= 60)
+         scb->dcdb.cmd_attribute |= IPS_TIMEOUT60;
+      else
+         scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M;
+   }
+
+   /* assume success */
+   scb->scsi_cmd->result = DID_OK << 16;
+
+   /* success */
+   return (1);
+}
+
+/****************************************************************************/
+/*                                                                          */
+/* Routine Name: ips_newusrcmd                                              */
+/*                                                                          */
+/* Routine Description:                                                     */
+/*                                                                          */
+/*   Process a user command and make it ready to send                       */
+/*                                                                          */
+/****************************************************************************/
+static int
+ips_newusrcmd(ips_ha_t *ha, ips_passthru_t *pt, ips_scb_t *scb) {
+   IPS_SG_LIST    *sg_list;
+   char           *user_area;
+   char           *kern_area;
+   u32             datasize;
+
+   DBG("ips_usrcmd");
+
+   if ((!scb) || (!pt) || (!ha))
+      return (0);
+
+   /* Save the S/G list pointer so it doesn't get clobbered */
+   sg_list = scb->sg_list;
+
+   /* copy in the CP */
+   memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof(IPS_IOCTL_CMD));
+   memcpy(&scb->dcdb, &pt->CoppCP.dcdb, sizeof(IPS_DCDB_TABLE));
+
+   /* FIX stuff that might be wrong */
+   scb->sg_list = sg_list;
+   scb->scb_busaddr = VIRT_TO_BUS(scb);
+   scb->bus = scb->scsi_cmd->channel;
+   scb->target_id = scb->scsi_cmd->target;
+   scb->lun = scb->scsi_cmd->lun;
+   scb->sg_len = 0;
+   scb->data_len = 0;
+   scb->flags = 0;
+   scb->op_code = 0;
+   scb->callback = ipsintr_done;
+   scb->timeout = ips_cmd_timeout;
+   scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
+
+   /* we don't support DCDB/READ/WRITE Scatter Gather */
+   if ((scb->cmd.basic_io.op_code == IPS_CMD_READ_SG) ||
+       (scb->cmd.basic_io.op_code == IPS_CMD_WRITE_SG) ||
+       (scb->cmd.basic_io.op_code == IPS_CMD_DCDB_SG))
+      return (0);
+
+   if (pt->CmdBSize) {
+      if (pt->CmdBSize > ha->ioctl_datasize) {
+         void *bigger_struct;
+
+         /* try to allocate a bigger struct */
+         bigger_struct = kmalloc(pt->CmdBSize, GFP_KERNEL|GFP_DMA);
+         if (bigger_struct) {
+            /* free the old memory */
+            kfree(ha->ioctl_data);
+
+            /* use the new memory */
+            ha->ioctl_data = bigger_struct;
+            ha->ioctl_datasize = pt->CmdBSize;
+         } else
+            return (0);
+
       }
+
+      scb->data_busaddr = VIRT_TO_BUS(ha->ioctl_data);
+
+      /* Attempt to copy in the data */
+      user_area = *((char **) &scb->scsi_cmd->cmnd[4]);
+      kern_area = ha->ioctl_data;
+      datasize = *((u32 *) &scb->scsi_cmd->cmnd[8]);
+
+      if (copy_from_user(kern_area, user_area, datasize) > 0) {
+#if IPS_DEBUG_PT >= 1
+         printk(KERN_NOTICE "(%s%d) passthru failed - unable to copy in user data\n",
+                ips_name, ha->host_num);
+#endif
+
+         return (0);
+      }
+
+   } else {
+      scb->data_busaddr = 0L;
+   }
+
+   if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
+      scb->cmd.dcdb.dcdb_address = VIRT_TO_BUS(&scb->dcdb);
+
+   if (pt->CmdBSize) {
+      if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
+         scb->dcdb.buffer_pointer = scb->data_busaddr;
+      else
+         scb->cmd.basic_io.sg_addr = scb->data_busaddr;
    }
 
    /* set timeouts */
@@ -1416,15+1896,15 @@ ips_usrcmd(ips_ha_t *ha, ips_passthru_t *pt, ips_scb_t *scb) {
       scb->timeout = pt->TimeOut;
 
       if (pt->TimeOut <= 10)
-         scb->dcdb.cmd_attribute |= TIMEOUT_10;
+         scb->dcdb.cmd_attribute |= IPS_TIMEOUT10;
       else if (pt->TimeOut <= 60)
-         scb->dcdb.cmd_attribute |= TIMEOUT_60;
+         scb->dcdb.cmd_attribute |= IPS_TIMEOUT60;
       else
-         scb->dcdb.cmd_attribute |= TIMEOUT_20M;
+         scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M;
    }
 
-   /* assume error */
-   scb->scsi_cmd->result = DID_ERROR << 16;
+   /* assume success */
+   scb->scsi_cmd->result = DID_OK << 16;
 
    /* success */
    return (1);
@@ -1440,7+1920,7 @@ ips_usrcmd(ips_ha_t *ha, ips_passthru_t *pt, ips_scb_t *scb) {
 /*                                                                          */
 /****************************************************************************/
 static void
-ips_cleanup_passthru(ips_scb_t *scb) {
+ips_cleanup_passthru(ips_ha_t *ha, ips_scb_t *scb) {
    ips_passthru_t *pt;
 
    DBG("ips_cleanup_passthru");
@@ -1456,10+1936,15 @@ ips_cleanup_passthru(ips_scb_t *scb) {
    pt = (ips_passthru_t *) scb->scsi_cmd->request_buffer;
 
    /* Copy data back to the user */
-   pt->BasicStatus = scb->basic_status;
-   pt->ExtendedStatus = scb->extended_status;
-
-   scb->scsi_cmd->result = DID_OK << 16;
+   if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_COMMAND) {
+      /* Copy data back to the user */
+      pt->BasicStatus = scb->basic_status;
+      pt->ExtendedStatus = scb->extended_status;
+   } else {
+      pt->BasicStatus = scb->basic_status;
+      pt->ExtendedStatus = scb->extended_status;
+      up(scb->sem);
+   }
 }
 
 #endif
@@ -1475,7+1960,7 @@ ips_cleanup_passthru(ips_scb_t *scb) {
 /****************************************************************************/
 static int
 ips_host_info(ips_ha_t *ha, char *ptr, off_t offset, int len) {
-   INFOSTR info;
+   IPS_INFOSTR info;
 
    DBG("ips_host_info");
 
@@ -1486,7+1971,7 @@ ips_host_info(ips_ha_t *ha, char *ptr, off_t offset, int len) {
 
    copy_info(&info, "\nIBM ServeRAID General Information:\n\n");
 
-   if ((ha->nvram->signature == NVRAM_PAGE5_SIGNATURE) &&
+   if ((ha->nvram->signature == IPS_NVRAM_P5_SIG) &&
        (ha->nvram->adapter_type != 0))
       copy_info(&info, "\tController Type                   : %s\n", ips_adapter_name[ha->ad_type-1]);
    else
@@ -1495,7+1980,7 @@ ips_host_info(ips_ha_t *ha, char *ptr, off_t offset, int len) {
    copy_info(&info, "\tIO port address                   : 0x%lx\n", ha->io_addr);
    copy_info(&info, "\tIRQ number                        : %d\n", ha->irq);
 
-   if (ha->nvram->signature == NVRAM_PAGE5_SIGNATURE)
+   if (ha->nvram->signature == IPS_NVRAM_P5_SIG)
       copy_info(&info, "\tBIOS Version                      : %c%c%c%c%c%c%c%c\n",
                 ha->nvram->bios_high[0], ha->nvram->bios_high[1],
                 ha->nvram->bios_high[2], ha->nvram->bios_high[3],
@@ -1541,11+2026,11 @@ ips_host_info(ips_ha_t *ha, char *ptr, off_t offset, int len) {
 /*                                                                          */
 /* Routine Description:                                                     */
 /*                                                                          */
-/*   Copy data into an INFOSTR structure                                    */
+/*   Copy data into an IPS_INFOSTR structure                                */
 /*                                                                          */
 /****************************************************************************/
 static void
-copy_mem_info(INFOSTR *info, char *data, int len) {
+copy_mem_info(IPS_INFOSTR *info, char *data, int len) {
    DBG("copy_mem_info");
 
    if (info->pos + len > info->length)
@@ -1577,7+2062,7 @@ copy_mem_info(INFOSTR *info, char *data, int len) {
 /*                                                                          */
 /****************************************************************************/
 static int
-copy_info(INFOSTR *info, char *fmt, ...) {
+copy_info(IPS_INFOSTR *info, char *fmt, ...) {
    va_list args;
    char buf[81];
    int len;
@@ -1616,11+2101,15 @@ ips_hainit(ips_ha_t *ha) {
    /* initialize status queue */
    ips_statinit(ha);
 
+   ha->reset_count = 1;
+
    /* Setup HBA ID's */
-   if (!ips_read_config(ha)) {
+   if (!ips_read_config(ha, IPS_INTR_IORL)) {
 
 #ifndef NO_IPS_RESET
 
+      ha->reset_count++;
+
       /* Try to reset the controller and try again */
       if (!ips_reset_adapter(ha)) {
          printk(KERN_WARNING "(%s%d) unable to reset controller.\n",
@@ -1629,7+2118,7 @@ ips_hainit(ips_ha_t *ha) {
          return (0);
       }
 
-      if (!ips_clear_adapter(ha)) {
+      if (!ips_clear_adapter(ha, IPS_INTR_IORL)) {
          printk(KERN_WARNING "(%s%d) unable to initialize controller.\n",
                 ips_name, ha->host_num);
 
@@ -1638,7+2127,7 @@ ips_hainit(ips_ha_t *ha) {
 
 #endif
 
-      if (!ips_read_config(ha)) {
+      if (!ips_read_config(ha, IPS_INTR_IORL)) {
          printk(KERN_WARNING "(%s%d) unable to read config from controller.\n",
                 ips_name, ha->host_num);
 
@@ -1647,31+2136,40 @@ ips_hainit(ips_ha_t *ha) {
    } /* end if */
 
    /* write driver version */
-   if (!ips_write_driver_status(ha)) {
+   if (!ips_write_driver_status(ha, IPS_INTR_IORL)) {
       printk(KERN_WARNING "(%s%d) unable to write driver info to controller.\n",
              ips_name, ha->host_num);
 
       return (0);
    }
 
-   if (!ips_read_adapter_status(ha)) {
+   if (!ips_read_adapter_status(ha, IPS_INTR_IORL)) {
       printk(KERN_WARNING "(%s%d) unable to read controller status.\n",
              ips_name, ha->host_num);
 
       return (0);
    }
 
-   if (!ips_read_subsystem_parameters(ha)) {
+   if (!ips_read_subsystem_parameters(ha, IPS_INTR_IORL)) {
       printk(KERN_WARNING "(%s%d) unable to read subsystem parameters.\n",
              ips_name, ha->host_num);
 
       return (0);
    }
 
+   /* FFDC */
+   if (ha->subsys->param[3] & 0x300000) {
+      struct timeval tv;
+
+      do_gettimeofday(&tv);
+      ha->last_ffdc = tv.tv_sec;
+      ips_ffdc_reset(ha, IPS_INTR_IORL);
+   }
+
    /* set limits on SID, LUN, BUS */
-   ha->ntargets = MAX_TARGETS + 1;
+   ha->ntargets = IPS_MAX_TARGETS + 1;
    ha->nlun = 1;
-   ha->nbus = (ha->enq->ucMaxPhysicalDevices / MAX_TARGETS);
+   ha->nbus = (ha->enq->ucMaxPhysicalDevices / IPS_MAX_TARGETS);
 
    switch (ha->conf->logical_drive[0].ucStripeSize) {
    case 4:
@@ -1736,21+2234,55 @@ ips_hainit(ips_ha_t *ha) {
 /*                                                                          */
 /*   Take the next command off the queue and send it to the controller      */
 /*                                                                          */
-/* ASSUMED to be called from within a lock                                  */
-/*                                                                          */
 /****************************************************************************/
 static void
-ips_next(ips_ha_t *ha) {
-   ips_scb_t    *scb;
-   Scsi_Cmnd    *SC;
-   Scsi_Cmnd    *p;
-   int           ret;
+ips_next(ips_ha_t *ha, int intr) {
+   ips_scb_t            *scb;
+   Scsi_Cmnd            *SC;
+   Scsi_Cmnd            *p;
+   ips_copp_wait_item_t *item;
+   int                   ret;
+   int                   intr_status;
+   u32                   cpu_flags;
+   u32                   cpu_flags2;
 
    DBG("ips_next");
 
    if (!ha)
       return ;
 
+   /*
+    * Block access to the queue function so
+    * this command won't time out
+    */
+   if (intr == IPS_INTR_ON) {
+       spin_lock_irqsave(&io_request_lock, cpu_flags2);
+       intr_status = IPS_INTR_IORL;
+   } else {
+       intr_status = intr;
+
+       /* Quiet the compiler */
+       cpu_flags2 = 0;
+   }
+
+   if (ha->subsys->param[3] & 0x300000) {
+      struct timeval tv;
+
+      do_gettimeofday(&tv);
+
+      IPS_HA_LOCK(cpu_flags);
+      if (tv.tv_sec - ha->last_ffdc > IPS_SECS_8HOURS) {
+         ha->last_ffdc = tv.tv_sec;
+         IPS_HA_UNLOCK(cpu_flags);
+         ips_ffdc_time(ha, intr_status);
+      } else {
+         IPS_HA_UNLOCK(cpu_flags);
+      }
+   }
+
+   if (intr == IPS_INTR_ON)
+       spin_unlock_irqrestore(&io_request_lock, cpu_flags2);
+
 #ifndef NO_IPS_CMDLINE
    /*
     * Send passthru commands
@@ -1759,32+2291,50 @@ ips_next(ips_ha_t *ha) {
     * since we limit the number that can be active
     * on the card at any one time
     */
+   IPS_HA_LOCK(cpu_flags);
+   IPS_QUEUE_LOCK(&ha->copp_waitlist);
    while ((ha->num_ioctl < IPS_MAX_IOCTL) &&
           (ha->copp_waitlist.head) &&
           (scb = ips_getscb(ha))) {
-      SC = ips_removeq_wait_head(&ha->copp_waitlist);
 
-      ret = ips_make_passthru(ha, SC, scb);
+      IPS_QUEUE_UNLOCK(&ha->copp_waitlist);
+      IPS_HA_UNLOCK(cpu_flags);
+      item = ips_removeq_copp_head(&ha->copp_waitlist);
+      scb->scsi_cmd = item->scsi_cmd;
+      scb->sem = item->sem;
+      kfree(item);
+
+      ret = ips_make_passthru(ha, scb->scsi_cmd, scb);
 
       switch (ret) {
       case IPS_FAILURE:
          if (scb->scsi_cmd) {
+            /* raise the semaphore */
+            if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_NEW_COMMAND)
+               up(scb->sem);
+
             scb->scsi_cmd->result = DID_ERROR << 16;
-            scb->scsi_cmd->scsi_done(scb->scsi_cmd);
          }
          ips_freescb(ha, scb);
          break;
       case IPS_SUCCESS_IMM:
-         if (scb->scsi_cmd)
-            scb->scsi_cmd->scsi_done(scb->scsi_cmd);
+         if (scb->scsi_cmd) {
+            /* raise the semaphore */
+            if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_NEW_COMMAND)
+               up(scb->sem);
+         }
+
          ips_freescb(ha, scb);
          break;
       default:
          break;
       } /* end case */
 
-      if (ret != IPS_SUCCESS)
+      if (ret != IPS_SUCCESS) {
+         IPS_HA_LOCK(cpu_flags);
+         IPS_QUEUE_LOCK(&ha->copp_waitlist);
          continue;
+      }
 
       ret = ips_send_cmd(ha, scb);
 
@@ -1796,27+2346,43 @@ ips_next(ips_ha_t *ha) {
       switch(ret) {
       case IPS_FAILURE:
          if (scb->scsi_cmd) {
+            /* raise the semaphore */
+            if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_NEW_COMMAND)
+               up(scb->sem);
+
             scb->scsi_cmd->result = DID_ERROR << 16;
-            scb->scsi_cmd->scsi_done(scb->scsi_cmd);
          }
 
          ips_freescb(ha, scb);
          break;
       case IPS_SUCCESS_IMM:
-         if (scb->scsi_cmd)
-            scb->scsi_cmd->scsi_done(scb->scsi_cmd);
+         if (scb->scsi_cmd) {
+            /* raise the semaphore */
+            if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_NEW_COMMAND)
+               up(scb->sem);
+         }
+
          ips_freescb(ha, scb);
          break;
       default:
          break;
       } /* end case */
+
+      IPS_HA_LOCK(cpu_flags);
+      IPS_QUEUE_LOCK(&ha->copp_waitlist);
    }
+
+   IPS_QUEUE_UNLOCK(&ha->copp_waitlist);
+   IPS_HA_UNLOCK(cpu_flags);
 #endif
 
    /*
     * Send "Normal" I/O commands
     */
+   IPS_HA_LOCK(cpu_flags);
+   IPS_QUEUE_LOCK(&ha->scb_waitlist);
    p = ha->scb_waitlist.head;
+   IPS_QUEUE_UNLOCK(&ha->scb_waitlist);
    while ((p) && (scb = ips_getscb(ha))) {
       if ((p->channel > 0) && (ha->dcdb_active[p->channel-1] & (1 << p->target))) {
          ips_freescb(ha, scb);
@@ -1824,6+2390,8 @@ ips_next(ips_ha_t *ha) {
          continue;
       }
 
+      IPS_HA_UNLOCK(cpu_flags);
+
       SC = ips_removeq_wait(&ha->scb_waitlist, p);
 
       SC->result = DID_OK;
@@ -1904,7+2472,7 @@ ips_next(ips_ha_t *ha) {
          scb->dcdb.transfer_length = 0;
 
       if (scb->data_len >= IPS_MAX_XFER) {
-         scb->dcdb.cmd_attribute |= TRANSFER_64K;
+         scb->dcdb.cmd_attribute |= IPS_TRANSFER64K;
          scb->dcdb.transfer_length = 0;
       }
 
@@ -1939,7+2507,11 @@ ips_next(ips_ha_t *ha) {
       } /* end case */
 
       p = (Scsi_Cmnd *) p->host_scribble;
+
+      IPS_HA_LOCK(cpu_flags);
    } /* end while */
+
+   IPS_HA_UNLOCK(cpu_flags);
 }
 
 /****************************************************************************/
@@ -1960,6+2532,8 @@ ips_putq_scb_head(ips_scb_queue_t *queue, ips_scb_t *item) {
    if (!item)
       return ;
 
+   IPS_QUEUE_LOCK(queue);
+
    item->q_next = queue->head;
    queue->head = item;
 
@@ -1967,6+2541,8 @@ ips_putq_scb_head(ips_scb_queue_t *queue, ips_scb_t *item) {
       queue->tail = item;
 
    queue->count++;
+
+   IPS_QUEUE_UNLOCK(queue);
 }
 
 /****************************************************************************/
@@ -1987,6+2563,8 @@ ips_putq_scb_tail(ips_scb_queue_t *queue, ips_scb_t *item) {
    if (!item)
       return ;
 
+   IPS_QUEUE_LOCK(queue);
+
    item->q_next = NULL;
 
    if (queue->tail)
@@ -1998,6+2576,8 @@ ips_putq_scb_tail(ips_scb_queue_t *queue, ips_scb_t *item) {
       queue->head = item;
 
    queue->count++;
+
+   IPS_QUEUE_UNLOCK(queue);
 }
 
 /****************************************************************************/
@@ -2017,10+2597,15 @@ ips_removeq_scb_head(ips_scb_queue_t *queue) {
 
    DBG("ips_removeq_scb_head");
 
+   IPS_QUEUE_LOCK(queue);
+
    item = queue->head;
 
-   if (!item)
+   if (!item) {
+      IPS_QUEUE_UNLOCK(queue);
+
       return (NULL);
+   }
 
    queue->head = item->q_next;
    item->q_next = NULL;
@@ -2030,6+2615,8 @@ ips_removeq_scb_head(ips_scb_queue_t *queue) {
 
    queue->count--;
 
+   IPS_QUEUE_UNLOCK(queue);
+
    return (item);
 }
 
@@ -2048,38+2635,206 @@ static inline ips_scb_t *
 ips_removeq_scb(ips_scb_queue_t *queue, ips_scb_t *item) {
    ips_scb_t  *p;
 
-   DBG("ips_removeq_scb");
+   DBG("ips_removeq_scb");
+
+   if (!item)
+      return (NULL);
+
+   IPS_QUEUE_LOCK(queue);
+
+   if (item == queue->head) {
+      IPS_QUEUE_UNLOCK(queue);
+
+      return (ips_removeq_scb_head(queue));
+   }
+
+   p = queue->head;
+
+   while ((p) && (item != p->q_next))
+      p = p->q_next;
+
+   if (p) {
+      /* found a match */
+      p->q_next = item->q_next;
+
+      if (!item->q_next)
+         queue->tail = p;
+
+      item->q_next = NULL;
+      queue->count--;
+
+      IPS_QUEUE_UNLOCK(queue);
+
+      return (item);
+   }
+
+   IPS_QUEUE_UNLOCK(queue);
+
+   return (NULL);
+}
+
+/****************************************************************************/
+/*                                                                          */
+/* Routine Name: ips_putq_wait_head                                         */
+/*                                                                          */
+/* Routine Description:                                                     */
+/*                                                                          */
+/*   Add an item to the head of the queue                                   */
+/*                                                                          */
+/* ASSUMED to be called from within a lock                                  */
+/*                                                                          */
+/****************************************************************************/
+static inline void
+ips_putq_wait_head(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
+   DBG("ips_putq_wait_head");
+
+   if (!item)
+      return ;
+
+   IPS_QUEUE_LOCK(queue);
+
+   item->host_scribble = (char *) queue->head;
+   queue->head = item;
+
+   if (!queue->tail)
+      queue->tail = item;
+
+   queue->count++;
+
+   IPS_QUEUE_UNLOCK(queue);
+}
+
+/****************************************************************************/
+/*                                                                          */
+/* Routine Name: ips_putq_wait_tail                                         */
+/*                                                                          */
+/* Routine Description:                                                     */
+/*                                                                          */
+/*   Add an item to the tail of the queue                                   */
+/*                                                                          */
+/* ASSUMED to be called from within a lock                                  */
+/*                                                                          */
+/****************************************************************************/
+static inline void
+ips_putq_wait_tail(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
+   DBG("ips_putq_wait_tail");
+
+   if (!item)
+      return ;
+
+   IPS_QUEUE_LOCK(queue);
+
+   item->host_scribble = NULL;
+
+   if (queue->tail)
+      queue->tail->host_scribble = (char *)item;
+
+   queue->tail = item;
+
+   if (!queue->head)
+      queue->head = item;
+
+   queue->count++;
+
+   IPS_QUEUE_UNLOCK(queue);
+}
+
+/****************************************************************************/
+/*                                                                          */
+/* Routine Name: ips_removeq_wait_head                                      */
+/*                                                                          */
+/* Routine Description:                                                     */
+/*                                                                          */
+/*   Remove the head of the queue                                           */
+/*                                                                          */
+/* ASSUMED to be called from within a lock                                  */
+/*                                                                          */
+/****************************************************************************/
+static inline Scsi_Cmnd *
+ips_removeq_wait_head(ips_wait_queue_t *queue) {
+   Scsi_Cmnd  *item;
+
+   DBG("ips_removeq_wait_head");
+
+   IPS_QUEUE_LOCK(queue);
+
+   item = queue->head;
+
+   if (!item) {
+      IPS_QUEUE_UNLOCK(queue);
+
+      return (NULL);
+   }
+
+   queue->head = (Scsi_Cmnd *) item->host_scribble;
+   item->host_scribble = NULL;
+
+   if (queue->tail == item)
+      queue->tail = NULL;
+
+   queue->count--;
+
+   IPS_QUEUE_UNLOCK(queue);
+
+   return (item);
+}
+
+/****************************************************************************/
+/*                                                                          */
+/* Routine Name: ips_removeq_wait                                           */
+/*                                                                          */
+/* Routine Description:                                                     */
+/*                                                                          */
+/*   Remove an item from a queue                                            */
+/*                                                                          */
+/* ASSUMED to be called from within a lock                                  */
+/*                                                                          */
+/****************************************************************************/
+static inline Scsi_Cmnd *
+ips_removeq_wait(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
+   Scsi_Cmnd  *p;
+
+   DBG("ips_removeq_wait");
 
    if (!item)
       return (NULL);
 
-   if (item == queue->head)
-      return (ips_removeq_scb_head(queue));
+   IPS_QUEUE_LOCK(queue);
+
+   if (item == queue->head) {
+      IPS_QUEUE_UNLOCK(queue);
+
+      return (ips_removeq_wait_head(queue));
+   }
 
    p = queue->head;
 
-   while ((p) && (item != p->q_next))
-      p = p->q_next;
+   while ((p) && (item != (Scsi_Cmnd *) p->host_scribble))
+      p = (Scsi_Cmnd *) p->host_scribble;
 
    if (p) {
       /* found a match */
-      p->q_next = item->q_next;
+      p->host_scribble = item->host_scribble;
 
-      if (!item->q_next)
+      if (!item->host_scribble)
          queue->tail = p;
 
-      item->q_next = NULL;
+      item->host_scribble = NULL;
       queue->count--;
 
+      IPS_QUEUE_UNLOCK(queue);
+
       return (item);
    }
 
+   IPS_QUEUE_UNLOCK(queue);
+
    return (NULL);
 }
 
 /****************************************************************************/
 /*                                                                          */
-/* Routine Name: ips_putq_wait_head                                         */
+/* Routine Name: ips_putq_copp_head                                         */
 /*                                                                          */
 /* Routine Description:                                                     */
 /*                                                                          */
@@ -2089,24+2844,28 @@ ips_removeq_scb(ips_scb_queue_t *queue, ips_scb_t *item) {
 /*                                                                          */
 /****************************************************************************/
 static inline void
-ips_putq_wait_head(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
-   DBG("ips_putq_wait_head");
+ips_putq_copp_head(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) {
+   DBG("ips_putq_copp_head");
 
    if (!item)
       return ;
 
-   item->host_scribble = (char *) queue->head;
+   IPS_QUEUE_LOCK(queue);
+
+   item->next = queue->head;
    queue->head = item;
 
    if (!queue->tail)
       queue->tail = item;
 
    queue->count++;
+
+   IPS_QUEUE_UNLOCK(queue);
 }
 
 /****************************************************************************/
 /*                                                                          */
-/* Routine Name: ips_putq_wait_tail                                         */
+/* Routine Name: ips_putq_copp_tail                                         */
 /*                                                                          */
 /* Routine Description:                                                     */
 /*                                                                          */
@@ -2116,16+2875,18 @@ ips_putq_wait_head(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
 /*                                                                          */
 /****************************************************************************/
 static inline void
-ips_putq_wait_tail(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
-   DBG("ips_putq_wait_tail");
+ips_putq_copp_tail(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) {
+   DBG("ips_putq_copp_tail");
 
    if (!item)
       return ;
 
-   item->host_scribble = NULL;
+   IPS_QUEUE_LOCK(queue);
+
+   item->next = NULL;
 
    if (queue->tail)
-      queue->tail->host_scribble = (char *)item;
+      queue->tail->next = item;
 
    queue->tail = item;
 
@@ -2133,11+2894,13 @@ ips_putq_wait_tail(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
       queue->head = item;
 
    queue->count++;
+
+   IPS_QUEUE_UNLOCK(queue);
 }
 
 /****************************************************************************/
 /*                                                                          */
-/* Routine Name: ips_removeq_wait_head                                      */
+/* Routine Name: ips_removeq_copp_head                                      */
 /*                                                                          */
 /* Routine Description:                                                     */
 /*                                                                          */
@@ -2146,31+2909,38 @@ ips_putq_wait_tail(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
 /* ASSUMED to be called from within a lock                                  */
 /*                                                                          */
 /****************************************************************************/
-static inline Scsi_Cmnd *
-ips_removeq_wait_head(ips_wait_queue_t *queue) {
-   Scsi_Cmnd  *item;
+static inline ips_copp_wait_item_t *
+ips_removeq_copp_head(ips_copp_queue_t *queue) {
+   ips_copp_wait_item_t *item;
 
-   DBG("ips_removeq_wait_head");
+   DBG("ips_removeq_copp_head");
+
+   IPS_QUEUE_LOCK(queue);
 
    item = queue->head;
 
-   if (!item)
+   if (!item) {
+      IPS_QUEUE_UNLOCK(queue);
+
       return (NULL);
+   }
 
-   queue->head = (Scsi_Cmnd *) item->host_scribble;
-   item->host_scribble = NULL;
+   queue->head = item->next;
+   item->next = NULL;
 
    if (queue->tail == item)
       queue->tail = NULL;
 
    queue->count--;
 
+   IPS_QUEUE_UNLOCK(queue);
+
    return (item);
 }
 
 /****************************************************************************/
 /*                                                                          */
-/* Routine Name: ips_removeq_wait                                           */
+/* Routine Name: ips_removeq_copp                                           */
 /*                                                                          */
 /* Routine Description:                                                     */
 /*                                                                          */
@@ -2179,36+2949,45 @@ ips_removeq_wait_head(ips_wait_queue_t *queue) {
 /* ASSUMED to be called from within a lock                                  */
 /*                                                                          */
 /****************************************************************************/
-static inline Scsi_Cmnd *
-ips_removeq_wait(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
-   Scsi_Cmnd  *p;
+static inline ips_copp_wait_item_t *
+ips_removeq_copp(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) {
+   ips_copp_wait_item_t *p;
 
-   DBG("ips_removeq_wait");
+   DBG("ips_removeq_copp");
 
    if (!item)
       return (NULL);
 
-   if (item == queue->head)
-      return (ips_removeq_wait_head(queue));
+   IPS_QUEUE_LOCK(queue);
+
+   if (item == queue->head) {
+      IPS_QUEUE_UNLOCK(queue);
+
+      return (ips_removeq_copp_head(queue));
+   }
 
    p = queue->head;
 
-   while ((p) && (item != (Scsi_Cmnd *) p->host_scribble))
-      p = (Scsi_Cmnd *) p->host_scribble;
+   while ((p) && (item != p->next))
+      p = p->next;
 
    if (p) {
       /* found a match */
-      p->host_scribble = item->host_scribble;
+      p->next = item->next;
 
-      if (!item->host_scribble)
+      if (!item->next)
          queue->tail = p;
 
-      item->host_scribble = NULL;
+      item->next = NULL;
       queue->count--;
 
+      IPS_QUEUE_UNLOCK(queue);
+
       return (item);
    }
 
+   IPS_QUEUE_UNLOCK(queue);
+
    return (NULL);
 }
 
@@ -2269,6+3048,7 @@ ipsintr_done(ips_ha_t *ha, ips_scb_t *scb) {
 static void
 ips_done(ips_ha_t *ha, ips_scb_t *scb) {
    int ret;
+   u32 cpu_flags;
 
    DBG("ips_done");
 
@@ -2277,8+3057,10 @@ ips_done(ips_ha_t *ha, ips_scb_t *scb) {
 
 #ifndef NO_IPS_CMDLINE
    if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd))) {
-      ips_cleanup_passthru(scb);
+      ips_cleanup_passthru(ha, scb);
+      IPS_HA_LOCK(cpu_flags);
       ha->num_ioctl--;
+      IPS_HA_UNLOCK(cpu_flags);
    } else {
 #endif
       /*
@@ -2342,11+3124,12 @@ ips_done(ips_ha_t *ha, ips_scb_t *scb) {
 
          scb->dcdb.cmd_attribute |=
             ips_command_direction[scb->scsi_cmd->cmnd[0]];
-  
+
          if (!scb->dcdb.cmd_attribute & 0x3)
             scb->dcdb.transfer_length = 0;
+
          if (scb->data_len >= IPS_MAX_XFER) {
-            scb->dcdb.cmd_attribute |= TRANSFER_64K;
+            scb->dcdb.cmd_attribute |= IPS_TRANSFER64K;
             scb->dcdb.transfer_length = 0;
          }
 
@@ -2379,15+3162,17 @@ ips_done(ips_ha_t *ha, ips_scb_t *scb) {
    } /* end if passthru */
 #endif
 
-   if (scb->bus)
+   if (scb->bus) {
+      IPS_HA_LOCK(cpu_flags);
       ha->dcdb_active[scb->bus-1] &= ~(1 << scb->target_id);
+      IPS_HA_UNLOCK(cpu_flags);
+   }
 
    /* call back to SCSI layer */
-   scb->scsi_cmd->scsi_done(scb->scsi_cmd);
-   ips_freescb(ha, scb);
+   if (scb->scsi_cmd && scb->scsi_cmd->cmnd[0] != IPS_IOCTL_NEW_COMMAND)
+      scb->scsi_cmd->scsi_done(scb->scsi_cmd);
 
-   /* do the next command */
-   ips_next(ha);
+   ips_freescb(ha, scb);
 }
 
 /****************************************************************************/
@@ -2426,19+3211,19 @@ ips_map_status(ips_scb_t *scb, ips_stat_t *sp) {
    /* default driver error */
    errcode = DID_ERROR;
 
-   switch (scb->basic_status & GSC_STATUS_MASK) {
-   case CMD_TIMEOUT:
+   switch (scb->basic_status & IPS_GSC_STATUS_MASK) {
+   case IPS_CMD_TIMEOUT:
       errcode = DID_TIME_OUT;
       break;
 
-   case INVAL_OPCO:
-   case INVAL_CMD_BLK:
-   case INVAL_PARM_BLK:
-   case LOG_DRV_ERROR:
-   case CMD_CMPLT_WERROR:
+   case IPS_INVAL_OPCO:
+   case IPS_INVAL_CMD_BLK:
+   case IPS_INVAL_PARM_BLK:
+   case IPS_LD_ERROR:
+   case IPS_CMD_CMPLT_WERROR:
       break;
 
-   case PHYS_DRV_ERROR:
+   case IPS_PHYS_DRV_ERROR:
       /*
        * For physical drive errors that
        * are not on a logical drive should
@@ -2449,14+3234,14 @@ ips_map_status(ips_scb_t *scb, ips_stat_t *sp) {
          errcode = DID_OK;
 
       switch (scb->extended_status) {
-      case SELECTION_TIMEOUT:
+      case IPS_ERR_SEL_TO:
          if (scb->bus) {
             scb->scsi_cmd->result |= DID_TIME_OUT << 16;
 
             return (0);
          }
          break;
-      case DATA_OVER_UNDER_RUN:
+      case IPS_ERR_OU_RUN:
          if ((scb->bus) && (scb->dcdb.transfer_length < scb->data_len)) {
             if ((scb->scsi_cmd->cmnd[0] == INQUIRY) &&
                 ((((char *) scb->scsi_cmd->buffer)[0] & 0x1f) == TYPE_DISK)) {
@@ -2475,7+3260,7 @@ ips_map_status(ips_scb_t *scb, ips_stat_t *sp) {
          }
 
          break;
-      case EXT_RECOVERY:
+      case IPS_ERR_RECOVERY:
          /* don't fail recovered errors */
          if (scb->bus) {
             scb->scsi_cmd->result |= DID_OK << 16;
@@ -2484,12+3269,12 @@ ips_map_status(ips_scb_t *scb, ips_stat_t *sp) {
          }
          break;
 
-      case EXT_HOST_RESET:
-      case EXT_DEVICE_RESET:
+      case IPS_ERR_HOST_RESET:
+      case IPS_ERR_DEV_RESET:
          errcode = DID_RESET;
          break;
 
-      case EXT_CHECK_CONDITION:
+      case IPS_ERR_CKCOND:
          break;
       } /* end switch */
    } /* end switch */
@@ -2509,7+3294,7 @@ ips_map_status(ips_scb_t *scb, ips_stat_t *sp) {
 /*                                                                          */
 /****************************************************************************/
 static int
-ips_send(ips_ha_t *ha, ips_scb_t *scb, scb_callback callback) {
+ips_send(ips_ha_t *ha, ips_scb_t *scb, ips_scb_callback callback) {
    int ret;
 
    DBG("ips_send");
@@ -2531,7+3316,7 @@ ips_send(ips_ha_t *ha, ips_scb_t *scb, scb_callback callback) {
 /*                                                                          */
 /****************************************************************************/
 static int
-ips_send_wait(ips_ha_t *ha, ips_scb_t *scb, int timeout) {
+ips_send_wait(ips_ha_t *ha, ips_scb_t *scb, int timeout, int intr) {
    int       ret;
 
    DBG("ips_send_wait");
@@ -2544,7+3329,7 @@ ips_send_wait(ips_ha_t *ha, ips_scb_t *scb, int timeout) {
    if ((ret == IPS_FAILURE) || (ret == IPS_SUCCESS_IMM))
       return (ret);
 
-   ret = ips_wait(ha, timeout, IPS_INTR_OFF);
+   ret = ips_wait(ha, timeout, intr);
 
    return (ret);
 }
@@ -2610,9+3395,9 @@ ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) {
                scb->scsi_cmd->result = DID_OK << 16;
 
             if (scb->scsi_cmd->cmnd[0] == INQUIRY) {
-               IPS_INQUIRYDATA inq;
+               IPS_INQ_DATA inq;
 
-               memset(&inq, 0, sizeof(IPS_INQUIRYDATA));
+               memset(&inq, 0, sizeof(IPS_INQ_DATA));
 
                inq.DeviceType = TYPE_PROCESSOR;
                inq.DeviceTypeQualifier = 0;
@@ -2628,7+3413,7 @@ ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) {
                scb->scsi_cmd->result = DID_OK << 16;
             }
          } else {
-            scb->cmd.logical_info.op_code = GET_LOGICAL_DRIVE_INFO;
+            scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO;
             scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb);
             scb->cmd.logical_info.buffer_addr = VIRT_TO_BUS(&ha->adapt->logical_drive_info);
             scb->cmd.logical_info.reserved = 0;
@@ -2647,10+3432,10 @@ ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) {
       case WRITE_6:
          if (!scb->sg_len) {
             scb->cmd.basic_io.op_code =
-            (scb->scsi_cmd->cmnd[0] == READ_6) ? IPS_READ : IPS_WRITE;
+            (scb->scsi_cmd->cmnd[0] == READ_6) ? IPS_CMD_READ : IPS_CMD_WRITE;
          } else {
             scb->cmd.basic_io.op_code =
-            (scb->scsi_cmd->cmnd[0] == READ_6) ? READ_SCATTER_GATHER : WRITE_SCATTER_GATHER;
+            (scb->scsi_cmd->cmnd[0] == READ_6) ? IPS_CMD_READ_SG : IPS_CMD_WRITE_SG;
          }
 
          scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
@@ -2678,10+3463,10 @@ ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) {
       case WRITE_10:
          if (!scb->sg_len) {
             scb->cmd.basic_io.op_code =
-            (scb->scsi_cmd->cmnd[0] == READ_10) ? IPS_READ : IPS_WRITE;
+            (scb->scsi_cmd->cmnd[0] == READ_10) ? IPS_CMD_READ : IPS_CMD_WRITE;
          } else {
             scb->cmd.basic_io.op_code =
-            (scb->scsi_cmd->cmnd[0] == READ_10) ? READ_SCATTER_GATHER : WRITE_SCATTER_GATHER;
+            (scb->scsi_cmd->cmnd[0] == READ_10) ? IPS_CMD_READ_SG : IPS_CMD_WRITE_SG;
          }
 
          scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
@@ -2719,14+3504,14 @@ ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) {
          break;
 
       case MODE_SENSE:
-         scb->cmd.basic_io.op_code = ENQUIRY;
+         scb->cmd.basic_io.op_code = IPS_CMD_ENQUIRY;
          scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
          scb->cmd.basic_io.sg_addr = VIRT_TO_BUS(ha->enq);
          ret = IPS_SUCCESS;
          break;
 
       case READ_CAPACITY:
-         scb->cmd.logical_info.op_code = GET_LOGICAL_DRIVE_INFO;
+         scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO;
          scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb);
          scb->cmd.logical_info.buffer_addr = VIRT_TO_BUS(&ha->adapt->logical_drive_info);
          scb->cmd.logical_info.reserved = 0;
@@ -2758,9+3543,9 @@ ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) {
    /* setup DCDB */
    if (scb->bus > 0) {
       if (!scb->sg_len)
-         scb->cmd.dcdb.op_code = DIRECT_CDB;
+         scb->cmd.dcdb.op_code = IPS_CMD_DCDB;
       else
-         scb->cmd.dcdb.op_code = DIRECT_CDB_SCATTER_GATHER;
+         scb->cmd.dcdb.op_code = IPS_CMD_DCDB_SG;
 
       ha->dcdb_active[scb->bus-1] |= (1 << scb->target_id);
       scb->cmd.dcdb.command_id = IPS_COMMAND_ID(ha, scb);
@@ -2770,19+3555,19 @@ ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) {
       scb->cmd.dcdb.reserved3 = 0;
 
       scb->dcdb.device_address = ((scb->bus - 1) << 4) | scb->target_id;
-      scb->dcdb.cmd_attribute |= DISCONNECT_ALLOWED;
+      scb->dcdb.cmd_attribute |= IPS_DISCONNECT_ALLOWED;
 
       if (scb->timeout) {
          if (scb->timeout <= 10)
-            scb->dcdb.cmd_attribute |= TIMEOUT_10;
+            scb->dcdb.cmd_attribute |= IPS_TIMEOUT10;
          else if (scb->timeout <= 60)
-            scb->dcdb.cmd_attribute |= TIMEOUT_60;
+            scb->dcdb.cmd_attribute |= IPS_TIMEOUT60;
          else
-            scb->dcdb.cmd_attribute |= TIMEOUT_20M;
+            scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M;
       }
 
-      if (!(scb->dcdb.cmd_attribute & TIMEOUT_20M))
-         scb->dcdb.cmd_attribute |= TIMEOUT_20M;
+      if (!(scb->dcdb.cmd_attribute & IPS_TIMEOUT20M))
+         scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M;
 
       scb->dcdb.sense_length = sizeof(scb->scsi_cmd->sense_buffer);
       scb->dcdb.buffer_pointer = scb->data_busaddr;
@@ -2817,7+3602,7 @@ ips_chkstatus(ips_ha_t *ha) {
 
    command_id = ips_statupd(ha);
 
-   if (command_id > (MAX_CMDS-1)) {
+   if (command_id > (IPS_MAX_CMDS-1)) {
       printk(KERN_NOTICE "(%s%d) invalid command id received: %d\n",
              ips_name, ha->host_num, command_id);
 
@@ -2827,7+3612,7 @@ ips_chkstatus(ips_ha_t *ha) {
    scb = &ha->scbs[command_id];
    sp->scb_addr = (u32) scb;
    sp->residue_len = 0;
-   scb->basic_status = basic_status = ha->adapt->p_status_tail->basic_status & BASIC_STATUS_MASK;
+   scb->basic_status = basic_status = ha->adapt->p_status_tail->basic_status & IPS_BASIC_STATUS_MASK;
    scb->extended_status = ext_status = ha->adapt->p_status_tail->extended_status;
 
    /* Remove the item from the active queue */
@@ -2846,12+3631,12 @@ ips_chkstatus(ips_ha_t *ha) {
    errcode = DID_OK;
    ret = 0;
 
-   if (((basic_status & GSC_STATUS_MASK) == SSUCCESS) ||
-       ((basic_status & GSC_STATUS_MASK) == RECOVERED_ERROR)) {
+   if (((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_SUCCESS) ||
+       ((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_RECOVERED_ERROR)) {
 
       if (scb->bus == 0) {
 #if IPS_DEBUG >= 1
-         if ((basic_status & GSC_STATUS_MASK) == RECOVERED_ERROR) {
+         if ((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_RECOVERED_ERROR) {
             printk(KERN_NOTICE "(%s%d) Recovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x\n",
                    ips_name, ha->host_num,
                    scb->cmd.basic_io.op_code, basic_status, ext_status);
@@ -2975,20+3760,20 @@ static int
 ips_online(ips_ha_t *ha, ips_scb_t *scb) {
    DBG("ips_online");
 
-   if (scb->target_id >= MAX_LOGICAL_DRIVES)
+   if (scb->target_id >= IPS_MAX_LD)
       return (0);
 
-   if ((scb->basic_status & GSC_STATUS_MASK) > 1) {
+   if ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1) {
       memset(&ha->adapt->logical_drive_info, 0, sizeof(ha->adapt->logical_drive_info));
 
       return (0);
    }
 
    if (scb->target_id < ha->adapt->logical_drive_info.no_of_log_drive &&
-       ha->adapt->logical_drive_info.drive_info[scb->target_id].state != OFF_LINE &&
-       ha->adapt->logical_drive_info.drive_info[scb->target_id].state != FREE &&
-       ha->adapt->logical_drive_info.drive_info[scb->target_id].state != CRS &&
-       ha->adapt->logical_drive_info.drive_info[scb->target_id].state != SYS)
+       ha->adapt->logical_drive_info.drive_info[scb->target_id].state != IPS_LD_OFFLINE &&
+       ha->adapt->logical_drive_info.drive_info[scb->target_id].state != IPS_LD_FREE &&
+       ha->adapt->logical_drive_info.drive_info[scb->target_id].state != IPS_LD_CRS &&
+       ha->adapt->logical_drive_info.drive_info[scb->target_id].state != IPS_LD_SYS)
       return (1);
    else
       return (0);
@@ -3005,11+3790,11 @@ ips_online(ips_ha_t *ha, ips_scb_t *scb) {
 /****************************************************************************/
 static int
 ips_inquiry(ips_ha_t *ha, ips_scb_t *scb) {
-   IPS_INQUIRYDATA inq;
+   IPS_INQ_DATA inq;
 
    DBG("ips_inquiry");
 
-   memset(&inq, 0, sizeof(IPS_INQUIRYDATA));
+   memset(&inq, 0, sizeof(IPS_INQ_DATA));
 
    inq.DeviceType = TYPE_DISK;
    inq.DeviceTypeQualifier = 0;
@@ -3036,14+3821,14 @@ ips_inquiry(ips_ha_t *ha, ips_scb_t *scb) {
 /****************************************************************************/
 static int
 ips_rdcap(ips_ha_t *ha, ips_scb_t *scb) {
-   CAPACITY_T *cap;
+   IPS_CAPACITY *cap;
 
    DBG("ips_rdcap");
 
    if (scb->scsi_cmd->bufflen < 8)
       return (0);
 
-   cap = (CAPACITY_T *) scb->scsi_cmd->request_buffer;
+   cap = (IPS_CAPACITY *) scb->scsi_cmd->request_buffer;
 
    cap->lba = htonl(ha->adapt->logical_drive_info.drive_info[scb->target_id].sector_count - 1);
    cap->len = htonl((u32) IPS_BLKSIZE);
@@ -3071,11+3856,11 @@ ips_msense(ips_ha_t *ha, ips_scb_t *scb) {
 
    if (ha->enq->ulDriveSize[scb->target_id] > 0x400000 &&
        (ha->enq->ucMiscFlag & 0x8) == 0) {
-      heads = NORM_MODE_HEADS;
-      sectors = NORM_MODE_SECTORS;
+      heads = IPS_NORM_HEADS;
+      sectors = IPS_NORM_SECTORS;
    } else {
-      heads = COMP_MODE_HEADS;
-      sectors = COMP_MODE_SECTORS;
+      heads = IPS_COMP_HEADS;
+      sectors = IPS_COMP_SECTORS;
    }
 
    cylinders = ha->enq->ulDriveSize[scb->target_id] / (heads * sectors);
@@ -3088,7+3873,7 @@ ips_msense(ips_ha_t *ha, ips_scb_t *scb) {
    case 0x03: /* page 3 */
       mdata.pdata.pg3.pg_pc = 0x3;
       mdata.pdata.pg3.pg_res1 = 0;
-      mdata.pdata.pg3.pg_len = sizeof(DADF_T);
+      mdata.pdata.pg3.pg_len = sizeof(IPS_DADF);
       mdata.plh.plh_len = 3 + mdata.plh.plh_bdl + mdata.pdata.pg3.pg_len;
       mdata.pdata.pg3.pg_trk_z = 0;
       mdata.pdata.pg3.pg_asec_z = 0;
@@ -3110,7+3895,7 @@ ips_msense(ips_ha_t *ha, ips_scb_t *scb) {
    case 0x4:
       mdata.pdata.pg4.pg_pc = 0x4;
       mdata.pdata.pg4.pg_res1 = 0;
-      mdata.pdata.pg4.pg_len = sizeof(RDDG_T);
+      mdata.pdata.pg4.pg_len = sizeof(IPS_RDDG);
       mdata.plh.plh_len = 3 + mdata.plh.plh_bdl + mdata.pdata.pg4.pg_len;
       mdata.pdata.pg4.pg_cylu = (cylinders >> 8) & 0xffff;
       mdata.pdata.pg4.pg_cyll = cylinders & 0xff;
@@ -3204,6+3989,12 @@ ips_free(ips_ha_t *ha) {
          ha->dummy = NULL;
       }
 
+      if (ha->ioctl_data) {
+         kfree(ha->ioctl_data);
+         ha->ioctl_data = NULL;
+         ha->ioctl_datasize = 0;
+      }
+
       if (ha->scbs) {
          for (i = 0; i < ha->max_cmds; i++) {
             if (ha->scbs[i].sg_list)
@@ -3241,7+4032,7 @@ ips_allocatescbs(ips_ha_t *ha) {
       scb_p = &ha->scbs[i];
 
       /* allocate S/G list */
-      scb_p->sg_list = (SG_LIST *) kmalloc(sizeof(SG_LIST) * MAX_SG_ELEMENTS, GFP_KERNEL|GFP_DMA);
+      scb_p->sg_list = (IPS_SG_LIST *) kmalloc(sizeof(IPS_SG_LIST) * IPS_MAX_SG, GFP_KERNEL|GFP_DMA);
 
       if (! scb_p->sg_list)
          return (0);
@@ -3268,7+4059,7 @@ ips_allocatescbs(ips_ha_t *ha) {
 /****************************************************************************/
 static void
 ips_init_scb(ips_ha_t *ha, ips_scb_t *scb) {
-   SG_LIST *sg_list;
+   IPS_SG_LIST *sg_list;
 
    DBG("ips_init_scb");
 
@@ -3279,19+4070,19 @@ ips_init_scb(ips_ha_t *ha, ips_scb_t *scb) {
 
    /* zero fill */
    memset(scb, 0, sizeof(ips_scb_t));
-   memset(ha->dummy, 0, sizeof(BASIC_IO_CMD));
+   memset(ha->dummy, 0, sizeof(IPS_IO_CMD));
 
    /* Initialize dummy command bucket */
    ha->dummy->op_code = 0xFF;
    ha->dummy->ccsar = VIRT_TO_BUS(ha->dummy);
-   ha->dummy->command_id = MAX_CMDS;
+   ha->dummy->command_id = IPS_MAX_CMDS;
 
    /* set bus address of scb */
    scb->scb_busaddr = VIRT_TO_BUS(scb);
    scb->sg_list = sg_list;
 
    /* Neptune Fix */
-   scb->cmd.basic_io.cccr = ILE;
+   scb->cmd.basic_io.cccr = IPS_BIT_ILE;
    scb->cmd.basic_io.ccsar = VIRT_TO_BUS(ha->dummy);
 }
 
@@ -3309,13+4100,13 @@ ips_init_scb(ips_ha_t *ha, ips_scb_t *scb) {
 static ips_scb_t *
 ips_getscb(ips_ha_t *ha) {
    ips_scb_t     *scb;
-   unsigned int   cpu_flags;
+   u32            cpu_flags;
 
    DBG("ips_getscb");
 
-   spin_lock_irqsave(&ha->scb_lock, cpu_flags);
+   IPS_SCB_LOCK(cpu_flags);
    if ((scb = ha->scb_freelist) == NULL) {
-      spin_unlock_irqrestore(&ha->scb_lock, cpu_flags);
+      IPS_SCB_UNLOCK(cpu_flags);
 
       return (NULL);
    }
@@ -3323,7+4114,7 @@ ips_getscb(ips_ha_t *ha) {
    ha->scb_freelist = scb->q_next;
    scb->q_next = NULL;
 
-   spin_unlock_irqrestore(&ha->scb_lock, cpu_flags);
+   IPS_SCB_UNLOCK(cpu_flags);
 
    ips_init_scb(ha, scb);
 
@@ -3343,16+4134,16 @@ ips_getscb(ips_ha_t *ha) {
 /****************************************************************************/
 static void
 ips_freescb(ips_ha_t *ha, ips_scb_t *scb) {
-   unsigned int cpu_flags;
+   u32          cpu_flags;
 
    DBG("ips_freescb");
 
    /* check to make sure this is not our "special" scb */
    if (IPS_COMMAND_ID(ha, scb) < (ha->max_cmds - 1)) {
-      spin_lock_irqsave(&ha->scb_lock, cpu_flags);
+      IPS_SCB_LOCK(cpu_flags);
       scb->q_next = ha->scb_freelist;
       ha->scb_freelist = scb;
-      spin_unlock_irqrestore(&ha->scb_lock, cpu_flags);
+      IPS_SCB_UNLOCK(cpu_flags);
    }
 }
 
@@ -3369,10+4160,11 @@ static int
 ips_reset_adapter(ips_ha_t *ha) {
    u8  Isr;
    u8  Cbsp;
-   u8  PostByte[MAX_POST_BYTES];
-   u8  ConfigByte[MAX_CONFIG_BYTES];
+   u8  PostByte[IPS_MAX_POST_BYTES];
+   u8  ConfigByte[IPS_MAX_CONFIG_BYTES];
    int i, j;
    int reset_counter;
+   u32 cpu_flags;
 
    DBG("ips_reset_adapter");
 
@@ -3381,108+4173,125 @@ ips_reset_adapter(ips_ha_t *ha) {
           ha->io_addr, ha->irq);
 #endif
 
+   IPS_HA_LOCK(cpu_flags);
+
    reset_counter = 0;
 
    while (reset_counter < 2) {
       reset_counter++;
 
-      outb(RST, ha->io_addr + SCPR);
-      MDELAY(ONE_SEC);
-      outb(0, ha->io_addr + SCPR);
-      MDELAY(ONE_SEC);
+      outb(IPS_BIT_RST, ha->io_addr + IPS_REG_SCPR);
+      MDELAY(IPS_ONE_SEC);
+      outb(0, ha->io_addr + IPS_REG_SCPR);
+      MDELAY(IPS_ONE_SEC);
 
-      for (i = 0; i < MAX_POST_BYTES; i++) {
+      for (i = 0; i < IPS_MAX_POST_BYTES; i++) {
          for (j = 0; j < 45; j++) {
-            Isr = inb(ha->io_addr + HISR);
-            if (Isr & GHI)
+            Isr = inb(ha->io_addr + IPS_REG_HISR);
+            if (Isr & IPS_BIT_GHI)
                break;
 
-            MDELAY(ONE_SEC);
+            MDELAY(IPS_ONE_SEC);
          }
 
          if (j >= 45) {
             /* error occured */
             if (reset_counter < 2)
                continue;
-            else
+            else {
                /* reset failed */
+               IPS_HA_UNLOCK(cpu_flags);
+
                return (0);
+            }
          }
 
-         PostByte[i] = inb(ha->io_addr + ISPR);
-         outb(Isr, ha->io_addr + HISR);
+         PostByte[i] = inb(ha->io_addr + IPS_REG_ISPR);
+         outb(Isr, ha->io_addr + IPS_REG_HISR);
       }
 
-      if (PostByte[0] < GOOD_POST_BASIC_STATUS) {
+      if (PostByte[0] < IPS_GOOD_POST_STATUS) {
          printk("(%s%d) reset controller fails (post status %x %x).\n",
                 ips_name, ha->host_num, PostByte[0], PostByte[1]);
 
+         IPS_HA_UNLOCK(cpu_flags);
+
          return (0);
       }
 
-      for (i = 0; i < MAX_CONFIG_BYTES; i++) {
+      for (i = 0; i < IPS_MAX_CONFIG_BYTES; i++) {
          for (j = 0; j < 240; j++) {
-            Isr = inb(ha->io_addr + HISR);
-            if (Isr & GHI)
+            Isr = inb(ha->io_addr + IPS_REG_HISR);
+            if (Isr & IPS_BIT_GHI)
                break;
 
-            MDELAY(ONE_SEC); /* 100 msec */
+            MDELAY(IPS_ONE_SEC); /* 100 msec */
          }
 
          if (j >= 240) {
             /* error occured */
             if (reset_counter < 2)
                continue;
-            else
+            else {
                /* reset failed */
+               IPS_HA_UNLOCK(cpu_flags);
+
                return (0);
+            }
          }
 
-         ConfigByte[i] = inb(ha->io_addr + ISPR);
-         outb(Isr, ha->io_addr + HISR);
+         ConfigByte[i] = inb(ha->io_addr + IPS_REG_ISPR);
+         outb(Isr, ha->io_addr + IPS_REG_HISR);
       }
 
       if (ConfigByte[0] == 0 && ConfigByte[1] == 2) {
          printk("(%s%d) reset controller fails (status %x %x).\n",
                 ips_name, ha->host_num, ConfigByte[0], ConfigByte[1]);
 
+         IPS_HA_UNLOCK(cpu_flags);
+
          return (0);
       }
 
       for (i = 0; i < 240; i++) {
-         Cbsp = inb(ha->io_addr + CBSP);
+         Cbsp = inb(ha->io_addr + IPS_REG_CBSP);
 
-         if ((Cbsp & OP) == 0)
+         if ((Cbsp & IPS_BIT_OP) == 0)
             break;
 
-         MDELAY(ONE_SEC);
+         MDELAY(IPS_ONE_SEC);
       }
 
       if (i >= 240) {
          /* error occured */
          if (reset_counter < 2)
             continue;
-         else
+         else {
             /* reset failed */
+            IPS_HA_UNLOCK(cpu_flags);
+
             return (0);
+         }
       }
 
       /* setup CCCR */
-      outw(0x1010, ha->io_addr + CCCR);
+      outw(0x1010, ha->io_addr + IPS_REG_CCCR);
 
       /* Enable busmastering */
-      outb(EBM, ha->io_addr + SCPR);
+      outb(IPS_BIT_EBM, ha->io_addr + IPS_REG_SCPR);
 
       /* setup status queues */
       ips_statinit(ha);
 
       /* Enable interrupts */
-      outb(EI, ha->io_addr + HISR);
+      outb(IPS_BIT_EI, ha->io_addr + IPS_REG_HISR);
 
       /* if we get here then everything went OK */
       break;
    }
 
+   IPS_HA_UNLOCK(cpu_flags);
+
    return (1);
 }
 
@@ -3502,14+4311,14 @@ ips_statinit(ips_ha_t *ha) {
    DBG("ips_statinit");
 
    ha->adapt->p_status_start = ha->adapt->status;
-   ha->adapt->p_status_end = ha->adapt->status + MAX_CMDS;
+   ha->adapt->p_status_end = ha->adapt->status + IPS_MAX_CMDS;
    ha->adapt->p_status_tail = ha->adapt->status;
 
    phys_status_start = VIRT_TO_BUS(ha->adapt->status);
-   outl(phys_status_start, ha->io_addr + SQSR);
-   outl(phys_status_start + STATUS_Q_SIZE, ha->io_addr + SQER);
-   outl(phys_status_start + STATUS_SIZE, ha->io_addr + SQHR);
-   outl(phys_status_start, ha->io_addr + SQTR);
+   outl(phys_status_start, ha->io_addr + IPS_REG_SQSR);
+   outl(phys_status_start + IPS_STATUS_Q_SIZE, ha->io_addr + IPS_REG_SQER);
+   outl(phys_status_start + IPS_STATUS_SIZE, ha->io_addr + IPS_REG_SQHR);
+   outl(phys_status_start, ha->io_addr + IPS_REG_SQTR);
 
    ha->adapt->hw_status_start = phys_status_start;
    ha->adapt->hw_status_tail = phys_status_start;
@@ -3532,13+4341,13 @@ ips_statupd(ips_ha_t *ha) {
 
    if (ha->adapt->p_status_tail != ha->adapt->p_status_end) {
       ha->adapt->p_status_tail++;
-      ha->adapt->hw_status_tail += sizeof(STATUS);
+      ha->adapt->hw_status_tail += sizeof(IPS_STATUS);
    } else {
       ha->adapt->p_status_tail = ha->adapt->p_status_start;
       ha->adapt->hw_status_tail = ha->adapt->hw_status_start;
    }
 
-   outl(ha->adapt->hw_status_tail, ha->io_addr + SQTR);
+   outl(ha->adapt->hw_status_tail, ha->io_addr + IPS_REG_SQTR);
 
    command_id = ha->adapt->p_status_tail->command_id;
 
@@ -3560,6+4369,7 @@ static int
 ips_issue(ips_ha_t *ha, ips_scb_t *scb) {
    u32       TimeOut;
    u16       val;
+   u32       cpu_flags;
 
    DBG("ips_issue");
 
@@ -3577,17+4387,19 @@ ips_issue(ips_ha_t *ha, ips_scb_t *scb) {
              ips_name,
              scb->cmd.basic_io.command_id);
 #if IPS_DEBUG >= 11
-      MDELAY(ONE_SEC);
+      MDELAY(IPS_ONE_SEC);
 #endif
 #endif
 
+   IPS_HA_LOCK(cpu_flags);
+
    TimeOut = 0;
 
-   while ((val = inw(ha->io_addr + CCCR)) & SEMAPHORE) {
+   while ((val = inw(ha->io_addr + IPS_REG_CCCR)) & IPS_BIT_SEM) {
       UDELAY(1000);
 
-      if (++TimeOut >= SEMAPHORE_TIMEOUT) {
-         if (!(val & START_STOP_BIT))
+      if (++TimeOut >= IPS_SEM_TIMEOUT) {
+         if (!(val & IPS_BIT_START_STOP))
             break;
 
          printk(KERN_WARNING "(%s%d) ips_issue val [0x%x].\n",
@@ -3595,12+4407,16 @@ ips_issue(ips_ha_t *ha, ips_scb_t *scb) {
          printk(KERN_WARNING "(%s%d) ips_issue semaphore chk timeout.\n",
                 ips_name, ha->host_num);
 
+         IPS_HA_UNLOCK(cpu_flags);
+
          return (IPS_FAILURE);
       } /* end if */
    } /* end while */
 
-   outl(scb->scb_busaddr, ha->io_addr + CCSAR);
-   outw(START_COMMAND, ha->io_addr + CCCR);
+   outl(scb->scb_busaddr, ha->io_addr + IPS_REG_CCSAR);
+   outw(IPS_BIT_START_CMD, ha->io_addr + IPS_REG_CCCR);
+
+   IPS_HA_UNLOCK(cpu_flags);
 
    return (IPS_SUCCESS);
 }
@@ -3620,18+4436,18 @@ ips_isintr(ips_ha_t *ha) {
 
    DBG("ips_isintr");
 
-   Isr = inb(ha->io_addr + HISR);
+   Isr = inb(ha->io_addr + IPS_REG_HISR);
 
    if (Isr == 0xFF)
       /* ?!?! Nothing really there */
       return (0);
 
-   if (Isr & SCE)
+   if (Isr & IPS_BIT_SCE)
       return (1);
-   else if (Isr & (SQO | GHI)) {
+   else if (Isr & (IPS_BIT_SQO | IPS_BIT_GHI)) {
       /* status queue overflow or GHI */
       /* just clear the interrupt */
-      outb(Isr, ha->io_addr + HISR);
+      outb(Isr, ha->io_addr + IPS_REG_HISR);
    }
 
    return (0);
@@ -3649,15+4465,23 @@ ips_isintr(ips_ha_t *ha) {
 static int
 ips_wait(ips_ha_t *ha, int time, int intr) {
    int        ret;
+   u8         done;
 
    DBG("ips_wait");
 
    ret = IPS_FAILURE;
+   done = FALSE;
 
-   time *= ONE_SEC; /* convert seconds to milliseconds */
+   time *= IPS_ONE_SEC; /* convert seconds to milliseconds */
 
-   while (time > 0) {
-      if (intr == IPS_INTR_OFF) {
+   while ((time > 0) && (!done)) {
+      if (intr == IPS_INTR_ON) {
+         if (ha->waitflag == FALSE) {
+            ret = IPS_SUCCESS;
+            done = TRUE;
+            break;
+         }
+      } else if (intr == IPS_INTR_IORL) {
          if (ha->waitflag == FALSE) {
             /*
              * controller generated an interupt to
@@ -3665,28+4489,50 @@ ips_wait(ips_ha_t *ha, int time, int intr) {
              * and ips_intr() has serviced the interrupt.
              */
             ret = IPS_SUCCESS;
+            done = TRUE;
             break;
          }
 
          /*
-          * NOTE: Interrupts are disabled here
-          * On an SMP system interrupts will only
-          * be disabled on one processor.
-          * So, ultimately we still need to set the
-          * "I'm in the interrupt handler flag"
+          * NOTE: we already have the io_request_lock so
+          * even if we get an interrupt it won't get serviced
+          * until after we finish.
           */
+
          while (test_and_set_bit(IPS_IN_INTR, &ha->flags))
             UDELAY(1000);
 
          ips_intr(ha);
 
          clear_bit(IPS_IN_INTR, &ha->flags);
-
-      } else {
+      } else if (intr == IPS_INTR_HAL) {
          if (ha->waitflag == FALSE) {
+            /*
+             * controller generated an interupt to
+             * acknowledge completion of the command
+             * and ips_intr() has serviced the interrupt.
+             */
             ret = IPS_SUCCESS;
+            done = TRUE;
             break;
          }
+
+         /*
+          * NOTE: since we were not called with the iorequest lock
+          * we must obtain it before we can call the interrupt handler.
+          * We were called under the HA lock so we can assume that interrupts
+          * are masked.
+          */
+         spin_lock(&io_request_lock);
+
+         while (test_and_set_bit(IPS_IN_INTR, &ha->flags))
+            UDELAY(1000);
+
+         ips_intr(ha);
+
+         clear_bit(IPS_IN_INTR, &ha->flags);
+
+         spin_unlock(&io_request_lock);
       }
 
       UDELAY(1000); /* 1 milisecond */
@@ -3706,10+4552,10 @@ ips_wait(ips_ha_t *ha, int time, int intr) {
 /*                                                                          */
 /****************************************************************************/
 static int
-ips_write_driver_status(ips_ha_t *ha) {
+ips_write_driver_status(ips_ha_t *ha, int intr) {
    DBG("ips_write_driver_status");
 
-   if (!ips_readwrite_page5(ha, FALSE)) {
+   if (!ips_readwrite_page5(ha, FALSE, intr)) {
       printk(KERN_WARNING "(%s%d) unable to read NVRAM page 5.\n",
              ips_name, ha->host_num);
 
@@ -3718,7+4564,7 @@ ips_write_driver_status(ips_ha_t *ha) {
 
    /* check to make sure the page has a valid */
    /* signature */
-   if (ha->nvram->signature != NVRAM_PAGE5_SIGNATURE) {
+   if (ha->nvram->signature != IPS_NVRAM_P5_SIG) {
 #if IPS_DEBUG >= 1
       printk("(%s%d) NVRAM page 5 has an invalid signature: %X.\n",
              ips_name, ha->host_num, ha->nvram->signature);
@@ -3739,12+4585,12 @@ ips_write_driver_status(ips_ha_t *ha) {
    ha->ad_type = ha->nvram->adapter_type;
 
    /* change values (as needed) */
-   ha->nvram->operating_system = OS_LINUX;
+   ha->nvram->operating_system = IPS_OS_LINUX;
    strncpy((char *) ha->nvram->driver_high, IPS_VERSION_HIGH, 4);
    strncpy((char *) ha->nvram->driver_low, IPS_VERSION_LOW, 4);
 
    /* now update the page */
-   if (!ips_readwrite_page5(ha, TRUE)) {
+   if (!ips_readwrite_page5(ha, TRUE, intr)) {
       printk(KERN_WARNING "(%s%d) unable to write NVRAM page 5.\n",
              ips_name, ha->host_num);
 
@@ -3764,7+4610,7 @@ ips_write_driver_status(ips_ha_t *ha) {
 /*                                                                          */
 /****************************************************************************/
 static int
-ips_read_adapter_status(ips_ha_t *ha) {
+ips_read_adapter_status(ips_ha_t *ha, int intr) {
    ips_scb_t *scb;
    int        ret;
 
@@ -3775,9+4621,9 @@ ips_read_adapter_status(ips_ha_t *ha) {
    ips_init_scb(ha, scb);
 
    scb->timeout = ips_cmd_timeout;
-   scb->cdb[0] = ENQUIRY;
+   scb->cdb[0] = IPS_CMD_ENQUIRY;
 
-   scb->cmd.basic_io.op_code = ENQUIRY;
+   scb->cmd.basic_io.op_code = IPS_CMD_ENQUIRY;
    scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
    scb->cmd.basic_io.sg_count = 0;
    scb->cmd.basic_io.sg_addr = VIRT_TO_BUS(ha->enq);
@@ -3787,7+4633,7 @@ ips_read_adapter_status(ips_ha_t *ha) {
    scb->cmd.basic_io.reserved = 0;
 
    /* send command */
-   ret = ips_send_wait(ha, scb, ips_cmd_timeout);
+   ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr);
    if ((ret == IPS_FAILURE) || (ret == IPS_SUCCESS_IMM))
       return (0);
 
@@ -3804,7+4650,7 @@ ips_read_adapter_status(ips_ha_t *ha) {
 /*                                                                          */
 /****************************************************************************/
 static int
-ips_read_subsystem_parameters(ips_ha_t *ha) {
+ips_read_subsystem_parameters(ips_ha_t *ha, int intr) {
    ips_scb_t *scb;
    int        ret;
 
@@ -3815,9+4661,9 @@ ips_read_subsystem_parameters(ips_ha_t *ha) {
    ips_init_scb(ha, scb);
 
    scb->timeout = ips_cmd_timeout;
-   scb->cdb[0] = GET_SUBSYS_PARAM;
+   scb->cdb[0] = IPS_CMD_GET_SUBSYS;
 
-   scb->cmd.basic_io.op_code = GET_SUBSYS_PARAM;
+   scb->cmd.basic_io.op_code = IPS_CMD_GET_SUBSYS;
    scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
    scb->cmd.basic_io.sg_count = 0;
    scb->cmd.basic_io.sg_addr = VIRT_TO_BUS(ha->subsys);
@@ -3827,7+4673,7 @@ ips_read_subsystem_parameters(ips_ha_t *ha) {
    scb->cmd.basic_io.reserved = 0;
 
    /* send command */
-   ret = ips_send_wait(ha, scb, ips_cmd_timeout);
+   ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr);
    if ((ret == IPS_FAILURE) || (ret == IPS_SUCCESS_IMM))
       return (0);
 
@@ -3844,7+4690,7 @@ ips_read_subsystem_parameters(ips_ha_t *ha) {
 /*                                                                          */
 /****************************************************************************/
 static int
-ips_read_config(ips_ha_t *ha) {
+ips_read_config(ips_ha_t *ha, int intr) {
    ips_scb_t *scb;
    int        i;
    int        ret;
@@ -3861,18+4707,18 @@ ips_read_config(ips_ha_t *ha) {
    ips_init_scb(ha, scb);
 
    scb->timeout = ips_cmd_timeout;
-   scb->cdb[0] = READ_NVRAM_CONFIGURATION;
+   scb->cdb[0] = IPS_CMD_READ_CONF;
 
-   scb->cmd.basic_io.op_code = READ_NVRAM_CONFIGURATION;
+   scb->cmd.basic_io.op_code = IPS_CMD_READ_CONF;
    scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
    scb->cmd.basic_io.sg_addr = VIRT_TO_BUS(ha->conf);
 
    /* send command */
-   if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout)) == IPS_FAILURE) ||
+   if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) ||
        (ret == IPS_SUCCESS_IMM) ||
-       ((scb->basic_status & GSC_STATUS_MASK) > 1)) {
+       ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) {
 
-      memset(ha->conf, 0, sizeof(CONFCMD));
+      memset(ha->conf, 0, sizeof(IPS_CONF));
 
       /* reset initiator IDs */
       ha->conf->init_id[0] = IPS_ADAPTER_ID;
@@ -3891,11+4737,11 @@ ips_read_config(ips_ha_t *ha) {
 /*                                                                          */
 /* Routine Description:                                                     */
 /*                                                                          */
-/*   Read the configuration on the adapter                                  */
+/*   Read nvram page 5 from the adapter                                     */
 /*                                                                          */
 /****************************************************************************/
 static int
-ips_readwrite_page5(ips_ha_t *ha, int write) {
+ips_readwrite_page5(ips_ha_t *ha, int write, int intr) {
    ips_scb_t *scb;
    int        ret;
 
@@ -3906,9+4752,9 @@ ips_readwrite_page5(ips_ha_t *ha, int write) {
    ips_init_scb(ha, scb);
 
    scb->timeout = ips_cmd_timeout;
-   scb->cdb[0] = RW_NVRAM_PAGE;
+   scb->cdb[0] = IPS_CMD_RW_NVRAM_PAGE;
 
-   scb->cmd.nvram.op_code = RW_NVRAM_PAGE;
+   scb->cmd.nvram.op_code = IPS_CMD_RW_NVRAM_PAGE;
    scb->cmd.nvram.command_id = IPS_COMMAND_ID(ha, scb);
    scb->cmd.nvram.page = 5;
    scb->cmd.nvram.write = write;
@@ -3917,11+4763,11 @@ ips_readwrite_page5(ips_ha_t *ha, int write) {
    scb->cmd.nvram.reserved2 = 0;
 
    /* issue the command */
-   if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout)) == IPS_FAILURE) ||
+   if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) ||
        (ret == IPS_SUCCESS_IMM) ||
-       ((scb->basic_status & GSC_STATUS_MASK) > 1)) {
+       ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) {
 
-      memset(ha->nvram, 0, sizeof(NVRAM_PAGE5));
+      memset(ha->nvram, 0, sizeof(IPS_NVRAM_P5));
 
       return (0);
    }
@@ -3939,7+4785,7 @@ ips_readwrite_page5(ips_ha_t *ha, int write) {
 /*                                                                          */
 /****************************************************************************/
 static int
-ips_clear_adapter(ips_ha_t *ha) {
+ips_clear_adapter(ips_ha_t *ha, int intr) {
    ips_scb_t *scb;
    int        ret;
 
@@ -3950,43+4796,415 @@ ips_clear_adapter(ips_ha_t *ha) {
    ips_init_scb(ha, scb);
 
    scb->timeout = ips_reset_timeout;
-   scb->cdb[0] = CONFIG_SYNC;
+   scb->cdb[0] = IPS_CMD_CONFIG_SYNC;
 
-   scb->cmd.config_sync.op_code = CONFIG_SYNC;
+   scb->cmd.config_sync.op_code = IPS_CMD_CONFIG_SYNC;
    scb->cmd.config_sync.command_id = IPS_COMMAND_ID(ha, scb);
    scb->cmd.config_sync.channel = 0;
-   scb->cmd.config_sync.source_target = POCL;
+   scb->cmd.config_sync.source_target = IPS_POCL;
    scb->cmd.config_sync.reserved = 0;
    scb->cmd.config_sync.reserved2 = 0;
    scb->cmd.config_sync.reserved3 = 0;
 
    /* issue command */
-   ret = ips_send_wait(ha, scb, ips_reset_timeout);
+   ret = ips_send_wait(ha, scb, ips_reset_timeout, intr);
    if ((ret == IPS_FAILURE) || (ret == IPS_SUCCESS_IMM))
       return (0);
 
    /* send unlock stripe command */
    ips_init_scb(ha, scb);
 
-   scb->cdb[0] = GET_ERASE_ERROR_TABLE;
+   scb->cdb[0] = IPS_CMD_ERROR_TABLE;
    scb->timeout = ips_reset_timeout;
 
-   scb->cmd.unlock_stripe.op_code = GET_ERASE_ERROR_TABLE;
+   scb->cmd.unlock_stripe.op_code = IPS_CMD_ERROR_TABLE;
    scb->cmd.unlock_stripe.command_id = IPS_COMMAND_ID(ha, scb);
    scb->cmd.unlock_stripe.log_drv = 0;
-   scb->cmd.unlock_stripe.control = CSL;
+   scb->cmd.unlock_stripe.control = IPS_CSL;
    scb->cmd.unlock_stripe.reserved = 0;
    scb->cmd.unlock_stripe.reserved2 = 0;
    scb->cmd.unlock_stripe.reserved3 = 0;
 
    /* issue command */
-   ret = ips_send_wait(ha, scb, ips_reset_timeout);
+   ret = ips_send_wait(ha, scb, ips_reset_timeout, intr);
    if ((ret == IPS_FAILURE) || (ret == IPS_SUCCESS_IMM))
       return (0);
 
    return (1);
 }
 
+/****************************************************************************/
+/*                                                                          */
+/* Routine Name: ips_ffdc_reset                                             */
+/*                                                                          */
+/* Routine Description:                                                     */
+/*                                                                          */
+/*   FFDC: write reset info                                                 */
+/*                                                                          */
+/****************************************************************************/
+static void
+ips_ffdc_reset(ips_ha_t *ha, int intr) {
+   ips_scb_t *scb;
+
+   DBG("ips_ffdc_reset");
+
+   scb = &ha->scbs[ha->max_cmds-1];
+
+   ips_init_scb(ha, scb);
+
+   scb->timeout = ips_cmd_timeout;
+   scb->cdb[0] = IPS_CMD_FFDC;
+   scb->cmd.ffdc.op_code = IPS_CMD_FFDC;
+   scb->cmd.ffdc.command_id = IPS_COMMAND_ID(ha, scb);
+   scb->cmd.ffdc.reset_count = ha->reset_count;
+   scb->cmd.ffdc.reset_type = 0x80;
+
+   /* convert time to what the card wants */
+   ips_fix_ffdc_time(ha, scb, ha->last_ffdc);
+
+   /* issue command */
+   ips_send_wait(ha, scb, ips_cmd_timeout, intr);
+}
+
+/****************************************************************************/
+/*                                                                          */
+/* Routine Name: ips_ffdc_time                                              */
+/*                                                                          */
+/* Routine Description:                                                     */
+/*                                                                          */
+/*   FFDC: write time info                                                  */
+/*                                                                          */
+/****************************************************************************/
+static void
+ips_ffdc_time(ips_ha_t *ha, int intr) {
+   ips_scb_t *scb;
+
+   DBG("ips_ffdc_time");
+
+#if IPS_DEBUG >= 1
+   printk(KERN_NOTICE "(%s%d) Sending time update.\n",
+          ips_name, ha->host_num);
+#endif
+
+   scb = &ha->scbs[ha->max_cmds-1];
+
+   ips_init_scb(ha, scb);
+
+   scb->timeout = ips_cmd_timeout;
+   scb->cdb[0] = IPS_CMD_FFDC;
+   scb->cmd.ffdc.op_code = IPS_CMD_FFDC;
+   scb->cmd.ffdc.command_id = IPS_COMMAND_ID(ha, scb);
+   scb->cmd.ffdc.reset_count = 0;
+   scb->cmd.ffdc.reset_type = 0x80;
+
+   /* convert time to what the card wants */
+   ips_fix_ffdc_time(ha, scb, ha->last_ffdc);
+
+   /* issue command */
+   ips_send_wait(ha, scb, ips_cmd_timeout, intr);
+}
+
+/****************************************************************************/
+/*                                                                          */
+/* Routine Name: ips_fix_ffdc_time                                          */
+/*                                                                          */
+/* Routine Description:                                                     */
+/*   Adjust time_t to what the card wants                                   */
+/*                                                                          */
+/****************************************************************************/
+static void
+ips_fix_ffdc_time(ips_ha_t *ha, ips_scb_t *scb, time_t current_time) {
+   long days;
+   long rem;
+   int  i;
+   int  year;
+   int  yleap;
+   int  year_lengths[2] = { IPS_DAYS_NORMAL_YEAR, IPS_DAYS_LEAP_YEAR };
+   int  month_lengths[12][2] = { {31, 31},
+                                 {28, 29},
+                                 {31, 31},
+                                 {30, 30},
+                                 {31, 31},
+                                 {30, 30},
+                                 {31, 31},
+                                 {31, 31},
+                                 {30, 30},
+                                 {31, 31},
+                                 {30, 30},
+                                 {31, 31} };
+
+   days = current_time / IPS_SECS_DAY;
+   rem = current_time % IPS_SECS_DAY;
+
+   scb->cmd.ffdc.hour = (rem / IPS_SECS_HOUR);
+   rem = rem % IPS_SECS_HOUR;
+   scb->cmd.ffdc.minute = (rem / IPS_SECS_MIN);
+   scb->cmd.ffdc.second = (rem % IPS_SECS_MIN);
+
+   year = IPS_EPOCH_YEAR;
+   while (days < 0 || days >= year_lengths[yleap = IPS_IS_LEAP_YEAR(year)]) {
+      int newy;
+
+      newy = year + (days / IPS_DAYS_NORMAL_YEAR);
+      if (days < 0)
+         --newy;
+      days -= (newy - year) * IPS_DAYS_NORMAL_YEAR +
+         IPS_NUM_LEAP_YEARS_THROUGH(newy - 1) -
+         IPS_NUM_LEAP_YEARS_THROUGH(year - 1);
+      year = newy;
+   }
+
+   scb->cmd.ffdc.yearH = year / 100;
+   scb->cmd.ffdc.yearL = year % 100;
+
+   for (i = 0; days >= month_lengths[i][yleap]; ++i)
+      days -= month_lengths[i][yleap];
+
+   scb->cmd.ffdc.month = i + 1;
+   scb->cmd.ffdc.day = days + 1;
+}
+
+/****************************************************************************
+ * BIOS Flash Routines                                                      *
+ ****************************************************************************/
+
+/****************************************************************************/
+/*                                                                          */
+/* Routine Name: ips_erase_bios                                             */
+/*                                                                          */
+/* Routine Description:                                                     */
+/*   Erase the BIOS on the adapter                                          */
+/*                                                                          */
+/****************************************************************************/
+static int
+ips_erase_bios(ips_ha_t *ha) {
+   int   timeout;
+   u8    status;
+
+   /* Clear the status register */
+   outl(0, ha->io_addr + IPS_REG_FLAP);
+   if (ha->revision_id == IPS_REVID_TROMBONE64)
+      UDELAY(5); /* 5 us */
+
+   outb(0x50, ha->io_addr + IPS_REG_FLDP);
+   if (ha->revision_id == IPS_REVID_TROMBONE64)
+      UDELAY(5); /* 5 us */
+
+   /* Erase Setup */
+   outb(0x20, ha->io_addr + IPS_REG_FLDP);
+   if (ha->revision_id == IPS_REVID_TROMBONE64)
+      UDELAY(5); /* 5 us */
+
+   /* Erase Confirm */
+   outb(0xD0, ha->io_addr + IPS_REG_FLDP);
+   if (ha->revision_id == IPS_REVID_TROMBONE64)
+      UDELAY(5); /* 5 us */
+
+   /* Erase Status */
+   outb(0x70, ha->io_addr + IPS_REG_FLDP);
+   if (ha->revision_id == IPS_REVID_TROMBONE64)
+      UDELAY(5); /* 5 us */
+
+   timeout = 80000; /* 80 seconds */
+
+   while (timeout > 0) {
+      if (ha->revision_id == IPS_REVID_TROMBONE64) {
+         outl(0, ha->io_addr + IPS_REG_FLAP);
+         UDELAY(5); /* 5 us */
+      }
+
+      status = inb(ha->io_addr + IPS_REG_FLDP);
+
+      if (status & 0x80)
+         break;
+
+      MDELAY(1);
+      timeout--;
+   }
+
+   /* check for timeout */
+   if (timeout <= 0) {
+      /* timeout */
+
+      /* try to suspend the erase */
+      outb(0xB0, ha->io_addr + IPS_REG_FLDP);
+      if (ha->revision_id == IPS_REVID_TROMBONE64)
+         UDELAY(5); /* 5 us */
+
+      /* wait for 10 seconds */
+      timeout = 10000;
+      while (timeout > 0) {
+         if (ha->revision_id == IPS_REVID_TROMBONE64) {
+            outl(0, ha->io_addr + IPS_REG_FLAP);
+            UDELAY(5); /* 5 us */
+         }
+
+         status = inb(ha->io_addr + IPS_REG_FLDP);
+
+         if (status & 0xC0)
+            break;
+
+         MDELAY(1);
+         timeout--;
+      }
+
+      return (1);
+   }
+
+   /* check for valid VPP */
+   if (status & 0x08)
+      /* VPP failure */
+      return (1);
+
+   /* check for succesful flash */
+   if (status & 0x30)
+      /* sequence error */
+      return (1);
+
+   /* Otherwise, we were successful */
+   /* clear status */
+   outb(0x50, ha->io_addr + IPS_REG_FLDP);
+   if (ha->revision_id == IPS_REVID_TROMBONE64)
+      UDELAY(5); /* 5 us */
+
+   /* enable reads */
+   outb(0xFF, ha->io_addr + IPS_REG_FLDP);
+   if (ha->revision_id == IPS_REVID_TROMBONE64)
+      UDELAY(5); /* 5 us */
+
+   return (0);
+}
+
+/****************************************************************************/
+/*                                                                          */
+/* Routine Name: ips_program_bios                                           */
+/*                                                                          */
+/* Routine Description:                                                     */
+/*   Program the BIOS on the adapter                                        */
+/*                                                                          */
+/****************************************************************************/
+static int
+ips_program_bios(ips_ha_t *ha, char *buffer, int buffersize) {
+   int   i;
+   int   timeout;
+   u8    status;
+
+   for (i = 0; i < buffersize; i++) {
+      /* write a byte */
+      outl(i, ha->io_addr + IPS_REG_FLAP);
+      if (ha->revision_id == IPS_REVID_TROMBONE64)
+         UDELAY(5); /* 5 us */
+
+      outb(0x40, ha->io_addr + IPS_REG_FLDP);
+      if (ha->revision_id == IPS_REVID_TROMBONE64)
+         UDELAY(5); /* 5 us */
+
+      outb(buffer[i], ha->io_addr + IPS_REG_FLDP);
+      if (ha->revision_id == IPS_REVID_TROMBONE64)
+         UDELAY(5); /* 5 us */
+
+      /* wait up to one second */
+      timeout = 1000;
+      while (timeout > 0) {
+         if (ha->revision_id == IPS_REVID_TROMBONE64) {
+            outl(0, ha->io_addr + IPS_REG_FLAP);
+            UDELAY(5); /* 5 us */
+         }
+
+         status = inb(ha->io_addr + IPS_REG_FLDP);
+
+         if (status & 0x80)
+            break;
+
+         MDELAY(1);
+         timeout--;
+      }
+
+      if (timeout == 0) {
+         /* timeout error */
+         outl(0, ha->io_addr + IPS_REG_FLAP);
+         if (ha->revision_id == IPS_REVID_TROMBONE64)
+            UDELAY(5); /* 5 us */
+
+         outb(0xFF, ha->io_addr + IPS_REG_FLDP);
+         if (ha->revision_id == IPS_REVID_TROMBONE64)
+            UDELAY(5); /* 5 us */
+
+         return (1);
+      }
+
+      /* check the status */
+      if (status & 0x18) {
+         /* programming error */
+         outl(0, ha->io_addr + IPS_REG_FLAP);
+         if (ha->revision_id == IPS_REVID_TROMBONE64)
+            UDELAY(5); /* 5 us */
+
+         outb(0xFF, ha->io_addr + IPS_REG_FLDP);
+         if (ha->revision_id == IPS_REVID_TROMBONE64)
+            UDELAY(5); /* 5 us */
+
+         return (1);
+      }
+   } /* end for */
+
+   /* Enable reading */
+   outl(0, ha->io_addr + IPS_REG_FLAP);
+   if (ha->revision_id == IPS_REVID_TROMBONE64)
+      UDELAY(5); /* 5 us */
+
+   outb(0xFF, ha->io_addr + IPS_REG_FLDP);
+   if (ha->revision_id == IPS_REVID_TROMBONE64)
+      UDELAY(5); /* 5 us */
+
+   return (0);
+}
+
+/****************************************************************************/
+/*                                                                          */
+/* Routine Name: ips_verify_bios                                            */
+/*                                                                          */
+/* Routine Description:                                                     */
+/*   Verify the BIOS on the adapter                                         */
+/*                                                                          */
+/****************************************************************************/
+static int
+ips_verify_bios(ips_ha_t *ha, char *buffer, int buffersize) {
+   u8    checksum;
+   int   i;
+
+   /* test 1st byte */
+   outl(0, ha->io_addr + IPS_REG_FLAP);
+   if (ha->revision_id == IPS_REVID_TROMBONE64)
+      UDELAY(5); /* 5 us */
+
+   if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55)
+      return (1);
+
+   outl(1, ha->io_addr + IPS_REG_FLAP);
+   if (ha->revision_id == IPS_REVID_TROMBONE64)
+      UDELAY(5); /* 5 us */
+   if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA)
+      return (1);
+
+   checksum = 0xff;
+   for (i = 2; i < buffersize; i++) {
+
+      outl(i, ha->io_addr + IPS_REG_FLAP);
+      if (ha->revision_id == IPS_REVID_TROMBONE64)
+         UDELAY(5); /* 5 us */
+
+      checksum = (u8) checksum + inb(ha->io_addr + IPS_REG_FLDP);
+   }
+
+   if (checksum != 0)
+      /* failure */
+      return (1);
+   else
+      /* success */
+      return (0);
+}
+
 #if defined (MODULE)
 
 Scsi_Host_Template driver_template = IPS;
index d760ae3..e93fe81 100644 (file)
 #ifndef _IPS_H_
    #define _IPS_H_
 
-   #include <linux/config.h>
    #include <asm/uaccess.h>
    #include <asm/io.h>
 
     * Some handy macros
     */
    #ifndef LinuxVersionCode
-      #define LinuxVersionCode(x,y,z)   (((x)<<16)+((y)<<8)+(z))
+      #define LinuxVersionCode(x,y,z)  (((x)<<16)+((y)<<8)+(z))
    #endif
 
-   #define HA(x)                       ((ips_ha_t *) x->hostdata)
+   #define IPS_HA(x)                   ((ips_ha_t *) x->hostdata)
    #define IPS_COMMAND_ID(ha, scb)     (int) (scb - ha->scbs)
-   #define VIRT_TO_BUS(x)              (unsigned int)virt_to_bus((void *) x)
+   
+   #ifndef VIRT_TO_BUS
+      #define VIRT_TO_BUS(x)           (unsigned int)virt_to_bus((void *) x)
+   #endif
 
-   #define UDELAY udelay
-   #define MDELAY mdelay
+   #ifndef UDELAY
+      #define UDELAY udelay
+   #endif
+   
+   #ifndef MDELAY
+      #define MDELAY mdelay
+   #endif
 
-   #define verify_area_20(t,a,sz)       (0) /* success */
-   #define PUT_USER                     put_user
-   #define __PUT_USER                   __put_user
-   #define PUT_USER_RET                 put_user_ret
-   #define GET_USER                     get_user
-   #define __GET_USER                   __get_user
-   #define GET_USER_RET                 get_user_ret
+   #ifndef verify_area_20
+      #define verify_area_20(t,a,sz)   (0) /* success */
+   #endif
+   
+   #ifndef PUT_USER
+      #define PUT_USER                 put_user
+   #endif
+   
+   #ifndef __PUT_USER
+      #define __PUT_USER               __put_user
+   #endif
+   
+   #ifndef PUT_USER_RET
+      #define PUT_USER_RET             put_user_ret
+   #endif
+   
+   #ifndef GET_USER
+      #define GET_USER                 get_user
+   #endif
+   
+   #ifndef __GET_USER
+      #define __GET_USER               __get_user
+   #endif
+   
+   #ifndef GET_USER_RET
+      #define GET_USER_RET             get_user_ret
+   #endif
 
-/*
- * Adapter address map equates
- */
-   #define HISR                         0x08    /* Host Interrupt Status Reg   */
-   #define CCSAR                        0x10    /* Cmd Channel System Addr Reg */
-   #define CCCR                         0x14    /* Cmd Channel Control Reg     */
-   #define SQHR                         0x20    /* Status Q Head Reg           */
-   #define SQTR                         0x24    /* Status Q Tail Reg           */
-   #define SQER                         0x28    /* Status Q End Reg            */
-   #define SQSR                         0x2C    /* Status Q Start Reg          */
-   #define SCPR                         0x05    /* Subsystem control port reg  */
-   #define ISPR                         0x06    /* interrupt status port reg   */
-   #define CBSP                         0x07    /* CBSP register               */
+   /*
+    * Lock macros
+    */
+   #define IPS_SCB_LOCK(cpu_flags)      spin_lock_irqsave(&ha->scb_lock, cpu_flags)
+   #define IPS_SCB_UNLOCK(cpu_flags)    spin_unlock_irqrestore(&ha->scb_lock, cpu_flags)
+   #define IPS_QUEUE_LOCK(queue)        spin_lock_irqsave(&(queue)->lock, (queue)->cpu_flags)
+   #define IPS_QUEUE_UNLOCK(queue)      spin_unlock_irqrestore(&(queue)->lock, (queue)->cpu_flags)
+   #define IPS_HA_LOCK(cpu_flags)       spin_lock_irqsave(&ha->ips_lock, cpu_flags)
+   #define IPS_HA_UNLOCK(cpu_flags)     spin_unlock_irqrestore(&ha->ips_lock, cpu_flags)
 
-/*
- * Adapter register bit equates
- */
-   #define GHI                          0x04    /* HISR General Host Interrupt */
-   #define SQO                          0x02    /* HISR Status Q Overflow      */
-   #define SCE                          0x01    /* HISR Status Channel Enqueue */
-   #define SEMAPHORE                    0x08    /* CCCR Semaphore Bit          */
-   #define ILE                          0x10    /* CCCR ILE Bit                */
-   #define START_COMMAND                0x101A  /* CCCR Start Command Channel  */
-   #define START_STOP_BIT               0x0002  /* CCCR Start/Stop Bit         */
-   #define RST                          0x80    /* SCPR Reset Bit              */
-   #define EBM                          0x02    /* SCPR Enable Bus Master      */
-   #define EI                           0x80    /* HISR Enable Interrupts      */
-   #define OP                           0x01    /* OP bit in CBSP              */
+   /*
+    * Adapter address map equates
+    */
+   #define IPS_REG_HISR                 0x08    /* Host Interrupt Status Reg   */
+   #define IPS_REG_CCSAR                0x10    /* Cmd Channel System Addr Reg */
+   #define IPS_REG_CCCR                 0x14    /* Cmd Channel Control Reg     */
+   #define IPS_REG_SQHR                 0x20    /* Status Q Head Reg           */
+   #define IPS_REG_SQTR                 0x24    /* Status Q Tail Reg           */
+   #define IPS_REG_SQER                 0x28    /* Status Q End Reg            */
+   #define IPS_REG_SQSR                 0x2C    /* Status Q Start Reg          */
+   #define IPS_REG_SCPR                 0x05    /* Subsystem control port reg  */
+   #define IPS_REG_ISPR                 0x06    /* interrupt status port reg   */
+   #define IPS_REG_CBSP                 0x07    /* CBSP register               */
+   #define IPS_REG_FLAP                 0x18    /* Flash address port          */
+   #define IPS_REG_FLDP                 0x1C    /* Flash data port             */
 
-/*
- * Adapter Command ID Equates
- */
-   #define GET_LOGICAL_DRIVE_INFO       0x19
-   #define GET_SUBSYS_PARAM             0x40
-   #define READ_NVRAM_CONFIGURATION     0x38
-   #define RW_NVRAM_PAGE                0xBC
-   #define IPS_READ                     0x02
-   #define IPS_WRITE                    0x03
-   #define ENQUIRY                      0x05
-   #define FLUSH_CACHE                  0x0A
-   #define NORM_STATE                   0x00
-   #define READ_SCATTER_GATHER          0x82
-   #define WRITE_SCATTER_GATHER         0x83
-   #define DIRECT_CDB                   0x04
-   #define DIRECT_CDB_SCATTER_GATHER    0x84
-   #define CONFIG_SYNC                  0x58
-   #define POCL                         0x30
-   #define GET_ERASE_ERROR_TABLE        0x17
-   #define RESET_CHANNEL                0x1A
-   #define CSL                          0xFF
-   #define ADAPT_RESET                  0xFF
+   /*
+    * Adapter register bit equates
+    */
+   #define IPS_BIT_GHI                  0x04    /* HISR General Host Interrupt */
+   #define IPS_BIT_SQO                  0x02    /* HISR Status Q Overflow      */
+   #define IPS_BIT_SCE                  0x01    /* HISR Status Channel Enqueue */
+   #define IPS_BIT_SEM                  0x08    /* CCCR Semaphore Bit          */
+   #define IPS_BIT_ILE                  0x10    /* CCCR ILE Bit                */
+   #define IPS_BIT_START_CMD            0x101A  /* CCCR Start Command Channel  */
+   #define IPS_BIT_START_STOP           0x0002  /* CCCR Start/Stop Bit         */
+   #define IPS_BIT_RST                  0x80    /* SCPR Reset Bit              */
+   #define IPS_BIT_EBM                  0x02    /* SCPR Enable Bus Master      */
+   #define IPS_BIT_EI                   0x80    /* HISR Enable Interrupts      */
+   #define IPS_BIT_OP                   0x01    /* OP bit in CBSP              */
 
-/*
- * Adapter Equates
- */
+   /*
+    * Adapter Command ID Equates
+    */
+   #define IPS_CMD_GET_LD_INFO          0x19
+   #define IPS_CMD_GET_SUBSYS           0x40
+   #define IPS_CMD_READ_CONF            0x38
+   #define IPS_CMD_RW_NVRAM_PAGE        0xBC
+   #define IPS_CMD_READ                 0x02
+   #define IPS_CMD_WRITE                0x03
+   #define IPS_CMD_FFDC                 0xD7
+   #define IPS_CMD_ENQUIRY              0x05
+   #define IPS_CMD_FLUSH                0x0A
+   #define IPS_CMD_READ_SG              0x82
+   #define IPS_CMD_WRITE_SG             0x83
+   #define IPS_CMD_DCDB                 0x04
+   #define IPS_CMD_DCDB_SG              0x84
+   #define IPS_CMD_CONFIG_SYNC          0x58
+   #define IPS_CMD_ERROR_TABLE          0x17
+
+   /*
+    * Adapter Equates
+    */
+   #define IPS_CSL                      0xFF
+   #define IPS_POCL                     0x30
+   #define IPS_NORM_STATE               0x00
    #define IPS_MAX_ADAPTERS             16
    #define IPS_MAX_IOCTL                1
    #define IPS_MAX_IOCTL_QUEUE          8
    #define IPS_MAX_QUEUE                128
    #define IPS_BLKSIZE                  512
-   #define MAX_SG_ELEMENTS              17
-   #define MAX_LOGICAL_DRIVES           8
-   #define MAX_CHANNELS                 3
-   #define MAX_TARGETS                  15
-   #define MAX_CHUNKS                   16
-   #define MAX_CMDS                     128
+   #define IPS_MAX_SG                   17
+   #define IPS_MAX_LD                   8
+   #define IPS_MAX_CHANNELS             4
+   #define IPS_MAX_TARGETS              15
+   #define IPS_MAX_CHUNKS               16
+   #define IPS_MAX_CMDS                 128
    #define IPS_MAX_XFER                 0x10000
-   #define COMP_MODE_HEADS              128
-   #define COMP_MODE_SECTORS            32
-   #define NORM_MODE_HEADS              254
-   #define NORM_MODE_SECTORS            63
-   #define NVRAM_PAGE5_SIGNATURE        0xFFDDBB99
-   #define MAX_POST_BYTES               0x02
-   #define MAX_CONFIG_BYTES             0x02
-   #define GOOD_POST_BASIC_STATUS       0x80
-   #define SEMAPHORE_TIMEOUT            2000
-   #define IPS_INTR_OFF                 0
-   #define IPS_INTR_ON                  1
+   #define IPS_NVRAM_P5_SIG             0xFFDDBB99
+   #define IPS_MAX_POST_BYTES           0x02
+   #define IPS_MAX_CONFIG_BYTES         0x02
+   #define IPS_GOOD_POST_STATUS         0x80
+   #define IPS_SEM_TIMEOUT              2000
+   #define IPS_IOCTL_COMMAND            0x0D
+   #define IPS_IOCTL_NEW_COMMAND        0x81
+   #define IPS_INTR_ON                  0
+   #define IPS_INTR_IORL                1
+   #define IPS_INTR_HAL                 2
    #define IPS_ADAPTER_ID               0xF
    #define IPS_VENDORID                 0x1014
    #define IPS_DEVICEID                 0x002E
-   #define TIMEOUT_10                   0x10
-   #define TIMEOUT_60                   0x20
-   #define TIMEOUT_20M                  0x30
-   #define STATUS_SIZE                  4
-   #define STATUS_Q_SIZE                (MAX_CMDS+1) * STATUS_SIZE
-   #define ONE_MSEC                     1
-   #define ONE_SEC                      1000
+   #define IPS_IOCTL_SIZE               8192
+   #define IPS_STATUS_SIZE              4
+   #define IPS_STATUS_Q_SIZE            (IPS_MAX_CMDS+1) * IPS_STATUS_SIZE
+   #define IPS_ONE_MSEC                 1
+   #define IPS_ONE_SEC                  1000
+   
+   /*
+    * Geometry Settings
+    */
+   #define IPS_COMP_HEADS               128
+   #define IPS_COMP_SECTORS             32
+   #define IPS_NORM_HEADS               254
+   #define IPS_NORM_SECTORS             63
 
-/*
- * Adapter Basic Status Codes
- */
-   #define BASIC_STATUS_MASK            0xFF
-   #define GSC_STATUS_MASK              0x0F
-   #define SSUCCESS                     0x00
-   #define RECOVERED_ERROR              0x01
-   #define IPS_CHECK_CONDITION          0x02
-   #define INVAL_OPCO                   0x03
-   #define INVAL_CMD_BLK                0x04
-   #define INVAL_PARM_BLK               0x05
+   /*
+    * Adapter Basic Status Codes
+    */
+   #define IPS_BASIC_STATUS_MASK        0xFF
+   #define IPS_GSC_STATUS_MASK          0x0F
+   #define IPS_CMD_SUCCESS              0x00
+   #define IPS_CMD_RECOVERED_ERROR      0x01
+   #define IPS_INVAL_OPCO               0x03
+   #define IPS_INVAL_CMD_BLK            0x04
+   #define IPS_INVAL_PARM_BLK           0x05
    #define IPS_BUSY                     0x08
-   #define ADAPT_HARDWARE_ERROR         0x09
-   #define ADAPT_FIRMWARE_ERROR         0x0A
-   #define CMD_CMPLT_WERROR             0x0C
-   #define LOG_DRV_ERROR                0x0D
-   #define CMD_TIMEOUT                  0x0E
-   #define PHYS_DRV_ERROR               0x0F
+   #define IPS_CMD_CMPLT_WERROR         0x0C
+   #define IPS_LD_ERROR                 0x0D
+   #define IPS_CMD_TIMEOUT              0x0E
+   #define IPS_PHYS_DRV_ERROR           0x0F
 
-/*
- * Adapter Extended Status Equates
- */
-   #define SELECTION_TIMEOUT            0xF0
-   #define DATA_OVER_UNDER_RUN          0xF2
-   #define EXT_HOST_RESET               0xF7
-   #define EXT_DEVICE_RESET             0xF8
-   #define EXT_RECOVERY                 0xFC
-   #define EXT_CHECK_CONDITION          0xFF
+   /*
   * Adapter Extended Status Equates
   */
+   #define IPS_ERR_SEL_TO               0xF0
+   #define IPS_ERR_OU_RUN               0xF2
+   #define IPS_ERR_HOST_RESET           0xF7
+   #define IPS_ERR_DEV_RESET            0xF8
+   #define IPS_ERR_RECOVERY             0xFC
+   #define IPS_ERR_CKCOND               0xFF
 
-/*
- * Operating System Defines
- */
-   #define OS_WINDOWS_NT                0x01
-   #define OS_NETWARE                   0x02
-   #define OS_OPENSERVER                0x03
-   #define OS_UNIXWARE                  0x04
-   #define OS_SOLARIS                   0x05
-   #define OS_OS2                       0x06
-   #define OS_LINUX                     0x07
-   #define OS_FREEBSD                   0x08
+   /*
   * Operating System Defines
   */
+   #define IPS_OS_WINDOWS_NT            0x01
+   #define IPS_OS_NETWARE               0x02
+   #define IPS_OS_OPENSERVER            0x03
+   #define IPS_OS_UNIXWARE              0x04
+   #define IPS_OS_SOLARIS               0x05
+   #define IPS_OS_OS2                   0x06
+   #define IPS_OS_LINUX                 0x07
+   #define IPS_OS_FREEBSD               0x08
 
-/*
- * Adapter Command/Status Packet Definitions
- */
+   /*
+    * Adapter Revision ID's
+    */
+   #define IPS_REVID_SERVERAID          0x02
+   #define IPS_REVID_NAVAJO             0x03
+   #define IPS_REVID_SERVERAID2         0x04
+   #define IPS_REVID_CLARINETP1         0x05
+   #define IPS_REVID_CLARINETP2         0x07
+   #define IPS_REVID_CLARINETP3         0x0D
+   #define IPS_REVID_TROMBONE32         0x0F
+   #define IPS_REVID_TROMBONE64         0x10
+
+   /*
+    * Adapter Command/Status Packet Definitions
+    */
    #define IPS_SUCCESS                  0x01 /* Successfully completed       */
    #define IPS_SUCCESS_IMM              0x02 /* Success - Immediately        */
    #define IPS_FAILURE                  0x04 /* Completed with Error         */
 
-/*
- * Logical Drive Equates
- */
-   #define OFF_LINE                     0x02
-   #define OKAY                         0x03
-   #define FREE                         0x00
-   #define SYS                          0x06
-   #define CRS                          0x24
+   /*
   * Logical Drive Equates
   */
+   #define IPS_LD_OFFLINE               0x02
+   #define IPS_LD_OKAY                  0x03
+   #define IPS_LD_FREE                  0x00
+   #define IPS_LD_SYS                   0x06
+   #define IPS_LD_CRS                   0x24
 
-/*
- * DCDB Table Equates
- */
-   #define NO_DISCONNECT                0x00
-   #define DISCONNECT_ALLOWED           0x80
-   #define NO_AUTO_REQUEST_SENSE        0x40
-   #define IPS_DATA_NONE               0x00
-   #define IPS_DATA_UNK                        0x00
+   /*
   * DCDB Table Equates
   */
+   #define IPS_NO_DISCONNECT            0x00
+   #define IPS_DISCONNECT_ALLOWED       0x80
+   #define IPS_NO_AUTO_REQSEN           0x40
+   #define IPS_DATA_NONE                0x00
+   #define IPS_DATA_UNK                 0x00
    #define IPS_DATA_IN                  0x01
    #define IPS_DATA_OUT                 0x02
-   #define TRANSFER_64K                 0x08
-   #define NOTIMEOUT                    0x00
-   #define TIMEOUT10                    0x10
-   #define TIMEOUT60                    0x20
-   #define TIMEOUT20M                   0x30
+   #define IPS_TRANSFER64K              0x08
+   #define IPS_NOTIMEOUT                0x00
+   #define IPS_TIMEOUT10                0x10
+   #define IPS_TIMEOUT60                0x20
+   #define IPS_TIMEOUT20M               0x30
 
-/*
- * Host adapter Flags (bit numbers)
- */
+   /*
   * Host adapter Flags (bit numbers)
   */
    #define IPS_IN_INTR                  0
    #define IPS_IN_ABORT                 1
    #define IPS_IN_RESET                 2
 
-/*
- * SCB Flags
- */
-   #define SCB_ACTIVE                   0x00001
-   #define SCB_WAITING                  0x00002
+   /*
   * SCB Flags
   */
+   #define IPS_SCB_ACTIVE               0x00001
+   #define IPS_SCB_WAITING              0x00002
 
-/*
- * Passthru stuff
- */
-   #define COPPUSRCMD                  (('C'<<8) | 65)
+   /*
+    * Passthru stuff
+    */
+   #define IPS_COPPUSRCMD              (('C'<<8) | 65)
+   #define IPS_COPPIOCCMD              (('C'<<8) | 66)
    #define IPS_NUMCTRLS                (('C'<<8) | 68)
    #define IPS_CTRLINFO                (('C'<<8) | 69)
+   #define IPS_FLASHBIOS               (('C'<<8) | 70)
 
-/*
- * Scsi_Host Template
- */
+   /* time oriented stuff */
+   #define IPS_IS_LEAP_YEAR(y)           (((y % 4 == 0) && ((y % 100 != 0) || (y % 400 == 0))) ? 1 : 0)
+   #define IPS_NUM_LEAP_YEARS_THROUGH(y) ((y) / 4 - (y) / 100 + (y) / 400)
+
+   #define IPS_SECS_MIN                 60
+   #define IPS_SECS_HOUR                3600
+   #define IPS_SECS_8HOURS              28800
+   #define IPS_SECS_DAY                 86400
+   #define IPS_DAYS_NORMAL_YEAR         365
+   #define IPS_DAYS_LEAP_YEAR           366
+   #define IPS_EPOCH_YEAR               1970
+
+   /*
+    * Scsi_Host Template
+    */
  #define IPS {                            \
     next : NULL,                          \
     module : NULL,                        \
     bios_param : ips_biosparam,           \
     can_queue : 0,                        \
     this_id: -1,                          \
-    sg_tablesize : MAX_SG_ELEMENTS,       \
+    sg_tablesize : IPS_MAX_SG,            \
     cmd_per_lun: 16,                      \
     present : 0,                          \
     unchecked_isa_dma : 0,                \
@@ -313,7+379,7 @@ typedef struct {
    u16       reserved;
    u32       ccsar;
    u32       cccr;
-} BASIC_IO_CMD, *PBASIC_IO_CMD;
+} IPS_IO_CMD, *PIPS_IO_CMD;
 
 typedef struct {
    u8        op_code;
@@ -324,7+390,7 @@ typedef struct {
    u32       reserved3;
    u32       ccsar;
    u32       cccr;
-} LOGICAL_INFO, *PLOGICAL_INFO;
+} IPS_LD_CMD, *PIPS_LD_CMD;
 
 typedef struct {
    u8        op_code;
@@ -334,7+400,7 @@ typedef struct {
    u32       reserved3;
    u32       buffer_addr;
    u32       reserved4;
-} IOCTL_INFO, *PIOCTL_INFO;
+} IPS_IOCTL_CMD, *PIPS_IOCTL_CMD;
 
 typedef struct {
    u8        op_code;
@@ -345,7+411,7 @@ typedef struct {
    u32       reserved3;
    u32       ccsar;
    u32       cccr;
-} DCDB_CMD, *PDCDB_CMD;
+} IPS_DCDB_CMD, *PIPS_DCDB_CMD;
 
 typedef struct {
    u8        op_code;
@@ -357,7+423,7 @@ typedef struct {
    u32       reserved3;
    u32       ccsar;
    u32       cccr;
-} CONFIG_SYNC_CMD, *PCONFIG_SYNC_CMD;
+} IPS_CS_CMD, *PIPS_CS_CMD;
 
 typedef struct {
    u8        op_code;
@@ -369,7+435,7 @@ typedef struct {
    u32       reserved3;
    u32       ccsar;
    u32       cccr;
-} UNLOCK_STRIPE_CMD, *PUNLOCK_STRIPE_CMD;
+} IPS_US_CMD, *PIPS_US_CMD;
 
 typedef struct {
    u8        op_code;
@@ -381,7+447,7 @@ typedef struct {
    u32       reserved4;
    u32       ccsar;
    u32       cccr;
-} FLUSH_CACHE_CMD, *PFLUSH_CACHE_CMD;
+} IPS_FC_CMD, *PIPS_FC_CMD;
 
 typedef struct {
    u8        op_code;
@@ -393,7+459,7 @@ typedef struct {
    u32       reserved3;
    u32       ccsar;
    u32       cccr;
-} STATUS_CMD, *PSTATUS_CMD;
+} IPS_STATUS_CMD, *PIPS_STATUS_CMD;
 
 typedef struct {
    u8        op_code;
@@ -405,19+471,36 @@ typedef struct {
    u32       reserved2;
    u32       ccsar;
    u32       cccr;
-} NVRAM_CMD, *PNVRAM_CMD;
+} IPS_NVRAM_CMD, *PIPS_NVRAM_CMD;
+
+typedef struct {
+   u8     op_code;
+   u8     command_id;
+   u8     reset_count;
+   u8     reset_type;
+   u8     second;
+   u8     minute;
+   u8     hour;
+   u8     day;
+   u8     reserved1[4];
+   u8     month;
+   u8     yearH;
+   u8     yearL;
+   u8     reserved2;
+} IPS_FFDC_CMD, *PIPS_FFDC_CMD;
 
 typedef union {
-   BASIC_IO_CMD      basic_io;
-   LOGICAL_INFO      logical_info;
-   IOCTL_INFO        ioctl_info;
-   DCDB_CMD          dcdb;
-   CONFIG_SYNC_CMD   config_sync;
-   UNLOCK_STRIPE_CMD unlock_stripe;
-   FLUSH_CACHE_CMD   flush_cache;
-   STATUS_CMD        status;
-   NVRAM_CMD         nvram;
-} HOST_COMMAND, *PHOST_COMMAND;
+   IPS_IO_CMD        basic_io;
+   IPS_LD_CMD        logical_info;
+   IPS_IOCTL_CMD     ioctl_info;
+   IPS_DCDB_CMD      dcdb;
+   IPS_CS_CMD        config_sync;
+   IPS_US_CMD        unlock_stripe;
+   IPS_FC_CMD        flush_cache;
+   IPS_STATUS_CMD    status;
+   IPS_NVRAM_CMD     nvram;
+   IPS_FFDC_CMD      ffdc;
+} IPS_HOST_COMMAND, *PIPS_HOST_COMMAND;
 
 typedef struct {
    u8         logical_id;
@@ -425,25+508,13 @@ typedef struct {
    u8         raid_level;
    u8         state;
    u32        sector_count;
-} DRIVE_INFO, *PDRIVE_INFO;
-
-typedef struct {
-   u8         no_of_log_drive;
-   u8         reserved[3];
-   DRIVE_INFO drive_info[MAX_LOGICAL_DRIVES];
-} LOGICAL_DRIVE_INFO, *PLOGICAL_DRIVE_INFO;
+} IPS_DRIVE_INFO, *PIPS_DRIVE_INFO;
 
 typedef struct {
-   u8        ha_num;
-   u8        bus_num;
-   u8        id;
-   u8        device_type;
-   u32       data_len;
-   u32       data_ptr;
-   u8        scsi_cdb[12];
-   u32       data_counter;
-   u32       block_size;
-} NON_DISK_DEVICE_INFO, *PNON_DISK_DEVICE_INFO;
+   u8             no_of_log_drive;
+   u8             reserved[3];
+   IPS_DRIVE_INFO drive_info[IPS_MAX_LD];
+} IPS_LD_INFO, *PIPS_LD_INFO;
 
 typedef struct {
    u8         device_address;
@@ -458,24+529,24 @@ typedef struct {
    u8         sense_info[64];
    u8         scsi_status;
    u8         reserved2[3];
-} DCDB_TABLE, *PDCDB_TABLE;
+} IPS_DCDB_TABLE, *PIPS_DCDB_TABLE;
 
 typedef struct {
    volatile u8      reserved;
    volatile u8      command_id;
    volatile u8      basic_status;
    volatile u8      extended_status;
-} STATUS, *PSTATUS;
+} IPS_STATUS, *PIPS_STATUS;
 
 typedef struct {
-   STATUS               status[MAX_CMDS + 1];
-   volatile PSTATUS     p_status_start;
-   volatile PSTATUS     p_status_end;
-   volatile PSTATUS     p_status_tail;
+   IPS_STATUS           status[IPS_MAX_CMDS + 1];
+   volatile PIPS_STATUS p_status_start;
+   volatile PIPS_STATUS p_status_end;
+   volatile PIPS_STATUS p_status_tail;
    volatile u32         hw_status_start;
    volatile u32         hw_status_tail;
-   LOGICAL_DRIVE_INFO   logical_drive_info;
-} ADAPTER_AREA, *PADAPTER_AREA;
+   IPS_LD_INFO          logical_drive_info;
+} IPS_ADAPTER, *PIPS_ADAPTER;
 
 typedef struct {
    u8        ucLogDriveCount;
@@ -488,7+559,7 @@ typedef struct {
    u8        ucNVramDevChgCnt;
    u8        CodeBlkVersion[8];
    u8        BootBlkVersion[8];
-   u32       ulDriveSize[MAX_LOGICAL_DRIVES];
+   u32       ulDriveSize[IPS_MAX_LD];
    u8        ucConcurrentCmdCount;
    u8        ucMaxPhysicalDevices;
    u16       usFlashRepgmCount;
@@ -499,8+570,8 @@ typedef struct {
    u16       usConfigUpdateCount;
    u8        ucBlkFlag;
    u8        reserved;
-   u16       usAddrDeadDisk[MAX_CHANNELS * MAX_TARGETS];
-} ENQCMD, *PENQCMD;
+   u16       usAddrDeadDisk[IPS_MAX_CHANNELS * IPS_MAX_TARGETS];
+} IPS_ENQ, *PIPS_ENQ;
 
 typedef struct {
    u8        ucInitiator;
@@ -509,7+580,7 @@ typedef struct {
    u8        ucState;
    u32       ulBlockCount;
    u8        ucDeviceId[28];
-} DEVSTATE, *PDEVSTATE;
+} IPS_DEVSTATE, *PIPS_DEVSTATE;
 
 typedef struct {
    u8        ucChn;
@@ -517,7+588,7 @@ typedef struct {
    u16       ucReserved;
    u32       ulStartSect;
    u32       ulNoOfSects;
-} CHUNK, *PCHUNK;
+} IPS_CHUNK, *PIPS_CHUNK;
 
 typedef struct {
    u16       ucUserField;
@@ -528,8+599,8 @@ typedef struct {
    u8        ucParams;
    u8        ucReserved;
    u32       ulLogDrvSize;
-   CHUNK     chunk[MAX_CHUNKS];
-} LOGICAL_DRIVE, *PLOGICAL_DRIVE;
+   IPS_CHUNK chunk[IPS_MAX_CHUNKS];
+} IPS_LD, *PIPS_LD;
 
 typedef struct {
    u8        board_disc[8];
@@ -539,7+610,7 @@ typedef struct {
    u8        ucCompression;
    u8        ucNvramType;
    u32       ulNvramSize;
-} HARDWARE_DISC, *PHARDWARE_DISC;
+} IPS_HARDWARE, *PIPS_HARDWARE;  
 
 typedef struct {
    u8             ucLogDriveCount;
@@ -563,12+634,12 @@ typedef struct {
    u16            user_field;
    u8             ucRebuildRate;
    u8             ucReserve;
-   HARDWARE_DISC  hardware_disc;
-   LOGICAL_DRIVE  logical_drive[MAX_LOGICAL_DRIVES];
-   DEVSTATE       dev[MAX_CHANNELS][MAX_TARGETS+1];
+   IPS_HARDWARE   hardware_disc;
+   IPS_LD         logical_drive[IPS_MAX_LD];
+   IPS_DEVSTATE   dev[IPS_MAX_CHANNELS][IPS_MAX_TARGETS+1];
    u8             reserved[512];
 
-} CONFCMD, *PCONFCMD;
+} IPS_CONF, *PIPS_CONF;
 
 typedef struct {
    u32        signature;
@@ -583,11+654,11 @@ typedef struct {
    u8         driver_high[4];
    u8         driver_low[4];
    u8         reserved4[100];
-} NVRAM_PAGE5, *PNVRAM_PAGE5;
+} IPS_NVRAM_P5, *PIPS_NVRAM_P5;
 
-typedef struct _SUBSYS_PARAM {
+typedef struct _IPS_SUBSYS {
    u32        param[128];
-} SUBSYS_PARAM, *PSUBSYS_PARAM;
+} IPS_SUBSYS, *PIPS_SUBSYS;
 
 /*
  * Inquiry Data Format
@@ -614,7+685,7 @@ typedef struct {
    u8        ProductRevisionLevel[4];
    u8        VendorSpecific[20];
    u8        Reserved3[40];
-} IPS_INQUIRYDATA, *IPS_PINQUIRYDATA;
+} IPS_INQ_DATA, *PIPS_INQ_DATA;
 
 /*
  * Read Capacity Data Format
@@ -622,7+693,7 @@ typedef struct {
 typedef struct {
    u32       lba;
    u32       len;
-} CAPACITY_T;
+} IPS_CAPACITY;
 
 /*
  * Sense Data Format
@@ -646,7+717,7 @@ typedef struct {
    u32       pg_rmb:1;      /* Removeable                   */
    u32       pg_hsec:1;     /* Hard sector formatting       */
    u32       pg_ssec:1;     /* Soft sector formatting       */
-} DADF_T;
+} IPS_DADF;
 
 typedef struct {
    u8        pg_pc:6;        /* Page Code                     */
@@ -662,9+733,9 @@ typedef struct {
    u32       pg_landu:16;    /* Landing zone cylinder (upper) */
    u32       pg_landl:8;     /* Landing zone cylinder (lower) */
    u32       pg_res2:24;     /* Reserved                      */
-} RDDG_T;
+} IPS_RDDG;
 
-struct blk_desc {
+struct ips_blk_desc {
    u8       bd_dencode;
    u8       bd_nblks1;
    u8       bd_nblks2;
@@ -681,15+752,15 @@ typedef struct {
    u8       plh_res:7; /* Reserved                */
    u8       plh_wp:1;  /* Write protect           */
    u8       plh_bdl;   /* Block descriptor length */
-} SENSE_PLH_T;
+} ips_sense_plh_t;
 
 typedef struct {
-   SENSE_PLH_T     plh;
-   struct blk_desc blk_desc;
+   ips_sense_plh_t     plh;
+   struct ips_blk_desc blk_desc;
 
    union {
-      DADF_T        pg3;
-      RDDG_T        pg4;
+      IPS_DADF      pg3;
+      IPS_RDDG      pg4;
    } pdata;
 } ips_mdata_t;
 
@@ -699,14+770,14 @@ typedef struct {
 typedef struct ips_sglist {
    u32       address;
    u32       length;
-} SG_LIST, *PSG_LIST;
+} IPS_SG_LIST, *PIPS_SG_LIST;
 
-typedef struct _INFOSTR {
+typedef struct _IPS_INFOSTR {
    char *buffer;
    int   length;
    int   offset;
    int   pos;
-} INFOSTR;
+} IPS_INFOSTR;
 
 /*
  * Status Info
@@ -722,7+793,9 @@ typedef struct ips_stat {
 typedef struct ips_scb_queue {
    struct ips_scb *head;
    struct ips_scb *tail;
-   unsigned int    count;
+   u32             count;
+   u32             cpu_flags;
+   spinlock_t      lock;
 } ips_scb_queue_t;
 
 /*
@@ -731,12+804,28 @@ typedef struct ips_scb_queue {
 typedef struct ips_wait_queue {
    Scsi_Cmnd      *head;
    Scsi_Cmnd      *tail;
-   unsigned int    count;
+   u32             count;
+   u32             cpu_flags;
+   spinlock_t      lock;
 } ips_wait_queue_t;
 
+typedef struct ips_copp_wait_item {
+   Scsi_Cmnd                 *scsi_cmd;
+   struct semaphore          *sem;
+   struct ips_copp_wait_item *next;
+} ips_copp_wait_item_t;
+
+typedef struct ips_copp_queue {
+   struct ips_copp_wait_item *head;
+   struct ips_copp_wait_item *tail;
+   u32                        count;
+   u32                        cpu_flags;
+   spinlock_t                 lock;
+} ips_copp_queue_t;
+
 typedef struct ips_ha {
-   u8                 ha_id[MAX_CHANNELS+1];
-   u32                dcdb_active[MAX_CHANNELS];
+   u8                 ha_id[IPS_MAX_CHANNELS+1];
+   u32                dcdb_active[IPS_MAX_CHANNELS];
    u32                io_addr;            /* Base I/O address           */
    u8                 irq;                /* IRQ for adapter            */
    u8                 ntargets;           /* Number of targets          */
@@ -751,35+840,39 @@ typedef struct ips_ha {
    struct ips_scb    *scbs;               /* Array of all CCBS          */
    struct ips_scb    *scb_freelist;       /* SCB free list              */
    ips_wait_queue_t   scb_waitlist;       /* Pending SCB list           */
-   ips_wait_queue_t   copp_waitlist;      /* Pending PT list            */
+   ips_copp_queue_t   copp_waitlist;      /* Pending PT list            */
    ips_scb_queue_t    scb_activelist;     /* Active SCB list            */
-   BASIC_IO_CMD      *dummy;              /* dummy command              */
-   ADAPTER_AREA      *adapt;              /* Adapter status area        */
-   ENQCMD            *enq;                /* Adapter Enquiry data       */
-   CONFCMD           *conf;               /* Adapter config data        */
-   NVRAM_PAGE5       *nvram;              /* NVRAM page 5 data          */
-   SUBSYS_PARAM      *subsys;             /* Subsystem parameters       */
+   IPS_IO_CMD        *dummy;              /* dummy command              */
+   IPS_ADAPTER       *adapt;              /* Adapter status area        */
+   IPS_ENQ           *enq;                /* Adapter Enquiry data       */
+   IPS_CONF          *conf;               /* Adapter config data        */
+   IPS_NVRAM_P5      *nvram;              /* NVRAM page 5 data          */
+   IPS_SUBSYS        *subsys;             /* Subsystem parameters       */
+   char              *ioctl_data;         /* IOCTL data area            */
+   u32                ioctl_datasize;     /* IOCTL data size            */
    u32                cmd_in_progress;    /* Current command in progress*/
    u32                flags;              /* HA flags                   */
    u8                 waitflag;           /* are we waiting for cmd     */
    u8                 active;
-   u32                reserved:16;        /* reserved space             */
-   wait_queue_head_t  copp_queue;         /* passthru sync queue        */
+   u16                reset_count;        /* number of resets           */
+   u32                last_ffdc;          /* last time we sent ffdc info*/
+   u8                 revision_id;        /* Revision level             */
 
    #if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,0)
    spinlock_t         scb_lock;
    spinlock_t         copp_lock;
+   spinlock_t         ips_lock;
    #endif
 } ips_ha_t;
 
-typedef void (*scb_callback) (ips_ha_t *, struct ips_scb *);
+typedef void (*ips_scb_callback) (ips_ha_t *, struct ips_scb *);
 
 /*
  * SCB Format
  */
 typedef struct ips_scb {
-   HOST_COMMAND      cmd;
-   DCDB_TABLE        dcdb;
+   IPS_HOST_COMMAND  cmd;
+   IPS_DCDB_TABLE    dcdb;
    u8                target_id;
    u8                bus;
    u8                lun;
@@ -794,32+887,54 @@ typedef struct ips_scb {
    u32               sg_len;
    u32               flags;
    u32               op_code;
-   SG_LIST          *sg_list;
+   IPS_SG_LIST      *sg_list;
    Scsi_Cmnd        *scsi_cmd;
    struct ips_scb   *q_next;
-   scb_callback      callback;
+   ips_scb_callback  callback;
+   struct semaphore *sem;
 } ips_scb_t;
 
+typedef struct ips_scb_pt {
+   IPS_HOST_COMMAND  cmd;
+   IPS_DCDB_TABLE    dcdb;
+   u8                target_id;
+   u8                bus;
+   u8                lun;
+   u8                cdb[12];
+   u32               scb_busaddr;
+   u32               data_busaddr;
+   u32               timeout;
+   u8                basic_status;
+   u8                extended_status;
+   u16               breakup;
+   u32               data_len;
+   u32               sg_len;
+   u32               flags;
+   u32               op_code;
+   IPS_SG_LIST      *sg_list;
+   Scsi_Cmnd        *scsi_cmd;
+   struct ips_scb   *q_next;
+   ips_scb_callback  callback;
+} ips_scb_pt_t;
+
 /*
  * Passthru Command Format
  */
 typedef struct {
-   u8         CoppID[4];
-   u32        CoppCmd;
-   u32        PtBuffer;
-   u8        *CmdBuffer;
-   u32        CmdBSize;
-   ips_scb_t  CoppCP;
-   u32        TimeOut;
-   u8         BasicStatus;
-   u8         ExtendedStatus;
-   u16        reserved;
+   u8            CoppID[4];
+   u32           CoppCmd;
+   u32           PtBuffer;
+   u8           *CmdBuffer;
+   u32           CmdBSize;
+   ips_scb_pt_t  CoppCP;
+   u32           TimeOut;
+   u8            BasicStatus;
+   u8            ExtendedStatus;
+   u16           reserved;
 } ips_passthru_t;
 
 #endif
 
-
-
 /*
  * Overrides for Emacs so that we almost follow Linus's tabbing style.
  * Emacs will notice this stuff at the end of the file and automatically
index 2c7dbb0..399148c 100644 (file)
@@ -62,7+62,7 @@ obj-$(CONFIG_SOUND_VMIDI)     += v_midi.o
 obj-$(CONFIG_SOUND_VIDC)       += vidc_mod.o
 obj-$(CONFIG_SOUND_WAVEARTIST) += waveartist.o
 obj-$(CONFIG_SOUND_SGALAXY)    += sgalaxy.o ad1848.o
-obj-$(CONFIG_SOUND_AD1816)     += ad1816.o sound.o
+obj-$(CONFIG_SOUND_AD1816)     += ad1816.o
 obj-$(CONFIG_SOUND_ACI_MIXER)  += aci.o
 obj-$(CONFIG_SOUND_AWE32_SYNTH)        += awe_wave.o
 
index 0b30ebb..fe26b4c 100644 (file)
@@ -64,14+64,12 @@ if [ "$CONFIG_FB" = "y" ]; then
    fi
    if [ "$CONFIG_PPC" = "y" ]; then
       bool '  Open Firmware frame buffer device support' CONFIG_FB_OF
-      if [ "$CONFIG_FB_OF" = "y" ]; then
-        bool '    Apple "control" display support' CONFIG_FB_CONTROL
-        bool '    Apple "platinum" display support' CONFIG_FB_PLATINUM
-        bool '    Apple "valkyrie" display support' CONFIG_FB_VALKYRIE
-        bool '    IMS Twin Turbo display support' CONFIG_FB_IMSTT
-        bool '    Chips 65550 display support' CONFIG_FB_CT65550
-        bool '    S3 Trio display support' CONFIG_FB_S3TRIO
-      fi
+      bool '  Apple "control" display support' CONFIG_FB_CONTROL
+      bool '  Apple "platinum" display support' CONFIG_FB_PLATINUM
+      bool '  Apple "valkyrie" display support' CONFIG_FB_VALKYRIE
+      bool '  Chips 65550 display support' CONFIG_FB_CT65550
+      bool '  IMS Twin Turbo display support' CONFIG_FB_IMSTT
+      bool '  S3 Trio display support' CONFIG_FB_S3TRIO
       tristate '  VGA 16-color graphics console' CONFIG_FB_VGA16
    fi
    if [ "$CONFIG_MAC" = "y" ]; then
index 333fd65..bcc2b9b 100644 (file)
@@ -77,6+77,7 @@ static struct fb_var_screeninfo fb_var = { 0, };
      *  Interface used by the world
      */
 
+static void __init s3triofb_of_init(struct device_node *dp);
 static int s3trio_get_fix(struct fb_fix_screeninfo *fix, int con,
                          struct fb_info *info);
 static int s3trio_get_var(struct fb_var_screeninfo *var, int con,
@@ -263,12+264,11 @@ static int s3trio_set_cmap(struct fb_cmap *cmap, int kspc, int con,
 
 int __init s3triofb_init(void)
 {
-#ifdef __powerpc__
-    /* We don't want to be called like this. */
-    /* We rely on Open Firmware (offb) instead. */
-#else /* !__powerpc__ */
-    /* To be merged with cybervision */
-#endif /* !__powerpc__ */
+       struct device_node *dp;
+
+       dp = find_devices("S3Trio");
+       if (dp != 0)
+           s3triofb_of_init(dp);
        return 0;
 }
 
@@ -376,10+376,10 @@ int __init s3trio_init(struct device_node *dp){
      *  We heavily rely on OF for the moment. This needs fixing.
      */
 
-void __init s3triofb_init_of(struct device_node *dp)
+static void __init s3triofb_of_init(struct device_node *dp)
 {
     int i, *pp, len;
-    unsigned long address;
+    unsigned long address, size;
     u_long *CursorBase;
 
     strncat(s3trio_name, dp->name, sizeof(s3trio_name));
@@ -416,9+416,13 @@ void __init s3triofb_init_of(struct device_node *dp)
        fb_fix.line_length = fb_var.xres_virtual;
     fb_fix.smem_len = fb_fix.line_length*fb_var.yres;
 
-    s3trio_init(dp);
     address = 0xc6000000;
-    s3trio_base = ioremap(address,64*1024*1024);
+    size = 64*1024*1024;
+    if (!request_mem_region(address, size, "S3triofb"))
+       return;
+
+    s3trio_init(dp);
+    s3trio_base = ioremap(address, size);
     fb_fix.smem_start = address;
     fb_fix.type = FB_TYPE_PACKED_PIXELS;
     fb_fix.type_aux = 0;
@@ -695,12+699,6 @@ static void do_install_cmap(int con, struct fb_info *info)
                    s3trio_setcolreg, &fb_info);
 }
 
-int s3triofb_setup(char *options) {
-
-        return 0;
-
-}
-
 static void Trio_WaitQueue(u_short fifo) {
 
        u_short status;
index 96a3b9a..22f6031 100644 (file)
@@ -113,8+113,8 @@ static struct pmu_sleep_notifier chips_sleep_notifier = {
  * Exported functions
  */
 int chips_init(void);
-void chips_of_init(struct device_node *dp);
 
+static void chips_of_init(struct device_node *dp);
 static int chips_get_fix(struct fb_fix_screeninfo *fix, int con,
                         struct fb_info *info);
 static int chips_get_var(struct fb_var_screeninfo *var, int con,
@@ -625,17+625,15 @@ static void __init init_chips(struct fb_info_chips *p)
 
 int __init chips_init(void)
 {
-#ifndef CONFIG_FB_OF
        struct device_node *dp;
 
        dp = find_devices("chips65550");
        if (dp != 0)
                chips_of_init(dp);
-#endif /* CONFIG_FB_OF */
        return 0;
 }
 
-void __init chips_of_init(struct device_node *dp)
+static void __init chips_of_init(struct device_node *dp)
 {
        struct fb_info_chips *p;
        unsigned long addr;
@@ -649,6+647,10 @@ void __init chips_of_init(struct device_node *dp)
                return;
        memset(p, 0, sizeof(*p));
        addr = dp->addrs[0].address;
+       if (!request_mem_region(addr, dp->addrs[0].size, "chipsfb")) {
+               kfree(p);
+               return;
+       }
 #ifdef __BIG_ENDIAN
        addr += 0x800000;       // Use big-endian aperture
 #endif
index a88919d..e381984 100644 (file)
 #ifdef CONFIG_AMIGA
 #include <asm/amigahw.h>
 #endif
-#ifdef CONFIG_FB_OF
-#include <asm/prom.h>
-#endif
 
 #include <video/fbcon.h>
 #include <video/fbcon-mfb.h>
@@ -472,9+469,6 @@ int clgenfb_setup (char *options);
 
 static int clgenfb_open (struct fb_info *info, int user);
 static int clgenfb_release (struct fb_info *info, int user);
-#if defined(CONFIG_FB_OF)
-int clgen_of_init (struct device_node *dp);
-#endif
 
 /* function table of the above functions */
 static struct fb_ops clgenfb_ops = {
@@ -2400,34+2394,6 @@ static void __init get_prep_addrs (unsigned long *display, unsigned long *regist
 
 
 
-#ifdef CONFIG_FB_OF
-static void __init get_of_addrs (const struct device_node *dp,
-                         unsigned long *display, unsigned long *registers)
-{
-       int i;
-
-       DPRINTK ("ENTER\n");
-
-       /* Map in frame buffer and registers */
-       for (i = 0; i < dp->n_addrs; ++i) {
-               unsigned long addr = dp->addrs[i].address;
-               unsigned long size = dp->addrs[i].size;
-               printk ("dp->addrs[%d].address = %lx, dp->addrs[%d].size = %lx\n",
-                       i, addr, i, size);
-               if (size >= 0x800000) {
-                       *display = addr;
-               } else {
-                       *registers = addr;
-               }
-       }
-
-       DPRINTK ("EXIT\n");
-}
-#endif                         /* CONFIG_FB_OF */
-
-
-
-
 #ifdef CONFIG_PCI
 /* Pulled the logic from XFree86 Cirrus driver to get the memory size,
  * based on the DRAM bandwidth bit and DRAM bank switching bit.  This
@@ -2529,9+2495,6 @@ static void __exit clgen_pci_unmap (struct clgenfb_info *info)
 static int __init clgen_pci_setup (struct clgenfb_info *info,
                                   clgen_board_t *btype)
 {
-#ifdef CONFIG_FB_OF
-       struct device_node *dp;
-#endif                         /* CONFIG_FB_OF */
        struct pci_dev *pdev;
        unsigned long board_addr, board_size;
 
@@ -2554,29+2517,12 @@ static int __init clgen_pci_setup (struct clgenfb_info *info,
        pcibios_write_config_dword (0, pdev->devfn, PCI_BASE_ADDRESS_0, 0x00000000);
 #endif
 
-#ifdef CONFIG_FB_OF
-       /* Ok, so its an ugly hack, since we could have passed it down from
-        * clgen_of_init() if we'd done it right. */
-       DPRINTK ("Attempt to get OF info for MacPicasso\n");
-       dp = find_devices ("MacPicasso");
-       if (dp != 0) {
-               if (dp->n_addrs != 2) {
-                       printk (KERN_ERR "expecting 2 address for clgen (got %d)\n", dp->n_addrs);
-                       DPRINTK ("EXIT, returning 1\n");
-                       return 1;
-               }
-               get_of_addrs (dp, &board_addr, &info->fbregs_phys);
-       } else
-#endif
-       {
-
 #ifdef CONFIG_PREP
-               get_prep_addrs (&board_addr, &info->fbregs_phys);
+       get_prep_addrs (&board_addr, &info->fbregs_phys);
 #else                          /* CONFIG_PREP */
-               DPRINTK ("Attempt to get PCI info for Cirrus Graphics Card\n");
-               get_pci_addrs (pdev, &board_addr, &info->fbregs_phys);
+       DPRINTK ("Attempt to get PCI info for Cirrus Graphics Card\n");
+       get_pci_addrs (pdev, &board_addr, &info->fbregs_phys);
 #endif                         /* CONFIG_PREP */
-       }
 
        DPRINTK ("Board address: 0x%lx, register address: 0x%lx\n", board_addr, info->fbregs_phys);
 
@@ -2838,14+2784,6 @@ int __init clgenfb_init(void)
 
 
 
-#if defined(CONFIG_FB_OF)
-int __init clgen_of_init (struct device_node *dp)
-{
-       return clgenfb_init ();
-}
-#endif                         /* CONFIG_FB_OF */
-
-
     /*
      *  Cleanup (only needed for module)
      */
index 1045389..b609f43 100644 (file)
@@ -146,11+146,9 @@ static int default_cmode = CMODE_NVRAM;
  * Exported functions
  */
 int control_init(void);
-#ifdef CONFIG_FB_OF
-void control_of_init(struct device_node *dp);
-#endif
 void control_setup(char *);
 
+static void control_of_init(struct device_node *dp);
 static int read_control_sense(struct fb_info_control *p);
 static inline int control_vram_reqd(int video_mode, int color_mode);
 static void set_control_clock(unsigned char *params);
@@ -195,6+193,7 @@ int init_module(void)
 
 void cleanup_module(void)
 {
+       /* FIXME: clean up and release regions */
 }
 #endif
 
@@ -638,17+637,15 @@ static void control_set_hardware(struct fb_info_control *p, struct fb_par_contro
 
 int __init control_init(void)
 {
-#ifndef CONFIG_FB_OF
        struct device_node *dp;
 
        dp = find_devices("control");
        if (dp != 0)
                control_of_init(dp);
-#endif /* CONFIG_FB_OF */
        return 0;
 }
 
-void __init control_of_init(struct device_node *dp)
+static void __init control_of_init(struct device_node *dp)
 {
        struct fb_info_control  *p;
        unsigned long           addr, size;
@@ -667,6+664,11 @@ void __init control_of_init(struct device_node *dp)
        for (i = 0; i < dp->n_addrs; ++i) {
                addr = dp->addrs[i].address;
                size = dp->addrs[i].size;
+               /* Let's assume we can request either all or nothing */
+               if (!request_mem_region(addr, size, "controlfb")) {
+                   kfree(p);
+                   return;
+               }
                if (size >= 0x800000) {
                        /* use the big-endian aperture (??) */
                        addr += 0x800000;
@@ -679,6+681,7 @@ void __init control_of_init(struct device_node *dp)
                }
        }
        p->cmap_regs_phys = 0xf301b000;  /* XXX not in prom? */
+       request_mem_region(p->cmap_regs_phys, 0x1000, "controlfb cmap");
        p->cmap_regs = ioremap(p->cmap_regs_phys, 0x1000);
 
        /* Work out which banks of VRAM we have installed. */
index 9cb20fc..6ca8c3d 100644 (file)
@@ -67,7+67,6 @@ extern int hitfb_setup(char*);
 extern int vfb_init(void);
 extern int vfb_setup(char*);
 extern int offb_init(void);
-extern int offb_setup(char*);
 extern int atyfb_init(void);
 extern int atyfb_setup(char*);
 extern int aty128fb_init(void);
@@ -83,7+82,6 @@ extern int virgefb_init(void);
 extern int virgefb_setup(char*);
 extern int resolver_video_setup(char*);
 extern int s3triofb_init(void);
-extern int s3triofb_setup(char*);
 extern int vesafb_init(void);
 extern int vesafb_setup(char*);
 extern int vga16fb_init(void);
@@ -96,10+94,13 @@ extern int hpfb_init(void);
 extern int hpfb_setup(char*);
 extern int sbusfb_init(void);
 extern int sbusfb_setup(char*);
-extern int valkyriefb_init(void);
-extern int valkyriefb_setup(char*);
 extern int control_init(void);
 extern int control_setup(char*);
+extern int platinum_init(void);
+extern int platinum_setup(char*);
+extern int valkyriefb_init(void);
+extern int valkyriefb_setup(char*);
+extern int chips_init(void);
 extern int g364fb_init(void);
 extern int sa1100fb_init(void);
 extern int sa1100fb_setup(char*);
@@ -122,6+123,7 @@ static struct {
        int (*init)(void);
        int (*setup)(char*);
 } fb_drivers[] __initdata = {
+
 #ifdef CONFIG_FB_SBUS
        /*
         * Sbusfb must be initialized _before_ other frame buffer devices that
@@ -129,27+131,17 @@ static struct {
         */
        { "sbus", sbusfb_init, sbusfb_setup },
 #endif
-#ifdef CONFIG_FB_3DFX
-       { "tdfx", tdfxfb_init, tdfxfb_setup },
-#endif
-#ifdef CONFIG_FB_SGIVW
-       { "sgivw", sgivwfb_init, sgivwfb_setup },
-#endif
+
+       /*
+        * Chipset specific drivers that use resource management
+        */
+
 #ifdef CONFIG_FB_RETINAZ3
        { "retz3", retz3fb_init, retz3fb_setup },
 #endif
-#ifdef CONFIG_FB_ACORN
-       { "acorn", acornfb_init, acornfb_setup },
-#endif
 #ifdef CONFIG_FB_AMIGA
        { "amifb", amifb_init, amifb_setup },
 #endif
-#ifdef CONFIG_FB_ATARI
-       { "atafb", atafb_init, atafb_setup },
-#endif
-#ifdef CONFIG_FB_MAC
-       { "macfb", macfb_init, macfb_setup },
-#endif
 #ifdef CONFIG_FB_CYBER
        { "cyber", cyberfb_init, cyberfb_setup },
 #endif
@@ -171,79+163,120 @@ static struct {
 #ifdef CONFIG_FB_ATY128
        { "aty128fb", aty128fb_init, aty128fb_setup },
 #endif
+#ifdef CONFIG_FB_VIRGE
+       { "virge", virgefb_init, virgefb_setup },
+#endif
+#ifdef CONFIG_FB_RIVA
+       { "riva", rivafb_init, rivafb_setup },
+#endif
+#ifdef CONFIG_FB_CONTROL
+       { "controlfb", control_init, control_setup },
+#endif
+#ifdef CONFIG_FB_PLATINUM
+       { "platinumfb", platinum_init, platinum_setup },
+#endif
+#ifdef CONFIG_FB_VALKYRIE
+       { "valkyriefb", valkyriefb_init, valkyriefb_setup },
+#endif
+#ifdef CONFIG_FB_CT65550
+       { "chipsfb", chips_init, NULL },
+#endif
+#ifdef CONFIG_FB_IMSTT
+       { "imsttfb", imsttfb_init, imsttfb_setup },
+#endif
+#ifdef CONFIG_FB_S3TRIO
+       { "s3trio", s3triofb_init, NULL },
+#endif 
+#ifdef CONFIG_FB_FM2
+       { "fm2fb", fm2fb_init, fm2fb_setup },
+#endif 
+#ifdef CONFIG_FB_SIS
+       { "sisfb", sisfb_init, sisfb_setup },
+#endif
+
+       /*
+        * Generic drivers that are used as fallbacks
+        * 
+        * These depend on resource management and must be initialized
+        * _after_ all other frame buffer devices that use resource
+        * management!
+        */
+
 #ifdef CONFIG_FB_OF
+       { "offb", offb_init, NULL },
+#endif
+#ifdef CONFIG_FB_VESA
+       { "vesa", vesafb_init, vesafb_setup },
+#endif 
+
        /*
-        * Offb must be initialized _after_ all other frame buffer devices
-        * that use PCI probing and PCI resources! [ Geert ]
+        * Chipset specific drivers that don't use resource management (yet)
         */
-       { "offb", offb_init, offb_setup },
+
+#ifdef CONFIG_FB_3DFX
+       { "tdfx", tdfxfb_init, tdfxfb_setup },
+#endif
+#ifdef CONFIG_FB_SGIVW
+       { "sgivw", sgivwfb_init, sgivwfb_setup },
 #endif
+#ifdef CONFIG_FB_ACORN
+       { "acorn", acornfb_init, acornfb_setup },
+#endif
+#ifdef CONFIG_FB_ATARI
+       { "atafb", atafb_init, atafb_setup },
+#endif
+#ifdef CONFIG_FB_MAC
+       { "macfb", macfb_init, macfb_setup },
+#endif
+#ifdef CONFIG_FB_HGA
+       { "hga", hgafb_init, hgafb_setup },
+#endif 
 #ifdef CONFIG_FB_IGA
         { "igafb", igafb_init, igafb_setup },
 #endif
-#ifdef CONFIG_FB_IMSTT
-       { "imsttfb", imsttfb_init, imsttfb_setup },
-#endif
 #ifdef CONFIG_APOLLO
        { "apollo", dnfb_init, NULL },
 #endif
 #ifdef CONFIG_FB_Q40
        { "q40fb", q40fb_init, NULL },
 #endif
-#ifdef CONFIG_FB_S3TRIO
-       { "s3trio", s3triofb_init, s3triofb_setup },
-#endif 
 #ifdef CONFIG_FB_TGA
        { "tga", tgafb_init, tgafb_setup },
 #endif
-#ifdef CONFIG_FB_VIRGE
-       { "virge", virgefb_init, virgefb_setup },
-#endif
-#ifdef CONFIG_FB_RIVA
-       { "riva", rivafb_init, rivafb_setup },
-#endif
-#ifdef CONFIG_FB_VESA
-       { "vesa", vesafb_init, vesafb_setup },
-#endif 
-#ifdef CONFIG_FB_VGA16
-       { "vga16", vga16fb_init, vga16fb_setup },
-#endif 
-#ifdef CONFIG_FB_HGA
-       { "hga", hgafb_init, hgafb_setup },
-#endif 
 #ifdef CONFIG_FB_HP300
        { "hpfb", hpfb_init, hpfb_setup },
 #endif 
-#ifdef CONFIG_FB_CONTROL
-       { "controlfb", control_init, control_setup },
-#endif
-#ifdef CONFIG_FB_VALKYRIE
-       { "valkyriefb", valkyriefb_init, valkyriefb_setup },
-#endif
 #ifdef CONFIG_FB_G364
        { "g364", g364fb_init, NULL },
 #endif
 #ifdef CONFIG_FB_SA1100
        { "sa1100", sa1100fb_init, sa1100fb_setup },
 #endif
-#ifdef CONFIG_FB_FM2
-       { "fm2fb", fm2fb_init, fm2fb_setup },
-#endif 
 #ifdef CONFIG_FB_SUN3
        { "sun3", sun3fb_init, sun3fb_setup },
 #endif
 #ifdef CONFIG_FB_HIT
        { "hitfb", hitfb_init, hitfb_setup },
 #endif
+
+       /*
+        * Generic drivers that don't use resource management (yet)
+        */
+
+#ifdef CONFIG_FB_VGA16
+       { "vga16", vga16fb_init, vga16fb_setup },
+#endif 
+
 #ifdef CONFIG_GSP_RESOLVER
        /* Not a real frame buffer device... */
        { "resolver", NULL, resolver_video_setup },
 #endif
-#ifdef CONFIG_FB_SIS
-       { "sisfb", sisfb_init, sisfb_setup },
-#endif
+
 #ifdef CONFIG_FB_VIRTUAL
-       /* Must be last to avoid that vfb becomes your primary display */
+       /*
+        * Vfb must be last to avoid that it becomes your primary display if
+        * other display devices are present
+        */
        { "vfb", vfb_init, vfb_setup },
 #endif
 };
@@ -264,6+297,10 @@ static int first_fb_vc = 0;
 static int last_fb_vc = MAX_NR_CONSOLES-1;
 static int fbcon_is_default = 1;
 
+#ifdef CONFIG_FB_OF
+static int ofonly __initdata = 0;
+#endif
+
 static int fbmem_read_proc(char *buf, char **start, off_t offset,
                           int len, int *eof, void *private)
 {
@@ -728,6+765,13 @@ fbmem_init(void)
        if (devfs_register_chrdev(FB_MAJOR,"fb",&fb_fops))
                printk("unable to get major %d for fb devs\n", FB_MAJOR);
 
+#ifdef CONFIG_FB_OF
+       if (ofonly) {
+               offb_init();
+               return;
+       }
+#endif
+
        /*
         *  Probe for all builtin frame buffer devices
         */
@@ -787,6+831,13 @@ int __init video_setup(char *options)
            fbcon_is_default = 0;
     }
 
+#ifdef CONFIG_FB_OF
+    if (!strcmp(options, "ofonly")) {
+           ofonly = 1;
+           return 0;
+    }
+#endif
+
     if (num_pref_init_funcs == FB_MAX)
            return 0;
 
index d3b3e5a..1749f32 100644 (file)
@@ -355,6+355,7 @@ struct fb_info_imstt {
        struct imstt_regvals init;
        struct imstt_cursor cursor;
        unsigned long frame_buffer_phys;
+       unsigned long board_size;
        __u8 *frame_buffer;
        unsigned long dc_regs_phys;
        __u32 *dc_regs;
@@ -1879,62+1880,13 @@ init_imstt(struct fb_info_imstt *p)
 #endif /* CONFIG_FB_COMPAT_XPMAC */
 }
 
-#if defined(CONFIG_FB_OF) && !defined(MODULE)
-void __init 
-imsttfb_of_init(struct device_node *dp)
-{
-       struct fb_info_imstt *p;
-       int i;
-       __u32 addr = 0;
-       __u8 bus, devfn;
-       __u16 cmd;
-
-       for (i = 0; i < dp->n_addrs; i++) {
-               if (dp->addrs[i].size >= 0x02000000)
-                       addr = dp->addrs[i].address;
-       }
-       if (!addr)
-               return;
-
-       if (!pci_device_loc(dp, &bus, &devfn)) {
-               if (!pcibios_read_config_word(bus, devfn, PCI_COMMAND, &cmd) && !(cmd & PCI_COMMAND_MEMORY)) {
-                       cmd |= PCI_COMMAND_MEMORY;
-                       pcibios_write_config_word(bus, devfn, PCI_COMMAND, cmd);
-               }
-       }
-
-       p = kmalloc(sizeof(struct fb_info_imstt), GFP_ATOMIC);
-       if (!p)
-               return;
-       memset(p, 0, sizeof(struct fb_info_imstt));
-
-       if (dp->name[11] == '8' || (dp->name[6] == '3' && dp->name[7] == 'd'))
-               p->ramdac = TVP;
-       else
-               p->ramdac = IBM;
-
-       p->frame_buffer_phys = addr;
-       p->frame_buffer = (__u8 *)ioremap(addr, p->ramdac == IBM ? 0x400000 : 0x800000);
-       p->dc_regs_phys = addr + 0x800000;
-       p->dc_regs = (__u32 *)ioremap(addr + 0x800000, 0x1000);
-       p->cmap_regs_phys = addr + 0x840000;
-       p->cmap_regs = (__u8 *)ioremap(addr + 0x840000, 0x1000);
-
-       init_imstt(p);
-}
-#endif
-
 int __init 
 imsttfb_init(void)
 {
        int i;
-#if defined(CONFIG_FB_OF) && !defined(MODULE)
-       /* We don't want to be called like this. */
-       /* We rely on Open Firmware (offb) instead. */
-#elif defined(CONFIG_PCI)
        struct pci_dev *pdev = NULL;
        struct fb_info_imstt *p;
-       __u32 addr;
+       unsigned long addr, size;
        __u16 cmd;
 
        while ((pdev = pci_find_device(PCI_VENDOR_ID_IMS, PCI_ANY_ID, pdev))) {
@@ -1944,6+1896,7 @@ imsttfb_init(void)
                        continue;
 
                addr = pci_resource_start (pdev, 0);
+               size = pci_resource_len (pdev, 0);
                if (!addr)
                        continue;
 
@@ -1952,6+1905,10 @@ imsttfb_init(void)
                        continue;
                memset(p, 0, sizeof(struct fb_info_imstt));
 
+               if (!request_mem_region(addr, size, "imsttfb")) {
+                       kfree(p);
+                       continue;
+               }
                printk("imsttfb: device=%04x\n", pdev->device);
 
                switch (pdev->device) {
@@ -1965,6+1922,7 @@ imsttfb_init(void)
                }
 
                p->frame_buffer_phys = addr;
+               p->board_size = size;
                p->frame_buffer = (__u8 *)ioremap(addr, p->ramdac == IBM ? 0x400000 : 0x800000);
                p->dc_regs_phys = addr + 0x800000;
                p->dc_regs = (__u32 *)ioremap(addr + 0x800000, 0x1000);
@@ -1973,7+1931,6 @@ imsttfb_init(void)
 
                init_imstt(p);
        }
-#endif /* CONFIG_PCI */
        for (i = 0; i < FB_MAX; i++) {
                if (fb_info_imstt_p[i])
                        return 0;
@@ -2059,6+2016,7 @@ cleanup_module (void)
                iounmap(p->dc_regs);
                iounmap(p->frame_buffer);
                kfree(p);
+               release_mem_region(p->frame_buffer_phys, p->board_size);
        }
 }
 
index cbdc984..9ddb301 100644 (file)
 #include <linux/matroxfb.h>
 #include <asm/uaccess.h>
 
-#if defined(CONFIG_FB_OF)
+#ifdef CONFIG_PPC
 unsigned char nvram_read_byte(int);
 static int default_vmode = VMODE_NVRAM;
 static int default_cmode = CMODE_NVRAM;
@@ -2343,7+2343,7 @@ int __init matroxfb_setup(char *options) {
                        mem = simple_strtoul(this_opt+4, NULL, 0);
                else if (!strncmp(this_opt, "mode:", 5))
                        strncpy(videomode, this_opt+5, sizeof(videomode)-1);
-#ifdef CONFIG_FB_OF
+#ifdef CONFIG_PPC
                else if (!strncmp(this_opt, "vmode:", 6)) {
                        unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0);
                        if (vmode > 0 && vmode <= VMODE_MAX)
@@ -2519,7+2519,7 @@ MODULE_PARM(cross4MB, "i");
 MODULE_PARM_DESC(cross4MB, "Specifies that 4MB boundary can be in middle of line. (default=autodetected)");
 MODULE_PARM(dfp, "i");
 MODULE_PARM_DESC(dfp, "Specifies whether to use digital flat panel interface of G200/G400 (0 or 1) (default=0)");
-#ifdef CONFIG_FB_OF
+#ifdef CONFIG_PPC
 MODULE_PARM(vmode, "i");
 MODULE_PARM_DESC(vmode, "Specify the vmode mode number that should be used (640x480 default)");
 MODULE_PARM(cmode, "i");
index 69bb8cc..1399d68 100644 (file)
@@ -68,14+68,12 @@ struct fb_info_offb {
 #define mach_eieio()   do {} while (0)
 #endif
 
-static int ofonly = 0;
 
     /*
      *  Interface used by the world
      */
 
 int offb_init(void);
-int offb_setup(char*);
 
 static int offb_get_fix(struct fb_fix_screeninfo *fix, int con,
                        struct fb_info *info);
@@ -90,7+88,6 @@ static int offb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
 
 extern boot_infos_t *boot_infos;
 
-static int offb_init_driver(struct device_node *);
 static void offb_init_nodriver(struct device_node *);
 static void offb_init_fb(const char *name, const char *full_name, int width,
                      int height, int depth, int pitch, unsigned long address,
@@ -238,29+235,6 @@ static int offb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
 }
 
 
-#ifdef CONFIG_FB_S3TRIO
-extern void s3triofb_init_of(struct device_node *dp);
-#endif /* CONFIG_FB_S3TRIO */
-#ifdef CONFIG_FB_IMSTT
-extern void imsttfb_of_init(struct device_node *dp);
-#endif
-#ifdef CONFIG_FB_CT65550
-extern void chips_of_init(struct device_node *dp);
-#endif /* CONFIG_FB_CT65550 */
-#ifdef CONFIG_FB_CONTROL
-extern void control_of_init(struct device_node *dp);
-#endif /* CONFIG_FB_CONTROL */
-#ifdef CONFIG_FB_VALKYRIE
-extern void valkyrie_of_init(struct device_node *dp);
-#endif /* CONFIG_FB_VALKYRIE */
-#ifdef CONFIG_FB_PLATINUM
-extern void platinum_of_init(struct device_node *dp);
-#endif /* CONFIG_FB_PLATINUM */
-#ifdef CONFIG_FB_CLGEN
-extern void clgen_of_init(struct device_node *dp);
-#endif /* CONFIG_FB_CLGEN */
-
-
     /*
      *  Initialisation
      */
@@ -324,89+298,22 @@ int __init offb_init(void)
        }
 
        /* initialize it */
-       if (ofonly || macos_display == NULL 
-           || !offb_init_driver(macos_display)) {
-           offb_init_fb(macos_display? macos_display->name: "MacOS display",
-                        macos_display? macos_display->full_name: "MacOS display",
-                        boot_infos->dispDeviceRect[2],
-                        boot_infos->dispDeviceRect[3],
-                        boot_infos->dispDeviceDepth,
-                        boot_infos->dispDeviceRowBytes, addr, NULL);
-       }
+       offb_init_fb(macos_display? macos_display->name: "MacOS display",
+                    macos_display? macos_display->full_name: "MacOS display",
+                    boot_infos->dispDeviceRect[2],
+                    boot_infos->dispDeviceRect[3],
+                    boot_infos->dispDeviceDepth,
+                    boot_infos->dispDeviceRowBytes, addr, NULL);
     }
 
     for (dpy = 0; dpy < prom_num_displays; dpy++) {
        if ((dp = find_path_device(prom_display_paths[dpy])))
-           if (ofonly || !offb_init_driver(dp))
-               offb_init_nodriver(dp);
-    }
-
-    if (!ofonly) {
-       for (dp = find_type_devices("display"); dp != NULL; dp = dp->next) {
-           for (dpy = 0; dpy < prom_num_displays; dpy++)
-               if (strcmp(dp->full_name, prom_display_paths[dpy]) == 0)
-                   break;
-           if (dpy >= prom_num_displays && dp != macos_display)
-               offb_init_driver(dp);
-       }
+           offb_init_nodriver(dp);
     }
     return 0;
 }
 
 
-    /*
-     *  This function is intended to go away as soon as all OF-aware frame
-     *  buffer device drivers have been converted to use PCI probing and PCI
-     *  resources. [ Geert ]
-     */
-
-static int __init offb_init_driver(struct device_node *dp)
-{
-#ifdef CONFIG_FB_S3TRIO
-    if (!strncmp(dp->name, "S3Trio", 6)) {
-       s3triofb_init_of(dp);
-       return 1;
-    }
-#endif /* CONFIG_FB_S3TRIO */
-#ifdef CONFIG_FB_IMSTT
-    if (!strncmp(dp->name, "IMS,tt", 6)) {
-       imsttfb_of_init(dp);
-       return 1;
-    }
-#endif
-#ifdef CONFIG_FB_CT65550
-    if (!strcmp(dp->name, "chips65550")) {
-       chips_of_init(dp);
-       return 1;
-    }
-#endif /* CONFIG_FB_CT65550 */
-#ifdef CONFIG_FB_CONTROL
-    if(!strcmp(dp->name, "control")) {
-       control_of_init(dp);
-       return 1;
-    }
-#endif /* CONFIG_FB_CONTROL */
-#ifdef CONFIG_FB_VALKYRIE
-    if(!strcmp(dp->name, "valkyrie")) {
-       valkyrie_of_init(dp);
-       return 1;
-    }
-#endif /* CONFIG_FB_VALKYRIE */
-#ifdef CONFIG_FB_PLATINUM
-    if (!strncmp(dp->name, "platinum",8)) {
-       platinum_of_init(dp);
-       return 1;
-    }
-#endif /* CONFIG_FB_PLATINUM */
-#ifdef CONFIG_FB_CLGEN
-    if (!strncmp(dp->name, "MacPicasso",10) || !strncmp(dp->name, "54m30",5)) {
-       clgen_of_init(dp);
-       return 1;
-    }
-#endif /* CONFIG_FB_CLGEN */
-    return 0;
-}
-
 static void __init offb_init_nodriver(struct device_node *dp)
 {
     int *pp, i;
@@ -685,21+592,6 @@ static void offb_init_fb(const char *name, const char *full_name,
 }
 
 
-    /*
-     *  Setup: parse used options
-     */
-
-int offb_setup(char *options)
-{
-    if (!options || !*options)
-       return 0;
-
-    if (!strcmp(options, "ofonly"))
-       ofonly = 1;
-    return 0;
-}
-
-
 static int offbcon_switch(int con, struct fb_info *info)
 {
     /* Do we have to save the colormap? */
index 3bbd7fe..558b6f4 100644 (file)
@@ -126,6+126,7 @@ static void platinum_blank(int blank, struct fb_info *fb);
  * internal functions
  */
 
+static void platinum_of_init(struct device_node *dp);
 static inline int platinum_vram_reqd(int video_mode, int color_mode);
 static int read_platinum_sense(struct fb_info_platinum *info);
 static void set_platinum_clock(struct fb_info_platinum *info);
@@ -153,12+154,8 @@ static void do_install_cmap(int con, struct fb_info *info);
  */
 
 int platinum_init(void);
-#ifdef CONFIG_FB_OF
-void platinum_of_init(struct device_node *dp);
-#endif
 int platinum_setup(char*);
 
-
 static struct fb_ops platinumfb_ops = {
        owner:          THIS_MODULE,
        fb_get_fix:     platinum_get_fix,
@@ -625,13+622,11 @@ static int __init init_platinum(struct fb_info_platinum *info)
 
 int __init platinum_init(void)
 {
-#ifndef CONFIG_FB_OF
        struct device_node *dp;
 
        dp = find_devices("platinum");
        if (dp != 0)
                platinum_of_init(dp);
-#endif /* CONFIG_FB_OF */
        return 0;
 }
 
@@ -643,7+638,7 @@ int __init platinum_init(void)
 #define invalidate_cache(addr)
 #endif
 
-void __init platinum_of_init(struct device_node *dp)
+static void __init platinum_of_init(struct device_node *dp)
 {
        struct fb_info_platinum *info;
        unsigned long           addr, size;
@@ -664,6+659,11 @@ void __init platinum_of_init(struct device_node *dp)
        for (i = 0; i < dp->n_addrs; ++i) {
                addr = dp->addrs[i].address;
                size = dp->addrs[i].size;
+               /* Let's assume we can request either all or nothing */
+               if (!request_mem_region(addr, size, "platinumfb")) {
+                       kfree(info);
+                       return;
+               }
                if (size >= 0x400000) {
                        /* frame buffer - map only 4MB */
                        info->frame_buffer_phys = addr;
@@ -677,6+677,7 @@ void __init platinum_of_init(struct device_node *dp)
        }
 
        info->cmap_regs_phys = 0xf301b000;      /* XXX not in prom? */
+       request_mem_region(info->cmap_regs_phys, 0x1000, "platinumfb cmap");
        info->cmap_regs = ioremap(info->cmap_regs_phys, 0x1000);
 
        /* Grok total video ram */
index 6739cec..9e7132f 100644 (file)
@@ -1,7+1,8 @@
 /*
  *  valkyriefb.c -- frame buffer device for the PowerMac 'valkyrie' display
  *
- *  Created 8 August 1998 by Martin Costabel and Kevin Schoedel
+ *  Created 8 August 1998 by 
+ *  Martin Costabel <costabel@wanadoo.fr> and Kevin Schoedel
  *
  *  Vmode-switching changes and vmode 15/17 modifications created 29 August
  *  1998 by Barry K. Nathan <barryn@pobox.com>.
@@ -114,9+115,9 @@ struct fb_info_valkyrie {
  * Exported functions
  */
 int valkyriefb_init(void);
-void valkyrie_of_init(struct device_node *dp);
 int valkyriefb_setup(char*);
 
+static void valkyrie_of_init(struct device_node *dp);
 static int valkyrie_get_fix(struct fb_fix_screeninfo *fix, int con,
                         struct fb_info *info);
 static int valkyrie_get_var(struct fb_var_screeninfo *var, int con,
@@ -547,20+548,18 @@ static void valkyrie_set_par(const struct fb_par_valkyrie *par,
 
 int __init valkyriefb_init(void)
 {
-#ifndef CONFIG_FB_OF
        struct device_node *dp;
 
        dp = find_devices("valkyrie");
        if (dp != 0)
                valkyrie_of_init(dp);
-#endif /* CONFIG_FB_OF */
        return 0;
 }
 
-void __init valkyrie_of_init(struct device_node *dp)
+static void __init valkyrie_of_init(struct device_node *dp)
 {
        struct fb_info_valkyrie *p;
-       unsigned long addr, size;
+       unsigned long addr;
        
        if(dp->n_addrs != 1) {
                printk(KERN_ERR "expecting 1 address for valkyrie (got %d)", dp->n_addrs);
@@ -574,13+573,16 @@ void __init valkyrie_of_init(struct device_node *dp)
 
        /* Map in frame buffer and registers */
        addr = dp->addrs[0].address;
-       size = 4096;
+       if (!request_mem_region(addr, dp->addrs[0].size, "valkyriefb")) {
+               kfree(p);
+               return;
+       }
        p->frame_buffer_phys  = addr;
        p->frame_buffer  = __ioremap(addr, 0x100000, _PAGE_WRITETHRU);
        p->cmap_regs_phys     = addr + 0x304000;
-       p->cmap_regs     = ioremap(p->cmap_regs_phys,     size);
+       p->cmap_regs     = ioremap(p->cmap_regs_phys,4096);
        p->valkyrie_regs_phys = addr + 0x30a000;
-       p->valkyrie_regs = ioremap(p->valkyrie_regs_phys, size);
+       p->valkyrie_regs = ioremap(p->valkyrie_regs_phys, 4096);
 
        /*
         * kps: As far as I know, all Valkyries have fixed usable VRAM.
@@ -650,31+652,9 @@ static int valkyrie_var_to_par(struct fb_var_screeninfo *var,
        struct valkyrie_regvals *init;
        struct fb_info_valkyrie *p = (struct fb_info_valkyrie *) fb_info;
 
-    /* these are old variables that are no longer needed with my new code
-       [bkn]
-
-       int xres = var->xres;
-       int yres = var->yres;
-     */
-
-    /*
-     *  Get the video params out of 'var'. If a value doesn't fit, round it up,
-     *  if it's too big, return -EINVAL.
-     *
-     *  Suggestion: Round up in the following order: bits_per_pixel, xres,
-     *  yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale,
-     *  bitfields, horizontal timing, vertical timing.
-     */
 
        if(mac_var_to_vmode(var, &par->vmode, &par->cmode) != 0) {
-               printk(KERN_ERR "valkyrie_var_to_par: mac_var_to_vmode unsuccessful.\n");
-               printk(KERN_ERR "valkyrie_var_to_par: var->xres = %d\n", var->xres);
-               printk(KERN_ERR "valkyrie_var_to_par: var->yres = %d\n", var->yres);
-               printk(KERN_ERR "valkyrie_var_to_par: var->xres_virtual = %d\n", var->xres_virtual);
-               printk(KERN_ERR "valkyrie_var_to_par: var->yres_virtual = %d\n", var->yres_virtual);
-               printk(KERN_ERR "valkyrie_var_to_par: var->bits_per_pixel = %d\n", var->bits_per_pixel);
-               printk(KERN_ERR "valkyrie_var_to_par: var->pixclock = %d\n", var->pixclock);
-               printk(KERN_ERR "valkyrie_var_to_par: var->vmode = %d\n", var->vmode);
+               printk(KERN_ERR "valkyrie_var_to_par: %dx%dx%d unsuccessful.\n",var->xres,var->yres,var->bits_per_pixel);
                return -EINVAL;
        }
 
index c8984b3..8ff0eaa 100644 (file)
 /*
  * valkyriefb.h: Constants of all sorts for valkyriefb
  *
- * Created 8 August 1998 by Martin Costabel and Kevin Schoedel
+ *  Created 8 August 1998 by 
+ *  Martin Costabel <costabel@wanadoo.fr> and Kevin Schoedel
  *
  * Vmode-switching changes and vmode 15/17 modifications created 29 August
  * 1998 by Barry K. Nathan <barryn@pobox.com>.
+ * 
+ * vmode 10 changed by Steven Borley <sjb@salix.demon.co.uk>, 14 mai 2000
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -141,7+144,8 @@ static struct valkyrie_regvals valkyrie_reg_init_11 = {
 /* Register values for 800x600, 60Hz mode (10) */
 static struct valkyrie_regvals valkyrie_reg_init_10 = {
     12,
-    { 20, 53, 2 },  /* pixel clock = 41.41MHz for V=59.78Hz */
+    { 25, 32, 3 },  /* pixel clock = 40.0015MHz,
+                     used to be 20,53,2, pixel clock 41.41MHz for V=59.78Hz */
     { 800, 1600 },
        800, 600
 };
index 62acffd..455c4af 100644 (file)
@@ -489,10+489,10 @@ static struct inode * find_inode(struct super_block * sb, unsigned long ino, str
                if (tmp == head)
                        break;
                inode = list_entry(tmp, struct inode, i_hash);
-               if (inode->i_sb != sb)
-                       continue;
                if (inode->i_ino != ino)
                        continue;
+               if (inode->i_sb != sb)
+                       continue;
                if (find_actor && !find_actor(inode, ino, opaque))
                        continue;
                break;
index 3961ac4..66ab89c 100644 (file)
 #ifndef _ALPHA_HARDIRQ_H
 #define _ALPHA_HARDIRQ_H
 
-/* Initially just a straight copy of the i386 code.  */
-
 #include <linux/config.h>
 #include <linux/threads.h>
 
-#ifndef CONFIG_SMP
-extern int __local_irq_count;
-#define local_irq_count(cpu)  ((void)(cpu), __local_irq_count)
-extern unsigned long __irq_attempt[];
-#define irq_attempt(cpu, irq)  ((void)(cpu), __irq_attempt[irq])
-#else
-#define local_irq_count(cpu)  (cpu_data[cpu].irq_count)
-#define irq_attempt(cpu, irq) (cpu_data[cpu].irq_attempt[irq])
-#endif
+/* entry.S is sensitive to the offsets of these fields */
+typedef struct {
+       unsigned int __softirq_active;
+       unsigned int __softirq_mask;
+       unsigned int __local_irq_count;
+       unsigned int __local_bh_count;
+       unsigned int __syscall_count;
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
 
 /*
  * Are we in an interrupt context? Either doing bottom half
@@ -31,6+30,9 @@ extern unsigned long __irq_attempt[];
 
 #ifndef CONFIG_SMP
 
+extern unsigned long __irq_attempt[];
+#define irq_attempt(cpu, irq)  ((void)(cpu), __irq_attempt[irq])
+
 #define hardirq_trylock(cpu)   (local_irq_count(cpu) == 0)
 #define hardirq_endlock(cpu)   ((void) 0)
 
@@ -41,6+43,8 @@ extern unsigned long __irq_attempt[];
 
 #else
 
+#define irq_attempt(cpu, irq) (cpu_data[cpu].irq_attempt[irq])
+
 #include <asm/atomic.h>
 #include <linux/spinlock.h>
 #include <asm/smp.h>
index 3143b08..44ec5e8 100644 (file)
@@ -33,7+33,6 @@ struct cpuinfo_alpha {
        unsigned long irq_attempt[NR_IRQS];
        unsigned long prof_multiplier;
        unsigned long prof_counter;
-       int irq_count, bh_count;
        unsigned char mcheck_expected;
        unsigned char mcheck_taken;
        unsigned char mcheck_extra;
index ef77f86..dd18dc4 100644 (file)
@@ -6,13+6,6 @@
 #include <asm/atomic.h>
 #include <asm/hardirq.h>
 
-#ifndef CONFIG_SMP
-extern int __local_bh_count;
-#define local_bh_count(cpu)    ((void)(cpu), __local_bh_count)
-#else
-#define local_bh_count(cpu)    (cpu_data[cpu].bh_count)
-#endif
-
 extern inline void cpu_bh_disable(int cpu)
 {
        local_bh_count(cpu)++;
index c12ed91..550310f 100644 (file)
 #include <linux/config.h>
 #include <linux/threads.h>
 
-extern unsigned int local_irq_count[NR_CPUS];
-extern unsigned int local_bh_count[NR_CPUS];
-
-#define local_irq_count(cpu)   (local_irq_count[(cpu)])
-#define local_bh_count(cpu)    (local_bh_count[(cpu)])
+/* entry.S is sensitive to the offsets of these fields */
+typedef struct {
+       unsigned int __softirq_active;
+       unsigned int __softirq_mask;
+       unsigned int __local_irq_count;
+       unsigned int __local_bh_count;
+       unsigned int __syscall_count;
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
 
 /*
  * Are we in an interrupt context? Either doing bottom half
index aef1822..3860288 100644 (file)
 #include <linux/threads.h>
 #include <linux/irq.h>
 
+/* entry.S is sensitive to the offsets of these fields */
 typedef struct {
+       unsigned int __softirq_active;
+       unsigned int __softirq_mask;
        unsigned int __local_irq_count;
        unsigned int __local_bh_count;
-       unsigned int __nmi_counter;
-       unsigned int __pad[5];
+       unsigned int __syscall_count;
+       unsigned int __nmi_count;       /* arch dependent */
 } ____cacheline_aligned irq_cpustat_t;
 
-extern irq_cpustat_t irq_stat [NR_CPUS];
-
-/*
- * Simple wrappers reducing source bloat
- */
-#define local_irq_count(cpu) (irq_stat[(cpu)].__local_irq_count)
-#define local_bh_count(cpu) (irq_stat[(cpu)].__local_bh_count)
-#define nmi_counter(cpu) (irq_stat[(cpu)].__nmi_counter)
+#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
 
 /*
  * Are we in an interrupt context? Either doing bottom half
index 7b24f38..38a12be 100644 (file)
 #include <linux/threads.h>
 #include <linux/irq.h>
 
+/* entry.S is sensitive to the offsets of these fields */
 typedef struct {
+       unsigned int __softirq_active;
+       unsigned int __softirq_mask;
        unsigned int __local_irq_count;
        unsigned int __local_bh_count;
-       unsigned int __nmi_counter;
-# if NR_CPUS > 1
-       unsigned int __pad[13];         /* this assumes 64-byte cache-lines... */
-# endif
+       unsigned int __syscall_count;
+       unsigned int __nmi_count;       /* arch dependent */
 } ____cacheline_aligned irq_cpustat_t;
 
-extern irq_cpustat_t irq_stat[NR_CPUS];
-
-/*
- * Simple wrappers reducing source bloat
- */
-#define local_irq_count(cpu)   (irq_stat[(cpu)].__local_irq_count)
-#define local_bh_count(cpu)    (irq_stat[(cpu)].__local_bh_count)
-#define nmi_counter(cpu)       (irq_stat[(cpu)].__nmi_counter)
+#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
 
 /*
  * Are we in an interrupt context? Either doing bottom half
dissimilarity index 67%
index aac7e85..8a1e6a4 100644 (file)
-#ifndef __M68K_HARDIRQ_H
-#define __M68K_HARDIRQ_H
-
-#include <linux/threads.h>
-
-extern unsigned int local_irq_count[NR_CPUS];
-
-#define in_interrupt() (local_irq_count[smp_processor_id()] + local_bh_count[smp_processor_id()] != 0)
-
-#define in_irq() (local_irq_count[smp_processor_id()] != 0)
-
-#define hardirq_trylock(cpu)   (local_irq_count[cpu] == 0)
-#define hardirq_endlock(cpu)   do { } while (0)
-
-#define irq_enter(cpu)         (local_irq_count[cpu]++)
-#define irq_exit(cpu)          (local_irq_count[cpu]--)
-
-#define synchronize_irq()      barrier()
-
-#endif
+#ifndef __M68K_HARDIRQ_H
+#define __M68K_HARDIRQ_H
+
+#include <linux/threads.h>
+
+/* entry.S is sensitive to the offsets of these fields */
+typedef struct {
+       unsigned int __softirq_active;
+       unsigned int __softirq_mask;
+       unsigned int __local_irq_count;
+       unsigned int __local_bh_count;
+       unsigned int __syscall_count;
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
+
+#define in_interrupt() (local_irq_count(smp_processor_id()) + local_bh_count(smp_processor_id()) != 0)
+
+#define in_irq() (local_irq_count(smp_processor_id()) != 0)
+
+#define hardirq_trylock(cpu)   (local_irq_count(cpu) == 0)
+#define hardirq_endlock(cpu)   do { } while (0)
+
+#define irq_enter(cpu)         (local_irq_count(cpu)++)
+#define irq_exit(cpu)          (local_irq_count(cpu)--)
+
+#define synchronize_irq()      barrier()
+
+#endif
index a51563c..89a3e39 100644 (file)
 
 #include <asm/atomic.h>
 
-extern unsigned int local_bh_count[NR_CPUS];
-
-#define local_bh_disable()     (local_bh_count[smp_processor_id()]++)
-#define local_bh_enable()      (local_bh_count[smp_processor_id()]--)
+#define local_bh_disable()     (local_bh_count(smp_processor_id())++)
+#define local_bh_enable()      (local_bh_count(smp_processor_id())--)
 
 #define in_softirq() (local_bh_count != 0)
 
 /* These are for the irq's testing the lock */
-#define softirq_trylock(cpu)  (local_bh_count[cpu] ? 0 : (local_bh_count[cpu]=1))
-#define softirq_endlock(cpu)  (local_bh_count[cpu] = 0)
+#define softirq_trylock(cpu)  (local_bh_count(cpu) ? 0 : (local_bh_count(cpu)=1))
+#define softirq_endlock(cpu)  (local_bh_count(cpu) = 0)
 #define synchronize_bh()       barrier()
 
 #endif
index 64dab98..a33bb7c 100644 (file)
@@ -52,7+52,7 @@ asmlinkage void resume(void);
 #else
 #include <asm/hardirq.h>
 #define __sti() ({                                                             \
-       if (!local_irq_count[smp_processor_id()])                               \
+       if (!local_irq_count(smp_processor_id()))                               \
                asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory");    \
 })
 #endif
index 4331f13..eead2fb 100644 (file)
 #include <linux/threads.h>
 #include <linux/irq.h>
 
+/* entry.S is sensitive to the offsets of these fields */
 typedef struct {
+       unsigned int __softirq_active;
+       unsigned int __softirq_mask;
        unsigned int __local_irq_count;
        unsigned int __local_bh_count;
+       unsigned int __syscall_count;
 } ____cacheline_aligned irq_cpustat_t;
 
-extern irq_cpustat_t irq_stat [NR_CPUS];
-
-/*
- * Simple wrappers reducing source bloat
- */
-#define local_irq_count(cpu) (irq_stat[(cpu)].__local_irq_count)
-#define local_bh_count(cpu) (irq_stat[(cpu)].__local_bh_count)
+#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
 
 /*
  * Are we in an interrupt context? Either doing bottom half
index bae7fcd..f521b72 100644 (file)
 #ifndef _ASM_MC146818RTC_H
 #define _ASM_MC146818RTC_H
 
+#include <linux/config.h>
 #include <asm/io.h>
 
 #ifndef RTC_PORT
index 192b61f..088fb88 100644 (file)
 #include <linux/threads.h>
 #include <linux/irq.h>
 
+/* entry.S is sensitive to the offsets of these fields */
 typedef struct {
-       unsigned long __local_irq_count;
-       unsigned long __local_bh_count;
-       unsigned long __pad[14];
+       unsigned int __softirq_active;
+       unsigned int __softirq_mask;
+       unsigned int __local_irq_count;
+       unsigned int __local_bh_count;
+       unsigned int __syscall_count;
 } ____cacheline_aligned irq_cpustat_t;
 
-extern irq_cpustat_t irq_stat [NR_CPUS];
-
-/*
- * Simple wrappers reducing source bloat
- */
-#define local_irq_count(cpu) (irq_stat[(cpu)].__local_irq_count)
-#define local_bh_count(cpu) (irq_stat[(cpu)].__local_bh_count)
+#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
 
 /*
  * Are we in an interrupt context? Either doing bottom half
index 565d6cb..3e8cab4 100644 (file)
@@ -63,7+63,6 @@ struct cpuinfo_mips {
        unsigned long *pte_quick;
        unsigned long pgtable_cache_sz;
        unsigned long last_asn;
-       unsigned int irq_count, bh_count;
        unsigned long asid_cache;
 #if defined(CONFIG_SGI_IP27)
        cpuid_t         p_cpuid;        /* PROM assigned cpuid */
index ed0420d..b8a8f8d 100644 (file)
@@ -20,7+20,6 @@ struct cpuinfo_mips {                         /* XXX  */
        unsigned long smp_local_irq_count;
        unsigned long prof_multiplier;
        unsigned long prof_counter;
-       int irq_count, bh_count;
 } __attribute__((aligned(64)));
 
 extern struct cpuinfo_mips cpu_data[NR_CPUS];
index cc7425e..0739899 100644 (file)
 #include <linux/config.h>
 #include <asm/smp.h>
 
+/* entry.S is sensitive to the offsets of these fields */
 typedef struct {
+       unsigned int __softirq_active;
+       unsigned int __softirq_mask;
        unsigned int __local_irq_count;
        unsigned int __local_bh_count;
-       unsigned int __pad[6];
+       unsigned int __syscall_count;
 } ____cacheline_aligned irq_cpustat_t;
 
-extern irq_cpustat_t irq_stat [NR_CPUS];
-
-/*
- * Simple wrappers reducing source bloat
- */
-#define local_irq_count(cpu) (irq_stat[(cpu)].__local_irq_count)
-#define local_bh_count(cpu) (irq_stat[(cpu)].__local_bh_count)
+#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
 
 /*
  * Are we in an interrupt context? Either doing bottom half
index f23ed41..4eaed0b 100644 (file)
@@ -4,8+4,6 @@
 #include <asm/atomic.h>
 #include <asm/hardirq.h>
 
-extern unsigned int local_bh_count[NR_CPUS];
-
 #define local_bh_disable()     do { local_bh_count(smp_processor_id())++; barrier(); } while (0)
 #define local_bh_enable()      do { barrier(); local_bh_count(smp_processor_id())--; } while (0)
 
index c21db1c..b32a068 100644 (file)
 #include <linux/threads.h>
 #include <asm/lowcore.h>
 #include <linux/sched.h>
+
+/* No irq_cpustat_t for s390, the data is held directly in S390_lowcore */
+
+/*
+ * Simple wrappers reducing source bloat.  S390 specific because each
+ * cpu stores its data in S390_lowcore (PSA) instead of using a cache
+ * aligned array element like most architectures.
+ */
+
+#ifdef CONFIG_SMP
+
+#define softirq_active(cpu)    (safe_get_cpu_lowcore(cpu).__softirq_active)
+#define softirq_mask(cpu)      (safe_get_cpu_lowcore(cpu).__softirq_mask)
+#define local_irq_count(cpu)   (safe_get_cpu_lowcore(cpu).__local_irq_count)
+#define local_bh_count(cpu)    (safe_get_cpu_lowcore(cpu).__local_bh_count)
+#define syscall_count(cpu)     (safe_get_cpu_lowcore(cpu).__syscall_count)
+
+#else  /* CONFIG_SMP */
+
+/* Optimize away the cpu calculation, it is always current PSA */
+#define softirq_active(cpu)    ((void)(cpu), S390_lowcore.__softirq_active)
+#define softirq_mask(cpu)      ((void)(cpu), S390_lowcore.__softirq_mask)
+#define local_irq_count(cpu)   ((void)(cpu), S390_lowcore.__local_irq_count)
+#define local_bh_count(cpu)    ((void)(cpu), S390_lowcore.__local_bh_count)
+#define syscall_count(cpu)     ((void)(cpu), S390_lowcore.__syscall_count)
+
+#endif /* CONFIG_SMP */
+
 /*
  * Are we in an interrupt context? Either doing bottom half
  * or hardware interrupt processing?
+ * Special definitions for s390, always access current PSA.
  */
-#define in_interrupt() ((atomic_read(&S390_lowcore.local_irq_count) + atomic_read(&S390_lowcore.local_bh_count)) != 0)
+#define in_interrupt() ((S390_lowcore.__local_irq_count + S390_lowcore.__local_bh_count) != 0)
 
-#define in_irq() (atomic_read(&S390_lowcore.local_irq_count) != 0)
+#define in_irq() (S390_lowcore.__local_irq_count != 0)
 
 #ifndef CONFIG_SMP
 
-#define hardirq_trylock(cpu)   (atomic_read(&S390_lowcore.local_irq_count) == 0)
+#define hardirq_trylock(cpu)   (local_irq_count(cpu) == 0)
 #define hardirq_endlock(cpu)   do { } while (0)
 
-#define hardirq_enter(cpu)     (atomic_inc(&S390_lowcore.local_irq_count))
-#define hardirq_exit(cpu)      (atomic_dec(&S390_lowcore.local_irq_count))
+#define hardirq_enter(cpu)     (local_irq_count(cpu)++)
+#define hardirq_exit(cpu)      (local_irq_count(cpu)--)
 
 #define synchronize_irq()      do { } while (0)
 
@@ -54,14+83,14 @@ static inline void release_irqlock(int cpu)
 
 static inline void hardirq_enter(int cpu)
 {
-        atomic_inc(&safe_get_cpu_lowcore(cpu).local_irq_count);
+        ++local_irq_count(cpu);
        atomic_inc(&global_irq_count);
 }
 
 static inline void hardirq_exit(int cpu)
 {
        atomic_dec(&global_irq_count);
-        atomic_dec(&safe_get_cpu_lowcore(cpu).local_irq_count);
+        --local_irq_count(cpu);
 }
 
 static inline int hardirq_trylock(int cpu)
index 895c246..5efcdd4 100644 (file)
@@ -734,8+734,8 @@ static inline void irq_exit(int cpu, unsigned int irq)
 
 #else
 
-#define irq_enter(cpu, irq)     (++local_irq_count[cpu])
-#define irq_exit(cpu, irq)      (--local_irq_count[cpu])
+#define irq_enter(cpu, irq)     (++local_irq_count(cpu))
+#define irq_exit(cpu, irq)      (--local_irq_count(cpu))
 
 #endif
 
index 22ab31b..3430056 100644 (file)
 #define __LC_SAVE_AREA                  0xC00
 #define __LC_KERNEL_STACK               0xC40
 #define __LC_KERNEL_LEVEL               0xC44
-#define __LC_CPUID                      0xC50
-#define __LC_CPUADDR                    0xC58
-#define __LC_IPLDEV                     0xC6C
+#define __LC_IRQ_STAT                   0xC48
+#define __LC_CPUID                      0xC60
+#define __LC_CPUADDR                    0xC68
+#define __LC_IPLDEV                     0xC7C
 
 
 /* interrupt handler start with all io, external and mcck interrupt disabled */
@@ -145,19+146,26 @@ struct _lowcore
        __u32        save_area[16];            /* 0xc00 */
        __u32        kernel_stack;             /* 0xc40 */
        __u32        kernel_level;             /* 0xc44 */
-       atomic_t     local_bh_count;           /* 0xc48 */
-       atomic_t     local_irq_count;          /* 0xc4c */
-       struct       cpuinfo_S390 cpu_data;    /* 0xc50 */
-       __u32        ipl_device;               /* 0xc6c */
+       /* entry.S sensitive area start */
+       /* Next 6 words are the s390 equivalent of irq_stat */
+       __u32        __softirq_active;         /* 0xc48 */
+       __u32        __softirq_mask;           /* 0xc4c */
+       __u32        __local_irq_count;        /* 0xc50 */
+       __u32        __local_bh_count;         /* 0xc54 */
+       __u32        __syscall_count;          /* 0xc58 */
+       __u8         pad10[0xc60-0xc5c];       /* 0xc5c */
+       struct       cpuinfo_S390 cpu_data;    /* 0xc60 */
+       __u32        ipl_device;               /* 0xc7c */
+       /* entry.S sensitive area end */
 
         /* SMP info area: defined by DJB */
-        __u64        jiffy_timer_cc;           /* 0xc70 */
-       atomic_t     ext_call_fast;            /* 0xc78 */
-       atomic_t     ext_call_queue;           /* 0xc7c */
-        atomic_t     ext_call_count;           /* 0xc80 */
+        __u64        jiffy_timer_cc;           /* 0xc80 */
+       atomic_t     ext_call_fast;            /* 0xc88 */
+       atomic_t     ext_call_queue;           /* 0xc8c */
+        atomic_t     ext_call_count;           /* 0xc90 */
 
         /* Align SMP info to the top 1k of prefix area */
-       __u8         pad10[0x1000-0xc84];      /* 0xc84 */
+       __u8         pad11[0x1000-0xc94];      /* 0xc94 */
 } __attribute__((packed)); /* End structure*/
 
 extern __inline__ void set_prefix(__u32 address)
index b0ad1dc..ce1254e 100644 (file)
 #include <asm/hardirq.h>
 #include <asm/lowcore.h>
 
-#define cpu_bh_disable(cpu)    do { atomic_inc(&S390_lowcore.local_bh_count); barrier(); } while (0)
-#define cpu_bh_enable(cpu)     do { barrier(); atomic_dec(&S390_lowcore.local_bh_count); } while (0)
+#define cpu_bh_disable(cpu)    do { local_bh_count(cpu)++; barrier(); } while (0)
+#define cpu_bh_enable(cpu)     do { barrier(); local_bh_count(cpu)--; } while (0)
 
 #define local_bh_disable()     cpu_bh_disable(smp_processor_id())
 #define local_bh_enable()      cpu_bh_enable(smp_processor_id())
 
-#define in_softirq() (atomic_read(&S390_lowcore.local_bh_count) != 0)
+#define in_softirq() (local_bh_count(smp_processor_id()) != 0)
 
 #endif /* __ASM_SOFTIRQ_H */
 
index 592b31d..cfb53de 100644 (file)
 #include <linux/config.h>
 #include <linux/threads.h>
 
-extern unsigned int __local_irq_count[NR_CPUS];
-extern unsigned int __local_bh_count[NR_CPUS];
+/* entry.S is sensitive to the offsets of these fields */
+typedef struct {
+       unsigned int __softirq_active;
+       unsigned int __softirq_mask;
+       unsigned int __local_irq_count;
+       unsigned int __local_bh_count;
+       unsigned int __syscall_count;
+} ____cacheline_aligned irq_cpustat_t;
 
-#define local_irq_count(cpu) (__local_irq_count[(cpu)])
-#define local_bh_count(cpu) (__local_bh_count[(cpu)])
+#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
 
 /*
  * Are we in an interrupt context? Either doing bottom half
  * or hardware interrupt processing?
  */
 #define in_interrupt() ({ int __cpu = smp_processor_id(); \
-       (__local_irq_count[__cpu] + __local_bh_count[__cpu] != 0); })
+       (local_irq_count(__cpu) + local_bh_count(__cpu) != 0); })
 
-#define in_irq() (__local_irq_count[smp_processor_id()] != 0)
+#define in_irq() (local_irq_count(smp_processor_id()) != 0)
 
 #ifndef CONFIG_SMP
 
-#define hardirq_trylock(cpu)   (__local_irq_count[cpu] == 0)
+#define hardirq_trylock(cpu)   (local_irq_count(cpu) == 0)
 #define hardirq_endlock(cpu)   do { } while (0)
 
-#define irq_enter(cpu, irq)    (__local_irq_count[cpu]++)
-#define irq_exit(cpu, irq)     (__local_irq_count[cpu]--)
+#define irq_enter(cpu, irq)    (local_irq_count(cpu)++)
+#define irq_exit(cpu, irq)     (local_irq_count(cpu)--)
 
 #define synchronize_irq()      barrier()
 
index 44f4e04..5e539b0 100644 (file)
 #include <asm/atomic.h>
 #include <asm/hardirq.h>
 
-#define cpu_bh_disable(cpu)    do { __local_bh_count[(cpu)]++; barrier(); } while (0)
-#define cpu_bh_enable(cpu)     do { barrier(); __local_bh_count[(cpu)]--; } while (0)
+#define cpu_bh_disable(cpu)    do { local_bh_count(cpu)++; barrier(); } while (0)
+#define cpu_bh_enable(cpu)     do { barrier(); local_bh_count(cpu)--; } while (0)
 
 #define local_bh_disable()     cpu_bh_disable(smp_processor_id())
 #define local_bh_enable()      cpu_bh_enable(smp_processor_id())
 
-#define in_softirq() (__local_bh_count[smp_processor_id()] != 0)
+#define in_softirq() (local_bh_count(smp_processor_id()) != 0)
 
 #endif /* __ASM_SH_SOFTIRQ_H */
index 8b7b095..cfee071 100644 (file)
 #include <linux/config.h>
 #include <linux/threads.h>
 
-#ifndef CONFIG_SMP
-extern unsigned int __local_irq_count;
-#define local_irq_count(cpu)   __local_irq_count
+/* entry.S is sensitive to the offsets of these fields */
+typedef struct {
+       unsigned int __softirq_active;
+       unsigned int __softirq_mask;
+       unsigned int __local_irq_count;
+       unsigned int __local_bh_count;
+       unsigned int __syscall_count;
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
 
 /*
  * Are we in an interrupt context? Either doing bottom half
  * or hardware interrupt processing?
  */
-#define in_interrupt()  ((__local_irq_count + __local_bh_count) != 0)
+#define in_interrupt() ({ int __cpu = smp_processor_id(); \
+       (local_irq_count(__cpu) + local_bh_count(__cpu) != 0); })
+
+#define in_irq() ({ int __cpu = smp_processor_id(); \
+       (local_irq_count(__cpu) != 0); })
 
-#define hardirq_trylock(cpu)   ((void)(cpu), __local_irq_count == 0)
+#ifndef CONFIG_SMP
+
+#define hardirq_trylock(cpu)   (local_irq_count(cpu) == 0)
 #define hardirq_endlock(cpu)   do { (void)(cpu); } while (0)
 
-#define hardirq_enter(cpu)     (__local_irq_count++)
-#define hardirq_exit(cpu)      (__local_irq_count--)
+#define hardirq_enter(cpu)     (++local_irq_count(cpu))
+#define hardirq_exit(cpu)      (--local_irq_count(cpu))
 
 #define synchronize_irq()      barrier()
 
-#define in_irq() (__local_irq_count != 0)
-
 #else
 
 #include <asm/atomic.h>
@@ -37,22+48,10 @@ extern unsigned int __local_irq_count;
 #include <asm/system.h>
 #include <asm/smp.h>
 
-extern unsigned int __local_irq_count[NR_CPUS];
-#define local_irq_count(cpu)   __local_irq_count[cpu]
 extern unsigned char global_irq_holder;
 extern spinlock_t global_irq_lock;
 extern atomic_t global_irq_count;
 
-/*
- * Are we in an interrupt context? Either doing bottom half
- * or hardware interrupt processing?
- */
-#define in_interrupt() ({ int __cpu = smp_processor_id(); \
-       (local_irq_count(__cpu) + local_bh_count(__cpu) != 0); })
-
-#define in_irq() ({ int __cpu = smp_processor_id(); \
-       (local_irq_count(__cpu) != 0); })
-
 static inline void release_irqlock(int cpu)
 {
        /* if we didn't own the irq lock, just ignore.. */
diff --git a/include/asm-sparc/highmem.h b/include/asm-sparc/highmem.h
new file mode 100644 (file)
index 0000000..ede2167
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * highmem.h: virtual kernel memory mappings for high memory
+ *
+ * Used in CONFIG_HIGHMEM systems for memory pages which
+ * are not addressable by direct kernel virtual adresses.
+ *
+ * Copyright (C) 1999 Gerhard Wichert, Siemens AG
+ *                   Gerhard.Wichert@pdb.siemens.de
+ *
+ *
+ * Redesigned the x86 32-bit VM architecture to deal with 
+ * up to 16 Terrabyte physical memory. With current x86 CPUs
+ * we now support up to 64 Gigabytes physical RAM.
+ *
+ * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
+ */
+
+#ifndef _ASM_HIGHMEM_H
+#define _ASM_HIGHMEM_H
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <asm/vaddrs.h>
+#include <asm/kmap_types.h>
+#include <asm/pgtable.h>
+
+/* undef for production */
+#define HIGHMEM_DEBUG 1
+
+/* declarations for highmem.c */
+extern unsigned long highstart_pfn, highend_pfn;
+
+extern pte_t *kmap_pte;
+extern pgprot_t kmap_prot;
+extern pte_t *pkmap_page_table;
+
+extern void kmap_init(void) __init;
+
+/*
+ * Right now we initialize only a single pte table. It can be extended
+ * easily, subsequent pte tables have to be allocated in one physical
+ * chunk of RAM.
+ */
+#define LAST_PKMAP 1024
+
+#define LAST_PKMAP_MASK (LAST_PKMAP-1)
+#define PKMAP_NR(virt)  ((virt-PKMAP_BASE) >> PAGE_SHIFT)
+#define PKMAP_ADDR(nr)  (PKMAP_BASE + ((nr) << PAGE_SHIFT))
+
+extern unsigned long kmap_high(struct page *page);
+extern void kunmap_high(struct page *page);
+
+extern inline unsigned long kmap(struct page *page)
+{
+       if (in_interrupt())
+               BUG();
+       if (page < highmem_start_page)
+               return (unsigned long) page_address(page);
+       return kmap_high(page);
+}
+
+extern inline void kunmap(struct page *page)
+{
+       if (in_interrupt())
+               BUG();
+       if (page < highmem_start_page)
+               return;
+       kunmap_high(page);
+}
+
+/*
+ * The use of kmap_atomic/kunmap_atomic is discouraged - kmap/kunmap
+ * gives a more generic (and caching) interface. But kmap_atomic can
+ * be used in IRQ contexts, so in some (very limited) cases we need
+ * it.
+ */
+extern inline unsigned long kmap_atomic(struct page *page, enum km_type type)
+{
+       unsigned long idx;
+       unsigned long vaddr;
+
+       if (page < highmem_start_page)
+               return (unsigned long) page_address(page);
+
+       idx = type + KM_TYPE_NR*smp_processor_id();
+       vaddr = FIX_KMAP_BEGIN + idx * PAGE_SIZE;
+
+/* XXX Fix - Anton */
+#if 0
+       __flush_cache_one(vaddr);
+#else
+       flush_cache_all();
+#endif
+
+#if HIGHMEM_DEBUG
+       if (!pte_none(*(kmap_pte+idx)))
+               BUG();
+#endif
+       set_pte(kmap_pte+idx, mk_pte(page, kmap_prot));
+/* XXX Fix - Anton */
+#if 0
+       __flush_tlb_one(vaddr);
+#else
+       flush_tlb_all();
+#endif
+
+       return vaddr;
+}
+
+extern inline void kunmap_atomic(unsigned long vaddr, enum km_type type)
+{
+#if HIGHMEM_DEBUG
+       unsigned long idx = type + KM_TYPE_NR*smp_processor_id();
+
+#if 0
+       if (vaddr < FIXADDR_START) // FIXME
+               return;
+#endif
+
+       if (vaddr != FIX_KMAP_BEGIN + idx * PAGE_SIZE)
+               BUG();
+
+/* XXX Fix - Anton */
+#if 0
+       __flush_cache_one(vaddr);
+#else
+       flush_cache_all();
+#endif
+
+       /*
+        * force other mappings to Oops if they'll try to access
+        * this pte without first remap it
+        */
+       pte_clear(kmap_pte+idx);
+/* XXX Fix - Anton */
+#if 0
+       __flush_tlb_one(vaddr);
+#else
+       flush_tlb_all();
+#endif
+#endif
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_HIGHMEM_H */
index 5859d82..4b6dd0d 100644 (file)
@@ -23,16+23,14 @@ BTFIXUPDEF_CALL(char *, __irq_itoa, unsigned int)
 
 /* IRQ handler dispatch entry and exit. */
 #ifdef CONFIG_SMP
-extern unsigned int __local_irq_count[NR_CPUS];
 #define irq_enter(cpu, irq)                     \
 do {    hardirq_enter(cpu);                     \
         spin_unlock_wait(&global_irq_lock);     \
        } while(0)
 #define irq_exit(cpu, irq)      hardirq_exit(cpu)
 #else
-extern unsigned int __local_irq_count;
-#define irq_enter(cpu, irq)     (__local_irq_count++)
-#define irq_exit(cpu, irq)      (__local_irq_count--)
+#define irq_enter(cpu, irq)     (++local_irq_count(cpu))
+#define irq_exit(cpu, irq)      (--local_irq_count(cpu))
 #endif
 
 /* Dave Redman (djhr@tadpole.co.uk)
diff --git a/include/asm-sparc/kmap_types.h b/include/asm-sparc/kmap_types.h
new file mode 100644 (file)
index 0000000..d92d81b
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef _ASM_KMAP_TYPES_H
+#define _ASM_KMAP_TYPES_H
+
+enum km_type {
+       KM_BOUNCE_READ,
+       KM_BOUNCE_WRITE,
+       KM_TYPE_NR
+};
+
+#endif
index 20e9d80..180709c 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: pgalloc.h,v 1.6 2000/07/10 20:56:53 anton Exp $ */
+/* $Id: pgalloc.h,v 1.9 2000/08/01 04:53:58 anton Exp $ */
 #ifndef _SPARC_PGALLOC_H
 #define _SPARC_PGALLOC_H
 
@@ -85,7+85,9 @@ BTFIXUPDEF_CALL(void, flush_sig_insns, struct mm_struct *, unsigned long)
 #define __flush_page_to_ram(addr) BTFIXUP_CALL(__flush_page_to_ram)(addr)
 #define flush_sig_insns(mm,insn_addr) BTFIXUP_CALL(flush_sig_insns)(mm,insn_addr)
 
-#define flush_page_to_ram(page)    __flush_page_to_ram(page_address(page))
+extern void flush_page_to_ram(struct page *page);
+
+#define flush_dcache_page(page)                        do { } while (0)
 
 extern struct pgtable_cache_struct {
        unsigned long *pgd_cache;
index f35407d..100f25a 100644 (file)
 #include <asm/smp.h>
 #include <asm/hardirq.h>
 
-
-#ifdef CONFIG_SMP
-extern unsigned int __local_bh_count[NR_CPUS];
-#define local_bh_count(cpu)    __local_bh_count[cpu]
-
 #define local_bh_disable()     (local_bh_count(smp_processor_id())++)
 #define local_bh_enable()      (local_bh_count(smp_processor_id())--)
 
 #define in_softirq() (local_bh_count(smp_processor_id()) != 0)
 
-#else
-
-extern unsigned int __local_bh_count;
-#define local_bh_count(cpu)    __local_bh_count
-
-#define local_bh_disable()     (__local_bh_count++)
-#define local_bh_enable()      (__local_bh_count--)
-
-#define in_softirq() (__local_bh_count != 0)
-
-#endif /* SMP */
-
 #endif /* __SPARC_SOFTIRQ_H */
index a70d4df..7be8e70 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: stat.h,v 1.11 2000/01/16 15:22:53 jj Exp $ */
+/* $Id: stat.h,v 1.12 2000/08/04 05:35:55 davem Exp $ */
 #ifndef _SPARC_STAT_H
 #define _SPARC_STAT_H
 
index 4174294..0a101ca 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: system.h,v 1.82 2000/05/09 17:40:15 davem Exp $ */
+/* $Id: system.h,v 1.83 2000/08/04 05:35:55 davem Exp $ */
 #include <linux/config.h>
 
 #ifndef __SPARC_SYSTEM_H
index 5cbec82..704f790 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: vaddrs.h,v 1.25 2000/06/05 06:08:46 anton Exp $ */
+/* $Id: vaddrs.h,v 1.26 2000/08/01 04:53:58 anton Exp $ */
 #ifndef _SPARC_VADDRS_H
 #define _SPARC_VADDRS_H
 
  * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com)
  */
 
+#define SRMMU_MAXMEM           0x0c000000
+
+#define SRMMU_NOCACHE_VADDR    0xfc000000      /* KERNBASE + SRMMU_MAXMEM */
+/* XXX Make this dynamic based on ram size - Anton */
+#define SRMMU_NOCACHE_NPAGES   256
+#define SRMMU_NOCACHE_SIZE     (SRMMU_NOCACHE_NPAGES * PAGE_SIZE)
+#define SRMMU_NOCACHE_END      (SRMMU_NOCACHE_VADDR + SRMMU_NOCACHE_SIZE)
+
+#define FIX_KMAP_BEGIN         0xfc100000
+#define FIX_KMAP_END (FIX_KMAP_BEGIN + ((KM_TYPE_NR*NR_CPUS)-1)*PAGE_SIZE)
+
+#define PKMAP_BASE             0xfc140000
+#define PKMAP_BASE_END         (PKMAP_BASE+LAST_PKMAP*PAGE_SIZE)
+
 #define SUN4M_IOBASE_VADDR     0xfd000000 /* Base for mapping pages */
 #define IOBASE_VADDR           0xfe000000
 #define IOBASE_END             0xfe300000
diff --git a/include/asm-sparc64/display7seg.h b/include/asm-sparc64/display7seg.h
new file mode 100644 (file)
index 0000000..955a350
--- /dev/null
@@ -0,0 +1,79 @@
+/* $Id: display7seg.h,v 1.2 2000/08/02 06:22:35 davem Exp $
+ *
+ * display7seg - Driver interface for the 7-segment display
+ * present on Sun Microsystems CP1400 and CP1500
+ *
+ * Copyright (c) 2000 Eric Brower <ebrower@usa.net>
+ *
+ */
+
+#ifndef __display7seg_h__
+#define __display7seg_h__
+
+#define D7S_IOC        'p'
+
+#define D7SIOCRD _IOR(D7S_IOC, 0x45, int)      /* Read device state    */
+#define D7SIOCWR _IOW(D7S_IOC, 0x46, int)      /* Write device state   */
+#define D7SIOCTM _IO (D7S_IOC, 0x47)           /* Translate mode (FLIP)*/
+
+/*
+ * ioctl flag definitions
+ *
+ * POINT       - Toggle decimal point  (0=absent 1=present)
+ * ALARM       - Toggle alarm LED              (0=green  1=red)
+ * FLIP                - Toggle inverted mode  (0=normal 1=flipped) 
+ * bits 0-4    - Character displayed   (see definitions below)
+ *
+ * Display segments are defined as follows, 
+ * subject to D7S_FLIP register state:
+ *
+ *    a
+ *   ---
+ * f|   |b
+ *   -g-
+ * e|   |c
+ *   ---
+ *    d
+ */
+
+#define D7S_POINT      (1 << 7)        /* Decimal point*/
+#define D7S_ALARM      (1 << 6)        /* Alarm LED    */
+#define D7S_FLIP       (1 << 5)        /* Flip display */
+
+#define D7S_0          0x00            /* Numerals 0-9 */
+#define D7S_1          0x01
+#define D7S_2          0x02
+#define D7S_3          0x03
+#define D7S_4          0x04
+#define D7S_5          0x05
+#define D7S_6          0x06
+#define D7S_7          0x07
+#define D7S_8          0x08
+#define D7S_9          0x09
+#define D7S_A          0x0A            /* Letters A-F, H, L, P */
+#define D7S_B          0x0B
+#define D7S_C          0x0C
+#define D7S_D          0x0D
+#define D7S_E          0x0E
+#define D7S_F          0x0F
+#define D7S_H          0x10
+#define D7S_E2         0x11
+#define D7S_L          0x12
+#define D7S_P          0x13
+#define D7S_SEGA       0x14            /* Individual segments */
+#define D7S_SEGB       0x15
+#define D7S_SEGC       0x16
+#define D7S_SEGD       0x17
+#define D7S_SEGE       0x18
+#define D7S_SEGF       0x19
+#define D7S_SEGG       0x1A
+#define D7S_SEGABFG 0x1B               /* Segment groupings */
+#define D7S_SEGCDEG    0x1C
+#define D7S_SEGBCEF 0x1D
+#define D7S_SEGADG     0x1E
+#define D7S_BLANK      0x1F            /* Clear all segments */
+
+#define D7S_MIN_VAL    0x0
+#define D7S_MAX_VAL    0x1F
+
+#endif /* ifndef __display7seg_h__ */
index 0902390..e4007b6 100644 (file)
 #include <linux/brlock.h>
 #include <linux/spinlock.h>
 
+/* entry.S is sensitive to the offsets of these fields */
+typedef struct {
+       unsigned int __softirq_active;
+       unsigned int __softirq_mask;
 #ifndef CONFIG_SMP
-extern unsigned int __local_irq_count;
-#define local_irq_count(cpu)   __local_irq_count
-#define irq_enter(cpu, irq)    (__local_irq_count++)
-#define irq_exit(cpu, irq)     (__local_irq_count--)
+       unsigned int __local_irq_count;
 #else
+       unsigned int __unused_on_SMP;   /* DaveM says use brlock for SMP irq. KAO */
+#endif
+       unsigned int __local_bh_count;
+       unsigned int __syscall_count;
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
+/* Note that local_irq_count() is replaced by sparc64 specific version for SMP */
+
+#ifndef CONFIG_SMP
+#define irq_enter(cpu, irq)    ((void)(irq), local_irq_count(cpu)++)
+#define irq_exit(cpu, irq)     ((void)(irq), local_irq_count(cpu)--)
+#else
+#undef local_irq_count
 #define local_irq_count(cpu)   (__brlock_array[cpu][BR_GLOBALIRQ_LOCK])
 #define irq_enter(cpu, irq)    br_read_lock(BR_GLOBALIRQ_LOCK)
 #define irq_exit(cpu, irq)     br_read_unlock(BR_GLOBALIRQ_LOCK)
index c70b95d..0927fe5 100644 (file)
@@ -34,7+34,7 @@ extern struct prom_cpuinfo linux_cpus[64];
 /* Keep this a multiple of 64-bytes for cache reasons. */
 struct cpuinfo_sparc {
        /* Dcache line 1 */
-       unsigned int    bh_count;
+       unsigned int    __pad0;         /* bh_count moved to irq_stat for consistency. KAO */
        unsigned int    multiplier;
        unsigned int    counter;
        unsigned int    idle_volume;
index b224a27..730da1b 100644 (file)
 #include <asm/hardirq.h>
 #include <asm/system.h>                /* for membar() */
 
-#ifndef CONFIG_SMP
-extern unsigned int __local_bh_count;
-#define local_bh_count(cpu)    __local_bh_count
-#else
-#define local_bh_count(cpu)    (cpu_data[cpu].bh_count)
-#endif
-
 #define local_bh_disable()     (local_bh_count(smp_processor_id())++)
 #define local_bh_enable()      (local_bh_count(smp_processor_id())--)
 
index 4a4faba..48ae70d 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: stat.h,v 1.6 1999/12/21 14:09:48 jj Exp $ */
+/* $Id: stat.h,v 1.7 2000/08/04 05:35:55 davem Exp $ */
 #ifndef _SPARC64_STAT_H
 #define _SPARC64_STAT_H
 
index cf5cd0b..803a15a 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: system.h,v 1.60 2000/05/29 05:34:02 davem Exp $ */
+/* $Id: system.h,v 1.61 2000/08/04 05:35:55 davem Exp $ */
 #ifndef __SPARC64_SYSTEM_H
 #define __SPARC64_SYSTEM_H
 
index 698a6f2..a350944 100644 (file)
@@ -50,6+50,7 @@ enum chipset_type {
        VIA_VP3,
        VIA_MVP3,
        VIA_MVP4,
+       VIA_APOLLO_SUPER,
        VIA_APOLLO_PRO,
        SIS_GENERIC,
        AMD_GENERIC,
index 8eb1718..9d214fa 100644 (file)
@@ -61,20+61,9 @@ enum
        TASKLET_SOFTIRQ
 };
 
-#if SMP_CACHE_BYTES <= 32
-/* It is trick to make assembly easier. */
-#define SOFTIRQ_STATE_PAD 32
-#else
-#define SOFTIRQ_STATE_PAD SMP_CACHE_BYTES
-#endif
-
-struct softirq_state
-{
-       __u32   active;
-       __u32   mask;
-} __attribute__ ((__aligned__(SOFTIRQ_STATE_PAD)));
-
-extern struct softirq_state softirq_state[NR_CPUS];
+/* softirq mask and active fields moved to irq_cpustat_t in
+ * asm/hardirq.h to get better cache usage.  KAO
+ */
 
 struct softirq_action
 {
@@ -87,7+76,7 @@ extern void open_softirq(int nr, void (*action)(struct softirq_action*), void *d
 
 static inline void __cpu_raise_softirq(int cpu, int nr)
 {
-       softirq_state[cpu].active |= (1<<nr);
+       softirq_active(cpu) |= (1<<nr);
 }
 
 
diff --git a/include/linux/irq_cpustat.h b/include/linux/irq_cpustat.h
new file mode 100644 (file)
index 0000000..98cf96f
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef __irq_cpustat_h
+#define __irq_cpustat_h
+
+/*
+ * Contains default mappings for irq_cpustat_t, used by almost every
+ * architecture.  Some arch (like s390) have per cpu hardware pages and
+ * they define their own mappings for irq_stat.
+ *
+ * Keith Owens <kaos@ocs.com.au> July 2000.
+ */
+
+/*
+ * Simple wrappers reducing source bloat.  Define all irq_stat fields
+ * here, even ones that are arch dependent.  That way we get common
+ * definitions instead of differing sets for each arch.
+ */
+
+extern irq_cpustat_t irq_stat[];                       /* defined in asm/hardirq.h */
+
+#ifdef CONFIG_SMP
+#define __IRQ_STAT(cpu, member)        (irq_stat[cpu].member)
+#else
+#define __IRQ_STAT(cpu, member)        ((void)(cpu), irq_stat[0].member)
+#endif 
+
+  /* arch independent irq_stat fields */
+#define softirq_active(cpu)    __IRQ_STAT((cpu), __softirq_active)
+#define softirq_mask(cpu)      __IRQ_STAT((cpu), __softirq_mask)
+#define local_irq_count(cpu)   __IRQ_STAT((cpu), __local_irq_count)
+#define local_bh_count(cpu)    __IRQ_STAT((cpu), __local_bh_count)
+#define syscall_count(cpu)     __IRQ_STAT((cpu), __syscall_count)
+  /* arch dependent irq_stat fields */
+#define nmi_count(cpu)         __IRQ_STAT((cpu), __nmi_count)          /* i386, ia64 */
+
+#endif /* __irq_cpustat_h */
index b522397..398660c 100644 (file)
@@ -9,7+9,7 @@
 struct ip_tunnel
 {
        struct ip_tunnel        *next;
-       struct net_device               *dev;
+       struct net_device       *dev;
        struct net_device_stats stat;
 
        int                     recursion;      /* Depth of hard_start_xmit recursion */
@@ -25,6+25,25 @@ struct ip_tunnel
        struct ip_tunnel_parm   parms;
 };
 
+#define IPTUNNEL_XMIT() do {                                           \
+       int err;                                                        \
+       int pkt_len = skb->len;                                         \
+                                                                       \
+       iph->tot_len = htons(skb->len);                                 \
+       ip_select_ident(iph, &rt->u.dst);                               \
+       ip_send_check(iph);                                             \
+                                                                       \
+       err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, do_ip_send); \
+       if (err == NET_XMIT_SUCCESS || err == NET_XMIT_CN) {            \
+               stats->tx_bytes += pkt_len;                             \
+               stats->tx_packets++;                                    \
+       } else {                                                        \
+               stats->tx_errors++;                                     \
+               stats->tx_aborted_errors++;                             \
+       }                                                               \
+} while (0)
+
+
 extern int     ipip_init(void);
 extern int     ipgre_init(void);
 extern int     sit_init(void);
index 45eb977..18b8158 100644 (file)
@@ -26,17+26,20 @@ static void release(struct task_struct * p)
 {
        if (p != current) {
 #ifdef CONFIG_SMP
-               int has_cpu;
-
                /*
                 * Wait to make sure the process isn't on the
                 * runqueue (active on some other CPU still)
                 */
-               do {
+               for (;;) {
                        spin_lock_irq(&runqueue_lock);
-                       has_cpu = p->has_cpu;
+                       if (!p->has_cpu)
+                               break;
                        spin_unlock_irq(&runqueue_lock);
-               } while (has_cpu);
+                       do {
+                               barrier();
+                       } while (p->has_cpu);
+               }
+               spin_unlock_irq(&runqueue_lock);
 #endif
                atomic_dec(&p->user->processes);
                free_uid(p->user);
index 8fc4594..348210c 100644 (file)
@@ -112,6+112,7 @@ int exec_usermodehelper(char *program_path, char *argv[], char *envp[])
                struct user_struct *user = current->user;
                current->user = INIT_USER;
                atomic_inc(&current->user->__count);
+               atomic_dec(&user->processes);
                free_uid(user);
        }
 
index 241855d..bcc6d2e 100644 (file)
@@ -353,6+353,9 @@ EXPORT_SYMBOL(add_timer);
 EXPORT_SYMBOL(del_timer);
 EXPORT_SYMBOL(request_irq);
 EXPORT_SYMBOL(free_irq);
+#if !defined(CONFIG_ARCH_S390)
+EXPORT_SYMBOL(irq_stat);       /* No separate irq_stat for s390, it is part of PSA */
+#endif
 
 /* waitqueue handling */
 EXPORT_SYMBOL(add_wait_queue);
index 6d99e08..688b30c 100644 (file)
@@ -506,7+506,7 @@ tq_scheduler_back:
        release_kernel_lock(prev, this_cpu);
 
        /* Do "administrative" work here while we don't hold any locks */
-       if (softirq_state[this_cpu].active & softirq_state[this_cpu].mask)
+       if (softirq_active(this_cpu) & softirq_mask(this_cpu))
                goto handle_softirq;
 handle_softirq_back:
 
index 19e068c..8c54103 100644 (file)
    - Bottom halves: globally serialized, grr...
  */
 
+/* No separate irq_stat for s390, it is part of PSA */
+#if !defined(CONFIG_ARCH_S390)
+irq_cpustat_t irq_stat[NR_CPUS];
+#endif /* CONFIG_ARCH_S390 */
 
-struct softirq_state softirq_state[NR_CPUS];
 static struct softirq_action softirq_vec[32];
 
 asmlinkage void do_softirq()
@@ -53,15+56,15 @@ asmlinkage void do_softirq()
        local_bh_disable();
 
        local_irq_disable();
-       mask = softirq_state[cpu].mask;
-       active = softirq_state[cpu].active & mask;
+       mask = softirq_mask(cpu);
+       active = softirq_active(cpu) & mask;
 
        if (active) {
                struct softirq_action *h;
 
 restart:
                /* Reset active bitmask before enabling irqs */
-               softirq_state[cpu].active &= ~active;
+               softirq_active(cpu) &= ~active;
 
                local_irq_enable();
 
@@ -77,7+80,7 @@ restart:
 
                local_irq_disable();
 
-               active = softirq_state[cpu].active;
+               active = softirq_active(cpu);
                if ((active &= mask) != 0)
                        goto retry;
        }
@@ -107,7+110,7 @@ void open_softirq(int nr, void (*action)(struct softirq_action*), void *data)
        softirq_vec[nr].action = action;
 
        for (i=0; i<NR_CPUS; i++)
-               softirq_state[i].mask |= (1<<nr);
+               softirq_mask(i) |= (1<<nr);
        spin_unlock_irqrestore(&softirq_mask_lock, flags);
 }
 
index d9f96da..daae4df 100644 (file)
@@ -8,6+8,7 @@
  * able to have per-user limits for system resources. 
  */
 
+#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
index 8349685..e11b5d0 100644 (file)
@@ -118,6+118,8 @@ static void flush_all_zero_pkmaps(void)
 {
        int i;
 
+       flush_cache_all();
+
        for (i = 0; i < LAST_PKMAP; i++) {
                struct page *page;
                pte_t pte;
@@ -181,7+183,7 @@ start:
                }
        }
        vaddr = PKMAP_ADDR(last_pkmap_nr);
-       pkmap_page_table[last_pkmap_nr] = mk_pte(page, kmap_prot);
+       set_pte(pkmap_page_table + last_pkmap_nr, mk_pte(page, kmap_prot));
 
        pkmap_count[last_pkmap_nr] = 1;
        page->virtual = vaddr;
index 1e19a91..941cb59 100644 (file)
@@ -29,7+29,7 @@ int nr_lru_pages;
 pg_data_t *pgdat_list;
 
 static char *zone_names[MAX_NR_ZONES] = { "DMA", "Normal", "HighMem" };
-static int zone_balance_ratio[MAX_NR_ZONES] = { 128, 128, 128, };
+static int zone_balance_ratio[MAX_NR_ZONES] = { 32, 128, 128, };
 static int zone_balance_min[MAX_NR_ZONES] = { 10 , 10, 10, };
 static int zone_balance_max[MAX_NR_ZONES] = { 255 , 255, 255, };
 
@@ -430,7+430,16 @@ void show_free_areas_core(int nid)
                zone_t *zone = NODE_DATA(nid)->node_zones + type;
                unsigned long nr, total, flags;
 
-               printk("  %s: ", zone->name);
+               printk("  %c%d%d %s: ",
+                      (zone->free_pages > zone->pages_low
+                       ? (zone->free_pages > zone->pages_high
+                          ? ' '
+                          : 'H')
+                       : (zone->free_pages > zone->pages_min
+                          ? 'M'
+                          : 'L')),
+                      zone->zone_wake_kswapd, zone->low_on_memory,
+                      zone->name);
 
                total = 0;
                if (zone->size) {
index cbdd0cb..4dda15d 100644 (file)
@@ -444,20+444,24 @@ static inline int memory_pressure(void)
  */
 static inline int keep_kswapd_awake(void)
 {
+       int all_recent = 1;
        pg_data_t *pgdat = pgdat_list;
 
        do {
                int i;
                for(i = 0; i < MAX_NR_ZONES; i++) {
                        zone_t *zone = pgdat->node_zones+ i;
-                       if (zone->size &&
-                           !zone->zone_wake_kswapd)
-                               return 0;
+                       if (zone->size) {
+                               if (zone->free_pages < zone->pages_min)
+                                       return 1;
+                               if (!zone->zone_wake_kswapd)
+                                       all_recent = 0;
+                       }
                }
                pgdat = pgdat->node_next;
        } while (pgdat);
 
-       return 1;
+       return all_recent;
 }
 
 /*
@@ -470,6+474,9 @@ static inline int keep_kswapd_awake(void)
  *
  * Don't try _too_ hard, though. We don't want to have bad
  * latency.
+ *
+ * Note: only called by kswapd and try_to_free_pages
+ *       both can WAIT at top level.
  */
 #define FREE_COUNT     8
 #define SWAP_COUNT     16
@@ -548,7+555,7 @@ static int do_try_to_free_pages(unsigned int gfp_mask)
        }
        /* Return 1 if any page is freed, or
         * there are no more memory pressure   */
-       return (count < FREE_COUNT || !memory_pressure());
+       return (count < FREE_COUNT || !keep_kswapd_awake());
  
 done:
        return 1;
index a569c0c..3c6c9b7 100644 (file)
@@ -5,7+5,7 @@
  *     Authors:
  *     Lennert Buytenhek               <buytenh@gnu.org>
  *
- *     $Id: br.c,v 1.43 2000/05/25 02:21:36 davem Exp $
+ *     $Id: br.c,v 1.44 2000/08/04 06:08:32 davem Exp $
  *
  *     This program is free software; you can redistribute it and/or
  *     modify it under the terms of the GNU General Public License
@@ -43,7+43,9 @@ int __init br_init(void)
        printk(KERN_INFO "NET4: Ethernet Bridge 008 for NET4.0\n");
 
        br_handle_frame_hook = br_handle_frame;
+#ifdef CONFIG_INET
        br_ioctl_hook = br_ioctl_deviceless_stub;
+#endif
 #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
        br_fdb_get_hook = br_fdb_get;
        br_fdb_put_hook = br_fdb_put;
@@ -60,7+62,9 @@ static void __br_clear_frame_hook(void)
 
 static void __br_clear_ioctl_hook(void)
 {
+#ifdef CONFIG_INET
        br_ioctl_hook = NULL;
+#endif 
 }
 
 static void __exit br_deinit(void)
index b0d9895..f6df3a5 100644 (file)
@@ -407,7+407,7 @@ static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev)
 
        for (h=0; h<=PNEIGH_HASHMASK; h++) {
                np = &tbl->phash_buckets[h]; 
-               for (np = &tbl->phash_buckets[h]; (n=*np) != NULL; np = &n->next) {
+               while ((n=*np) != NULL) {
                        if (n->dev == dev || dev == NULL) {
                                *np = n->next;
                                if (tbl->pdestructor)
index ab8cb89..3aaa2fd 100644 (file)
@@ -7,7+7,7 @@
  *             handler for protocols to use and generic option handler.
  *
  *
- * Version:    $Id: sock.c,v 1.95 2000/07/08 00:20:43 davem Exp $
+ * Version:    $Id: sock.c,v 1.96 2000/07/26 01:04:14 davem Exp $
  *
  * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
index 81d8ebe..2dfd176 100644 (file)
@@ -1,6+1,6 @@
 /* linux/net/inet/arp.c
  *
- * Version:    $Id: arp.c,v 1.87 2000/07/07 22:40:35 davem Exp $
+ * Version:    $Id: arp.c,v 1.88 2000/08/02 06:05:02 davem Exp $
  *
  * Copyright (C) 1994 by Florian  La Roche
  *
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
-#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
-static char *ax2asc2(ax25_address *a, char *buf);
-#endif
 
 
 /*
@@ -1015,6+1012,9 @@ out:
 #ifndef CONFIG_PROC_FS
 static int arp_get_info(char *buffer, char **start, off_t offset, int length) { return 0; }
 #else
+#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
+static char *ax2asc2(ax25_address *a, char *buf);
+#endif
 #define HBUFFERLEN 30
 
 static int arp_get_info(char *buffer, char **start, off_t offset, int length)
@@ -1168,6+1168,7 @@ void __init arp_init (void)
 }
 
 
+#ifdef CONFIG_PROC_FS
 #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
 
 /*
@@ -1202,3+1203,4 @@ char *ax2asc2(ax25_address *a, char *buf)
 }
 
 #endif
+#endif
index a7f5d3e..050f528 100644 (file)
@@ -1,7+1,7 @@
 /*
  *     NET3    IP device support routines.
  *
- *     Version: $Id: devinet.c,v 1.36 2000/01/09 02:19:46 davem Exp $
+ *     Version: $Id: devinet.c,v 1.37 2000/07/26 01:04:15 davem Exp $
  *
  *             This program is free software; you can redistribute it and/or
  *             modify it under the terms of the GNU General Public License
index 6cac59c..ee7e44c 100644 (file)
@@ -3,7+3,7 @@
  *     
  *             Alan Cox, <alan@redhat.com>
  *
- *     Version: $Id: icmp.c,v 1.70 2000/06/21 17:16:21 davem Exp $
+ *     Version: $Id: icmp.c,v 1.71 2000/08/02 06:01:48 davem Exp $
  *
  *     This program is free software; you can redistribute it and/or
  *     modify it under the terms of the GNU General Public License
@@ -669,7+669,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, unsigned long info)
        room -= sizeof(struct iphdr) + icmp_param.replyopts.optlen;
        room -= sizeof(struct icmphdr);
 
-       icmp_param.data_len=(iph->ihl<<2)+(skb_in->tail-(u8*)iph);
+       icmp_param.data_len=(skb_in->tail-(u8*)iph);
        if (icmp_param.data_len > room)
                icmp_param.data_len = room;
        
index 94d6499..0af9ec3 100644 (file)
@@ -8,7+8,7 @@
  *     the older version didn't come out right using gcc 2.5.8, the newer one
  *     seems to fall out with gcc 2.6.2.
  *
- *     Version: $Id: igmp.c,v 1.39 2000/06/21 17:17:32 davem Exp $
+ *     Version: $Id: igmp.c,v 1.40 2000/07/26 01:04:16 davem Exp $
  *
  *     Authors:
  *             Alan Cox <Alan.Cox@linux.org>
index a316401..c2a3ea2 100644 (file)
@@ -668,7+668,6 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
        int    gre_hlen;
        u32    dst;
        int    mtu;
-       int    err;
 
        if (tunnel->recursion++) {
                tunnel->stat.collisions++;
@@ -856,26+855,12 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
                }
        }
 
-       iph->tot_len            =       htons(skb->len);
-       ip_select_ident(iph, &rt->u.dst);
-       ip_send_check(iph);
-
 #ifdef CONFIG_NETFILTER
        nf_conntrack_put(skb->nfct);
        skb->nfct = NULL;
 #endif
 
-       err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
-               do_ip_send);
-       if(err < 0) {
-               if(net_ratelimit())
-                       printk(KERN_ERR "ipgre_tunnel_xmit: ip_send() failed, err=%d\n", -err);
-               skb = NULL;
-               goto tx_error;
-       }
-
-       stats->tx_bytes += skb->len;
-       stats->tx_packets++;
+       IPTUNNEL_XMIT();
        tunnel->recursion--;
        return 0;
 
@@ -884,8+869,7 @@ tx_error_icmp:
 
 tx_error:
        stats->tx_errors++;
-       if(skb)
-               dev_kfree_skb(skb);
+       dev_kfree_skb(skb);
        tunnel->recursion--;
        return 0;
 }
index 89b3206..53e6644 100644 (file)
@@ -5,7+5,7 @@
  *
  *             The options processing module for ip.c
  *
- * Version:    $Id: ip_options.c,v 1.18 1999/06/09 08:29:06 davem Exp $
+ * Version:    $Id: ip_options.c,v 1.19 2000/07/26 01:04:17 davem Exp $
  *
  * Authors:    A.N.Kuznetsov
  *             
index c1c0bb0..22429bb 100644 (file)
@@ -5,7+5,7 @@
  *
  *             The IP to API glue.
  *             
- * Version:    $Id: ip_sockglue.c,v 1.49 2000/07/08 00:20:43 davem Exp $
+ * Version:    $Id: ip_sockglue.c,v 1.50 2000/07/26 01:04:17 davem Exp $
  *
  * Authors:    see ip.c
  *
index 765da51..f0e9bb5 100644 (file)
@@ -1,5+1,5 @@
 /*
- *  $Id: ipconfig.c,v 1.33 2000/06/21 17:21:43 davem Exp $
+ *  $Id: ipconfig.c,v 1.34 2000/07/26 01:04:18 davem Exp $
  *
  *  Automatic Configuration of IP -- use BOOTP or RARP or user-supplied
  *  information to configure own IP address and routes.
index 1177033..02af22f 100644 (file)
@@ -1,7+1,7 @@
 /*
  *     Linux NET3:     IP/IP protocol decoder. 
  *
- *     Version: $Id: ipip.c,v 1.37 2000/07/07 23:47:45 davem Exp $
+ *     Version: $Id: ipip.c,v 1.38 2000/08/02 06:03:59 davem Exp $
  *
  *     Authors:
  *             Sam Lantinga (slouken@cs.ucdavis.edu)  02/01/95
@@ -534,7+534,6 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
        int    max_headroom;                    /* The extra header space needed */
        u32    dst = tiph->daddr;
        int    mtu;
-       int    err;
 
        if (tunnel->recursion++) {
                tunnel->stat.collisions++;
@@ -637,26+636,12 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
        if ((iph->ttl = tiph->ttl) == 0)
                iph->ttl        =       old_iph->ttl;
 
-       iph->tot_len            =       htons(skb->len);
-       ip_select_ident(iph, &rt->u.dst);
-       ip_send_check(iph);
-
 #ifdef CONFIG_NETFILTER
        nf_conntrack_put(skb->nfct);
        skb->nfct = NULL;
 #endif
 
-       err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
-               do_ip_send);
-       if(err < 0) {
-               if(net_ratelimit())
-                       printk(KERN_ERR "ipip_tunnel_xmit: ip_send() failed, err=%d\n", -err);
-               skb = NULL;
-               goto tx_error;
-       }
-
-       stats->tx_bytes += skb->len;
-       stats->tx_packets++;
+       IPTUNNEL_XMIT();
        tunnel->recursion--;
        return 0;
 
@@ -664,8+649,7 @@ tx_error_icmp:
        dst_link_failure(skb);
 tx_error:
        stats->tx_errors++;
-       if(skb)
-               dev_kfree_skb(skb);
+       dev_kfree_skb(skb);
        tunnel->recursion--;
        return 0;
 }
index e9d087d..dc946b9 100644 (file)
@@ -9,7+9,7 @@
  *     as published by the Free Software Foundation; either version
  *     2 of the License, or (at your option) any later version.
  *
- *     Version: $Id: ipmr.c,v 1.53 2000/05/05 02:17:17 davem Exp $
+ *     Version: $Id: ipmr.c,v 1.54 2000/08/02 06:05:16 davem Exp $
  *
  *     Fixes:
  *     Michael Chastain        :       Incorrect size of copying.
@@ -1581,6+1581,7 @@ int ipmr_get_route(struct sk_buff *skb, struct rtmsg *rtm, int nowait)
 }
 #endif
 
+#ifdef CONFIG_PROC_FS  
 /*
  *     The /proc interfaces to multicast routing /proc/ip_mr_cache /proc/ip_mr_vif
  */
@@ -1711,7+1712,6 @@ done:
        return len;
 }
 
-#ifdef CONFIG_PROC_FS  
 #endif 
 
 #ifdef CONFIG_IP_PIMSM_V2
index 3661440..aaaa134 100644 (file)
  *     license in recognition of the original copyright.
  *                             -- Alan Cox.
  *
- *     $Id: ipfwadm_core.c,v 1.3 2000/06/09 07:35:49 davem Exp $
+ *     $Id: ipfwadm_core.c,v 1.4 2000/07/26 01:04:21 davem Exp $
  *
  *     Ported from BSD to Linux,
  *             Alan Cox 22/Nov/1994.
index 39cd96e..d267223 100644 (file)
@@ -9,7+9,7 @@
  *      as published by the Free Software Foundation; either version
  *      2 of the License, or (at your option) any later version.
  * 
- *  $Id: syncookies.c,v 1.11 2000/01/16 05:11:27 davem Exp $
+ *  $Id: syncookies.c,v 1.12 2000/07/26 01:04:19 davem Exp $
  *
  *  Missing: IPv6 support. 
  */
index 1fcf0e2..d9f7dd8 100644 (file)
@@ -5,7+5,7 @@
  *
  *             Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:    $Id: tcp_ipv4.c,v 1.209 2000/07/12 03:49:30 davem Exp $
+ * Version:    $Id: tcp_ipv4.c,v 1.210 2000/07/26 01:04:19 davem Exp $
  *
  *             IPv4 specific functions
  *
index 582531a..62b89af 100644 (file)
@@ -5,7+5,7 @@
  *     Authors:
  *     Pedro Roque             <roque@di.fc.ul.pt>     
  *
- *     $Id: mcast.c,v 1.31 2000/06/21 17:23:54 davem Exp $
+ *     $Id: mcast.c,v 1.32 2000/07/26 01:04:21 davem Exp $
  *
  *     Based on linux/ipv4/igmp.c and linux/ipv4/ip_sockglue.c 
  *
index b3ba438..57430f2 100644 (file)
@@ -314,7+314,7 @@ ip6t_do_table(struct sk_buff **pskb,
 
        /* Initialization */
        ipv6 = (*pskb)->nh.ipv6h;
-       protohdr = (u_int32_t *)ipv6 + IPV6_HDR_LEN;
+       protohdr = (u_int32_t *)((char *)ipv6 + IPV6_HDR_LEN);
        datalen = (*pskb)->len - IPV6_HDR_LEN;
        indev = in ? in->name : nulldevname;
        outdev = out ? out->name : nulldevname;
index c8a631f..b77f878 100644 (file)
@@ -6,7+6,7 @@
  *     Pedro Roque             <roque@di.fc.ul.pt>     
  *     Alexey Kuznetsov        <kuznet@ms2.inr.ac.ru>
  *
- *     $Id: sit.c,v 1.41 2000/07/07 23:47:45 davem Exp $
+ *     $Id: sit.c,v 1.42 2000/08/02 06:03:59 davem Exp $
  *
  *     This program is free software; you can redistribute it and/or
  *      modify it under the terms of the GNU General Public License
@@ -440,7+440,6 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
        int    mtu;
        struct in6_addr *addr6; 
        int addr_type;
-       int err;
 
        if (tunnel->recursion++) {
                tunnel->stat.collisions++;
@@ -565,27+564,12 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
        if ((iph->ttl = tiph->ttl) == 0)
                iph->ttl        =       iph6->hop_limit;
 
-       iph->tot_len            =       htons(skb->len);
-       ip_select_ident(iph, &rt->u.dst);
-       ip_send_check(iph);
-
 #ifdef CONFIG_NETFILTER
        nf_conntrack_put(skb->nfct);
        skb->nfct = NULL;
 #endif
 
-       err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, 
-               do_ip_send);
-       if(err < 0) {
-               if(net_ratelimit())
-                       printk(KERN_ERR "ipip6_tunnel_xmit: ip_send() failed, err=%d\n", -err);
-               skb = NULL;
-               goto tx_error;
-       }
-
-       stats->tx_bytes += skb->len;
-       stats->tx_packets++;
-
+       IPTUNNEL_XMIT();
        tunnel->recursion--;
        return 0;
 
@@ -593,8+577,7 @@ tx_error_icmp:
        dst_link_failure(skb);
 tx_error:
        stats->tx_errors++;
-       if(skb)
-               dev_kfree_skb(skb);
+       dev_kfree_skb(skb);
        tunnel->recursion--;
        return 0;
 }
index b822688..da99c07 100644 (file)
@@ -617,7+617,6 @@ EXPORT_SYMBOL(ipt_unregister_match);
 EXPORT_SYMBOL(register_gifconf);
 
 EXPORT_SYMBOL(net_call_rx_atomic);
-EXPORT_SYMBOL(softirq_state);
 EXPORT_SYMBOL(softnet_data);
 
 #endif  /* CONFIG_NET */
index b342c4f..b0ea8b7 100644 (file)
@@ -5,7+5,7 @@
  *
  *             PACKET - implements raw packet sockets.
  *
- * Version:    $Id: af_packet.c,v 1.36 2000/07/08 00:20:43 davem Exp $
+ * Version:    $Id: af_packet.c,v 1.37 2000/07/26 01:04:21 davem Exp $
  *
  * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
index 93a4fbb..d1728e6 100644 (file)
@@ -336,7+336,7 @@ __rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task,
        } else {
                task->tk_running = 0;
                if (task->tk_callback) {
-                       printk(KERN_ERR "RPC: %4d overwrites an active callback\n", task->tk_pid);
+                       dprintk(KERN_ERR "RPC: %4d overwrites an active callback\n", task->tk_pid);
                        BUG();
                }
                task->tk_callback = action;
index 628269f..1d32726 100644 (file)
@@ -8,7+8,7 @@
  *             as published by the Free Software Foundation; either version
  *             2 of the License, or (at your option) any later version.
  *
- * Version:    $Id: af_unix.c,v 1.101 2000/07/06 01:41:46 davem Exp $
+ * Version:    $Id: af_unix.c,v 1.102 2000/07/26 01:04:21 davem Exp $
  *
  * Fixes:
  *             Linus Torvalds  :       Assorted bug cures.
index 0eec0f9..4cc31e4 100644 (file)
@@ -419,7+419,14 @@ function define_string () {
 function string () {
        old=$(eval echo "\${$2}")
        def=${old:-$3}
-       readln "$1 ($2) [$def] " "$def" "$old"
+       while :; do
+         readln "$1 ($2) [$def] " "$def" "$old"
+         if [ "$ans" = "?" ]; then
+           help "$2"
+         else
+           break
+         fi
+       done
        define_string "$2" "$ans"
 }
 #
close