summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-08-08 18:54:49 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-08-08 18:54:49 +0000
commit5514f4babeeb3af00ee0c325e3cda7a562cc3d65 (patch)
treeedd733879cab73e41324a99ca5da7bc154c4196d
parent6a9366db547e958e8c9bf8e1c13bcea6cb2bf393 (diff)
Merge with Linux 2.4.0-test6-pre4.
-rw-r--r--CREDITS4
-rw-r--r--Documentation/Configure.help13
-rw-r--r--Documentation/kbuild/config-language.txt1
-rw-r--r--Makefile2
-rw-r--r--arch/alpha/kernel/alpha_ksyms.c3
-rw-r--r--arch/alpha/kernel/entry.S4
-rw-r--r--arch/alpha/kernel/irq_alpha.c4
-rw-r--r--arch/alpha/kernel/irq_smp.c8
-rw-r--r--arch/alpha/kernel/smp.c4
-rw-r--r--arch/arm/kernel/armksyms.c2
-rw-r--r--arch/arm/kernel/entry-common.S12
-rw-r--r--arch/arm/kernel/irq.c4
-rw-r--r--arch/i386/kernel/entry.S16
-rw-r--r--arch/i386/kernel/i386_ksyms.c2
-rw-r--r--arch/i386/kernel/io_apic.c2
-rw-r--r--arch/i386/kernel/irq.c6
-rw-r--r--arch/i386/kernel/traps.c2
-rw-r--r--arch/ia64/kernel/entry.S6
-rw-r--r--arch/ia64/kernel/ia64_ksyms.c4
-rw-r--r--arch/ia64/kernel/irq.c4
-rw-r--r--arch/m68k/atari/ataints.c4
-rw-r--r--arch/m68k/kernel/entry.S10
-rw-r--r--arch/m68k/kernel/ints.c4
-rw-r--r--arch/m68k/kernel/m68k_ksyms.c2
-rw-r--r--arch/mips/baget/irq.c1
-rw-r--r--arch/mips/dec/irq.c4
-rw-r--r--arch/mips/kernel/entry.S4
-rw-r--r--arch/mips/kernel/irq.c6
-rw-r--r--arch/mips/kernel/mips_ksyms.c1
-rw-r--r--arch/mips/kernel/scall_o32.S4
-rw-r--r--arch/mips/orion/irq.c5
-rw-r--r--arch/mips/orion/misc.c2
-rw-r--r--arch/mips/orion/setup.c2
-rw-r--r--arch/mips/sgi/kernel/indy_int.c4
-rw-r--r--arch/mips64/kernel/entry.S6
-rw-r--r--arch/mips64/kernel/scall_64.S4
-rw-r--r--arch/mips64/kernel/scall_o32.S4
-rw-r--r--arch/mips64/sgi-ip22/ip22-int.c4
-rw-r--r--arch/mips64/sgi-ip27/ip27-irq.c4
-rw-r--r--arch/ppc/kernel/entry.S8
-rw-r--r--arch/ppc/kernel/irq.c1
-rw-r--r--arch/ppc/kernel/local_irq.h2
-rw-r--r--arch/ppc/kernel/ppc_ksyms.c1
-rw-r--r--arch/s390/kernel/entry.S28
-rw-r--r--arch/s390/kernel/irq.c14
-rw-r--r--arch/s390/kernel/process.c4
-rw-r--r--arch/s390/kernel/s390io.c7
-rw-r--r--arch/s390/mm/fault.c2
-rw-r--r--arch/sh/kernel/entry.S8
-rw-r--r--arch/sh/kernel/irq.c7
-rw-r--r--arch/sparc/config.in3
-rw-r--r--arch/sparc/kernel/irq.c23
-rw-r--r--arch/sparc/kernel/rtrap.S6
-rw-r--r--arch/sparc/kernel/sparc_ksyms.c2
-rw-r--r--arch/sparc/mm/init.c135
-rw-r--r--arch/sparc/mm/srmmu.c29
-rw-r--r--arch/sparc64/config.in25
-rw-r--r--arch/sparc64/defconfig12
-rw-r--r--arch/sparc64/kernel/ebus.c8
-rw-r--r--arch/sparc64/kernel/entry.S6
-rw-r--r--arch/sparc64/kernel/ioctl32.c13
-rw-r--r--arch/sparc64/kernel/irq.c14
-rw-r--r--arch/sparc64/kernel/process.c4
-rw-r--r--arch/sparc64/kernel/rtrap.S28
-rw-r--r--arch/sparc64/kernel/signal.c6
-rw-r--r--arch/sparc64/kernel/smp.c1
-rw-r--r--arch/sparc64/kernel/sparc64_ksyms.c10
-rw-r--r--arch/sparc64/kernel/sunos_ioctl32.c4
-rw-r--r--arch/sparc64/kernel/sys_sparc.c40
-rw-r--r--arch/sparc64/kernel/sys_sparc32.c134
-rw-r--r--arch/sparc64/kernel/sys_sunos32.c35
-rw-r--r--arch/sparc64/kernel/traps.c13
-rw-r--r--arch/sparc64/solaris/fs.c12
-rw-r--r--arch/sparc64/solaris/ioctl.c13
-rw-r--r--arch/sparc64/solaris/timod.c5
-rw-r--r--drivers/char/Config.in2
-rw-r--r--drivers/char/agp/agpgart_be.c15
-rw-r--r--drivers/char/drm/agpsupport.c29
-rw-r--r--drivers/char/drm/drmP.h4
-rw-r--r--drivers/char/drm/drm_syms.c3
-rw-r--r--drivers/char/radio-typhoon.c28
-rw-r--r--drivers/net/appletalk/ltpc.c14
-rw-r--r--drivers/net/pcmcia/ray_cs.c3
-rw-r--r--drivers/net/pppoe.c164
-rw-r--r--drivers/net/wan/syncppp.c3
-rw-r--r--drivers/sbus/char/Makefile8
-rw-r--r--drivers/sbus/char/display7seg.c238
-rw-r--r--drivers/scsi/3w-xxxx.c6
-rw-r--r--drivers/scsi/ips.c1948
-rw-r--r--drivers/scsi/ips.h651
-rw-r--r--drivers/sound/Makefile2
-rw-r--r--drivers/video/Config.in14
-rw-r--r--drivers/video/S3triofb.c30
-rw-r--r--drivers/video/chipsfb.c10
-rw-r--r--drivers/video/clgenfb.c68
-rw-r--r--drivers/video/controlfb.c15
-rw-r--r--drivers/video/fbmem.c163
-rw-r--r--drivers/video/imsttfb.c60
-rw-r--r--drivers/video/matrox/matroxfb_base.c6
-rw-r--r--drivers/video/offb.c122
-rw-r--r--drivers/video/platinumfb.c15
-rw-r--r--drivers/video/valkyriefb.c44
-rw-r--r--drivers/video/valkyriefb.h8
-rw-r--r--fs/inode.c4
-rw-r--r--include/asm-alpha/hardirq.h26
-rw-r--r--include/asm-alpha/smp.h1
-rw-r--r--include/asm-alpha/softirq.h7
-rw-r--r--include/asm-arm/hardirq.h15
-rw-r--r--include/asm-i386/hardirq.h16
-rw-r--r--include/asm-ia64/hardirq.h18
-rw-r--r--include/asm-m68k/hardirq.h21
-rw-r--r--include/asm-m68k/softirq.h10
-rw-r--r--include/asm-m68k/system.h2
-rw-r--r--include/asm-mips/hardirq.h12
-rw-r--r--include/asm-mips/mc146818rtc.h1
-rw-r--r--include/asm-mips64/hardirq.h17
-rw-r--r--include/asm-mips64/processor.h1
-rw-r--r--include/asm-mips64/smp.h1
-rw-r--r--include/asm-ppc/hardirq.h13
-rw-r--r--include/asm-ppc/softirq.h2
-rw-r--r--include/asm-s390/hardirq.h43
-rw-r--r--include/asm-s390/irq.h4
-rw-r--r--include/asm-s390/lowcore.h32
-rw-r--r--include/asm-s390/softirq.h6
-rw-r--r--include/asm-sh/hardirq.h23
-rw-r--r--include/asm-sh/softirq.h6
-rw-r--r--include/asm-sparc/hardirq.h41
-rw-r--r--include/asm-sparc/highmem.h149
-rw-r--r--include/asm-sparc/irq.h6
-rw-r--r--include/asm-sparc/kmap_types.h10
-rw-r--r--include/asm-sparc/pgalloc.h6
-rw-r--r--include/asm-sparc/softirq.h17
-rw-r--r--include/asm-sparc/stat.h2
-rw-r--r--include/asm-sparc/system.h2
-rw-r--r--include/asm-sparc/vaddrs.h16
-rw-r--r--include/asm-sparc64/display7seg.h79
-rw-r--r--include/asm-sparc64/hardirq.h23
-rw-r--r--include/asm-sparc64/smp.h2
-rw-r--r--include/asm-sparc64/softirq.h7
-rw-r--r--include/asm-sparc64/stat.h2
-rw-r--r--include/asm-sparc64/system.h2
-rw-r--r--include/linux/agp_backend.h1
-rw-r--r--include/linux/interrupt.h19
-rw-r--r--include/linux/irq_cpustat.h35
-rw-r--r--include/net/ipip.h21
-rw-r--r--kernel/exit.c13
-rw-r--r--kernel/kmod.c1
-rw-r--r--kernel/ksyms.c3
-rw-r--r--kernel/sched.c2
-rw-r--r--kernel/softirq.c15
-rw-r--r--kernel/user.c1
-rw-r--r--mm/highmem.c4
-rw-r--r--mm/page_alloc.c13
-rw-r--r--mm/vmscan.c17
-rw-r--r--net/bridge/br.c6
-rw-r--r--net/core/neighbour.c2
-rw-r--r--net/core/sock.c2
-rw-r--r--net/ipv4/arp.c10
-rw-r--r--net/ipv4/devinet.c2
-rw-r--r--net/ipv4/icmp.c4
-rw-r--r--net/ipv4/igmp.c2
-rw-r--r--net/ipv4/ip_gre.c20
-rw-r--r--net/ipv4/ip_options.c2
-rw-r--r--net/ipv4/ip_sockglue.c2
-rw-r--r--net/ipv4/ipconfig.c2
-rw-r--r--net/ipv4/ipip.c22
-rw-r--r--net/ipv4/ipmr.c4
-rw-r--r--net/ipv4/netfilter/ipfwadm_core.c2
-rw-r--r--net/ipv4/syncookies.c2
-rw-r--r--net/ipv4/tcp_ipv4.c2
-rw-r--r--net/ipv6/mcast.c2
-rw-r--r--net/ipv6/netfilter/ip6_tables.c2
-rw-r--r--net/ipv6/sit.c23
-rw-r--r--net/netsyms.c1
-rw-r--r--net/packet/af_packet.c2
-rw-r--r--net/sunrpc/sched.c2
-rw-r--r--net/unix/af_unix.c2
-rw-r--r--scripts/Configure9
178 files changed, 3571 insertions, 1862 deletions
diff --git a/CREDITS b/CREDITS
index 6398542e8..49ba8e308 100644
--- 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
diff --git a/Documentation/Configure.help b/Documentation/Configure.help
index b94126f2c..585a2b83b 100644
--- a/Documentation/Configure.help
+++ b/Documentation/Configure.help
@@ -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:
diff --git a/Documentation/kbuild/config-language.txt b/Documentation/kbuild/config-language.txt
index dc1756013..d139848da 100644
--- a/Documentation/kbuild/config-language.txt
+++ b/Documentation/kbuild/config-language.txt
@@ -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.
diff --git a/Makefile b/Makefile
index b618f5ad0..a1555ea3e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 4
SUBLEVEL = 0
-EXTRAVERSION = -test6-pre3
+EXTRAVERSION = -test6-pre4
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c
index 078aa7d3d..4ac2e8b0d 100644
--- a/arch/alpha/kernel/alpha_ksyms.c
+++ b/arch/alpha/kernel/alpha_ksyms.c
@@ -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);
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S
index 253b8d6c1..ac80051ed 100644
--- a/arch/alpha/kernel/entry.S
+++ b/arch/alpha/kernel/entry.S
@@ -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
diff --git a/arch/alpha/kernel/irq_alpha.c b/arch/alpha/kernel/irq_alpha.c
index 066af7e1e..59f102496 100644
--- a/arch/alpha/kernel/irq_alpha.c
+++ b/arch/alpha/kernel/irq_alpha.c
@@ -14,11 +14,7 @@
#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
diff --git a/arch/alpha/kernel/irq_smp.c b/arch/alpha/kernel/irq_smp.c
index 90a3c30b2..9022228a0 100644
--- a/arch/alpha/kernel/irq_smp.c
+++ b/arch/alpha/kernel/irq_smp.c
@@ -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--) {
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
index e51ff9d18..4f7a04b3f 100644
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -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;
}
/*
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index 6723291df..fc14d6c45 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -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);
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index b4fbfe628..c260b8e19 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -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)
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 40a47c45f..8af0c3b3f 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -46,8 +46,6 @@
*/
#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;
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
index da7fd047d..c36d01cce 100644
--- a/arch/i386/kernel/entry.S
+++ b/arch/i386/kernel/entry.S
@@ -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
diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c
index 380ac4996..c11ab01f2 100644
--- a/arch/i386/kernel/i386_ksyms.c
+++ b/arch/i386/kernel/i386_ksyms.c
@@ -141,6 +141,4 @@ EXPORT_SYMBOL(screen_info);
EXPORT_SYMBOL(get_wchan);
-EXPORT_SYMBOL(irq_stat);
-
EXPORT_SYMBOL(rtc_lock);
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index 406a30771..525f78624 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -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;
}
diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c
index fcc0a72f5..92ddd01f5 100644
--- a/arch/i386/kernel/irq.c
+++ b/arch/i386/kernel/irq.c
@@ -61,8 +61,6 @@
* 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;
}
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index eea525873..7bd8a04d0 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -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
/*
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index 3aadb43a0..f9beac21d 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -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
;;
diff --git a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c
index 7f01b667c..2e4ffe403 100644
--- a/arch/ia64/kernel/ia64_ksyms.c
+++ b/arch/ia64/kernel/ia64_ksyms.c
@@ -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);
diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c
index ed7eb88fc..c913fdc3d 100644
--- a/arch/ia64/kernel/irq.c
+++ b/arch/ia64/kernel/irq.c
@@ -60,8 +60,6 @@
* 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: ");
diff --git a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c
index f47ff3a7a..f92c45f60 100644
--- a/arch/m68k/atari/ataints.c
+++ b/arch/m68k/atari/ataints.c
@@ -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 */
diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S
index 5f08ef216..7cbb69d03 100644
--- a/arch/m68k/kernel/entry.S
+++ b/arch/m68k/kernel/entry.S
@@ -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)
diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c
index 9dc6427e6..74e1e4c1e 100644
--- a/arch/m68k/kernel/ints.c
+++ b/arch/m68k/kernel/ints.c
@@ -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,
diff --git a/arch/m68k/kernel/m68k_ksyms.c b/arch/m68k/kernel/m68k_ksyms.c
index 6f8300422..7bf46149f 100644
--- a/arch/m68k/kernel/m68k_ksyms.c
+++ b/arch/m68k/kernel/m68k_ksyms.c
@@ -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);
diff --git a/arch/mips/baget/irq.c b/arch/mips/baget/irq.c
index 08b15a7a8..03d68ee17 100644
--- a/arch/mips/baget/irq.c
+++ b/arch/mips/baget/irq.c
@@ -29,7 +29,6 @@
#include <asm/baget/baget.h>
-irq_cpustat_t irq_stat [NR_CPUS];
unsigned long spurious_count = 0;
/*
diff --git a/arch/mips/dec/irq.c b/arch/mips/dec/irq.c
index 7551ae681..91e1ce463 100644
--- a/arch/mips/dec/irq.c
+++ b/arch/mips/dec/irq.c
@@ -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)
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S
index bde21011f..bc56db51b 100644
--- a/arch/mips/kernel/entry.S
+++ b/arch/mips/kernel/entry.S
@@ -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
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
index 54c2c3c81..fcb7a632f 100644
--- a/arch/mips/kernel/irq.c
+++ b/arch/mips/kernel/irq.c
@@ -47,8 +47,6 @@
* 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. */
diff --git a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c
index b58272f46..3b3c43111 100644
--- a/arch/mips/kernel/mips_ksyms.c
+++ b/arch/mips/kernel/mips_ksyms.c
@@ -140,4 +140,3 @@ EXPORT_SYMBOL(ide_ops);
#endif
EXPORT_SYMBOL(get_wchan);
-EXPORT_SYMBOL(irq_stat);
diff --git a/arch/mips/kernel/scall_o32.S b/arch/mips/kernel/scall_o32.S
index ddf69a964..bdc72ca4e 100644
--- a/arch/mips/kernel/scall_o32.S
+++ b/arch/mips/kernel/scall_o32.S
@@ -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
diff --git a/arch/mips/orion/irq.c b/arch/mips/orion/irq.c
index f61690b85..1721b47ae 100644
--- a/arch/mips/orion/irq.c
+++ b/arch/mips/orion/irq.c
@@ -25,9 +25,6 @@
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. */
diff --git a/arch/mips/orion/misc.c b/arch/mips/orion/misc.c
index 1c6d9e2fa..0d8881058 100644
--- a/arch/mips/orion/misc.c
+++ b/arch/mips/orion/misc.c
@@ -35,10 +35,8 @@
#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, };
diff --git a/arch/mips/orion/setup.c b/arch/mips/orion/setup.c
index 8d4cc54f0..c247d6b52 100644
--- a/arch/mips/orion/setup.c
+++ b/arch/mips/orion/setup.c
@@ -35,10 +35,8 @@
#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>
diff --git a/arch/mips/sgi/kernel/indy_int.c b/arch/mips/sgi/kernel/indy_int.c
index 06d8573cb..2e104bf79 100644
--- a/arch/mips/sgi/kernel/indy_int.c
+++ b/arch/mips/sgi/kernel/indy_int.c
@@ -55,8 +55,6 @@
* 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:
diff --git a/arch/mips64/kernel/entry.S b/arch/mips64/kernel/entry.S
index 8f61ca7ee..ee4881448 100644
--- a/arch/mips64/kernel/entry.S
+++ b/arch/mips64/kernel/entry.S
@@ -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?
diff --git a/arch/mips64/kernel/scall_64.S b/arch/mips64/kernel/scall_64.S
index a6ac27f68..2e65e1732 100644
--- a/arch/mips64/kernel/scall_64.S
+++ b/arch/mips64/kernel/scall_64.S
@@ -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
diff --git a/arch/mips64/kernel/scall_o32.S b/arch/mips64/kernel/scall_o32.S
index de5b98494..a43fef7bd 100644
--- a/arch/mips64/kernel/scall_o32.S
+++ b/arch/mips64/kernel/scall_o32.S
@@ -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
diff --git a/arch/mips64/sgi-ip22/ip22-int.c b/arch/mips64/sgi-ip22/ip22-int.c
index 891e121f6..19c61e6dc 100644
--- a/arch/mips64/sgi-ip22/ip22-int.c
+++ b/arch/mips64/sgi-ip22/ip22-int.c
@@ -53,8 +53,6 @@
* 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:
diff --git a/arch/mips64/sgi-ip27/ip27-irq.c b/arch/mips64/sgi-ip27/ip27-irq.c
index f5160af15..ead444bb5 100644
--- a/arch/mips64/sgi-ip27/ip27-irq.c
+++ b/arch/mips64/sgi-ip27/ip27-irq.c
@@ -59,16 +59,12 @@
* 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;
/*
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S
index 8ccb0f571..d40a54cf1 100644
--- a/arch/ppc/kernel/entry.S
+++ b/arch/ppc/kernel/entry.S
@@ -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
diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c
index ee63ca902..64ef4b4dc 100644
--- a/arch/ppc/kernel/irq.c
+++ b/arch/ppc/kernel/irq.c
@@ -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];
diff --git a/arch/ppc/kernel/local_irq.h b/arch/ppc/kernel/local_irq.h
index 840b14d6f..5c616bbbd 100644
--- a/arch/ppc/kernel/local_irq.h
+++ b/arch/ppc/kernel/local_irq.h
@@ -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;
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
index 3f0b52ead..1317359e7 100644
--- a/arch/ppc/kernel/ppc_ksyms.c
+++ b/arch/ppc/kernel/ppc_ksyms.c
@@ -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 */
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 9acccfd97..9913d5967 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -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:
#
diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c
index 298aa2482..ba513325a 100644
--- a/arch/s390/kernel/irq.c
+++ b/arch/s390/kernel/irq.c
@@ -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;
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 93d4dff76..6f6a5287b 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -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;
}
diff --git a/arch/s390/kernel/s390io.c b/arch/s390/kernel/s390io.c
index 7a4e531d5..b1db16707 100644
--- a/arch/s390/kernel/s390io.c
+++ b/arch/s390/kernel/s390io.c
@@ -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));
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index cfc744a63..f20a9d49e 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -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;
diff --git a/arch/sh/kernel/entry.S b/arch/sh/kernel/entry.S
index cbca87e69..450d49824 100644
--- a/arch/sh/kernel/entry.S
+++ b/arch/sh/kernel/entry.S
@@ -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)
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index 399d435af..a353b0995 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -41,9 +41,6 @@
#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;
}
diff --git a/arch/sparc/config.in b/arch/sparc/config.in
index e79dfd803..570f86325 100644
--- a/arch/sparc/config.in
+++ b/arch/sparc/config.in
@@ -1,10 +1,11 @@
-# $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'
diff --git a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c
index 65e95afdb..a6fd32fa4 100644
--- a/arch/sparc/kernel/irq.c
+++ b/arch/sparc/kernel/irq.c
@@ -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())
diff --git a/arch/sparc/kernel/rtrap.S b/arch/sparc/kernel/rtrap.S
index dcfc2dc78..c44040bde 100644
--- a/arch/sparc/kernel/rtrap.S
+++ b/arch/sparc/kernel/rtrap.S
@@ -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
diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c
index a51995713..37c276c7f 100644
--- a/arch/sparc/kernel/sparc_ksyms.c
+++ b/arch/sparc/kernel/sparc_ksyms.c
@@ -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);
diff --git a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c
index 5ac1845a3..ced31b91f 100644
--- a/arch/sparc/mm/init.c
+++ b/arch/sparc/mm/init.c
@@ -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);
+}
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index 612436b47..c7f839f28 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -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);
}
}
diff --git a/arch/sparc64/config.in b/arch/sparc64/config.in
index 95c148eee..c57f14bb1 100644
--- a/arch/sparc64/config.in
+++ b/arch/sparc64/config.in
@@ -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'
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index e013e47fb..168109d49 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -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
diff --git a/arch/sparc64/kernel/ebus.c b/arch/sparc64/kernel/ebus.c
index f64422a0e..5872046b1 100644
--- a/arch/sparc64/kernel/ebus.c
+++ b/arch/sparc64/kernel/ebus.c
@@ -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();
}
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
index 3195d3e75..e95e0392e 100644
--- a/arch/sparc64/kernel/entry.S
+++ b/arch/sparc64/kernel/entry.S
@@ -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
diff --git a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c
index 98e209de2..d4f499726 100644
--- a/arch/sparc64/kernel/ioctl32.c
+++ b/arch/sparc64/kernel/ioctl32.c
@@ -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)
@@ -72,7 +72,7 @@
#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;
}
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index 12925b1c2..c7f4905b8 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -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);
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index 2d5d81452..5784201e2 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -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;
diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S
index 1c9b6ac3f..3295938e6 100644
--- a/arch/sparc64/kernel/rtrap.S
+++ b/arch/sparc64/kernel/rtrap.S
@@ -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
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c
index c666dc408..d1e7e4215 100644
--- a/arch/sparc64/kernel/signal.c
+++ b/arch/sparc64/kernel/signal.c
@@ -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);
}
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index f99b9660c..96f8624ca 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -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;
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
index eccc7885a..4a79b76bf 100644
--- a/arch/sparc64/kernel/sparc64_ksyms.c
+++ b/arch/sparc64/kernel/sparc64_ksyms.c
@@ -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);
diff --git a/arch/sparc64/kernel/sunos_ioctl32.c b/arch/sparc64/kernel/sunos_ioctl32.c
index d32ea68c2..bcfa77a39 100644
--- a/arch/sparc64/kernel/sunos_ioctl32.c
+++ b/arch/sparc64/kernel/sunos_ioctl32.c
@@ -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;
}
diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c
index 859d0c7ea..e869af4e6 100644
--- a/arch/sparc64/kernel/sys_sparc.c
+++ b/arch/sparc64/kernel/sys_sparc.c
@@ -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;
}
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index 89c1a90ea..7d8a71d6a 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -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) {
diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c
index 3f43e99dc..9015a2fec 100644
--- a/arch/sparc64/kernel/sys_sunos32.c
+++ b/arch/sparc64/kernel/sys_sunos32.c
@@ -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;
}
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
index 7b5d32614..de4968ac4 100644
--- a/arch/sparc64/kernel/traps.c
+++ b/arch/sparc64/kernel/traps.c
@@ -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);
diff --git a/arch/sparc64/solaris/fs.c b/arch/sparc64/solaris/fs.c
index 090eb96a1..3cf5b6883 100644
--- a/arch/sparc64/solaris/fs.c
+++ b/arch/sparc64/solaris/fs.c
@@ -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)
@@ -25,8 +25,6 @@
#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);
diff --git a/arch/sparc64/solaris/ioctl.c b/arch/sparc64/solaris/ioctl.c
index 18d73e686..0e899da18 100644
--- a/arch/sparc64/solaris/ioctl.c
+++ b/arch/sparc64/solaris/ioctl.c
@@ -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)
@@ -31,9 +31,6 @@
#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 */
diff --git a/arch/sparc64/solaris/timod.c b/arch/sparc64/solaris/timod.c
index 946b20fae..3ef9c943b 100644
--- a/arch/sparc64/solaris/timod.c
+++ b/arch/sparc64/solaris/timod.c
@@ -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)
@@ -27,9 +27,6 @@
#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,
diff --git a/drivers/char/Config.in b/drivers/char/Config.in
index f41c3d48b..2ac91160d 100644
--- a/drivers/char/Config.in
+++ b/drivers/char/Config.in
@@ -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
diff --git a/drivers/char/agp/agpgart_be.c b/drivers/char/agp/agpgart_be.c
index dcc8176f9..573419a28 100644
--- a/drivers/char/agp/agpgart_be.c
+++ b/drivers/char/agp/agpgart_be.c
@@ -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;
}
diff --git a/drivers/char/drm/agpsupport.c b/drivers/char/drm/agpsupport.c
index 48a6aa5f9..e1e1ccedd 100644
--- a/drivers/char/drm/agpsupport.c
+++ b/drivers/char/drm/agpsupport.c
@@ -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",
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index 3e5149c91..e4783c8db 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -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);
diff --git a/drivers/char/drm/drm_syms.c b/drivers/char/drm/drm_syms.c
index e7aaf569d..661ac4816 100644
--- a/drivers/char/drm/drm_syms.c
+++ b/drivers/char/drm/drm_syms.c
@@ -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);
diff --git a/drivers/char/radio-typhoon.c b/drivers/char/radio-typhoon.c
index 434dff875..a0bbf343f 100644
--- a/drivers/char/radio-typhoon.c
+++ b/drivers/char/radio-typhoon.c
@@ -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 */
diff --git a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c
index 681379708..d9b818824 100644
--- a/drivers/net/appletalk/ltpc.c
+++ b/drivers/net/appletalk/ltpc.c
@@ -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;
diff --git a/drivers/net/pcmcia/ray_cs.c b/drivers/net/pcmcia/ray_cs.c
index 36b11f907..281940845 100644
--- a/drivers/net/pcmcia/ray_cs.c
+++ b/drivers/net/pcmcia/ray_cs.c
@@ -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);
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c
index a2da24437..84dc28025 100644
--- a/drivers/net/pppoe.c
+++ b/drivers/net/pppoe.c
@@ -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);
diff --git a/drivers/net/wan/syncppp.c b/drivers/net/wan/syncppp.c
index 1ee37e20e..096d8164a 100644
--- a/drivers/net/wan/syncppp.c
+++ b/drivers/net/wan/syncppp.c
@@ -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;
diff --git a/drivers/sbus/char/Makefile b/drivers/sbus/char/Makefile
index 4a88efda3..84ee1ad22 100644
--- a/drivers/sbus/char/Makefile
+++ b/drivers/sbus/char/Makefile
@@ -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
index 000000000..c9d4ea0f6
--- /dev/null
+++ b/drivers/sbus/char/display7seg.c
@@ -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
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
index ebe4e33ba..ba6cc03cf 100644
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -62,6 +62,8 @@
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)
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index e5c5ca10f..9ebe9e927 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -66,6 +66,18 @@
/* 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> */
/* */
/*****************************************************************************/
@@ -78,9 +90,7 @@
*
*/
-#if defined (MODULE)
- #include <linux/module.h>
-#endif /* MODULE */
+#include <linux/module.h>
#include <asm/io.h>
#include <asm/byteorder.h>
@@ -110,14 +120,33 @@
#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"
@@ -132,7 +161,7 @@
#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);
}
@@ -2053,8 +2640,13 @@ ips_removeq_scb(ips_scb_queue_t *queue, ips_scb_t *item) {
if (!item)
return (NULL);
- if (item == queue->head)
+ IPS_QUEUE_LOCK(queue);
+
+ if (item == queue->head) {
+ IPS_QUEUE_UNLOCK(queue);
+
return (ips_removeq_scb_head(queue));
+ }
p = queue->head;
@@ -2071,9 +2663,13 @@ ips_removeq_scb(ips_scb_queue_t *queue, ips_scb_t *item) {
item->q_next = NULL;
queue->count--;
+ IPS_QUEUE_UNLOCK(queue);
+
return (item);
}
+ IPS_QUEUE_UNLOCK(queue);
+
return (NULL);
}
@@ -2095,6 +2691,8 @@ ips_putq_wait_head(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
if (!item)
return ;
+ IPS_QUEUE_LOCK(queue);
+
item->host_scribble = (char *) queue->head;
queue->head = item;
@@ -2102,6 +2700,8 @@ ips_putq_wait_head(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
queue->tail = item;
queue->count++;
+
+ IPS_QUEUE_UNLOCK(queue);
}
/****************************************************************************/
@@ -2122,6 +2722,8 @@ ips_putq_wait_tail(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
if (!item)
return ;
+ IPS_QUEUE_LOCK(queue);
+
item->host_scribble = NULL;
if (queue->tail)
@@ -2133,6 +2735,8 @@ ips_putq_wait_tail(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
queue->head = item;
queue->count++;
+
+ IPS_QUEUE_UNLOCK(queue);
}
/****************************************************************************/
@@ -2152,10 +2756,15 @@ ips_removeq_wait_head(ips_wait_queue_t *queue) {
DBG("ips_removeq_wait_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;
@@ -2165,6 +2774,8 @@ ips_removeq_wait_head(ips_wait_queue_t *queue) {
queue->count--;
+ IPS_QUEUE_UNLOCK(queue);
+
return (item);
}
@@ -2188,8 +2799,13 @@ ips_removeq_wait(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
if (!item)
return (NULL);
- if (item == queue->head)
+ IPS_QUEUE_LOCK(queue);
+
+ if (item == queue->head) {
+ IPS_QUEUE_UNLOCK(queue);
+
return (ips_removeq_wait_head(queue));
+ }
p = queue->head;
@@ -2206,9 +2822,172 @@ ips_removeq_wait(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
item->host_scribble = NULL;
queue->count--;
+ IPS_QUEUE_UNLOCK(queue);
+
return (item);
}
+ IPS_QUEUE_UNLOCK(queue);
+
+ return (NULL);
+}
+
+/****************************************************************************/
+/* */
+/* Routine Name: ips_putq_copp_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_copp_head(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) {
+ DBG("ips_putq_copp_head");
+
+ if (!item)
+ return ;
+
+ 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_copp_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_copp_tail(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) {
+ DBG("ips_putq_copp_tail");
+
+ if (!item)
+ return ;
+
+ IPS_QUEUE_LOCK(queue);
+
+ item->next = NULL;
+
+ if (queue->tail)
+ queue->tail->next = item;
+
+ queue->tail = item;
+
+ if (!queue->head)
+ queue->head = item;
+
+ queue->count++;
+
+ IPS_QUEUE_UNLOCK(queue);
+}
+
+/****************************************************************************/
+/* */
+/* Routine Name: ips_removeq_copp_head */
+/* */
+/* Routine Description: */
+/* */
+/* Remove the head of the queue */
+/* */
+/* ASSUMED to be called from within a lock */
+/* */
+/****************************************************************************/
+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_copp_head");
+
+ IPS_QUEUE_LOCK(queue);
+
+ item = queue->head;
+
+ if (!item) {
+ IPS_QUEUE_UNLOCK(queue);
+
+ return (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_copp */
+/* */
+/* Routine Description: */
+/* */
+/* Remove an item from a queue */
+/* */
+/* ASSUMED to be called from within a lock */
+/* */
+/****************************************************************************/
+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_copp");
+
+ if (!item)
+ return (NULL);
+
+ IPS_QUEUE_LOCK(queue);
+
+ if (item == queue->head) {
+ IPS_QUEUE_UNLOCK(queue);
+
+ return (ips_removeq_copp_head(queue));
+ }
+
+ p = queue->head;
+
+ while ((p) && (item != p->next))
+ p = p->next;
+
+ if (p) {
+ /* found a match */
+ p->next = item->next;
+
+ if (!item->next)
+ queue->tail = p;
+
+ 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;
diff --git a/drivers/scsi/ips.h b/drivers/scsi/ips.h
index d760ae3a6..e93fe8153 100644
--- a/drivers/scsi/ips.h
+++ b/drivers/scsi/ips.h
@@ -47,7 +47,6 @@
#ifndef _IPS_H_
#define _IPS_H_
- #include <linux/config.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -67,209 +66,276 @@
* 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, \
@@ -291,7 +357,7 @@
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
diff --git a/drivers/sound/Makefile b/drivers/sound/Makefile
index 2c7dbb018..399148c74 100644
--- a/drivers/sound/Makefile
+++ b/drivers/sound/Makefile
@@ -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
diff --git a/drivers/video/Config.in b/drivers/video/Config.in
index 0b30ebb38..fe26b4c01 100644
--- a/drivers/video/Config.in
+++ b/drivers/video/Config.in
@@ -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
diff --git a/drivers/video/S3triofb.c b/drivers/video/S3triofb.c
index 333fd6576..bcc2b9b7b 100644
--- a/drivers/video/S3triofb.c
+++ b/drivers/video/S3triofb.c
@@ -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;
diff --git a/drivers/video/chipsfb.c b/drivers/video/chipsfb.c
index 96a3b9a79..22f6031b2 100644
--- a/drivers/video/chipsfb.c
+++ b/drivers/video/chipsfb.c
@@ -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
diff --git a/drivers/video/clgenfb.c b/drivers/video/clgenfb.c
index a88919d65..e38198485 100644
--- a/drivers/video/clgenfb.c
+++ b/drivers/video/clgenfb.c
@@ -56,9 +56,6 @@
#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)
*/
diff --git a/drivers/video/controlfb.c b/drivers/video/controlfb.c
index 10453891d..b609f43f2 100644
--- a/drivers/video/controlfb.c
+++ b/drivers/video/controlfb.c
@@ -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. */
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 9cb20fc0d..6ca8c3dcf 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -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;
diff --git a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c
index d3b3e5a38..1749f3246 100644
--- a/drivers/video/imsttfb.c
+++ b/drivers/video/imsttfb.c
@@ -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);
}
}
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c
index cbdc9848b..9ddb30140 100644
--- a/drivers/video/matrox/matroxfb_base.c
+++ b/drivers/video/matrox/matroxfb_base.c
@@ -95,7 +95,7 @@
#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");
diff --git a/drivers/video/offb.c b/drivers/video/offb.c
index 69bb8cc72..1399d6882 100644
--- a/drivers/video/offb.c
+++ b/drivers/video/offb.c
@@ -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? */
diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c
index 3bbd7fe48..558b6f44e 100644
--- a/drivers/video/platinumfb.c
+++ b/drivers/video/platinumfb.c
@@ -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 */
diff --git a/drivers/video/valkyriefb.c b/drivers/video/valkyriefb.c
index 6739cecf9..9e7132f86 100644
--- a/drivers/video/valkyriefb.c
+++ b/drivers/video/valkyriefb.c
@@ -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;
}
diff --git a/drivers/video/valkyriefb.h b/drivers/video/valkyriefb.h
index c8984b38b..8ff0eaabf 100644
--- a/drivers/video/valkyriefb.h
+++ b/drivers/video/valkyriefb.h
@@ -1,10 +1,13 @@
/*
* 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
};
diff --git a/fs/inode.c b/fs/inode.c
index 62acffd58..455c4af6e 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -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;
diff --git a/include/asm-alpha/hardirq.h b/include/asm-alpha/hardirq.h
index 3961ac4a4..66ab89ce4 100644
--- a/include/asm-alpha/hardirq.h
+++ b/include/asm-alpha/hardirq.h
@@ -1,20 +1,19 @@
#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>
diff --git a/include/asm-alpha/smp.h b/include/asm-alpha/smp.h
index 3143b0872..44ec5e8ea 100644
--- a/include/asm-alpha/smp.h
+++ b/include/asm-alpha/smp.h
@@ -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;
diff --git a/include/asm-alpha/softirq.h b/include/asm-alpha/softirq.h
index ef77f861e..dd18dc490 100644
--- a/include/asm-alpha/softirq.h
+++ b/include/asm-alpha/softirq.h
@@ -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)++;
diff --git a/include/asm-arm/hardirq.h b/include/asm-arm/hardirq.h
index c12ed91e3..550310ffe 100644
--- a/include/asm-arm/hardirq.h
+++ b/include/asm-arm/hardirq.h
@@ -4,11 +4,16 @@
#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
diff --git a/include/asm-i386/hardirq.h b/include/asm-i386/hardirq.h
index aef182212..3860288ad 100644
--- a/include/asm-i386/hardirq.h
+++ b/include/asm-i386/hardirq.h
@@ -5,21 +5,17 @@
#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
diff --git a/include/asm-ia64/hardirq.h b/include/asm-ia64/hardirq.h
index 7b24f385c..38a12be6e 100644
--- a/include/asm-ia64/hardirq.h
+++ b/include/asm-ia64/hardirq.h
@@ -11,23 +11,17 @@
#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
diff --git a/include/asm-m68k/hardirq.h b/include/asm-m68k/hardirq.h
index aac7e8597..8a1e6a445 100644
--- a/include/asm-m68k/hardirq.h
+++ b/include/asm-m68k/hardirq.h
@@ -3,17 +3,26 @@
#include <linux/threads.h>
-extern unsigned int local_irq_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 in_interrupt() (local_irq_count[smp_processor_id()] + local_bh_count[smp_processor_id()] != 0)
+#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
-#define in_irq() (local_irq_count[smp_processor_id()] != 0)
+#define in_interrupt() (local_irq_count(smp_processor_id()) + local_bh_count(smp_processor_id()) != 0)
-#define hardirq_trylock(cpu) (local_irq_count[cpu] == 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 irq_enter(cpu) (local_irq_count(cpu)++)
+#define irq_exit(cpu) (local_irq_count(cpu)--)
#define synchronize_irq() barrier()
diff --git a/include/asm-m68k/softirq.h b/include/asm-m68k/softirq.h
index a51563cd7..89a3e3971 100644
--- a/include/asm-m68k/softirq.h
+++ b/include/asm-m68k/softirq.h
@@ -7,16 +7,14 @@
#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
diff --git a/include/asm-m68k/system.h b/include/asm-m68k/system.h
index 64dab98d8..a33bb7c14 100644
--- a/include/asm-m68k/system.h
+++ b/include/asm-m68k/system.h
@@ -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
diff --git a/include/asm-mips/hardirq.h b/include/asm-mips/hardirq.h
index 4331f1367..eead2fb87 100644
--- a/include/asm-mips/hardirq.h
+++ b/include/asm-mips/hardirq.h
@@ -14,18 +14,16 @@
#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
diff --git a/include/asm-mips/mc146818rtc.h b/include/asm-mips/mc146818rtc.h
index bae7fcd1a..f521b7239 100644
--- a/include/asm-mips/mc146818rtc.h
+++ b/include/asm-mips/mc146818rtc.h
@@ -10,6 +10,7 @@
#ifndef _ASM_MC146818RTC_H
#define _ASM_MC146818RTC_H
+#include <linux/config.h>
#include <asm/io.h>
#ifndef RTC_PORT
diff --git a/include/asm-mips64/hardirq.h b/include/asm-mips64/hardirq.h
index 192b61f7b..088fb8853 100644
--- a/include/asm-mips64/hardirq.h
+++ b/include/asm-mips64/hardirq.h
@@ -14,19 +14,16 @@
#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
diff --git a/include/asm-mips64/processor.h b/include/asm-mips64/processor.h
index 565d6cb88..3e8cab4b5 100644
--- a/include/asm-mips64/processor.h
+++ b/include/asm-mips64/processor.h
@@ -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 */
diff --git a/include/asm-mips64/smp.h b/include/asm-mips64/smp.h
index ed0420dd4..b8a8f8d75 100644
--- a/include/asm-mips64/smp.h
+++ b/include/asm-mips64/smp.h
@@ -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];
diff --git a/include/asm-ppc/hardirq.h b/include/asm-ppc/hardirq.h
index cc7425e24..07398997a 100644
--- a/include/asm-ppc/hardirq.h
+++ b/include/asm-ppc/hardirq.h
@@ -4,19 +4,16 @@
#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
diff --git a/include/asm-ppc/softirq.h b/include/asm-ppc/softirq.h
index f23ed416b..4eaed0be6 100644
--- a/include/asm-ppc/softirq.h
+++ b/include/asm-ppc/softirq.h
@@ -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)
diff --git a/include/asm-s390/hardirq.h b/include/asm-s390/hardirq.h
index c21db1cd7..b32a0684a 100644
--- a/include/asm-s390/hardirq.h
+++ b/include/asm-s390/hardirq.h
@@ -16,21 +16,50 @@
#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)
diff --git a/include/asm-s390/irq.h b/include/asm-s390/irq.h
index 895c24649..5efcdd40b 100644
--- a/include/asm-s390/irq.h
+++ b/include/asm-s390/irq.h
@@ -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
diff --git a/include/asm-s390/lowcore.h b/include/asm-s390/lowcore.h
index 22ab31bd8..3430056da 100644
--- a/include/asm-s390/lowcore.h
+++ b/include/asm-s390/lowcore.h
@@ -41,9 +41,10 @@
#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)
diff --git a/include/asm-s390/softirq.h b/include/asm-s390/softirq.h
index b0ad1dc56..ce1254eba 100644
--- a/include/asm-s390/softirq.h
+++ b/include/asm-s390/softirq.h
@@ -17,13 +17,13 @@
#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 */
diff --git a/include/asm-sh/hardirq.h b/include/asm-sh/hardirq.h
index 592b31d95..cfb53de78 100644
--- a/include/asm-sh/hardirq.h
+++ b/include/asm-sh/hardirq.h
@@ -4,28 +4,33 @@
#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()
diff --git a/include/asm-sh/softirq.h b/include/asm-sh/softirq.h
index 44f4e0423..5e539b0ae 100644
--- a/include/asm-sh/softirq.h
+++ b/include/asm-sh/softirq.h
@@ -4,12 +4,12 @@
#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 */
diff --git a/include/asm-sparc/hardirq.h b/include/asm-sparc/hardirq.h
index 8b7b095ad..cfee071dc 100644
--- a/include/asm-sparc/hardirq.h
+++ b/include/asm-sparc/hardirq.h
@@ -10,26 +10,37 @@
#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
index 000000000..ede2167e1
--- /dev/null
+++ b/include/asm-sparc/highmem.h
@@ -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 */
diff --git a/include/asm-sparc/irq.h b/include/asm-sparc/irq.h
index 5859d82e9..4b6dd0dae 100644
--- a/include/asm-sparc/irq.h
+++ b/include/asm-sparc/irq.h
@@ -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
index 000000000..d92d81b20
--- /dev/null
+++ b/include/asm-sparc/kmap_types.h
@@ -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
diff --git a/include/asm-sparc/pgalloc.h b/include/asm-sparc/pgalloc.h
index 20e9d805e..180709c85 100644
--- a/include/asm-sparc/pgalloc.h
+++ b/include/asm-sparc/pgalloc.h
@@ -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;
diff --git a/include/asm-sparc/softirq.h b/include/asm-sparc/softirq.h
index f35407dc8..100f25a22 100644
--- a/include/asm-sparc/softirq.h
+++ b/include/asm-sparc/softirq.h
@@ -14,26 +14,9 @@
#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 */
diff --git a/include/asm-sparc/stat.h b/include/asm-sparc/stat.h
index a70d4df3c..7be8e7092 100644
--- a/include/asm-sparc/stat.h
+++ b/include/asm-sparc/stat.h
@@ -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
diff --git a/include/asm-sparc/system.h b/include/asm-sparc/system.h
index 4174294ca..0a101cacd 100644
--- a/include/asm-sparc/system.h
+++ b/include/asm-sparc/system.h
@@ -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
diff --git a/include/asm-sparc/vaddrs.h b/include/asm-sparc/vaddrs.h
index 5cbec8210..704f79003 100644
--- a/include/asm-sparc/vaddrs.h
+++ b/include/asm-sparc/vaddrs.h
@@ -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
@@ -12,6 +12,20 @@
* 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
index 000000000..955a35022
--- /dev/null
+++ b/include/asm-sparc64/display7seg.h
@@ -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__ */
diff --git a/include/asm-sparc64/hardirq.h b/include/asm-sparc64/hardirq.h
index 090239035..e4007b644 100644
--- a/include/asm-sparc64/hardirq.h
+++ b/include/asm-sparc64/hardirq.h
@@ -11,12 +11,27 @@
#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)
diff --git a/include/asm-sparc64/smp.h b/include/asm-sparc64/smp.h
index c70b95dad..0927fe5cc 100644
--- a/include/asm-sparc64/smp.h
+++ b/include/asm-sparc64/smp.h
@@ -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;
diff --git a/include/asm-sparc64/softirq.h b/include/asm-sparc64/softirq.h
index b224a279a..730da1b30 100644
--- a/include/asm-sparc64/softirq.h
+++ b/include/asm-sparc64/softirq.h
@@ -11,13 +11,6 @@
#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())--)
diff --git a/include/asm-sparc64/stat.h b/include/asm-sparc64/stat.h
index 4a4fabac0..48ae70dc9 100644
--- a/include/asm-sparc64/stat.h
+++ b/include/asm-sparc64/stat.h
@@ -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
diff --git a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h
index cf5cd0b02..803a15a51 100644
--- a/include/asm-sparc64/system.h
+++ b/include/asm-sparc64/system.h
@@ -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
diff --git a/include/linux/agp_backend.h b/include/linux/agp_backend.h
index 698a6f262..a35094450 100644
--- a/include/linux/agp_backend.h
+++ b/include/linux/agp_backend.h
@@ -50,6 +50,7 @@ enum chipset_type {
VIA_VP3,
VIA_MVP3,
VIA_MVP4,
+ VIA_APOLLO_SUPER,
VIA_APOLLO_PRO,
SIS_GENERIC,
AMD_GENERIC,
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 8eb171810..9d214fadc 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -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
index 000000000..98cf96ff4
--- /dev/null
+++ b/include/linux/irq_cpustat.h
@@ -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 */
diff --git a/include/net/ipip.h b/include/net/ipip.h
index b522397f8..398660ca8 100644
--- a/include/net/ipip.h
+++ b/include/net/ipip.h
@@ -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);
diff --git a/kernel/exit.c b/kernel/exit.c
index 993ba31f3..3e95fe878 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -26,17 +26,20 @@ 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);
diff --git a/kernel/kmod.c b/kernel/kmod.c
index 8fc459453..348210c3b 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -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);
}
diff --git a/kernel/ksyms.c b/kernel/ksyms.c
index 241855d8e..bcc6d2e31 100644
--- a/kernel/ksyms.c
+++ b/kernel/ksyms.c
@@ -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);
diff --git a/kernel/sched.c b/kernel/sched.c
index 6d99e08ab..688b30c7b 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -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:
diff --git a/kernel/softirq.c b/kernel/softirq.c
index 19e068c65..8c5410315 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -38,8 +38,11 @@
- 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);
}
diff --git a/kernel/user.c b/kernel/user.c
index d9f96da0a..daae4dff4 100644
--- a/kernel/user.c
+++ b/kernel/user.c
@@ -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>
diff --git a/mm/highmem.c b/mm/highmem.c
index 834968569..e11b5d0b1 100644
--- a/mm/highmem.c
+++ b/mm/highmem.c
@@ -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;
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 1e19a9109..941cb5909 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -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) {
diff --git a/mm/vmscan.c b/mm/vmscan.c
index cbdd0cb7f..4dda15dd1 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -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;
diff --git a/net/bridge/br.c b/net/bridge/br.c
index a569c0c97..3c6c9b72d 100644
--- a/net/bridge/br.c
+++ b/net/bridge/br.c
@@ -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)
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index b0d989516..f6df3a526 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -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)
diff --git a/net/core/sock.c b/net/core/sock.c
index ab8cb89e8..3aaa2fd9a 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -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>
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 81d8ebe80..2dfd1763c 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -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
*
@@ -122,9 +122,6 @@
#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
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index a7f5d3e49..050f5283d 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -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
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 6cac59c91..ee7e44cd2 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -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;
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 94d64999f..0af9ec321 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -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>
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index a316401b0..c2a3ea271 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -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;
}
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index 89b3206f0..53e664444 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -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
*
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index c1c0bb047..22429bb5e 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -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
*
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index 765da5148..f0e9bb5bb 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -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.
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 1177033ca..02af22ff9 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -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;
}
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index e9d087d49..dc946b97b 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -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
diff --git a/net/ipv4/netfilter/ipfwadm_core.c b/net/ipv4/netfilter/ipfwadm_core.c
index 36614409d..aaaa134ba 100644
--- a/net/ipv4/netfilter/ipfwadm_core.c
+++ b/net/ipv4/netfilter/ipfwadm_core.c
@@ -20,7 +20,7 @@
* 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.
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index 39cd96ede..d267223ed 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -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.
*/
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 1fcf0e255..d9f7dd80d 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -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
*
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 582531a97..62b89af5c 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -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
*
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index b3ba4383d..57430f29f 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -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;
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index c8a631f9f..b77f8789d 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -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;
}
diff --git a/net/netsyms.c b/net/netsyms.c
index b8226883b..da99c0783 100644
--- a/net/netsyms.c
+++ b/net/netsyms.c
@@ -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 */
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index b342c4f14..b0ea8b730 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -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>
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index 93a4fbb18..d1728e6a6 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -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;
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 628269f57..1d327267e 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -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.
diff --git a/scripts/Configure b/scripts/Configure
index 0eec0f93d..4cc31e42b 100644
--- a/scripts/Configure
+++ b/scripts/Configure
@@ -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"
}
#